Passed
Push — master ( 200c36...e69374 )
by
unknown
11:08 queued 14s
created

LocaleSubscriber   A

Complexity

Total Complexity 20

Size/Duplication

Total Lines 97
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 43
dl 0
loc 97
rs 10
c 0
b 0
f 0
wmc 20

4 Methods

Rating   Name   Duplication   Size   Complexity  
A getSubscribedEvents() 0 5 1
C getCurrentLanguage() 0 56 13
A __construct() 0 6 1
A onKernelRequest() 0 22 5
1
<?php
2
3
declare(strict_types=1);
4
5
/* For licensing terms, see /license.txt */
6
7
namespace Chamilo\CoreBundle\EventSubscriber;
8
9
use Chamilo\CoreBundle\Entity\Course;
10
use Chamilo\CoreBundle\Settings\SettingsManager;
11
use Chamilo\CourseBundle\Settings\SettingsCourseManager;
12
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
13
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
14
use Symfony\Component\HttpFoundation\Request;
15
use Symfony\Component\HttpKernel\Event\RequestEvent;
16
use Symfony\Component\HttpKernel\KernelEvents;
17
18
/**
19
 * Handles locale selection based on platform, user, and course settings.
20
 */
21
class LocaleSubscriber implements EventSubscriberInterface
22
{
23
    public function __construct(
24
        private string $defaultLocale,
25
        private SettingsManager $settingsManager,
26
        private ParameterBagInterface $parameterBag,
27
        private SettingsCourseManager $courseSettingsManager
28
    ) {
29
    }
30
31
    public function onKernelRequest(RequestEvent $event): void
32
    {
33
        $request = $event->getRequest();
34
35
        $installed = $this->parameterBag->has('installed') && 1 === (int) $this->parameterBag->get('installed');
36
        if (!$installed || !$request->hasSession()) {
37
            return;
38
        }
39
40
        $sessionHandler = $request->getSession();
41
42
        // Override locale if forced via ?_locale=xx
43
        if ($attrLocale = $request->query->get('_locale')) {
44
            $sessionHandler->set('_selected_locale', $attrLocale);
45
        }
46
47
        // Determine locale based on priority logic
48
        $locale = $this->getCurrentLanguage($request);
49
50
        // Apply locale to request and session
51
        $request->setLocale($locale);
52
        $sessionHandler->set('_locale', $locale);
53
    }
54
55
    public function getCurrentLanguage(Request $request): string
56
    {
57
        $sessionHandler = $request->getSession();
58
        $localeList = [];
59
60
        // 1. Platform default locale
61
        if ($platformLocale = $this->settingsManager->getSetting('language.platform_language')) {
62
            $localeList['platform_lang'] = $platformLocale;
63
        }
64
65
        // 2. User profile locale from session
66
        if ($userLocale = $sessionHandler->get('_locale_user')) {
67
            $localeList['user_profil_lang'] = $userLocale;
68
        }
69
70
        // 3. Course locale or user locale if course allows user language
71
        $course = $sessionHandler->get('course');
72
        if ($course instanceof Course) {
73
            $userLocale = $localeList['user_profil_lang'] ?? null;
74
            $courseLocale = $course->getCourseLanguage();
75
76
            $this->courseSettingsManager->setCourse($course);
77
            if ($this->courseSettingsManager->getCourseSettingValue('show_course_in_user_language') === '1' && $userLocale) {
78
                $localeList['course_lang'] = $userLocale;
79
            } elseif ($courseLocale) {
80
                $localeList['course_lang'] = $courseLocale;
81
            }
82
        }
83
84
        // 4. Locale selected manually via URL
85
        if ($localeFromUrl = $sessionHandler->get('_selected_locale')) {
86
            $localeList['user_selected_lang'] = $localeFromUrl;
87
        }
88
89
        // 5. Resolve locale based on configured language priorities
90
        foreach ([
91
                     'language_priority_1',
92
                     'language_priority_2',
93
                     'language_priority_3',
94
                     'language_priority_4',
95
                 ] as $settingKey) {
96
            $priority = $this->settingsManager->getSetting("language.$settingKey");
97
            if (!empty($priority) && !empty($localeList[$priority])) {
98
                return $localeList[$priority];
99
            }
100
        }
101
102
        // 6. Fallback order if priorities are not defined
103
        foreach (['platform_lang', 'user_profil_lang', 'course_lang', 'user_selected_lang'] as $key) {
104
            if (!empty($localeList[$key])) {
105
                return $localeList[$key];
106
            }
107
        }
108
109
        // 7. Final fallback to system default
110
        return $this->defaultLocale;
111
    }
112
113
    public static function getSubscribedEvents(): array
114
    {
115
        return [
116
            // must be registered before the default Locale listener
117
            KernelEvents::REQUEST => [['onKernelRequest', 20]],
118
        ];
119
    }
120
}
121