Completed
Push — master ( c13142...c0435c )
by Tobias
02:34
created

src/Api/HttpApi.php (4 issues)

Severity

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
declare(strict_types=1);
4
/*
5
 * This software may be modified and distributed under the terms
6
 * of the MIT license. See the LICENSE file for details.
7
 */
8
9
namespace Billogram\Api;
10
11
use Billogram\Exception\Domain as DomainExceptions;
12
use Billogram\Exception\DomainException;
13
use Billogram\Hydrator\NoopHydrator;
14
use Http\Client\HttpClient;
15
use Billogram\Hydrator\Hydrator;
16
use Billogram\RequestBuilder;
17
use Psr\Http\Message\ResponseInterface;
18
19
/**
20
 * @author Tobias Nyholm <[email protected]>
21
 */
22
abstract class HttpApi
23
{
24
    /**
25
     * @var HttpClient
26
     */
27
    protected $httpClient;
28
    /**
29
     * @var Hydrator
30
     */
31
    protected $hydrator;
32
    /**
33
     * @var RequestBuilder
34
     */
35
    protected $requestBuilder;
36
37
    /**
38
     * @param HttpClient     $httpClient
39
     * @param RequestBuilder $requestBuilder
40
     * @param Hydrator       $hydrator
41
     */
42 13
    public function __construct(HttpClient $httpClient, Hydrator $hydrator, RequestBuilder $requestBuilder)
43
    {
44 13
        $this->httpClient = $httpClient;
45 13
        $this->requestBuilder = $requestBuilder;
46 13
        if (!$hydrator instanceof NoopHydrator) {
47 13
            $this->hydrator = $hydrator;
48
        }
49 13
    }
50
51
    /**
52
     * Send a GET request with query parameters.
53
     *
54
     * @param string $path           Request path
55
     * @param array  $params         GET parameters
56
     * @param array  $requestHeaders Request Headers
57
     *
58
     * @return ResponseInterface
59
     */
60 9
    protected function httpGet(string $path, array $params = [], array $requestHeaders = []): ResponseInterface
61
    {
62 9
        if (count($params) > 0) {
63 9
            $path .= '?'.http_build_query($params);
64
        }
65
66 9
        return $this->httpClient->sendRequest(
67 9
            $this->requestBuilder->create('GET', $path, $requestHeaders)
68
        );
69
    }
70
71
    /**
72
     * Send a POST request with JSON-encoded parameters.
73
     *
74
     * @param string $path           Request path
75
     * @param array  $params         POST parameters to be JSON encoded
76
     * @param array  $requestHeaders Request headers
77
     *
78
     * @return ResponseInterface
79
     */
80 3
    protected function httpPost(string $path, array $params = [], array $requestHeaders = []): ResponseInterface
81
    {
82 3
        return $this->httpPostRaw($path, $this->createJsonBody($params), $requestHeaders);
83
    }
84
85
    /**
86
     * Send a POST request with raw data.
87
     *
88
     * @param string       $path           Request path
89
     * @param array|string $body           Request body
90
     * @param array        $requestHeaders Request headers
91
     *
92
     * @return ResponseInterface
93
     */
94 3
    protected function httpPostRaw(string $path, $body, array $requestHeaders = []): ResponseInterface
95
    {
96 3
        return $response = $this->httpClient->sendRequest(
0 ignored issues
show
$response is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
97 3
            $this->requestBuilder->create('POST', $path, $requestHeaders, $body)
98
        );
99
    }
100
101
    /**
102
     * Send a PUT request with JSON-encoded parameters.
103
     *
104
     * @param string $path           Request path
105
     * @param array  $params         POST parameters to be JSON encoded
106
     * @param array  $requestHeaders Request headers
107
     *
108
     * @return ResponseInterface
109
     */
110 3
    protected function httpPut(string $path, array $params = [], array $requestHeaders = []): ResponseInterface
111
    {
112 3
        return $this->httpClient->sendRequest(
113 3
            $this->requestBuilder->create('PUT', $path, $requestHeaders, $this->createJsonBody($params))
114
        );
115
    }
116
117
    /**
118
     * Send a DELETE request with JSON-encoded parameters.
119
     *
120
     * @param string $path           Request path
121
     * @param array  $params         POST parameters to be JSON encoded
122
     * @param array  $requestHeaders Request headers
123
     *
124
     * @return ResponseInterface
125
     */
126 1
    protected function httpDelete(string $path, array $params = [], array $requestHeaders = []): ResponseInterface
127
    {
128 1
        return $this->httpClient->sendRequest(
129 1
            $this->requestBuilder->create('DELETE', $path, $requestHeaders, $this->createJsonBody($params))
130
        );
131
    }
132
133
    /**
134
     * Create a JSON encoded version of an array of parameters.
135
     *
136
     * @param array $params Request parameters
137
     *
138
     * @return null|string
139
     */
140 7
    private function createJsonBody(array $params)
141
    {
142 7
        return (count($params) === 0) ? null : json_encode($params, empty($params) ? JSON_FORCE_OBJECT : 0);
143
    }
144
145
    /**
146
     * Handle HTTP errors.
147
     *
148
     * Call is controlled by the specific API methods.
149
     *
150
     * @param ResponseInterface $response
151
     *
152
     * @throws DomainException
153
     */
154
    protected function handleErrors(ResponseInterface $response)
155
    {
156
        switch ($response->getStatusCode()) {
157
            case 404:
158
                throw new DomainExceptions\NotFoundException($response->getBody()->__toString());
159
                break;
0 ignored issues
show
break; does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
160
            case 400:
161
                throw new DomainExceptions\ValidationException($response->getBody()->__toString());
162
                break;
0 ignored issues
show
break; does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
163
            default:
164
                throw new DomainExceptions\UnknownErrorException($response->getBody()->__toString());
165
                break;
0 ignored issues
show
break; does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
166
        }
167
    }
168
}
169