Completed
Push — master ( 731920...cab86c )
by Jamie
04:51 queued 02:29
created

Eventbrite::getLastRequest()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

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