group-8.x-1.x-dev/src/Hook/QueryHooks.php

src/Hook/QueryHooks.php
<?php

declare(strict_types=1);

namespace Drupal\group\Hook;

use Drupal\Core\Database\Query\AlterableInterface;
use Drupal\Core\Database\Query\SelectInterface;
use Drupal\Core\DependencyInjection\ClassResolverInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Hook\Attribute\Hook;
use Drupal\Core\Hook\Order\Order;
use Drupal\group\QueryAccess\EntityQueryAlter;
use Drupal\group\QueryAccess\GroupQueryAlter;
use Drupal\group\QueryAccess\GroupRelationshipQueryAlter;
use Drupal\views\Plugin\views\query\QueryPluginBase;
use Drupal\views\Plugin\views\query\Sql;
use Drupal\views\ViewExecutable;

/**
 * Query hook implementations for Group.
 */
final class QueryHooks {

  public function __construct(
    protected ClassResolverInterface $classResolver,
    protected EntityTypeManagerInterface $entityTypeManager,
  ) {}

  /**
   * Implements hook_query_TAG_alter().
   */
  #[Hook('query_entity_query_alter', order: Order::Last)]
  public function entityQueryAlter(AlterableInterface $query): void {
    if (!$query instanceof SelectInterface) {
      return;
    }

    $entity_type_id = $query->getMetaData('entity_type');
    if ($query->hasTag($entity_type_id . '_access')) {
      $entity_type = $this->entityTypeManager->getDefinition($entity_type_id);

      // Add specific access checks based on the entity type. Please note that
      // we first check for the group and relationship entity types because we
      // have full control over those and can therefore optimize the query more.
      // If the query is for a different entity type, we fall back to the
      // default query alter.
      //
      // PLEASE KEEP IN MIND that this means that a plugin that allows you to
      // nest groups will have no query access added for nested groups
      // whatsoever. This is by design as those plugins should opt to use the
      // permission calculator system, as it's way faster and automatically
      // included in GroupQueryAlter.
      switch ($entity_type_id) {
        case 'group':
          $class_name = GroupQueryAlter::class;
          break;

        case 'group_content':
          $class_name = GroupRelationshipQueryAlter::class;
          break;

        default:
          $class_name = EntityQueryAlter::class;
      }

      $this->classResolver
        ->getInstanceFromDefinition($class_name)
        ->alter($query, $entity_type);
    }
  }

  /**
   * Implements hook_query_TAG_alter().
   *
   * This uses the custom 'views_entity_query' tag added in :viewsQueryAlter().
   */
  #[Hook('query_views_entity_query_alter')]
  public function viewsEntityQueryAlter(AlterableInterface $query): void {
    if (!$query instanceof SelectInterface) {
      return;
    }

    $entity_type_id = $query->getMetaData('entity_type');
    $query->addTag($entity_type_id . '_access');
    $this->entityQueryAlter($query);
  }

  /**
   * Implements hook_views_query_alter().
   */
  #[Hook('views_query_alter', order: Order::Last)]
  public function viewsQueryAlter(ViewExecutable $view, QueryPluginBase $query): void {
    if (!$query instanceof Sql || !empty($query->options['disable_sql_rewrite'])) {
      return;
    }

    $table_info = $query->getEntityTableInfo();
    $base_table = reset($table_info);
    if (empty($base_table['entity_type']) || $base_table['relationship_id'] != 'none') {
      return;
    }

    // Add a custom tag so we don't trigger all other 'entity_query' tag alters.
    $entity_type_id = $base_table['entity_type'];
    $query->addTag('views_entity_query');

    // Build the Views query already so we can access the DB query.
    $query->build($view);
    $view->built = TRUE;

    // Add metadata to the DB query.
    $query = $view->build_info['query'];
    $count_query = $view->build_info['count_query'];
    $query->addMetaData('entity_type', $entity_type_id);
    $count_query->addMetaData('entity_type', $entity_type_id);
  }

}

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

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