a12s-1.0.0-beta7/modules/theme_builder/src/Block/SettingsAlterBase.php

modules/theme_builder/src/Block/SettingsAlterBase.php
<?php

declare(strict_types=1);

namespace Drupal\a12s_theme_builder\Block;

use Drupal\block\BlockInterface;
use Drupal\Component\Utility\NestedArray;
use Drupal\Core\DependencyInjection\DependencySerializationTrait;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Form\SubformState;
use Drupal\Core\Form\SubformStateInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\Core\Utility\Error;

/**
 * The base class for altering block configuration.
 */
abstract class SettingsAlterBase implements SettingsAlterInterface {

  use DependencySerializationTrait;
  use StringTranslationTrait;

  /**
   * List the classes altering block configuration.
   *
   * @todo Create a plugin manager? For now, it doesn't seems relevant.
   */
  const BLOCK_SETTINGS_ALTER_CLASSES = [
    GlobalAttributes::class,
    MenuBlockAttributes::class,
    LanguageSwitcher::class,
  ];

  /**
   * {@inheritdoc}
   */
  public static function trustedCallbacks(): array {
    return ['preRenderBlock'];
  }

  /**
   * {@inheritdoc}
   */
  public static function getInstance(): ?static {
    try {
      /** @noinspection PhpIncompatibleReturnTypeInspection */
      return \Drupal::classResolver(static::class);
    }
    catch (\InvalidArgumentException $e) {
      Error::logException(\Drupal::logger('a12s_theme_builder'), $e);
    }

    return NULL;
  }

  /**
   * {@inheritdoc}
   */
  public static function alterForm(BlockInterface $entity, array &$form, FormStateInterface $formState): void {
    $instance = self::getInstance();

    if ($instance && $instance->applies($entity)) {
      $key = $instance->configurationKey();
      $settings = $entity->getThirdPartySetting('a12s_theme_builder', $key, []);

      $form['a12s_theme_builder']['#tree'] = TRUE;
      $form['a12s_theme_builder']['#weight'] = 0;
      $form['a12s_theme_builder'][$key] = [
        '#parents' => ['a12s_theme_builder', $key],
      ];
      $subformState = SubformState::createForSubform($form['a12s_theme_builder'][$key], $form, $formState);
      $instance->buildForm($form['a12s_theme_builder'][$key], $subformState, $settings);

      $form['actions']['submit']['#submit'][] = static::class . '::submit';
      $form['#submit'][] = static::class . '::submit';
    }
  }

  /**
   * {@inheritdoc}
   */
  public static function submit(array $form, FormStateInterface $formState): void {
    if ($instance = self::getInstance()) {
      $key = $instance->configurationKey();
      $subformState = SubformState::createForSubform($form['a12s_theme_builder'][$key], $form, $formState);
      $instance->submitForm($form['a12s_theme_builder'][$key], $subformState);
    }
  }

  /**
   * Merge the given values with the default ones.
   *
   * @param array $values
   */
  protected function mergeWithDefault(array &$values): void {
    $values = NestedArray::mergeDeep($this->defaultValues(), $values);
  }

  /**
   * Clean recursively the given values by comparing with default values.
   *
   * All values identical to default values are removed, all empty values are
   * also removed.
   *
   * @param array $values
   *
   * @return array
   */
  protected function cleanValues(array $values): array {
    // Remove default values.
    $cleanValues = function(array $values, array $defaults) use (&$cleanValues) {
      $values = array_intersect_key($values, $defaults);

      foreach ($values as $key => $item) {
        if (is_array($item)) {
          // This should never happen...
          if (!is_array($defaults[$key])) {
            \Drupal::logger('a12s_theme_builder')->error('The value %name has an invalid array structure for the key %key.', [
              '%name' => $values['name'],
              '%key' => $key,
            ]);
            throw new \InvalidArgumentException();
          }
          else {
            $values[$key] = $cleanValues($item, $defaults[$key]);

            if (empty($values[$key])) {
              unset($values[$key]);
            }
          }
        }
        else {
          $item = match (gettype($defaults[$key])) {
            'integer' => (int) $item,
            'boolean' => (bool) $item,
            default => (string) $item,
          };

          if ($item === $defaults[$key]) {
            unset($values[$key]);
          }
        }
      }

      return $values;
    };

    try {
      return $cleanValues($values, $this->defaultValues());
    }
    catch (\InvalidArgumentException $e) {
      return [];
    }
  }

  /**
   * Save the third-party settings.
   *
   * @param array $values
   *   The values to store.
   * @param \Drupal\Core\Form\FormStateInterface $formState
   *   The subform state.
   */
  protected function saveSettings(array $values, FormStateInterface $formState): void {
    $key = $this->configurationKey();
    /** @var \Drupal\block\Entity\Block $block */
    $block = $formState->getFormObject()->getEntity();

    if (empty($values)) {
      $block->unsetThirdPartySetting('a12s_theme_builder', $key);
    }
    else {
      $block->setThirdPartySetting('a12s_theme_builder', $key, $values);
    }

    $block->save();
  }

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, SubformStateInterface $formState): void {
    $values = $formState->getValues();
    $values = $this->cleanValues($values);
    $this->saveSettings($values, $formState);
  }

  /**
   * Whether this instance uses a pre-render callback or not.
   *
   * @return bool
   */
  protected function usePreRenderCallback(): bool {
    return FALSE;
  }

  /**
   * {@inheritdoc}
   */
  public function preRenderBlock($build): array {
    return $build;
  }

  /**
   * {@inheritdoc}
   */
  public static function alterView(BlockInterface $block, array &$build): void {
    $instance = static::getInstance();

    if ($instance && $instance->applies($block)) {
      $key = $instance->configurationKey();
      $settings = $block->getThirdPartySetting('a12s_theme_builder', $key, []);

      if ($settings) {
        $build['#a12s_theme_builder'][$key] = $settings;

        if ($instance->usePreRenderCallback()) {
          $build['#pre_render'][] = [$instance, 'preRenderBlock'];
        }
      }
    }
  }

}

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

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