You are here

function workflow_access_node_access_records in Workflow 8

Same name and namespace in other branches
  1. 5.2 workflow_access.module \workflow_access_node_access_records()
  2. 5 workflow_access.module \workflow_access_node_access_records()
  3. 6.2 workflow_access/workflow_access.module \workflow_access_node_access_records()
  4. 6 workflow_access/workflow_access.module \workflow_access_node_access_records()
  5. 7.2 workflow_access/workflow_access.module \workflow_access_node_access_records()
  6. 7 workflow_access/workflow_access.module \workflow_access_node_access_records()

Implements hook_node_access_records().

Returns a list of grant records for the passed in node object. This hook is invoked by function node_access_acquire_grants().

File

modules/workflow_access/workflow_access.module, line 149
Provides node access permissions based on workflow states.

Code

function workflow_access_node_access_records(NodeInterface $node) {
  $grants = [];

  // Only relevant for content with Workflow.
  if (!($workflow_field_names = workflow_get_workflow_field_names($node, $node
    ->getEntityTypeId()))) {
    return $grants;
  }

  // Create grants for each translation of the node.
  $priority = workflow_access_get_setting('workflow_access_priority');
  foreach ($node
    ->getTranslationLanguages() as $langcode => $language) {
    $translation = $node
      ->getTranslation($langcode);

    // @todo How to handle not published entities?
    // if (!$translation->isPublished()) {
    //   return;
    // }
    // Get 'author' of this entity. Some entities (e.g., taxonomy_term)
    // do not have a uid. But then again: node_access is only for nodes...
    $uid = $translation
      ->getOwnerId() ? (int) $translation
      ->getOwnerId() : 0;
    $workflow_transitions = [];
    if (isset($translation->workflow_transitions)) {
      $workflow_transitions = $translation->workflow_transitions;
    }
    else {

      // Sometimes, a node is saved without going through workflow_transition_form.
      // E.g.,
      // - when saving a node with workflow_node programmatically with node_save();
      // - when changing a state on a node view page/history tab;
      // - when rebuilding permissions via batch for Workflow Fields.
      // In that case, we need to create the workflow_transitions ourselves to
      // calculate the grants.
      foreach ($workflow_field_names as $field_name) {

        // Create a dummy transition, just to set $workflow_transitions.
        $old_sid = $new_sid = $translation->{$field_name}->value;
        if ($old_sid) {

          /** @var \Drupal\workflow\Entity\WorkflowTransitionInterface $transition */
          $transition = WorkflowTransition::create([
            $old_sid,
            'field_name' => $field_name,
          ]);
          $transition
            ->setTargetEntity($translation);
          $transition
            ->setValues($new_sid, $translation
            ->getOwnerId(), \Drupal::time()
            ->getRequestTime(), '');
          $workflow_transitions[$field_name] = $transition;
        }
      }
    }
    $count_workflow_fields = 0;
    foreach ($workflow_transitions as $field_name => $transition) {

      // @todo Add support for multiple workflows per entity.
      if (++$count_workflow_fields > 1) {
        continue;
      }
      if (!($current_sid = workflow_node_current_state($translation, $field_name))) {
        continue;
      }
      foreach (workflow_access_get_workflow_access_by_sid($current_sid) as $rid => $grant) {

        // Anonymous ($uid == 0) author is not allowed for role 'Author' (== -1).
        // Both logically (Anonymous having more rights then authenticated)
        // and technically ($gid must be a positive integer).
        if ($uid == 0 && $rid == WORKFLOW_ROLE_AUTHOR_RID) {
          continue;
        }
        $grants[] = [
          'realm' => $uid > 0 && $rid == WORKFLOW_ROLE_AUTHOR_RID ? 'workflow_access_owner' : 'workflow_access',
          'gid' => $uid > 0 && $rid == WORKFLOW_ROLE_AUTHOR_RID ? $uid : workflow_access_get_role_gid($rid),
          'grant_view' => (int) $grant['grant_view'],
          'grant_update' => (int) $grant['grant_update'],
          'grant_delete' => (int) $grant['grant_delete'],
          'priority' => $priority,
          'langcode' => $langcode,
          'field_name' => $field_name,
        ];
      }
    }
  }
  return $grants;
}