Completed
Push — master ( 558007...566e39 )
by Jérémy
23s queued 11s
created

RequestListener::setIgnoreTransaction()   B

Complexity

Conditions 8
Paths 6

Size

Total Lines 17
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 9
dl 0
loc 17
rs 8.4444
c 0
b 0
f 0
cc 8
nc 6
nop 1
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of Ekino New Relic bundle.
7
 *
8
 * (c) Ekino - Thomas Rabaix <[email protected]>
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 Ekino\NewRelicBundle\Listener;
15
16
use Ekino\NewRelicBundle\NewRelic\Config;
17
use Ekino\NewRelicBundle\NewRelic\NewRelicInteractorInterface;
18
use Ekino\NewRelicBundle\TransactionNamingStrategy\TransactionNamingStrategyInterface;
19
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
20
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
0 ignored issues
show
Bug introduced by
The type Symfony\Component\HttpKe...\Event\GetResponseEvent 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...
21
use Symfony\Component\HttpKernel\Event\ResponseEvent;
22
use Symfony\Component\HttpKernel\HttpKernelInterface;
23
use Symfony\Component\HttpKernel\KernelEvents;
24
25
class RequestListener implements EventSubscriberInterface
26
{
27
    private $ignoredRoutes;
28
    private $ignoredPaths;
29
    private $config;
30
    private $interactor;
31
    private $transactionNamingStrategy;
32
    private $symfonyCache;
33
34
    public function __construct(
35
        Config $config,
36
        NewRelicInteractorInterface $interactor,
37
        array $ignoreRoutes,
38
        array $ignoredPaths,
39
        TransactionNamingStrategyInterface $transactionNamingStrategy,
40
        bool $symfonyCache = false
41
    ) {
42
        $this->config = $config;
43
        $this->interactor = $interactor;
44
        $this->ignoredRoutes = $ignoreRoutes;
45
        $this->ignoredPaths = $ignoredPaths;
46
        $this->transactionNamingStrategy = $transactionNamingStrategy;
47
        $this->symfonyCache = $symfonyCache;
48
    }
49
50
    public static function getSubscribedEvents(): array
51
    {
52
        return [
53
            KernelEvents::REQUEST => [
54
                 ['setApplicationName', 255],
55
                 ['setIgnoreTransaction', 31],
56
                 ['setTransactionName', -10],
57
            ],
58
        ];
59
    }
60
61
    /**
62
     * @param GetResponseEvent|ResponseEvent $event
63
     */
64
    public function setApplicationName($event): void
65
    {
66
        if (!$event instanceof GetResponseEvent && !$event instanceof ResponseEvent) {
0 ignored issues
show
introduced by
$event is always a sub-type of Symfony\Component\HttpKernel\Event\ResponseEvent.
Loading history...
67
            throw new \InvalidArgumentException(\sprintf('Expected instance of type %s, %s given', \class_exists(ResponseEvent::class) ? ResponseEvent::class : GetResponseEvent::class, \is_object($event) ? \get_class($event) : \gettype($event)));
68
        }
69
70
        if (!$this->isEventValid($event)) {
71
            return;
72
        }
73
74
        $appName = $this->config->getName();
75
76
        if (!$appName) {
77
            return;
78
        }
79
80
        if ($this->symfonyCache) {
81
            $this->interactor->startTransaction($appName);
82
        }
83
84
        // Set application name if different from ini configuration
85
        if ($appName !== \ini_get('newrelic.appname')) {
86
            $this->interactor->setApplicationName($appName, $this->config->getLicenseKey(), $this->config->getXmit());
87
        }
88
    }
89
90
    /**
91
     * @param GetResponseEvent|ResponseEvent $event
92
     */
93
    public function setTransactionName($event): void
94
    {
95
        if (!$event instanceof GetResponseEvent && !$event instanceof ResponseEvent) {
0 ignored issues
show
introduced by
$event is always a sub-type of Symfony\Component\HttpKernel\Event\ResponseEvent.
Loading history...
96
            throw new \InvalidArgumentException(\sprintf('Expected instance of type %s, %s given', \class_exists(ResponseEvent::class) ? ResponseEvent::class : GetResponseEvent::class, \is_object($event) ? \get_class($event) : \gettype($event)));
97
        }
98
99
        if (!$this->isEventValid($event)) {
100
            return;
101
        }
102
103
        $transactionName = $this->transactionNamingStrategy->getTransactionName($event->getRequest());
104
105
        $this->interactor->setTransactionName($transactionName);
106
    }
107
108
    /**
109
     * @param GetResponseEvent|ResponseEvent $event
110
     */
111
    public function setIgnoreTransaction($event): void
112
    {
113
        if (!$event instanceof GetResponseEvent && !$event instanceof ResponseEvent) {
0 ignored issues
show
introduced by
$event is always a sub-type of Symfony\Component\HttpKernel\Event\ResponseEvent.
Loading history...
114
            throw new \InvalidArgumentException(\sprintf('Expected instance of type %s, %s given', \class_exists(ResponseEvent::class) ? ResponseEvent::class : GetResponseEvent::class, \is_object($event) ? \get_class($event) : \gettype($event)));
115
        }
116
117
        if (!$this->isEventValid($event)) {
118
            return;
119
        }
120
121
        $request = $event->getRequest();
122
        if (\in_array($request->get('_route'), $this->ignoredRoutes, true)) {
123
            $this->interactor->ignoreTransaction();
124
        }
125
126
        if (\in_array($request->getPathInfo(), $this->ignoredPaths, true)) {
127
            $this->interactor->ignoreTransaction();
128
        }
129
    }
130
131
    /**
132
     * Make sure we should consider this event. Example: make sure it is a master request.
133
     *
134
     * @param GetResponseEvent|ResponseEvent $event
135
     */
136
    private function isEventValid($event): bool
137
    {
138
        if (!$event instanceof GetResponseEvent && !$event instanceof ResponseEvent) {
0 ignored issues
show
introduced by
$event is always a sub-type of Symfony\Component\HttpKernel\Event\ResponseEvent.
Loading history...
139
            throw new \InvalidArgumentException(\sprintf('Expected instance of type %s, %s given', \class_exists(ResponseEvent::class) ? ResponseEvent::class : GetResponseEvent::class, \is_object($event) ? \get_class($event) : \gettype($event)));
140
        }
141
142
        return HttpKernelInterface::MASTER_REQUEST === $event->getRequestType();
143
    }
144
}
145