3 * Copyright 2010 Google Inc.
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
18 // Check for the required json and curl extensions, the Google APIs PHP Client
19 // won't function without them.
20 if (! function_exists('curl_init')) {
21 throw new Exception('Google PHP API Client requires the CURL PHP extension');
24 if (! function_exists('json_decode')) {
25 throw new Exception('Google PHP API Client requires the JSON PHP extension');
28 if (! function_exists('http_build_query')) {
29 throw new Exception('Google PHP API Client requires http_build_query()');
32 if (! ini_get('date.timezone') && function_exists('date_default_timezone_set')) {
33 date_default_timezone_set('UTC');
36 // hack around with the include paths a bit so the library 'just works'
37 set_include_path(dirname(__FILE__) . PATH_SEPARATOR . get_include_path());
39 require_once "config.php";
40 // If a local configuration file is found, merge it's values with the default configuration
41 if (file_exists(dirname(__FILE__) . '/local_config.php')) {
42 $defaultConfig = $apiConfig;
43 require_once (dirname(__FILE__) . '/local_config.php');
44 $apiConfig = array_merge($defaultConfig, $apiConfig);
47 // Include the top level classes, they each include their own dependencies
48 require_once 'service/Google_Model.php';
49 require_once 'service/Google_Service.php';
50 require_once 'service/Google_ServiceResource.php';
51 require_once 'auth/Google_AssertionCredentials.php';
52 require_once 'auth/Google_Signer.php';
53 require_once 'auth/Google_P12Signer.php';
54 require_once 'service/Google_BatchRequest.php';
55 require_once 'external/URITemplateParser.php';
56 require_once 'auth/Google_Auth.php';
57 require_once 'cache/Google_Cache.php';
58 require_once 'io/Google_IO.php';
59 require_once('service/Google_MediaFileUpload.php');
62 * The Google API Client
63 * http://code.google.com/p/google-api-php-client/
65 * @author Chris Chabot <chabotc@google.com>
66 * @author Chirag Shah <chirags@google.com>
71 * @var Google_Auth $auth
83 * @var Google_Cache $cache
89 * @var boolean $useBatch
91 static $useBatch = false;
93 /** @var array $scopes */
94 protected $scopes = array();
96 /** @var bool $useObjects */
97 protected $useObjects = false;
99 // definitions of services that are discovered.
100 protected $services = array();
102 // Used to track authenticated state, can't discover services after doing authenticate()
103 private $authenticated = false;
105 public function __construct($config = array()) {
107 $apiConfig = array_merge($apiConfig, $config);
108 self::$cache = new $apiConfig['cacheClass']();
109 self::$auth = new $apiConfig['authClass']();
110 self::$io = new $apiConfig['ioClass']();
116 public function addService($service, $version = false) {
118 if ($this->authenticated) {
119 throw new Google_Exception('Cant add services after having authenticated');
121 $this->services[$service] = array();
122 if (isset($apiConfig['services'][$service])) {
123 // Merge the service descriptor with the default values
124 $this->services[$service] = array_merge($this->services[$service], $apiConfig['services'][$service]);
128 public function authenticate($code = null) {
129 $service = $this->prepareService();
130 $this->authenticated = true;
131 return self::$auth->authenticate($service, $code);
136 * @visible For Testing
138 public function prepareService() {
142 $scopes = $this->scopes;
144 foreach ($this->services as $key => $val) {
145 if (isset($val['scope'])) {
146 if (is_array($val['scope'])) {
147 $scopes = array_merge($val['scope'], $scopes);
149 $scopes[] = $val['scope'];
152 $scopes[] = 'https://www.googleapis.com/auth/' . $key;
154 unset($val['discoveryURI']);
155 unset($val['scope']);
156 $service = array_merge($service, $val);
159 $service['scope'] = implode(' ', $scopes);
164 * Set the OAuth 2.0 access token using the string that resulted from calling authenticate()
165 * or Google_Client#getAccessToken().
166 * @param string $accessToken JSON encoded string containing in the following format:
167 * {"access_token":"TOKEN", "refresh_token":"TOKEN", "token_type":"Bearer",
168 * "expires_in":3600, "id_token":"TOKEN", "created":1320790426}
170 public function setAccessToken($accessToken) {
171 if ($accessToken == null || 'null' == $accessToken) {
174 self::$auth->setAccessToken($accessToken);
178 * Set the type of Auth class the client should use.
179 * @param string $authClassName
181 public function setAuthClass($authClassName) {
182 self::$auth = new $authClassName();
186 * Construct the OAuth 2.0 authorization request URI.
189 public function createAuthUrl() {
190 $service = $this->prepareService();
191 return self::$auth->createAuthUrl($service['scope']);
195 * Get the OAuth 2.0 access token.
196 * @return string $accessToken JSON encoded string in the following format:
197 * {"access_token":"TOKEN", "refresh_token":"TOKEN", "token_type":"Bearer",
198 * "expires_in":3600,"id_token":"TOKEN", "created":1320790426}
200 public function getAccessToken() {
201 $token = self::$auth->getAccessToken();
202 return (null == $token || 'null' == $token) ? null : $token;
206 * Returns if the access_token is expired.
207 * @return bool Returns True if the access_token is expired.
209 public function isAccessTokenExpired() {
210 return self::$auth->isAccessTokenExpired();
214 * Set the developer key to use, these are obtained through the API Console.
215 * @see http://code.google.com/apis/console-help/#generatingdevkeys
216 * @param string $developerKey
218 public function setDeveloperKey($developerKey) {
219 self::$auth->setDeveloperKey($developerKey);
223 * Set OAuth 2.0 "state" parameter to achieve per-request customization.
224 * @see http://tools.ietf.org/html/draft-ietf-oauth-v2-22#section-3.1.2.2
225 * @param string $state
227 public function setState($state) {
228 self::$auth->setState($state);
232 * @param string $accessType Possible values for access_type include:
233 * {@code "offline"} to request offline access from the user. (This is the default value)
234 * {@code "online"} to request online access from the user.
236 public function setAccessType($accessType) {
237 self::$auth->setAccessType($accessType);
241 * @param string $approvalPrompt Possible values for approval_prompt include:
242 * {@code "force"} to force the approval UI to appear. (This is the default value)
243 * {@code "auto"} to request auto-approval when possible.
245 public function setApprovalPrompt($approvalPrompt) {
246 self::$auth->setApprovalPrompt($approvalPrompt);
250 * Set the application name, this is included in the User-Agent HTTP header.
251 * @param string $applicationName
253 public function setApplicationName($applicationName) {
255 $apiConfig['application_name'] = $applicationName;
259 * Set the OAuth 2.0 Client ID.
260 * @param string $clientId
262 public function setClientId($clientId) {
264 $apiConfig['oauth2_client_id'] = $clientId;
265 self::$auth->clientId = $clientId;
269 * Get the OAuth 2.0 Client ID.
271 public function getClientId() {
272 return self::$auth->clientId;
276 * Set the OAuth 2.0 Client Secret.
277 * @param string $clientSecret
279 public function setClientSecret($clientSecret) {
281 $apiConfig['oauth2_client_secret'] = $clientSecret;
282 self::$auth->clientSecret = $clientSecret;
286 * Get the OAuth 2.0 Client Secret.
288 public function getClientSecret() {
289 return self::$auth->clientSecret;
293 * Set the OAuth 2.0 Redirect URI.
294 * @param string $redirectUri
296 public function setRedirectUri($redirectUri) {
298 $apiConfig['oauth2_redirect_uri'] = $redirectUri;
299 self::$auth->redirectUri = $redirectUri;
303 * Get the OAuth 2.0 Redirect URI.
305 public function getRedirectUri() {
306 return self::$auth->redirectUri;
310 * Fetches a fresh OAuth 2.0 access token with the given refresh token.
311 * @param string $refreshToken
314 public function refreshToken($refreshToken) {
315 self::$auth->refreshToken($refreshToken);
319 * Revoke an OAuth2 access token or refresh token. This method will revoke the current access
320 * token, if a token isn't provided.
321 * @throws Google_AuthException
322 * @param string|null $token The token (access token or a refresh token) that should be revoked.
323 * @return boolean Returns True if the revocation was successful, otherwise False.
325 public function revokeToken($token = null) {
326 self::$auth->revokeToken($token);
330 * Verify an id_token. This method will verify the current id_token, if one
332 * @throws Google_AuthException
333 * @param string|null $token The token (id_token) that should be verified.
334 * @return Google_LoginTicket Returns an apiLoginTicket if the verification was
337 public function verifyIdToken($token = null) {
338 return self::$auth->verifyIdToken($token);
342 * @param Google_AssertionCredentials $creds
345 public function setAssertionCredentials(Google_AssertionCredentials $creds) {
346 self::$auth->setAssertionCredentials($creds);
350 * This function allows you to overrule the automatically generated scopes,
351 * so that you can ask for more or less permission in the auth flow
352 * Set this before you call authenticate() though!
353 * @param array $scopes, ie: array('https://www.googleapis.com/auth/plus.me', 'https://www.googleapis.com/auth/moderator')
355 public function setScopes($scopes) {
356 $this->scopes = is_string($scopes) ? explode(" ", $scopes) : $scopes;
360 * Declare if objects should be returned by the api service classes.
362 * @param boolean $useObjects True if objects should be returned by the service classes.
363 * False if associative arrays should be returned (default behavior).
366 public function setUseObjects($useObjects) {
368 $apiConfig['use_objects'] = $useObjects;
372 * Declare if objects should be returned by the api service classes.
374 * @param boolean $useBatch True if the experimental batch support should
375 * be enabled. Defaults to False.
378 public function setUseBatch($useBatch) {
379 self::$useBatch = $useBatch;
384 * @return Google_Auth the implementation of apiAuth.
386 public static function getAuth() {
387 return Google_Client::$auth;
392 * @return Google_IO the implementation of apiIo.
394 public static function getIo() {
395 return Google_Client::$io;
399 * @return Google_Cache the implementation of apiCache.
401 public function getCache() {
402 return Google_Client::$cache;
406 // Exceptions that the Google PHP API Library can throw
407 class Google_Exception extends Exception {}
408 class Google_AuthException extends Google_Exception {}
409 class Google_CacheException extends Google_Exception {}
410 class Google_IOException extends Google_Exception {}
411 class Google_ServiceException extends Google_Exception {
413 * Optional list of errors returned in a JSON body of an HTTP error response.
415 protected $errors = array();
418 * Override default constructor to add ability to set $errors.
420 * @param string $message
422 * @param Exception|null $previous
423 * @param [{string, string}] errors List of errors returned in an HTTP
424 * response. Defaults to [].
426 public function __construct($message, $code = 0, Exception $previous = null,
428 if(version_compare(PHP_VERSION, '5.3.0') >= 0) {
429 parent::__construct($message, $code, $previous);
431 parent::__construct($message, $code);
434 $this->errors = $errors;
438 * An example of the possible errors returned.
441 * "domain": "global",
442 * "reason": "authError",
443 * "message": "Invalid Credentials",
444 * "locationType": "header",
445 * "location": "Authorization",
448 * @return [{string, string}] List of errors return in an HTTP response or [].
450 public function getErrors() {
451 return $this->errors;