computed_field-8.x-2.x-dev/src/Entity/ComputedField.php

src/Entity/ComputedField.php
<?php

namespace Drupal\computed_field\Entity;

use Drupal\computed_field\Field\ComputedFieldSettingsTrait;
use Drupal\computed_field\Field\FieldStorageDefinition;
use Drupal\computed_field\Plugin\ComputedField\ComputedFieldPluginInterface;
use Drupal\Core\Entity\EntityStorageInterface;
use Drupal\Core\Field\FieldConfigBase;
use Drupal\Core\Plugin\DefaultSingleLazyPluginCollection;
use Drupal\field\FieldConfigInterface;

/**
 * Provides the Computed Field entity.
 *
 * This class implements \Drupal\field\FieldConfigInterface so that the
 * field_config list builder \Drupal\field_ui\FieldConfigListBuilder includes it
 * in 'Manage fields' field UI pages. This requires a few minor hacks in various
 * places to make it work.
 *
 * @ConfigEntityType(
 *   id = "computed_field",
 *   label = @Translation("Computed Field"),
 *   label_collection = @Translation("Computed Fields"),
 *   label_singular = @Translation("computed field"),
 *   label_plural = @Translation("computed fields"),
 *   label_count = @PluralTranslation(
 *     singular = "@count computed field",
 *     plural = "@count computed fields",
 *   ),
 *   handlers = {
 *     "route_provider" = {
 *       "html" = "Drupal\Core\Entity\Routing\AdminHtmlRouteProvider",
 *     },
 *     "storage" = "Drupal\computed_field\Entity\Handler\ComputedFieldStorage",
 *   },
 *   admin_permission = "administer computed_field entities",
 *   entity_keys = {
 *     "id" = "id",
 *     "label" = "label",
 *   },
 *   config_export = {
 *     "id",
 *     "label",
 *     "field_name",
 *     "entity_type",
 *     "bundle",
 *     "plugin_id",
 *     "plugin_config",
 *   },
 * )
 */
class ComputedField extends FieldConfigBase implements
    ComputedFieldInterface,
    FieldConfigInterface {

  use ComputedFieldSettingsTrait;

  /**
   * The field ID.
   *
   * The ID consists of the following pieces:
   *  - the entity type
   *  - the bundle
   *  - the field name. For fields created in the admin UI, this is prefixed
   *    with 'computed_'.
   *
   * Example: node.article.computed_my_field, user.user.computed_my_field.
   *
   * @var string
   *
   * @see static::id()
   */
  protected $id;

  /**
   * The field name.
   *
   * @var string
   */
  protected $field_name;

  /**
   * The field lame.
   *
   * @var string
   */
  protected $label = '';

  /**
   * The entity type this field is attached to.
   *
   * @var string
   */
  protected $entity_type = '';

  /**
   * The name of the bundle the field is attached to.
   *
   * @var string
   */
  protected $bundle;

  /**
   * The field value plugin ID.
   *
   * @var string
   */
  protected $plugin_id;

  /**
   * The field value plugin configuration.
   *
   * @var array
   */
  protected $plugin_config = [];

  /**
   * The plugin collection.
   *
   * @var \Drupal\Component\Plugin\DefaultSingleLazyPluginCollection
   */
  protected $pluginCollection = NULL;

  /**
   * {@inheritdoc}
   */
  public function id() {
    // This method *defines* rather than *supplies* the entity ID, as it is
    // called during the entity creation process, by
    // ConfigEntityBase::__construct(). This is the same pattern used by the
    // field_config and field_storage_config entity types.
    return $this->entity_type . '.' . $this->bundle . '.' . $this->field_name;
  }

  /**
   * {@inheritdoc}
   */
  public function getTargetEntityTypeId(): string {
    return $this->entity_type;
  }

  /**
   * {@inheritdoc}
   */
  public function getTargetBundle(): string {
    return $this->bundle;
  }

  /**
   * {@inheritdoc}
   */
  public function getType() {
    return $this->getFieldValuePlugin()->getFieldType();
  }

  /**
   * {@inheritdoc}
   */
  public function getName() {
    return $this->field_name;
  }

  /**
   * {@inheritdoc}
   */
  public function getFieldValuePlugin(): ComputedFieldPluginInterface {
    return $this->getPluginCollection()->get($this->plugin_id);
  }

  /**
   * {@inheritdoc}
   */
  public function getPluginCollections() {
    $collections = [];
    if ($this->getPluginCollection()) {
      $collections['plugin_config'] = $this->getPluginCollection();
    }
    return $collections;
  }

  /**
   * Encapsulates the creation of the computed field's plugin collection.
   *
   * @return \Drupal\Component\Plugin\DefaultSingleLazyPluginCollection
   *   The computed field's plugin collection.
   */
  protected function getPluginCollection() {
    if (!$this->pluginCollection && $this->plugin_id && !is_null($this->plugin_config)) {
      $this->pluginCollection = new DefaultSingleLazyPluginCollection(
        \Drupal::service('plugin.manager.computed_field'),
        $this->plugin_id,
        $this->plugin_config
      );
    }
    return $this->pluginCollection;
  }

  /**
   * {@inheritdoc}
   */
  public function postCreate(EntityStorageInterface $storage) {
    // DIRTY HACK! DO NOTHING!
    // This is needed because when going to the 'add' form, there is no plugin
    // yet, but parent::postCreate() expects one to exist.
    // This will break things if EntityBase::postCreate() ever adds code.
  }

  /**
   * {@inheritdoc}
   */
  public function preSave(EntityStorageInterface $storage) {
    // Notify the entity storage. This ensures the field is added to the field
    // map.
    if ($this->isNew()) {
      \Drupal::service('field_definition.listener')->onFieldDefinitionCreate($this);
    }
    else {
      \Drupal::service('field_definition.listener')->onFieldDefinitionUpdate($this, $this->original);
    }

    parent::preSave($storage);
  }

  /**
   * {@inheritdoc}
   */
  public function postSave(EntityStorageInterface $storage, $update = TRUE) {
    // We rely on the parent class's postSave() to clear field definitions.
    parent::postSave($storage, $update);
  }

  /**
   * {@inheritdoc}
   */
  public static function postDelete(EntityStorageInterface $storage, array $entities) {
    // The parent class doesn't handle clearing caches on delete.
    // See https://www.drupal.org/project/drupal/issues/3336639.
    // Clear the cache upfront, to refresh the results of getBundles().
    \Drupal::service('entity_field.manager')->clearCachedFieldDefinitions();

    // Notify the entity storage.
    foreach ($entities as $entity) {
      \Drupal::service('field_definition.listener')->onFieldDefinitionDelete($entity);
    }

    // @todo Deleting a computed field entity leaves behind the configuration in
    // the entity view display. See
    // https://www.drupal.org/project/drupal/issues/3016895.
  }

  /**
   * {@inheritdoc}
   */
  public function getClass() {
    return \Drupal::service('computed_field.computed_field_class_factory')->getFieldItemClass($this->getType());
  }

  /**
   * {@inheritdoc}
   */
  public function isComputed() {
    return TRUE;
  }

  /**
   * {@inheritdoc}
   */
  public function isReadOnly() {
    return TRUE;
  }

  /**
   * {@inheritdoc}
   */
  public function getDisplayOptions($display_context) {
    // Hide configurable fields by default. The display option is set to the
    // default formatter when a new computed_field entity is saved in
    // \Drupal\computed_field\Form\ComputedFieldForm\configureEntityViewDisplay().
    return ['region' => 'hidden'];
  }

  /**
   * {@inheritdoc}
   */
  public function isDisplayConfigurable($context) {
    return match ($context) {
      'view' => TRUE,
      'form' => FALSE,
    };
  }

  /**
   * {@inheritdoc}
   */
  public function getFieldStorageDefinition() {
    $plugin = $this->getFieldValuePlugin();
    // Create a dummy with just the essentials.
    $definition = FieldStorageDefinition::create($this->getType())
      ->setName($this->getName())
      ->setComputed(TRUE)
      ->setCardinality($plugin->getFieldCardinality())
      ->setTargetEntityTypeId($this->entity_type);

    // Get settings from the computed field plugin.
    $settings = $this->getSettings();
    $definition->setSettings($settings);

    return $definition;
  }

  /**
   * {@inheritdoc}
   */
  public function getUniqueIdentifier() {
    return $this->getTargetEntityTypeId() . '-' . $this->getTargetBundle() . '-' . $this->getName();
  }

  /**
   * {@inheritdoc}
   */
  public function isDeleted() {
    return FALSE;
  }

  /**
   * {@inheritdoc}
   */
  protected function linkTemplates() {
    $link_templates["{$this->entity_type}-field-edit-form"] = 'entity.field_config.' . $this->entity_type . '_field_edit_form';
    $link_templates["{$this->entity_type}-field-delete-form"] = 'entity.field_config.' . $this->entity_type . '_field_delete_form';

    // This link template needs to exist because
    // \Drupal\field_ui\FieldConfigListBuilder assumes its presence.
    $link_templates["{$this->entity_type}-storage-edit-form"] = 'entity.field_config.' . $this->entity_type . '_storage_edit_form';

    return $link_templates;
  }

  /**
   * {@inheritdoc}
   */
  protected function urlRouteParameters($rel) {
    $parameters = parent::urlRouteParameters($rel);
    $entity_type = \Drupal::entityTypeManager()->getDefinition($this->entity_type);
    $bundle_parameter_key = $entity_type->getBundleEntityType() ?: 'bundle';
    $parameters[$bundle_parameter_key] = $this->bundle;
    return $parameters;
  }

}

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

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