Drupal 7: Custom Revert Revision Action module

David G - DrupalRecently in a live project I had a request to do a bulk update of content really quickly. I ended up altering about 500 nodes of content by searching and replacing “computer science” to “computing” wherever it occurred in a Node, such as the Title field or the Body field. Having completed the task asap — it turns out I converted fields that I should not have updated. So I wanted to find or write some code that reverted a Node to the previous revision of a content. This is my solution to that task.

I know my website has Views and Views Bulk Operations installed already on it, because other tasks on the website require these modules. So I wanted to try to create a custom VBO action that performs the required task for any set of selected nodes of a view.

After about 1 days worth of on-and-off trial and error I ended up with the following code within a custom module:

/**
 * Implements hook_action_info().
 */
function revert_last_revision_action_info() {
  $action = array(
    'revert_to_last_revision' => array(
      'label'        => t('Revert to Last Revision'),
      'type'         => 'node',
      'configurable' => FALSE,
      'triggers'     => array('any'),
      // I believe this view_property causes the 2nd save to not occur as it's
      // not a save action -- aka in our custom function we do our own save
      // which will not be overwritten.
      'behavior'     => array('view_property'),
    ),
  );
  return $action;
}

/**
 * Action function for revert_to_last_revision.
 */
function revert_to_last_revision(&$entity, $context = array()) {
  $revision_list = node_revision_list($entity);
  unset($revision_list[$entity->vid]);
  if (count($revision_list) > 0) {
    $last_revision = max(array_keys($revision_list));
    $entity = entity_revision_load('node', $last_revision);
    $entity->revision = TRUE;
    $entity->log = "Reverted via bulk operation action.";
    entity_save('node', $entity);
  }
}

This is essentially a very typical custom Drupal Action. An action in the Drupal CMS can be reacted to by a Trigger for example. So in this code our custom action is created by defining the hook hook_action_info. The hook defines the action’s name; the condition on which it applies, and the steps to perform for the action.

In this code the steps to perform are invoked by the function REVSION_REVERT_NODE. This function takes the selected Node(s) of the View and uses the Drupal Node API functions to lookup the revision history for the node, and peels off the previous revision of the node and saves the previous revision as a new revision for this node.

Of importance to note in this process are the following 2 items:

  • I don’t associate the new revision with any specific user, the logged in user becomes the revision creator. This is because another user may not have permissions to modify the content type; my goal is to simply to a bulk fix of many nodes as a site administrator.
  • Typically an action invokes a save or pre_save default action. If we let this occur 2 new revisions are created and the revision I want isn’t the last one! … so by setting the behavior of this action as view_property. No default action is taken and our save is sufficient to create the revision.

Here is a series of screenshots of the end result of the action running on a sample node!

My default content has 2 revisions created with Devel Generate.

My default content has 2 revisions created with Devel Generate.

We can then select the item(s) we want to revert 1 revision using Views Bulk Operations.

We can then select the item(s) we want to revert 1 revision using Views Bulk Operations.

Then we accept the confirmation question to perform our action on our node(s).

Then we accept the confirmation question to perform our action on our node(s).

Lastly, we can inspect the Revisions of the altered node to assure that a new revision was made from CURRENT_REVISION-1 content.

Lastly, we can inspect the Revisions of the altered node to assure that a new revision was made from CURRENT_REVISION-1 content.

So as you can see this fully works. If you’d like to try this module you simply need to install Views, Views Bulk Operations, and my custom Revert Last Revision module currently released to Github.

Lastly, unfortunately in my project I didn’t have revision(s) of my Nodes to rollback to — so this code was created for naught :(. But, it was fun learning experience and I could see using it in the future during misadventures!

Looking for quality web hosting? Look no further than Arvixe Web Hosting!

Tags: , , , | Posted under Drupal | RSS 2.0

Author Spotlight

David Gurba

I am a web programmer currently employed at UCSB. I have been developing web applications professionally for 8+ years now. For the last 5 years I’ve been actively developing websites primarily in PHP using Drupal. I have experience using LAMP and developing data driven websites for clients in aviation, higher education and e-commerce. If you’d like to contact me I can be reached at david.gurba@arvixe.com

Leave a Reply

Your email address will not be published. Required fields are marked *