Passed
Push — master ( f3afa2...91110f )
by Markus
03:19
created

HttpHandler::popHeader()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 4
nc 2
nop 1
dl 0
loc 9
rs 9.6666
c 0
b 0
f 0
1
<?php
2
3
namespace Msschl\Monolog\Handler;
4
5
use Http\Client\HttpClient;
6
use Http\Discovery\HttpClientDiscovery;
7
use Http\Discovery\MessageFactoryDiscovery;
8
use Http\Message\MessageFactory;
9
use Monolog\Formatter\FormatterInterface;
10
use Monolog\Formatter\JsonFormatter;
11
use Monolog\Handler\AbstractProcessingHandler;
12
use Monolog\Logger;
13
14
/**
15
 * This file is part of the msschl\monolog-http-handler package.
16
 *
17
 * Copyright (c) 2018 Markus Schlotbohm
18
 *
19
 * For the full copyright and license information, please view the LICENSE.md
20
 * file that was distributed with this source code.
21
 */
22
class HttpHandler extends AbstractProcessingHandler
23
{
24
25
	/**
26
	 * The http client instance.
27
	 *
28
     * @var \Http\Client\HttpClient
29
     */
30
    protected $client;
31
32
    /**
33
     * The message factory instance.
34
     *
35
     * @var \Http\Message\MessageFactory
36
     */
37
    protected $messageFactory;
38
39
    /**
40
     * The options array.
41
     *
42
     * @var array
43
     */
44
    protected $options = [
45
    	'uri'             => null,
46
    	'method'          => 'GET',
47
    	'headers'         => [
48
    		'Content-Type' => 'application/json'
49
    	],
50
    	'protocolVersion' => '1.1'
51
    ];
52
53
    /**
54
     * Initializes a new instance of the {@see HttpHandler} class.
55
     *
56
     * @param  array                $options The array of options consisting of the uri, method, headers and protocol
57
     *                                       version.
58
     * @param  HttpClient|null      $client  An instance of a psr-7 http client implementation or null when the
59
     *                                       HttpClientDiscovery should be used to find an instance.
60
     * @param  MessageFactory|null  $factory An instance of a psr-7 message factory implementation or null when
61
     *                                       the MessageFactoryDiscovery should be used to find an instance.
62
     * @param  int                  $level   The minimum logging level at which this handler will be triggered.
63
     * @param  boolean              $bubble  Whether the messages that are handled can bubble up the stack or not.
64
     */
65
	public function __construct(
66
		array $options = [],
67
		HttpClient $client = null,
68
		MessageFactory $factory = null,
69
		$level = Logger::DEBUG,
70
		$bubble = true
71
	) {
72
		$this->client = $client ?: HttpClientDiscovery::find();
73
		$this->messageFactory = $factory ?: MessageFactoryDiscovery::find();
74
75
		$this->setOptions($options);
76
77
		parent::__construct($level, $bubble);
78
	}
79
80
	/**
81
	 * Sets the options for the monolog http handler.
82
	 *
83
	 * @param  array $options The array of options.
84
	 * @return self
85
	 */
86
	public function setOptions(array $options)
87
	{
88
		$this->options = array_merge($this->options, $options);
89
90
		return $this;
91
	}
92
93
	/**
94
	 * Sets the uri.
95
	 *
96
	 * @param  string|null $uri Sets the http server uri or null to disable the {@see HttpHandler}.
97
	 * @return self
98
	 */
99
	public function setUri(string $uri = null)
100
	{
101
		$this->options['uri'] = $uri;
102
103
		return $this;
104
	}
105
106
	/**
107
	 * Gets the uri.
108
	 *
109
	 * @return string|null
110
	 */
111
	public function getUri()
112
	{
113
		return $this->options['uri'];
114
	}
115
116
	/**
117
	 * Sets the http method.
118
	 *
119
	 * @param  string $method The http method e.g. 'GET'.
120
	 * @return self
121
	 */
122
	public function setMethod(string $method)
123
	{
124
		$this->options['method'] = $method;
125
126
		return $this;
127
	}
128
129
	/**
130
	 * Gets the http method.
131
	 *
132
	 * @return string
133
	 */
134
	public function getMethod() : string
135
	{
136
		return $this->options['method'] ?? 'GET';
137
	}
138
139
	/**
140
	 * Sets the headers array. Overrides all existing header key and value pairs.
141
	 *
142
	 * @param  array $headers The headers array.
143
	 * @return self
144
	 */
145
	public function setHeaders(array $headers)
146
	{
147
		$this->options['headers'] = $headers;
148
149
		return $this;
150
	}
151
152
	/**
153
	 * Gets the headers.
154
	 *
155
	 * @return array
156
	 */
157
	public function getHeaders() : array
158
	{
159
		return $this->options['headers'] ?? [ 'Content-Type' => 'application/json' ];
160
	}
161
162
	/**
163
	 * Gets a value for a specific header key.
164
	 *
165
	 * @param  string $key The header key.
166
	 * @return string|null
167
	 */
168
	public function getHeader(string $key)
169
	{
170
		return $this->getHeaders()[$key] ?? null;
171
	}
172
173
	/**
174
	 * Pushes a header value onto the headers array.
175
	 *
176
	 * @param  string $key   The header key.
177
	 * @param  string $value The header value.
178
	 * @return self
179
	 */
180
	public function pushHeader(string $key, string $value)
181
	{
182
		$headers = $this->getHeaders();
183
184
		$headers[$key] = $value;
185
186
		$this->setHeaders($headers);
187
188
		return $this;
189
	}
190
191
	/**
192
	 * Pops a header value from the headers array.
193
	 *
194
	 * @param  string $key The header key.
195
	 * @return string|null
196
	 */
197
	public function popHeader(string $key)
198
	{
199
		$value = $this->getHeader($key);
200
201
		if ($value !== null) {
202
			unset($this->options['headers'][$key]);
203
		}
204
205
		return $value;
206
	}
207
208
	/**
209
	 * Sets the http protocol version.
210
	 *
211
	 * @param  string $version The http protocol version.
212
	 * @return self
213
	 */
214
	public function setProtocolVersion(string $version = '1.1')
215
	{
216
		$this->options['protocolVersion'] = $version;
217
218
		return $this;
219
	}
220
221
	/**
222
	 * Gets the http protocol version.
223
	 *
224
	 * @return string
225
	 */
226
	public function getProtocolVersion() : string
227
	{
228
		return $this->options['protocolVersion'] ?? '1.1';
229
	}
230
231
	/**
232
	 * Handles a set of records at once.
233
	 *
234
	 * @param  array  $records The records to handle (an array of record arrays)
235
	 * @return bool
236
	 */
237
	public function handleBatch(array $records)
238
	{
239
		foreach ($records as $key => $record) {
240
	        if ($this->isHandling($record)) {
241
	        	$record = $this->processRecord($record);
242
	    		$records['records'][] = $record;
243
	    	}
244
245
			unset($records[$key]);
246
	    }
247
248
	    $records['formatted'] = $this->getFormatter()->formatBatch($records['records'] ?? []);
249
250
	    $this->write($records);
251
252
	    return false === $this->bubble;
253
	}
254
255
	/**
256
     * Gets the default formatter.
257
     *
258
     * @return \Monolog\Formatter\JsonFormatter
259
     */
260
    protected function getDefaultFormatter() : FormatterInterface
261
    {
262
        return new JsonFormatter();
263
    }
264
265
	/**
266
     * Returns the HTTP adapter.
267
     *
268
     * @return \Http\Client\HttpClient
269
     */
270
    protected function getHttpClient(): HttpClient
271
    {
272
        return $this->client;
273
    }
274
275
    /**
276
     * Returns the message factory.
277
     *
278
     * @return \Http\Message\MessageFactory
279
     */
280
    protected function getMessageFactory(): MessageFactory
281
    {
282
        return $this->messageFactory;
283
    }
284
285
    /**
286
     * Writes the record.
287
     *
288
     * @param  array $record
289
     * @return void
290
     */
291
    protected function write(array $record)
292
    {
293
    	$uri = $this->getUri();
294
295
    	if (empty($uri)) {
296
    		return;
297
    	}
298
299
    	$request = $this->getMessageFactory()->createRequest(
300
    		$this->getMethod(),
301
    		$this->getUri(),
302
    		$this->getHeaders(),
303
    		$record['formatted'],
304
    		$this->getProtocolVersion()
305
    	);
306
307
    	try {
308
    		$this->getHttpClient()->sendRequest($request);
309
    	} catch (\Exception $e) {
310
    		// QUESTION(msschl): How to handle the thrown exceptions???
311
    		return;
312
    	}
313
    }
314
}