type_tray-1.0.x-dev/src/Form/TypeTraySettingsForm.php

src/Form/TypeTraySettingsForm.php
<?php

namespace Drupal\type_tray\Form;

use Drupal\Component\Utility\Html;
use Drupal\Component\Utility\Xss;
use Drupal\Core\Cache\CacheTagsInvalidatorInterface;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Config\TypedConfigManagerInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Form\ConfigFormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\filter\Entity\FilterFormat;
use Drupal\type_tray\Controller\TypeTrayController;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Form to configure type_tray settings.
 */
class TypeTraySettingsForm extends ConfigFormBase {

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

  /**
   * The cache tags invalidator service.
   *
   * @var \Drupal\Core\Cache\CacheTagsInvalidatorInterface
   */
  protected $cacheTagsInvalidator;

  /**
   * {@inheritdoc}
   */
  public function __construct(ConfigFactoryInterface $config_factory, TypedConfigManagerInterface $typed_config_manager, EntityTypeManagerInterface $entity_type_manager, CacheTagsInvalidatorInterface $cache_tags_invalidator) {
    parent::__construct($config_factory, $typed_config_manager);
    $this->entityTypeManager = $entity_type_manager;
    $this->cacheTagsInvalidator = $cache_tags_invalidator;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('config.factory'),
      $container->get('config.typed'),
      $container->get('entity_type.manager'),
      $container->get('cache_tags.invalidator'),
    );
  }

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

  /**
   * {@inheritdoc}
   */
  protected function getEditableConfigNames() {
    return ['type_tray.settings'];
  }

  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state) {
    $config = $this->config('type_tray.settings');

    // Define the categories available.
    $categories = $config->get('categories') ?? [];
    $form['categories'] = [
      '#type' => 'textarea',
      '#title' => $this->t('Categories'),
      '#description' => $this->t('Enter the categories to be used, one per line. Use the format key|label, where "key" is the category machine name, and "label" its human-visible name.'),
      '#default_value' => $this->buildStringFromCategories($categories),
      '#rows' => 10,
      '#required' => TRUE,
    ];

    $form['fallback_label'] = [
      '#type' => 'textfield',
      '#title' => $this->t('Fallback category'),
      '#description' => $this->t('Enter the string to be used when a content type is not categorized.'),
      '#default_value' => $config->get('fallback_label') ?? TypeTrayController::UNCATEGORIZED_LABEL,
      '#required' => TRUE,
    ];

    $formats = filter_formats();
    $options = array_combine(array_keys($formats), array_map(function ($item) {
      assert($item instanceof FilterFormat);
      return $item->label();
    }, $formats));
    $form['text_format'] = [
      '#type' => 'select',
      '#title' => $this->t('Extended description format'),
      '#description' => $this->t('Indicate the text format to be used when writing extended descriptions for each content type.'),
      '#options' => $options,
      '#default_value' => $config->get('text_format') ?? 'plain_text',
      '#required' => TRUE,
    ];

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

  /**
   * {@inheritdoc}
   */
  public function validateForm(array &$form, FormStateInterface $form_state) {
    $old_categories = $this->config('type_tray.settings')->get('categories') ?? [];
    if (empty($old_categories)) {
      return;
    }
    $new_categories = static::extractCategoriesFromString($form_state->getValue('categories', []));
    /** @var \Drupal\node\Entity\NodeType[] $types */
    $types = $this->entityTypeManager->getStorage('node_type')->loadMultiple();
    $removed = array_diff_key($old_categories, $new_categories);
    $cant_remove = [];
    foreach ($types as $type) {
      $type_category = $type->getThirdPartySetting('type_tray', 'type_category');
      if (!empty($type_category) && in_array($type_category, array_keys($removed))) {
        $cant_remove[] = $type_category . '|' . $removed[$type_category];
      }
    }
    if (!empty($cant_remove)) {
      $form_state->setErrorByName('categories', $this->t('The following categories are in use and cannot be removed: %categories.', [
        '%categories' => implode(", ", $cant_remove),
      ]));
    }
  }

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {
    $config = $this->config('type_tray.settings');

    $categories = static::extractCategoriesFromString($form_state->getValue('categories'));
    if (!empty($categories)) {
      $config->set('categories', $categories);
    }

    $config->set('fallback_label', Xss::filter($form_state->getValue('fallback_label', TypeTrayController::UNCATEGORIZED_LABEL)));
    $config->set('text_format', $form_state->getValue('text_format', 'plain_text'));

    $config->save();

    $this->cacheTagsInvalidator->invalidateTags([
      'config:node_type_list',
    ]);

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

  /**
   * Generates a string representation of an array of 'allowed values'.
   *
   * This string format is suitable for edition in a textarea.
   *
   * @param array $values
   *   An array of values, where array keys are values and array values are
   *   labels.
   *
   * @return string
   *   The string representation of the $values array:
   *    - Values are separated by a carriage return.
   *    - Each value is in the format "value|label" or "value".
   */
  public static function buildStringFromCategories(array $values) {
    $lines = [];
    foreach ($values as $key => $value) {
      $lines[] = "$key|$value";
    }
    return implode("\n", $lines);
  }

  /**
   * Convert a key|value-based string into an associative array.
   *
   * @param string $string
   *   The string we want to convert, where each line is a key|value pair, or
   *   where each key|value pair is separated by commas.
   *
   * @return array
   *   An associative array representing the string passed in.
   */
  public static function extractCategoriesFromString($string) {
    $values = [];

    $list = explode("\n", $string);
    $list = array_map('trim', $list);
    $list = array_filter($list, 'strlen');

    foreach ($list as $position => $text) {
      $text = Xss::filter($text);
      if (strpos($text, "|") === FALSE || strpos($text, "|") === 0) {
        // If users enter only one text value in a row (i.e. no "|"), assume
        // it's a label, and generate a key for it.
        $key = Html::cleanCssIdentifier($text);
        $value = $text;
      }
      else {
        $parts = explode("|", $text);
        $key = $parts[0];
        $value = $parts[1];
      }

      $values[$key] = $value;
    }

    return $values;
  }

}

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

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