class KernelEventListener in Permissions by Term 8.2
Same name and namespace in other branches
- 8 src/Listener/KernelEventListener.php \Drupal\permissions_by_term\Listener\KernelEventListener
Class KernelEventListener.
@package Drupal\permissions_by_term
Hierarchy
- class \Drupal\permissions_by_term\Listener\KernelEventListener implements \Symfony\Component\EventDispatcher\EventSubscriberInterface
Expanded class hierarchy of KernelEventListener
1 string reference to 'KernelEventListener'
1 service uses KernelEventListener
File
- src/
Listener/ KernelEventListener.php, line 28
Namespace
Drupal\permissions_by_term\ListenerView source
class KernelEventListener implements EventSubscriberInterface {
/**
* @var AccessCheck
*/
private $accessCheckService;
/**
* @var TermHandler
*/
private $term;
/**
* @var ContainerAwareEventDispatcher
*/
private $eventDispatcher;
/**
* @var AccessStorage
*/
private $accessStorageService;
/**
* @var KillSwitch
*/
private $pageCacheKillSwitch;
/**
* @var bool
*/
private $disabledNodeAccessRecords;
public function __construct(AccessCheck $accessCheck, AccessStorage $accessStorage, TermHandler $termHandler, ContainerAwareEventDispatcher $eventDispatcher, KillSwitch $pageCacheKillSwitch, ConfigFactoryInterface $configFactory) {
$this->accessCheckService = $accessCheck;
$this->accessStorageService = $accessStorage;
$this->term = $termHandler;
$this->eventDispatcher = $eventDispatcher;
$this->pageCacheKillSwitch = $pageCacheKillSwitch;
$this->disabledNodeAccessRecords = $configFactory
->get('permissions_by_term.settings')
->get('disable_node_access_records');
}
/**
* Access restriction on kernel request.
*/
public function onKernelRequest(GetResponseEvent $event) {
if ($event
->isMasterRequest()) {
if (($result = $this
->handleAccessToNodePages($event)) instanceof Response) {
$event
->setResponse($result);
}
if (($result = $this
->handleAccessToTermAutocompleteLists($event)) instanceof Response) {
$event
->setResponse($result);
}
if (($result = $this
->handleAccessToTaxonomyTermViewsPages()) instanceof Response) {
$event
->setResponse($result);
}
}
}
/**
* Restricts access on kernel response.
*/
public function onKernelResponse(FilterResponseEvent $event) {
$this
->restrictTermAccessAtAutoCompletion($event);
}
/**
* Restricts access to terms on AJAX auto completion.
*/
private function restrictTermAccessAtAutoCompletion(FilterResponseEvent $event) {
if ($event
->getRequest()->attributes
->get('target_type') === 'taxonomy_term' && $event
->getRequest()->attributes
->get('_route') === 'system.entity_autocomplete') {
$json_suggested_terms = $event
->getResponse()
->getContent();
$suggested_terms = json_decode($json_suggested_terms);
$allowed_terms = [];
foreach ($suggested_terms as $term) {
$tid = $this->term
->getTermIdByName($term->label);
$termLangcode = \Drupal::languageManager()
->getCurrentLanguage()
->getId();
if ($this->term
->getTerm() instanceof Term) {
$termLangcode = $this->term
->getTerm()
->language()
->getId();
}
if ($this->accessCheckService
->isAccessAllowedByDatabase($tid, \Drupal::currentUser()
->id(), $termLangcode)) {
$allowed_terms[] = [
'value' => $term->value,
'label' => $term->label,
];
}
}
$json_response = new JsonResponse($allowed_terms);
$event
->setResponse($json_response);
}
}
/**
* The subscribed events.
*/
public static function getSubscribedEvents() : array {
return [
KernelEvents::REQUEST => 'onKernelRequest',
KernelEvents::RESPONSE => 'onKernelResponse',
];
}
private function canRequestGetNode(Request $request) : bool {
if (method_exists($request->attributes, 'get') && !empty($request->attributes
->get('node'))) {
if (method_exists($request->attributes
->get('node'), 'get')) {
return TRUE;
}
}
return FALSE;
}
private function handleAccessToTaxonomyTermViewsPages() {
$url_object = \Drupal::service('path.validator')
->getUrlIfValid(\Drupal::service('path.current')
->getPath());
if ($url_object instanceof Url && $url_object
->getRouteName() === 'entity.taxonomy_term.canonical') {
$route_parameters = $url_object
->getrouteParameters();
$termLangcode = \Drupal::languageManager()
->getCurrentLanguage()
->getId();
if (!$this->accessCheckService
->isAccessAllowedByDatabase($route_parameters['taxonomy_term'], \Drupal::currentUser()
->id(), $termLangcode)) {
$this->pageCacheKillSwitch
->trigger();
throw new AccessDeniedHttpException();
}
}
}
private function handleAccessToNodePages(GetResponseEvent $event) {
// Restricts access to nodes (views/edit).
if ($this
->canRequestGetNode($event
->getRequest())) {
$node = $event
->getRequest()->attributes
->get('node');
if (!$this->accessCheckService
->canUserAccessByNode($node, false, $this->accessStorageService
->getLangCode($node
->id()))) {
$accessDeniedEvent = new PermissionsByTermDeniedEvent($node
->id());
$this->eventDispatcher
->dispatch(PermissionsByTermDeniedEvent::NAME, $accessDeniedEvent);
if ($this->disabledNodeAccessRecords) {
$this->pageCacheKillSwitch
->trigger();
}
throw new AccessDeniedHttpException();
}
}
}
private function handleAccessToTermAutocompleteLists(GetResponseEvent $event) {
// Restrict access to taxonomy terms by autocomplete list.
if ($event
->getRequest()->attributes
->get('target_type') === 'taxonomy_term' && $event
->getRequest()->attributes
->get('_route') === 'system.entity_autocomplete') {
$query_string = $event
->getRequest()
->get('q');
$query_string = trim($query_string);
$tid = $this->term
->getTermIdByName($query_string);
$term = $this->term
->getTerm();
$termLangcode = \Drupal::languageManager()
->getCurrentLanguage()
->getId();
if ($term instanceof Term) {
$termLangcode = $term
->language()
->getId();
}
if (!$this->accessCheckService
->isAccessAllowedByDatabase($tid, \Drupal::currentUser()
->id(), $termLangcode)) {
throw new AccessDeniedHttpException();
}
}
}
}