diff --git a/example.settings.fast404.php b/example.settings.fast404.php index 30d6823..a080ebd 100644 --- a/example.settings.fast404.php +++ b/example.settings.fast404.php @@ -138,10 +138,16 @@ * regular 404 error. In this case you can specify a URL to another page and it * will be read and displayed (it can't be redirected to because we have to * give a 30x header to do that. This page needs to be in your docroot. + * Accepts a normal path, or an array, keyed by langcodes. * * Default value for this setting is FALSE. */ # $settings['fast404_HTML_error_page'] = './my_page.html'; +# The page is translatable. +# $settings['fast404_HTML_error_page'] = [ +# 'en' => './my_page-en.html', +# 'fr' => './my_page-fr.html', +# ]; /** * Load the fast404.inc file. diff --git a/fast404.services.yml b/fast404.services.yml index b9b5a9f..dc989d3 100644 --- a/fast404.services.yml +++ b/fast404.services.yml @@ -1,6 +1,6 @@ services: fast404.: class: Drupal\fast404\EventSubscriber\Fast404EventSubscriber - arguments: ['@request_stack'] + arguments: ['@request_stack', '@language_manager'] tags: - { name: event_subscriber } diff --git a/src/EventSubscriber/Fast404EventSubscriber.php b/src/EventSubscriber/Fast404EventSubscriber.php index 6caff8a..d60b950 100644 --- a/src/EventSubscriber/Fast404EventSubscriber.php +++ b/src/EventSubscriber/Fast404EventSubscriber.php @@ -2,14 +2,15 @@ namespace Drupal\fast404\EventSubscriber; +use Drupal\Core\Language\LanguageManagerInterface; +use Drupal\Core\Site\Settings; +use Drupal\fast404\Fast404; +use Symfony\Component\EventDispatcher\EventSubscriberInterface; +use Symfony\Component\HttpFoundation\RequestStack; +use Symfony\Component\HttpKernel\Event\GetResponseEvent; use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; use Symfony\Component\HttpKernel\KernelEvents; -use Symfony\Component\HttpKernel\Event\GetResponseEvent; -use Symfony\Component\EventDispatcher\EventSubscriberInterface; -use Symfony\Component\HttpFoundation\RequestStack; -use Drupal\Core\Site\Settings; -use Drupal\fast404\Fast404; /** * Class Fast404EventSubscriber. @@ -25,14 +26,24 @@ class Fast404EventSubscriber implements EventSubscriberInterface { */ public $requestStack; + /** + * The language manager + * + * @var \Drupal\Core\Language\LanguageManagerInterface + */ + protected $languageManager; + /** * Constructs a new Fast404EventSubscriber instance. * * @param \Symfony\Component\HttpFoundation\RequestStack $request_stack * The Request Stack. + * @param \Drupal\Core\Language\LanguageManagerInterface $language_manager + * The language manager. */ - public function __construct(RequestStack $request_stack) { + public function __construct(RequestStack $request_stack, LanguageManagerInterface $language_manager) { $this->requestStack = $request_stack; + $this->languageManager = $language_manager; } /** @@ -40,7 +51,7 @@ class Fast404EventSubscriber implements EventSubscriberInterface { */ public function onKernelRequest(GetResponseEvent $event) { $request = $this->requestStack->getCurrentRequest(); - $fast_404 = new Fast404($request); + $fast_404 = new Fast404($request, $this->languageManager->getCurrentLanguage()->getId()); $fast_404->extensionCheck(); if ($fast_404->isPathBlocked()) { @@ -63,7 +74,7 @@ class Fast404EventSubscriber implements EventSubscriberInterface { // Check to see if we will completely replace the Drupal 404 page. if (Settings::get('fast404_not_found_exception', FALSE)) { if ($event->getException() instanceof NotFoundHttpException) { - $fast_404 = new Fast404($event->getRequest()); + $fast_404 = new Fast404($event->getRequest(), $this->languageManager->getCurrentLanguage()->getId()); $event->setResponse($fast_404->response(TRUE)); } } diff --git a/src/Fast404.php b/src/Fast404.php index 0939279..d6e822f 100644 --- a/src/Fast404.php +++ b/src/Fast404.php @@ -2,10 +2,10 @@ namespace Drupal\fast404; -use Drupal\Core\Site\Settings; +use Drupal\Component\Render\FormattableMarkup; use Drupal\Core\Database\Database; +use Drupal\Core\Site\Settings; use Drupal\Core\StringTranslation\StringTranslationTrait; -use Drupal\Component\Render\FormattableMarkup; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Exception\ServiceUnavailableHttpException; @@ -40,14 +40,24 @@ class Fast404 { */ public $loadHtml = TRUE; + /** + * The langcode to use for the translated 404 page if it exists. + * + * @var string + */ + public $langcode = NULL; + /** * Fast404 constructor. * * @param \Symfony\Component\HttpFoundation\Request $request * The current request. + * @param string $langcode + * The current langcode. */ - public function __construct(Request $request) { + public function __construct(Request $request, $langcode = NULL) { $this->request = $request; + $this->langcode = $langcode; } /** @@ -198,10 +208,21 @@ class Fast404 { public function response($return = FALSE) { $message = Settings::get('fast404_html', '404 Not Found

Not Found

The requested URL "@path" was not found on this server.

'); $return_gone = Settings::get('fast404_return_gone', FALSE); - $custom_404_path = Settings::get('fast404_HTML_error_page', FALSE); + $custom_404 = Settings::get('fast404_HTML_error_page', FALSE); + $custom_404_path = NULL; // If a file is set to provide us with Fast 404 joy, load it. - if (($this->loadHtml || Settings::get('fast404_HTML_error_all_paths', FALSE) === TRUE) && file_exists($custom_404_path)) { - $message = @file_get_contents($custom_404_path, FALSE); + if (($this->loadHtml || Settings::get('fast404_HTML_error_all_paths', FALSE) === TRUE)) { + if (is_array($custom_404)) { + // If it is an array, get path depending on the langcode, if langcode is NULL, default to the first value. + $custom_404_path = $this->langcode && isset($custom_404[$this->langcode]) ? $custom_404[$this->langcode] : reset($custom_404); + } + else { + $custom_404_path = $custom_404; + } + + if (file_exists($custom_404_path)) { + $message = @file_get_contents($custom_404_path, FALSE); + } } $headers = [ Settings::get('fast404_HTTP_status_method', 'mod_php') === 'FastCGI' ? 'Status:' : 'HTTP/1.0' => $return_gone ? '410 Gone' : '404 Not Found', diff --git a/tests/src/Unit/Fast404EventSubscriberTest.php b/tests/src/Unit/Fast404EventSubscriberTest.php index 4140dd0..0229e98 100644 --- a/tests/src/Unit/Fast404EventSubscriberTest.php +++ b/tests/src/Unit/Fast404EventSubscriberTest.php @@ -63,8 +63,17 @@ class Fast404EventSubscriberTest extends UnitTestCase { $requestStackStub = $this->getMockBuilder('\Symfony\Component\HttpFoundation\RequestStack') ->disableOriginalConstructor() ->getMock(); + $langaugeManagerStub = $this->getMockBuilder('\Drupal\Core\Language\LanguageManager') + ->disableOriginalConstructor() + ->getMock(); + $languageStub = $this->getMockBuilder('\Drupal\Core\Language\Language') + ->disableOriginalConstructor() + ->getMock(); + $languageStub->method('getId')->willReturn('en'); + $langaugeManagerStub->method('getCurrentLanguage')->willReturn($languageStub); + $subscriber = $this->getMockBuilder('\Drupal\fast404\EventSubscriber\Fast404EventSubscriber') - ->setConstructorArgs([$requestStackStub]) + ->setConstructorArgs([$requestStackStub, $langaugeManagerStub]) ->getMock(); return $subscriber; }