"Cambiado por" en los nodos

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

Me gustaría tener una columna "cambiado por" en la nodetabla, exactamente como tenemos un "creado por" (el campo uid). Esto haría un seguimiento de quién realizó el último cambio en ese nodo. Sé que esto podría derivarse de la node_revisiontabla, pero esto depende de las revisiones habilitadas para los tipos de contenido que me interesan.

Entonces, ¿cuál es la mejor manera de hacer esto? ¿Y por qué Drupal Core no ofrece esto por defecto? Pensé que "cambiado por" es una información bastante estándar que un CMS debe adjuntar al contenido.

cherouvim
fuente
2
¿Hay alguna razón por la que no puede habilitar la revisión? Parece la forma más fácil de obtener lo que necesita. Probablemente sea lo que haría. Si las personas van a editar nodos con frecuencia, también significa que tiene una copia de seguridad de versiones anteriores.
Chapabu
Sí, puedo. Sin embargo, me gustaría saber si es posible tenerlo en la nodemesa principal . Se ve más sencillo.
cherouvim

Respuestas:

18

Pensé que esto sería bastante difícil de hacer, pero resulta que es bastante fácil.

Solo necesita crear un módulo personalizado que agregue una columna a la tabla de nodos en la instalación, implementar hook_schema_alter()para que Drupal conozca la nueva columna y agregar algo de lógica para proporcionar un valor antes de que se guarde el nodo.

Aquí hay un pequeño módulo que hará el truco:

Archivo: node_table_alter.info

name = Node Table Alter
core = 7.x

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

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

Es posible que desee agregar lógica para eliminar el campo nuevamente en la desinstalación, y agregar un índice a la tabla para la changed_bycolumna (ver db_add_index()), pero esto debería darle un buen lugar para comenzar.

La belleza de este método es que ha agregado efectivamente una nueva propiedad al nodo. Podrá usar node_load(), EntityFieldQuerys, etc. con él como si fuera cualquiera de las otras propiedades estándar de un nodo.

¡Dios bendiga a Drupal por ser tan extensible!

Clive
fuente
Por cierto, puede usar exactamente la misma lógica para responder a su otra pregunta .
Clive
2
Para una integración completa de la entidad, y si está utilizando el módulo API de la entidad, también deberá implementar hook_entity_property_info () para evitar información sobre esta nueva propiedad.
Pierre Buyle
@PierreBuyle Buen punto, no pensé en eso
Clive
1
Esto es exactamente lo que hace el módulo UUID. Compruébelo para una implementación más completa de algo similar. drupal.org/project/uuid
paul-m
¡Muchas gracias por la explicación detallada y la solución limpia!
cherouvim
1

Supongo que podría agregar un campo de referencia de entidad (llamémoslo field_changed_by_user) al tipo de contenido que necesita rastrear. Luego, podría usar hook_node_presavepara guardar la identificación de usuario en el nodo de esta manera:

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

Creo que también es posible actualizar el campo con la identificación del usuario simplemente creando una regla. Puedes leer más aquí .

Marius Ilie
fuente