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

src/Stub/EntityQueryServiceStub.php
<?php

namespace Drupal\test_helpers\Stub;

use Drupal\Core\Database\Query\ConditionInterface;
use Drupal\Core\Entity\Query\QueryBase;
use Drupal\Core\Entity\Query\QueryFactoryInterface;
use Drupal\test_helpers\StubFactory\EntityQueryStubFactory;
use Drupal\test_helpers\TestHelpers;

/**
 * A stub of the Drupal's default QueryFactoryInterface class.
 *
 *  @package TestHelpers\DrupalServiceStubs
 */
class EntityQueryServiceStub implements QueryFactoryInterface {

  /**
   * An EntityQueryStubFactory factory.
   *
   * @var \Drupal\test_helpers\StubFactory\EntityQueryStubFactory
   */
  protected EntityQueryStubFactory $stubQueryStubFactory;

  /**
   * The list of namespaces.
   *
   * @var array
   */
  protected array $namespaces;

  /**
   * A list of execute functions per entity type.
   *
   * @var array
   */
  protected array $executeFunctions;

  /**
   * {@inheritdoc}
   */
  public function __construct() {
    $this->stubQueryStubFactory = new EntityQueryStubFactory();
    $this->namespaces = QueryBase::getNamespaces($this);
    $this->namespaces[] = 'Drupal\Core\Entity\Query\Sql';
  }

  /**
   * Returns the base execute function closure.
   */
  public static function stubGetExecuteBaseFunction() {
    $executeBaseFunction = function () {
      $result = [];
      // @phpstan-ignore-next-line `$this` will be available in the runtime.
      $storage = TestHelpers::service('entity_type.manager')->getStorage($this->entityTypeId);
      // @phpstan-ignore-next-line `$this` will be available in the runtime.
      if ($this->latestRevision ?? NULL) {
        $allEntities = $storage->stubGetAllLatestRevision();
      }
      else {
        $allEntities = $storage->loadMultiple();
      }

      $resultEntities = [];
      foreach ($allEntities as $entity) {
        // @phpstan-ignore-next-line `$this` will be available in the runtime.
        foreach ($this->condition->conditions() as $condition) {
          // SqlContentEntityStorage::buildPropertyQuery() adds a strange
          // condition to check that default_langcode = 1, here we just skip it.
          // @todo Investigate it deeper.
          if ($condition['field'] == 'default_langcode' && $condition['value'] === [1]) {
            continue 1;
          }
          if (!TestHelpers::matchEntityCondition($entity, $condition)) {
            continue 2;
          }
        }
        $resultEntities[] = $entity;
      }

      // @phpstan-ignore-next-line `$this` will be available in the runtime.
      if ($this->sort) {
        // @phpstan-ignore-next-line `$this` will be available in the runtime.
        $sortList = array_reverse($this->sort);
        foreach ($sortList as $rule) {
          usort(
            $resultEntities,
            function ($a, $b) use ($rule) {
              if ($rule['direction'] == 'DESC') {
                $val2 = $a->{$rule['field']}->value ?? NULL;
                $val1 = $b->{$rule['field']}->value ?? NULL;
              }
              else {
                $val1 = $a->{$rule['field']}->value ?? NULL;
                $val2 = $b->{$rule['field']}->value ?? NULL;
              }
              if (is_string($val1) && is_string($val1)) {
                // For now let's use default comparison. It's not easy to detect
                // right string comparison rules, because it depends a lot on
                // database's field configuration.
                // If it doesn't fit for some tests - just use stubExecute to
                // check the conditions manually and hardcode the result.
                return strcmp($val1, $val2);
              }
              else {
                return $val1 <=> $val2;
              }
            }
          );
        }
      }
      // @phpstan-ignore-next-line `$this` will be available in the runtime.
      if ($this->range) {
        // @phpstan-ignore-next-line `$this` will be available in the runtime.
        $resultEntities = array_slice($resultEntities, $this->range['start'], $this->range['length']);
      }
      $result = [];
      foreach ($resultEntities as $entity) {
        // @phpstan-ignore-next-line `$this` will be available in the runtime.
        if ($this->latestRevision ?? NULL) {
          $key = $entity->getRevisionId();
        }
        else {
          $key = $entity->id();
        }
        $result[$key] = $entity->id();

      }
      return $result;
    };
    return $executeBaseFunction;
  }

  /**
   * {@inheritdoc}
   */
  public function get($entityType, $conjunction) {
    $executeFunction =
      $this->executeFunctions[$entityType->id()]
      ?? $this->executeFunctions['all']
      ?? $this->stubGetExecuteBaseFunction();
    $query = $this->stubQueryStubFactory->get($entityType, $conjunction, $executeFunction);
    return $query;
  }

  /**
   * {@inheritdoc}
   */
  public function getAggregate($entityType, $conjunction) {
    // @todo Implement a custom getAggregate call.
    return $this->get($entityType, $conjunction);
  }

  /**
   * Sets the function to handle execute calls.
   *
   * You can call `$this->stubExecuteBase()` in your custom callback function
   * to execute the base stub behavior for the query.
   *
   * @param callable $function
   *   The execute function.
   * @param string $entityTypeId
   *   The entity type to attach, all entity types by default.
   */
  public function stubSetExecuteHandler(callable $function, string $entityTypeId = 'all') {
    $this->executeFunctions[$entityTypeId] = $function;
  }

  /**
   * Checks if the passed conditions matches to configured.
   *
   * @param \Drupal\Core\Database\Query\ConditionInterface $conditionsExpected
   *   The expected conditions.
   * @param bool $onlyListed
   *   Return FALSE if class contains more conditions than expected.
   * @param bool $throwErrors
   *   Enables throwing notice errors when matching fails, with the explanation
   *   what exactly doesn't match.
   *
   * @return bool
   *   TRUE if matches, FALSE if not matches.
   */
  public function stubCheckConditionsMatch(ConditionInterface $conditionsExpected, bool $onlyListed = FALSE, bool $throwErrors = TRUE) {
    // @phpstan-ignore-next-line `$this` will be available in the runtime.
    return TestHelpers::matchConditions($this->condition, $conditionsExpected, $onlyListed, $throwErrors);
  }

}

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

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