Version Description
Release Date: December 16th, 2014
-
Hotfix:
- Fixing API library to prevent fatal error.
-
Bugfixes:
- Fixes the way of getting data from the Google API. cURL was used, but is changed into core wp_remote functionality to prevent errors when cURL isn't enabled.
Download this release
Release Info
Developer | joostdevalk |
Plugin | Google Analytics for WordPress by MonsterInsights |
Version | 5.2.6 |
Comparing to | |
See all releases |
Code changes from version 5.2.4 to 5.2.6
- admin/api-libs/google/Google_Client.php +25 -39
- admin/api-libs/google/auth/Google_AssertionCredentials.php +6 -6
- admin/api-libs/google/auth/Google_Auth.php +2 -5
- admin/api-libs/google/auth/Google_AuthNone.php +2 -2
- admin/api-libs/google/auth/Google_LoginTicket.php +3 -3
- admin/api-libs/google/auth/Google_OAuth2.php +41 -45
- admin/api-libs/google/auth/Google_P12Signer.php +6 -6
- admin/api-libs/google/auth/Google_PemVerifier.php +7 -7
- admin/api-libs/google/auth/Google_Signer.php +1 -3
- admin/api-libs/google/auth/Google_Verifier.php +1 -3
- admin/api-libs/google/cache/Google_ApcCache.php +3 -3
- admin/api-libs/google/cache/Google_Cache.php +1 -4
- admin/api-libs/google/cache/Google_FileCache.php +5 -5
- admin/api-libs/google/cache/Google_MemcacheCache.php +6 -6
- admin/api-libs/google/cache/Google_WPCache.php +53 -0
- admin/api-libs/google/class-api-google.php +62 -3
- admin/api-libs/google/config.php +3 -3
- admin/api-libs/google/io/Google_CacheParser.php +9 -9
- admin/api-libs/google/io/Google_CurlIO.php +12 -14
- admin/api-libs/google/io/Google_HttpRequest.php +3 -3
- admin/api-libs/google/io/Google_HttpStreamIO.php +12 -14
- admin/api-libs/google/io/Google_IO.php +23 -28
- admin/api-libs/google/io/Google_REST.php +9 -9
- admin/api-libs/google/io/Google_WPIO.php +122 -0
- admin/api-libs/google/service/Google_BatchRequest.php +10 -10
- admin/api-libs/google/service/Google_MediaFileUpload.php +9 -9
- admin/api-libs/google/service/Google_Model.php +3 -3
- admin/api-libs/google/service/Google_Service.php +1 -1
- admin/api-libs/google/service/Google_ServiceResource.php +15 -15
- admin/api-libs/google/service/Google_Utils.php +1 -1
- admin/api-libs/googleanalytics/class-api-googleanalytics.php +18 -5
- admin/api-libs/googleanalytics/class-google-analytics-client.php +3 -7
- admin/class-admin.php +32 -2
- admin/dashboards/class-admin-dashboards-collector.php +11 -16
- googleanalytics.php +4 -2
- includes/class-utils.php +15 -0
- readme.txt +25 -3
admin/api-libs/google/Google_Client.php
CHANGED
@@ -35,25 +35,11 @@ set_include_path(dirname(__FILE__) . PATH_SEPARATOR . get_include_path());
|
|
35 |
require_once "config.php";
|
36 |
// If a local configuration file is found, merge it's values with the default configuration
|
37 |
if (file_exists(dirname(__FILE__) . '/local_config.php')) {
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
}
|
42 |
|
43 |
-
// Include the top level classes, they each include their own dependencies
|
44 |
-
require_once 'service/Google_Model.php';
|
45 |
-
require_once 'service/Google_Service.php';
|
46 |
-
require_once 'service/Google_ServiceResource.php';
|
47 |
-
require_once 'auth/Google_AssertionCredentials.php';
|
48 |
-
require_once 'auth/Google_Signer.php';
|
49 |
-
require_once 'auth/Google_P12Signer.php';
|
50 |
-
require_once 'service/Google_BatchRequest.php';
|
51 |
-
require_once 'external/URITemplateParser.php';
|
52 |
-
require_once 'auth/Google_Auth.php';
|
53 |
-
require_once 'cache/Google_Cache.php';
|
54 |
-
require_once 'io/Google_IO.php';
|
55 |
-
require_once( 'service/Google_MediaFileUpload.php' );
|
56 |
-
|
57 |
/**
|
58 |
* The Google API Client
|
59 |
* http://code.google.com/p/google-api-php-client/
|
@@ -61,22 +47,22 @@ require_once( 'service/Google_MediaFileUpload.php' );
|
|
61 |
* @author Chris Chabot <chabotc@google.com>
|
62 |
* @author Chirag Shah <chirags@google.com>
|
63 |
*/
|
64 |
-
class
|
65 |
/**
|
66 |
* @static
|
67 |
-
* @var
|
68 |
*/
|
69 |
static $auth;
|
70 |
|
71 |
/**
|
72 |
* @static
|
73 |
-
* @var
|
74 |
*/
|
75 |
static $io;
|
76 |
|
77 |
/**
|
78 |
* @static
|
79 |
-
* @var
|
80 |
*/
|
81 |
static $cache;
|
82 |
|
@@ -112,7 +98,7 @@ class Google_Client {
|
|
112 |
public function addService($service, $version = false) {
|
113 |
global $apiConfig;
|
114 |
if ($this->authenticated) {
|
115 |
-
throw new
|
116 |
}
|
117 |
$this->services[$service] = array();
|
118 |
if (isset($apiConfig['services'][$service])) {
|
@@ -158,7 +144,7 @@ class Google_Client {
|
|
158 |
|
159 |
/**
|
160 |
* Set the OAuth 2.0 access token using the string that resulted from calling authenticate()
|
161 |
-
* or
|
162 |
* @param string $accessToken JSON encoded string containing in the following format:
|
163 |
* {"access_token":"TOKEN", "refresh_token":"TOKEN", "token_type":"Bearer",
|
164 |
* "expires_in":3600, "id_token":"TOKEN", "created":1320790426}
|
@@ -314,7 +300,7 @@ class Google_Client {
|
|
314 |
/**
|
315 |
* Revoke an OAuth2 access token or refresh token. This method will revoke the current access
|
316 |
* token, if a token isn't provided.
|
317 |
-
* @throws
|
318 |
* @param string|null $token The token (access token or a refresh token) that should be revoked.
|
319 |
* @return boolean Returns True if the revocation was successful, otherwise False.
|
320 |
*/
|
@@ -325,9 +311,9 @@ class Google_Client {
|
|
325 |
/**
|
326 |
* Verify an id_token. This method will verify the current id_token, if one
|
327 |
* isn't provided.
|
328 |
-
* @throws
|
329 |
* @param string|null $token The token (id_token) that should be verified.
|
330 |
-
* @return
|
331 |
* successful.
|
332 |
*/
|
333 |
public function verifyIdToken($token = null) {
|
@@ -335,10 +321,10 @@ class Google_Client {
|
|
335 |
}
|
336 |
|
337 |
/**
|
338 |
-
* @param
|
339 |
* @return void
|
340 |
*/
|
341 |
-
public function setAssertionCredentials(
|
342 |
self::$auth->setAssertionCredentials($creds);
|
343 |
}
|
344 |
|
@@ -399,34 +385,34 @@ class Google_Client {
|
|
399 |
|
400 |
/**
|
401 |
* @static
|
402 |
-
* @return
|
403 |
*/
|
404 |
public static function getAuth() {
|
405 |
-
return
|
406 |
}
|
407 |
|
408 |
/**
|
409 |
* @static
|
410 |
-
* @return
|
411 |
*/
|
412 |
public static function getIo() {
|
413 |
-
return
|
414 |
}
|
415 |
|
416 |
/**
|
417 |
-
* @return
|
418 |
*/
|
419 |
public function getCache() {
|
420 |
-
return
|
421 |
}
|
422 |
}
|
423 |
|
424 |
// Exceptions that the Google PHP API Library can throw
|
425 |
-
class
|
426 |
-
class
|
427 |
-
class
|
428 |
-
class
|
429 |
-
class
|
430 |
/**
|
431 |
* Optional list of errors returned in a JSON body of an HTTP error response.
|
432 |
*/
|
35 |
require_once "config.php";
|
36 |
// If a local configuration file is found, merge it's values with the default configuration
|
37 |
if (file_exists(dirname(__FILE__) . '/local_config.php')) {
|
38 |
+
$defaultConfig = $apiConfig;
|
39 |
+
require_once( dirname( __FILE__ ) . '/local_config.php' );
|
40 |
+
$apiConfig = array_merge( $defaultConfig, $apiConfig );
|
41 |
}
|
42 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
43 |
/**
|
44 |
* The Google API Client
|
45 |
* http://code.google.com/p/google-api-php-client/
|
47 |
* @author Chris Chabot <chabotc@google.com>
|
48 |
* @author Chirag Shah <chirags@google.com>
|
49 |
*/
|
50 |
+
class Yoast_Google_Client {
|
51 |
/**
|
52 |
* @static
|
53 |
+
* @var Yoast_Google_Auth $auth
|
54 |
*/
|
55 |
static $auth;
|
56 |
|
57 |
/**
|
58 |
* @static
|
59 |
+
* @var Yoast_Google_IO $io
|
60 |
*/
|
61 |
static $io;
|
62 |
|
63 |
/**
|
64 |
* @static
|
65 |
+
* @var Yoast_Google_Cache $cache
|
66 |
*/
|
67 |
static $cache;
|
68 |
|
98 |
public function addService($service, $version = false) {
|
99 |
global $apiConfig;
|
100 |
if ($this->authenticated) {
|
101 |
+
throw new Yoast_Google_Exception('Cant add services after having authenticated');
|
102 |
}
|
103 |
$this->services[$service] = array();
|
104 |
if (isset($apiConfig['services'][$service])) {
|
144 |
|
145 |
/**
|
146 |
* Set the OAuth 2.0 access token using the string that resulted from calling authenticate()
|
147 |
+
* or Yoast_Google_Client#getAccessToken().
|
148 |
* @param string $accessToken JSON encoded string containing in the following format:
|
149 |
* {"access_token":"TOKEN", "refresh_token":"TOKEN", "token_type":"Bearer",
|
150 |
* "expires_in":3600, "id_token":"TOKEN", "created":1320790426}
|
300 |
/**
|
301 |
* Revoke an OAuth2 access token or refresh token. This method will revoke the current access
|
302 |
* token, if a token isn't provided.
|
303 |
+
* @throws Yoast_Google_AuthException
|
304 |
* @param string|null $token The token (access token or a refresh token) that should be revoked.
|
305 |
* @return boolean Returns True if the revocation was successful, otherwise False.
|
306 |
*/
|
311 |
/**
|
312 |
* Verify an id_token. This method will verify the current id_token, if one
|
313 |
* isn't provided.
|
314 |
+
* @throws Yoast_Google_AuthException
|
315 |
* @param string|null $token The token (id_token) that should be verified.
|
316 |
+
* @return Yoast_Google_LoginTicket Returns an apiLoginTicket if the verification was
|
317 |
* successful.
|
318 |
*/
|
319 |
public function verifyIdToken($token = null) {
|
321 |
}
|
322 |
|
323 |
/**
|
324 |
+
* @param Yoast_Google_AssertionCredentials $creds
|
325 |
* @return void
|
326 |
*/
|
327 |
+
public function setAssertionCredentials(Yoast_Google_AssertionCredentials $creds) {
|
328 |
self::$auth->setAssertionCredentials($creds);
|
329 |
}
|
330 |
|
385 |
|
386 |
/**
|
387 |
* @static
|
388 |
+
* @return Yoast_Google_Auth the implementation of apiAuth.
|
389 |
*/
|
390 |
public static function getAuth() {
|
391 |
+
return Yoast_Google_Client::$auth;
|
392 |
}
|
393 |
|
394 |
/**
|
395 |
* @static
|
396 |
+
* @return Yoast_Google_IO the implementation of apiIo.
|
397 |
*/
|
398 |
public static function getIo() {
|
399 |
+
return Yoast_Google_Client::$io;
|
400 |
}
|
401 |
|
402 |
/**
|
403 |
+
* @return Yoast_Google_Cache the implementation of apiCache.
|
404 |
*/
|
405 |
public function getCache() {
|
406 |
+
return Yoast_Google_Client::$cache;
|
407 |
}
|
408 |
}
|
409 |
|
410 |
// Exceptions that the Google PHP API Library can throw
|
411 |
+
class Yoast_Google_Exception extends Exception {}
|
412 |
+
class Yoast_Google_AuthException extends Yoast_Google_Exception {}
|
413 |
+
class Yoast_Google_CacheException extends Yoast_Google_Exception {}
|
414 |
+
class Yoast_Google_IOException extends Yoast_Google_Exception {}
|
415 |
+
class Yoast_Google_ServiceException extends Yoast_Google_Exception {
|
416 |
/**
|
417 |
* Optional list of errors returned in a JSON body of an HTTP error response.
|
418 |
*/
|
admin/api-libs/google/auth/Google_AssertionCredentials.php
CHANGED
@@ -20,7 +20,7 @@
|
|
20 |
*
|
21 |
* @author Chirag Shah <chirags@google.com>
|
22 |
*/
|
23 |
-
class
|
24 |
const MAX_TOKEN_LIFETIME_SECS = 3600;
|
25 |
|
26 |
public $serviceAccountName;
|
@@ -64,7 +64,7 @@ class Google_AssertionCredentials {
|
|
64 |
$now = time();
|
65 |
|
66 |
$jwtParams = array(
|
67 |
-
'aud' =>
|
68 |
'scope' => $this->scopes,
|
69 |
'iat' => $now,
|
70 |
'exp' => $now + self::MAX_TOKEN_LIFETIME_SECS,
|
@@ -89,14 +89,14 @@ class Google_AssertionCredentials {
|
|
89 |
$header = array('typ' => 'JWT', 'alg' => 'RS256');
|
90 |
|
91 |
$segments = array(
|
92 |
-
|
93 |
-
|
94 |
);
|
95 |
|
96 |
$signingInput = implode('.', $segments);
|
97 |
-
$signer = new
|
98 |
$signature = $signer->sign($signingInput);
|
99 |
-
$segments[] =
|
100 |
|
101 |
return implode(".", $segments);
|
102 |
}
|
20 |
*
|
21 |
* @author Chirag Shah <chirags@google.com>
|
22 |
*/
|
23 |
+
class Yoast_Google_AssertionCredentials {
|
24 |
const MAX_TOKEN_LIFETIME_SECS = 3600;
|
25 |
|
26 |
public $serviceAccountName;
|
64 |
$now = time();
|
65 |
|
66 |
$jwtParams = array(
|
67 |
+
'aud' => Yoast_Google_OAuth2::OAUTH2_TOKEN_URI,
|
68 |
'scope' => $this->scopes,
|
69 |
'iat' => $now,
|
70 |
'exp' => $now + self::MAX_TOKEN_LIFETIME_SECS,
|
89 |
$header = array('typ' => 'JWT', 'alg' => 'RS256');
|
90 |
|
91 |
$segments = array(
|
92 |
+
Yoast_Google_Utils::urlSafeB64Encode(json_encode($header)),
|
93 |
+
Yoast_Google_Utils::urlSafeB64Encode(json_encode($payload))
|
94 |
);
|
95 |
|
96 |
$signingInput = implode('.', $segments);
|
97 |
+
$signer = new Yoast_Google_P12Signer($this->privateKey, $this->privateKeyPassword);
|
98 |
$signature = $signer->sign($signingInput);
|
99 |
+
$segments[] = Yoast_Google_Utils::urlSafeB64Encode($signature);
|
100 |
|
101 |
return implode(".", $segments);
|
102 |
}
|
admin/api-libs/google/auth/Google_Auth.php
CHANGED
@@ -15,17 +15,14 @@
|
|
15 |
* limitations under the License.
|
16 |
*/
|
17 |
|
18 |
-
require_once "Google_AuthNone.php";
|
19 |
-
require_once "Google_OAuth2.php";
|
20 |
-
|
21 |
/**
|
22 |
* Abstract class for the Authentication in the API client
|
23 |
* @author Chris Chabot <chabotc@google.com>
|
24 |
*
|
25 |
*/
|
26 |
-
abstract class
|
27 |
abstract public function authenticate($service);
|
28 |
-
abstract public function sign(
|
29 |
abstract public function createAuthUrl($scope);
|
30 |
|
31 |
abstract public function getAccessToken();
|
15 |
* limitations under the License.
|
16 |
*/
|
17 |
|
|
|
|
|
|
|
18 |
/**
|
19 |
* Abstract class for the Authentication in the API client
|
20 |
* @author Chris Chabot <chabotc@google.com>
|
21 |
*
|
22 |
*/
|
23 |
+
abstract class Yoast_Google_Auth {
|
24 |
abstract public function authenticate($service);
|
25 |
+
abstract public function sign(Yoast_Google_HttpRequest $request);
|
26 |
abstract public function createAuthUrl($scope);
|
27 |
|
28 |
abstract public function getAccessToken();
|
admin/api-libs/google/auth/Google_AuthNone.php
CHANGED
@@ -20,7 +20,7 @@
|
|
20 |
* @author Chris Chabot <chabotc@google.com>
|
21 |
* @author Chirag Shah <chirags@google.com>
|
22 |
*/
|
23 |
-
class
|
24 |
public $key = null;
|
25 |
|
26 |
public function __construct() {
|
@@ -38,7 +38,7 @@ class Google_AuthNone extends Google_Auth {
|
|
38 |
public function refreshToken($refreshToken) {/* noop*/}
|
39 |
public function revokeToken() {/* noop*/}
|
40 |
|
41 |
-
public function sign(
|
42 |
if ($this->key) {
|
43 |
$request->setUrl($request->getUrl() . ((strpos($request->getUrl(), '?') === false) ? '?' : '&')
|
44 |
. 'key='.urlencode($this->key));
|
20 |
* @author Chris Chabot <chabotc@google.com>
|
21 |
* @author Chirag Shah <chirags@google.com>
|
22 |
*/
|
23 |
+
class Yoast_Google_AuthNone extends Yoast_Google_Auth {
|
24 |
public $key = null;
|
25 |
|
26 |
public function __construct() {
|
38 |
public function refreshToken($refreshToken) {/* noop*/}
|
39 |
public function revokeToken() {/* noop*/}
|
40 |
|
41 |
+
public function sign(Yoast_Google_HttpRequest $request) {
|
42 |
if ($this->key) {
|
43 |
$request->setUrl($request->getUrl() . ((strpos($request->getUrl(), '?') === false) ? '?' : '&')
|
44 |
. 'key='.urlencode($this->key));
|
admin/api-libs/google/auth/Google_LoginTicket.php
CHANGED
@@ -20,7 +20,7 @@
|
|
20 |
*
|
21 |
* @author Brian Eaton <beaton@google.com>
|
22 |
*/
|
23 |
-
class
|
24 |
const USER_ATTR = "id";
|
25 |
|
26 |
// Information from id token envelope.
|
@@ -42,14 +42,14 @@ class Google_LoginTicket {
|
|
42 |
|
43 |
/**
|
44 |
* Returns the numeric identifier for the user.
|
45 |
-
* @throws
|
46 |
* @return
|
47 |
*/
|
48 |
public function getUserId() {
|
49 |
if (array_key_exists(self::USER_ATTR, $this->payload)) {
|
50 |
return $this->payload[self::USER_ATTR];
|
51 |
}
|
52 |
-
throw new
|
53 |
}
|
54 |
|
55 |
/**
|
20 |
*
|
21 |
* @author Brian Eaton <beaton@google.com>
|
22 |
*/
|
23 |
+
class Yoast_Google_LoginTicket {
|
24 |
const USER_ATTR = "id";
|
25 |
|
26 |
// Information from id token envelope.
|
42 |
|
43 |
/**
|
44 |
* Returns the numeric identifier for the user.
|
45 |
+
* @throws Yoast_Google_AuthException
|
46 |
* @return
|
47 |
*/
|
48 |
public function getUserId() {
|
49 |
if (array_key_exists(self::USER_ATTR, $this->payload)) {
|
50 |
return $this->payload[self::USER_ATTR];
|
51 |
}
|
52 |
+
throw new Yoast_Google_AuthException("No user_id in token");
|
53 |
}
|
54 |
|
55 |
/**
|
admin/api-libs/google/auth/Google_OAuth2.php
CHANGED
@@ -15,10 +15,6 @@
|
|
15 |
* limitations under the License.
|
16 |
*/
|
17 |
|
18 |
-
require_once "Google_Verifier.php";
|
19 |
-
require_once "Google_LoginTicket.php";
|
20 |
-
require_once "service/Google_Utils.php";
|
21 |
-
|
22 |
/**
|
23 |
* Authentication class that deals with the OAuth 2 web-server authentication flow
|
24 |
*
|
@@ -26,7 +22,7 @@ require_once "service/Google_Utils.php";
|
|
26 |
* @author Chirag Shah <chirags@google.com>
|
27 |
*
|
28 |
*/
|
29 |
-
class
|
30 |
public $clientId;
|
31 |
public $clientSecret;
|
32 |
public $developerKey;
|
@@ -37,7 +33,7 @@ class Google_OAuth2 extends Google_Auth {
|
|
37 |
public $approvalPrompt = 'force';
|
38 |
public $requestVisibleActions;
|
39 |
|
40 |
-
/** @var
|
41 |
public $assertionCredentials;
|
42 |
|
43 |
const OAUTH2_REVOKE_URI = 'https://accounts.google.com/o/oauth2/revoke';
|
@@ -84,7 +80,7 @@ class Google_OAuth2 extends Google_Auth {
|
|
84 |
/**
|
85 |
* @param $service
|
86 |
* @param string|null $code
|
87 |
-
* @throws
|
88 |
* @return string
|
89 |
*/
|
90 |
public function authenticate($service, $code = null) {
|
@@ -95,7 +91,7 @@ class Google_OAuth2 extends Google_Auth {
|
|
95 |
|
96 |
if ($code) {
|
97 |
// We got here from the redirect from a successful authorization grant, fetch the access token
|
98 |
-
$request =
|
99 |
'code' => $code,
|
100 |
'grant_type' => 'authorization_code',
|
101 |
'redirect_uri' => $this->redirectUri,
|
@@ -114,7 +110,7 @@ class Google_OAuth2 extends Google_Auth {
|
|
114 |
if ($decodedResponse != null && $decodedResponse['error']) {
|
115 |
$response = $decodedResponse['error'];
|
116 |
}
|
117 |
-
throw new
|
118 |
}
|
119 |
}
|
120 |
|
@@ -156,15 +152,15 @@ class Google_OAuth2 extends Google_Auth {
|
|
156 |
|
157 |
/**
|
158 |
* @param string $token
|
159 |
-
* @throws
|
160 |
*/
|
161 |
public function setAccessToken($token) {
|
162 |
$token = json_decode($token, true);
|
163 |
if ($token == null) {
|
164 |
-
throw new
|
165 |
}
|
166 |
if (! isset($token['access_token'])) {
|
167 |
-
throw new
|
168 |
}
|
169 |
$this->token = $token;
|
170 |
}
|
@@ -189,17 +185,17 @@ class Google_OAuth2 extends Google_Auth {
|
|
189 |
$this->approvalPrompt = $approvalPrompt;
|
190 |
}
|
191 |
|
192 |
-
public function setAssertionCredentials(
|
193 |
$this->assertionCredentials = $creds;
|
194 |
}
|
195 |
|
196 |
/**
|
197 |
* Include an accessToken in a given apiHttpRequest.
|
198 |
-
* @param
|
199 |
-
* @return
|
200 |
-
* @throws
|
201 |
*/
|
202 |
-
public function sign(
|
203 |
// add the developer key to the request before signing it
|
204 |
if ($this->developerKey) {
|
205 |
$requestUrl = $request->getUrl();
|
@@ -220,7 +216,7 @@ class Google_OAuth2 extends Google_Auth {
|
|
220 |
$this->refreshTokenWithAssertion();
|
221 |
} else {
|
222 |
if (! array_key_exists('refresh_token', $this->token)) {
|
223 |
-
throw new
|
224 |
. "and a refresh token is not available. Refresh tokens are not "
|
225 |
. "returned for responses that were auto-approved.");
|
226 |
}
|
@@ -252,7 +248,7 @@ class Google_OAuth2 extends Google_Auth {
|
|
252 |
|
253 |
/**
|
254 |
* Fetches a fresh access token with a given assertion token.
|
255 |
-
* @param
|
256 |
* @return void
|
257 |
*/
|
258 |
public function refreshTokenWithAssertion($assertionCredentials = null) {
|
@@ -268,33 +264,33 @@ class Google_OAuth2 extends Google_Auth {
|
|
268 |
}
|
269 |
|
270 |
private function refreshTokenRequest($params) {
|
271 |
-
$http = new
|
272 |
-
$request =
|
273 |
|
274 |
$code = $request->getResponseHttpCode();
|
275 |
$body = $request->getResponseBody();
|
276 |
if (200 == $code) {
|
277 |
$token = json_decode($body, true);
|
278 |
if ($token == null) {
|
279 |
-
throw new
|
280 |
}
|
281 |
|
282 |
if (! isset($token['access_token']) || ! isset($token['expires_in'])) {
|
283 |
-
throw new
|
284 |
}
|
285 |
|
286 |
$this->token['access_token'] = $token['access_token'];
|
287 |
$this->token['expires_in'] = $token['expires_in'];
|
288 |
$this->token['created'] = time();
|
289 |
} else {
|
290 |
-
throw new
|
291 |
}
|
292 |
}
|
293 |
|
294 |
/**
|
295 |
* Revoke an OAuth2 access token or refresh token. This method will revoke the current access
|
296 |
* token, if a token isn't provided.
|
297 |
-
* @throws
|
298 |
* @param string|null $token The token (access token or a refresh token) that should be revoked.
|
299 |
* @return boolean Returns True if the revocation was successful, otherwise False.
|
300 |
*/
|
@@ -302,8 +298,8 @@ class Google_OAuth2 extends Google_Auth {
|
|
302 |
if (!$token) {
|
303 |
$token = $this->token['access_token'];
|
304 |
}
|
305 |
-
$request = new
|
306 |
-
$response =
|
307 |
$code = $response->getResponseHttpCode();
|
308 |
if ($code == 200) {
|
309 |
$this->token = null;
|
@@ -334,7 +330,7 @@ class Google_OAuth2 extends Google_Auth {
|
|
334 |
// are PEM encoded certificates.
|
335 |
private function getFederatedSignOnCerts() {
|
336 |
// This relies on makeRequest caching certificate responses.
|
337 |
-
$request =
|
338 |
self::OAUTH2_FEDERATED_SIGNON_CERTS_URL));
|
339 |
if ($request->getResponseHttpCode() == 200) {
|
340 |
$certs = json_decode($request->getResponseBody(), true);
|
@@ -342,7 +338,7 @@ class Google_OAuth2 extends Google_Auth {
|
|
342 |
return $certs;
|
343 |
}
|
344 |
}
|
345 |
-
throw new
|
346 |
"Failed to retrieve verification certificates: '" .
|
347 |
$request->getResponseBody() . "'.",
|
348 |
$request->getResponseHttpCode());
|
@@ -356,7 +352,7 @@ class Google_OAuth2 extends Google_Auth {
|
|
356 |
*
|
357 |
* @param $id_token
|
358 |
* @param $audience
|
359 |
-
* @return
|
360 |
*/
|
361 |
public function verifyIdToken($id_token = null, $audience = null) {
|
362 |
if (!$id_token) {
|
@@ -375,28 +371,28 @@ class Google_OAuth2 extends Google_Auth {
|
|
375 |
function verifySignedJwtWithCerts($jwt, $certs, $required_audience) {
|
376 |
$segments = explode(".", $jwt);
|
377 |
if (count($segments) != 3) {
|
378 |
-
throw new
|
379 |
}
|
380 |
$signed = $segments[0] . "." . $segments[1];
|
381 |
-
$signature =
|
382 |
|
383 |
// Parse envelope.
|
384 |
-
$envelope = json_decode(
|
385 |
if (!$envelope) {
|
386 |
-
throw new
|
387 |
}
|
388 |
|
389 |
// Parse token
|
390 |
-
$json_body =
|
391 |
$payload = json_decode($json_body, true);
|
392 |
if (!$payload) {
|
393 |
-
throw new
|
394 |
}
|
395 |
|
396 |
// Check signature
|
397 |
$verified = false;
|
398 |
foreach ($certs as $keyName => $pem) {
|
399 |
-
$public_key = new
|
400 |
if ($public_key->verify($signed, $signature)) {
|
401 |
$verified = true;
|
402 |
break;
|
@@ -404,7 +400,7 @@ class Google_OAuth2 extends Google_Auth {
|
|
404 |
}
|
405 |
|
406 |
if (!$verified) {
|
407 |
-
throw new
|
408 |
}
|
409 |
|
410 |
// Check issued-at timestamp
|
@@ -413,7 +409,7 @@ class Google_OAuth2 extends Google_Auth {
|
|
413 |
$iat = $payload["iat"];
|
414 |
}
|
415 |
if (!$iat) {
|
416 |
-
throw new
|
417 |
}
|
418 |
$earliest = $iat - self::CLOCK_SKEW_SECS;
|
419 |
|
@@ -424,20 +420,20 @@ class Google_OAuth2 extends Google_Auth {
|
|
424 |
$exp = $payload["exp"];
|
425 |
}
|
426 |
if (!$exp) {
|
427 |
-
throw new
|
428 |
}
|
429 |
if ($exp >= $now + self::MAX_TOKEN_LIFETIME_SECS) {
|
430 |
-
throw new
|
431 |
"Expiration time too far in future: $json_body");
|
432 |
}
|
433 |
|
434 |
$latest = $exp + self::CLOCK_SKEW_SECS;
|
435 |
if ($now < $earliest) {
|
436 |
-
throw new
|
437 |
"Token used too early, $now < $earliest: $json_body");
|
438 |
}
|
439 |
if ($now > $latest) {
|
440 |
-
throw new
|
441 |
"Token used too late, $now > $latest: $json_body");
|
442 |
}
|
443 |
|
@@ -446,10 +442,10 @@ class Google_OAuth2 extends Google_Auth {
|
|
446 |
// Check audience
|
447 |
$aud = $payload["aud"];
|
448 |
if ($aud != $required_audience) {
|
449 |
-
throw new
|
450 |
}
|
451 |
|
452 |
// All good.
|
453 |
-
return new
|
454 |
}
|
455 |
}
|
15 |
* limitations under the License.
|
16 |
*/
|
17 |
|
|
|
|
|
|
|
|
|
18 |
/**
|
19 |
* Authentication class that deals with the OAuth 2 web-server authentication flow
|
20 |
*
|
22 |
* @author Chirag Shah <chirags@google.com>
|
23 |
*
|
24 |
*/
|
25 |
+
class Yoast_Google_OAuth2 extends Yoast_Google_Auth {
|
26 |
public $clientId;
|
27 |
public $clientSecret;
|
28 |
public $developerKey;
|
33 |
public $approvalPrompt = 'force';
|
34 |
public $requestVisibleActions;
|
35 |
|
36 |
+
/** @var Yoast_Google_AssertionCredentials $assertionCredentials */
|
37 |
public $assertionCredentials;
|
38 |
|
39 |
const OAUTH2_REVOKE_URI = 'https://accounts.google.com/o/oauth2/revoke';
|
80 |
/**
|
81 |
* @param $service
|
82 |
* @param string|null $code
|
83 |
+
* @throws Yoast_Google_AuthException
|
84 |
* @return string
|
85 |
*/
|
86 |
public function authenticate($service, $code = null) {
|
91 |
|
92 |
if ($code) {
|
93 |
// We got here from the redirect from a successful authorization grant, fetch the access token
|
94 |
+
$request = Yoast_Google_Client::$io->makeRequest(new Yoast_Google_HttpRequest(self::OAUTH2_TOKEN_URI, 'POST', array(), array(
|
95 |
'code' => $code,
|
96 |
'grant_type' => 'authorization_code',
|
97 |
'redirect_uri' => $this->redirectUri,
|
110 |
if ($decodedResponse != null && $decodedResponse['error']) {
|
111 |
$response = $decodedResponse['error'];
|
112 |
}
|
113 |
+
throw new Yoast_Google_AuthException("Error fetching OAuth2 access token, message: '$response'", $request->getResponseHttpCode());
|
114 |
}
|
115 |
}
|
116 |
|
152 |
|
153 |
/**
|
154 |
* @param string $token
|
155 |
+
* @throws Yoast_Google_AuthException
|
156 |
*/
|
157 |
public function setAccessToken($token) {
|
158 |
$token = json_decode($token, true);
|
159 |
if ($token == null) {
|
160 |
+
throw new Yoast_Google_AuthException('Could not json decode the token');
|
161 |
}
|
162 |
if (! isset($token['access_token'])) {
|
163 |
+
throw new Yoast_Google_AuthException("Invalid token format");
|
164 |
}
|
165 |
$this->token = $token;
|
166 |
}
|
185 |
$this->approvalPrompt = $approvalPrompt;
|
186 |
}
|
187 |
|
188 |
+
public function setAssertionCredentials(Yoast_Google_AssertionCredentials $creds) {
|
189 |
$this->assertionCredentials = $creds;
|
190 |
}
|
191 |
|
192 |
/**
|
193 |
* Include an accessToken in a given apiHttpRequest.
|
194 |
+
* @param Yoast_Google_HttpRequest $request
|
195 |
+
* @return Yoast_Google_HttpRequest
|
196 |
+
* @throws Yoast_Google_AuthException
|
197 |
*/
|
198 |
+
public function sign(Yoast_Google_HttpRequest $request) {
|
199 |
// add the developer key to the request before signing it
|
200 |
if ($this->developerKey) {
|
201 |
$requestUrl = $request->getUrl();
|
216 |
$this->refreshTokenWithAssertion();
|
217 |
} else {
|
218 |
if (! array_key_exists('refresh_token', $this->token)) {
|
219 |
+
throw new Yoast_Google_AuthException("The OAuth 2.0 access token has expired, "
|
220 |
. "and a refresh token is not available. Refresh tokens are not "
|
221 |
. "returned for responses that were auto-approved.");
|
222 |
}
|
248 |
|
249 |
/**
|
250 |
* Fetches a fresh access token with a given assertion token.
|
251 |
+
* @param Yoast_Google_AssertionCredentials $assertionCredentials optional.
|
252 |
* @return void
|
253 |
*/
|
254 |
public function refreshTokenWithAssertion($assertionCredentials = null) {
|
264 |
}
|
265 |
|
266 |
private function refreshTokenRequest($params) {
|
267 |
+
$http = new Yoast_Google_HttpRequest(self::OAUTH2_TOKEN_URI, 'POST', array(), $params);
|
268 |
+
$request = Yoast_Google_Client::$io->makeRequest($http);
|
269 |
|
270 |
$code = $request->getResponseHttpCode();
|
271 |
$body = $request->getResponseBody();
|
272 |
if (200 == $code) {
|
273 |
$token = json_decode($body, true);
|
274 |
if ($token == null) {
|
275 |
+
throw new Yoast_Google_AuthException("Could not json decode the access token");
|
276 |
}
|
277 |
|
278 |
if (! isset($token['access_token']) || ! isset($token['expires_in'])) {
|
279 |
+
throw new Yoast_Google_AuthException("Invalid token format");
|
280 |
}
|
281 |
|
282 |
$this->token['access_token'] = $token['access_token'];
|
283 |
$this->token['expires_in'] = $token['expires_in'];
|
284 |
$this->token['created'] = time();
|
285 |
} else {
|
286 |
+
throw new Yoast_Google_AuthException("Error refreshing the OAuth2 token, message: '$body'", $code);
|
287 |
}
|
288 |
}
|
289 |
|
290 |
/**
|
291 |
* Revoke an OAuth2 access token or refresh token. This method will revoke the current access
|
292 |
* token, if a token isn't provided.
|
293 |
+
* @throws Yoast_Google_AuthException
|
294 |
* @param string|null $token The token (access token or a refresh token) that should be revoked.
|
295 |
* @return boolean Returns True if the revocation was successful, otherwise False.
|
296 |
*/
|
298 |
if (!$token) {
|
299 |
$token = $this->token['access_token'];
|
300 |
}
|
301 |
+
$request = new Yoast_Google_HttpRequest(self::OAUTH2_REVOKE_URI, 'POST', array(), "token=$token");
|
302 |
+
$response = Yoast_Google_Client::$io->makeRequest($request);
|
303 |
$code = $response->getResponseHttpCode();
|
304 |
if ($code == 200) {
|
305 |
$this->token = null;
|
330 |
// are PEM encoded certificates.
|
331 |
private function getFederatedSignOnCerts() {
|
332 |
// This relies on makeRequest caching certificate responses.
|
333 |
+
$request = Yoast_Google_Client::$io->makeRequest(new Yoast_Google_HttpRequest(
|
334 |
self::OAUTH2_FEDERATED_SIGNON_CERTS_URL));
|
335 |
if ($request->getResponseHttpCode() == 200) {
|
336 |
$certs = json_decode($request->getResponseBody(), true);
|
338 |
return $certs;
|
339 |
}
|
340 |
}
|
341 |
+
throw new Yoast_Google_AuthException(
|
342 |
"Failed to retrieve verification certificates: '" .
|
343 |
$request->getResponseBody() . "'.",
|
344 |
$request->getResponseHttpCode());
|
352 |
*
|
353 |
* @param $id_token
|
354 |
* @param $audience
|
355 |
+
* @return Yoast_Google_LoginTicket
|
356 |
*/
|
357 |
public function verifyIdToken($id_token = null, $audience = null) {
|
358 |
if (!$id_token) {
|
371 |
function verifySignedJwtWithCerts($jwt, $certs, $required_audience) {
|
372 |
$segments = explode(".", $jwt);
|
373 |
if (count($segments) != 3) {
|
374 |
+
throw new Yoast_Google_AuthException("Wrong number of segments in token: $jwt");
|
375 |
}
|
376 |
$signed = $segments[0] . "." . $segments[1];
|
377 |
+
$signature = Yoast_Google_Utils::urlSafeB64Decode($segments[2]);
|
378 |
|
379 |
// Parse envelope.
|
380 |
+
$envelope = json_decode(Yoast_Google_Utils::urlSafeB64Decode($segments[0]), true);
|
381 |
if (!$envelope) {
|
382 |
+
throw new Yoast_Google_AuthException("Can't parse token envelope: " . $segments[0]);
|
383 |
}
|
384 |
|
385 |
// Parse token
|
386 |
+
$json_body = Yoast_Google_Utils::urlSafeB64Decode($segments[1]);
|
387 |
$payload = json_decode($json_body, true);
|
388 |
if (!$payload) {
|
389 |
+
throw new Yoast_Google_AuthException("Can't parse token payload: " . $segments[1]);
|
390 |
}
|
391 |
|
392 |
// Check signature
|
393 |
$verified = false;
|
394 |
foreach ($certs as $keyName => $pem) {
|
395 |
+
$public_key = new Yoast_Google_PemVerifier($pem);
|
396 |
if ($public_key->verify($signed, $signature)) {
|
397 |
$verified = true;
|
398 |
break;
|
400 |
}
|
401 |
|
402 |
if (!$verified) {
|
403 |
+
throw new Yoast_Google_AuthException("Invalid token signature: $jwt");
|
404 |
}
|
405 |
|
406 |
// Check issued-at timestamp
|
409 |
$iat = $payload["iat"];
|
410 |
}
|
411 |
if (!$iat) {
|
412 |
+
throw new Yoast_Google_AuthException("No issue time in token: $json_body");
|
413 |
}
|
414 |
$earliest = $iat - self::CLOCK_SKEW_SECS;
|
415 |
|
420 |
$exp = $payload["exp"];
|
421 |
}
|
422 |
if (!$exp) {
|
423 |
+
throw new Yoast_Google_AuthException("No expiration time in token: $json_body");
|
424 |
}
|
425 |
if ($exp >= $now + self::MAX_TOKEN_LIFETIME_SECS) {
|
426 |
+
throw new Yoast_Google_AuthException(
|
427 |
"Expiration time too far in future: $json_body");
|
428 |
}
|
429 |
|
430 |
$latest = $exp + self::CLOCK_SKEW_SECS;
|
431 |
if ($now < $earliest) {
|
432 |
+
throw new Yoast_Google_AuthException(
|
433 |
"Token used too early, $now < $earliest: $json_body");
|
434 |
}
|
435 |
if ($now > $latest) {
|
436 |
+
throw new Yoast_Google_AuthException(
|
437 |
"Token used too late, $now > $latest: $json_body");
|
438 |
}
|
439 |
|
442 |
// Check audience
|
443 |
$aud = $payload["aud"];
|
444 |
if ($aud != $required_audience) {
|
445 |
+
throw new Yoast_Google_AuthException("Wrong recipient, $aud != $required_audience: $json_body");
|
446 |
}
|
447 |
|
448 |
// All good.
|
449 |
+
return new Yoast_Google_LoginTicket($envelope, $payload);
|
450 |
}
|
451 |
}
|
admin/api-libs/google/auth/Google_P12Signer.php
CHANGED
@@ -22,7 +22,7 @@
|
|
22 |
*
|
23 |
* @author Brian Eaton <beaton@google.com>
|
24 |
*/
|
25 |
-
class
|
26 |
// OpenSSL private key resource
|
27 |
private $privateKey;
|
28 |
|
@@ -36,18 +36,18 @@ class Google_P12Signer extends Google_Signer {
|
|
36 |
// This throws on error
|
37 |
$certs = array();
|
38 |
if (!openssl_pkcs12_read($p12, $certs, $password)) {
|
39 |
-
throw new
|
40 |
"Is this a .p12 file? Is the password correct? OpenSSL error: " .
|
41 |
openssl_error_string());
|
42 |
}
|
43 |
// TODO(beaton): is this part of the contract for the openssl_pkcs12_read
|
44 |
// method? What happens if there are multiple private keys? Do we care?
|
45 |
if (!array_key_exists("pkey", $certs) || !$certs["pkey"]) {
|
46 |
-
throw new
|
47 |
}
|
48 |
$this->privateKey = openssl_pkey_get_private($certs["pkey"]);
|
49 |
if (!$this->privateKey) {
|
50 |
-
throw new
|
51 |
}
|
52 |
}
|
53 |
|
@@ -59,11 +59,11 @@ class Google_P12Signer extends Google_Signer {
|
|
59 |
|
60 |
function sign($data) {
|
61 |
if(version_compare(PHP_VERSION, '5.3.0') < 0) {
|
62 |
-
throw new
|
63 |
"PHP 5.3.0 or higher is required to use service accounts.");
|
64 |
}
|
65 |
if (!openssl_sign($data, $signature, $this->privateKey, "sha256")) {
|
66 |
-
throw new
|
67 |
}
|
68 |
return $signature;
|
69 |
}
|
22 |
*
|
23 |
* @author Brian Eaton <beaton@google.com>
|
24 |
*/
|
25 |
+
class Yoast_Google_P12Signer extends Yoast_Google_Signer {
|
26 |
// OpenSSL private key resource
|
27 |
private $privateKey;
|
28 |
|
36 |
// This throws on error
|
37 |
$certs = array();
|
38 |
if (!openssl_pkcs12_read($p12, $certs, $password)) {
|
39 |
+
throw new Yoast_Google_AuthException("Unable to parse the p12 file. " .
|
40 |
"Is this a .p12 file? Is the password correct? OpenSSL error: " .
|
41 |
openssl_error_string());
|
42 |
}
|
43 |
// TODO(beaton): is this part of the contract for the openssl_pkcs12_read
|
44 |
// method? What happens if there are multiple private keys? Do we care?
|
45 |
if (!array_key_exists("pkey", $certs) || !$certs["pkey"]) {
|
46 |
+
throw new Yoast_Google_AuthException("No private key found in p12 file.");
|
47 |
}
|
48 |
$this->privateKey = openssl_pkey_get_private($certs["pkey"]);
|
49 |
if (!$this->privateKey) {
|
50 |
+
throw new Yoast_Google_AuthException("Unable to load private key in ");
|
51 |
}
|
52 |
}
|
53 |
|
59 |
|
60 |
function sign($data) {
|
61 |
if(version_compare(PHP_VERSION, '5.3.0') < 0) {
|
62 |
+
throw new Yoast_Google_AuthException(
|
63 |
"PHP 5.3.0 or higher is required to use service accounts.");
|
64 |
}
|
65 |
if (!openssl_sign($data, $signature, $this->privateKey, "sha256")) {
|
66 |
+
throw new Yoast_Google_AuthException("Unable to sign data");
|
67 |
}
|
68 |
return $signature;
|
69 |
}
|
admin/api-libs/google/auth/Google_PemVerifier.php
CHANGED
@@ -20,7 +20,7 @@
|
|
20 |
*
|
21 |
* @author Brian Eaton <beaton@google.com>
|
22 |
*/
|
23 |
-
class
|
24 |
private $publicKey;
|
25 |
|
26 |
/**
|
@@ -28,16 +28,16 @@ class Google_PemVerifier extends Google_Verifier {
|
|
28 |
*
|
29 |
* $pem: a PEM encoded certificate (not a file).
|
30 |
* @param $pem
|
31 |
-
* @throws
|
32 |
-
* @throws
|
33 |
*/
|
34 |
function __construct($pem) {
|
35 |
if (!function_exists('openssl_x509_read')) {
|
36 |
-
throw new
|
37 |
}
|
38 |
$this->publicKey = openssl_x509_read($pem);
|
39 |
if (!$this->publicKey) {
|
40 |
-
throw new
|
41 |
}
|
42 |
}
|
43 |
|
@@ -53,13 +53,13 @@ class Google_PemVerifier extends Google_Verifier {
|
|
53 |
* Returns true if the signature is valid, false otherwise.
|
54 |
* @param $data
|
55 |
* @param $signature
|
56 |
-
* @throws
|
57 |
* @return bool
|
58 |
*/
|
59 |
function verify($data, $signature) {
|
60 |
$status = openssl_verify($data, $signature, $this->publicKey, "sha256");
|
61 |
if ($status === -1) {
|
62 |
-
throw new
|
63 |
}
|
64 |
return $status === 1;
|
65 |
}
|
20 |
*
|
21 |
* @author Brian Eaton <beaton@google.com>
|
22 |
*/
|
23 |
+
class Yoast_Google_PemVerifier extends Yoast_Google_Verifier {
|
24 |
private $publicKey;
|
25 |
|
26 |
/**
|
28 |
*
|
29 |
* $pem: a PEM encoded certificate (not a file).
|
30 |
* @param $pem
|
31 |
+
* @throws Yoast_Google_AuthException
|
32 |
+
* @throws Yoast_Google_Exception
|
33 |
*/
|
34 |
function __construct($pem) {
|
35 |
if (!function_exists('openssl_x509_read')) {
|
36 |
+
throw new Yoast_Google_Exception('Google API PHP client needs the openssl PHP extension');
|
37 |
}
|
38 |
$this->publicKey = openssl_x509_read($pem);
|
39 |
if (!$this->publicKey) {
|
40 |
+
throw new Yoast_Google_AuthException("Unable to parse PEM: $pem");
|
41 |
}
|
42 |
}
|
43 |
|
53 |
* Returns true if the signature is valid, false otherwise.
|
54 |
* @param $data
|
55 |
* @param $signature
|
56 |
+
* @throws Yoast_Google_AuthException
|
57 |
* @return bool
|
58 |
*/
|
59 |
function verify($data, $signature) {
|
60 |
$status = openssl_verify($data, $signature, $this->publicKey, "sha256");
|
61 |
if ($status === -1) {
|
62 |
+
throw new Yoast_Google_AuthException('Signature verification error: ' . openssl_error_string());
|
63 |
}
|
64 |
return $status === 1;
|
65 |
}
|
admin/api-libs/google/auth/Google_Signer.php
CHANGED
@@ -15,14 +15,12 @@
|
|
15 |
* limitations under the License.
|
16 |
*/
|
17 |
|
18 |
-
require_once "Google_P12Signer.php";
|
19 |
-
|
20 |
/**
|
21 |
* Signs data.
|
22 |
*
|
23 |
* @author Brian Eaton <beaton@google.com>
|
24 |
*/
|
25 |
-
abstract class
|
26 |
/**
|
27 |
* Signs data, returns the signature as binary data.
|
28 |
*/
|
15 |
* limitations under the License.
|
16 |
*/
|
17 |
|
|
|
|
|
18 |
/**
|
19 |
* Signs data.
|
20 |
*
|
21 |
* @author Brian Eaton <beaton@google.com>
|
22 |
*/
|
23 |
+
abstract class Yoast_Google_Signer {
|
24 |
/**
|
25 |
* Signs data, returns the signature as binary data.
|
26 |
*/
|
admin/api-libs/google/auth/Google_Verifier.php
CHANGED
@@ -15,14 +15,12 @@
|
|
15 |
* limitations under the License.
|
16 |
*/
|
17 |
|
18 |
-
require_once "Google_PemVerifier.php";
|
19 |
-
|
20 |
/**
|
21 |
* Verifies signatures.
|
22 |
*
|
23 |
* @author Brian Eaton <beaton@google.com>
|
24 |
*/
|
25 |
-
abstract class
|
26 |
/**
|
27 |
* Checks a signature, returns true if the signature is correct,
|
28 |
* false otherwise.
|
15 |
* limitations under the License.
|
16 |
*/
|
17 |
|
|
|
|
|
18 |
/**
|
19 |
* Verifies signatures.
|
20 |
*
|
21 |
* @author Brian Eaton <beaton@google.com>
|
22 |
*/
|
23 |
+
abstract class Yoast_Google_Verifier {
|
24 |
/**
|
25 |
* Checks a signature, returns true if the signature is correct,
|
26 |
* false otherwise.
|
admin/api-libs/google/cache/Google_ApcCache.php
CHANGED
@@ -23,11 +23,11 @@
|
|
23 |
*
|
24 |
* @author Chris Chabot <chabotc@google.com>
|
25 |
*/
|
26 |
-
class
|
27 |
|
28 |
public function __construct() {
|
29 |
if (! function_exists('apc_add')) {
|
30 |
-
throw new
|
31 |
}
|
32 |
}
|
33 |
|
@@ -84,7 +84,7 @@ class Google_APCCache extends Google_Cache {
|
|
84 |
*/
|
85 |
public function set($key, $value) {
|
86 |
if (@apc_store($key, array('time' => time(), 'data' => serialize($value))) == false) {
|
87 |
-
throw new
|
88 |
}
|
89 |
}
|
90 |
|
23 |
*
|
24 |
* @author Chris Chabot <chabotc@google.com>
|
25 |
*/
|
26 |
+
class Yoast_Google_APCCache extends Yoast_Google_Cache {
|
27 |
|
28 |
public function __construct() {
|
29 |
if (! function_exists('apc_add')) {
|
30 |
+
throw new Yoast_Google_CacheException("Apc functions not available");
|
31 |
}
|
32 |
}
|
33 |
|
84 |
*/
|
85 |
public function set($key, $value) {
|
86 |
if (@apc_store($key, array('time' => time(), 'data' => serialize($value))) == false) {
|
87 |
+
throw new Yoast_Google_CacheException("Couldn't store data");
|
88 |
}
|
89 |
}
|
90 |
|
admin/api-libs/google/cache/Google_Cache.php
CHANGED
@@ -15,15 +15,12 @@
|
|
15 |
* limitations under the License.
|
16 |
*/
|
17 |
|
18 |
-
require_once "Google_FileCache.php";
|
19 |
-
require_once "Google_MemcacheCache.php";
|
20 |
-
|
21 |
/**
|
22 |
* Abstract storage class
|
23 |
*
|
24 |
* @author Chris Chabot <chabotc@google.com>
|
25 |
*/
|
26 |
-
abstract class
|
27 |
|
28 |
/**
|
29 |
* Retrieves the data for the given key, or false if they
|
15 |
* limitations under the License.
|
16 |
*/
|
17 |
|
|
|
|
|
|
|
18 |
/**
|
19 |
* Abstract storage class
|
20 |
*
|
21 |
* @author Chris Chabot <chabotc@google.com>
|
22 |
*/
|
23 |
+
abstract class Yoast_Google_Cache {
|
24 |
|
25 |
/**
|
26 |
* Retrieves the data for the given key, or false if they
|
admin/api-libs/google/cache/Google_FileCache.php
CHANGED
@@ -24,7 +24,7 @@
|
|
24 |
*
|
25 |
* @author Chris Chabot <chabotc@google.com>
|
26 |
*/
|
27 |
-
class
|
28 |
private $path;
|
29 |
|
30 |
public function __construct() {
|
@@ -44,7 +44,7 @@ class Google_FileCache extends Google_Cache {
|
|
44 |
if (! @mkdir($storageDir, 0755, true)) {
|
45 |
// make sure the failure isn't because of a concurrency issue
|
46 |
if (! is_dir($storageDir)) {
|
47 |
-
throw new
|
48 |
}
|
49 |
}
|
50 |
// @codeCoverageIgnoreEnd
|
@@ -114,7 +114,7 @@ class Google_FileCache extends Google_Cache {
|
|
114 |
}
|
115 |
if (! is_dir($storageDir)) {
|
116 |
if (! @mkdir($storageDir, 0755, true)) {
|
117 |
-
throw new
|
118 |
}
|
119 |
}
|
120 |
// we serialize the whole request object, since we don't only want the
|
@@ -123,7 +123,7 @@ class Google_FileCache extends Google_Cache {
|
|
123 |
$this->createLock($storageFile);
|
124 |
if (! @file_put_contents($storageFile, $data)) {
|
125 |
$this->removeLock($storageFile);
|
126 |
-
throw new
|
127 |
}
|
128 |
$this->removeLock($storageFile);
|
129 |
}
|
@@ -131,7 +131,7 @@ class Google_FileCache extends Google_Cache {
|
|
131 |
public function delete($key) {
|
132 |
$file = $this->getCacheFile(md5($key));
|
133 |
if (! @unlink($file)) {
|
134 |
-
throw new
|
135 |
}
|
136 |
}
|
137 |
}
|
24 |
*
|
25 |
* @author Chris Chabot <chabotc@google.com>
|
26 |
*/
|
27 |
+
class Yoast_Google_FileCache extends Yoast_Google_Cache {
|
28 |
private $path;
|
29 |
|
30 |
public function __construct() {
|
44 |
if (! @mkdir($storageDir, 0755, true)) {
|
45 |
// make sure the failure isn't because of a concurrency issue
|
46 |
if (! is_dir($storageDir)) {
|
47 |
+
throw new Yoast_Google_CacheException("Could not create storage directory: $storageDir");
|
48 |
}
|
49 |
}
|
50 |
// @codeCoverageIgnoreEnd
|
114 |
}
|
115 |
if (! is_dir($storageDir)) {
|
116 |
if (! @mkdir($storageDir, 0755, true)) {
|
117 |
+
throw new Yoast_Google_CacheException("Could not create storage directory: $storageDir");
|
118 |
}
|
119 |
}
|
120 |
// we serialize the whole request object, since we don't only want the
|
123 |
$this->createLock($storageFile);
|
124 |
if (! @file_put_contents($storageFile, $data)) {
|
125 |
$this->removeLock($storageFile);
|
126 |
+
throw new Yoast_Google_CacheException("Could not store data in the file");
|
127 |
}
|
128 |
$this->removeLock($storageFile);
|
129 |
}
|
131 |
public function delete($key) {
|
132 |
$file = $this->getCacheFile(md5($key));
|
133 |
if (! @unlink($file)) {
|
134 |
+
throw new Yoast_Google_CacheException("Cache file could not be deleted");
|
135 |
}
|
136 |
}
|
137 |
}
|
admin/api-libs/google/cache/Google_MemcacheCache.php
CHANGED
@@ -23,18 +23,18 @@
|
|
23 |
*
|
24 |
* @author Chris Chabot <chabotc@google.com>
|
25 |
*/
|
26 |
-
class
|
27 |
private $connection = false;
|
28 |
|
29 |
public function __construct() {
|
30 |
global $apiConfig;
|
31 |
if (! function_exists('memcache_connect')) {
|
32 |
-
throw new
|
33 |
}
|
34 |
$this->host = $apiConfig['ioMemCacheCache_host'];
|
35 |
$this->port = $apiConfig['ioMemCacheCache_port'];
|
36 |
if (empty($this->host) || empty($this->port)) {
|
37 |
-
throw new
|
38 |
}
|
39 |
}
|
40 |
|
@@ -79,7 +79,7 @@ class Google_MemcacheCache extends Google_Cache {
|
|
79 |
// so this potentially saves a lot of overhead
|
80 |
private function connect() {
|
81 |
if (! $this->connection = @memcache_pconnect($this->host, $this->port)) {
|
82 |
-
throw new
|
83 |
}
|
84 |
}
|
85 |
|
@@ -108,14 +108,14 @@ class Google_MemcacheCache extends Google_Cache {
|
|
108 |
* @inheritDoc
|
109 |
* @param string $key
|
110 |
* @param string $value
|
111 |
-
* @throws
|
112 |
*/
|
113 |
public function set($key, $value) {
|
114 |
$this->check();
|
115 |
// we store it with the cache_time default expiration so objects will at least get cleaned eventually.
|
116 |
if (@memcache_set($this->connection, $key, array('time' => time(),
|
117 |
'data' => $value), false) == false) {
|
118 |
-
throw new
|
119 |
}
|
120 |
}
|
121 |
|
23 |
*
|
24 |
* @author Chris Chabot <chabotc@google.com>
|
25 |
*/
|
26 |
+
class Yoast_Google_MemcacheCache extends Yoast_Google_Cache {
|
27 |
private $connection = false;
|
28 |
|
29 |
public function __construct() {
|
30 |
global $apiConfig;
|
31 |
if (! function_exists('memcache_connect')) {
|
32 |
+
throw new Yoast_Google_CacheException("Memcache functions not available");
|
33 |
}
|
34 |
$this->host = $apiConfig['ioMemCacheCache_host'];
|
35 |
$this->port = $apiConfig['ioMemCacheCache_port'];
|
36 |
if (empty($this->host) || empty($this->port)) {
|
37 |
+
throw new Yoast_Google_CacheException("You need to supply a valid memcache host and port");
|
38 |
}
|
39 |
}
|
40 |
|
79 |
// so this potentially saves a lot of overhead
|
80 |
private function connect() {
|
81 |
if (! $this->connection = @memcache_pconnect($this->host, $this->port)) {
|
82 |
+
throw new Yoast_Google_CacheException("Couldn't connect to memcache server");
|
83 |
}
|
84 |
}
|
85 |
|
108 |
* @inheritDoc
|
109 |
* @param string $key
|
110 |
* @param string $value
|
111 |
+
* @throws Yoast_Google_CacheException
|
112 |
*/
|
113 |
public function set($key, $value) {
|
114 |
$this->check();
|
115 |
// we store it with the cache_time default expiration so objects will at least get cleaned eventually.
|
116 |
if (@memcache_set($this->connection, $key, array('time' => time(),
|
117 |
'data' => $value), false) == false) {
|
118 |
+
throw new Yoast_Google_CacheException("Couldn't store data in cache");
|
119 |
}
|
120 |
}
|
121 |
|
admin/api-libs/google/cache/Google_WPCache.php
ADDED
@@ -0,0 +1,53 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/*
|
3 |
+
* This class implements the caching mechanism for WordPress
|
4 |
+
*/
|
5 |
+
class Yoast_Google_WPCache extends Yoast_Google_Cache {
|
6 |
+
|
7 |
+
/**
|
8 |
+
* If wp_cache_get doesn't exists, include the file
|
9 |
+
*
|
10 |
+
*/
|
11 |
+
public function __construct() {
|
12 |
+
|
13 |
+
if( ! function_exists('wp_cache_get') ) {
|
14 |
+
require_once( ABSPATH . 'wp-includes/cache.php' );
|
15 |
+
}
|
16 |
+
}
|
17 |
+
|
18 |
+
/**
|
19 |
+
* Retrieves the data for the given key, or false if they
|
20 |
+
* key is unknown or expired
|
21 |
+
*
|
22 |
+
* @param String $key The key who's data to retrieve
|
23 |
+
* @param boolean|int $expiration - Expiration time in seconds
|
24 |
+
*
|
25 |
+
* @return mixed
|
26 |
+
*
|
27 |
+
*/
|
28 |
+
public function get($key, $expiration = false) {
|
29 |
+
return wp_cache_get( $key );
|
30 |
+
}
|
31 |
+
|
32 |
+
/**
|
33 |
+
* Store the key => $value set. The $value is serialized
|
34 |
+
* by this function so can be of any type
|
35 |
+
*
|
36 |
+
* @param string $key Key of the data
|
37 |
+
* @param string $value data
|
38 |
+
*/
|
39 |
+
public function set($key, $value) {
|
40 |
+
wp_cache_set( $key, $value ) ;
|
41 |
+
}
|
42 |
+
|
43 |
+
/**
|
44 |
+
* Removes the key/data pair for the given $key
|
45 |
+
*
|
46 |
+
* @param String $key
|
47 |
+
*/
|
48 |
+
public function delete($key) {
|
49 |
+
wp_cache_delete( $key );
|
50 |
+
}
|
51 |
+
|
52 |
+
|
53 |
+
}
|
admin/api-libs/google/class-api-google.php
CHANGED
@@ -2,7 +2,7 @@
|
|
2 |
|
3 |
if ( ! class_exists( 'Yoast_Api_Google' ) ) {
|
4 |
|
5 |
-
class Yoast_Api_Google{
|
6 |
|
7 |
public $options;
|
8 |
|
@@ -14,10 +14,69 @@ if ( ! class_exists( 'Yoast_Api_Google' ) ) {
|
|
14 |
}
|
15 |
|
16 |
/**
|
17 |
-
* Autoload the
|
18 |
*/
|
19 |
private function load_api_google_files() {
|
20 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
21 |
}
|
22 |
|
23 |
}
|
2 |
|
3 |
if ( ! class_exists( 'Yoast_Api_Google' ) ) {
|
4 |
|
5 |
+
class Yoast_Api_Google {
|
6 |
|
7 |
public $options;
|
8 |
|
14 |
}
|
15 |
|
16 |
/**
|
17 |
+
* Register the Autoload the Google class
|
18 |
*/
|
19 |
private function load_api_google_files() {
|
20 |
+
spl_autoload_register( array( $this, 'autoload_api_google_files' ) );
|
21 |
+
}
|
22 |
+
|
23 |
+
/**
|
24 |
+
* Autoload the API Google class
|
25 |
+
*
|
26 |
+
* @param string $class_name - The class that should be loaded
|
27 |
+
*/
|
28 |
+
private function autoload_api_google_files( $class_name ) {
|
29 |
+
$path = dirname( __FILE__ );
|
30 |
+
$class_name = strtolower( $class_name );
|
31 |
+
$oauth_files = array(
|
32 |
+
// Main requires
|
33 |
+
'yoast_google_client' => 'Google_Client',
|
34 |
+
|
35 |
+
// Requires in classes
|
36 |
+
'yoast_google_model' => 'service/Google_Model',
|
37 |
+
'yoast_google_service' => 'service/Google_Service',
|
38 |
+
'yoast_google_serviceresource' => 'service/Google_ServiceResource',
|
39 |
+
'yoast_google_assertion' => 'auth/Google_AssertionCredentials',
|
40 |
+
'yoast_google_signer' => 'auth/Google_Signer',
|
41 |
+
'yoast_google_p12signer' => 'auth/Google_P12Signer',
|
42 |
+
'yoast_google_batchrequest' => 'service/Google_BatchRequest',
|
43 |
+
'yoast_google_uritemplate' => 'external/URITemplateParser',
|
44 |
+
'yoast_google_auth' => 'auth/Google_Auth',
|
45 |
+
'yoast_google_cache' => 'cache/Google_Cache',
|
46 |
+
'yoast_google_io' => 'io/Google_IO',
|
47 |
+
'yoast_google_mediafileupload' => 'service/Google_MediaFileUpload',
|
48 |
+
'yoast_google_authnone' => 'auth/Google_AuthNone',
|
49 |
+
'yoast_google_oauth2' => 'auth/Google_OAuth2',
|
50 |
+
'yoast_google_verifier' => 'auth/Google_Verifier',
|
51 |
+
'yoast_google_loginticket' => 'auth/Google_LoginTicket',
|
52 |
+
'yoast_google_utils' => 'service/Google_Utils',
|
53 |
+
'yoast_google_pemverifier' => 'auth/Google_PemVerifier',
|
54 |
+
|
55 |
+
// Caching
|
56 |
+
'yoast_google_filecache' => 'cache/Google_FileCache',
|
57 |
+
'yoast_google_memcachecache' => 'cache/Google_MemcacheCache',
|
58 |
+
'yoast_google_cacheparser' => 'io/Google_CacheParser',
|
59 |
+
|
60 |
+
// Requests
|
61 |
+
'yoast_google_httprequest' => 'io/Google_HttpRequest',
|
62 |
+
'yoast_google_httpstream_io' => 'io/Google_HttpStreamIO',
|
63 |
+
'yoast_google_rest' => 'io/Google_REST',
|
64 |
+
|
65 |
+
// Wordpress
|
66 |
+
'yoast_google_wpio' => 'io/Google_WPIO',
|
67 |
+
'yoast_google_wpcache' => 'cache/Google_WPCache',
|
68 |
+
|
69 |
+
// REPLACE ME!
|
70 |
+
'yoast_google_curlio' => 'io/Google_CurlIO',
|
71 |
+
);
|
72 |
+
|
73 |
+
if ( ! empty( $oauth_files[$class_name] ) ) {
|
74 |
+
if ( file_exists( $path . '/' . $oauth_files[$class_name] . '.php' ) ) {
|
75 |
+
require_once( $path . '/' . $oauth_files[$class_name] . '.php' );
|
76 |
+
}
|
77 |
+
|
78 |
+
}
|
79 |
+
|
80 |
}
|
81 |
|
82 |
}
|
admin/api-libs/google/config.php
CHANGED
@@ -36,9 +36,9 @@ $apiConfig = array(
|
|
36 |
'site_name' => 'www.example.org',
|
37 |
|
38 |
// Which Authentication, Storage and HTTP IO classes to use.
|
39 |
-
'authClass' => '
|
40 |
-
'ioClass' => '
|
41 |
-
'cacheClass' => '
|
42 |
|
43 |
// Don't change these unless you're working against a special development or testing environment.
|
44 |
'basePath' => 'https://www.googleapis.com',
|
36 |
'site_name' => 'www.example.org',
|
37 |
|
38 |
// Which Authentication, Storage and HTTP IO classes to use.
|
39 |
+
'authClass' => 'Yoast_Google_OAuth2',
|
40 |
+
'ioClass' => 'Yoast_Google_WPIO',
|
41 |
+
'cacheClass' => 'Yoast_Google_WPCache',
|
42 |
|
43 |
// Don't change these unless you're working against a special development or testing environment.
|
44 |
'basePath' => 'https://www.googleapis.com',
|
admin/api-libs/google/io/Google_CacheParser.php
CHANGED
@@ -19,7 +19,7 @@
|
|
19 |
* implementation is guided by the guidance offered in rfc2616-sec13.
|
20 |
* @author Chirag Shah <chirags@google.com>
|
21 |
*/
|
22 |
-
class
|
23 |
public static $CACHEABLE_HTTP_METHODS = array('GET', 'HEAD');
|
24 |
public static $CACHEABLE_STATUS_CODES = array('200', '203', '300', '301');
|
25 |
|
@@ -29,11 +29,11 @@ class Google_CacheParser {
|
|
29 |
* Check if an HTTP request can be cached by a private local cache.
|
30 |
*
|
31 |
* @static
|
32 |
-
* @param
|
33 |
* @return bool True if the request is cacheable.
|
34 |
* False if the request is uncacheable.
|
35 |
*/
|
36 |
-
public static function isRequestCacheable (
|
37 |
$method = $resp->getRequestMethod();
|
38 |
if (! in_array($method, self::$CACHEABLE_HTTP_METHODS)) {
|
39 |
return false;
|
@@ -54,11 +54,11 @@ class Google_CacheParser {
|
|
54 |
* Check if an HTTP response can be cached by a private local cache.
|
55 |
*
|
56 |
* @static
|
57 |
-
* @param
|
58 |
* @return bool True if the response is cacheable.
|
59 |
* False if the response is un-cacheable.
|
60 |
*/
|
61 |
-
public static function isResponseCacheable (
|
62 |
// First, check if the HTTP request was cacheable before inspecting the
|
63 |
// HTTP response.
|
64 |
if (false == self::isRequestCacheable($resp)) {
|
@@ -105,11 +105,11 @@ class Google_CacheParser {
|
|
105 |
|
106 |
/**
|
107 |
* @static
|
108 |
-
* @param
|
109 |
* @return bool True if the HTTP response is considered to be expired.
|
110 |
* False if it is considered to be fresh.
|
111 |
*/
|
112 |
-
public static function isExpired(
|
113 |
// HTTP/1.1 clients and caches MUST treat other invalid date formats,
|
114 |
// especially including the value “0”, as in the past.
|
115 |
$parsedExpires = false;
|
@@ -161,10 +161,10 @@ class Google_CacheParser {
|
|
161 |
/**
|
162 |
* Determine if a cache entry should be revalidated with by the origin.
|
163 |
*
|
164 |
-
* @param
|
165 |
* @return bool True if the entry is expired, else return false.
|
166 |
*/
|
167 |
-
public static function mustRevalidate(
|
168 |
// [13.3] When a cache has a stale entry that it would like to use as a
|
169 |
// response to a client's request, it first has to check with the origin
|
170 |
// server to see if its cached entry is still usable.
|
19 |
* implementation is guided by the guidance offered in rfc2616-sec13.
|
20 |
* @author Chirag Shah <chirags@google.com>
|
21 |
*/
|
22 |
+
class Yoast_Google_CacheParser {
|
23 |
public static $CACHEABLE_HTTP_METHODS = array('GET', 'HEAD');
|
24 |
public static $CACHEABLE_STATUS_CODES = array('200', '203', '300', '301');
|
25 |
|
29 |
* Check if an HTTP request can be cached by a private local cache.
|
30 |
*
|
31 |
* @static
|
32 |
+
* @param Yoast_Google_HttpRequest $resp
|
33 |
* @return bool True if the request is cacheable.
|
34 |
* False if the request is uncacheable.
|
35 |
*/
|
36 |
+
public static function isRequestCacheable (Yoast_Google_HttpRequest $resp) {
|
37 |
$method = $resp->getRequestMethod();
|
38 |
if (! in_array($method, self::$CACHEABLE_HTTP_METHODS)) {
|
39 |
return false;
|
54 |
* Check if an HTTP response can be cached by a private local cache.
|
55 |
*
|
56 |
* @static
|
57 |
+
* @param Yoast_Google_HttpRequest $resp
|
58 |
* @return bool True if the response is cacheable.
|
59 |
* False if the response is un-cacheable.
|
60 |
*/
|
61 |
+
public static function isResponseCacheable (Yoast_Google_HttpRequest $resp) {
|
62 |
// First, check if the HTTP request was cacheable before inspecting the
|
63 |
// HTTP response.
|
64 |
if (false == self::isRequestCacheable($resp)) {
|
105 |
|
106 |
/**
|
107 |
* @static
|
108 |
+
* @param Yoast_Google_HttpRequest $resp
|
109 |
* @return bool True if the HTTP response is considered to be expired.
|
110 |
* False if it is considered to be fresh.
|
111 |
*/
|
112 |
+
public static function isExpired(Yoast_Google_HttpRequest $resp) {
|
113 |
// HTTP/1.1 clients and caches MUST treat other invalid date formats,
|
114 |
// especially including the value “0”, as in the past.
|
115 |
$parsedExpires = false;
|
161 |
/**
|
162 |
* Determine if a cache entry should be revalidated with by the origin.
|
163 |
*
|
164 |
+
* @param Yoast_Google_HttpRequest $response
|
165 |
* @return bool True if the entry is expired, else return false.
|
166 |
*/
|
167 |
+
public static function mustRevalidate(Yoast_Google_HttpRequest $response) {
|
168 |
// [13.3] When a cache has a stale entry that it would like to use as a
|
169 |
// response to a client's request, it first has to check with the origin
|
170 |
// server to see if its cached entry is still usable.
|
admin/api-libs/google/io/Google_CurlIO.php
CHANGED
@@ -22,9 +22,7 @@
|
|
22 |
* @author Chirag Shah <chirags@google.com>
|
23 |
*/
|
24 |
|
25 |
-
|
26 |
-
|
27 |
-
class Google_CurlIO extends Google_IO {
|
28 |
private static $ENTITY_HTTP_METHODS = array("POST" => null, "PUT" => null);
|
29 |
private static $HOP_BY_HOP = array(
|
30 |
'connection', 'keep-alive', 'proxy-authenticate', 'proxy-authorization',
|
@@ -55,24 +53,24 @@ class Google_CurlIO extends Google_IO {
|
|
55 |
* (which can modify the request in what ever way fits the auth mechanism)
|
56 |
* and then calls apiCurlIO::makeRequest on the signed request
|
57 |
*
|
58 |
-
* @param
|
59 |
-
* @return
|
60 |
* responseHttpCode, responseHeaders and responseBody.
|
61 |
*/
|
62 |
-
public function authenticatedRequest(
|
63 |
-
$request =
|
64 |
return $this->makeRequest($request);
|
65 |
}
|
66 |
|
67 |
/**
|
68 |
* Execute a apiHttpRequest
|
69 |
*
|
70 |
-
* @param
|
71 |
-
* @return
|
72 |
* headers and response body filled in
|
73 |
-
* @throws
|
74 |
*/
|
75 |
-
public function makeRequest(
|
76 |
// First, check to see if we have a valid cached version.
|
77 |
$cached = $this->getCachedRequest($request);
|
78 |
if ($cached !== false) {
|
@@ -120,7 +118,7 @@ class Google_CurlIO extends Google_IO {
|
|
120 |
$curlError = curl_error($ch);
|
121 |
curl_close($ch);
|
122 |
if ($curlErrorNum != CURLE_OK) {
|
123 |
-
throw new
|
124 |
}
|
125 |
|
126 |
// Parse out the raw response into usable bits
|
@@ -162,7 +160,7 @@ class Google_CurlIO extends Google_IO {
|
|
162 |
* @param $headerSize
|
163 |
* @return array
|
164 |
*/
|
165 |
-
|
166 |
if (stripos($respData, parent::CONNECTION_ESTABLISHED) !== false) {
|
167 |
$respData = str_ireplace(parent::CONNECTION_ESTABLISHED, '', $respData);
|
168 |
}
|
@@ -178,7 +176,7 @@ class Google_CurlIO extends Google_IO {
|
|
178 |
return array($responseHeaders, $responseBody);
|
179 |
}
|
180 |
|
181 |
-
|
182 |
$responseHeaders = array();
|
183 |
|
184 |
$responseHeaderLines = explode("\r\n", $rawHeaders);
|
22 |
* @author Chirag Shah <chirags@google.com>
|
23 |
*/
|
24 |
|
25 |
+
class Yoast_Google_CurlIO extends Yoast_Google_IO {
|
|
|
|
|
26 |
private static $ENTITY_HTTP_METHODS = array("POST" => null, "PUT" => null);
|
27 |
private static $HOP_BY_HOP = array(
|
28 |
'connection', 'keep-alive', 'proxy-authenticate', 'proxy-authorization',
|
53 |
* (which can modify the request in what ever way fits the auth mechanism)
|
54 |
* and then calls apiCurlIO::makeRequest on the signed request
|
55 |
*
|
56 |
+
* @param Yoast_Google_HttpRequest $request
|
57 |
+
* @return Yoast_Google_HttpRequest The resulting HTTP response including the
|
58 |
* responseHttpCode, responseHeaders and responseBody.
|
59 |
*/
|
60 |
+
public function authenticatedRequest(Yoast_Google_HttpRequest $request) {
|
61 |
+
$request = Yoast_Google_Client::$auth->sign($request);
|
62 |
return $this->makeRequest($request);
|
63 |
}
|
64 |
|
65 |
/**
|
66 |
* Execute a apiHttpRequest
|
67 |
*
|
68 |
+
* @param Yoast_Google_HttpRequest $request the http request to be executed
|
69 |
+
* @return Yoast_Google_HttpRequest http request with the response http code, response
|
70 |
* headers and response body filled in
|
71 |
+
* @throws Yoast_Google_IOException on curl or IO error
|
72 |
*/
|
73 |
+
public function makeRequest(Yoast_Google_HttpRequest $request) {
|
74 |
// First, check to see if we have a valid cached version.
|
75 |
$cached = $this->getCachedRequest($request);
|
76 |
if ($cached !== false) {
|
118 |
$curlError = curl_error($ch);
|
119 |
curl_close($ch);
|
120 |
if ($curlErrorNum != CURLE_OK) {
|
121 |
+
throw new Yoast_Google_IOException("HTTP Error: ($respHttpCode) $curlError");
|
122 |
}
|
123 |
|
124 |
// Parse out the raw response into usable bits
|
160 |
* @param $headerSize
|
161 |
* @return array
|
162 |
*/
|
163 |
+
public static function parseHttpResponse($respData, $headerSize) {
|
164 |
if (stripos($respData, parent::CONNECTION_ESTABLISHED) !== false) {
|
165 |
$respData = str_ireplace(parent::CONNECTION_ESTABLISHED, '', $respData);
|
166 |
}
|
176 |
return array($responseHeaders, $responseBody);
|
177 |
}
|
178 |
|
179 |
+
public static function parseResponseHeaders($rawHeaders) {
|
180 |
$responseHeaders = array();
|
181 |
|
182 |
$responseHeaderLines = explode("\r\n", $rawHeaders);
|
admin/api-libs/google/io/Google_HttpRequest.php
CHANGED
@@ -23,7 +23,7 @@
|
|
23 |
* @author Chirag Shah <chirags@google.com>
|
24 |
*
|
25 |
*/
|
26 |
-
class
|
27 |
const USER_AGENT_SUFFIX = "google-api-php-client/0.6.5";
|
28 |
private $batchHeaders = array(
|
29 |
'Content-Type' => 'application/http',
|
@@ -119,7 +119,7 @@ class Google_HttpRequest {
|
|
119 |
* to be normalized.
|
120 |
*/
|
121 |
public function setResponseHeaders($headers) {
|
122 |
-
$headers =
|
123 |
if ($this->responseHeaders) {
|
124 |
$headers = array_merge($this->responseHeaders, $headers);
|
125 |
}
|
@@ -215,7 +215,7 @@ class Google_HttpRequest {
|
|
215 |
* to be set and normalized.
|
216 |
*/
|
217 |
public function setRequestHeaders($headers) {
|
218 |
-
$headers =
|
219 |
if ($this->requestHeaders) {
|
220 |
$headers = array_merge($this->requestHeaders, $headers);
|
221 |
}
|
23 |
* @author Chirag Shah <chirags@google.com>
|
24 |
*
|
25 |
*/
|
26 |
+
class Yoast_Google_HttpRequest {
|
27 |
const USER_AGENT_SUFFIX = "google-api-php-client/0.6.5";
|
28 |
private $batchHeaders = array(
|
29 |
'Content-Type' => 'application/http',
|
119 |
* to be normalized.
|
120 |
*/
|
121 |
public function setResponseHeaders($headers) {
|
122 |
+
$headers = Yoast_Google_Utils::normalize($headers);
|
123 |
if ($this->responseHeaders) {
|
124 |
$headers = array_merge($this->responseHeaders, $headers);
|
125 |
}
|
215 |
* to be set and normalized.
|
216 |
*/
|
217 |
public function setRequestHeaders($headers) {
|
218 |
+
$headers = Yoast_Google_Utils::normalize($headers);
|
219 |
if ($this->requestHeaders) {
|
220 |
$headers = array_merge($this->requestHeaders, $headers);
|
221 |
}
|
admin/api-libs/google/io/Google_HttpStreamIO.php
CHANGED
@@ -16,14 +16,12 @@
|
|
16 |
*/
|
17 |
|
18 |
/**
|
19 |
-
* Http Streams based implementation of
|
20 |
*
|
21 |
* @author Stuart Langley <slangley@google.com>
|
22 |
*/
|
23 |
|
24 |
-
|
25 |
-
|
26 |
-
class Google_HttpStreamIO extends Google_IO {
|
27 |
|
28 |
private static $ENTITY_HTTP_METHODS = array("POST" => null, "PUT" => null);
|
29 |
|
@@ -40,26 +38,26 @@ class Google_HttpStreamIO extends Google_IO {
|
|
40 |
* Perform an authenticated / signed apiHttpRequest.
|
41 |
* This function takes the apiHttpRequest, calls apiAuth->sign on it
|
42 |
* (which can modify the request in what ever way fits the auth mechanism)
|
43 |
-
* and then calls
|
44 |
*
|
45 |
-
* @param
|
46 |
-
* @return
|
47 |
* responseHttpCode, responseHeaders and responseBody.
|
48 |
*/
|
49 |
-
public function authenticatedRequest(
|
50 |
-
$request =
|
51 |
return $this->makeRequest($request);
|
52 |
}
|
53 |
|
54 |
/**
|
55 |
* Execute a apiHttpRequest
|
56 |
*
|
57 |
-
* @param
|
58 |
-
* @return
|
59 |
* response headers and response body filled in
|
60 |
-
* @throws
|
61 |
*/
|
62 |
-
public function makeRequest(
|
63 |
// First, check to see if we have a valid cached version.
|
64 |
$cached = $this->getCachedRequest($request);
|
65 |
if ($cached !== false) {
|
@@ -112,7 +110,7 @@ class Google_HttpStreamIO extends Google_IO {
|
|
112 |
$context);
|
113 |
|
114 |
if (false === $response_data) {
|
115 |
-
throw new
|
116 |
}
|
117 |
|
118 |
$respHttpCode = $this->getHttpResponseCode($http_response_header);
|
16 |
*/
|
17 |
|
18 |
/**
|
19 |
+
* Http Streams based implementation of Yoast_Google_IO.
|
20 |
*
|
21 |
* @author Stuart Langley <slangley@google.com>
|
22 |
*/
|
23 |
|
24 |
+
class Yoast_Google_HttpStreamIO extends Yoast_Google_IO {
|
|
|
|
|
25 |
|
26 |
private static $ENTITY_HTTP_METHODS = array("POST" => null, "PUT" => null);
|
27 |
|
38 |
* Perform an authenticated / signed apiHttpRequest.
|
39 |
* This function takes the apiHttpRequest, calls apiAuth->sign on it
|
40 |
* (which can modify the request in what ever way fits the auth mechanism)
|
41 |
+
* and then calls Yoast_Google_HttpStreamIO::makeRequest on the signed request
|
42 |
*
|
43 |
+
* @param Yoast_Google_HttpRequest $request
|
44 |
+
* @return Yoast_Google_HttpRequest The resulting HTTP response including the
|
45 |
* responseHttpCode, responseHeaders and responseBody.
|
46 |
*/
|
47 |
+
public function authenticatedRequest(Yoast_Google_HttpRequest $request) {
|
48 |
+
$request = Yoast_Google_Client::$auth->sign($request);
|
49 |
return $this->makeRequest($request);
|
50 |
}
|
51 |
|
52 |
/**
|
53 |
* Execute a apiHttpRequest
|
54 |
*
|
55 |
+
* @param Yoast_Google_HttpRequest $request the http request to be executed
|
56 |
+
* @return Yoast_Google_HttpRequest http request with the response http code,
|
57 |
* response headers and response body filled in
|
58 |
+
* @throws Yoast_Google_IOException on curl or IO error
|
59 |
*/
|
60 |
+
public function makeRequest(Yoast_Google_HttpRequest $request) {
|
61 |
// First, check to see if we have a valid cached version.
|
62 |
$cached = $this->getCachedRequest($request);
|
63 |
if ($cached !== false) {
|
110 |
$context);
|
111 |
|
112 |
if (false === $response_data) {
|
113 |
+
throw new Yoast_Google_IOException("HTTP Error: Unable to connect");
|
114 |
}
|
115 |
|
116 |
$respHttpCode = $this->getHttpResponseCode($http_response_header);
|
admin/api-libs/google/io/Google_IO.php
CHANGED
@@ -15,33 +15,28 @@
|
|
15 |
* limitations under the License.
|
16 |
*/
|
17 |
|
18 |
-
require_once 'io/Google_HttpRequest.php';
|
19 |
-
require_once 'io/Google_HttpStreamIO.php';
|
20 |
-
require_once 'io/Google_CurlIO.php';
|
21 |
-
require_once 'io/Google_REST.php';
|
22 |
-
|
23 |
/**
|
24 |
* Abstract IO class
|
25 |
*
|
26 |
* @author Chris Chabot <chabotc@google.com>
|
27 |
*/
|
28 |
-
abstract class
|
29 |
const CONNECTION_ESTABLISHED = "HTTP/1.0 200 Connection established\r\n\r\n";
|
30 |
const FORM_URLENCODED = 'application/x-www-form-urlencoded';
|
31 |
/**
|
32 |
* An utility function that first calls $this->auth->sign($request) and then executes makeRequest()
|
33 |
* on that signed request. Used for when a request should be authenticated
|
34 |
-
* @param
|
35 |
-
* @return
|
36 |
*/
|
37 |
-
abstract function authenticatedRequest(
|
38 |
|
39 |
/**
|
40 |
* Executes a apIHttpRequest and returns the resulting populated httpRequest
|
41 |
-
* @param
|
42 |
-
* @return
|
43 |
*/
|
44 |
-
abstract function makeRequest(
|
45 |
|
46 |
/**
|
47 |
* Set options that update the transport implementation's behavior.
|
@@ -52,14 +47,14 @@ abstract class Google_IO {
|
|
52 |
/**
|
53 |
* @visible for testing.
|
54 |
* Cache the response to an HTTP request if it is cacheable.
|
55 |
-
* @param
|
56 |
* @return bool Returns true if the insertion was successful.
|
57 |
* Otherwise, return false.
|
58 |
*/
|
59 |
-
protected function setCachedRequest(
|
60 |
// Determine if the request is cacheable.
|
61 |
-
if (
|
62 |
-
|
63 |
return true;
|
64 |
}
|
65 |
|
@@ -68,25 +63,25 @@ abstract class Google_IO {
|
|
68 |
|
69 |
/**
|
70 |
* @visible for testing.
|
71 |
-
* @param
|
72 |
-
* @return
|
73 |
* false if the operation was unsuccessful.
|
74 |
*/
|
75 |
-
protected function getCachedRequest(
|
76 |
-
if (false ==
|
77 |
false;
|
78 |
}
|
79 |
|
80 |
-
return
|
81 |
}
|
82 |
|
83 |
/**
|
84 |
* @visible for testing
|
85 |
* Process an http request that contains an enclosed entity.
|
86 |
-
* @param
|
87 |
-
* @return
|
88 |
*/
|
89 |
-
protected function processEntityRequest(
|
90 |
$postBody = $request->getPostBody();
|
91 |
$contentType = $request->getRequestHeader("content-type");
|
92 |
|
@@ -114,13 +109,13 @@ abstract class Google_IO {
|
|
114 |
/**
|
115 |
* Check if an already cached request must be revalidated, and if so update
|
116 |
* the request with the correct ETag headers.
|
117 |
-
* @param
|
118 |
-
* @param
|
119 |
* return bool If the cached object needs to be revalidated, false if it is
|
120 |
* still current and can be re-used.
|
121 |
*/
|
122 |
protected function checkMustRevaliadateCachedRequest($cached, $request) {
|
123 |
-
if (
|
124 |
$addHeaders = array();
|
125 |
if ($cached->getResponseHeader('etag')) {
|
126 |
// [13.3.4] If an entity tag has been provided by the origin server,
|
@@ -139,7 +134,7 @@ abstract class Google_IO {
|
|
139 |
|
140 |
/**
|
141 |
* Update a cached request, using the headers from the last response.
|
142 |
-
* @param
|
143 |
* @param mixed Associative array of response headers from the last request.
|
144 |
*/
|
145 |
protected function updateCachedRequest($cached, $responseHeaders) {
|
15 |
* limitations under the License.
|
16 |
*/
|
17 |
|
|
|
|
|
|
|
|
|
|
|
18 |
/**
|
19 |
* Abstract IO class
|
20 |
*
|
21 |
* @author Chris Chabot <chabotc@google.com>
|
22 |
*/
|
23 |
+
abstract class Yoast_Google_IO {
|
24 |
const CONNECTION_ESTABLISHED = "HTTP/1.0 200 Connection established\r\n\r\n";
|
25 |
const FORM_URLENCODED = 'application/x-www-form-urlencoded';
|
26 |
/**
|
27 |
* An utility function that first calls $this->auth->sign($request) and then executes makeRequest()
|
28 |
* on that signed request. Used for when a request should be authenticated
|
29 |
+
* @param Yoast_Google_HttpRequest $request
|
30 |
+
* @return Yoast_Google_HttpRequest $request
|
31 |
*/
|
32 |
+
abstract function authenticatedRequest(Yoast_Google_HttpRequest $request);
|
33 |
|
34 |
/**
|
35 |
* Executes a apIHttpRequest and returns the resulting populated httpRequest
|
36 |
+
* @param Yoast_Google_HttpRequest $request
|
37 |
+
* @return Yoast_Google_HttpRequest $request
|
38 |
*/
|
39 |
+
abstract function makeRequest(Yoast_Google_HttpRequest $request);
|
40 |
|
41 |
/**
|
42 |
* Set options that update the transport implementation's behavior.
|
47 |
/**
|
48 |
* @visible for testing.
|
49 |
* Cache the response to an HTTP request if it is cacheable.
|
50 |
+
* @param Yoast_Google_HttpRequest $request
|
51 |
* @return bool Returns true if the insertion was successful.
|
52 |
* Otherwise, return false.
|
53 |
*/
|
54 |
+
protected function setCachedRequest(Yoast_Google_HttpRequest $request) {
|
55 |
// Determine if the request is cacheable.
|
56 |
+
if (Yoast_Google_CacheParser::isResponseCacheable($request)) {
|
57 |
+
Yoast_Google_Client::$cache->set($request->getCacheKey(), $request);
|
58 |
return true;
|
59 |
}
|
60 |
|
63 |
|
64 |
/**
|
65 |
* @visible for testing.
|
66 |
+
* @param Yoast_Google_HttpRequest $request
|
67 |
+
* @return Yoast_Google_HttpRequest|bool Returns the cached object or
|
68 |
* false if the operation was unsuccessful.
|
69 |
*/
|
70 |
+
protected function getCachedRequest(Yoast_Google_HttpRequest $request) {
|
71 |
+
if (false == Yoast_Google_CacheParser::isRequestCacheable($request)) {
|
72 |
false;
|
73 |
}
|
74 |
|
75 |
+
return Yoast_Google_Client::$cache->get($request->getCacheKey());
|
76 |
}
|
77 |
|
78 |
/**
|
79 |
* @visible for testing
|
80 |
* Process an http request that contains an enclosed entity.
|
81 |
+
* @param Yoast_Google_HttpRequest $request
|
82 |
+
* @return Yoast_Google_HttpRequest Processed request with the enclosed entity.
|
83 |
*/
|
84 |
+
protected function processEntityRequest(Yoast_Google_HttpRequest $request) {
|
85 |
$postBody = $request->getPostBody();
|
86 |
$contentType = $request->getRequestHeader("content-type");
|
87 |
|
109 |
/**
|
110 |
* Check if an already cached request must be revalidated, and if so update
|
111 |
* the request with the correct ETag headers.
|
112 |
+
* @param Yoast_Google_HttpRequest $cached A previously cached response.
|
113 |
+
* @param Yoast_Google_HttpRequest $request The outbound request.
|
114 |
* return bool If the cached object needs to be revalidated, false if it is
|
115 |
* still current and can be re-used.
|
116 |
*/
|
117 |
protected function checkMustRevaliadateCachedRequest($cached, $request) {
|
118 |
+
if (Yoast_Google_CacheParser::mustRevalidate($cached)) {
|
119 |
$addHeaders = array();
|
120 |
if ($cached->getResponseHeader('etag')) {
|
121 |
// [13.3.4] If an entity tag has been provided by the origin server,
|
134 |
|
135 |
/**
|
136 |
* Update a cached request, using the headers from the last response.
|
137 |
+
* @param Yoast_Google_HttpRequest $cached A previously cached response.
|
138 |
* @param mixed Associative array of response headers from the last request.
|
139 |
*/
|
140 |
protected function updateCachedRequest($cached, $responseHeaders) {
|
admin/api-libs/google/io/Google_REST.php
CHANGED
@@ -21,18 +21,18 @@
|
|
21 |
* @author Chris Chabot <chabotc@google.com>
|
22 |
* @author Chirag Shah <chirags@google.com>
|
23 |
*/
|
24 |
-
class
|
25 |
/**
|
26 |
* Executes a apiServiceRequest using a RESTful call by transforming it into
|
27 |
* an apiHttpRequest, and executed via apiIO::authenticatedRequest().
|
28 |
*
|
29 |
-
* @param
|
30 |
* @return array decoded result
|
31 |
-
* @throws
|
32 |
* invalid or malformed post body, invalid url)
|
33 |
*/
|
34 |
-
static public function execute(
|
35 |
-
$httpRequest =
|
36 |
$decodedResponse = self::decodeHttpResponse($httpRequest);
|
37 |
$ret = isset($decodedResponse['data'])
|
38 |
? $decodedResponse['data'] : $decodedResponse;
|
@@ -43,8 +43,8 @@ class Google_REST {
|
|
43 |
/**
|
44 |
* Decode an HTTP Response.
|
45 |
* @static
|
46 |
-
* @throws
|
47 |
-
* @param
|
48 |
* @return mixed|null
|
49 |
*/
|
50 |
public static function decodeHttpResponse($response) {
|
@@ -63,14 +63,14 @@ class Google_REST {
|
|
63 |
$err .= ": ($code) $body";
|
64 |
}
|
65 |
|
66 |
-
throw new
|
67 |
}
|
68 |
|
69 |
// Only attempt to decode the response, if the response code wasn't (204) 'no content'
|
70 |
if ($code != '204') {
|
71 |
$decoded = json_decode($body, true);
|
72 |
if ($decoded === null || $decoded === "") {
|
73 |
-
throw new
|
74 |
}
|
75 |
}
|
76 |
return $decoded;
|
21 |
* @author Chris Chabot <chabotc@google.com>
|
22 |
* @author Chirag Shah <chirags@google.com>
|
23 |
*/
|
24 |
+
class Yoast_Google_REST {
|
25 |
/**
|
26 |
* Executes a apiServiceRequest using a RESTful call by transforming it into
|
27 |
* an apiHttpRequest, and executed via apiIO::authenticatedRequest().
|
28 |
*
|
29 |
+
* @param Yoast_Google_HttpRequest $req
|
30 |
* @return array decoded result
|
31 |
+
* @throws Yoast_Google_ServiceException on server side error (ie: not authenticated,
|
32 |
* invalid or malformed post body, invalid url)
|
33 |
*/
|
34 |
+
static public function execute(Yoast_Google_HttpRequest $req) {
|
35 |
+
$httpRequest = Yoast_Google_Client::$io->makeRequest($req);
|
36 |
$decodedResponse = self::decodeHttpResponse($httpRequest);
|
37 |
$ret = isset($decodedResponse['data'])
|
38 |
? $decodedResponse['data'] : $decodedResponse;
|
43 |
/**
|
44 |
* Decode an HTTP Response.
|
45 |
* @static
|
46 |
+
* @throws Yoast_Google_ServiceException
|
47 |
+
* @param Yoast_Google_HttpRequest $response The http response to be decoded.
|
48 |
* @return mixed|null
|
49 |
*/
|
50 |
public static function decodeHttpResponse($response) {
|
63 |
$err .= ": ($code) $body";
|
64 |
}
|
65 |
|
66 |
+
throw new Yoast_Google_ServiceException($err, $code, null, $decoded['error']['errors']);
|
67 |
}
|
68 |
|
69 |
// Only attempt to decode the response, if the response code wasn't (204) 'no content'
|
70 |
if ($code != '204') {
|
71 |
$decoded = json_decode($body, true);
|
72 |
if ($decoded === null || $decoded === "") {
|
73 |
+
throw new Yoast_Google_ServiceException("Invalid json in service response: $body");
|
74 |
}
|
75 |
}
|
76 |
return $decoded;
|
admin/api-libs/google/io/Google_WPIO.php
ADDED
@@ -0,0 +1,122 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/*
|
3 |
+
* Copyright 2010 Google Inc.
|
4 |
+
*
|
5 |
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
6 |
+
* you may not use this file except in compliance with the License.
|
7 |
+
* You may obtain a copy of the License at
|
8 |
+
*
|
9 |
+
* http://www.apache.org/licenses/LICENSE-2.0
|
10 |
+
*
|
11 |
+
* Unless required by applicable law or agreed to in writing, software
|
12 |
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
13 |
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14 |
+
* See the License for the specific language governing permissions and
|
15 |
+
* limitations under the License.
|
16 |
+
*/
|
17 |
+
|
18 |
+
/**
|
19 |
+
* WP based implementation of apiIO.
|
20 |
+
*
|
21 |
+
*/
|
22 |
+
|
23 |
+
class Yoast_Google_WPIO extends Yoast_Google_IO {
|
24 |
+
private static $ENTITY_HTTP_METHODS = array("POST" => null, "PUT" => null);
|
25 |
+
private static $HOP_BY_HOP = array(
|
26 |
+
'connection', 'keep-alive', 'proxy-authenticate', 'proxy-authorization',
|
27 |
+
'te', 'trailers', 'transfer-encoding', 'upgrade');
|
28 |
+
|
29 |
+
/**
|
30 |
+
* Perform an authenticated / signed apiHttpRequest.
|
31 |
+
* This function takes the apiHttpRequest, calls apiAuth->sign on it
|
32 |
+
* (which can modify the request in what ever way fits the auth mechanism)
|
33 |
+
* and then calls apiWPIO::makeRequest on the signed request
|
34 |
+
*
|
35 |
+
* @param Yoast_Google_HttpRequest $request
|
36 |
+
* @return Yoast_Google_HttpRequest The resulting HTTP response including the
|
37 |
+
* responseHttpCode, responseHeaders and responseBody.
|
38 |
+
*/
|
39 |
+
public function authenticatedRequest(Yoast_Google_HttpRequest $request) {
|
40 |
+
$request = Yoast_Google_Client::$auth->sign($request);
|
41 |
+
return $this->makeRequest($request);
|
42 |
+
}
|
43 |
+
|
44 |
+
/**
|
45 |
+
* Execute a apiHttpRequest
|
46 |
+
*
|
47 |
+
* @param Yoast_Google_HttpRequest $request the http request to be executed
|
48 |
+
* @return Yoast_Google_HttpRequest http request with the response http code, response
|
49 |
+
* headers and response body filled in
|
50 |
+
*/
|
51 |
+
public function makeRequest(Yoast_Google_HttpRequest $request) {
|
52 |
+
|
53 |
+
// First, check to see if we have a valid cached version.
|
54 |
+
$cached = $this->getCachedRequest($request);
|
55 |
+
if ($cached !== false) {
|
56 |
+
if (!$this->checkMustRevaliadateCachedRequest($cached, $request)) {
|
57 |
+
return $cached;
|
58 |
+
}
|
59 |
+
}
|
60 |
+
|
61 |
+
if (array_key_exists($request->getRequestMethod(),
|
62 |
+
self::$ENTITY_HTTP_METHODS)) {
|
63 |
+
$request = $this->processEntityRequest($request);
|
64 |
+
}
|
65 |
+
|
66 |
+
$params = array(
|
67 |
+
'user-agent' => $request->getUserAgent()
|
68 |
+
);
|
69 |
+
|
70 |
+
if ($request->getPostBody()) {
|
71 |
+
$params['body'] = $request->getPostBody();
|
72 |
+
}
|
73 |
+
|
74 |
+
$requestHeaders = $request->getRequestHeaders();
|
75 |
+
if ($requestHeaders && is_array($requestHeaders)) {
|
76 |
+
$params['headers'] = $requestHeaders;
|
77 |
+
}
|
78 |
+
|
79 |
+
|
80 |
+
switch( $request->getRequestMethod() ) {
|
81 |
+
case 'POST' :
|
82 |
+
$response = wp_remote_post( $request->getUrl(), $params );
|
83 |
+
break;
|
84 |
+
|
85 |
+
case 'GET' :
|
86 |
+
$response = wp_remote_get( $request->getUrl(), $params );
|
87 |
+
break;
|
88 |
+
}
|
89 |
+
|
90 |
+
$responseBody = wp_remote_retrieve_body( $response );
|
91 |
+
$respHttpCode = wp_remote_retrieve_response_code( $response );
|
92 |
+
$responseHeaders = wp_remote_retrieve_headers( $response );
|
93 |
+
|
94 |
+
if ($respHttpCode == 304 && $cached) {
|
95 |
+
// If the server responded NOT_MODIFIED, return the cached request.
|
96 |
+
$this->updateCachedRequest($cached, $responseHeaders);
|
97 |
+
return $cached;
|
98 |
+
}
|
99 |
+
|
100 |
+
// Fill in the apiHttpRequest with the response values
|
101 |
+
$request->setResponseHttpCode($respHttpCode);
|
102 |
+
$request->setResponseHeaders($responseHeaders);
|
103 |
+
|
104 |
+
$request->setResponseBody($responseBody);
|
105 |
+
// Store the request in cache (the function checks to see if the request
|
106 |
+
// can actually be cached)
|
107 |
+
$this->setCachedRequest($request);
|
108 |
+
// And finally return it
|
109 |
+
|
110 |
+
return $request;
|
111 |
+
}
|
112 |
+
|
113 |
+
/**
|
114 |
+
* Set options that update default behavior.
|
115 |
+
*
|
116 |
+
* @param array $optParams Multiple options used by a session.
|
117 |
+
*/
|
118 |
+
public function setOptions($optParams) {
|
119 |
+
|
120 |
+
}
|
121 |
+
|
122 |
+
}
|
admin/api-libs/google/service/Google_BatchRequest.php
CHANGED
@@ -18,7 +18,7 @@
|
|
18 |
/**
|
19 |
* @author Chirag Shah <chirags@google.com>
|
20 |
*/
|
21 |
-
class
|
22 |
/** @var string Multipart Boundary. */
|
23 |
private $boundary;
|
24 |
|
@@ -30,7 +30,7 @@ class Google_BatchRequest {
|
|
30 |
$this->boundary = str_replace('"', '', $boundary);
|
31 |
}
|
32 |
|
33 |
-
public function add(
|
34 |
if (false == $key) {
|
35 |
$key = mt_rand();
|
36 |
}
|
@@ -41,7 +41,7 @@ class Google_BatchRequest {
|
|
41 |
public function execute() {
|
42 |
$body = '';
|
43 |
|
44 |
-
/** @var
|
45 |
foreach($this->requests as $key => $req) {
|
46 |
$body .= "--{$this->boundary}\n";
|
47 |
$body .= $req->toBatchString($key) . "\n";
|
@@ -52,18 +52,18 @@ class Google_BatchRequest {
|
|
52 |
|
53 |
global $apiConfig;
|
54 |
$url = $apiConfig['basePath'] . '/batch';
|
55 |
-
$httpRequest = new
|
56 |
$httpRequest->setRequestHeaders(array(
|
57 |
'Content-Type' => 'multipart/mixed; boundary=' . $this->boundary));
|
58 |
|
59 |
$httpRequest->setPostBody($body);
|
60 |
-
$response =
|
61 |
|
62 |
$response = $this->parseResponse($response);
|
63 |
return $response;
|
64 |
}
|
65 |
|
66 |
-
public function parseResponse(
|
67 |
$contentType = $response->getResponseHeader('content-type');
|
68 |
$contentType = explode(';', $contentType);
|
69 |
$boundary = false;
|
@@ -84,18 +84,18 @@ class Google_BatchRequest {
|
|
84 |
$part = trim($part);
|
85 |
if (!empty($part)) {
|
86 |
list($metaHeaders, $part) = explode("\r\n\r\n", $part, 2);
|
87 |
-
$metaHeaders =
|
88 |
|
89 |
$status = substr($part, 0, strpos($part, "\n"));
|
90 |
$status = explode(" ", $status);
|
91 |
$status = $status[1];
|
92 |
|
93 |
-
list($partHeaders, $partBody) =
|
94 |
-
$response = new
|
95 |
$response->setResponseHttpCode($status);
|
96 |
$response->setResponseHeaders($partHeaders);
|
97 |
$response->setResponseBody($partBody);
|
98 |
-
$response =
|
99 |
|
100 |
// Need content id.
|
101 |
$responses[$metaHeaders['content-id']] = $response;
|
18 |
/**
|
19 |
* @author Chirag Shah <chirags@google.com>
|
20 |
*/
|
21 |
+
class Yoast_Google_BatchRequest {
|
22 |
/** @var string Multipart Boundary. */
|
23 |
private $boundary;
|
24 |
|
30 |
$this->boundary = str_replace('"', '', $boundary);
|
31 |
}
|
32 |
|
33 |
+
public function add(Yoast_Google_HttpRequest $request, $key = false) {
|
34 |
if (false == $key) {
|
35 |
$key = mt_rand();
|
36 |
}
|
41 |
public function execute() {
|
42 |
$body = '';
|
43 |
|
44 |
+
/** @var Yoast_Google_HttpRequest $req */
|
45 |
foreach($this->requests as $key => $req) {
|
46 |
$body .= "--{$this->boundary}\n";
|
47 |
$body .= $req->toBatchString($key) . "\n";
|
52 |
|
53 |
global $apiConfig;
|
54 |
$url = $apiConfig['basePath'] . '/batch';
|
55 |
+
$httpRequest = new Yoast_Google_HttpRequest($url, 'POST');
|
56 |
$httpRequest->setRequestHeaders(array(
|
57 |
'Content-Type' => 'multipart/mixed; boundary=' . $this->boundary));
|
58 |
|
59 |
$httpRequest->setPostBody($body);
|
60 |
+
$response = Yoast_Google_Client::$io->makeRequest($httpRequest);
|
61 |
|
62 |
$response = $this->parseResponse($response);
|
63 |
return $response;
|
64 |
}
|
65 |
|
66 |
+
public function parseResponse(Yoast_Google_HttpRequest $response) {
|
67 |
$contentType = $response->getResponseHeader('content-type');
|
68 |
$contentType = explode(';', $contentType);
|
69 |
$boundary = false;
|
84 |
$part = trim($part);
|
85 |
if (!empty($part)) {
|
86 |
list($metaHeaders, $part) = explode("\r\n\r\n", $part, 2);
|
87 |
+
$metaHeaders = Yoast_Google_CurlIO::parseResponseHeaders($metaHeaders);
|
88 |
|
89 |
$status = substr($part, 0, strpos($part, "\n"));
|
90 |
$status = explode(" ", $status);
|
91 |
$status = $status[1];
|
92 |
|
93 |
+
list($partHeaders, $partBody) = Yoast_Google_CurlIO::parseHttpResponse($part, false);
|
94 |
+
$response = new Yoast_Google_HttpRequest("");
|
95 |
$response->setResponseHttpCode($status);
|
96 |
$response->setResponseHeaders($partHeaders);
|
97 |
$response->setResponseBody($partBody);
|
98 |
+
$response = Yoast_Google_REST::decodeHttpResponse($response);
|
99 |
|
100 |
// Need content id.
|
101 |
$responses[$metaHeaders['content-id']] = $response;
|
admin/api-libs/google/service/Google_MediaFileUpload.php
CHANGED
@@ -19,7 +19,7 @@
|
|
19 |
* @author Chirag Shah <chirags@google.com>
|
20 |
*
|
21 |
*/
|
22 |
-
class
|
23 |
const UPLOAD_MEDIA_TYPE = 'media';
|
24 |
const UPLOAD_MULTIPART_TYPE = 'multipart';
|
25 |
const UPLOAD_RESUMABLE_TYPE = 'resumable';
|
@@ -209,7 +209,7 @@ class Google_MediaFileUpload {
|
|
209 |
}
|
210 |
|
211 |
|
212 |
-
public function nextChunk(
|
213 |
if (false == $this->resumeUri) {
|
214 |
$this->resumeUri = $this->getResumeUri($req);
|
215 |
}
|
@@ -226,37 +226,37 @@ class Google_MediaFileUpload {
|
|
226 |
'expect' => '',
|
227 |
);
|
228 |
|
229 |
-
$httpRequest = new
|
230 |
-
$response =
|
231 |
$code = $response->getResponseHttpCode();
|
232 |
if (308 == $code) {
|
233 |
$range = explode('-', $response->getResponseHeader('range'));
|
234 |
$this->progress = $range[1] + 1;
|
235 |
return false;
|
236 |
} else {
|
237 |
-
return
|
238 |
}
|
239 |
}
|
240 |
|
241 |
-
private function getResumeUri(
|
242 |
$result = null;
|
243 |
$body = $httpRequest->getPostBody();
|
244 |
if ($body) {
|
245 |
$httpRequest->setRequestHeaders(array(
|
246 |
'content-type' => 'application/json; charset=UTF-8',
|
247 |
-
'content-length' =>
|
248 |
'x-upload-content-type' => $this->mimeType,
|
249 |
'x-upload-content-length' => $this->size,
|
250 |
'expect' => '',
|
251 |
));
|
252 |
}
|
253 |
|
254 |
-
$response =
|
255 |
$location = $response->getResponseHeader('location');
|
256 |
$code = $response->getResponseHttpCode();
|
257 |
if (200 == $code && true == $location) {
|
258 |
return $location;
|
259 |
}
|
260 |
-
throw new
|
261 |
}
|
262 |
}
|
19 |
* @author Chirag Shah <chirags@google.com>
|
20 |
*
|
21 |
*/
|
22 |
+
class Yoast_Google_MediaFileUpload {
|
23 |
const UPLOAD_MEDIA_TYPE = 'media';
|
24 |
const UPLOAD_MULTIPART_TYPE = 'multipart';
|
25 |
const UPLOAD_RESUMABLE_TYPE = 'resumable';
|
209 |
}
|
210 |
|
211 |
|
212 |
+
public function nextChunk(Yoast_Google_HttpRequest $req, $chunk=false) {
|
213 |
if (false == $this->resumeUri) {
|
214 |
$this->resumeUri = $this->getResumeUri($req);
|
215 |
}
|
226 |
'expect' => '',
|
227 |
);
|
228 |
|
229 |
+
$httpRequest = new Yoast_Google_HttpRequest($this->resumeUri, 'PUT', $headers, $chunk);
|
230 |
+
$response = Yoast_Google_Client::$io->authenticatedRequest($httpRequest);
|
231 |
$code = $response->getResponseHttpCode();
|
232 |
if (308 == $code) {
|
233 |
$range = explode('-', $response->getResponseHeader('range'));
|
234 |
$this->progress = $range[1] + 1;
|
235 |
return false;
|
236 |
} else {
|
237 |
+
return Yoast_Google_REST::decodeHttpResponse($response);
|
238 |
}
|
239 |
}
|
240 |
|
241 |
+
private function getResumeUri(Yoast_Google_HttpRequest $httpRequest) {
|
242 |
$result = null;
|
243 |
$body = $httpRequest->getPostBody();
|
244 |
if ($body) {
|
245 |
$httpRequest->setRequestHeaders(array(
|
246 |
'content-type' => 'application/json; charset=UTF-8',
|
247 |
+
'content-length' => Yoast_Google_Utils::getStrLen($body),
|
248 |
'x-upload-content-type' => $this->mimeType,
|
249 |
'x-upload-content-length' => $this->size,
|
250 |
'expect' => '',
|
251 |
));
|
252 |
}
|
253 |
|
254 |
+
$response = Yoast_Google_Client::$io->makeRequest($httpRequest);
|
255 |
$location = $response->getResponseHeader('location');
|
256 |
$code = $response->getResponseHttpCode();
|
257 |
if (200 == $code && true == $location) {
|
258 |
return $location;
|
259 |
}
|
260 |
+
throw new Yoast_Google_Exception("Failed to start the resumable upload");
|
261 |
}
|
262 |
}
|
admin/api-libs/google/service/Google_Model.php
CHANGED
@@ -22,7 +22,7 @@
|
|
22 |
* @author Chirag Shah <chirags@google.com>
|
23 |
*
|
24 |
*/
|
25 |
-
class
|
26 |
public function __construct( /* polymorphic */ ) {
|
27 |
if (func_num_args() == 1 && is_array(func_get_arg(0))) {
|
28 |
// Initialize the model with the array's contents.
|
@@ -101,14 +101,14 @@ class Google_Model {
|
|
101 |
|
102 |
/**
|
103 |
* Verify if $obj is an array.
|
104 |
-
* @throws
|
105 |
* @param array $obj Items that should be validated.
|
106 |
* @param string $type Array items should be of this type.
|
107 |
* @param string $method Method expecting an array as an argument.
|
108 |
*/
|
109 |
public function assertIsArray($obj, $type, $method) {
|
110 |
if ($obj && !is_array($obj)) {
|
111 |
-
throw new
|
112 |
. " array containing items of type $type.");
|
113 |
}
|
114 |
}
|
22 |
* @author Chirag Shah <chirags@google.com>
|
23 |
*
|
24 |
*/
|
25 |
+
class Yoast_Google_Model {
|
26 |
public function __construct( /* polymorphic */ ) {
|
27 |
if (func_num_args() == 1 && is_array(func_get_arg(0))) {
|
28 |
// Initialize the model with the array's contents.
|
101 |
|
102 |
/**
|
103 |
* Verify if $obj is an array.
|
104 |
+
* @throws Yoast_Google_Exception Thrown if $obj isn't an array.
|
105 |
* @param array $obj Items that should be validated.
|
106 |
* @param string $type Array items should be of this type.
|
107 |
* @param string $method Method expecting an array as an argument.
|
108 |
*/
|
109 |
public function assertIsArray($obj, $type, $method) {
|
110 |
if ($obj && !is_array($obj)) {
|
111 |
+
throw new Yoast_Google_Exception("Incorrect parameter type passed to $method(), expected an"
|
112 |
. " array containing items of type $type.");
|
113 |
}
|
114 |
}
|
admin/api-libs/google/service/Google_Service.php
CHANGED
@@ -15,7 +15,7 @@
|
|
15 |
* limitations under the License.
|
16 |
*/
|
17 |
|
18 |
-
class
|
19 |
public $version;
|
20 |
public $servicePath;
|
21 |
public $resource;
|
15 |
* limitations under the License.
|
16 |
*/
|
17 |
|
18 |
+
class Yoast_Google_Service {
|
19 |
public $version;
|
20 |
public $servicePath;
|
21 |
public $resource;
|
admin/api-libs/google/service/Google_ServiceResource.php
CHANGED
@@ -24,7 +24,7 @@
|
|
24 |
* @author Chirag Shah <chirags@google.com>
|
25 |
*
|
26 |
*/
|
27 |
-
class
|
28 |
// Valid query parameters that work, but don't appear in discovery.
|
29 |
private $stackParameters = array(
|
30 |
'alt' => array('type' => 'string', 'location' => 'query'),
|
@@ -41,7 +41,7 @@ class Google_ServiceResource {
|
|
41 |
'mediaUpload' => array('type' => 'complex', 'location' => 'query'),
|
42 |
);
|
43 |
|
44 |
-
/** @var
|
45 |
private $service;
|
46 |
|
47 |
/** @var string $serviceName */
|
@@ -63,12 +63,12 @@ class Google_ServiceResource {
|
|
63 |
/**
|
64 |
* @param $name
|
65 |
* @param $arguments
|
66 |
-
* @return
|
67 |
-
* @throws
|
68 |
*/
|
69 |
public function __call($name, $arguments) {
|
70 |
if (! isset($this->methods[$name])) {
|
71 |
-
throw new
|
72 |
}
|
73 |
$method = $this->methods[$name];
|
74 |
$parameters = $arguments[0];
|
@@ -108,13 +108,13 @@ class Google_ServiceResource {
|
|
108 |
$method['parameters'] = array_merge($method['parameters'], $this->stackParameters);
|
109 |
foreach ($parameters as $key => $val) {
|
110 |
if ($key != 'postBody' && ! isset($method['parameters'][$key])) {
|
111 |
-
throw new
|
112 |
}
|
113 |
}
|
114 |
if (isset($method['parameters'])) {
|
115 |
foreach ($method['parameters'] as $paramName => $paramSpec) {
|
116 |
if (isset($paramSpec['required']) && $paramSpec['required'] && ! isset($parameters[$paramName])) {
|
117 |
-
throw new
|
118 |
}
|
119 |
if (isset($parameters[$paramName])) {
|
120 |
$value = $parameters[$paramName];
|
@@ -142,7 +142,7 @@ class Google_ServiceResource {
|
|
142 |
// Process Media Request
|
143 |
$contentType = false;
|
144 |
if (isset($method['mediaUpload'])) {
|
145 |
-
$media =
|
146 |
if ($media) {
|
147 |
$contentType = isset($media['content-type']) ? $media['content-type']: null;
|
148 |
$postBody = isset($media['postBody']) ? $media['postBody'] : null;
|
@@ -151,27 +151,27 @@ class Google_ServiceResource {
|
|
151 |
}
|
152 |
}
|
153 |
|
154 |
-
$url =
|
155 |
-
$httpRequest = new
|
156 |
if ($postBody) {
|
157 |
$contentTypeHeader = array();
|
158 |
if (isset($contentType) && $contentType) {
|
159 |
$contentTypeHeader['content-type'] = $contentType;
|
160 |
} else {
|
161 |
$contentTypeHeader['content-type'] = 'application/json; charset=UTF-8';
|
162 |
-
$contentTypeHeader['content-length'] =
|
163 |
}
|
164 |
$httpRequest->setRequestHeaders($contentTypeHeader);
|
165 |
}
|
166 |
|
167 |
-
$httpRequest =
|
168 |
-
if (
|
169 |
return $httpRequest;
|
170 |
}
|
171 |
|
172 |
// Terminate immediately if this is a resumable request.
|
173 |
if (isset($parameters['uploadType']['value'])
|
174 |
-
&&
|
175 |
$contentTypeHeader = array();
|
176 |
if (isset($contentType) && $contentType) {
|
177 |
$contentTypeHeader['content-type'] = $contentType;
|
@@ -183,7 +183,7 @@ class Google_ServiceResource {
|
|
183 |
return $httpRequest;
|
184 |
}
|
185 |
|
186 |
-
return
|
187 |
}
|
188 |
|
189 |
public function useObjects() {
|
24 |
* @author Chirag Shah <chirags@google.com>
|
25 |
*
|
26 |
*/
|
27 |
+
class Yoast_Google_ServiceResource {
|
28 |
// Valid query parameters that work, but don't appear in discovery.
|
29 |
private $stackParameters = array(
|
30 |
'alt' => array('type' => 'string', 'location' => 'query'),
|
41 |
'mediaUpload' => array('type' => 'complex', 'location' => 'query'),
|
42 |
);
|
43 |
|
44 |
+
/** @var Yoast_Google_Service $service */
|
45 |
private $service;
|
46 |
|
47 |
/** @var string $serviceName */
|
63 |
/**
|
64 |
* @param $name
|
65 |
* @param $arguments
|
66 |
+
* @return Yoast_Google_HttpRequest|array
|
67 |
+
* @throws Yoast_Google_Exception
|
68 |
*/
|
69 |
public function __call($name, $arguments) {
|
70 |
if (! isset($this->methods[$name])) {
|
71 |
+
throw new Yoast_Google_Exception("Unknown function: {$this->serviceName}->{$this->resourceName}->{$name}()");
|
72 |
}
|
73 |
$method = $this->methods[$name];
|
74 |
$parameters = $arguments[0];
|
108 |
$method['parameters'] = array_merge($method['parameters'], $this->stackParameters);
|
109 |
foreach ($parameters as $key => $val) {
|
110 |
if ($key != 'postBody' && ! isset($method['parameters'][$key])) {
|
111 |
+
throw new Yoast_Google_Exception("($name) unknown parameter: '$key'");
|
112 |
}
|
113 |
}
|
114 |
if (isset($method['parameters'])) {
|
115 |
foreach ($method['parameters'] as $paramName => $paramSpec) {
|
116 |
if (isset($paramSpec['required']) && $paramSpec['required'] && ! isset($parameters[$paramName])) {
|
117 |
+
throw new Yoast_Google_Exception("($name) missing required param: '$paramName'");
|
118 |
}
|
119 |
if (isset($parameters[$paramName])) {
|
120 |
$value = $parameters[$paramName];
|
142 |
// Process Media Request
|
143 |
$contentType = false;
|
144 |
if (isset($method['mediaUpload'])) {
|
145 |
+
$media = Yoast_Google_MediaFileUpload::process($postBody, $parameters);
|
146 |
if ($media) {
|
147 |
$contentType = isset($media['content-type']) ? $media['content-type']: null;
|
148 |
$postBody = isset($media['postBody']) ? $media['postBody'] : null;
|
151 |
}
|
152 |
}
|
153 |
|
154 |
+
$url = Yoast_Google_REST::createRequestUri($servicePath, $method['path'], $parameters);
|
155 |
+
$httpRequest = new Yoast_Google_HttpRequest($url, $method['httpMethod'], null, $postBody);
|
156 |
if ($postBody) {
|
157 |
$contentTypeHeader = array();
|
158 |
if (isset($contentType) && $contentType) {
|
159 |
$contentTypeHeader['content-type'] = $contentType;
|
160 |
} else {
|
161 |
$contentTypeHeader['content-type'] = 'application/json; charset=UTF-8';
|
162 |
+
$contentTypeHeader['content-length'] = Yoast_Google_Utils::getStrLen($postBody);
|
163 |
}
|
164 |
$httpRequest->setRequestHeaders($contentTypeHeader);
|
165 |
}
|
166 |
|
167 |
+
$httpRequest = Yoast_Google_Client::$auth->sign($httpRequest);
|
168 |
+
if (Yoast_Google_Client::$useBatch) {
|
169 |
return $httpRequest;
|
170 |
}
|
171 |
|
172 |
// Terminate immediately if this is a resumable request.
|
173 |
if (isset($parameters['uploadType']['value'])
|
174 |
+
&& Yoast_Google_MediaFileUpload::UPLOAD_RESUMABLE_TYPE == $parameters['uploadType']['value']) {
|
175 |
$contentTypeHeader = array();
|
176 |
if (isset($contentType) && $contentType) {
|
177 |
$contentTypeHeader['content-type'] = $contentType;
|
183 |
return $httpRequest;
|
184 |
}
|
185 |
|
186 |
+
return Yoast_Google_REST::execute($httpRequest);
|
187 |
}
|
188 |
|
189 |
public function useObjects() {
|
admin/api-libs/google/service/Google_Utils.php
CHANGED
@@ -21,7 +21,7 @@
|
|
21 |
*
|
22 |
* @author Chirag Shah <chirags@google.com>
|
23 |
*/
|
24 |
-
class
|
25 |
public static function urlSafeB64Encode($data) {
|
26 |
$b64 = base64_encode($data);
|
27 |
$b64 = str_replace(array('+', '/', '\r', '\n', '='),
|
21 |
*
|
22 |
* @author Chirag Shah <chirags@google.com>
|
23 |
*/
|
24 |
+
class Yoast_Google_Utils {
|
25 |
public static function urlSafeB64Encode($data) {
|
26 |
$b64 = base64_encode($data);
|
27 |
$b64 = str_replace(array('+', '/', '\r', '\n', '='),
|
admin/api-libs/googleanalytics/class-api-googleanalytics.php
CHANGED
@@ -14,19 +14,32 @@ if ( ! class_exists( 'Yoast_Api_Googleanalytics' ) ) {
|
|
14 |
}
|
15 |
|
16 |
/**
|
17 |
-
* Autoload the Oauth classes
|
18 |
*/
|
19 |
private function load_api_oauth_files() {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
20 |
$oauth_files = array(
|
21 |
-
'
|
22 |
'yoast_google_analytics_client' => 'class-google-analytics-client',
|
23 |
);
|
24 |
|
25 |
-
|
26 |
-
if ( file_exists(
|
27 |
-
require_once(
|
28 |
}
|
|
|
29 |
}
|
|
|
30 |
}
|
31 |
|
32 |
}
|
14 |
}
|
15 |
|
16 |
/**
|
17 |
+
* Register the Autoload the Oauth classes
|
18 |
*/
|
19 |
private function load_api_oauth_files() {
|
20 |
+
spl_autoload_register( array( $this, 'autoload_api_oauth_files' ) );
|
21 |
+
}
|
22 |
+
|
23 |
+
/**
|
24 |
+
* Autoload the API Oauth classes
|
25 |
+
*
|
26 |
+
* @param string $class_name - The class that should be loaded
|
27 |
+
*/
|
28 |
+
private function autoload_api_oauth_files( $class_name ) {
|
29 |
+
$path = dirname( __FILE__ );
|
30 |
+
$class_name = strtolower( $class_name );
|
31 |
$oauth_files = array(
|
32 |
+
'yoast_googleanalytics_reporting' => 'class-googleanalytics-reporting',
|
33 |
'yoast_google_analytics_client' => 'class-google-analytics-client',
|
34 |
);
|
35 |
|
36 |
+
if ( ! empty( $oauth_files[$class_name] ) ) {
|
37 |
+
if ( file_exists( $path . '/' . $oauth_files[$class_name] . '.php' ) ) {
|
38 |
+
require_once( $path . '/' . $oauth_files[$class_name] . '.php' );
|
39 |
}
|
40 |
+
|
41 |
}
|
42 |
+
|
43 |
}
|
44 |
|
45 |
}
|
admin/api-libs/googleanalytics/class-google-analytics-client.php
CHANGED
@@ -1,10 +1,6 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
|
4 |
-
require_once( WPSEO_PREMIUM_PATH . 'classes/google/Google_Client.php' );
|
5 |
-
}
|
6 |
-
|
7 |
-
class Yoast_Google_Analytics_Client extends Google_Client {
|
8 |
|
9 |
protected $http_response_code;
|
10 |
|
@@ -122,7 +118,7 @@ class Yoast_Google_Analytics_Client extends Google_Client {
|
|
122 |
}
|
123 |
|
124 |
}
|
125 |
-
} catch (
|
126 |
return false;
|
127 |
}
|
128 |
}
|
@@ -137,7 +133,7 @@ class Yoast_Google_Analytics_Client extends Google_Client {
|
|
137 |
|
138 |
public function do_request( $target_request_url ) {
|
139 |
// Do list sites request
|
140 |
-
$request = new
|
141 |
|
142 |
// Get list sites response
|
143 |
$response = $this->getIo()->authenticatedRequest( $request );
|
1 |
<?php
|
2 |
|
3 |
+
class Yoast_Google_Analytics_Client extends Yoast_Google_Client {
|
|
|
|
|
|
|
|
|
4 |
|
5 |
protected $http_response_code;
|
6 |
|
118 |
}
|
119 |
|
120 |
}
|
121 |
+
} catch ( Yoast_Google_AuthException $exception ) {
|
122 |
return false;
|
123 |
}
|
124 |
}
|
133 |
|
134 |
public function do_request( $target_request_url ) {
|
135 |
// Do list sites request
|
136 |
+
$request = new Yoast_Google_HttpRequest( $target_request_url );
|
137 |
|
138 |
// Get list sites response
|
139 |
$response = $this->getIo()->authenticatedRequest( $request );
|
admin/class-admin.php
CHANGED
@@ -47,8 +47,17 @@ if ( ! class_exists( 'Yoast_GA_Admin' ) ) {
|
|
47 |
add_action( 'admin_notices', array( $this, 'config_warning' ) );
|
48 |
}
|
49 |
|
50 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
51 |
|
|
|
52 |
if ( ! function_exists( 'wp_verify_nonce' ) ) {
|
53 |
require_once( ABSPATH . 'wp-includes/pluggable.php' );
|
54 |
}
|
@@ -80,6 +89,13 @@ if ( ! class_exists( 'Yoast_GA_Admin' ) ) {
|
|
80 |
echo '<div class="error"><p>' . sprintf( __( 'Please configure your %sGoogle Analytics settings%s!', 'google-analytics-for-wordpress' ), '<a href="' . admin_url( 'admin.php?page=yst_ga_settings' ) . '">', '</a>' ) . '</p></div>';
|
81 |
}
|
82 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
83 |
/**
|
84 |
* This function saves the settings in the option field and returns a wp success message on success
|
85 |
*
|
@@ -131,6 +147,20 @@ if ( ! class_exists( 'Yoast_GA_Admin' ) ) {
|
|
131 |
exit;
|
132 |
}
|
133 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
134 |
/**
|
135 |
* Transform the Profile ID into an helpful UA code
|
136 |
*
|
@@ -143,7 +173,7 @@ if ( ! class_exists( 'Yoast_GA_Admin' ) ) {
|
|
143 |
$ua_code = null;
|
144 |
|
145 |
foreach ( $profiles as $profile ) {
|
146 |
-
foreach( $profile['profiles'] as $subprofile ) {
|
147 |
if ( isset( $subprofile['id'] ) && $subprofile['id'] == $profile_id ) {
|
148 |
$ua_code = $subprofile['ua_code'];
|
149 |
}
|
47 |
add_action( 'admin_notices', array( $this, 'config_warning' ) );
|
48 |
}
|
49 |
|
50 |
+
$last_run = get_transient( 'yst_ga_last_wp_run' );
|
51 |
+
if ( $last_run === false || Yoast_GA_Utils::hours_between( strtotime( $last_run ), time() ) >= 48 ) {
|
52 |
+
// Show error, something went wrong
|
53 |
+
if ( ! is_null( $this->get_tracking_code() ) ) {
|
54 |
+
if ( ! isset( $_GET['page'] ) || ( isset( $_GET['page'] ) && $_GET['page'] !== 'yst_ga_settings' ) ) {
|
55 |
+
add_action( 'admin_notices', array( $this, 'warning_fetching_data' ) );
|
56 |
+
}
|
57 |
+
}
|
58 |
+
}
|
59 |
|
60 |
+
if ( $_SERVER['REQUEST_METHOD'] == 'POST' ) {
|
61 |
if ( ! function_exists( 'wp_verify_nonce' ) ) {
|
62 |
require_once( ABSPATH . 'wp-includes/pluggable.php' );
|
63 |
}
|
89 |
echo '<div class="error"><p>' . sprintf( __( 'Please configure your %sGoogle Analytics settings%s!', 'google-analytics-for-wordpress' ), '<a href="' . admin_url( 'admin.php?page=yst_ga_settings' ) . '">', '</a>' ) . '</p></div>';
|
90 |
}
|
91 |
|
92 |
+
/**
|
93 |
+
* Throw a warning when the fetching failed
|
94 |
+
*/
|
95 |
+
public function warning_fetching_data() {
|
96 |
+
echo '<div class="error"><p>' . sprintf( __( 'Failed to fetch the new data from Google Analytics. Please %sreauthenticate on the settings page%s!', 'google-analytics-for-wordpress' ), '<a href="' . admin_url( 'admin.php?page=yst_ga_settings' ) . '">', '</a>' ) . '</p></div>';
|
97 |
+
}
|
98 |
+
|
99 |
/**
|
100 |
* This function saves the settings in the option field and returns a wp success message on success
|
101 |
*
|
147 |
exit;
|
148 |
}
|
149 |
|
150 |
+
/**
|
151 |
+
* Run a this deactivation hook on deactivation of GA. When this happens we'll
|
152 |
+
* remove the options for the profiles and the refresh token.
|
153 |
+
*/
|
154 |
+
public static function ga_deactivation_hook() {
|
155 |
+
// Remove the refresh token
|
156 |
+
delete_option( 'yoast-ga-refresh_token' );
|
157 |
+
|
158 |
+
// Remove the ga accounts and response
|
159 |
+
delete_option( 'yst_ga_accounts' );
|
160 |
+
delete_option( 'yst_ga_response' );
|
161 |
+
|
162 |
+
}
|
163 |
+
|
164 |
/**
|
165 |
* Transform the Profile ID into an helpful UA code
|
166 |
*
|
173 |
$ua_code = null;
|
174 |
|
175 |
foreach ( $profiles as $profile ) {
|
176 |
+
foreach ( $profile['profiles'] as $subprofile ) {
|
177 |
if ( isset( $subprofile['id'] ) && $subprofile['id'] == $profile_id ) {
|
178 |
$ua_code = $subprofile['ua_code'];
|
179 |
}
|
admin/dashboards/class-admin-dashboards-collector.php
CHANGED
@@ -98,7 +98,7 @@ if ( ! class_exists( 'Yoast_GA_Dashboards_Collector' ) ) {
|
|
98 |
add_action( 'yst_ga_aggregate_data', array( $this, 'aggregate_data' ) );
|
99 |
|
100 |
// Check if the WP cron did run on time
|
101 |
-
if ( isset( $_GET['page'] ) && $_GET['page'] === 'yst_ga_dashboard' ) {
|
102 |
add_action( 'shutdown', array( $this, 'check_api_call_hook' ) );
|
103 |
}
|
104 |
}
|
@@ -116,8 +116,8 @@ if ( ! class_exists( 'Yoast_GA_Dashboards_Collector' ) ) {
|
|
116 |
/**
|
117 |
* Check if the WP cron did run yesterday. If not, we need to run it form here
|
118 |
*/
|
119 |
-
public function check_api_call_hook() {
|
120 |
-
$last_run =
|
121 |
|
122 |
if ( $last_run === false ) {
|
123 |
/**
|
@@ -128,25 +128,20 @@ if ( ! class_exists( 'Yoast_GA_Dashboards_Collector' ) ) {
|
|
128 |
$this->aggregate_data();
|
129 |
} else {
|
130 |
// Transient exists
|
131 |
-
if (
|
132 |
$this->aggregate_data();
|
133 |
}
|
134 |
}
|
135 |
}
|
136 |
|
|
|
137 |
/**
|
138 |
-
*
|
139 |
-
*
|
140 |
-
* @param $last_run datetime
|
141 |
-
* @param $now datetime
|
142 |
*
|
143 |
-
* @return
|
144 |
*/
|
145 |
-
private function
|
146 |
-
|
147 |
-
$hours = $seconds / 3600;
|
148 |
-
|
149 |
-
return floor( $hours );
|
150 |
}
|
151 |
|
152 |
/**
|
@@ -399,11 +394,11 @@ if ( ! class_exists( 'Yoast_GA_Dashboards_Collector' ) ) {
|
|
399 |
if ( $storage_name != 'auto' ) {
|
400 |
$name = $storage_name;
|
401 |
}
|
402 |
-
|
403 |
/**
|
404 |
* Success, set a transient which stores the latest runtime
|
405 |
*/
|
406 |
-
if ( ! empty($response
|
407 |
set_transient( 'yst_ga_last_wp_run', date( 'Y-m-d' ), 48 * HOUR_IN_SECONDS );
|
408 |
}
|
409 |
|
98 |
add_action( 'yst_ga_aggregate_data', array( $this, 'aggregate_data' ) );
|
99 |
|
100 |
// Check if the WP cron did run on time
|
101 |
+
if ( isset( $_GET['page'] ) && ( $_GET['page'] === 'yst_ga_dashboard' || $_GET['page'] === 'yst_ga_settings' ) ) {
|
102 |
add_action( 'shutdown', array( $this, 'check_api_call_hook' ) );
|
103 |
}
|
104 |
}
|
116 |
/**
|
117 |
* Check if the WP cron did run yesterday. If not, we need to run it form here
|
118 |
*/
|
119 |
+
public function check_api_call_hook( ) {
|
120 |
+
$last_run = $this->get_last_aggregate_run();
|
121 |
|
122 |
if ( $last_run === false ) {
|
123 |
/**
|
128 |
$this->aggregate_data();
|
129 |
} else {
|
130 |
// Transient exists
|
131 |
+
if ( Yoast_GA_Utils::hours_between( strtotime( $last_run ), time() ) >= 24 ) {
|
132 |
$this->aggregate_data();
|
133 |
}
|
134 |
}
|
135 |
}
|
136 |
|
137 |
+
|
138 |
/**
|
139 |
+
* Get the datetime when the aggregate data function was succesful
|
|
|
|
|
|
|
140 |
*
|
141 |
+
* @return datetime
|
142 |
*/
|
143 |
+
private function get_last_aggregate_run() {
|
144 |
+
return get_transient( 'yst_ga_last_wp_run' );
|
|
|
|
|
|
|
145 |
}
|
146 |
|
147 |
/**
|
394 |
if ( $storage_name != 'auto' ) {
|
395 |
$name = $storage_name;
|
396 |
}
|
397 |
+
|
398 |
/**
|
399 |
* Success, set a transient which stores the latest runtime
|
400 |
*/
|
401 |
+
if ( ! empty( $response ) ) {
|
402 |
set_transient( 'yst_ga_last_wp_run', date( 'Y-m-d' ), 48 * HOUR_IN_SECONDS );
|
403 |
}
|
404 |
|
googleanalytics.php
CHANGED
@@ -4,7 +4,7 @@ Plugin Name: Google Analytics by Yoast
|
|
4 |
Plugin URI: https://yoast.com/wordpress/plugins/google-analytics/#utm_source=wordpress&utm_medium=plugin&utm_campaign=wpgaplugin&utm_content=v504
|
5 |
Description: This plugin makes it simple to add Google Analytics to your WordPress blog, adding lots of features, eg. error page, search result and automatic clickout and download tracking.
|
6 |
Author: Team Yoast
|
7 |
-
Version: 5.2.
|
8 |
Requires at least: 3.8
|
9 |
Author URI: https://yoast.com/
|
10 |
License: GPL v3
|
@@ -30,7 +30,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
30 |
|
31 |
// This plugin was originally based on Rich Boakes' Analytics plugin: http://boakes.org/analytics, but has since been rewritten and refactored multiple times.
|
32 |
|
33 |
-
define( 'GAWP_VERSION', '5.2.
|
34 |
|
35 |
define( 'GAWP_FILE', __FILE__ );
|
36 |
|
@@ -51,3 +51,5 @@ if ( is_admin() ) {
|
|
51 |
global $yoast_ga_frontend;
|
52 |
$yoast_ga_frontend = new Yoast_GA_Frontend;
|
53 |
}
|
|
|
|
4 |
Plugin URI: https://yoast.com/wordpress/plugins/google-analytics/#utm_source=wordpress&utm_medium=plugin&utm_campaign=wpgaplugin&utm_content=v504
|
5 |
Description: This plugin makes it simple to add Google Analytics to your WordPress blog, adding lots of features, eg. error page, search result and automatic clickout and download tracking.
|
6 |
Author: Team Yoast
|
7 |
+
Version: 5.2.6
|
8 |
Requires at least: 3.8
|
9 |
Author URI: https://yoast.com/
|
10 |
License: GPL v3
|
30 |
|
31 |
// This plugin was originally based on Rich Boakes' Analytics plugin: http://boakes.org/analytics, but has since been rewritten and refactored multiple times.
|
32 |
|
33 |
+
define( 'GAWP_VERSION', '5.2.6' );
|
34 |
|
35 |
define( 'GAWP_FILE', __FILE__ );
|
36 |
|
51 |
global $yoast_ga_frontend;
|
52 |
$yoast_ga_frontend = new Yoast_GA_Frontend;
|
53 |
}
|
54 |
+
|
55 |
+
register_deactivation_hook( __FILE__, array( 'Yoast_GA_Admin', 'ga_deactivation_hook' ) );
|
includes/class-utils.php
CHANGED
@@ -19,5 +19,20 @@ if ( ! class_exists( 'Yoast_GA_Utils' ) ) {
|
|
19 |
}
|
20 |
return $wp_seo_active;
|
21 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
22 |
}
|
23 |
}
|
19 |
}
|
20 |
return $wp_seo_active;
|
21 |
}
|
22 |
+
|
23 |
+
/**
|
24 |
+
* Calculate the date difference, return the amount of hours between the two dates
|
25 |
+
*
|
26 |
+
* @param $last_run datetime
|
27 |
+
* @param $now datetime
|
28 |
+
*
|
29 |
+
* @return int
|
30 |
+
*/
|
31 |
+
public static function hours_between( $last_run, $now ) {
|
32 |
+
$seconds = max( ( $now - $last_run ), 1 );
|
33 |
+
$hours = $seconds / 3600;
|
34 |
+
|
35 |
+
return floor( $hours );
|
36 |
+
}
|
37 |
}
|
38 |
}
|
readme.txt
CHANGED
@@ -1,10 +1,10 @@
|
|
1 |
-
|
2 |
Contributors: joostdevalk,PvW_NL
|
3 |
Donate link: https://yoast.com/donate/
|
4 |
Tags: analytics, google analytics, statistics, tracking, stats, google, yoast
|
5 |
Requires at least: 3.8
|
6 |
Tested up to: 4.1
|
7 |
-
Stable tag: 5.2.
|
8 |
|
9 |
Track your WordPress site easily with the latest tracking codes and lots added data for search result pages and error pages.
|
10 |
|
@@ -49,6 +49,28 @@ This section describes how to install the plugin and get it working.
|
|
49 |
|
50 |
== Changelog ==
|
51 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
52 |
= 5.2.4 =
|
53 |
|
54 |
Release Date: December 15th, 2014
|
@@ -57,7 +79,7 @@ Release Date: December 15th, 2014
|
|
57 |
* Moved from OAuth1 to OAuth2 for Google Analytics API requests.
|
58 |
* Open authentication and reauthentication for Google in a new window.
|
59 |
* Force reloading of CSS and JS on version change of plugin.
|
60 |
-
*
|
61 |
|
62 |
= 5.2.3 =
|
63 |
|
1 |
+
=== Google Analytics by Yoast ===
|
2 |
Contributors: joostdevalk,PvW_NL
|
3 |
Donate link: https://yoast.com/donate/
|
4 |
Tags: analytics, google analytics, statistics, tracking, stats, google, yoast
|
5 |
Requires at least: 3.8
|
6 |
Tested up to: 4.1
|
7 |
+
Stable tag: 5.2.6
|
8 |
|
9 |
Track your WordPress site easily with the latest tracking codes and lots added data for search result pages and error pages.
|
10 |
|
49 |
|
50 |
== Changelog ==
|
51 |
|
52 |
+
= 5.2.6 =
|
53 |
+
|
54 |
+
Release Date: December 16th, 2014
|
55 |
+
|
56 |
+
* Hotfix:
|
57 |
+
* Fixing API library to prevent fatal error.
|
58 |
+
|
59 |
+
* Bugfixes:
|
60 |
+
* Fixes the way of getting data from the Google API. cURL was used, but is changed into core wp_remote functionality to prevent errors when cURL isn't enabled.
|
61 |
+
|
62 |
+
= 5.2.5 =
|
63 |
+
|
64 |
+
Release Date: December 16th, 2014
|
65 |
+
|
66 |
+
* Enhancements:
|
67 |
+
* When deactivating the plugin the options with API-details will be cleared.
|
68 |
+
* Show notice when the plugin isn't able to fetch data from Google for more than 48 hours.
|
69 |
+
|
70 |
+
* Bugfixes:
|
71 |
+
* Fixes the way of getting data from the Google API. cURL was used, but is changed into core wp_remote functionality to prevent errors when cURL isn't enabled.
|
72 |
+
* Using autoloader for Google OAuth libraries instead of require them immediately to prevent conflicts with already loaded files.
|
73 |
+
|
74 |
= 5.2.4 =
|
75 |
|
76 |
Release Date: December 15th, 2014
|
79 |
* Moved from OAuth1 to OAuth2 for Google Analytics API requests.
|
80 |
* Open authentication and reauthentication for Google in a new window.
|
81 |
* Force reloading of CSS and JS on version change of plugin.
|
82 |
+
* Refactoring fetching profiles from Google Analytics
|
83 |
|
84 |
= 5.2.3 =
|
85 |
|