Passed
Push — main ( b15a24...935ae5 )
by Axel
04:15
created

UserEventSubscriber::setLocale()   B

Complexity

Conditions 9
Paths 24

Size

Total Lines 31
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 9
eloc 19
nc 24
nop 1
dl 0
loc 31
rs 8.0555
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the Zikula package.
7
 *
8
 * Copyright Zikula - https://ziku.la/
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
namespace Zikula\UsersBundle\EventSubscriber;
15
16
use Symfony\Component\DependencyInjection\Attribute\Autowire;
17
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
18
use Symfony\Component\HttpFoundation\RequestStack;
19
use Symfony\Component\HttpKernel\Event\ExceptionEvent;
20
use Symfony\Component\HttpKernel\KernelEvents;
21
use Symfony\Component\Routing\RouterInterface;
22
use Zikula\UsersBundle\Entity\User;
23
use Zikula\UsersBundle\Event\UserPostLoginSuccessEvent;
0 ignored issues
show
Bug introduced by
The type Zikula\UsersBundle\Event\UserPostLoginSuccessEvent was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
24
use Zikula\UsersBundle\Event\UserPostLogoutSuccessEvent;
0 ignored issues
show
Bug introduced by
The type Zikula\UsersBundle\Event...rPostLogoutSuccessEvent was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
25
26
class UserEventSubscriber implements EventSubscriberInterface
27
{
28
    public function __construct(
29
        private readonly RequestStack $requestStack,
30
        private readonly RouterInterface $router,
31
        #[Autowire('%kernel.environment%')]
32
        private readonly string $environment
33
    ) {
34
    }
35
36
    public static function getSubscribedEvents(): array
37
    {
38
        return [
39
            UserPostLogoutSuccessEvent::class => ['clearUsersNamespace'],
40
            UserPostLoginSuccessEvent::class => ['setLocale'],
41
            KernelEvents::EXCEPTION => ['clearUsersNamespace'],
42
        ];
43
    }
44
45
    /**
46
     * Set the locale in the session based on previous user selection after successful login.
47
     *
48
     * @see \Zikula\Bundle\CoreBundle\EventSubscriber\LocaleSubscriber
49
     */
50
    public function setLocale(UserPostLoginSuccessEvent $event): void
51
    {
52
        /** @var User $userEntity */
53
        $userEntity = $event->getUser();
54
        $locale = $userEntity->getLocale();
55
        if (empty($locale)) {
56
            return;
57
        }
58
59
        $request = $this->requestStack->getCurrentRequest();
60
        if (null === $request) {
61
            return;
62
        }
63
64
        $url = $event->getRedirectUrl();
65
        if ('' !== $url) {
66
            $httpRoot = $request->getSchemeAndHttpHost() . $request->getBaseUrl();
67
            if (0 === mb_strpos($url, $httpRoot)) {
68
                $url = str_replace($httpRoot, '', $url);
69
            }
70
            try {
71
                $pathInfo = $this->router->match($url);
72
                if ($pathInfo['_route']) {
73
                    $event->setRedirectUrl($this->router->generate($pathInfo['_route'], ['_locale' => $locale]));
74
                }
75
            } catch (\Exception $exception) {
76
                // ignore
77
            }
78
        }
79
        if ($request->hasSession() && ($session = $request->getSession())) {
80
            $session->set('_locale', $locale);
81
        }
82
    }
83
84
    /**
85
     * Clears the session variable namespace used by the Users bundle.
86
     * Triggered by the 'UserPostLogoutSuccessEvent' and Kernel::EXCEPTION events.
87
     * This is to ensure no leakage of authentication information across sessions or between critical
88
     * errors. This prevents, for example, the login process from becoming confused about its state
89
     * if it detects session variables containing authentication information which might make it think
90
     * that a re-attempt is in progress.
91
     */
92
    public function clearUsersNamespace($event, string $eventName): void
93
    {
94
        $request = $this->requestStack->getCurrentRequest();
95
96
        $doClear = false;
97
        if ($event instanceof ExceptionEvent || KernelEvents::EXCEPTION === $eventName) {
98
            if (null !== $request) {
99
                $doClear = $request->attributes->has('_zkModule') && 'ZikulaUsersBundle' === $request->attributes->get('_zkModule');
100
            }
101
        } else {
102
            // Logout
103
            $doClear = true;
104
        }
105
106
        if ('prod' === $this->environment && $doClear && $request->hasSession() && ($session = $request->getSession())) {
107
            $session->clear();
108
        }
109
    }
110
}
111