rabbit_hole-8.x-1.x-dev/src/Plugin/Field/FieldWidget/RabbitHoleDefaultWidget.php

src/Plugin/Field/FieldWidget/RabbitHoleDefaultWidget.php
<?php

namespace Drupal\rabbit_hole\Plugin\Field\FieldWidget;

use Drupal\Component\Utility\NestedArray;
use Drupal\Component\Utility\SortArray;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Field\WidgetBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Session\AccountProxyInterface;
use Drupal\rabbit_hole\Entity\BehaviorSettings;
use Drupal\rabbit_hole\EntityHelper;
use Drupal\rabbit_hole\FormManglerService;
use Drupal\rabbit_hole\Plugin\RabbitHoleBehaviorPluginManager;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Default field widget for 'Rabbit hole' field-type.
 *
 * @FieldWidget(
 *   id = "rabbit_hole_default",
 *   label = @Translation("Rabbit hole"),
 *   field_types = {
 *     "rabbit_hole"
 *   }
 * )
 */
class RabbitHoleDefaultWidget extends WidgetBase {

  /**
   * Rabbit hole behavior plugins manager.
   *
   * @var \Drupal\rabbit_hole\Plugin\RabbitHoleBehaviorPluginManager
   */
  protected $rhBehaviorPluginManager;

  /**
   * Provides operations for bundles configuration.
   *
   * @var \Drupal\rabbit_hole\EntityHelper
   */
  protected $rhEntityHelper;

  /**
   * Rabbit hole behaviours (actions) form alterations.
   *
   * @var \Drupal\rabbit_hole\FormManglerService
   */
  protected $rhFormManager;

  /**
   * Current active user.
   *
   * @var \Drupal\Core\Session\AccountProxyInterface
   */
  protected $currentUser;

  /**
   * Constructs a RabbitHole 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\rabbit_hole\Plugin\RabbitHoleBehaviorPluginManager $rh_behavior_plugin_manager
   *   Rabbit hole behavior plugins manager.
   * @param \Drupal\rabbit_hole\EntityHelper $rh_entity_helper
   *   Rabbit hole behaviours (actions) form alterations.
   * @param \Drupal\rabbit_hole\FormManglerService $rh_form_manager
   *   Rabbit hole behaviours (actions) form alterations.
   */
  public function __construct($plugin_id,
                              $plugin_definition,
                              FieldDefinitionInterface $field_definition,
                              array $settings,
                              array $third_party_settings,
                              RabbitHoleBehaviorPluginManager $rh_behavior_plugin_manager,
                              EntityHelper $rh_entity_helper,
                              FormManglerService $rh_form_manager,
                              AccountProxyInterface $current_user) {
    parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings, $third_party_settings);
    $this->rhBehaviorPluginManager = $rh_behavior_plugin_manager;
    $this->rhEntityHelper = $rh_entity_helper;
    $this->rhFormManager = $rh_form_manager;
    $this->currentUser = $current_user;
  }

  /**
   * {@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('plugin.manager.rabbit_hole_behavior_plugin'),
      $container->get('rabbit_hole.entity_helper'),
      $container->get('rabbit_hole.form_mangler'),
      $container->get('current_user'),
    );
  }

  /**
   * {@inheritdoc}
   */
  public static function defaultSettings() {
    return [
      'advanced' => TRUE,
    ] + parent::defaultSettings();
  }

  /**
   * {@inheritdoc}
   */
  public function settingsForm(array $form, FormStateInterface $form_state) {
    $element['advanced'] = [
      '#type' => 'checkbox',
      '#title' => $this->t('Show the setting field on the advanced sidebar.'),
      '#description' => $this->t('Option works only when an advanced sidebar exists.'),
      '#default_value' => $this->getSetting('advanced'),
    ];
    return $element;
  }

  /**
   * {@inheritdoc}
   */
  public function settingsSummary() {
    $summary = [];

    $advanced = $this->getSetting('advanced') ? $this->t('advanced sidebar') : $this->t('main form');
    $summary[] = $this->t('Field location: show on the @advanced', ['@advanced' => $advanced]);

    return $summary;
  }

  /**
   * {@inheritdoc}
   */
  public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) {
    // Prepare required variables.
    $entity = $form_state->getFormObject()->getEntity();
    $entity_type_id = $entity->getEntityTypeId();
    $form_state->set('entity_type_id', $entity_type_id);

    // User without 'rabbit hole administer *' permission should not be able to
    // see and administer Rabbit Hole settings.
    if (!$this->currentUser->hasPermission('rabbit hole administer ' . $entity_type_id)) {
      return $element;
    }

    $bundle = $entity->bundle();
    $bundle_settings = BehaviorSettings::loadByEntityTypeBundle($entity_type_id, $bundle);
    $action_options = $this->rhBehaviorPluginManager->getBehaviors();

    // Prepare default action.
    $input = $form_state->getUserInput();
    $action = NestedArray::getValue($input,
      [$items->getName(), $delta, 'action']);
    if (!$action) {
      $action = $items[$delta]->action ?? FormManglerService::RABBIT_HOLE_USE_DEFAULT;
    }

    // Prepare element wrapper.
    $id_prefix = implode('-', [$items->getName(), $delta]);
    $wrapper_id = $id_prefix . '-ajax-wrapper';
    $element = [
      '#type' => 'details',
      '#open' => FALSE,
      '#attributes' => [
        'class' => ['rabbit-hole-settings-form'],
      ],
      '#attached' => [
        'library' => ['rabbit_hole/field-ui'],
      ],
    ] + $element;

    if ($this->getSetting('advanced')) {
      $element['#group'] = 'advanced';
    }

    $element['action'] = [
      '#type' => 'select',
      '#title' => $this->t('Behaviour'),
      '#required' => FALSE,
      '#empty_option' => $this->t('Global @bundle behavior (@setting)', [
        '@bundle' => strtolower($this->rhEntityHelper->getBundleLabel($entity_type_id, $bundle)),
        '@setting' => $action_options[$bundle_settings->getAction()],
      ]),
      '#empty_value' => FormManglerService::RABBIT_HOLE_USE_DEFAULT,
      '#options' => $action_options,
      '#default_value' => $action,
      '#ajax' => [
        'callback' => [$this, 'ajaxRefresh'],
        'wrapper' => $wrapper_id,
      ],
    ];

    // Container for plugin-related settings.
    $element['settings'] = [
      '#prefix' => '<div id="' . $wrapper_id . '">',
      '#suffix' => '</div>',
    ];

    if ($action) {
      $settings = $items[$delta]->settings ?? [];
      if ($this->rhBehaviorPluginManager->getDefinition($action, FALSE)) {
        if ($settings_form = $this->rhBehaviorPluginManager->createInstance($action, $settings)->buildConfigurationForm([], $form_state)) {
          $element['settings'] += $settings_form;
        }
      }
    }

    return $element;
  }

  /**
   * {@inheritdoc}
   *
   * Override a parent function a bit - add a specific value extraction.
   */
  public function extractFormValues(FieldItemListInterface $items, array $form, FormStateInterface $form_state) {
    // Field always has only 1 value.
    $delta = 0;
    $field_name = $this->fieldDefinition->getName();

    // Extract the values from $form_state->getValues().
    $path = array_merge($form['#parents'], [$field_name, $delta]);
    $key_exists = NULL;
    $values = NestedArray::getValue($form_state->getValues(), $path, $key_exists);
    $values = [$values];

    if ($key_exists) {
      // Account for drag-and-drop reordering if needed.
      if (!$this->handlesMultipleValues()) {
        // Remove the 'value' of the 'add more' button.
        unset($values['add_more']);

        // The original delta, before drag-and-drop reordering, is needed to
        // route errors to the correct form element.
        foreach ($values as $delta => &$value) {
          $value['_original_delta'] = $delta;
        }

        usort($values, function ($a, $b) {
          return SortArray::sortByKeyInt($a, $b, '_weight');
        });
      }

      // Let the widget massage the submitted values.
      $values = $this->massageFormValues($values, $form, $form_state);

      // Assign the values and remove the empty ones.
      $items->setValue($values);
      $items->filterEmptyItems();

      // Put delta mapping in $form_state, so that flagErrors() can use it.
      $field_state = static::getWidgetState($form['#parents'], $field_name, $form_state);
      foreach ($items as $delta => $item) {
        $field_state['original_deltas'][$delta] = $item->_original_delta ?? $delta;
        unset($item->_original_delta, $item->_weight);
      }
      static::setWidgetState($form['#parents'], $field_name, $form_state, $field_state);
    }
  }

  /**
   * Ajax callback.
   */
  public static function ajaxRefresh(array $form, FormStateInterface $form_state) {
    $triggering_element = $form_state->getTriggeringElement();
    $parents = $triggering_element['#array_parents'];
    // Find the path to settings fieldset, which should be on the same level.
    if ($action_index = array_search('action', $parents, TRUE)) {
      $parents[$action_index] = 'settings';
    }
    return NestedArray::getValue($form, $parents);
  }

}

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

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