field_css-2.0.0-rc4/src/Plugin/Field/FieldFormatter/CssFormatter.php

src/Plugin/Field/FieldFormatter/CssFormatter.php
<?php

namespace Drupal\field_css\Plugin\Field\FieldFormatter;

use Drupal\Component\Utility\Html;
use Drupal\Component\Utility\NestedArray;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Field\FormatterBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Routing\CurrentRouteMatch;
use Drupal\field_css\Traits\CssTrait;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Plugin implementation of the CSS formatter.
 *
 * @FieldFormatter(
 *   id = "css",
 *   label = @Translation("CSS"),
 *   field_types = {"css"}
 * )
 */
class CssFormatter extends FormatterBase {

  use CssTrait;

  /**
   * The current route match service.
   *
   * @var \Drupal\Core\Routing\CurrentRouteMatch
   */
  protected $currentRouteMatch;

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
    $instance = parent::create(
      $container,
      $configuration,
      $plugin_id,
      $plugin_definition,
    );
    $instance->setCurrentRouteMatch($container->get('current_route_match'));
    return $instance;
  }

  /**
   * Sets $currentRouteMatch property.
   */
  public function setCurrentRouteMatch(CurrentRouteMatch $current_route_match) {
    $this->currentRouteMatch = $current_route_match;
  }

  /**
   * {@inheritdoc}
   */
  public static function defaultSettings() {
    return [
      'location' => 'head',
      'prefix' => 'none',
      'fixed_prefix_value' => '',
    ] + parent::defaultSettings();
  }

  /**
   * Returns an array of selector options.
   *
   * @return array
   *   An array of selector options.
   */
  public static function getSelectorOptions() {
    return [
      'none' => 'None',
      'entity-item' => 'EntityType-Id (e.g. scoped-css--node-4938)',
      'fixed-value' => 'Fixed Value',
    ];
  }

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

    $form['location'] = [
      '#type' => 'radios',
      '#title' => $this->t('Location'),
      '#options' => [
        'head' => $this->t('HEAD'),
        'body' => $this->t('BODY'),
      ],
      '#default_value' => $this->getSetting('location'),
    ];

    $form['prefix'] = [
      '#type' => 'select',
      '#title' => $this->t('Selector Prefix'),
      '#default_value' => $this->getSetting('prefix'),
      '#options' => $this->getSelectorOptions(),
      '#required' => TRUE,
      '#description' => $this->t('What selector should prefix all css rules.'),
    ];

    $field_name = $this->fieldDefinition->getName();
    $form['fixed_prefix_value'] = [
      '#type' => 'textfield',
      '#title' => $this->t('Fixed Prefix Value'),
      '#default_value' => $this->getSetting('fixed_prefix_value'),
      '#element_validate' => [[$this, 'validateFixedPrefixValue']],
      '#description' => $this->t('Provide the fixed value declaration that will prefix all custom declarations. The value should be a valid CSS class without a leading period.'),
      '#states' => [
        'visible' => [
          ':input[name="fields[' . $field_name . '][settings_edit_form][settings][prefix]"]' => ['value' => 'fixed-value'],
        ],
      ],
    ];

    return $form;
  }

  /**
   * Validation method for the fixed_prefix_value field.
   *
   * @param array $element
   *   The element being validated.
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The current state of the form.
   * @param array $complete_form
   *   The complete form array.
   */
  public static function validateFixedPrefixValue(array &$element, FormStateInterface $form_state, array &$complete_form) {
    $values = $form_state->getValues();
    $fixed_prefix_value = NestedArray::getValue($values, $element['#parents']);
    // Use NestedArray::getValue() to also get the value for the 'prefix'
    // field, but replace the final value in the #parents array
    // ('fixed_prefix_value') with 'prefix' to get that value.
    $prefix_value = NestedArray::getValue($values, array_replace(
      $element['#parents'], [(count($element['#parents']) - 1) => 'prefix']
    ));

    if ($prefix_value == 'fixed-value') {
      if (empty($fixed_prefix_value)) {
        $form_state->setError($element, t('A Fixed Prefix Value must be entered.'));
      }
      else {
        if (substr($fixed_prefix_value, 0, 1) === '.') {
          $form_state->setError($element, t('The Fixed Prefix Value must not begin with a period.'));
        }
        // Remove leading period before running through cleanCssIdentifier().
        $fixed_prefix_value = ltrim($fixed_prefix_value, '.');
        if ($fixed_prefix_value != Html::cleanCssIdentifier($fixed_prefix_value)) {
          $form_state->setError($element, t('The Fixed Prefix Value must be a valid CSS class.'));
        }
      }
    }
  }

  /**
   * {@inheritdoc}
   */
  public function settingsSummary() {
    $summary = [
      $this->t('Location: @location', ['@location' => strtoupper($this->getSetting('location'))]),
      $this->t('Selector Prefix: @selector', ['@selector' => $this->getSelectorOptions()[$this->getSetting('prefix')]]),
    ];
    if ($this->getSetting('prefix') == 'fixed-value') {
      $summary[] = $this->t('Fixed Prefix Value: @value', ['@value' => $this->getSetting('fixed_prefix_value')]);
    }

    return $summary;
  }

  /**
   * {@inheritdoc}
   */
  public function view(FieldItemListInterface $items, $langcode = NULL) {
    // Whether <style> element is rendered in <head> or <body>.
    $location = $this->getSetting('location');
    // If the route is for certain Layout Builder routes, then override the
    // location to 'body'. If the <style> element is rendered in <head>, then
    // CSS changes will not be updated by Layout Builder's live preview
    // feature. This forces an editor reload the page to see CSS changes.
    $routes = [
      'layout_builder.add_block',
      'layout_builder.update_block',
      'layout_builder.remove_block',
      'layout_builder.defaults.*',
      'layout_builder.overrides.*',
    ];
    foreach ($routes as $item) {
      if (preg_match("/$item/", $this->currentRouteMatch->getRouteName())) {
        $location = 'body';
        break;
      }
    }

    $element = [];

    $entity = $items->getEntity();
    $entity_type = $entity->getEntityType();
    $key_prefix = $entity_type->id() . '_' . $entity->id() . '_' . $items->getName();

    foreach ($items as $delta => $item) {
      if ($item->value) {
        $prefix_setting = $this->getSetting('prefix');

        if ($prefix_setting == 'entity-item') {
          $prefix = $this->generatePrefix($entity, TRUE);
          $processed_value = $this->addSelectorPrefix($item->value, $prefix);
        }
        elseif ($prefix_setting == 'fixed-value') {
          $processed_value = $this->addSelectorPrefix($item->value, '.' . $this->getSetting('fixed_prefix_value'));
        }
        else {
          $processed_value = $this->formatCss($item->value);
        }

        if ($location == 'head') {
          $element[$delta]['#attached']['html_head'][] = [
            [
              '#type' => 'html_tag',
              '#tag' => 'style',
              '#value' => $processed_value,
              '#weight' => 100,
            ],
            $key_prefix . '_' . $delta,
          ];
        }
        else {
          $element[$delta]['value'] = [
            '#type' => 'html_tag',
            '#tag' => 'style',
            '#value' => $processed_value,
          ];
        }
      }
    }

    return $element;
  }

  /**
   * {@inheritdoc}
   */
  public function viewElements(FieldItemListInterface $items, $langcode) {
    return [];
  }

}

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

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