Я создал собственный модуль, который создает настраиваемый тип поля (с средством форматирования и виджетом), и я хотел бы сделать одно свойство поля инкрементным (чтобы увеличить его значение на единицу для каждого экземпляра поля.)
Что у меня есть до сих пор:
- 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->значения);
}
}
- 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']);
}
вернуть $значения;
}
- 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. На сегодняшний день я не узнал, как заставить его работать с настраиваемыми свойствами поля.