"Alterado por" nos nós

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

Eu gostaria de ter uma coluna "alterada por" na nodetabela, exatamente como temos uma "criada por" (o campo uid). Isso acompanharia quem fez a última alteração nesse nó. Eu sei que isso pode ser derivado da node_revisiontabela, mas isso depende das revisões ativadas para os tipos de conteúdo que estou interessado.

Então, qual é a melhor maneira de fazer isso? E por que o núcleo Drupal não oferece isso por padrão? Eu pensei que "alterado por" é uma informação bastante padrão que um CMS deve anexar ao conteúdo.

cherouvim
fonte
2
Existe um motivo para não ativar a revisão? Parece a maneira mais fácil de obter o que você precisa. Provavelmente é o que eu faria. Se as pessoas estiverem editando nós com frequência, isso também significa que você tem um backup das versões anteriores.
Chapabu 03/03/12
Sim eu posso. Eu gostaria de saber se é possível colocá-lo na nodemesa principal . Parece mais direto.
Cherouvim

Respostas:

18

Eu pensei que isso seria bastante difícil de fazer, mas, como se vê, é bastante fácil.

Você só precisa criar um módulo personalizado que adicione uma coluna à tabela de nós na instalação, implemente hook_schema_alter()para que o Drupal conheça a nova coluna e adicione alguma lógica para fornecer um valor antes que o nó seja salvo.

Aqui está um pequeno módulo que fará o truque:

Arquivo: node_table_alter.info

name = Node Table Alter
core = 7.x

Arquivo: 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);
}

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

Você pode adicionar lógica para remover o campo novamente na desinstalação e adicionar um índice à tabela da changed_bycoluna (consulte a seção db_add_index()), mas isso deve lhe dar um bom lugar para começar.

A vantagem desse método é que você adicionou efetivamente uma nova propriedade ao nó. Você vai ser capaz de usar node_load(), EntityFieldQuerys, etc. com ela como se fosse qualquer uma das outras propriedades padrão para um nó.

Deus abençoe Drupal por ser tão extensível!

Clive
fonte
BTW, você pode usar exatamente a mesma lógica para responder sua outra pergunta .
Clive
2
Para uma integração completa da entidade, e se você estiver usando o módulo API da entidade, também será necessário implementar hook_entity_property_info () para fornecer informações sobre esta nova propriedade.
Pierre Buyle
@PierreBuyle Bom ponto, não pensei nisso #
Clive
11
É exatamente isso que o módulo UUID faz. Confira para uma implementação mais completa de algo semelhante. drupal.org/project/uuid
paul-m
Muito obrigado pela explicação detalhada e solução limpa!
Cherouvim
1

Eu acho que você pode adicionar um campo de referência da entidade (vamos chamá-lo field_changed_by_user) ao tipo de conteúdo que você precisa acompanhar. Então você pode usar hook_node_presavepara salvar o ID do usuário no nó desta forma:

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

Eu acho que também é possível atualizar o campo com o ID do usuário apenas criando uma regra. Você pode ler mais aqui .

Marius Ilie
fonte