NodeTypeAccessService.php in Nodetype access 8
File
src/NodeTypeAccessService.php
View source
<?php
namespace Drupal\nodetype_access;
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Database\Query\AlterableInterface;
use Drupal\Core\Database\Query\SelectInterface;
use Drupal\Core\Entity\EntityTypeBundleInfoInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\node\NodeInterface;
class NodeTypeAccessService {
protected $entityTypeBundleInfo;
public function __construct(EntityTypeBundleInfoInterface $entityTypeBundleInfo) {
$this->entityTypeBundleInfo = $entityTypeBundleInfo;
}
protected function makeViewAnyPermissionId($bundleId) {
return "view any {$bundleId} content";
}
public function permissions() {
$permissions = array();
foreach ($this->entityTypeBundleInfo
->getBundleInfo('node') as $bundleId => $info) {
$permissions[$this
->makeViewAnyPermissionId($bundleId)] = [
'title' => t('View published %bundle_label content', array(
'%bundle_label' => $info['label'],
)),
];
}
return $permissions;
}
protected function permittedBundleIds(AccountInterface $account) {
$bundleIds = [];
foreach ($this->entityTypeBundleInfo
->getAllBundleInfo()['node'] as $bundleId => $info) {
if ($account
->hasPermission($this
->makeViewAnyPermissionId($bundleId))) {
$bundleIds[$bundleId] = $bundleId;
}
}
return $bundleIds;
}
public function hookNodeAccess(NodeInterface $node, $op, AccountInterface $account) {
if ($op === 'view') {
$bundleIsPermitted = in_array($node
->bundle(), $this
->permittedBundleIds($account));
return AccessResult::forbiddenIf(!$bundleIsPermitted)
->cachePerPermissions();
}
}
public function hookQueryNodeAccessAlter(AlterableInterface $query) {
$account = $query
->getMetaData('account') ?? \Drupal::currentUser();
$op = $query
->getMetaData('op') ?? 'view';
if ($query instanceof SelectInterface && $op === 'view') {
$nodeTableAlias = $this
->extractBaseTableAlias($query);
if (!$nodeTableAlias) {
throw new \Exception('Query tagged for node access but there is no node table, specify the base_table using meta data.');
}
$permittedBundleIds = $this
->permittedBundleIds($account);
if ($permittedBundleIds) {
$query
->condition("{$nodeTableAlias}.type", $permittedBundleIds, 'IN');
}
else {
$query
->alwaysFalse();
}
}
}
private function extractBaseTableAlias(AlterableInterface $query) {
$tables = $query
->getTables();
$base_table = $query
->getMetaData('base_table');
if (!$base_table) {
$table_mapping = \Drupal::entityTypeManager()
->getStorage('node')
->getTableMapping();
$node_base_tables = $table_mapping
->getTableNames();
foreach ($tables as $table_info) {
if (!$table_info instanceof SelectInterface) {
$table = $table_info['table'];
if ($table == 'node' || $table == 'node_field_data') {
$base_table = $table;
break;
}
if (in_array($table, $node_base_tables)) {
$base_table = $table;
}
}
}
}
if (isset($base_table)) {
foreach ($tables as $table_alias => $tableinfo) {
$table = $tableinfo['table'];
if (!$table instanceof SelectInterface && $table == $base_table) {
return $table_alias;
}
}
}
}
}