17

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.

2 Answers 2

34

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.
    }
  }
}
?>
5
  • 4
    I've gotta stop answering my own questions ;-) Jun 29, 2011 at 19:35
  • 6
    why? It was still helpful to me, worth a +1 ;-)
    – uwe
    Jun 30, 2011 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 :) Nov 22, 2016 at 4:11
  • Above code is not going to work if you are using revisioning module Mar 23, 2018 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, 2018 at 8:32
1

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 agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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