When a content is translated, and this translated content have a publish_on value, the Scheduler can't read the publish_on value.
For example, I created a content (by default is English) and translated it to Spanish.
scheduler/src/SchedulerManager.php
if (!empty($scheduler_enabled_types)) {
$query = \Drupal::entityQuery('node')
->exists('publish_on')
->condition('publish_on', REQUEST_TIME, '<=')
->condition('type', $scheduler_enabled_types, 'IN')
->sort('publish_on')
->sort('nid');
$nids = $query->execute();
}
This $nids is not empty, because there is a publish_on in Spanish language.
But the code try to get the value in the default language (English). And this is NULL
$node->publish_on->value
'publish_on' =>
array (size=3)
'x-default' => null
'es' => string '1469556000'
Comments
Comment #2
jkamizato commentedComment #3
jkamizato commentedComment #4
jkamizato commentedNew patch from 561d033463b88a6213e612a03341724be4d827fb version.
This is my current version.
Comment #6
lucas.constantino commentedApplying the same concept, but for unpublish schedules as well.
This patches seem really palliative, though, as they don't address some possible configuration regarding i18n:
1 - Schedules could either be independent or synchronized among languages, such as https://www.drupal.org/node/1182450.
2 - Should we allow the user to choose which languages CAN be scheduled?
Nice work so far.
Comment #7
lucas.constantino commentedForgot the patch:
Comment #8
lucas.constantino commentedNow that I payed a little more attention to the code I see this patch is actually doing something completely unexpected: it is performing a scheduled job to ALL translation that contain a scheduled job, but not necessarily the ones that should be target. For instance, if I say that the English version of a node should be publish on a day, and the Spanish version on the day that follows, both are going to end up publish when the English version gets published.
Comment #9
lucas.constantino commentedLast patch had a bug related to unpublishing the node translations. Here goes an updated one.
Comment #10
jkamizato commentedGreat!
@lucas.constantino I will test your patch soon as possible !!!
Thanks!!!
Comment #11
jonathan1055 commentedYou have to set the status to 'needs review' then automated tests will run on the patch files you upload.
By the way, we had this functionality in 7.x, and used https://www.drupal.org/project/i18n hook_i18n_sync_options() to give admins the option to always keep the dates in sync for translated nodes. We need to find out if the equivalent code has moved to core for 8.x as we do not want to re-invent things.
Comment #12
jkamizato commented@lucas.constantino
Unfortunately, your patch doesn't work.For publish: Keep the same error (Is publishing for other languages)
For unpublish: Don't change the status.
Sorry @lucas.constantino, my bad!
@jonathan1055
I think the code hasn't moved, because without this fix, the cron is broken in D8.
Comment #13
jonathan1055 commentedI don't quite understand what you mean. What I was talking about was the question of whether the I18n sync functionality has moved into 8.x core now that multi-lingual support is in core, as there is no i18n module in Drupal 8. The functionality to keep selected custom fields synced between translations sounds like a basic requirement which might be available without us having to write it for each contrib module.
Comment #14
jkamizato commented@jonathan1055
I understood that you said: i18n was in the scheduler module already. Sorry.
Comment #15
jkamizato commented@lucas.constantino
I used your patch and fixed to publish_on.
Now, change the status for the correct language. What I did was:
I added this:
Comment #19
jkamizato commentedFix the error.
Comment #20
jkamizato commentedComment #21
jkamizato commentedComment #22
jkamizato commentedComment #25
jkamizato commentedThe test is wrong.
Doesn't make sense to publish a node if the publish_on value is less than REQUEST_TIME
Comment #26
jkamizato commentedComment #27
jkamizato commentedComment #28
jkamizato commentedComment #29
jonathan1055 commentedIn your patch, the changes for
src/Tests/SchedulerFunctionalTest.phpsimply have the effect of always skipping the assertion for 'node is published after cron'. Maybe you did not mean this, but all you have done is remove the assertions which were failing. You can't just do that ;-)Can you explain why you think the test is wrong?
Comment #30
jkamizato commentedHello jonathan1055
Yes, you are correct... I am debugging to figure out why my test is failing.
Comment #31
jkamizato commentedHello jonathan1055
I don't know why... but, if you watch the $node->publish_on->value BEFORE and AFTER the db_update behind, the value keep the same. I think thats why my fix doesn't pass in this test.
Its strange, because I verify in the DB and is updated, but if you see the variable, this keep the old value.
Comment #32
jonathan1055 commentedIt will not have changed because the db_update does not affect the
$nodeobject directly. To see the effect you need to clear the cache then re-load the node. Here is an example of this code, from SchedulerNonEnabledTypeTest.php:Then you should be able to see that the value has changed.
Comment #33
jkamizato commentedHello jonathan1055
After working a lot, I fixed the test. Like I said before, the db_update('node_field_data') doesn't working well. Because its necessary to update the db_update('node_field_revision') as well. But I don't think this is a good practice.
So, I replaced the db_update to this:
$node->publish_on->value = time() - 1;
and
$node->save();
This ensure that the node_field_data and node_field_revision is, both, updated.
As you can see in the code, I made this:
Now, the $node_updated->publish_on->value is correty
Comment #34
jkamizato commentedComment #35
jkamizato commentedComment #36
jkamizato commentedComment #37
jkamizato commentedPatch recreated for the last version.
Comment #38
jkamizato commentedFixed error foreach
Comment #39
jkamizato commentedNew patch with code clean
Comment #40
jkamizato commentedFixed error to apply the patch
Comment #41
jkamizato commentedVersion basead on 8.x-1.x
Comment #42
jkamizato commentedComment #45
adrianopulzThis version is to work with this patch (https://www.drupal.org/files/issues/2790459-5.move_rules_to_submodule.patch) applied.
Comment #49
adrianopulzSmall fix for the patch from comment #45. This patch only will work if the patch posted here: https://www.drupal.org/files/issues/2790459-5.move_rules_to_submodule.patch has already been applied.
Comment #50
kopin commentedThe latest Patch seems to be working only on Publish, not unpublish
Comment #51
kopin commentedThis code seems to be doing the opposite form witch its intended. If empty() will make the the loop jump out and go to the next time.
I've changeed it to:
That way it doesn't matter is the publish on is older than request time or not.
We also need to look if the unbuplish_on value is set BEFORE triggering the event otherwise there is not point in even doing it since the node has several languages.
Comment #52
jonathan1055 commentedHi Kopin and adrianopulz,
Thank you for your new contributions to this thread. However, I am still very sceptical about this whole approach. It should not be Scheduler's job within the publish/unpublish cron functions to be making decisions on what other nodes to process. That should all be done way before the cron job processing. Nodes should be scheduled, then the cron processing simply picks up the nodes that are due now.
Please see my comments in #11 and #13 as these have not been addressed. The syncing of node data should really be out of scope of Scheduler altogether, so the whole approach here may be wrong.
Also, my question in #29 was not resolved. I believe that the current test is correct, and the change made to the test in this patch simply removes the failing assertions which are caused by the code changes. This gives a false impression that the code changes are correct. The point about using node_save() and not db_update() is a slight diversion here. The tests in this class are to check the most basic functionality of Scheduler, without doing anything more than the minimum to prove it. I may look into using node_save() here, but that is a separate issue.
We need to use pre-existing functionality in D8.x (either core or contrib) which cater for field data sync.
lucas.constantino had some very good observations in #6 and #8 regarding what this patch is doing, and questioning why. I think we need to step back and make those decisions at a higher level first, then we can decide on how to achieve it.
Comment #53
kopin commentedIn our case we NEED to be able to Publish and unpublish different translations at different times. I think it's a functionality that should exist. The content is not always translated right away and published at the same time.
Without this patch, even if you are not publishing any translations, the basic scheduler functionality doesn't work with multilingual enabled on the site.
Comment #54
jonathan1055 commentedAbsolutely, I totally agree.
I will investigate and try to find a different method to solve this, as I do not believe that we need to get all translations of a node during the cron processing. It should be driven by the scheduling dates already on the nodes.
Comment #56
jonathan1055 commentedI now realise the fundamental difference between D7 and D8 multi-lingual sites. In 7.x each translation was a different node with a different id, but in 8.x all translations are associated with one node id.
There was nothing wrong in principle with the functional test, apart from the fact that the
node_field_revisiontable now also needs to be updated in addition tonode_field, as the ->getTranslation() method uses this. I may re-write that test completely (it was the first one we wrote in 7.x and has been converted verbatim to 8.x). For now, I have made a quick fix commit to updatenode_field_revision.Attached is a patch, now just for the SchedulerManager.php file. It is mainly doing the same as the above patches. Two small changes to
unpublish()(1) Need to skip not just if there is no unpublish date on this translation, but also if there is a date the future.
(2) the test for a publish_on date should only skip the processing if the date was in the past. This is to cater for the future posibility of allowing a publish_on date to be after the unpublish_on date, that is, to allow re-publishing.
I also changed the sequencing of tests, to first skip translations which are not due to be processed. It is better to get these out of the way, and not call other hook funtions on content we know right away will be ignored. I also added better commenting.
Please test this patch and let me know if it continues to work for you. In the meantime I will start writing automated tests for the translation processing.
Comment #57
jkamizato commentedComment #58
jonathan1055 commentedHi jkamizato,
Did you make a comment? If so, it is blank. It would be good if you can test the patch in #56.
Comment #59
balintcsaba commentedPatch #56 is working for me. Thanks!
Comment #60
jonathan1055 commentedThanks for marking RTBC. However, before I commit the changes I want to add tests. This patch should fail with the current code as it only contains the test file, not the fixes in #56
Comment #62
jonathan1055 commentedAs intended, the new test fails without the code fix.
Here's the patch with both.
Comment #64
jkamizato commented@jonathan1055 Tested everything right for me :)
Thanks!!!
Comment #65
jonathan1055 commentedThanks jkamizato for starting off this issue. The main cron processing to publish translations is now committed.
All is fine when the scheduling dates are set to be translatable and independent on each translation. However, I discovered a slight problem when the date is set to be not translatable - this is where a scheduler date entered on one translation is copied to all other translations. This works fine, but our automatic unpublishing of a scheduled node, which is done in
hook_node_presave()is only executed for the translation being saved. The status of the other translations is not changed. Hence we can get the situation where a new translation is scheduled to be published, the date is set on all translations, but the existing published translation remains published. This could be said to be an admin/setup problem. If you want every translation publish-on date to be synchronised then you should also set the node status to be synchronised too. That solves the problem.Does anyone have thoughts on this? We could give a message if the dates are synchronised but status is not set to be synchronised. I do not think we should force both settings. Adding code to
hook_node_presave()could be done, but that may be over-complex.Comment #66
jonathan1055 commentedI have created a follow-up #2871164: Ensure Scheduler dates and status field have consistent translatable settings
This original issue can be now be marked 'fixed'.
Thanks everyone for your help on this. Please check the follow-up issue, I would like to hear the opinions of those who actually use scheduled date translations on real sites.