ノードの「変更者」


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

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

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


2
リビジョンを有効にできない理由はありますか?必要なものを手に入れる最も簡単な方法のようです。それはおそらく私がすることです。人々がノードを頻繁に編集する場合は、以前のバージョンのバックアップがあることも意味します。
Chapabu

はい、できます。メインnodeテーブルに置くことが可能かどうか知りたいのですが。より簡単に見えます。
cherouvim

回答:


18

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

インストール時にノードテーブルに列を追加するカスタムモジュールを作成し、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をとても拡張可能であることを祝福します!


ところで、あなたは他の質問に答えるために全く同じロジックを使うことができます。
クライヴ

2
完全なエンティティ統合のために、またエンティティAPIモジュールを使用している場合は、この新しいプロパティに関する情報を無効にするためにhook_entity_property_info()も実装する必要があります。
Pierre Buyle、2012年

@PierreBuyle良い点、それについては考えていませんでした
クライヴ

1
これはまさにUUIDモジュールが行うことです。同様のもののより完全な実装については、それをチェックしてください。drupal.org/project/uuid
paul-m

詳細な説明とクリーンなソリューションに感謝します!
cherouvim

1

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でフィールドを更新することも可能だと思います。詳しくはこちらをご覧ください

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.