Completed
Pull Request — master (#12)
by Steven
03:05
created

Client::prepareQueryParams()   A

Complexity

Conditions 3
Paths 1

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 3

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 10
ccs 6
cts 6
cp 1
rs 9.4285
cc 3
eloc 5
nc 1
nop 1
crap 3
1
<?php namespace Stevenmaguire\Yelp;
2
3
use GuzzleHttp\Client as HttpClient;
4
use GuzzleHttp\HandlerStack;
5
use GuzzleHttp\Subscriber\Oauth\Oauth1;
6
use GuzzleHttp\Exception\ClientException;
7
8
class Client
9
{
10
    /**
11
     * API host url
12
     *
13
     * @var string
14
     */
15
    protected $apiHost;
16
17
    /**
18
     * Consumer key
19
     *
20
     * @var string
21
     */
22
    protected $consumerKey;
23
24
    /**
25
     * Consumer secret
26
     *
27
     * @var string
28
     */
29
    protected $consumerSecret;
30
31
    /**
32
     * Access token
33
     *
34
     * @var string
35
     */
36
    protected $token;
37
38
    /**
39
     * Access token secret
40
     *
41
     * @var string
42
     */
43
    protected $tokenSecret;
44
45
    /**
46
     * Default search term
47
     *
48
     * @var string
49
     */
50
    protected $defaultTerm = 'bar';
51
52
    /**
53
     * Default location
54
     *
55
     * @var string
56
     */
57
    protected $defaultLocation = 'Chicago, IL';
58
59
    /**
60
     * Default search limit
61
     *
62
     * @var integer
63
     */
64
    protected $searchLimit = 3;
65
66
    /**
67
     * Search path
68
     *
69
     * @var string
70
     */
71
    protected $searchPath = '/v2/search/';
72
73
    /**
74
     * Business path
75
     *
76
     * @var string
77
     */
78
    protected $businessPath = '/v2/business/';
79
80
    /**
81
     * Phone search path
82
     *
83
     * @var string
84
     */
85
    protected $phoneSearchPath = '/v2/phone_search/';
86
87
    /**
88
     * [$httpClient description]
89
     *
90
     * @var [type]
91
     */
92
    protected $httpClient;
93
94
    /**
95
     * Create new client
96
     *
97
     * @param array $configuration
98
     */
99 18
    public function __construct($configuration = [])
100
    {
101 18
        $this->parseConfiguration($configuration)
102 18
            ->createHttpClient();
103 18
    }
104
105
    /**
106
     * Build query string params using defaults
107
     *
108
     * @param  array $attributes
109
     *
110
     * @return string
111
     */
112 4
    public function buildQueryParams($attributes = [])
113
    {
114
        $defaults = array(
115 4
            'term' => $this->defaultTerm,
116 4
            'location' => $this->defaultLocation,
117 4
            'limit' => $this->searchLimit
118 4
        );
119 4
        $attributes = array_merge($defaults, $attributes);
120
121 4
        return $this->prepareQueryParams($attributes);
122
    }
123
124
    /**
125
     * Build unsigned url
126
     *
127
     * @param  string   $host
128
     * @param  string   $path
129
     *
130
     * @return string   Unsigned url
131
     */
132 16
    protected function buildUnsignedUrl($host, $path)
133
    {
134 16
        return "http://" . $host . $path;
135
    }
136
137
    /**
138
     * Builds and sets a preferred http client.
139
     *
140
     * @return Client
141
     */
142 18
    protected function createHttpClient()
143
    {
144 18
        $stack = HandlerStack::create();
145
146 18
        $middleware = new Oauth1([
147 18
            'consumer_key'    => $this->consumerKey,
148 18
            'consumer_secret' => $this->consumerSecret,
149 18
            'token'           => $this->token,
150 18
            'token_secret'    => $this->tokenSecret
151 18
        ]);
152
153 18
        $stack->push($middleware);
154
155 18
        $client = new HttpClient([
156
            'handler' => $stack
157 18
        ]);
158
159 18
        return $this->setHttpClient($client);
160
    }
161
162
    /**
163
     * Query the Business API by business id
164
     *
165
     * @param    string   $businessId      The ID of the business to query
166
     * @param    array    $attributes      Optional attributes to include in query string
167
     *
168
     * @return   stdClass                   The JSON response from the request
169
     */
170 10
    public function getBusiness($businessId, $attributes = [])
171
    {
172 10
        $businessPath = $this->businessPath . urlencode($businessId) . "?" . $this->prepareQueryParams($attributes);
173
174 10
        return $this->request($businessPath);
175
    }
176
177
    /**
178
     * Maps legacy configuration keys to updated keys.
179
     *
180
     * @param  array   $configuration
181
     *
182
     * @return array
183
     */
184 18
    protected function mapConfiguration(array $configuration)
185
    {
186
        array_walk($configuration, function ($value, $key) use (&$configuration) {
187 18
            $newKey = lcfirst(str_replace(' ', '', ucwords(str_replace('_', ' ', $key))));
188 18
            $configuration[$newKey] = $value;
189 18
        });
190
191 18
        return $configuration;
192
    }
193
194
    /**
195
     * Parse configuration using defaults
196
     *
197
     * @param  array $configuration
198
     *
199
     * @return client
200
     */
201 18
    protected function parseConfiguration($configuration = [])
202
    {
203
        $defaults = array(
204 18
            'consumerKey' => null,
205 18
            'consumerSecret' => null,
206 18
            'token' => null,
207 18
            'tokenSecret' => null,
208
            'apiHost' => 'api.yelp.com'
209 18
        );
210
211 18
        $configuration = array_merge($defaults, $this->mapConfiguration($configuration));
212
213 18
        array_walk($configuration, [$this, 'setConfig']);
214
215 18
        return $this;
216
    }
217
218
    /**
219
     * Updates query params array to apply yelp specific formatting rules.
220
     *
221
     * @param  array   $params
222
     *
223
     * @return string
224
     */
225
    protected function prepareQueryParams($params = [])
226
    {
227 16
        array_walk($params, function ($value, $key) use (&$params) {
228 8
            if (is_bool($value)) {
229 2
                $params[$key] = $value ? 'true' : 'false';
230 2
            }
231 16
        });
232
233 16
        return http_build_query($params);
234
    }
235
236
    /**
237
     * Makes a request to the Yelp API and returns the response
238
     *
239
     * @param    string $path    The path of the APi after the domain
240
     *
241
     * @return   stdClass The JSON response from the request
242
     * @throws   Exception
243
     */
244 16
    protected function request($path)
245
    {
246 16
        $url = $this->buildUnsignedUrl($this->apiHost, $path);
247
248
        try {
249 16
            $response = $this->httpClient->get($url, ['auth' => 'oauth']);
250 16
        } catch (ClientException $e) {
251 4
            $exception = new Exception($e->getMessage());
252
253 4
            throw $exception->setResponseBody($e->getResponse()->getBody());
254
        }
255
256 12
        return json_decode($response->getBody());
257
    }
258
259
    /**
260
     * Query the Search API by a search term and location
261
     *
262
     * @param    array    $attributes   Query attributes
263
     *
264
     * @return   stdClass               The JSON response from the request
265
     */
266 4
    public function search($attributes = [])
267
    {
268 4
        $query_string = $this->buildQueryParams($attributes);
269 4
        $searchPath = $this->searchPath . "?" . $query_string;
270
271 4
        return $this->request($searchPath);
272
    }
273
274
    /**
275
     * Search for businesses by phone number
276
     *
277
     * @see https://www.yelp.com/developers/documentation/v2/phone_search
278
     *
279
     * @param    array    $attributes   Query attributes
280
     *
281
     * @return   stdClass               The JSON response from the request
282
     */
283 2
    public function searchByPhone($attributes = [])
284
    {
285 2
        $searchPath = $this->phoneSearchPath . "?" . $this->prepareQueryParams($attributes);
286
287 2
        return $this->request($searchPath);
288
    }
289
290
    /**
291
     * Attempts to set a given value.
292
     *
293
     * @param mixed   $value
294
     * @param string  $key
295
     *
296
     * @return Client
297
     */
298 18
    protected function setConfig($value, $key)
299
    {
300 18
        if (property_exists($this, $key)) {
301 18
            $this->$key = $value;
302 18
        }
303
304 18
        return $this;
305
    }
306
307
    /**
308
     * Set default location
309
     *
310
     * @param string $location
311
     *
312
     * @return Client
313
     */
314 2
    public function setDefaultLocation($location)
315
    {
316 2
        $this->defaultLocation = $location;
317 2
        return $this;
318
    }
319
320
    /**
321
     * Set default term
322
     *
323
     * @param string $term
324
     *
325
     * @return Client
326
     */
327 2
    public function setDefaultTerm($term)
328
    {
329 2
        $this->defaultTerm = $term;
330 2
        return $this;
331
    }
332
333
    /**
334
     * Updates the yelp client's http client to the given http client. Client.
335
     *
336
     * @param HttpClient  $client
337
     *
338
     * @return  Client
339
     */
340 18
    public function setHttpClient(HttpClient $client)
341
    {
342 18
        $this->httpClient = $client;
343
344 18
        return $this;
345
    }
346
347
    /**
348
     * Set search limit
349
     *
350
     * @param integer $limit
351
     *
352
     * @return Client
353
     */
354 2
    public function setSearchLimit($limit)
355
    {
356 2
        if (is_int($limit)) {
357 2
            $this->searchLimit = $limit;
358 2
        }
359 2
        return $this;
360
    }
361
362
    /**
363
     * Retrives the value of a given property from the client.
364
     *
365
     * @param  string  $property
366
     *
367
     * @return mixed|null
368
     */
369 2
    public function __get($property)
370
    {
371 2
        if (property_exists($this, $property)) {
372 2
            return $this->$property;
373
        }
374
375 2
        return null;
376
    }
377
}
378