web-dev-qa-db-ja.com

ノードが「公開済み」から「非公開」に変更されたことをどのように検出できますか?

hook_node_update() では、更新後のノードの「ステータス」(公開されているかどうかにかかわらず)を簡単に確認できます。

しかし、更新されたノードが公開されたかどうかを確認する簡単な方法はありますか、今は公開されていませんか? (またはその逆)?

ルールには「ノード値が変更された」などの条件があると思いますが、プログラムでこれを実行したいと思います。

Drupal 7でこれに対処しているように見えるdrupal.orgで fagoによるこの問題 (ルールの開発者)を見つけましたが、いい説明をいただければ幸いです。

16
geerlingguy

気にしないで。上記のリンクされた問題(特に コメント#38 )を読んだ後、$ nodeオブジェクト(実際には任意のエンティティ)が「元の」キャッシュコピーを$ entity-> originalに保存していることがわかりました。

したがって、ノードが 'status = 1'から 'status = 0'に変化したかどうかを検出したかったのです(これはノードが非公開のときに発生します)。次のコードはこれを実行します。

<?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.
    }
  }
}
?>
31
geerlingguy

node_save()には、次のコードが含まれています。

_  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()は、データベースからエンティティ(この場合はノード)をロードします。実行中のモジュールから変更が行われる前にエンティティオブジェクトを返します。

コードは、事前保存および更新フックの前に実行されます。

_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');
_

これらのフックでは、_$node->original_などの_$node->original->status_の変更前にノードプロパティを確認できます。

1
kiamlaluno