diff -u b/src/Plugin/Derivative/WorkflowLocalTask.php b/src/Plugin/Derivative/WorkflowLocalTask.php --- b/src/Plugin/Derivative/WorkflowLocalTask.php +++ b/src/Plugin/Derivative/WorkflowLocalTask.php @@ -60,10 +60,10 @@ $entity_types = $workflowManager->listWorkflowFieldsByEntities(); foreach ($entity_types as $entity_type_id => $fields) { - $this->derivatives["$entity_type_id.workflow"] = [ - 'route_name' => "entity.$entity_type_id.workflow", - 'title' => $this->t('Definition'), - 'base_route' => "entity.$entity_type_id.edit_form", + $this->derivatives["entity.$entity_type_id.workflow_history"] = [ + 'route_name' => "entity.$entity_type_id.workflow_history", + 'title' => $this->t('Workflow'), + 'base_route' => "entity.$entity_type_id.canonical", 'weight' => 100, ]; } diff -u b/src/Routing/RouteSubscriber.php b/src/Routing/RouteSubscriber.php --- b/src/Routing/RouteSubscriber.php +++ b/src/Routing/RouteSubscriber.php @@ -90,7 +90,7 @@ '_title' => 'Workflow history', ], [ - '_custom_access' => '\Drupal\workflow\Controller\WorkflowTransitionListController::historyAccess', + '_custom_access' => '\Drupal\workflow\Access\WorkflowHistoryAccess::access', ], [ '_admin_route' => TRUE, only in patch2: unchanged: --- /dev/null +++ b/src/Access/WorkflowHistoryAccess.php @@ -0,0 +1,80 @@ +id() : -1; + + $entity_type = $route->getOption('_workflow_entity_type_id'); + $entity = $routeMatch->getParameter($entity_type); + + $entity_id = $entity->id(); + $entity_bundle = $entity->bundle(); + $field_name = $routeMatch->getParameter('field_name'); + + if (isset($access[$uid][$entity_type][$entity_id][$field_name ? $field_name : 'no_field'])) { + return $access[$uid][$entity_type][$entity_id][$field_name ? $field_name : 'no_field']; + } + + $access_result = AccessResult::forbidden(); + + // When having multiple workflows per bundle, use Views display + // 'Workflow history per entity' instead! + $fields = _workflow_info_fields($entity, $entity_type, $entity_bundle, $field_name); + if (!$fields) { + return AccessResult::forbidden(); + } + + // @todo: Keep below code aligned between WorkflowState, ~Transition, ~TransitionListController + // Determine if user is owner of the entity. + $is_owner = WorkflowManager::isOwner($account, $entity); + + /* + * Determine if user has Access. Fill the cache. + */ + // @todo: what to do with multiple workflow_fields per bundle? Use Views instead! Or introduce a setting. + // @todo D8-port: workflow_tab_access: use proper 'WORKFLOW_TYPE' permissions + foreach ($fields as $definition) { + $type_id = $definition->getSetting('workflow_type'); + if ($account->hasPermission("access any $type_id workflow_transion overview")) { + $access_result = AccessResult::allowed(); + } + elseif ($is_owner && $account->hasPermission("access own $type_id workflow_transion overview")) { + $access_result = AccessResult::allowed(); + } + elseif ($account->hasPermission('administer nodes')) { + $access_result = AccessResult::allowed(); + } + $access[$uid][$entity_type][$entity_id][$field_name ? $field_name : 'no_field'] = $access_result; + } + + return $access_result; + } +} \ No newline at end of file only in patch2: unchanged: --- a/src/Controller/WorkflowTransitionListController.php +++ b/src/Controller/WorkflowTransitionListController.php @@ -58,7 +58,7 @@ class WorkflowTransitionListController extends EntityListController implements C /** * Generates an overview table of older revisions of a node, - * but only if this::historyAccess() allows it. + * but only if WorkflowHistoryAccess::access() allows it. * * @param EntityInterface $node * A node object. @@ -137,77 +137,4 @@ class WorkflowTransitionListController extends EntityListController implements C return $form; } - /** - * Menu access control callback. Checks access to Workflow tab. - * - * This used to be D7-function workflow_tab_access($user, $entity). - * - * The History tab should not be used with multiple workflows per entity. - * Use the dedicated view for this use case. - * @todo D8: remove this in favour of View 'Workflow history per entity'. - * @todo D8-port: make this workflow for non-Node entity types. - * - * @param \Drupal\Core\Session\AccountInterface $account - * Run access checks for this account. - * - * @return \Drupal\Core\Access\AccessResult - */ - public function historyAccess(AccountInterface $account) { - static $access = []; - - $uid = ($account) ? $account->id() : -1; - - // @todo D8-port: make Workflow History tab happen for every entity_type. - // @see workflow.routing.yml, workflow.links.task.yml, WorkflowTransitionListController. - // ATM it only works for Nodes and Terms. - // This is a hack. The Route should always pass an object. - // On view tab, $entity is object, - // On workflow tab, $entity is id(). - // Get the entity for this form. - $entity = workflow_url_get_entity(); - - /* @var $entity EntityInterface */ - // Figure out the $entity's bundle and id. - $entity_type = $entity->getEntityTypeId(); - $entity_bundle = $entity->bundle(); - $entity_id = ($entity) ? $entity->id() : ''; - $field_name = workflow_url_get_field_name(); - - if (isset($access[$uid][$entity_type][$entity_id][$field_name ? $field_name : 'no_field'])) { - return $access[$uid][$entity_type][$entity_id][$field_name ? $field_name : 'no_field']; - } - - $access_result = AccessResult::forbidden(); - - // When having multiple workflows per bundle, use Views display - // 'Workflow history per entity' instead! - $fields = _workflow_info_fields($entity, $entity_type, $entity_bundle, $field_name); - if (!$fields) { - return AccessResult::forbidden(); - } - - // @todo: Keep below code aligned between WorkflowState, ~Transition, ~TransitionListController - // Determine if user is owner of the entity. - $is_owner = WorkflowManager::isOwner($account, $entity); - /** - * Determine if user has Access. Fill the cache. - */ - // @todo: what to do with multiple workflow_fields per bundle? Use Views instead! Or introduce a setting. - // @todo D8-port: workflow_tab_access: use proper 'WORKFLOW_TYPE' permissions - foreach ($fields as $definition) { - $type_id = $definition->getSetting('workflow_type'); - if ($account->hasPermission("access any $type_id workflow_transion overview")) { - $access_result = AccessResult::allowed(); - } - elseif ($is_owner && $account->hasPermission("access own $type_id workflow_transion overview")) { - $access_result = AccessResult::allowed(); - } - elseif ($account->hasPermission('administer nodes')) { - $access_result = AccessResult::allowed(); - } - $access[$uid][$entity_type][$entity_id][$field_name ? $field_name : 'no_field'] = $access_result; - } - return $access_result; - } - } only in patch2: unchanged: --- a/workflow.module +++ b/workflow.module @@ -545,38 +545,22 @@ function workflow_url_get_entity(\Drupal\Core\Entity\EntityInterface $entity = N return $entity; } - // @todo: get entity for any route. - $entity_type = 'node'; - $value = workflow_url_get_parameter($entity_type); - if ($value && is_object($value)) { - return $value; - } - if ($value && !is_object($value)) { - // On workflow tab, we'd get an id. - // This is an indicator that the route is mal-configured. - workflow_debug(__FILE__, __FUNCTION__, __LINE__, 'route declaration is not optimal.'); - $entity = \Drupal::entityTypeManager()->getStorage($entity_type)->load($value); - return $entity; - } + $routeMatch = \Drupal::routeMatch(); + $route = $routeMatch->getRouteObject(); + $entity_type = $route->getOption('_workflow_entity_type_id'); - // It was not a Node, try a Term. - // On term pages, we get objects, or id's. - $entity_type = 'taxonomy_term'; $value = workflow_url_get_parameter($entity_type); if ($value && is_object($value)) { return $value; } if ($value && !is_object($value)) { + // On workflow tab, we'd get an id. // This is an indicator that the route is mal-configured. workflow_debug(__FILE__, __FUNCTION__, __LINE__, 'route declaration is not optimal.'); $entity = \Drupal::entityTypeManager()->getStorage($entity_type)->load($value); return $entity; } - if (!$value) { - // We may be on a entity add page/ - // Or we may be on a page of some unknown entity. - } return $value; }