You are here

function pbf_node_access_records in Permissions by field 8

Implements hook_node_access_records().

All node access modules must implement this hook. If the module is interested in the privacy of the node passed in, return a list of node access values for each grant ID we offer.

File

./pbf.module, line 106
Contains pbf.module.

Code

function pbf_node_access_records(NodeInterface $node) {
  if (!$node
    ->isPublished()) {
    return NULL;
  }

  // Check if a Pbf field is attached to the node.
  $field_definitions = $node
    ->getFieldDefinitions();
  $grants = [];

  /** @var \Drupal\Core\Field\FieldDefinitionInterface $field_definition */
  foreach ($field_definitions as $field_name => $field_definition) {
    if ($field_definition instanceof FieldConfigInterface && $field_definition
      ->getType() == 'pbf') {
      $values = $node->{$field_name}
        ->getValue();
      if (empty($values)) {
        continue;
      }
      $target_entity_type_id = $field_definition
        ->getSetting('target_type');
      $priority = $field_definition
        ->getSetting('priority');
      $user_method = $field_definition
        ->getSetting('user_method');
      switch ($target_entity_type_id) {
        case 'node':
        case 'taxonomy_term':
          foreach ($values as $value) {

            // If node's permissions are set as public, we let standard
            // permissions applied, and so we do not populate a grants array.
            if ($value['grant_public']) {
              continue;
            }
            $grants[] = pbf_create_grant($value, $field_name, $priority);
          }
          break;
        case 'user':
          foreach ($values as $value) {

            // If node's permissions are set as public, we use standard
            // permissions, and so do not populate a grants array.
            if ($value['grant_public']) {
              continue;
            }

            // If the field which reference user grant access directly to this
            // user for this node.
            if ($user_method == 'user') {
              $grants[] = pbf_create_grant($value, PBF_BY_USER_ID, $priority);
            }

            // If the field which reference user grant access to users which
            // reference this user. We grant access to these users who have
            // same Pbf field set on this user.
            if ($user_method == 'ref_user') {
              $grants[] = pbf_create_grant($value, $field_name, $priority);

              // We grant access to the user referenced too.
              $grants[] = pbf_create_grant($value, PBF_BY_USER_ID, $priority);
            }
          }
          break;
        case 'user_role':
          foreach ($values as $value) {

            // If node's permissions are set as public, we use standard
            // permissions, and so do not populate a grants array.
            if ($value['grant_public']) {
              continue;
            }
            $role_ids = \Drupal::config('pbf.settings')
              ->get('pbf_roles_gids');
            if (isset($role_ids[$value['target_id']]) && is_int($role_ids[$value['target_id']])) {

              // Replace the Role target_id (string) by our role id (integer).
              $value['target_id'] = $role_ids[$value['target_id']];
              $grants[] = pbf_create_grant($value, PBF_BY_ROLE_ID, $priority);
            }
          }
          break;
      }
    }
  }

  // If there is some custom permissions then we need to
  // grant access to node's author according to standard permissions defined.
  // Otherwise, standard permissions applied to node
  // and so we return an empty array. We set this realm only if anonymous user
  // is not the node's owner.
  if ($grants && $node
    ->getOwnerId()) {
    $grants[] = array(
      'realm' => 'pbf_author',
      'gid' => $node
        ->getOwnerId(),
      'grant_view' => 1,
      'grant_update' => $node
        ->getOwner()
        ->hasPermission('edit own ' . $node
        ->bundle() . ' content') ? 1 : 0,
      'grant_delete' => $node
        ->getOwner()
        ->hasPermission('delete own ' . $node
        ->bundle() . ' content') ? 1 : 0,
      'priority' => 0,
    );
  }
  return $grants;
}