bookish_admin-1.0.x-dev/modules/bookish_tags/src/Plugin/Field/FieldWidget/BookishTagsWidget.php

modules/bookish_tags/src/Plugin/Field/FieldWidget/BookishTagsWidget.php
<?php

namespace Drupal\bookish_tags\Plugin\Field\FieldWidget;

use Drupal\Component\Utility\Crypt;
use Drupal\Core\Entity\EntityReferenceSelection\SelectionPluginManagerInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Field\WidgetBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\KeyValueStore\KeyValueFactoryInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Site\Settings;
use Drupal\Core\Url;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Plugin implementation of the 'bookish_tags_widget' widget.
 *
 * @FieldWidget(
 *   id = "bookish_tags_widget",
 *   label = @Translation("Bookish tags"),
 *   description = @Translation("An autocomplete widget that uses Tagify."),
 *   field_types = {
 *     "entity_reference"
 *   },
 *   multiple_values = TRUE
 * )
 */
class BookishTagsWidget extends WidgetBase {

  /**
   * The key value factory.
   *
   * @var \Drupal\Core\KeyValueStore\KeyValueFactoryInterface
   */
  protected $keyValueFactory;

  /**
   * The current user.
   *
   * @var \Drupal\Core\Session\AccountInterface
   */
  protected $currentUser;

  /**
   * The selection plugin manager.
   *
   * @var \Drupal\Core\Entity\EntityReferenceSelection\SelectionPluginManagerInterface
   */
  protected $selectionManager;

  /**
   * The entity type manager.
   *
   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
   */
  protected $entityTypeManager;

  /**
   * Constructs a BookishTagsWidget object.
   *
   * @param string $plugin_id
   *   The plugin_id for the widget.
   * @param mixed $plugin_definition
   *   The plugin implementation definition.
   * @param \Drupal\Core\Field\FieldDefinitionInterface $field_definition
   *   The definition of the field to which the widget is associated.
   * @param array $settings
   *   The widget settings.
   * @param array $third_party_settings
   *   Any third party settings.
   * @param \Drupal\Core\KeyValueStore\KeyValueFactoryInterface $key_value_factory
   *   The key value factory.
   * @param \Drupal\Core\Session\AccountInterface $current_user
   *   The current user.
   * @param \Drupal\Core\Entity\EntityReferenceSelection\SelectionPluginManagerInterface $selection_manager
   *   The selection plugin manager.
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
   *   The entity type manager.
   */
  public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, array $third_party_settings, KeyValueFactoryInterface $key_value_factory, AccountInterface $current_user, SelectionPluginManagerInterface $selection_manager, EntityTypeManagerInterface $entity_type_manager) {
    parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings, $third_party_settings);
    $this->keyValueFactory = $key_value_factory;
    $this->currentUser = $current_user;
    $this->selectionManager = $selection_manager;
    $this->entityTypeManager = $entity_type_manager;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
    return new static(
      $plugin_id,
      $plugin_definition,
      $configuration['field_definition'],
      $configuration['settings'],
      $configuration['third_party_settings'],
      $container->get('keyvalue'),
      $container->get('current_user'),
      $container->get('plugin.manager.entity_reference_selection'),
      $container->get('entity_type.manager'),
    );
  }

  /**
   * {@inheritdoc}
   */
  public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) {
    $entity = $items->getEntity();
    /** @var \Drupal\taxonomy\TermInterface[] $referenced_entities */
    $referenced_entities = $items->referencedEntities();
    $default_value = [];

    foreach ($referenced_entities as $entity) {
      $default_value[] = [
        'value' => $entity->getName(),
        'entity_id' => $entity->id(),
      ];
    }

    $selection_settings = $this->getFieldSetting('handler_settings') + [
      'match_operator' => 'CONTAINS',
      'match_limit' => 10,
    ];
    $target_type = $this->getFieldSetting('target_type');
    $selection_handler = $this->getFieldSetting('handler');
    $data = serialize($selection_settings) . $target_type . $selection_handler;
    $selection_settings_key = Crypt::hmacBase64($data, Settings::getHashSalt());

    $key_value_storage = $this->keyValueFactory->get('entity_autocomplete');
    if (!$key_value_storage->has($selection_settings_key)) {
      $key_value_storage->set($selection_settings_key, $selection_settings);
    }

    $element += [
      '#type' => 'textfield',
      '#default_value' => json_encode($default_value),
      '#maxlength' => NULL,
      '#attached' => ['library' => ['bookish_tags/tagify']],
      '#attributes' => [
        'class' => ['bookish-tags-widget'],
        'data-autocomplete-url' => Url::fromRoute('system.entity_autocomplete', [
          'target_type' => $target_type,
          'selection_handler' => $selection_handler,
          'selection_settings_key' => $selection_settings_key,
        ])->toString(),
      ],
    ];

    return $element;
  }

  /**
   * {@inheritdoc}
   */
  public function massageFormValues($values, array $form, FormStateInterface $form_state) {
    if (!is_string($values)) {
      return [];
    }
    $target_type = $this->getFieldSetting('target_type');
    $selection_settings = $this->getFieldSetting('handler_settings') + [
      'match_operator' => 'CONTAINS',
      'match_limit' => 10,
      'target_type' => $target_type,
    ];
    $bundle = $this->getAutocreateBundle();
    $uid = $this->currentUser->id();
    $handler = $this->selectionManager->getInstance($selection_settings);
    $data = json_decode($values, TRUE);
    if (!is_array($data)) {
      return [];
    }
    $items = [];
    $term_storage = $this->entityTypeManager->getStorage('taxonomy_term');
    foreach ($data as $current) {
      // Find if a tag already exists, to avoid duplicates.
      $terms = $term_storage->loadByProperties([
        'name' => $current['value'],
      ]);
      if (!empty($terms)) {
        reset($terms);
        $current['entity_id'] = key($terms);
      }
      if (!empty($current['entity_id'])) {
        $items[] = ['target_id' => $current['entity_id']];
      }
      else {
        $entity = $handler->createNewEntity($target_type, $bundle, $current['value'], $uid);
        $items[] = ['entity' => $entity];
      }
    }
    return $items;
  }

  /**
   * Returns the name of the bundle which will be used for autocreated entities.
   *
   * @return string
   *   The bundle name. If autocreate is not active, NULL will be returned.
   */
  protected function getAutocreateBundle() {
    $bundle = NULL;
    if ($this->getSelectionHandlerSetting('auto_create')) {
      $target_bundles = $this->getSelectionHandlerSetting('target_bundles');
      // If there's no target bundle at all, use the target_type. It's the
      // default for bundleless entity types.
      if (empty($target_bundles)) {
        $bundle = $this->getFieldSetting('target_type');
      }
      // If there's only one target bundle, use it.
      elseif (count($target_bundles) == 1) {
        $bundle = reset($target_bundles);
      }
      // If there's more than one target bundle, use the autocreate bundle
      // stored in selection handler settings.
      elseif (!$bundle = $this->getSelectionHandlerSetting('auto_create_bundle')) {
        // If no bundle has been set as auto create target means that there is
        // an inconsistency in entity reference field settings.
        trigger_error(sprintf(
          "The 'Create referenced entities if they don't already exist' option is enabled but a specific destination bundle is not set. You should re-visit and fix the settings of the '%s' (%s) field.",
          $this->fieldDefinition->getLabel(),
          $this->fieldDefinition->getName()
        ), E_USER_WARNING);
      }
    }

    return $bundle;
  }

  /**
   * Returns the value of a setting for the entity reference selection handler.
   *
   * @param string $setting_name
   *   The setting name.
   *
   * @return mixed
   *   The setting value.
   */
  protected function getSelectionHandlerSetting($setting_name) {
    $settings = $this->getFieldSetting('handler_settings');
    return $settings[$setting_name] ?? NULL;
  }

}

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

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