1
1
<?php
2
2
3
3
/**
4
- * A simple wrapper for the Twitter API
4
+ * A Twitter library in PHP.
5
5
*
6
6
* @package codebird
7
+ * @version 2.3.0
7
8
* @author J.M. <me@mynetx.net>
8
- * @copyright 2010-2012 J.M. <me@mynetx.net>
9
+ * @copyright 2010-2013 J.M. <me@mynetx.net>
9
10
*
10
11
* This program is free software: you can redistribute it and/or modify
11
12
* it under the terms of the GNU General Public License as published by
33
34
unset($ id );
34
35
35
36
/**
36
- * A simple wrapper for the Twitter API
37
+ * A Twitter library in PHP.
37
38
*
38
39
* @package codebird
39
40
* @subpackage codebird-php
@@ -55,20 +56,25 @@ class Codebird
55
56
*/
56
57
private static $ _oauth_consumer_secret = null ;
57
58
59
+ /**
60
+ * The app-only bearer token. Used to authorize app-only requests
61
+ */
62
+ private static $ _oauth_bearer_token = null ;
63
+
58
64
/**
59
65
* The API endpoint to use
60
66
*/
61
- private $ _endpoint = 'https://api.twitter.com/1.1/ ' ;
67
+ private static $ _endpoint = 'https://api.twitter.com/1.1/ ' ;
62
68
63
69
/**
64
70
* The API endpoint to use for OAuth requests
65
71
*/
66
- private $ _endpoint_oauth = 'https://api.twitter.com/ ' ;
72
+ private static $ _endpoint_oauth = 'https://api.twitter.com/ ' ;
67
73
68
74
/**
69
75
* The API endpoint to use for untransitioned methods
70
76
*/
71
- private $ _endpoint_old = 'https://api.twitter.com/1/ ' ;
77
+ private static $ _endpoint_old = 'https://api.twitter.com/1/ ' ;
72
78
73
79
/**
74
80
* The Request or access token. Used to sign requests
@@ -98,7 +104,7 @@ class Codebird
98
104
/**
99
105
* The current Codebird version
100
106
*/
101
- private $ _version = '2.2.3 ' ;
107
+ private $ _version = '2.3.0 ' ;
102
108
103
109
/**
104
110
* Returns singleton class instance
@@ -128,6 +134,18 @@ public static function setConsumerKey($key, $secret)
128
134
self ::$ _oauth_consumer_secret = $ secret ;
129
135
}
130
136
137
+ /**
138
+ * Sets the OAuth2 app-only auth bearer token
139
+ *
140
+ * @param string $token OAuth2 bearer token
141
+ *
142
+ * @return void
143
+ */
144
+ public static function setBearerToken ($ token )
145
+ {
146
+ self ::$ _oauth_bearer_token = $ token ;
147
+ }
148
+
131
149
/**
132
150
* Gets the current Codebird version
133
151
*
@@ -186,6 +204,10 @@ public function __call($fn, $params)
186
204
parse_str ($ params [0 ], $ apiparams );
187
205
}
188
206
}
207
+ $ app_only_auth = false ;
208
+ if (count ($ params ) > 1 ) {
209
+ $ app_only_auth = !! $ params [1 ];
210
+ }
189
211
190
212
// map function name to API method
191
213
$ method = '' ;
@@ -239,7 +261,14 @@ public function __call($fn, $params)
239
261
// geek-geek: Now allowing to specify filenames as params
240
262
$ this ->_detectFilenames ($ method_template , $ apiparams );
241
263
242
- return $ this ->_callApi ($ httpmethod , $ method , $ method_template , $ apiparams , $ multipart );
264
+ return $ this ->_callApi (
265
+ $ httpmethod ,
266
+ $ method ,
267
+ $ method_template ,
268
+ $ apiparams ,
269
+ $ multipart ,
270
+ $ app_only_auth
271
+ );
243
272
}
244
273
245
274
/**
@@ -279,7 +308,7 @@ public function oauth_authenticate()
279
308
if ($ this ->_oauth_token == null ) {
280
309
throw new Exception ('To get the authenticate URL, the OAuth token must be set. ' );
281
310
}
282
- return $ this -> _endpoint_oauth . 'oauth/authenticate?oauth_token= ' . $ this ->_url ($ this ->_oauth_token );
311
+ return self :: $ _endpoint_oauth . 'oauth/authenticate?oauth_token= ' . $ this ->_url ($ this ->_oauth_token );
283
312
}
284
313
285
314
/**
@@ -292,7 +321,55 @@ public function oauth_authorize()
292
321
if ($ this ->_oauth_token == null ) {
293
322
throw new Exception ('To get the authorize URL, the OAuth token must be set. ' );
294
323
}
295
- return $ this ->_endpoint_oauth . 'oauth/authorize?oauth_token= ' . $ this ->_url ($ this ->_oauth_token );
324
+ return self ::$ _endpoint_oauth . 'oauth/authorize?oauth_token= ' . $ this ->_url ($ this ->_oauth_token );
325
+ }
326
+
327
+ /**
328
+ * Gets the OAuth bearer token
329
+ *
330
+ * @return string The OAuth bearer token
331
+ */
332
+
333
+ public function oauth2_token ()
334
+ {
335
+ if (! function_exists ('curl_init ' )) {
336
+ throw new Exception ('To make API requests, the PHP curl extension must be available. ' );
337
+ }
338
+ if (self ::$ _oauth_consumer_key == null ) {
339
+ throw new Exception ('To obtain a bearer token, the consumer key must be set. ' );
340
+ }
341
+ $ ch = false ;
342
+ $ post_fields = array (
343
+ 'grant_type ' => 'client_credentials '
344
+ );
345
+ $ url = self ::$ _endpoint_oauth . 'oauth2/token ' ;
346
+ $ ch = curl_init ($ url );
347
+ curl_setopt ($ ch , CURLOPT_POST , 1 );
348
+ curl_setopt ($ ch , CURLOPT_POSTFIELDS , $ post_fields );
349
+ curl_setopt ($ ch , CURLOPT_RETURNTRANSFER , 1 );
350
+ curl_setopt ($ ch , CURLOPT_FOLLOWLOCATION , 0 );
351
+ curl_setopt ($ ch , CURLOPT_HEADER , 1 );
352
+ curl_setopt ($ ch , CURLOPT_SSL_VERIFYHOST , 0 );
353
+ curl_setopt ($ ch , CURLOPT_SSL_VERIFYPEER , 0 );
354
+ curl_setopt ($ ch , CURLOPT_USERPWD , self ::$ _oauth_consumer_key . ': ' . self ::$ _oauth_consumer_secret );
355
+ curl_setopt ($ ch , CURLOPT_HTTPHEADER , array (
356
+ 'Expect: '
357
+ ));
358
+ $ reply = curl_exec ($ ch );
359
+ $ httpstatus = curl_getinfo ($ ch , CURLINFO_HTTP_CODE );
360
+ $ reply = $ this ->_parseApiReply ('oauth2/token ' , $ reply );
361
+ if ($ this ->_return_format == CODEBIRD_RETURNFORMAT_OBJECT ) {
362
+ $ reply ->httpstatus = $ httpstatus ;
363
+ if ($ httpstatus == 200 ) {
364
+ self ::setBearerToken ($ reply ->access_token );
365
+ }
366
+ } else {
367
+ $ reply ['httpstatus ' ] = $ httpstatus ;
368
+ if ($ httpstatus == 200 ) {
369
+ self ::setBearerToken ($ reply ['access_token ' ]);
370
+ }
371
+ }
372
+ return $ reply ;
296
373
}
297
374
298
375
/**
@@ -374,12 +451,10 @@ private function _nonce($length = 8)
374
451
* @param string $httpmethod Usually either 'GET' or 'POST' or 'DELETE'
375
452
* @param string $method The API method to call
376
453
* @param array optional $params The API call parameters, associative
377
- * @param bool optional $multipart Whether the request is going to be multipart/form-data
378
454
*
379
- * @return string The API call parameters including the signature
380
- * If multipart, the Authorization HTTP header is returned
455
+ * @return string Authorization HTTP header
381
456
*/
382
- private function _sign ($ httpmethod , $ method , $ params = array (), $ multipart = false )
457
+ private function _sign ($ httpmethod , $ method , $ params = array ())
383
458
{
384
459
if (self ::$ _oauth_consumer_key == null ) {
385
460
throw new Exception ('To generate a signature, the consumer key must be set. ' );
@@ -398,6 +473,7 @@ private function _sign($httpmethod, $method, $params = array(), $multipart = fal
398
473
if ($ this ->_oauth_token != null ) {
399
474
$ sign_base_params ['oauth_token ' ] = $ this ->_url ($ this ->_oauth_token );
400
475
}
476
+ $ oauth_params = $ sign_base_params ;
401
477
foreach ($ params as $ key => $ value ) {
402
478
$ sign_base_params [$ key ] = $ this ->_url ($ value );
403
479
}
@@ -408,18 +484,16 @@ private function _sign($httpmethod, $method, $params = array(), $multipart = fal
408
484
}
409
485
$ sign_base_string = substr ($ sign_base_string , 0 , -1 );
410
486
$ signature = $ this ->_sha1 ($ httpmethod . '& ' . $ this ->_url ($ method ) . '& ' . $ this ->_url ($ sign_base_string ));
411
- if ($ multipart ) {
412
- $ params = array_merge ($ sign_base_params , array (
413
- 'oauth_signature ' => $ signature
414
- ));
415
- ksort ($ params );
416
- $ authorization = 'Authorization: OAuth ' ;
417
- foreach ($ params as $ key => $ value ) {
418
- $ authorization .= $ key . '=" ' . $ this ->_url ($ value ) . '", ' ;
419
- }
420
- return substr ($ authorization , 0 , -2 );
487
+
488
+ $ params = array_merge ($ oauth_params , array (
489
+ 'oauth_signature ' => $ signature
490
+ ));
491
+ ksort ($ params );
492
+ $ authorization = 'Authorization: OAuth ' ;
493
+ foreach ($ params as $ key => $ value ) {
494
+ $ authorization .= $ key . '=" ' . $ this ->_url ($ value ) . '", ' ;
421
495
}
422
- return ( $ httpmethod == ' GET ' ? $ method . ' ? ' : '' ) . $ sign_base_string . ' &oauth_signature= ' . $ this -> _url ( $ signature );
496
+ return substr ( $ authorization , 0 , - 2 );
423
497
}
424
498
425
499
/**
@@ -585,7 +659,9 @@ private function _detectMethod($method, $params)
585
659
586
660
// OAuth
587
661
'oauth/access_token ' ,
588
- 'oauth/request_token '
662
+ 'oauth/request_token ' ,
663
+ 'oauth2/token ' ,
664
+ 'oauth2/invalidate_token '
589
665
);
590
666
foreach ($ httpmethods as $ httpmethod => $ methods ) {
591
667
if (in_array ($ method , $ methods )) {
@@ -710,12 +786,12 @@ private function _detectFilenames($method, &$params)
710
786
*/
711
787
private function _getEndpoint ($ method , $ method_template )
712
788
{
713
- if (substr ($ method , 0 , 6 ) == 'oauth/ ' ) {
714
- $ url = $ this -> _endpoint_oauth . $ method ;
789
+ if (substr ($ method , 0 , 5 ) == 'oauth ' ) {
790
+ $ url = self :: $ _endpoint_oauth . $ method ;
715
791
} elseif ($ this ->_detectOld ($ method_template )) {
716
- $ url = $ this -> _endpoint_old . $ method . '.json ' ;
792
+ $ url = self :: $ _endpoint_old . $ method . '.json ' ;
717
793
} else {
718
- $ url = $ this -> _endpoint . $ method . '.json ' ;
794
+ $ url = self :: $ _endpoint . $ method . '.json ' ;
719
795
}
720
796
return $ url ;
721
797
}
@@ -728,22 +804,28 @@ private function _getEndpoint($method, $method_template)
728
804
* @param string $method_template The templated API method to call
729
805
* @param array optional $params The parameters to send along
730
806
* @param bool optional $multipart Whether to use multipart/form-data
807
+ * @param bool optional $app_only_auth Whether to use app-only bearer authentication
731
808
*
732
809
* @return mixed The API reply, encoded in the set return_format
733
810
*/
734
811
735
- private function _callApi ($ httpmethod , $ method , $ method_template , $ params = array (), $ multipart = false )
812
+ private function _callApi ($ httpmethod , $ method , $ method_template , $ params = array (), $ multipart = false , $ app_only_auth = false )
736
813
{
737
814
if (! function_exists ('curl_init ' )) {
738
815
throw new Exception ('To make API requests, the PHP curl extension must be available. ' );
739
816
}
740
817
$ url = $ this ->_getEndpoint ($ method , $ method_template );
741
818
$ ch = false ;
742
819
if ($ httpmethod == 'GET ' ) {
743
- $ ch = curl_init ($ this ->_sign ($ httpmethod , $ url , $ params ));
820
+ $ url_with_params = $ url ;
821
+ if (count ($ params ) > 0 ) {
822
+ $ url_with_params .= '? ' . http_build_query ($ params );
823
+ }
824
+ $ authorization = $ this ->_sign ('GET ' , $ url , $ params );
825
+ $ ch = curl_init ($ url_with_params );
744
826
} else {
745
827
if ($ multipart ) {
746
- $ authorization = $ this ->_sign ('POST ' , $ url , array (), true );
828
+ $ authorization = $ this ->_sign ('POST ' , $ url , array ());
747
829
$ post_fields = $ params ;
748
830
} else {
749
831
$ post_fields = $ this ->_sign ('POST ' , $ url , $ params );
@@ -752,6 +834,16 @@ private function _callApi($httpmethod, $method, $method_template, $params = arra
752
834
curl_setopt ($ ch , CURLOPT_POST , 1 );
753
835
curl_setopt ($ ch , CURLOPT_POSTFIELDS , $ post_fields );
754
836
}
837
+ if ($ app_only_auth ) {
838
+ if (self ::$ _oauth_consumer_key == null ) {
839
+ throw new Exception ('To make an app-only auth API request, the consumer key must be set. ' );
840
+ }
841
+ // automatically fetch bearer token, if necessary
842
+ if (self ::$ _oauth_bearer_token == null ) {
843
+ $ this ->oauth2_token ();
844
+ }
845
+ $ authorization = 'Authorization: Bearer ' . self ::$ _oauth_bearer_token ;
846
+ }
755
847
curl_setopt ($ ch , CURLOPT_RETURNTRANSFER , 1 );
756
848
curl_setopt ($ ch , CURLOPT_FOLLOWLOCATION , 0 );
757
849
curl_setopt ($ ch , CURLOPT_HEADER , 1 );
0 commit comments