b5635d82730fc10a3df2f0967b3d27ede4a3112e
[yaffs-website] / web / modules / contrib / permissions_by_term / src / Service / AccessCheck.php
1 <?php
2
3 namespace Drupal\permissions_by_term\Service;
4
5 use Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher;
6 use Drupal\Core\Access\AccessResult;
7 use Drupal\Core\Database\Connection;
8 use Drupal\permissions_by_term\Event\PermissionsByTermDeniedEvent;
9 use Drupal\user\Entity\User;
10 use Drupal\taxonomy\Entity\Term;
11
12 /**
13  * AccessCheckService class.
14  */
15 class AccessCheck {
16
17   /**
18    * The database connection.
19    *
20    * @var \Drupal\Core\Database\Connection
21    */
22   protected $database;
23
24   /**
25    * @var ContainerAwareEventDispatcher
26    */
27   private $eventDispatcher;
28
29   /**
30    * Constructs AccessCheck object.
31    *
32    * @param Connection $database
33    *   The database connection.
34    */
35   public function __construct(Connection $database, ContainerAwareEventDispatcher $eventDispatcher) {
36     $this->database  = $database;
37     $this->eventDispatcher = $eventDispatcher;
38   }
39
40   /**
41    * @param int $nid
42    * @param bool $uid
43    * @param string $langcode
44    *
45    * @return array|bool
46    */
47   public function canUserAccessByNodeId($nid, $uid = FALSE, $langcode = '') {
48                 $langcode = ($langcode === '') ? \Drupal::languageManager()->getCurrentLanguage()->getId() : $langcode;
49
50     if (\Drupal::currentUser()->hasPermission('bypass node access')) {
51       return TRUE;
52     }
53
54     if (!$singleTermRestriction = \Drupal::config('permissions_by_term.settings.single_term_restriction')->get('value')) {
55       $access_allowed = TRUE;
56     } else {
57       $access_allowed = FALSE;
58     }
59
60     $terms = $this->database
61       ->query("SELECT tid FROM {taxonomy_index} WHERE nid = :nid",
62       [':nid' => $nid])->fetchAll();
63
64     if (empty($terms)) {
65       return TRUE;
66     }
67
68     foreach ($terms as $term) {
69       $termInfo = Term::load($term->tid);
70
71       if ($termInfo instanceof Term && $termInfo->get('langcode')->getLangcode() == $langcode) {
72         $access_allowed = $this->isAccessAllowedByDatabase($term->tid, $uid, $termInfo->get('langcode')->getLangcode());
73         if (!$access_allowed) {
74           if ($singleTermRestriction) {
75             return $access_allowed;
76           }
77         }
78
79         if ($access_allowed && !$singleTermRestriction) {
80           return $access_allowed;
81         }
82       }
83
84     }
85
86     return $access_allowed;
87   }
88
89   /**
90    * @param int      $tid
91    * @param bool|int $uid
92    * @param string   $langcode
93    * @return bool
94    */
95   public function isAccessAllowedByDatabase($tid, $uid = FALSE, $langcode = '') {
96                 $langcode = ($langcode === '') ? \Drupal::languageManager()->getCurrentLanguage()->getId() : $langcode;
97
98     if ($uid === FALSE || (int) $uid === 0) {
99       $user = \Drupal::currentUser();
100     } elseif (is_numeric($uid)) {
101       $user = User::load($uid);
102     }
103
104     $tid = (int) $tid;
105
106     if (!$this->isAnyPermissionSetForTerm($tid, $langcode)) {
107       return TRUE;
108     }
109
110     /* At this point permissions are enabled, check to see if this user or one
111      * of their roles is allowed.
112      */
113     $aUserRoles = $user->getRoles();
114
115     foreach ($aUserRoles as $sUserRole) {
116
117       if ($this->isTermAllowedByUserRole($tid, $sUserRole, $langcode)) {
118         return TRUE;
119       }
120
121     }
122
123     $iUid = intval($user->id());
124
125     if ($this->isTermAllowedByUserId($tid, $iUid, $langcode)) {
126       return TRUE;
127     }
128
129     return FALSE;
130
131   }
132
133   /**
134    * @param int    $tid
135    * @param int    $iUid
136    * @param string $langcode
137    *
138    * @return bool
139    */
140   private function isTermAllowedByUserId($tid, $iUid, $langcode) {
141     $query_result = $this->database->query("SELECT uid FROM {permissions_by_term_user} WHERE tid = :tid AND uid = :uid AND langcode = :langcode",
142       [':tid' => $tid, ':uid' => $iUid, ':langcode' => $langcode])->fetchField();
143
144     if (!empty($query_result)) {
145       return TRUE;
146     }
147     else {
148       return FALSE;
149     }
150   }
151
152   /**
153    * @param int    $tid
154    * @param string $sUserRole
155    * @param string $langcode
156    *
157    * @return bool
158    */
159   public function isTermAllowedByUserRole($tid, $sUserRole, $langcode) {
160     $query_result = $this->database->query("SELECT rid FROM {permissions_by_term_role} WHERE tid = :tid AND rid IN (:user_roles) AND langcode = :langcode",
161       [':tid' => $tid, ':user_roles' => $sUserRole, ':langcode' => $langcode])->fetchField();
162
163     if (!empty($query_result)) {
164       return TRUE;
165     }
166     else {
167       return FALSE;
168     }
169
170   }
171
172   /**
173    * @param int    $tid
174    * @param string $langcode
175    *
176    * @return bool
177    */
178   public function isAnyPermissionSetForTerm($tid, $langcode = '') {
179                 $langcode = ($langcode === '') ? \Drupal::languageManager()->getCurrentLanguage()->getId() : $langcode;
180
181     $iUserTableResults = intval($this->database->query("SELECT COUNT(1) FROM {permissions_by_term_user} WHERE tid = :tid AND langcode = :langcode",
182       [':tid' => $tid, ':langcode' => $langcode])->fetchField());
183
184     $iRoleTableResults = intval($this->database->query("SELECT COUNT(1) FROM {permissions_by_term_role} WHERE tid = :tid AND langcode = :langcode",
185       [':tid' => $tid, ':langcode' => $langcode])->fetchField());
186
187     if ($iUserTableResults > 0 ||
188       $iRoleTableResults > 0) {
189       return TRUE;
190     }
191
192   }
193
194   /**
195    * @param string $nodeId
196    * @param string $langcode
197    *
198    * @return AccessResult
199    */
200   public function handleNode($nodeId, $langcode) {
201     if ($this->canUserAccessByNodeId($nodeId, false, $langcode) === TRUE) {
202       return AccessResult::neutral();
203     }
204     else {
205       $accessDeniedEvent = new PermissionsByTermDeniedEvent($nodeId);
206       $this->eventDispatcher->dispatch(PermissionsByTermDeniedEvent::NAME, $accessDeniedEvent);
207
208       return AccessResult::forbidden();
209     }
210   }
211
212 }