Test Failed
Push — master ( b43d38...503dcc )
by Zbigniew
06:16
created

SystemRequestSubscriber::onKernelRequest()   B

Complexity

Conditions 5
Paths 5

Size

Total Lines 48

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 29
CRAP Score 5.0009

Importance

Changes 0
Metric Value
dl 0
loc 48
ccs 29
cts 30
cp 0.9667
rs 8.8234
c 0
b 0
f 0
cc 5
nc 5
nop 1
crap 5.0009
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the zibios/sharep.
7
 *
8
 * (c) Zbigniew Ślązak
9
 */
10
11
namespace App\EventSubscriber;
12
13
use App\Entity\Access\User;
14
use App\Entity\System\RequestLog;
15
use App\Entity\System\RequestLogDetail;
16
use App\Enum\Entity\RequestLogTypeEnum;
17
use Doctrine\ORM\EntityManagerInterface;
18
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
19
use Symfony\Component\HttpKernel\Event\ExceptionEvent;
20
use Symfony\Component\HttpKernel\Event\RequestEvent;
21
use Symfony\Component\HttpKernel\Event\ResponseEvent;
22
use Symfony\Component\HttpKernel\KernelEvents;
23
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
24
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
25
26
class SystemRequestSubscriber implements EventSubscriberInterface
27
{
28
    /** @var EntityManagerInterface */
29
    private $entityManager;
30
    /** @var TokenStorageInterface TokenStorageInterface */
31
    private $tokenStorage;
32
    /** @var RequestLog|null */
33
    private $requestLog;
34
    /** @var RequestLogDetail|null */
35
    private $requestLogDetail;
36
37 21
    public function __construct(EntityManagerInterface $entityManager, TokenStorageInterface $tokenStorage)
38
    {
39 21
        $this->entityManager = $entityManager;
40 21
        $this->tokenStorage = $tokenStorage;
41 21
    }
42
43 1
    public static function getSubscribedEvents(): array
44
    {
45
        return [
46
            KernelEvents::REQUEST => [
47 1
                ['onKernelRequest', 0],
48
            ],
49
            KernelEvents::RESPONSE => [
50
                ['onKernelResponse', 0],
51
            ],
52
            KernelEvents::EXCEPTION => [
53
                ['onKernelException', 0],
54
            ],
55
        ];
56
    }
57
58 16
    public function onKernelRequest(RequestEvent $event): void
59
    {
60 16
        if (!$event->isMasterRequest()) {
61 3
            return;
62
        }
63
64 16
        $request = $event->getRequest();
65
66 16
        if ('_wdt' === $request->attributes->get('_route')) {
67
            return;
68
        }
69
70 16
        $member = null;
71 16
        $token = $this->tokenStorage->getToken();
72 16
        if ($token instanceof TokenInterface) {
73
            /** @var User $user */
74 16
            $user = $token->getUser();
75 16
            if ($user instanceof User) {
76 12
                $user = $this->entityManager->find(User::class, $user->getId());
77 12
                $member = $user->getMember();
78
            }
79
        }
80
81 16
        $this->requestLog = new RequestLog(
82 16
            RequestLogTypeEnum::HTTP(),
83 16
            $request->getPathInfo(),
84 16
            new \DateTimeImmutable(),
85
            $member
86
        );
87
88 16
        $this->requestLogDetail = new RequestLogDetail(
89 16
            $this->requestLog,
90 16
            $request->getRequestUri(),
91 16
            json_encode(
92
                [
93 16
                    'query' => $request->query->all(),
94 16
                    'request' => $request->request->all(),
95 16
                    'attributes' => $request->attributes->all(),
96 16
                    'headers' => $request->headers->all(),
97
                ],
98 16
                JSON_THROW_ON_ERROR
99
            )
100
        );
101
102 16
        $this->entityManager->persist($this->requestLog);
103 16
        $this->entityManager->persist($this->requestLogDetail);
104 16
        $this->entityManager->flush();
105 16
    }
106
107 21 View Code Duplication
    public function onKernelResponse(ResponseEvent $event): void
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
108
    {
109 21
        if (null === $this->requestLog) {
110 8
            return;
111
        }
112
113 16
        if (!$event->isMasterRequest()) {
114
            return;
115
        }
116
117 16
        $this->requestLog->setFinishedAt(new \DateTimeImmutable());
118 16
        $this->requestLog->setSuccessful(true);
119
120 16
        $this->entityManager->persist($this->requestLog);
121 16
        $this->entityManager->persist($this->requestLogDetail);
0 ignored issues
show
Bug introduced by
It seems like $this->requestLogDetail can be null; however, persist() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
122 16
        $this->entityManager->flush();
123 16
    }
124
125 3 View Code Duplication
    public function onKernelException(ExceptionEvent $event): void
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
126
    {
127 3
        if (null === $this->requestLog) {
128 3
            return;
129
        }
130
131
        if (!$event->isMasterRequest()) {
132
            return;
133
        }
134
135
        $this->requestLog->setSuccessful(false);
136
137
        $this->entityManager->persist($this->requestLog);
138
        $this->entityManager->persist($this->requestLogDetail);
0 ignored issues
show
Bug introduced by
It seems like $this->requestLogDetail can be null; however, persist() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
139
        $this->entityManager->flush();
140
    }
141
}
142