Passed
Push — master ( e2d128...3c83db )
by Petar
08:36
created

isAdminSiteaccess()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 1
eloc 4
c 1
b 0
f 1
nc 1
nop 1
dl 0
loc 6
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Netgen\Bundle\EzPlatformSiteApiBundle\EventListener;
6
7
use Exception;
8
use eZ\Publish\Core\MVC\ConfigResolverInterface;
9
use eZ\Publish\Core\MVC\Symfony\Routing\Generator\UrlAliasGenerator;
10
use eZ\Publish\Core\MVC\Symfony\Routing\UrlAliasRouter;
11
use eZ\Publish\Core\MVC\Symfony\SiteAccess;
12
use EzSystems\EzPlatformAdminUiBundle\EzPlatformAdminUiBundle;
13
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
14
use Symfony\Component\HttpFoundation\RedirectResponse;
15
use Symfony\Component\HttpFoundation\Request;
16
use Symfony\Component\HttpFoundation\Response;
17
use Symfony\Component\HttpKernel\Controller\ControllerReference;
18
use Symfony\Component\HttpKernel\Event\RequestEvent;
19
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
20
use Symfony\Component\HttpKernel\Fragment\FragmentHandler;
21
use Symfony\Component\HttpKernel\KernelEvents;
22
use Symfony\Component\Routing\RouterInterface;
23
use function class_exists;
24
use function in_array;
25
26
class InternalContentViewRouteListener implements EventSubscriberInterface
27
{
28
    /**
29
     * @var \eZ\Publish\Core\MVC\ConfigResolverInterface
30
     */
31
    private $configResolver;
32
33
    /**
34
     * @var \Symfony\Component\HttpKernel\Fragment\FragmentHandler
35
     */
36
    private $fragmentHandler;
37
38
    /**
39
     * @var \Symfony\Component\Routing\RouterInterface
40
     */
41
    private $router;
42
43
    /**
44
     * @var array
45
     */
46
    private $siteaccessGroups;
47
48
    public function __construct(
49
        ConfigResolverInterface $configResolver,
50
        FragmentHandler $fragmentHandler,
51
        RouterInterface $router,
52
        array $siteaccessGroups
53
    ) {
54
        $this->configResolver = $configResolver;
55
        $this->fragmentHandler = $fragmentHandler;
56
        $this->router = $router;
57
        $this->siteaccessGroups = $siteaccessGroups;
58
    }
59
60
    public static function getSubscribedEvents(): array
61
    {
62
        return [
63
            KernelEvents::REQUEST => ['onKernelRequest', 0],
64
        ];
65
    }
66
67
    public function onKernelRequest(RequestEvent $event): void
68
    {
69
        if (!$event->isMasterRequest()) {
70
            return;
71
        }
72
73
        $request = $event->getRequest();
74
75
        if (!$this->isInternalContentViewRoute($request)) {
76
            return;
77
        }
78
79
        $siteaccess = $request->attributes->get('siteaccess');
80
81
        if (!$siteaccess instanceof SiteAccess || $this->isAdminSiteaccess($siteaccess)) {
82
            return;
83
        }
84
85
        if (!$this->configResolver->getParameter('ng_site_api.enable_internal_view_route')) {
86
            throw new NotFoundHttpException(
87
                'Internal Content view route has been disabled, check your Site API configuration for: "ng_site_api.enable_internal_view_route"'
88
            );
89
        }
90
91
        $event->setResponse($this->getResponse($request));
92
    }
93
94
    private function getResponse(Request $request): Response
95
    {
96
        if ($this->configResolver->getParameter('ng_site_api.redirect_internal_view_route_to_url_alias')) {
97
            return new RedirectResponse($this->generateUrlAlias($request), 308);
98
        }
99
100
        return new Response($this->renderView($request));
101
    }
102
103
    private function renderView(Request $request): ?string
104
    {
105
        $attributes = [
106
            'contentId' => $request->attributes->getInt('contentId'),
107
            'layout' => $request->attributes->getBoolean('layout', true),
108
            'viewType' => 'full',
109
        ];
110
111
        $locationId = $request->attributes->get('locationId');
112
113
        if ($locationId !== null) {
114
            $attributes['locationId'] = (int) $locationId;
115
        }
116
117
        return $this->fragmentHandler->render(
118
            new ControllerReference('ng_content::viewAction', $attributes)
119
        );
120
    }
121
122
    private function isInternalContentViewRoute(Request $request): bool
123
    {
124
        return $request->attributes->get('_route') === UrlAliasGenerator::INTERNAL_CONTENT_VIEW_ROUTE;
125
    }
126
127
    private function isAdminSiteaccess(SiteAccess $siteaccess) : bool
128
    {
129
        return in_array(
130
            $siteaccess->name,
131
            $this->siteaccessGroups[$this->getAdminSiteaccessGroupName()] ?? [],
132
            true
133
        );
134
    }
135
136
    private function getAdminSiteaccessGroupName(): string
137
    {
138
        if (class_exists(EzPlatformAdminUiBundle::class)) {
139
            return EzPlatformAdminUiBundle::ADMIN_GROUP_NAME;
140
        }
141
142
        return 'admin_group';
143
    }
144
145
    private function generateUrlAlias(Request $request): string
146
    {
147
        $parameters = [
148
            'contentId' => $request->attributes->getInt('contentId'),
149
        ];
150
151
        $locationId = $request->attributes->get('locationId');
152
153
        if ($locationId !== null) {
154
            $parameters['locationId'] = (int) $locationId;
155
        }
156
157
        try {
158
            return $this->router->generate(UrlAliasRouter::URL_ALIAS_ROUTE_NAME, $parameters);
159
        } catch (Exception $e) {
160
            throw new NotFoundHttpException('URL alias could not be generated');
161
        }
162
    }
163
}
164