«Изменено» на узлах


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

Я хотел бы иметь столбец «изменено» в nodeтаблице, точно так же, как у нас есть «созданный» (поле uid). Это будет отслеживать, кто сделал последнее изменение на этом узле. Я знаю, что это может быть получено из node_revisionтаблицы, но это зависит от того, какие версии включены для интересующих меня типов контента.

Итак, каков наилучший способ сделать это? И почему ядро ​​Drupal не предлагает это по умолчанию? Я думал, что «изменено» - довольно стандартная часть информации, которую CMS должна прикреплять к контенту.


2
Есть ли причина, по которой вы не можете включить пересмотр? Похоже, самый простой способ получить то, что вам нужно. Это, вероятно, то, что я сделал бы. Если люди будут часто редактировать узлы, это также означает, что у вас есть резервная копия предыдущих версий.
Чапабу

Да, я могу. Хотелось бы знать, возможно ли это иметь на главном nodeстоле. Это выглядит более простым.
Черувим

Ответы:


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 и т.д. с ним , как если бы она была какой - либо из других стандартных свойств узла.

Да благословит Бог Друпал за то, что он так расширяем!


Кстати, вы можете использовать точно такую ​​же логику, чтобы ответить на ваш другой вопрос .
Клайв

2
Для полной интеграции сущностей, и если вы используете модуль Entity API, вам также потребуется реализовать hook_entity_property_info () для получения информации об этом новом свойстве.
Пьер Байль

@PierreBuyle Хороший вопрос, не думал об этом
Клайв

1
Это именно то, что делает модуль UUID. Проверьте это для более полной реализации чего-то подобного. drupal.org/project/uuid
paul-m

Большое спасибо за подробное объяснение и чистое решение!
Черувим

1

Я думаю, вы могли бы добавить поле ссылки на сущность (давайте назовем его field_changed_by_user) к типу контента, который вы хотите отслеживать. Затем вы можете использовать hook_node_presaveдля сохранения идентификатора пользователя на узле, как это:

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;
  }
}

Я думаю, что также возможно обновить поле с идентификатором пользователя, просто создав правило. Вы можете прочитать больше здесь .

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.