SiteOffSubscriber::getSubscribedEvents()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 0
dl 0
loc 5
rs 10
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\CoreBundle\EventSubscriber;
15
16
use Symfony\Bundle\SecurityBundle\Security;
17
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
18
use Symfony\Component\HttpFoundation\JsonResponse;
19
use Symfony\Component\HttpKernel\Event\RequestEvent;
20
use Symfony\Component\HttpKernel\KernelEvents;
21
use Symfony\Component\Routing\RouterInterface;
22
use Twig\Environment;
23
use Zikula\CoreBundle\Response\PlainResponse;
24
25
class SiteOffSubscriber implements EventSubscriberInterface
26
{
27
    public function __construct(
28
        private readonly Security $security,
29
        private readonly RouterInterface $router,
30
        private readonly Environment $twig,
31
        private readonly bool $maintenanceModeEnabled,
32
        private readonly ?string $maintenanceReason
33
    ) {
34
    }
35
36
    public static function getSubscribedEvents(): array
37
    {
38
        return [
39
            // priority set high to catch request before other subscribers
40
            KernelEvents::REQUEST => ['onKernelRequestSiteOff', 110],
41
        ];
42
    }
43
44
    public function onKernelRequestSiteOff(RequestEvent $event): void
45
    {
46
        if (!$this->maintenanceModeEnabled) {
47
            return;
48
        }
49
50
        if (!$event->isMainRequest()) {
51
            return;
52
        }
53
54
        $response = $event->getResponse();
55
        $request = $event->getRequest();
56
        $this->router->getContext()->setBaseUrl($request->getBaseUrl());
57
        try {
58
            $routeInfo = $this->router->match($request->getPathInfo());
59
        } catch (\Exception) {
60
            return;
61
        }
62
        if ('nucleos_user_security_login' === $routeInfo['_route']) {
63
            return;
64
        }
65
        if ($response instanceof PlainResponse
66
            || $response instanceof JsonResponse
67
            || $request->isXmlHttpRequest()) {
68
            return;
69
        }
70
71
        if ($this->security->isGranted('ROLE_ADMIN')) {
72
            return;
73
        }
74
75
        $hasOnlyBasicAccess = !$this->security->isGranted('IS_AUTHENTICATED');
76
        if ($hasOnlyBasicAccess && $request->hasSession() && null !== $request->getSession()) {
77
            $request->getSession()->invalidate(); // logout
78
        }
79
        $response = new PlainResponse();
80
        $response->headers->add(['HTTP/1.1 503 Service Unavailable']);
81
        $response->setStatusCode(503);
82
        $content = $this->twig->render('@Core/System/siteoff.html.twig', [
83
            'reason' => $this->maintenanceReason,
84
        ]);
85
        $response->setContent($content);
86
        $event->setResponse($response);
87
        $event->stopPropagation();
88
    }
89
}
90