graphql_compose-1.0.0-beta20/src/Form/InformationForm.php

src/Form/InformationForm.php
<?php

declare(strict_types=1);

namespace Drupal\graphql_compose\Form;

use Drupal\Component\Uuid\UuidInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Form\ConfigFormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\graphql\Entity\ServerInterface;
use Drupal\graphql_compose\Utility\ComposeConfig;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Info GraphQL Compose settings form.
 */
class InformationForm extends ConfigFormBase {

  /**
   * Construct a new GraphQL Compose settings form.
   *
   * @param \Drupal\Component\Uuid\UuidInterface $uuid
   *   The UUID service.
   * @param \Drupal\Core\Extension\ModuleHandlerInterface $moduleHandler
   *   The module handler service.
   * @param \Drupal\graphql\Entity\ServerInterface $graphqlServer
   *   The GraphQL server being edited, if any.
   */
  public function __construct(
    protected UuidInterface $uuid,
    protected ModuleHandlerInterface $moduleHandler,
    protected ServerInterface $graphqlServer,
  ) {}

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('uuid'),
      $container->get('module_handler'),
      $container->get('current_route_match')->getParameter('graphql_server'),
    );
  }

  /**
   * {@inheritdoc}
   */
  public function getFormId() {
    return 'graphql_compose_info';
  }

  /**
   * {@inheritdoc}
   */
  protected function getEditableConfigNames() {
    return [ComposeConfig::name()];
  }

  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state) {
    $form_state->set('graphql_server', $this->graphqlServer);

    $form['info'] = [
      '#type' => 'fieldset',
      '#title' => $this->t('Schema information'),
      '#description' => $this->t('Add version information to the %query query.', [
        '%query' => 'info',
      ]),
    ];

    $form['info']['schema_version'] = [
      '#type' => 'textfield',
      '#title' => $this->t('Schema version'),
      '#default_value' => ComposeConfig::get('settings.schema_version'),
      '#size' => 10,
    ];

    $form['info']['schema_description'] = [
      '#type' => 'textfield',
      '#title' => $this->t('Schema description'),
      '#default_value' => ComposeConfig::get('settings.schema_description'),
      '#maxlength' => 255,
    ];

    $form['site'] = [
      '#type' => 'fieldset',
      '#title' => $this->t('Site information'),
      '#description' => $this->t('Add site information to the %query query.', [
        '%query' => 'info',
      ]),
    ];

    $form['site']['site_name'] = [
      '#type' => 'checkbox',
      '#title' => $this->t('Add site name'),
      '#default_value' => ComposeConfig::get('settings.site_name'),
    ];

    $form['site']['site_slogan'] = [
      '#type' => 'checkbox',
      '#title' => $this->t('Add site slogan'),
      '#default_value' => ComposeConfig::get('settings.site_slogan'),
    ];

    $form['site']['site_front'] = [
      '#type' => 'checkbox',
      '#title' => $this->t('Add home path'),
      '#default_value' => ComposeConfig::get('settings.site_front'),
    ];

    $form['custom'] = [
      '#type' => 'fieldset',
      '#title' => $this->t('Custom content'),
      '#description' => $this->t('Add custom content to the %query query.', [
        '%query' => 'info',
      ]),
      '#tree' => TRUE,
    ];

    $form['custom']['settings'] = [
      '#type' => 'table',
      '#prefix' => '<div id="custom-settings-wrapper">',
      '#suffix' => '</div>',
      '#header' => [
        $this->t('Field name'),
        $this->t('Description'),
        $this->t('Value'),
        $this->t('Type'),
        $this->t('Operation'),
        $this->t('Weight'),
      ],
      '#tabledrag' => [
        [
          'action' => 'order',
          'relationship' => 'sibling',
          'group' => 'table-sort-weight',
        ],
      ],
      '#empty' => $this->t('No custom content added yet.'),
    ];

    if (is_null($form_state->get('custom_fields'))) {
      $form_state->set(
        'custom_fields',
        ComposeConfig::get('settings.custom')
      );
    }
    $fields = $form_state->get('custom_fields') ?: [];

    // Sort fields by weight value.
    uasort($fields, function ($a, $b) {
      return $a['weight'] <=> $b['weight'];
    });

    foreach ($fields as $uuid => $field) {

      $form['custom']['settings'][$uuid]['#attributes']['class'][] = 'draggable';
      $form['custom']['settings'][$uuid]['#weight'] = $field['weight'];

      $form['custom']['settings'][$uuid]['name'] = [
        '#type' => 'textfield',
        '#title' => $this->t('Field name'),
        '#title_display' => 'invisible',
        '#required' => TRUE,
        '#default_value' => $field['name'],
        '#placeholder' => $this->t('Field name'),
        '#maxlength' => 50,
        '#size' => 25,
        '#element_validate' => [SchemaForm::class . '::validateNameSdl'],
      ];

      $form['custom']['settings'][$uuid]['description'] = [
        '#type' => 'textfield',
        '#title' => $this->t('Value'),
        '#title_display' => 'invisible',
        '#default_value' => $field['description'],
        '#placeholder' => $this->t('Description'),
        '#maxlength' => 255,
      ];

      $form['custom']['settings'][$uuid]['value'] = [
        '#type' => 'textfield',
        '#title' => $this->t('Value'),
        '#title_display' => 'invisible',
        '#required' => TRUE,
        '#default_value' => $field['value'],
        '#placeholder' => $this->t('Value'),
        '#maxlength' => 255,
        '#element_validate' => ['::validateTypeValue'],
      ];

      if ($this->moduleHandler->moduleExists('token')) {
        $form['custom']['settings'][$uuid]['value']['#element_validate'][] = 'token_element_validate';
        $form['custom']['settings'][$uuid]['value']['#token_types'] = [];
      }

      $form['custom']['settings'][$uuid]['type'] = [
        '#type' => 'select',
        '#title' => $this->t('Type'),
        '#title_display' => 'invisible',
        '#required' => TRUE,
        '#options' => [
          'boolean' => $this->t('Boolean'),
          'float' => $this->t('Float'),
          'int' => $this->t('Integer'),
          'string' => $this->t('String'),
        ],
        '#default_value' => $field['type'],
        '#element_validate' => ['::validateMatchingCustomType'],
      ];

      $form['custom']['settings'][$uuid]['remove'] = [
        '#name' => 'remove-' . $uuid,
        '#type' => 'submit',
        '#value' => $this->t('Delete'),
        '#submit' => ['::removeCustomField'],
        '#ajax' => [
          'callback' => '::removeCustomFieldCallback',
          'wrapper' => 'custom-settings-wrapper',
        ],
        '#attributes' => [
          'class' => ['button--small', 'button--danger'],
        ],
        '#limit_validation_errors' => [],
      ];

      // TableDrag: Weight column element.
      $form['custom']['settings'][$uuid]['weight'] = [
        '#type' => 'weight',
        '#title' => $this->t('Weight'),
        '#title_display' => 'invisible',
        '#default_value' => $field['weight'],
        '#attributes' => [
          'class' => [
            'table-sort-weight',
          ],
        ],
      ];
    }

    if ($this->moduleHandler->moduleExists('token')) {
      $form['custom']['tokens'] = [
        '#type' => 'container',
      ];

      $form['custom']['tokens']['token_help'] = [
        '#theme' => 'token_tree_link',
        '#token_types' => [],
      ];
    }

    $form['custom']['add'] = [
      '#type' => 'submit',
      '#value' => $this->t('Add custom setting'),
      '#ajax' => [
        'callback' => '::addCustomFieldCallback',
        'wrapper' => 'custom-settings-wrapper',
      ],
      '#attributes' => [
        'class' => ['button--small'],
      ],
      '#limit_validation_errors' => [],
      '#submit' => ['::addCustomField'],
    ];

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

  /**
   * Add a custom field.
   *
   * @param array $form
   *   The form.
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The form state.
   */
  public function addCustomField(array &$form, FormStateInterface $form_state): void {
    $form_state->setRebuild();

    $uuid = $this->uuid->generate();
    $fields = $form_state->get('custom_fields') ?: [];

    $fields[$uuid] = [
      'uuid' => $uuid,
      'name' => '',
      'description' => '',
      'value' => '',
      'type' => 'string',
      'weight' => 0,
    ];

    $form_state->set('custom_fields', $fields);
  }

  /**
   * Add a custom field ajax callback.
   *
   * @param array $form
   *   The form.
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The form state.
   *
   * @return array
   *   The form element.
   */
  public function addCustomFieldCallback(array &$form, FormStateInterface $form_state) {
    return $form['custom']['settings'];
  }

  /**
   * Remove a custom field.
   *
   * @param array $form
   *   The form.
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The form state.
   */
  public function removeCustomField(array &$form, FormStateInterface $form_state): void {
    $form_state->setRebuild();

    $triggering_element = $form_state->getTriggeringElement();
    $parents = $triggering_element['#array_parents'];
    $uuid = array_slice($parents, -2, 1)[0];

    $fields = $form_state->get('custom_fields');
    unset($fields[$uuid]);

    $form_state->set('custom_fields', $fields);
  }

  /**
   * Remove a custom field ajax callback.
   *
   * @param array $form
   *   The form.
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The form state.
   *
   * @return array
   *   The form element.
   */
  public function removeCustomFieldCallback(array &$form, FormStateInterface $form_state): array {
    return $form['custom']['settings'];
  }

  /**
   * Ensure the selected type matches the data value (roughly).
   *
   * @param array $element
   *   The form element.
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The form state.
   */
  public function validateTypeValue($element, FormStateInterface $form_state): void {
    $parents = $element['#array_parents'];
    $uuid = array_slice($parents, -2, 1)[0];

    $value = $element['#value'];
    $type = $form_state->getValue(['custom', 'settings', $uuid, 'type']);

    switch ($type) {
      case 'string':
        if (!is_string($value)) {
          $form_state->setError($element, $this->t('The value must be a string.'));
        }
        break;

      case 'float':
        if (filter_var($value, FILTER_VALIDATE_FLOAT) === FALSE) {
          $form_state->setError($element, $this->t('The value must be a float.'));
        }
        break;

      case 'int':
        if (filter_var($value, FILTER_VALIDATE_INT) === FALSE) {
          $form_state->setError($element, $this->t('The value must be an integer.'));
        }
        break;

      case 'boolean':
        if (filter_var($value, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE) === NULL) {
          $form_state->setError($element, $this->t('The value must be a boolean.'));
        }
        break;
    }
  }

  /**
   * Allow the same name to be defined, but ensure its the same type.
   *
   * @param array $element
   *   The form element.
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The form state.
   */
  public function validateMatchingCustomType($element, FormStateInterface $form_state): void {
    $parents = $element['#array_parents'];
    $uuid = array_slice($parents, -2, 1)[0];

    $type = $element['#value'];
    $name = $form_state->getValue(['custom', 'settings', $uuid, 'name']);
    $fields = $form_state->getValue(['custom', 'settings']);

    foreach ($fields as $field) {
      if ($field['name'] === $name && $field['type'] !== $type) {
        $form_state->setError(
          $element,
          $this->t('Fields with matching names must have matching types.')
        );
      }
    }
  }

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {
    $custom_settings = [];
    $custom_values = $form_state->getValue(['custom', 'settings']) ?: [];

    foreach ($custom_values as $uuid => $values) {
      $custom_settings[$uuid] = [
        'name' => $values['name'],
        'description' => $values['description'] ?: NULL,
        'value' => $values['value'],
        'type' => $values['type'],
        'weight' => $values['weight'],
      ];
    }

    $this->config(ComposeConfig::name())
      ->set('settings.schema_description', $form_state->getValue('schema_description') ?: NULL)
      ->set('settings.schema_version', $form_state->getValue('schema_version') ?: NULL)
      ->set('settings.site_front', $form_state->getValue('site_front'))
      ->set('settings.site_name', $form_state->getValue('site_name'))
      ->set('settings.site_slogan', $form_state->getValue('site_slogan'))
      ->set('settings.custom', $custom_settings)
      ->save();

    _graphql_compose_cache_flush();

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

}

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

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