View source
<?php
namespace Drupal\permissions_by_term\Service;
use Drupal\Component\Utility\Environment;
use Drupal\Core\Database\Connection;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\node\Entity\Node;
use Drupal\permissions_by_term\Factory\NodeAccessRecordFactory;
use Drupal\permissions_by_term\Model\NodeAccessRecordModel;
use Drupal\user\Entity\User;
class NodeAccess {
private $uniqueGid = 0;
private $accessStorage;
private $userEntityStorage;
private $node;
private $entityTypeManager;
private $accessCheck;
private $loadedUid;
private $userInstance;
private $database;
public function __construct(AccessStorage $accessStorage, NodeAccessRecordFactory $nodeAccessRecordFactory, EntityTypeManagerInterface $entityTypeManager, AccessCheck $accessCheck, Connection $database) {
$this->accessStorage = $accessStorage;
$this->nodeAccessRecordFactory = $nodeAccessRecordFactory;
$this->entityTypeManager = $entityTypeManager;
$this->userEntityStorage = $this->entityTypeManager
->getStorage('user');
$this->node = $this->entityTypeManager
->getStorage('node');
$this->accessCheck = $accessCheck;
$this->database = $database;
}
public function createGrant($nid, $gid) {
return $this->nodeAccessRecordFactory
->create(AccessStorage::NODE_ACCESS_REALM, $gid, $nid, $this->accessStorage
->getLangCode($nid), 0, 0);
}
public function getUniqueGid() {
return $this->uniqueGid;
}
public function setUniqueGid($uniqueGid) {
$this->uniqueGid = $uniqueGid;
}
public function canUserBypassNodeAccess($uid) {
$user = $this
->getUserInstance($uid);
if ($user
->hasPermission('bypass node access')) {
return TRUE;
}
return FALSE;
}
public function canUserDeleteNode($uid, $nodeType, $nid) {
$user = $this
->getUserInstance($uid);
if ($user
->hasPermission('delete any ' . $nodeType . ' content')) {
return TRUE;
}
if ($this
->isNodeOwner($nid, $uid) && $this
->canDeleteOwnNode($uid, $nodeType)) {
return TRUE;
}
return FALSE;
}
public function isNodeOwner($nid, $uid) {
$node = $this->node
->load($nid);
if ((int) $node
->getOwnerId() == (int) $uid) {
return TRUE;
}
return FALSE;
}
public function getNidsForAccessRebuild() : array {
return $this->database
->select('node', 'n')
->fields('n', [
'nid',
])
->execute()
->fetchCol();
}
private function canUpdateOwnNode($uid, $nodeType) {
$user = $this
->getUserInstance($uid);
if ($user
->hasPermission('edit own ' . $nodeType . ' content')) {
return 1;
}
return 0;
}
private function canDeleteOwnNode($uid, $nodeType) {
$user = $this
->getUserInstance($uid);
if ($user
->hasPermission('delete own ' . $nodeType . ' content')) {
return 1;
}
return 0;
}
public function getGrantsByNid($nid) {
$grants = [];
foreach ($this->grants as $grant) {
if ($grant->nid == $nid) {
$grants[] = $grant;
}
}
return $grants;
}
public function getLoadedUid() {
return $this->loadedUid;
}
public function setLoadedUid($loadedUid) {
$this->loadedUid = $loadedUid;
}
public function getUserInstance($uid) {
if ($this
->getLoadedUid() !== $uid) {
$user = $this->userEntityStorage
->load($uid);
$this
->setUserInstance($user);
return $user;
}
return $this->userInstance;
}
public function setUserInstance($userInstance) {
$this->userInstance = $userInstance;
}
public function isAccessRecordExisting($nid) {
$query = $this->database
->select('node_access', 'na')
->fields('na', [
'nid',
])
->condition('na.nid', $nid)
->condition('na.realm', AccessStorage::NODE_ACCESS_REALM);
$result = $query
->execute()
->fetchCol();
if (empty($result)) {
return FALSE;
}
return TRUE;
}
public static function rebuildNodeAccessOne($nid) {
\Drupal::database()
->delete('node_access')
->condition('nid', $nid)
->execute();
\Drupal::entityTypeManager()
->getStorage('node')
->resetCache([
$nid,
]);
$node = Node::load($nid);
if (!empty($node)) {
$grants = \Drupal::entityTypeManager()
->getAccessControlHandler('node')
->acquireGrants($node);
\Drupal::service('node.grant_storage')
->write($node, $grants);
}
return 'Processed node ' . $nid;
}
public function rebuildAccess() : void {
$nids = $this
->getNidsForAccessRebuild();
if (count($nids) > 50) {
$operations = array_map(function ($id) {
return [
'Drupal\\permissions_by_term\\Service\\NodeAccess::rebuildNodeAccessOne',
[
$id,
],
];
}, $nids);
$batch = [
'title' => t('Updating content access permissions'),
'operations' => $operations,
'finished' => 'Drupal\\permissions_by_term\\Service\\NodeAccess::rebuildComplete',
];
batch_set($batch);
batch_process(\Drupal::service('path.current')
->getPath());
}
else {
Environment::setTimeLimit(240);
rsort($nids);
foreach ($nids as $nid) {
$this
->rebuildNodeAccessOne($nid);
}
}
}
public static function rebuildComplete() {
$cacheInvalidator = \Drupal::service('permissions_by_term.cache_invalidator');
$cacheInvalidator
->invalidate();
}
}