Score:4

วิธีทำให้ชื่อคำศัพท์อนุกรมวิธานไม่ซ้ำกันต่อผู้ใช้

ธง cn

ฉันมีคำศัพท์อนุกรมวิธาน กลุ่ม.

ความต้องการ

  • ผู้ใช้ที่แตกต่างกันสามารถสร้างกลุ่มที่มีชื่อเดียวกันได้ (ผู้ใช้ A สามารถสร้าง แอปเปิ้ล กลุ่มและผู้ใช้ B ยังสามารถสร้าง แอปเปิ้ล กลุ่ม.)
  • ผู้ใช้คนเดียวกันไม่สามารถสร้างสองกลุ่มด้วยชื่อเดียวกันได้ (ผู้ใช้ A ไม่สามารถสร้างสองกลุ่มได้ แอปเปิ้ล กลุ่ม.)

ฉันจะใช้สิ่งนี้ได้อย่างไร

D8/9 เสนอข้อจำกัดของฟิลด์ ตามที่อธิบายไว้ในคำตอบนี้ และ โพสต์บล็อกนี้แต่สิ่งนี้ทำให้ฟิลด์ไม่ซ้ำกันสำหรับผู้ใช้ทุกคน

ฉันต้องการที่จะทำให้ ชื่อศัพท์อนุกรมวิธาน มีเอกลักษณ์ ต่อผู้ใช้. นอกจากนี้ สิ่งนี้จำเป็นต้องทำงานร่วมกับ JSON:API ฉันจะทำสิ่งนี้ได้อย่างไร

Score:4
ธง cn

คุณได้รับอนุญาตให้เพิ่ม ข้อ จำกัด การตรวจสอบที่กำหนดเอง ใช้ขั้นตอนนี้:

  1. ขั้นตอนที่ 1: กำหนดข้อจำกัด:

    คำจำกัดความข้อจำกัดจะไปอยู่ในเนมสเปซ Drupal[MODULENAME]\Plugin\Validation\Constraint และจะขยาย Symfony\Component\Validator\Constraint ในคลาสนี้ จะมีการกำหนดประเภทของการละเมิดข้อจำกัด พร้อมด้วยข้อความแสดงข้อผิดพลาดที่จะแสดงสำหรับการละเมิดที่กำหนด

  2. ขั้นตอนที่ 2: สร้างการตรวจสอบความถูกต้องสำหรับข้อจำกัด

    ขั้นตอนต่อไปคือการสร้างคลาสที่จะตรวจสอบข้อจำกัด การตรวจสอบข้อจำกัดจะไปอยู่ในเนมสเปซ Drupal[MODULENAME]\Plugin\Validation\Constraint และจะขยาย Symfony\Component\Validator\ConstraintValidator ในคลาสนี้ ค่าที่ส่งจะถูกส่งกลับ และการละเมิดใดๆ จะถูกลงทะเบียน

    โปรดทราบว่าชื่อของคลาสตัวตรวจสอบความถูกต้องของคุณคาดว่าจะเป็น ${ConstraintClassName}Validator ตามค่าเริ่มต้น หากคุณต้องการใช้ชื่ออื่น คุณอาจเขียนทับเมธอด validatedBy() ของคลาส Constraint ที่คุณสร้างไว้ในขั้นตอนที่ 1

และสำหรับขั้นตอนสุดท้าย คุณสามารถเพิ่มข้อจำกัดใหม่ลงในฟิลด์ของคุณได้ เช่นเดียวกับ คำตอบที่คุณกล่าวถึง

เมื่อมีข้อมูลนี้แล้ว คุณสามารถเพิ่มฟิลด์อ้างอิงผู้ใช้ในอนุกรมวิธานของคุณ ดังนั้นแต่ละคำจะมีข้อมูลเกี่ยวกับผู้แต่ง คุณสามารถใช้ hook_Entity_Type_presave เพื่อตั้งค่าฟิลด์นี้โดยทางโปรแกรม

จากนั้นคุณสามารถสร้างข้อ จำกัด ที่กำหนดเองได้ ไม่ซ้ำกัน PerArthor (หรือชื่อใดก็ได้ที่คุณต้องการ) จากนั้นในขั้นตอนที่ 2 ที่คุณกำหนดเมธอด isUniquePerUser คุณสามารถเรียกใช้คิวรีและรับรายการคำศัพท์อนุกรมวิธานซึ่งมีเลเบลเท่ากับค่าและผู้เขียนเท่ากับผู้ใช้ปัจจุบัน หากการสืบค้นนี้ส่งคืนค่า หมายความว่าคำนี้ไม่ซ้ำกัน (ผู้ใช้ได้นิยามคำนี้มาก่อน) และคุณสามารถแจ้งข้อผิดพลาดได้

cn flag
สุดยอด! วิธีนี้ดูเหมือนจะเป็นวิธีที่ดี ยกเว้นชื่อคำไม่ใช่ฟิลด์ ใช่ไหม มันเหมือนกับชื่อโหนด/หน้า -- มันไม่สามารถเข้าถึงได้ (เท่าที่ฉันรู้) เป็นฟิลด์ แล้วฉันจะทำอย่างไรในกรณีนี้?
apaderno avatar
us flag
@PatrickKenny ชื่อโหนดเป็นฟิลด์เอนทิตี: `$fields['title'] = BaseFieldDefinition::create('string')->setLabel(t('Title'))->setRequired(TRUE)->setTranslatable(TRUE )->setRevisionable(TRUE)->setSetting('max_length', 255)->setDisplayOptions('view', ['label' => 'hidden','type' => 'string','weight' => - 5,]);` อย่าสับสนกับ Drupal ที่แสดงชื่อหน้าในบล็อก
apaderno avatar
us flag
เช่นเดียวกับชื่อศัพท์อนุกรมวิธาน: `$fields['name'] = BaseFieldDefinition::create('string')->setLabel(t('Name'))->setTranslatable(TRUE)->setRevisionable(TRUE )->setRequired(TRUE)->setSetting('max_length', 255)->setDisplayOptions('view', ['label' => 'hidden','type' => 'string','weight' => - 5,]);`
cn flag
@apaderno ขอบคุณ มันมีประโยชน์มาก น่าเสียดาย ใน `hook_entity_bundle_field_info_alter()` ดูเหมือนว่าจะไม่มีฟิลด์ `name` ซึ่งนั่นทำให้ฉันสับสน คำถามติดตามผลที่นี่: https://drupal.stackexchange.com/questions/305789/how-to-set-a-validation-constraint-for-the-taxonomy-term-name
apaderno avatar
us flag
@PatrickKenny นั่นเป็นเพราะ `hook_entity_bundle_field_info_alter()` ใช้สำหรับฟิลด์บันเดิล ในขณะที่ชื่ออนุกรมวิธานเป็นฟิลด์พื้นฐาน ซึ่งหมายความว่ามีอยู่ในบันเดิลอนุกรมวิธานทุกชุด
Alireza Tabatabaeian avatar
cn flag
@PatrickKenny คุณสามารถใช้ `hook_entity_base_field_info_alter` https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Entity%21entity.api.php/function/hook_entity_base_field_info_alter/8.2.x เพื่อเปลี่ยนฟิลด์ฐาน คำจำกัดความเช่น id หรือชื่อเรื่องหรือ ...
Score:3
ธง cn

ขอบคุณ @Alireza Tabatabaeian สำหรับสิ่งนี้ ฉันแค่โพสต์รหัสที่ฉันใช้ตามคำตอบนั้น

ในอนุกรมวิธานที่ฉันต้องการใช้ข้อจำกัด ฉันได้เพิ่ม a field_term_ref_author การอ้างอิงเอนทิตีกับผู้ใช้

mymodule.php

ฟังก์ชัน MYMOUDLE_taxonomy_term_presave (TermInterface $term) {
  $คำศัพท์ = $term->bundle();
  สวิตช์ (คำศัพท์ $) {
    กรณี 'my_vocab_type':
      ถ้า ($term->isNew()) {
        // ตั้งค่าผู้เขียน (ผ่านฟิลด์ที่กำหนดเอง)
        $current_user = \Drupal::currentUser()->id();
        $term->set('field_term_ref_author', $current_user);
      }
    หยุดพัก;

ฟังก์ชัน MYMODULE_entity_base_field_info_alter(&$fields, $entity_type) {
  ถ้า ($entity_type->id() === 'taxonomy_term') {
    ถ้า (isset($fields['name'])) {
      $fields['name']->addConstraint('TermNameUniquePerUser');
    }
  }
}

mymodule/src/Plugin/Validation/Constraint/TermNameUniquePerUser.php

<?php

เนมสเปซ Drupal\MYMODULE\Plugin\Validation\Constraint;

ใช้ Symfony\Component\Validator\Constraint;

/**
 * ตรวจสอบว่าค่าที่ส่งนั้นไม่ซ้ำกันสำหรับผู้ใช้
 *
 * @ข้อ จำกัด (
 * id = "TermNameUniquePerUser",
 * label = @Translation("ชื่อคำศัพท์เฉพาะต่อผู้ใช้", บริบท = "การตรวจสอบความถูกต้อง"),
 * ประเภท = "สตริง"
 * )
 */
คลาส TermNameUniquePerUser ขยายข้อ จำกัด {
  // ข้อความที่จะแสดงหากค่าไม่ซ้ำกัน
  public $notUnique = 'คุณสร้างคำศัพท์ชื่อ %value แล้ว';

}

mymodule/src/Plugin/Validation/Constraint/TermNameUniquePerUserValidator.php

<?php

เนมสเปซ Drupal\MYMODULE\Plugin\Validation\Constraint;

ใช้ Symfony\Component\Validator\Constraint;
ใช้ Symfony\Component\Validator\ConstraintValidator

/**
 * ตรวจสอบข้อ จำกัด TermNameUniquePerUser
 */
class TermNameUniquePerUserValidator ขยาย ConstraintValidator {

  /**
   * {@inheritdoc}
   */
  ตรวจสอบฟังก์ชั่นสาธารณะ ($ รายการ, ข้อ จำกัด $ ข้อ จำกัด ) {
    foreach ($ รายการเป็น $ รายการ) {
      // ตรวจสอบต่อไปว่าค่าไม่ซ้ำกันหรือไม่
      ถ้า (!$this->isUnique($item->value)) {
        $this->context->addViolation($constraint->notUnique, ['%value' => $item->value]);
      }
    }
  }

  /**
   * เป็นเอกลักษณ์?
   *
   * @param สตริง $value
   */
  ฟังก์ชันส่วนตัว isUnique($value) {
    $uid = \Drupal::currentUser()->id();
    $term_name_query = \Drupal::entityQuery('taxonomy_term')
      ->เงื่อนไข('ชื่อ', $value, '=')
      ->condition('field_term_ref_author', $uid);
    // หากแบบสอบถามมีผลลัพธ์ใด ๆ แสดงว่าไม่ซ้ำกัน
    // ดังนั้นเราควรกลับตรงกันข้ามว่ามีผลลัพธ์หรือไม่
    กลับ !($term_name_query->execute());
  }

}

ข้อดีเกี่ยวกับการเขียนเอนทิตีคิวรีแบบนี้คือ ถ้าคำศัพท์อนุกรมวิธานไม่มี a field_term_ref_author ฟิลด์ จะไม่มีผลลัพธ์ใด ๆ ดังนั้นข้อจำกัดจะประเมินอย่างถูกต้องกับคำที่อยู่ในกลุ่มที่ไม่อยู่ภายใต้ข้อจำกัด (แม้ว่าสิ่งนี้จะส่งผลให้แบบสอบถามฐานข้อมูลเสียเปล่า)

โพสต์คำตอบ

คนส่วนใหญ่ไม่เข้าใจว่าการถามคำถามมากมายจะปลดล็อกการเรียนรู้และปรับปรุงความสัมพันธ์ระหว่างบุคคล ตัวอย่างเช่น ในการศึกษาของ Alison แม้ว่าผู้คนจะจำได้อย่างแม่นยำว่ามีคำถามกี่ข้อที่ถูกถามในการสนทนา แต่พวกเขาไม่เข้าใจความเชื่อมโยงระหว่างคำถามและความชอบ จากการศึกษาทั้ง 4 เรื่องที่ผู้เข้าร่วมมีส่วนร่วมในการสนทนาด้วยตนเองหรืออ่านบันทึกการสนทนาของผู้อื่น ผู้คนมักไม่ตระหนักว่าการถามคำถามจะมีอิทธิพลหรือมีอิทธิพลต่อระดับมิตรภาพระหว่างผู้สนทนา