Drupal → Создание вычисляемого поля сущности (computed field)

08.05.2021

Пример создания у материалов вычисляемого поля "Age", которое будет возвращать число секунд, прошедшее с момента добавления ноды. Значение не будет хранится в базе, а будет высчитываться при первом обращении к нему.

1. Создаём класс поля:

// src/ComputedNodeAgeFieldItemList.php

namespace Drupal\MODULENAME;

use Drupal\Core\Field\FieldItemList;
use Drupal\Core\TypedData\ComputedItemListTrait;
use Drupal\node\NodeInterface;

class ComputedNodeAgeFieldItemList extends FieldItemList {

  use ComputedItemListTrait;

  /**
   * {@inheritdoc}
   */
  protected function computeValue() {
    $node = $this->getEntity(); /** @var NodeInterface $node */
    $node_age = \Drupal::time()->getCurrentTime() - $node->getCreatedTime();
    $this->list[0] = $this->createItem(0, $node_age);
  }

}

2. Добавляем поле к материалам:

// MODULENAME.module

use Drupal\computed_field_example\ComputedNodeAgeFieldItemList;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Field\BaseFieldDefinition;

/**
 * Implements hook_entity_base_field_info().
 */
function MODULENAME_entity_base_field_info(EntityTypeInterface $entity_type): ?array {
  if ($entity_type->id() == 'node') {
    $fields['age'] = BaseFieldDefinition::create('integer')
      ->setLabel(t('Age'))
      ->setComputed(TRUE)
      ->setClass(ComputedNodeAgeFieldItemList::class)
      ->setReadOnly(TRUE)
      ->setDisplayConfigurable('view', TRUE)
      ->setDisplayOptions('view', [
        'type' => 'number_integer',
      ]);

    return $fields;
  }

  return NULL;
}

3. Сбрасываем кэш.

После этого можно обращаться к полю стандартным способом:

$age = $node->get('age')->value;

Подробнее про вычисляемые поля на drupal.org.
Код в виде модуля на github.

Написанное актуально для
Drupal 8+
Похожие записи

Комментарии

$age = $node->get('age')->value;

$age = $node->age->value;

А значения поля кешируются, или каждый раз вычисляются?

Добавить комментарий