7a54e86db6b1e34c7c333289e4e500ad5377eea8
[yaffs-website] / web / modules / contrib / redirect / modules / redirect_404 / src / EventSubscriber / Redirect404Subscriber.php
1 <?php
2
3 namespace Drupal\redirect_404\EventSubscriber;
4
5 use Drupal\Component\Utility\Unicode;
6 use Drupal\Core\Config\ConfigFactoryInterface;
7 use Drupal\Core\Language\LanguageManagerInterface;
8 use Drupal\Core\Path\PathMatcherInterface;
9 use Drupal\redirect_404\RedirectNotFoundStorageInterface;
10 use Drupal\Core\Path\CurrentPathStack;
11 use Symfony\Component\HttpFoundation\RequestStack;
12 use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
13 use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
14 use Symfony\Component\HttpKernel\KernelEvents;
15 use Symfony\Component\EventDispatcher\EventSubscriberInterface;
16
17 /**
18  * An EventSubscriber that listens to redirect 404 errors.
19  */
20 class Redirect404Subscriber implements EventSubscriberInterface {
21
22   /**
23    * The current path.
24    *
25    * @var \Drupal\Core\Path\CurrentPathStack
26    */
27   protected $currentPath;
28
29   /**
30    * The path matcher.
31    *
32    * @var \Drupal\Core\Path\PathMatcherInterface
33    */
34   protected $pathMatcher;
35
36   /**
37    * The request stack (get the URL argument(s) and combined it with the path).
38    *
39    * @var \Symfony\Component\HttpFoundation\RequestStack
40    */
41   protected $requestStack;
42
43   /**
44    * The language manager.
45    *
46    * @var \Drupal\Core\Language\LanguageManagerInterface
47    */
48   protected $languageManager;
49
50   /**
51    * The redirect storage.
52    *
53    * @var \Drupal\redirect_404\RedirectNotFoundStorageInterface
54    */
55   protected $redirectStorage;
56
57   /**
58    * The configuration factory.
59    *
60    * @var \Drupal\Core\Config\ConfigFactoryInterface
61    */
62   protected $config;
63
64   /**
65    * Constructs a new Redirect404Subscriber.
66    *
67    * @param \Drupal\Core\Path\CurrentPathStack $current_path
68    *   The current path.
69    * @param \Drupal\Core\Path\PathMatcherInterface $path_matcher
70    *   The path matcher service.
71    * @param \Symfony\Component\HttpFoundation\RequestStack $request_stack
72    *   The request stack.
73    * @param \Drupal\Core\Language\LanguageManagerInterface $language_manager
74    *   The language manager.
75    * @param \Drupal\redirect_404\RedirectNotFoundStorageInterface $redirect_storage
76    *   A redirect storage.
77    * @param \Drupal\Core\Config\ConfigFactoryInterface $config
78    *   The configuration factory.
79    */
80   public function __construct(CurrentPathStack $current_path, PathMatcherInterface $path_matcher, RequestStack $request_stack, LanguageManagerInterface $language_manager, RedirectNotFoundStorageInterface $redirect_storage, ConfigFactoryInterface $config) {
81     $this->currentPath = $current_path;
82     $this->pathMatcher = $path_matcher;
83     $this->requestStack = $request_stack;
84     $this->languageManager = $language_manager;
85     $this->redirectStorage = $redirect_storage;
86     $this->config = $config->get('redirect_404.settings');
87   }
88
89   /**
90    * {@inheritdoc}
91    */
92   public static function getSubscribedEvents() {
93     $events[KernelEvents::EXCEPTION][] = 'onKernelException';
94     return $events;
95   }
96
97   /**
98    * Logs an exception of 404 Redirect errors.
99    *
100    * @param GetResponseForExceptionEvent $event
101    *   Is given by the event dispatcher.
102    */
103   public function onKernelException(GetResponseForExceptionEvent $event) {
104     // Only log page not found (404) errors.
105     if ($event->getException() instanceof NotFoundHttpException) {
106       $path = $this->currentPath->getPath();
107
108       // Ignore paths specified in the redirect settings.
109       if ($pages = Unicode::strtolower($this->config->get('pages'))) {
110         // Do not trim a trailing slash if that is the complete path.
111         $path_to_match = $path === '/' ? $path : rtrim($path, '/');
112
113         if ($this->pathMatcher->matchPath(Unicode::strtolower($path_to_match), $pages)) {
114           return;
115         }
116       }
117
118       // Allow to store paths with arguments.
119       if ($query_string = $this->requestStack->getCurrentRequest()->getQueryString()) {
120         $query_string = '?' . $query_string;
121       }
122       $path .= $query_string;
123       $langcode = $this->languageManager->getCurrentLanguage()->getId();
124
125       // Write record.
126       $this->redirectStorage->logRequest($path, $langcode);
127     }
128   }
129
130 }