My site makes use of workbench_moderation_node_history table on views. For example, I believe the workbench_moderation : current filter will only work if that table is populated for the content type the view is displaying.
I had a content type with ~60k nodes, and I turned workbench_moderation on for it, but couldn't use the current filter for that content type because the values weren't initialized for the most recent revision.
The feature request: Should that table be populated when you set a content type to use workbench moderation? Should there be a button on another page to do the initializing?
For now, I wrote this short script (mostly re-used code from workbench_moderation.module) to accomplish what I was looking for in the command line, and it works fine. It only populates the table for nodes without a value in it.
Right now, this code is to be put in a standalone file in your site's root directory (for example). Then it is run via drush.
usage:
drush scr yourfile.php the_content_types_machine_name
Is this something others want built as part of the module?
$args=drush_get_arguments();
if (count($args)!=3) {
echo 'Usage: drush scr ' . $args[1] . " contenttype\n";
exit();
}
$sql = 'SELECT nid
FROM node n
WHERE n.type = \'' . $args[2] . '\'';
$result = db_query($sql);
echo 'Up to ' . $result->rowCount() . " nodes\n";
$i=$result->rowCount();
foreach ($result as $record) {
initialize_wbmod_nodehistory($record->nid);
if($i-- % 150==0)
echo $i . " remaining\n";
}
function initialize_wbmod_nodehistory($nid) {
$hid_count = db_select('workbench_moderation_node_history')
->condition('nid', $nid)
->countQuery()->execute()->fetchField();
if($hid_count>0)
return;
$node=node_load($nid);
$user=user_load($node->workbench_moderation['my_revision']->uid);
$state=$node->workbench_moderation['my_revision']->state;
$old_revision = $node->workbench_moderation['my_revision'];
// Get the number of revisions for this node with vids greater than $node->vid
$vid_count = db_select('node_revision', 'r')
->condition('r.nid', $node->nid)
->condition('r.vid', $node->vid, '>')
->countQuery()->execute()->fetchField();
// If the number of greater vids is 0, then this is the most current revision
$current = ($vid_count == 0);
// Build a history record.
$new_revision = (object) array(
'from_state' => $old_revision->state,
'state' => $state,
'nid' => $node->nid,
'vid' => $node->vid,
'uid' => $user->uid,
'current' => $current,
'published' => ($state == workbench_moderation_state_published()),
'stamp' => $_SERVER['REQUEST_TIME'],
);
// If this is the new 'current' moderation record, it should be the only one
// flagged 'current' in {workbench_moderation_node_history}.
if ($new_revision->current) {
$query = db_update('workbench_moderation_node_history')
->condition('nid', $node->nid)
->fields(array('current' => 0))
->execute();
}
// If this revision is to be published, the new moderation record should be
// the only one flagged 'published' in both
// {workbench_moderation_node_history} AND {node_revision}
if ($new_revision->published) {
$query = db_update('workbench_moderation_node_history')
->condition('nid', $node->nid)
->fields(array('published' => 0))
->execute();
$query = db_update('node_revision')
->condition('nid', $node->nid)
->fields(array('status' => 0))
->execute();
}
// Save the node history record.
drupal_write_record('workbench_moderation_node_history', $new_revision);
// Update the node's content_moderation information so that we can publish it
// if necessary.
$node->workbench_moderation['my_revision'] = $new_revision;
if ($new_revision->current) {
$node->workbench_moderation['current'] = $new_revision;
}
// Handle the published revision.
if ($new_revision->published) {
// If we're moderating a revision to the published state, mark the new
// revision as the published revision.
$node->workbench_moderation['published'] = $new_revision;
}
elseif (isset($node->workbench_moderation['published']) && $new_revision->vid == $node->workbench_moderation['published']->vid && $new_revision->from_state == workbench_moderation_state_published()) {
// If we're moderating the published revision to a non-published state,
// remove the workbench moderation 'published' property.
unset($node->workbench_moderation['published']);
}
// 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
// running node_save() from within a node submission.
if (!empty($node->workbench_moderation['published'])) {
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);
}
Comments
Comment #1
cecrs commentedMaybe write it up as a patch? It could be a drush command in the existing module, and someone who doesn't have drush can still execute a script via the devel php interface.
Comment #2
cecrs commentedHere is a first pass at a patch. I applied this to 1.x dev.
Comment #3
cecrs commentedComment #4
ashrafabedThank you, that's what I had in mind - just wanted to be sure there was interest in it.
One suggestion if we're making it into a patch, change the name of initialize_workbench_moderation_nodehistory to _initialize_workbench_moderation_nodehistory, or workbench_moderation_initialize_node_history? To better follow Drupal naming conventions (correct me if I'm wrong on the first one's format). Will test it as well when I have some time.
Comment #5
cecrs commentedSure, makes sense. I went with workbench_moderation_initialize_node_moderation_history.
Comment #6
brockfanning commented#5 still applies, but it doesn't work because workbench_moderation changed a column name. So here is a new version of the patch with that change. As well, some minor fixes involving the drush help text and general code style.
Comment #7
brockfanning commentedSome additional code standard fixes.