og-8.x-1.x-dev/src/Plugin/views/argument_validator/Group.php

src/Plugin/views/argument_validator/Group.php
<?php

namespace Drupal\og\Plugin\views\argument_validator;

use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityTypeBundleInfoInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Plugin\Context\EntityContextDefinition;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\og\GroupTypeManagerInterface;
use Drupal\views\Plugin\views\argument_validator\ArgumentValidatorPluginBase;
use Drupal\views\Attribute\ViewsArgumentValidator;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Validate whether an argument is a valid group.
 *
 * This supports numeric arguments group entity id. This validator also sets the
 * argument's title to the group label, which is the main reason behind this
 * validator.
 */
#[ViewsArgumentValidator(
  id: "og_group",
  title: new TranslatableMarkup("OG group")
)]
class Group extends ArgumentValidatorPluginBase implements ContainerFactoryPluginInterface {

  /**
   * If this validator can handle multiple arguments.
   */
  protected bool $multipleCapable = TRUE;

  public function __construct(
    array $configuration,
    $plugin_id,
    $plugin_definition,
    protected readonly EntityTypeManagerInterface $entityTypeManager,
    protected readonly EntityTypeBundleInfoInterface $entityTypeBundleInfo,
    protected readonly GroupTypeManagerInterface $groupTypeManager,
  ) {
    parent::__construct($configuration, $plugin_id, $plugin_definition);
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
    return new static(
      $configuration,
      $plugin_id,
      $plugin_definition,
      $container->get('entity_type.manager'),
      $container->get('entity_type.bundle.info'),
      $container->get('og.group_type_manager')
    );
  }

  /**
   * {@inheritdoc}
   */
  public function defineOptions() {
    $options = parent::defineOptions();
    $options['group_type'] = ['default' => 'node'];
    $options['access'] = ['default' => FALSE];
    $options['operation'] = ['default' => 'view'];
    $options['multiple'] = ['default' => FALSE];

    return $options;
  }

  /**
   * {@inheritdoc}
   */
  public function buildOptionsForm(&$form, FormStateInterface $form_state) {
    $group_types = $this->groupTypeManager->getGroupMap();

    // If no groups have been created yet, show only the error message and hide
    // the other elements.
    if (empty($group_types)) {
      $form['empty'] = [
        '#type' => 'html_tag',
        '#tag' => 'p',
        '#value' => $this->t('No groups have been set up yet.'),
      ];
      return $form;
    }

    $entity_type_options = [];
    foreach ($group_types as $entity_type => $bundles) {
      $definition = $this->entityTypeManager->getDefinition($entity_type);
      $entity_type_options[$entity_type] = $definition->getLabel();
    }

    $form['group_type'] = [
      '#type' => 'select',
      '#title' => $this->t('Entity type'),
      '#options' => $entity_type_options,
      '#default_value' => $this->options['group_type'],
      '#required' => TRUE,
    ];

    // Offer the option to filter by access to the entity in the argument.
    $form['access'] = [
      '#type' => 'checkbox',
      '#title' => $this->t('Validate user has access to the OG Group'),
      '#default_value' => $this->options['access'],
    ];
    $form['operation'] = [
      '#type' => 'radios',
      '#title' => $this->t('Access operation to check'),
      '#options' => [
        'view' => $this->t('View'),
        'update' => $this->t('Edit'),
        'delete' => $this->t('Delete'),
      ],
      '#default_value' => $this->options['operation'],
      '#states' => [
        'visible' => [
          ':input[name="options[validate][options][og_group][access]"]' => ['checked' => TRUE],
        ],
      ],
    ];

    // If class is multiple capable give the option to validate single/multiple.
    if ($this->multipleCapable) {
      $form['multiple'] = [
        '#type' => 'radios',
        '#title' => $this->t('Multiple arguments'),
        '#options' => [
          0 => $this->t('Single ID'),
          1 => $this->t('One or more IDs separated by , or +'),
        ],
        '#default_value' => (string) $this->options['multiple'],
      ];
    }

    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function validateArgument($argument) {
    if ($this->multipleCapable && $this->options['multiple'] && isset($argument)) {
      // At this point only interested in individual IDs no matter what type,
      // just splitting by the allowed delimiters.
      $ids = array_filter(preg_split('/[,+ ]/', $argument));
    }
    elseif ($argument) {
      $ids = [$argument];
    }
    // No specified argument should be invalid.
    else {
      return FALSE;
    }

    $group_type = $this->options['group_type'];
    $entities = $this->entityTypeManager->getStorage($group_type)->loadMultiple($ids);

    $labels = [];
    // Validate each id => entity. If any fails break out and return false.
    foreach ($ids as $id) {
      // There is no entity for this ID.
      if (!isset($entities[$id])) {
        return FALSE;
      }
      if (!$this->validateEntity($entities[$id])) {
        return FALSE;
      }
      $labels[] = $entities[$id]->label();
    }

    $this->argument->argument = $argument;
    $this->argument->validated_title = implode(' + ', $labels);

    return TRUE;
  }

  /**
   * Validates an individual entity against class access settings.
   */
  protected function validateEntity(EntityInterface $entity): bool {
    // If access restricted by entity operation.
    if ($this->options['access'] && !$entity->access($this->options['operation'])) {
      return FALSE;
    }

    $entity_type = $entity->getEntityTypeId();
    $bundle = $entity->bundle();

    // If entity is not a group type.
    if (!$this->groupTypeManager->isGroup($entity_type, $bundle)) {
      return FALSE;
    }

    return TRUE;
  }

  /**
   * {@inheritdoc}
   */
  public function calculateDependencies() {
    $dependencies = parent::calculateDependencies();

    $entity_type_id = $this->options['group_type'];
    $bundle_entity_type = $this->entityTypeManager->getDefinition($entity_type_id)->getBundleEntityType();

    // The bundle entity type might not exist. For example, users do not have
    // bundles.
    if ($this->entityTypeManager->hasHandler($bundle_entity_type, 'storage')) {
      $bundle_entity_storage = $this->entityTypeManager->getStorage($bundle_entity_type);
      $group_types = $this->groupTypeManager->getGroupMap();

      foreach ($bundle_entity_storage->loadMultiple($group_types[$this->options['group_type']]) as $bundle_entity) {
        $dependencies[$bundle_entity->getConfigDependencyKey()][] = $bundle_entity->getConfigDependencyName();
      }
    }

    return $dependencies;
  }

  /**
   * {@inheritdoc}
   */
  public function getContextDefinition() {
    return EntityContextDefinition::fromEntityTypeId($this->options['group_type'])
      ->setLabel($this->argument->adminLabel())
      ->setRequired(FALSE);
  }

}

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

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