forked from wbobeirne/Phlickr
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Api.php
604 lines (580 loc) · 19.2 KB
/
Api.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
<?php
/**
* @version $Id$
* @author Andrew Morton <[email protected]>
* @license http://opensource.org/licenses/lgpl-license.php
* GNU Lesser General Public License, Version 2.1
* @package Phlickr
*/
/**
* Include Phlickr_Cache, a core class.
*/
require_once dirname(__FILE__) . '/Cache.php';
/**
* Include the Phlickr exceptions, core classes.
*/
require_once dirname(__FILE__) . '/Exception.php';
/**
* Include Phlickr_Request, a core class.
*/
require_once dirname(__FILE__) . '/Request.php';
/**
* Include Phlickr_CResponse, a core class.
*/
require_once dirname(__FILE__) . '/Response.php';
/**
* Phlickr_Api acts as a connection to the Flickr API and provides several
* shortcut methods for interacting with it.
*
* Sample usage:
* <code>
* <?php
* include_once '/Api.php';
* $api = new Phlickr_Api(FLICKR_API_KEY, FLICRK_API_SECRET);
*
* // Authentication is no longer done with an email/password. the first step
* // is requesting a frob and then building a Flickr URL to log into.
* $frob = $api->requestFrob();
* // request read and write permissions (write implies read)
* $url = $api->buildAuthUrl('write', $frob);
* print "frob: $frob\n";
* // you'll need open the link and log into you Flickr account to grant
* // permissions to this API key.
* print "url: $url\n";
*
* // once you've logged in and validated the fob you can turn it into an
* // auth token that's good for a while.
* print "token: " . $api->getTokenFromFrob($frob) . "\n";
*
* // check if the authentication token is valid.
* print $api->isAuthValid();
*
* // execute a flickr echo test method.
* $response = $api->executeMethod('flickr.test.echo', array('foo'=>'bar'));
* print $response;
* ?>
* </code>
*
* This class is responsible for:
* - Storing an API key.
* - Storing user authentication information and verifying it can be used to
* login to the service.
* - Storing a cache of results to previous API calls. This cache can be
* serialized and restored across sessions to allow offline, use.
* - Acting as a facade to provide clients with "one line" access to API
* methods.
*
* Calls to the Flickr API have several steps. First, a Phlickr_Request is
* constructed with a reference to a Phlickr_Api. When the Phlickr_Request
* executes it returns a Phlickr_Response. All other classes just wrap
* Phlickr_Response's output in some way, to make it easier to use.
*
* @package Phlickr
* @author Andrew Morton <[email protected]>
* @since 0.1.0
*/
class Phlickr_Api {
/**
* The default Flickr API endpoint URL for REST requests.
*
* @var string
* @see setEndpointUrl()
*/
const REST_ENDPOINT_URL = 'https://www.flickr.com/services/rest/';
/**
* The name of the API key label in the settings files created by saveAs()
* and read by createFrom().
*
* @var string This should be all lowercase.
*/
const SETTING_API_KEY = 'api_key';
/**
* The name of the API secret label in the settings files created by saveAs()
* and read by createFrom().
*
* @var string This should be all lowercase.
*/
const SETTING_API_SECRET = 'api_secret';
/**
* The name of the API authorization token label in the settings files
* created by saveAs() and read by createFrom().
*
* @var string This should be all lowercase.
*/
const SETTING_API_TOKEN = 'api_token';
/**
* The name of the cache filename label in the settings files created by
* saveAs() and read by createFrom().
*
* @var string This should be all lowercase.
*/
const SETTING_API_CACHE = 'cache_file';
/**
* A Flickr API key.
*
* To obtain one see http://flickr.com/services/api/misc.api_keys.html .
*
* @var string
* @see getKey()
*/
private $_key = null;
/**
* The shared secret that goes with the API key.
*
* @var string
* @since 0.2.3
* @see getSecret()
*/
private $_secret = null;
/**
* The token associated with a Flickr account.
*
* @var string
* @see getAuthToken()
* @since 0.2.3
*/
private $_token = null;
/**
* The Request Cache.
*
* @var object Phlickr_Cache
* @see getCache(), setCache()
*/
private $_cache = null;
/**
* The cache filename.
*
* @var string Full path of the cache file
* @see getCacheFilename(), setCacheFilename()
*/
private $_cacheFilename = '';
/**
* The Flickr REST endpoint URL.
*
* @var string
* @see getEndpointUrl(), setEndpointUrl()
* @uses REST_ENDPOINT_URL Used as a default.
*/
private $_endpointUrl = Phlickr_Api::REST_ENDPOINT_URL;
/**
* The cached Flickr user id. This will be null until isValidAuth() or
* getUserId() is called.
*
* @var string
* @see isValidAuth(), getUserId()
*/
private $_userId = null;
/**
* Constructor.
*
* @param string $key Flickr API key.
* @param string $secret Flickr API shared secret.
* @param string $token
* @see getKey(), getSecret(), getAuthToken(), setAuthToken()
*/
public function __construct($key, $secret, $token = null) {
// key (required)
if (isset($key)) {
$this->_key = (string) $key;
} else {
throw new Phlickr_Exception('Must provide a Flickr API key.');
}
// secret (required)
if (isset($secret)) {
$this->_secret = (string) $secret;
} else {
throw new Phlickr_Exception('Must provide a Flickr API secret.');
}
// token
if (isset($token)) {
$this->_token = (string) $token;
}
$this->_cache = new Phlickr_Cache();
}
/**
* Destructor. If a cache filename is set, save the contents of the cache
* to the file using Phlickr_Cache::saveAs().
*
* @since 0.2.4
* @see setCacheFilename()
* @uses Phlickr_Api::getCacheFilename() to determine if and where the
* destructor should save the cached data.
* @uses Phlickr_Cache::saveAs() to save the cache.
*/
public function __destruct() {
if ($this->_cacheFilename != '') {
$this->_cache->saveAs($this->_cacheFilename);
}
}
/**
* Create an Api from settings saved into a file by saveAs().
*
* If the file does not exist, is invalid, or cannot be loaded, then you're
* going to get an exception.
*
* The format of the file is:
* <code>
* api_key=0123456789abcdef0123456789abcedf
* api_secret=abcedf0123456789
* api_token=123-abcdef0123456789
* cache_file=c:\temp\flickr.tmp
* </code>
* The token and cache filename settings are optional. The label of each
* setting is defined by a constant in this class.
*
* @param string $fileName Name of the file containing the saved Api
* settings.
* @return object Phlickr_Api
* @since 0.2.4
* @see saveAs()
* @uses SETTING_API_KEY Label of the API key setting.
* @uses SETTING_API_SECRET Label of the API secret setting.
* @uses SETTING_API_TOKEN Label of the API token setting.
* @uses SETTING_API_CACHE Label of the cache filename setting.
* @uses setCacheFilename() to assign the cache filename if one is
* present in the settings file.
*/
static public function createFrom($filename) {
// create an array for the settings
$config = array();
// load the file
$contents = file_get_contents($filename);
// parse the key=value pairs into an associative array.
preg_match_all('/([-_a-zA-Z]+)=(.+)/', $contents, $matches, PREG_SET_ORDER);
foreach($matches as $match) {
$config[strtolower($match[1])] = $match[2];
}
// build an api object from the settings
$api = new Phlickr_Api(
$config[self::SETTING_API_KEY],
$config[self::SETTING_API_SECRET],
$config[self::SETTING_API_TOKEN]
);
// set the cache filename
if (isset($config[self::SETTING_API_CACHE])) {
$api->setCacheFilename($config[self::SETTING_API_CACHE]);
}
return $api;
}
/**
* Save the settings from an Api object so that it can be recreated later
* by createFrom().
*
* @param string $fileName Name of the file to save the Api settings.
* @return void
* @since 0.2.4
* @see createFrom()
* @uses SETTING_API_KEY Label of the API key setting.
* @uses SETTING_API_SECRET Label of the API secret setting.
* @uses SETTING_API_TOKEN Label of the API token setting.
* @uses SETTING_API_CACHE Label of the cache filename setting.
*/
public function saveAs($filename) {
$settings = self::SETTING_API_KEY . "={$this->getKey()}\n";
$settings .= self::SETTING_API_SECRET . "={$this->getSecret()}\n";
$settings .= self::SETTING_API_TOKEN . "={$this->getAuthToken()}\n";
$settings .= self::SETTING_API_CACHE . "={$this->getCacheFilename()}\n";
file_put_contents($filename, $settings);
}
/**
* Returns the Phlickr_Cache associated with this connection.
*
* @return object Phlickr_Cache
* @see setCache()
*/
public function getCache() {
return $this->_cache;
}
/**
* Assign a cache to this API.
*
* Be aware that if the new cache has data it will be used.
*
* @param object Phlickr_Cache $cache The cache to use
* @return void
* @see getCache()
*/
public function setCache(Phlickr_Cache $cache) {
return $this->_cache = $cache;
}
/**
* Get the file name where the cache is saved when the Api object is
* destroyed.
*
* @return string The full path of the file.
* @since 0.2.4
* @see __destruct(), setCacheFilename()
*/
public function getCacheFilename() {
return $this->_cacheFilename;
}
/**
* Set the name of the file used to save the cache when the object is
* destroyed.
*
* If the file exists and is readable, an attempt will be made to load it
* as a cache object using Phlickr_Cache::createFrom(). If the file does
* not contain a valid cache object then a new, empty, cache object will
* used and any previous cached information will be discarded.
*
* @param string The full path of the file.
* @return void
* @since 0.2.4
* @see __destruct(), getCacheFilename(), Phlickr_Cache::createFrom()
*/
public function setCacheFilename($filename) {
$this->_cacheFilename = (string) $filename;
if (file_exists($this->_cacheFilename)) {
$this->_cache = Phlickr_Cache::createFrom($this->_cacheFilename);
}
}
/**
* Add a response to the cache.
*
* Use this function to seed the cache with a response. It's helpful for
* writing unit tests or offline use.
*
* @param string $method Name of Flickr API method.
* @param array $params Array of parameters. The ordering isn't important,
* they'll be sorted when building the request.
* @param string $xml The XML return. This should be the payload, i.e.
* everything in the <resp></resp> element.
* @return void
* @uses Phlickr_Request::buildUrl() to construct the URL that the cache
* uses as a key.
* @uses Phlickr_Cache::set() to store the results in the cache.
*/
public function addResponseToCache($method, $params, $xml) {
$url = $this->createRequest($method, $params)->buildUrl();
//print "\nCACHED : $url\n";
$this->_cache->set($url, $xml);
}
/**
* Get the API key.
*
* @return string
* @see __construct()
* @uses Phlickr_Api::$_key Value is loaded from this variable.
*/
public function getKey() {
return $this->_key;
}
/**
* Get the API secret that corresponds to key.
*
* @return string
* @see __construct()
* @link http://flickr.com/services/api/auth.spec.html
*/
public function getSecret() {
return $this->_secret;
}
/**
* Return the token being used for authentication.
*
* @return string
* @see __construct(), setAuthToken(), setAuthTokenFromFrob()
* @todo Deprecate and then rename this to getToken()
*/
public function getAuthToken() {
return $this->_token;
}
/**
* Set the Flickr authentication token.
*
* @param string $token
* @return void
* @see __construct(), getAuthToken(), setAuthTokenFromFrob()
* @todo Deprecate and then rename this to setToken()
*/
public function setAuthToken($token) {
$this->_token = (string) $token;
// if the token changes the user has likely changed
$this->_userId = null;
}
/**
* Set the auth token from a frob.
*
* The user needed to authenticate the frob.
*
* @param string $frob
* @return string The new token
* @see __construct(), requestFrob(), getToken()
* @since 0.2.3
* @uses executeMethod() to call flickr.auth.getToken
* @todo Deprecate and then rename this to setTokenFromFrob()
*/
public function setAuthTokenFromFrob($frob) {
$resp = $this->executeMethod('flickr.auth.getToken',
array('frob' => (string) $frob));
$xml = $resp->getXml()->auth;
// assign the usefull stuff
$this->_token = (string) $xml->token;
$this->_userId = (string) $xml->user['nsid'];
// return the token incase they're interested
return $this->_token;
}
/**
* Check if current authentication info is valid.
*
* @return boolean
* @see setAuth()
* @since 0.2.3
* @uses getUserId() To determine if the authentication is valid.
*/
public function isAuthValid() {
if (is_null($this->getUserId())) {
return false;
} else {
return true;
}
}
/**
* Return the Flickr user id of the current authenticated user.
*
* If the authentication info is incorrect, null will be returned.
*
* @return string
* @see setAuth(), getAuthToken(), Phlickr_User,
* Phlickr_AuthedUser
* @uses executeMethod() to call flickr.auth.checkToken
*/
public function getUserId() {
if (is_null($this->_userId)) {
try {
$response = $this->executeMethod('flickr.auth.checkToken');
$this->_userId = (string) $response->xml->auth->user['nsid'];
} catch (Phlickr_Exception $ex) {
// invalid login (or connection problem)
$this->_userId = null;
}
}
return $this->_userId;
}
/**
* Return an array of the API's parameters for use with a Phlickr_Request.
*
* @return array
* @see Phlickr_Request::buildUrl()
*/
public function getParamsForRequest() {
$params['api_key'] = $this->_key;
if (isset($this->_token)) {
$params['auth_token'] = $this->_token;
}
return $params;
}
/**
* Return the URL of the Flickr endpoint.
*
* @return string
* @see setEndpointUrl()
*/
public function getEndpointUrl() {
return $this->_endpointUrl;
}
/**
* Set the URL of the Flickr endpoint.
*
* @return string
* @see getEndpointUrl(), REST_ENDPOINT_URL
*/
public function setEndpointUrl($endpointUrl) {
$this->_endpointUrl = (string) $endpointUrl;
}
/**
* Request a frob used to get a token.
*
* Hand this to buildAuthUrl() so the user can authenticate and grant
* permissions to the application.
*
* I have no idea where the title frob came from.
*
* @return string
* @link http://flickr.com/services/api/flickr.auth.getFrob.html
* @see buildAuthUrl()
* @since 0.2.3
* @uses executeMethod() to call flickr.auth.getFrob
*/
function requestFrob() {
$resp = $this->executeMethod('flickr.auth.getFrob');
return (string) $resp->getXml()->frob;
}
/**
* Build a URL to request a token.
*
* If a frob is omitted it is assumed that you've registered a callback URL
* as per the Flickr documentation.
*
* @param string $perms The desired permissions 'read', 'write', or
* 'delete'.
* @param string $frob optional Frob
* @return void
* @see requestFrob()
* @since 0.2.3
* @uses Phlickr_Request::signParams() to create a signed URL.
*/
function buildAuthUrl($perms, $frob ='') {
$params = array('api_key' => $this->getKey(), 'perms' => $perms);
if ($frob != '') {
$params['frob'] = (string) $frob;
}
return 'http://flickr.com/services/auth/?'.
Phlickr_Request::signParams($this->getSecret(), $params);
}
/**
* Create a Phlickr_Request associated with this API object.
*
* See the {@link http://flickr.com/services/api/ Flickr API} for a complete
* list of methods and parameters.
*
* @param string $method Name of the Flickr API method
* @param array $params Associative array of parameter name/value pairs
* @return object Phlickr_Request
* @uses Phlickr_Request
*/
public function createRequest($method, $params = array()) {
return new Phlickr_Request($this, $method, $params);
}
/**
* Execute a method with the given parameters.
*
* See the {@link http://flickr.com/services/api/ Flickr API} for a complete
* list of methods and parameters.
*
* @param string $method Name of the Flickr API method
* @param array $params Associative array of parameter name/value pairs
* @param boolean $allowCached If a cached response exists should it be
* returned?
* @return object Phlickr_Response
* @throws Phlickr_Exception, Phlickr_XmlParseException,
* Phlickr_ConnectionException
* @uses createRequest() to build the Phlickr_Request object.
* @uses Phlickr_Request::execute() to execute the method.
*/
public function executeMethod($method, $params = array(), $allowCached = true, $isPost = false) {
return $this->createRequest($method, $params)->execute($allowCached, $isPost);
}
/**
* Fetches a list of available photo licenses for Flickr.
*
* @return array
* @see Phlickr_AuthedPhoto::setLicense()
*/
public function getLicenses() {
$resp = $this->executeMethod(
'flickr.photos.licenses.getInfo',
array(),
TRUE
);
$licenses = array();
foreach ($resp->xml->licenses->license as $license) {
$licenses[(string)$license['id']] = array(
'id' => (string)$license['id'],
'name' => (string)$license['name'],
'url' => (string)$license['url'],
);
}
return $licenses;
}
}