og-8.x-1.x-dev/src/Plugin/EntityReferenceSelection/OgSelection.php

src/Plugin/EntityReferenceSelection/OgSelection.php
<?php

declare(strict_types=1);

namespace Drupal\og\Plugin\EntityReferenceSelection;

use Drupal\Core\Entity\Attribute\EntityReferenceSelection;
use Drupal\Core\Entity\EntityFieldManagerInterface;
use Drupal\Core\Entity\EntityReferenceSelection\SelectionInterface;
use Drupal\Core\Entity\EntityReferenceSelection\SelectionPluginManagerInterface;
use Drupal\Core\Entity\EntityRepositoryInterface;
use Drupal\Core\Entity\EntityTypeBundleInfoInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Entity\Plugin\EntityReferenceSelection\DefaultSelection;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\og\MembershipManagerInterface;
use Drupal\og\Og;
use Drupal\og\OgAccessInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\Request;

/**
 * Provide default OG selection handler.
 *
 * Note that the id is correctly defined as "og:default" and not the other way
 * around, as seen in most other default selection handler (e.g. "default:node")
 * as OG's selection handler is a wrapper around those entity specific default
 * ones. That is, the same selection handler will be returned no matter what is
 * the target type of the reference field. Internally, it will call the original
 * selection handler, and use it for building the queries.
 */
#[EntityReferenceSelection(
  id: 'og:default',
  label: new TranslatableMarkup('OG selection'),
  group: 'og',
  weight: 1,
)]
class OgSelection extends DefaultSelection {

  public function __construct(
    array $configuration,
    $plugin_id,
    $plugin_definition,
    EntityTypeManagerInterface $entity_type_manager,
    ModuleHandlerInterface $module_handler,
    AccountInterface $current_user,
    EntityFieldManagerInterface $entity_field_manager,
    EntityTypeBundleInfoInterface $entity_type_bundle_info,
    EntityRepositoryInterface $entity_repository,
    protected SelectionPluginManagerInterface $selectionManager,
    protected OgAccessInterface $ogAccess,
    protected MembershipManagerInterface $membershipManager,
    protected ?Request $request,
  ) {
    parent::__construct($configuration, $plugin_id, $plugin_definition, $entity_type_manager, $module_handler, $current_user, $entity_field_manager, $entity_type_bundle_info, $entity_repository);
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition): self {
    return new static(
      $configuration,
      $plugin_id,
      $plugin_definition,
      $container->get('entity_type.manager'),
      $container->get('module_handler'),
      $container->get('current_user'),
      $container->get('entity_field.manager'),
      $container->get('entity_type.bundle.info'),
      $container->get('entity.repository'),
      $container->get('plugin.manager.entity_reference_selection'),
      $container->get('og.access'),
      $container->get('og.membership_manager'),
      $container->get('request_stack')->getCurrentRequest(),
    );
  }

  /**
   * Get the selection handler of the field.
   *
   * @return \Drupal\Core\Entity\EntityReferenceSelection\SelectionInterface
   *   Returns the selection handler.
   */
  public function getSelectionHandler(): SelectionInterface {
    $options = $this->getConfiguration();
    // The 'handler' key intentionally absent as we want the selection manager
    // to choose the best option.
    // @see \Drupal\Core\Entity\EntityReferenceSelection\SelectionPluginManager::getInstance()
    unset($options['handler']);
    // Remove also the backwards compatibility layer because that will be passed
    // to the chosen selection handler setter and, as an effect, will trigger a
    // deprecation notice.
    // @see \Drupal\Core\Entity\EntityReferenceSelection\SelectionPluginBase::resolveBackwardCompatibilityConfiguration()
    unset($options['handler_settings']);

    $plugin = $this->selectionManager->getInstance($options);
    assert($plugin instanceof SelectionInterface);

    return $plugin;
  }

  /**
   * Overrides ::buildEntityQuery.
   *
   * Return only group in the matching results.
   *
   * @param string|null $match
   *   (Optional) Text to match the label against. Defaults to NULL.
   * @param string $match_operator
   *   (Optional) The operation the matching should be done with. Defaults
   *   to "CONTAINS".
   *
   * @return \Drupal\Core\Entity\Query\QueryInterface
   *   The EntityQuery object with the basic conditions and sorting applied to
   *   it.
   */
  protected function buildEntityQuery($match = NULL, $match_operator = 'CONTAINS') {

    // Getting the original entity selection handler. OG selection handler using
    // the default selection handler of the entity, which the field reference
    // to, and add another logic to the query object i.e. check if the entities
    // bundle defined as group.
    $query = $this->getSelectionHandler()->buildEntityQuery($match, $match_operator);
    $target_type = $this->configuration['target_type'];
    $definition = $this->entityTypeManager->getDefinition($target_type);

    if ($bundle_key = $definition->getKey('bundle')) {
      $group_bundle_ids = Og::groupTypeManager()->getGroupMap()[$target_type];
      if ($group_bundle_ids) {
        $query->condition($bundle_key, $group_bundle_ids, 'IN');
      }
    }

    if ($this->currentUser->hasPermission('administer organic groups')) {
      // User can see all the groups.
      return $query;
    }

    $entity = $this->configuration['entity'] ?? NULL;
    if (!$entity && $this->request instanceof Request) {
      // Get the autocomplete query parameters from the entity 'add' form to
      // build a lightweight entity stub.
      $entity_type_id = $this->request->query->get('entity_type');
      if (is_string($entity_type_id) && !empty($entity_type_id)) {
        $storage = $this->entityTypeManager->getStorage($entity_type_id);
        $entity_type = $storage->getEntityType();

        $values = [];
        $bundle = $this->request->query->get('bundle');
        if (is_string($bundle) && !empty($bundle) && $entity_type->hasKey('bundle')) {
          $values[$entity_type->getKey('bundle')] = $bundle;
        }
        $entity = $storage->create($values);

        $this->configuration['entity'] = $entity;
      }
    }

    // We still don't have a group content entity.
    if (empty($this->configuration['entity'])) {
      throw new \Exception('No group content entity to assess access from groups.');
    }

    /** @var \Drupal\Core\Entity\EntityInterface $entity */
    $entity = $this->configuration['entity'];

    $ids = [];

    foreach ($this->getUserGroups() as $group) {
      // Check if the current user can perform the "create" operation on this
      // entity.
      $access_result = $this->ogAccess->userAccessGroupContentEntityOperation('create', $group, $entity, $this->currentUser);
      if ($access_result->isAllowed()) {
        $ids[] = $group->id();
      }
    }

    // Get the identifier key of the entity.
    $identifier_key = $definition->getKey('id');
    if ($ids) {
      $query->condition($identifier_key, $ids, 'IN');
    }
    else {
      // User doesn't have permission to select any group so falsify this
      // query.
      $query->condition($identifier_key, -1);
    }

    return $query;
  }

  /**
   * Return all the user's groups.
   *
   * @return \Drupal\Core\Entity\ContentEntityInterface[]
   *   Array with the user's group, or an empty array if none found.
   */
  protected function getUserGroups() {
    $other_groups = $this->membershipManager->getUserGroups($this->currentUser->id());
    return $other_groups[$this->configuration['target_type']] ?? [];
  }

  /**
   * {@inheritdoc}
   */
  public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
    $form = parent::buildConfigurationForm($form, $form_state);

    // Remove creation of entities that don't exist.
    unset($form['auto_create']);

    // Filter out the bundles that are not groups.
    $entity_type_id = $this->configuration['target_type'];
    $entity_type = $this->entityTypeManager->getDefinition($entity_type_id);
    $bundles_info = $this->entityTypeBundleInfo->getBundleInfo($entity_type_id);

    if ($entity_type->hasKey('bundle')) {
      $group_bundle_ids = Og::groupTypeManager()->getGroupMap()[$entity_type_id];
      $bundle_options = [];
      foreach ($group_bundle_ids as $group_bundle_id) {
        $bundle_options[$group_bundle_id] = $bundles_info[$group_bundle_id]['label'];
      }

      natsort($bundle_options);
      $form['target_bundles']['#options'] = $bundle_options;

      // Ensure the target bundles aren't required.
      $form['target_bundles']['#required'] = FALSE;
      $form['target_bundles']['#description'] = new TranslatableMarkup('The bundles of the entity type that can be referenced. Optional, leave empty for all bundles.');
    }

    return $form;
  }

}

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

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