04efba3a by Jeff Balicki

Oauth

1 parent 329f0d2f
Showing 71 changed files with 4140 additions and 35 deletions
<?php
session_start();
if(!isset($_SESSION['google_data'])):header("Location:index.php");endif;
?>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Login with Google Account by CodexWorld</title>
<style type="text/css">
h1
{
font-family:Arial, Helvetica, sans-serif;
color:#999999;
}
.wrapper{width:600px; margin-left:auto;margin-right:auto;}
.welcome_txt{
margin: 20px;
background-color: #EBEBEB;
padding: 10px;
border: #D6D6D6 solid 1px;
-moz-border-radius:5px;
-webkit-border-radius:5px;
border-radius:5px;
}
.google_box{
margin: 20px;
background-color: #FFF0DD;
padding: 10px;
border: #F7CFCF solid 1px;
-moz-border-radius:5px;
-webkit-border-radius:5px;
border-radius:5px;
}
.google_box .image{ text-align:center;}
</style>
</head>
<body>
<div class="wrapper">
<h1>Google Profile Details </h1>
<?php
echo '<div class="welcome_txt">Welcome <b>'.$_SESSION['google_data']['given_name'].'</b></div>';
echo '<div class="google_box">';
echo '<p class="image"><img src="'.$_SESSION['google_data']['picture'].'" alt="" width="300" height="220"/></p>';
echo '<p><b>Google ID : </b>' . $_SESSION['google_data']['id'].'</p>';
echo '<p><b>Name : </b>' . $_SESSION['google_data']['name'].'</p>';
echo '<p><b>Email : </b>' . $_SESSION['google_data']['email'].'</p>';
echo '<p><b>Gender : </b>' . $_SESSION['google_data']['gender'].'</p>';
echo '<p><b>Locale : </b>' . $_SESSION['google_data']['locale'].'</p>';
echo '<p><b>Google+ Link : </b>' . $_SESSION['google_data']['link'].'</p>';
echo '<p><b>You are login with : </b>Google</p>';
echo '<p><b>Logout from <a href="logout.php?logout">Google</a></b></p>';
echo '</div>';
?>
</div>
</body>
</html>
\ No newline at end of file
<?php
//session_start();
include_once("src/Google_Client.php");
include_once("src/contrib/Google_Oauth2Service.php");
######### edit details ##########
$clientId = '326088686201-1llld5s7s3uhb2shl4g2g9djkvq584pc.apps.googleusercontent.com'; //Google CLIENT ID
$clientSecret = 'F4Fa8MdTT17f4voG4lRaOCuc'; //Google CLIENT SECRET
$redirectUrl = 'http://banners.gotenzing.com/oauth2callback'; //return url (url to script)
$homeUrl = 'http://banners.gotenzing.com/'; //return to home
##################################
$gClient = new Google_Client();
$gClient->setApplicationName('banners.gotenzing.com');
$gClient->setClientId($clientId);
$gClient->setClientSecret($clientSecret);
$gClient->setRedirectUri($redirectUrl);
$google_oauthV2 = new Google_Oauth2Service($gClient);
?>
\ No newline at end of file
<?php
if (!isset($_SESSION['token'])){
include(' loggedin.php');
echo '<form>
<dl class="TzMenu"><a style="font-size: 25px; color: #fff !important;" href="./login.php" target="_parent">Login</a></dl></form>';
}else{
include('loggedin.php');
return;
?>
<form method="post">
<dl class="TzMenu">
<dt><label for="username">Username:</label></dt>
<dd><input type="text" name="username" id="username" /></dd>
</dl>
<dl class="TzMenu">
<dt><label for="password">Password:</label></dt>
<dd><input type="password" name="password" id="password" /></dd>
</dl>
<dl class="TzMenu">
<dt><input type="submit" value=" Log In " /></dt>
</dl>
</form>
<script type="text/javascript">
addEvent(window, 'load', function() {
document.getElementById('username').select();
});
</script>
};
\ No newline at end of file
......
<?php
class Users {
public $tableName = 'users';
function __construct(){
//database configuration
$dbServer = 'localhost'; //Define database server host
$dbUsername = 'root'; //Define database username
$dbPassword = 'root'; //Define database password
$dbName = 'banners'; //Define database name
//connect databse
$con = mysqli_connect($dbServer,$dbUsername,$dbPassword,$dbName);
if(mysqli_connect_errno()){
die("Failed to connect with MySQL: ".mysqli_connect_error());
}else{
$this->connect = $con;
}
}
function checkUser($oauth_provider,$oauth_uid,$fname,$lname,$email,$gender,$locale,$link,$picture){
$prevQuery = mysqli_query($this->connect,"SELECT * FROM $this->tableName WHERE oauth_provider = '".$oauth_provider."' AND oauth_uid = '".$oauth_uid."'") or die(mysqli_error($this->connect));
if(mysqli_num_rows($prevQuery) > 0){
$update = mysqli_query($this->connect,"UPDATE $this->tableName SET oauth_provider = '".$oauth_provider."', oauth_uid = '".$oauth_uid."', fname = '".$fname."', lname = '".$lname."', email = '".$email."', gender = '".$gender."', locale = '".$locale."', picture = '".$picture."', gpluslink = '".$link."', modified = '".date("Y-m-d H:i:s")."' WHERE oauth_provider = '".$oauth_provider."' AND oauth_uid = '".$oauth_uid."'") or die(mysqli_error($this->connect));
}else{
$insert = mysqli_query($this->connect,"INSERT INTO $this->tableName SET oauth_provider = '".$oauth_provider."', oauth_uid = '".$oauth_uid."', fname = '".$fname."', lname = '".$lname."', email = '".$email."', gender = '".$gender."', locale = '".$locale."', picture = '".$picture."', gpluslink = '".$link."', created = '".date("Y-m-d H:i:s")."', modified = '".date("Y-m-d H:i:s")."'") or die(mysqli_error($this->connect));
}
$query = mysqli_query($this->connect,"SELECT * FROM $this->tableName WHERE oauth_provider = '".$oauth_provider."' AND oauth_uid = '".$oauth_uid."'") or die(mysqli_error($this->connect));
$result = mysqli_fetch_array($query);
return $result;
}
}
?>
\ No newline at end of file
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Tenzing Communications Inc.</title>
<style type="text/css">
body {
margin:0;
padding:0;
background-color: #3b0d32;
color: #777;
}
#login{
display: table;
margin: 0 auto;
}
</style>
<script type="text/javascript">
// document.domain = 'gotenzing.com';
</script>
</head>
<body><div id="login"><?php
include_once("./config.php");
include_once("functions.php");
//print_r($_GET);die;
if(isset($_REQUEST['code'])){
$gClient->authenticate();
$_SESSION['token'] = $gClient->getAccessToken();
header('Location: ' . filter_var($redirect_url, FILTER_SANITIZE_URL));
}
if (isset($_SESSION['token'])) {
$gClient->setAccessToken($_SESSION['token']);
}
if ($gClient->getAccessToken()) {
$userProfile = $google_oauthV2->userinfo->get();
//DB Insert
$gUser = new Users();
$gUser->checkUser('google',$userProfile['id'],$userProfile['given_name'],$userProfile['family_name'],$userProfile['email'],$userProfile['gender'],$userProfile['locale'],$userProfile['link'],$userProfile['picture']);
$_SESSION['google_data'] = $userProfile; // Storing Google User Data in Session
header("location: account.php");
$_SESSION['token'] = $gClient->getAccessToken();
} else {
$authUrl = $gClient->createAuthUrl();
}
echo '<img src="tenzing.gif" width="259" alt="Tenzing" /></br>';
if(isset($authUrl)) {
echo '<a href="'.$authUrl.'"><img width="259" style="padding:20px;" src="./images/glogin.png" alt=""/></a>';
} else {
}
?>
</div>
</body>
</html>
<?php
include_once("config.php");
if(array_key_exists('logout',$_GET))
{
unset($_SESSION['token']);
unset($_SESSION['google_data']); //Google session data unset
$gClient->revokeToken();
session_destroy();
header("Location:index.php");
}
?>
\ No newline at end of file
<?php
session_start();
$db = new mysqli('localhost', 'root', 'root');
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
......@@ -8,7 +8,7 @@
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Tenzing Communications Inc.</title>
<script src="https://apis.google.com/js/platform.js" async defer></script>
<style type="text/css">
body, h1 {
margin: 0;
......@@ -55,11 +55,13 @@
</head>
<body>
<?php
<?php
if (isset($_SESSION['username'])) {
include('includes/loggedin.php');
?>
} else {
include('includes/auth.php');
}
?>
<div id="TzLogo">
<img src="tenzing.gif" width="259" height="75" alt="Tenzing" />
......
<?php
/*
* Copyright 2012 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Credentials object used for OAuth 2.0 Signed JWT assertion grants.
*
* @author Chirag Shah <chirags@google.com>
*/
class Google_AssertionCredentials {
const MAX_TOKEN_LIFETIME_SECS = 3600;
public $serviceAccountName;
public $scopes;
public $privateKey;
public $privateKeyPassword;
public $assertionType;
public $prn;
/**
* @param $serviceAccountName
* @param $scopes array List of scopes
* @param $privateKey
* @param string $privateKeyPassword
* @param string $assertionType
* @param bool|string $prn The email address of the user for which the
* application is requesting delegated access.
*/
public function __construct(
$serviceAccountName,
$scopes,
$privateKey,
$privateKeyPassword = 'notasecret',
$assertionType = 'http://oauth.net/grant_type/jwt/1.0/bearer',
$prn = false) {
$this->serviceAccountName = $serviceAccountName;
$this->scopes = is_string($scopes) ? $scopes : implode(' ', $scopes);
$this->privateKey = $privateKey;
$this->privateKeyPassword = $privateKeyPassword;
$this->assertionType = $assertionType;
$this->prn = $prn;
}
public function generateAssertion() {
$now = time();
$jwtParams = array(
'aud' => Google_OAuth2::OAUTH2_TOKEN_URI,
'scope' => $this->scopes,
'iat' => $now,
'exp' => $now + self::MAX_TOKEN_LIFETIME_SECS,
'iss' => $this->serviceAccountName,
);
if ($this->prn !== false) {
$jwtParams['prn'] = $this->prn;
}
return $this->makeSignedJwt($jwtParams);
}
/**
* Creates a signed JWT.
* @param array $payload
* @return string The signed JWT.
*/
private function makeSignedJwt($payload) {
$header = array('typ' => 'JWT', 'alg' => 'RS256');
$segments = array(
Google_Utils::urlSafeB64Encode(json_encode($header)),
Google_Utils::urlSafeB64Encode(json_encode($payload))
);
$signingInput = implode('.', $segments);
$signer = new Google_P12Signer($this->privateKey, $this->privateKeyPassword);
$signature = $signer->sign($signingInput);
$segments[] = Google_Utils::urlSafeB64Encode($signature);
return implode(".", $segments);
}
}
<?php
/*
* Copyright 2010 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
require_once "Google_AuthNone.php";
require_once "Google_OAuth2.php";
/**
* Abstract class for the Authentication in the API client
* @author Chris Chabot <chabotc@google.com>
*
*/
abstract class Google_Auth {
abstract public function authenticate($service);
abstract public function sign(Google_HttpRequest $request);
abstract public function createAuthUrl($scope);
abstract public function getAccessToken();
abstract public function setAccessToken($accessToken);
abstract public function setDeveloperKey($developerKey);
abstract public function refreshToken($refreshToken);
abstract public function revokeToken();
}
<?php
/*
* Copyright 2010 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Do-nothing authentication implementation, use this if you want to make un-authenticated calls
* @author Chris Chabot <chabotc@google.com>
* @author Chirag Shah <chirags@google.com>
*/
class Google_AuthNone extends Google_Auth {
public $key = null;
public function __construct() {
global $apiConfig;
if (!empty($apiConfig['developer_key'])) {
$this->setDeveloperKey($apiConfig['developer_key']);
}
}
public function setDeveloperKey($key) {$this->key = $key;}
public function authenticate($service) {/*noop*/}
public function setAccessToken($accessToken) {/* noop*/}
public function getAccessToken() {return null;}
public function createAuthUrl($scope) {return null;}
public function refreshToken($refreshToken) {/* noop*/}
public function revokeToken() {/* noop*/}
public function sign(Google_HttpRequest $request) {
if ($this->key) {
$request->setUrl($request->getUrl() . ((strpos($request->getUrl(), '?') === false) ? '?' : '&')
. 'key='.urlencode($this->key));
}
return $request;
}
}
<?php
/*
* Copyright 2011 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Class to hold information about an authenticated login.
*
* @author Brian Eaton <beaton@google.com>
*/
class Google_LoginTicket {
const USER_ATTR = "id";
// Information from id token envelope.
private $envelope;
// Information from id token payload.
private $payload;
/**
* Creates a user based on the supplied token.
*
* @param string $envelope Header from a verified authentication token.
* @param string $payload Information from a verified authentication token.
*/
public function __construct($envelope, $payload) {
$this->envelope = $envelope;
$this->payload = $payload;
}
/**
* Returns the numeric identifier for the user.
* @throws Google_AuthException
* @return
*/
public function getUserId() {
if (array_key_exists(self::USER_ATTR, $this->payload)) {
return $this->payload[self::USER_ATTR];
}
throw new Google_AuthException("No user_id in token");
}
/**
* Returns attributes from the login ticket. This can contain
* various information about the user session.
* @return array
*/
public function getAttributes() {
return array("envelope" => $this->envelope, "payload" => $this->payload);
}
}
<?php
/*
* Copyright 2011 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Signs data.
*
* Only used for testing.
*
* @author Brian Eaton <beaton@google.com>
*/
class Google_P12Signer extends Google_Signer {
// OpenSSL private key resource
private $privateKey;
// Creates a new signer from a .p12 file.
function __construct($p12, $password) {
if (!function_exists('openssl_x509_read')) {
throw new Exception(
'The Google PHP API library needs the openssl PHP extension');
}
// This throws on error
$certs = array();
if (!openssl_pkcs12_read($p12, $certs, $password)) {
throw new Google_AuthException("Unable to parse the p12 file. " .
"Is this a .p12 file? Is the password correct? OpenSSL error: " .
openssl_error_string());
}
// TODO(beaton): is this part of the contract for the openssl_pkcs12_read
// method? What happens if there are multiple private keys? Do we care?
if (!array_key_exists("pkey", $certs) || !$certs["pkey"]) {
throw new Google_AuthException("No private key found in p12 file.");
}
$this->privateKey = openssl_pkey_get_private($certs["pkey"]);
if (!$this->privateKey) {
throw new Google_AuthException("Unable to load private key in ");
}
}
function __destruct() {
if ($this->privateKey) {
openssl_pkey_free($this->privateKey);
}
}
function sign($data) {
if(version_compare(PHP_VERSION, '5.3.0') < 0) {
throw new Google_AuthException(
"PHP 5.3.0 or higher is required to use service accounts.");
}
if (!openssl_sign($data, $signature, $this->privateKey, "sha256")) {
throw new Google_AuthException("Unable to sign data");
}
return $signature;
}
}
<?php
/*
* Copyright 2011 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Verifies signatures using PEM encoded certificates.
*
* @author Brian Eaton <beaton@google.com>
*/
class Google_PemVerifier extends Google_Verifier {
private $publicKey;
/**
* Constructs a verifier from the supplied PEM-encoded certificate.
*
* $pem: a PEM encoded certificate (not a file).
* @param $pem
* @throws Google_AuthException
* @throws Google_Exception
*/
function __construct($pem) {
if (!function_exists('openssl_x509_read')) {
throw new Google_Exception('Google API PHP client needs the openssl PHP extension');
}
$this->publicKey = openssl_x509_read($pem);
if (!$this->publicKey) {
throw new Google_AuthException("Unable to parse PEM: $pem");
}
}
function __destruct() {
if ($this->publicKey) {
openssl_x509_free($this->publicKey);
}
}
/**
* Verifies the signature on data.
*
* Returns true if the signature is valid, false otherwise.
* @param $data
* @param $signature
* @throws Google_AuthException
* @return bool
*/
function verify($data, $signature) {
$status = openssl_verify($data, $signature, $this->publicKey, "sha256");
if ($status === -1) {
throw new Google_AuthException('Signature verification error: ' . openssl_error_string());
}
return $status === 1;
}
}
<?php
/*
* Copyright 2011 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
require_once "Google_P12Signer.php";
/**
* Signs data.
*
* @author Brian Eaton <beaton@google.com>
*/
abstract class Google_Signer {
/**
* Signs data, returns the signature as binary data.
*/
abstract public function sign($data);
}
<?php
/*
* Copyright 2011 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
require_once "Google_PemVerifier.php";
/**
* Verifies signatures.
*
* @author Brian Eaton <beaton@google.com>
*/
abstract class Google_Verifier {
/**
* Checks a signature, returns true if the signature is correct,
* false otherwise.
*/
abstract public function verify($data, $signature);
}
<?php
/*
* Copyright 2010 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* A persistent storage class based on the APC cache, which is not
* really very persistent, as soon as you restart your web server
* the storage will be wiped, however for debugging and/or speed
* it can be useful, kinda, and cache is a lot cheaper then storage.
*
* @author Chris Chabot <chabotc@google.com>
*/
class googleApcCache extends Google_Cache {
public function __construct() {
if (! function_exists('apc_add')) {
throw new Google_CacheException("Apc functions not available");
}
}
private function isLocked($key) {
if ((@apc_fetch($key . '.lock')) === false) {
return false;
}
return true;
}
private function createLock($key) {
// the interesting thing is that this could fail if the lock was created in the meantime..
// but we'll ignore that out of convenience
@apc_add($key . '.lock', '', 5);
}
private function removeLock($key) {
// suppress all warnings, if some other process removed it that's ok too
@apc_delete($key . '.lock');
}
private function waitForLock($key) {
// 20 x 250 = 5 seconds
$tries = 20;
$cnt = 0;
do {
// 250 ms is a long time to sleep, but it does stop the server from burning all resources on polling locks..
usleep(250);
$cnt ++;
} while ($cnt <= $tries && $this->isLocked($key));
if ($this->isLocked($key)) {
// 5 seconds passed, assume the owning process died off and remove it
$this->removeLock($key);
}
}
/**
* @inheritDoc
*/
public function get($key, $expiration = false) {
if (($ret = @apc_fetch($key)) === false) {
return false;
}
if (!$expiration || (time() - $ret['time'] > $expiration)) {
$this->delete($key);
return false;
}
return unserialize($ret['data']);
}
/**
* @inheritDoc
*/
public function set($key, $value) {
if (@apc_store($key, array('time' => time(), 'data' => serialize($value))) == false) {
throw new Google_CacheException("Couldn't store data");
}
}
/**
* @inheritDoc
* @param String $key
*/
public function delete($key) {
@apc_delete($key);
}
}
<?php
/*
* Copyright 2008 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
require_once "Google_FileCache.php";
require_once "Google_MemcacheCache.php";
/**
* Abstract storage class
*
* @author Chris Chabot <chabotc@google.com>
*/
abstract class Google_Cache {
/**
* Retrieves the data for the given key, or false if they
* key is unknown or expired
*
* @param String $key The key who's data to retrieve
* @param boolean|int $expiration Expiration time in seconds
*
*/
abstract function get($key, $expiration = false);
/**
* Store the key => $value set. The $value is serialized
* by this function so can be of any type
*
* @param string $key Key of the data
* @param string $value data
*/
abstract function set($key, $value);
/**
* Removes the key/data pair for the given $key
*
* @param String $key
*/
abstract function delete($key);
}
<?php
/*
* Copyright 2008 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* This class implements a basic on disk storage. While that does
* work quite well it's not the most elegant and scalable solution.
* It will also get you into a heap of trouble when you try to run
* this in a clustered environment. In those cases please use the
* MySql back-end
*
* @author Chris Chabot <chabotc@google.com>
*/
class Google_FileCache extends Google_Cache {
private $path;
public function __construct() {
global $apiConfig;
$this->path = $apiConfig['ioFileCache_directory'];
}
private function isLocked($storageFile) {
// our lock file convention is simple: /the/file/path.lock
return file_exists($storageFile . '.lock');
}
private function createLock($storageFile) {
$storageDir = dirname($storageFile);
if (! is_dir($storageDir)) {
// @codeCoverageIgnoreStart
if (! @mkdir($storageDir, 0755, true)) {
// make sure the failure isn't because of a concurrency issue
if (! is_dir($storageDir)) {
throw new Google_CacheException("Could not create storage directory: $storageDir");
}
}
// @codeCoverageIgnoreEnd
}
@touch($storageFile . '.lock');
}
private function removeLock($storageFile) {
// suppress all warnings, if some other process removed it that's ok too
@unlink($storageFile . '.lock');
}
private function waitForLock($storageFile) {
// 20 x 250 = 5 seconds
$tries = 20;
$cnt = 0;
do {
// make sure PHP picks up on file changes. This is an expensive action but really can't be avoided
clearstatcache();
// 250 ms is a long time to sleep, but it does stop the server from burning all resources on polling locks..
usleep(250);
$cnt ++;
} while ($cnt <= $tries && $this->isLocked($storageFile));
if ($this->isLocked($storageFile)) {
// 5 seconds passed, assume the owning process died off and remove it
$this->removeLock($storageFile);
}
}
private function getCacheDir($hash) {
// use the first 2 characters of the hash as a directory prefix
// this should prevent slowdowns due to huge directory listings
// and thus give some basic amount of scalability
return $this->path . '/' . substr($hash, 0, 2);
}
private function getCacheFile($hash) {
return $this->getCacheDir($hash) . '/' . $hash;
}
public function get($key, $expiration = false) {
$storageFile = $this->getCacheFile(md5($key));
// See if this storage file is locked, if so we wait upto 5 seconds for the lock owning process to
// complete it's work. If the lock is not released within that time frame, it's cleaned up.
// This should give us a fair amount of 'Cache Stampeding' protection
if ($this->isLocked($storageFile)) {
$this->waitForLock($storageFile);
}
if (file_exists($storageFile) && is_readable($storageFile)) {
$now = time();
if (! $expiration || (($mtime = @filemtime($storageFile)) !== false && ($now - $mtime) < $expiration)) {
if (($data = @file_get_contents($storageFile)) !== false) {
$data = unserialize($data);
return $data;
}
}
}
return false;
}
public function set($key, $value) {
$storageDir = $this->getCacheDir(md5($key));
$storageFile = $this->getCacheFile(md5($key));
if ($this->isLocked($storageFile)) {
// some other process is writing to this file too, wait until it's done to prevent hickups
$this->waitForLock($storageFile);
}
if (! is_dir($storageDir)) {
if (! @mkdir($storageDir, 0755, true)) {
throw new Google_CacheException("Could not create storage directory: $storageDir");
}
}
// we serialize the whole request object, since we don't only want the
// responseContent but also the postBody used, headers, size, etc
$data = serialize($value);
$this->createLock($storageFile);
if (! @file_put_contents($storageFile, $data)) {
$this->removeLock($storageFile);
throw new Google_CacheException("Could not store data in the file");
}
$this->removeLock($storageFile);
}
public function delete($key) {
$file = $this->getCacheFile(md5($key));
if (! @unlink($file)) {
throw new Google_CacheException("Cache file could not be deleted");
}
}
}
<?php
/*
* Copyright 2008 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* A persistent storage class based on the memcache, which is not
* really very persistent, as soon as you restart your memcache daemon
* the storage will be wiped, however for debugging and/or speed
* it can be useful, kinda, and cache is a lot cheaper then storage.
*
* @author Chris Chabot <chabotc@google.com>
*/
class Google_MemcacheCache extends Google_Cache {
private $connection = false;
public function __construct() {
global $apiConfig;
if (! function_exists('memcache_connect')) {
throw new Google_CacheException("Memcache functions not available");
}
$this->host = $apiConfig['ioMemCacheCache_host'];
$this->port = $apiConfig['ioMemCacheCache_port'];
if (empty($this->host) || empty($this->port)) {
throw new Google_CacheException("You need to supply a valid memcache host and port");
}
}
private function isLocked($key) {
$this->check();
if ((@memcache_get($this->connection, $key . '.lock')) === false) {
return false;
}
return true;
}
private function createLock($key) {
$this->check();
// the interesting thing is that this could fail if the lock was created in the meantime..
// but we'll ignore that out of convenience
@memcache_add($this->connection, $key . '.lock', '', 0, 5);
}
private function removeLock($key) {
$this->check();
// suppress all warnings, if some other process removed it that's ok too
@memcache_delete($this->connection, $key . '.lock');
}
private function waitForLock($key) {
$this->check();
// 20 x 250 = 5 seconds
$tries = 20;
$cnt = 0;
do {
// 250 ms is a long time to sleep, but it does stop the server from burning all resources on polling locks..
usleep(250);
$cnt ++;
} while ($cnt <= $tries && $this->isLocked($key));
if ($this->isLocked($key)) {
// 5 seconds passed, assume the owning process died off and remove it
$this->removeLock($key);
}
}
// I prefer lazy initialization since the cache isn't used every request
// so this potentially saves a lot of overhead
private function connect() {
if (! $this->connection = @memcache_pconnect($this->host, $this->port)) {
throw new Google_CacheException("Couldn't connect to memcache server");
}
}
private function check() {
if (! $this->connection) {
$this->connect();
}
}
/**
* @inheritDoc
*/
public function get($key, $expiration = false) {
$this->check();
if (($ret = @memcache_get($this->connection, $key)) === false) {
return false;
}
if (! $expiration || (time() - $ret['time'] > $expiration)) {
$this->delete($key);
return false;
}
return $ret['data'];
}
/**
* @inheritDoc
* @param string $key
* @param string $value
* @throws Google_CacheException
*/
public function set($key, $value) {
$this->check();
// we store it with the cache_time default expiration so objects will at least get cleaned eventually.
if (@memcache_set($this->connection, $key, array('time' => time(),
'data' => $value), false) == false) {
throw new Google_CacheException("Couldn't store data in cache");
}
}
/**
* @inheritDoc
* @param String $key
*/
public function delete($key) {
$this->check();
@memcache_delete($this->connection, $key);
}
}
<?php
/*
* Copyright 2010 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
global $apiConfig;
$apiConfig = array(
// True if objects should be returned by the service classes.
// False if associative arrays should be returned (default behavior).
'use_objects' => false,
// The application_name is included in the User-Agent HTTP header.
'application_name' => '',
// OAuth2 Settings, you can get these keys at https://code.google.com/apis/console
'oauth2_client_id' => '',
'oauth2_client_secret' => '',
'oauth2_redirect_uri' => '',
// The developer key, you get this at https://code.google.com/apis/console
'developer_key' => '',
// Site name to show in the Google's OAuth 1 authentication screen.
'site_name' => 'www.example.org',
// Which Authentication, Storage and HTTP IO classes to use.
'authClass' => 'Google_OAuth2',
'ioClass' => 'Google_CurlIO',
'cacheClass' => 'Google_FileCache',
// Don't change these unless you're working against a special development or testing environment.
'basePath' => 'https://www.googleapis.com',
// IO Class dependent configuration, you only have to configure the values
// for the class that was configured as the ioClass above
'ioFileCache_directory' =>
(function_exists('sys_get_temp_dir') ?
sys_get_temp_dir() . '/Google_Client' :
'/tmp/Google_Client'),
// Definition of service specific values like scopes, oauth token URLs, etc
'services' => array(
'analytics' => array('scope' => 'https://www.googleapis.com/auth/analytics.readonly'),
'calendar' => array(
'scope' => array(
"https://www.googleapis.com/auth/calendar",
"https://www.googleapis.com/auth/calendar.readonly",
)
),
'books' => array('scope' => 'https://www.googleapis.com/auth/books'),
'latitude' => array(
'scope' => array(
'https://www.googleapis.com/auth/latitude.all.best',
'https://www.googleapis.com/auth/latitude.all.city',
)
),
'moderator' => array('scope' => 'https://www.googleapis.com/auth/moderator'),
'oauth2' => array(
'scope' => array(
'https://www.googleapis.com/auth/userinfo.profile',
'https://www.googleapis.com/auth/userinfo.email',
)
),
'plus' => array('scope' => 'https://www.googleapis.com/auth/plus.me'),
'siteVerification' => array('scope' => 'https://www.googleapis.com/auth/siteverification'),
'tasks' => array('scope' => 'https://www.googleapis.com/auth/tasks'),
'urlshortener' => array('scope' => 'https://www.googleapis.com/auth/urlshortener')
)
);
\ No newline at end of file
This diff could not be displayed because it is too large.
<?php
/*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
/**
* The "text" collection of methods.
* Typical usage is:
* <code>
* $freebaseService = new Google_FreebaseService(...);
* $text = $freebaseService->text;
* </code>
*/
class Google_TextServiceResource extends Google_ServiceResource {
/**
* Returns blob attached to node at specified id as HTML (text.get)
*
* @param string $id The id of the item that you want data about
* @param array $optParams Optional parameters.
*
* @opt_param string maxlength The max number of characters to return. Valid only for 'plain' format.
* @opt_param string format Sanitizing transformation.
* @return Google_ContentserviceGet
*/
public function get($id, $optParams = array()) {
$params = array('id' => $id);
$params = array_merge($params, $optParams);
$data = $this->__call('get', array($params));
if ($this->useObjects()) {
return new Google_ContentserviceGet($data);
} else {
return $data;
}
}
}
/**
* Service definition for Google_Freebase (v1).
*
* <p>
* Lets you access the Freebase repository of open data.
* </p>
*
* <p>
* For more information about this service, see the
* <a href="http://wiki.freebase.com/wiki/API" target="_blank">API Documentation</a>
* </p>
*
* @author Google, Inc.
*/
class Google_FreebaseService extends Google_Service {
public $text;
/**
* Constructs the internal representation of the Freebase service.
*
* @param Google_Client $client
*/
public function __construct(Google_Client $client) {
$this->servicePath = 'freebase/v1/';
$this->version = 'v1';
$this->serviceName = 'freebase';
$client->addService($this->serviceName, $this->version);
$this->text = new Google_TextServiceResource($this, $this->serviceName, 'text', json_decode('{"methods": {"get": {"httpMethod": "GET", "response": {"$ref": "ContentserviceGet"}, "id": "freebase.text.get", "parameters": {"maxlength": {"type": "integer", "location": "query", "format": "uint32"}, "id": {"repeated": true, "required": true, "type": "string", "location": "path"}, "format": {"default": "plain", "enum": ["html", "plain", "raw"], "type": "string", "location": "query"}}, "path": "text{/id*}"}}}', true));
}
}
class Google_ContentserviceGet extends Google_Model {
public $result;
public function setResult($result) {
$this->result = $result;
}
public function getResult() {
return $this->result;
}
}
<?php
/*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
/**
* The "userinfo" collection of methods.
* Typical usage is:
* <code>
* $oauth2Service = new Google_Oauth2Service(...);
* $userinfo = $oauth2Service->userinfo;
* </code>
*/
class Google_UserinfoServiceResource extends Google_ServiceResource {
/**
* (userinfo.get)
*
* @param array $optParams Optional parameters.
* @return Google_Userinfo
*/
public function get($optParams = array()) {
$params = array();
$params = array_merge($params, $optParams);
$data = $this->__call('get', array($params));
if ($this->useObjects()) {
return new Google_Userinfo($data);
} else {
return $data;
}
}
}
/**
* The "v2" collection of methods.
* Typical usage is:
* <code>
* $oauth2Service = new Google_Oauth2Service(...);
* $v2 = $oauth2Service->v2;
* </code>
*/
class Google_UserinfoV2ServiceResource extends Google_ServiceResource {
}
/**
* The "me" collection of methods.
* Typical usage is:
* <code>
* $oauth2Service = new Google_Oauth2Service(...);
* $me = $oauth2Service->me;
* </code>
*/
class Google_UserinfoV2MeServiceResource extends Google_ServiceResource {
/**
* (me.get)
*
* @param array $optParams Optional parameters.
* @return Google_Userinfo
*/
public function get($optParams = array()) {
$params = array();
$params = array_merge($params, $optParams);
$data = $this->__call('get', array($params));
if ($this->useObjects()) {
return new Google_Userinfo($data);
} else {
return $data;
}
}
}
/**
* Service definition for Google_Oauth2 (v2).
*
* <p>
* OAuth2 API
* </p>
*
* <p>
* For more information about this service, see the
* <a href="" target="_blank">API Documentation</a>
* </p>
*
* @author Google, Inc.
*/
class Google_Oauth2Service extends Google_Service {
public $userinfo;
public $userinfo_v2_me;
/**
* Constructs the internal representation of the Oauth2 service.
*
* @param Google_Client $client
*/
public function __construct(Google_Client $client) {
$this->servicePath = '';
$this->version = 'v2';
$this->serviceName = 'oauth2';
$client->addService($this->serviceName, $this->version);
$this->userinfo = new Google_UserinfoServiceResource($this, $this->serviceName, 'userinfo', json_decode('{"methods": {"get": {"path": "oauth2/v2/userinfo", "scopes": ["https://www.googleapis.com/auth/userinfo.email", "https://www.googleapis.com/auth/userinfo.profile"], "id": "oauth2.userinfo.get", "httpMethod": "GET", "response": {"$ref": "Userinfo"}}}}', true));
$this->userinfo_v2_me = new Google_UserinfoV2MeServiceResource($this, $this->serviceName, 'me', json_decode('{"methods": {"get": {"path": "userinfo/v2/me", "scopes": ["https://www.googleapis.com/auth/userinfo.email", "https://www.googleapis.com/auth/userinfo.profile"], "id": "oauth2.userinfo.v2.me.get", "httpMethod": "GET", "response": {"$ref": "Userinfo"}}}}', true));
}
}
class Google_Tokeninfo extends Google_Model {
public $issued_to;
public $user_id;
public $expires_in;
public $access_type;
public $audience;
public $scope;
public $email;
public $verified_email;
public function setIssued_to($issued_to) {
$this->issued_to = $issued_to;
}
public function getIssued_to() {
return $this->issued_to;
}
public function setUser_id($user_id) {
$this->user_id = $user_id;
}
public function getUser_id() {
return $this->user_id;
}
public function setExpires_in($expires_in) {
$this->expires_in = $expires_in;
}
public function getExpires_in() {
return $this->expires_in;
}
public function setAccess_type($access_type) {
$this->access_type = $access_type;
}
public function getAccess_type() {
return $this->access_type;
}
public function setAudience($audience) {
$this->audience = $audience;
}
public function getAudience() {
return $this->audience;
}
public function setScope($scope) {
$this->scope = $scope;
}
public function getScope() {
return $this->scope;
}
public function setEmail($email) {
$this->email = $email;
}
public function getEmail() {
return $this->email;
}
public function setVerified_email($verified_email) {
$this->verified_email = $verified_email;
}
public function getVerified_email() {
return $this->verified_email;
}
}
class Google_Userinfo extends Google_Model {
public $family_name;
public $name;
public $picture;
public $locale;
public $gender;
public $email;
public $birthday;
public $link;
public $given_name;
public $timezone;
public $id;
public $verified_email;
public function setFamily_name($family_name) {
$this->family_name = $family_name;
}
public function getFamily_name() {
return $this->family_name;
}
public function setName($name) {
$this->name = $name;
}
public function getName() {
return $this->name;
}
public function setPicture($picture) {
$this->picture = $picture;
}
public function getPicture() {
return $this->picture;
}
public function setLocale($locale) {
$this->locale = $locale;
}
public function getLocale() {
return $this->locale;
}
public function setGender($gender) {
$this->gender = $gender;
}
public function getGender() {
return $this->gender;
}
public function setEmail($email) {
$this->email = $email;
}
public function getEmail() {
return $this->email;
}
public function setBirthday($birthday) {
$this->birthday = $birthday;
}
public function getBirthday() {
return $this->birthday;
}
public function setLink($link) {
$this->link = $link;
}
public function getLink() {
return $this->link;
}
public function setGiven_name($given_name) {
$this->given_name = $given_name;
}
public function getGiven_name() {
return $this->given_name;
}
public function setTimezone($timezone) {
$this->timezone = $timezone;
}
public function getTimezone() {
return $this->timezone;
}
public function setId($id) {
$this->id = $id;
}
public function getId() {
return $this->id;
}
public function setVerified_email($verified_email) {
$this->verified_email = $verified_email;
}
public function getVerified_email() {
return $this->verified_email;
}
}
<?php
/*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
/**
* The "languages" collection of methods.
* Typical usage is:
* <code>
* $translateService = new Google_TranslateService(...);
* $languages = $translateService->languages;
* </code>
*/
class Google_LanguagesServiceResource extends Google_ServiceResource {
/**
* List the source/target languages supported by the API (languages.list)
*
* @param array $optParams Optional parameters.
*
* @opt_param string target the language and collation in which the localized results should be returned
* @return Google_LanguagesListResponse
*/
public function listLanguages($optParams = array()) {
$params = array();
$params = array_merge($params, $optParams);
$data = $this->__call('list', array($params));
if ($this->useObjects()) {
return new Google_LanguagesListResponse($data);
} else {
return $data;
}
}
}
/**
* The "detections" collection of methods.
* Typical usage is:
* <code>
* $translateService = new Google_TranslateService(...);
* $detections = $translateService->detections;
* </code>
*/
class Google_DetectionsServiceResource extends Google_ServiceResource {
/**
* Detect the language of text. (detections.list)
*
* @param string $q The text to detect
* @param array $optParams Optional parameters.
* @return Google_DetectionsListResponse
*/
public function listDetections($q, $optParams = array()) {
$params = array('q' => $q);
$params = array_merge($params, $optParams);
$data = $this->__call('list', array($params));
if ($this->useObjects()) {
return new Google_DetectionsListResponse($data);
} else {
return $data;
}
}
}
/**
* The "translations" collection of methods.
* Typical usage is:
* <code>
* $translateService = new Google_TranslateService(...);
* $translations = $translateService->translations;
* </code>
*/
class Google_TranslationsServiceResource extends Google_ServiceResource {
/**
* Returns text translations from one language to another. (translations.list)
*
* @param string $q The text to translate
* @param string $target The target language into which the text should be translated
* @param array $optParams Optional parameters.
*
* @opt_param string source The source language of the text
* @opt_param string format The format of the text
* @opt_param string cid The customization id for translate
* @return Google_TranslationsListResponse
*/
public function listTranslations($q, $target, $optParams = array()) {
$params = array('q' => $q, 'target' => $target);
$params = array_merge($params, $optParams);
$data = $this->__call('list', array($params));
if ($this->useObjects()) {
return new Google_TranslationsListResponse($data);
} else {
return $data;
}
}
}
/**
* Service definition for Google_Translate (v2).
*
* <p>
* Lets you translate text from one language to another
* </p>
*
* <p>
* For more information about this service, see the
* <a href="http://code.google.com/apis/language/translate/v2/using_rest.html" target="_blank">API Documentation</a>
* </p>
*
* @author Google, Inc.
*/
class Google_TranslateService extends Google_Service {
public $languages;
public $detections;
public $translations;
/**
* Constructs the internal representation of the Translate service.
*
* @param Google_Client $client
*/
public function __construct(Google_Client $client) {
$this->servicePath = 'language/translate/';
$this->version = 'v2';
$this->serviceName = 'translate';
$client->addService($this->serviceName, $this->version);
$this->languages = new Google_LanguagesServiceResource($this, $this->serviceName, 'languages', json_decode('{"methods": {"list": {"httpMethod": "GET", "response": {"$ref": "LanguagesListResponse"}, "id": "language.languages.list", "parameters": {"target": {"type": "string", "location": "query"}}, "path": "v2/languages"}}}', true));
$this->detections = new Google_DetectionsServiceResource($this, $this->serviceName, 'detections', json_decode('{"methods": {"list": {"httpMethod": "GET", "response": {"$ref": "DetectionsListResponse"}, "id": "language.detections.list", "parameters": {"q": {"repeated": true, "required": true, "type": "string", "location": "query"}}, "path": "v2/detect"}}}', true));
$this->translations = new Google_TranslationsServiceResource($this, $this->serviceName, 'translations', json_decode('{"methods": {"list": {"httpMethod": "GET", "response": {"$ref": "TranslationsListResponse"}, "id": "language.translations.list", "parameters": {"q": {"repeated": true, "required": true, "type": "string", "location": "query"}, "source": {"type": "string", "location": "query"}, "format": {"enum": ["html", "text"], "type": "string", "location": "query"}, "target": {"required": true, "type": "string", "location": "query"}, "cid": {"repeated": true, "type": "string", "location": "query"}}, "path": "v2"}}}', true));
}
}
class Google_DetectionsListResponse extends Google_Model {
protected $__detectionsType = 'Google_DetectionsResourceItems';
protected $__detectionsDataType = 'array';
public $detections;
public function setDetections(/* array(Google_DetectionsResourceItems) */ $detections) {
$this->assertIsArray($detections, 'Google_DetectionsResourceItems', __METHOD__);
$this->detections = $detections;
}
public function getDetections() {
return $this->detections;
}
}
class Google_DetectionsResourceItems extends Google_Model {
public $isReliable;
public $confidence;
public $language;
public function setIsReliable($isReliable) {
$this->isReliable = $isReliable;
}
public function getIsReliable() {
return $this->isReliable;
}
public function setConfidence($confidence) {
$this->confidence = $confidence;
}
public function getConfidence() {
return $this->confidence;
}
public function setLanguage($language) {
$this->language = $language;
}
public function getLanguage() {
return $this->language;
}
}
class Google_LanguagesListResponse extends Google_Model {
protected $__languagesType = 'Google_LanguagesResource';
protected $__languagesDataType = 'array';
public $languages;
public function setLanguages(/* array(Google_LanguagesResource) */ $languages) {
$this->assertIsArray($languages, 'Google_LanguagesResource', __METHOD__);
$this->languages = $languages;
}
public function getLanguages() {
return $this->languages;
}
}
class Google_LanguagesResource extends Google_Model {
public $name;
public $language;
public function setName($name) {
$this->name = $name;
}
public function getName() {
return $this->name;
}
public function setLanguage($language) {
$this->language = $language;
}
public function getLanguage() {
return $this->language;
}
}
class Google_TranslationsListResponse extends Google_Model {
protected $__translationsType = 'Google_TranslationsResource';
protected $__translationsDataType = 'array';
public $translations;
public function setTranslations(/* array(Google_TranslationsResource) */ $translations) {
$this->assertIsArray($translations, 'Google_TranslationsResource', __METHOD__);
$this->translations = $translations;
}
public function getTranslations() {
return $this->translations;
}
}
class Google_TranslationsResource extends Google_Model {
public $detectedSourceLanguage;
public $translatedText;
public function setDetectedSourceLanguage($detectedSourceLanguage) {
$this->detectedSourceLanguage = $detectedSourceLanguage;
}
public function getDetectedSourceLanguage() {
return $this->detectedSourceLanguage;
}
public function setTranslatedText($translatedText) {
$this->translatedText = $translatedText;
}
public function getTranslatedText() {
return $this->translatedText;
}
}
<?php
/*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
/**
* The "url" collection of methods.
* Typical usage is:
* <code>
* $urlshortenerService = new Google_UrlshortenerService(...);
* $url = $urlshortenerService->url;
* </code>
*/
class Google_UrlServiceResource extends Google_ServiceResource {
/**
* Creates a new short URL. (url.insert)
*
* @param Google_Url $postBody
* @param array $optParams Optional parameters.
* @return Google_Url
*/
public function insert(Google_Url $postBody, $optParams = array()) {
$params = array('postBody' => $postBody);
$params = array_merge($params, $optParams);
$data = $this->__call('insert', array($params));
if ($this->useObjects()) {
return new Google_Url($data);
} else {
return $data;
}
}
/**
* Retrieves a list of URLs shortened by a user. (url.list)
*
* @param array $optParams Optional parameters.
*
* @opt_param string start-token Token for requesting successive pages of results.
* @opt_param string projection Additional information to return.
* @return Google_UrlHistory
*/
public function listUrl($optParams = array()) {
$params = array();
$params = array_merge($params, $optParams);
$data = $this->__call('list', array($params));
if ($this->useObjects()) {
return new Google_UrlHistory($data);
} else {
return $data;
}
}
/**
* Expands a short URL or gets creation time and analytics. (url.get)
*
* @param string $shortUrl The short URL, including the protocol.
* @param array $optParams Optional parameters.
*
* @opt_param string projection Additional information to return.
* @return Google_Url
*/
public function get($shortUrl, $optParams = array()) {
$params = array('shortUrl' => $shortUrl);
$params = array_merge($params, $optParams);
$data = $this->__call('get', array($params));
if ($this->useObjects()) {
return new Google_Url($data);
} else {
return $data;
}
}
}
/**
* Service definition for Google_Urlshortener (v1).
*
* <p>
* Lets you create, inspect, and manage goo.gl short URLs
* </p>
*
* <p>
* For more information about this service, see the
* <a href="http://code.google.com/apis/urlshortener/v1/getting_started.html" target="_blank">API Documentation</a>
* </p>
*
* @author Google, Inc.
*/
class Google_UrlshortenerService extends Google_Service {
public $url;
/**
* Constructs the internal representation of the Urlshortener service.
*
* @param Google_Client $client
*/
public function __construct(Google_Client $client) {
$this->servicePath = 'urlshortener/v1/';
$this->version = 'v1';
$this->serviceName = 'urlshortener';
$client->addService($this->serviceName, $this->version);
$this->url = new Google_UrlServiceResource($this, $this->serviceName, 'url', json_decode('{"methods": {"insert": {"scopes": ["https://www.googleapis.com/auth/urlshortener"], "request": {"$ref": "Url"}, "response": {"$ref": "Url"}, "httpMethod": "POST", "path": "url", "id": "urlshortener.url.insert"}, "list": {"scopes": ["https://www.googleapis.com/auth/urlshortener"], "parameters": {"start-token": {"type": "string", "location": "query"}, "projection": {"enum": ["ANALYTICS_CLICKS", "FULL"], "type": "string", "location": "query"}}, "response": {"$ref": "UrlHistory"}, "httpMethod": "GET", "path": "url/history", "id": "urlshortener.url.list"}, "get": {"httpMethod": "GET", "response": {"$ref": "Url"}, "id": "urlshortener.url.get", "parameters": {"shortUrl": {"required": true, "type": "string", "location": "query"}, "projection": {"enum": ["ANALYTICS_CLICKS", "ANALYTICS_TOP_STRINGS", "FULL"], "type": "string", "location": "query"}}, "path": "url"}}}', true));
}
}
class Google_AnalyticsSnapshot extends Google_Model {
public $shortUrlClicks;
protected $__countriesType = 'Google_StringCount';
protected $__countriesDataType = 'array';
public $countries;
protected $__platformsType = 'Google_StringCount';
protected $__platformsDataType = 'array';
public $platforms;
protected $__browsersType = 'Google_StringCount';
protected $__browsersDataType = 'array';
public $browsers;
protected $__referrersType = 'Google_StringCount';
protected $__referrersDataType = 'array';
public $referrers;
public $longUrlClicks;
public function setShortUrlClicks($shortUrlClicks) {
$this->shortUrlClicks = $shortUrlClicks;
}
public function getShortUrlClicks() {
return $this->shortUrlClicks;
}
public function setCountries(/* array(Google_StringCount) */ $countries) {
$this->assertIsArray($countries, 'Google_StringCount', __METHOD__);
$this->countries = $countries;
}
public function getCountries() {
return $this->countries;
}
public function setPlatforms(/* array(Google_StringCount) */ $platforms) {
$this->assertIsArray($platforms, 'Google_StringCount', __METHOD__);
$this->platforms = $platforms;
}
public function getPlatforms() {
return $this->platforms;
}
public function setBrowsers(/* array(Google_StringCount) */ $browsers) {
$this->assertIsArray($browsers, 'Google_StringCount', __METHOD__);
$this->browsers = $browsers;
}
public function getBrowsers() {
return $this->browsers;
}
public function setReferrers(/* array(Google_StringCount) */ $referrers) {
$this->assertIsArray($referrers, 'Google_StringCount', __METHOD__);
$this->referrers = $referrers;
}
public function getReferrers() {
return $this->referrers;
}
public function setLongUrlClicks($longUrlClicks) {
$this->longUrlClicks = $longUrlClicks;
}
public function getLongUrlClicks() {
return $this->longUrlClicks;
}
}
class Google_AnalyticsSummary extends Google_Model {
protected $__weekType = 'Google_AnalyticsSnapshot';
protected $__weekDataType = '';
public $week;
protected $__allTimeType = 'Google_AnalyticsSnapshot';
protected $__allTimeDataType = '';
public $allTime;
protected $__twoHoursType = 'Google_AnalyticsSnapshot';
protected $__twoHoursDataType = '';
public $twoHours;
protected $__dayType = 'Google_AnalyticsSnapshot';
protected $__dayDataType = '';
public $day;
protected $__monthType = 'Google_AnalyticsSnapshot';
protected $__monthDataType = '';
public $month;
public function setWeek(Google_AnalyticsSnapshot $week) {
$this->week = $week;
}
public function getWeek() {
return $this->week;
}
public function setAllTime(Google_AnalyticsSnapshot $allTime) {
$this->allTime = $allTime;
}
public function getAllTime() {
return $this->allTime;
}
public function setTwoHours(Google_AnalyticsSnapshot $twoHours) {
$this->twoHours = $twoHours;
}
public function getTwoHours() {
return $this->twoHours;
}
public function setDay(Google_AnalyticsSnapshot $day) {
$this->day = $day;
}
public function getDay() {
return $this->day;
}
public function setMonth(Google_AnalyticsSnapshot $month) {
$this->month = $month;
}
public function getMonth() {
return $this->month;
}
}
class Google_StringCount extends Google_Model {
public $count;
public $id;
public function setCount($count) {
$this->count = $count;
}
public function getCount() {
return $this->count;
}
public function setId($id) {
$this->id = $id;
}
public function getId() {
return $this->id;
}
}
class Google_Url extends Google_Model {
public $status;
public $kind;
public $created;
protected $__analyticsType = 'Google_AnalyticsSummary';
protected $__analyticsDataType = '';
public $analytics;
public $longUrl;
public $id;
public function setStatus($status) {
$this->status = $status;
}
public function getStatus() {
return $this->status;
}
public function setKind($kind) {
$this->kind = $kind;
}
public function getKind() {
return $this->kind;
}
public function setCreated($created) {
$this->created = $created;
}
public function getCreated() {
return $this->created;
}
public function setAnalytics(Google_AnalyticsSummary $analytics) {
$this->analytics = $analytics;
}
public function getAnalytics() {
return $this->analytics;
}
public function setLongUrl($longUrl) {
$this->longUrl = $longUrl;
}
public function getLongUrl() {
return $this->longUrl;
}
public function setId($id) {
$this->id = $id;
}
public function getId() {
return $this->id;
}
}
class Google_UrlHistory extends Google_Model {
public $nextPageToken;
protected $__itemsType = 'Google_Url';
protected $__itemsDataType = 'array';
public $items;
public $kind;
public $itemsPerPage;
public $totalItems;
public function setNextPageToken($nextPageToken) {
$this->nextPageToken = $nextPageToken;
}
public function getNextPageToken() {
return $this->nextPageToken;
}
public function setItems(/* array(Google_Url) */ $items) {
$this->assertIsArray($items, 'Google_Url', __METHOD__);
$this->items = $items;
}
public function getItems() {
return $this->items;
}
public function setKind($kind) {
$this->kind = $kind;
}
public function getKind() {
return $this->kind;
}
public function setItemsPerPage($itemsPerPage) {
$this->itemsPerPage = $itemsPerPage;
}
public function getItemsPerPage() {
return $this->itemsPerPage;
}
public function setTotalItems($totalItems) {
$this->totalItems = $totalItems;
}
public function getTotalItems() {
return $this->totalItems;
}
}
<?php
/*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
/**
* The "webfonts" collection of methods.
* Typical usage is:
* <code>
* $webfontsService = new Google_WebfontsService(...);
* $webfonts = $webfontsService->webfonts;
* </code>
*/
class Google_WebfontsServiceResource extends Google_ServiceResource {
/**
* Retrieves the list of fonts currently served by the Google Web Fonts Developer API
* (webfonts.list)
*
* @param array $optParams Optional parameters.
*
* @opt_param string sort Enables sorting of the list
* @return Google_WebfontList
*/
public function listWebfonts($optParams = array()) {
$params = array();
$params = array_merge($params, $optParams);
$data = $this->__call('list', array($params));
if ($this->useObjects()) {
return new Google_WebfontList($data);
} else {
return $data;
}
}
}
/**
* Service definition for Google_Webfonts (v1).
*
* <p>
* The Google Web Fonts Developer API.
* </p>
*
* <p>
* For more information about this service, see the
* <a href="http://code.google.com/apis/webfonts/docs/developer_api.html" target="_blank">API Documentation</a>
* </p>
*
* @author Google, Inc.
*/
class Google_WebfontsService extends Google_Service {
public $webfonts;
/**
* Constructs the internal representation of the Webfonts service.
*
* @param Google_Client $client
*/
public function __construct(Google_Client $client) {
$this->servicePath = 'webfonts/v1/';
$this->version = 'v1';
$this->serviceName = 'webfonts';
$client->addService($this->serviceName, $this->version);
$this->webfonts = new Google_WebfontsServiceResource($this, $this->serviceName, 'webfonts', json_decode('{"methods": {"list": {"httpMethod": "GET", "response": {"$ref": "WebfontList"}, "id": "webfonts.webfonts.list", "parameters": {"sort": {"enum": ["alpha", "date", "popularity", "style", "trending"], "type": "string", "location": "query"}}, "path": "webfonts"}}}', true));
}
}
class Google_Webfont extends Google_Model {
public $kind;
public $variants;
public $subsets;
public $family;
public function setKind($kind) {
$this->kind = $kind;
}
public function getKind() {
return $this->kind;
}
public function setVariants($variants) {
$this->variants = $variants;
}
public function getVariants() {
return $this->variants;
}
public function setSubsets($subsets) {
$this->subsets = $subsets;
}
public function getSubsets() {
return $this->subsets;
}
public function setFamily($family) {
$this->family = $family;
}
public function getFamily() {
return $this->family;
}
}
class Google_WebfontList extends Google_Model {
protected $__itemsType = 'Google_Webfont';
protected $__itemsDataType = 'array';
public $items;
public $kind;
public function setItems(/* array(Google_Webfont) */ $items) {
$this->assertIsArray($items, 'Google_Webfont', __METHOD__);
$this->items = $items;
}
public function getItems() {
return $this->items;
}
public function setKind($kind) {
$this->kind = $kind;
}
public function getKind() {
return $this->kind;
}
}
<?php
/*
Copyright (c) 2010 Kevin M Burns Jr, http://kevburnsjr.com/
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/**
* A URI Template Parser which is used by the apiREST class to resolve the REST requests
* Blogpost: http://lab.kevburnsjr.com/php-uri-template-parser
* Source: http://github.com/KevBurnsJr/php-uri-template-parser
*/
class URI_Template_Parser {
public static $operators = array('+', ';', '?', '/', '.');
public static $reserved_operators = array('|', '!', '@');
public static $explode_modifiers = array('+', '*');
public static $partial_modifiers = array(':', '^');
public static $gen_delims = array(':', '/', '?', '#', '[', ']', '@');
public static $gen_delims_pct = array('%3A', '%2F', '%3F', '%23', '%5B', '%5D', '%40');
public static $sub_delims = array('!', '$', '&', '\'', '(', ')', '*', '+', ',', ';', '=');
public static $sub_delims_pct = array('%21', '%24', '%26', '%27', '%28', '%29', '%2A', '%2B', '%2C', '%3B', '%3D');
public static $reserved;
public static $reserved_pct;
public function __construct($template) {
self::$reserved = array_merge(self::$gen_delims, self::$sub_delims);
self::$reserved_pct = array_merge(self::$gen_delims_pct, self::$sub_delims_pct);
$this->template = $template;
}
public function expand($data) {
// Modification to make this a bit more performant (since gettype is very slow)
if (! is_array($data)) {
$data = (array)$data;
}
/*
// Original code, which uses a slow gettype() statement, kept in place for if the assumption that is_array always works here is incorrect
switch (gettype($data)) {
case "boolean":
case "integer":
case "double":
case "string":
case "object":
$data = (array)$data;
break;
}
*/
// Resolve template vars
preg_match_all('/\{([^\}]*)\}/', $this->template, $em);
foreach ($em[1] as $i => $bare_expression) {
preg_match('/^([\+\;\?\/\.]{1})?(.*)$/', $bare_expression, $lm);
$exp = new StdClass();
$exp->expression = $em[0][$i];
$exp->operator = $lm[1];
$exp->variable_list = $lm[2];
$exp->varspecs = explode(',', $exp->variable_list);
$exp->vars = array();
foreach ($exp->varspecs as $varspec) {
preg_match('/^([a-zA-Z0-9_]+)([\*\+]{1})?([\:\^][0-9-]+)?(\=[^,]+)?$/', $varspec, $vm);
$var = new StdClass();
$var->name = $vm[1];
$var->modifier = isset($vm[2]) && $vm[2] ? $vm[2] : null;
$var->modifier = isset($vm[3]) && $vm[3] ? $vm[3] : $var->modifier;
$var->default = isset($vm[4]) ? substr($vm[4], 1) : null;
$exp->vars[] = $var;
}
// Add processing flags
$exp->reserved = false;
$exp->prefix = '';
$exp->delimiter = ',';
switch ($exp->operator) {
case '+':
$exp->reserved = 'true';
break;
case ';':
$exp->prefix = ';';
$exp->delimiter = ';';
break;
case '?':
$exp->prefix = '?';
$exp->delimiter = '&';
break;
case '/':
$exp->prefix = '/';
$exp->delimiter = '/';
break;
case '.':
$exp->prefix = '.';
$exp->delimiter = '.';
break;
}
$expressions[] = $exp;
}
// Expansion
$this->expansion = $this->template;
foreach ($expressions as $exp) {
$part = $exp->prefix;
$exp->one_var_defined = false;
foreach ($exp->vars as $var) {
$val = '';
if ($exp->one_var_defined && isset($data[$var->name])) {
$part .= $exp->delimiter;
}
// Variable present
if (isset($data[$var->name])) {
$exp->one_var_defined = true;
$var->data = $data[$var->name];
$val = self::val_from_var($var, $exp);
// Variable missing
} else {
if ($var->default) {
$exp->one_var_defined = true;
$val = $var->default;
}
}
$part .= $val;
}
if (! $exp->one_var_defined) $part = '';
$this->expansion = str_replace($exp->expression, $part, $this->expansion);
}
return $this->expansion;
}
private function val_from_var($var, $exp) {
$val = '';
if (is_array($var->data)) {
$i = 0;
if ($exp->operator == '?' && ! $var->modifier) {
$val .= $var->name . '=';
}
foreach ($var->data as $k => $v) {
$del = $var->modifier ? $exp->delimiter : ',';
$ek = rawurlencode($k);
$ev = rawurlencode($v);
// Array
if ($k !== $i) {
if ($var->modifier == '+') {
$val .= $var->name . '.';
}
if ($exp->operator == '?' && $var->modifier || $exp->operator == ';' && $var->modifier == '*' || $exp->operator == ';' && $var->modifier == '+') {
$val .= $ek . '=';
} else {
$val .= $ek . $del;
}
// List
} else {
if ($var->modifier == '+') {
if ($exp->operator == ';' && $var->modifier == '*' || $exp->operator == ';' && $var->modifier == '+' || $exp->operator == '?' && $var->modifier == '+') {
$val .= $var->name . '=';
} else {
$val .= $var->name . '.';
}
}
}
$val .= $ev . $del;
$i ++;
}
$val = trim($val, $del);
// Strings, numbers, etc.
} else {
if ($exp->operator == '?') {
$val = $var->name . (isset($var->data) ? '=' : '');
} else if ($exp->operator == ';') {
$val = $var->name . ($var->data ? '=' : '');
}
$val .= rawurlencode($var->data);
if ($exp->operator == '+') {
$val = str_replace(self::$reserved_pct, self::$reserved, $val);
}
}
return $val;
}
public function match($uri) {}
public function __toString() {
return $this->template;
}
}
<?php
/*
* Copyright 2012 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Implement the caching directives specified in rfc2616. This
* implementation is guided by the guidance offered in rfc2616-sec13.
* @author Chirag Shah <chirags@google.com>
*/
class Google_CacheParser {
public static $CACHEABLE_HTTP_METHODS = array('GET', 'HEAD');
public static $CACHEABLE_STATUS_CODES = array('200', '203', '300', '301');
private function __construct() {}
/**
* Check if an HTTP request can be cached by a private local cache.
*
* @static
* @param Google_HttpRequest $resp
* @return bool True if the request is cacheable.
* False if the request is uncacheable.
*/
public static function isRequestCacheable (Google_HttpRequest $resp) {
$method = $resp->getRequestMethod();
if (! in_array($method, self::$CACHEABLE_HTTP_METHODS)) {
return false;
}
// Don't cache authorized requests/responses.
// [rfc2616-14.8] When a shared cache receives a request containing an
// Authorization field, it MUST NOT return the corresponding response
// as a reply to any other request...
if ($resp->getRequestHeader("authorization")) {
return false;
}
return true;
}
/**
* Check if an HTTP response can be cached by a private local cache.
*
* @static
* @param Google_HttpRequest $resp
* @return bool True if the response is cacheable.
* False if the response is un-cacheable.
*/
public static function isResponseCacheable (Google_HttpRequest $resp) {
// First, check if the HTTP request was cacheable before inspecting the
// HTTP response.
if (false == self::isRequestCacheable($resp)) {
return false;
}
$code = $resp->getResponseHttpCode();
if (! in_array($code, self::$CACHEABLE_STATUS_CODES)) {
return false;
}
// The resource is uncacheable if the resource is already expired and
// the resource doesn't have an ETag for revalidation.
$etag = $resp->getResponseHeader("etag");
if (self::isExpired($resp) && $etag == false) {
return false;
}
// [rfc2616-14.9.2] If [no-store is] sent in a response, a cache MUST NOT
// store any part of either this response or the request that elicited it.
$cacheControl = $resp->getParsedCacheControl();
if (isset($cacheControl['no-store'])) {
return false;
}
// Pragma: no-cache is an http request directive, but is occasionally
// used as a response header incorrectly.
$pragma = $resp->getResponseHeader('pragma');
if ($pragma == 'no-cache' || strpos($pragma, 'no-cache') !== false) {
return false;
}
// [rfc2616-14.44] Vary: * is extremely difficult to cache. "It implies that
// a cache cannot determine from the request headers of a subsequent request
// whether this response is the appropriate representation."
// Given this, we deem responses with the Vary header as uncacheable.
$vary = $resp->getResponseHeader('vary');
if ($vary) {
return false;
}
return true;
}
/**
* @static
* @param Google_HttpRequest $resp
* @return bool True if the HTTP response is considered to be expired.
* False if it is considered to be fresh.
*/
public static function isExpired(Google_HttpRequest $resp) {
// HTTP/1.1 clients and caches MUST treat other invalid date formats,
// especially including the value “0”, as in the past.
$parsedExpires = false;
$responseHeaders = $resp->getResponseHeaders();
if (isset($responseHeaders['expires'])) {
$rawExpires = $responseHeaders['expires'];
// Check for a malformed expires header first.
if (empty($rawExpires) || (is_numeric($rawExpires) && $rawExpires <= 0)) {
return true;
}
// See if we can parse the expires header.
$parsedExpires = strtotime($rawExpires);
if (false == $parsedExpires || $parsedExpires <= 0) {
return true;
}
}
// Calculate the freshness of an http response.
$freshnessLifetime = false;
$cacheControl = $resp->getParsedCacheControl();
if (isset($cacheControl['max-age'])) {
$freshnessLifetime = $cacheControl['max-age'];
}
$rawDate = $resp->getResponseHeader('date');
$parsedDate = strtotime($rawDate);
if (empty($rawDate) || false == $parsedDate) {
$parsedDate = time();
}
if (false == $freshnessLifetime && isset($responseHeaders['expires'])) {
$freshnessLifetime = $parsedExpires - $parsedDate;
}
if (false == $freshnessLifetime) {
return true;
}
// Calculate the age of an http response.
$age = max(0, time() - $parsedDate);
if (isset($responseHeaders['age'])) {
$age = max($age, strtotime($responseHeaders['age']));
}
return $freshnessLifetime <= $age;
}
/**
* Determine if a cache entry should be revalidated with by the origin.
*
* @param Google_HttpRequest $response
* @return bool True if the entry is expired, else return false.
*/
public static function mustRevalidate(Google_HttpRequest $response) {
// [13.3] When a cache has a stale entry that it would like to use as a
// response to a client's request, it first has to check with the origin
// server to see if its cached entry is still usable.
return self::isExpired($response);
}
}
\ No newline at end of file
<?php
/*
* Copyright 2010 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Curl based implementation of apiIO.
*
* @author Chris Chabot <chabotc@google.com>
* @author Chirag Shah <chirags@google.com>
*/
require_once 'Google_CacheParser.php';
class Google_CurlIO implements Google_IO {
const CONNECTION_ESTABLISHED = "HTTP/1.0 200 Connection established\r\n\r\n";
const FORM_URLENCODED = 'application/x-www-form-urlencoded';
private static $ENTITY_HTTP_METHODS = array("POST" => null, "PUT" => null);
private static $HOP_BY_HOP = array(
'connection', 'keep-alive', 'proxy-authenticate', 'proxy-authorization',
'te', 'trailers', 'transfer-encoding', 'upgrade');
private $curlParams = array (
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => 0,
CURLOPT_FAILONERROR => false,
CURLOPT_SSL_VERIFYPEER => true,
CURLOPT_HEADER => true,
CURLOPT_VERBOSE => false,
);
/**
* Perform an authenticated / signed apiHttpRequest.
* This function takes the apiHttpRequest, calls apiAuth->sign on it
* (which can modify the request in what ever way fits the auth mechanism)
* and then calls apiCurlIO::makeRequest on the signed request
*
* @param Google_HttpRequest $request
* @return Google_HttpRequest The resulting HTTP response including the
* responseHttpCode, responseHeaders and responseBody.
*/
public function authenticatedRequest(Google_HttpRequest $request) {
$request = Google_Client::$auth->sign($request);
return $this->makeRequest($request);
}
/**
* Execute a apiHttpRequest
*
* @param Google_HttpRequest $request the http request to be executed
* @return Google_HttpRequest http request with the response http code, response
* headers and response body filled in
* @throws Google_IOException on curl or IO error
*/
public function makeRequest(Google_HttpRequest $request) {
// First, check to see if we have a valid cached version.
$cached = $this->getCachedRequest($request);
if ($cached !== false) {
if (Google_CacheParser::mustRevalidate($cached)) {
$addHeaders = array();
if ($cached->getResponseHeader('etag')) {
// [13.3.4] If an entity tag has been provided by the origin server,
// we must use that entity tag in any cache-conditional request.
$addHeaders['If-None-Match'] = $cached->getResponseHeader('etag');
} elseif ($cached->getResponseHeader('date')) {
$addHeaders['If-Modified-Since'] = $cached->getResponseHeader('date');
}
$request->setRequestHeaders($addHeaders);
} else {
// No need to revalidate the request, return it directly
return $cached;
}
}
if (array_key_exists($request->getRequestMethod(),
self::$ENTITY_HTTP_METHODS)) {
$request = $this->processEntityRequest($request);
}
$ch = curl_init();
curl_setopt_array($ch, $this->curlParams);
curl_setopt($ch, CURLOPT_URL, $request->getUrl());
if ($request->getPostBody()) {
curl_setopt($ch, CURLOPT_POSTFIELDS, $request->getPostBody());
}
$requestHeaders = $request->getRequestHeaders();
if ($requestHeaders && is_array($requestHeaders)) {
$parsed = array();
foreach ($requestHeaders as $k => $v) {
$parsed[] = "$k: $v";
}
curl_setopt($ch, CURLOPT_HTTPHEADER, $parsed);
}
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $request->getRequestMethod());
curl_setopt($ch, CURLOPT_USERAGENT, $request->getUserAgent());
$respData = curl_exec($ch);
// Retry if certificates are missing.
if (curl_errno($ch) == CURLE_SSL_CACERT) {
error_log('SSL certificate problem, verify that the CA cert is OK.'
. ' Retrying with the CA cert bundle from google-api-php-client.');
curl_setopt($ch, CURLOPT_CAINFO, dirname(__FILE__) . '/cacerts.pem');
$respData = curl_exec($ch);
}
$respHeaderSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
$respHttpCode = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE);
$curlErrorNum = curl_errno($ch);
$curlError = curl_error($ch);
curl_close($ch);
if ($curlErrorNum != CURLE_OK) {
throw new Google_IOException("HTTP Error: ($respHttpCode) $curlError");
}
// Parse out the raw response into usable bits
list($responseHeaders, $responseBody) =
self::parseHttpResponse($respData, $respHeaderSize);
if ($respHttpCode == 304 && $cached) {
// If the server responded NOT_MODIFIED, return the cached request.
if (isset($responseHeaders['connection'])) {
$hopByHop = array_merge(
self::$HOP_BY_HOP,
explode(',', $responseHeaders['connection'])
);
$endToEnd = array();
foreach($hopByHop as $key) {
if (isset($responseHeaders[$key])) {
$endToEnd[$key] = $responseHeaders[$key];
}
}
$cached->setResponseHeaders($endToEnd);
}
return $cached;
}
// Fill in the apiHttpRequest with the response values
$request->setResponseHttpCode($respHttpCode);
$request->setResponseHeaders($responseHeaders);
$request->setResponseBody($responseBody);
// Store the request in cache (the function checks to see if the request
// can actually be cached)
$this->setCachedRequest($request);
// And finally return it
return $request;
}
/**
* @visible for testing.
* Cache the response to an HTTP request if it is cacheable.
* @param Google_HttpRequest $request
* @return bool Returns true if the insertion was successful.
* Otherwise, return false.
*/
public function setCachedRequest(Google_HttpRequest $request) {
// Determine if the request is cacheable.
if (Google_CacheParser::isResponseCacheable($request)) {
Google_Client::$cache->set($request->getCacheKey(), $request);
return true;
}
return false;
}
/**
* @visible for testing.
* @param Google_HttpRequest $request
* @return Google_HttpRequest|bool Returns the cached object or
* false if the operation was unsuccessful.
*/
public function getCachedRequest(Google_HttpRequest $request) {
if (false == Google_CacheParser::isRequestCacheable($request)) {
false;
}
return Google_Client::$cache->get($request->getCacheKey());
}
/**
* @param $respData
* @param $headerSize
* @return array
*/
public static function parseHttpResponse($respData, $headerSize) {
if (stripos($respData, self::CONNECTION_ESTABLISHED) !== false) {
$respData = str_ireplace(self::CONNECTION_ESTABLISHED, '', $respData);
}
if ($headerSize) {
$responseBody = substr($respData, $headerSize);
$responseHeaders = substr($respData, 0, $headerSize);
} else {
list($responseHeaders, $responseBody) = explode("\r\n\r\n", $respData, 2);
}
$responseHeaders = self::parseResponseHeaders($responseHeaders);
return array($responseHeaders, $responseBody);
}
public static function parseResponseHeaders($rawHeaders) {
$responseHeaders = array();
$responseHeaderLines = explode("\r\n", $rawHeaders);
foreach ($responseHeaderLines as $headerLine) {
if ($headerLine && strpos($headerLine, ':') !== false) {
list($header, $value) = explode(': ', $headerLine, 2);
$header = strtolower($header);
if (isset($responseHeaders[$header])) {
$responseHeaders[$header] .= "\n" . $value;
} else {
$responseHeaders[$header] = $value;
}
}
}
return $responseHeaders;
}
/**
* @visible for testing
* Process an http request that contains an enclosed entity.
* @param Google_HttpRequest $request
* @return Google_HttpRequest Processed request with the enclosed entity.
*/
public function processEntityRequest(Google_HttpRequest $request) {
$postBody = $request->getPostBody();
$contentType = $request->getRequestHeader("content-type");
// Set the default content-type as application/x-www-form-urlencoded.
if (false == $contentType) {
$contentType = self::FORM_URLENCODED;
$request->setRequestHeaders(array('content-type' => $contentType));
}
// Force the payload to match the content-type asserted in the header.
if ($contentType == self::FORM_URLENCODED && is_array($postBody)) {
$postBody = http_build_query($postBody, '', '&');
$request->setPostBody($postBody);
}
// Make sure the content-length header is set.
if (!$postBody || is_string($postBody)) {
$postsLength = strlen($postBody);
$request->setRequestHeaders(array('content-length' => $postsLength));
}
return $request;
}
/**
* Set options that update cURL's default behavior.
* The list of accepted options are:
* {@link http://php.net/manual/en/function.curl-setopt.php]
*
* @param array $optCurlParams Multiple options used by a cURL session.
*/
public function setOptions($optCurlParams) {
foreach ($optCurlParams as $key => $val) {
$this->curlParams[$key] = $val;
}
}
}
\ No newline at end of file
<?php
/*
* Copyright 2010 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* HTTP Request to be executed by apiIO classes. Upon execution, the
* responseHttpCode, responseHeaders and responseBody will be filled in.
*
* @author Chris Chabot <chabotc@google.com>
* @author Chirag Shah <chirags@google.com>
*
*/
class Google_HttpRequest {
const USER_AGENT_SUFFIX = "google-api-php-client/0.6.0";
private $batchHeaders = array(
'Content-Type' => 'application/http',
'Content-Transfer-Encoding' => 'binary',
'MIME-Version' => '1.0',
'Content-Length' => ''
);
protected $url;
protected $requestMethod;
protected $requestHeaders;
protected $postBody;
protected $userAgent;
protected $responseHttpCode;
protected $responseHeaders;
protected $responseBody;
public $accessKey;
public function __construct($url, $method = 'GET', $headers = array(), $postBody = null) {
$this->setUrl($url);
$this->setRequestMethod($method);
$this->setRequestHeaders($headers);
$this->setPostBody($postBody);
global $apiConfig;
if (empty($apiConfig['application_name'])) {
$this->userAgent = self::USER_AGENT_SUFFIX;
} else {
$this->userAgent = $apiConfig['application_name'] . " " . self::USER_AGENT_SUFFIX;
}
}
/**
* Misc function that returns the base url component of the $url
* used by the OAuth signing class to calculate the base string
* @return string The base url component of the $url.
* @see http://oauth.net/core/1.0a/#anchor13
*/
public function getBaseUrl() {
if ($pos = strpos($this->url, '?')) {
return substr($this->url, 0, $pos);
}
return $this->url;
}
/**
* Misc function that returns an array of the query parameters of the current
* url used by the OAuth signing class to calculate the signature
* @return array Query parameters in the query string.
*/
public function getQueryParams() {
if ($pos = strpos($this->url, '?')) {
$queryStr = substr($this->url, $pos + 1);
$params = array();
parse_str($queryStr, $params);
return $params;
}
return array();
}
/**
* @return string HTTP Response Code.
*/
public function getResponseHttpCode() {
return (int) $this->responseHttpCode;
}
/**
* @param int $responseHttpCode HTTP Response Code.
*/
public function setResponseHttpCode($responseHttpCode) {
$this->responseHttpCode = $responseHttpCode;
}
/**
* @return $responseHeaders (array) HTTP Response Headers.
*/
public function getResponseHeaders() {
return $this->responseHeaders;
}
/**
* @return string HTTP Response Body
*/
public function getResponseBody() {
return $this->responseBody;
}
/**
* @param array $headers The HTTP response headers
* to be normalized.
*/
public function setResponseHeaders($headers) {
$headers = Google_Utils::normalize($headers);
if ($this->responseHeaders) {
$headers = array_merge($this->responseHeaders, $headers);
}
$this->responseHeaders = $headers;
}
/**
* @param string $key
* @return array|boolean Returns the requested HTTP header or
* false if unavailable.
*/
public function getResponseHeader($key) {
return isset($this->responseHeaders[$key])
? $this->responseHeaders[$key]
: false;
}
/**
* @param string $responseBody The HTTP response body.
*/
public function setResponseBody($responseBody) {
$this->responseBody = $responseBody;
}
/**
* @return string $url The request URL.
*/
public function getUrl() {
return $this->url;
}
/**
* @return string $method HTTP Request Method.
*/
public function getRequestMethod() {
return $this->requestMethod;
}
/**
* @return array $headers HTTP Request Headers.
*/
public function getRequestHeaders() {
return $this->requestHeaders;
}
/**
* @param string $key
* @return array|boolean Returns the requested HTTP header or
* false if unavailable.
*/
public function getRequestHeader($key) {
return isset($this->requestHeaders[$key])
? $this->requestHeaders[$key]
: false;
}
/**
* @return string $postBody HTTP Request Body.
*/
public function getPostBody() {
return $this->postBody;
}
/**
* @param string $url the url to set
*/
public function setUrl($url) {
if (substr($url, 0, 4) == 'http') {
$this->url = $url;
} else {
// Force the path become relative.
if (substr($url, 0, 1) !== '/') {
$url = '/' . $url;
}
global $apiConfig;
$this->url = $apiConfig['basePath'] . $url;
}
}
/**
* @param string $method Set he HTTP Method and normalize
* it to upper-case, as required by HTTP.
*
*/
public function setRequestMethod($method) {
$this->requestMethod = strtoupper($method);
}
/**
* @param array $headers The HTTP request headers
* to be set and normalized.
*/
public function setRequestHeaders($headers) {
$headers = Google_Utils::normalize($headers);
if ($this->requestHeaders) {
$headers = array_merge($this->requestHeaders, $headers);
}
$this->requestHeaders = $headers;
}
/**
* @param string $postBody the postBody to set
*/
public function setPostBody($postBody) {
$this->postBody = $postBody;
}
/**
* Set the User-Agent Header.
* @param string $userAgent The User-Agent.
*/
public function setUserAgent($userAgent) {
$this->userAgent = $userAgent;
}
/**
* @return string The User-Agent.
*/
public function getUserAgent() {
return $this->userAgent;
}
/**
* Returns a cache key depending on if this was an OAuth signed request
* in which case it will use the non-signed url and access key to make this
* cache key unique per authenticated user, else use the plain request url
* @return string The md5 hash of the request cache key.
*/
public function getCacheKey() {
$key = $this->getUrl();
if (isset($this->accessKey)) {
$key .= $this->accessKey;
}
if (isset($this->requestHeaders['authorization'])) {
$key .= $this->requestHeaders['authorization'];
}
return md5($key);
}
public function getParsedCacheControl() {
$parsed = array();
$rawCacheControl = $this->getResponseHeader('cache-control');
if ($rawCacheControl) {
$rawCacheControl = str_replace(', ', '&', $rawCacheControl);
parse_str($rawCacheControl, $parsed);
}
return $parsed;
}
/**
* @param string $id
* @return string A string representation of the HTTP Request.
*/
public function toBatchString($id) {
$str = '';
foreach($this->batchHeaders as $key => $val) {
$str .= $key . ': ' . $val . "\n";
}
$str .= "Content-ID: $id\n";
$str .= "\n";
$path = parse_url($this->getUrl(), PHP_URL_PATH);
$str .= $this->getRequestMethod() . ' ' . $path . " HTTP/1.1\n";
foreach($this->getRequestHeaders() as $key => $val) {
$str .= $key . ': ' . $val . "\n";
}
if ($this->getPostBody()) {
$str .= "\n";
$str .= $this->getPostBody();
}
return $str;
}
}
<?php
/**
* Copyright 2010 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
require_once 'io/Google_HttpRequest.php';
require_once 'io/Google_CurlIO.php';
require_once 'io/Google_REST.php';
/**
* Abstract IO class
*
* @author Chris Chabot <chabotc@google.com>
*/
interface Google_IO {
/**
* An utility function that first calls $this->auth->sign($request) and then executes makeRequest()
* on that signed request. Used for when a request should be authenticated
* @param Google_HttpRequest $request
* @return Google_HttpRequest $request
*/
public function authenticatedRequest(Google_HttpRequest $request);
/**
* Executes a apIHttpRequest and returns the resulting populated httpRequest
* @param Google_HttpRequest $request
* @return Google_HttpRequest $request
*/
public function makeRequest(Google_HttpRequest $request);
/**
* Set options that update the transport implementation's behavior.
* @param $options
*/
public function setOptions($options);
}
<?php
/*
* Copyright 2010 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* This class implements the RESTful transport of apiServiceRequest()'s
*
* @author Chris Chabot <chabotc@google.com>
* @author Chirag Shah <chirags@google.com>
*/
class Google_REST {
/**
* Executes a apiServiceRequest using a RESTful call by transforming it into
* an apiHttpRequest, and executed via apiIO::authenticatedRequest().
*
* @param Google_HttpRequest $req
* @return array decoded result
* @throws Google_ServiceException on server side error (ie: not authenticated,
* invalid or malformed post body, invalid url)
*/
static public function execute(Google_HttpRequest $req) {
$httpRequest = Google_Client::$io->makeRequest($req);
$decodedResponse = self::decodeHttpResponse($httpRequest);
$ret = isset($decodedResponse['data'])
? $decodedResponse['data'] : $decodedResponse;
return $ret;
}
/**
* Decode an HTTP Response.
* @static
* @throws Google_ServiceException
* @param Google_HttpRequest $response The http response to be decoded.
* @return mixed|null
*/
public static function decodeHttpResponse($response) {
$code = $response->getResponseHttpCode();
$body = $response->getResponseBody();
$decoded = null;
if ($code != '200' && $code != '201' && $code != '204') {
$decoded = json_decode($body, true);
$err = 'Error calling ' . $response->getRequestMethod() . ' ' . $response->getUrl();
if ($decoded != null && isset($decoded['error']['message']) && isset($decoded['error']['code'])) {
// if we're getting a json encoded error definition, use that instead of the raw response
// body for improved readability
$err .= ": ({$decoded['error']['code']}) {$decoded['error']['message']}";
} else {
$err .= ": ($code) $body";
}
throw new Google_ServiceException($err, $code, null, $decoded['error']['errors']);
}
// Only attempt to decode the response, if the response code wasn't (204) 'no content'
if ($code != '204') {
$decoded = json_decode($body, true);
if ($decoded === null || $decoded === "") {
throw new Google_ServiceException("Invalid json in service response: $body");
}
}
return $decoded;
}
/**
* Parse/expand request parameters and create a fully qualified
* request uri.
* @static
* @param string $servicePath
* @param string $restPath
* @param array $params
* @return string $requestUrl
*/
static function createRequestUri($servicePath, $restPath, $params) {
$requestUrl = $servicePath . $restPath;
$uriTemplateVars = array();
$queryVars = array();
foreach ($params as $paramName => $paramSpec) {
// Discovery v1.0 puts the canonical location under the 'location' field.
if (! isset($paramSpec['location'])) {
$paramSpec['location'] = $paramSpec['restParameterType'];
}
if ($paramSpec['type'] == 'boolean') {
$paramSpec['value'] = ($paramSpec['value']) ? 'true' : 'false';
}
if ($paramSpec['location'] == 'path') {
$uriTemplateVars[$paramName] = $paramSpec['value'];
} else {
if (isset($paramSpec['repeated']) && is_array($paramSpec['value'])) {
foreach ($paramSpec['value'] as $value) {
$queryVars[] = $paramName . '=' . rawurlencode($value);
}
} else {
$queryVars[] = $paramName . '=' . rawurlencode($paramSpec['value']);
}
}
}
if (count($uriTemplateVars)) {
$uriTemplateParser = new URI_Template_Parser($requestUrl);
$requestUrl = $uriTemplateParser->expand($uriTemplateVars);
}
//FIXME work around for the the uri template lib which url encodes
// the @'s & confuses our servers.
$requestUrl = str_replace('%40', '@', $requestUrl);
if (count($queryVars)) {
$requestUrl .= '?' . implode($queryVars, '&');
}
return $requestUrl;
}
}
<?php
/*
* Copyright 2012 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @author Chirag Shah <chirags@google.com>
*/
class Google_BatchRequest {
/** @var string Multipart Boundary. */
private $boundary;
/** @var array service requests to be executed. */
private $requests = array();
public function __construct($boundary = false) {
$boundary = (false == $boundary) ? mt_rand() : $boundary;
$this->boundary = str_replace('"', '', $boundary);
}
public function add(Google_HttpRequest $request, $key = false) {
if (false == $key) {
$key = mt_rand();
}
$this->requests[$key] = $request;
}
public function execute() {
$body = '';
/** @var Google_HttpRequest $req */
foreach($this->requests as $key => $req) {
$body .= "--{$this->boundary}\n";
$body .= $req->toBatchString($key) . "\n";
}
$body = rtrim($body);
$body .= "\n--{$this->boundary}--";
global $apiConfig;
$url = $apiConfig['basePath'] . '/batch';
$httpRequest = new Google_HttpRequest($url, 'POST');
$httpRequest->setRequestHeaders(array(
'Content-Type' => 'multipart/mixed; boundary=' . $this->boundary));
$httpRequest->setPostBody($body);
$response = Google_Client::$io->makeRequest($httpRequest);
$response = $this->parseResponse($response);
return $response;
}
public function parseResponse(Google_HttpRequest $response) {
$contentType = $response->getResponseHeader('content-type');
$contentType = explode(';', $contentType);
$boundary = false;
foreach($contentType as $part) {
$part = (explode('=', $part, 2));
if (isset($part[0]) && 'boundary' == trim($part[0])) {
$boundary = $part[1];
}
}
$body = $response->getResponseBody();
if ($body) {
$body = str_replace("--$boundary--", "--$boundary", $body);
$parts = explode("--$boundary", $body);
$responses = array();
foreach($parts as $part) {
$part = trim($part);
if (!empty($part)) {
list($metaHeaders, $part) = explode("\r\n\r\n", $part, 2);
$metaHeaders = Google_CurlIO::parseResponseHeaders($metaHeaders);
$status = substr($part, 0, strpos($part, "\n"));
$status = explode(" ", $status);
$status = $status[1];
list($partHeaders, $partBody) = Google_CurlIO::parseHttpResponse($part, false);
$response = new Google_HttpRequest("");
$response->setResponseHttpCode($status);
$response->setResponseHeaders($partHeaders);
$response->setResponseBody($partBody);
$response = Google_REST::decodeHttpResponse($response);
// Need content id.
$responses[$metaHeaders['content-id']] = $response;
}
}
return $responses;
}
return null;
}
}
\ No newline at end of file
<?php
/**
* Copyright 2012 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @author Chirag Shah <chirags@google.com>
*
*/
class Google_MediaFileUpload {
const UPLOAD_MEDIA_TYPE = 'media';
const UPLOAD_MULTIPART_TYPE = 'multipart';
const UPLOAD_RESUMABLE_TYPE = 'resumable';
/** @var string $mimeType */
public $mimeType;
/** @var string $data */
public $data;
/** @var bool $resumable */
public $resumable;
/** @var int $chunkSize */
public $chunkSize;
/** @var int $size */
public $size;
/** @var string $resumeUri */
public $resumeUri;
/** @var int $progress */
public $progress;
/**
* @param $mimeType string
* @param $data string The bytes you want to upload.
* @param $resumable bool
* @param bool $chunkSize File will be uploaded in chunks of this many bytes.
* only used if resumable=True
*/
public function __construct($mimeType, $data, $resumable=false, $chunkSize=false) {
$this->mimeType = $mimeType;
$this->data = $data;
$this->size = strlen($this->data);
$this->resumable = $resumable;
if(!$chunkSize) {
$this->chunkSize = 256 * 1024;
}
$this->progress = 0;
}
/**
* @static
* @param $meta
* @param $params
* @return array|bool
*/
public static function process($meta, &$params) {
$payload = array();
$meta = is_string($meta) ? json_decode($meta, true) : $meta;
$uploadType = self::getUploadType($meta, $payload, $params);
if (!$uploadType) {
// Process as a normal API request.
return false;
}
// Process as a media upload request.
$params['uploadType'] = array(
'type' => 'string',
'location' => 'query',
'value' => $uploadType,
);
if (isset($params['file'])) {
// This is a standard file upload with curl.
$file = $params['file']['value'];
unset($params['file']);
return self::processFileUpload($file);
}
$mimeType = isset($params['mimeType'])
? $params['mimeType']['value']
: false;
unset($params['mimeType']);
$data = isset($params['data'])
? $params['data']['value']
: false;
unset($params['data']);
if (self::UPLOAD_RESUMABLE_TYPE == $uploadType) {
$payload['content-type'] = $mimeType;
} elseif (self::UPLOAD_MEDIA_TYPE == $uploadType) {
// This is a simple media upload.
$payload['content-type'] = $mimeType;
$payload['postBody'] = $data;
}
elseif (self::UPLOAD_MULTIPART_TYPE == $uploadType) {
// This is a multipart/related upload.
$boundary = isset($params['boundary']['value']) ? $params['boundary']['value'] : mt_rand();
$boundary = str_replace('"', '', $boundary);
$payload['content-type'] = 'multipart/related; boundary=' . $boundary;
$related = "--$boundary\r\n";
$related .= "Content-Type: application/json; charset=UTF-8\r\n";
$related .= "\r\n" . json_encode($meta) . "\r\n";
$related .= "--$boundary\r\n";
$related .= "Content-Type: $mimeType\r\n";
$related .= "Content-Transfer-Encoding: base64\r\n";
$related .= "\r\n" . base64_encode($data) . "\r\n";
$related .= "--$boundary--";
$payload['postBody'] = $related;
}
return $payload;
}
/**
* Process standard file uploads.
* @param $file
* @internal param $fileName
* @return array Inclues the processed file name.
* @visible For testing.
*/
public static function processFileUpload($file) {
if (!$file) return array();
if (substr($file, 0, 1) != '@') {
$file = '@' . $file;
}
// This is a standard file upload with curl.
return array('postBody' => array('file' => $file));
}
/**
* Valid upload types:
* - resumable (UPLOAD_RESUMABLE_TYPE)
* - media (UPLOAD_MEDIA_TYPE)
* - multipart (UPLOAD_MULTIPART_TYPE)
* - none (false)
* @param $meta
* @param $payload
* @param $params
* @return bool|string
*/
public static function getUploadType($meta, &$payload, &$params) {
if (isset($params['mediaUpload'])
&& get_class($params['mediaUpload']['value']) == 'Google_MediaFileUpload') {
$upload = $params['mediaUpload']['value'];
unset($params['mediaUpload']);
$payload['content-type'] = $upload->mimeType;
if (isset($upload->resumable) && $upload->resumable) {
return self::UPLOAD_RESUMABLE_TYPE;
}
}
// Allow the developer to override the upload type.
if (isset($params['uploadType'])) {
return $params['uploadType']['value'];
}
$data = isset($params['data']['value'])
? $params['data']['value'] : false;
if (false == $data && false == isset($params['file'])) {
// No upload data available.
return false;
}
if (isset($params['file'])) {
return self::UPLOAD_MEDIA_TYPE;
}
if (false == $meta) {
return self::UPLOAD_MEDIA_TYPE;
}
return self::UPLOAD_MULTIPART_TYPE;
}
public function nextChunk(Google_HttpRequest $req) {
if (false == $this->resumeUri) {
$this->resumeUri = $this->getResumeUri($req);
}
$data = substr($this->data, $this->progress, $this->chunkSize);
$lastBytePos = $this->progress + strlen($data) - 1;
$headers = array(
'content-range' => "bytes $this->progress-$lastBytePos/$this->size",
'content-type' => $req->getRequestHeader('content-type'),
'content-length' => $this->chunkSize,
'expect' => '',
);
$httpRequest = new Google_HttpRequest($this->resumeUri, 'PUT', $headers, $data);
$response = Google_Client::$io->authenticatedRequest($httpRequest);
$code = $response->getResponseHttpCode();
if (308 == $code) {
$range = explode('-', $response->getResponseHeader('range'));
$this->progress = $range[1] + 1;
return false;
} else {
return Google_REST::decodeHttpResponse($response);
}
}
private function getResumeUri(Google_HttpRequest $httpRequest) {
$result = null;
$body = $httpRequest->getPostBody();
if ($body) {
$httpRequest->setRequestHeaders(array(
'content-type' => 'application/json; charset=UTF-8',
'content-length' => Google_Utils::getStrLen($body),
'x-upload-content-type' => $this->mimeType,
'expect' => '',
));
}
$response = Google_Client::$io->makeRequest($httpRequest);
$location = $response->getResponseHeader('location');
$code = $response->getResponseHttpCode();
if (200 == $code && true == $location) {
return $location;
}
throw new Google_Exception("Failed to start the resumable upload");
}
}
\ No newline at end of file
<?php
/*
* Copyright 2011 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* This class defines attributes, valid values, and usage which is generated from
* a given json schema. http://tools.ietf.org/html/draft-zyp-json-schema-03#section-5
*
* @author Chirag Shah <chirags@google.com>
*
*/
class Google_Model {
public function __construct( /* polymorphic */ ) {
if (func_num_args() == 1 && is_array(func_get_arg(0))) {
// Initialize the model with the array's contents.
$array = func_get_arg(0);
$this->mapTypes($array);
}
}
/**
* Initialize this object's properties from an array.
*
* @param array $array Used to seed this object's properties.
* @return void
*/
protected function mapTypes($array) {
foreach ($array as $key => $val) {
$this->$key = $val;
$keyTypeName = "__$key" . 'Type';
$keyDataType = "__$key" . 'DataType';
if ($this->useObjects() && property_exists($this, $keyTypeName)) {
if ($this->isAssociativeArray($val)) {
if (isset($this->$keyDataType) && 'map' == $this->$keyDataType) {
foreach($val as $arrayKey => $arrayItem) {
$val[$arrayKey] = $this->createObjectFromName($keyTypeName, $arrayItem);
}
$this->$key = $val;
} else {
$this->$key = $this->createObjectFromName($keyTypeName, $val);
}
} else if (is_array($val)) {
$arrayObject = array();
foreach ($val as $arrayIndex => $arrayItem) {
$arrayObject[$arrayIndex] = $this->createObjectFromName($keyTypeName, $arrayItem);
}
$this->$key = $arrayObject;
}
}
}
}
/**
* Returns true only if the array is associative.
* @param array $array
* @return bool True if the array is associative.
*/
protected function isAssociativeArray($array) {
if (!is_array($array)) {
return false;
}
$keys = array_keys($array);
foreach($keys as $key) {
if (is_string($key)) {
return true;
}
}
return false;
}
/**
* Given a variable name, discover its type.
*
* @param $name
* @param $item
* @return object The object from the item.
*/
private function createObjectFromName($name, $item) {
$type = $this->$name;
return new $type($item);
}
protected function useObjects() {
global $apiConfig;
return (isset($apiConfig['use_objects']) && $apiConfig['use_objects']);
}
/**
* Verify if $obj is an array.
* @throws Google_Exception Thrown if $obj isn't an array.
* @param array $obj Items that should be validated.
* @param string $type Array items should be of this type.
* @param string $method Method expecting an array as an argument.
*/
public function assertIsArray($obj, $type, $method) {
if ($obj && !is_array($obj)) {
throw new Google_Exception("Incorrect parameter type passed to $method(), expected an"
. " array containing items of type $type.");
}
}
}
<?php
/*
* Copyright 2010 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class Google_Service {
public $version;
public $servicePath;
public $resource;
}
<?php
/**
* Copyright 2010 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Implements the actual methods/resources of the discovered Google API using magic function
* calling overloading (__call()), which on call will see if the method name (plus.activities.list)
* is available in this service, and if so construct an apiHttpRequest representing it.
*
* @author Chris Chabot <chabotc@google.com>
* @author Chirag Shah <chirags@google.com>
*
*/
class Google_ServiceResource {
// Valid query parameters that work, but don't appear in discovery.
private $stackParameters = array(
'alt' => array('type' => 'string', 'location' => 'query'),
'boundary' => array('type' => 'string', 'location' => 'query'),
'fields' => array('type' => 'string', 'location' => 'query'),
'trace' => array('type' => 'string', 'location' => 'query'),
'userIp' => array('type' => 'string', 'location' => 'query'),
'userip' => array('type' => 'string', 'location' => 'query'),
'file' => array('type' => 'complex', 'location' => 'body'),
'data' => array('type' => 'string', 'location' => 'body'),
'mimeType' => array('type' => 'string', 'location' => 'header'),
'uploadType' => array('type' => 'string', 'location' => 'query'),
'mediaUpload' => array('type' => 'complex', 'location' => 'query'),
);
/** @var Google_Service $service */
private $service;
/** @var string $serviceName */
private $serviceName;
/** @var string $resourceName */
private $resourceName;
/** @var array $methods */
private $methods;
public function __construct($service, $serviceName, $resourceName, $resource) {
$this->service = $service;
$this->serviceName = $serviceName;
$this->resourceName = $resourceName;
$this->methods = isset($resource['methods']) ? $resource['methods'] : array($resourceName => $resource);
}
/**
* @param $name
* @param $arguments
* @return Google_HttpRequest|array
* @throws Google_Exception
*/
public function __call($name, $arguments) {
if (! isset($this->methods[$name])) {
throw new Google_Exception("Unknown function: {$this->serviceName}->{$this->resourceName}->{$name}()");
}
$method = $this->methods[$name];
$parameters = $arguments[0];
// postBody is a special case since it's not defined in the discovery document as parameter, but we abuse the param entry for storing it
$postBody = null;
if (isset($parameters['postBody'])) {
if (is_object($parameters['postBody'])) {
$this->stripNull($parameters['postBody']);
}
// Some APIs require the postBody to be set under the data key.
if (is_array($parameters['postBody']) && 'latitude' == $this->serviceName) {
if (!isset($parameters['postBody']['data'])) {
$rawBody = $parameters['postBody'];
unset($parameters['postBody']);
$parameters['postBody']['data'] = $rawBody;
}
}
$postBody = is_array($parameters['postBody']) || is_object($parameters['postBody'])
? json_encode($parameters['postBody'])
: $parameters['postBody'];
unset($parameters['postBody']);
if (isset($parameters['optParams'])) {
$optParams = $parameters['optParams'];
unset($parameters['optParams']);
$parameters = array_merge($parameters, $optParams);
}
}
if (!isset($method['parameters'])) {
$method['parameters'] = array();
}
$method['parameters'] = array_merge($method['parameters'], $this->stackParameters);
foreach ($parameters as $key => $val) {
if ($key != 'postBody' && ! isset($method['parameters'][$key])) {
throw new Google_Exception("($name) unknown parameter: '$key'");
}
}
if (isset($method['parameters'])) {
foreach ($method['parameters'] as $paramName => $paramSpec) {
if (isset($paramSpec['required']) && $paramSpec['required'] && ! isset($parameters[$paramName])) {
throw new Google_Exception("($name) missing required param: '$paramName'");
}
if (isset($parameters[$paramName])) {
$value = $parameters[$paramName];
$parameters[$paramName] = $paramSpec;
$parameters[$paramName]['value'] = $value;
unset($parameters[$paramName]['required']);
} else {
unset($parameters[$paramName]);
}
}
}
// Discovery v1.0 puts the canonical method id under the 'id' field.
if (! isset($method['id'])) {
$method['id'] = $method['rpcMethod'];
}
// Discovery v1.0 puts the canonical path under the 'path' field.
if (! isset($method['path'])) {
$method['path'] = $method['restPath'];
}
$servicePath = $this->service->servicePath;
// Process Media Request
$contentType = false;
if (isset($method['mediaUpload'])) {
$media = Google_MediaFileUpload::process($postBody, $parameters);
if ($media) {
$contentType = isset($media['content-type']) ? $media['content-type']: null;
$postBody = isset($media['postBody']) ? $media['postBody'] : null;
$servicePath = $method['mediaUpload']['protocols']['simple']['path'];
$method['path'] = '';
}
}
$url = Google_REST::createRequestUri($servicePath, $method['path'], $parameters);
$httpRequest = new Google_HttpRequest($url, $method['httpMethod'], null, $postBody);
if ($postBody) {
$contentTypeHeader = array();
if (isset($contentType) && $contentType) {
$contentTypeHeader['content-type'] = $contentType;
} else {
$contentTypeHeader['content-type'] = 'application/json; charset=UTF-8';
$contentTypeHeader['content-length'] = Google_Utils::getStrLen($postBody);
}
$httpRequest->setRequestHeaders($contentTypeHeader);
}
$httpRequest = Google_Client::$auth->sign($httpRequest);
if (Google_Client::$useBatch) {
return $httpRequest;
}
// Terminate immediatly if this is a resumable request.
if (isset($parameters['uploadType']['value'])
&& 'resumable' == $parameters['uploadType']['value']) {
return $httpRequest;
}
return Google_REST::execute($httpRequest);
}
public function useObjects() {
global $apiConfig;
return (isset($apiConfig['use_objects']) && $apiConfig['use_objects']);
}
protected function stripNull(&$o) {
$o = (array) $o;
foreach ($o as $k => $v) {
if ($v === null || strstr($k, "\0*\0__")) {
unset($o[$k]);
}
elseif (is_object($v) || is_array($v)) {
$this->stripNull($o[$k]);
}
}
}
}
<?php
/*
* Copyright 2011 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Collection of static utility methods used for convenience across
* the client library.
*
* @author Chirag Shah <chirags@google.com>
*/
class Google_Utils {
public static function urlSafeB64Encode($data) {
$b64 = base64_encode($data);
$b64 = str_replace(array('+', '/', '\r', '\n', '='),
array('-', '_'),
$b64);
return $b64;
}
public static function urlSafeB64Decode($b64) {
$b64 = str_replace(array('-', '_'),
array('+', '/'),
$b64);
return base64_decode($b64);
}
/**
* Misc function used to count the number of bytes in a post body, in the world of multi-byte chars
* and the unpredictability of strlen/mb_strlen/sizeof, this is the only way to do that in a sane
* manner at the moment.
*
* This algorithm was originally developed for the
* Solar Framework by Paul M. Jones
*
* @link http://solarphp.com/
* @link http://svn.solarphp.com/core/trunk/Solar/Json.php
* @link http://framework.zend.com/svn/framework/standard/trunk/library/Zend/Json/Decoder.php
* @param string $str
* @return int The number of bytes in a string.
*/
static public function getStrLen($str) {
$strlenVar = strlen($str);
$d = $ret = 0;
for ($count = 0; $count < $strlenVar; ++ $count) {
$ordinalValue = ord($str{$ret});
switch (true) {
case (($ordinalValue >= 0x20) && ($ordinalValue <= 0x7F)):
// characters U-00000000 - U-0000007F (same as ASCII)
$ret ++;
break;
case (($ordinalValue & 0xE0) == 0xC0):
// characters U-00000080 - U-000007FF, mask 110XXXXX
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
$ret += 2;
break;
case (($ordinalValue & 0xF0) == 0xE0):
// characters U-00000800 - U-0000FFFF, mask 1110XXXX
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
$ret += 3;
break;
case (($ordinalValue & 0xF8) == 0xF0):
// characters U-00010000 - U-001FFFFF, mask 11110XXX
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
$ret += 4;
break;
case (($ordinalValue & 0xFC) == 0xF8):
// characters U-00200000 - U-03FFFFFF, mask 111110XX
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
$ret += 5;
break;
case (($ordinalValue & 0xFE) == 0xFC):
// characters U-04000000 - U-7FFFFFFF, mask 1111110X
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
$ret += 6;
break;
default:
$ret ++;
}
}
return $ret;
}
/**
* Normalize all keys in an array to lower-case.
* @param array $arr
* @return array Normalized array.
*/
public static function normalize($arr) {
if (!is_array($arr)) {
return array();
}
$normalized = array();
foreach ($arr as $key => $val) {
$normalized[strtolower($key)] = $val;
}
return $normalized;
}
}
\ No newline at end of file