Passed
Push — master ( 3aff2b...13d978 )
by Michael
03:06
created

HttpClient::request()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 22
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 13
CRAP Score 3

Importance

Changes 0
Metric Value
dl 0
loc 22
ccs 13
cts 13
cp 1
rs 9.2
c 0
b 0
f 0
cc 3
eloc 13
nc 4
nop 1
crap 3
1
<?php
2
declare(strict_types = 1);
3
4
namespace Mikemirten\Component\JsonApi\HttpClient;
5
6
use GuzzleHttp\Psr7\Stream;
7
use Mikemirten\Component\JsonApi\Document\AbstractDocument;
8
use Mikemirten\Component\JsonApi\Hydrator\DocumentHydrator;
9
use Psr\Http\Message\RequestInterface;
10
use Psr\Http\Message\ResponseInterface;
11
use Psr\Http\Message\StreamInterface;
12
13
/**
14
 * HttpClient
15
 * Supports JsonApi requests & responses
16
 *
17
 * @package Mikemirten\Component\JsonApi\HttpClient
18
 */
19
class HttpClient implements HttpClientInterface
20
{
21
    /**
22
     * @var HttpClientInterface
23
     */
24
    protected $client;
25
26
    /**
27
     * @var DocumentHydrator
28
     */
29
    protected $hydrator;
30
31
    /**
32
     * HttpClient constructor.
33
     *
34
     * @param HttpClientInterface $client
35
     * @param DocumentHydrator    $hydrator
36
     */
37 3
    public function __construct(HttpClientInterface $client, DocumentHydrator $hydrator)
38
    {
39 3
        $this->client   = $client;
40 3
        $this->hydrator = $hydrator;
41 3
    }
42
43
    /**
44
     * {@inheritdoc}
45
     */
46 3
    public function request(RequestInterface $request): ResponseInterface
47
    {
48 3
        if ($request instanceof JsonApiRequest) {
49 1
            $document = $request->getDocument();
50 1
            $stream   = $this->documentToStream($document);
51 1
            $request  = $request->withBody($stream);
52
        }
53
54 3
        $response = $this->client->request($request);
55
56 3
        if (in_array('application/vnd.api+json', $response->getHeader('Content-Type'), true)) {
57 1
            $stream = $response->getBody();
58
59 1
            return new JsonApiResponse(
60 1
                $response->getStatusCode(),
61 1
                $response->getHeaders(),
62 1
                $this->streamToDocument($stream)
63
            );
64
        }
65
66 2
        return $response;
67
    }
68
69
    /**
70
     * Create a JsonApi document by serialized data from stream
71
     *
72
     * @param  StreamInterface $stream
73
     * @return AbstractDocument
74
     */
75 1
    protected function streamToDocument(StreamInterface $stream): AbstractDocument
76
    {
77 1
        $content = $stream->getContents();
78 1
        $decoded = json_decode($content);
79
80 1
        if (json_last_error() !== JSON_ERROR_NONE) {
81
            throw new \RuntimeException('Decoding error: "' . json_last_error_msg() . '""');
82
        }
83
84 1
        return $this->hydrator->hydrate($decoded);
85
    }
86
87
    /**
88
     * Create a stream contains serialized JsonApi-document
89
     *
90
     * @param  AbstractDocument $document
91
     * @return StreamInterface
92
     */
93 1
    protected function documentToStream(AbstractDocument $document): StreamInterface
94
    {
95 1
        $encoded = json_encode($document->toArray());
96
97 1
        if (json_last_error() !== JSON_ERROR_NONE) {
98
            throw new \RuntimeException('Encoding error: "' . json_last_error_msg() . '""');
99
        }
100
101 1
        $stream = fopen('php://memory', 'r+');
102
103 1
        fwrite($stream, $encoded);
104 1
        fseek($stream, 0);
105
106 1
        return new Stream($stream);
107
    }
108
}