Updated all the contrib modules to their latest versions.
[yaffs-website] / web / modules / contrib / permissions_by_term / src / Listener / KernelEventListener.php
1 <?php
2
3 namespace Drupal\permissions_by_term\Listener;
4
5 use Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher;
6 use Drupal\permissions_by_term\Event\PermissionsByTermDeniedEvent;
7 use Drupal\permissions_by_term\Service\AccessCheck;
8 use Drupal\permissions_by_term\Service\AccessStorage;
9 use Drupal\permissions_by_term\Service\TermHandler;
10 use Symfony\Component\EventDispatcher\EventSubscriberInterface;
11 use Symfony\Component\HttpFoundation\JsonResponse;
12 use Symfony\Component\HttpFoundation\RedirectResponse;
13 use Symfony\Component\HttpFoundation\Request;
14 use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
15 use Symfony\Component\HttpKernel\Event\GetResponseEvent;
16 use Symfony\Component\HttpKernel\KernelEvents;
17
18 /**
19  * Class KernelEventListener.
20  *
21  * @package Drupal\permissions_by_term
22  */
23 class KernelEventListener implements EventSubscriberInterface
24 {
25
26   /**
27    * @var AccessCheck
28    */
29   private $accessCheckService;
30
31   /**
32    * @var TermHandler
33    */
34   private $term;
35
36   /**
37    * @var ContainerAwareEventDispatcher
38    */
39   private $eventDispatcher;
40
41   /**
42    * @var AccessStorage
43    */
44   private $accessStorageService;
45
46   /**
47    * Instantiating of objects on class construction.
48    */
49   public function __construct()
50   {
51     $this->accessCheckService = \Drupal::service('permissions_by_term.access_check');
52     $this->accessStorageService = \Drupal::service('permissions_by_term.access_storage');
53     $this->term = \Drupal::service('permissions_by_term.term_handler');
54     $this->eventDispatcher = \Drupal::service('event_dispatcher');
55   }
56
57   /**
58    * Access restriction on kernel request.
59    */
60   public function onKernelRequest(GetResponseEvent $event)
61   {
62     // Restricts access to nodes (views/edit).
63     if ($this->canRequestGetNode($event->getRequest())) {
64       $nid = $event->getRequest()->attributes->get('node')->get('nid')->getValue()['0']['value'];
65       if (!$this->accessCheckService->canUserAccessByNodeId($nid, false, $this->accessStorageService->getLangCode($nid))) {
66         $accessDeniedEvent = new PermissionsByTermDeniedEvent($nid);
67         $this->eventDispatcher->dispatch(PermissionsByTermDeniedEvent::NAME, $accessDeniedEvent);
68
69         $this->sendUserToAccessDeniedPage();
70       }
71     }
72
73     // Restrict access to taxonomy terms by autocomplete list.
74     if ($event->getRequest()->attributes->get('target_type') == 'taxonomy_term' &&
75       $event->getRequest()->attributes->get('_route') == 'system.entity_autocomplete') {
76       $query_string = $event->getRequest()->get('q');
77       $query_string = trim($query_string);
78
79       $tid = $this->term->getTermIdByName($query_string);
80
81       $term = $this->term->getTerm();
82       $termLangcode = \Drupal::languageManager()->getCurrentLanguage()->getId();
83       if ($term instanceof \Drupal\taxonomy\Entity\Term) {
84         $termLangcode = $term->language()->getId();
85       }
86
87       if (!$this->accessCheckService->isAccessAllowedByDatabase($tid, \Drupal::currentUser()->id(), $termLangcode)) {
88         $this->sendUserToAccessDeniedPage();
89       }
90     }
91   }
92
93   /**
94    * Restricts access on kernel response.
95    */
96   public function onKernelResponse(FilterResponseEvent $event) {
97     $this->restrictTermAccessAtAutoCompletion($event);
98   }
99
100   /**
101    * Restricts access to terms on AJAX auto completion.
102    */
103   private function restrictTermAccessAtAutoCompletion(FilterResponseEvent $event) {
104     if ($event->getRequest()->attributes->get('target_type') == 'taxonomy_term' &&
105       $event->getRequest()->attributes->get('_route') == 'system.entity_autocomplete'
106     ) {
107       $json_suggested_terms = $event->getResponse()->getContent();
108       $suggested_terms = json_decode($json_suggested_terms);
109       $allowed_terms = [];
110       foreach ($suggested_terms as $term) {
111         $tid = $this->term->getTermIdByName($term->label);
112         $termLangcode = \Drupal::languageManager()->getCurrentLanguage()->getId();
113         if ($this->term->getTerm() instanceof \Drupal\taxonomy\Entity\Term) {
114           $termLangcode = $this->term->getTerm()->language()->getId();
115         }
116
117         if ($this->accessCheckService->isAccessAllowedByDatabase($tid, \Drupal::currentUser()->id(), $termLangcode)) {
118           $allowed_terms[] = [
119             'value' => $term->value,
120             'label' => $term->label,
121           ];
122         }
123       }
124
125       $json_response = new JsonResponse($allowed_terms);
126       $event->setResponse($json_response);
127     }
128   }
129
130   /**
131    * The subscribed events.
132    */
133   public static function getSubscribedEvents()
134   {
135     return [
136       KernelEvents::REQUEST => 'onKernelRequest',
137       KernelEvents::RESPONSE => 'onKernelResponse',
138     ];
139   }
140
141   private function canRequestGetNode(Request $request) {
142     if (method_exists($request->attributes, 'get') && !empty($request->attributes->get('node'))) {
143       if (method_exists($request->attributes->get('node'), 'get')) {
144         return TRUE;
145       }
146     }
147
148     return FALSE;
149   }
150
151   private function sendUserToAccessDeniedPage() {
152     $redirect_url = new \Drupal\Core\Url('system.403');
153     $response = new RedirectResponse($redirect_url->toString());
154     $response->send();
155     return $response;
156   }
157
158 }