entity_agree-2.0.x-dev/src/Plugin/Field/FieldWidget/AgreementWidget.php

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

namespace Drupal\entity_agree\Plugin\Field\FieldWidget;

use Drupal\Component\Utility\Html;
use Drupal\Component\Utility\NestedArray;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Field\WidgetBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\entity_agree\Plugin\Field\FieldType\AgreementItem;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Agreement configuration field widget.
 *
 * @FieldWidget(
 *   id = "entity_agree_default",
 *   label = @Translation("Agreement configuration"),
 *   field_types = {
 *     "entity_agree"
 *   },
 *   multiple_values = TRUE
 * )
 */
class AgreementWidget extends WidgetBase {

  /**
   * Agreement handler plugin manager.
   *
   * @var \Drupal\entity_agree\AgreementHandlerPluginManager
   */
  protected $agreementHandlerPluginManager;

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
    $widget = parent::create($container, $configuration, $plugin_id, $plugin_definition);
    $widget->agreementHandlerPluginManager = $container->get('plugin.manager.entity_agree_handler');
    return $widget;
  }

  /**
   * {@inheritdoc}
   */
  public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) {
    $element['#id'] = Html::getId('entity-agree-widget');
    $element['#type'] = 'fieldset';

    $ajax = [
      'callback' => [$this, 'ajax'],
      'wrapper' => $element['#id'],
      'element' => $element['#field_parents'] + [$items->getName(), 'widget'],
    ];

    $element['value'] = [
      '#title' => $this->t('Agreement status'),
      '#type' => 'select',
      '#options' => [
        AgreementItem::ENTITY_AGREE_STATUS_NA => $this->t('Not an agreement'),
        AgreementItem::ENTITY_AGREE_STATUS_ACTIVE => $this->t('Active'),
        AgreementItem::ENTITY_AGREE_STATUS_INACTIVE => $this->t('Inactive'),
      ],
      '#default_value' => $items[0]->value,
    ];

    // Try to obtain the handler config from widget state.
    $config = $this->getHandlerConfig($element, $form_state);

    // If NULL, that means the handler config has not been set into widget
    // state (initial load), so use the value form the field item.
    if ($config === NULL) {
      $config = unserialize($items[0]->config, ['allowed_classes' => FALSE]);
    }

    // When initializing, this could be NULL, etc., so just make it an array.
    if (!is_array($config)) {
      $config = [];
    }

    $this->setHandlerConfig($element, $form_state, $config);

    // Build out handler plugin config forms.
    $plugin_ids_used = [];
    foreach ($config as $key => $plugin_config) {
      $plugin_ids_used[] = $plugin_config['id'];

      /** @var \Drupal\entity_agree\AgreementHandlerInterface $plugin */
      $plugin = $this->agreementHandlerPluginManager->createInstance($plugin_config['id'], $plugin_config['config']);
      $element['config'][$key] = [
        '#type' => 'fieldset',
        '#title' => $plugin->getCategory() . ' - ' . $plugin->getLabel(),
      ];

      $plugin_form = [];
      $element['config'][$key]['config'] = $plugin->buildConfigurationForm($plugin_form, $form_state);

      // Removal button.
      $name = $element['#field_parents'] + [
        $this->fieldDefinition->getName(),
        $key,
        'remove',
      ];
      $element['config'][$key]['remove'] = [
        '#type' => 'button',
        '#name' => Html::getId(implode('--', $name)),
        '#value' => $this->t('Remove'),
        '#entity_agree_op' => 'remove_handler',
        '#entity_agree_pos' => $key,
        '#limit_validation_errors' => [],
        '#ajax' => $ajax,
      ];
    }

    $element['add_handler']['plugin_id'] = [
      '#title' => $this->t('Handler'),
      '#type' => 'select',
      '#options' => $this->agreementHandlerPluginManager->getPluginSelectionOptions($plugin_ids_used),
    ];
    $element['add_handler']['button'] = [
      '#type' => 'button',
      '#value' => $this->t('Add'),
      '#entity_agree_op' => 'add_handler',
      '#limit_validation_errors' => [],
      '#ajax' => $ajax,
    ];

    $element['#element_validate'] = [[$this, 'elementValidate']];

    return $element;
  }

  /**
   * {@inheritdoc}
   */
  public function massageFormValues(array $values, array $form, FormStateInterface $form_state) {
    // Serialize the config array.
    $values['config'] = serialize($values['config']);
    unset($values['add_handler']);
    return $values;
  }

  /**
   * Validation callback.
   */
  public function elementValidate(&$element, FormStateInterface $form_state, &$form) {
    $op = $form_state->getTriggeringElement()['#entity_agree_op'] ?? NULL;

    $value = $form_state->getValue($element['#parents']);
    $config = $this->getHandlerConfig($element, $form_state);

    switch ($op) {
      case 'add_handler':
        // Add handler.
        $config[] = [
          'id' => $value['add_handler']['plugin_id'],
          'config' => [],
        ];
        $form_state->setRebuild();
        break;

      case 'remove_handler':
        // Remove handler.
        $pos = $form_state->getTriggeringElement()['#entity_agree_pos'] ?? NULL;
        if ($pos !== NULL && isset($config[$pos])) {
          unset($config[$pos]);
          $config = array_values($config);
        }
        $form_state->setRebuild();
        break;
    }

    // Run through the plugins, validate, obtain updated config.
    foreach ($config as $key => $plugin_config) {
      /** @var \Drupal\entity_agree\AgreementHandlerInterface $plugin */
      $plugin = $this->agreementHandlerPluginManager->createInstance($plugin_config['id'], []);
      if (!empty($element['config'][$key]['config'])) {
        $plugin->validateConfigurationForm($element['config'][$key]['config'], $form_state);
      }
      $config[$key]['config'] = $plugin->getConfiguration();
    }

    // Set the changes into form state and the handler config.
    $value['config'] = $config;
    $form_state->setValue($element['#parents'], $value);
    $this->setHandlerConfig($element, $form_state, $config);
  }

  /**
   * Ajax callback.
   */
  public function ajax(array $form, FormStateInterface $form_state) {
    return NestedArray::getValue($form, $form_state->getTriggeringElement()['#ajax']['element']);
  }

  /**
   * Get the widget's handler configuration.
   *
   * @param array $element
   *   The widget's main form element.
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   Form state.
   *
   * @return array|null
   *   The widget's handler configuration.
   */
  protected function getHandlerConfig(array $element, FormStateInterface $form_state) {
    $field_state = static::getWidgetState($element['#field_parents'], $this->fieldDefinition->getName(), $form_state);
    return $field_state['config'] ?? NULL;
  }

  /**
   * Set the widget's handler configuration.
   *
   * @param array $element
   *   The widget's main form element.
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   Form state.
   * @param array $config
   *   The widget's handler configuration.
   */
  protected function setHandlerConfig(array $element, FormStateInterface $form_state, array $config) {
    $field_state = static::getWidgetState($element['#field_parents'], $this->fieldDefinition->getName(), $form_state);
    $field_state['config'] = $config;
    static::setWidgetState($element['#field_parents'], $this->fieldDefinition->getName(), $form_state, $field_state);
  }

}

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

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