Auf Knoten "geändert von"

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

Ich möchte eine Spalte "geändert von" in der nodeTabelle haben, genau wie wir eine Spalte "erstellt von" (das UID-Feld) haben. Dies würde verfolgen, wer die letzte Änderung an diesem Knoten vorgenommen hat. Ich weiß, dass dies aus der node_revisionTabelle abgeleitet werden kann, aber dies hängt von den Revisionen ab, die für die von mir interessierten Inhaltstypen aktiviert werden.

Was ist der beste Weg, dies zu tun? Und warum bietet Drupal Core dies nicht standardmäßig an? Ich dachte, dass "geändert von" eine ziemlich übliche Information ist, die ein CMS an Inhalte anhängen sollte.

Cherouvim
quelle
2
Gibt es einen Grund, warum Sie die Revision nicht aktivieren können? Scheint der einfachste Weg zu sein, um das zu bekommen, was Sie brauchen. Es ist wahrscheinlich das, was ich tun würde. Wenn Benutzer häufig Knoten bearbeiten, bedeutet dies auch, dass Sie eine Sicherungskopie früherer Versionen haben.
Chapabu
Ja, ich kann. Ich würde gerne wissen, ob es möglich ist, es auf dem nodeHaupttisch zu haben. Es sieht einfacher aus.
Cherouvim

Antworten:

18

Ich dachte, das wäre ziemlich schwierig, aber wie sich herausstellt, ist es ziemlich einfach.

Sie müssen lediglich ein benutzerdefiniertes Modul erstellen, das der Knotentabelle bei der Installation eine Spalte hinzufügt, implementieren, hook_schema_alter()damit Drupal über die neue Spalte informiert ist, und eine Logik hinzufügen, um einen Wert bereitzustellen, bevor der Knoten gespeichert wird.

Hier ist ein kleines Modul, das den Trick macht:

Datei: node_table_alter.info

name = Node Table Alter
core = 7.x

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

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

Möglicherweise möchten Sie Logik hinzufügen, um das Feld bei der Deinstallation erneut zu entfernen, und der Tabelle für die changed_bySpalte einen Index hinzufügen (siehe db_add_index()). Dies sollte Ihnen jedoch einen guten Ausgangspunkt bieten.

Das Schöne an dieser Methode ist, dass Sie dem Knoten effektiv eine neue Eigenschaft hinzugefügt haben. Sie werden nutzen können node_load(), EntityFieldQuerys usw. mit ihm , als ob er einen der anderen Standardeigenschaften für einen Knoten waren.

Gott segne Drupal dafür, dass er so erweiterbar ist!

Clive
quelle
Übrigens können Sie genau dieselbe Logik verwenden, um Ihre andere Frage zu beantworten .
Clive
2
Für eine vollständige Entitätsintegration und wenn Sie das Entitäts-API-Modul verwenden, müssen Sie außerdem hook_entity_property_info () implementieren, um Informationen zu dieser neuen Eigenschaft bereitzustellen.
Pierre Buyle
@PierreBuyle Guter Punkt, daran habe ich nicht gedacht
Clive
1
Genau das macht das UUID-Modul. Probieren Sie es aus, um eine vollständigere Implementierung von etwas Ähnlichem zu erhalten. drupal.org/project/uuid
Paul-m
Vielen Dank für die ausführliche Erklärung und die saubere Lösung!
Cherouvim
1

Ich denke, Sie könnten field_changed_by_userdem Inhaltstyp, den Sie verfolgen möchten, ein Entitätsreferenzfeld hinzufügen (nennen wir es ). Dann können Sie hook_node_presavedie Benutzer-ID folgendermaßen auf dem Knoten speichern:

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

Ich denke, es ist auch möglich, das Feld mit der Benutzer-ID zu aktualisieren, indem Sie einfach eine Regel erstellen. Sie können mehr lesen hier .

Marius Ilie
quelle