access_by_ref.module in Access by Reference 8
File
access_by_ref.module
View source
<?php
use Drupal\node\NodeInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\user\Entity\User;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Routing\Access\AccessInterface;
use Drupal\Core\Entity;
function haveNodeAccess($target_id, $op, $account) {
$target_node = \Drupal::service('entity_type.manager')
->getStorage('node')
->load($target_id);
if (isset($target_node) && $target_node
->access($op) == 1) {
return $target_node;
}
else {
return false;
}
}
function access_by_ref_node_access(NodeInterface $node, $op, AccountInterface $account) {
if (!isset($account) || $op != 'update' || $account
->id() == 0 || !isset($node) || $account
->id() == $node
->getOwner()
->id() || !$account
->hasPermission('access node by reference')) {
return AccessResult::neutral();
}
$configs = access_by_ref_get_config($node);
$control_entity = $node;
foreach ($configs as $config) {
$field = $config['node_field'];
$extra = $config['reference_data'];
$vals = $node->{$field}
->getValue();
$grant_access = false;
switch ($config['reference_type']) {
case 'user':
$uid = \Drupal::currentUser()
->id();
foreach ($vals as $value) {
if ($value['target_id'] == $uid) {
$control_entity = \Drupal::currentUser();
$grant_access = true;
}
}
break;
case 'user_mail':
$umail = \Drupal::currentUser()
->getEmail();
foreach ($vals as $value) {
if (strcasecmp($value['value'], $umail) == 0) {
$control_entity = User::load(\Drupal::currentUser());
$grant_access = true;
break;
}
}
break;
case 'shared':
$user = User::load(\Drupal::currentUser()
->id());
$ufield = $config['reference_data'];
$uvals = $user
->get($ufield)
->getValue();
foreach ($vals as $value) {
foreach ($uvals as $uvalue) {
if ($value['value'] == $uvalue['value']) {
$control_entity = $user;
$grant_access = true;
break;
}
}
}
break;
case 'inherit':
$handler = $node->{$field}
->getFieldDefinition()
->getSetting('handler');
switch ($handler) {
case 'default:node':
foreach ($vals as $value) {
$target = $value['target_id'];
if ($control_entity = haveNodeAccess($target, $op, $account)) {
$grant_access = true;
break;
}
}
break;
case 'default:paragraph':
foreach ($vals as $value) {
$target = $value['target_id'];
$paragraph = \Drupal\paragraphs\Entity\Paragraph::load($target);
$parvals = $paragraph->{$extra}
->getValue();
foreach ($parvals as $target) {
if ($control_entity = haveNodeAccess($target, $op, $account)) {
$grant_access = true;
break;
}
}
}
break;
}
break;
case 'manage_referenced':
$nids = access_by_ref_get_overlords($node, $config['node_field']);
foreach ($nids as $nid) {
if ($control_entity = haveNodeAccess($nid, $op, $account)) {
$grant_access = true;
break;
}
}
break;
case 'secret':
if (!isset($_GET[$field])) {
break;
}
foreach ($vals as $value) {
if ($_GET[$field] == $value['value']) {
$grant_access = true;
break;
}
}
break;
}
if ($grant_access) {
return AccessResult::allowed()
->cachePerPermissions()
->cachePerUser()
->addCacheableDependency($control_entity);
}
}
return AccessResult::neutral()
->cachePerPermissions()
->addCacheableDependency($control_entity);
}
function access_by_ref_get_config(NodeInterface $node) {
$my_type = $node
->getType();
$sql = 'SELECT * FROM {access_by_ref} WHERE `node_type` = :ntype';
$result = \Drupal::database()
->query($sql, array(
':ntype' => $my_type,
));
$rows = array();
while ($row = $result
->fetchAssoc()) {
$rows[] = $row;
}
return $rows;
}
function access_by_ref_get_overlords(NodeInterface $node, $overfield) {
$table = "node__{$overfield}";
$targetfield = $overfield . "_target_id";
$parms = array(
':nid' => $node
->id(),
':ntype' => $node
->getType(),
);
$sql = "SELECT entity_id FROM {$table} WHERE {$targetfield} = :nid AND bundle = :ntype";
$rows = array();
$result = \Drupal::database()
->query($sql, $parms);
while ($row = $result
->fetchAssoc()) {
$rows[] = $row['entity_id'];
}
return $rows;
}
function access_by_ref_entity_presave(EntityInterface $entity) {
}