LocaleRewriteSubscriber::onKernelRequest()   A
last analyzed

Complexity

Conditions 4
Paths 4

Size

Total Lines 15
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 4

Importance

Changes 3
Bugs 0 Features 0
Metric Value
cc 4
eloc 7
nc 4
nop 1
dl 0
loc 15
ccs 8
cts 8
cp 1
crap 4
rs 10
c 3
b 0
f 0
1
<?php
2
3
namespace Braunstetter\LocalizedRoutes\EventSubscriber;
4
5
6
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
7
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
8
use Symfony\Component\HttpFoundation\RedirectResponse;
9
use Symfony\Component\HttpFoundation\Request;
10
use Symfony\Component\HttpKernel\Event\RequestEvent;
11
use Symfony\Component\HttpKernel\KernelEvents;
12
use Symfony\Component\Routing\Route;
13
use Symfony\Component\Routing\RouteCollection;
14
use Symfony\Component\Routing\RouterInterface;
15
use Symfony\Component\VarDumper\VarDumper;
16
17
class LocaleRewriteSubscriber implements EventSubscriberInterface
18
{
19
20
    private RouteCollection $routeCollection;
21
    private ?array $enabledLocales;
22
    private mixed $localeRouteParam;
23
24 6
    public function __construct(RouterInterface $router, array|null $enabledLocales = null)
25
    {
26 6
        $this->routeCollection = $router->getRouteCollection();
27 6
        $this->localeRouteParam = '_locale';
28 6
        $this->enabledLocales = $enabledLocales;
29
    }
30
31 4
    public function onKernelRequest(RequestEvent $event)
32
    {
33 4
        $request = $event->getRequest();
34 4
        $path = $request->getPathInfo();
35 4
36
        //Get the locale from the user's browser.
37 4
        $locale = $this->getPreferredLanguage($request);
38
39
        //If no locale from browser or locale not in list of known locales supported then set to defaultLocale set in config.yml
40 3
        if (!$this->isLocaleSupported($locale)) {
41
            $locale = $this->getDefaultLocale($request);
42
        }
43 3
44 2
        if ($this->routeExists($path) && $locale) {
45
            $event->setResponse(new RedirectResponse("/" . $locale . $path));
46
        }
47 3
    }
48 2
49
    private function isLocaleSupported($locale): bool
50
    {
51
52
        if ($this->enabledLocales === null) {
53
            return true;
54 4
        }
55
56
        if ($locale) {
57 4
            return $this->isLocaleEnabled($locale);
58 1
        }
59
60
        return false;
61 3
    }
62 2
63
    private function getPreferredLanguage(Request $request): ?string
64
    {
65 1
        return $request->getPreferredLanguage() ? explode('_', $request->getPreferredLanguage())[0] : null;
66
    }
67
68 3
    private function routeExists(string $path): bool
69
    {
70 3
        return !empty(array_filter(iterator_to_array($this->routeCollection->getIterator()), function($routeObject) use ($path) {
71
            return $routeObject->getPath() === "/{" . $this->localeRouteParam . "}" . $path;
72
        }));
73 4
    }
74
75 4
    private function getDefaultLocale(Request $request): ?string
76 4
    {
77
        return $this->isLocaleEnabled($request->getDefaultLocale()) ? $request->getDefaultLocale() : null;
78
    }
79
80 2
    public static function getSubscribedEvents(): array
81
    {
82 2
        return [
83
            KernelEvents::REQUEST => ['onKernelRequest', 64]
84
        ];
85 3
    }
86
87
    private function isLocaleEnabled(string $locale): bool
88 3
    {
89
        if ($this->enabledLocales === null) {
90
            return true;
91
        }
92 3
93
        return !empty(array_filter($this->enabledLocales, function($supportedLocale) use ($locale) {
94 3
            return in_array($supportedLocale, explode('_', $locale));
95 1
        }));
96
    }
97
98
}