In hook_node_update(), I can easily tell the 'status' of a node (whether it's published or not) after it's been updated.

However, is there an easy way to check to see if the updated node was published, but now is not? (Or vice-versa)?

I think Rules might have some condition for 'node value has changed' or something along those lines, but I'd like to do this programmatically.

I found this issue by fago (developer of Rules) on drupal.org that seems to deal with this in Drupal 7, but a nice explanation would be appreciated.

up vote 30 down vote accepted

Nevermind. After reading through the issue linked above (especially comment #38), I found that the $node object (any entity, actually) stores the 'original' cached copy in $entity->original.

So, I wanted to detect whether a node changed from 'status = 1' to 'status = 0' (this happens when the node is unpublished), and the following code does this:

<?php
function custom_node_update($node) {
  if ($node->type == 'article') {
    // Act on the unpublishing of an article.
    if ($node->original->status == 1 && $node->status == 0) {
      // Do something here.
    }
    // Act on the publishing of an article.
    if ($node->original->status == 0 && $node->status == 1) {
      // Do something here.
    }
  }
}
?>
  • 3
    I've gotta stop answering my own questions ;-) – geerlingguy Jun 29 '11 at 19:35
  • 5
    why? It was still helpful to me, worth a +1 ;-) – MotoTribe Jun 30 '11 at 4:43
  • Heh, this is about the 10th time I've landed on my own answer in Google results. Future me thanks past me for answering :) – geerlingguy Nov 22 '16 at 4:11
  • Above code is not going to work if you are using revisioning module – Mohammad Anwar Mar 23 at 20:29
  • For the record, this could not be not working for status + workflow + translation, I had to use $entity->original->getTranslation($lng)->status->value == 0 && $entity->getTranslation($lng)->status->value == 1 – Teenage Jun 21 at 8:32

node_save() contains the following code.

  try {
    // Load the stored entity, if any.
    if (!empty($node->nid) && !isset($node->original)) {
      $node->original = entity_load_unchanged('node', $node->nid);
    }
  }

entity_load_unchanged() loads the entity (in this case the node) from the database; it returns the entity object before any changes made from the running modules.

The code is executed before any pre-save, and update hooks.

module_invoke_all('node_presave', $node);
module_invoke_all('entity_presave', $node, 'node');

//... 

node_invoke($node, $op);

// Save fields.
$function = "field_attach_$op";
$function('node', $node);

module_invoke_all('node_' . $op, $node);
module_invoke_all('entity_' . $op, $node, 'node');

In those hooks, it is possible to see the node properties before any change in $node->original, for example with $node->original->status.

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.