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 ( 204680...a42ad1 )
by Cees-Jan
10s
created

LoggerMiddleware   A

Complexity

Total Complexity 13

Size/Duplication

Total Lines 153
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Importance

Changes 0
Metric Value
wmc 13
lcom 1
cbo 3
dl 0
loc 153
rs 10
c 0
b 0
f 0

6 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A pre() 0 17 2
A post() 0 19 2
B error() 0 30 4
A iterateHeaders() 0 10 3
A addResponseToContext() 0 8 1
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\Log\LoggerInterface;
10
use React\Promise\CancellablePromiseInterface;
11
use Throwable;
12
use function React\Promise\reject;
13
use function React\Promise\resolve;
14
15
class LoggerMiddleware implements MiddlewareInterface
16
{
17
    const REQUEST  = 'request';
18
    const RESPONSE = 'response';
19
    const ERROR    = 'error';
20
21
    /**
22
     * @var LoggerInterface
23
     */
24
    private $logger;
25
26
    /**
27
     * @var array
28
     */
29
    private $context = [
30
        self::REQUEST => [
31
            'method' => null,
32
            'uri' => null,
33
            'protocol_version' => null,
34
            'headers' => [],
35
        ],
36
        self::RESPONSE => [
37
            'status_code' => null,
38
            'status_reason' => null,
39
            'protocol_version' => null,
40
            'headers' => [],
41
        ],
42
    ];
43
44
    /**
45
     * LogMiddleware constructor.
46
     * @param LoggerInterface $logger
47
     */
48
    public function __construct(LoggerInterface $logger)
49
    {
50
        $this->logger = $logger;
51
    }
52
53
    /**
54
     * @param RequestInterface $request
55
     * @param array $options
56
     * @return CancellablePromiseInterface
57
     *
58
     * @Last()
59
     */
60
    public function pre(
61
        RequestInterface $request,
62
        string $transactionId,
63
        array $options = []
64
    ): CancellablePromiseInterface {
65
        if (!isset($options[self::class][Options::LEVEL])) {
66
            return resolve($request);
67
        }
68
69
        $this->context[$transactionId][self::REQUEST]['method'] = $request->getMethod();
70
        $this->context[$transactionId][self::REQUEST]['uri'] = (string)$request->getUri();
71
        $this->context[$transactionId][self::REQUEST]['protocol_version'] = (string)$request->getProtocolVersion();
72
        $ignoreHeaders = $options[self::class][Options::IGNORE_HEADERS] ?? [];
73
        $this->iterateHeaders(self::REQUEST, $transactionId, $request->getHeaders(), $ignoreHeaders);
74
75
        return resolve($request);
76
    }
77
78
    /**
79
     * @param ResponseInterface $response
80
     * @param array $options
81
     * @return CancellablePromiseInterface
82
     *
83
     * @Last()
84
     */
85
    public function post(
86
        ResponseInterface $response,
87
        string $transactionId,
88
        array $options = []
89
    ): CancellablePromiseInterface {
90
        if (!isset($options[self::class][Options::LEVEL])) {
91
            unset($this->context[$transactionId]);
92
            return resolve($response);
93
        }
94
95
        $message = 'Request ' . $transactionId . ' completed.';
96
97
        $this->addResponseToContext($response, $transactionId, $options);
98
99
        $this->logger->log($options[self::class][Options::LEVEL], $message, $this->context[$transactionId]);
100
        unset($this->context[$transactionId]);
101
102
        return resolve($response);
103
    }
104
105
    /**
106
     * @param Throwable $throwable
107
     * @param array $options
108
     * @return CancellablePromiseInterface
109
     *
110
     * @Last()
111
     */
112
    public function error(
113
        Throwable $throwable,
114
        string $transactionId,
115
        array $options = []
116
    ): CancellablePromiseInterface {
117
        if (!isset($options[self::class][Options::ERROR_LEVEL])) {
118
            unset($this->context[$transactionId]);
119
            return reject($throwable);
120
        }
121
122
        $message = $throwable->getMessage();
123
124
        $response = null;
125
        if (method_exists($throwable, 'getResponse')) {
126
            $response = $throwable->getResponse();
127
        }
128
        if ($response instanceof ResponseInterface) {
129
            $this->addResponseToContext($response, $transactionId, $options);
130
        }
131
132
        $this->context[$transactionId][self::ERROR]['code']  = $throwable->getCode();
133
        $this->context[$transactionId][self::ERROR]['file']  = $throwable->getFile();
134
        $this->context[$transactionId][self::ERROR]['line']  = $throwable->getLine();
135
        $this->context[$transactionId][self::ERROR]['trace'] = $throwable->getTraceAsString();
136
137
        $this->logger->log($options[self::class][Options::ERROR_LEVEL], $message, $this->context[$transactionId]);
138
        unset($this->context[$transactionId]);
139
140
        return reject($throwable);
141
    }
142
143
    /**
144
     * @param string $prefix
145
     * @param array $headers
146
     * @param array $ignoreHeaders
147
     */
148
    protected function iterateHeaders(string $prefix, string $transactionId, array $headers, array $ignoreHeaders)
149
    {
150
        foreach ($headers as $header => $value) {
151
            if (in_array($header, $ignoreHeaders)) {
152
                continue;
153
            }
154
155
            $this->context[$transactionId][$prefix]['headers'][$header] = $value;
156
        }
157
    }
158
159
    private function addResponseToContext(ResponseInterface $response, string $transactionId, array $options)
160
    {
161
        $this->context[$transactionId][self::RESPONSE]['status_code']      = $response->getStatusCode();
162
        $this->context[$transactionId][self::RESPONSE]['status_reason']    = $response->getReasonPhrase();
163
        $this->context[$transactionId][self::RESPONSE]['protocol_version'] = $response->getProtocolVersion();
164
        $ignoreHeaders = $options[self::class][Options::IGNORE_HEADERS] ?? [];
165
        $this->iterateHeaders(self::RESPONSE, $transactionId, $response->getHeaders(), $ignoreHeaders);
166
    }
167
}
168