diff --git a/core/modules/workflows/src/WorkflowDeleteAccessCheck.php b/core/modules/workflows/src/WorkflowDeleteAccessCheck.php new file mode 100644 index 0000000000..a93e0eb376 --- /dev/null +++ b/core/modules/workflows/src/WorkflowDeleteAccessCheck.php @@ -0,0 +1,49 @@ +getRouteObject()->getRequirement('_workflow_access'); + $workflow_operation = $this->getOperation($route_match); if (!preg_match('/^(?add|update|delete)-(?state|transition)$/', $workflow_operation, $matches)) { throw new \Exception("Invalid _workflow_access operation '$workflow_operation' specified for route '{$route_match->getRouteName()}'."); } @@ -68,4 +68,17 @@ public function access(RouteMatchInterface $route_match, AccountInterface $accou 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'); + } + } diff --git a/core/modules/workflows/tests/src/Unit/WorkflowStateTransitionOperationsAccessCheckTest.php b/core/modules/workflows/tests/src/Unit/WorkflowStateTransitionOperationsAccessCheckTest.php index 33b369fa2e..9aa06abaf3 100644 --- a/core/modules/workflows/tests/src/Unit/WorkflowStateTransitionOperationsAccessCheckTest.php +++ b/core/modules/workflows/tests/src/Unit/WorkflowStateTransitionOperationsAccessCheckTest.php @@ -6,6 +6,7 @@ use Drupal\Core\Routing\RouteMatch; use Drupal\Core\Session\AccountInterface; use Drupal\Tests\UnitTestCase; +use Drupal\workflows\WorkflowDeleteAccessCheck; use Drupal\workflows\WorkflowStateTransitionOperationsAccessCheck; use Drupal\workflows\WorkflowInterface; use Prophecy\Argument; @@ -145,4 +146,33 @@ public function invalidOperationNameTestCases() { ]; } + /** + * @covers \Drupal\workflows\WorkflowDeleteAccessCheck::access + * @expectedDeprecation Using the _workflow_state_delete_access check is deprecated in Drupal 8.6.0 and will be removed before Drupal 9.0.0, use _workflow_access instead. As an internal API _workflow_state_delete_access may also be removed in a minor release. + * @group legacy + */ + public function testLegacyWorkflowStateDeleteAccessCheck() { + $workflow_entity_access_result = AccessResult::allowed(); + + // When using the legacy access check, passing a route with a state called + // 'foo-state' will result in an entity access check of + // 'delete-state:foo-state'. + $workflow = $this->prophesize(WorkflowInterface::class); + $workflow->access('delete-state:foo-state', Argument::type(AccountInterface::class), TRUE) + ->shouldBeCalled() + ->willReturn($workflow_entity_access_result); + + $route = new Route(NULL, [ + 'workflow' => NULL, + 'workflow_state' => NULL, + ], ['_workflow_state_delete_access' => 'true']); + $route_match = new RouteMatch(NULL, $route, [ + 'workflow' => $workflow->reveal(), + 'workflow_state' => 'foo-state', + ]); + + $access_check = new WorkflowDeleteAccessCheck(); + $this->assertEquals($workflow_entity_access_result, $access_check->access($route_match, $this->prophesize(AccountInterface::class)->reveal())); + } + } diff --git a/core/modules/workflows/workflows.services.yml b/core/modules/workflows/workflows.services.yml index 14271afbf0..c6e60afe0a 100644 --- a/core/modules/workflows/workflows.services.yml +++ b/core/modules/workflows/workflows.services.yml @@ -8,3 +8,7 @@ services: class: \Drupal\workflows\WorkflowStateTransitionOperationsAccessCheck tags: - { name: access_check, applies_to: _workflow_access } + workflows.access_check.delete_state: + class: \Drupal\workflows\WorkflowDeleteAccessCheck + tags: + - { name: access_check, applies_to: _workflow_state_delete_access }