web-dev-qa-db-ja.com

ノードの「変更者」

mysql> select nid, uid, created, changed from node;
+-----+-----+------------+------------+
| nid | uid | created    | changed    |
+-----+-----+------------+------------+
|   1 |   8 | 1336040166 | 1336046390 |
+-----+-----+------------+------------+

「作成者」(uidフィールド)とまったく同じように、nodeテーブルに「変更者」列を配置したいと思います。これにより、そのノードで最後に変更したユーザーを追跡できます。これはnode_revisionテーブルですが、これは、興味のあるコンテンツタイプで有効になっているリビジョンによって異なります。

それで、これを行うための最良の方法は何ですか? Drupalコアがデフォルトでこれを提供しないのはなぜですか? "changed by"は、CMSがコンテンツに添付すべきかなり標準的な情報であると思いました。

9
cherouvim

これはかなり難しいと思いましたが、結局のところ、それはかなり簡単です。

インストール時に列をノードテーブルに追加するカスタムモジュールを作成する必要があるだけで、実装 hook_schema_alter() なので、Drupalは新しい列を認識しています、ノードが保存される前に値を提供するロジックを追加します。

これはトリックを行う小さなモジュールです:

ファイル:node_table_alter.info

_name = Node Table Alter
core = 7.x
_

ファイル:node_table_alter.install

_function node_table_alter_install() {
  // Add the new field to the node table
  $field = array(
    'description' => 'Stores the user id of the last user to alter the node',
    'type' => 'int',
    'unsigned' => TRUE
  );

  db_add_field('node', 'changed_by', $field);
}
_

ファイル:node_table_alter.module

_function node_table_alter_schema_alter(&$schema) {
  // Add the new field to the schema cache
  $schema['node']['fields']['changed_by'] = array(
    'description' => 'Stores the user id of the last user to alter the node',
    'type' => 'int',
    'unsigned' => TRUE
  );
}

function node_table_alter_node_presave($node) {
  // Populate the changed_by column with current user's id
  $node->changed_by = $GLOBALS['user']->uid;
}
_

アンインストール時にフィールドを再度削除するロジックを追加し、_changed_by_列のテーブルにインデックスを追加することもできます( db_add_index() を参照)。あなたに始めるのに良い場所を与えます。

このメソッドの優れた点は、新しいプロパティをノードに効果的に追加したことです。 node_load()EntityFieldQuerysなどを、ノードの他の標準プロパティのように使用できます。

神のご加護Drupal非常に拡張可能であること!

18
Clive

エンティティ参照フィールドを追加できると思います(これをfield_changed_by_user)を追跡する必要があるコンテンツタイプに変更します。次に、hook_node_presaveは、次のようにユーザーIDをノードに保存します。

function hook_node_presave($node) {
  if ($node->nid && $node->type == 'content_type_to_track_changes_for') {
    global $user;
    $node->field_changed_by_user['und'][0]['target_id'] = $user->uid;
  }
}

ルールを作成するだけで、ユーザーのIDでフィールドを更新することも可能だと思います。あなたはもっと読むことができます ここ

1
Marius Ilie