forked from Camalot9/Lightweight-PHP-Picasa-API
/
Picasa.php
2110 lines (1947 loc) · 109 KB
/
Picasa.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
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<?php
define('PICASA_API_BASE_DIR', __DIR__);
require_once PICASA_API_BASE_DIR . '/Picasa/Image.php';
require_once PICASA_API_BASE_DIR . '/Picasa/ImageCollection.php';
require_once PICASA_API_BASE_DIR . '/Picasa/Album.php';
require_once PICASA_API_BASE_DIR . '/Picasa/Account.php';
require_once PICASA_API_BASE_DIR . '/Picasa/Comment.php';
require_once PICASA_API_BASE_DIR . '/Picasa/Tag.php';
require_once PICASA_API_BASE_DIR . '/Picasa/Author.php';
require_once PICASA_API_BASE_DIR . '/Picasa/Exception.php';
require_once PICASA_API_BASE_DIR . '/Picasa/Logger.php';
require_once PICASA_API_BASE_DIR . '/Picasa/Exception/CaptchaRequiredException.php';
require_once PICASA_API_BASE_DIR . '/Picasa/Exception/UnauthorizedException.php';
require_once PICASA_API_BASE_DIR . '/Picasa/Exception/BadRequestException.php';
require_once PICASA_API_BASE_DIR . '/Picasa/Exception/FailedAuthorizationException.php';
require_once PICASA_API_BASE_DIR . '/Picasa/Exception/FileNotFoundException.php';
require_once PICASA_API_BASE_DIR . '/Picasa/Exception/InternalServerErrorException.php';
require_once PICASA_API_BASE_DIR . '/Picasa/Exception/ConflictException.php';
require_once PICASA_API_BASE_DIR . '/Picasa/Exception/InvalidUsernameOrPasswordException.php';
/**
* The primary class for interactions with Picasa.
* This class was developed in order to let PHP Picasa developers stay away
* from the low-level query building and request sending. The Picasa class handles authorizations, including both AuthSub and
* Client Login authorization establishment and management. It also handles retrieving of image data from Picasa Web Albums,
* storing the information in classes inside the Picasa subfolder. Additionally, photo posting, updating, and deleting is all
* made easy through the Picasa class. Essentially just determine what verb you want to do ("get", "post", "delete", or "update"),
* then figure out what noun you want to perform the verb on ("album", "image", "tag", or "comment"). If you put the two words together,
* chances are good that you will find the method you want. For instance, to *post* an *image*, you call {@link Picasa::postImage()}.
* Provide the attributes of the image as parameters in the method and the photo will be created as a Picasa Web Album.
*
* In addition to utility methods, this class stores authorization information once an instance has been authorized. For persistence, since
* there is no caching mechanism with this API, this class has methods for storing and retrieving an authorization session from
* the user's cookies.
*
* Because this class attempts to be so high level, not every single piece of Picasa's functionality options can be offered. This API
* should cover a huge percentage of desired functionality. However, in case there is something offered by Picasa's Data API that
* is not offered through this API, the class was made to be easily extendible. For instance, if Picasa one day offers the ability
* to upload videos and the latest version of this API does not offer video uploads, a PHP programmer could write a class that extends
* the Picasa class and would have access to all the methods for managing authorizations and posting and retrieving data. Additionally,
* there are generic PHP methods such as {@link Picasa::do_request()} that are useful for performing operations that would normally
* be handled by an installed PHP package. These classes are also protected rather than private, so they can be used by classes
* that extend this one, making your own extensions to this API easily doable.
*
* @package Picasa
* @version Version 3.0
* @license http://www.gnu.org/licenses/ GNU Public License Version 3
* @copyright Copyright (c) 2008 Cameron Hinkle
* @author Cameron Hinkle
* @since Version 3.0
*/
class Picasa {
/**
* The Url, without the protocol, of Picasa Web.
*
* @var string
* @static
* @access protected
*/
protected static $PICASA_URL = 'picasaweb.google.com';
/**
* The base for a standard query. All non-authenticated queries begin with this string.
*
* @var string
* @static
* @access protected
*/
protected static $BASE_QUERY_URL = 'http://picasaweb.google.com/data/feed/api';
/**
* The base for queries that use the "entry" path instead of the "feed" path. It's not clear
* what differentiates this path from the path in {@link Picasa::$BASE_QUERY_URL}, but the documentation
* makes it clear when each is necessary.
*
* @var string
* @static
* @access protected
*/
protected static $BASE_ENTRY_QUERY_URL = 'http://picasaweb.google.com/data/entry/api';
/**
* The base for queries that use the "media" path instead of the "feed" path. This path is required
* for updating the binary data in an image.
*
* @var string
* @static
* @access protected
*/
protected static $BASE_MEDIA_QUERY_URL = 'http://picasaweb.google.com/data/media/api';
/**
* A number designated to represeting the Client Login method for Authorizing an object.
* There is no significance to the number assigned to this variable.
*
* @var int
* @static
* @access public
*/
public static $AUTH_TYPE_CLIENT_LOGIN = 2;
/**
* A number designated to represeting the AuthSub method for Authorizing an object.
* There is no significance to the number assigned to this variable.
*
* @var string
* @static
* @access public
*/
public static $AUTH_TYPE_AUTH_SUB = 3;
/**
* The title of the cookie to use when setting and retrieving an AuthSub token from a user's Cookies.
*
* @var string
* @static
* @access public
*/
public static $COOKIE_NAME_AUTH_SUB_TOKEN = 'auth_sub_token';
/**
* The title of the cookie to use when setting and retrieving an Client Login token from a user's Cookies.
*
* @var string
* @static
* @access public
*/
public static $COOKIE_NAME_CLIENT_LOGIN_TOKEN = 'client_login_token';
/**
* The email address or username that this instantiation is associated with.
* The field isn't currently used for anything because
* the username is never captured when using AuthSub authentication, and it's not required when executing requests that require
* authentication.
*
* @var string
* @access private
*/
private $emailAddress;
/**
* A token supplied by Google after a successful attempt to authorize this object.
* The Auth Token is like a Golden Ticket
* for doing operations that require authorization.
*
* @var string
* @access private
*/
private $auth;
/**
* An array that is in an acceptable format for the php function stream_context_create() to create a context.
* For an authorized instance, this array holds the HTTP header with the authorization information
* necessary to make authenticated requests. It is useful to have because it holds both the authorization
* token as well as the authorization type in the same object.
*
* @link http://www.php.net/stream_context_create
* @var array
* @access private
*/
private $contextArray;
/**
* The type of authorization that has been used to authenticate this instance.
* It must either be {@link Picasa::$AUTH_TYPE_AUTH_SUB} or {@link Picasa::$AUTH_TYPE_CLIENT_LOGIN}. The auth type is
* required because the authorization header has to be formatted differently depending on what type
* of authorization was used.
*
* @link http://code.google.com/apis/accounts/docs/AuthForWebApps.html
* @link http://code.google.com/apis/accounts/docs/AuthForInstalledApps.html
* @var int
* @access private
*/
private $authType;
/**
* The constructor allows the instantiation of an unauthorized or authorized Picasa object.
* All fields can be left blank
* for an unauthorized instantiation. If an unauthorized instantiation is created, the object can later be authorized
* using {@link setAuthorizationInfo()}, {@link authorizeWithClientLogin()}, or {@link authorizeWithAuthSub()}.
*
* @access public
* @param string $authToken An string representing an authorization issued by Google. If a valid token is supplied,
* certain requests that are not allowed for unathorized objects are allowed. Optional,
* the default is null.
* @param int $authType An integer indicating what type of authorization was used. Options are restricted to
* {@link Picasa::$AUTH_TYPE_CLIENT_LOGIN} and {@link Picasa::$AUTH_TYPE_AUTH_SUB}. If
* the $authToken is not null, this field has to be supplied. Optional, default is null.
* @param array $contextArray The context array holds header information and can contain authorization information
* in the headers. Optional, the default is null.
* @throws Picasa_Exception_FailedAuthorizationException If $authToken is supplied but not $authType, or
* if $authToken is not equal to {@link Picasa::$AUTH_TYPE_CLIENT_LOGIN}
* or {@link Picasa::$AUTH_TYPE_AUTH_SUB}.
*/
public function __construct($authToken=null, $authType=null, $contextArray=null) {
if ($authToken != null) {
if ($authType == null) {
throw new Picasa_Exception_FailedAuthorizationException("You must declare an authorization type along with the token.");
}
if ($authType != Picasa::$AUTH_TYPE_AUTH_SUB && $authType != Picasa::$AUTH_TYPE_CLIENT_LOGIN) {
throw new Picasa_Exception_FailedAuthorizationException("Invalid authorization type was supplied.");
}
$this->setAuthorizationInfo($authToken, $authType);
} else if ($contextArray != null) {
$this->contextArray = $contextArray;
} else {
$this->contextArray = $this->constructContextArray(false);
$this->auth=null;
}
}
/**
* Sets the private fields in the object with authorization information that is passed in.
* The fields are accessed when requests that require authorization are executed.
*
* @access public
* @param string $authToken An authorization token returned by Picasa when a successful authentication request is executed.
* @param string $authType A string indicating which type of authorization was requested. Options are "ClientLogin"
* and "AuthSub". ClientLogin allows authorization directly with a username and password
* sent by the server, whereas AuthSub requires that the user be redirected to a login page hosted by Google.
* @return void
*/
public function setAuthorizationInfo ($authToken, $authType) {
$this->auth = $authToken;
$this->authType = $authType;
$this->contextArray = $this->constructContextArray(true);
}
/**
* Getter method for the $auth private field.
*
* @access public
* @return string The auth token supplied by executing a successful authentication request to Google.
* The same field is used regardless of the type of authorization requested.
*/
public function getAuthToken() {
return $this->auth;
}
/**
* Fetches the type of authorization this instantiation is configured with.
*
* @access public
* @return int Possible return values are {@link Picasa::$AUTH_TYPE_AUTH_SUB}, {@link Picasa:$AUTH_TYPE_CLIENT_LOGIN},
* and null if this object is not authenticated.
*/
public function getAuthType() {
return $this->authType;
}
/**
* Fetches the context array for this object.
* The context array is defined at all times, whether or not the object is authenticated. However, when it is
* authenticated, it becomes possible to include the authorization token in the array.
*
* @access public
* @return array
*/
public function getContextArray() {
return $this->contextArray;
}
/**
* Turns a context array into a resource, which can then be used in PHP methods such as {@link file_get_contents()} and {@link fopen()}.
*
* @access public
* @return resource A resource representing the context stored in the {@link $contextArray} private member.
* @link http://www.php.net/stream_context_create
*/
public function getContext() {
return stream_context_create($this->contextArray);
}
/**
* Determines whether the instantiated Picasa object has been authenticated.
* In the case of a AuthSub authentication, the validity of the authentication is actually tested. In the case of ClientLogin
* authentication, it just checks for the existence of the auth token; there is no way in Picasa's API
* to test the validity of a ClientLogin authentication. If the instantiation has not been authenticated,
* this method will look for an auth token in the user's cookie and attempt to authenticate the object
* automatically, in which case true will be returned.
*
* @access public
* @return boolean true if this instantiation is authenticated, false otherwise.
*/
public function isAuthenticated() {
if ($this->authType === Picasa::$AUTH_TYPE_CLIENT_LOGIN) {
return true;
} else if ($this->authType === null) {
return false;
} else {
try {
return $this->isAuthorizationValid();
} catch (Picasa_Exception $e) {
return false;
}
}
}
/**
* Clears authentication fields in the object and sets the header information back to the default, non-autenticated version.
* Also clear the authorization out of the user's cookie. It essentially logs them out.
*
* @access public
* @return void
*/
public function clearAuthentication() {
if (array_key_exists(Picasa::$COOKIE_NAME_AUTH_SUB_TOKEN, $_COOKIE)) {
@setcookie(Picasa::$COOKIE_NAME_AUTH_SUB_TOKEN, "");
}
if (array_key_exists(Picasa::$COOKIE_NAME_CLIENT_LOGIN_TOKEN, $_COOKIE)) {
@setcookie(Picasa::$COOKIE_NAME_CLIENT_LOGIN_TOKEN, "");
}
$this->auth = null;
$this->emailAddress = null;
$this->contextArray = $this->constructContextArray(false);
$this->authType = null;
}
/**
* Authorizes a Google email address through the Client Login method, described in Google's documentation
* ({@link http://code.google.com/apis/accounts/docs/AuthForInstalledApps.html}). This allows special functions such
* as posting images and comments.
*
* On a successful authorization, true is returned and the $auth private member is set to the authorization string
* returned by Google. If the authorization attempt fails, false is returned, and the $error private member is set
* to the error code returned by Google. Possible error codes can be found at the URL listed above.
*
* @param string $emailAddress The email address of the account that is going to be authorized. Can also just be the user's Google
* username.
* @param string $password The account's password, required for authorization.
* @param string $source The source, which is a three part string. This string should take the form:
* "companyName-applicationName-versionID". Optional, the default is null.
* @param string $loginToken The token returned by Google when the CAPTCHA challenge was requested. Use
* {@link Picasa_Exception_CaptchaRequiredException::getCaptchaToken()} to get this value. If the client
* is not responding to a Captcha challenge, leave this null. Optional, the default is null.
* @param string $loginCaptcha The text input by the user representing the CAPTCHA challenge presented to them. If the client
* is not responding to a Captcha challenge, leave this null. Optional, the default is null.
* @param boolean $saveAuthorizationToCookie If this is true, the authorization token returned from Google is stored in the users'
* browser cookie so that it can be retrieved later and the user can be logged in without
* have to enter his email address and password (assuming the cookie and token both
* do not expire. false will only store the token in the current instance, which is not
* persistent and disapears as soon as the page loads. Optional, the default is true.
* @param int $expires The number of seconds after the cookie is set that it should expire. If $saveAuthorizationToCookie
* is false, this parameter is ignored. Optional, the default is 2,592,000 seconds (30 days).
* @param string $service The service that the account is being authorized for. Each service has a different service
* code. The code for Picasa is lh2, which is the default.
* @return string The authorization token returned by Google.
* @throws Picasa_Exception_CaptchaRequiredException If the response from Google indicates that a CAPTCHA challenge is required.
* @throws Picasa_Exception_InvalidUsernameOrPasswordException If either the username or password that was supplied was invalid.
* @throws Picasa_Exception A more generic exception if a different type of error occurs.
* @link http://code.google.com/apis/accounts/docs/AuthForInstalledApps.html
*/
public function authorizeWithClientLogin($emailAddress, $password, $source=null, $loginToken=null, $loginCaptcha=null, $saveAuthorizationToCookie=true, $expires=2592000, $service="lh2")
{
$this->emailAddress = $emailAddress;
Picasa_Logger::getLogger()->logIfEnabled("Authenticating for ".$emailAddress);
if ($source == null) {
$source = $this->emailAddress."-UsingLightweightPicasaAPI-3.0";
}
$host="www.google.com";
$path="/accounts/ClientLogin";
$data="Email=".urlencode($emailAddress)."&Passwd=".urlencode($password)."&service=".urlencode($service)."&source=".urlencode($source);
if ($loginToken != null && $loginCaptcha != null) {
$data .= "&logintoken=".urlencode($loginToken)."&logincaptcha=".urlencode($loginCaptcha);
}
$buf = "";
try {
$buf = Picasa::do_request($host, $path, $data, "POST", null, "application/x-www-form-urlencoded", "ssl://", 443);
} catch (Picasa_Exception $e) {
$buf = $e->getResponse();
$errorValue = Picasa::getResponseValue($buf,"Error");
// A CAPTCHA may be required here, so pull the necessary information out of the response
if (strcmp($errorValue,"CaptchaRequired") == 0) {
$url = Picasa::getResponseValue($buf,"Url");
$token = Picasa::getResponseValue($buf,"CaptchaToken");
$captchaUrl = Picasa::getResponseValue($buf,"CaptchaUrl");
throw new Picasa_Exception_CaptchaRequiredException("A CAPTCHA is required.", $e->getUrl(), $emailAddress, $password, $token, $captchaUrl, $buf);
} else if (strcmp($errorValue,"BadAuthentication") == 0) {
throw new Picasa_Exception_InvalidUsernameOrPasswordException("Username or password was invalid.");
} else {
throw Picasa::getExceptionFromInvalidPost($e->getResponse(), $e->getMessage());
}
}
$authString = Picasa::getResponseValue($buf,"Auth");
$this->setAuthorizationInfo($authString, Picasa::$AUTH_TYPE_CLIENT_LOGIN);
if ($saveAuthorizationToCookie) {
$this->saveAuthToCookie($expires);
}
return $authString;
}
/**
* Authorizes the current object with Google's AuthSub authorization method, described in Google's documentation
* ({@link http://code.google.com/apis/accounts/docs/AuthForWebApps.html}). With this method, the user has to
* have been redirected to a Google login page ({@link redirectToLoginPage()}) and granted access to your application
* to access their private data. This method should be called on the page that the user is directed to after he
* logs in. This method will always convert the token recieved from a single use token to a session token (for
* your convenience).
*
* This method will return the authorization token returned from Google. However, the current object is automatically
* authenticated when this method executes successfully and that token is automatically saved in the {@link Picasa:$auth}
* field. The returned token is probably not useful in many cases, but there wasn't anything better to return.
*
* @access public
* @param string $token An authorization token supplied by Picasa in a URL parameter called "token"
* after the user logs in through the Google-hosted login page. Optional, the default
* is null. If null is passed, the token is taken from the $_GET superglobal.
* @param boolean $saveAuthorizationToCookie If true, the returned authentication token is saved to the
* user's cookie. If false, just stores the token in the $auth
* field of the current object. Optional, default is true.
* @param int $expires The number of seconds after the current time that the cookie should remain in
* the user's browser for. Optional, default is 2592000 (30 days).
* @return string The authorization token returned from Google.
* @see redirectToLoginPage()
* @link http://code.google.com/apis/accounts/docs/AuthForWebApps.html
*/
public function authorizeWithAuthSub ($token=null, $saveAuthorizationToCookie=true, $expires=2592000) {
if ($token == null || strcmp($token, "") == 0 || strcmp($token, "null") == 0) {
if (array_key_exists("token", $_GET)) {
$token = @$_GET['token'];
} else {
throw new Picasa_Exception_FailedAuthorizationException("No token was found. The token must either be passed to this method or accessible from the URL as a parameter.");
}
}
$this->setAuthorizationInfo($token, Picasa::$AUTH_TYPE_AUTH_SUB);
$sessionToken = null;
try {
$sessionToken = $this->convertFromSingleUseToSessionToken();
} catch (Picasa_Exception $e) {
throw new Picasa_Exception_FailedAuthorizationException($e->getMessage());
}
if ($saveAuthorizationToCookie) {
$this->saveAuthToCookie($expires);
}
return $sessionToken;
}
/**
* Checks if an AuthSub authorization is valid by requesting the information from Picasa.
* This method can only be used
* on AuthSub authorizations; Picasa does not currently support this feature for Client Login authentications.
*
* @access public
* @return boolean true if the authorization is valid, false if not.
* @throws Picasa_Exception If the authorization is of type Client Login.
*/
public function isAuthorizationValid() {
if ($this->authType == Picasa::$AUTH_TYPE_CLIENT_LOGIN) {
throw new Picasa_Exception("This method only applicable for AuthSub authorizations.");
}
$host = 'www.google.com';
$path = '/accounts/AuthSubTokenInfo';
$header = array(1 => $this->getAuthHeader());
try {
Picasa::do_request($host, $path, null, "GET", $header, "application/x-www-form-urlencoded", 'ssl://', 443);
} catch (Picasa_Exception $e) {
// If there was an exception, we can assume that the authorization is not valid.
return false;
}
return true;
}
/**
* When authorizing with AuthSub, Picasa initially issues a single-use token, which can only be used once.
* This method will convert that single use token into a session token, which will remain valid for a very long time.
*
* @access public
* @return string The authorization token returned from Google.
* @throws {@link Picasa_Exception} If something was wrong with the request to Picasa. In this case the token will not
* be converted. An exception subclass that is specific to the error encountered will
* be thrown, so the client can catch the individual subclasses and respond accordingly.
*/
public function convertFromSingleUseToSessionToken() {
$host='www.google.com';
$path='/accounts/AuthSubSessionToken';
$header = array( 1 => $this->getAuthHeader());
$authString = null;
try {
$buf = Picasa::do_request($host, $path, null, "GET", $header, "application/x-www-form-urlencoded", 'ssl://', 443);
$authString = Picasa::getResponseValue($buf,"Token");
$this->setAuthorizationInfo($authString, Picasa::$AUTH_TYPE_AUTH_SUB);
} catch (Picasa_Exception $e) {
throw Picasa::getExceptionFromInvalidPost($e->getResponse(), $e->getMessage());
}
return $authString;
}
/**
* If the current instantiation is authorized using the "AuthSub" method, this actively invalidates the token.
*
* @access public
* @return boolean true if the authorization was successfully deactivated. false if it was not.
* @throws Picasa_Exception If the current instantiation is not authorized with AuthSub.
*/
public function deauthorize () {
// Deauthorizations only available with AuthSub
if ($this->authType == Picasa::$AUTH_TYPE_CLIENT_LOGIN) {
throw new Picasa_Exception("Deauthorization only available with AuthSub type authorizations.");
}
$host = 'www.google.com';
$path = '/accounts/AuthSubRevokeToken';
$header = array (1 => $this->getAuthHeader());
try {
Picasa::do_request($host, $path, null, "GET", $header, "application/x-www-form-urlencoded", 'ssl://', 443);
$this->clearAuthentication();
} catch (Picasa_Exception $e) {
throw Picasa::getExceptionFromInvalidPost($e->getResponse(), $e->getMessage());
}
return true;
}
/**
* Saves the authentication token that was returned from Google to the user's browser in a cookie.
* This way it can be accessed later and if it's still valid, the user does not need to be required to log in again. Since this deals
* with cookies, no output can go to the browser before this method is called or it will fail.
*
* @access protected
* @param int $expires The number of seconds after the current time that the cookie should remain in the user's
* browser for. Optional, default is2592000 (30 days).
* @return boolean The result of the call to PHP's {@see setcookie()} function.
* @link http://us2.php.net/manual/en/function.setcookie.php
*/
protected function saveAuthToCookie($expires=2592000) {
$cookieName = Picasa::$COOKIE_NAME_AUTH_SUB_TOKEN;
if ($this->authType == Picasa::$AUTH_TYPE_CLIENT_LOGIN) {
$cookieName = Picasa::$COOKIE_NAME_CLIENT_LOGIN_TOKEN;
}
return @setcookie($cookieName, $this->auth, time()+$expires);
}
/**
* Redirects the user to Google's AuthSub login page so that they can login to access restricted functions.
* The URL in the $next parameter must be registered with Google. At the URL specified there, the "token" value must be pulled from
* the request and passed to {@see Picasa::authorizeWithAuthSub()} for the authorization to be complete.
*
* @access public
* @static
* @param string $next The URL that the user should be redirected to after visiting the login page. This URL must be
* registered with Google in advance. See
* {@link http://code.google.com/apis/accounts/docs/RegistrationForWebAppsAuto.html}.
* @param int $session Must be either 1 or 0. This indicates if the login should be transferable to a session
* token, which is valid for a long time, wherease the default token is only useable once.
* 1 to enable session tokens, 0 to disable.
* @return void
*/
public static function redirectToLoginPage($next, $session=1) {
$url = Picasa::getUrlToLoginPage($next, $session);
header("Location: $url");
}
/**
* Constructs the URL that the user should be redirected to in order to be authorized with the AuthSub method.
* The URL is a page hosted by Google that will allow the user to login to his Picasa Account. When the user returns to the client
* domain (specified in the $next parameter), a token supplied, appended to the URL. Retrieving that token (using
* PHP's "$_GET" superglobal; the key is "token") and pass it to {@link authorizeWithAuthSub} to enable requests for the user
* that were previously disabled, such as posting photos and accessing private albums.
*
* @access public
* @static
* @param string $next The URL that the user should be redirected to once they have logged into their account.
* @param int $session Must be either 1 or 0. This indicates if the login should be transferable to a session
* token, which is valid for a long time, wherease the default token is only useable once.
* 1 to enable session tokens, 0 to disable.
* @return string The URL that the user should be redirected to in order to log in to their Picasa account.
*/
public static function getUrlToLoginPage ($next, $session=1) {
$url = 'https://www.google.com/accounts/AuthSubRequest?next='.urlencode($next).'&scope='.urlencode(Picasa::$BASE_QUERY_URL).'&session='.$session;
return $url;
}
/**
* Retrieves a list of Picasa Albums contained within a {@link Picasa_Account} object based on the criteria supplied.
* Passing null for any of the parameters will leave it up to Picasa to define the default values.
*
* @access public
* @param string $username The username on the account to get the albums for.
* @param int $maxResults The maximum number of results to return. Optional, the default is null.
* @param int $startIndex The first element number with the search results to return. Useful for pagination. Optional,
* the default is null.
* @param string $visibility Restrict the search to albums with the access rights specified here. Options are "public",
* "private", and "all". Authorization is required for "private" and "all" options. Optional,
* default is "public".
* @param int $thumbsize Comma-delimited list of thumbnail sizes to fetch. Options are 32, 48, 64, 72, 144, 160, 200,
* 288, 320, 400, 512, 576, 640, 720, 800. URLs for the corresponding thumbnails are stored in
* the $thumbUrlMap of the {@link Picasa_Image} class. Optional, default is null. The default
* value will let Picasa choose the thumbnail sizes, which are stored in the $smallThumb,
* $mediumThumb, and $largeThumb fields of the {@link Picasa_Image} class.
* @param int $imgmax Size of image to return in the $content field of the {@link Picasa_Image} field. Options are
* 32, 48, 64, 72, 144, 160, 200, 288, 320, 400, 512, 576, 640, 720, 800, 912, 1024, 1152, 1280,
* 1440, 1600. Only values of 800 and less are displayable within a <a> HTML tag, all other
* values can only be downloaded directly through the user's browser. Optional, default value is
* null. The default value will let Picasa determine the size to return, which will not be useable
* within a <a> tag.
* @return Picasa_Account An Account including all albums within the specified user's account.
* @throws {@link Picasa_Exception} If the request was somehow invalid. This could mean that the requested object
* does not have permission to retrieve the feed or the parameters supplied are not
* allowed by Picasa, or a number of other possible errors. A subclass of
* {@link Picasa_Exception} will be thrown, which will indicate specifically what
* the problem was with the request.
* @link http://code.google.com/apis/picasaweb/reference.html#Parameters
*/
public function getAlbumsByUsername($username, $maxResults=null, $startIndex=null, $visibility="public", $thumbsize=null, $imgmax=null) {
$query = Picasa::$BASE_QUERY_URL.'/user/'.$username.'?kind=album';
$query.=Picasa::buildQueryParams($maxResults, $startIndex, null, null, $visibility, $thumbsize, $imgmax);
$account = null;
$useCache = false;
if (strcmp($visibility,"public") === 0) {
$useCache = true;
}
try {
Picasa_Logger::getLogger()->logIfEnabled("Fetching albums for user ".$username);
$account = new Picasa_Account($query, null, $this->contextArray, $useCache);
} catch (Picasa_Exception $e) {
throw $e;
}
return $account;
}
/**
* Retrieves all images meeting the supplied parameters.
* Passing null for any of the parameters will leave it up to Picasa to define the default values.
*
* @access public
* @param string $username The username on the account to get the images for. Optional, default is null.
* @param int $maxResults The maximum number of results to return. Optional, the default is null.
* @param int $startIndex The first element number with the search results to return. Useful for pagination.
* Optional, the default is null.
* @param string $keywords Space-delimited list of keywords to search for. Title and description are included
* in the search. Optional, default is an empty string.
* @param string $tags Space-delimited list of tags to search for. Only images with all tags in the list are
* included in the search results. Optional, default is empty string.
* @param string $visibility Restrict the search to images with the access rights specified here. Options are
* "public", "private", and "all". Authorization is required for "private" and "all" options.
* Optional, default is "public".
* @param int $thumbsize Comma-delimited list of thumbnail sizes to fetch. Options are 32, 48, 64, 72, 144, 160,
* 200, 288, 320, 400, 512, 576, 640, 720, 800. URLs for the corresponding thumbnails are stored
* in the $thumbUrlMap of the {@link Picasa_Image} class. Optional, default is null. The default
* value will let Picasa choose the thumbnail sizes, which are stored in the $smallThumb, $mediumThumb,
* and $largeThumb fields of the {@link Picasa_Image} class.
* @param int $imgmax Size of image to return in the $content field of the {@link Picasa_Image} field. Options are 32,
* 48, 64, 72, 144, 160, 200, 288, 320, 400, 512, 576, 640, 720, 800, 912, 1024, 1152, 1280, 1440,
* 1600. Only values of 800 and less are displayable within a <a> HTML tag, all other values can
* only be downloaded directly through the user's browser. Optional, default value is null. The
* default value will let Picasa determine the size to return, which will not be useable within a <a> tag.
* @param string $sortDescending Whether or not to sort the items returned by date added descending.
* @param string $boundingBox Searches for images tagged as having been taken within a set of four coordinates. The
* coordinates should be in the order west, south, east, north
* @param string $location Searches for photos tagged as having been taken at a named location. For instance "London".
* @return Picasa_ImageCollection An object holding meta information about the requested feed, as well as an array of
* {@link Picasa_Image} objects with each object that meets the supplied parameters.
* @throws {@link Picasa_Exception} If the request was somehow invalid. This could mean that the requested object
* does not have permission to retrieve the feed or the parameters supplied are not
* allowed by Picasa, or a number of other possible errors. A subclass of
* {@link Picasa_Exception} will be thrown, which will indicate specifically what
* the problem was with the request.
* @link http://code.google.com/apis/picasaweb/reference.html#Parameters
*/
public function getImages($username=null, $maxResults=null, $startIndex=null, $keywords=null, $tags=null, $visibility=null, $thumbsize=null, $imgmax=null, $sortDescending=true, $boundingBox=null, $location=null) {
$query = Picasa::$BASE_QUERY_URL;
if ($username==null) {
$query .= '/all';
} else {
$query .= '/user/'.$username;
}
$query .= '?kind=photo'.Picasa::buildQueryParams($maxResults, $startIndex, $keywords, $tags, $visibility, $thumbsize, $imgmax, null, $sortDescending, $boundingBox, $location);
$images = null;
$useCache = false;
if (strcmp($visibility,"public") === 0) {
$useCache = true;
}
try {
$images = new Picasa_ImageCollection($query, null, $this->contextArray, $useCache);
} catch (Picasa_Exception $e) {
throw $e;
}
return $images;
}
/**
* Retrieves the Picasa web album with the specified id.
* The album will contain all images that meet the specified criteria and is in the specified album.
* Passing null for any of the parameters will leave it up to Picasa to define the default values.
*
* @access public
* @param string $username The username on the account that the album is in.
* @param string $albumid The id number of the desired album.
* @param int $maxResults The maximum number of results to return. Optional, the default is null.
* @param int $startIndex The first element number with the search results to return. Useful for pagination.
* Optional, the default is null.
* @param string $keywords Space-delimited list of keywords to search for. Title and description are included in
* the search. Optional, default is an empty string.
* @param string $tags Space-delimited list of tags to search for. Only images with all tags in the list are
* included in the search results. Optional, default is empty string.
* @param int $thumbsize Comma-delimited list of thumbnail sizes to fetch. Options are 32, 48, 64, 72, 144, 160, 200,
* 288, 320, 400, 512, 576, 640, 720, 800. URLs for the corresponding thumbnails are stored in the
* $thumbUrlMap of the {@link Picasa_Image} class. Optional, default is null. The default value
* will let Picasa choose the thumbnail sizes, which are stored in the $smallThumb, $mediumThumb,
* and $largeThumb fields of the {@link Picasa_Image} class.
* @param int $imgmax Size of image to return in the $content field of the {@link Picasa_Image} field. Options are 32,
* 48, 64, 72, 144, 160, 200, 288, 320, 400, 512, 576, 640, 720, 800, 912, 1024, 1152, 1280, 1440,
* 1600. Only values of 800 and less are displayable within a <a> HTML tag, all other values can
* only be downloaded directly through the user's browser. Optional, default value is null. The
* default value will let Picasa determine the size to return, which will not be useable within a <a> tag.
* @return Picasa_Album An object representing the album with the supplied id. Only photos in the album that meet
* the parameters passed into this method will be included in the album. This way, you can
* (for isntance) search for tags and keywords within an album.
* @throws {@link Picasa_Exception} If the request was somehow invalid. This could mean that the requested object
* does not have permission to retrieve the feed or the parameters supplied are not
* allowed by Picasa, or a number of other possible errors. A subclass of
* {@link Picasa_Exception} will be thrown, which will indicate specifically what
* the problem was with the request.
* @link http://code.google.com/apis/picasaweb/reference.html#Parameters
*/
public function getAlbumById($username, $albumid, $maxResults=null, $startIndex=null, $keywords=null, $tags=null, $thumbsize=null, $imgmax=null) {
$query = Picasa::$BASE_QUERY_URL . '/user/'.$username . '/albumid/'.$albumid;
$query.='?kind=photo'.Picasa::buildQueryParams($maxResults, $startIndex, $keywords, $tags, null, $thumbsize, $imgmax);
$album = null;
// See if the instance is authenticated and don't use the cache if it is just in case
// Use a quick way to test for authentication because it would take too long to validate
$useCache = false;
if ($this->auth === null) {
$useCache = true;
}
try {
Picasa_Logger::getLogger()->logIfEnabled("Fetching album ".$albumid." for user ".$username);
$album = new Picasa_Album($query, null, $this->contextArray, $useCache);
} catch (Picasa_Exception $e) {
throw $e;
}
return $album;
}
/**
* Retrieves an Album as an Entry as opposed to a Feed.
* Picasa's data api makes a distinction between the two. The
* two different types will sometimes contain different fields. This method should only be used if you are sure that the
* field you need is not accessible through a feed, only through an entry. It is declared protected so that client code
* cannot call it directly, only extensions of the Picasa class.
*
* @access protected
* @param string $username The username on the account that the album is in.
* @param string $albumid The id number of the desired album.
* @throws {@link Picasa_Exception} If the request was somehow invalid. This could mean that the requested object
* does not have permission to retrieve the feed or the parameters supplied are not
* allowed by Picasa, or a number of other possible errors. A subclass of
* {@link Picasa_Exception} will be thrown, which will indicate specifically what
* the problem was with the request.
* @link http://code.google.com/apis/picasaweb/reference.html#Parameters
*/
protected function getAlbumByIdAsEntry($username, $albumid) {
$query = Picasa::$BASE_ENTRY_QUERY_URL . '/user/'.$username . '/albumid/'.$albumid;
$album = null;
$useCache = true;
if ($this->auth !== null) {
$useCache = false;
}
try {
$album = new Picasa_Album($query, null, $this->contextArray, $useCache);
} catch (Picasa_Exception $e) {
throw $e;
}
return $album;
}
/**
* Retrieves the image with the given id.
*
* @access public
* @todo Refactor to use buildQueryParams()
* @param string $username The username on the account that the image is in.
* @param string $albumid The id number of the album that the image is located in.
* @param string $imageid The id number of the desired image.
* @param int $thumbsize Comma-delimited list of thumbnail sizes to fetch. Options are 32, 48, 64, 72, 144, 160, 200,
* 288, 320, 400, 512, 576, 640, 720, 800. URLs for the corresponding thumbnails are stored in the
* $thumbUrlMap of the {@link Picasa_Image} class. Optional, default is null. The default value
* will let Picasa choose the thumbnail sizes, which are stored in the $smallThumb, $mediumThumb,
* and $largeThumb fields of the {@link Picasa_Image} class.
* @param int $imgmax Size of image to return in the $content field of the {@link Picasa_Image} field. Options are 32,
* 48, 64, 72, 144, 160, 200, 288, 320, 400, 512, 576, 640, 720, 800, 912, 1024, 1152, 1280, 1440,
* 1600. Only values of 800 and less are displayable within a <a> HTML tag, all other values can
* only be downloaded directly through the user's browser. Optional, default value is null. The
* default value will let Picasa determine the size to return, which will not be useable within a <a> tag.
* @return Picasa_Image The requested image.
* @throws {@link Picasa_Exception} If the request was somehow invalid. For instance, if
* the image or album do not exist.
*/
public function getImageById($username, $albumid, $imageid, $thumbsize=null, $imgmax=null) {
$image = null;
$params = '';
if ($thumbsize !== null) {
$params .= '?thumbsize='.$thumbsize;
if ($imgmax !== null) {
$params .= '&imgmax='.$imgmax;
}
} else if ($imgmax !== null) {
$params .= '?imgmax='.$imgmax;
}
$useCache = true;
if ($this->auth !== null) {
$useCache = false;
}
try {
Picasa_Logger::getLogger()->logIfEnabled("Fetching image ".$imageid." for user ".$username);
$image = new Picasa_Image(Picasa::$BASE_QUERY_URL.'/user/'.$username.'/albumid/'.$albumid.'/photoid/'.$imageid.$params, null, $this->contextArray, $useCache);
} catch (Picasa_Exception $e) {
throw $e;
}
return $image;
}
/**
* Retrieves the image with the given id as an entry as opposed to a feed.
* Picasa's data api makes a distinction between the two. The
* two different types will sometimes contain different fields. This method should only be used if you are sure that the
* field you need is not accessible through a feed, only through an entry. It is declared protected so that client code
* cannot call it directly, only extensions of the Picasa class.
*
* @access protected
* @param string $username The username on the account that the image is in.
* @param string $albumid The id number of the album that the image is located in.
* @param string $imageid The id number of the desired image.
* @return Picasa_Image The requested image.
* @throws {@link Picasa_Exception} If the request was somehow invalid. For instance, if
* the image or album do not exist.
*/
protected function getImageByIdAsEntry($username, $albumid, $imageid) {
$image = null;
$useCache = true;
if ($this->auth !== null) {
$useCache = false;
}
try {
$image = new Picasa_Image(Picasa::$BASE_ENTRY_QUERY_URL.'/user/'.$username.'/albumid/'.$albumid.'/photoid/'.$imageid, null, $this->contextArray, $useCache);
} catch (Picasa_Exception $e) {
throw $e;
}
return $image;
}
/**
* Retrieves tags that meet the supplied parameters.
* Notice that this method will not retrieve tags specific to one
* image. To get tags by image, get an entire image object (using, for instance, {@link getImageById()}),
* and then call {@link Picasa_Image::getTags()} on that image.
* Passing null for any of the parameters will leave it up to Picasa to define the default values.
*
* @access public
* @param string $username The username on the account to get the tags out of.
* @param string $albumid The id number of the album that the requested tags are in. Optional, the default is null.
* @param int $maxResults The maximum number of results to return. Optional, the default is null.
* @param int $startIndex The first element number with the search results to return. Useful for pagination. Optional,
* the default is null.
* @param string $visibility Restrict the search to tags in images with the access rights specified here.
* Options are "public", "private", and "all". Authorization is required for "private" and
* "all" options. Optional, default is "public".
* @return array An array of {@link Picasa_Tag} objects, one for each tag in the requested feed.
* @throws {@link Picasa_Exception} If the request was somehow invalid. This could mean that the requested object
* does not have permission to retrieve the feed or the parameters supplied are not
* allowed by Picasa, or a number of other possible errors. A subclass of
* {@link Picasa_Exception} will be thrown, which will indicate specifically what
* the problem was with the request.
*/
public function getTagsByUsername($username, $albumid=null, $maxResults=null, $startIndex=null, $visibility="public") {
$query = Picasa::$BASE_QUERY_URL.'/user/'.$username;
if ($albumid != null) {
$query.='/albumid/'.$albumid;
}
$query.='?kind=tag'.Picasa::buildQueryParams($maxResults, $startIndex, null, null, $visibility, null, null);
$tags = null;
$useCache = false;
if (strcmp($visibility,"public") === 0) {
$useCache = true;
}
try {
$tags = Picasa_Tag::getTagArray($query, null, $this->contextArray, $useCache);
} catch (Picasa_Exception $e) {
throw $e;
}
return $tags;
}
/**
* Retrieves the comment with the given id.
*
* @access public
* @param string $username The username on the account that the comment is in.
* @param string $albumid The id number of the album that the comment is located in.
* @param string $imageid The id number of the image that the comment is in.
* @param string $commentid The id number of the requested comment.
* @return Picasa_Image The requested comment.
* @throws {@link Picasa_Exception} If the request was somehow invalid. For instance, if
* the image or album or comment do not exist.
*/
public function getCommentById($username, $albumid, $imageid, $commentid) {
$comment = null;
$useCache = true;
if ($this->auth !== null) {
$useCache = false;
}
try {
// Comments have to be retrieved with the entry url
$comment = new Picasa_Comment(null, Picasa::$BASE_ENTRY_QUERY_URL.'/user/'.$username.'/albumid/'.$albumid.'/photoid/'.$imageid.'/commentid/'.$commentid, $this->contextArray, $useCache);
} catch (Picasa_Exception $e) {
throw $e;
}
return $comment;
}
/**
* Gets all comments that meet the criteria specified in the parameters.
* The client can request images specific to
* just a user or to a user and an album. To get comments specific to an image, use {@link getImageById()} and call
* {@link Picasa_Image::getComments()} on the returned object.
* Passing null for any of the parameters will leave it up to Picasa to define the default values.
*
* @access public
* @param string $username The username on the account to get the comments out of. It is not possible to get
* comments without specifying the username, so this field is required.
* @param string $albumid The id number of the album that the desired comments are in. Optional, the default
* is null.
* @param int $maxResults The maximum number of results to return. Optional, the default is null.
* @param int $startIndex The first element number with the search results to return. Useful for pagination.
* Optional, the default is null.
* @param string $visibility Restrict the search to comments in images with the access rights specified here.
* Options are "public", "private", and "all". Authorization is required for "private"
* and "all" options. Optional, default is "public".
* @return array An array of {@link Picasa_Comment} objects, one for each comment in the requested feed.
* @throws {@link Picasa_Exception} If something was wrong with the requested feed. A specific subclass of
* {@link Picasa_Exception} will be thrown based on what kind of problem was
* encountered, unless the type of error was unknown, in which case {@link Picasa_Exception}
* itself will be thrown.
*/
public function getCommentsByUsername($username, $albumid=null, $maxResults=null, $startIndex=null, $visibility="public") {
$query = Picasa::$BASE_QUERY_URL.'/user/'.$username;
if ($albumid != null) {
$query.='/albumid/'.$albumid;
}
$query.='?kind=comment'.Picasa::buildQueryParams($maxResults, $startIndex, null, null, $visibility, null, null);
$comments = null;
$useCache = false;
if (strcmp($visibility,"public") === 0) {
$useCache = true;
}
try {
$comments = Picasa_Comment::getCommentArray($query, null, $this->contextArray, $useCache);
} catch (Picasa_Exception $e) {
throw $e;
}
return $comments;
}
/**
* Retrieves contacts of the user specified in the parameter.
* A contact is a Picasa user who the specified user
* has declared as a "Favorite". Should return an empty array unless the current Picasa instantiation is authorized.
*
* @access public
* @param string $username The username on the account to get the contacts from.
* @return array An array of {@link Picasa_Author} objects, one for each of the user's contacts.