Eventbrite::validMethod()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 7
rs 9.4285
cc 2
eloc 4
nc 2
nop 1
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 jamiehollern\eventbrite
19
 * @todo    Add a batch method.
20
 * @todo    Allow the token to be passed as a query string.
21
 * @todo    Properly deal with errors/non-200 responses correctly?
22
 */
23
class Eventbrite
24
{
25
    /**
26
     * The current version of this library.
27
     */
28
    const VERSION = '1.0.1';
29
30
    /**
31
     * An array of valid HTTP verbs.
32
     */
33
    private static $valid_verbs = ['get', 'post', 'put', 'patch', 'delete'];
34
35
    /**
36
     * The API endpoint to get the current user's details.
37
     */
38
    const CURRENT_USER_ENDPOINT = 'users/me/';
39
40
    /**
41
     * @var string The Eventbrite OAuth token.
42
     */
43
    private $token;
44
45
    /**
46
     * @var \GuzzleHttp\Client
47
     */
48
    private $client;
49
50
    /**
51
     * @var \GuzzleHttp\Psr7\Request
52
     */
53
    private $last_request = null;
54
55
    /**
56
     * @var \Psr\Http\Message\ResponseInterface
57
     */
58
    private $last_response = null;
59
60
    /**
61
     * @param string $token
62
     *   The OAuth token to authenticate the request
63
     * @param array  $config
64
     *   An array of Guzzle config options so that everything is configurable.
65
     *
66
     * @throws \Exception
67
     */
68
    public function __construct($token, $config = [])
69
    {
70
        $default_config = [
71
            'base_uri' => 'https://www.eventbriteapi.com/v3/',
72
            // Turn exceptions off so we can handle the responses ourselves.
73
            'exceptions' => false,
74
            'timeout' => 30,
75
        ];
76
        $config = array_merge($default_config, $config);
77
        // Add this last so it's always there and isn't overwritten.
78
        $config['headers']['User-Agent'] = 'jamiehollern\eventbrite v' . self::VERSION . ' ' . \GuzzleHttp\default_user_agent();
79
        if (!empty($token)) {
80
            $this->token = $token;
81
            // Set the authorisation header.
82
            $config['headers']['Authorization'] = 'Bearer ' . $this->token;
83
            $this->client = new Client($config);
84
        } else {
85
            throw new \Exception('An OAuth token is required to connect to the Eventbrite API.');
86
        }
87
    }
88
89
    /**
90
     * Make the call to Eventbrite, only synchronous calls at present.
91
     *
92
     * @param string $verb
93
     * @param string $endpoint
94
     * @param array  $options
95
     *
96
     * @return array|mixed|\Psr\Http\Message\ResponseInterface
97
     * @throws \Exception
98
     */
99
    public function call($verb, $endpoint, $options = [])
100
    {
101
        if ($this->validMethod($verb)) {
102
            // Get the headers and body from the options.
103
            $headers = isset($options['headers']) ? $options['headers'] : [];
104
            $body = isset($options['body']) ? $options['body'] : null;
105
            $pv = isset($options['protocol_version']) ? $options['protocol_version'] : '1.1';
106
            // Make the request.
107
            $request = new Request($verb, $endpoint, $headers, $body, $pv);
108
            // Save the request as the last request.
109
            $this->last_request = $request;
110
            // Send it.
111
            $response = $this->client->send($request, $options);
112
            if ($response instanceof ResponseInterface) {
113
                // Set the last response.
114
                $this->last_response = $response;
115
                // If the caller wants the raw response, give it to them.
116
                if (isset($options['parse_response']) && $options['parse_response'] === false) {
117
                    return $response;
118
                }
119
                $parsed_response = $this->parseResponse($response);
120
                return $parsed_response;
121
            } else {
122
                // This only really happens when the network is interrupted.
123
                throw new BadResponseException('A bad response was received.',
124
                    $request);
125
            }
126
        } else {
127
            throw new \Exception('Unrecognised HTTP verb.');
128
        }
129
    }
130
131
    /**
132
     * A slightly abstracted wrapper around call().
133
     *
134
     * This essentially splits the call options array into different parameters
135
     * to make it more obvious to less advanced users what parameters can be
136
     * passed to the client.
137
     *
138
     * @param string $verb
139
     * @param string $endpoint
140
     * @param null   $params
141
     * @param null   $body
142
     * @param null   $headers
143
     * @param array  $options
144
     *
145
     * @return array|mixed|\Psr\Http\Message\ResponseInterface
146
     * @throws \Exception
147
     */
148
    public function makeRequest($verb, $endpoint, $params = null, $body = null, $headers = null, $options = [])
149
    {
150
        // We can only have one body, so overwrite it if it exists.
151
        if ($body !== null) {
152
            $options['body'] = $body;
153
        }
154
        // Merge the mergeable arrays if necessary.
155
        $mergeable = [
156
            'query' => $params,
157
            'headers' => $headers,
158
        ];
159
        foreach ($mergeable as $key => $value) {
160
            if ($value !== null) {
161
                if (!isset($options[$key])) {
162
                    $options[$key] = [];
163
                }
164
                $options[$key] = array_merge($options[$key], $value);
165
            }
166
        }
167
        // Make the call.
168
        return $this->call($verb, $endpoint, $options);
169
    }
170
171
    /**
172
     * Checks if the HTTP method being used is correct.
173
     *
174
     * @param string $http_method
175
     *
176
     * @return bool
177
     */
178
    public function validMethod($http_method)
179
    {
180
        if (in_array(strtolower($http_method), self::$valid_verbs)) {
181
            return true;
182
        }
183
        return false;
184
    }
185
186
    /**
187
     * Parses the response from
188
     *
189
     * @param \Psr\Http\Message\ResponseInterface $response
190
     *
191
     * @return array
192
     */
193
    public function parseResponse(ResponseInterface $response)
194
    {
195
        $body = $response->getBody()->getContents();
196
        return [
197
            'code' => $response->getStatusCode(),
198
            'headers' => $response->getHeaders(),
199
            'body' => ($this->isValidJson($body)) ? json_decode($body,
200
                true) : $body,
201
        ];
202
    }
203
204
    /**
205
     * Checks a string to see if it's JSON. True if it is, false if it's not.
206
     *
207
     * @param string $string
208
     *
209
     * @return bool
210
     */
211
    public function isValidJson($string)
212
    {
213
        if (is_string($string)) {
214
            json_decode($string);
215
            return (json_last_error() === JSON_ERROR_NONE);
216
        }
217
        return false;
218
    }
219
220
    /**
221
     * Checks if the class can connect to the Eventbrite API.
222
     *
223
     * Checks if we can connect to the API by calling the user endpoint and
224
     * checking the response code. If the response code is 2xx it returns true,
225
     * otherwise false.
226
     *
227
     * @return bool
228
     */
229
    public function canConnect()
230
    {
231
        $data = $this->get(self::CURRENT_USER_ENDPOINT);
0 ignored issues
show
Documentation Bug introduced by
The method get does not exist on object<jamiehollern\eventbrite\Eventbrite>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
232
        if (strpos($data['code'], '2') === 0) {
233
            return true;
234
        }
235
        return false;
236
    }
237
238
    /**
239
     * Provides shortcut methods named by HTTP verbs.
240
     *
241
     * Provides shortcut methods for GET, POST, PUT, PATCH and DELETE.
242
     *
243
     * @param string $method
244
     * @param array  $args
245
     *
246
     * @return array|mixed|\Psr\Http\Message\ResponseInterface
247
     * @throws \Exception
248
     */
249
    public function __call($method, $args) {
250
        if ($this->validMethod($method)) {
251
            array_unshift($args, $method);
252
            return call_user_func_array(array($this, 'makeRequest'), $args);
253
        } else {
254
            throw new \BadMethodCallException('Method not found in class.');
255
        }
256
    }
257
258
    /**
259
     * Returns the last request object for inspection.
260
     *
261
     * @return \GuzzleHttp\Psr7\Request
262
     */
263
    public function getLastRequest()
264
    {
265
        return $this->last_request;
266
    }
267
268
    /**
269
     * Returns the last response object for inspection.
270
     *
271
     * @return \Psr\Http\Message\ResponseInterface
272
     */
273
    public function getLastResponse()
274
    {
275
        return $this->last_response;
276
    }
277
278
}
279