Completed
Push — master ( 62cfcc...2524ae )
by Joel
06:31
created

EventListener/RequestResponseListener.php (2 issues)

Severity
1
<?php
2
3
namespace RedirectionIO\Client\ProxySymfony\EventListener;
4
5
use RedirectionIO\Client\Sdk\Exception\ExceptionInterface;
6
use RedirectionIO\Client\Sdk\Client;
7
use RedirectionIO\Client\Sdk\HttpMessage\Request;
8
use RedirectionIO\Client\Sdk\HttpMessage\Response;
9
use Symfony\Component\HttpFoundation\RedirectResponse as SymfonyRedirectResponse;
10
use Symfony\Component\HttpFoundation\Request as SymfonyRequest;
11
use Symfony\Component\HttpFoundation\Response as SymfonyResponse;
12
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
13
use Symfony\Component\HttpKernel\Event\PostResponseEvent;
14
15
class RequestResponseListener
16
{
17
    private $client;
18
    private $excludedPrefixes;
19
20
    public function __construct(Client $client, array $excludedPrefixes = [])
21
    {
22
        $this->client = $client;
23
        $this->excludedPrefixes = $excludedPrefixes;
24
    }
25
26
    public function onKernelRequest(GetResponseEvent $event)
27
    {
28
        if (!$event->isMasterRequest()) {
29
            return;
30
        }
31
32
        $request = $event->getRequest();
33
34
        if ($this->isExcludedPrefix($request->getPathInfo())) {
35
            return;
36
        }
37
38
        $response = $this->client->findRedirect($this->createSdkRequest($request));
39
        $request->attributes->set('redirectionio_response', $response);
40
41
        if (!$response) {
42
            return;
43
        }
44
45
        410 === $response->getStatusCode()
46
            ? $event->setResponse((new SymfonyResponse())->setStatusCode(410))
47
            : $event->setResponse(new SymfonyRedirectResponse($response->getLocation(), $response->getStatusCode()));
48
    }
49
50
    public function onKernelTerminate(PostResponseEvent $event)
51
    {
52
        if ($this->isExcludedPrefix($event->getRequest()->getPathInfo())) {
53
            return;
54
        }
55
56
        $response = $event->getRequest()->attributes->get('redirectionio_response');
57
58
        if (!$response) {
59
            $symfonyResponse = $event->getResponse();
60
            $location = $symfonyResponse->headers->get('location', null);
61
62
            $response = new Response($event->getResponse()->getStatusCode(), null, $location);
63
        }
64
65
        $request = $this->createSdkRequest($event->getRequest());
66
67
        try {
68
            $this->client->log($request, $response);
69
        } catch (ExceptionInterface $exception) {
70
            // do nothing
71
        }
72
    }
73
74
    private function createSdkRequest(SymfonyRequest $symfonyRequest)
75
    {
76
        return new Request(
77
            $symfonyRequest->getHttpHost(),
78
            $this->getFullPath($symfonyRequest),
79
            $symfonyRequest->headers->get('User-Agent'),
80
            $symfonyRequest->headers->get('Referer'),
81
            $symfonyRequest->getScheme()
82
        );
83
    }
84
85
    private function getFullPath(SymfonyRequest $symfonyRequest)
86
    {
87
        if (null === ($requestUri = $symfonyRequest->getRequestUri())) {
0 ignored issues
show
The condition null === $requestUri = $...equest->getRequestUri() is always false.
Loading history...
88
            return '/';
89
        }
90
91
        if ('' !== $requestUri && '/' !== $requestUri[0]) {
92
            $requestUri = '/'.$requestUri;
93
        }
94
95
        if (null === ($baseUrl = $symfonyRequest->getBaseUrl())) {
0 ignored issues
show
The condition null === $baseUrl = $symfonyRequest->getBaseUrl() is always false.
Loading history...
96
            return $requestUri;
97
        }
98
99
        $pathInfo = substr($requestUri, \strlen($baseUrl));
100
101
        if (false === $pathInfo || '' === $pathInfo) {
102
            return '/';
103
        }
104
105
        return (string) $pathInfo;
106
    }
107
108
    private function isExcludedPrefix($url): bool
109
    {
110
        foreach ($this->excludedPrefixes as $excludedPrefix) {
111
            if (0 === strpos($url, $excludedPrefix)) {
112
                return true;
113
            }
114
        }
115
116
        return false;
117
    }
118
}
119