Mercurial > hg > isophonics-drupal-site
diff core/modules/workflows/src/WorkflowStateTransitionOperationsAccessCheck.php @ 18:af1871eacc83
Update to Drupal core 8.7.1
author | Chris Cannam |
---|---|
date | Thu, 09 May 2019 15:33:08 +0100 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/core/modules/workflows/src/WorkflowStateTransitionOperationsAccessCheck.php Thu May 09 15:33:08 2019 +0100 @@ -0,0 +1,84 @@ +<?php + +namespace Drupal\workflows; + +use Drupal\Core\Access\AccessResult; +use Drupal\Core\Routing\Access\AccessInterface; +use Drupal\Core\Routing\RouteMatchInterface; +use Drupal\Core\Session\AccountInterface; + +/** + * Provides an access check for state and transition operations. + */ +class WorkflowStateTransitionOperationsAccessCheck implements AccessInterface { + + /** + * Checks access for operations of workflow states and transitions. + * + * The value of '_workflow_access' is used to check to kind of access that + * should be applied to a route in the context of a workflow and a state or + * transition. States and transitions can individually have access control + * applied to them for 'add', 'update' and 'delete'. By default workflows will + * use the admin permission 'administer workflows' for all of these + * operations, except for delete-state which checks there is at least one + * state, a state does not have data and it's not a required state. + * + * For the update and delete operations, a workflow and a state or transition + * is required in the route for the access check to be applied. For the "add" + * operation, only a workflow is required. The '_workflow_access' requirement + * translates into access checks on the workflow entity type in the formats: + * - @code"$operation-state:$state_id"@endcode + * - @code"$operation-transition:$transition_id"@endcode + * + * For example the following route definition with the path + * "/test-workflow/foo-state/delete" the 'delete-state:foo-state' operation + * will be checked: + * @code + * pattern: '/{workflow}/{workflow_state}/delete' + * requirements: + * _workflow_access: 'delete-state' + * @endcode + * + * @param \Drupal\Core\Routing\RouteMatchInterface $route_match + * The parametrized route + * @param \Drupal\Core\Session\AccountInterface $account + * The currently logged in account. + * + * @return \Drupal\Core\Access\AccessResultInterface + * An access result. + * + * @throws \Exception + * Throws an exception when a route is defined with an invalid operation. + */ + public function access(RouteMatchInterface $route_match, AccountInterface $account) { + $workflow_operation = $this->getOperation($route_match); + if (!preg_match('/^(?<operation>add|update|delete)-(?<type>state|transition)$/', $workflow_operation, $matches)) { + throw new \Exception("Invalid _workflow_access operation '$workflow_operation' specified for route '{$route_match->getRouteName()}'."); + } + + $parameters = $route_match->getParameters(); + $workflow = $parameters->get('workflow'); + if ($workflow && $matches['operation'] === 'add') { + return $workflow->access($workflow_operation, $account, TRUE); + } + if ($workflow && $type = $parameters->get(sprintf('workflow_%s', $matches['type']))) { + return $workflow->access(sprintf('%s:%s', $workflow_operation, $type), $account, TRUE); + } + + return AccessResult::neutral(); + } + + /** + * Get the operation that will be used for the access check + * + * @param \Drupal\Core\Routing\RouteMatchInterface $route_match + * The parametrized route + * + * @return string + * The access operation. + */ + protected function getOperation(RouteMatchInterface $route_match) { + return $route_match->getRouteObject()->getRequirement('_workflow_access'); + } + +}