onKernelRequest()   A
last analyzed

Complexity

Conditions 5
Paths 4

Size

Total Lines 21

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 21
rs 9.2728
c 0
b 0
f 0
cc 5
nc 4
nop 1
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the Explicit Architecture POC,
7
 * which is created on top of the Symfony Demo application.
8
 *
9
 * (c) Herberto Graça <[email protected]>
10
 *
11
 * For the full copyright and license information, please view the LICENSE
12
 * file that was distributed with this source code.
13
 */
14
15
namespace Acme\App\Presentation\Web\Infrastructure\Router\Symfony\EventSubscriber;
16
17
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
18
use Symfony\Component\HttpFoundation\RedirectResponse;
19
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
20
use Symfony\Component\HttpKernel\KernelEvents;
21
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
22
23
/**
24
 * When visiting the homepage, this listener redirects the user to the most
25
 * appropriate localized version according to the browser settings.
26
 *
27
 * See https://symfony.com/doc/current/components/http_kernel/introduction.html#the-kernel-request-event
28
 *
29
 * @author Oleg Voronkovich <[email protected]>
30
 */
31
class RedirectToPreferredLocaleSubscriber implements EventSubscriberInterface
32
{
33
    /**
34
     * @var UrlGeneratorInterface
35
     */
36
    private $urlGenerator;
37
38
    /**
39
     * @var array
40
     */
41
    private $locales;
42
43
    /**
44
     * @var mixed
45
     */
46
    private $defaultLocale;
47
48
    public function __construct(UrlGeneratorInterface $urlGenerator, string $locales, string $defaultLocale = null)
49
    {
50
        $this->urlGenerator = $urlGenerator;
51
52
        $this->locales = explode('|', trim($locales));
53
        if (empty($this->locales)) {
54
            throw new \UnexpectedValueException('The list of supported locales must not be empty.');
55
        }
56
57
        $this->defaultLocale = $defaultLocale ?: $this->locales[0];
58
59
        if (!\in_array($this->defaultLocale, $this->locales, true)) {
60
            throw new \UnexpectedValueException(sprintf('The default locale ("%s") must be one of "%s".', $this->defaultLocale, $locales));
61
        }
62
63
        // Add the default locale at the first position of the array,
64
        // because Symfony\HttpFoundation\Request::getPreferredLanguage
65
        // returns the first element when no an appropriate language is found
66
        array_unshift($this->locales, $this->defaultLocale);
67
        $this->locales = array_unique($this->locales);
68
    }
69
70
    public static function getSubscribedEvents(): array
71
    {
72
        return [
73
            KernelEvents::REQUEST => 'onKernelRequest',
74
        ];
75
    }
76
77
    public function onKernelRequest(GetResponseEvent $event): void
78
    {
79
        $request = $event->getRequest();
80
81
        // Ignore sub-requests and all URLs but the homepage
82
        if (!$event->isMasterRequest() || $request->getPathInfo() !== '/') {
83
            return;
84
        }
85
        // Ignore requests from referrers with the same HTTP host in order to prevent
86
        // changing language for users who possibly already selected it for this application.
87
        if (mb_stripos((string) $request->headers->get('referer'), $request->getSchemeAndHttpHost()) === 0) {
88
            return;
89
        }
90
91
        $preferredLanguage = $request->getPreferredLanguage($this->locales);
92
93
        if ($preferredLanguage !== $this->defaultLocale) {
94
            $response = new RedirectResponse($this->urlGenerator->generate('homepage', ['_locale' => $preferredLanguage]));
95
            $event->setResponse($response);
96
        }
97
    }
98
}
99