workflow_participants-8.x-2.x-dev/src/StateTransitionValidation.php
src/StateTransitionValidation.php
<?php namespace Drupal\workflow_participants; use Drupal\content_moderation\ModerationInformationInterface; use Drupal\content_moderation\StateTransitionValidationInterface; use Drupal\Core\Entity\ContentEntityInterface; use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\Core\Session\AccountInterface; use Drupal\workflows\StateInterface; use Drupal\workflows\TransitionInterface; use Drupal\workflows\WorkflowInterface; /** * Decorated state transition validation service. * * This overrides the base class to allow for access to transitions for * workflow participants. */ class StateTransitionValidation implements StateTransitionValidationInterface { /** * The entity type manager. * * @var \Drupal\Core\Entity\EntityTypeManagerInterface */ protected $entityTypeManager; /** * The decorated service. * * @var \Drupal\content_moderation\StateTransitionValidationInterface */ protected $inner; /** * The moderation information service. * * @var \Drupal\content_moderation\ModerationInformationInterface */ protected $moderationInformation; /** * Constructs the state transition validator. * * Since this is extending the decorated service, no inner service is needed. * * @param \Drupal\content_moderation\StateTransitionValidationInterface $inner * The inner service. * @param \Drupal\content_moderation\ModerationInformationInterface $moderation_information * The moderation information service. * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager * The entity type manager service. */ public function __construct(StateTransitionValidationInterface $inner, ModerationInformationInterface $moderation_information, EntityTypeManagerInterface $entity_type_manager) { $this->inner = $inner; $this->moderationInformation = $moderation_information; $this->entityTypeManager = $entity_type_manager; } /** * {@inheritdoc} */ public function getValidTransitions(ContentEntityInterface $entity, AccountInterface $user) { $transitions = $this->inner->getValidTransitions($entity, $user); // In addition to those granted by content moderation, check for transitions // that allow editor/reviewer transitions. return $transitions + $this->getParticipantTransitions($entity, $user); } /** * Get valid transitions for editors and reviewers. * * @param \Drupal\Core\Entity\ContentEntityInterface $entity * The moderated entity. * @param \Drupal\Core\Session\AccountInterface $account * The current authenticated user. * * @return \Drupal\workflows\TransitionInterface[] * The allowed state transitions. */ protected function getParticipantTransitions(ContentEntityInterface $entity, AccountInterface $account) { if (!$entity->id()) { return []; } // This logic is copied from // Drupal\content_moderation\StateTransitionValidation::getValidTransitions. $workflow = $this->moderationInformation->getWorkflowForEntity($entity); $current_state = $entity->moderation_state->value ? $workflow->getTypePlugin()->getState($entity->moderation_state->value) : $workflow->getTypePlugin()->getInitialState($entity); // Legal transitions include those that are possible from the current state, // filtered by those whose target is legal on this bundle and that the // user has access to execute. $participants = $this->entityTypeManager->getStorage('workflow_participants')->loadForModeratedEntity($entity); $transitions = array_filter($current_state->getTransitions(), function (TransitionInterface $transition) use ($workflow, $participants, $account) { return $participants->userMayTransition($workflow, $transition, $account); }); return $transitions; } /** * {@inheritdoc} */ public function isTransitionValid(WorkflowInterface $workflow, StateInterface $original_state, StateInterface $new_state, AccountInterface $user, ContentEntityInterface $entity = NULL) { // We can only make a determination if we have the entity, otherwise we // won't be able to reference the participants. if ($entity) { // As this may be occurring during validation, the moderation state on the // entity may be the new state, rather than the current state, so make // sure we're working with the current version. $original_entity = $entity->isNew() ? $entity : $this->entityTypeManager->getStorage($entity->getEntityTypeId())->loadRevision($entity->getLoadedRevisionId()); $transition = $workflow->getTypePlugin()->getTransitionFromStateToState($original_state->id(), $new_state->id()); return in_array($transition->id(), array_keys($this->getValidTransitions($original_entity, $user))); } return FALSE; } }