diff --git a/workbench_moderation.module b/workbench_moderation.module index f510e2e..a5c0fc5 100644 --- a/workbench_moderation.module +++ b/workbench_moderation.module @@ -675,13 +675,28 @@ function workbench_moderation_node_update($node) { return; } - // Set default moderation state values. + // Set moderation state values. if (!isset($node->workbench_moderation_state_current)) { - $node->workbench_moderation_state_current = ($node->status ? workbench_moderation_state_published() : workbench_moderation_state_none()); - }; + $node->workbench_moderation_state_current = !empty($node->original->workbench_moderation['current']->state) ? $node->original->workbench_moderation['current']->state : workbench_moderation_state_none(); + } if (!isset($node->workbench_moderation_state_new)) { - $node->workbench_moderation_state_new = variable_get('workbench_moderation_default_state_' . $node->type, workbench_moderation_state_none()); - }; + // Moving from published to unpublished. + if ($node->status == NODE_NOT_PUBLISHED && isset($node->original->status) && $node->original->status == NODE_PUBLISHED) { + $node->workbench_moderation_state_new = variable_get('workbench_moderation_default_state_' . $node->type, workbench_moderation_state_none()); + } + // Moving from unpublished to published. + elseif ($node->status == NODE_PUBLISHED && isset($node->original->status) && $node->original->status == NODE_NOT_PUBLISHED) { + $node->workbench_moderation_state_new = workbench_moderation_state_published(); + } + else { + if (!empty($node->original->workbench_moderation['current']->state)) { + $node->workbench_moderation_state_new = $node->original->workbench_moderation['current']->state; + } + else { + $node->workbench_moderation_state_new = variable_get('workbench_moderation_default_state_' . $node->type, workbench_moderation_state_none()); + } + } + } // If this is a new node, give it some information about 'my revision'. if (!isset($node->workbench_moderation)) { @@ -1526,8 +1541,11 @@ function workbench_moderation_moderate($node, $state) { // If we're moderating the published revision to a non-published state, // remove the workbench moderation 'published' property. unset($node->workbench_moderation['published']); + drupal_register_shutdown_function('workbench_moderation_store_unpublish', $node); + } + // If we're moderating an unpublished revision and there is an existing // published revision, make sure that the published revision is live. // We do this in a shutdown function to avoid race conditions when @@ -1536,7 +1554,6 @@ function workbench_moderation_moderate($node, $state) { drupal_register_shutdown_function('workbench_moderation_store', $node); } - // Notify other modules that the state was changed. module_invoke_all('workbench_moderation_transition', $node, $old_revision->state, $state); } @@ -1580,6 +1597,44 @@ function workbench_moderation_store($node) { } /** + * Shutdown callback for unpublishing a node revision. + * + * This function is called by drupal_register_shutdown_function(). + * The purpose is to delay a node_save() call so that a live revision + * is not called during hook_node_update(). + * + * Instead, we delay the update until the new revision is saved. This way, + * we can more safely call the revision and pick up changes to items + * that are not revisioned (such as menu and path assignments). + * + * @see workbench_moderation_moderate() + * + * @param $node + * The node being saved. + */ +function workbench_moderation_store_unpublish($node) { + if (!isset($node->nid)) { + watchdog('Workbench moderation', 'Failed to save node revision: node not passed to shutdown function.', array(), WATCHDOG_NOTICE); + return; + } + watchdog('Workbench moderation', 'Saved node revision: %node as live version for node %live.', array('%node' => $node->vid, '%live' => $node->nid), WATCHDOG_NOTICE, l($node->title, 'node/' . $node->nid)); + + // Remove the moderation record's "published" flag. + $query = db_update('workbench_moderation_node_history') + ->condition('hid', $node->workbench_moderation['published']->hid) + ->fields(array('published' => 0)) + ->execute(); + + // Make sure the 'current' revision is the 'live' revision -- ie, the revision + // in {node}. + $live_revision = workbench_moderation_node_current_load($node); + $live_revision->status = 0; + $live_revision->revision = 0; + $live_revision->workbench_moderation['updating_live_revision'] = TRUE; + node_save($live_revision); +} + +/** * Helper function to redirect after a state change submission. * * @param $node diff --git a/workbench_moderation.node.inc b/workbench_moderation.node.inc index 5baaf59..c5ede9b 100644 --- a/workbench_moderation.node.inc +++ b/workbench_moderation.node.inc @@ -284,24 +284,9 @@ function workbench_moderation_node_unpublish_form_submit($form, &$form_state) { global $user; $node = $form['node']['#value']; - // Remove the moderation record's "published" flag. - $query = db_update('workbench_moderation_node_history') - ->condition('hid', $node->workbench_moderation['published']->hid) - ->fields(array('published' => 0)) - ->execute(); - - // Moderate the revision. + // Moderate the revision. This will do the heavy lifting workbench_moderation_moderate($node, $form_state['values']['state']); - // Make sure the 'current' revision is the 'live' revision -- ie, the revision - // in {node}. - $live_revision = workbench_moderation_node_current_load($node); - $live_revision->status = 0; - $live_revision->revision = 0; - $live_revision->workbench_moderation['updating_live_revision'] = TRUE; - // @TODO: do we trust node_save() here? - node_save($live_revision); - drupal_set_message(t('The live revision of this content has been unpublished.')); $form_state['redirect'] ="node/{$node->nid}/moderation"; }