Completed
Push — develop ( db547a...eaa9a9 )
by Jamie
02:16
created

Eventbrite::makeRequest()   B

Complexity

Conditions 6
Paths 18

Size

Total Lines 22
Code Lines 12

Duplication

Lines 12
Ratio 54.55 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 12
loc 22
rs 8.6737
cc 6
eloc 12
nc 18
nop 6
1
<?php
2
/**
3
 * @file
4
 * A lightweight wrapper for the Eventbrite API using Guzzle 6. Inspired by
5
 * drewm/mailchimp-api.
6
 */
7
namespace jamiehollern\eventbrite;
8
9
use GuzzleHttp\Client;
10
use GuzzleHttp\Psr7\Request;
11
use GuzzleHttp\Exception\BadResponseException;
12
use Psr\Http\Message\ResponseInterface;
13
use Exception;
14
15
/**
16
 * Class Eventbrite
17
 *
18
 * @package EventbritePHP
19
 * @todo    Add a batch method.
20
 * @todo    Allow the token to be passed as a query string.
21
 */
22
class Eventbrite
23
{
24
    /**
25
     * The current version of this library.
26
     */
27
    const VERSION = '0.1';
28
29
    /**
30
     * The API endpoint to get the current user's details.
31
     */
32
    const CURRENT_USER_ENDPOINT = 'users/me/';
33
34
    /**
35
     * @var string The Eventbrite OAuth token.
36
     */
37
    private $token;
38
39
    /**
40
     * @var \GuzzleHttp\Client
41
     */
42
    private $client;
43
44
    /**
45
     * @var \Psr\Http\Message\ResponseInterface
46
     */
47
    private $last_response = null;
48
49
    /**
50
     * @param string $token
51
     *   The OAuth token to authenticate the request
52
     * @param array  $config
53
     *   An array of Guzzle config options so that everything is configurable.
54
     *
55
     * @throws \Exception
56
     */
57
    public function __construct($token, $config = [])
58
    {
59
        $default_config = [
60
          'base_uri' => 'https://www.eventbriteapi.com/v3/',
61
          // Turn exceptions off so we can handle the responses ourselves.
62
          'exceptions' => false,
63
          'timeout' => 30,
64
        ];
65
        $config = array_merge($config, $default_config);
66
        // Add this last so it's always there and isn't overwritten.
67
        $config['headers']['User-Agent'] = 'jamiehollern\eventbrite v' . self::VERSION . ' ' . \GuzzleHttp\default_user_agent();
68
        if (!empty($token)) {
69
            $this->token = $token;
70
            // Set the authorisation header.
71
            $config['headers']['Authorization'] = 'Bearer ' . $this->token;
72
            $this->client = new Client($config);
73
        } else {
74
            throw new \Exception('An OAuth token is required to connect to the Eventbrite API.');
75
        }
76
    }
77
78
    /**
79
     * Make the call to Eventbrite, only synchronous calls at present.
80
     *
81
     * @param string $verb
82
     * @param string $endpoint
83
     * @param array  $options
84
     *
85
     * @return array|mixed|\Psr\Http\Message\ResponseInterface
86
     * @throws \Exception
87
     */
88
    public function call($verb, $endpoint, $options = [])
89
    {
90
        if ($this->validMethod($verb)) {
91
            // Get the headers and body from the options.
92
            $headers = isset($options['headers']) ? $options['headers'] : [];
93
            $body = isset($options['body']) ? $options['body'] : [];
94
            $pv = isset($options['protocol_version']) ? $options['protocol_version'] : '1.1';
95
            // Make the request.
96
            $request = new Request($verb, $endpoint, $headers, $body, $pv);
97
            // Send it.
98
            $response = $this->client->send($request, $options);
99
            if ($response instanceof ResponseInterface) {
100
                // Set the last response.
101
                $this->last_response = $response;
102
                // If the caller wants the raw response, give it to them.
103
                if (isset($options['parse_response']) && $options['parse_response'] === false) {
104
                    return $response;
105
                }
106
                $parsed_response = $this->parseResponse($response);
107
                return $parsed_response;
108
            } else {
109
                // This only really happens when the network is interrupted.
110
                throw new BadResponseException('A bad response was received.',
111
                  $request);
112
            }
113
        } else {
114
            throw new \Exception('Unrecognised HTTP verb.');
115
        }
116
    }
117
118
    /**
119
     * A slightly abstracted wrapper around call().
120
     *
121
     * This essentially splits the call options array into different parameters
122
     * to make it more obvious to less advanced users what parameters can be
123
     * passed to the client.
124
     *
125
     * @param       $verb
126
     * @param       $endpoint
127
     * @param null  $params
128
     * @param null  $body
129
     * @param null  $headers
130
     * @param array $options
131
     *
132
     * @return array|mixed|\Psr\Http\Message\ResponseInterface
133
     * @throws \Exception
134
     */
135
    public function makeRequest($verb, $endpoint, $params = null, $body = null, $headers = null, $options = [])
136
    {
137
        // Merge the query string.
138 View Code Duplication
        if ($params !== null) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
139
            if (!isset($options['query'])) {
140
                $options['query'] = [];
141
            }
142
            $options['query'] = array_merge($options['query'], $params);
143
        }
144
        // We can only have one body, so overwrite it if it exists.
145
        if ($body !== null) {
146
            $options['body'] = $body;
147
        }
148
        // Merge the headers.
149 View Code Duplication
        if ($headers !== null) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
150
            if (!isset($options['headers'])) {
151
                $options['headers'] = [];
152
            }
153
            $options['headers'] = array_merge($options['headers'], $headers);
154
        }
155
        return $this->call($verb, $endpoint, $options);
156
    }
157
158
    /**
159
     * Checks if the HTTP method being used is correct.
160
     *
161
     * @param $http_method
162
     *
163
     * @return bool
164
     */
165
    public function validMethod($http_method)
166
    {
167
        $valid_methods = ['get', 'post', 'put', 'patch', 'delete'];
168
        if (in_array(strtolower($http_method), $valid_methods)) {
169
            return true;
170
        }
171
        return false;
172
    }
173
174
    /**
175
     * Parses the response from
176
     *
177
     * @param \Psr\Http\Message\ResponseInterface $response
178
     *
179
     * @return array
180
     */
181
    private function parseResponse(ResponseInterface $response)
182
    {
183
        $body = $response->getBody()->getContents();
184
        return [
185
          'code' => $response->getStatusCode(),
186
          'headers' => $response->getHeaders(),
187
          'body' => ($this->isValidJson($body)) ? json_decode($body,
188
            true) : $body,
189
        ];
190
    }
191
192
    /**
193
     * Checks a string to see if it's JSON. True if it is, false if it's not.
194
     *
195
     * @param string $string
196
     *
197
     * @return bool
198
     */
199
    public function isValidJson($string)
200
    {
201
        if (is_string($string)) {
202
            json_decode($string);
203
            return (json_last_error() === JSON_ERROR_NONE);
204
        }
205
        return false;
206
    }
207
208
    /**
209
     * Checks if the class can connect to the Eventbrite API.
210
     *
211
     * Checks if we can connect to the API by calling the user endpoint and
212
     * checking the response code. If the response code is 2xx it returns true,
213
     * otherwise false.
214
     *
215
     * @return bool
216
     */
217
    public function canConnect()
218
    {
219
        $data = $this->get(self::CURRENT_USER_ENDPOINT);
220
        if (strpos($data['code'], '2') === 0) {
221
            return true;
222
        }
223
        return false;
224
    }
225
226
    /**
227
     * Wrapper shortcut on the makeRequest method for "GET" requests.
228
     *
229
     * @param       string $endpoint
230
     * @param array        $options
231
     *
232
     * @return array|mixed|\Psr\Http\Message\ResponseInterface
233
     * @throws \Exception
234
     */
235
    public function get($endpoint, $params = null, $body = null, $headers = null, $options = [])
236
    {
237
        return $this->makeRequest('GET', $endpoint, $params, $body, $headers, $options);
238
    }
239
240
    /**
241
     * Wrapper shortcut on the makeRequest method for "POST" requests.
242
     *
243
     * @param       $endpoint
244
     * @param array $options
245
     *
246
     * @return array|mixed|\Psr\Http\Message\ResponseInterface
247
     * @throws \Exception
248
     */
249
    public function post($endpoint, $params = null, $body = null, $headers = null, $options = [])
250
    {
251
        return $this->makeRequest('POST', $endpoint, $params, $body, $headers,
252
          $options);
253
    }
254
255
    /**
256
     * Wrapper shortcut on the makeRequest method for "PUT" requests.
257
     *
258
     * @param       $endpoint
259
     * @param array $options
260
     *
261
     * @return array|mixed|\Psr\Http\Message\ResponseInterface
262
     * @throws \Exception
263
     */
264
    public function put($endpoint, $params = null, $body = null, $headers = null, $options = [])
265
    {
266
        return $this->makeRequest('PUT', $endpoint, $params, $body, $headers, $options);
267
    }
268
269
    /**
270
     * Wrapper shortcut on the makeRequest method for "PATCH" requests.
271
     *
272
     * @param       $endpoint
273
     * @param array $options
274
     *
275
     * @return array|mixed|\Psr\Http\Message\ResponseInterface
276
     * @throws \Exception
277
     */
278
    public function patch($endpoint, $params = null, $body = null, $headers = null, $options = [])
279
    {
280
        return $this->makeRequest('PATCH', $endpoint, $params, $body, $headers, $options);
281
    }
282
283
    /**
284
     * Wrapper shortcut on the makeRequest method for "DELETE" requests.
285
     *
286
     * @param       $endpoint
287
     * @param array $options
288
     *
289
     * @return array|mixed|\Psr\Http\Message\ResponseInterface
290
     * @throws \Exception
291
     */
292
    public function delete($endpoint, $params = null, $body = null, $headers = null, $options = [])
293
    {
294
        return $this->makeRequest('DELETE', $endpoint, $params, $body, $headers, $options);
295
    }
296
297
    /**
298
     * Returns the last response object for inspection.
299
     *
300
     * @return \Psr\Http\Message\ResponseInterface
301
     */
302
    public function getLastResponse()
303
    {
304
        return $this->last_response;
305
    }
306
307
}
308