Response   A
last analyzed

Complexity

Total Complexity 13

Size/Duplication

Total Lines 137
Duplicated Lines 0 %

Test Coverage

Coverage 85.71%

Importance

Changes 4
Bugs 0 Features 1
Metric Value
eloc 30
c 4
b 0
f 1
dl 0
loc 137
ccs 30
cts 35
cp 0.8571
rs 10
wmc 13

8 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 11 1
A getHeader() 0 3 2
A parseRawResponse() 0 20 3
A getRawData() 0 3 1
A getHeaders() 0 3 1
A getStatusCode() 0 3 1
A checkTransportError() 0 4 3
A getReasonPhrase() 0 3 1
1
<?php
2
/**
3
 * ActiveRecord for API
4
 *
5
 * @link      https://github.com/hiqdev/yii2-hiart
6
 * @package   yii2-hiart
7
 * @license   BSD-3-Clause
8
 * @copyright Copyright (c) 2015-2019, HiQDev (http://hiqdev.com/)
9
 */
10
11
namespace hiqdev\hiart\curl;
12
13
use hiqdev\hiart\AbstractRequest;
14
use hiqdev\hiart\AbstractResponse;
15
use hiqdev\hiart\ResponseErrorException;
16
17
/**
18
 * Class Response represents response through cURL library.
19
 */
20
class Response extends AbstractResponse
21
{
22
    /**
23
     * @var string
24
     */
25
    protected $rawData;
26
27
    /**
28
     * @var array[]
29
     */
30
    protected $headers = [];
31
32
    /**
33
     * @var string
34
     */
35
    protected $statusCode;
36
37
    /**
38
     * @var string
39
     */
40
    protected $reasonPhrase;
41
42
    /**
43
     * Response constructor.
44
     *
45
     * @param AbstractRequest $request
46
     * @param string $rawBody the raw response, returned by `curl_exec()` method
47
     * @param array $info the cURL information, returned by `curl_getinfo()` method
48
     * @param string $error the cURL error message, if present. Empty string otherwise.
49
     * @param int $errorCode the cURL error code, if present. Integer `0` otherwise.
50
     * @throws ResponseErrorException
51
     */
52 2
    public function __construct(AbstractRequest $request, $rawBody, $info, $error, $errorCode)
53
    {
54 2
        $this->request = $request;
55
56 2
        $this->checkTransportError($error, $errorCode);
57
58 2
        $parsedResponse = $this->parseRawResponse($rawBody, $info);
59 2
        $this->headers = $parsedResponse['headers'];
60 2
        $this->statusCode = $parsedResponse['statusCode'];
61 2
        $this->rawData = $parsedResponse['data'];
62 2
        $this->reasonPhrase = $parsedResponse['reasonPhrase'];
63 2
    }
64
65
    /**
66
     * @return mixed|string
67
     */
68 2
    public function getRawData()
69
    {
70 2
        return $this->rawData;
71
    }
72
73
    /**
74
     * @param string $name the header name
75
     * @return array|null
76
     */
77 2
    public function getHeader($name)
78
    {
79 2
        return isset($this->headers[strtolower($name)]) ? $this->headers[strtolower($name)] : null;
80
    }
81
82
    /**
83
     * {@inheritdoc}
84
     */
85 2
    public function getStatusCode()
86
    {
87 2
        return $this->statusCode;
88
    }
89
90
    /**
91
     * {@inheritdoc}
92
     */
93
    public function getReasonPhrase()
94
    {
95
        return $this->reasonPhrase;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->reasonPhrase returns the type string which is incompatible with the return type mandated by hiqdev\hiart\ResponseInterface::getReasonPhrase() of hiqdev\hiart\ResponseInterface.

In the issue above, the returned value is violating the contract defined by the mentioned interface.

Let's take a look at an example:

interface HasName {
    /** @return string */
    public function getName();
}

class Name {
    public $name;
}

class User implements HasName {
    /** @return string|Name */
    public function getName() {
        return new Name('foo'); // This is a violation of the ``HasName`` interface
                                // which only allows a string value to be returned.
    }
}
Loading history...
96
    }
97
98
    /**
99
     * Parses raw response and returns parsed information.
100
     *
101
     * @param string $data the raw response
102
     * @param array $info the curl information (result of `gurl_getinfo` call)
103
     * @return array array with the following keys will be returned:
104
     *  - data: string, response data;
105
     *  - headers: array, response headers;
106
     *  - statusCode: string, the response status-code;
107
     *  - reasonPhrase: string, the response reason phrase (OK, NOT FOUND, etc)
108
     */
109 2
    protected function parseRawResponse($data, $info)
110
    {
111 2
        $result = [];
112
113 2
        $headerSize = $info['header_size'];
114 2
        $result['data'] = substr($data, $headerSize);
115
116 2
        $rawHeaders = explode("\r\n", substr($data, 0, $headerSize));
117
        // First line is status-code HTTP/1.1 200 OK
118 2
        list(, $result['statusCode'], $result['reasonPhrase']) = explode(' ', array_shift($rawHeaders), 3);
119 2
        foreach ($rawHeaders as $line) {
120 2
            if ($line === '') {
121 2
                continue;
122
            }
123
124 2
            list($key, $value) = explode(': ', $line);
125 2
            $result['headers'][strtolower($key)][] = $value;
126
        }
127
128 2
        return $result;
129
    }
130
131
    /**
132
     * Checks $error and $errorCode for transport errors.
133
     *
134
     * @param string $error the cURL error message, if present. Empty string otherwise.
135
     * @param int $errorCode the cURL error code, if present. Integer `0` otherwise.
136
     * @throws ResponseErrorException when the error is present
137
     */
138 2
    protected function checkTransportError($error, $errorCode)
139
    {
140 2
        if ($error !== '' || $errorCode !== 0) {
141
            throw new ResponseErrorException($error, $this, $errorCode);
142
        }
143 2
    }
144
145
    /**
146
     * Returns array of all headers.
147
     * Key - Header name
148
     * Value - array of header values. For example:.
149
     *
150
     * ```php
151
     * ['Location' => ['http://example.com'], 'Expires' => ['Thu, 01 Jan 1970 00:00:00 GMT']]
152
     * @return array
153
     */
154
    public function getHeaders()
155
    {
156
        return $this->headers;
157
    }
158
}
159