Completed
Push — master ( 91fdab...75a7b9 )
by
unknown
13:37
created

AdminBundle/EventListener/ToolbarListener.php (1 issue)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
namespace Kunstmaan\AdminBundle\EventListener;
4
5
use Kunstmaan\AdminBundle\Helper\AdminRouteHelper;
6
use Kunstmaan\AdminBundle\Helper\Toolbar\DataCollector;
7
use Symfony\Component\DependencyInjection\ContainerInterface;
8
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
9
use Symfony\Component\HttpFoundation\Request;
10
use Symfony\Component\HttpFoundation\Response;
11
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
12
use Symfony\Component\HttpKernel\HttpKernel;
13
use Symfony\Component\HttpKernel\KernelEvents;
14
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
15
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
16
use Symfony\Component\Security\Core\Authorization\AuthorizationChecker;
17
use Symfony\Component\Security\Guard\Token\PostAuthenticationGuardToken;
18
19
class ToolbarListener implements EventSubscriberInterface
20
{
21
    const DISABLED = 1;
22
23
    const ENABLED = 2;
24
25
    /**
26
     * @var \Twig_Environment
27
     */
28
    protected $twig;
29
30
    /**
31
     * @var UrlGeneratorInterface
32
     */
33
    protected $urlGenerator;
34
35
    /**
36
     * @var DataCollector
37
     */
38
    protected $dataCollector;
39
40
    /**
41
     * @var AuthorizationChecker
42
     */
43
    protected $authorizationChecker;
44
45
    /**
46
     * @var TokenStorageInterface
47
     */
48
    protected $tokenStorage;
49
50
    /**
51
     * @var bool
52
     */
53
    protected $enabled;
54
55
    /**
56
     * @var ContainerInterface
57
     */
58
    private $container;
59
60
    /**
61
     * @var AdminRouteHelper
62
     */
63
    protected $adminRouteHelper;
64
65
    /**
66
     * @var array
67
     */
68
    protected $providerKeys;
69
70
    /**
71
     * @var array
72
     */
73
    protected $adminFirewallName;
74
75
    /**
76
     * ToolbarListener constructor.
77
     *
78
     * @param \Twig_Environment     $twig
79
     * @param UrlGeneratorInterface $urlGenerator
80
     * @param DataCollector         $dataCollector
81
     * @param AuthorizationChecker  $authorizationChecker
82
     * @param TokenStorageInterface $tokenStorage
83
     * @param bool                  $enabled
84
     * @param ContainerInterface    $container
85
     * @param AdminRouteHelper      $adminRouteHelper
86
     * @param array                 $providerKeys
87
     * @param string                $adminFirewallName
88
     */
89
    public function __construct(
90
        \Twig_Environment $twig,
91
        UrlGeneratorInterface $urlGenerator,
92
        DataCollector $dataCollector,
93
        AuthorizationChecker $authorizationChecker,
94
        TokenStorageInterface $tokenStorage,
95
        $enabled,
96
        ContainerInterface $container,
97
        AdminRouteHelper $adminRouteHelper,
98
        array $providerKeys,
99
        $adminFirewallName = 'main'
100
    ) {
101
        $this->twig = $twig;
102
        $this->urlGenerator = $urlGenerator;
103
        $this->dataCollector = $dataCollector;
104
        $this->authorizationChecker = $authorizationChecker;
105
        $this->tokenStorage = $tokenStorage;
106
        $this->enabled = $enabled;
107
        $this->container = $container;
108
        $this->adminRouteHelper = $adminRouteHelper;
109
        $this->providerKeys = $providerKeys;
110
        $this->adminFirewallName = $adminFirewallName;
0 ignored issues
show
Documentation Bug introduced by
It seems like $adminFirewallName of type string is incompatible with the declared type array of property $adminFirewallName.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
111
    }
112
113
    /**
114
     * @return array
115
     */
116
    public static function getSubscribedEvents()
117
    {
118
        return [
119
            KernelEvents::RESPONSE => ['onKernelResponse', -125],
120
        ];
121
    }
122
123
    /**
124
     * @return bool
125
     */
126
    public function isEnabled()
127
    {
128
        return !$this->container->has('profiler') && $this->enabled;
129
    }
130
131
    /**
132
     * @param FilterResponseEvent $event
133
     */
134
    public function onKernelResponse(FilterResponseEvent $event)
135
    {
136
        if (!$this->isEnabled() || HttpKernel::MASTER_REQUEST !== $event->getRequestType()) {
137
            return;
138
        }
139
140
        $response = $event->getResponse();
141
        $request = $event->getRequest();
142
        $session = $request->getSession();
143
        $url = $event->getRequest()->getRequestUri();
144
        $token = $this->tokenStorage->getToken();
145
146
        if (null !== $token && method_exists($token, 'getProviderKey')) {
147
            $key = $token->getProviderKey();
148
        } else {
149
            $key = $this->adminFirewallName;
150
        }
151
152
        // Only enable toolbar when the kunstmaan_admin.toolbar_firewall_names config value contains the current firewall name.
153
        if (!\in_array($key, $this->providerKeys, false)) {
154
            return false;
155
        }
156
157
        // Only enable toolbar when we can find an authenticated user in the session from the kunstmaan_admin.admin_firewall_name config value.
158
        $authenticated = false;
159
        /** @var PostAuthenticationGuardToken $token */
160
        if ($session->has(sprintf('_security_%s', $this->adminFirewallName))) {
161
            $token = unserialize($session->get(sprintf('_security_%s', $this->adminFirewallName)));
162
            $authenticated = $token->isAuthenticated();
163
        }
164
165
        // Do not capture redirects or modify XML HTTP Requests
166
        if (!$authenticated || !$event->isMasterRequest() || $request->isXmlHttpRequest() || $this->adminRouteHelper->isAdminRoute($url)) {
167
            return;
168
        }
169
170 View Code Duplication
        if ($response->isRedirection() || ($response->headers->has('Content-Type') && false === strpos(
171
                    $response->headers->get('Content-Type'),
172
                    'html'
173
                ))
174
            || 'html' !== $request->getRequestFormat()
175
            || false !== stripos($response->headers->get('Content-Disposition'), 'attachment;')
176
        ) {
177
            return;
178
        }
179
180
        $this->injectToolbar($response, $request);
181
    }
182
183
    /**
184
     * Injects the admin toolbar into the given Response.
185
     *
186
     * @param Response $response A Response instance
187
     */
188
    protected function injectToolbar(Response $response, Request $request)
189
    {
190
        $content = $response->getContent();
191
        $pos = strripos($content, '</body>');
192
193
        if (false !== $pos) {
194
            $toolbar = "\n".str_replace(
195
                    "\n",
196
                    '',
197
                    $this->twig->render(
198
                        '@KunstmaanAdmin/Toolbar/toolbar.html.twig'
199
                        ,
200
                        ['collectors' => $this->dataCollector->getDataCollectors()]
201
                    )
202
                )."\n";
203
            $content = substr($content, 0, $pos).$toolbar.substr($content, $pos);
204
            $response->setContent($content);
205
        }
206
    }
207
}
208