entity_type_access_conditions-1.0.1/src/EntityAlters.php

src/EntityAlters.php
<?php

declare(strict_types=1);

namespace Drupal\entity_type_access_conditions;

use Drupal\conditions_helper\ConditionsEvaluator;
use Drupal\conditions_helper\Form\ConditionsFormBuilder;
use Drupal\Core\Access\AccessResult;
use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
use Drupal\Core\DependencyInjection\DependencySerializationTrait;
use Drupal\Core\Entity\EntityFormInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Plugin\Context\ContextRepositoryInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\entity_type_access_conditions\Form\SettingsForm;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Entity Alters class for altering entity type forms and access.
 */
class EntityAlters implements ContainerInjectionInterface {

  use DependencySerializationTrait;
  use StringTranslationTrait;

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    $context_repository = $container->get('context.repository');
    $entity_type_manager = $container->get('entity_type.manager');
    $conditions_helper_form_builder = $container->get('conditions_helper.form_builder');
    $conditions_evaluator = $container->get('conditions_helper.evaluator');
    $plugin_manager = $container->get('plugin.manager.entity_type_access_conditions');
    $module_handler = $container->get('module_handler');

    assert($context_repository instanceof ContextRepositoryInterface);
    assert($entity_type_manager instanceof EntityTypeManagerInterface);
    assert($conditions_helper_form_builder instanceof ConditionsFormBuilder);
    assert($conditions_evaluator instanceof ConditionsEvaluator);
    assert($plugin_manager instanceof EntityTypeAccessConditionsPluginManager);
    assert($module_handler instanceof ModuleHandlerInterface);

    return new self(
      $context_repository,
      $entity_type_manager,
      $conditions_helper_form_builder,
      $conditions_evaluator,
      $plugin_manager,
      $module_handler,
    );
  }

  /**
   * Constructor for FormAlters.
   */
  public function __construct(
    protected readonly ContextRepositoryInterface $contextRepository,
    protected readonly EntityTypeManagerInterface $entityTypeManager,
    protected readonly ConditionsFormBuilder $conditionsHelperFormBuilder,
    protected readonly ConditionsEvaluator $conditionsEvaluator,
    protected readonly EntityTypeAccessConditionsPluginManager $pluginManager,
    protected readonly ModuleHandlerInterface $moduleHandler,
  ) {
  }

  /**
   * Get the form IDs that we want to alter.
   *
   * @return array
   *   The form IDs.
   */
  public function getFormIds(): array {
    $form_ids = $this->pluginManager->getAlteredForms();
    $this->moduleHandler->alter('entity_type_access_conditions_form_ids', $form_ids);
    return $form_ids;
  }

  /**
   * Alter the form.
   *
   * @param array $form
   *   The form array.
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The form state object.
   * @param string $form_id
   *   The form ID.
   */
  public function formAlter(array &$form, FormStateInterface $form_state, $form_id): void {
    $form_object = $form_state->getFormObject();
    if ($form_object instanceof EntityFormInterface) {
      // Grab the entity from the form.
      $entity = $form_object->getEntity();

      if (!empty($entity) && $entity instanceof EntityInterface) {
        $form['third_party_settings'] = [
          '#tree' => TRUE,
        ];

        $form['third_party_settings']['entity_type_access_conditions'] = [
          '#type' => 'details',
          '#title' => $this->t('Entity Type Access Conditions'),
          '#open' => TRUE,
          '#tree' => TRUE,
        ];

        $available_conditions = $this->conditionsHelperFormBuilder->getAvailableConditions(SettingsForm::SETTINGS);
        $available_contexts = $this->contextRepository->getAvailableContexts();
        $stored_values = $entity->getThirdPartySettings('entity_type_access_conditions') ?? [];
        $this->conditionsHelperFormBuilder->buildConditionsForm($form['third_party_settings']['entity_type_access_conditions'], $form_state, $available_conditions, $available_contexts, $stored_values);

        // Add our submission handler to be first.
        array_unshift(
          $form['actions']['submit']['#submit'],
          [$this, 'formAlterSubmit']
        );
      }
    }
  }

  /**
   * Submit callback for the form being submitted.
   *
   * @param array $form
   *   The form being altered.
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The form state object.
   */
  public function formAlterSubmit(array &$form, FormStateInterface $form_state): void {
    $this->conditionsHelperFormBuilder->submitConditionsForm(
      $form,
      $form_state,
      ['third_party_settings', 'entity_type_access_conditions']
    );
  }

  /**
   * Check if the entity is accessible and block if not.
   */
  public function entityAccess(EntityInterface $entity, $operation, AccountInterface $account) {
    if ($account->hasPermission('bypass entity type access conditions')) {
      return AccessResult::neutral();
    }

    return $this->checkAccess($entity, $operation, $account);
  }

  /**
   * Check if the entity can be created.
   */
  public function entityCreateAccess(AccountInterface $account, array $context, ?string $entity_bundle) {
    if ($account->hasPermission('bypass entity type access conditions')) {
      return AccessResult::neutral();
    }

    if (empty($entity_bundle)) {
      return AccessResult::neutral();
    }

    if (empty($context['entity_type_id'])) {
      return AccessResult::neutral();
    }

    $plugin = $this->pluginManager->getDefinition($context['entity_type_id'], FALSE);
    if (!$plugin) {
      return AccessResult::neutral();
    }

    // If the operation is not restricted, return neutral.
    $restricted_operations = $plugin['restricted_operations'];
    if (!in_array('create', $restricted_operations)) {
      return AccessResult::neutral();
    }

    $entity_definition = $this->entityTypeManager->getDefinition($context['entity_type_id']);
    $entity_type = $entity_definition->getBundleEntityType();

    if (empty($entity_type)) {
      return AccessResult::neutral();
    }

    $entity_type_plugin = $this->pluginManager->getDefinition($entity_type, FALSE);
    if (!$entity_type_plugin) {
      return AccessResult::neutral();
    }

    $entity = $this->entityTypeManager->getStorage($entity_type_plugin['id'])->load($entity_bundle);
    if (!$entity) {
      return AccessResult::neutral();
    }

    return $this->checkAccess($entity, 'create', $account);

  }

  /**
   * Check if the entity is accessible.
   */
  private function checkAccess(EntityInterface $entity, string $operation, AccountInterface $account) {
    // Check if the entity supports third party settings.
    if (!method_exists($entity, 'getThirdPartySettings')) {
      return AccessResult::neutral();
    }

    $type = $entity->getEntityTypeId();
    $plugin = $this->pluginManager->getDefinition($type, FALSE);

    // If we don't have a plugin defined for this entity type, return neutral.
    if (!$plugin) {
      return AccessResult::neutral();
    }

    // If the operation is not restricted, return neutral.
    $restricted_operations = $plugin['restricted_operations'];
    if (!in_array($operation, $restricted_operations)) {
      return AccessResult::neutral();
    }

    // If we have no conditions set, return neutral.
    $entity_access_conditions = $entity->getThirdPartySettings('entity_type_access_conditions') ?? [];
    if (empty($entity_access_conditions)) {
      return AccessResult::neutral();
    }

    // Evaluate the conditions.
    $result = $this->conditionsEvaluator->evaluateConditions($entity_access_conditions);

    // If the conditions are not met, return forbidden.
    if ($result === FALSE) {
      $access_result = AccessResult::forbidden();
      $access_result->addCacheableDependency($entity);
      return $access_result;
    }

    // Default to neutral.
    return AccessResult::neutral();
  }

}

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

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