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 | |
| 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 |
|
