View source
<?php
namespace Drupal\permissions_by_term\Service;
use Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher;
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Database\Connection;
use Drupal\permissions_by_term\Event\PermissionsByTermDeniedEvent;
use Drupal\user\Entity\User;
use Drupal\taxonomy\Entity\Term;
class AccessCheck {
protected $database;
private $eventDispatcher;
public function __construct(Connection $database, ContainerAwareEventDispatcher $eventDispatcher) {
$this->database = $database;
$this->eventDispatcher = $eventDispatcher;
}
public function canUserAccessByNodeId($nid, $uid = FALSE, $langcode = '') {
$langcode = $langcode === '' ? \Drupal::languageManager()
->getCurrentLanguage()
->getId() : $langcode;
if (\Drupal::currentUser()
->hasPermission('bypass node access')) {
return TRUE;
}
if (!($singleTermRestriction = \Drupal::config('permissions_by_term.settings.single_term_restriction')
->get('value'))) {
$access_allowed = TRUE;
}
else {
$access_allowed = FALSE;
}
$terms = $this->database
->query("SELECT tid FROM {taxonomy_index} WHERE nid = :nid", [
':nid' => $nid,
])
->fetchAll();
if (empty($terms)) {
return TRUE;
}
foreach ($terms as $term) {
$termInfo = Term::load($term->tid);
if ($termInfo instanceof Term && $termInfo
->get('langcode')
->getLangcode() == $langcode) {
$access_allowed = $this
->isAccessAllowedByDatabase($term->tid, $uid, $termInfo
->get('langcode')
->getLangcode());
if (!$access_allowed) {
if ($singleTermRestriction) {
return $access_allowed;
}
}
if ($access_allowed && !$singleTermRestriction) {
return $access_allowed;
}
}
}
return $access_allowed;
}
public function isAccessAllowedByDatabase($tid, $uid = FALSE, $langcode = '') {
$langcode = $langcode === '' ? \Drupal::languageManager()
->getCurrentLanguage()
->getId() : $langcode;
if ($uid === FALSE || (int) $uid === 0) {
$user = \Drupal::currentUser();
}
elseif (is_numeric($uid)) {
$user = User::load($uid);
}
$tid = (int) $tid;
if (!$this
->isAnyPermissionSetForTerm($tid, $langcode)) {
return TRUE;
}
$aUserRoles = $user
->getRoles();
foreach ($aUserRoles as $sUserRole) {
if ($this
->isTermAllowedByUserRole($tid, $sUserRole, $langcode)) {
return TRUE;
}
}
$iUid = intval($user
->id());
if ($this
->isTermAllowedByUserId($tid, $iUid, $langcode)) {
return TRUE;
}
return FALSE;
}
private function isTermAllowedByUserId($tid, $iUid, $langcode) {
$query_result = $this->database
->query("SELECT uid FROM {permissions_by_term_user} WHERE tid = :tid AND uid = :uid AND langcode = :langcode", [
':tid' => $tid,
':uid' => $iUid,
':langcode' => $langcode,
])
->fetchField();
if (!empty($query_result)) {
return TRUE;
}
else {
return FALSE;
}
}
public function isTermAllowedByUserRole($tid, $sUserRole, $langcode) {
$query_result = $this->database
->query("SELECT rid FROM {permissions_by_term_role} WHERE tid = :tid AND rid IN (:user_roles) AND langcode = :langcode", [
':tid' => $tid,
':user_roles' => $sUserRole,
':langcode' => $langcode,
])
->fetchField();
if (!empty($query_result)) {
return TRUE;
}
else {
return FALSE;
}
}
public function isAnyPermissionSetForTerm($tid, $langcode = '') {
$langcode = $langcode === '' ? \Drupal::languageManager()
->getCurrentLanguage()
->getId() : $langcode;
$iUserTableResults = intval($this->database
->query("SELECT COUNT(1) FROM {permissions_by_term_user} WHERE tid = :tid AND langcode = :langcode", [
':tid' => $tid,
':langcode' => $langcode,
])
->fetchField());
$iRoleTableResults = intval($this->database
->query("SELECT COUNT(1) FROM {permissions_by_term_role} WHERE tid = :tid AND langcode = :langcode", [
':tid' => $tid,
':langcode' => $langcode,
])
->fetchField());
if ($iUserTableResults > 0 || $iRoleTableResults > 0) {
return TRUE;
}
}
public function handleNode($nodeId, $langcode) {
if ($this
->canUserAccessByNodeId($nodeId, false, $langcode) === TRUE) {
return AccessResult::neutral();
}
else {
$accessDeniedEvent = new PermissionsByTermDeniedEvent($nodeId);
$this->eventDispatcher
->dispatch(PermissionsByTermDeniedEvent::NAME, $accessDeniedEvent);
return AccessResult::forbidden();
}
}
}