association-1.0.0-alpha2/src/Plugin/Association/Behavior/EntityManifestBehavior.php

src/Plugin/Association/Behavior/EntityManifestBehavior.php
<?php

namespace Drupal\association\Plugin\Association\Behavior;

use Drupal\association\Attribute\AssociationBehavior;
use Drupal\association\Entity\AssociationInterface;
use Drupal\association\Entity\AssociationTypeInterface;
use Drupal\association\Plugin\BehaviorBase;
use Drupal\association\Plugin\BehaviorInterface;
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Access\AccessResultInterface;
use Drupal\Core\Plugin\PluginWithFormsInterface;
use Drupal\Core\Plugin\PluginWithFormsTrait;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\StringTranslation\TranslatableMarkup;

/**
 * Behavior for managing associations which have a prescriptive entity manifest.
 *
 * Manages Entity Associations that need to maintain the specific counts of
 * entities and bundles allowed. Each entity bundle can have a separate
 * cardinality constraint. This gives a associations a more templated content
 * building experience.
 */
#[AssociationBehavior(
  id: 'entity_manifest',
  label: new TranslatableMarkup('Entity manifest'),
  manager_builder: '\Drupal\association\Behavior\Manager\EntityManifestBuilder',
  forms: [
    'configure' => '\Drupal\association\Behavior\Form\ConfigureManifestBehaviorForm',
  ],
)]
class EntityManifestBehavior extends BehaviorBase implements PluginWithFormsInterface {

  use PluginWithFormsTrait;

  /**
   * {@inheritdoc}
   */
  public function defaultConfiguration() {
    return [
      'manifest' => [],
    ];
  }

  /**
   * {@inheritdoc}
   */
  public function getEntityTypes(): array {
    $allowedTypes = $this->adapterManager->getEntityTypes();
    $manifest = $this->getConfiguration()['manifest'] ?? [];

    $entityTypes = [];
    foreach ($manifest as $tagInfo) {
      foreach ($tagInfo['entity_types'] as $type => $bundles) {
        if (isset($allowedTypes[$type])) {
          $entityTypes[$type] = $type;
        }
      }
    }
    return $entityTypes;
  }

  /**
   * {@inheritdoc}
   */
  public function isValidEntity($tag, $entity_type, $bundle): bool {
    $config = $this->getConfiguration();
    return !empty($config['manifest'][$tag]['entity_types'][$entity_type][$bundle]);
  }

  /**
   * {@inheritdoc}
   */
  public function getTags(): array {
    $manifest = $this->configuration['manifest'] ?? [];

    $tags = [];
    foreach ($manifest as $key => $definition) {
      $tags[$key] = $definition['label'];
    }

    return $tags;
  }

  /**
   * {@inheritdoc}
   */
  public function getTagLabel($tag, $entity_type_id, $bundle) {
    return $this->configuration['manifest'][$tag]['label'] ?? '';
  }

  /**
   * {@inheritdoc}
   */
  public function createAccess(AssociationInterface $association, $tag, $entity_type_id, $bundle, AccountInterface $account): AccessResultInterface {
    if (!$this->isValidEntity($tag, $entity_type_id, $bundle)) {
      return AccessResult::forbidden();
    }

    $definition = $this->getConfiguration()['manifest'][$tag];

    // If not an unlimited number of items, we need to ensure that it's okay
    // to create another new instance of the entity type.
    if ($definition['limit'] !== BehaviorInterface::CARDINALITY_UNLIMITED) {
      $count = $this->entityTypeManager
        ->getStorage('association_link')
        ->getQuery()
        ->accessCheck(FALSE)
        ->condition('association', $association->id())
        ->condition('tag', $tag)
        ->count()
        ->execute();

      return $count < $definition['limit'] ? AccessResult::allowed() : AccessResult::forbidden();
    }

    return AccessResult::allowed();
  }

  /**
   * {@inheritdoc}
   */
  public function validateConfigUpdate(AssociationTypeInterface $assocation_type, array $changes): array {
    $errors = [];
    $current = $this->getConfiguration()['manifest'] ?? [];
    $missing = array_diff_key($current, $changes['manifest']);

    if ($missing) {
      $errors[] = $this->t('Entities have been removed from the manifest after association type has data: @types', [
        '@types' => implode(', ', array_keys($missing)),
      ]);
    }
    else {
      foreach ($current as $tag => $info) {
        $tagChange = $changes['manifest'][$tag];

        if ($info['required'] && !$tagChange['required']) {
          $errors[] = $this->t('Cannot remove required flag for @tag.', [
            '@tag' => $tag,
          ]);
        }

        foreach ($info['entity_types'] as $entityTypeId => $bundles) {
          if (empty($tagChange['entity_types'][$entityTypeId])) {
            $errors[] = $this->t('Entity type of "@entity_type" cannot be removed from @tag', [
              '@entity_type' => $entityTypeId,
              '@tag' => $tag,
            ]);
          }
          elseif ($diff = array_diff($tagChange['entity_types'][$entityTypeId], $bundles)) {
            $errors[] = $this->t('Entity type %entity_type missing bundles "@bundles" from @tag', [
              '%entity_type' => $entityTypeId,
              '@bundles' => implode(', ', $diff),
              '@tag' => $tag,
            ]);
          }
        }

        if (array_keys($tagChange['entity_types']) != array_keys($info['entity_types'])) {
          $errors[] = $this->t('Entity manifest bundle and required properties cannot be changed for @tag', [
            '@tag' => $tag,
          ]);
        }

        if ($tagChange['limit'] < $info['limit']) {
          $errors[] = $this->t('Entity manifest limit cannot be reduced for @tag', [
            '@tag' => $tag,
          ]);
        }
      }
    }

    return $errors;
  }

}

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

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