Chris@18
|
1 <?php
|
Chris@18
|
2
|
Chris@18
|
3 namespace Drupal\workflows;
|
Chris@18
|
4
|
Chris@18
|
5 use Drupal\Core\Access\AccessResult;
|
Chris@18
|
6 use Drupal\Core\Routing\Access\AccessInterface;
|
Chris@18
|
7 use Drupal\Core\Routing\RouteMatchInterface;
|
Chris@18
|
8 use Drupal\Core\Session\AccountInterface;
|
Chris@18
|
9
|
Chris@18
|
10 /**
|
Chris@18
|
11 * Provides an access check for state and transition operations.
|
Chris@18
|
12 */
|
Chris@18
|
13 class WorkflowStateTransitionOperationsAccessCheck implements AccessInterface {
|
Chris@18
|
14
|
Chris@18
|
15 /**
|
Chris@18
|
16 * Checks access for operations of workflow states and transitions.
|
Chris@18
|
17 *
|
Chris@18
|
18 * The value of '_workflow_access' is used to check to kind of access that
|
Chris@18
|
19 * should be applied to a route in the context of a workflow and a state or
|
Chris@18
|
20 * transition. States and transitions can individually have access control
|
Chris@18
|
21 * applied to them for 'add', 'update' and 'delete'. By default workflows will
|
Chris@18
|
22 * use the admin permission 'administer workflows' for all of these
|
Chris@18
|
23 * operations, except for delete-state which checks there is at least one
|
Chris@18
|
24 * state, a state does not have data and it's not a required state.
|
Chris@18
|
25 *
|
Chris@18
|
26 * For the update and delete operations, a workflow and a state or transition
|
Chris@18
|
27 * is required in the route for the access check to be applied. For the "add"
|
Chris@18
|
28 * operation, only a workflow is required. The '_workflow_access' requirement
|
Chris@18
|
29 * translates into access checks on the workflow entity type in the formats:
|
Chris@18
|
30 * - @code"$operation-state:$state_id"@endcode
|
Chris@18
|
31 * - @code"$operation-transition:$transition_id"@endcode
|
Chris@18
|
32 *
|
Chris@18
|
33 * For example the following route definition with the path
|
Chris@18
|
34 * "/test-workflow/foo-state/delete" the 'delete-state:foo-state' operation
|
Chris@18
|
35 * will be checked:
|
Chris@18
|
36 * @code
|
Chris@18
|
37 * pattern: '/{workflow}/{workflow_state}/delete'
|
Chris@18
|
38 * requirements:
|
Chris@18
|
39 * _workflow_access: 'delete-state'
|
Chris@18
|
40 * @endcode
|
Chris@18
|
41 *
|
Chris@18
|
42 * @param \Drupal\Core\Routing\RouteMatchInterface $route_match
|
Chris@18
|
43 * The parametrized route
|
Chris@18
|
44 * @param \Drupal\Core\Session\AccountInterface $account
|
Chris@18
|
45 * The currently logged in account.
|
Chris@18
|
46 *
|
Chris@18
|
47 * @return \Drupal\Core\Access\AccessResultInterface
|
Chris@18
|
48 * An access result.
|
Chris@18
|
49 *
|
Chris@18
|
50 * @throws \Exception
|
Chris@18
|
51 * Throws an exception when a route is defined with an invalid operation.
|
Chris@18
|
52 */
|
Chris@18
|
53 public function access(RouteMatchInterface $route_match, AccountInterface $account) {
|
Chris@18
|
54 $workflow_operation = $this->getOperation($route_match);
|
Chris@18
|
55 if (!preg_match('/^(?<operation>add|update|delete)-(?<type>state|transition)$/', $workflow_operation, $matches)) {
|
Chris@18
|
56 throw new \Exception("Invalid _workflow_access operation '$workflow_operation' specified for route '{$route_match->getRouteName()}'.");
|
Chris@18
|
57 }
|
Chris@18
|
58
|
Chris@18
|
59 $parameters = $route_match->getParameters();
|
Chris@18
|
60 $workflow = $parameters->get('workflow');
|
Chris@18
|
61 if ($workflow && $matches['operation'] === 'add') {
|
Chris@18
|
62 return $workflow->access($workflow_operation, $account, TRUE);
|
Chris@18
|
63 }
|
Chris@18
|
64 if ($workflow && $type = $parameters->get(sprintf('workflow_%s', $matches['type']))) {
|
Chris@18
|
65 return $workflow->access(sprintf('%s:%s', $workflow_operation, $type), $account, TRUE);
|
Chris@18
|
66 }
|
Chris@18
|
67
|
Chris@18
|
68 return AccessResult::neutral();
|
Chris@18
|
69 }
|
Chris@18
|
70
|
Chris@18
|
71 /**
|
Chris@18
|
72 * Get the operation that will be used for the access check
|
Chris@18
|
73 *
|
Chris@18
|
74 * @param \Drupal\Core\Routing\RouteMatchInterface $route_match
|
Chris@18
|
75 * The parametrized route
|
Chris@18
|
76 *
|
Chris@18
|
77 * @return string
|
Chris@18
|
78 * The access operation.
|
Chris@18
|
79 */
|
Chris@18
|
80 protected function getOperation(RouteMatchInterface $route_match) {
|
Chris@18
|
81 return $route_match->getRouteObject()->getRequirement('_workflow_access');
|
Chris@18
|
82 }
|
Chris@18
|
83
|
Chris@18
|
84 }
|