«Modifié par» sur les nœuds

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

J'aimerais avoir une colonne "modifié par" sur la nodetable, exactement comme nous avons une "créé par" (le champ uid). Cela permettrait de savoir qui a effectué le dernier changement sur ce nœud. Je sais que cela pourrait être dérivé du node_revisiontableau mais cela dépend des révisions activées pour les types de contenu qui m'intéressent.

Alors, quelle est la meilleure façon de procéder? Et pourquoi le noyau Drupal ne propose-t-il pas cela par défaut? Je pensais que «changé par» est une information assez standard qu'un CMS devrait attacher au contenu.

cherouvim
la source
2
Y a-t-il une raison pour laquelle vous ne pouvez pas activer la révision? Semble être le moyen le plus simple d'obtenir ce dont vous avez besoin. C'est probablement ce que je ferais. Si des personnes doivent fréquemment modifier des nœuds, cela signifie également que vous disposez d'une sauvegarde des versions précédentes.
Chapabu
Oui je peux. J'aimerais savoir s'il est possible de l'avoir sur la nodetable principale . Cela semble plus simple.
cherouvim

Réponses:

18

Je pensais que ce serait assez difficile à faire, mais il s'avère que c'est assez facile.

Il vous suffit de créer un module personnalisé qui ajoute une colonne à la table des nœuds lors de l'installation, de l'implémenter hook_schema_alter()pour que Drupal connaisse la nouvelle colonne et d'ajouter une logique pour fournir une valeur avant que le nœud ne soit enregistré.

Voici un petit module qui fera l'affaire:

Fichier: node_table_alter.info

name = Node Table Alter
core = 7.x

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

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

Vous souhaiterez peut-être ajouter une logique pour supprimer à nouveau le champ lors de la désinstallation et ajouter un index à la table de la changed_bycolonne (voir db_add_index()), mais cela devrait vous donner un bon point de départ.

La beauté de cette méthode est que vous avez effectivement ajouté une nouvelle propriété au nœud. Vous pourrez utiliser node_load(), EntityFieldQuerys, etc. avec lui comme s'il s'agissait de l'une des autres propriétés standard d'un nœud.

Que Dieu bénisse Drupal pour être si extensible!

Clive
la source
BTW vous pouvez utiliser exactement la même logique pour répondre à votre autre question .
Clive
2
Pour une intégration complète des entités et si vous utilisez le module API d'entité, vous devrez également implémenter hook_entity_property_info () pour publier des informations sur cette nouvelle propriété.
Pierre Buyle
@PierreBuyle Bon point, je n'y ai pas pensé
Clive
1
C'est exactement ce que fait le module UUID. Consultez-le pour une implémentation plus complète de quelque chose de similaire. drupal.org/project/uuid
paul-m
Merci beaucoup pour l'explication détaillée et la solution propre!
cherouvim
1

Je suppose que vous pouvez ajouter un champ de référence d'entité (appelons-le field_changed_by_user) au type de contenu que vous devez suivre. Ensuite, vous pouvez utiliser hook_node_presavepour enregistrer l'ID utilisateur sur le nœud comme ceci:

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

Je pense qu'il est également possible de mettre à jour le champ avec l'ID de l'utilisateur simplement en créant une règle. Vous pouvez en lire plus ici .

Marius Ilie
la source