Passed
Push — main ( bf434a...128b22 )
by Michael
02:11
created

LocaleRewriteSubscriber::getDefaultLocale()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 1
nc 2
nop 1
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 2
rs 10
c 0
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 5
    public function __construct(RouterInterface $router, array|null $enabledLocales = null)
25
    {
26 5
        $this->routeCollection = $router->getRouteCollection();
27 5
        $this->localeRouteParam = '_locale';
28 5
        $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
        $route_exists = $this->routeExists($path);
36
37 4
        if ($route_exists) {
38
39
            //Get the locale from the user's browser.
40 3
            $locale = $this->getPreferredLanguage($request);
41
42
            //If no locale from browser or locale not in list of known locales supported then set to defaultLocale set in config.yml
43 3
            if (!$this->isLocaleSupported($locale)) {
44 2
                $locale = $this->getDefaultLocale($request);
45
            }
46
47 3
            if ($locale) {
48 2
                $event->setResponse(new RedirectResponse("/" . $locale . $path));
49
            }
50
        }
51
52
    }
53
54 4
    private function isLocaleSupported($locale): bool
55
    {
56
57 4
        if ($this->enabledLocales === null) {
58 1
            return true;
59
        }
60
61 3
        if ($locale) {
62 2
            return $this->isLocaleEnabled($locale);
63
        }
64
65 1
        return false;
66
    }
67
68 3
    private function getPreferredLanguage(Request $request): ?string
69
    {
70 3
        return $request->getPreferredLanguage() ? explode('_', $request->getPreferredLanguage())[0] : null;
71
    }
72
73 4
    private function routeExists(string $path): bool
74
    {
75 4
        return !empty(array_filter(iterator_to_array($this->routeCollection->getIterator()), function($routeObject) use ($path) {
76 4
            return $routeObject->getPath() === "/{" . $this->localeRouteParam . "}" . $path;
77
        }));
78
    }
79
80 2
    private function getDefaultLocale(Request $request): ?string
81
    {
82 2
        return $this->isLocaleEnabled($request->getDefaultLocale()) ? $request->getDefaultLocale() : null;
83
    }
84
85 1
    public static function getSubscribedEvents(): array
86
    {
87
        return [
88 1
            KernelEvents::REQUEST => ['onKernelRequest', 64]
89
        ];
90
    }
91
92 2
    private function isLocaleEnabled(string $locale): bool
93
    {
94 2
        $supportedLocale = array_filter($this->enabledLocales, function($supportedLocale) use ($locale) {
0 ignored issues
show
Bug introduced by
It seems like $this->enabledLocales can also be of type null; however, parameter $array of array_filter() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

94
        $supportedLocale = array_filter(/** @scrutinizer ignore-type */ $this->enabledLocales, function($supportedLocale) use ($locale) {
Loading history...
95 2
            return in_array($supportedLocale, explode('_', $locale));
96
        });
97
98 2
        return !empty($supportedLocale);
99
    }
100
101
}