GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Push — master ( bbeb53...693765 )
by Cees-Jan
110:07 queued 70:16
created

LoggerMiddleware::post()   A

Complexity

Conditions 5
Paths 5

Size

Total Lines 26

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 5.1158

Importance

Changes 0
Metric Value
dl 0
loc 26
ccs 10
cts 12
cp 0.8333
rs 9.1928
c 0
b 0
f 0
cc 5
nc 5
nop 3
crap 5.1158
1
<?php declare(strict_types=1);
2
3
namespace ApiClients\Middleware\Log;
4
5
use ApiClients\Foundation\Middleware\Annotation\Last;
6
use ApiClients\Foundation\Middleware\MiddlewareInterface;
7
use Psr\Http\Message\RequestInterface;
8
use Psr\Http\Message\ResponseInterface;
9
use Psr\Http\Message\UriInterface;
10
use Psr\Log\LoggerInterface;
11
use React\Promise\CancellablePromiseInterface;
12
use Throwable;
13
use function React\Promise\reject;
14
use function React\Promise\resolve;
15
16
class LoggerMiddleware implements MiddlewareInterface
17
{
18
    private const REQUEST  = 'request';
19
    private const RESPONSE = 'response';
20
    private const ERROR    = 'error';
21
22
    /**
23
     * @var LoggerInterface
24
     */
25
    private $logger;
26
27
    private $context = [];
28
29 4
    public function __construct(LoggerInterface $logger)
30
    {
31 4
        $this->logger = $logger;
32 4
    }
33
34
    /**
35
     * @Last()
36
     */
37 4
    public function pre(
38
        RequestInterface $request,
39
        string $transactionId,
40
        array $options = []
41
    ): CancellablePromiseInterface {
42 4
        if (!isset($options[self::class][Options::LEVEL]) && !isset($options[self::class][Options::ERROR_LEVEL])) {
43 1
            return resolve($request);
44
        }
45
46 3
        $this->context[$transactionId][self::REQUEST]['method'] = $request->getMethod();
47 3
        $this->context[$transactionId][self::REQUEST]['uri'] = (string)$this->stripQueryItems(
48 3
            $request->getUri(),
49 3
            $options
50
        );
51 3
        $this->context[$transactionId][self::REQUEST]['protocol_version'] = (string)$request->getProtocolVersion();
52 3
        $ignoreHeaders = $options[self::class][Options::IGNORE_HEADERS] ?? [];
53 3
        $this->context[$transactionId] = $this->iterateHeaders(
54 3
            $this->context[$transactionId],
55 3
            self::REQUEST,
56 3
            $request->getHeaders(),
57 3
            $ignoreHeaders
58
        );
59
60 3
        if (!isset($options[self::class][Options::URL_LEVEL])) {
61 2
            return resolve($request);
62
        }
63
64 1
        $message = 'Requesting: ' . $this->context[$transactionId][self::REQUEST]['uri'];
65 1
        $this->logger->log($options[self::class][Options::URL_LEVEL], $message, $this->context[$transactionId]);
66
67 1
        return resolve($request);
68
    }
69
70
    /**
71
     * @Last()
72
     */
73 2
    public function post(
74
        ResponseInterface $response,
75
        string $transactionId,
76
        array $options = []
77
    ): CancellablePromiseInterface {
78 2
        if (!isset($this->context[$transactionId])) {
79 1
            return resolve($response);
80
        }
81
82 1
        $context = $this->context[$transactionId];
83 1
        if (!isset($options[self::class][Options::LEVEL]) && !isset($options[self::class][Options::ERROR_LEVEL])) {
84
            unset($this->context[$transactionId]);
85
        }
86
87 1
        if (!isset($options[self::class][Options::LEVEL])) {
88
            return resolve($response);
89
        }
90
91 1
        $message = 'Request ' . $transactionId . ' completed.';
92
93 1
        $context = $this->addResponseToContext($context, $response, $options);
94
95 1
        $this->logger->log($options[self::class][Options::LEVEL], $message, $context);
96
97 1
        return resolve($response);
98
    }
99
100
    /**
101
     * @Last()
102
     */
103 3
    public function error(
104
        Throwable $throwable,
105
        string $transactionId,
106
        array $options = []
107
    ): CancellablePromiseInterface {
108 3
        if (!isset($this->context[$transactionId])) {
109 1
            return reject($throwable);
110
        }
111
112 2
        $context = $this->context[$transactionId];
113 2
        unset($this->context[$transactionId]);
114
115 2
        if (!isset($options[self::class][Options::ERROR_LEVEL])) {
116
            return reject($throwable);
117
        }
118
119 2
        $message = $throwable->getMessage();
120
121 2
        $response = null;
122 2
        if (method_exists($throwable, 'getResponse')) {
123 1
            $response = $throwable->getResponse();
124
        }
125 2
        if ($response instanceof ResponseInterface) {
126 1
            $context = $this->addResponseToContext($context, $response, $options);
127
        }
128
129 2
        $context[self::ERROR]['code']  = $throwable->getCode();
130 2
        $context[self::ERROR]['file']  = $throwable->getFile();
131 2
        $context[self::ERROR]['line']  = $throwable->getLine();
132 2
        $context[self::ERROR]['trace'] = $throwable->getTraceAsString();
133
134 2
        if (method_exists($throwable, 'getContext')) {
135
            $context[self::ERROR]['context'] = $throwable->getContext();
136
        }
137
138 2
        $this->logger->log($options[self::class][Options::ERROR_LEVEL], $message, $context);
139
140 2
        return reject($throwable);
141
    }
142
143 3
    protected function iterateHeaders(
144
        array $context,
145
        string $prefix,
146
        array $headers,
147
        array $ignoreHeaders
148
    ): array {
149 3
        foreach ($headers as $header => $value) {
150 3
            if (in_array($header, $ignoreHeaders, true)) {
151 3
                continue;
152
            }
153
154 3
            $context[$prefix]['headers'][$header] = $value;
155
        }
156
157 3
        return $context;
158
    }
159
160 2
    private function addResponseToContext(
161
        array $context,
162
        ResponseInterface $response,
163
        array $options
164
    ): array {
165 2
        $context[self::RESPONSE]['status_code']      = $response->getStatusCode();
166 2
        $context[self::RESPONSE]['status_reason']    = $response->getReasonPhrase();
167 2
        $context[self::RESPONSE]['protocol_version'] = $response->getProtocolVersion();
168 2
        $ignoreHeaders = $options[self::class][Options::IGNORE_HEADERS] ?? [];
169 2
        $context  = $this->iterateHeaders(
170 2
            $context,
171 2
            self::RESPONSE,
172 2
            $response->getHeaders(),
173 2
            $ignoreHeaders
174
        );
175
176 2
        return $context;
177
    }
178
179 3
    private function stripQueryItems(UriInterface $uri, array $options): UriInterface
180
    {
181 3
        parse_str($uri->getQuery(), $query);
182 3
        foreach ($options[self::class][Options::IGNORE_URI_QUERY_ITEMS] ?? [] as $item) {
183 1
            unset($query[$item], $query[$item . '[]']);
184
        }
185
186 3
        return $uri->withQuery(http_build_query($query));
187
    }
188
}
189