I am working on the Scheduler project, on a request to synchronise the scheduled dates for nodes which have translations. All works fine, except that we have hit the situation where we need to prevent synchronisation of a node when it is actually being published during a Scheduler cron run. If the sync is not prevented then the other translated nodes (which are also scheduled for publishing) get changed immediately. This has unpredicatable and unwanted side-effects. The full details are in #1182450: i18n support - Synchronize scheduled dates in translated nodes

Fortunately, there is a very nice and simple solution to this, but it requires a new hook function to be called from within the i18n_sync module. The change is entirely within i18n_sync_node_check(). The existing function is:

/**
 * Check whether this node is to be synced
 */
function i18n_sync_node_check($node) {
  return translation_supported_type($node->type) && i18n_object_langcode($node) && i18n_sync();
}

which can be changed to:

/**
 * Check whether this node is to be synced
 */
function i18n_sync_node_check($node) {
  // Allow modules to selectively prevent synchronisation for specific nodes
  // under certain criteria, by implementing hook_i18n_sync_node_check($node).
  $module_checks = TRUE; 
  foreach (module_implements('i18n_sync_node_check') as $module) {
    $function = $module . '_i18n_sync_node_check';
    $module_checks = $module_checks && $function($node);
  }
  return translation_supported_type($node->type) && i18n_object_langcode($node) && i18n_sync() && $module_checks;
}

I'll post a patch here, so you can try it out.

Thanks for a great module,
Jonathan

CommentFileSizeAuthor
#1 2136557_1.hook_to_pevent_sync.patch912 bytesjonathan1055

Comments

jonathan1055’s picture

Status: Active » Needs review
StatusFileSize
new912 bytes

Here is a patch against the dev of 30th Oct.

jose reyero’s picture

This patch may work though I'm not sure we need another hook. Thinking of some of the options i18n_sync provides:

- If you are possitive that node doesn't need synchronization, you can disable it beforehand.

if function_exists('i18n_sync') {i18n_sync(FALSE)};

- If some fields need specific synchronization, you can add your synchronization callback to the field info, see i18n_sync_field_info_alter().

- Or maybe also it is a configuration issue. I mean either there are other nodes/fields to be synchronized or not, and I cannot imagine why they are marked to be syncd but you don't want them to be so. If specific scheduler fields are a problem when synchronized, we can just unmark them, can't we?

Anyway, if this is not a solution, we can work out some better hook, I mean if we are adding one, I'd rather add a more powerful one and also that is invoked only once every time.

jose reyero’s picture

Status: Needs review » Needs work
jonathan1055’s picture

Hi Jose,
Thank you for your comments and taking the time to consider this issue. Let me explain the situation in more detail.

Nodes may be set to have their scheduled publish_on and unpublish_on dates synchronised. That is good when the node is edited, it all works perfectly. Say for example there are three nodes which are linked as translations of each other. A publish_on date is set for one of them and the other two get the same date via sync.

Then during the cron run all three nodes are scheduled to be published by scheduler. Scheduler publishes the first node, altering its status and removing the publish_on date. If sync is not disabled then the other two nodes get their status and publish_on dates changed immediately, without going via Scheduler. Then scheduler attempts to complete the processing it started, but the nodes are now already published and have no publish_on date. Scheduler has not done the publishing - which has implications for third-party modules which have implemented rules to be triggered by Scheduler, or modules which have implemented Schedulers own api for reacting to publish/unpublish events. Only $status and the scheduler date fields are changed by Scheduler during cron publishing, so if sync was turned off or not allowed for the nodes being processed during the cron run that would solve the problem exactly. Scheduler could implement the hook to disallow sync on the node it is processing. At all other times sync would be allowed and everything would work as is.

In answer to your specific points:

  1. Yes I had already found i18n_sync(FALSE) and used it in a patch for Scheduler in #1182450: i18n support - Synchronize scheduled dates in translated nodes. However, the other maintainer did not like the use of calling specific third-party modules, as that can lead to problems later if those functions are changed.
  2. I had also tried to use i18n_sync_field_info_alter() but I could not make it not do the sync. The $fields array always contains the scheduler fields so they always get synchronised
  3. The two scheduler fields and $node->status are the ones which should not be synced during cron publishing, but I could not find a sensible way to store and change those sync settings programatically and restore them afterwards. It might work but is clumsy. Disallowing at the node level seemed a better option

Hope that has explained the situation. The call to the hook I have suggested is quite simple, but if you would like to develop a more powerful one as you suggested then I would be happy to help.

Jonathan