Passed
Branch master (203e41)
by Nate
01:56
created

HttpClientCall   A

Complexity

Total Complexity 11

Size/Duplication

Total Lines 147
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 4

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 11
lcom 1
cbo 4
dl 0
loc 147
ccs 35
cts 35
cp 1
rs 10
c 0
b 0
f 0

6 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 6 1
A execute() 0 6 1
A enqueue() 0 20 3
A wait() 0 4 1
A request() 0 8 2
A createResponse() 0 13 3
1
<?php
2
/*
3
 * Copyright (c) Nate Brunette.
4
 * Distributed under the MIT License (http://opensource.org/licenses/MIT)
5
 */
6
7
declare(strict_types=1);
8
9
namespace Tebru\Retrofit\Internal;
10
11
use Psr\Http\Message\RequestInterface;
12
use Psr\Http\Message\ResponseInterface;
13
use Tebru\Retrofit\Call;
14
use Tebru\Retrofit\HttpClient;
15
use Tebru\Retrofit\Response;
16
use Throwable;
17
18
/**
19
 * Class HttpClientCall
20
 *
21
 * @author Nate Brunette <[email protected]>
22
 */
23
final class HttpClientCall implements Call
24
{
25
    /**
26
     * A retrofit http client implementation
27
     *
28
     * @var HttpClient
29
     */
30
    private $client;
31
32
    /**
33
     * A web service resource as a method model
34
     *
35
     * @var ServiceMethod
36
     */
37
    private $serviceMethod;
38
39
    /**
40
     * The runtime arguments that a request should be constructed with
41
     *
42
     * @var array
43
     */
44
    private $args;
45
46
    /**
47
     * The constructed request
48
     *
49
     * @var RequestInterface
50
     */
51
    private $request;
52
53
    /**
54
     * Constructor
55
     *
56
     * @param HttpClient $client
57
     * @param ServiceMethod $serviceMethod
58
     * @param array $args
59
     */
60 17
    public function __construct(HttpClient $client, ServiceMethod $serviceMethod, array $args)
61
    {
62 17
        $this->client = $client;
63 17
        $this->serviceMethod = $serviceMethod;
64 17
        $this->args = $args;
65 17
    }
66
67
    /**
68
     * Execute request synchronously
69
     *
70
     * A [@see Response] will be returned
71
     *
72
     * @return Response
73
     */
74 12
    public function execute(): Response
75
    {
76 12
        $response = $this->client->send($this->request());
77
78 12
        return $this->createResponse($response);
79
    }
80
81
    /**
82
     * Execute request asynchronously
83
     *
84
     * This method accepts two optional callbacks.
85
     *
86
     * onResponse() will be called for any request that gets a response,
87
     * whether it was successful or not. It will send a [@see Response] as
88
     * the parameter.
89
     *
90
     * onFailure() will be called in the event a network request failed. It
91
     * will send the [@see Throwable] that was encountered.
92
     *
93
     * Example of method signatures:
94
     *
95
     * $call->enqueue(
96
     *     function (\Tebru\Retrofit\Call $call, \Tebru\Retrofit\Response $response) {},
97
     *     function (\Throwable $throwable) {}
98
     * );
99
     *
100
     * @param callable $onResponse On any response
101
     * @param callable $onFailure On any network request failure
102
     * @return Call
103
     * @throws \LogicException
104
     */
105 4
    public function enqueue(?callable $onResponse = null, ?callable $onFailure = null): Call
106
    {
107 4
        $this->client->sendAsync(
108 4
            $this->request(),
109 4
            function (ResponseInterface $response) use ($onResponse) {
110 2
                if ($onResponse !== null) {
111 2
                    $onResponse($this->createResponse($response));
112
                }
113 4
            },
114 4
            function (Throwable $throwable) use ($onFailure) {
115 2
                if ($onFailure === null) {
116 1
                    throw $throwable;
117
                }
118
119 1
                $onFailure($throwable);
120 4
            }
121
        );
122
123 4
        return $this;
124
    }
125
126
    /**
127
     * When making requests asynchronously, call wait() to execute the requests
128
     *
129
     * @return void
130
     */
131 4
    public function wait(): void
132
    {
133 4
        $this->client->wait();
134 3
    }
135
136
    /**
137
     * Get the PSR-7 request
138
     *
139
     * @return RequestInterface
140
     */
141 16
    public function request(): RequestInterface
142
    {
143 16
        if ($this->request === null) {
144 16
            $this->request = $this->serviceMethod->toRequest($this->args);
145
        }
146
147 16
        return $this->request;
148
    }
149
150
    /**
151
     * Create a [@see Response] from a PSR-7 response
152
     *
153
     * @param ResponseInterface $response
154
     * @return RetrofitResponse
155
     */
156 14
    private function createResponse(ResponseInterface $response): RetrofitResponse
157
    {
158 14
        $code = $response->getStatusCode();
159 14
        if ($code >= 200 && $code < 300) {
160 12
            $responseBody = $this->serviceMethod->toResponseBody($response);
161
162 12
            return new RetrofitResponse($response, $responseBody, null);
163
        }
164
165 2
        $errorBody = $this->serviceMethod->toErrorBody($response);
166
167 2
        return new RetrofitResponse($response, null, $errorBody);
168
    }
169
}
170