3 namespace Drupal\permissions_by_term\Listener;
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;
19 * Class KernelEventListener.
21 * @package Drupal\permissions_by_term
23 class KernelEventListener implements EventSubscriberInterface
29 private $accessCheckService;
37 * @var ContainerAwareEventDispatcher
39 private $eventDispatcher;
44 private $accessStorageService;
47 * Instantiating of objects on class construction.
49 public function __construct()
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');
58 * Access restriction on kernel request.
60 public function onKernelRequest(GetResponseEvent $event)
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);
69 $this->sendUserToAccessDeniedPage();
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);
79 $tid = $this->term->getTermIdByName($query_string);
81 $term = $this->term->getTerm();
82 $termLangcode = \Drupal::languageManager()->getCurrentLanguage()->getId();
83 if ($term instanceof \Drupal\taxonomy\Entity\Term) {
84 $termLangcode = $term->language()->getId();
87 if (!$this->accessCheckService->isAccessAllowedByDatabase($tid, \Drupal::currentUser()->id(), $termLangcode)) {
88 $this->sendUserToAccessDeniedPage();
94 * Restricts access on kernel response.
96 public function onKernelResponse(FilterResponseEvent $event) {
97 $this->restrictTermAccessAtAutoCompletion($event);
101 * Restricts access to terms on AJAX auto completion.
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'
107 $json_suggested_terms = $event->getResponse()->getContent();
108 $suggested_terms = json_decode($json_suggested_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();
117 if ($this->accessCheckService->isAccessAllowedByDatabase($tid, \Drupal::currentUser()->id(), $termLangcode)) {
119 'value' => $term->value,
120 'label' => $term->label,
125 $json_response = new JsonResponse($allowed_terms);
126 $event->setResponse($json_response);
131 * The subscribed events.
133 public static function getSubscribedEvents()
136 KernelEvents::REQUEST => 'onKernelRequest',
137 KernelEvents::RESPONSE => 'onKernelResponse',
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')) {
151 private function sendUserToAccessDeniedPage() {
152 $redirect_url = new \Drupal\Core\Url('system.403');
153 $response = new RedirectResponse($redirect_url->toString());