eav_field-2.x-dev/src/Entity/EavAttribute.php

src/Entity/EavAttribute.php
<?php

namespace Drupal\eav_field\Entity;

use Drupal\Core\Annotation\Translation;
use Drupal\Core\Entity\Annotation\ContentEntityType;
use Drupal\Core\Entity\ContentEntityBase;
use Drupal\Core\Entity\EntityFieldManagerInterface;
use Drupal\Core\Entity\EntityStorageInterface;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Field\BaseFieldDefinition;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\Core\Field\FieldTypePluginManager;
use Drupal\Core\Field\FormatterPluginManager;
use Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem;
use Drupal\Core\Field\WidgetPluginManager;

/**
 * @ContentEntityType(
 *   id = "eav_attribute",
 *   label = @Translation("EAV attribute"),
 *   base_table = "eav_attribute",
 *   data_table = "eav_attribute_field_data",
 *   entity_keys = {
 *     "id" = "aid",
 *     "uuid" = "uuid",
 *     "label" = "label",
 *     "langcode" = "langcode",
 *     "weight" = "weight",
 *     "status" = "status",
 *   },
 *   translatable = TRUE,
 *   fieldable = TRUE,
 *   field_ui_base_route = "entity.eav_attribute.collection",
 *   handlers = {
 *     "storage" = "\Drupal\eav_field\EavAttributeStorage",
 *     "form" = {
 *       "add" = "\Drupal\eav_field\Form\EavAttributeForm",
 *       "edit" = "\Drupal\eav_field\Form\EavAttributeForm",
 *       "delete" = "\Drupal\Core\Entity\ContentEntityDeleteForm",
 *     },
 *     "list_builder" = "\Drupal\eav_field\EavAttributeListBuilder",
 *   },
 *   links = {
 *     "add-form" = "/admin/structure/eav/attributes/add",
 *     "edit-form" = "/admin/structure/eav/attributes/{eav_attribute}/edit",
 *     "delete-form" = "/admin/structure/eav/attributes/{eav_attribute}/delete",
 *     "collection" = "/admin/structure/eav/attributes",
 *   },
 *   admin_permission = "administer eav attributes",
 * )
 */
class EavAttribute extends ContentEntityBase implements EavAttributeInterface {

  /**
   * {@inheritDoc}
   */
  public static function baseFieldDefinitions(EntityTypeInterface $entity_type): array {
    $fields = parent::baseFieldDefinitions($entity_type); /** @var BaseFieldDefinition[] $fields */
    $i = 0;

    $fields['aid']
      ->setLabel(t('EAV attribute ID'))
      ->setDescription(t('EAV attribute ID'));

    $fields['label'] = BaseFieldDefinition::create('string')
      ->setLabel(t('Label'))
      ->setRequired(TRUE)
      ->setDisplayOptions('form', [
        'type' => 'string_textfield',
        'weight' => $i++,
      ])
      ->setDisplayConfigurable('form', TRUE);

    $fields['admin_label'] = BaseFieldDefinition::create('string')
      ->setLabel(t('Administrative label'))
      ->setDisplayOptions('form', [
        'type' => 'string_textfield',
        'weight' => $i++,
      ])
      ->setDisplayConfigurable('form', TRUE);

    $fields['machine_name'] = BaseFieldDefinition::create('string')
      ->setLabel(t('Machine name'))
      ->setRequired(TRUE)
      ->addConstraint('UniqueField')
      ->setDisplayOptions('form', [
        'type' => 'string_textfield',
        'weight' => $i++,
      ])
      ->setDisplayConfigurable('form', TRUE);

    $allowed_field_types = array_keys(EavValue::getFieldTypes());
    $fields['value_type'] = BaseFieldDefinition::create('list_string')
      ->setLabel(t('Value field type'))
      ->setRequired(TRUE)
      ->setDefaultValue('string')
      ->setSettings([
        'allowed_values' => array_combine($allowed_field_types, $allowed_field_types),
      ])
      ->setDisplayOptions('form', [
        'type' => 'options_select',
        'weight' => $i++,
      ])
      ->setDisplayConfigurable('form', TRUE);

    $fields['value_storage_config'] = BaseFieldDefinition::create('map')
      ->setLabel(t('Value storage config'));

    $fields['value_config'] = BaseFieldDefinition::create('map')
      ->setLabel(t('Value field config'));

    $fields['value_widget_type'] = BaseFieldDefinition::create('list_string')
      ->setLabel(t('Widget'))
      ->setRequired(TRUE)
      ->setDefaultValue('string_textfield')
      ->setSetting('allowed_values_function', [static::class, 'getValueWidgetTypeAllowedValues'])
      ->setDisplayOptions('form', [
        'type' => 'options_select',
        'weight' => $i++,
      ])
      ->setDisplayConfigurable('form', TRUE);

    $fields['value_widget_settings'] = BaseFieldDefinition::create('map')
      ->setLabel(t('Widget settings'));

    $fields['value_formatter_type'] = BaseFieldDefinition::create('list_string')
      ->setLabel(t('Formatter'))
      ->setSetting('allowed_values_function', [static::class, 'getValueFormatterTypeAllowedValues'])
      ->setDisplayOptions('form', [
        'type' => 'options_select',
        'weight' => $i++,
      ])
      ->setDisplayConfigurable('form', TRUE);

    $fields['value_formatter_settings'] = BaseFieldDefinition::create('map')
      ->setLabel(t('Formatter settings'));

    $fields['description'] = BaseFieldDefinition::create('text_long')
      ->setLabel(t('Description'))
      ->setDisplayOptions('form', [
        'type' => 'text_textfield',
        'weight' => $i++,
      ])
      ->setDisplayConfigurable('form', TRUE);

    $fields['primary'] = BaseFieldDefinition::create('boolean')
      ->setLabel(t('Is primary attribute'))
      ->setDefaultValue(FALSE)
      ->setDisplayOptions('form', [
        'type' => 'boolean_checkbox',
        'weight' => $i++,
      ])
      ->setDisplayConfigurable('form', TRUE);

    $fields['weight'] = BaseFieldDefinition::create('integer')
      ->setLabel(t('Weight'))
      ->setDisplayOptions('form', [
        'type' => 'number',
        'weight' => $i++,
      ])
      ->setDisplayConfigurable('form', TRUE);

    $fields['status'] = BaseFieldDefinition::create('boolean')
      ->setLabel(t('Active'))
      ->setDefaultValue(TRUE)
      ->setDisplayOptions('form', [
        'type' => 'boolean_checkbox',
        'weight' => $i++,
      ])
      ->setDisplayConfigurable('form', TRUE);

    $fields['created'] = BaseFieldDefinition::create('created')
      ->setLabel(t('Created'))
      ->setDescription(t('The time that the attribute was created.'))
      ->setDefaultValueCallback(static::class . '::getRequestTime');

    return $fields;
  }

  /**
   * {@inheritDoc}
   */
  public function preSave(EntityStorageInterface $storage): void {
    parent::preSave($storage);

    // Generate machine name
    $machine_name = $this->getMachineName();
    if (!$machine_name) {
      $machine_name = \Drupal::transliteration()->transliterate(mb_strtolower($this->label()));
    }

    // Clear machine name
    $machine_name = str_replace(['-', ' ', '.'], '_', $machine_name);
    $machine_name = preg_replace('/[^a-z0-9_]/', '', $machine_name);

    // Set machine name
    $this->setMachineName($machine_name);

    // Calculate weight
    if ($this->getWeight() === NULL) {
      $this->set('weight', self::getMaxWeight() + 1);
    }
  }

  /**
   * {@inheritDoc}
   */
  public static function create(array $values = []): EavAttributeInterface {
    /** @noinspection All */
    return parent::create($values);
  }

  /**
   * {@inheritDoc}
   */
  public static function load($id): ?EavAttributeInterface {
    return parent::load($id);
  }

  /**
   * {@inheritDoc}
   */
  public static function loadByProperties(array $values): array {
    return \Drupal::entityTypeManager()->getStorage('eav_attribute')->loadByProperties($values);
  }

  /**
   * {@inheritDoc}
   */
  public static function loadByMachineName(string $machine_name): ?EavAttributeInterface {
    static $cache = [];

    if (!isset($cache[$machine_name])) {
      $attributes_ids = \Drupal::entityQuery('eav_attribute')
        ->condition('machine_name', $machine_name)
        ->accessCheck(FALSE)
        ->execute();
      if ($attributes_ids) {
        $cache[$machine_name] = current($attributes_ids);
      }
    }

    return isset($cache[$machine_name]) ? self::load($cache[$machine_name]) : NULL;
  }

  /**
   * {@inheritDoc}
   */
  public static function loadByLabel(string $label): ?EavAttributeInterface {
    static $cache = [];

    if (!isset($cache[$label])) {
      $attributes_ids = \Drupal::entityQuery('eav_attribute')
        ->condition('label', $label)
        ->accessCheck(FALSE)
        ->execute();
      if ($attributes_ids) {
        $cache[$label] = current($attributes_ids);
      }
    }

    return isset($cache[$label]) ? self::load($cache[$label]) : NULL;
  }

  /**
   * {@inheritDoc}
   */
  public function loadUnchanged(): ?EavAttributeInterface {
    return $this->entityTypeManager()->getStorage('eav_attribute')->loadUnchanged($this->id());
  }

  /**
   * {@inheritDoc}
   *
   * @return EavAttributeInterface[]
   */
  public static function loadMultiple(array $ids = NULL): array {
    return parent::loadMultiple($ids);
  }

  /**
   * {@inheritDoc}
   */
  public function getAdministrativeLabel(): string {
    return $this->get('admin_label')->value ?: $this->label();
  }

  /**
   * {@inheritDoc}
   */
  public function getMachineName(): ?string {
    return $this->get('machine_name')->value;
  }

  /**
   * {@inheritDoc}
   */
  public function setMachineName(string $machine_name): self {
    return $this->set('machine_name', $machine_name);
  }

  /**
   * {@inheritDoc}
   */
  public function getWeight(): ?int {
    return $this->get('weight')->value;
  }

  /**
   * {@inheritDoc}
   */
  public function setWeight(int $weight): EavAttributeInterface {
    return $this->set('weight', $weight);
  }

  /**
   * {@inheritDoc}
   */
  public function getValueType(): string {
    return $this->get('value_type')->value;
  }

  /**
   * {@inheritDoc}
   */
  public function setValueType(string $value_type): EavAttributeInterface {
    return $this->set('value_type', $value_type);
  }

  /**
   * {@inheritDoc}
   */
  public function getValueFieldName(): string {
    return $this->getValueType() . '_value';
  }

  /**
   * {@inheritDoc}
   */
  public function getValueStorageConfigArray(bool $with_defaults = TRUE): array {
    $value_storage_config_array = $this->get('value_storage_config')->getValue()[0] ?? [];

    if ($with_defaults) {
      $default_values = [
        'field_name' => $this->getValueFieldName(),
        'entity_type' => 'eav_value',
        'type' => $this->getValueType(),
      ];

      $field_type_manager = \Drupal::service('plugin.manager.field.field_type'); /** @var FieldTypePluginManager $field_type_manager */
      $default_settings = $field_type_manager->getDefaultStorageSettings($this->getValueType());

      $value_storage_config_array = $default_values + $value_storage_config_array + ['settings' => $default_settings];
    }

    return $value_storage_config_array;
  }

  /**
   * {@inheritDoc}
   */
  public function getValueCardinality(): int {
    $value_storage_config_array = $this->getValueStorageConfigArray();
    return $value_storage_config_array['cardinality'] ?? 1;
  }

  /**
   * {@inheritDoc}
   */
  public function valueIsMultiple(): bool {
    $value_cardinality = $this->getValueCardinality();
    return ($value_cardinality > 1 || $value_cardinality == FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED);
  }

  /**
   * {@inheritDoc}
   */
  public function getValueConfigArray(bool $with_defaults = TRUE): array {
    $value_config_array = $this->get('value_config')->getValue()[0] ?? [];

    if ($with_defaults) {
      $default_values = [
        'field_name' => $this->getValueFieldName(),
        'entity_type' => 'eav_value',
        'bundle' => 'eav_value',
      ];

      $field_type_manager = \Drupal::service('plugin.manager.field.field_type'); /** @var FieldTypePluginManager $field_type_manager */
      $default_settings = $field_type_manager->getDefaultFieldSettings($this->getValueType());

      $value_config_array = $default_values + $value_config_array + ['settings' => $default_settings];
    }

    return $value_config_array;
  }

  /**
   * {@inheritDoc}
   */
  public function getValueFieldDefaultValues(): ?array {
    return $this->getValueConfigArray()['default_value'] ?? NULL;
  }

  /**
   * {@inheritDoc}
   */
  public function getValueWidgetType(): string {
    return $this->get('value_widget_type')->value;
  }

  /**
   * {@inheritDoc}
   */
  public function getValueWidgetSettings(): array {
    return $this->get('value_widget_settings')->getValue()[0] ?? [];
  }

  /**
   * {@inheritDoc}
   */
  public function getValueFormatterType(): ?string {
    return $this->get('value_formatter_type')->value;
  }

  /**
   * {@inheritDoc}
   */
  public function getValueFormatterSettings(): array {
    return $this->get('value_formatter_settings')->getValue()[0] ?? [];
  }

  /**
   * {@inheritDoc}
   */
  public function isActive(): bool {
    return (bool)$this->get('status')->value;
  }

  /**
   * {@inheritDoc}
   */
  public function isPrimary(): bool {
    return (bool)$this->get('primary')->value;
  }

  /**
   * {@inheritDoc}
   */
  public function getValueFieldDefinition(): BaseFieldDefinition {
    $entity_field_manager = \Drupal::service('entity_field.manager'); /** @var EntityFieldManagerInterface $entity_field_manager */
    /** @noinspection All */
    return $entity_field_manager->getFieldDefinitions('eav_value', 'eav_value')[$this->getValueFieldName()];
  }

  /**
   * {@inheritDoc}
   */
  public function configureValueFieldDefinition(): BaseFieldDefinition {
    $field_definition = $this->getValueFieldDefinition();
    $field_storage_definition = $field_definition->getFieldStorageDefinition();
    $field_config_array = $this->getValueConfigArray();
    $field_storage_config_array = $this->getValueStorageConfigArray();

    // Configure field storage
    if (!empty($field_storage_config_array['settings'])) {
      $field_storage_definition->setSettings($field_storage_config_array['settings']);
    }
    $field_storage_definition->setCardinality($field_storage_config_array['cardinality'] ?? 1);
    $field_definition->setCardinality($field_storage_config_array['cardinality'] ?? 1);

    // Configure field
    $field_definition->setLabel($this->label());
    if ($field_storage_definition->getCardinality() != 1) {
      $field_definition->setLabel(t('Values'));
    }
    if (!empty($field_config_array['settings'])) {
      $field_definition->setSettings($field_config_array['settings']);
    }
    if (isset($field_config_array['default_value'])) {
      $field_definition->setDefaultValue($field_config_array['default_value']);
    }
    if (isset($field_config_array['description'])) {
      $field_definition->setDescription($field_config_array['description']);
    }
    if (isset($field_config_array['required'])) {
      $field_definition->setRequired($field_config_array['required']);
    }

    $options_allowed_values_static_cache = &drupal_static('options_allowed_values', []);
    $valie_field_name = $this->getValueFieldName();
    unset(
      $options_allowed_values_static_cache['eav_value:' . $valie_field_name],
      $options_allowed_values_static_cache['eav_value:' . $valie_field_name . ':entity']
    );

    return $field_definition;
  }

  /**
   * {@inheritDoc}
   */
  public function getCategoriesIds(): array {
    return array_map(function (EntityReferenceItem $item) {
      return (int)$item->target_id;
    }, iterator_to_array($this->get('category')));
  }

  /**
   * {@inheritDoc}
   */
  public function setCategories(array $categories): EavAttributeInterface {
    return $this->set('category', $categories);
  }

  /**
   * {@inheritDoc}
   */
  public function getDescription(): ?array {
    if (!($description_items = $this->get('description'))->isEmpty()) {
      return $description_items->first()->getValue();
    }

    return NULL;
  }

  /**
   * {@inheritDoc}
   */
  public static function getMaxWeight(): int {
    $query = \Drupal::database()->select('eav_attribute_field_data', 'a');
    $query->addExpression('MAX(a.weight)');
    return (int)$query->execute()->fetchField();
  }

  /**
   * {@inheritDoc}
   */
  public static function getValueWidgetTypeAllowedValues(FieldStorageDefinitionInterface $field_storage_definition, EavAttributeInterface $attribute = NULL, bool &$cacheable = TRUE): array {
    $cacheable = FALSE;

    $widget_manager = \Drupal::service('plugin.manager.field.widget'); /** @var WidgetPluginManager $widget_manager */
    $field_type = $attribute ? $attribute->getValueType() : NULL;
    return $widget_manager->getOptions($field_type);
  }

  /**
   * {@inheritDoc}
   */
  public static function getValueFormatterTypeAllowedValues(FieldStorageDefinitionInterface $field_storage_definition, EavAttributeInterface $attribute = NULL, bool &$cacheable = TRUE): array {
    $cacheable = FALSE;

    $formatter_manager = \Drupal::service('plugin.manager.field.formatter'); /** @var FormatterPluginManager $formatter_manager */
    $field_type = $attribute ? $attribute->getValueType() : NULL;
    return $formatter_manager->getOptions($field_type);
  }

  /**
   * {@inheritDoc}
   */
  public static function sort(EavAttributeInterface $a, EavAttributeInterface $b): int {
    return $a->getWeight() <=> $b->getWeight();
  }

  /**
   * Return request timestamp.
   */
  public static function getRequestTime(): int {
    return \Drupal::time()->getRequestTime();
  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc