Score:0

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

ธง jp

ฉันสร้างโมดูลแบบกำหนดเองซึ่งสร้างประเภทฟิลด์แบบกำหนดเอง (พร้อมตัวจัดรูปแบบและวิดเจ็ต) และฉันต้องการทำให้คุณสมบัติหนึ่งของฟิลด์เพิ่มขึ้น (เพื่อเพิ่มค่าทีละหนึ่งสำหรับแต่ละอินสแตนซ์ของฟิลด์)

สิ่งที่ฉันมีคือ:

  1. web/modules/custom/asciinema/src/Plugin/Field/FieldType/AsciinemaItem.php (คำจำกัดความของฟิลด์)
  สคีมาของฟังก์ชันสแตติกสาธารณะ (FieldStorageDefinitionInterface $field_definition) {
    กลับ [
      // คอลัมน์มีค่าที่ฟิลด์จะจัดเก็บ
      'คอลัมน์' => [
        // แสดงรายการค่าที่ฟิลด์จะบันทึก
        'ความช่วยเหลือ' => [
          'type' => 'อนุกรม',
          'ขนาด' => 'ปกติ',
          'description' => 'id ของอินสแตนซ์ asciinema',
          'ไม่ได้ลงนาม' => จริง,
          'ไม่เป็นโมฆะ' => จริง,
        ]
      ]
      .....
      'คีย์เฉพาะ' => [
        'ช่วยเหลือ' => ['ช่วยเหลือ'],
      ]
    ];

  // ฟังก์ชันนี้ช่วยให้แน่ใจว่าค่าจะเพิ่มขึ้นทุกครั้งที่มีการบันทึกอินสแตนซ์ของฟิลด์ใหม่
  ฟังก์ชั่นสาธารณะ preSave () {
    ถ้า ($this->getEntity()->isNew()) {
      // เพิ่มมูลค่าของความช่วยเหลือเมื่อต้องจัดการกับเอนทิตีใหม่
      $fieldConfig = $this->getFieldDefinition();
      $field_name = $fieldConfig->getName();
      $entity_type = $fieldConfig->getTargetEntityTypeId();
      
      $query = \Drupal::database()->select($entity_type . '__' . $field_name, 'ef')
                ->fields('ef', [$field_name . '_' . 'ช่วยเหลือ'])
                ->orderBy($field_name . '_' . 'ช่วยเหลือ', 'DESC');
      $lastIndex = $query->execute()->fetchField();
      
      $result = !empty($lastIndex) ? $lastIndex + 1 : 1;

      $this->values['aid'] = ผลลัพธ์ $;
      $this->setValue($this->values);
    }
  }
  1. web/modules/custom/asciinema/src/Plugin/Field/FieldWidget/AsciinemaDefaultWidget.php (วิดเจ็ตฟิลด์)
 ฟังก์ชั่นสาธารณะ formElement(
    FieldItemListInterface $รายการ
    $เดลต้า
    อาร์เรย์ $องค์ประกอบ,
    อาร์เรย์ &$ ฟอร์ม
    FormStateInterface $form_state
  ) {
    // ค่าปัจจุบันพร้อมทางเลือกสำรอง
    $aid = isset($items[$delta]->aid) ? $items[$delta]->aid : 0;
    ....
    $element['asciinema']['id']['aid'] = [
      '#title' => t('เอดส์'),
      '#description' => t('Asciinema ID.'),
      '#disabled' => จริง,
      '#type' => 'ช่องข้อความ',
      '#default_value' => $ช่วยเหลือ,
    ];
    ....
    ส่งคืนองค์ประกอบ $;

    ....

  การนวดฟังก์ชั่นสาธารณะFormValues(
    อาร์เรย์ $values,
    อาร์เรย์ $form,
    FormStateInterface $form_state
  ) {
    foreach (ค่า $ เป็น & $ ค่า) {
      //ไอดี.
      $value['aid'] = $value['asciinema']['id']['aid'];
    ....
      unset($value['asciinema']);
    }

    คืนค่า $;
  }
  1. เว็บ/โมดูล/กำหนดเอง/asciinema/src/Plugin/Field/FieldFormatter/AsciinemaDefaultFormatter.php (ตัวจัดรูปแบบ):
  ฟังก์ชั่นสาธารณะ viewElements (FieldItemListInterface $items, $langcode) {
    $องค์ประกอบ = [];
    $แหล่งที่มา = [];

    foreach ($items เป็น $delta => $item) {
      // แสดงผลโดยใช้ธีม asciinema_default
      $แหล่งที่มา['asciinema'] = [
        '#theme' => 'asciinema_default',
        '#asciinema' => [
          'aid' => $item->aid,
        ]
      ];
      ...
      $องค์ประกอบ[$เดลต้า] = [
        '#markup' => \Drupal::service('renderer')->render($source),
      ];
    }

    ส่งคืนองค์ประกอบ $;

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

ข้อสังเกต: ข้อความ PHP: Uncaught ข้อยกเว้นของ PHP Drupal\Core\Entity\EntityStorageException: "SQLSTATE[23505]: การละเมิดเฉพาะ: 7 ข้อผิดพลาด: ค่าคีย์ที่ซ้ำกันละเมิดข้อจำกัดเฉพาะ "node_revision__asciinema__asciinema_aid__key"
php_1 | รายละเอียด: คีย์ (asciinema_aid)=(4) มีอยู่แล้ว:

ฉันชอบที่จะค้นหาว่ามีอะไรขาดหายไปหรือหาวิธีที่ดีกว่าและสะอาดกว่าในการจัดการกับฟิลด์ที่เพิ่มขึ้น

แก้ไข:

ฉันสามารถหลีกเลี่ยงข้อ จำกัด ได้โดยการลบ:

'คีย์เฉพาะ' => [
        'ช่วยเหลือ' => ['ช่วยเหลือ'],
      ]

... จากคำจำกัดความของ schema และเพิ่มเงื่อนไขพิเศษในฟังก์ชัน presave()

ฟังก์ชั่นสาธารณะ preSave () {
    ถ้า ($this->getEntity()->isNew() || ว่าง($this->values['aid'])) {
      ...
    }

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

Jaypan avatar
de flag
คุณอาจต้องการรวมเป้าหมายโดยรวมของคุณ เนื่องจากเป็นไปได้มากว่ามีวิธี Drupal มากกว่านี้ในการทำสิ่งที่คุณพยายามทำ ซึ่งจะไม่เกี่ยวข้องกับสิ่งที่คุณแสดง
dasj19 avatar
jp flag
@Jaypan เป้าหมายสุดท้ายของฉันคือการมีช่องที่ให้ข้อมูลเพื่อแสดงผู้เล่น asciinema: https://asciinema.org/ ฉันสร้างฟิลด์แบบกำหนดเองพร้อมคุณสมบัติสำหรับแต่ละส่วนของข้อมูลที่ต้องการเพื่อแสดงโปรแกรมเล่น ตอนนี้ฉันต้องการรหัสเฉพาะสำหรับแต่ละฟิลด์อินสแตนซ์เพื่อให้สามารถมีผู้เล่นหลายคนในหน้าเดียวกันและไม่ขัดแย้งกัน
cn flag
เหตุใดจึงไม่ใช้รหัสนิติบุคคล หรือหากเป็นฟิลด์ที่มีหลายค่า ให้ผสมระหว่างรหัสเอนทิตีและเดลต้าของฟิลด์

โพสต์คำตอบ

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