headless_cms-1.0.3/modules/headless_cms_notify/src/Form/HeadlessNotifyTransportForm.php

modules/headless_cms_notify/src/Form/HeadlessNotifyTransportForm.php
<?php

declare(strict_types=1);

namespace Drupal\headless_cms_notify\Form;

use Drupal\Component\Plugin\ConfigurableInterface;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Entity\EntityForm;
use Drupal\Core\Form\FormStateInterface;
use Drupal\headless_cms_notify\Entity\HeadlessNotifyTransportInterface;
use Drupal\headless_cms_notify\HeadlessNotifyTransportServiceInterface;
use Drupal\headless_cms_notify\Plugin\HeadlessNotifyTransportPluginFormInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Provides the form to add / edit an HeadlessNotifyTransport entity.
 */
class HeadlessNotifyTransportForm extends EntityForm {

  /**
   * The original transport.
   */
  protected ?HeadlessNotifyTransportInterface $originalTransport = NULL;

  public function __construct(
    ConfigFactoryInterface $configFactory,
    protected HeadlessNotifyTransportServiceInterface $transportService,
  ) {
    $this->configFactory = $configFactory;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('config.factory'),
      $container->get('headless_cms_notify.transport_service'),
    );
  }

  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state) {
    // If the form is rebuilding.
    if ($form_state->isRebuilding()) {

      // If an transport plugin change triggered the rebuild.
      if ($form_state->getTriggeringElement()['#name'] == 'transport_plugin') {
        // Update the transport plugin.
        $this->updateTransportPlugin($form_state);
      }
    }
    elseif ($this->operation == "edit") {
      // Only when the form is first built.
      /** @var \Drupal\headless_cms_notify\Entity\HeadlessNotifyTransport $transport */
      $transport = $this->entity;
      $this->originalTransport = clone $transport;
    }

    return parent::buildForm($form, $form_state);
  }

  /**
   * {@inheritdoc}
   */
  public function form(array $form, FormStateInterface $form_state) {
    $form = parent::form($form, $form_state);

    /** @var \Drupal\headless_cms_notify\Entity\HeadlessNotifyTransport $transport  */
    $transport = $this->entity;

    $form['label'] = [
      '#type' => 'textfield',
      '#title' => $this->t('Label'),
      '#maxlength' => 255,
      '#default_value' => $transport->label(),
      '#description' => $this->t("Label for the transport."),
      '#required' => TRUE,
    ];

    $form['id'] = [
      '#type' => 'machine_name',
      '#default_value' => $transport->id(),
      '#machine_name' => [
        'exists' => '\Drupal\headless_cms_notify\Entity\HeadlessNotifyTransport::load',
      ],
      '#disabled' => !$transport->isNew(),
    ];

    // This is the element that contains all of the dynamic parts of the form.
    $form['transport'] = [
      '#type' => 'container',
      '#prefix' => '<div id="transport-settings">',
      '#suffix' => '</div>',
    ];

    $plugins = $this->transportService->loadTransportPlugins();
    $pluginOptions = [];
    // Show the current transport plugin.
    if (!$transport->isNew()) {
      $plugin = $transport->getTransportPlugin();
      $pluginOptions[$plugin->getPluginId()] = $plugin->getLabel();
    }

    // Populate the plugin options.
    foreach ($plugins as $pluginId => $definition) {
      $pluginOptions[$pluginId] = (string) $definition['label'];
    }

    if (count($pluginOptions) === 0) {
      $form['transport']['transport_plugin'] = [
        '#type' => 'fieldset',
        '#title' => $this->t('Transport Plugin'),
        '#description' => $this->t('No transport plugins available!<br />Please install a module that provides a transport plugin, e.g. `headless_cms_notify_webhook`.'),
      ];
    }
    else {
      $form['transport']['transport_plugin'] = [
        '#type' => 'select',
        '#title' => $this->t('Transport Plugin'),
        '#description' => $this->t('Select the plugin used for transport'),
        '#options' => $pluginOptions,
        '#required' => TRUE,
        '#default_value' => $transport->getTransportPluginId(),
        '#ajax' => [
          'callback' => [$this, 'ajaxUpdateSettings'],
          'event' => 'change',
          'wrapper' => 'transport-settings',
        ],
      ];
    }

    $form['transport']['transport_plugin_configuration'] = [
      '#type' => 'container',
      '#title' => $this->t('Transport plugin settings'),
      '#title_display' => FALSE,
      '#tree' => TRUE,
    ];

    $plugin = $transport->getTransportPlugin();
    if ($plugin instanceof HeadlessNotifyTransportPluginFormInterface) {
      $plugin_form_state = $this->createPluginFormState($form_state);
      $form['transport']['transport_plugin_configuration'] += $plugin->buildConfigurationForm([], $plugin_form_state);
      $form_state->setValue('transport_plugin_configuration', $plugin_form_state->getValues());
    }

    return $form;
  }

  /**
   * Creates a FormStateInterface object for a plugin.
   *
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The form state to copy values from.
   *
   * @return \Drupal\Core\Form\FormStateInterface
   *   A clone of the form state object with values from the plugin.
   */
  protected function createPluginFormState(FormStateInterface $form_state) {
    // Clone the form state.
    $plugin_form_state = clone $form_state;

    // Clear the values, except for this plugin type's settings.
    $plugin_form_state->setValues($form_state->getValue('transport_plugin_configuration', []));

    return $plugin_form_state;
  }

  /**
   * AJAX callback to update the dynamic settings on the form.
   */
  public function ajaxUpdateSettings(array &$form, FormStateInterface $form_state) {
    return $form['transport'];
  }

  /**
   * Update the transport plugin.
   */
  protected function updateTransportPlugin(FormStateInterface $form_state) {
    /** @var \Drupal\headless_cms_notify\Entity\HeadlessNotifyTransport $transport */
    $transport = $this->entity;

    /** @var \Drupal\headless_cms_notify\HeadlessNotifyTransportPluginInterface $plugin */
    $plugin = $transport->getTransportPlugin();
    if (!$plugin instanceof ConfigurableInterface) {
      return;
    }

    $transport->setTransportPlugin($plugin);

    // If an original transport exists and the
    // plugin ID matches the existing one.
    if ($this->originalTransport && $this->originalTransport->getTransportPluginId() == $plugin->getPluginId()) {
      // Use the configuration from the original profile's plugin.
      /** @var \Drupal\Component\Plugin\ConfigurableInterface $originalPlugin */
      $originalPlugin = $this->originalTransport->getTransportPlugin();

      if ($originalPlugin instanceof ConfigurableInterface) {
        $configuration = $originalPlugin->getConfiguration();
      }
    }
    else {
      // Use the plugin's default configuration.
      $configuration = $plugin->defaultConfiguration();
    }

    $plugin->setConfiguration($configuration);
    $form_state->setValue('transport_plugin_configuration', []);
    $form_state->getUserInput()['transport_plugin_configuration'] = [];
  }

  /**
   * {@inheritdoc}
   */
  public function validateForm(array &$form, FormStateInterface $form_state) {
    parent::validateForm($form, $form_state);

    // Only validate when submitting the form, not on AJAX rebuild.
    if (!$form_state->isSubmitted()) {
      return;
    }

    /** @var \Drupal\headless_cms_notify\Entity\HeadlessNotifyTransport $transport */
    $transport = $this->entity;

    // If the transport plugin contains a config form, validate it as well.
    if ($plugin = $transport->getTransportPlugin()) {
      if ($plugin instanceof HeadlessNotifyTransportPluginFormInterface) {
        $plugin_form_state = $this->createPluginFormState($form_state);
        $plugin->validateConfigurationForm($form, $plugin_form_state);
        $form_state->setValue('transport_plugin_configuration', $plugin_form_state->getValues());
        $this->moveFormStateErrors($plugin_form_state, $form_state);
        $this->moveFormStateStorage($plugin_form_state, $form_state);
      }
    }
    else {
      $form_state->setErrorByName('transport_plugin', $this->t('No transport plugin selected.'));
    }

    $form_state->cleanValues();
  }

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {
    /** @var \Drupal\headless_cms_notify\Entity\HeadlessNotifyTransport $transport */
    $transport = $this->entity;

    // Submit plugin configuration if available.
    if ($plugin = $transport->getTransportPlugin()) {
      if ($plugin instanceof HeadlessNotifyTransportPluginFormInterface) {
        $plugin_form_state = $this->createPluginFormState($form_state);
        $plugin->submitConfigurationForm($form, $plugin_form_state);
        $form_state->setValue('transport_plugin_configuration', $plugin_form_state->getValues());
      }
    }

    parent::submitForm($form, $form_state);
  }

  /**
   * {@inheritdoc}
   */
  public function save(array $form, FormStateInterface $form_state) {
    /** @var \Drupal\headless_cms_notify\Entity\HeadlessNotifyTransport $transport */
    $transport = $this->entity;
    $status = $transport->save();

    if ($status) {
      $this->messenger()->addMessage($this->t('Saved the %label transport.', [
        '%label' => $transport->label(),
      ]));
    }
    else {
      $this->messenger()->addMessage($this->t('The %label transport was not saved.', [
        '%label' => $transport->label(),
      ]));
    }

    $form_state->setRedirectUrl($transport->toUrl('collection'));

    return $status;
  }

  /**
   * Moves form errors from one form state to another.
   *
   * @param \Drupal\Core\Form\FormStateInterface $from
   *   The form state object to move from.
   * @param \Drupal\Core\Form\FormStateInterface $to
   *   The form state object to move to.
   */
  protected function moveFormStateErrors(FormStateInterface $from, FormStateInterface $to) {
    foreach ($from->getErrors() as $name => $error) {
      $to->setErrorByName($name, $error);
    }
  }

  /**
   * Moves storage variables from one form state to another.
   *
   * @param \Drupal\Core\Form\FormStateInterface $from
   *   The form state object to move from.
   * @param \Drupal\Core\Form\FormStateInterface $to
   *   The form state object to move to.
   */
  protected function moveFormStateStorage(FormStateInterface $from, FormStateInterface $to) {
    foreach ($from->getStorage() as $index => $value) {
      $to->set($index, $value);
    }
  }

}

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

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