social_course-8.x-2.11/src/EventSubscriber/NodeQueryAccessAlterSubscriber.php

src/EventSubscriber/NodeQueryAccessAlterSubscriber.php
<?php

declare(strict_types=1);

namespace Drupal\social_course\EventSubscriber;

use Drupal\Core\Entity\EntityTypeManager;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Session\AccountProxyInterface;
use Drupal\group\Plugin\Group\Relation\GroupRelationTypeManagerInterface;
use Drupal\social_node\Event\NodeQueryAccessEvent;
use Drupal\social_node\Event\SocialNodeEvents;
use Drupal\social_node\SocialNodeQueryAccessAlterInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

/**
 * Alters node query access for sections.
 */
class NodeQueryAccessAlterSubscriber implements EventSubscriberInterface, SocialNodeQueryAccessAlterInterface {

  /**
   * Constructs QueryAccessSubscriber.
   *
   * @param \Drupal\Core\Entity\EntityTypeManager $entityTypeManager
   *   The entity type definition.
   */
  public function __construct(
    protected EntityTypeManager $entityTypeManager,
    protected GroupRelationTypeManagerInterface $pluginManager,
    protected AccountProxyInterface $currentUser,
  ) {}

  /**
   * Ensures the query is joined with the memberships.
   *
   * @param \Drupal\Core\Session\AccountInterface $account
   *   The user account.
   * @param \Drupal\social_node\Event\NodeQueryAccessEvent $event
   *   The event object.
   *
   * @return string
   *   The membership join alias.
   *
   * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
   */
  protected function ensureMembershipJoin(AccountInterface $account, NodeQueryAccessEvent $event): string {
    $query = $event->query();

    // Join the memberships of the current user.
    $group_relationship_data_table = $this->entityTypeManager
      ->getDefinition('group_content')
      ->getDataTable();

    foreach ($query->getTables() as $join_info) {
      if (
        $join_info['table'] === $group_relationship_data_table &&
        str_contains((string) $join_info['condition'], 'group_membership')
      ) {
        return $join_info['alias'];
      }
    }

    $group_relationship_table = $this->ensureGroupRelationshipJoin($event);

    return $query->leftJoin(
      $group_relationship_data_table,
      'group_membership',
      "$group_relationship_table.gid=%alias.gid AND %alias.plugin_id='group_membership' AND %alias.entity_id=:account_id",
      [':account_id' => $account->id()]
    );
  }

  /**
   * Ensures the query is joined with the "group_relationship" table.
   *
   * @param \Drupal\social_node\Event\NodeQueryAccessEvent $event
   *   The event object.
   *
   * @return string
   *   The group relationship join alias.
   *
   * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
   * @throws \Exception
   */
  private function ensureGroupRelationshipJoin(NodeQueryAccessEvent $event): string {
    $query = $event->query();

    $group_relationship_data_table = $this->entityTypeManager
      ->getDefinition('group_content')
      ->getDataTable();

    foreach ($query->getTables() as $join_info) {
      if (
        $join_info['table'] === $group_relationship_data_table &&
        str_contains((string) $join_info['condition'], 'plugin_ids_in_use')
      ) {
        return $join_info['alias'];
      }
    }

    // If the table wasn't joined in any of the previous query builder,
    // we join it here.
    // Join table with group relationship with nodes.
    $node_base_table = $event->ensureNodeDataTable();
    $plugin_ids = $this->pluginManager->getPluginIdsByEntityTypeAccess('node');

    return $query->leftJoin(
      $group_relationship_data_table,
      'group_relationship',
      "$node_base_table.nid=group_relationship.entity_id AND group_relationship.plugin_id IN (:plugin_ids_in_use[])",
      [':plugin_ids_in_use[]' => $plugin_ids]
    );
  }

  /**
   * {@inheritdoc}
   */
  public static function getSubscribedEvents(): array {
    if (!class_exists('\Drupal\social_node\Event\SocialNodeEvents')) {
      return [];
    }

    $events[SocialNodeEvents::NODE_QUERY_ACCESS_ALTER][] = ['alterQueryAccess'];
    return $events;
  }

  /**
   * {@inheritdoc}
   */
  public function alterQueryAccess(NodeQueryAccessEvent $event): void {
    $plugin_ids = $this->pluginManager->getPluginIdsByEntityTypeAccess('node');
    if (empty($plugin_ids)) {
      // If no group relationship plugins for "node" entity type is enabled.
      return;
    }

    $account = $event->account();
    $or = $event->getConditions();

    // Join table with group relationship with nodes.
    $node_base_table = $event->ensureNodeDataTable();
    // Make sure we have joined a group membership table.
    $membership_table = $this->ensureMembershipJoin($account, $event);

    $or->condition(
      $event->query()->andConditionGroup()
        ->condition("$node_base_table.type", 'course_section')
        ->isNotNull("$membership_table.entity_id")
    );

    // Allow access to course_article and course_video if the user
    // is the author.
    $or->condition(
      $event->query()->andConditionGroup()
        ->condition("$node_base_table.type", 'course_article')
        ->condition("$node_base_table.uid", $this->currentUser->id())
    );

    $or->condition(
      $event->query()->andConditionGroup()
        ->condition("$node_base_table.type", 'course_video')
        ->condition("$node_base_table.uid", $this->currentUser->id())
    );
  }

}

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

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