Completed
Branch v3-fusion-support (d44c19)
by Steven
03:37
created

HttpTrait   A

Complexity

Total Complexity 19

Size/Duplication

Total Lines 168
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 4

Importance

Changes 0
Metric Value
wmc 19
lcom 2
cbo 4
dl 0
loc 168
rs 10
c 0
b 0
f 0

7 Methods

Rating   Name   Duplication   Size   Complexity  
A appendParametersToUrl() 0 14 3
A getHttpClient() 0 4 1
A getRequest() 0 21 3
A getResponse() 0 10 2
C prepareQueryParams() 0 25 8
A processRequest() 0 6 1
A setHttpClient() 0 6 1
1
<?php
2
3
namespace Stevenmaguire\Yelp\Tool;
4
5
use \Exception;
6
use GuzzleHttp\Client as HttpClient;
7
use GuzzleHttp\Exception\BadResponseException;
8
use GuzzleHttp\Psr7\Request;
9
use GuzzleHttp\Psr7\Uri;
10
use Psr\Http\Message\RequestInterface;
11
use Stevenmaguire\Yelp\Exception\ClientConfigurationException;
12
use Stevenmaguire\Yelp\Exception\HttpException;
13
14
trait HttpTrait
15
{
16
    /**
17
     * API host url
18
     *
19
     * @var string
20
     */
21
    protected $apiHost;
22
23
    /**
24
     * HTTP client
25
     *
26
     * @var GuzzleHttp\Client
27
     */
28
    protected $httpClient;
29
30
    /**
31
     * Prepares and appends parameters, if provided, to the given url.
32
     *
33
     * @param  string  $url
34
     * @param  array   $parameters
35
     * @param  array   $options
36
     *
37
     * @return string
38
     */
39
    protected function appendParametersToUrl($url, array $parameters = array(), array $options = array())
40
    {
41
        $url = rtrim($url, '?');
42
        $queryString = $this->prepareQueryParams($parameters, $options);
43
44
        if ($queryString) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $queryString of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
45
            $uri = new Uri($url);
46
            $existingQuery = $uri->getQuery();
47
            $updatedQuery = empty($existingQuery) ? $queryString : $existingQuery . '&' . $queryString;
48
            $url = (string) $uri->withQuery($updatedQuery);
49
        }
50
51
        return $url;
52
    }
53
54
    /**
55
     * Returns the yelp client's http client to the given http client. Client.
56
     *
57
     * @return  GuzzleHttp\Client|null
58
     */
59
    public function getHttpClient()
60
    {
61
        return $this->httpClient;
62
    }
63
64
    /**
65
     * Creates a PSR-7 Request instance.
66
     *
67
     * @param  null|string $method HTTP method for the request.
68
     * @param  null|string $uri URI for the request.
69
     * @param  array $headers Headers for the message.
70
     * @param  string|resource|StreamInterface $body Message body.
71
     * @param  string $version HTTP protocol version.
72
     *
73
     * @return GuzzleHttp\Psr7\Request
74
     */
75
    public function getRequest(
76
        $method,
77
        $uri,
78
        array $headers = [],
79
        $body = null,
80
        $version = '1.1'
81
    ) {
82
        $uriComponents = parse_url($uri);
83
84
        if (!isset($uriComponents['host'])) {
85
            $uriComponents['host'] = $this->apiHost;
86
        }
87
88
        if (!isset($uriComponents['scheme'])) {
89
            $uriComponents['scheme'] = 'https';
90
        }
91
92
        $uri = (string) Uri::fromParts($uriComponents);
0 ignored issues
show
Security Bug introduced by
It seems like $uriComponents defined by parse_url($uri) on line 82 can also be of type false; however, GuzzleHttp\Psr7\Uri::fromParts() does only seem to accept array, did you maybe forget to handle an error condition?

This check looks for type mismatches where the missing type is false. This is usually indicative of an error condtion.

Consider the follow example

<?php

function getDate($date)
{
    if ($date !== null) {
        return new DateTime($date);
    }

    return false;
}

This function either returns a new DateTime object or false, if there was an error. This is a typical pattern in PHP programming to show that an error has occurred without raising an exception. The calling code should check for this returned false before passing on the value to another function or method that may not be able to handle a false.

Loading history...
93
94
        return new Request($method, $uri, $headers, $body, $version);
95
    }
96
97
    /**
98
     * Sends a request instance and returns a response instance.
99
     *
100
     * WARNING: This method does not attempt to catch exceptions caused by HTTP
101
     * errors! It is recommended to wrap this method in a try/catch block.
102
     *
103
     * @param  RequestInterface $request
104
     * @return ResponseInterface
105
     * @throws Stevenmaguire\Yelp\Exception\HttpException
106
     */
107
    public function getResponse(RequestInterface $request)
108
    {
109
        try {
110
            return $this->getHttpClient()->send($request);
111
        } catch (BadResponseException $e) {
112
            $exception = new HttpException($e->getMessage());
113
114
            throw $exception->setResponseBody($e->getResponse()->getBody());
115
        }
116
    }
117
118
    /**
119
     * Updates query params array to apply yelp specific formatting rules.
120
     *
121
     * @param  array   $params
122
     * @param  array   $options
123
     *
124
     * @return string|null
125
     */
126
    protected function prepareQueryParams($params = [], $options = [])
127
    {
128
        array_walk($params, function ($value, $key) use (&$params, $options) {
129
            if (is_bool($value)) {
130
                $params[$key] = $value ? 'true' : 'false';
131
            }
132
            if (isset($options['to_csv'])) {
133
                if (!is_array($options['to_csv'])) {
134
                     $options['to_csv'] = explode(',', $options['to_csv']);
135
                }
136
137
                if (in_array($key, $options['to_csv']) && is_array($value)) {
138
                    $params[$key] = implode(',', $value);
139
                }
140
            }
141
        });
142
143
        $queryString = http_build_query($params);
144
145
        if (strlen($queryString)) {
146
            return $queryString;
147
        }
148
149
        return null;
150
    }
151
152
    /**
153
     * Makes a request to the Yelp API and returns the response
154
     *
155
     * @param    string $path    The path of the APi after the domain
0 ignored issues
show
Bug introduced by
There is no parameter named $path. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
156
     *
157
     * @return   stdClass The JSON response from the request
158
     * @throws   Stevenmaguire\Yelp\Exception\ClientConfigurationException
159
     * @throws   Stevenmaguire\Yelp\Exception\HttpException
160
     */
161
    protected function processRequest(RequestInterface $request)
162
    {
163
        $response = $this->getResponse($request);
164
165
        return json_decode($response->getBody());
166
    }
167
168
    /**
169
     * Updates the yelp client's http client to the given http client. Client.
170
     *
171
     * @param GuzzleHttp\Client  $client
172
     *
173
     * @return  mixed
174
     */
175
    public function setHttpClient(HttpClient $client)
176
    {
177
        $this->httpClient = $client;
0 ignored issues
show
Documentation Bug introduced by
It seems like $client of type object<GuzzleHttp\Client> is incompatible with the declared type object<Stevenmaguire\Yelp\Tool\GuzzleHttp\Client> of property $httpClient.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
178
179
        return $this;
180
    }
181
}
182