test_helpers-1.0.0-alpha6/src/Stub/TypedDataManagerStub.php

src/Stub/TypedDataManagerStub.php
<?php

namespace Drupal\test_helpers\Stub;

use Drupal\Core\Entity\Plugin\DataType\EntityAdapter;
use Drupal\Core\TypedData\Plugin\DataType\ItemList;
use Drupal\Core\TypedData\TypedDataManager;
use Drupal\test_helpers\TestHelpers;
use Symfony\Component\Serializer\NameConverter\CamelCaseToSnakeCaseNameConverter;

/**
 * A stub of the Drupal's default TypedDataManager class.
 *
 *  @package TestHelpers\DrupalServiceStubs
 *
 * @phpstan-ignore-next-line We still need to alter the plugin declaration.
 */
class TypedDataManagerStub extends TypedDataManager {

  /**
   * {@inheritdoc}
   */
  public function getDefinition($plugin_id, $exception_on_invalid = TRUE) {
    if (!isset($this->definitions[$plugin_id])) {
      $this->tryLoadDefinition($plugin_id);
    }
    return parent::getDefinition($plugin_id, $exception_on_invalid);
  }

  /**
   * Tries to find a suitable definition class by plugin_id and load it.
   *
   * @param string $plugin_id
   *   The plugin id.
   *
   * @return bool
   *   Is the plugin found and added.
   */
  protected function tryLoadDefinition(string $plugin_id): bool {
    if (strpos($plugin_id, ':')) {
      [$category, $name] = explode(':', $plugin_id);
    }
    else {
      $category = NULL;
      $name = NULL;
    }
    switch ($category) {
      // @todo Add other plugin categories here.
      case 'field_item':
        $plugin = 'Field';
        $suffixes = ['Item'];
        // @todo Add ability to add namespaces manually from a test.
        $namespaces = [
          'Drupal\Core\Field\Plugin\Field\FieldType',
          'Drupal\text\Plugin\Field\FieldType',
          'Drupal\image\Plugin\Field\FieldType',
          'Drupal\link\Plugin\Field\FieldType',
          'Drupal\options\Plugin\Field\FieldType',
          'Drupal\test_helpers\Plugin\Field\FieldType',
        ];
        break;

      case NULL:
        switch ($plugin_id) {
          // Hardcoding some known plugin classes.
          case 'entity':
            $this->stubSetPlugin(EntityAdapter::class);
            return TRUE;

          case 'list':
            $this->stubSetPlugin(ItemList::class);
            return TRUE;

          default:
            /*
             * For null category there is probably a DataType plugin, trying
             * match them by name.
             * Match examples:
             * string => Drupal\Core\TypedData\Plugin\DataType\StringData
             * integer => Drupal\Core\TypedData\Plugin\DataType\IntegerData
             * language => Drupal\Core\TypedData\Plugin\DataType\Language
             * entity_reference =>
             *   Drupal\Core\Entity\Plugin\DataType\EntityReference
             */
            $name = $plugin_id;
            $plugin = 'TypedData';
            $suffixes = ['', 'Data'];
            // @todo Add ability to add namespaces manually from a test.
            $namespaces = [
              'Drupal\Core\TypedData\Plugin\DataType',
              'Drupal\Core\Entity\Plugin\DataType',
              'Drupal\test_helpers\DataType',
            ];
            break;
        }
        break;

      default:
        // @todo Add check for other plugin ids.
        return FALSE;

    }

    $className = (new CamelCaseToSnakeCaseNameConverter(NULL, FALSE))->denormalize($name);
    foreach ($namespaces as $namespace) {
      foreach ($suffixes as $suffix) {
        if (class_exists($classNameFull = $namespace . '\\' . $className . $suffix)) {
          $this->stubSetPlugin($classNameFull, $plugin, $category);
          return TRUE;
        }
      }
    }
    return FALSE;
  }

  /**
   * Initiates a plugin in stub.
   *
   * @param string $class
   *   The class.
   * @param string $plugin
   *   The plugin name.
   * @param string|null $namespace
   *   The namespace to use.
   */
  public function stubInitPlugin(string $class, string $plugin = 'TypedData', ?string $namespace = NULL): void {
    $definition = TestHelpers::getPluginDefinition($class, $plugin);
    $id = self::getIdWithNamespace($definition['id'], $namespace);

    if (!isset($definition['list_class'])) {
      $definition['list_class'] = 'Drupal\Core\Field\FieldItemList';
    }

    $definitionClass = $definition['definition_class'];
    $definitionObject = new $definitionClass($definition);
    $this->definitions[$id] = new $class($definitionObject);
    $this->definitions[$id]->setTypedDataManager($this);
  }

  /**
   * Sets a plugin to stub.
   *
   * @param string $class
   *   The class name.
   * @param string $plugin
   *   The plugin name.
   * @param string|null $namespace
   *   The namespace to use.
   */
  public function stubSetPlugin(string $class, string $plugin = 'TypedData', ?string $namespace = NULL): void {
    $definition = TestHelpers::getPluginDefinition($class, $plugin);
    if (!isset($definition['list_class'])) {
      $definition['list_class'] = 'Drupal\Core\Field\FieldItemList';
    }
    $this->definitions[self::getIdWithNamespace($definition['id'], $namespace)] = $definition;
  }

  /**
   * Registers a new field type by plugin class.
   *
   * @param string $class
   *   The class name.
   */
  public function stubAddFieldType(string $class): void {
    $this->stubSetPlugin($class, 'Field', 'field_item');
  }

  /**
   * Sets a definition to stub.
   *
   * @param mixed $definition
   *   The definition.
   * @param string|null $namespace
   *   The namespace to use.
   * @param string|null $customId
   *   Sets the custom id, if needed.
   */
  public function stubSetDefinition($definition, ?string $namespace = NULL, ?string $customId = NULL): void {
    $this->definitions[self::getIdWithNamespace($customId ?? $definition['id'], $namespace)] = $definition;
  }

  /**
   * Sets a definition from class.
   *
   * @param string $class
   *   The class name.
   * @param string $plugin
   *   The plugin name.
   * @param string|null $namespace
   *   The namespace to use.
   */
  public function stubSetDefinitionFromClass(string $class, string $plugin = 'TypedData', ?string $namespace = NULL): void {
    $definition = TestHelpers::getPluginDefinition($class, $plugin);
    self::stubSetDefinition($definition, $plugin, $namespace);
  }

  /**
   * Combined the id with namespace.
   *
   * @param string $id
   *   The id string.
   * @param string|null $namespace
   *   The namespace.
   *
   * @return string
   *   The combined string.
   */
  protected function getIdWithNamespace(string $id, ?string $namespace = NULL) {
    return $namespace
      ? $namespace . ':' . $id
      : $id;
  }

}

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

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