toolshed-8.x-1.x-dev/src/Element/CssClassField.php

src/Element/CssClassField.php
<?php

namespace Drupal\toolshed\Element;

use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Render\Element\Textfield;

/**
 * Create a form element for entering and validating CSS classes.
 *
 * @FormElement("css_class")
 */
class CssClassField extends Textfield {

  /**
   * {@inheritdoc}
   */
  public function getInfo(): array {
    $info = parent::getInfo();

    // We don't need all the extra process method for autocomplete.
    $info['#process'] = [
      static::class . '::processAjaxForm',
      static::class . '::processGroup',
    ];

    $info['#element_validate'][] = static::class . '::validateCssClasses';
    unset($info['#maxlength']);

    return $info;
  }

  /**
   * {@inheritdoc}
   */
  public static function valueCallback(&$element, $input, FormStateInterface $form_state): mixed {
    if ($input !== FALSE && $input !== NULL) {
      return is_string($input) ? preg_split('#\s+#', $input, -1, PREG_SPLIT_NO_EMPTY) : $input;
    }

    return NULL;
  }

  /**
   * {@inheritdoc}
   */
  public static function preRenderTextfield($element): array {
    if (is_array($element['#value'])) {
      $element['#attributes']['value'] = implode(' ', $element['#value']);
    }

    return parent::preRenderTextfield($element);
  }

  /**
   * Validate that the CSS classes entered here are in a valid CSS format.
   *
   * @param array $element
   *   Array definition of this css class element.
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The form state object, containing the build, info and values of the
   *   current form.
   */
  public static function validateCssClasses(array $element, FormStateInterface $form_state): void {
    // If the class names were entered, ensure that they are valid CSS classes.
    $classStr = implode(' ', $element['#value']);
    preg_match_all('/(?<=^| )[\w\-_][\w\-_\[\]:\/]*(?: +|$)/i', $classStr, $matches, PREG_PATTERN_ORDER);

    // If the valid class names match the sequences seperated by spaces, then
    // all the class names were valid. Otherwise the naming violations are
    // excluded from the $matches variable.
    if (count($matches[0]) !== count($element['#value'])) {
      $cssErrors = array_diff($element['#value'], array_map('trim', $matches[0]));
      $form_state->setError($element, t(
        'All class values must be valid CSS names. This means they must start with a letter, and can only contain alphanumeric characters, dashes, underscores and brackets. These classes violate these rules: "%cssErrors"',
        ['%cssErrors' => implode(', ', $cssErrors)]
      ));
    }
    else {
      $classes = preg_split('#\s+#', $classStr, -1, PREG_SPLIT_NO_EMPTY);
      $form_state->setValue($element['#parents'], $classes);
    }
  }

}

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

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