View source
<?php
declare (strict_types=1);
namespace Drupal\scheduled_transitions;
use Drupal\content_moderation\ModerationInformationInterface;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
use Drupal\Core\Entity\ContentEntityType;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Entity\TranslatableInterface;
use Drupal\scheduled_transitions\Form\Entity\ScheduledTransitionAddForm;
use Drupal\scheduled_transitions\Form\ScheduledTransitionForm;
use Drupal\scheduled_transitions\Form\ScheduledTransitionsSettingsForm as SettingsForm;
use Drupal\scheduled_transitions\Routing\ScheduledTransitionsRouteProvider;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Access\AccessResultInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\scheduled_transitions\ScheduledTransitionsPermissions as Permissions;
class ScheduledTransitionsEntityHooks implements ContainerInjectionInterface {
protected $configFactory;
protected $entityTypeManager;
protected $moderatedEntityTypes;
protected $moderationInformation;
public function __construct(ConfigFactoryInterface $configFactory, EntityTypeManagerInterface $entityTypeManager, ModerationInformationInterface $moderationInformation) {
$this->configFactory = $configFactory;
$this->entityTypeManager = $entityTypeManager;
$this->moderationInformation = $moderationInformation;
}
public static function create(ContainerInterface $container) {
return new static($container
->get('config.factory'), $container
->get('entity_type.manager'), $container
->get('content_moderation.moderation_information'));
}
public function entityTypeBuild(array &$entityTypes) : void {
foreach ($entityTypes as $entityType) {
if (!$entityType
->hasLinkTemplate('canonical') || !$entityType instanceof ContentEntityType) {
continue;
}
if ($entityType
->id() === 'scheduled_transition') {
continue;
}
$routeProviders = $entityType
->getRouteProviderClasses() ?: [];
$routeProviders['scheduled_transitions'] = ScheduledTransitionsRouteProvider::class;
$entityType
->setHandlerClass('route_provider', $routeProviders);
$canonicalPath = $entityType
->getLinkTemplate('canonical');
$entityType
->setFormClass(ScheduledTransitionsRouteProvider::FORM, ScheduledTransitionForm::class)
->setLinkTemplate(ScheduledTransitionsRouteProvider::LINK_TEMPLATE, $canonicalPath . ScheduledTransitionsRouteProvider::CANONICAL_PATH_SUFFIX);
$entityType
->setFormClass(ScheduledTransitionsRouteProvider::FORM_ADD, ScheduledTransitionAddForm::class)
->setLinkTemplate(ScheduledTransitionsRouteProvider::LINK_TEMPLATE_ADD, $canonicalPath . ScheduledTransitionsRouteProvider::CANONICAL_PATH_SUFFIX_ADD);
}
}
public function entityDelete(EntityInterface $entity) : void {
$transitionStorage = $this->entityTypeManager
->getStorage('scheduled_transition');
$transitionsForEntity = $this
->loadByHostEntity($entity);
$transitionStorage
->delete($transitionsForEntity);
}
public function entityRevisionDelete(EntityInterface $entity) : void {
$transitionStorage = $this->entityTypeManager
->getStorage('scheduled_transition');
$transitionsForEntity = $this
->loadByHostEntity($entity, TRUE);
$transitionStorage
->delete($transitionsForEntity);
}
public function entityAccess(EntityInterface $entity, string $operation, AccountInterface $account) : AccessResultInterface {
$access = AccessResult::neutral();
if ($operation === Permissions::ENTITY_OPERATION_VIEW_TRANSITIONS) {
$access
->cachePerPermissions();
$permission = Permissions::viewScheduledTransitionsPermission($entity
->getEntityTypeId(), $entity
->bundle());
if ($account
->hasPermission($permission)) {
$access
->addCacheTags([
SettingsForm::SETTINGS_TAG,
]);
$mirrorOperation = $this
->mirrorOperations('view scheduled transition');
if (isset($mirrorOperation)) {
$access = $access
->orIf($entity
->access($mirrorOperation, $account, TRUE));
}
}
else {
$access = $access
->andIf(AccessResult::forbidden("The '{$permission}' permission is required."));
}
}
elseif ($operation === Permissions::ENTITY_OPERATION_ADD_TRANSITION) {
$access
->cachePerPermissions();
$permission = Permissions::addScheduledTransitionsPermission($entity
->getEntityTypeId(), $entity
->bundle());
if ($account
->hasPermission($permission)) {
$access
->addCacheTags([
SettingsForm::SETTINGS_TAG,
]);
$mirrorOperation = $this
->mirrorOperations('add scheduled transition');
if (isset($mirrorOperation)) {
$access = $access
->orIf($entity
->access($mirrorOperation, $account, TRUE));
}
}
else {
$access = $access
->andIf(AccessResult::forbidden("The '{$permission}' permission is required."));
}
}
if ($operation === Permissions::ENTITY_OPERATION_RESCHEDULE_TRANSITIONS) {
$access
->cachePerPermissions();
$permission = Permissions::rescheduleScheduledTransitionsPermission($entity
->getEntityTypeId(), $entity
->bundle());
if ($account
->hasPermission($permission)) {
$access
->addCacheTags([
SettingsForm::SETTINGS_TAG,
]);
$mirrorOperation = $this
->mirrorOperations('reschedule scheduled transitions');
if (isset($mirrorOperation)) {
$access = $access
->orIf($entity
->access($mirrorOperation, $account, TRUE));
}
}
else {
$access = $access
->andIf(AccessResult::forbidden("The '{$permission}' permission is required."));
}
}
return $access;
}
protected function mirrorOperations(string $operation) : ?string {
$mirrorOperation = $this->configFactory
->get('scheduled_transitions.settings')
->get('mirror_operations.' . $operation);
return is_string($mirrorOperation) ? $mirrorOperation : NULL;
}
protected function loadByHostEntity(EntityInterface $entity, bool $revision_match = FALSE) : array {
$transitionStorage = $this->entityTypeManager
->getStorage('scheduled_transition');
$query = $transitionStorage
->getQuery()
->condition('entity.target_id', $entity
->id())
->condition('entity.target_type', $entity
->getEntityTypeId())
->accessCheck(FALSE);
if ($revision_match) {
$query
->condition('entity_revision_id', $entity
->getRevisionId());
}
if ($entity instanceof TranslatableInterface && !$entity
->isDefaultTranslation()) {
$query
->condition('entity_revision_langcode', $entity
->language()
->getId());
}
$ids = $query
->execute();
return $transitionStorage
->loadMultiple($ids);
}
}