Google Analytics for WordPress by MonsterInsights - Version 5.2.6

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 Icon 128x128 Google Analytics for WordPress by MonsterInsights
Version 5.2.6
Comparing to
See all releases

Code changes from version 5.2.4 to 5.2.6

Files changed (37) hide show
  1. admin/api-libs/google/Google_Client.php +25 -39
  2. admin/api-libs/google/auth/Google_AssertionCredentials.php +6 -6
  3. admin/api-libs/google/auth/Google_Auth.php +2 -5
  4. admin/api-libs/google/auth/Google_AuthNone.php +2 -2
  5. admin/api-libs/google/auth/Google_LoginTicket.php +3 -3
  6. admin/api-libs/google/auth/Google_OAuth2.php +41 -45
  7. admin/api-libs/google/auth/Google_P12Signer.php +6 -6
  8. admin/api-libs/google/auth/Google_PemVerifier.php +7 -7
  9. admin/api-libs/google/auth/Google_Signer.php +1 -3
  10. admin/api-libs/google/auth/Google_Verifier.php +1 -3
  11. admin/api-libs/google/cache/Google_ApcCache.php +3 -3
  12. admin/api-libs/google/cache/Google_Cache.php +1 -4
  13. admin/api-libs/google/cache/Google_FileCache.php +5 -5
  14. admin/api-libs/google/cache/Google_MemcacheCache.php +6 -6
  15. admin/api-libs/google/cache/Google_WPCache.php +53 -0
  16. admin/api-libs/google/class-api-google.php +62 -3
  17. admin/api-libs/google/config.php +3 -3
  18. admin/api-libs/google/io/Google_CacheParser.php +9 -9
  19. admin/api-libs/google/io/Google_CurlIO.php +12 -14
  20. admin/api-libs/google/io/Google_HttpRequest.php +3 -3
  21. admin/api-libs/google/io/Google_HttpStreamIO.php +12 -14
  22. admin/api-libs/google/io/Google_IO.php +23 -28
  23. admin/api-libs/google/io/Google_REST.php +9 -9
  24. admin/api-libs/google/io/Google_WPIO.php +122 -0
  25. admin/api-libs/google/service/Google_BatchRequest.php +10 -10
  26. admin/api-libs/google/service/Google_MediaFileUpload.php +9 -9
  27. admin/api-libs/google/service/Google_Model.php +3 -3
  28. admin/api-libs/google/service/Google_Service.php +1 -1
  29. admin/api-libs/google/service/Google_ServiceResource.php +15 -15
  30. admin/api-libs/google/service/Google_Utils.php +1 -1
  31. admin/api-libs/googleanalytics/class-api-googleanalytics.php +18 -5
  32. admin/api-libs/googleanalytics/class-google-analytics-client.php +3 -7
  33. admin/class-admin.php +32 -2
  34. admin/dashboards/class-admin-dashboards-collector.php +11 -16
  35. googleanalytics.php +4 -2
  36. includes/class-utils.php +15 -0
  37. 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
- $defaultConfig = $apiConfig;
39
- require_once (dirname(__FILE__) . '/local_config.php');
40
- $apiConfig = array_merge($defaultConfig, $apiConfig);
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 Google_Client {
65
  /**
66
  * @static
67
- * @var Google_Auth $auth
68
  */
69
  static $auth;
70
 
71
  /**
72
  * @static
73
- * @var Google_IO $io
74
  */
75
  static $io;
76
 
77
  /**
78
  * @static
79
- * @var Google_Cache $cache
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 Google_Exception('Cant add services after having authenticated');
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 Google_Client#getAccessToken().
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 Google_AuthException
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 Google_AuthException
329
  * @param string|null $token The token (id_token) that should be verified.
330
- * @return Google_LoginTicket Returns an apiLoginTicket if the verification was
331
  * successful.
332
  */
333
  public function verifyIdToken($token = null) {
@@ -335,10 +321,10 @@ class Google_Client {
335
  }
336
 
337
  /**
338
- * @param Google_AssertionCredentials $creds
339
  * @return void
340
  */
341
- public function setAssertionCredentials(Google_AssertionCredentials $creds) {
342
  self::$auth->setAssertionCredentials($creds);
343
  }
344
 
@@ -399,34 +385,34 @@ class Google_Client {
399
 
400
  /**
401
  * @static
402
- * @return Google_Auth the implementation of apiAuth.
403
  */
404
  public static function getAuth() {
405
- return Google_Client::$auth;
406
  }
407
 
408
  /**
409
  * @static
410
- * @return Google_IO the implementation of apiIo.
411
  */
412
  public static function getIo() {
413
- return Google_Client::$io;
414
  }
415
 
416
  /**
417
- * @return Google_Cache the implementation of apiCache.
418
  */
419
  public function getCache() {
420
- return Google_Client::$cache;
421
  }
422
  }
423
 
424
  // Exceptions that the Google PHP API Library can throw
425
- class Google_Exception extends Exception {}
426
- class Google_AuthException extends Google_Exception {}
427
- class Google_CacheException extends Google_Exception {}
428
- class Google_IOException extends Google_Exception {}
429
- class Google_ServiceException extends Google_Exception {
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 Google_AssertionCredentials {
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' => Google_OAuth2::OAUTH2_TOKEN_URI,
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
- Google_Utils::urlSafeB64Encode(json_encode($header)),
93
- Google_Utils::urlSafeB64Encode(json_encode($payload))
94
  );
95
 
96
  $signingInput = implode('.', $segments);
97
- $signer = new Google_P12Signer($this->privateKey, $this->privateKeyPassword);
98
  $signature = $signer->sign($signingInput);
99
- $segments[] = Google_Utils::urlSafeB64Encode($signature);
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 Google_Auth {
27
  abstract public function authenticate($service);
28
- abstract public function sign(Google_HttpRequest $request);
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 Google_AuthNone extends Google_Auth {
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(Google_HttpRequest $request) {
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 Google_LoginTicket {
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 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 Google_AuthException("No user_id in token");
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 Google_OAuth2 extends Google_Auth {
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 Google_AssertionCredentials $assertionCredentials */
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 Google_AuthException
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 = Google_Client::$io->makeRequest(new Google_HttpRequest(self::OAUTH2_TOKEN_URI, 'POST', array(), array(
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 Google_AuthException("Error fetching OAuth2 access token, message: '$response'", $request->getResponseHttpCode());
118
  }
119
  }
120
 
@@ -156,15 +152,15 @@ class Google_OAuth2 extends Google_Auth {
156
 
157
  /**
158
  * @param string $token
159
- * @throws Google_AuthException
160
  */
161
  public function setAccessToken($token) {
162
  $token = json_decode($token, true);
163
  if ($token == null) {
164
- throw new Google_AuthException('Could not json decode the token');
165
  }
166
  if (! isset($token['access_token'])) {
167
- throw new Google_AuthException("Invalid token format");
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(Google_AssertionCredentials $creds) {
193
  $this->assertionCredentials = $creds;
194
  }
195
 
196
  /**
197
  * Include an accessToken in a given apiHttpRequest.
198
- * @param Google_HttpRequest $request
199
- * @return Google_HttpRequest
200
- * @throws Google_AuthException
201
  */
202
- public function sign(Google_HttpRequest $request) {
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 Google_AuthException("The OAuth 2.0 access token has expired, "
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 Google_AssertionCredentials $assertionCredentials optional.
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 Google_HttpRequest(self::OAUTH2_TOKEN_URI, 'POST', array(), $params);
272
- $request = Google_Client::$io->makeRequest($http);
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 Google_AuthException("Could not json decode the access token");
280
  }
281
 
282
  if (! isset($token['access_token']) || ! isset($token['expires_in'])) {
283
- throw new Google_AuthException("Invalid token format");
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 Google_AuthException("Error refreshing the OAuth2 token, message: '$body'", $code);
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 Google_AuthException
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 Google_HttpRequest(self::OAUTH2_REVOKE_URI, 'POST', array(), "token=$token");
306
- $response = Google_Client::$io->makeRequest($request);
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 = Google_Client::$io->makeRequest(new Google_HttpRequest(
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 Google_AuthException(
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 Google_LoginTicket
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 Google_AuthException("Wrong number of segments in token: $jwt");
379
  }
380
  $signed = $segments[0] . "." . $segments[1];
381
- $signature = Google_Utils::urlSafeB64Decode($segments[2]);
382
 
383
  // Parse envelope.
384
- $envelope = json_decode(Google_Utils::urlSafeB64Decode($segments[0]), true);
385
  if (!$envelope) {
386
- throw new Google_AuthException("Can't parse token envelope: " . $segments[0]);
387
  }
388
 
389
  // Parse token
390
- $json_body = Google_Utils::urlSafeB64Decode($segments[1]);
391
  $payload = json_decode($json_body, true);
392
  if (!$payload) {
393
- throw new Google_AuthException("Can't parse token payload: " . $segments[1]);
394
  }
395
 
396
  // Check signature
397
  $verified = false;
398
  foreach ($certs as $keyName => $pem) {
399
- $public_key = new Google_PemVerifier($pem);
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 Google_AuthException("Invalid token signature: $jwt");
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 Google_AuthException("No issue time in token: $json_body");
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 Google_AuthException("No expiration time in token: $json_body");
428
  }
429
  if ($exp >= $now + self::MAX_TOKEN_LIFETIME_SECS) {
430
- throw new Google_AuthException(
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 Google_AuthException(
437
  "Token used too early, $now < $earliest: $json_body");
438
  }
439
  if ($now > $latest) {
440
- throw new Google_AuthException(
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 Google_AuthException("Wrong recipient, $aud != $required_audience: $json_body");
450
  }
451
 
452
  // All good.
453
- return new Google_LoginTicket($envelope, $payload);
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 Google_P12Signer extends Google_Signer {
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 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 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 Google_AuthException("Unable to load private key in ");
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 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 Google_AuthException("Unable to sign data");
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 Google_PemVerifier extends Google_Verifier {
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 Google_AuthException
32
- * @throws Google_Exception
33
  */
34
  function __construct($pem) {
35
  if (!function_exists('openssl_x509_read')) {
36
- throw new 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 Google_AuthException("Unable to parse PEM: $pem");
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 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 Google_AuthException('Signature verification error: ' . openssl_error_string());
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 Google_Signer {
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 Google_Verifier {
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 Google_APCCache extends Google_Cache {
27
 
28
  public function __construct() {
29
  if (! function_exists('apc_add')) {
30
- throw new Google_CacheException("Apc functions not available");
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 Google_CacheException("Couldn't store data");
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 Google_Cache {
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 Google_FileCache extends Google_Cache {
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 Google_CacheException("Could not create storage directory: $storageDir");
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 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,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 Google_CacheException("Could not store data in the file");
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 Google_CacheException("Cache file could not be deleted");
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 Google_MemcacheCache extends Google_Cache {
27
  private $connection = false;
28
 
29
  public function __construct() {
30
  global $apiConfig;
31
  if (! function_exists('memcache_connect')) {
32
- throw new 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 Google_CacheException("You need to supply a valid memcache host and port");
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 Google_CacheException("Couldn't connect to memcache server");
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 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 Google_CacheException("Couldn't store data in cache");
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 Oauth classes
18
  */
19
  private function load_api_google_files() {
20
- require_once( dirname( __FILE__ ) . '/Google_Client.php' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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' => 'Google_OAuth2',
40
- 'ioClass' => 'Google_CurlIO',
41
- 'cacheClass' => 'Google_FileCache',
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 Google_CacheParser {
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 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 (Google_HttpRequest $resp) {
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 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 (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,11 +105,11 @@ class Google_CacheParser {
105
 
106
  /**
107
  * @static
108
- * @param 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(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,10 +161,10 @@ class Google_CacheParser {
161
  /**
162
  * Determine if a cache entry should be revalidated with by the origin.
163
  *
164
- * @param Google_HttpRequest $response
165
  * @return bool True if the entry is expired, else return false.
166
  */
167
- public static function mustRevalidate(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.
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
- require_once 'Google_CacheParser.php';
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 Google_HttpRequest $request
59
- * @return Google_HttpRequest The resulting HTTP response including the
60
  * responseHttpCode, responseHeaders and responseBody.
61
  */
62
- public function authenticatedRequest(Google_HttpRequest $request) {
63
- $request = Google_Client::$auth->sign($request);
64
  return $this->makeRequest($request);
65
  }
66
 
67
  /**
68
  * Execute a apiHttpRequest
69
  *
70
- * @param Google_HttpRequest $request the http request to be executed
71
- * @return Google_HttpRequest http request with the response http code, response
72
  * headers and response body filled in
73
- * @throws Google_IOException on curl or IO error
74
  */
75
- public function makeRequest(Google_HttpRequest $request) {
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 Google_IOException("HTTP Error: ($respHttpCode) $curlError");
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
- private static function parseHttpResponse($respData, $headerSize) {
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
- private static function parseResponseHeaders($rawHeaders) {
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 Google_HttpRequest {
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 = Google_Utils::normalize($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 = Google_Utils::normalize($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 Google_IO.
20
  *
21
  * @author Stuart Langley <slangley@google.com>
22
  */
23
 
24
- require_once 'Google_CacheParser.php';
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 Google_HttpStreamIO::makeRequest on the signed request
44
  *
45
- * @param Google_HttpRequest $request
46
- * @return Google_HttpRequest The resulting HTTP response including the
47
  * responseHttpCode, responseHeaders and responseBody.
48
  */
49
- public function authenticatedRequest(Google_HttpRequest $request) {
50
- $request = Google_Client::$auth->sign($request);
51
  return $this->makeRequest($request);
52
  }
53
 
54
  /**
55
  * Execute a apiHttpRequest
56
  *
57
- * @param Google_HttpRequest $request the http request to be executed
58
- * @return Google_HttpRequest http request with the response http code,
59
  * response headers and response body filled in
60
- * @throws Google_IOException on curl or IO error
61
  */
62
- public function makeRequest(Google_HttpRequest $request) {
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 Google_IOException("HTTP Error: Unable to connect");
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 Google_IO {
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 Google_HttpRequest $request
35
- * @return Google_HttpRequest $request
36
  */
37
- abstract function authenticatedRequest(Google_HttpRequest $request);
38
 
39
  /**
40
  * Executes a apIHttpRequest and returns the resulting populated httpRequest
41
- * @param Google_HttpRequest $request
42
- * @return Google_HttpRequest $request
43
  */
44
- abstract function makeRequest(Google_HttpRequest $request);
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 Google_HttpRequest $request
56
  * @return bool Returns true if the insertion was successful.
57
  * Otherwise, return false.
58
  */
59
- protected function setCachedRequest(Google_HttpRequest $request) {
60
  // Determine if the request is cacheable.
61
- if (Google_CacheParser::isResponseCacheable($request)) {
62
- Google_Client::$cache->set($request->getCacheKey(), $request);
63
  return true;
64
  }
65
 
@@ -68,25 +63,25 @@ abstract class Google_IO {
68
 
69
  /**
70
  * @visible for testing.
71
- * @param Google_HttpRequest $request
72
- * @return Google_HttpRequest|bool Returns the cached object or
73
  * false if the operation was unsuccessful.
74
  */
75
- protected function getCachedRequest(Google_HttpRequest $request) {
76
- if (false == Google_CacheParser::isRequestCacheable($request)) {
77
  false;
78
  }
79
 
80
- return Google_Client::$cache->get($request->getCacheKey());
81
  }
82
 
83
  /**
84
  * @visible for testing
85
  * Process an http request that contains an enclosed entity.
86
- * @param Google_HttpRequest $request
87
- * @return Google_HttpRequest Processed request with the enclosed entity.
88
  */
89
- protected function processEntityRequest(Google_HttpRequest $request) {
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 Google_HttpRequest $cached A previously cached response.
118
- * @param Google_HttpRequest $request The outbound request.
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 (Google_CacheParser::mustRevalidate($cached)) {
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 Google_HttpRequest $cached A previously cached response.
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 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 Google_HttpRequest $req
30
  * @return array decoded result
31
- * @throws Google_ServiceException on server side error (ie: not authenticated,
32
  * invalid or malformed post body, invalid url)
33
  */
34
- static public function execute(Google_HttpRequest $req) {
35
- $httpRequest = Google_Client::$io->makeRequest($req);
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 Google_ServiceException
47
- * @param Google_HttpRequest $response The http response to be decoded.
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 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 Google_ServiceException("Invalid json in service response: $body");
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 Google_BatchRequest {
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(Google_HttpRequest $request, $key = false) {
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 Google_HttpRequest $req */
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 Google_HttpRequest($url, 'POST');
56
  $httpRequest->setRequestHeaders(array(
57
  'Content-Type' => 'multipart/mixed; boundary=' . $this->boundary));
58
 
59
  $httpRequest->setPostBody($body);
60
- $response = Google_Client::$io->makeRequest($httpRequest);
61
 
62
  $response = $this->parseResponse($response);
63
  return $response;
64
  }
65
 
66
- public function parseResponse(Google_HttpRequest $response) {
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 = 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) = Google_CurlIO::parseHttpResponse($part, false);
94
- $response = new Google_HttpRequest("");
95
  $response->setResponseHttpCode($status);
96
  $response->setResponseHeaders($partHeaders);
97
  $response->setResponseBody($partBody);
98
- $response = Google_REST::decodeHttpResponse($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 Google_MediaFileUpload {
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(Google_HttpRequest $req, $chunk=false) {
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 Google_HttpRequest($this->resumeUri, 'PUT', $headers, $chunk);
230
- $response = 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 Google_REST::decodeHttpResponse($response);
238
  }
239
  }
240
 
241
- private function getResumeUri(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' => 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 = 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 Google_Exception("Failed to start the resumable upload");
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 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,14 +101,14 @@ class Google_Model {
101
 
102
  /**
103
  * Verify if $obj is an array.
104
- * @throws 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 Google_Exception("Incorrect parameter type passed to $method(), expected an"
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 Google_Service {
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 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,7 +41,7 @@ class Google_ServiceResource {
41
  'mediaUpload' => array('type' => 'complex', 'location' => 'query'),
42
  );
43
 
44
- /** @var Google_Service $service */
45
  private $service;
46
 
47
  /** @var string $serviceName */
@@ -63,12 +63,12 @@ class Google_ServiceResource {
63
  /**
64
  * @param $name
65
  * @param $arguments
66
- * @return Google_HttpRequest|array
67
- * @throws Google_Exception
68
  */
69
  public function __call($name, $arguments) {
70
  if (! isset($this->methods[$name])) {
71
- throw new Google_Exception("Unknown function: {$this->serviceName}->{$this->resourceName}->{$name}()");
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 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 Google_Exception("($name) missing required param: '$paramName'");
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 = 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,27 +151,27 @@ class Google_ServiceResource {
151
  }
152
  }
153
 
154
- $url = Google_REST::createRequestUri($servicePath, $method['path'], $parameters);
155
- $httpRequest = new 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'] = Google_Utils::getStrLen($postBody);
163
  }
164
  $httpRequest->setRequestHeaders($contentTypeHeader);
165
  }
166
 
167
- $httpRequest = Google_Client::$auth->sign($httpRequest);
168
- if (Google_Client::$useBatch) {
169
  return $httpRequest;
170
  }
171
 
172
  // Terminate immediately if this is a resumable request.
173
  if (isset($parameters['uploadType']['value'])
174
- && Google_MediaFileUpload::UPLOAD_RESUMABLE_TYPE == $parameters['uploadType']['value']) {
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 Google_REST::execute($httpRequest);
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 Google_Utils {
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
- 'yoast_api_googleanalytics_reporting' => 'class-googleanalytics-reporting',
22
  'yoast_google_analytics_client' => 'class-google-analytics-client',
23
  );
24
 
25
- foreach ( $oauth_files as $key => $name ) {
26
- if ( file_exists( dirname( __FILE__ ) . '/' . $name . '.php' ) ) {
27
- require_once( dirname( __FILE__ ) . '/' . $name . '.php' );
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
- if ( ! class_exists( 'Google_Client' ) ) {
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 ( Google_AuthException $exception ) {
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 Google_HttpRequest( $target_request_url );
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
- if ( $_SERVER['REQUEST_METHOD'] == 'POST' ) {
 
 
 
 
 
 
 
 
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 = get_transient( 'yst_ga_last_wp_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 ( $this->hours_between( strtotime( $last_run ), time() ) >= 24 ) {
132
  $this->aggregate_data();
133
  }
134
  }
135
  }
136
 
 
137
  /**
138
- * Calculate the date difference, return the amount of hours between the two dates
139
- *
140
- * @param $last_run datetime
141
- * @param $now datetime
142
  *
143
- * @return int
144
  */
145
- private function hours_between( $last_run, $now ) {
146
- $seconds = max( ( $now - $last_run ), 1 );
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['body'] ) ) {
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.4
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.4' );
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
- === 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.4
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
- * Refactored fetching profiles from Google Analytics.
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