You are here

public function WorkflowAccessControlHandler::access in Workflow 8

Checks access to an operation on a given entity or entity translation.

Use \Drupal\Core\Entity\EntityAccessControlHandlerInterface::createAccess() to check access to create an entity.

Parameters

\Drupal\Core\Entity\EntityInterface $entity: The entity for which to check access.

string $operation: The operation access should be checked for. Usually one of "view", "view label", "update" or "delete".

\Drupal\Core\Session\AccountInterface $account: (optional) The user session for which to check access, or NULL to check access for the current user. Defaults to NULL.

bool $return_as_object: (optional) Defaults to FALSE.

Return value

bool|\Drupal\Core\Access\AccessResultInterface The access result. Returns a boolean if $return_as_object is FALSE (this is the default) and otherwise an AccessResultInterface object. When a boolean is returned, the result of AccessInterface::isAllowed() is returned, i.e. TRUE means access is explicitly allowed, FALSE means access is either explicitly forbidden or "no opinion".

Overrides EntityAccessControlHandler::access

File

src/WorkflowAccessControlHandler.php, line 46

Class

WorkflowAccessControlHandler
Defines the access control handler for the workflow entity type.

Namespace

Drupal\workflow

Code

public function access(EntityInterface $entity, $operation, AccountInterface $account = NULL, $return_as_object = FALSE) {
  $account = workflow_current_user($account);
  $result = parent::access($entity, $operation, $account, TRUE);

  // Only for Edit/Delete transition. For Add/create, use createAccess.
  switch ($entity
    ->getEntityTypeId()) {
    case 'workflow_scheduled_transition':
      switch ($operation) {
        case 'update':

          // This operation is not defined for Scheduled Transitions.
          $result = AccessResult::forbidden();
          break;
        case 'delete':

          // This operation is not defined for Scheduled Transitions.
          $result = AccessResult::forbidden();
          break;
        case 'revert':

          // This operation is not defined for Scheduled Transitions.
          $result = AccessResult::forbidden();
          break;
        default:
          $result = parent::access($entity, $operation, $account, TRUE);
          break;
      }
      break;
    case 'workflow_transition':

      /** @var \Drupal\workflow\Entity\WorkflowTransitionInterface $transition */
      $transition = $entity;
      $is_owner = WorkflowManager::isOwner($account, $transition);
      $type_id = $transition
        ->getWorkflowId();
      switch ($operation) {
        case 'update':
          if ($account
            ->hasPermission("bypass {$type_id} workflow_transition access")) {
            $result = AccessResult::allowed()
              ->cachePerPermissions();
          }
          elseif ($account
            ->hasPermission("edit any {$type_id} workflow_transition")) {
            $result = AccessResult::allowed()
              ->cachePerPermissions();
          }
          elseif ($is_owner && $account
            ->hasPermission("edit own {$type_id} workflow_transition")) {
            $result = AccessResult::allowed()
              ->cachePerPermissions();
          }
          return $return_as_object ? $result : $result
            ->isAllowed();
        case 'delete':

          // The delete operation is not defined for Transitions.
          $result = AccessResult::forbidden();
          break;
        case 'revert':
          if (!$transition
            ->isRevertable()) {

            // No access for same state transitions.
            $result = AccessResult::forbidden();
          }
          elseif ($account
            ->hasPermission("revert any {$type_id} workflow_transition")) {

            // OK, add operation.
            $result = AccessResult::allowed();
          }
          elseif ($is_owner && $account
            ->hasPermission("revert own {$type_id} workflow_transition")) {

            // OK, add operation.
            $result = AccessResult::allowed();
          }
          else {

            // No access.
            $result = AccessResult::forbidden();
          }
          if ($result == AccessResult::allowed()) {

            // Ask other modules if the reversion is allowed.
            // Reversing old and new sid!
            $permitted = \Drupal::moduleHandler()
              ->invokeAll('workflow', [
              'transition revert',
              $transition,
              $account,
            ]);

            // Remove access if it is vetoed by other module.
            if (in_array(FALSE, $permitted, TRUE)) {
              $result = AccessResult::forbidden();
            }
          }
          break;
        default:
          $result = parent::access($entity, $operation, $account, TRUE);
          break;
      }
      break;
    case 'workflow_config_transition':

      // This is not (yet) configured.
      break;
    case 'workflow_state':
      switch ($operation) {
        case 'view label':

          // The following two lines are copied from below, and need to be reviewed carefully.
          $result = AccessResult::allowed();
          return $return_as_object ? $result : $result
            ->isAllowed();
        default:

          // E.g., operation 'update' on the WorkflowStates config page.
          break;
      }
      break;
  }
  $result = $result
    ->cachePerPermissions();
  return $return_as_object ? $result : $result
    ->isAllowed();
}