Рейтинг:0

Как установить добавочное свойство в настраиваемое поле?

флаг jp

Я создал собственный модуль, который создает настраиваемый тип поля (с средством форматирования и виджетом), и я хотел бы сделать одно свойство поля инкрементным (чтобы увеличить его значение на единицу для каждого экземпляра поля.)

Что у меня есть до сих пор:

  1. web/modules/custom/asciinema/src/Plugin/Field/FieldType/AsciinemaItem.php (определение поля)
  схема общедоступной статической функции (FieldStorageDefinitionInterface $field_definition) {
    возвращаться [
      // столбцы содержат значения, которые будут храниться в поле
      'столбцы' => [
        // Список значений, которые будет сохранять поле.
        'помощь' => [
          'тип' => 'серийный',
          'размер' => 'нормальный',
          'description' => 'Идентификатор экземпляра 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 = !пусто($lastIndex) ? $lastIndex + 1 : 1;

      $this->values['aid'] = $result;
      $this->setValue($this->значения);
    }
  }
  1. web/modules/custom/asciinema/src/Plugin/Field/FieldWidget/AsciinemaDefaultWidget.php (виджет поля).
 публичная функция formElement(
    FieldItemListInterface $items,
    $ дельта,
    массив $элемент,
    массив & $ форма,
    FormStateИнтерфейс $form_state
  ) {
    // Текущие значения с запасными вариантами.
    $aid = isset($items[$delta]->aid) ? $items[$delta]->помощь : 0;
    ....
    $element['asciinema']['id']['aid'] = [
      '#title' => т('ПОМОЩЬ'),
      '#description' => t('Идентификатор Asciinema.'),
      '#отключено' => ИСТИНА,
      '#тип' => 'текстовое поле',
      '#default_value' => $помощь,
    ];
    ....
    вернуть $элемент;

    ....

  публичная функция massageFormValues(
    массив $значений,
    массив $ форма,
    FormStateИнтерфейс $form_state
  ) {
    foreach ($значения как &$значение) {
      // Я БЫ.
      $value['aid'] = $value['asciinema']['id']['aid'];
    ....
      сбросить ($ значение ['asciinema']);
    }

    вернуть $значения;
  }
  1. web/modules/custom/asciinema/src/Plugin/Field/FieldFormatter/AsciinemaDefaultFormatter.php (форматер):
  публичная функция viewElements (FieldItemListInterface $items, $langcode) {
    $элементы = [];
    $ источник = [];

    foreach ($items as $delta => $item) {
      // Визуализация вывода с использованием темы asciinema_default.
      $ источник ['asciinema'] = [
        '#theme' => 'asciinema_default',
        '#asciinema' => [
          'помощь' => $item->помощь,
        ],
      ];
      ...
      $элементы[$дельта] = [
        '#markup' => \Drupal::service('renderer')->render($source),
      ];
    }

    вернуть $элементы;

Как сейчас, я могу сохранить значения, введенные в моем пользовательском поле, и помогать увеличивается для каждого экземпляра поля. Однако я не могу редактировать какие-либо из прошлых данных, потому что это будет генерировать:

ВНИМАНИЕ: сообщение PHP: неперехваченное исключение PHP Drupal\Core\Entity\EntityStorageException: "SQLSTATE [23505]: уникальное нарушение: 7 ОШИБКА: повторяющееся значение ключа нарушает уникальное ограничение "node_revision__asciinema__asciinema_aid__key"
php_1 | ПОДРОБНО: Ключ (asciinema_aid)=(4) уже существует.:

Я хотел бы узнать, чего не хватает, или найти лучший и более чистый способ работы с добавочными полями.

РЕДАКТИРОВАТЬ:

Мне удалось обойти ограничения, удалив:

'уникальные ключи' => [
        'помощь' => ['помощь'],
      ],

... из определений схемы и добавления дополнительного условия в функцию presave().

публичная функция preSave() {
    if ($this->getEntity()->isNew() || пусто($this->values['aid'])) {
      ...
    }

Однако я не считаю это окончательным ответом, а скорее обходным путем.Я также хотел бы использовать ограничения базы данных, такие как AUTO INCREMENT или UNIQUE KEY. На сегодняшний день я не узнал, как заставить его работать с настраиваемыми свойствами поля.

Jaypan avatar
флаг de
Вы можете указать, какова ваша общая цель, так как вполне возможно, что существует более друпаловский способ сделать то, что вы пытаетесь сделать, который не будет включать ничего из того, что вы показали.
dasj19 avatar
флаг jp
@Jaypan Ну, моя конечная цель - иметь поле, которое предоставляет информацию для отображения проигрывателя asciinema: https://asciinema.org/. Я создал настраиваемое поле со свойствами для каждой части необходимых данных для отображения плеера. Теперь мне нужен уникальный идентификатор для каждого экземпляра поля, чтобы иметь возможность иметь несколько игроков на одной странице и не конфликтовать друг с другом.
флаг cn
Почему бы не использовать идентификатор объекта? Или, если поле с несколькими значениями, комбинация идентификатора объекта и дельты поля?

Ответить или комментировать

Большинство людей не понимают, что склонность к познанию нового открывает путь к обучению и улучшает межличностные связи. В исследованиях Элисон, например, хотя люди могли точно вспомнить, сколько вопросов было задано в их разговорах, они не чувствовали интуитивно связи между вопросами и симпатиями. В четырех исследованиях, в которых участники сами участвовали в разговорах или читали стенограммы чужих разговоров, люди, как правило, не осознавали, что задаваемый вопрос повлияет — или повлиял — на уровень дружбы между собеседниками.