“ เปลี่ยนแปลงโดย” บนโหนด


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

ฉันต้องการที่จะมีคอลัมน์ "เปลี่ยนแปลงโดย" บนnodeโต๊ะเหมือนกับที่เรามี "สร้างโดย" (ฟิลด์ uid) สิ่งนี้จะติดตามว่าใครทำการเปลี่ยนแปลงล่าสุดบนโหนดนั้น ฉันรู้ว่านี่อาจมาจากnode_revisionตาราง แต่ขึ้นอยู่กับการแก้ไขที่เปิดใช้งานสำหรับประเภทเนื้อหาที่ฉันสนใจ

ดังนั้นวิธีที่ดีที่สุดในการทำเช่นนี้คืออะไร? และทำไม Drupal core จึงไม่เสนอสิ่งนี้เป็นค่าเริ่มต้น ฉันคิดว่า "เปลี่ยนแปลงโดย" เป็นข้อมูลมาตรฐานที่ CMS ควรแนบกับเนื้อหา


2
มีเหตุผลที่คุณไม่สามารถเปิดใช้การแก้ไขได้หรือไม่ ดูเหมือนว่าวิธีที่ง่ายที่สุดที่จะได้รับสิ่งที่คุณต้องการ มันอาจเป็นสิ่งที่ฉันทำ หากคนกำลังจะแก้ไขโหนดบ่อยครั้งก็หมายความว่าคุณมีการสำรองข้อมูลของรุ่นก่อนหน้า
Chapabu

ใช่ฉันทำได้. ฉันต้องการทราบว่าเป็นไปได้ที่จะมีไว้ในnodeตารางหลักแม้ว่า มันดูตรงไปตรงมามากขึ้น
cherouvim

คำตอบ:


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, ฯลฯ กับมันราวกับว่ามันเป็นใด ๆ ของคุณสมบัติมาตรฐานอื่น ๆ สำหรับโหนด

ขอพระเจ้าอวยพร Drupal ที่ยืดออกได้!


BTW คุณสามารถใช้ตรงตรรกะเดียวกันที่จะตอบคำถามอื่น ๆ ของคุณ
Clive

2
สำหรับการรวมเอนทิตีที่สมบูรณ์และหากคุณกำลังใช้โมดูล Entity API คุณจะต้องใช้ hook_entity_property_info () เพื่อ pvoide informatiom เกี่ยวกับคุณสมบัติใหม่นี้
Pierre Buyle

@PierreBuyle จุดที่ดีไม่ได้คิดอย่างนั้น
ไคลฟ์

1
นี่คือสิ่งที่โมดูล UUID ทำ ลองใช้งานสิ่งที่คล้ายกันมากขึ้น drupal.org/project/uuid
paul-m

ขอบคุณมากสำหรับคำอธิบายโดยละเอียดและวิธีแก้ปัญหาที่สะอาด!
cherouvim

1

ฉันเดาว่าคุณสามารถเพิ่มเขตข้อมูลอ้างอิงเอนทิตี (ลองเรียกมันว่าfield_changed_by_user) กับประเภทเนื้อหาที่คุณต้องการติดตาม จากนั้นคุณสามารถใช้hook_node_presaveเพื่อบันทึก ID ผู้ใช้ไปยังโหนดดังนี้:

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

ฉันคิดว่าเป็นไปได้ที่จะอัปเดตฟิลด์ด้วยรหัสผู้ใช้เพียงแค่สร้างกฎ คุณสามารถอ่านเพิ่มเติมที่นี่

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.