HttpClient   A
last analyzed

Complexity

Total Complexity 16

Size/Duplication

Total Lines 181
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Test Coverage

Coverage 100%

Importance

Changes 12
Bugs 1 Features 5
Metric Value
wmc 16
c 12
b 1
f 5
lcom 1
cbo 3
dl 0
loc 181
ccs 55
cts 55
cp 1
rs 10

9 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A post() 0 4 1
A request() 0 7 1
A createRequest() 0 10 2
A send() 0 18 2
A headerCallback() 0 10 2
A getRequestHeaders() 0 8 2
A addConfigOption() 0 4 1
A buildUri() 0 20 4
1
<?php
2
3
namespace Artstorm\MonkeyLearn\HttpClient;
4
5
class HttpClient implements HttpClientInterface
6
{
7
    /**
8
     * Client config.
9
     *
10
     * @var array
11
     */
12
    protected $config;
13
14
    /**
15
     * Headers returned in the response.
16
     *
17
     * @var array
18
     */
19
    protected $responseHeaders = [];
20
21
    /**
22
     * Assign dependencies.
23
     *
24
     * @param array $config
25
     */
26 20
    public function __construct(array $config = [])
27
    {
28 20
        $this->config = $config;
29 20
    }
30
31
    /**
32
     * Adds an option to config options array
33
     *
34
     * @param  string $option
35
     *
36
     * @return void
37
     */
38 4
    public function addConfigOption($option)
39
    {
40 4
        $this->config['options'][] = $option;
41 4
    }
42
43
    /**
44
     * Make a POST request.
45
     *
46
     * @param  string $path
47
     * @param  mixed  $body
48
     * @param  array  $headers
49
     *
50
     * @return Request
51
     */
52 8
    public function post($path, $body = null, array $headers = [])
53
    {
54 8
        return $this->request($path, $body, 'POST', $headers);
55
    }
56
57
    /**
58
     * Send request with HTTP client.
59
     *
60
     * @param  string $path
61
     * @param  mixed  $body
62
     * @param  string $method
63
     * @param  array  $headers
64
     *
65
     * @return Response
66
     */
67 8
    protected function request($path, $body = null, $method = 'GET', array $headers = [])
68
    {
69 8
        $request = $this->createRequest($method, $path, $body, $headers);
70 8
        $response = $this->send($request);
71
72 8
        return $response;
73
    }
74
75
    /**
76
     * Create request with HTTP client.
77
     *
78
     * @param  string $method
79
     * @param  string $path
80
     * @param  mixed  $body
81
     * @param  array  $headers
82
     *
83
     * @return Request
84
     */
85 8
    protected function createRequest($method, $path, $body = null, array $headers = [])
86
    {
87 8
        $defaultHeaders = isset($this->config['headers']) ? $this->config['headers'] : [];
88 8
        return new Request(
89 8
            $method,
90 8
            $path,
91 8
            array_merge($defaultHeaders, $headers),
92
            $body
93 8
        );
94
    }
95
96
    /**
97
     * Send the request.
98
     *
99
     * @param  Request $request
100
     *
101
     * @return Response
102
     */
103 4
    public function send(Request $request)
104
    {
105 4
        $client = new CurlClient;
106 4
        $client->setOption(CURLOPT_URL, $this->buildUri($request->getPath()));
107 4
        $client->setOption(CURLOPT_RETURNTRANSFER, true);
108 4
        $client->setOption(CURLOPT_HTTPHEADER, $this->getRequestHeaders($request));
109 4
        $client->setOption(CURLOPT_POST, true);
110 4
        $client->setOption(CURLOPT_POSTFIELDS, $request->getBody());
111 4
        $client->setOption(CURLOPT_HEADERFUNCTION, [&$this, 'headerCallback']);
112
113 4
        if (!$result = $client->execute()) {
114 2
            $result = 'cURL Error: '.$client->error();
115 2
        }
116
117 4
        $client->close();
118
119 4
        return new Response(200, $this->responseHeaders, $result);
120
    }
121
122
    /**
123
     * Callback to store response headers.
124
     *
125
     * @param  resource $curl
126
     * @param  string   $header
127
     *
128
     * @return int
129
     */
130 2
    public function headerCallback($curl, $header)
131
    {
132 2
        $pair = explode(': ', $header);
133
        // We're only interested in the headers that forms a pair
134 2
        if (count($pair) == 2) {
135 2
            $this->responseHeaders[reset($pair)] = end($pair);
136 2
        }
137
138 2
        return strlen($header);
139
    }
140
141
    /**
142
     * Prepare the request headers to be sent.
143
     *
144
     * @param  Request $request
145
     * @param  array   $headers
146
     *
147
     * @return array
148
     */
149 4
    protected function getRequestHeaders(Request $request, array $headers = [])
150
    {
151 4
        foreach ($request->getHeaders() as $key => $value) {
152 2
            array_push($headers, sprintf('%s: %s', $key, $value));
153 4
        }
154
155 4
        return $headers;
156
    }
157
158
    /**
159
     * Build uri with possible base uri.
160
     *
161
     * @param  string $uri
162
     *
163
     * @return string
164
     */
165 8
    protected function buildUri($uri)
166
    {
167
        // Prepare any existing options
168 8
        if (array_key_exists('options', $this->config)) {
169 4
            $options = [];
170 4
            foreach ($this->config['options'] as $option) {
171 4
                $options[$option] = '1';
172 4
            }
173
174
            // Append options as querystring
175 4
            $query = http_build_query($options);
176 4
            $uri = $uri.'?'.$query;
177 4
        }
178
179 8
        if (isset($this->config['base_uri'])) {
180 2
            return $this->config['base_uri'].$uri;
181
        }
182
183 6
        return $uri;
184
    }
185
}
186