Google Analyticator - Version 6.3.3

Version Description

  • Using the admin_url() function for internal links. Should help people with WP installed in a sub directory.
  • Added all vars to reset function to delete / deauthorize from Google.
Download this release

Release Info

Developer VideoUserManuals
Plugin Icon 128x128 Google Analyticator
Version 6.3.3
Comparing to
See all releases

Code changes from version 6.2 to 6.3.3

Files changed (43) hide show
  1. class.analytics.stats.php +249 -360
  2. download-button.png +0 -0
  3. external-tracking.js +43 -43
  4. external-tracking.min.js +4 -4
  5. google-analyticator.php +1049 -1036
  6. google-analytics-stats-widget.php +254 -256
  7. google-analytics-summary-widget.php +617 -603
  8. google-api-php-client/src/Google_Client.php +465 -0
  9. google-api-php-client/src/auth/Google_AssertionCredentials.php +95 -0
  10. google-api-php-client/src/auth/Google_Auth.php +36 -0
  11. google-api-php-client/src/auth/Google_AuthNone.php +48 -0
  12. google-api-php-client/src/auth/Google_LoginTicket.php +63 -0
  13. google-api-php-client/src/auth/Google_OAuth2.php +444 -0
  14. google-api-php-client/src/auth/Google_P12Signer.php +66 -0
  15. google-api-php-client/src/auth/Google_PemVerifier.php +66 -0
  16. google-api-php-client/src/auth/Google_Signer.php +30 -0
  17. google-api-php-client/src/auth/Google_Verifier.php +31 -0
  18. google-api-php-client/src/cache/Google_ApcCache.php +98 -0
  19. google-api-php-client/src/cache/Google_Cache.php +55 -0
  20. google-api-php-client/src/cache/Google_FileCache.php +137 -0
  21. google-api-php-client/src/cache/Google_MemcacheCache.php +130 -0
  22. google-api-php-client/src/config.php +81 -0
  23. google-api-php-client/src/contrib/Google_AdsenseService.php +1144 -0
  24. google-api-php-client/src/contrib/Google_AnalyticsService.php +1887 -0
  25. google-api-php-client/src/contrib/Google_Oauth2Service.php +265 -0
  26. google-api-php-client/src/external/URITemplateParser.php +213 -0
  27. google-api-php-client/src/io/Google_CacheParser.php +173 -0
  28. google-api-php-client/src/io/Google_CurlIO.php +278 -0
  29. google-api-php-client/src/io/Google_HttpRequest.php +304 -0
  30. google-api-php-client/src/io/Google_IO.php +49 -0
  31. google-api-php-client/src/io/Google_REST.php +128 -0
  32. google-api-php-client/src/io/cacerts.pem +714 -0
  33. google-api-php-client/src/service/Google_BatchRequest.php +110 -0
  34. google-api-php-client/src/service/Google_MediaFileUpload.php +244 -0
  35. google-api-php-client/src/service/Google_Model.php +115 -0
  36. google-api-php-client/src/service/Google_Service.php +22 -0
  37. google-api-php-client/src/service/Google_ServiceResource.php +196 -0
  38. google-api-php-client/src/service/Google_Utils.php +117 -0
  39. google-api-php-client/static/Credentials.png +0 -0
  40. jquery.sparkline.min.js +84 -84
  41. privacy.png +0 -0
  42. readme.txt +40 -10
  43. wlcms-plugin-advert.png +0 -0
class.analytics.stats.php CHANGED
@@ -1,360 +1,249 @@
1
- <?php
2
-
3
- # Include SimplePie if it doesn't exist
4
- if ( !class_exists('SimplePie') ) {
5
- require_once (ABSPATH . WPINC . '/class-feed.php');
6
- }
7
-
8
- /**
9
- * Handles interactions with Google Analytics' Stat API
10
- *
11
- * @author Spiral Web Consulting
12
- **/
13
- class GoogleAnalyticsStats
14
- {
15
-
16
- # Class variables
17
- var $baseFeed = 'https://www.google.com/analytics/feeds';
18
- var $accountId;
19
- var $token = false;
20
- var $responseHash = array();
21
- var $responseCode = '';
22
-
23
- /**
24
- * Constructor
25
- *
26
- * @param token - a one-time use token to be exchanged for a real token
27
- **/
28
- function GoogleAnalyticsStats($token = false)
29
- {
30
- # If we need to request a permanent token
31
- if ( $token ) {
32
-
33
- # Check if we're deauthorizing an account
34
- if ( $token == 'deauth' ) {
35
-
36
- # Get the current token
37
- $this->token = get_option('ga_google_token');
38
-
39
- # Revoke the current token
40
- $response = $this->http('https://www.google.com/accounts/AuthSubRevokeToken');
41
-
42
- # Remove the current token
43
- update_option('ga_google_token', '');
44
-
45
- return '';
46
-
47
- }
48
-
49
- $this->token = $token;
50
-
51
- # Request authentication with Google
52
- $response = $this->http('https://www.google.com/accounts/AuthSubSessionToken');
53
-
54
- # Get the authentication token
55
- $this->token = substr(strstr($response, "Token="), 6);
56
-
57
- # Save the token for future use
58
- update_option('ga_google_token', $this->token);
59
-
60
- # Remove the old username and password fields if they still exists
61
- delete_option('google_stats_user');
62
- delete_option('google_stats_password');
63
-
64
- } else {
65
- $this->token = get_option('ga_google_token');
66
- }
67
- }
68
-
69
- /**
70
- * Connects using the WordPress HTTP API to get data
71
- *
72
- * @param url - url to request
73
- * @param post - post data to pass through WordPress
74
- * @return the raw http response
75
- **/
76
- function http($url, $post = false)
77
- {
78
- # Return false if the token has not been set
79
- if ( trim($this->token) == '' )
80
- return '';
81
-
82
- # Set the arguments to pass to WordPress
83
- $args = array(
84
- 'sslverify' => false
85
- );
86
-
87
- # Add the optional post values
88
- if ( $post ) {
89
- $post .= '&service=analytics&source=google-analyticator-' . GOOGLE_ANALYTICATOR_VERSION;
90
- $args['body'] = $post;
91
- }
92
-
93
- # Set the content to form data
94
- $args['headers'] = array('Content-Type' => 'application/x-www-form-urlencoded');
95
-
96
- # Add the token information
97
- if ( $this->token ) {
98
- $args['headers']['Authorization'] = 'AuthSub token="' . $this->token . '"';
99
- }
100
-
101
- # Disable the fopen transport since it doesn't work with the Google API
102
- add_filter('use_fopen_transport', create_function('$a', 'return false;'));
103
-
104
- # Check compatibility mode settings
105
- if ( get_option('ga_compatibility') == 'level1' ) {
106
- add_filter('use_curl_transport', create_function('$a', 'return false;'));
107
- } elseif ( get_option('ga_compatibility') == 'level2' ) {
108
- add_filter('use_curl_transport', create_function('$a', 'return false;'));
109
- add_filter('use_streams_transport', create_function('$a', 'return false;'));
110
- }
111
-
112
- # Make the connection
113
- if ( $post )
114
- $response = wp_remote_post($url, $args);
115
- else
116
- $response = wp_remote_get($url, $args);
117
-
118
- # Check for WordPress error
119
- if ( is_wp_error($response) ) {
120
- $this->responseHash['error'] = __('WordPress HTTP error.', 'google-analyticator');
121
- return '';
122
- }
123
-
124
- # Set the message response
125
- $this->responseCode = $response['response']['code'];
126
-
127
- # Build an array of messages
128
- foreach( explode("\n", $response['body']) as $line ) {
129
- if ( trim($line) != '' ) {
130
- $pos = strpos($line, '=');
131
- if ( $pos !== false ) {
132
- $this->responseHash[strtolower(substr($line, 0, $pos))] = substr($line, $pos+1);
133
- }
134
- }
135
- }
136
-
137
- # Return the body of the response
138
- return $response['body'];
139
- }
140
-
141
- /**
142
- * Checks if the username and password worked by looking at the token
143
- *
144
- * @return Boolean if the login details worked
145
- **/
146
- function checkLogin()
147
- {
148
- if ( $this->token != false )
149
- return true;
150
- else
151
- return false;
152
- }
153
-
154
- /**
155
- * Sets the account id to use for queries
156
- *
157
- * @param id - the account id
158
- **/
159
- function setAccount($id)
160
- {
161
- $this->accountId = $id;
162
- }
163
-
164
- /**
165
- * Get a list of Analytics accounts
166
- *
167
- * @return a list of analytics accounts
168
- **/
169
- function getAnalyticsAccounts()
170
- {
171
- # Request the list of accounts
172
- $response = $this->http($this->baseFeed . '/accounts/default');
173
-
174
- # Check if the response received exists, else stop processing now
175
- if ( $response == '' || $this->responseCode != '200' )
176
- return false;
177
-
178
- # Parse the XML using SimplePie
179
- $simplePie = new SimplePie();
180
- $simplePie->set_raw_data($response);
181
- $simplePie->init();
182
- $simplePie->handle_content_type();
183
- $accounts = $simplePie->get_items();
184
-
185
- # Make an array of the accounts
186
- $ids = array();
187
- foreach ( $accounts AS $account ) {
188
- $id = array();
189
-
190
- # Get the list of properties
191
- $properties = $account->get_item_tags('http://schemas.google.com/analytics/2009', 'property');
192
-
193
- # Loop through the properties
194
- foreach ( $properties AS $property ) {
195
-
196
- # Get the property information
197
- $name = $property['attribs']['']['name'];
198
- $value = $property['attribs']['']['value'];
199
-
200
- # Add the propery data to the id array
201
- $id[$name] = $value;
202
-
203
- }
204
-
205
- # Add the backward compatibility array items
206
- $id['title'] = $account->get_title();
207
- $id['id'] = 'ga:' . $id['ga:profileId'];
208
-
209
- $ids[] = $id;
210
- }
211
-
212
- return $ids;
213
- }
214
-
215
- /**
216
- * Get a specific data metric
217
- *
218
- * @param metric - the metric to get
219
- * @param startDate - the start date to get
220
- * @param endDate - the end date to get
221
- * @return the specific metric
222
- **/
223
- function getMetric($metric, $startDate, $endDate)
224
- {
225
- # Ensure the start date is after Jan 1 2005
226
- $startDate = $this->verifyStartDate($startDate);
227
-
228
- # Request the metric data
229
- $response = $this->http($this->baseFeed . "/data?ids=$this->accountId&start-date=$startDate&end-date=$endDate&metrics=$metric");
230
-
231
- # Check if the response received exists, else stop processing now
232
- if ( $response == '' || $this->responseCode != '200' )
233
- return false;
234
-
235
- # Parse the XML using SimplePie
236
- $simplePie = new SimplePie();
237
- $simplePie->set_raw_data($response);
238
- $simplePie->init();
239
- $simplePie->handle_content_type();
240
- $datas = $simplePie->get_items();
241
-
242
- # Read out the data until the metric is found
243
- foreach ( $datas AS $data ) {
244
- $data_tag = $data->get_item_tags('http://schemas.google.com/analytics/2009', 'metric');
245
- return $data_tag[0]['attribs']['']['value'];
246
- }
247
- }
248
-
249
- /**
250
- * Get a specific data metrics
251
- *
252
- * @param metrics - the metrics to get
253
- * @param startDate - the start date to get
254
- * @param endDate - the end date to get
255
- * @param dimensions - the dimensions to grab
256
- * @param sort - the properties to sort on
257
- * @param filter - the property to filter on
258
- * @param limit - the number of items to get
259
- * @return the specific metrics in array form
260
- **/
261
- function getMetrics($metric, $startDate, $endDate, $dimensions = false, $sort = false, $filter = false, $limit = false)
262
- {
263
- # Ensure the start date is after Jan 1 2005
264
- $startDate = $this->verifyStartDate($startDate);
265
-
266
- # Build the query url
267
- $url = $this->baseFeed . "/data?ids=$this->accountId&start-date=$startDate&end-date=$endDate&metrics=$metric";
268
-
269
- # Add optional dimensions
270
- if ( $dimensions )
271
- $url .= "&dimensions=$dimensions";
272
-
273
- # Add optional sort
274
- if ( $sort )
275
- $url .= "&sort=$sort";
276
-
277
- # Add optional filter
278
- if ( $filter )
279
- $url .= "&filters=$filter";
280
-
281
- # Add optional limit
282
- if ( $limit )
283
- $url .= "&max-results=$limit";
284
-
285
- # Request the metric data
286
- $response = $this->http($url);
287
-
288
- # Check if the response received exists, else stop processing now
289
- if ( $response == '' || $this->responseCode != '200' )
290
- return false;
291
-
292
- # Parse the XML using SimplePie
293
- $simplePie = new SimplePie();
294
- $simplePie->set_raw_data($response);
295
- $simplePie->enable_order_by_date(false);
296
- $simplePie->init();
297
- $simplePie->handle_content_type();
298
- $datas = $simplePie->get_items();
299
-
300
- $ids = array();
301
-
302
- # Read out the data until the metric is found
303
- foreach ( $datas AS $data ) {
304
- $metrics = $data->get_item_tags('http://schemas.google.com/analytics/2009', 'metric');
305
- $dimensions = $data->get_item_tags('http://schemas.google.com/analytics/2009', 'dimension');
306
- $id = array();
307
-
308
- $id['title'] = $data->get_title();
309
-
310
- # Loop through the dimensions
311
- if ( is_array($dimensions) ) {
312
- foreach ( $dimensions AS $property ) {
313
-
314
- # Get the property information
315
- $name = $property['attribs']['']['name'];
316
- $value = $property['attribs']['']['value'];
317
-
318
- # Add the propery data to the id array
319
- $id[$name] = $value;
320
-
321
- }
322
- }
323
-
324
- # Loop through the metrics
325
- if ( is_array($metrics) ) {
326
- foreach ( $metrics AS $property ) {
327
-
328
- # Get the property information
329
- $name = $property['attribs']['']['name'];
330
- $value = $property['attribs']['']['value'];
331
-
332
- # Add the propery data to the id array
333
- $id[$name] = $value;
334
-
335
- }
336
- }
337
-
338
- $ids[] = $id;
339
- }
340
-
341
- return $ids;
342
- }
343
-
344
- /**
345
- * Checks the date against Jan. 1 2005 because GA API only works until that date
346
- *
347
- * @param date - the date to compare
348
- * @return the correct date
349
- **/
350
- function verifyStartDate($date)
351
- {
352
- if ( strtotime($date) > strtotime('2005-01-01') )
353
- return $date;
354
- else
355
- return '2005-01-01';
356
- }
357
-
358
- } // END class
359
-
360
- ?>
1
+ <?php
2
+
3
+ # Include SimplePie if it doesn't exist
4
+ if ( !class_exists('SimplePie') ) {
5
+ require_once (ABSPATH . WPINC . '/class-feed.php');
6
+ }
7
+
8
+ require_once 'google-api-php-client/src/Google_Client.php';
9
+ require_once 'google-api-php-client/src/contrib/Google_AnalyticsService.php';
10
+
11
+ /**
12
+ * Handles interactions with Google Analytics' Stat API
13
+ *
14
+ * @author http://www.codebyjeff.com
15
+ **/
16
+ class GoogleAnalyticsStats
17
+ {
18
+
19
+ var $client = false;
20
+ var $accountId;
21
+ var $baseFeed = 'https://www.googleapis.com/analytics/v3';
22
+ var $token = false;
23
+
24
+
25
+ /**
26
+ * Constructor
27
+ *
28
+ * @param token - a one-time use token to be exchanged for a real token
29
+ **/
30
+ function GoogleAnalyticsStats()
31
+ {
32
+
33
+ $this->client = new Google_Client();
34
+
35
+ $this->client->setClientId(GOOGLE_ANALYTICATOR_CLIENTID);
36
+ $this->client->setClientSecret(GOOGLE_ANALYTICATOR_CLIENTSECRET);
37
+ $this->client->setRedirectUri(GOOGLE_ANALYTICATOR_REDIRECT);
38
+ $this->client->setScopes(array(GOOGLE_ANALYTICATOR_SCOPE));
39
+
40
+ // Magic. Returns objects from the Analytics Service instead of associative arrays.
41
+ $this->client->setUseObjects(true);
42
+
43
+ try {
44
+ $this->analytics = new Google_AnalyticsService($this->client);
45
+ }
46
+ catch (Google_ServiceException $e)
47
+ {
48
+ print 'There was an Analytics API service error ' . $e->getCode() . ':' . $e->getMessage();
49
+
50
+ }
51
+
52
+ }
53
+
54
+ function checkLogin()
55
+ {
56
+ $ga_google_authtoken = get_option('ga_google_authtoken');
57
+
58
+ if (!empty($ga_google_authtoken))
59
+ {
60
+ $this->client->setAccessToken($ga_google_authtoken);
61
+ }
62
+ else
63
+ {
64
+ $authCode = get_option('ga_google_token');
65
+
66
+ if (empty($authCode)) return false;
67
+
68
+
69
+ $accessToken = $this->client->authenticate($authCode);
70
+
71
+ if($accessToken)
72
+ {
73
+ $this->client->setAccessToken($accessToken);
74
+ update_option('ga_google_authtoken', $accessToken);
75
+ }
76
+ else
77
+ {
78
+ return false;
79
+ }
80
+ }
81
+
82
+ $this->token = $this->client->getAccessToken();
83
+ return true;
84
+ }
85
+
86
+ function deauthorize()
87
+ {
88
+ update_option('ga_google_token', '');
89
+ update_option('ga_google_authtoken', '');
90
+ }
91
+
92
+ function getSingleProfile()
93
+ {
94
+
95
+ $webproperty_id = get_option('ga_uid');
96
+ list($pre, $account_id, $post) = explode('-',$webproperty_id);
97
+
98
+ if (empty($webproperty_id)) return false;
99
+
100
+ try {
101
+ $profiles = $this->analytics->management_profiles->listManagementProfiles($account_id, $webproperty_id);
102
+ }
103
+ catch (Google_ServiceException $e)
104
+ {
105
+ print 'There was an Analytics API service error ' . $e->getCode() . ': ' . $e->getMessage();
106
+ return false;
107
+ }
108
+
109
+ $profile_id = $profiles->items[0]->id;
110
+ if (empty($profile_id)) return false;
111
+
112
+ $account_array = array();
113
+ array_push($account_array, array('id'=>$profile_id, 'ga:webPropertyId'=>$webproperty_id));
114
+ return $account_array;
115
+
116
+ }
117
+
118
+ function getAllProfiles()
119
+ {
120
+ $profile_array = array();
121
+
122
+ try {
123
+ $profiles = $this->analytics->management_webproperties->listManagementWebproperties('~all');
124
+ }
125
+ catch (Google_ServiceException $e)
126
+ {
127
+ print 'There was an Analytics API service error ' . $e->getCode() . ': ' . $e->getMessage();
128
+ }
129
+
130
+
131
+ if( !empty( $profiles->items ) )
132
+ {
133
+ foreach( $profiles->items as $profile )
134
+ {
135
+ $profile_array[ $profile->id ] = str_replace('http://','',$profile->name );
136
+ }
137
+ }
138
+
139
+ return $profile_array;
140
+ }
141
+
142
+ function getAnalyticsAccounts()
143
+ {
144
+ $analytics = new Google_AnalyticsService($this->client);
145
+ $accounts = $analytics->management_accounts->listManagementAccounts();
146
+ $account_array = array();
147
+
148
+ $items = $accounts->getItems();
149
+
150
+ if (count($items) > 0) {
151
+ foreach ($items as $key => $item)
152
+ {
153
+ $account_id = $item->getId();
154
+
155
+ $webproperties = $analytics->management_webproperties->listManagementWebproperties($account_id);
156
+
157
+ if (!empty($webproperties))
158
+ {
159
+ foreach ($webproperties->getItems() as $webp_key => $webp_item) {
160
+ $profiles = $analytics->management_profiles->listManagementProfiles($account_id, $webp_item->id);
161
+
162
+ $profile_id = $profiles->items[0]->id;
163
+ array_push($account_array, array('id'=>$profile_id, 'ga:webPropertyId'=>$webp_item->id));
164
+ }
165
+ }
166
+ }
167
+
168
+ return $account_array;
169
+ }
170
+ return false;
171
+
172
+ }
173
+
174
+
175
+
176
+ /**
177
+ * Sets the account id to use for queries
178
+ *
179
+ * @param id - the account id
180
+ **/
181
+ function setAccount($id)
182
+ {
183
+ $this->accountId = $id;
184
+ }
185
+
186
+
187
+ /**
188
+ * Get a specific data metrics
189
+ *
190
+ * @param metrics - the metrics to get
191
+ * @param startDate - the start date to get
192
+ * @param endDate - the end date to get
193
+ * @param dimensions - the dimensions to grab
194
+ * @param sort - the properties to sort on
195
+ * @param filter - the property to filter on
196
+ * @param limit - the number of items to get
197
+ * @return the specific metrics in array form
198
+ **/
199
+ function getMetrics($metric, $startDate, $endDate, $dimensions = false, $sort = false, $filter = false, $limit = false)
200
+ {
201
+ $analytics = new Google_AnalyticsService($this->client);
202
+
203
+ $params = array();
204
+
205
+ if ($dimensions)
206
+ {
207
+ $params['dimensions'] = $dimensions;
208
+ }
209
+ if ($sort)
210
+ {
211
+ $params['sort'] = $sort;
212
+ }
213
+ if ($filter)
214
+ {
215
+ $params['filters'] = $filter;
216
+ }
217
+ if ($limit)
218
+ {
219
+ $params['max-results'] = $limit;
220
+ }
221
+
222
+ return $analytics->data_ga->get(
223
+ 'ga:' . $this->accountId,
224
+ $startDate,
225
+ $endDate,
226
+ $metric,
227
+ $params
228
+ );
229
+ }
230
+
231
+
232
+
233
+
234
+
235
+ /**
236
+ * Checks the date against Jan. 1 2005 because GA API only works until that date
237
+ *
238
+ * @param date - the date to compare
239
+ * @return the correct date
240
+ **/
241
+ function verifyStartDate($date)
242
+ {
243
+ if ( strtotime($date) > strtotime('2005-01-01') )
244
+ return $date;
245
+ else
246
+ return '2005-01-01';
247
+ }
248
+
249
+ } // END class
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
download-button.png ADDED
Binary file
external-tracking.js CHANGED
@@ -1,44 +1,44 @@
1
- jQuery(document).ready(function() {
2
-
3
- jQuery('a').each(function() {
4
- var a = jQuery(this);
5
- var href = a.attr('href');
6
-
7
- // Check if the a tag has a href, if not, stop for the current link
8
- if ( href == undefined )
9
- return;
10
-
11
- var url = href.replace('http://','').replace('https://','');
12
- var hrefArray = href.split('.').reverse();
13
- var extension = hrefArray[0].toLowerCase();
14
- var hrefArray = href.split('/').reverse();
15
- var domain = hrefArray[2];
16
- var downloadTracked = false;
17
-
18
- // If the link is a download
19
- if (jQuery.inArray(extension,analyticsFileTypes) != -1) {
20
- // Mark the link as already tracked
21
- downloadTracked = true;
22
-
23
- // Add the tracking code
24
- a.click(function() {
25
- if ( analyticsEventTracking == 'enabled' ) {
26
- _gaq.push(['_trackEvent', 'Downloads', extension.toUpperCase(), href]);
27
- } else
28
- _gaq.push(['_trackPageview', analyticsDownloadsPrefix + url]);
29
- });
30
- }
31
-
32
- // If the link is external
33
- if ( ( href.match(/^http/) ) && ( !href.match(document.domain) ) && ( downloadTracked == false ) ) {
34
- // Add the tracking code
35
- a.click(function() {
36
- if ( analyticsEventTracking == 'enabled' ) {
37
- _gaq.push(['_trackEvent', 'Outbound Traffic', href.match(/:\/\/(.[^/]+)/)[1], href]);
38
- } else
39
- _gaq.push(['_trackPageview', analyticsOutboundPrefix + url]);
40
- });
41
- }
42
- });
43
-
44
  });
1
+ jQuery(document).ready(function() {
2
+
3
+ jQuery('a').each(function() {
4
+ var a = jQuery(this);
5
+ var href = a.attr('href');
6
+
7
+ // Check if the a tag has a href, if not, stop for the current link
8
+ if ( href == undefined )
9
+ return;
10
+
11
+ var url = href.replace('http://','').replace('https://','');
12
+ var hrefArray = href.split('.').reverse();
13
+ var extension = hrefArray[0].toLowerCase();
14
+ var hrefArray = href.split('/').reverse();
15
+ var domain = hrefArray[2];
16
+ var downloadTracked = false;
17
+
18
+ // If the link is a download
19
+ if (jQuery.inArray(extension,analyticsFileTypes) != -1) {
20
+ // Mark the link as already tracked
21
+ downloadTracked = true;
22
+
23
+ // Add the tracking code
24
+ a.click(function() {
25
+ if ( analyticsEventTracking == 'enabled' ) {
26
+ _gaq.push(['_trackEvent', 'Downloads', extension.toUpperCase(), href]);
27
+ } else
28
+ _gaq.push(['_trackPageview', analyticsDownloadsPrefix + url]);
29
+ });
30
+ }
31
+
32
+ // If the link is external
33
+ if ( ( href.match(/^http/) ) && ( !href.match(document.domain) ) && ( downloadTracked == false ) ) {
34
+ // Add the tracking code
35
+ a.click(function() {
36
+ if ( analyticsEventTracking == 'enabled' ) {
37
+ _gaq.push(['_trackEvent', 'Outbound Traffic', href.match(/:\/\/(.[^/]+)/)[1], href]);
38
+ } else
39
+ _gaq.push(['_trackPageview', analyticsOutboundPrefix + url]);
40
+ });
41
+ }
42
+ });
43
+
44
  });
external-tracking.min.js CHANGED
@@ -1,5 +1,5 @@
1
- jQuery(document).ready(function(){jQuery('a').each(function(){var a=jQuery(this);var href=a.attr('href');if(href==undefined)
2
- return;var url=href.replace('http://','').replace('https://','');var hrefArray=href.split('.').reverse();var extension=hrefArray[0].toLowerCase();var hrefArray=href.split('/').reverse();var domain=hrefArray[2];var downloadTracked=false;if(jQuery.inArray(extension,analyticsFileTypes)!=-1){downloadTracked=true;a.click(function(){if(analyticsEventTracking=='enabled'){_gaq.push(['_trackEvent','Downloads',extension.toUpperCase(),href]);}else
3
- _gaq.push(['_trackPageview',analyticsDownloadsPrefix+url]);});}
4
- if((href.match(/^http/))&&(!href.match(document.domain))&&(downloadTracked==false)){a.click(function(){if(analyticsEventTracking=='enabled'){_gaq.push(['_trackEvent','Outbound Traffic',href.match(/:\/\/(.[^/]+)/)[1],href]);}else
5
  _gaq.push(['_trackPageview',analyticsOutboundPrefix+url]);});}});});
1
+ jQuery(document).ready(function(){jQuery('a').each(function(){var a=jQuery(this);var href=a.attr('href');if(href==undefined)
2
+ return;var url=href.replace('http://','').replace('https://','');var hrefArray=href.split('.').reverse();var extension=hrefArray[0].toLowerCase();var hrefArray=href.split('/').reverse();var domain=hrefArray[2];var downloadTracked=false;if(jQuery.inArray(extension,analyticsFileTypes)!=-1){downloadTracked=true;a.click(function(){if(analyticsEventTracking=='enabled'){_gaq.push(['_trackEvent','Downloads',extension.toUpperCase(),href]);}else
3
+ _gaq.push(['_trackPageview',analyticsDownloadsPrefix+url]);});}
4
+ if((href.match(/^http/))&&(!href.match(document.domain))&&(downloadTracked==false)){a.click(function(){if(analyticsEventTracking=='enabled'){_gaq.push(['_trackEvent','Outbound Traffic',href.match(/:\/\/(.[^/]+)/)[1],href]);}else
5
  _gaq.push(['_trackPageview',analyticsOutboundPrefix+url]);});}});});
google-analyticator.php CHANGED
@@ -1,1037 +1,1050 @@
1
- <?php
2
- /*
3
- * Plugin Name: Google Analyticator
4
- * Version: 6.2
5
- * Plugin URI: http://ronaldheft.com/code/analyticator/
6
- * Description: Adds the necessary JavaScript code to enable <a href="http://www.google.com/analytics/">Google's Analytics</a>. After enabling this plugin visit <a href="options-general.php?page=google-analyticator.php">the settings page</a> and enter your Google Analytics' UID and enable logging.
7
- * Author: Ronald Heft
8
- * Author URI: http://ronaldheft.com/
9
- * Text Domain: google-analyticator
10
- */
11
-
12
- define('GOOGLE_ANALYTICATOR_VERSION', '6.2');
13
-
14
- // Constants for enabled/disabled state
15
- define("ga_enabled", "enabled", true);
16
- define("ga_disabled", "disabled", true);
17
-
18
- // Defaults, etc.
19
- define("key_ga_uid", "ga_uid", true);
20
- define("key_ga_status", "ga_status", true);
21
- define("key_ga_admin", "ga_admin_status", true);
22
- define("key_ga_admin_disable", "ga_admin_disable", true);
23
- define("key_ga_admin_role", "ga_admin_role", true);
24
- define("key_ga_dashboard_role", "ga_dashboard_role", true);
25
- define("key_ga_adsense", "ga_adsense", true);
26
- define("key_ga_extra", "ga_extra", true);
27
- define("key_ga_extra_after", "ga_extra_after", true);
28
- define("key_ga_event", "ga_event", true);
29
- define("key_ga_outbound", "ga_outbound", true);
30
- define("key_ga_outbound_prefix", "ga_outbound_prefix", true);
31
- define("key_ga_downloads", "ga_downloads", true);
32
- define("key_ga_downloads_prefix", "ga_downloads_prefix", true);
33
- define("key_ga_widgets", "ga_widgets", true);
34
- define("key_ga_sitespeed", "ga_sitespeed", true);
35
-
36
- define("ga_uid_default", "XX-XXXXX-X", true);
37
- define("ga_status_default", ga_disabled, true);
38
- define("ga_admin_default", ga_enabled, true);
39
- define("ga_admin_disable_default", 'remove', true);
40
- define("ga_adsense_default", "", true);
41
- define("ga_extra_default", "", true);
42
- define("ga_extra_after_default", "", true);
43
- define("ga_event_default", ga_enabled, true);
44
- define("ga_outbound_default", ga_enabled, true);
45
- define("ga_outbound_prefix_default", 'outgoing', true);
46
- define("ga_downloads_default", "", true);
47
- define("ga_downloads_prefix_default", "download", true);
48
- define("ga_widgets_default", ga_enabled, true);
49
- define("ga_sitespeed_default", ga_enabled, true);
50
-
51
- // Create the default key and status
52
- add_option(key_ga_status, ga_status_default, '');
53
- add_option(key_ga_uid, ga_uid_default, '');
54
- add_option(key_ga_admin, ga_admin_default, '');
55
- add_option(key_ga_admin_disable, ga_admin_disable_default, '');
56
- add_option(key_ga_admin_role, array('administrator'), '');
57
- add_option(key_ga_dashboard_role, array('administrator'), '');
58
- add_option(key_ga_adsense, ga_adsense_default, '');
59
- add_option(key_ga_extra, ga_extra_default, '');
60
- add_option(key_ga_extra_after, ga_extra_after_default, '');
61
- add_option(key_ga_event, ga_event_default, '');
62
- add_option(key_ga_outbound, ga_outbound_default, '');
63
- add_option(key_ga_outbound_prefix, ga_outbound_prefix_default, '');
64
- add_option(key_ga_downloads, ga_downloads_default, '');
65
- add_option(key_ga_downloads_prefix, ga_downloads_prefix_default, '');
66
- add_option('ga_profileid', '', '');
67
- add_option(key_ga_widgets, ga_widgets_default, '');
68
- add_option('ga_google_token', '', '');
69
- add_option('ga_compatibility', 'off', '');
70
- add_option(key_ga_sitespeed, ga_sitespeed_default, '');
71
-
72
- # Check if we have a version of WordPress greater than 2.8
73
- if ( function_exists('register_widget') ) {
74
-
75
- # Check if widgets are enabled
76
- if ( get_option(key_ga_widgets) == 'enabled' ) {
77
-
78
- # Include Google Analytics Stats widget
79
- require_once('google-analytics-stats-widget.php');
80
-
81
- # Include the Google Analytics Summary widget
82
- require_once('google-analytics-summary-widget.php');
83
- $google_analytics_summary = new GoogleAnalyticsSummary();
84
-
85
- }
86
-
87
- }
88
-
89
- // Create a option page for settings
90
- add_action('admin_init', 'ga_admin_init');
91
- add_action('admin_menu', 'add_ga_option_page');
92
-
93
- // Initialize the options
94
- function ga_admin_init() {
95
- # Load the localization information
96
- $plugin_dir = basename(dirname(__FILE__));
97
- load_plugin_textdomain('google-analyticator', 'wp-content/plugins/' . $plugin_dir . '/localizations', $plugin_dir . '/localizations');
98
- }
99
-
100
- # Add the core Google Analytics script, with a high priority to ensure last script for async tracking
101
- add_action('wp_head', 'add_google_analytics', 999999);
102
- add_action('login_head', 'add_google_analytics', 999999);
103
-
104
- # Initialize outbound link tracking
105
- add_action('init', 'ga_outgoing_links');
106
-
107
- // Hook in the options page function
108
- function add_ga_option_page() {
109
- $plugin_page = add_options_page(__('Google Analyticator Settings', 'google-analyticator'), 'Google Analytics', 'manage_options', basename(__FILE__), 'ga_options_page');
110
-
111
- # Include javascript on the GA settings page
112
- add_action('admin_head-' . $plugin_page, 'ga_admin_ajax');
113
- }
114
-
115
- add_action('plugin_action_links_' . plugin_basename(__FILE__), 'ga_filter_plugin_actions');
116
-
117
- // Add settings option
118
- function ga_filter_plugin_actions($links) {
119
- $new_links = array();
120
-
121
- $new_links[] = '<a href="options-general.php?page=google-analyticator.php">' . __('Settings', 'google-analyticator') . '</a>';
122
-
123
- return array_merge($new_links, $links);
124
- }
125
-
126
- add_filter('plugin_row_meta', 'ga_filter_plugin_links', 10, 2);
127
-
128
- // Add FAQ and support information
129
- function ga_filter_plugin_links($links, $file)
130
- {
131
- if ( $file == plugin_basename(__FILE__) )
132
- {
133
- $links[] = '<a href="http://forums.ronaldheft.com/viewforum.php?f=5">' . __('FAQ', 'google-analyticator') . '</a>';
134
- $links[] = '<a href="http://forums.ronaldheft.com/viewforum.php?f=6">' . __('Support', 'google-analyticator') . '</a>';
135
- $links[] = '<a href="http://ronaldheft.com/code/donate/">' . __('Donate', 'google-analyticator') . '</a>';
136
- }
137
-
138
- return $links;
139
- }
140
-
141
- function ga_options_page() {
142
- // If we are a postback, store the options
143
- if (isset($_POST['info_update'])) {
144
- # Verify nonce
145
- check_admin_referer('google-analyticator-update_settings');
146
-
147
- // Update the status
148
- $ga_status = $_POST[key_ga_status];
149
- if (($ga_status != ga_enabled) && ($ga_status != ga_disabled))
150
- $ga_status = ga_status_default;
151
- update_option(key_ga_status, $ga_status);
152
-
153
- // Update the UID
154
- $ga_uid = $_POST[key_ga_uid];
155
- if ($ga_uid == '')
156
- $ga_uid = ga_uid_default;
157
- update_option(key_ga_uid, $ga_uid);
158
-
159
- // Update the admin logging
160
- $ga_admin = $_POST[key_ga_admin];
161
- if (($ga_admin != ga_enabled) && ($ga_admin != ga_disabled))
162
- $ga_admin = ga_admin_default;
163
- update_option(key_ga_admin, $ga_admin);
164
-
165
- // Update the admin disable setting
166
- $ga_admin_disable = $_POST[key_ga_admin_disable];
167
- if ( $ga_admin_disable == '' )
168
- $ga_admin_disable = ga_admin_disable_default;
169
- update_option(key_ga_admin_disable, $ga_admin_disable);
170
-
171
- // Update the admin level
172
- if ( array_key_exists(key_ga_admin_role, $_POST) ) {
173
- $ga_admin_role = $_POST[key_ga_admin_role];
174
- } else {
175
- $ga_admin_role = "";
176
- }
177
- update_option(key_ga_admin_role, $ga_admin_role);
178
-
179
- // Update the dashboard level
180
- if ( array_key_exists(key_ga_dashboard_role, $_POST) ) {
181
- $ga_dashboard_role = $_POST[key_ga_dashboard_role];
182
- } else {
183
- $ga_dashboard_role = "";
184
- }
185
- update_option(key_ga_dashboard_role, $ga_dashboard_role);
186
-
187
- // Update the extra tracking code
188
- $ga_extra = $_POST[key_ga_extra];
189
- update_option(key_ga_extra, $ga_extra);
190
-
191
- // Update the extra after tracking code
192
- $ga_extra_after = $_POST[key_ga_extra_after];
193
- update_option(key_ga_extra_after, $ga_extra_after);
194
-
195
- // Update the adsense key
196
- $ga_adsense = $_POST[key_ga_adsense];
197
- update_option(key_ga_adsense, $ga_adsense);
198
-
199
- // Update the event tracking
200
- $ga_event = $_POST[key_ga_event];
201
- if (($ga_event != ga_enabled) && ($ga_event != ga_disabled))
202
- $ga_event = ga_event_default;
203
- update_option(key_ga_event, $ga_event);
204
-
205
- // Update the outbound tracking
206
- $ga_outbound = $_POST[key_ga_outbound];
207
- if (($ga_outbound != ga_enabled) && ($ga_outbound != ga_disabled))
208
- $ga_outbound = ga_outbound_default;
209
- update_option(key_ga_outbound, $ga_outbound);
210
-
211
- // Update the outbound prefix
212
- $ga_outbound_prefix = $_POST[key_ga_outbound_prefix];
213
- if ($ga_outbound_prefix == '')
214
- $ga_outbound_prefix = ga_outbound_prefix_default;
215
- update_option(key_ga_outbound_prefix, $ga_outbound_prefix);
216
-
217
- // Update the download tracking code
218
- $ga_downloads = $_POST[key_ga_downloads];
219
- update_option(key_ga_downloads, $ga_downloads);
220
-
221
- // Update the download prefix
222
- $ga_downloads_prefix = $_POST[key_ga_downloads_prefix];
223
- if ($ga_downloads_prefix == '')
224
- $ga_downloads_prefix = ga_downloads_prefix_default;
225
- update_option(key_ga_downloads_prefix, $ga_downloads_prefix);
226
-
227
- // Update the profile id
228
- update_option('ga_profileid', $_POST['ga_profileid']);
229
-
230
- // Update the widgets option
231
- $ga_widgets = $_POST[key_ga_widgets];
232
- if (($ga_widgets != ga_enabled) && ($ga_widgets != ga_disabled))
233
- $ga_widgets = ga_widgets_default;
234
- update_option(key_ga_widgets, $ga_widgets);
235
-
236
- // Update the compatibility options
237
- $ga_compatibility = $_POST['ga_compatibility'];
238
- if ( $ga_compatibility == '' )
239
- $ga_compatibility = 'off';
240
- update_option('ga_compatibility', $ga_compatibility);
241
-
242
- // Update the sitespeed option
243
- $ga_sitespeed = $_POST[key_ga_sitespeed];
244
- if (($ga_sitespeed != ga_enabled) && ($ga_sitespeed != ga_disabled))
245
- $ga_sitespeed = ga_widgets_default;
246
- update_option(key_ga_sitespeed, $ga_sitespeed);
247
-
248
- // Give an updated message
249
- echo "<div class='updated fade'><p><strong>" . __('Google Analyticator settings saved.', 'google-analyticator') . "</strong></p></div>";
250
- }
251
-
252
- // Output the options page
253
- ?>
254
-
255
- <div class="wrap">
256
-
257
- <h2><?php _e('Google Analyticator Settings', 'google-analyticator'); ?></h2>
258
-
259
- <p><em>Like Google Analyticator? Help support it <a href="http://ronaldheft.com/code/donate/">by donating to the developer</a>. This helps cover the cost of maintaining the plugin and development time toward new features. Every donation, no matter how small, is appreciated.</em></p>
260
-
261
- <form method="post" action="options-general.php?page=google-analyticator.php">
262
- <?php
263
- # Add a nonce
264
- wp_nonce_field('google-analyticator-update_settings');
265
- ?>
266
-
267
- <h3><?php _e('Basic Settings', 'google-analyticator'); ?></h3>
268
- <?php if (get_option(key_ga_status) == ga_disabled) { ?>
269
- <div style="margin:10px auto; border:3px #f00 solid; background-color:#fdd; color:#000; padding:10px; text-align:center;">
270
- <?php _e('Google Analytics integration is currently <strong>DISABLED</strong>.', 'google-analyticator'); ?>
271
- </div>
272
- <?php } ?>
273
- <?php if ((get_option(key_ga_uid) == "XX-XXXXX-X") && (get_option(key_ga_status) != ga_disabled)) { ?>
274
- <div style="margin:10px auto; border:3px #f00 solid; background-color:#fdd; color:#000; padding:10px; text-align:center;">
275
- <?php _e('Google Analytics integration is currently enabled, but you did not enter a UID. Tracking will not occur.', 'google-analyticator'); ?>
276
- </div>
277
- <?php } ?>
278
- <table class="form-table" cellspacing="2" cellpadding="5" width="100%">
279
- <tr>
280
- <th width="30%" valign="top" style="padding-top: 10px;">
281
- <label for="<?php echo key_ga_status ?>"><?php _e('Google Analytics logging is', 'google-analyticator'); ?>:</label>
282
- </th>
283
- <td>
284
- <?php
285
- echo "<select name='".key_ga_status."' id='".key_ga_status."'>\n";
286
-
287
- echo "<option value='".ga_enabled."'";
288
- if(get_option(key_ga_status) == ga_enabled)
289
- echo " selected='selected'";
290
- echo ">" . __('Enabled', 'google-analyticator') . "</option>\n";
291
-
292
- echo "<option value='".ga_disabled."'";
293
- if(get_option(key_ga_status) == ga_disabled)
294
- echo" selected='selected'";
295
- echo ">" . __('Disabled', 'google-analyticator') . "</option>\n";
296
-
297
- echo "</select>\n";
298
- ?>
299
- </td>
300
- </tr>
301
- <?php
302
- # Check if we have a version of WordPress greater than 2.8, and check if we have the memory to use the api
303
- if ( function_exists('register_widget') ) {
304
- ?>
305
- <tr>
306
- <th width="30%" valign="top" style="padding-top: 10px;">
307
- <label><?php _e('Authenticate with Google', 'google-analyticator'); ?>:</label>
308
- </th>
309
- <td>
310
- <?php if ( ( trim(get_option('ga_google_token')) == '' && !isset($_GET['token']) ) || ( isset($_GET['token']) && $_GET['token'] == 'deauth' ) ) { ?>
311
- <p style="margin-top: 7px;"><a href="https://www.google.com/accounts/AuthSubRequest?<?php echo http_build_query(array( 'next' => admin_url('/options-general.php?page=google-analyticator.php'),
312
- 'scope' => 'https://www.google.com/analytics/feeds/',
313
- 'secure' => 0,
314
- 'session' => 1,
315
- 'hd' => 'default'
316
- )); ?>"><?php _e('Click here to login to Google, thus authenticating Google Analyticator with your Analytics account.', 'google-analyticator'); ?></a></p>
317
- <?php } else { ?>
318
- <p style="margin-top: 7px;"><?php _e('Currently authenticated with Google.', 'google-analyticator'); ?> <a href="<?php echo admin_url('/options-general.php?page=google-analyticator.php&token=deauth'); ?>"><?php _e('Deauthorize Google Analyticator.', 'google-analyticator'); ?></a></p>
319
- <?php if ( isset($_GET['token']) && $_GET['token'] != 'deauth' ) { ?>
320
- <p style="color: red; display: none;" id="ga_connect_error"><?php _e('Failed to authenticate with Google. <a href="http://forums.ronaldheft.com/viewtopic.php?f=5&t=851">Read this support article</a> on Analyticator\'s support forums for help.', 'google-analyticator'); ?></p>
321
- <?php } ?>
322
- <?php } ?>
323
- <p style="margin: 5px 10px;" class="setting-description"><?php _e('Clicking the above link will authenticate Google Analyticator with Google. Authentication with Google is needed for use with the stats widget. In addition, authenticating will enable you to select your Analytics account through a drop-down instead of searching for your UID. If you are not going to use the stat widget, <strong>authenticating with Google is optional</strong>.', 'google-analyticator'); ?></p>
324
- </td>
325
- </tr>
326
- <?php } ?>
327
- <tr id="ga_ajax_accounts">
328
- <th valign="top" style="padding-top: 10px;">
329
- <label for="<?php echo key_ga_uid; ?>"><?php _e('Google Analytics UID', 'google-analyticator'); ?>:</label>
330
- </th>
331
- <td>
332
- <?php
333
- echo "<input type='text' size='50' ";
334
- echo "name='".key_ga_uid."' ";
335
- echo "id='".key_ga_uid."' ";
336
- echo "value='".get_option(key_ga_uid)."' />\n";
337
- ?>
338
- <p style="margin: 5px 10px;" class="setting-description"><?php _e('Enter your Google Analytics\' UID in this box (<a href="http://forums.ronaldheft.com/viewtopic.php?f=5&amp;t=6">where can I find my UID?</a>). The UID is needed for Google Analytics to log your website stats.', 'google-analyticator'); ?> <strong><?php if ( function_exists('register_widget') ) _e('If you are having trouble finding your UID, authenticate with Google in the above field. After returning from Google, you will be able to select your account through a drop-down box.', 'google-analyticator'); ?></strong></p>
339
- </td>
340
- </tr>
341
- </table>
342
- <h3><?php _e('Advanced Settings', 'google-analyticator'); ?></h3>
343
- <table class="form-table" cellspacing="2" cellpadding="5" width="100%">
344
- <tr>
345
- <th width="30%" valign="top" style="padding-top: 10px;">
346
- <label for="<?php echo key_ga_admin ?>"><?php _e('Track all logged in WordPress users', 'google-analyticator'); ?>:</label>
347
- </th>
348
- <td>
349
- <?php
350
- echo "<select name='".key_ga_admin."' id='".key_ga_admin."'>\n";
351
-
352
- echo "<option value='".ga_enabled."'";
353
- if(get_option(key_ga_admin) == ga_enabled)
354
- echo " selected='selected'";
355
- echo ">" . __('Yes', 'google-analyticator') . "</option>\n";
356
-
357
- echo "<option value='".ga_disabled."'";
358
- if(get_option(key_ga_admin) == ga_disabled)
359
- echo" selected='selected'";
360
- echo ">" . __('No', 'google-analyticator') . "</option>\n";
361
-
362
- echo "</select>\n";
363
-
364
- ?>
365
- <p style="margin: 5px 10px;" class="setting-description"><?php _e('Selecting "no" to this option will prevent logged in WordPress users from showing up on your Google Analytics reports. This setting will prevent yourself or other users from showing up in your Analytics reports. Use the next setting to determine what user groups to exclude.', 'google-analyticator'); ?></p>
366
- </td>
367
- </tr>
368
- <tr>
369
- <th width="30%" valign="top" style="padding-top: 10px;">
370
- <label for="<?php echo key_ga_admin_role ?>"><?php _e('User roles to not track', 'google-analyticator'); ?>:</label>
371
- </th>
372
- <td>
373
- <?php
374
- global $wp_roles;
375
- $roles = $wp_roles->get_names();
376
- $selected_roles = get_option(key_ga_admin_role);
377
- if ( !is_array($selected_roles) ) $selected_roles = array();
378
-
379
- # Loop through the roles
380
- foreach ( $roles AS $role => $name ) {
381
- echo '<input type="checkbox" value="' . $role . '" name="' . key_ga_admin_role . '[]"';
382
- if ( in_array($role, $selected_roles) )
383
- echo " checked='checked'";
384
- $name_pos = strpos($name, '|');
385
- $name = ( $name_pos ) ? substr($name, 0, $name_pos) : $name;
386
- echo ' /> ' . _x($name, 'User role') . '<br />';
387
- }
388
- ?>
389
- <p style="margin: 5px 10px;" class="setting-description"><?php _e('Specifies the user roles to not include in your WordPress Analytics report. If a user is logged into WordPress with one of these roles, they will not show up in your Analytics report.', 'google-analyticator'); ?></p>
390
- </td>
391
- </tr>
392
- <tr>
393
- <th width="30%" valign="top" style="padding-top: 10px;">
394
- <label for="<?php echo key_ga_admin_disable ?>"><?php _e('Method to prevent tracking', 'google-analyticator'); ?>:</label>
395
- </th>
396
- <td>
397
- <?php
398
- echo "<select name='".key_ga_admin_disable."' id='".key_ga_admin_disable."'>\n";
399
-
400
- echo "<option value='remove'";
401
- if(get_option(key_ga_admin_disable) == 'remove')
402
- echo " selected='selected'";
403
- echo ">" . __('Remove', 'google-analyticator') . "</option>\n";
404
-
405
- echo "<option value='admin'";
406
- if(get_option(key_ga_admin_disable) == 'admin')
407
- echo" selected='selected'";
408
- echo ">" . __('Use \'admin\' variable', 'google-analyticator') . "</option>\n";
409
-
410
- echo "</select>\n";
411
- ?>
412
- <p style="margin: 5px 10px;" class="setting-description"><?php _e('Selecting the "Remove" option will physically remove the tracking code from logged in users. Selecting the "Use \'admin\' variable" option will assign a variable called \'admin\' to logged in users. This option will allow Google Analytics\' site overlay feature to work, but you will have to manually configure Google Analytics to exclude tracking from pageviews with the \'admin\' variable.', 'google-analyticator'); ?></p>
413
- </td>
414
- </tr>
415
- <tr>
416
- <th width="30%" valign="top" style="padding-top: 10px;">
417
- <label for="<?php echo key_ga_sitespeed ?>"><?php _e('Site speed tracking', 'google-analyticator'); ?>:</label>
418
- </th>
419
- <td>
420
- <?php
421
- echo "<select name='".key_ga_sitespeed."' id='".key_ga_sitespeed."'>\n";
422
-
423
- echo "<option value='".ga_enabled."'";
424
- if(get_option(key_ga_sitespeed) == ga_enabled)
425
- echo " selected='selected'";
426
- echo ">" . __('Enabled', 'google-analyticator') . "</option>\n";
427
-
428
- echo "<option value='".ga_disabled."'";
429
- if(get_option(key_ga_sitespeed) == ga_disabled)
430
- echo" selected='selected'";
431
- echo ">" . __('Disabled', 'google-analyticator') . "</option>\n";
432
-
433
- echo "</select>\n";
434
- ?>
435
- <p style="margin: 5px 10px;" class="setting-description"><?php _e('Disabling this option will turn off the tracking required for <a href="http://www.google.com/support/analyticshelp/bin/answer.py?hl=en&answer=1205784&topic=1120718&utm_source=gablog&utm_medium=blog&utm_campaign=newga-blog&utm_content=sitespeed">Google Analytics\' Site Speed tracking report</a>.', 'google-analyticator'); ?></p>
436
- </td>
437
- </tr>
438
- <tr>
439
- <th width="30%" valign="top" style="padding-top: 10px;">
440
- <label for="<?php echo key_ga_outbound ?>"><?php _e('Outbound link tracking', 'google-analyticator'); ?>:</label>
441
- </th>
442
- <td>
443
- <?php
444
- echo "<select name='".key_ga_outbound."' id='".key_ga_outbound."'>\n";
445
-
446
- echo "<option value='".ga_enabled."'";
447
- if(get_option(key_ga_outbound) == ga_enabled)
448
- echo " selected='selected'";
449
- echo ">" . __('Enabled', 'google-analyticator') . "</option>\n";
450
-
451
- echo "<option value='".ga_disabled."'";
452
- if(get_option(key_ga_outbound) == ga_disabled)
453
- echo" selected='selected'";
454
- echo ">" . __('Disabled', 'google-analyticator') . "</option>\n";
455
-
456
- echo "</select>\n";
457
- ?>
458
- <p style="margin: 5px 10px;" class="setting-description"><?php _e('Disabling this option will turn off the tracking of outbound links. It\'s recommended not to disable this option unless you\'re a privacy advocate (now why would you be using Google Analytics in the first place?) or it\'s causing some kind of weird issue.', 'google-analyticator'); ?></p>
459
- </td>
460
- </tr>
461
- <tr>
462
- <th width="30%" valign="top" style="padding-top: 10px;">
463
- <label for="<?php echo key_ga_event ?>"><?php _e('Event tracking', 'google-analyticator'); ?>:</label>
464
- </th>
465
- <td>
466
- <?php
467
- echo "<select name='".key_ga_event."' id='".key_ga_event."'>\n";
468
-
469
- echo "<option value='".ga_enabled."'";
470
- if(get_option(key_ga_event) == ga_enabled)
471
- echo " selected='selected'";
472
- echo ">" . __('Enabled', 'google-analyticator') . "</option>\n";
473
-
474
- echo "<option value='".ga_disabled."'";
475
- if(get_option(key_ga_event) == ga_disabled)
476
- echo" selected='selected'";
477
- echo ">" . __('Disabled', 'google-analyticator') . "</option>\n";
478
-
479
- echo "</select>\n";
480
- ?>
481
- <p style="margin: 5px 10px;" class="setting-description"><?php _e('Enabling this option will treat outbound links and downloads as events instead of pageviews. Since the introduction of <a href="http://code.google.com/apis/analytics/docs/tracking/eventTrackerOverview.html">event tracking in Analytics</a>, this is the recommended way to track these types of actions. Only disable this option if you must use the old pageview tracking method.', 'google-analyticator'); ?></p>
482
- </td>
483
- </tr>
484
- <tr>
485
- <th valign="top" style="padding-top: 10px;">
486
- <label for="<?php echo key_ga_downloads; ?>"><?php _e('Download extensions to track', 'google-analyticator'); ?>:</label>
487
- </th>
488
- <td>
489
- <?php
490
- echo "<input type='text' size='50' ";
491
- echo "name='".key_ga_downloads."' ";
492
- echo "id='".key_ga_downloads."' ";
493
- echo "value='".stripslashes(get_option(key_ga_downloads))."' />\n";
494
- ?>
495
- <p style="margin: 5px 10px;" class="setting-description"><?php _e('Enter any extensions of files you would like to be tracked as a download. For example to track all MP3s and PDFs enter <strong>mp3,pdf</strong>. <em>Outbound link tracking must be enabled for downloads to be tracked.</em>', 'google-analyticator'); ?></p>
496
- </td>
497
- </tr>
498
- <tr>
499
- <th valign="top" style="padding-top: 10px;">
500
- <label for="<?php echo key_ga_outbound_prefix; ?>"><?php _e('Prefix external links with', 'google-analyticator'); ?>:</label>
501
- </th>
502
- <td>
503
- <?php
504
- echo "<input type='text' size='50' ";
505
- echo "name='".key_ga_outbound_prefix."' ";
506
- echo "id='".key_ga_outbound_prefix."' ";
507
- echo "value='".stripslashes(get_option(key_ga_outbound_prefix))."' />\n";
508
- ?>
509
- <p style="margin: 5px 10px;" class="setting-description"><?php _e('Enter a name for the section tracked external links will appear under. This option has no effect if event tracking is enabled.', 'google-analyticator'); ?></em></p>
510
- </td>
511
- </tr>
512
- <tr>
513
- <th valign="top" style="padding-top: 10px;">
514
- <label for="<?php echo key_ga_downloads_prefix; ?>"><?php _e('Prefix download links with', 'google-analyticator'); ?>:</label>
515
- </th>
516
- <td>
517
- <?php
518
- echo "<input type='text' size='50' ";
519
- echo "name='".key_ga_downloads_prefix."' ";
520
- echo "id='".key_ga_downloads_prefix."' ";
521
- echo "value='".stripslashes(get_option(key_ga_downloads_prefix))."' />\n";
522
- ?>
523
- <p style="margin: 5px 10px;" class="setting-description"><?php _e('Enter a name for the section tracked download links will appear under. This option has no effect if event tracking is enabled.', 'google-analyticator'); ?></em></p>
524
- </td>
525
- </tr>
526
- <tr>
527
- <th valign="top" style="padding-top: 10px;">
528
- <label for="<?php echo key_ga_adsense; ?>"><?php _e('Google Adsense ID', 'google-analyticator'); ?>:</label>
529
- </th>
530
- <td>
531
- <?php
532
- echo "<input type='text' size='50' ";
533
- echo "name='".key_ga_adsense."' ";
534
- echo "id='".key_ga_adsense."' ";
535
- echo "value='".get_option(key_ga_adsense)."' />\n";
536
- ?>
537
- <p style="margin: 5px 10px;" class="setting-description"><?php _e('Enter your Google Adsense ID assigned by Google Analytics in this box. This enables Analytics tracking of Adsense information if your Adsense and Analytics accounts are linked.', 'google-analyticator'); ?></p>
538
- </td>
539
- </tr>
540
- <tr>
541
- <th valign="top" style="padding-top: 10px;">
542
- <label for="<?php echo key_ga_extra; ?>"><?php _e('Additional tracking code', 'google-analyticator'); ?><br />(<?php _e('before tracker initialization', 'google-analyticator'); ?>):</label>
543
- </th>
544
- <td>
545
- <?php
546
- echo "<textarea cols='50' rows='8' ";
547
- echo "name='".key_ga_extra."' ";
548
- echo "id='".key_ga_extra."'>";
549
- echo stripslashes(get_option(key_ga_extra))."</textarea>\n";
550
- ?>
551
- <p style="margin: 5px 10px;" class="setting-description"><?php _e('Enter any additional lines of tracking code that you would like to include in the Google Analytics tracking script. The code in this section will be displayed <strong>before</strong> the Google Analytics tracker is initialized. Read <a href="http://www.google.com/analytics/InstallingGATrackingCode.pdf">Google Analytics tracker manual</a> to learn what code goes here and how to use it.', 'google-analyticator'); ?></p>
552
- </td>
553
- </tr>
554
- <tr>
555
- <th valign="top" style="padding-top: 10px;">
556
- <label for="<?php echo key_ga_extra_after; ?>"><?php _e('Additional tracking code', 'google-analyticator'); ?><br />(<?php _e('after tracker initialization', 'google-analyticator'); ?>):</label>
557
- </th>
558
- <td>
559
- <?php
560
- echo "<textarea cols='50' rows='8' ";
561
- echo "name='".key_ga_extra_after."' ";
562
- echo "id='".key_ga_extra_after."'>";
563
- echo stripslashes(get_option(key_ga_extra_after))."</textarea>\n";
564
- ?>
565
- <p style="margin: 5px 10px;" class="setting-description"><?php _e('Enter any additional lines of tracking code that you would like to include in the Google Analytics tracking script. The code in this section will be displayed <strong>after</strong> the Google Analytics tracker is initialized. Read <a href="http://www.google.com/analytics/InstallingGATrackingCode.pdf">Google Analytics tracker manual</a> to learn what code goes here and how to use it.', 'google-analyticator'); ?></p>
566
- </td>
567
- </tr>
568
- <?php
569
- # Check if we have a version of WordPress greater than 2.8
570
- if ( function_exists('register_widget') ) {
571
- ?>
572
- <tr>
573
- <th valign="top" style="padding-top: 10px;">
574
- <label for="ga_profileid"><?php _e('Google Analytics profile ID', 'google-analyticator'); ?>:</label>
575
- </th>
576
- <td>
577
- <?php
578
- echo "<input type='text' size='50' ";
579
- echo "name='ga_profileid' ";
580
- echo "id='ga_profileid' ";
581
- echo "value='".get_option('ga_profileid')."' />\n";
582
- ?>
583
- <p style="margin: 5px 10px;" class="setting-description"><?php _e('Enter your Google Analytics\' profile ID in this box. Entering your profile ID is optional, and is only useful if you have multiple profiles associated with a single UID. By entering your profile ID, the dashboard widget will display stats based on the profile ID you specify.', 'google-analyticator'); ?></p>
584
- </td>
585
- </tr>
586
- <tr>
587
- <th width="30%" valign="top" style="padding-top: 10px;">
588
- <label for="<?php echo key_ga_dashboard_role ?>"><?php _e('User roles that can see the dashboard widget', 'google-analyticator'); ?>:</label>
589
- </th>
590
- <td>
591
- <?php
592
- global $wp_roles;
593
- $roles = $wp_roles->get_names();
594
- $selected_roles = get_option(key_ga_dashboard_role);
595
- if ( !is_array($selected_roles) ) $selected_roles = array();
596
-
597
- # Loop through the roles
598
- foreach ( $roles AS $role => $name ) {
599
- echo '<input type="checkbox" value="' . $role . '" name="' . key_ga_dashboard_role . '[]"';
600
- if ( in_array($role, $selected_roles) )
601
- echo " checked='checked'";
602
- $name_pos = strpos($name, '|');
603
- $name = ( $name_pos ) ? substr($name, 0, $name_pos) : $name;
604
- echo ' /> ' . _x($name, 'User role') . '<br />';
605
- }
606
- ?>
607
- <p style="margin: 5px 10px;" class="setting-description"><?php _e('Specifies the user roles that can see the dashboard widget. If a user is not in one of these role groups, they will not see the dashboard widget.', 'google-analyticator'); ?></p>
608
- </td>
609
- </tr>
610
- <tr>
611
- <th width="30%" valign="top" style="padding-top: 10px;">
612
- <label for="<?php echo key_ga_widgets; ?>"><?php _e('Include widgets', 'google-analyticator'); ?>:</label>
613
- </th>
614
- <td>
615
- <?php
616
- echo "<select name='".key_ga_widgets."' id='".key_ga_widgets."'>\n";
617
-
618
- echo "<option value='".ga_enabled."'";
619
- if(get_option(key_ga_widgets) == ga_enabled)
620
- echo " selected='selected'";
621
- echo ">" . __('Enabled', 'google-analyticator') . "</option>\n";
622
-
623
- echo "<option value='".ga_disabled."'";
624
- if(get_option(key_ga_widgets) == ga_disabled)
625
- echo" selected='selected'";
626
- echo ">" . __('Disabled', 'google-analyticator') . "</option>\n";
627
-
628
- echo "</select>\n";
629
- ?>
630
- <p style="margin: 5px 10px;" class="setting-description"><?php _e('Disabling this option will completely remove the Dashboard Summary widget and the theme Stats widget. Use this option if you would prefer to not see the widgets.', 'google-analyticator'); ?></p>
631
- </td>
632
- </tr>
633
- <tr>
634
- <th width="30%" valign="top" style="padding-top: 10px;">
635
- <label for="ga_compatibility"><?php _e('Authentication compatibility', 'google-analyticator'); ?>:</label>
636
- </th>
637
- <td>
638
- <?php
639
- echo "<select name='ga_compatibility' id='ga_compatibility'>\n";
640
-
641
- echo "<option value='off'";
642
- if(get_option('ga_compatibility') == 'off')
643
- echo " selected='selected'";
644
- echo ">" . __('Off', 'google-analyticator') . "</option>\n";
645
-
646
- echo "<option value='level1'";
647
- if(get_option('ga_compatibility') == 'level1')
648
- echo " selected='selected'";
649
- echo ">" . __('Disable cURL', 'google-analyticator') . "</option>\n";
650
-
651
- echo "<option value='level2'";
652
- if(get_option('ga_compatibility') == 'level2')
653
- echo " selected='selected'";
654
- echo ">" . __('Disable cURL and PHP Streams', 'google-analyticator') . "</option>\n";
655
-
656
- echo "</select>\n";
657
- ?>
658
- <p style="margin: 5px 10px;" class="setting-description"><?php _e('If you\'re having trouble authenticating with Google for use with the stats widgets, try setting these compatibility modes. Try disabling cURL first and re-authenticate. If that fails, try disabling cURL and PHP Streams.', 'google-analyticator'); ?></p>
659
- </td>
660
- </tr>
661
- <?php } ?>
662
- </table>
663
- <p class="submit">
664
- <input type="submit" name="info_update" value="<?php _e('Save Changes', 'google-analyticator'); ?>" />
665
- </p>
666
- </div>
667
- </form>
668
-
669
- <?php
670
- }
671
-
672
- /**
673
- * Adds AJAX to the GA settings page
674
- **/
675
- function ga_admin_ajax()
676
- {
677
- if ( function_exists('register_widget') ) {
678
-
679
- # Only attempt to replace code if we're authenticated or attempting to authenticate
680
- if ( ( isset($_REQUEST['token']) && $_REQUEST['token'] != '' ) || ( trim(get_option('ga_google_token')) != '' ) ) {
681
- ?>
682
- <script type="text/javascript">
683
-
684
- jQuery(document).ready(function(){
685
-
686
- // Grab the widget data
687
- jQuery.ajax({
688
- type: 'post',
689
- url: 'admin-ajax.php',
690
- data: {
691
- action: 'ga_ajax_accounts',
692
- _ajax_nonce: '<?php echo wp_create_nonce("google-analyticator-accounts_get"); ?>'<?php if ( isset($_GET['token']) ) { ?>,
693
- token: '<?php echo esc_js($_GET["token"]); ?>'
694
- <?php } ?>
695
- },
696
- success: function(html) {
697
- if ( html != '' )
698
- jQuery('#ga_ajax_accounts').html(html);
699
- else
700
- jQuery('#ga_connect_error').show();
701
- }
702
- });
703
-
704
- });
705
-
706
- </script>
707
- <?php
708
- }
709
- }
710
- }
711
-
712
- # Look for the ajax list call
713
- add_action('wp_ajax_ga_ajax_accounts', 'ga_ajax_accounts');
714
-
715
- /**
716
- * An AJAX function to get a list of accounts in a drop down
717
- **/
718
- function ga_ajax_accounts()
719
- {
720
- # Check the ajax widget
721
- check_ajax_referer('google-analyticator-accounts_get');
722
-
723
- # Get the list of accounts if available
724
- $ga_accounts = ga_get_analytics_accounts();
725
-
726
- if ( $ga_accounts !== false ) {
727
- ?>
728
-
729
- <th valign="top" style="padding-top: 10px;">
730
- <label for="<?php echo key_ga_uid; ?>"><?php _e('Google Analytics account', 'google-analyticator'); ?>:</label>
731
- </th>
732
- <td>
733
- <?php
734
- // sort the $ga_accounts array by ga:accountName and then title
735
- $sorted_ga_accounts = array();
736
- foreach ($ga_accounts as $ga_account) {
737
- $sorted_ga_accounts[$ga_account['ga:accountName']][] = $ga_account;
738
- }
739
- foreach( $sorted_ga_accounts as $id => $sorted_ga_account) {
740
- usort($sorted_ga_accounts[$id], 'ga_sort_account_list');
741
- }
742
-
743
- # Create a select box
744
- echo '<select name="' . key_ga_uid . '" id="' . key_ga_uid . '">';
745
- echo '<option value="XX-XXXXX-X">' . __('Select an Account', 'google-analyticator') . '</option>';
746
-
747
- # The list of accounts
748
- foreach ( $sorted_ga_accounts AS $account_name => $account_list ) {
749
- echo "<optgroup label='".htmlentities($account_name)."'>\n";
750
- foreach( $account_list as $account) {
751
- $select = ( get_option(key_ga_uid) == $account['ga:webPropertyId'] ) ? ' selected="selected"' : '';
752
- echo '<option value="' . $account['ga:webPropertyId'] . '"' . $select . '>' . $account['title'] . '</option>';
753
- }
754
- echo "</optgroup>\n";
755
- }
756
-
757
- # Close the select box
758
- echo '</select>';
759
- ?>
760
- <p style="margin: 5px 10px;" class="setting-description"><?php _e('Select the Analytics account you wish to enable tracking for. An account must be selected for tracking to occur.', 'google-analyticator'); ?></p>
761
- </td>
762
-
763
- <?php
764
- }
765
- die();
766
- }
767
-
768
- function ga_sort_account_list($a, $b) {
769
- return strcmp($a['title'],$b['title']);
770
- }
771
-
772
- /**
773
- * Checks if the WordPress API is a valid method for selecting an account
774
- *
775
- * @return a list of accounts if available, false if none available
776
- **/
777
- function ga_get_analytics_accounts()
778
- {
779
- $accounts = array();
780
-
781
- # Get the class for interacting with the Google Analytics
782
- require_once('class.analytics.stats.php');
783
-
784
- # Create a new Gdata call
785
- if ( isset($_POST['token']) && $_POST['token'] != '' )
786
- $stats = new GoogleAnalyticsStats($_POST['token']);
787
- elseif ( trim(get_option('ga_google_token')) != '' )
788
- $stats = new GoogleAnalyticsStats();
789
- else
790
- return false;
791
-
792
- # Check if Google sucessfully logged in
793
- if ( ! $stats->checkLogin() )
794
- return false;
795
-
796
- # Get a list of accounts
797
- $accounts = $stats->getAnalyticsAccounts();
798
-
799
- # Return the account array if there are accounts
800
- if ( count($accounts) > 0 )
801
- return $accounts;
802
- else
803
- return false;
804
- }
805
-
806
- /**
807
- * Add http_build_query if it doesn't exist already
808
- **/
809
- if ( !function_exists('http_build_query') ) {
810
- function http_build_query($params, $key = null)
811
- {
812
- $ret = array();
813
-
814
- foreach( (array) $params as $name => $val ) {
815
- $name = urlencode($name);
816
-
817
- if ( $key !== null )
818
- $name = $key . "[" . $name . "]";
819
-
820
- if ( is_array($val) || is_object($val) )
821
- $ret[] = http_build_query($val, $name);
822
- elseif ($val !== null)
823
- $ret[] = $name . "=" . urlencode($val);
824
- }
825
-
826
- return implode("&", $ret);
827
- }
828
- }
829
-
830
- /**
831
- * Echos out the core Analytics tracking code
832
- **/
833
- function add_google_analytics()
834
- {
835
- # Fetch variables used in the tracking code
836
- $uid = stripslashes(get_option(key_ga_uid));
837
- $extra = stripslashes(get_option(key_ga_extra));
838
- $extra_after = stripslashes(get_option(key_ga_extra_after));
839
- $extensions = str_replace (",", "|", get_option(key_ga_downloads));
840
-
841
- # Determine if the GA is enabled and contains a valid UID
842
- if ( ( get_option(key_ga_status) != ga_disabled ) && ( $uid != "XX-XXXXX-X" ) )
843
- {
844
- # Determine if the user is an admin, and should see the tracking code
845
- if ( ( get_option(key_ga_admin) == ga_enabled || !ga_current_user_is(get_option(key_ga_admin_role)) ) && get_option(key_ga_admin_disable) == 'remove' || get_option(key_ga_admin_disable) != 'remove' )
846
- {
847
- # Disable the tracking code on the post preview page
848
- if ( !function_exists("is_preview") || ( function_exists("is_preview") && !is_preview() ) )
849
- {
850
- # Add the notice that Google Analyticator tracking is enabled
851
- echo "<!-- Google Analytics Tracking by Google Analyticator " . GOOGLE_ANALYTICATOR_VERSION . ": http://ronaldheft.com/code/analyticator/ -->\n";
852
-
853
- # Add the Adsense data if specified
854
- if ( get_option(key_ga_adsense) != '' )
855
- echo '<script type="text/javascript">window.google_analytics_uacct = "' . get_option(key_ga_adsense) . "\";</script>\n";
856
-
857
- # Include the file types to track
858
- $extensions = explode(',', stripslashes(get_option(key_ga_downloads)));
859
- $ext = "";
860
- foreach ( $extensions AS $extension )
861
- $ext .= "'$extension',";
862
- $ext = substr($ext, 0, -1);
863
-
864
- # Include the link tracking prefixes
865
- $outbound_prefix = stripslashes(get_option(key_ga_outbound_prefix));
866
- $downloads_prefix = stripslashes(get_option(key_ga_downloads_prefix));
867
- $event_tracking = get_option(key_ga_event);
868
-
869
- ?>
870
- <script type="text/javascript">
871
- var analyticsFileTypes = [<?php echo strtolower($ext); ?>];
872
- <?php if ( $event_tracking != 'enabled' ) { ?>
873
- var analyticsOutboundPrefix = '/<?php echo $outbound_prefix; ?>/';
874
- var analyticsDownloadsPrefix = '/<?php echo $downloads_prefix; ?>/';
875
- <?php } ?>
876
- var analyticsEventTracking = '<?php echo $event_tracking; ?>';
877
- </script>
878
- <?php
879
- # Add the first part of the core tracking code
880
- ?>
881
- <script type="text/javascript">
882
- var _gaq = _gaq || [];
883
- _gaq.push(['_setAccount', '<?php echo $uid; ?>']);
884
- <?php
885
-
886
- # Add any tracking code before the trackPageview
887
- do_action('google_analyticator_extra_js_before');
888
- if ( '' != $extra )
889
- echo " $extra\n";
890
-
891
- # Add the track pageview function
892
- echo " _gaq.push(['_trackPageview']);\n";
893
-
894
- # Add the site speed tracking
895
- if ( get_option(key_ga_sitespeed) == ga_enabled )
896
- echo " _gaq.push(['_trackPageLoadTime']);\n";
897
-
898
- # Disable page tracking if admin is logged in
899
- if ( ( get_option(key_ga_admin) == ga_disabled ) && ( ga_current_user_is(get_option(key_ga_admin_role)) ) )
900
- echo " _gaq.push(['_setCustomVar', 'admin']);\n";
901
-
902
- # Add any tracking code after the trackPageview
903
- do_action('google_analyticator_extra_js_after');
904
- if ( '' != $extra_after )
905
- echo " $extra_after\n";
906
-
907
- # Add the final section of the tracking code
908
- ?>
909
-
910
- (function() {
911
- var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
912
- ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
913
- var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
914
- })();
915
- </script>
916
- <?php
917
- }
918
- } else {
919
- # Add the notice that Google Analyticator tracking is enabled
920
- echo "<!-- Google Analytics Tracking by Google Analyticator " . GOOGLE_ANALYTICATOR_VERSION . ": http://ronaldheft.com/code/analyticator/ -->\n";
921
- echo " <!-- " . __('Tracking code is hidden, since the settings specify not to track admins. Tracking is occurring for non-admins.', 'google-analyticator') . " -->\n";
922
- }
923
- }
924
- }
925
-
926
- /**
927
- * Adds outbound link tracking to Google Analyticator
928
- **/
929
- function ga_outgoing_links()
930
- {
931
- # Fetch the UID
932
- $uid = stripslashes(get_option(key_ga_uid));
933
-
934
- # If GA is enabled and has a valid key
935
- if ( (get_option(key_ga_status) != ga_disabled ) && ( $uid != "XX-XXXXX-X" ) )
936
- {
937
- # If outbound tracking is enabled
938
- if ( get_option(key_ga_outbound) == ga_enabled )
939
- {
940
- # If this is not an admin page
941
- if ( !is_admin() )
942
- {
943
- # Display page tracking if user is not an admin
944
- if ( ( get_option(key_ga_admin) == ga_enabled || !ga_current_user_is(get_option(key_ga_admin_role)) ) && get_option(key_ga_admin_disable) == 'remove' || get_option(key_ga_admin_disable) != 'remove' )
945
- {
946
- add_action('wp_print_scripts', 'ga_external_tracking_js');
947
- }
948
- }
949
- }
950
- }
951
- }
952
-
953
- /**
954
- * Adds the scripts required for outbound link tracking
955
- **/
956
- function ga_external_tracking_js()
957
- {
958
- wp_enqueue_script('ga-external-tracking', plugins_url('/google-analyticator/external-tracking.min.js'), array('jquery'), GOOGLE_ANALYTICATOR_VERSION);
959
- }
960
-
961
- /**
962
- * Determines if a specific user fits a role
963
- **/
964
- function ga_current_user_is($roles)
965
- {
966
- if ( !$roles ) return false;
967
-
968
- global $current_user;
969
- get_currentuserinfo();
970
- $user_id = intval( $current_user->ID );
971
-
972
- if ( !$user_id ) {
973
- return false;
974
- }
975
- $user = new WP_User($user_id); // $user->roles
976
-
977
- foreach ( $roles as $role )
978
- if ( in_array($role, $user->roles) ) return true;
979
-
980
- return false;
981
- }
982
-
983
- /**
984
- * EXPERIMENTAL: Retrieve Google's visits for the given page
985
- * More work needs to be done. Needs caching, needs to be less resource intensive, and
986
- * needs an automated way to determine the page.
987
- * Function may/will change in future releases. Only use if you know what you're doing.
988
- *
989
- * @param url - the page url, missing the domain information
990
- * @param days - the number of days to get
991
- * @return the number of visits
992
- **/
993
- function get_analytics_visits_by_page($page, $days = 31)
994
- {
995
- require_once('class.analytics.stats.php');
996
-
997
- # Create a new API object
998
- $api = new GoogleAnalyticsStats();
999
-
1000
- # Get the current accounts accounts
1001
- $accounts = ga_get_analytics_accounts();
1002
-
1003
- # Verify accounts exist
1004
- if ( count($accounts) <= 0 )
1005
- return 0;
1006
-
1007
- # Loop throught the account and return the current account
1008
- foreach ( $accounts AS $account )
1009
- {
1010
- # Check if the UID matches the selected UID
1011
- if ( $account['ga:webPropertyId'] == get_option('ga_uid') )
1012
- {
1013
- $api->setAccount($account['id']);
1014
- break;
1015
- }
1016
- }
1017
-
1018
- # Encode the page url
1019
- $page = urlencode($page);
1020
-
1021
- # Get the metric information from Google
1022
- $before = date('Y-m-d', strtotime('-' . $days . ' days'));
1023
- $yesterday = date('Y-m-d', strtotime('-1 day'));
1024
- $stats = $api->getMetrics('ga:visits', $before, $yesterday, 'ga:pagePath', false, 'ga:pagePath%3D%3D' . $page, 1);
1025
-
1026
- # Check the size of the stats array
1027
- if ( count($stats) <= 0 || !is_array($stats) ) {
1028
- return 0;
1029
- } else {
1030
- # Loop through each stat for display
1031
- foreach ( $stats AS $stat ) {
1032
- return $stat['ga:visits'];
1033
- }
1034
- }
1035
- }
1036
-
 
 
 
 
 
 
 
 
 
 
 
 
 
1037
  ?>
1
+ <?php
2
+ /*
3
+ * Plugin Name: Google Analyticator
4
+ * Version: 6.3.4
5
+ * Plugin URI: http://wordpress.org/extend/plugins/google-analyticator/
6
+ * Description: Adds the necessary JavaScript code to enable <a href="http://www.google.com/analytics/">Google's Analytics</a>. After enabling this plugin you need to authenticate with Google, then select your domain and you're set.
7
+ * Author: Video User Manuals
8
+ * Author URI: http://www.videousermanuals.com
9
+ * Text Domain: google-analyticator
10
+ */
11
+
12
+ define('GOOGLE_ANALYTICATOR_VERSION', '6.3.4');
13
+
14
+ define('GOOGLE_ANALYTICATOR_CLIENTID', '1007949979410.apps.googleusercontent.com');
15
+ define('GOOGLE_ANALYTICATOR_CLIENTSECRET', 'q06U41XDXtzaXD14E-KO1hti'); //don't worry - this don't need to be secret in our case
16
+ define('GOOGLE_ANALYTICATOR_REDIRECT', 'urn:ietf:wg:oauth:2.0:oob');
17
+ define('GOOGLE_ANALYTICATOR_SCOPE', 'https://www.googleapis.com/auth/analytics.readonly');
18
+
19
+ // Constants for enabled/disabled state
20
+ define("ga_enabled", "enabled", true);
21
+ define("ga_disabled", "disabled", true);
22
+
23
+ // Defaults, etc.
24
+ define("key_ga_uid", "ga_uid", true);
25
+ define("key_ga_status", "ga_status", true);
26
+ define("key_ga_admin", "ga_admin_status", true);
27
+ define("key_ga_admin_disable", "ga_admin_disable", true);
28
+ define("key_ga_admin_role", "ga_admin_role", true);
29
+ define("key_ga_dashboard_role", "ga_dashboard_role", true);
30
+ define("key_ga_adsense", "ga_adsense", true);
31
+ define("key_ga_extra", "ga_extra", true);
32
+ define("key_ga_extra_after", "ga_extra_after", true);
33
+ define("key_ga_event", "ga_event", true);
34
+ define("key_ga_outbound", "ga_outbound", true);
35
+ define("key_ga_outbound_prefix", "ga_outbound_prefix", true);
36
+ define("key_ga_downloads", "ga_downloads", true);
37
+ define("key_ga_downloads_prefix", "ga_downloads_prefix", true);
38
+ define("key_ga_widgets", "ga_widgets", true);
39
+ define("key_ga_sitespeed", "ga_sitespeed", true);
40
+
41
+ define("ga_uid_default", "UA-XXXXXXXX-X", true);
42
+ define("ga_google_token_default", "", true);
43
+ define("ga_status_default", ga_disabled, true);
44
+ define("ga_admin_default", ga_enabled, true);
45
+ define("ga_admin_disable_default", 'remove', true);
46
+ define("ga_adsense_default", "", true);
47
+ define("ga_extra_default", "", true);
48
+ define("ga_extra_after_default", "", true);
49
+ define("ga_event_default", ga_enabled, true);
50
+ define("ga_outbound_default", ga_enabled, true);
51
+ define("ga_outbound_prefix_default", 'outgoing', true);
52
+ define("ga_downloads_default", "", true);
53
+ define("ga_downloads_prefix_default", "download", true);
54
+ define("ga_widgets_default", ga_enabled, true);
55
+ define("ga_sitespeed_default", ga_enabled, true);
56
+
57
+ // Create the default key and status
58
+ add_option(key_ga_status, ga_status_default, '');
59
+ add_option(key_ga_uid, ga_uid_default, '');
60
+ add_option(key_ga_admin, ga_admin_default, '');
61
+ add_option(key_ga_admin_disable, ga_admin_disable_default, '');
62
+ add_option(key_ga_admin_role, array('administrator'), '');
63
+ add_option(key_ga_dashboard_role, array('administrator'), '');
64
+ add_option(key_ga_adsense, ga_adsense_default, '');
65
+ add_option(key_ga_extra, ga_extra_default, '');
66
+ add_option(key_ga_extra_after, ga_extra_after_default, '');
67
+ add_option(key_ga_event, ga_event_default, '');
68
+ add_option(key_ga_outbound, ga_outbound_default, '');
69
+ add_option(key_ga_outbound_prefix, ga_outbound_prefix_default, '');
70
+ add_option(key_ga_downloads, ga_downloads_default, '');
71
+ add_option(key_ga_downloads_prefix, ga_downloads_prefix_default, '');
72
+ add_option(key_ga_sitespeed, ga_sitespeed_default, '');
73
+ add_option(key_ga_widgets, ga_widgets_default, '');
74
+ add_option('ga_defaults', 'yes' );
75
+ add_option('ga_google_token', '', '');
76
+
77
+
78
+ $useAuth = ( get_option( 'ga_google_token' ) == '' ? false : true );
79
+
80
+
81
+ # Check if we have a version of WordPress greater than 2.8
82
+ if ( function_exists('register_widget') ) {
83
+
84
+ # Check if widgets are enabled and the auth has been set!
85
+ if ( get_option(key_ga_widgets) == 'enabled' && $useAuth ) {
86
+
87
+ # Include Google Analytics Stats widget
88
+ require_once('google-analytics-stats-widget.php');
89
+
90
+ # Include the Google Analytics Summary widget
91
+ require_once('google-analytics-summary-widget.php');
92
+ $google_analytics_summary = new GoogleAnalyticsSummary();
93
+
94
+ }
95
+
96
+ }
97
+
98
+ // Create a option page for settings
99
+ add_action('admin_init', 'ga_admin_init');
100
+ add_action('admin_menu', 'add_ga_option_page');
101
+
102
+ // Initialize the options
103
+ function ga_admin_init() {
104
+ # Load the localization information
105
+ $plugin_dir = basename(dirname(__FILE__));
106
+ load_plugin_textdomain('google-analyticator', 'wp-content/plugins/' . $plugin_dir . '/localizations', $plugin_dir . '/localizations');
107
+ }
108
+
109
+ # Add the core Google Analytics script, with a high priority to ensure last script for async tracking
110
+ add_action('wp_head', 'add_google_analytics', 999999);
111
+ add_action('login_head', 'add_google_analytics', 999999);
112
+
113
+ # Initialize outbound link tracking
114
+ add_action('init', 'ga_outgoing_links');
115
+
116
+ // Hook in the options page function
117
+ function add_ga_option_page() {
118
+
119
+ $plugin_page = add_options_page(__('Google Analyticator Settings', 'google-analyticator'), 'Google Analytics', 'manage_options', basename(__FILE__), 'ga_options_page');
120
+ add_action('load-'.$plugin_page, 'ga_pre_load' );
121
+
122
+ $activate_page = add_submenu_page( null, 'Activation', 'Google Analytics', 'manage_options', 'ga_activate' , 'ga_activate');
123
+
124
+
125
+ $reset_page = add_submenu_page(null, 'Reset', 'Reset', 'activate_plugins', 'ga_reset', 'ga_reset' );
126
+ add_action('load-'.$reset_page, 'ga_do_reset' );
127
+
128
+ }
129
+
130
+ add_action('plugin_action_links_' . plugin_basename(__FILE__), 'ga_filter_plugin_actions');
131
+
132
+ function ga_pre_load()
133
+ {
134
+
135
+ if( isset( $_POST['key_ga_google_token'] ) ):
136
+
137
+ check_admin_referer('google-analyticator-update_settings');
138
+
139
+ // Nolonger defaults
140
+ update_option('ga_defaults', 'no');
141
+
142
+ // Update GA Token
143
+ update_option('ga_google_token', $_POST['key_ga_google_token']);
144
+
145
+
146
+ endif;
147
+
148
+ if( get_option('ga_defaults') == 'yes' ):
149
+
150
+ wp_redirect( admin_url('options-general.php?page=ga_activate') );
151
+ exit;
152
+
153
+ endif;
154
+ }
155
+
156
+ function ga_activate()
157
+ {
158
+
159
+ if (! function_exists('curl_init')) {
160
+ print('Google PHP API Client requires the CURL PHP extension');
161
+ return;
162
+ }
163
+
164
+ if (! function_exists('json_decode')) {
165
+ print('Google PHP API Client requires the JSON PHP extension');
166
+ return;
167
+ }
168
+
169
+ if (! function_exists('http_build_query')) {
170
+ print('Google PHP API Client requires http_build_query()');
171
+ return;
172
+ }
173
+
174
+ $url = http_build_query( array(
175
+ 'next' => admin_url('/options-general.php?page=google-analyticator.php'),
176
+ 'scope' => GOOGLE_ANALYTICATOR_SCOPE,
177
+ 'response_type'=>'code',
178
+ 'redirect_uri'=>GOOGLE_ANALYTICATOR_REDIRECT,
179
+ 'client_id'=>GOOGLE_ANALYTICATOR_CLIENTID
180
+ )
181
+ );
182
+
183
+ ?>
184
+ <div class="wrap">
185
+
186
+ <h2>Activate Google Analyticator</h2>
187
+
188
+ <p><strong>Google Authentication Code </strong> </p>
189
+
190
+ <p>You need to sign in to Google and grant this plugin access to your Google Analytics account</p>
191
+
192
+ <p>
193
+ <a
194
+ onclick="window.open('https://accounts.google.com/o/oauth2/auth?<?php echo $url ?>', 'activate','width=700, height=600, menubar=0, status=0, location=0, toolbar=0')"
195
+ target="_blank"
196
+ href="javascript:void(0);"> Click Here </a> - <small> Or <a target="_blank" href="https://accounts.google.com/o/oauth2/auth?<?php echo $url ?>">here</a> if you have popups blocked</small>
197
+ </p>
198
+
199
+ <div id="key">
200
+
201
+ <p>Enter your Google Authentication Code in this box. This code will be used to get an Authentication Token so you can access your website stats.</p>
202
+ <form method="post" action="<?php echo admin_url('options-general.php?page=google-analyticator.php');?>">
203
+ <?php wp_nonce_field('google-analyticator-update_settings'); ?>
204
+ <input type="text" name="key_ga_google_token" value="" style="width:450px;"/>
205
+ <input type="submit" value="Save &amp; Continue" />
206
+ </form>
207
+ </div>
208
+
209
+ <br /><br /><br />
210
+ <hr />
211
+ <br />
212
+
213
+ <p><strong>I Don't Want To Authenticate Through Google </strong> </p>
214
+
215
+ <p>If you don't want to authenticate through Google and only use the tracking capability of the plugin (<strong><u>not the dashboard functionality</u></strong>), you can do this by clicking the button below. </p>
216
+ <p>You will be asked on the next page to manually enter your Google Analytics UID.</p>
217
+ <form method="post" action="<?php echo admin_url('options-general.php?page=google-analyticator.php');?>">
218
+ <input type="hidden" name="key_ga_google_token" value="" />
219
+ <?php wp_nonce_field('google-analyticator-update_settings'); ?>
220
+ <input type="submit" value="Continue Without Authentication" />
221
+ </form>
222
+
223
+
224
+ </div>
225
+
226
+ <?php
227
+ }
228
+
229
+ // Add settings option
230
+ function ga_filter_plugin_actions($links) {
231
+ $new_links = array();
232
+
233
+ $new_links[] = '<a href="' . admin_url('options-general.php?page=google-analyticator.php').'">' . __('Settings', 'google-analyticator') . '</a>';
234
+ $new_links[] = '<a href="' . admin_url('options-general.php?page=ga_reset">') . __('Reset', 'google-analyticator') . '</a>';
235
+
236
+ return array_merge($new_links, $links);
237
+ }
238
+
239
+ function ga_do_reset()
240
+ {
241
+ // Delete all GA options.
242
+ delete_option(key_ga_status);
243
+ delete_option(key_ga_uid);
244
+ delete_option(key_ga_admin);
245
+ delete_option(key_ga_admin_disable);
246
+ delete_option(key_ga_admin_role);
247
+ delete_option(key_ga_dashboard_role);
248
+ delete_option(key_ga_adsense);
249
+ delete_option(key_ga_extra);
250
+ delete_option(key_ga_extra_after);
251
+ delete_option(key_ga_event);
252
+ delete_option(key_ga_outbound);
253
+ delete_option(key_ga_outbound_prefix);
254
+ delete_option(key_ga_downloads);
255
+ delete_option(key_ga_downloads_prefix);
256
+ delete_option(key_ga_sitespeed);
257
+ delete_option(key_ga_widgets);
258
+ delete_option('ga_defaults');
259
+ delete_option('ga_google_token');
260
+ delete_option('ga_google_authtoken');
261
+ delete_option('ga_profileid');
262
+
263
+
264
+
265
+ wp_redirect( admin_url( 'options-general.php?page=ga_activate' ) );
266
+ exit;
267
+ }
268
+
269
+ function ga_reset(){ /* Wont ever run. */ }
270
+
271
+
272
+ function ga_options_page() {
273
+
274
+ // If we are a postback, store the options
275
+ if (isset($_POST['info_update'])) {
276
+ # Verify nonce
277
+ check_admin_referer('google-analyticator-update_settings');
278
+
279
+ update_option('ga_defaults', 'no');
280
+
281
+
282
+ // Update the status
283
+ $ga_status = $_POST[key_ga_status];
284
+ if (($ga_status != ga_enabled) && ($ga_status != ga_disabled))
285
+ $ga_status = ga_status_default;
286
+ update_option(key_ga_status, $ga_status);
287
+
288
+ // Update the UID
289
+ $ga_uid = $_POST[key_ga_uid];
290
+ if ($ga_uid == '')
291
+ $ga_uid = ga_uid_default;
292
+ update_option(key_ga_uid, $ga_uid);
293
+
294
+ // Update the admin logging
295
+ $ga_admin = $_POST[key_ga_admin];
296
+ if (($ga_admin != ga_enabled) && ($ga_admin != ga_disabled))
297
+ $ga_admin = ga_admin_default;
298
+ update_option(key_ga_admin, $ga_admin);
299
+
300
+ // Update the admin disable setting
301
+ $ga_admin_disable = $_POST[key_ga_admin_disable];
302
+ if ( $ga_admin_disable == '' )
303
+ $ga_admin_disable = ga_admin_disable_default;
304
+ update_option(key_ga_admin_disable, $ga_admin_disable);
305
+
306
+ // Update the admin level
307
+ if ( array_key_exists(key_ga_admin_role, $_POST) ) {
308
+ $ga_admin_role = $_POST[key_ga_admin_role];
309
+ } else {
310
+ $ga_admin_role = "";
311
+ }
312
+ update_option(key_ga_admin_role, $ga_admin_role);
313
+
314
+ // Update the dashboard level
315
+ if ( array_key_exists(key_ga_dashboard_role, $_POST) ) {
316
+ $ga_dashboard_role = $_POST[key_ga_dashboard_role];
317
+ } else {
318
+ $ga_dashboard_role = "";
319
+ }
320
+ update_option(key_ga_dashboard_role, $ga_dashboard_role);
321
+
322
+ // Update the extra tracking code
323
+ $ga_extra = $_POST[key_ga_extra];
324
+ update_option(key_ga_extra, $ga_extra);
325
+
326
+ // Update the extra after tracking code
327
+ $ga_extra_after = $_POST[key_ga_extra_after];
328
+ update_option(key_ga_extra_after, $ga_extra_after);
329
+
330
+ // Update the adsense key
331
+ $ga_adsense = $_POST[key_ga_adsense];
332
+ update_option(key_ga_adsense, $ga_adsense);
333
+
334
+ // Update the event tracking
335
+ $ga_event = $_POST[key_ga_event];
336
+ if (($ga_event != ga_enabled) && ($ga_event != ga_disabled))
337
+ $ga_event = ga_event_default;
338
+ update_option(key_ga_event, $ga_event);
339
+
340
+ // Update the outbound tracking
341
+ $ga_outbound = $_POST[key_ga_outbound];
342
+ if (($ga_outbound != ga_enabled) && ($ga_outbound != ga_disabled))
343
+ $ga_outbound = ga_outbound_default;
344
+ update_option(key_ga_outbound, $ga_outbound);
345
+
346
+ // Update the outbound prefix
347
+ $ga_outbound_prefix = $_POST[key_ga_outbound_prefix];
348
+ if ($ga_outbound_prefix == '')
349
+ $ga_outbound_prefix = ga_outbound_prefix_default;
350
+ update_option(key_ga_outbound_prefix, $ga_outbound_prefix);
351
+
352
+ // Update the download tracking code
353
+ $ga_downloads = $_POST[key_ga_downloads];
354
+ update_option(key_ga_downloads, $ga_downloads);
355
+
356
+ // Update the download prefix
357
+ $ga_downloads_prefix = $_POST[key_ga_downloads_prefix];
358
+ if ($ga_downloads_prefix == '')
359
+ $ga_downloads_prefix = ga_downloads_prefix_default;
360
+ update_option(key_ga_downloads_prefix, $ga_downloads_prefix);
361
+
362
+ // Update the widgets option
363
+ $ga_widgets = $_POST[key_ga_widgets];
364
+ if (($ga_widgets != ga_enabled) && ($ga_widgets != ga_disabled))
365
+ $ga_widgets = ga_widgets_default;
366
+ update_option(key_ga_widgets, $ga_widgets);
367
+
368
+
369
+ // Update the sitespeed option
370
+ $ga_sitespeed = $_POST[key_ga_sitespeed];
371
+ if (($ga_sitespeed != ga_enabled) && ($ga_sitespeed != ga_disabled))
372
+ $ga_sitespeed = ga_widgets_default;
373
+ update_option(key_ga_sitespeed, $ga_sitespeed);
374
+
375
+ // Give an updated message
376
+ echo "<div class='updated fade'><p><strong>" . __('Google Analyticator settings saved.', 'google-analyticator') . "</strong></p></div>";
377
+ }
378
+
379
+
380
+ // Are we using the auth system?
381
+ $useAuth = ( get_option( 'ga_google_token' ) == '' ? false : true );
382
+
383
+
384
+ // Output the options page
385
+ ?>
386
+
387
+ <div class="wrap">
388
+
389
+ <h2><?php _e('Google Analyticator Settings', 'google-analyticator'); ?></h2>
390
+
391
+ <form method="post" action="<?php echo admin_url('options-general.php?page=google-analyticator.php');?>">
392
+ <?php
393
+ # Add a nonce
394
+ wp_nonce_field('google-analyticator-update_settings');
395
+ ?>
396
+
397
+ <?php if (get_option(key_ga_status) == ga_disabled) { ?>
398
+ <div style="margin:10px auto; border:3px #f00 solid; background-color:#fdd; color:#000; padding:10px; text-align:center;">
399
+ <?php _e('Google Analytics integration is currently <strong>DISABLED</strong>.', 'google-analyticator'); ?>
400
+ </div>
401
+ <?php } ?>
402
+ <?php if ((get_option(key_ga_uid) == "XX-XXXXX-X") && (get_option(key_ga_status) != ga_disabled)) { ?>
403
+ <div style="margin:10px auto; border:3px #f00 solid; background-color:#fdd; color:#000; padding:10px; text-align:center;">
404
+ <?php _e('Google Analytics integration is currently enabled, but you did not enter a UID. Tracking will not occur.', 'google-analyticator'); ?>
405
+ </div>
406
+ <?php } ?>
407
+ <table class="form-table" cellspacing="2" cellpadding="5" width="100%">
408
+
409
+ <tr>
410
+ <td colspan="2">
411
+ <h3><?php _e('Basic Settings', 'google-analyticator'); ?></h3>
412
+ </td>
413
+ </tr>
414
+
415
+ <tr>
416
+ <th width="30%" valign="top" style="padding-top: 10px;">
417
+ <label for="<?php echo key_ga_status ?>"><?php _e('Google Analytics logging is', 'google-analyticator'); ?>:</label>
418
+ </th>
419
+ <td>
420
+ <?php
421
+ echo "<select name='".key_ga_status."' id='".key_ga_status."'>\n";
422
+
423
+ echo "<option value='".ga_enabled."'";
424
+ if(get_option(key_ga_status) == ga_enabled)
425
+ echo " selected='selected'";
426
+ echo ">" . __('Enabled', 'google-analyticator') . "</option>\n";
427
+
428
+ echo "<option value='".ga_disabled."'";
429
+ if(get_option(key_ga_status) == ga_disabled)
430
+ echo" selected='selected'";
431
+ echo ">" . __('Disabled', 'google-analyticator') . "</option>\n";
432
+
433
+ echo "</select>\n";
434
+ ?>
435
+ </td>
436
+ </tr>
437
+ <tr id="ga_ajax_accounts">
438
+ <th valign="top" style="padding-top: 10px;">
439
+ <label for="<?php echo key_ga_uid; ?>"><?php _e('Google Analytics UID', 'google-analyticator'); ?>:</label>
440
+ </th>
441
+ <td>
442
+ <?php
443
+
444
+ if( $useAuth ):
445
+
446
+ $uids = ga_get_analytics_accounts();
447
+
448
+ echo "<select name='".key_ga_uid."'> ";
449
+
450
+ foreach($uids as $id=>$domain):
451
+
452
+ echo '<option value="'.$id.'"';
453
+ // If set in DB.
454
+ if( get_option(key_ga_uid) == $id ) { echo ' selected="selected"'; }
455
+ // Else if the domain matches the current domain & nothing set in DB.
456
+ elseif( $_SERVER['HTTP_HOST'] == $domain && ( get_option(key_ga_uid) != '' ) ) { echo ' selected="selected"'; }
457
+ echo '>'.$domain.'</option>';
458
+
459
+ endforeach;
460
+
461
+ echo '</select>';
462
+
463
+ else:
464
+
465
+ echo '<input type="text" name="'.key_ga_uid.'" value="'. get_option( key_ga_uid ) .'" />';
466
+
467
+ endif;
468
+ ?>
469
+ </td>
470
+ </tr>
471
+ <tr>
472
+ <td colspan="2">
473
+ <h3><?php _e('Tracking Settings', 'google-analyticator'); ?></h3>
474
+ </td>
475
+ </tr>
476
+ <tr>
477
+ <th width="30%" valign="top" style="padding-top: 10px;">
478
+ <label for="<?php echo key_ga_admin ?>"><?php _e('Track all logged in WordPress users', 'google-analyticator'); ?>:</label>
479
+ </th>
480
+ <td>
481
+ <?php
482
+ echo "<select name='".key_ga_admin."' id='".key_ga_admin."'>\n";
483
+
484
+ echo "<option value='".ga_enabled."'";
485
+ if(get_option(key_ga_admin) == ga_enabled)
486
+ echo " selected='selected'";
487
+ echo ">" . __('Yes', 'google-analyticator') . "</option>\n";
488
+
489
+ echo "<option value='".ga_disabled."'";
490
+ if(get_option(key_ga_admin) == ga_disabled)
491
+ echo" selected='selected'";
492
+ echo ">" . __('No', 'google-analyticator') . "</option>\n";
493
+
494
+ echo "</select>\n";
495
+
496
+ ?>
497
+ <p class="setting-description"><?php _e('Selecting "no" to this option will prevent logged in WordPress users from showing up on your Google Analytics reports. This setting will prevent yourself or other users from showing up in your Analytics reports. Use the next setting to determine what user groups to exclude.', 'google-analyticator'); ?></p>
498
+ </td>
499
+ </tr>
500
+ <tr>
501
+ <th width="30%" valign="top" style="padding-top: 10px;">
502
+ <label for="<?php echo key_ga_admin_role ?>"><?php _e('User roles to not track', 'google-analyticator'); ?>:</label>
503
+ </th>
504
+ <td>
505
+ <?php
506
+ global $wp_roles;
507
+ $roles = $wp_roles->get_names();
508
+ $selected_roles = get_option(key_ga_admin_role);
509
+ if ( !is_array($selected_roles) ) $selected_roles = array();
510
+
511
+ # Loop through the roles
512
+ foreach ( $roles AS $role => $name ) {
513
+ echo '<input type="checkbox" value="' . $role . '" name="' . key_ga_admin_role . '[]"';
514
+ if ( in_array($role, $selected_roles) )
515
+ echo " checked='checked'";
516
+ $name_pos = strpos($name, '|');
517
+ $name = ( $name_pos ) ? substr($name, 0, $name_pos) : $name;
518
+ echo ' /> ' . _x($name, 'User role') . '<br />';
519
+ }
520
+ ?>
521
+ <p class="setting-description"><?php _e('Specifies the user roles to not include in your WordPress Analytics report. If a user is logged into WordPress with one of these roles, they will not show up in your Analytics report.', 'google-analyticator'); ?></p>
522
+ </td>
523
+ </tr>
524
+ <tr>
525
+ <th width="30%" valign="top" style="padding-top: 10px;">
526
+ <label for="<?php echo key_ga_admin_disable ?>"><?php _e('Method to prevent tracking', 'google-analyticator'); ?>:</label>
527
+ </th>
528
+ <td>
529
+ <?php
530
+ echo "<select name='".key_ga_admin_disable."' id='".key_ga_admin_disable."'>\n";
531
+
532
+ echo "<option value='remove'";
533
+ if(get_option(key_ga_admin_disable) == 'remove')
534
+ echo " selected='selected'";
535
+ echo ">" . __('Remove', 'google-analyticator') . "</option>\n";
536
+
537
+ echo "<option value='admin'";
538
+ if(get_option(key_ga_admin_disable) == 'admin')
539
+ echo" selected='selected'";
540
+ echo ">" . __('Use \'admin\' variable', 'google-analyticator') . "</option>\n";
541
+
542
+ echo "</select>\n";
543
+ ?>
544
+ <p class="setting-description"><?php _e('Selecting the "Remove" option will physically remove the tracking code from logged in users. Selecting the "Use \'admin\' variable" option will assign a variable called \'admin\' to logged in users. This option will allow Google Analytics\' site overlay feature to work, but you will have to manually configure Google Analytics to exclude tracking from pageviews with the \'admin\' variable.', 'google-analyticator'); ?></p>
545
+ </td>
546
+ </tr>
547
+ <tr>
548
+ <th width="30%" valign="top" style="padding-top: 10px;">
549
+ <label for="<?php echo key_ga_sitespeed ?>"><?php _e('Site speed tracking', 'google-analyticator'); ?>:</label>
550
+ </th>
551
+ <td>
552
+ <?php
553
+ echo "<select name='".key_ga_sitespeed."' id='".key_ga_sitespeed."'>\n";
554
+
555
+ echo "<option value='".ga_enabled."'";
556
+ if(get_option(key_ga_sitespeed) == ga_enabled)
557
+ echo " selected='selected'";
558
+ echo ">" . __('Enabled', 'google-analyticator') . "</option>\n";
559
+
560
+ echo "<option value='".ga_disabled."'";
561
+ if(get_option(key_ga_sitespeed) == ga_disabled)
562
+ echo" selected='selected'";
563
+ echo ">" . __('Disabled', 'google-analyticator') . "</option>\n";
564
+
565
+ echo "</select>\n";
566
+ ?>
567
+ <p class="setting-description"><?php _e('Disabling this option will turn off the tracking required for <a href="http://www.google.com/support/analyticshelp/bin/answer.py?hl=en&answer=1205784&topic=1120718&utm_source=gablog&utm_medium=blog&utm_campaign=newga-blog&utm_content=sitespeed">Google Analytics\' Site Speed tracking report</a>.', 'google-analyticator'); ?></p>
568
+ </td>
569
+ </tr>
570
+ <tr>
571
+ <td colspan="2">
572
+ <h3>Link Tracking Settings</h3>
573
+ </td>
574
+ </tr>
575
+ <tr>
576
+ <th width="30%" valign="top" style="padding-top: 10px;">
577
+ <label for="<?php echo key_ga_outbound ?>"><?php _e('Outbound link tracking', 'google-analyticator'); ?>:</label>
578
+ </th>
579
+ <td>
580
+ <?php
581
+ echo "<select name='".key_ga_outbound."' id='".key_ga_outbound."'>\n";
582
+
583
+ echo "<option value='".ga_enabled."'";
584
+ if(get_option(key_ga_outbound) == ga_enabled)
585
+ echo " selected='selected'";
586
+ echo ">" . __('Enabled', 'google-analyticator') . "</option>\n";
587
+
588
+ echo "<option value='".ga_disabled."'";
589
+ if(get_option(key_ga_outbound) == ga_disabled)
590
+ echo" selected='selected'";
591
+ echo ">" . __('Disabled', 'google-analyticator') . "</option>\n";
592
+
593
+ echo "</select>\n";
594
+ ?>
595
+ <p class="setting-description"><?php _e('Disabling this option will turn off the tracking of outbound links. It\'s recommended not to disable this option unless you\'re a privacy advocate (now why would you be using Google Analytics in the first place?) or it\'s causing some kind of weird issue.', 'google-analyticator'); ?></p>
596
+ </td>
597
+ </tr>
598
+ <tr>
599
+ <th width="30%" valign="top" style="padding-top: 10px;">
600
+ <label for="<?php echo key_ga_event ?>"><?php _e('Event tracking', 'google-analyticator'); ?>:</label>
601
+ </th>
602
+ <td>
603
+ <?php
604
+ echo "<select name='".key_ga_event."' id='".key_ga_event."'>\n";
605
+
606
+ echo "<option value='".ga_enabled."'";
607
+ if(get_option(key_ga_event) == ga_enabled)
608
+ echo " selected='selected'";
609
+ echo ">" . __('Enabled', 'google-analyticator') . "</option>\n";
610
+
611
+ echo "<option value='".ga_disabled."'";
612
+ if(get_option(key_ga_event) == ga_disabled)
613
+ echo" selected='selected'";
614
+ echo ">" . __('Disabled', 'google-analyticator') . "</option>\n";
615
+
616
+ echo "</select>\n";
617
+ ?>
618
+ <p class="setting-description"><?php _e('Enabling this option will treat outbound links and downloads as events instead of pageviews. Since the introduction of <a href="https://developers.google.com/analytics/devguides/collection/gajs/eventTrackerGuide">event tracking in Analytics</a>, this is the recommended way to track these types of actions. Only disable this option if you must use the old pageview tracking method.', 'google-analyticator'); ?></p>
619
+ </td>
620
+ </tr>
621
+ <tr>
622
+ <th valign="top" style="padding-top: 10px;">
623
+ <label for="<?php echo key_ga_downloads; ?>"><?php _e('Download extensions to track', 'google-analyticator'); ?>:</label>
624
+ </th>
625
+ <td>
626
+ <?php
627
+ echo "<input type='text' size='50' ";
628
+ echo "name='".key_ga_downloads."' ";
629
+ echo "id='".key_ga_downloads."' ";
630
+ echo "value='".stripslashes(get_option(key_ga_downloads))."' />\n";
631
+ ?>
632
+ <p class="setting-description"><?php _e('Enter any extensions of files you would like to be tracked as a download. For example to track all MP3s and PDFs enter <strong>mp3,pdf</strong>. <em>Outbound link tracking must be enabled for downloads to be tracked.</em>', 'google-analyticator'); ?></p>
633
+ </td>
634
+ </tr>
635
+ <tr>
636
+ <th valign="top" style="padding-top: 10px;">
637
+ <label for="<?php echo key_ga_outbound_prefix; ?>"><?php _e('Prefix external links with', 'google-analyticator'); ?>:</label>
638
+ </th>
639
+ <td>
640
+ <?php
641
+ echo "<input type='text' size='50' ";
642
+ echo "name='".key_ga_outbound_prefix."' ";
643
+ echo "id='".key_ga_outbound_prefix."' ";
644
+ echo "value='".stripslashes(get_option(key_ga_outbound_prefix))."' />\n";
645
+ ?>
646
+ <p class="setting-description"><?php _e('Enter a name for the section tracked external links will appear under. This option has no effect if event tracking is enabled.', 'google-analyticator'); ?></em></p>
647
+ </td>
648
+ </tr>
649
+ <tr>
650
+ <th valign="top" style="padding-top: 10px;">
651
+ <label for="<?php echo key_ga_downloads_prefix; ?>"><?php _e('Prefix download links with', 'google-analyticator'); ?>:</label>
652
+ </th>
653
+ <td>
654
+ <?php
655
+ echo "<input type='text' size='50' ";
656
+ echo "name='".key_ga_downloads_prefix."' ";
657
+ echo "id='".key_ga_downloads_prefix."' ";
658
+ echo "value='".stripslashes(get_option(key_ga_downloads_prefix))."' />\n";
659
+ ?>
660
+ <p class="setting-description"><?php _e('Enter a name for the section tracked download links will appear under. This option has no effect if event tracking is enabled.', 'google-analyticator'); ?></em></p>
661
+ </td>
662
+ </tr>
663
+ <tr>
664
+ <th valign="top" style="padding-top: 10px;">
665
+ <label for="<?php echo key_ga_adsense; ?>"><?php _e('Google Adsense ID', 'google-analyticator'); ?>:</label>
666
+ </th>
667
+ <td>
668
+ <?php
669
+ echo "<input type='text' size='50' ";
670
+ echo "name='".key_ga_adsense."' ";
671
+ echo "id='".key_ga_adsense."' ";
672
+ echo "value='".get_option(key_ga_adsense)."' />\n";
673
+ ?>
674
+ <p class="setting-description"><?php _e('Enter your Google Adsense ID assigned by Google Analytics in this box. This enables Analytics tracking of Adsense information if your Adsense and Analytics accounts are linked.', 'google-analyticator'); ?></p>
675
+ </td>
676
+ </tr>
677
+ <tr>
678
+ <td colspan="2">
679
+ <h3>Additional Tracking Code </h3>
680
+ </td>
681
+ </tr>
682
+ <tr>
683
+ <th valign="top" style="padding-top: 10px;">
684
+ <label for="<?php echo key_ga_extra; ?>"><?php _e('Additional tracking code', 'google-analyticator'); ?><br />(<?php _e('before tracker initialization', 'google-analyticator'); ?>):</label>
685
+ </th>
686
+ <td>
687
+ <?php
688
+ echo "<textarea cols='50' rows='8' ";
689
+ echo "name='".key_ga_extra."' ";
690
+ echo "id='".key_ga_extra."'>";
691
+ echo stripslashes(get_option(key_ga_extra))."</textarea>\n";
692
+ ?>
693
+ <p class="setting-description"><?php _e('Enter any additional lines of tracking code that you would like to include in the Google Analytics tracking script. The code in this section will be displayed <strong>before</strong> the Google Analytics tracker is initialized.', 'google-analyticator'); ?></p>
694
+ </td>
695
+ </tr>
696
+ <tr>
697
+ <th valign="top" style="padding-top: 10px;">
698
+ <label for="<?php echo key_ga_extra_after; ?>"><?php _e('Additional tracking code', 'google-analyticator'); ?><br />(<?php _e('after tracker initialization', 'google-analyticator'); ?>):</label>
699
+ </th>
700
+ <td>
701
+ <?php
702
+ echo "<textarea cols='50' rows='8' ";
703
+ echo "name='".key_ga_extra_after."' ";
704
+ echo "id='".key_ga_extra_after."'>";
705
+ echo stripslashes(get_option(key_ga_extra_after))."</textarea>\n";
706
+ ?>
707
+ <p class="setting-description"><?php _e('Enter any additional lines of tracking code that you would like to include in the Google Analytics tracking script. The code in this section will be displayed <strong>after</strong> the Google Analytics tracker is initialized.', 'google-analyticator'); ?></p>
708
+ </td>
709
+ </tr>
710
+ <tr>
711
+ <td colspan="2">
712
+ <h3>Admin Dashboard Widgets</h3>
713
+ <?php if(!$useAuth): ?>
714
+ <div style="margin:10px auto; border:3px #f00 solid; background-color:#fdd; color:#000; padding:10px; text-align:center;">
715
+ <?php _e('You have not authenticated with Google - you cannot use dashboard widgets! Reset the plugin to authenticate..', 'google-analyticator'); ?>
716
+ </div>
717
+ <?php endif;?>
718
+ </td>
719
+ </tr>
720
+ <tr<?php if(!$useAuth){echo ' style="display:none"';}?>>
721
+ <th width="30%" valign="top" style="padding-top: 10px;">
722
+ <label for="<?php echo key_ga_widgets; ?>"><?php _e('Include widgets', 'google-analyticator'); ?>:</label>
723
+ </th>
724
+ <td>
725
+ <?php
726
+ echo "<select name='".key_ga_widgets."' id='".key_ga_widgets."'>\n";
727
+
728
+ echo "<option value='".ga_enabled."'";
729
+ if(get_option(key_ga_widgets) == ga_enabled)
730
+ echo " selected='selected'";
731
+ echo ">" . __('Enabled', 'google-analyticator') . "</option>\n";
732
+
733
+ echo "<option value='".ga_disabled."'";
734
+ if(get_option(key_ga_widgets) == ga_disabled)
735
+ echo" selected='selected'";
736
+ echo ">" . __('Disabled', 'google-analyticator') . "</option>\n";
737
+
738
+ echo "</select>\n";
739
+ ?>
740
+ <p class="setting-description"><?php _e('Disabling this option will completely remove the Dashboard Summary widget and the theme Stats widget. Use this option if you would prefer to not see the widgets.', 'google-analyticator'); ?></p>
741
+ </td>
742
+ </tr>
743
+ <tr<?php if(!$useAuth){echo ' style="display:none"';}?>>
744
+ <th width="30%" valign="top" style="padding-top: 10px;">
745
+ <label for="<?php echo key_ga_dashboard_role ?>"><?php _e('User roles that can see the dashboard widget', 'google-analyticator'); ?>:</label>
746
+ </th>
747
+ <td>
748
+ <?php
749
+ global $wp_roles;
750
+ $roles = $wp_roles->get_names();
751
+ $selected_roles = get_option(key_ga_dashboard_role);
752
+ if ( !is_array($selected_roles) ) $selected_roles = array();
753
+
754
+ # Loop through the roles
755
+ foreach ( $roles AS $role => $name ) {
756
+ echo '<input type="checkbox" value="' . $role . '" name="' . key_ga_dashboard_role . '[]"';
757
+ if ( in_array($role, $selected_roles) )
758
+ echo " checked='checked'";
759
+ $name_pos = strpos($name, '|');
760
+ $name = ( $name_pos ) ? substr($name, 0, $name_pos) : $name;
761
+ echo ' /> ' . _x($name, 'User role') . '<br />';
762
+ }
763
+ ?>
764
+ <p class="setting-description"><?php _e('Specifies the user roles that can see the dashboard widget. If a user is not in one of these role groups, they will not see the dashboard widget.', 'google-analyticator'); ?></p>
765
+ </td>
766
+ </tr>
767
+
768
+ </table>
769
+ <p class="submit">
770
+ <input type="submit" name="info_update" value="<?php _e('Save Changes', 'google-analyticator'); ?>" />
771
+ </p>
772
+
773
+ <a href="<?php echo admin_url('/options-general.php?page=ga_reset'); ?>"><?php _e('Deauthorize &amp; Reset Google Analyticator.', 'google-analyticator'); ?></a>
774
+
775
+ </form>
776
+
777
+
778
+ <?php if (!get_option('wpm_o_user_id')): ?>
779
+ <img src="<?php echo plugins_url('wlcms-plugin-advert.png', __FILE__ ); ?>" alt="Learn how to make WordPress better" />
780
+ <form method="post" onsubmit="return quickValidate()" action="http://www.aweber.com/scripts/addlead.pl" target="_blank" >
781
+ <div style="display: none;">
782
+ <input type="hidden" name="meta_web_form_id" value="672327302" />
783
+ <input type="hidden" name="meta_split_id" value="" />
784
+ <input type="hidden" name="listname" value="vumpublic2" />
785
+ <input type="hidden" name="redirect" value="http://www.aweber.com/thankyou-coi.htm?m=video" id="redirect_9567c93ed4b6fb0c7cd9247553c362eb" />
786
+ <input type="hidden" name="meta_adtracking" value="ga-plugin" />
787
+ <input type="hidden" name="meta_message" value="1" />
788
+ <input type="hidden" name="meta_required" value="name,email" />
789
+ <input type="hidden" name="meta_tooltip" value="" />
790
+ </div>
791
+ <table style="text-align:center;margin-left: 20px;">
792
+ <tr>
793
+ <td><label class="previewLabel" for="awf_field-37978044"><strong>Name: </strong></label><input id="sub_name" type="text" name="name" class="text" tabindex="500" value="" /></td>
794
+ <td><label class="previewLabel" for="awf_field-37978045"><strong>Email: </strong></label> <input class="text" id="sub_email" type="text" name="email" tabindex="501" value="" /></td>
795
+ <td><span class="submit"><input name="submit" type="image" alt="submit" tabindex="502" src="<?php echo plugins_url('download-button.png', __FILE__); ?>" width="157" height="40" style="background: none; border: 0;" /></span></td>
796
+ </tr>
797
+ <tr>
798
+ <td colspan="3" style="padding-top: 20px;">
799
+ <a title="Privacy Policy" href="http://www.aweber.com/permission.htm" target="_blank"><img src="<?php echo plugins_url('privacy.png', __FILE__); ?>" alt="" title="" /></a>
800
+ </td>
801
+ </tr>
802
+ </table>
803
+ </form>
804
+ <?php endif;?>
805
+
806
+ <script type="text/javascript">
807
+ function quickValidate()
808
+ {
809
+ if (! jQuery('#sub_name').val() )
810
+ {
811
+ alert('Your Name is required');
812
+ return false;
813
+ }
814
+ if(! jQuery('#sub_email').val() )
815
+ {
816
+ alert('Your Email is required');
817
+ return false;
818
+ }
819
+
820
+ return true;
821
+
822
+ }
823
+ </script>
824
+
825
+ </div>
826
+ </form>
827
+
828
+ <?php
829
+ }
830
+
831
+ function ga_sort_account_list($a, $b) {
832
+ return strcmp($a['title'],$b['title']);
833
+ }
834
+
835
+ /**
836
+ * Checks if the WordPress API is a valid method for selecting an account
837
+ *
838
+ * @return a list of accounts if available, false if none available
839
+ **/
840
+ function ga_get_analytics_accounts()
841
+ {
842
+ $accounts = array();
843
+
844
+ # Get the class for interacting with the Google Analytics
845
+ require_once('class.analytics.stats.php');
846
+
847
+ # Create a new Gdata call
848
+ if ( isset($_POST['token']) && $_POST['token'] != '' )
849
+ $stats = new GoogleAnalyticsStats($_POST['token']);
850
+ elseif ( trim(get_option('ga_google_token')) != '' )
851
+ $stats = new GoogleAnalyticsStats();
852
+ else
853
+ return false;
854
+
855
+ # Check if Google sucessfully logged in
856
+ if ( ! $stats->checkLogin() )
857
+ return false;
858
+
859
+ # Get a list of accounts
860
+ $accounts = $stats->getAllProfiles();
861
+
862
+ natcasesort ($accounts);
863
+
864
+ # Return the account array if there are accounts
865
+ if ( count($accounts) > 0 )
866
+ return $accounts;
867
+ else
868
+ return false;
869
+ }
870
+
871
+ /**
872
+ * Add http_build_query if it doesn't exist already
873
+ **/
874
+ if ( !function_exists('http_build_query') ) {
875
+ function http_build_query($params, $key = null)
876
+ {
877
+ $ret = array();
878
+
879
+ foreach( (array) $params as $name => $val ) {
880
+ $name = urlencode($name);
881
+
882
+ if ( $key !== null )
883
+ $name = $key . "[" . $name . "]";
884
+
885
+ if ( is_array($val) || is_object($val) )
886
+ $ret[] = http_build_query($val, $name);
887
+ elseif ($val !== null)
888
+ $ret[] = $name . "=" . urlencode($val);
889
+ }
890
+
891
+ return implode("&", $ret);
892
+ }
893
+ }
894
+
895
+ /**
896
+ * Echos out the core Analytics tracking code
897
+ **/
898
+ function add_google_analytics()
899
+ {
900
+ # Fetch variables used in the tracking code
901
+ $uid = stripslashes(get_option(key_ga_uid));
902
+ $extra = stripslashes(get_option(key_ga_extra));
903
+ $extra_after = stripslashes(get_option(key_ga_extra_after));
904
+ $extensions = str_replace (",", "|", get_option(key_ga_downloads));
905
+
906
+ # Determine if the GA is enabled and contains a valid UID
907
+ if ( ( get_option(key_ga_status) != ga_disabled ) && ( $uid != "XX-XXXXX-X" ) )
908
+ {
909
+ # Determine if the user is an admin, and should see the tracking code
910
+ if ( ( get_option(key_ga_admin) == ga_enabled || !ga_current_user_is(get_option(key_ga_admin_role)) ) && get_option(key_ga_admin_disable) == 'remove' || get_option(key_ga_admin_disable) != 'remove' )
911
+ {
912
+ # Disable the tracking code on the post preview page
913
+ if ( !function_exists("is_preview") || ( function_exists("is_preview") && !is_preview() ) )
914
+ {
915
+ # Add the notice that Google Analyticator tracking is enabled
916
+ echo "<!-- Google Analytics Tracking by Google Analyticator " . GOOGLE_ANALYTICATOR_VERSION . ": http://www.videousermanuals.com/google-analyticator/ -->\n";
917
+
918
+ # Add the Adsense data if specified
919
+ if ( get_option(key_ga_adsense) != '' )
920
+ echo '<script type="text/javascript">window.google_analytics_uacct = "' . get_option(key_ga_adsense) . "\";</script>\n";
921
+
922
+ # Include the file types to track
923
+ $extensions = explode(',', stripslashes(get_option(key_ga_downloads)));
924
+ $ext = "";
925
+ foreach ( $extensions AS $extension )
926
+ $ext .= "'$extension',";
927
+ $ext = substr($ext, 0, -1);
928
+
929
+ # Include the link tracking prefixes
930
+ $outbound_prefix = stripslashes(get_option(key_ga_outbound_prefix));
931
+ $downloads_prefix = stripslashes(get_option(key_ga_downloads_prefix));
932
+ $event_tracking = get_option(key_ga_event);
933
+
934
+ ?>
935
+ <script type="text/javascript">
936
+ var analyticsFileTypes = [<?php echo strtolower($ext); ?>];
937
+ <?php if ( $event_tracking != 'enabled' ) { ?>
938
+ var analyticsOutboundPrefix = '/<?php echo $outbound_prefix; ?>/';
939
+ var analyticsDownloadsPrefix = '/<?php echo $downloads_prefix; ?>/';
940
+ <?php } ?>
941
+ var analyticsEventTracking = '<?php echo $event_tracking; ?>';
942
+ </script>
943
+ <?php
944
+ # Add the first part of the core tracking code
945
+ ?>
946
+ <script type="text/javascript">
947
+ var _gaq = _gaq || [];
948
+ _gaq.push(['_setAccount', '<?php echo $uid; ?>']);
949
+ _gaq.push(['_addDevId', 'i9k95']); // Google Analyticator App ID with Google
950
+ <?php
951
+
952
+ # Add any tracking code before the trackPageview
953
+ do_action('google_analyticator_extra_js_before');
954
+ if ( '' != $extra )
955
+ echo " $extra\n";
956
+
957
+ # Add the track pageview function
958
+ echo " _gaq.push(['_trackPageview']);\n";
959
+
960
+ # Add the site speed tracking
961
+ if ( get_option(key_ga_sitespeed) == ga_enabled )
962
+ echo " _gaq.push(['_trackPageLoadTime']);\n";
963
+
964
+ # Disable page tracking if admin is logged in
965
+ if ( ( get_option(key_ga_admin) == ga_disabled ) && ( ga_current_user_is(get_option(key_ga_admin_role)) ) )
966
+ echo " _gaq.push(['_setCustomVar', 'admin']);\n";
967
+
968
+ # Add any tracking code after the trackPageview
969
+ do_action('google_analyticator_extra_js_after');
970
+ if ( '' != $extra_after )
971
+ echo " $extra_after\n";
972
+
973
+ # Add the final section of the tracking code
974
+ ?>
975
+
976
+ (function() {
977
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
978
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
979
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
980
+ })();
981
+ </script>
982
+ <?php
983
+ }
984
+ } else {
985
+ # Add the notice that Google Analyticator tracking is enabled
986
+ echo "<!-- Google Analytics Tracking by Google Analyticator " . GOOGLE_ANALYTICATOR_VERSION . ": http://ronaldheft.com/code/analyticator/ -->\n";
987
+ echo " <!-- " . __('Tracking code is hidden, since the settings specify not to track admins. Tracking is occurring for non-admins.', 'google-analyticator') . " -->\n";
988
+ }
989
+ }
990
+ }
991
+
992
+ /**
993
+ * Adds outbound link tracking to Google Analyticator
994
+ **/
995
+ function ga_outgoing_links()
996
+ {
997
+ # Fetch the UID
998
+ $uid = stripslashes(get_option(key_ga_uid));
999
+
1000
+ # If GA is enabled and has a valid key
1001
+ if ( (get_option(key_ga_status) != ga_disabled ) && ( $uid != "XX-XXXXX-X" ) )
1002
+ {
1003
+ # If outbound tracking is enabled
1004
+ if ( get_option(key_ga_outbound) == ga_enabled )
1005
+ {
1006
+ # If this is not an admin page
1007
+ if ( !is_admin() )
1008
+ {
1009
+ # Display page tracking if user is not an admin
1010
+ if ( ( get_option(key_ga_admin) == ga_enabled || !ga_current_user_is(get_option(key_ga_admin_role)) ) && get_option(key_ga_admin_disable) == 'remove' || get_option(key_ga_admin_disable) != 'remove' )
1011
+ {
1012
+ add_action('wp_print_scripts', 'ga_external_tracking_js');
1013
+ }
1014
+ }
1015
+ }
1016
+ }
1017
+ }
1018
+
1019
+ /**
1020
+ * Adds the scripts required for outbound link tracking
1021
+ **/
1022
+ function ga_external_tracking_js()
1023
+ {
1024
+ wp_enqueue_script('ga-external-tracking', plugins_url('/google-analyticator/external-tracking.min.js'), array('jquery'), GOOGLE_ANALYTICATOR_VERSION);
1025
+ }
1026
+
1027
+ /**
1028
+ * Determines if a specific user fits a role
1029
+ **/
1030
+ function ga_current_user_is($roles)
1031
+ {
1032
+ if ( !$roles ) return false;
1033
+
1034
+ global $current_user;
1035
+ get_currentuserinfo();
1036
+ $user_id = intval( $current_user->ID );
1037
+
1038
+ if ( !$user_id ) {
1039
+ return false;
1040
+ }
1041
+ $user = new WP_User($user_id); // $user->roles
1042
+
1043
+ foreach ( $roles as $role )
1044
+ if ( in_array($role, $user->roles) ) return true;
1045
+
1046
+ return false;
1047
+ }
1048
+
1049
+
1050
  ?>
google-analytics-stats-widget.php CHANGED
@@ -1,257 +1,255 @@
1
- <?php
2
-
3
- /**
4
- * The Google Analytics Stats Widget
5
- *
6
- * Now using widget API available in WordPress 2.8
7
- * @author Spiral Web Consulting
8
- **/
9
- class GoogleStatsWidget extends WP_Widget
10
- {
11
- function GoogleStatsWidget() {
12
- $widget_ops = array('classname' => 'widget_google_stats', 'description' => __("Displays Stat Info From Google Analytics", 'google-analyticator') );
13
- $control_ops = array('width' => 400, 'height' => 400);
14
- $this->WP_Widget('googlestats', __('Google Analytics Stats', 'google-analyticator'), $widget_ops, $control_ops);
15
- }
16
-
17
- function widget($args, $instance) {
18
- extract($args);
19
- $title = apply_filters('widget_title', empty($instance['title']) ? '' : $instance['title']);
20
- $acnt = $instance['account'];
21
- $timeFrame = empty($instance['timeFrame']) ? '1' : $instance['timeFrame'];
22
- $pageBg = empty($instance['pageBg']) ? 'fff' : $instance['pageBg'];
23
- $widgetBg = empty($instance['widgetBg']) ? '999' : $instance['widgetBg'];
24
- $innerBg = empty($instance['innerBg']) ? 'fff' : $instance['innerBg'];
25
- $font = empty($instance['font']) ? '333' : $instance['font'];
26
- $line1 = empty($instance['line1']) ? 'Unique' : $instance['line1'];
27
- $line2 = empty($instance['line2']) ? 'Visitors' : $instance['line2'];
28
-
29
- # Before the widget
30
- echo $before_widget;
31
-
32
- # The title
33
- if ( $title )
34
- echo $before_title . $title . $after_title;
35
-
36
- # Make the stats chicklet
37
- echo '<!-- Data gathered from last ' . number_format($timeFrame) . ' days using Google Analyticator -->';
38
- $this->initiateBackground($pageBg, $font);
39
- $this->beginWidget($font, $widgetBg);
40
- $this->widgetInfo($this->getUniqueVisitors($acnt, $timeFrame), $line1, $line2, $innerBg, $font);
41
- $this->endWidget();
42
-
43
- # After the widget
44
- echo $after_widget;
45
- }
46
-
47
- function update($new_instance, $old_instance) {
48
- $instance = $old_instance;
49
- $instance['title'] = strip_tags(stripslashes($new_instance['title']));
50
- $instance['account'] = strip_tags(stripslashes($new_instance['account']));
51
- $instance['timeFrame'] = strip_tags(stripslashes($new_instance['timeFrame']));
52
- $instance['pageBg'] = strip_tags(stripslashes($new_instance['pageBg']));
53
- $instance['widgetBg'] = strip_tags(stripslashes($new_instance['widgetBg']));
54
- $instance['innerBg'] = strip_tags(stripslashes($new_instance['innerBg']));
55
- $instance['font'] = strip_tags(stripslashes($new_instance['font']));
56
- $instance['line1'] = strip_tags(stripslashes($new_instance['line1']));
57
- $instance['line2'] = strip_tags(stripslashes($new_instance['line2']));
58
-
59
- return $instance;
60
- }
61
-
62
- function form($instance) {
63
- //Defaults
64
- $instance = wp_parse_args( (array) $instance, array('title'=>'', 'account'=>'', 'timeFrame'=>'1', 'pageBg'=>'fff', 'widgetBg'=>'999', 'innerBg'=>'fff', 'font'=>'333', 'line1'=>'Unique', 'line2'=>'Visitors') );
65
-
66
- $title = htmlspecialchars($instance['title']);
67
- $acnt = htmlspecialchars($instance['account']);
68
- $timeFrame = htmlspecialchars($instance['timeFrame']);
69
- $pageBg = htmlspecialchars($instance['pageBg']);
70
- $widgetBg = htmlspecialchars($instance['widgetBg']);
71
- $innerBg = htmlspecialchars($instance['innerBg']);
72
- $font = htmlspecialchars($instance['font']);
73
- $line1 = htmlspecialchars($instance['line1']);
74
- $line2 = htmlspecialchars($instance['line2']);
75
-
76
- $accounts = array();
77
-
78
- # Get the current memory limit
79
- $current_mem_limit = substr(ini_get('memory_limit'), 0, -1);
80
-
81
- # Check if this limit is less than 96M, if so, increase it
82
- if ( $current_mem_limit < 96 || $current_mem_limit == '' ) {
83
- if ( function_exists('memory_get_usage') )
84
- @ini_set('memory_limit', '96M');
85
- }
86
-
87
- # Get the class for interacting with the Google Analytics
88
- require_once('class.analytics.stats.php');
89
-
90
- # Create a new Gdata call
91
- $stats = new GoogleAnalyticsStats();
92
-
93
- # Check if Google sucessfully logged in
94
- $login = $stats->checkLogin();
95
-
96
- # Get a list of accounts
97
- $accounts = $stats->getAnalyticsAccounts();
98
-
99
- # Output the options
100
- echo '<p style="text-align:right;"><label for="' . $this->get_field_name('title') . '">' . __('Title', 'google-analyticator') . ': <input style="width: 250px;" id="' . $this->get_field_id('title') . '" name="' . $this->get_field_name('title') . '" type="text" value="' . $title . '" /></label></p>';
101
- # The list of accounts
102
- echo '<p style="text-align:right;"><label for="' . $this->get_field_name('account') . '">' . __('Analytics account', 'google-analyticator') . ': ';
103
- echo '<select name="' . $this->get_field_name('account') . '" id="' . $this->get_field_id('account') . '" style="margin-top: -3px; margin-bottom: 10px;">';
104
- if ( count($accounts) > 0 )
105
- foreach ( $accounts AS $account ) { $select = ( $acnt == $account['id'] ) ? ' selected="selected"' : ''; echo '<option value="' . $account['id'] . '"' . $select . '>' . $account['title'] . '</option>'; }
106
- elseif ( $login == false )
107
- echo '<option value="">' . __('Authenticate on settings page.', 'google-analyticator') . '</option>';
108
- else
109
- echo '<option value="">' . __('No Analytics accounts available.', 'google-analyticator') . '</option>';
110
- echo '</select></label></p>';
111
- # Time frame
112
- echo '<p style="text-align:right;"><label for="' . $this->get_field_name('timeFrame') . '">' . __('Days of data to get', 'google-analyticator') . ': <input style="width: 150px;" id="' . $this->get_field_id('timeFrame') . '" name="' . $this->get_field_name('timeFrame') . '" type="text" value="' . $timeFrame . '" /></label></p>';
113
- # Page background
114
- echo '<p style="text-align:right;"><label for="' . $this->get_field_name('pageBg') . '">' . __('Page background', 'google-analyticator') . ': <input style="width: 150px;" id="' . $this->get_field_id('pageBg') . '" name="' . $this->get_field_name('pageBg') . '" type="text" value="' . $pageBg . '" /></label></p>';
115
- # Widget background
116
- echo '<p style="text-align:right;"><label for="' . $this->get_field_name('widgetBg') . '">' . __('Widget background', 'google-analyticator') . ': <input style="width: 150px;" id="' . $this->get_field_id('widgetBg') . '" name="' . $this->get_field_name('widgetBg') . '" type="text" value="' . $widgetBg . '" /></label></p>';
117
- # Inner background
118
- echo '<p style="text-align:right;"><label for="' . $this->get_field_name('innerBg') . '">' . __('Inner background', 'google-analyticator') . ': <input style="width: 150px;" id="' . $this->get_field_id('innerBg') . '" name="' . $this->get_field_name('innerBg') . '" type="text" value="' . $innerBg . '" /></label></p>';
119
- # Font color
120
- echo '<p style="text-align:right;"><label for="' . $this->get_field_name('font') . '">' . __('Font color', 'google-analyticator') . ': <input style="width: 150px;" id="' . $this->get_field_id('font') . '" name="' . $this->get_field_name('font') . '" type="text" value="' . $font . '" /></label></p>';
121
- # Text line 1
122
- echo '<p style="text-align:right;"><label for="' . $this->get_field_name('line1') . '">' . __('Line 1 text', 'google-analyticator') . ': <input style="width: 200px;" id="' . $this->get_field_id('line1') . '" name="' . $this->get_field_name('line1') . '" type="text" value="' . $line1 . '" /></label></p>';
123
- # Text line 2
124
- echo '<p style="text-align:right;"><label for="' . $this->get_field_name('line2') . '">' . __('Line 2 text', 'google-analyticator') . ': <input style="width: 200px;" id="' . $this->get_field_id('line2') . '" name="' . $this->get_field_name('line2') . '" type="text" value="' . $line2 . '" /></label></p>';
125
- }
126
-
127
- /**
128
- * This function is used to display the background color behind the widget. This is necessary
129
- * for the Google Analytics text to have the same background color as the page.
130
- *
131
- * @param $font_color - Hexadecimal value for the font color used within the Widget (does not effect "Powered By Google Analytics Text"). This effects border color as well.
132
- * @param $page_background_color - Hexadecimal value for the page background color
133
- * @return void
134
- **/
135
- function initiateBackground($page_background_color = 'FFF', $font_color = '000')
136
- {
137
- echo '<br />';
138
- echo '<div style="background:#' . $page_background_color . ';font-size:12px;color:#' . $font_color . ';font-family:\'Lucida Grande\',Helvetica,Verdana,Sans-Serif;">';
139
- }
140
-
141
- /**
142
- * This function starts the widget. The font color and widget background color are customizable.
143
- *
144
- * @param $font_color - Hexadecimal value for the font color used within the Widget (does not effect "Powered By Google Analytics Text"). This effects border color as well.
145
- * @param $widget_background_color - Hexadecimal value for the widget background color.
146
- * @return void
147
- **/
148
- function beginWidget($font_color = '000', $widget_background_color = 'FFF')
149
- {
150
- echo '<table style="width:auto!important;border-width:2px;border-color:#' . $font_color . ';border-style:solid;background:#' . $widget_background_color . ';"><tr>';
151
- }
152
-
153
- /**
154
- * This function encases the text that appears on the right hand side of the widget.
155
- * Both lines of text are customizable by each individual user.
156
- *
157
- * It also displays the visitor count that was pulled from the user's Google Analytics account.
158
- *
159
- * @param $visitor_count - Number of unique visits to the site pulled from the user's Google Analytics account.
160
- * @param $line_one - First line of text displayed on the right hand side of the widget.
161
- * @param $line_two - Second line of text displayed on the right hand side of the widget.
162
- * @param $inner_background_color - Hexadecimal value for the background color that surrounds the Visitor Count.
163
- * @param $font_color - Hexadecimal value for the font color used within the Widget (does not effect "Powered By Google Analytics Text"). This effects border color as well
164
- * @return void
165
- **/
166
- function widgetInfo($visitor_count, $line_one = 'Unique', $line_two = 'Visitors', $inner_background_color = 'FFF', $font_color = '000')
167
- {
168
-
169
- echo '<td style="width:auto!important;border-width:1px;border-color:#' . $font_color . ';border-style:solid;padding:0px 5px 0px 5px;text-align:right;background:#' . $inner_background_color . ';min-width:80px;*width:80px!important;"><div style="min-width:80px;">'. $visitor_count . '</div></td>';
170
-
171
- echo '<td style="width:auto!important;padding:0px 5px 0px 5px;text-align:center;font-size:11px;">' . $line_one . '<br />' . $line_two . '</td>';
172
-
173
- }
174
-
175
- /**
176
- * The function is used strictly for visual appearance. It also displays the Google Analytics text.
177
- *
178
- * @return void
179
- **/
180
- function endWidget()
181
- {
182
- // This closes off the widget.
183
- echo '</tr></table>';
184
-
185
- // The following is used to displayed the "Powered By Google Anayltics" text.
186
- echo '<div style="font-size:9px;color:#666666;margin-top:0px;font-family:Verdana;">Powered By <a href="http://google.com/analytics/" title="Google Analytics" style="text-decoration:none;"><img src="' . plugins_url('/google-analyticator/ga_logo.png') . '" alt="Google Analytics" style="border:0px;position:relative;top:4px;" /></a></div></div>';
187
- }
188
-
189
- /**
190
- * Grabs the cached value of the unique visits for the previous day
191
- *
192
- * @param account - the account to get the unique visitors from
193
- * @param time - the amount of days to get
194
- * @return void
195
- **/
196
- function getUniqueVisitors($account, $time = 1)
197
- {
198
- # Get the value from the database
199
- $visits = maybe_unserialize(get_option('google_stats_visits_' . $account));
200
-
201
- # Check to make sure the timeframe is an int and greater than one
202
- $time = (int) $time;
203
- if ( $time < 1 )
204
- $time = 1;
205
-
206
- # Check if the call has been made before
207
- if ( is_array($visits) ) {
208
-
209
- # Check if the last time called was within two hours, if so, return that
210
- if ( $visits['lastcalled'] > ( time() - 7200 ) )
211
- return $visits['unique'];
212
-
213
- }
214
-
215
- # If here, the call has not been made or it is expired
216
-
217
- # Get the current memory limit
218
- $current_mem_limit = substr(ini_get('memory_limit'), 0, -1);
219
-
220
- # Check if this limit is less than 96M, if so, increase it
221
- if ( $current_mem_limit < 96 || $current_mem_limit == '' ) {
222
- if ( function_exists('memory_get_usage') )
223
- @ini_set('memory_limit', '96M');
224
- }
225
-
226
- # Get the class for interacting with the Google Analytics
227
- require_once('class.analytics.stats.php');
228
-
229
- # Create a new Gdata call
230
- $stats = new GoogleAnalyticsStats();
231
-
232
- # Set the account to the one requested
233
- $stats->setAccount($account);
234
-
235
- # Get the latest stats
236
- $before = date('Y-m-d', strtotime('-' . $time . ' days'));
237
- $yesterday = date('Y-m-d', strtotime('-1 day'));
238
- $uniques = number_format($stats->getMetric('ga:visitors', $before, $yesterday));
239
-
240
- # Store the array
241
- update_option('google_stats_visits_' . $account, array('unique'=>$uniques, 'lastcalled'=>time()));
242
-
243
- # Return the visits
244
- return $uniques;
245
- }
246
-
247
- }// END class
248
-
249
- /**
250
- * Register Google Analytics Stat Widget.
251
- */
252
- function GoogleStatsWidget_init() {
253
- register_widget('GoogleStatsWidget');
254
- }
255
-
256
- add_action('widgets_init', 'GoogleStatsWidget_init');
257
  ?>
1
+ <?php
2
+
3
+ /**
4
+ * The Google Analytics Stats Widget
5
+ *
6
+ * Now using widget API available in WordPress 2.8
7
+ * @author Spiral Web Consulting
8
+ **/
9
+ class GoogleStatsWidget extends WP_Widget
10
+ {
11
+ function GoogleStatsWidget() {
12
+ $widget_ops = array('classname' => 'widget_google_stats', 'description' => __("Displays Stat Info From Google Analytics", 'google-analyticator') );
13
+ $control_ops = array('width' => 400, 'height' => 400);
14
+ $this->WP_Widget('googlestats', __('Google Analytics Stats', 'google-analyticator'), $widget_ops, $control_ops);
15
+ }
16
+
17
+ function widget($args, $instance) {
18
+ extract($args);
19
+ $title = apply_filters('widget_title', empty($instance['title']) ? '' : $instance['title']);
20
+ $acnt = $instance['account'];
21
+ $timeFrame = empty($instance['timeFrame']) ? '1' : $instance['timeFrame'];
22
+ $pageBg = empty($instance['pageBg']) ? 'fff' : $instance['pageBg'];
23
+ $widgetBg = empty($instance['widgetBg']) ? '999' : $instance['widgetBg'];
24
+ $innerBg = empty($instance['innerBg']) ? 'fff' : $instance['innerBg'];
25
+ $font = empty($instance['font']) ? '333' : $instance['font'];
26
+ $line1 = empty($instance['line1']) ? 'Unique' : $instance['line1'];
27
+ $line2 = empty($instance['line2']) ? 'Visitors' : $instance['line2'];
28
+
29
+ # Before the widget
30
+ echo $before_widget;
31
+
32
+ # The title
33
+ if ( $title )
34
+ echo $before_title . $title . $after_title;
35
+
36
+ # Make the stats chicklet
37
+ echo '<!-- Data gathered from last ' . number_format($timeFrame) . ' days using Google Analyticator -->';
38
+ $this->initiateBackground($pageBg, $font);
39
+ $this->beginWidget($font, $widgetBg);
40
+ $this->widgetInfo($this->getUniqueVisitors($acnt, $timeFrame), $line1, $line2, $innerBg, $font);
41
+ $this->endWidget();
42
+
43
+ # After the widget
44
+ echo $after_widget;
45
+ }
46
+
47
+ function update($new_instance, $old_instance) {
48
+ $instance = $old_instance;
49
+ $instance['title'] = strip_tags(stripslashes($new_instance['title']));
50
+ $instance['account'] = strip_tags(stripslashes($new_instance['account']));
51
+ $instance['timeFrame'] = strip_tags(stripslashes($new_instance['timeFrame']));
52
+ $instance['pageBg'] = strip_tags(stripslashes($new_instance['pageBg']));
53
+ $instance['widgetBg'] = strip_tags(stripslashes($new_instance['widgetBg']));
54
+ $instance['innerBg'] = strip_tags(stripslashes($new_instance['innerBg']));
55
+ $instance['font'] = strip_tags(stripslashes($new_instance['font']));
56
+ $instance['line1'] = strip_tags(stripslashes($new_instance['line1']));
57
+ $instance['line2'] = strip_tags(stripslashes($new_instance['line2']));
58
+
59
+ return $instance;
60
+ }
61
+
62
+ function form($instance) {
63
+ //Defaults
64
+ $instance = wp_parse_args( (array) $instance, array('title'=>'', 'account'=>'', 'timeFrame'=>'1', 'pageBg'=>'fff', 'widgetBg'=>'999', 'innerBg'=>'fff', 'font'=>'333', 'line1'=>'Unique', 'line2'=>'Visitors') );
65
+
66
+ $title = htmlspecialchars($instance['title']);
67
+ $acnt = htmlspecialchars($instance['account']);
68
+ $timeFrame = htmlspecialchars($instance['timeFrame']);
69
+ $pageBg = htmlspecialchars($instance['pageBg']);
70
+ $widgetBg = htmlspecialchars($instance['widgetBg']);
71
+ $innerBg = htmlspecialchars($instance['innerBg']);
72
+ $font = htmlspecialchars($instance['font']);
73
+ $line1 = htmlspecialchars($instance['line1']);
74
+ $line2 = htmlspecialchars($instance['line2']);
75
+
76
+ $accounts = array();
77
+
78
+ # Get the current memory limit
79
+ $current_mem_limit = substr(ini_get('memory_limit'), 0, -1);
80
+
81
+ # Check if this limit is less than 96M, if so, increase it
82
+ if ( $current_mem_limit < 96 || $current_mem_limit == '' ) {
83
+ if ( function_exists('memory_get_usage') )
84
+ @ini_set('memory_limit', '96M');
85
+ }
86
+
87
+ # Get the class for interacting with the Google Analytics
88
+ require_once('class.analytics.stats.php');
89
+
90
+ # Create a new Gdata call
91
+ $stats = new GoogleAnalyticsStats();
92
+
93
+ # Check if Google sucessfully logged in
94
+ $login = $stats->checkLogin();
95
+
96
+ # Get a list of accounts
97
+ //$accounts = $stats->getAnalyticsAccounts();
98
+ $accounts = $stats->getSingleProfile();
99
+
100
+ # Output the options
101
+ echo '<p style="text-align:right;"><label for="' . $this->get_field_name('title') . '">' . __('Title', 'google-analyticator') . ': <input style="width: 250px;" id="' . $this->get_field_id('title') . '" name="' . $this->get_field_name('title') . '" type="text" value="' . $title . '" /></label></p>';
102
+ # Time frame
103
+ echo '<p style="text-align:right;"><label for="' . $this->get_field_name('timeFrame') . '">' . __('Days of data to get', 'google-analyticator') . ': <input style="width: 150px;" id="' . $this->get_field_id('timeFrame') . '" name="' . $this->get_field_name('timeFrame') . '" type="text" value="' . $timeFrame . '" /></label></p>';
104
+ # Page background
105
+ echo '<p style="text-align:right;"><label for="' . $this->get_field_name('pageBg') . '">' . __('Page background', 'google-analyticator') . ': <input style="width: 150px;" id="' . $this->get_field_id('pageBg') . '" name="' . $this->get_field_name('pageBg') . '" type="text" value="' . $pageBg . '" /></label></p>';
106
+ # Widget background
107
+ echo '<p style="text-align:right;"><label for="' . $this->get_field_name('widgetBg') . '">' . __('Widget background', 'google-analyticator') . ': <input style="width: 150px;" id="' . $this->get_field_id('widgetBg') . '" name="' . $this->get_field_name('widgetBg') . '" type="text" value="' . $widgetBg . '" /></label></p>';
108
+ # Inner background
109
+ echo '<p style="text-align:right;"><label for="' . $this->get_field_name('innerBg') . '">' . __('Inner background', 'google-analyticator') . ': <input style="width: 150px;" id="' . $this->get_field_id('innerBg') . '" name="' . $this->get_field_name('innerBg') . '" type="text" value="' . $innerBg . '" /></label></p>';
110
+ # Font color
111
+ echo '<p style="text-align:right;"><label for="' . $this->get_field_name('font') . '">' . __('Font color', 'google-analyticator') . ': <input style="width: 150px;" id="' . $this->get_field_id('font') . '" name="' . $this->get_field_name('font') . '" type="text" value="' . $font . '" /></label></p>';
112
+ # Text line 1
113
+ echo '<p style="text-align:right;"><label for="' . $this->get_field_name('line1') . '">' . __('Line 1 text', 'google-analyticator') . ': <input style="width: 200px;" id="' . $this->get_field_id('line1') . '" name="' . $this->get_field_name('line1') . '" type="text" value="' . $line1 . '" /></label></p>';
114
+ # Text line 2
115
+ echo '<p style="text-align:right;"><label for="' . $this->get_field_name('line2') . '">' . __('Line 2 text', 'google-analyticator') . ': <input style="width: 200px;" id="' . $this->get_field_id('line2') . '" name="' . $this->get_field_name('line2') . '" type="text" value="' . $line2 . '" /></label></p>';
116
+ }
117
+
118
+ /**
119
+ * This function is used to display the background color behind the widget. This is necessary
120
+ * for the Google Analytics text to have the same background color as the page.
121
+ *
122
+ * @param $font_color - Hexadecimal value for the font color used within the Widget (does not effect "Powered By Google Analytics Text"). This effects border color as well.
123
+ * @param $page_background_color - Hexadecimal value for the page background color
124
+ * @return void
125
+ **/
126
+ function initiateBackground($page_background_color = 'FFF', $font_color = '000')
127
+ {
128
+ echo '<br />';
129
+ echo '<div style="background:#' . $page_background_color . ';font-size:12px;color:#' . $font_color . ';font-family:\'Lucida Grande\',Helvetica,Verdana,Sans-Serif;">';
130
+ }
131
+
132
+ /**
133
+ * This function starts the widget. The font color and widget background color are customizable.
134
+ *
135
+ * @param $font_color - Hexadecimal value for the font color used within the Widget (does not effect "Powered By Google Analytics Text"). This effects border color as well.
136
+ * @param $widget_background_color - Hexadecimal value for the widget background color.
137
+ * @return void
138
+ **/
139
+ function beginWidget($font_color = '000', $widget_background_color = 'FFF')
140
+ {
141
+ echo '<table style="width:auto!important;border-width:2px;border-color:#' . $font_color . ';border-style:solid;background:#' . $widget_background_color . ';"><tr>';
142
+ }
143
+
144
+ /**
145
+ * This function encases the text that appears on the right hand side of the widget.
146
+ * Both lines of text are customizable by each individual user.
147
+ *
148
+ * It also displays the visitor count that was pulled from the user's Google Analytics account.
149
+ *
150
+ * @param $visitor_count - Number of unique visits to the site pulled from the user's Google Analytics account.
151
+ * @param $line_one - First line of text displayed on the right hand side of the widget.
152
+ * @param $line_two - Second line of text displayed on the right hand side of the widget.
153
+ * @param $inner_background_color - Hexadecimal value for the background color that surrounds the Visitor Count.
154
+ * @param $font_color - Hexadecimal value for the font color used within the Widget (does not effect "Powered By Google Analytics Text"). This effects border color as well
155
+ * @return void
156
+ **/
157
+ function widgetInfo($visitor_count, $line_one = 'Unique', $line_two = 'Visitors', $inner_background_color = 'FFF', $font_color = '000')
158
+ {
159
+
160
+ echo '<td style="width:auto!important;border-width:1px;border-color:#' . $font_color . ';border-style:solid;padding:0px 5px 0px 5px;text-align:right;background:#' . $inner_background_color . ';min-width:80px;*width:80px!important;"><div style="min-width:80px;">'. $visitor_count . '</div></td>';
161
+
162
+ echo '<td style="width:auto!important;padding:0px 5px 0px 5px;text-align:center;font-size:11px;">' . $line_one . '<br />' . $line_two . '</td>';
163
+
164
+ }
165
+
166
+ /**
167
+ * The function is used strictly for visual appearance. It also displays the Google Analytics text.
168
+ *
169
+ * @return void
170
+ **/
171
+ function endWidget()
172
+ {
173
+ // This closes off the widget.
174
+ echo '</tr></table>';
175
+
176
+ // The following is used to displayed the "Powered By Google Anayltics" text.
177
+ echo '<div style="font-size:9px;color:#666666;margin-top:0px;font-family:Verdana;">Powered By <a href="http://google.com/analytics/" title="Google Analytics" style="text-decoration:none;"><img src="' . plugins_url('/google-analyticator/ga_logo.png') . '" alt="Google Analytics" style="border:0px;position:relative;top:4px;" /></a></div></div>';
178
+ }
179
+
180
+ /**
181
+ * Grabs the cached value of the unique visits for the previous day
182
+ *
183
+ * @param account - the account to get the unique visitors from
184
+ * @param time - the amount of days to get
185
+ * @return void
186
+ **/
187
+ function getUniqueVisitors($account, $time = 1)
188
+ {
189
+ # Get the value from the database
190
+ $visits = maybe_unserialize(get_option('google_stats_visits_' . $account));
191
+
192
+ # Check to make sure the timeframe is an int and greater than one
193
+ $time = (int) $time;
194
+ if ( $time < 1 )
195
+ $time = 1;
196
+
197
+ # Check if the call has been made before
198
+ if ( is_array($visits) ) {
199
+
200
+ # Check if the last time called was within two hours, if so, return that
201
+ if ( $visits['lastcalled'] > ( time() - 7200 ) )
202
+ return $visits['unique'];
203
+
204
+ }
205
+
206
+ # If here, the call has not been made or it is expired
207
+
208
+ # Get the current memory limit
209
+ $current_mem_limit = substr(ini_get('memory_limit'), 0, -1);
210
+
211
+ # Check if this limit is less than 96M, if so, increase it
212
+ if ( $current_mem_limit < 96 || $current_mem_limit == '' ) {
213
+ if ( function_exists('memory_get_usage') )
214
+ @ini_set('memory_limit', '96M');
215
+ }
216
+
217
+ # Get the class for interacting with the Google Analytics
218
+ require_once('class.analytics.stats.php');
219
+
220
+ # Create a new Gdata call
221
+ $stats = new GoogleAnalyticsStats();
222
+
223
+ # Set the account to the one requested
224
+ $stats->setAccount($account);
225
+
226
+ # Get the latest stats
227
+ $before = date('Y-m-d', strtotime('-' . $time . ' days'));
228
+ $yesterday = date('Y-m-d', strtotime('-1 day'));
229
+
230
+ # Check if Google sucessfully logged in
231
+ if ( ! $stats->checkLogin() )
232
+ return false;
233
+
234
+ // may need to parse this still
235
+ $result = $stats->getMetrics('ga:visitors', $before, $yesterday);
236
+ $uniques = number_format($result->totalsForAllResults['ga:visitors']);
237
+
238
+ # Store the array
239
+ update_option('google_stats_visits_' . $account, array('unique'=>$uniques, 'lastcalled'=>time()));
240
+
241
+ # Return the visits
242
+ return $uniques;
243
+ }
244
+
245
+ }// END class
246
+
247
+ /**
248
+ * Register Google Analytics Stat Widget.
249
+ */
250
+ function GoogleStatsWidget_init() {
251
+ register_widget('GoogleStatsWidget');
252
+ }
253
+
254
+ add_action('widgets_init', 'GoogleStatsWidget_init');
 
 
255
  ?>
google-analytics-summary-widget.php CHANGED
@@ -1,603 +1,617 @@
1
- <?php
2
-
3
- /**
4
- * Creates a summary widget for Google Analytics stats
5
- *
6
- * @author Ronald Heft
7
- **/
8
- class GoogleAnalyticsSummary
9
- {
10
- var $api = false;
11
- var $id = false;
12
-
13
- /**
14
- * Start the process of including the widget
15
- **/
16
- function GoogleAnalyticsSummary()
17
- {
18
- add_action('wp_dashboard_setup', array($this, 'addDashboardWidget'));
19
- add_action('admin_print_scripts-index.php', array($this, 'addJavascript'));
20
- add_action('admin_head-index.php', array($this, 'addTopJs'));
21
- add_action('wp_ajax_ga_stats_widget', array($this, 'ajaxWidget'));
22
- }
23
-
24
- /**
25
- * Add the widget to the dashboard
26
- **/
27
- function addDashboardWidget()
28
- {
29
- # Check if the user is an admin
30
- if ( ga_current_user_is(get_option(key_ga_dashboard_role)) ) {
31
- wp_add_dashboard_widget('google-analytics-summary', __('Google Analytics Summary', 'google-analyticator'), array($this, 'widget'));
32
- }
33
- }
34
-
35
- /**
36
- * Add the scripts to the admin
37
- **/
38
- function addJavascript()
39
- {
40
- # Include the Sparklines graphing library
41
- wp_enqueue_script('jquery-sparklines', plugins_url('/google-analyticator/jquery.sparkline.min.js'), array('jquery'), '1.5.1');
42
- }
43
-
44
- /**
45
- * Add the Javascript to the top
46
- **/
47
- function addTopJs()
48
- {
49
- ?>
50
- <script type="text/javascript">
51
-
52
- jQuery(document).ready(function(){
53
-
54
- // Add a link to see full stats on the Analytics website
55
- jQuery('#google-analytics-summary h3.hndle span').append('<span class="postbox-title-action"><a href="http://google.com/analytics/" class="edit-box open-box"><?php _e('View Full Stat Report', 'google-analyticator'); ?></a></span>');
56
-
57
- // Grab the widget data
58
- jQuery.ajax({
59
- type: 'post',
60
- url: 'admin-ajax.php',
61
- data: {
62
- action: 'ga_stats_widget',
63
- _ajax_nonce: '<?php echo wp_create_nonce("google-analyticator-statsWidget_get"); ?>'
64
- },
65
- success: function(html) {
66
- // Hide the loading message
67
- jQuery('#google-analytics-summary .inside small').remove();
68
-
69
- // Place the widget data in the area
70
- jQuery('#google-analytics-summary .inside .target').html(html);
71
-
72
- // Display the widget data
73
- jQuery('#google-analytics-summary .inside .target').slideDown();
74
-
75
- // Handle displaying the graph
76
- jQuery('.ga_visits').sparkline(ga_visits, { type:'line', width:'100%', height:'75px', lineColor:'#aaa', fillColor:'#f0f0f0', spotColor:false, minSpotColor:false, maxSpotColor:false, chartRangeMin:0 });
77
- }
78
- });
79
-
80
- });
81
-
82
- </script>
83
- <?php
84
- }
85
-
86
- /**
87
- * The widget display
88
- **/
89
- function widget()
90
- {
91
- echo '<small>' . __('Loading', 'google-analyticator') . '...</small>';
92
- echo '<div class="target" style="display: none;"></div>';
93
- }
94
-
95
- /**
96
- * AJAX data for the widget
97
- **/
98
- function ajaxWidget()
99
- {
100
- # Check the ajax widget
101
- check_ajax_referer('google-analyticator-statsWidget_get');
102
-
103
- # Attempt to login and get the current account
104
- $account = $this->getAnalyticsAccount();
105
- $profile_id = get_option('ga_profileid');
106
- if ( trim($profile_id) != '' ) {
107
- if ( substr($profile_id, 0, 3) == 'ga:' ) {
108
- $this->id = $profile_id;
109
- } else {
110
- $this->id = 'ga:' . $profile_id;
111
- }
112
- } else {
113
- $this->id = $account;
114
- }
115
- $this->api->setAccount($this->id);
116
-
117
- # Check that we can display the widget before continuing
118
- if ( $account == false || $this->id == false ) {
119
- # Output error message
120
- echo '<p style="margin: 0;">' . __('No Analytics account selected. Double check you are authenticated with Google on Google Analyticator\'s settings page and make sure an account is selected.', 'google-analyticator') . '</p>';
121
-
122
- # Add Javascript variable to prevent breaking the Javascript
123
- echo '<script type="text/javascript">var ga_visits = [];</script>';
124
-
125
- die();
126
- }
127
-
128
- # Add the header information for the visits graph
129
- echo '<p class="ga_visits_title" style="font-style: italic; font-family: Georgia, \'Times New Roman\', \'Bitstream Charter\', Times, serif; margin-top: 0px; color: #777; font-size: 13px;">' . __('Visits Over the Past 30 Days', 'google-analyticator') . '</p>';
130
-
131
- # Add the sparkline for the past 30 days
132
- $this->getVisitsGraph();
133
-
134
- # Add the summary header
135
- echo '<p style="font-style: italic; font-family: Georgia, \'Times New Roman\', \'Bitstream Charter\', Times, serif; color: #777; font-size: 13px;">' . __('Site Usage', 'google-analyticator') . '</p>';
136
-
137
- # Add the visitor summary
138
- $this->getSiteUsage();
139
-
140
- # Add the top 5 posts header
141
- echo '<p style="font-style: italic; font-family: Georgia, \'Times New Roman\', \'Bitstream Charter\', Times, serif; color: #777; font-size: 13px;">' . __('Top Pages', 'google-analyticator') . '</p>';
142
-
143
- # Add the top 5 posts
144
- $this->getTopPages();
145
-
146
- # Add the tab information
147
- echo '<table width="100%"><tr><td width="50%" valign="top">';
148
-
149
- # Add the top 5 referrers header
150
- echo '<p style="font-style: italic; font-family: Georgia, \'Times New Roman\', \'Bitstream Charter\', Times, serif; color: #777; font-size: 13px;">' . __('Top Referrers', 'google-analyticator') . '</p>';
151
-
152
- # Add the referrer information
153
- $this->getTopReferrers();
154
-
155
- # Add the second column
156
- echo '</td><td valign="top">';
157
-
158
- # Add the top 5 search header
159
- echo '<p style="font-style: italic; font-family: Georgia, \'Times New Roman\', \'Bitstream Charter\', Times, serif; color: #777; font-size: 13px;">' . __('Top Searches', 'google-analyticator') . '</p>';
160
-
161
- # Add the search information
162
- $this->getTopSearches();
163
-
164
- # Close the table
165
- echo '</td></tr></table>';
166
-
167
- die();
168
- }
169
-
170
- /**
171
- * Get the current analytics account
172
- *
173
- * @return the analytics account
174
- **/
175
- function getAnalyticsAccount()
176
- {
177
- $accounts = array();
178
-
179
- # Get the class for interacting with the Google Analytics
180
- require_once('class.analytics.stats.php');
181
-
182
- # Create a new Gdata call
183
- $this->api = new GoogleAnalyticsStats();
184
-
185
- # Check if Google sucessfully logged in
186
- if ( ! $this->api->checkLogin() )
187
- return false;
188
-
189
- # Get a list of accounts
190
- $accounts = $this->api->getAnalyticsAccounts();
191
-
192
- # Check if we actually have accounts
193
- if ( !is_array($accounts) )
194
- return false;
195
-
196
- # Check if we have a list of accounts
197
- if ( count($accounts) <= 0 )
198
- return false;
199
-
200
- # Loop throught the account and return the current account
201
- foreach ( $accounts AS $account ) {
202
-
203
- # Check if the UID matches the selected UID
204
- if ( $account['ga:webPropertyId'] == get_option('ga_uid') )
205
- return $account['id'];
206
-
207
- }
208
-
209
- return false;
210
- }
211
-
212
- /**
213
- * Get the visitors graph
214
- **/
215
- function getVisitsGraph()
216
- {
217
- # Get the value from the database
218
- $cached = maybe_unserialize(get_option('google_stats_visitsGraph_' . $this->id));
219
- $updated = false;
220
-
221
- # Check if the call has been made before
222
- if ( is_array($cached) ) {
223
-
224
- # Check if the last time called was within two hours, if so, mark to not retrieve and grab the stats array
225
- if ( $cached['lastcalled'] > ( time() - 7200 ) ) {
226
- $updated = true;
227
- $stats = $cached['stats'];
228
- }
229
-
230
- }
231
-
232
- # If the stats need to be updated
233
- if ( ! $updated ) {
234
-
235
- # Get the metrics needed to build the visits graph
236
- $before = date('Y-m-d', strtotime('-31 days'));
237
- $yesterday = date('Y-m-d', strtotime('-1 day'));
238
- $stats = $this->api->getMetrics('ga:visits', $before, $yesterday, 'ga:date', 'ga:date');
239
-
240
- # Store the serialized stats in the database
241
- update_option('google_stats_visitsGraph_' . $this->id, array('stats'=>$stats, 'lastcalled'=>time()));
242
-
243
- }
244
-
245
- # Create a list of the data points for graphing
246
- $data = '';
247
- $max = 0;
248
-
249
- # Check the size of the stats array
250
- if ( !isset($stats) || !is_array($stats) || count($stats) <= 0 ) {
251
- $data = '0,0';
252
- } else {
253
- foreach ( $stats AS $stat ) {
254
- # Verify the number is numeric
255
- if ( is_numeric($stat['ga:visits']) )
256
- $data .= $stat['ga:visits'] . ',';
257
- else
258
- $data .= '0,';
259
-
260
- # Update the max value if greater
261
- if ( $max < $stat['ga:visits'] )
262
- $max = $stat['ga:visits'];
263
- }
264
-
265
- # Shorten the string to remove the last comma
266
- $data = substr($data, 0, -1);
267
- }
268
-
269
- # Add a fake stat if need be
270
- if ( !isset($stat['ga:visits']) )
271
- $stat['ga:visits'] = 0;
272
-
273
- # Output the graph
274
- echo '<script type="text/javascript">var ga_visits = [' . $data . '];</script>';
275
- echo '<span class="ga_visits" title="' . sprintf(__('The most visits on a single day was %d. Yesterday there were %d visits.', 'google-analyticator'), $max, $stat['ga:visits']) . '"></span>';
276
- }
277
-
278
- /**
279
- * Get the site usage
280
- **/
281
- function getSiteUsage()
282
- {
283
- # Get the value from the database
284
- $cached = maybe_unserialize(get_option('google_stats_siteUsage_' . $this->id));
285
- $updated = false;
286
-
287
- # Check if the call has been made before
288
- if ( is_array($cached) ) {
289
-
290
- # Check if the last time called was within two hours, if so, mark to not retrieve and grab the stats array
291
- if ( $cached['lastcalled'] > ( time() - 7200 ) ) {
292
- $updated = true;
293
- $stats = $cached['stats'];
294
- }
295
-
296
- }
297
-
298
- # If the stats need to be updated
299
- if ( ! $updated ) {
300
-
301
- # Get the metrics needed to build the usage table
302
- $before = date('Y-m-d', strtotime('-31 days'));
303
- $yesterday = date('Y-m-d', strtotime('-1 day'));
304
- $stats = $this->api->getMetrics('ga:visits,ga:bounces,ga:entrances,ga:pageviews,ga:timeOnSite,ga:newVisits', $before, $yesterday);
305
-
306
- # Store the serialized stats in the database
307
- update_option('google_stats_siteUsage_' . $this->id, array('stats'=>$stats, 'lastcalled'=>time()));
308
-
309
- }
310
-
311
- # Create the site usage table
312
- if ( isset($stats[0]) ) {
313
- ?>
314
- <table width="100%">
315
- <tr>
316
- <td width=""><strong><?php echo number_format($stats[0]['ga:visits']); ?></strong></td>
317
- <td width=""><?php _e('Visits', 'google-analyticator'); ?></td>
318
- <?php if ( $stats[0]['ga:entrances'] <= 0 ) { ?>
319
- <td width="20%"><strong>0.00%</strong></td>
320
- <?php } else { ?>
321
- <td width="20%"><strong><?php echo number_format(round(($stats[0]['ga:bounces']/$stats[0]['ga:entrances'])*100, 2), 2); ?>%</strong></td>
322
- <?php } ?>
323
- <td width="30%"><?php _e('Bounce Rate', 'google-analyticator'); ?></td>
324
- </tr>
325
- <tr>
326
- <td><strong><?php echo number_format($stats[0]['ga:pageviews']); ?></strong></td>
327
- <td><?php _e('Pageviews', 'google-analyticator'); ?></td>
328
- <?php if ( $stats[0]['ga:visits'] <= 0 ) { ?>
329
- <td><strong>00:00:00</strong></td>
330
- <?php } else { ?>
331
- <td><strong><?php echo $this->sec2Time($stats[0]['ga:timeOnSite']/$stats[0]['ga:visits']); ?></strong></td>
332
- <?php } ?>
333
- <td><?php _e('Avg. Time on Site', 'google-analyticator'); ?></td>
334
- </tr>
335
- <tr>
336
- <?php if ( $stats[0]['ga:visits'] <= 0 ) { ?>
337
- <td><strong>0.00</strong></td>
338
- <?php } else { ?>
339
- <td><strong><?php echo number_format(round($stats[0]['ga:pageviews']/$stats[0]['ga:visits'], 2), 2); ?></strong></td>
340
- <?php } ?>
341
- <td><?php _e('Pages/Visit', 'google-analyticator'); ?></td>
342
- <?php if ( $stats[0]['ga:visits'] <= 0 ) { ?>
343
- <td><strong>0.00%</strong></td>
344
- <?php } else { ?>
345
- <td><strong><?php echo number_format(round(($stats[0]['ga:newVisits']/$stats[0]['ga:visits'])*100, 2), 2); ?>%</strong></td>
346
- <?php } ?>
347
- <td><?php _e('% New Visits', 'google-analyticator'); ?></td>
348
- </tr>
349
- </table>
350
- <?php
351
- }
352
- }
353
-
354
- /**
355
- * Get the top pages
356
- **/
357
- function getTopPages()
358
- {
359
- # Get the value from the database
360
- $cached = maybe_unserialize(get_option('google_stats_topPages_' . $this->id));
361
- $updated = false;
362
-
363
- # Check if the call has been made before
364
- if ( is_array($cached) ) {
365
-
366
- # Check if the last time called was within two hours, if so, mark to not retrieve and grab the stats array
367
- if ( $cached['lastcalled'] > ( time() - 7200 ) ) {
368
- $updated = true;
369
- $stats = $cached['stats'];
370
- }
371
-
372
- }
373
-
374
- # If the stats need to be updated
375
- if ( ! $updated ) {
376
-
377
- # Get the metrics needed to build the top pages
378
- $before = date('Y-m-d', strtotime('-31 days'));
379
- $yesterday = date('Y-m-d', strtotime('-1 day'));
380
- $stats = $this->api->getMetrics('ga:pageviews', $before, $yesterday, 'ga:pageTitle,ga:pagePath', '-ga:pageviews', 'ga:pagePath!%3D%2F', '10');
381
-
382
- # Store the serialized stats in the database
383
- update_option('google_stats_topPages_' . $this->id, array('stats'=>$stats, 'lastcalled'=>time()));
384
-
385
- }
386
-
387
- # Check the size of the stats array
388
- if ( count($stats) <= 0 || !is_array($stats) ) {
389
- echo '<p>' . __('There is no data for view.', 'google-analyticator') . '</p>';
390
- } else {
391
- # Build the top pages list
392
- echo '<ol>';
393
-
394
- # Set variables needed to correct (not set) bug
395
- $new_stats = array();
396
- $notset_stats = array();
397
-
398
- # Loop through each stat and create a new array
399
- foreach ( $stats AS $stat ) {
400
- # If the stat is not set
401
- if ( $stat['ga:pageTitle'] == '(not set)' ) {
402
- # Add it to separate array
403
- $notset_stats[] = $stat;
404
- } else {
405
- # Add it to new array with index set
406
- $new_stats[$stat['ga:pagePath']] = $stat;
407
- }
408
- }
409
-
410
- # Loop through all the (not set) stats and attempt to add them to their correct stat
411
- foreach ( $notset_stats AS $stat ) {
412
- # If the stat has a "partner"
413
- if ( $new_stats[$stat['ga:pagePath']] != NULL ) {
414
- # Add the pageviews to the stat
415
- $new_stats[$stat['ga:pagePath']]['ga:pageviews'] = $new_stats[$stat['ga:pagePath']]['ga:pageviews'] + $stat['ga:pageviews'];
416
- } else {
417
- # Stat goes to the ether since we couldn't find a partner (if anyone reads this and has a suggestion to improve, let me know)
418
- }
419
- }
420
-
421
- # Renew new_stats back to stats
422
- $stats = $new_stats;
423
-
424
- # Sort the stats array, since adding the (not set) items may have changed the order
425
- usort($stats, array($this, 'statSort'));
426
-
427
- # Since we can no longer rely on the API as a limiter, we need to keep track of this ourselves
428
- $stat_count = 0;
429
-
430
- # Loop through each stat for display
431
- foreach ( $stats AS $stat ) {
432
- echo '<li><a href="' . esc_url($stat['ga:pagePath']) . '">' . esc_html($stat['ga:pageTitle']) . '</a> - ' . number_format($stat['ga:pageviews']) . ' ' . __('Views', 'google-analyticator') . '</li>';
433
-
434
- # Increase the stat counter
435
- $stat_count++;
436
-
437
- # Stop at 5
438
- if ( $stat_count >= 5 )
439
- break;
440
- }
441
-
442
- # Finish the list
443
- echo '</ol>';
444
- }
445
- }
446
-
447
- /**
448
- * Get the top referrers
449
- **/
450
- function getTopReferrers()
451
- {
452
- # Get the value from the database
453
- $cached = maybe_unserialize(get_option('google_stats_topReferrers_' . $this->id));
454
- $updated = false;
455
-
456
- # Check if the call has been made before
457
- if ( is_array($cached) ) {
458
-
459
- # Check if the last time called was within two hours, if so, mark to not retrieve and grab the stats array
460
- if ( $cached['lastcalled'] > ( time() - 7200 ) ) {
461
- $updated = true;
462
- $stats = $cached['stats'];
463
- }
464
-
465
- }
466
-
467
- # If the stats need to be updated
468
- if ( ! $updated ) {
469
-
470
- # Get the metrics needed to build the top referrers
471
- $before = date('Y-m-d', strtotime('-31 days'));
472
- $yesterday = date('Y-m-d', strtotime('-1 day'));
473
- $stats = $this->api->getMetrics('ga:visits', $before, $yesterday, 'ga:source,ga:medium', '-ga:visits', 'ga:medium%3D%3Dreferral', '5');
474
-
475
- # Store the serialized stats in the database
476
- update_option('google_stats_topReferrers_' . $this->id, array('stats'=>$stats, 'lastcalled'=>time()));
477
-
478
- }
479
-
480
- # Check the size of the stats array
481
- if ( count($stats) <= 0 || !is_array($stats) ) {
482
- echo '<p>' . __('There is no data for view.', 'google-analyticator') . '</p>';
483
- } else {
484
- # Build the top pages list
485
- echo '<ol>';
486
-
487
- # Loop through each stat
488
- foreach ( $stats AS $stat ) {
489
- echo '<li><strong>' . esc_html($stat['ga:source']) . '</strong> - ' . number_format($stat['ga:visits']) . ' ' . __('Visits', 'google-analyticator') . '</li>';
490
- }
491
-
492
- # Finish the list
493
- echo '</ol>';
494
- }
495
- }
496
-
497
- /**
498
- * Get the top searches
499
- **/
500
- function getTopSearches()
501
- {
502
- # Get the value from the database
503
- $cached = maybe_unserialize(get_option('google_stats_topSearches_' . $this->id));
504
- $updated = false;
505
-
506
- # Check if the call has been made before
507
- if ( is_array($cached) ) {
508
-
509
- # Check if the last time called was within two hours, if so, mark to not retrieve and grab the stats array
510
- if ( $cached['lastcalled'] > ( time() - 7200 ) ) {
511
- $updated = true;
512
- $stats = $cached['stats'];
513
- }
514
-
515
- }
516
-
517
- # If the stats need to be updated
518
- if ( ! $updated ) {
519
-
520
- # Get the metrics needed to build the top searches
521
- $before = date('Y-m-d', strtotime('-31 days'));
522
- $yesterday = date('Y-m-d', strtotime('-1 day'));
523
- $stats = $this->api->getMetrics('ga:visits', $before, $yesterday, 'ga:keyword', '-ga:visits', 'ga:keyword!%3D(not%20set)', '5');
524
-
525
- # Store the serialized stats in the database
526
- update_option('google_stats_topSearches_' . $this->id, array('stats'=>$stats, 'lastcalled'=>time()));
527
-
528
- }
529
-
530
- # Check the size of the stats array
531
- if ( count($stats) <= 0 || !is_array($stats) ) {
532
- echo '<p>' . __('There is no data for view.', 'google-analyticator') . '</p>';
533
- } else {
534
- # Build the top pages list
535
- echo '<ol>';
536
-
537
- # Loop through each stat
538
- foreach ( $stats AS $stat ) {
539
- echo '<li><strong>' . esc_html($stat['ga:keyword']) . '</strong> - ' . number_format($stat['ga:visits']) . ' ' . __('Visits', 'google-analyticator') . '</li>';
540
- }
541
-
542
- # Finish the list
543
- echo '</ol>';
544
- }
545
- }
546
-
547
- /**
548
- * Sort a set of stats in descending order
549
- *
550
- * @return how the stat should be sorted
551
- **/
552
- function statSort($x, $y)
553
- {
554
- if ( $x['ga:pageviews'] == $y['ga:pageviews'] )
555
- return 0;
556
- elseif ( $x['ga:pageviews'] < $y['ga:pageviews'] )
557
- return 1;
558
- else
559
- return -1;
560
- }
561
-
562
- /**
563
- * Convert second to a time format
564
- **/
565
- function sec2Time($time)
566
- {
567
- # Check if numeric
568
- if ( is_numeric($time) ) {
569
- $value = array(
570
- "years" => '00',
571
- "days" => '00',
572
- "hours" => '00',
573
- "minutes" => '00',
574
- "seconds" => '00'
575
- );
576
- if ( $time >= 31556926 ) {
577
- $value["years"] = floor($time/31556926);
578
- $time = ($time%31556926);
579
- }
580
- if ( $time >= 86400 ) {
581
- $value["days"] = floor($time/86400);
582
- $time = ($time%86400);
583
- }
584
- if ( $time >= 3600 ) {
585
- $value["hours"] = str_pad(floor($time/3600), 2, 0, STR_PAD_LEFT);
586
- $time = ($time%3600);
587
- }
588
- if ( $time >= 60 ) {
589
- $value["minutes"] = str_pad(floor($time/60), 2, 0, STR_PAD_LEFT);
590
- $time = ($time%60);
591
- }
592
- $value["seconds"] = str_pad(floor($time), 2, 0, STR_PAD_LEFT);
593
-
594
- # Get the hour:minute:second version
595
- return $value['hours'] . ':' . $value['minutes'] . ':' . $value['seconds'];
596
- } else {
597
- return false;
598
- }
599
- }
600
-
601
- } // END class
602
-
603
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Creates a summary widget for Google Analytics stats
5
+ *
6
+ * @author Ronald Heft
7
+ **/
8
+ class GoogleAnalyticsSummary
9
+ {
10
+ var $api = false;
11
+ var $id = false;
12
+
13
+ /**
14
+ * Start the process of including the widget
15
+ **/
16
+ function GoogleAnalyticsSummary()
17
+ {
18
+ add_action('wp_dashboard_setup', array($this, 'addDashboardWidget'));
19
+ add_action('admin_print_scripts-index.php', array($this, 'addJavascript'));
20
+ add_action('admin_head-index.php', array($this, 'addTopJs'));
21
+ add_action('wp_ajax_ga_stats_widget', array($this, 'ajaxWidget'));
22
+ }
23
+
24
+ /**
25
+ * Add the widget to the dashboard
26
+ **/
27
+ function addDashboardWidget()
28
+ {
29
+ # Check if the user is an admin
30
+ if ( ga_current_user_is(get_option(key_ga_dashboard_role)) ) {
31
+ wp_add_dashboard_widget('google-analytics-summary', __('Google Analytics Summary', 'google-analyticator'), array($this, 'widget'));
32
+ }
33
+ }
34
+
35
+ /**
36
+ * Add the scripts to the admin
37
+ **/
38
+ function addJavascript()
39
+ {
40
+ # Include the Sparklines graphing library
41
+ wp_enqueue_script('jquery-sparklines', plugins_url('/google-analyticator/jquery.sparkline.min.js'), array('jquery'), '1.5.1');
42
+ }
43
+
44
+ /**
45
+ * Add the Javascript to the top
46
+ **/
47
+ function addTopJs()
48
+ {
49
+ ?>
50
+ <script type="text/javascript">
51
+
52
+ jQuery(document).ready(function(){
53
+
54
+ // Add a link to see full stats on the Analytics website
55
+ jQuery('#google-analytics-summary h3.hndle span').append('<span class="postbox-title-action"><a href="http://google.com/analytics/" class="edit-box open-box"><?php _e('View Full Stat Report', 'google-analyticator'); ?></a></span>');
56
+
57
+ // Grab the widget data
58
+ jQuery.ajax({
59
+ type: 'post',
60
+ url: 'admin-ajax.php',
61
+ data: {
62
+ action: 'ga_stats_widget',
63
+ _ajax_nonce: '<?php echo wp_create_nonce("google-analyticator-statsWidget_get"); ?>'
64
+ },
65
+ success: function(html) {
66
+ // Hide the loading message
67
+ jQuery('#google-analytics-summary .inside small').remove();
68
+
69
+ // Place the widget data in the area
70
+ jQuery('#google-analytics-summary .inside .target').html(html);
71
+
72
+ // Display the widget data
73
+ jQuery('#google-analytics-summary .inside .target').slideDown();
74
+
75
+ // Handle displaying the graph
76
+ jQuery('.ga_visits').sparkline(ga_visits, { type:'line', width:'100%', height:'75px', lineColor:'#aaa', fillColor:'#f0f0f0', spotColor:false, minSpotColor:false, maxSpotColor:false, chartRangeMin:0 });
77
+ }
78
+ });
79
+
80
+ });
81
+
82
+ </script>
83
+ <?php
84
+ }
85
+
86
+ /**
87
+ * The widget display
88
+ **/
89
+ function widget()
90
+ {
91
+ echo '<small>' . __('Loading', 'google-analyticator') . '...</small>';
92
+ echo '<div class="target" style="display: none;"></div>';
93
+ }
94
+
95
+ /**
96
+ * AJAX data for the widget
97
+ **/
98
+ function ajaxWidget()
99
+ {
100
+ # Check the ajax widget
101
+ check_ajax_referer('google-analyticator-statsWidget_get');
102
+
103
+ # Attempt to login and get the current account
104
+ $account = $this->getAnalyticsAccount();
105
+
106
+ $profile_id = get_option('ga_profileid');
107
+ if ( trim($profile_id) != '' ) {
108
+ if ( substr($profile_id, 0, 3) == 'ga:' ) {
109
+ $this->id = $profile_id;
110
+ } else {
111
+ $this->id = 'ga:' . $profile_id;
112
+ }
113
+ } else {
114
+ $this->id = $account;
115
+ }
116
+
117
+ $this->api->setAccount($this->id);
118
+
119
+ # Check that we can display the widget before continuing
120
+ if ( $account == false || $this->id == false ) {
121
+ # Output error message
122
+ echo '<p style="margin: 0;">' . __('No Analytics account selected. Double check you are authenticated with Google on Google Analyticator\'s settings page and make sure an account is selected.', 'google-analyticator') . '</p>';
123
+
124
+ # Add Javascript variable to prevent breaking the Javascript
125
+ echo '<script type="text/javascript">var ga_visits = [];</script>';
126
+
127
+ die();
128
+ }
129
+
130
+ # Add the header information for the visits graph
131
+ echo '<p class="ga_visits_title" style="font-style: italic; font-family: Georgia, \'Times New Roman\', \'Bitstream Charter\', Times, serif; margin-top: 0px; color: #777; font-size: 13px;">' . __('Visits Over the Past 30 Days', 'google-analyticator') . '</p>';
132
+
133
+ # Add the sparkline for the past 30 days
134
+ $this->getVisitsGraph();
135
+
136
+ # Add the summary header
137
+ echo '<p style="font-style: italic; font-family: Georgia, \'Times New Roman\', \'Bitstream Charter\', Times, serif; color: #777; font-size: 13px;">' . __('Site Usage', 'google-analyticator') . '</p>';
138
+
139
+ # Add the visitor summary
140
+ $this->getSiteUsage();
141
+
142
+ # Add the top 5 posts header
143
+ echo '<p style="font-style: italic; font-family: Georgia, \'Times New Roman\', \'Bitstream Charter\', Times, serif; color: #777; font-size: 13px;">' . __('Top Pages', 'google-analyticator') . '</p>';
144
+
145
+ # Add the top 5 posts
146
+ $this->getTopPages();
147
+
148
+ # Add the tab information
149
+ echo '<table width="100%"><tr><td width="50%" valign="top">';
150
+
151
+ # Add the top 5 referrers header
152
+ echo '<p style="font-style: italic; font-family: Georgia, \'Times New Roman\', \'Bitstream Charter\', Times, serif; color: #777; font-size: 13px;">' . __('Top Referrers', 'google-analyticator') . '</p>';
153
+
154
+ # Add the referrer information
155
+ $this->getTopReferrers();
156
+
157
+ # Add the second column
158
+ echo '</td><td valign="top">';
159
+
160
+ # Add the top 5 search header
161
+ echo '<p style="font-style: italic; font-family: Georgia, \'Times New Roman\', \'Bitstream Charter\', Times, serif; color: #777; font-size: 13px;">' . __('Top Searches', 'google-analyticator') . '</p>';
162
+
163
+ # Add the search information
164
+ $this->getTopSearches();
165
+
166
+ # Close the table
167
+ echo '</td></tr></table>';
168
+
169
+ die();
170
+ }
171
+
172
+ /**
173
+ * Get the current analytics account
174
+ *
175
+ * @return the analytics account
176
+ **/
177
+ function getAnalyticsAccount()
178
+ {
179
+ $accounts = array();
180
+
181
+ # Get the class for interacting with the Google Analytics
182
+ require_once('class.analytics.stats.php');
183
+
184
+ # Create a new Gdata call
185
+ $this->api = new GoogleAnalyticsStats();
186
+
187
+ # Check if Google sucessfully logged in
188
+ if ( ! $this->api->checkLogin() )
189
+ return false;
190
+
191
+ # Get a list of accounts
192
+ //$accounts = $this->api->getAnalyticsAccounts();
193
+ $accounts = $this->api->getSingleProfile();
194
+
195
+ # Check if we actually have accounts
196
+ if ( !is_array($accounts) )
197
+ return false;
198
+
199
+ # Check if we have a list of accounts
200
+ if ( count($accounts) <= 0 )
201
+ return false;
202
+
203
+ # Loop throught the account and return the current account
204
+ foreach ( $accounts AS $account ) {
205
+ # Check if the UID matches the selected UID
206
+ if ( $account['ga:webPropertyId'] == get_option('ga_uid') )
207
+ return $account['id'];
208
+ }
209
+
210
+ return false;
211
+ }
212
+
213
+ /**
214
+ * Get the visitors graph
215
+ **/
216
+ function getVisitsGraph()
217
+ {
218
+ # Get the value from the database
219
+ $cached = maybe_unserialize(get_option('google_stats_visitsGraph_' . $this->id));
220
+ $updated = false;
221
+
222
+ # Check if the call has been made before
223
+ if ( is_array($cached) ) {
224
+
225
+ # Check if the last time called was within two hours, if so, mark to not retrieve and grab the stats array
226
+ if ( $cached['lastcalled'] > ( time() - 7200 ) ) {
227
+ $updated = true;
228
+ $stats = $cached['stats'];
229
+ }
230
+
231
+ }
232
+
233
+ # If the stats need to be updated
234
+ if ( ! $updated ) {
235
+
236
+ # Get the metrics needed to build the visits graph
237
+ $before = date('Y-m-d', strtotime('-31 days'));
238
+ $yesterday = date('Y-m-d', strtotime('-1 day'));
239
+
240
+ $stats = $this->api->getMetrics('ga:visits', $before, $yesterday, 'ga:date', 'ga:date');
241
+
242
+ # Store the serialized stats in the database
243
+ update_option('google_stats_visitsGraph_' . $this->id, array('stats'=>$stats, 'lastcalled'=>time()));
244
+
245
+ }
246
+
247
+ # Create a list of the data points for graphing
248
+ $data = '';
249
+ $max = 0;
250
+
251
+ $rows = $stats->getRows();
252
+
253
+ # Check the size of the stats array
254
+ if ( !isset($rows) || !is_array($rows) || count($rows) <= 0 ) {
255
+ $data = '0,0';
256
+ } else {
257
+ foreach ( $rows AS $stat ) {
258
+ # Verify the number is numeric
259
+ if ( is_numeric($stat[1]) )
260
+ $data .= $stat[1] . ',';
261
+ else
262
+ $data .= '0,';
263
+
264
+ # Update the max value if greater
265
+ if ( $max < $stat[1] )
266
+ $max = $stat[1];
267
+
268
+ }
269
+
270
+ $yesterday_count = $rows[count($rows)-1][1];
271
+
272
+ # Shorten the string to remove the last comma
273
+ $data = substr($data, 0, -1);
274
+ }
275
+
276
+ # Add a fake stat if need be
277
+ if ( !isset($stat[1]) )
278
+ $stat[1] = 0;
279
+
280
+ # Output the graph
281
+ echo '<script type="text/javascript">var ga_visits = [' . $data . '];</script>';
282
+ echo '<span class="ga_visits" title="' . sprintf(__('The most visits on a single day was %d. Yesterday there were %d visits.', 'google-analyticator'), $max, $yesterday_count) . '"></span>';
283
+ }
284
+
285
+ /**
286
+ * Get the site usage
287
+ **/
288
+ function getSiteUsage()
289
+ {
290
+ # Get the value from the database
291
+ $cached = maybe_unserialize(get_option('google_stats_siteUsage_' . $this->id));
292
+ $updated = false;
293
+
294
+ # Check if the call has been made before
295
+ if ( is_array($cached) ) {
296
+
297
+ # Check if the last time called was within two hours, if so, mark to not retrieve and grab the stats array
298
+ if ( $cached['lastcalled'] > ( time() - 7200 ) ) {
299
+ $updated = true;
300
+ $stats = $cached['stats'];
301
+ }
302
+
303
+ }
304
+
305
+ # If the stats need to be updated
306
+ if ( ! $updated ) {
307
+
308
+ # Get the metrics needed to build the usage table
309
+ $before = date('Y-m-d', strtotime('-31 days'));
310
+ $yesterday = date('Y-m-d', strtotime('-1 day'));
311
+ $stats = $this->api->getMetrics('ga:visits,ga:bounces,ga:entrances,ga:pageviews,ga:timeOnSite,ga:newVisits', $before, $yesterday);
312
+
313
+ # Store the serialized stats in the database
314
+ update_option('google_stats_siteUsage_' . $this->id, array('stats'=>$stats, 'lastcalled'=>time()));
315
+
316
+ }
317
+
318
+ # Create the site usage table
319
+ if ( isset($stats->totalsForAllResults) ) {
320
+ ?>
321
+ <table width="100%">
322
+ <tr>
323
+ <td width=""><strong><?php echo number_format($stats->totalsForAllResults['ga:visits']); ?></strong></td>
324
+ <td width=""><?php _e('Visits', 'google-analyticator'); ?></td>
325
+ <?php if ( $stats->totalsForAllResults['ga:entrances'] <= 0 ) { ?>
326
+ <td width="20%"><strong>0.00%</strong></td>
327
+ <?php } else { ?>
328
+ <td width="20%"><strong><?php echo number_format(round(($stats->totalsForAllResults['ga:bounces']/$stats->totalsForAllResults['ga:entrances'])*100, 2), 2); ?>%</strong></td>
329
+ <?php } ?>
330
+ <td width="30%"><?php _e('Bounce Rate', 'google-analyticator'); ?></td>
331
+ </tr>
332
+ <tr>
333
+ <td><strong><?php echo number_format($stats->totalsForAllResults['ga:pageviews']); ?></strong></td>
334
+ <td><?php _e('Pageviews', 'google-analyticator'); ?></td>
335
+ <?php if ( $stats->totalsForAllResults['ga:visits'] <= 0 ) { ?>
336
+ <td><strong>00:00:00</strong></td>
337
+ <?php } else { ?>
338
+ <td><strong><?php echo $this->sec2Time($stats->totalsForAllResults['ga:timeOnSite']/$stats->totalsForAllResults['ga:visits']); ?></strong></td>
339
+ <?php } ?>
340
+ <td><?php _e('Avg. Time on Site', 'google-analyticator'); ?></td>
341
+ </tr>
342
+ <tr>
343
+ <?php if ( $stats->totalsForAllResults['ga:visits'] <= 0 ) { ?>
344
+ <td><strong>0.00</strong></td>
345
+ <?php } else { ?>
346
+ <td><strong><?php echo number_format(round($stats->totalsForAllResults['ga:pageviews']/$stats->totalsForAllResults['ga:visits'], 2), 2); ?></strong></td>
347
+ <?php } ?>
348
+ <td><?php _e('Pages/Visit', 'google-analyticator'); ?></td>
349
+ <?php if ( $stats->totalsForAllResults['ga:visits'] <= 0 ) { ?>
350
+ <td><strong>0.00%</strong></td>
351
+ <?php } else { ?>
352
+ <td><strong><?php echo number_format(round(($stats->totalsForAllResults['ga:newVisits']/$stats->totalsForAllResults['ga:visits'])*100, 2), 2); ?>%</strong></td>
353
+ <?php } ?>
354
+ <td><?php _e('% New Visits', 'google-analyticator'); ?></td>
355
+ </tr>
356
+ </table>
357
+ <?php
358
+ }
359
+ }
360
+
361
+ /**
362
+ * Get the top pages
363
+ **/
364
+ function getTopPages()
365
+ {
366
+ # Get the value from the database
367
+ $cached = maybe_unserialize(get_option('google_stats_topPages_' . $this->id));
368
+ $updated = false;
369
+
370
+ # Check if the call has been made before
371
+ if ( is_array($cached) ) {
372
+
373
+ # Check if the last time called was within two hours, if so, mark to not retrieve and grab the stats array
374
+ if ( $cached['lastcalled'] > ( time() - 7200 ) ) {
375
+ $updated = true;
376
+ $stats = $cached['stats'];
377
+ }
378
+
379
+ }
380
+
381
+ # If the stats need to be updated
382
+ if ( ! $updated ) {
383
+
384
+ # Get the metrics needed to build the top pages
385
+ $before = date('Y-m-d', strtotime('-31 days'));
386
+ $yesterday = date('Y-m-d', strtotime('-1 day'));
387
+ $stats = $this->api->getMetrics('ga:pageviews', $before, $yesterday, 'ga:pageTitle,ga:pagePath', '-ga:pageviews', 'ga:pagePath!=/', 10); //'ga:pagePath!%3D%2F'
388
+
389
+ # Store the serialized stats in the database
390
+ update_option('google_stats_topPages_' . $this->id, array('stats'=>$stats, 'lastcalled'=>time()));
391
+
392
+ }
393
+
394
+ $rows = $stats->getRows();
395
+
396
+ # Check the size of the stats array
397
+ if ( count($rows) <= 0 || !is_array($rows) ) {
398
+ echo '<p>' . __('There is no data for view.', 'google-analyticator') . '</p>';
399
+ } else {
400
+ # Build the top pages list
401
+ echo '<ol>';
402
+
403
+ # Set variables needed to correct (not set) bug
404
+ $new_stats = array();
405
+ $notset_stats = array();
406
+
407
+ # Loop through each stat and create a new array
408
+ foreach ( $rows AS $stat ) {
409
+ # If the stat is not set
410
+ if ( $stat[0] == '(not set)' ) {
411
+ # Add it to separate array
412
+ $notset_stats[] = $stat;
413
+ } else {
414
+ # Add it to new array with index set
415
+ $new_stats[$stat[1]] = $stat;
416
+ }
417
+ }
418
+
419
+ # Loop through all the (not set) stats and attempt to add them to their correct stat
420
+ foreach ( $notset_stats AS $stat ) {
421
+ # If the stat has a "partner"
422
+ if ( $new_stats[$stat[1]] != NULL ) {
423
+ # Add the pageviews to the stat
424
+ $new_stats[$stat[1]][2] = $new_stats[$stat[1]][2] + $stat[2];
425
+ } else {
426
+ # Stat goes to the ether since we couldn't find a partner (if anyone reads this and has a suggestion to improve, let me know)
427
+ }
428
+ }
429
+
430
+ # Renew new_stats back to stats
431
+ $stats = $new_stats;
432
+
433
+ # Sort the stats array, since adding the (not set) items may have changed the order
434
+ usort($stats, array($this, 'statSort'));
435
+
436
+ # Since we can no longer rely on the API as a limiter, we need to keep track of this ourselves
437
+ $stat_count = 0;
438
+
439
+ # Loop through each stat for display
440
+ foreach ( $stats AS $stat ) {
441
+ echo '<li><a href="' . esc_url($stat[1]) . '">' . esc_html($stat[0]) . '</a> - ' . number_format($stat[2]) . ' ' . __('Views', 'google-analyticator') . '</li>';
442
+
443
+ # Increase the stat counter
444
+ $stat_count++;
445
+
446
+ # Stop at 5
447
+ if ( $stat_count >= 5 )
448
+ break;
449
+ }
450
+
451
+ # Finish the list
452
+ echo '</ol>';
453
+ }
454
+ }
455
+
456
+ /**
457
+ * Get the top referrers
458
+ **/
459
+ function getTopReferrers()
460
+ {
461
+ # Get the value from the database
462
+ $cached = maybe_unserialize(get_option('google_stats_topReferrers_' . $this->id));
463
+ $updated = false;
464
+
465
+ # Check if the call has been made before
466
+ if ( is_array($cached) ) {
467
+
468
+ # Check if the last time called was within two hours, if so, mark to not retrieve and grab the stats array
469
+ if ( $cached['lastcalled'] > ( time() - 7200 ) ) {
470
+ $updated = true;
471
+ $stats = $cached['stats'];
472
+ }
473
+
474
+ }
475
+
476
+ # If the stats need to be updated
477
+ if ( ! $updated ) {
478
+
479
+ # Get the metrics needed to build the top referrers
480
+ $before = date('Y-m-d', strtotime('-31 days'));
481
+ $yesterday = date('Y-m-d', strtotime('-1 day'));
482
+ $stats = $this->api->getMetrics('ga:visits', $before, $yesterday, 'ga:source,ga:medium', '-ga:visits', 'ga:medium==referral', '5');
483
+
484
+ # Store the serialized stats in the database
485
+ update_option('google_stats_topReferrers_' . $this->id, array('stats'=>$stats, 'lastcalled'=>time()));
486
+
487
+ }
488
+
489
+ $rows = $stats->getRows();
490
+
491
+ # Check the size of the stats array
492
+ if ( count($rows) <= 0 || !is_array($rows) ) {
493
+ echo '<p>' . __('There is no data for view.', 'google-analyticator') . '</p>';
494
+ } else {
495
+ # Build the top pages list
496
+ echo '<ol>';
497
+
498
+ # Loop through each stat
499
+ foreach ( $rows AS $stat ) {
500
+ echo '<li><strong>' . esc_html($stat[0]) . '</strong> - ' . number_format($stat[2]) . ' ' . __('Visits', 'google-analyticator') . '</li>';
501
+ }
502
+
503
+ # Finish the list
504
+ echo '</ol>';
505
+ }
506
+ }
507
+
508
+ /**
509
+ * Get the top searches
510
+ **/
511
+ function getTopSearches()
512
+ {
513
+ # Get the value from the database
514
+ $cached = maybe_unserialize(get_option('google_stats_topSearches_' . $this->id));
515
+ $updated = false;
516
+
517
+ # Check if the call has been made before
518
+ if ( is_array($cached) ) {
519
+
520
+ # Check if the last time called was within two hours, if so, mark to not retrieve and grab the stats array
521
+ if ( $cached['lastcalled'] > ( time() - 7200 ) ) {
522
+ $updated = true;
523
+ $stats = $cached['stats'];
524
+ }
525
+
526
+ }
527
+
528
+ # If the stats need to be updated
529
+ if ( ! $updated ) {
530
+
531
+ # Get the metrics needed to build the top searches
532
+ $before = date('Y-m-d', strtotime('-31 days'));
533
+ $yesterday = date('Y-m-d', strtotime('-1 day'));
534
+ $stats = $this->api->getMetrics('ga:visits', $before, $yesterday, 'ga:keyword', '-ga:visits', 'ga:keyword!=(not set)', '5'); //'ga:keyword!=(not_set)'
535
+
536
+ # Store the serialized stats in the database
537
+ update_option('google_stats_topSearches_' . $this->id, array('stats'=>$stats, 'lastcalled'=>time()));
538
+
539
+ }
540
+
541
+ $rows = $stats->getRows();
542
+
543
+ # Check the size of the stats array
544
+ if ( count($rows) <= 0 || !is_array($rows) ) {
545
+ echo '<p>' . __('There is no data for view.', 'google-analyticator') . '</p>';
546
+ } else {
547
+ # Build the top pages list
548
+ echo '<ol>';
549
+
550
+ # Loop through each stat
551
+ foreach ( $rows AS $stat ) {
552
+ echo '<li><strong>' . esc_html($stat[0]) . '</strong> - ' . number_format($stat[1]) . ' ' . __('Visits', 'google-analyticator') . '</li>';
553
+ }
554
+
555
+ # Finish the list
556
+ echo '</ol>';
557
+ }
558
+ }
559
+
560
+ /**
561
+ * Sort a set of stats in descending order
562
+ *
563
+ * @return how the stat should be sorted
564
+ **/
565
+ function statSort($x, $y)
566
+ {
567
+ if ( $x[2] == $y[2] )
568
+ return 0;
569
+ elseif ( $x[2] < $y[2] )
570
+ return 1;
571
+ else
572
+ return -1;
573
+ }
574
+
575
+ /**
576
+ * Convert second to a time format
577
+ **/
578
+ function sec2Time($time)
579
+ {
580
+ # Check if numeric
581
+ if ( is_numeric($time) ) {
582
+ $value = array(
583
+ "years" => '00',
584
+ "days" => '00',
585
+ "hours" => '00',
586
+ "minutes" => '00',
587
+ "seconds" => '00'
588
+ );
589
+ if ( $time >= 31556926 ) {
590
+ $value["years"] = floor($time/31556926);
591
+ $time = ($time%31556926);
592
+ }
593
+ if ( $time >= 86400 ) {
594
+ $value["days"] = floor($time/86400);
595
+ $time = ($time%86400);
596
+ }
597
+ if ( $time >= 3600 ) {
598
+ $value["hours"] = str_pad(floor($time/3600), 2, 0, STR_PAD_LEFT);
599
+ $time = ($time%3600);
600
+ }
601
+ if ( $time >= 60 ) {
602
+ $value["minutes"] = str_pad(floor($time/60), 2, 0, STR_PAD_LEFT);
603
+ $time = ($time%60);
604
+ }
605
+ $value["seconds"] = str_pad(floor($time), 2, 0, STR_PAD_LEFT);
606
+
607
+ # Get the hour:minute:second version
608
+ return $value['hours'] . ':' . $value['minutes'] . ':' . $value['seconds'];
609
+ } else {
610
+ return false;
611
+ }
612
+ }
613
+
614
+
615
+
616
+
617
+ } // END class
google-api-php-client/src/Google_Client.php ADDED
@@ -0,0 +1,465 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ // Check for the required json and curl extensions, the Google APIs PHP Client
19
+ // won't function without them.
20
+ if (! function_exists('curl_init')) {
21
+ throw new Exception('Google PHP API Client requires the CURL PHP extension');
22
+ }
23
+
24
+ if (! function_exists('json_decode')) {
25
+ throw new Exception('Google PHP API Client requires the JSON PHP extension');
26
+ }
27
+
28
+ if (! function_exists('http_build_query')) {
29
+ throw new Exception('Google PHP API Client requires http_build_query()');
30
+ }
31
+
32
+ if (! ini_get('date.timezone') && function_exists('date_default_timezone_set')) {
33
+ date_default_timezone_set('UTC');
34
+ }
35
+
36
+ // hack around with the include paths a bit so the library 'just works'
37
+ set_include_path(dirname(__FILE__) . PATH_SEPARATOR . get_include_path());
38
+
39
+ require_once "config.php";
40
+ // If a local configuration file is found, merge it's values with the default configuration
41
+ if (file_exists(dirname(__FILE__) . '/local_config.php')) {
42
+ $defaultConfig = $apiConfig;
43
+ require_once (dirname(__FILE__) . '/local_config.php');
44
+ $apiConfig = array_merge($defaultConfig, $apiConfig);
45
+ }
46
+
47
+ // Include the top level classes, they each include their own dependencies
48
+ require_once 'service/Google_Model.php';
49
+ require_once 'service/Google_Service.php';
50
+ require_once 'service/Google_ServiceResource.php';
51
+ require_once 'auth/Google_AssertionCredentials.php';
52
+ require_once 'auth/Google_Signer.php';
53
+ require_once 'auth/Google_P12Signer.php';
54
+ require_once 'service/Google_BatchRequest.php';
55
+ require_once 'external/URITemplateParser.php';
56
+ require_once 'auth/Google_Auth.php';
57
+ require_once 'cache/Google_Cache.php';
58
+ require_once 'io/Google_IO.php';
59
+ require_once('service/Google_MediaFileUpload.php');
60
+
61
+ /**
62
+ * The Google API Client
63
+ * http://code.google.com/p/google-api-php-client/
64
+ *
65
+ * @author Chris Chabot <chabotc@google.com>
66
+ * @author Chirag Shah <chirags@google.com>
67
+ */
68
+ class Google_Client {
69
+ /**
70
+ * @static
71
+ * @var Google_Auth $auth
72
+ */
73
+ static $auth;
74
+
75
+ /**
76
+ * @static
77
+ * @var Google_IO $io
78
+ */
79
+ static $io;
80
+
81
+ /**
82
+ * @static
83
+ * @var Google_Cache $cache
84
+ */
85
+ static $cache;
86
+
87
+ /**
88
+ * @static
89
+ * @var boolean $useBatch
90
+ */
91
+ static $useBatch = false;
92
+
93
+ /** @var array $scopes */
94
+ protected $scopes = array();
95
+
96
+ /** @var bool $useObjects */
97
+ protected $useObjects = false;
98
+
99
+ // definitions of services that are discovered.
100
+ protected $services = array();
101
+
102
+ // Used to track authenticated state, can't discover services after doing authenticate()
103
+ private $authenticated = false;
104
+
105
+ public function __construct($config = array()) {
106
+ global $apiConfig;
107
+ $apiConfig = array_merge($apiConfig, $config);
108
+ self::$cache = new $apiConfig['cacheClass']();
109
+ self::$auth = new $apiConfig['authClass']();
110
+ self::$io = new $apiConfig['ioClass']();
111
+ }
112
+
113
+ /**
114
+ * Add a service
115
+ */
116
+ public function addService($service, $version = false) {
117
+ global $apiConfig;
118
+ if ($this->authenticated) {
119
+ throw new Google_Exception('Cant add services after having authenticated');
120
+ }
121
+ $this->services[$service] = array();
122
+ if (isset($apiConfig['services'][$service])) {
123
+ // Merge the service descriptor with the default values
124
+ $this->services[$service] = array_merge($this->services[$service], $apiConfig['services'][$service]);
125
+ }
126
+ }
127
+
128
+ public function authenticate($code = null) {
129
+ $service = $this->prepareService();
130
+ $this->authenticated = true;
131
+
132
+ try {
133
+ return self::$auth->authenticate($service, $code);
134
+ }
135
+ catch (Google_AuthException $e)
136
+ {
137
+ print 'There was an Analytics API service error ' . $e->getCode() . ':' . $e->getMessage();
138
+ return false;
139
+
140
+ }
141
+
142
+
143
+
144
+ }
145
+
146
+ /**
147
+ * @return array
148
+ * @visible For Testing
149
+ */
150
+ public function prepareService() {
151
+ $service = array();
152
+ $scopes = array();
153
+ if ($this->scopes) {
154
+ $scopes = $this->scopes;
155
+ } else {
156
+ foreach ($this->services as $key => $val) {
157
+ if (isset($val['scope'])) {
158
+ if (is_array($val['scope'])) {
159
+ $scopes = array_merge($val['scope'], $scopes);
160
+ } else {
161
+ $scopes[] = $val['scope'];
162
+ }
163
+ } else {
164
+ $scopes[] = 'https://www.googleapis.com/auth/' . $key;
165
+ }
166
+ unset($val['discoveryURI']);
167
+ unset($val['scope']);
168
+ $service = array_merge($service, $val);
169
+ }
170
+ }
171
+ $service['scope'] = implode(' ', $scopes);
172
+ return $service;
173
+ }
174
+
175
+ /**
176
+ * Set the OAuth 2.0 access token using the string that resulted from calling authenticate()
177
+ * or Google_Client#getAccessToken().
178
+ * @param string $accessToken JSON encoded string containing in the following format:
179
+ * {"access_token":"TOKEN", "refresh_token":"TOKEN", "token_type":"Bearer",
180
+ * "expires_in":3600, "id_token":"TOKEN", "created":1320790426}
181
+ */
182
+ public function setAccessToken($accessToken) {
183
+ if ($accessToken == null || 'null' == $accessToken) {
184
+ $accessToken = null;
185
+ }
186
+ self::$auth->setAccessToken($accessToken);
187
+ }
188
+
189
+ /**
190
+ * Set the type of Auth class the client should use.
191
+ * @param string $authClassName
192
+ */
193
+ public function setAuthClass($authClassName) {
194
+ self::$auth = new $authClassName();
195
+ }
196
+
197
+ /**
198
+ * Construct the OAuth 2.0 authorization request URI.
199
+ * @return string
200
+ */
201
+ public function createAuthUrl() {
202
+ $service = $this->prepareService();
203
+ return self::$auth->createAuthUrl($service['scope']);
204
+ }
205
+
206
+ /**
207
+ * Get the OAuth 2.0 access token.
208
+ * @return string $accessToken JSON encoded string in the following format:
209
+ * {"access_token":"TOKEN", "refresh_token":"TOKEN", "token_type":"Bearer",
210
+ * "expires_in":3600,"id_token":"TOKEN", "created":1320790426}
211
+ */
212
+ public function getAccessToken() {
213
+ $token = self::$auth->getAccessToken();
214
+ return (null == $token || 'null' == $token) ? null : $token;
215
+ }
216
+
217
+ /**
218
+ * Returns if the access_token is expired.
219
+ * @return bool Returns True if the access_token is expired.
220
+ */
221
+ public function isAccessTokenExpired() {
222
+ return self::$auth->isAccessTokenExpired();
223
+ }
224
+
225
+ /**
226
+ * Set the developer key to use, these are obtained through the API Console.
227
+ * @see http://code.google.com/apis/console-help/#generatingdevkeys
228
+ * @param string $developerKey
229
+ */
230
+ public function setDeveloperKey($developerKey) {
231
+ self::$auth->setDeveloperKey($developerKey);
232
+ }
233
+
234
+ /**
235
+ * Set OAuth 2.0 "state" parameter to achieve per-request customization.
236
+ * @see http://tools.ietf.org/html/draft-ietf-oauth-v2-22#section-3.1.2.2
237
+ * @param string $state
238
+ */
239
+ public function setState($state) {
240
+ self::$auth->setState($state);
241
+ }
242
+
243
+ /**
244
+ * @param string $accessType Possible values for access_type include:
245
+ * {@code "offline"} to request offline access from the user. (This is the default value)
246
+ * {@code "online"} to request online access from the user.
247
+ */
248
+ public function setAccessType($accessType) {
249
+ self::$auth->setAccessType($accessType);
250
+ }
251
+
252
+ /**
253
+ * @param string $approvalPrompt Possible values for approval_prompt include:
254
+ * {@code "force"} to force the approval UI to appear. (This is the default value)
255
+ * {@code "auto"} to request auto-approval when possible.
256
+ */
257
+ public function setApprovalPrompt($approvalPrompt) {
258
+ self::$auth->setApprovalPrompt($approvalPrompt);
259
+ }
260
+
261
+ /**
262
+ * Set the application name, this is included in the User-Agent HTTP header.
263
+ * @param string $applicationName
264
+ */
265
+ public function setApplicationName($applicationName) {
266
+ global $apiConfig;
267
+ $apiConfig['application_name'] = $applicationName;
268
+ }
269
+
270
+ /**
271
+ * Set the OAuth 2.0 Client ID.
272
+ * @param string $clientId
273
+ */
274
+ public function setClientId($clientId) {
275
+ global $apiConfig;
276
+ $apiConfig['oauth2_client_id'] = $clientId;
277
+ self::$auth->clientId = $clientId;
278
+ }
279
+
280
+ /**
281
+ * Get the OAuth 2.0 Client ID.
282
+ */
283
+ public function getClientId() {
284
+ return self::$auth->clientId;
285
+ }
286
+
287
+ /**
288
+ * Set the OAuth 2.0 Client Secret.
289
+ * @param string $clientSecret
290
+ */
291
+ public function setClientSecret($clientSecret) {
292
+ global $apiConfig;
293
+ $apiConfig['oauth2_client_secret'] = $clientSecret;
294
+ self::$auth->clientSecret = $clientSecret;
295
+ }
296
+
297
+ /**
298
+ * Get the OAuth 2.0 Client Secret.
299
+ */
300
+ public function getClientSecret() {
301
+ return self::$auth->clientSecret;
302
+ }
303
+
304
+ /**
305
+ * Set the OAuth 2.0 Redirect URI.
306
+ * @param string $redirectUri
307
+ */
308
+ public function setRedirectUri($redirectUri) {
309
+ global $apiConfig;
310
+ $apiConfig['oauth2_redirect_uri'] = $redirectUri;
311
+ self::$auth->redirectUri = $redirectUri;
312
+ }
313
+
314
+ /**
315
+ * Get the OAuth 2.0 Redirect URI.
316
+ */
317
+ public function getRedirectUri() {
318
+ return self::$auth->redirectUri;
319
+ }
320
+
321
+ /**
322
+ * Fetches a fresh OAuth 2.0 access token with the given refresh token.
323
+ * @param string $refreshToken
324
+ * @return void
325
+ */
326
+ public function refreshToken($refreshToken) {
327
+ self::$auth->refreshToken($refreshToken);
328
+ }
329
+
330
+ /**
331
+ * Revoke an OAuth2 access token or refresh token. This method will revoke the current access
332
+ * token, if a token isn't provided.
333
+ * @throws Google_AuthException
334
+ * @param string|null $token The token (access token or a refresh token) that should be revoked.
335
+ * @return boolean Returns True if the revocation was successful, otherwise False.
336
+ */
337
+ public function revokeToken($token = null) {
338
+ self::$auth->revokeToken($token);
339
+ }
340
+
341
+ /**
342
+ * Verify an id_token. This method will verify the current id_token, if one
343
+ * isn't provided.
344
+ * @throws Google_AuthException
345
+ * @param string|null $token The token (id_token) that should be verified.
346
+ * @return Google_LoginTicket Returns an apiLoginTicket if the verification was
347
+ * successful.
348
+ */
349
+ public function verifyIdToken($token = null) {
350
+ return self::$auth->verifyIdToken($token);
351
+ }
352
+
353
+ /**
354
+ * @param Google_AssertionCredentials $creds
355
+ * @return void
356
+ */
357
+ public function setAssertionCredentials(Google_AssertionCredentials $creds) {
358
+ self::$auth->setAssertionCredentials($creds);
359
+ }
360
+
361
+ /**
362
+ * This function allows you to overrule the automatically generated scopes,
363
+ * so that you can ask for more or less permission in the auth flow
364
+ * Set this before you call authenticate() though!
365
+ * @param array $scopes, ie: array('https://www.googleapis.com/auth/plus.me', 'https://www.googleapis.com/auth/moderator')
366
+ */
367
+ public function setScopes($scopes) {
368
+ $this->scopes = is_string($scopes) ? explode(" ", $scopes) : $scopes;
369
+ }
370
+
371
+ /**
372
+ * Declare if objects should be returned by the api service classes.
373
+ *
374
+ * @param boolean $useObjects True if objects should be returned by the service classes.
375
+ * False if associative arrays should be returned (default behavior).
376
+ * @experimental
377
+ */
378
+ public function setUseObjects($useObjects) {
379
+ global $apiConfig;
380
+ $apiConfig['use_objects'] = $useObjects;
381
+ }
382
+
383
+ /**
384
+ * Declare if objects should be returned by the api service classes.
385
+ *
386
+ * @param boolean $useBatch True if the experimental batch support should
387
+ * be enabled. Defaults to False.
388
+ * @experimental
389
+ */
390
+ public function setUseBatch($useBatch) {
391
+ self::$useBatch = $useBatch;
392
+ }
393
+
394
+ /**
395
+ * @static
396
+ * @return Google_Auth the implementation of apiAuth.
397
+ */
398
+ public static function getAuth() {
399
+ return Google_Client::$auth;
400
+ }
401
+
402
+ /**
403
+ * @static
404
+ * @return Google_IO the implementation of apiIo.
405
+ */
406
+ public static function getIo() {
407
+ return Google_Client::$io;
408
+ }
409
+
410
+ /**
411
+ * @return Google_Cache the implementation of apiCache.
412
+ */
413
+ public function getCache() {
414
+ return Google_Client::$cache;
415
+ }
416
+ }
417
+
418
+ // Exceptions that the Google PHP API Library can throw
419
+ class Google_Exception extends Exception {}
420
+ class Google_AuthException extends Google_Exception {}
421
+ class Google_CacheException extends Google_Exception {}
422
+ class Google_IOException extends Google_Exception {}
423
+ class Google_ServiceException extends Google_Exception {
424
+ /**
425
+ * Optional list of errors returned in a JSON body of an HTTP error response.
426
+ */
427
+ protected $errors = array();
428
+
429
+ /**
430
+ * Override default constructor to add ability to set $errors.
431
+ *
432
+ * @param string $message
433
+ * @param int $code
434
+ * @param Exception|null $previous
435
+ * @param [{string, string}] errors List of errors returned in an HTTP
436
+ * response. Defaults to [].
437
+ */
438
+ public function __construct($message, $code = 0, Exception $previous = null,
439
+ $errors = array()) {
440
+ if(version_compare(PHP_VERSION, '5.3.0') >= 0) {
441
+ parent::__construct($message, $code, $previous);
442
+ } else {
443
+ parent::__construct($message, $code);
444
+ }
445
+
446
+ $this->errors = $errors;
447
+ }
448
+
449
+ /**
450
+ * An example of the possible errors returned.
451
+ *
452
+ * {
453
+ * "domain": "global",
454
+ * "reason": "authError",
455
+ * "message": "Invalid Credentials",
456
+ * "locationType": "header",
457
+ * "location": "Authorization",
458
+ * }
459
+ *
460
+ * @return [{string, string}] List of errors return in an HTTP response or [].
461
+ */
462
+ public function getErrors() {
463
+ return $this->errors;
464
+ }
465
+ }
google-api-php-client/src/auth/Google_AssertionCredentials.php ADDED
@@ -0,0 +1,95 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * Copyright 2012 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
+ * Credentials object used for OAuth 2.0 Signed JWT assertion grants.
20
+ *
21
+ * @author Chirag Shah <chirags@google.com>
22
+ */
23
+ class Google_AssertionCredentials {
24
+ const MAX_TOKEN_LIFETIME_SECS = 3600;
25
+
26
+ public $serviceAccountName;
27
+ public $scopes;
28
+ public $privateKey;
29
+ public $privateKeyPassword;
30
+ public $assertionType;
31
+ public $prn;
32
+
33
+ /**
34
+ * @param $serviceAccountName
35
+ * @param $scopes array List of scopes
36
+ * @param $privateKey
37
+ * @param string $privateKeyPassword
38
+ * @param string $assertionType
39
+ * @param bool|string $prn The email address of the user for which the
40
+ * application is requesting delegated access.
41
+ */
42
+ public function __construct(
43
+ $serviceAccountName,
44
+ $scopes,
45
+ $privateKey,
46
+ $privateKeyPassword = 'notasecret',
47
+ $assertionType = 'http://oauth.net/grant_type/jwt/1.0/bearer',
48
+ $prn = false) {
49
+ $this->serviceAccountName = $serviceAccountName;
50
+ $this->scopes = is_string($scopes) ? $scopes : implode(' ', $scopes);
51
+ $this->privateKey = $privateKey;
52
+ $this->privateKeyPassword = $privateKeyPassword;
53
+ $this->assertionType = $assertionType;
54
+ $this->prn = $prn;
55
+ }
56
+
57
+ public function generateAssertion() {
58
+ $now = time();
59
+
60
+ $jwtParams = array(
61
+ 'aud' => Google_OAuth2::OAUTH2_TOKEN_URI,
62
+ 'scope' => $this->scopes,
63
+ 'iat' => $now,
64
+ 'exp' => $now + self::MAX_TOKEN_LIFETIME_SECS,
65
+ 'iss' => $this->serviceAccountName,
66
+ );
67
+
68
+ if ($this->prn !== false) {
69
+ $jwtParams['prn'] = $this->prn;
70
+ }
71
+
72
+ return $this->makeSignedJwt($jwtParams);
73
+ }
74
+
75
+ /**
76
+ * Creates a signed JWT.
77
+ * @param array $payload
78
+ * @return string The signed JWT.
79
+ */
80
+ private function makeSignedJwt($payload) {
81
+ $header = array('typ' => 'JWT', 'alg' => 'RS256');
82
+
83
+ $segments = array(
84
+ Google_Utils::urlSafeB64Encode(json_encode($header)),
85
+ Google_Utils::urlSafeB64Encode(json_encode($payload))
86
+ );
87
+
88
+ $signingInput = implode('.', $segments);
89
+ $signer = new Google_P12Signer($this->privateKey, $this->privateKeyPassword);
90
+ $signature = $signer->sign($signingInput);
91
+ $segments[] = Google_Utils::urlSafeB64Encode($signature);
92
+
93
+ return implode(".", $segments);
94
+ }
95
+ }
google-api-php-client/src/auth/Google_Auth.php ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ 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();
32
+ abstract public function setAccessToken($accessToken);
33
+ abstract public function setDeveloperKey($developerKey);
34
+ abstract public function refreshToken($refreshToken);
35
+ abstract public function revokeToken();
36
+ }
google-api-php-client/src/auth/Google_AuthNone.php ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ * Do-nothing authentication implementation, use this if you want to make un-authenticated calls
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() {
27
+ global $apiConfig;
28
+ if (!empty($apiConfig['developer_key'])) {
29
+ $this->setDeveloperKey($apiConfig['developer_key']);
30
+ }
31
+ }
32
+
33
+ public function setDeveloperKey($key) {$this->key = $key;}
34
+ public function authenticate($service) {/*noop*/}
35
+ public function setAccessToken($accessToken) {/* noop*/}
36
+ public function getAccessToken() {return null;}
37
+ public function createAuthUrl($scope) {return null;}
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));
45
+ }
46
+ return $request;
47
+ }
48
+ }
google-api-php-client/src/auth/Google_LoginTicket.php ADDED
@@ -0,0 +1,63 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * Copyright 2011 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
+ * Class to hold information about an authenticated login.
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.
27
+ private $envelope;
28
+
29
+ // Information from id token payload.
30
+ private $payload;
31
+
32
+ /**
33
+ * Creates a user based on the supplied token.
34
+ *
35
+ * @param string $envelope Header from a verified authentication token.
36
+ * @param string $payload Information from a verified authentication token.
37
+ */
38
+ public function __construct($envelope, $payload) {
39
+ $this->envelope = $envelope;
40
+ $this->payload = $payload;
41
+ }
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
+ /**
56
+ * Returns attributes from the login ticket. This can contain
57
+ * various information about the user session.
58
+ * @return array
59
+ */
60
+ public function getAttributes() {
61
+ return array("envelope" => $this->envelope, "payload" => $this->payload);
62
+ }
63
+ }
google-api-php-client/src/auth/Google_OAuth2.php ADDED
@@ -0,0 +1,444 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * Copyright 2008 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
+ 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
+ *
25
+ * @author Chris Chabot <chabotc@google.com>
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;
33
+ public $token;
34
+ public $redirectUri;
35
+ public $state;
36
+ public $accessType = 'offline';
37
+ public $approvalPrompt = 'force';
38
+
39
+ /** @var Google_AssertionCredentials $assertionCredentials */
40
+ public $assertionCredentials;
41
+
42
+ const OAUTH2_REVOKE_URI = 'https://accounts.google.com/o/oauth2/revoke';
43
+ const OAUTH2_TOKEN_URI = 'https://accounts.google.com/o/oauth2/token';
44
+ const OAUTH2_AUTH_URL = 'https://accounts.google.com/o/oauth2/auth';
45
+ const OAUTH2_FEDERATED_SIGNON_CERTS_URL = 'https://www.googleapis.com/oauth2/v1/certs';
46
+ const CLOCK_SKEW_SECS = 300; // five minutes in seconds
47
+ const AUTH_TOKEN_LIFETIME_SECS = 300; // five minutes in seconds
48
+ const MAX_TOKEN_LIFETIME_SECS = 86400; // one day in seconds
49
+
50
+ /**
51
+ * Instantiates the class, but does not initiate the login flow, leaving it
52
+ * to the discretion of the caller (which is done by calling authenticate()).
53
+ */
54
+ public function __construct() {
55
+ global $apiConfig;
56
+
57
+ if (! empty($apiConfig['developer_key'])) {
58
+ $this->developerKey = $apiConfig['developer_key'];
59
+ }
60
+
61
+ if (! empty($apiConfig['oauth2_client_id'])) {
62
+ $this->clientId = $apiConfig['oauth2_client_id'];
63
+ }
64
+
65
+ if (! empty($apiConfig['oauth2_client_secret'])) {
66
+ $this->clientSecret = $apiConfig['oauth2_client_secret'];
67
+ }
68
+
69
+ if (! empty($apiConfig['oauth2_redirect_uri'])) {
70
+ $this->redirectUri = $apiConfig['oauth2_redirect_uri'];
71
+ }
72
+
73
+ if (! empty($apiConfig['oauth2_access_type'])) {
74
+ $this->accessType = $apiConfig['oauth2_access_type'];
75
+ }
76
+
77
+ if (! empty($apiConfig['oauth2_approval_prompt'])) {
78
+ $this->approvalPrompt = $apiConfig['oauth2_approval_prompt'];
79
+ }
80
+ }
81
+
82
+ /**
83
+ * @param $service
84
+ * @param string|null $code
85
+ * @throws Google_AuthException
86
+ * @return string
87
+ */
88
+ public function authenticate($service, $code = null) {
89
+ if (!$code && isset($_GET['code'])) {
90
+ $code = $_GET['code'];
91
+ }
92
+
93
+ if ($code) {
94
+ // We got here from the redirect from a successful authorization grant, fetch the access token
95
+ $request = Google_Client::$io->makeRequest(new Google_HttpRequest(self::OAUTH2_TOKEN_URI, 'POST', array(), array(
96
+ 'code' => $code,
97
+ 'grant_type' => 'authorization_code',
98
+ 'redirect_uri' => $this->redirectUri,
99
+ 'client_id' => $this->clientId,
100
+ 'client_secret' => $this->clientSecret
101
+ )));
102
+
103
+ if ($request->getResponseHttpCode() == 200) {
104
+ $this->setAccessToken($request->getResponseBody());
105
+ $this->token['created'] = time();
106
+ return $this->getAccessToken();
107
+ } else {
108
+ $response = $request->getResponseBody();
109
+ $decodedResponse = json_decode($response, true);
110
+ if ($decodedResponse != null && $decodedResponse['error']) {
111
+ $response = $decodedResponse['error'];
112
+ }
113
+ throw new Google_AuthException("Error fetching OAuth2 access token, message: '$response'", $request->getResponseHttpCode());
114
+ }
115
+ }
116
+
117
+ $authUrl = $this->createAuthUrl($service['scope']);
118
+ header('Location: ' . $authUrl);
119
+ return true;
120
+ }
121
+
122
+ /**
123
+ * Create a URL to obtain user authorization.
124
+ * The authorization endpoint allows the user to first
125
+ * authenticate, and then grant/deny the access request.
126
+ * @param string $scope The scope is expressed as a list of space-delimited strings.
127
+ * @return string
128
+ */
129
+ public function createAuthUrl($scope) {
130
+ $params = array(
131
+ 'response_type=code',
132
+ 'redirect_uri=' . urlencode($this->redirectUri),
133
+ 'client_id=' . urlencode($this->clientId),
134
+ 'scope=' . urlencode($scope),
135
+ 'access_type=' . urlencode($this->accessType),
136
+ 'approval_prompt=' . urlencode($this->approvalPrompt)
137
+ );
138
+
139
+ if (isset($this->state)) {
140
+ $params[] = 'state=' . urlencode($this->state);
141
+ }
142
+ $params = implode('&', $params);
143
+ return self::OAUTH2_AUTH_URL . "?$params";
144
+ }
145
+
146
+ /**
147
+ * @param string $token
148
+ * @throws Google_AuthException
149
+ */
150
+ public function setAccessToken($token) {
151
+ $token = json_decode($token, true);
152
+ if ($token == null) {
153
+ throw new Google_AuthException('Could not json decode the token');
154
+ }
155
+ if (! isset($token['access_token'])) {
156
+ throw new Google_AuthException("Invalid token format");
157
+ }
158
+ $this->token = $token;
159
+ }
160
+
161
+ public function getAccessToken() {
162
+ return json_encode($this->token);
163
+ }
164
+
165
+ public function setDeveloperKey($developerKey) {
166
+ $this->developerKey = $developerKey;
167
+ }
168
+
169
+ public function setState($state) {
170
+ $this->state = $state;
171
+ }
172
+
173
+ public function setAccessType($accessType) {
174
+ $this->accessType = $accessType;
175
+ }
176
+
177
+ public function setApprovalPrompt($approvalPrompt) {
178
+ $this->approvalPrompt = $approvalPrompt;
179
+ }
180
+
181
+ public function setAssertionCredentials(Google_AssertionCredentials $creds) {
182
+ $this->assertionCredentials = $creds;
183
+ }
184
+
185
+ /**
186
+ * Include an accessToken in a given apiHttpRequest.
187
+ * @param Google_HttpRequest $request
188
+ * @return Google_HttpRequest
189
+ * @throws Google_AuthException
190
+ */
191
+ public function sign(Google_HttpRequest $request) {
192
+ // add the developer key to the request before signing it
193
+ if ($this->developerKey) {
194
+ $requestUrl = $request->getUrl();
195
+ $requestUrl .= (strpos($request->getUrl(), '?') === false) ? '?' : '&';
196
+ $requestUrl .= 'key=' . urlencode($this->developerKey);
197
+ $request->setUrl($requestUrl);
198
+ }
199
+
200
+ // Cannot sign the request without an OAuth access token.
201
+ if (null == $this->token && null == $this->assertionCredentials) {
202
+ return $request;
203
+ }
204
+
205
+ // Check if the token is set to expire in the next 30 seconds
206
+ // (or has already expired).
207
+ if ($this->isAccessTokenExpired()) {
208
+ if ($this->assertionCredentials) {
209
+ $this->refreshTokenWithAssertion();
210
+ } else {
211
+ if (! array_key_exists('refresh_token', $this->token)) {
212
+ throw new Google_AuthException("The OAuth 2.0 access token has expired, "
213
+ . "and a refresh token is not available. Refresh tokens are not "
214
+ . "returned for responses that were auto-approved.");
215
+ }
216
+ $this->refreshToken($this->token['refresh_token']);
217
+ }
218
+ }
219
+
220
+ // Add the OAuth2 header to the request
221
+ $request->setRequestHeaders(
222
+ array('Authorization' => 'Bearer ' . $this->token['access_token'])
223
+ );
224
+
225
+ return $request;
226
+ }
227
+
228
+ /**
229
+ * Fetches a fresh access token with the given refresh token.
230
+ * @param string $refreshToken
231
+ * @return void
232
+ */
233
+ public function refreshToken($refreshToken) {
234
+ $this->refreshTokenRequest(array(
235
+ 'client_id' => $this->clientId,
236
+ 'client_secret' => $this->clientSecret,
237
+ 'refresh_token' => $refreshToken,
238
+ 'grant_type' => 'refresh_token'
239
+ ));
240
+ }
241
+
242
+ /**
243
+ * Fetches a fresh access token with a given assertion token.
244
+ * @param Google_AssertionCredentials $assertionCredentials optional.
245
+ * @return void
246
+ */
247
+ public function refreshTokenWithAssertion($assertionCredentials = null) {
248
+ if (!$assertionCredentials) {
249
+ $assertionCredentials = $this->assertionCredentials;
250
+ }
251
+
252
+ $this->refreshTokenRequest(array(
253
+ 'grant_type' => 'assertion',
254
+ 'assertion_type' => $assertionCredentials->assertionType,
255
+ 'assertion' => $assertionCredentials->generateAssertion(),
256
+ ));
257
+ }
258
+
259
+ private function refreshTokenRequest($params) {
260
+ $http = new Google_HttpRequest(self::OAUTH2_TOKEN_URI, 'POST', array(), $params);
261
+ $request = Google_Client::$io->makeRequest($http);
262
+
263
+ $code = $request->getResponseHttpCode();
264
+ $body = $request->getResponseBody();
265
+ if (200 == $code) {
266
+ $token = json_decode($body, true);
267
+ if ($token == null) {
268
+ throw new Google_AuthException("Could not json decode the access token");
269
+ }
270
+
271
+ if (! isset($token['access_token']) || ! isset($token['expires_in'])) {
272
+ throw new Google_AuthException("Invalid token format");
273
+ }
274
+
275
+ $this->token['access_token'] = $token['access_token'];
276
+ $this->token['expires_in'] = $token['expires_in'];
277
+ $this->token['created'] = time();
278
+ } else {
279
+ throw new Google_AuthException("Error refreshing the OAuth2 token, message: '$body'", $code);
280
+ }
281
+ }
282
+
283
+ /**
284
+ * Revoke an OAuth2 access token or refresh token. This method will revoke the current access
285
+ * token, if a token isn't provided.
286
+ * @throws Google_AuthException
287
+ * @param string|null $token The token (access token or a refresh token) that should be revoked.
288
+ * @return boolean Returns True if the revocation was successful, otherwise False.
289
+ */
290
+ public function revokeToken($token = null) {
291
+ if (!$token) {
292
+ $token = $this->token['access_token'];
293
+ }
294
+ $request = new Google_HttpRequest(self::OAUTH2_REVOKE_URI, 'POST', array(), "token=$token");
295
+ $response = Google_Client::$io->makeRequest($request);
296
+ $code = $response->getResponseHttpCode();
297
+ if ($code == 200) {
298
+ $this->token = null;
299
+ return true;
300
+ }
301
+
302
+ return false;
303
+ }
304
+
305
+ /**
306
+ * Returns if the access_token is expired.
307
+ * @return bool Returns True if the access_token is expired.
308
+ */
309
+ public function isAccessTokenExpired() {
310
+ if (null == $this->token) {
311
+ return true;
312
+ }
313
+
314
+ // If the token is set to expire in the next 30 seconds.
315
+ $expired = ($this->token['created']
316
+ + ($this->token['expires_in'] - 30)) < time();
317
+
318
+ return $expired;
319
+ }
320
+
321
+ // Gets federated sign-on certificates to use for verifying identity tokens.
322
+ // Returns certs as array structure, where keys are key ids, and values
323
+ // are PEM encoded certificates.
324
+ private function getFederatedSignOnCerts() {
325
+ // This relies on makeRequest caching certificate responses.
326
+ $request = Google_Client::$io->makeRequest(new Google_HttpRequest(
327
+ self::OAUTH2_FEDERATED_SIGNON_CERTS_URL));
328
+ if ($request->getResponseHttpCode() == 200) {
329
+ $certs = json_decode($request->getResponseBody(), true);
330
+ if ($certs) {
331
+ return $certs;
332
+ }
333
+ }
334
+ throw new Google_AuthException(
335
+ "Failed to retrieve verification certificates: '" .
336
+ $request->getResponseBody() . "'.",
337
+ $request->getResponseHttpCode());
338
+ }
339
+
340
+ /**
341
+ * Verifies an id token and returns the authenticated apiLoginTicket.
342
+ * Throws an exception if the id token is not valid.
343
+ * The audience parameter can be used to control which id tokens are
344
+ * accepted. By default, the id token must have been issued to this OAuth2 client.
345
+ *
346
+ * @param $id_token
347
+ * @param $audience
348
+ * @return Google_LoginTicket
349
+ */
350
+ public function verifyIdToken($id_token = null, $audience = null) {
351
+ if (!$id_token) {
352
+ $id_token = $this->token['id_token'];
353
+ }
354
+
355
+ $certs = $this->getFederatedSignonCerts();
356
+ if (!$audience) {
357
+ $audience = $this->clientId;
358
+ }
359
+ return $this->verifySignedJwtWithCerts($id_token, $certs, $audience);
360
+ }
361
+
362
+ // Verifies the id token, returns the verified token contents.
363
+ // Visible for testing.
364
+ function verifySignedJwtWithCerts($jwt, $certs, $required_audience) {
365
+ $segments = explode(".", $jwt);
366
+ if (count($segments) != 3) {
367
+ throw new Google_AuthException("Wrong number of segments in token: $jwt");
368
+ }
369
+ $signed = $segments[0] . "." . $segments[1];
370
+ $signature = Google_Utils::urlSafeB64Decode($segments[2]);
371
+
372
+ // Parse envelope.
373
+ $envelope = json_decode(Google_Utils::urlSafeB64Decode($segments[0]), true);
374
+ if (!$envelope) {
375
+ throw new Google_AuthException("Can't parse token envelope: " . $segments[0]);
376
+ }
377
+
378
+ // Parse token
379
+ $json_body = Google_Utils::urlSafeB64Decode($segments[1]);
380
+ $payload = json_decode($json_body, true);
381
+ if (!$payload) {
382
+ throw new Google_AuthException("Can't parse token payload: " . $segments[1]);
383
+ }
384
+
385
+ // Check signature
386
+ $verified = false;
387
+ foreach ($certs as $keyName => $pem) {
388
+ $public_key = new Google_PemVerifier($pem);
389
+ if ($public_key->verify($signed, $signature)) {
390
+ $verified = true;
391
+ break;
392
+ }
393
+ }
394
+
395
+ if (!$verified) {
396
+ throw new Google_AuthException("Invalid token signature: $jwt");
397
+ }
398
+
399
+ // Check issued-at timestamp
400
+ $iat = 0;
401
+ if (array_key_exists("iat", $payload)) {
402
+ $iat = $payload["iat"];
403
+ }
404
+ if (!$iat) {
405
+ throw new Google_AuthException("No issue time in token: $json_body");
406
+ }
407
+ $earliest = $iat - self::CLOCK_SKEW_SECS;
408
+
409
+ // Check expiration timestamp
410
+ $now = time();
411
+ $exp = 0;
412
+ if (array_key_exists("exp", $payload)) {
413
+ $exp = $payload["exp"];
414
+ }
415
+ if (!$exp) {
416
+ throw new Google_AuthException("No expiration time in token: $json_body");
417
+ }
418
+ if ($exp >= $now + self::MAX_TOKEN_LIFETIME_SECS) {
419
+ throw new Google_AuthException(
420
+ "Expiration time too far in future: $json_body");
421
+ }
422
+
423
+ $latest = $exp + self::CLOCK_SKEW_SECS;
424
+ if ($now < $earliest) {
425
+ throw new Google_AuthException(
426
+ "Token used too early, $now < $earliest: $json_body");
427
+ }
428
+ if ($now > $latest) {
429
+ throw new Google_AuthException(
430
+ "Token used too late, $now > $latest: $json_body");
431
+ }
432
+
433
+ // TODO(beaton): check issuer field?
434
+
435
+ // Check audience
436
+ $aud = $payload["aud"];
437
+ if ($aud != $required_audience) {
438
+ throw new Google_AuthException("Wrong recipient, $aud != $required_audience: $json_body");
439
+ }
440
+
441
+ // All good.
442
+ return new Google_LoginTicket($envelope, $payload);
443
+ }
444
+ }
google-api-php-client/src/auth/Google_P12Signer.php ADDED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * Copyright 2011 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
+ * Signs data.
20
+ *
21
+ * Only used for testing.
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
+
29
+ // Creates a new signer from a .p12 file.
30
+ function __construct($p12, $password) {
31
+ if (!function_exists('openssl_x509_read')) {
32
+ throw new Exception(
33
+ 'The Google PHP API library needs the openssl PHP extension');
34
+ }
35
+
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
+
54
+ function __destruct() {
55
+ if ($this->privateKey) {
56
+ openssl_pkey_free($this->privateKey);
57
+ }
58
+ }
59
+
60
+ function sign($data) {
61
+ if (!openssl_sign($data, $signature, $this->privateKey, "sha256")) {
62
+ throw new Google_AuthException("Unable to sign data");
63
+ }
64
+ return $signature;
65
+ }
66
+ }
google-api-php-client/src/auth/Google_PemVerifier.php ADDED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * Copyright 2011 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
+ * Verifies signatures using PEM encoded certificates.
20
+ *
21
+ * @author Brian Eaton <beaton@google.com>
22
+ */
23
+ class Google_PemVerifier extends Google_Verifier {
24
+ private $publicKey;
25
+
26
+ /**
27
+ * Constructs a verifier from the supplied PEM-encoded certificate.
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
+
44
+ function __destruct() {
45
+ if ($this->publicKey) {
46
+ openssl_x509_free($this->publicKey);
47
+ }
48
+ }
49
+
50
+ /**
51
+ * Verifies the signature on data.
52
+ *
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
+ }
66
+ }
google-api-php-client/src/auth/Google_Signer.php ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * Copyright 2011 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
+ 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
+ */
29
+ abstract public function sign($data);
30
+ }
google-api-php-client/src/auth/Google_Verifier.php ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * Copyright 2011 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
+ 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.
29
+ */
30
+ abstract public function verify($data, $signature);
31
+ }
google-api-php-client/src/cache/Google_ApcCache.php ADDED
@@ -0,0 +1,98 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ * A persistent storage class based on the APC cache, which is not
20
+ * really very persistent, as soon as you restart your web server
21
+ * the storage will be wiped, however for debugging and/or speed
22
+ * it can be useful, kinda, and cache is a lot cheaper then storage.
23
+ *
24
+ * @author Chris Chabot <chabotc@google.com>
25
+ */
26
+ class googleApcCache 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
+
34
+ private function isLocked($key) {
35
+ if ((@apc_fetch($key . '.lock')) === false) {
36
+ return false;
37
+ }
38
+ return true;
39
+ }
40
+
41
+ private function createLock($key) {
42
+ // the interesting thing is that this could fail if the lock was created in the meantime..
43
+ // but we'll ignore that out of convenience
44
+ @apc_add($key . '.lock', '', 5);
45
+ }
46
+
47
+ private function removeLock($key) {
48
+ // suppress all warnings, if some other process removed it that's ok too
49
+ @apc_delete($key . '.lock');
50
+ }
51
+
52
+ private function waitForLock($key) {
53
+ // 20 x 250 = 5 seconds
54
+ $tries = 20;
55
+ $cnt = 0;
56
+ do {
57
+ // 250 ms is a long time to sleep, but it does stop the server from burning all resources on polling locks..
58
+ usleep(250);
59
+ $cnt ++;
60
+ } while ($cnt <= $tries && $this->isLocked($key));
61
+ if ($this->isLocked($key)) {
62
+ // 5 seconds passed, assume the owning process died off and remove it
63
+ $this->removeLock($key);
64
+ }
65
+ }
66
+
67
+ /**
68
+ * @inheritDoc
69
+ */
70
+ public function get($key, $expiration = false) {
71
+
72
+ if (($ret = @apc_fetch($key)) === false) {
73
+ return false;
74
+ }
75
+ if (!$expiration || (time() - $ret['time'] > $expiration)) {
76
+ $this->delete($key);
77
+ return false;
78
+ }
79
+ return unserialize($ret['data']);
80
+ }
81
+
82
+ /**
83
+ * @inheritDoc
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
+
91
+ /**
92
+ * @inheritDoc
93
+ * @param String $key
94
+ */
95
+ public function delete($key) {
96
+ @apc_delete($key);
97
+ }
98
+ }
google-api-php-client/src/cache/Google_Cache.php ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * Copyright 2008 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
+ 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
30
+ * key is unknown or expired
31
+ *
32
+ * @param String $key The key who's data to retrieve
33
+ * @param boolean|int $expiration Expiration time in seconds
34
+ *
35
+ */
36
+ abstract function get($key, $expiration = false);
37
+
38
+ /**
39
+ * Store the key => $value set. The $value is serialized
40
+ * by this function so can be of any type
41
+ *
42
+ * @param string $key Key of the data
43
+ * @param string $value data
44
+ */
45
+ abstract function set($key, $value);
46
+
47
+ /**
48
+ * Removes the key/data pair for the given $key
49
+ *
50
+ * @param String $key
51
+ */
52
+ abstract function delete($key);
53
+ }
54
+
55
+
google-api-php-client/src/cache/Google_FileCache.php ADDED
@@ -0,0 +1,137 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * Copyright 2008 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
+ * This class implements a basic on disk storage. While that does
20
+ * work quite well it's not the most elegant and scalable solution.
21
+ * It will also get you into a heap of trouble when you try to run
22
+ * this in a clustered environment. In those cases please use the
23
+ * MySql back-end
24
+ *
25
+ * @author Chris Chabot <chabotc@google.com>
26
+ */
27
+ class Google_FileCache extends Google_Cache {
28
+ private $path;
29
+
30
+ public function __construct() {
31
+ global $apiConfig;
32
+ $this->path = $apiConfig['ioFileCache_directory'];
33
+ }
34
+
35
+ private function isLocked($storageFile) {
36
+ // our lock file convention is simple: /the/file/path.lock
37
+ return file_exists($storageFile . '.lock');
38
+ }
39
+
40
+ private function createLock($storageFile) {
41
+ $storageDir = dirname($storageFile);
42
+ if (! is_dir($storageDir)) {
43
+ // @codeCoverageIgnoreStart
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
51
+ }
52
+ @touch($storageFile . '.lock');
53
+ }
54
+
55
+ private function removeLock($storageFile) {
56
+ // suppress all warnings, if some other process removed it that's ok too
57
+ @unlink($storageFile . '.lock');
58
+ }
59
+
60
+ private function waitForLock($storageFile) {
61
+ // 20 x 250 = 5 seconds
62
+ $tries = 20;
63
+ $cnt = 0;
64
+ do {
65
+ // make sure PHP picks up on file changes. This is an expensive action but really can't be avoided
66
+ clearstatcache();
67
+ // 250 ms is a long time to sleep, but it does stop the server from burning all resources on polling locks..
68
+ usleep(250);
69
+ $cnt ++;
70
+ } while ($cnt <= $tries && $this->isLocked($storageFile));
71
+ if ($this->isLocked($storageFile)) {
72
+ // 5 seconds passed, assume the owning process died off and remove it
73
+ $this->removeLock($storageFile);
74
+ }
75
+ }
76
+
77
+ private function getCacheDir($hash) {
78
+ // use the first 2 characters of the hash as a directory prefix
79
+ // this should prevent slowdowns due to huge directory listings
80
+ // and thus give some basic amount of scalability
81
+ return $this->path . '/' . substr($hash, 0, 2);
82
+ }
83
+
84
+ private function getCacheFile($hash) {
85
+ return $this->getCacheDir($hash) . '/' . $hash;
86
+ }
87
+
88
+ public function get($key, $expiration = false) {
89
+ $storageFile = $this->getCacheFile(md5($key));
90
+ // See if this storage file is locked, if so we wait upto 5 seconds for the lock owning process to
91
+ // complete it's work. If the lock is not released within that time frame, it's cleaned up.
92
+ // This should give us a fair amount of 'Cache Stampeding' protection
93
+ if ($this->isLocked($storageFile)) {
94
+ $this->waitForLock($storageFile);
95
+ }
96
+ if (file_exists($storageFile) && is_readable($storageFile)) {
97
+ $now = time();
98
+ if (! $expiration || (($mtime = @filemtime($storageFile)) !== false && ($now - $mtime) < $expiration)) {
99
+ if (($data = @file_get_contents($storageFile)) !== false) {
100
+ $data = unserialize($data);
101
+ return $data;
102
+ }
103
+ }
104
+ }
105
+ return false;
106
+ }
107
+
108
+ public function set($key, $value) {
109
+ $storageDir = $this->getCacheDir(md5($key));
110
+ $storageFile = $this->getCacheFile(md5($key));
111
+ if ($this->isLocked($storageFile)) {
112
+ // some other process is writing to this file too, wait until it's done to prevent hickups
113
+ $this->waitForLock($storageFile);
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
121
+ // responseContent but also the postBody used, headers, size, etc
122
+ $data = serialize($value);
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
+ }
130
+
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
+ }
google-api-php-client/src/cache/Google_MemcacheCache.php ADDED
@@ -0,0 +1,130 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * Copyright 2008 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
+ * A persistent storage class based on the memcache, which is not
20
+ * really very persistent, as soon as you restart your memcache daemon
21
+ * the storage will be wiped, however for debugging and/or speed
22
+ * it can be useful, kinda, and cache is a lot cheaper then storage.
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
+
41
+ private function isLocked($key) {
42
+ $this->check();
43
+ if ((@memcache_get($this->connection, $key . '.lock')) === false) {
44
+ return false;
45
+ }
46
+ return true;
47
+ }
48
+
49
+ private function createLock($key) {
50
+ $this->check();
51
+ // the interesting thing is that this could fail if the lock was created in the meantime..
52
+ // but we'll ignore that out of convenience
53
+ @memcache_add($this->connection, $key . '.lock', '', 0, 5);
54
+ }
55
+
56
+ private function removeLock($key) {
57
+ $this->check();
58
+ // suppress all warnings, if some other process removed it that's ok too
59
+ @memcache_delete($this->connection, $key . '.lock');
60
+ }
61
+
62
+ private function waitForLock($key) {
63
+ $this->check();
64
+ // 20 x 250 = 5 seconds
65
+ $tries = 20;
66
+ $cnt = 0;
67
+ do {
68
+ // 250 ms is a long time to sleep, but it does stop the server from burning all resources on polling locks..
69
+ usleep(250);
70
+ $cnt ++;
71
+ } while ($cnt <= $tries && $this->isLocked($key));
72
+ if ($this->isLocked($key)) {
73
+ // 5 seconds passed, assume the owning process died off and remove it
74
+ $this->removeLock($key);
75
+ }
76
+ }
77
+
78
+ // I prefer lazy initialization since the cache isn't used every request
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
+
86
+ private function check() {
87
+ if (! $this->connection) {
88
+ $this->connect();
89
+ }
90
+ }
91
+
92
+ /**
93
+ * @inheritDoc
94
+ */
95
+ public function get($key, $expiration = false) {
96
+ $this->check();
97
+ if (($ret = @memcache_get($this->connection, $key)) === false) {
98
+ return false;
99
+ }
100
+ if (! $expiration || (time() - $ret['time'] > $expiration)) {
101
+ $this->delete($key);
102
+ return false;
103
+ }
104
+ return $ret['data'];
105
+ }
106
+
107
+ /**
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
+
122
+ /**
123
+ * @inheritDoc
124
+ * @param String $key
125
+ */
126
+ public function delete($key) {
127
+ $this->check();
128
+ @memcache_delete($this->connection, $key);
129
+ }
130
+ }
google-api-php-client/src/config.php ADDED
@@ -0,0 +1,81 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ global $apiConfig;
19
+ $apiConfig = array(
20
+ // True if objects should be returned by the service classes.
21
+ // False if associative arrays should be returned (default behavior).
22
+ 'use_objects' => false,
23
+
24
+ // The application_name is included in the User-Agent HTTP header.
25
+ 'application_name' => '',
26
+
27
+ // OAuth2 Settings, you can get these keys at https://code.google.com/apis/console
28
+ 'oauth2_client_id' => '',
29
+ 'oauth2_client_secret' => '',
30
+ 'oauth2_redirect_uri' => '',
31
+
32
+ // The developer key, you get this at https://code.google.com/apis/console
33
+ 'developer_key' => '',
34
+
35
+ // Site name to show in the Google's OAuth 1 authentication screen.
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',
45
+
46
+ // IO Class dependent configuration, you only have to configure the values
47
+ // for the class that was configured as the ioClass above
48
+ 'ioFileCache_directory' =>
49
+ (function_exists('sys_get_temp_dir') ?
50
+ sys_get_temp_dir() . '/Google_Client' :
51
+ '/tmp/Google_Client'),
52
+
53
+ // Definition of service specific values like scopes, oauth token URLs, etc
54
+ 'services' => array(
55
+ 'analytics' => array('scope' => 'https://www.googleapis.com/auth/analytics.readonly'),
56
+ 'calendar' => array(
57
+ 'scope' => array(
58
+ "https://www.googleapis.com/auth/calendar",
59
+ "https://www.googleapis.com/auth/calendar.readonly",
60
+ )
61
+ ),
62
+ 'books' => array('scope' => 'https://www.googleapis.com/auth/books'),
63
+ 'latitude' => array(
64
+ 'scope' => array(
65
+ 'https://www.googleapis.com/auth/latitude.all.best',
66
+ 'https://www.googleapis.com/auth/latitude.all.city',
67
+ )
68
+ ),
69
+ 'moderator' => array('scope' => 'https://www.googleapis.com/auth/moderator'),
70
+ 'oauth2' => array(
71
+ 'scope' => array(
72
+ 'https://www.googleapis.com/auth/userinfo.profile',
73
+ 'https://www.googleapis.com/auth/userinfo.email',
74
+ )
75
+ ),
76
+ 'plus' => array('scope' => 'https://www.googleapis.com/auth/plus.me'),
77
+ 'siteVerification' => array('scope' => 'https://www.googleapis.com/auth/siteverification'),
78
+ 'tasks' => array('scope' => 'https://www.googleapis.com/auth/tasks'),
79
+ 'urlshortener' => array('scope' => 'https://www.googleapis.com/auth/urlshortener')
80
+ )
81
+ );
google-api-php-client/src/contrib/Google_AdsenseService.php ADDED
@@ -0,0 +1,1144 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
4
+ * use this file except in compliance with the License. You may obtain a copy of
5
+ * the License at
6
+ *
7
+ * http://www.apache.org/licenses/LICENSE-2.0
8
+ *
9
+ * Unless required by applicable law or agreed to in writing, software
10
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12
+ * License for the specific language governing permissions and limitations under
13
+ * the License.
14
+ */
15
+
16
+
17
+ /**
18
+ * The "urlchannels" collection of methods.
19
+ * Typical usage is:
20
+ * <code>
21
+ * $adsenseService = new Google_AdsenseService(...);
22
+ * $urlchannels = $adsenseService->urlchannels;
23
+ * </code>
24
+ */
25
+ class Google_UrlchannelsServiceResource extends Google_ServiceResource {
26
+
27
+
28
+ /**
29
+ * List all URL channels in the specified ad client for this AdSense account. (urlchannels.list)
30
+ *
31
+ * @param string $adClientId Ad client for which to list URL channels.
32
+ * @param array $optParams Optional parameters.
33
+ *
34
+ * @opt_param string pageToken A continuation token, used to page through URL channels. To retrieve the next page, set this parameter to the value of "nextPageToken" from the previous response.
35
+ * @opt_param int maxResults The maximum number of URL channels to include in the response, used for paging.
36
+ * @return Google_UrlChannels
37
+ */
38
+ public function listUrlchannels($adClientId, $optParams = array()) {
39
+ $params = array('adClientId' => $adClientId);
40
+ $params = array_merge($params, $optParams);
41
+ $data = $this->__call('list', array($params));
42
+ if ($this->useObjects()) {
43
+ return new Google_UrlChannels($data);
44
+ } else {
45
+ return $data;
46
+ }
47
+ }
48
+ }
49
+
50
+ /**
51
+ * The "adunits" collection of methods.
52
+ * Typical usage is:
53
+ * <code>
54
+ * $adsenseService = new Google_AdsenseService(...);
55
+ * $adunits = $adsenseService->adunits;
56
+ * </code>
57
+ */
58
+ class Google_AdunitsServiceResource extends Google_ServiceResource {
59
+
60
+
61
+ /**
62
+ * List all ad units in the specified ad client for this AdSense account. (adunits.list)
63
+ *
64
+ * @param string $adClientId Ad client for which to list ad units.
65
+ * @param array $optParams Optional parameters.
66
+ *
67
+ * @opt_param bool includeInactive Whether to include inactive ad units. Default: true.
68
+ * @opt_param string pageToken A continuation token, used to page through ad units. To retrieve the next page, set this parameter to the value of "nextPageToken" from the previous response.
69
+ * @opt_param int maxResults The maximum number of ad units to include in the response, used for paging.
70
+ * @return Google_AdUnits
71
+ */
72
+ public function listAdunits($adClientId, $optParams = array()) {
73
+ $params = array('adClientId' => $adClientId);
74
+ $params = array_merge($params, $optParams);
75
+ $data = $this->__call('list', array($params));
76
+ if ($this->useObjects()) {
77
+ return new Google_AdUnits($data);
78
+ } else {
79
+ return $data;
80
+ }
81
+ }
82
+ /**
83
+ * Gets the specified ad unit in the specified ad client. (adunits.get)
84
+ *
85
+ * @param string $adClientId Ad client for which to get the ad unit.
86
+ * @param string $adUnitId Ad unit to retrieve.
87
+ * @param array $optParams Optional parameters.
88
+ * @return Google_AdUnit
89
+ */
90
+ public function get($adClientId, $adUnitId, $optParams = array()) {
91
+ $params = array('adClientId' => $adClientId, 'adUnitId' => $adUnitId);
92
+ $params = array_merge($params, $optParams);
93
+ $data = $this->__call('get', array($params));
94
+ if ($this->useObjects()) {
95
+ return new Google_AdUnit($data);
96
+ } else {
97
+ return $data;
98
+ }
99
+ }
100
+ }
101
+
102
+ /**
103
+ * The "customchannels" collection of methods.
104
+ * Typical usage is:
105
+ * <code>
106
+ * $adsenseService = new Google_AdsenseService(...);
107
+ * $customchannels = $adsenseService->customchannels;
108
+ * </code>
109
+ */
110
+ class Google_AdunitsCustomchannelsServiceResource extends Google_ServiceResource {
111
+
112
+
113
+ /**
114
+ * List all custom channels which the specified ad unit belongs to. (customchannels.list)
115
+ *
116
+ * @param string $adClientId Ad client which contains the ad unit.
117
+ * @param string $adUnitId Ad unit for which to list custom channels.
118
+ * @param array $optParams Optional parameters.
119
+ *
120
+ * @opt_param string pageToken A continuation token, used to page through custom channels. To retrieve the next page, set this parameter to the value of "nextPageToken" from the previous response.
121
+ * @opt_param int maxResults The maximum number of custom channels to include in the response, used for paging.
122
+ * @return Google_CustomChannels
123
+ */
124
+ public function listAdunitsCustomchannels($adClientId, $adUnitId, $optParams = array()) {
125
+ $params = array('adClientId' => $adClientId, 'adUnitId' => $adUnitId);
126
+ $params = array_merge($params, $optParams);
127
+ $data = $this->__call('list', array($params));
128
+ if ($this->useObjects()) {
129
+ return new Google_CustomChannels($data);
130
+ } else {
131
+ return $data;
132
+ }
133
+ }
134
+ }
135
+
136
+ /**
137
+ * The "adclients" collection of methods.
138
+ * Typical usage is:
139
+ * <code>
140
+ * $adsenseService = new Google_AdsenseService(...);
141
+ * $adclients = $adsenseService->adclients;
142
+ * </code>
143
+ */
144
+ class Google_AdclientsServiceResource extends Google_ServiceResource {
145
+
146
+
147
+ /**
148
+ * List all ad clients in this AdSense account. (adclients.list)
149
+ *
150
+ * @param array $optParams Optional parameters.
151
+ *
152
+ * @opt_param string pageToken A continuation token, used to page through ad clients. To retrieve the next page, set this parameter to the value of "nextPageToken" from the previous response.
153
+ * @opt_param int maxResults The maximum number of ad clients to include in the response, used for paging.
154
+ * @return Google_AdClients
155
+ */
156
+ public function listAdclients($optParams = array()) {
157
+ $params = array();
158
+ $params = array_merge($params, $optParams);
159
+ $data = $this->__call('list', array($params));
160
+ if ($this->useObjects()) {
161
+ return new Google_AdClients($data);
162
+ } else {
163
+ return $data;
164
+ }
165
+ }
166
+ }
167
+
168
+ /**
169
+ * The "reports" collection of methods.
170
+ * Typical usage is:
171
+ * <code>
172
+ * $adsenseService = new Google_AdsenseService(...);
173
+ * $reports = $adsenseService->reports;
174
+ * </code>
175
+ */
176
+ class Google_ReportsServiceResource extends Google_ServiceResource {
177
+
178
+
179
+ /**
180
+ * Generate an AdSense report based on the report request sent in the query parameters. Returns the
181
+ * result as JSON; to retrieve output in CSV format specify "alt=csv" as a query parameter.
182
+ * (reports.generate)
183
+ *
184
+ * @param string $startDate Start of the date range to report on in "YYYY-MM-DD" format, inclusive.
185
+ * @param string $endDate End of the date range to report on in "YYYY-MM-DD" format, inclusive.
186
+ * @param array $optParams Optional parameters.
187
+ *
188
+ * @opt_param string sort The name of a dimension or metric to sort the resulting report on, optionally prefixed with "+" to sort ascending or "-" to sort descending. If no prefix is specified, the column is sorted ascending.
189
+ * @opt_param string locale Optional locale to use for translating report output to a local language. Defaults to "en_US" if not specified.
190
+ * @opt_param string metric Numeric columns to include in the report.
191
+ * @opt_param int maxResults The maximum number of rows of report data to return.
192
+ * @opt_param string filter Filters to be run on the report.
193
+ * @opt_param string currency Optional currency to use when reporting on monetary metrics. Defaults to the account's currency if not set.
194
+ * @opt_param int startIndex Index of the first row of report data to return.
195
+ * @opt_param string dimension Dimensions to base the report on.
196
+ * @opt_param string accountId Accounts upon which to report.
197
+ * @return Google_AdsenseReportsGenerateResponse
198
+ */
199
+ public function generate($startDate, $endDate, $optParams = array()) {
200
+ $params = array('startDate' => $startDate, 'endDate' => $endDate);
201
+ $params = array_merge($params, $optParams);
202
+ $data = $this->__call('generate', array($params));
203
+ if ($this->useObjects()) {
204
+ return new Google_AdsenseReportsGenerateResponse($data);
205
+ } else {
206
+ return $data;
207
+ }
208
+ }
209
+ }
210
+
211
+ /**
212
+ * The "accounts" collection of methods.
213
+ * Typical usage is:
214
+ * <code>
215
+ * $adsenseService = new Google_AdsenseService(...);
216
+ * $accounts = $adsenseService->accounts;
217
+ * </code>
218
+ */
219
+ class Google_AccountsServiceResource extends Google_ServiceResource {
220
+
221
+
222
+ /**
223
+ * List all accounts available to this AdSense account. (accounts.list)
224
+ *
225
+ * @param array $optParams Optional parameters.
226
+ *
227
+ * @opt_param string pageToken A continuation token, used to page through accounts. To retrieve the next page, set this parameter to the value of "nextPageToken" from the previous response.
228
+ * @opt_param int maxResults The maximum number of accounts to include in the response, used for paging.
229
+ * @return Google_Accounts
230
+ */
231
+ public function listAccounts($optParams = array()) {
232
+ $params = array();
233
+ $params = array_merge($params, $optParams);
234
+ $data = $this->__call('list', array($params));
235
+ if ($this->useObjects()) {
236
+ return new Google_Accounts($data);
237
+ } else {
238
+ return $data;
239
+ }
240
+ }
241
+ /**
242
+ * Get information about the selected AdSense account. (accounts.get)
243
+ *
244
+ * @param string $accountId Account to get information about.
245
+ * @param array $optParams Optional parameters.
246
+ *
247
+ * @opt_param bool tree Whether the tree of sub accounts should be returned.
248
+ * @return Google_Account
249
+ */
250
+ public function get($accountId, $optParams = array()) {
251
+ $params = array('accountId' => $accountId);
252
+ $params = array_merge($params, $optParams);
253
+ $data = $this->__call('get', array($params));
254
+ if ($this->useObjects()) {
255
+ return new Google_Account($data);
256
+ } else {
257
+ return $data;
258
+ }
259
+ }
260
+ }
261
+
262
+ /**
263
+ * The "urlchannels" collection of methods.
264
+ * Typical usage is:
265
+ * <code>
266
+ * $adsenseService = new Google_AdsenseService(...);
267
+ * $urlchannels = $adsenseService->urlchannels;
268
+ * </code>
269
+ */
270
+ class Google_AccountsUrlchannelsServiceResource extends Google_ServiceResource {
271
+
272
+
273
+ /**
274
+ * List all URL channels in the specified ad client for the specified account. (urlchannels.list)
275
+ *
276
+ * @param string $accountId Account to which the ad client belongs.
277
+ * @param string $adClientId Ad client for which to list URL channels.
278
+ * @param array $optParams Optional parameters.
279
+ *
280
+ * @opt_param string pageToken A continuation token, used to page through URL channels. To retrieve the next page, set this parameter to the value of "nextPageToken" from the previous response.
281
+ * @opt_param int maxResults The maximum number of URL channels to include in the response, used for paging.
282
+ * @return Google_UrlChannels
283
+ */
284
+ public function listAccountsUrlchannels($accountId, $adClientId, $optParams = array()) {
285
+ $params = array('accountId' => $accountId, 'adClientId' => $adClientId);
286
+ $params = array_merge($params, $optParams);
287
+ $data = $this->__call('list', array($params));
288
+ if ($this->useObjects()) {
289
+ return new Google_UrlChannels($data);
290
+ } else {
291
+ return $data;
292
+ }
293
+ }
294
+ }
295
+ /**
296
+ * The "adunits" collection of methods.
297
+ * Typical usage is:
298
+ * <code>
299
+ * $adsenseService = new Google_AdsenseService(...);
300
+ * $adunits = $adsenseService->adunits;
301
+ * </code>
302
+ */
303
+ class Google_AccountsAdunitsServiceResource extends Google_ServiceResource {
304
+
305
+
306
+ /**
307
+ * List all ad units in the specified ad client for the specified account. (adunits.list)
308
+ *
309
+ * @param string $accountId Account to which the ad client belongs.
310
+ * @param string $adClientId Ad client for which to list ad units.
311
+ * @param array $optParams Optional parameters.
312
+ *
313
+ * @opt_param bool includeInactive Whether to include inactive ad units. Default: true.
314
+ * @opt_param string pageToken A continuation token, used to page through ad units. To retrieve the next page, set this parameter to the value of "nextPageToken" from the previous response.
315
+ * @opt_param int maxResults The maximum number of ad units to include in the response, used for paging.
316
+ * @return Google_AdUnits
317
+ */
318
+ public function listAccountsAdunits($accountId, $adClientId, $optParams = array()) {
319
+ $params = array('accountId' => $accountId, 'adClientId' => $adClientId);
320
+ $params = array_merge($params, $optParams);
321
+ $data = $this->__call('list', array($params));
322
+ if ($this->useObjects()) {
323
+ return new Google_AdUnits($data);
324
+ } else {
325
+ return $data;
326
+ }
327
+ }
328
+ /**
329
+ * Gets the specified ad unit in the specified ad client for the specified account. (adunits.get)
330
+ *
331
+ * @param string $accountId Account to which the ad client belongs.
332
+ * @param string $adClientId Ad client for which to get the ad unit.
333
+ * @param string $adUnitId Ad unit to retrieve.
334
+ * @param array $optParams Optional parameters.
335
+ * @return Google_AdUnit
336
+ */
337
+ public function get($accountId, $adClientId, $adUnitId, $optParams = array()) {
338
+ $params = array('accountId' => $accountId, 'adClientId' => $adClientId, 'adUnitId' => $adUnitId);
339
+ $params = array_merge($params, $optParams);
340
+ $data = $this->__call('get', array($params));
341
+ if ($this->useObjects()) {
342
+ return new Google_AdUnit($data);
343
+ } else {
344
+ return $data;
345
+ }
346
+ }
347
+ }
348
+
349
+ /**
350
+ * The "customchannels" collection of methods.
351
+ * Typical usage is:
352
+ * <code>
353
+ * $adsenseService = new Google_AdsenseService(...);
354
+ * $customchannels = $adsenseService->customchannels;
355
+ * </code>
356
+ */
357
+ class Google_AccountsAdunitsCustomchannelsServiceResource extends Google_ServiceResource {
358
+
359
+
360
+ /**
361
+ * List all custom channels which the specified ad unit belongs to. (customchannels.list)
362
+ *
363
+ * @param string $accountId Account to which the ad client belongs.
364
+ * @param string $adClientId Ad client which contains the ad unit.
365
+ * @param string $adUnitId Ad unit for which to list custom channels.
366
+ * @param array $optParams Optional parameters.
367
+ *
368
+ * @opt_param string pageToken A continuation token, used to page through custom channels. To retrieve the next page, set this parameter to the value of "nextPageToken" from the previous response.
369
+ * @opt_param int maxResults The maximum number of custom channels to include in the response, used for paging.
370
+ * @return Google_CustomChannels
371
+ */
372
+ public function listAccountsAdunitsCustomchannels($accountId, $adClientId, $adUnitId, $optParams = array()) {
373
+ $params = array('accountId' => $accountId, 'adClientId' => $adClientId, 'adUnitId' => $adUnitId);
374
+ $params = array_merge($params, $optParams);
375
+ $data = $this->__call('list', array($params));
376
+ if ($this->useObjects()) {
377
+ return new Google_CustomChannels($data);
378
+ } else {
379
+ return $data;
380
+ }
381
+ }
382
+ }
383
+ /**
384
+ * The "adclients" collection of methods.
385
+ * Typical usage is:
386
+ * <code>
387
+ * $adsenseService = new Google_AdsenseService(...);
388
+ * $adclients = $adsenseService->adclients;
389
+ * </code>
390
+ */
391
+ class Google_AccountsAdclientsServiceResource extends Google_ServiceResource {
392
+
393
+
394
+ /**
395
+ * List all ad clients in the specified account. (adclients.list)
396
+ *
397
+ * @param string $accountId Account for which to list ad clients.
398
+ * @param array $optParams Optional parameters.
399
+ *
400
+ * @opt_param string pageToken A continuation token, used to page through ad clients. To retrieve the next page, set this parameter to the value of "nextPageToken" from the previous response.
401
+ * @opt_param int maxResults The maximum number of ad clients to include in the response, used for paging.
402
+ * @return Google_AdClients
403
+ */
404
+ public function listAccountsAdclients($accountId, $optParams = array()) {
405
+ $params = array('accountId' => $accountId);
406
+ $params = array_merge($params, $optParams);
407
+ $data = $this->__call('list', array($params));
408
+ if ($this->useObjects()) {
409
+ return new Google_AdClients($data);
410
+ } else {
411
+ return $data;
412
+ }
413
+ }
414
+ }
415
+ /**
416
+ * The "reports" collection of methods.
417
+ * Typical usage is:
418
+ * <code>
419
+ * $adsenseService = new Google_AdsenseService(...);
420
+ * $reports = $adsenseService->reports;
421
+ * </code>
422
+ */
423
+ class Google_AccountsReportsServiceResource extends Google_ServiceResource {
424
+
425
+
426
+ /**
427
+ * Generate an AdSense report based on the report request sent in the query parameters. Returns the
428
+ * result as JSON; to retrieve output in CSV format specify "alt=csv" as a query parameter.
429
+ * (reports.generate)
430
+ *
431
+ * @param string $accountId Account upon which to report.
432
+ * @param string $startDate Start of the date range to report on in "YYYY-MM-DD" format, inclusive.
433
+ * @param string $endDate End of the date range to report on in "YYYY-MM-DD" format, inclusive.
434
+ * @param array $optParams Optional parameters.
435
+ *
436
+ * @opt_param string sort The name of a dimension or metric to sort the resulting report on, optionally prefixed with "+" to sort ascending or "-" to sort descending. If no prefix is specified, the column is sorted ascending.
437
+ * @opt_param string locale Optional locale to use for translating report output to a local language. Defaults to "en_US" if not specified.
438
+ * @opt_param string metric Numeric columns to include in the report.
439
+ * @opt_param int maxResults The maximum number of rows of report data to return.
440
+ * @opt_param string filter Filters to be run on the report.
441
+ * @opt_param string currency Optional currency to use when reporting on monetary metrics. Defaults to the account's currency if not set.
442
+ * @opt_param int startIndex Index of the first row of report data to return.
443
+ * @opt_param string dimension Dimensions to base the report on.
444
+ * @return Google_AdsenseReportsGenerateResponse
445
+ */
446
+ public function generate($accountId, $startDate, $endDate, $optParams = array()) {
447
+ $params = array('accountId' => $accountId, 'startDate' => $startDate, 'endDate' => $endDate);
448
+ $params = array_merge($params, $optParams);
449
+ $data = $this->__call('generate', array($params));
450
+ if ($this->useObjects()) {
451
+ return new Google_AdsenseReportsGenerateResponse($data);
452
+ } else {
453
+ return $data;
454
+ }
455
+ }
456
+ }
457
+ /**
458
+ * The "customchannels" collection of methods.
459
+ * Typical usage is:
460
+ * <code>
461
+ * $adsenseService = new Google_AdsenseService(...);
462
+ * $customchannels = $adsenseService->customchannels;
463
+ * </code>
464
+ */
465
+ class Google_AccountsCustomchannelsServiceResource extends Google_ServiceResource {
466
+
467
+
468
+ /**
469
+ * List all custom channels in the specified ad client for the specified account.
470
+ * (customchannels.list)
471
+ *
472
+ * @param string $accountId Account to which the ad client belongs.
473
+ * @param string $adClientId Ad client for which to list custom channels.
474
+ * @param array $optParams Optional parameters.
475
+ *
476
+ * @opt_param string pageToken A continuation token, used to page through custom channels. To retrieve the next page, set this parameter to the value of "nextPageToken" from the previous response.
477
+ * @opt_param int maxResults The maximum number of custom channels to include in the response, used for paging.
478
+ * @return Google_CustomChannels
479
+ */
480
+ public function listAccountsCustomchannels($accountId, $adClientId, $optParams = array()) {
481
+ $params = array('accountId' => $accountId, 'adClientId' => $adClientId);
482
+ $params = array_merge($params, $optParams);
483
+ $data = $this->__call('list', array($params));
484
+ if ($this->useObjects()) {
485
+ return new Google_CustomChannels($data);
486
+ } else {
487
+ return $data;
488
+ }
489
+ }
490
+ /**
491
+ * Get the specified custom channel from the specified ad client for the specified account.
492
+ * (customchannels.get)
493
+ *
494
+ * @param string $accountId Account to which the ad client belongs.
495
+ * @param string $adClientId Ad client which contains the custom channel.
496
+ * @param string $customChannelId Custom channel to retrieve.
497
+ * @param array $optParams Optional parameters.
498
+ * @return Google_CustomChannel
499
+ */
500
+ public function get($accountId, $adClientId, $customChannelId, $optParams = array()) {
501
+ $params = array('accountId' => $accountId, 'adClientId' => $adClientId, 'customChannelId' => $customChannelId);
502
+ $params = array_merge($params, $optParams);
503
+ $data = $this->__call('get', array($params));
504
+ if ($this->useObjects()) {
505
+ return new Google_CustomChannel($data);
506
+ } else {
507
+ return $data;
508
+ }
509
+ }
510
+ }
511
+
512
+ /**
513
+ * The "adunits" collection of methods.
514
+ * Typical usage is:
515
+ * <code>
516
+ * $adsenseService = new Google_AdsenseService(...);
517
+ * $adunits = $adsenseService->adunits;
518
+ * </code>
519
+ */
520
+ class Google_AccountsCustomchannelsAdunitsServiceResource extends Google_ServiceResource {
521
+
522
+
523
+ /**
524
+ * List all ad units in the specified custom channel. (adunits.list)
525
+ *
526
+ * @param string $accountId Account to which the ad client belongs.
527
+ * @param string $adClientId Ad client which contains the custom channel.
528
+ * @param string $customChannelId Custom channel for which to list ad units.
529
+ * @param array $optParams Optional parameters.
530
+ *
531
+ * @opt_param bool includeInactive Whether to include inactive ad units. Default: true.
532
+ * @opt_param int maxResults The maximum number of ad units to include in the response, used for paging.
533
+ * @opt_param string pageToken A continuation token, used to page through ad units. To retrieve the next page, set this parameter to the value of "nextPageToken" from the previous response.
534
+ * @return Google_AdUnits
535
+ */
536
+ public function listAccountsCustomchannelsAdunits($accountId, $adClientId, $customChannelId, $optParams = array()) {
537
+ $params = array('accountId' => $accountId, 'adClientId' => $adClientId, 'customChannelId' => $customChannelId);
538
+ $params = array_merge($params, $optParams);
539
+ $data = $this->__call('list', array($params));
540
+ if ($this->useObjects()) {
541
+ return new Google_AdUnits($data);
542
+ } else {
543
+ return $data;
544
+ }
545
+ }
546
+ }
547
+
548
+ /**
549
+ * The "customchannels" collection of methods.
550
+ * Typical usage is:
551
+ * <code>
552
+ * $adsenseService = new Google_AdsenseService(...);
553
+ * $customchannels = $adsenseService->customchannels;
554
+ * </code>
555
+ */
556
+ class Google_CustomchannelsServiceResource extends Google_ServiceResource {
557
+
558
+
559
+ /**
560
+ * List all custom channels in the specified ad client for this AdSense account.
561
+ * (customchannels.list)
562
+ *
563
+ * @param string $adClientId Ad client for which to list custom channels.
564
+ * @param array $optParams Optional parameters.
565
+ *
566
+ * @opt_param string pageToken A continuation token, used to page through custom channels. To retrieve the next page, set this parameter to the value of "nextPageToken" from the previous response.
567
+ * @opt_param int maxResults The maximum number of custom channels to include in the response, used for paging.
568
+ * @return Google_CustomChannels
569
+ */
570
+ public function listCustomchannels($adClientId, $optParams = array()) {
571
+ $params = array('adClientId' => $adClientId);
572
+ $params = array_merge($params, $optParams);
573
+ $data = $this->__call('list', array($params));
574
+ if ($this->useObjects()) {
575
+ return new Google_CustomChannels($data);
576
+ } else {
577
+ return $data;
578
+ }
579
+ }
580
+ /**
581
+ * Get the specified custom channel from the specified ad client. (customchannels.get)
582
+ *
583
+ * @param string $adClientId Ad client which contains the custom channel.
584
+ * @param string $customChannelId Custom channel to retrieve.
585
+ * @param array $optParams Optional parameters.
586
+ * @return Google_CustomChannel
587
+ */
588
+ public function get($adClientId, $customChannelId, $optParams = array()) {
589
+ $params = array('adClientId' => $adClientId, 'customChannelId' => $customChannelId);
590
+ $params = array_merge($params, $optParams);
591
+ $data = $this->__call('get', array($params));
592
+ if ($this->useObjects()) {
593
+ return new Google_CustomChannel($data);
594
+ } else {
595
+ return $data;
596
+ }
597
+ }
598
+ }
599
+
600
+ /**
601
+ * The "adunits" collection of methods.
602
+ * Typical usage is:
603
+ * <code>
604
+ * $adsenseService = new Google_AdsenseService(...);
605
+ * $adunits = $adsenseService->adunits;
606
+ * </code>
607
+ */
608
+ class Google_CustomchannelsAdunitsServiceResource extends Google_ServiceResource {
609
+
610
+
611
+ /**
612
+ * List all ad units in the specified custom channel. (adunits.list)
613
+ *
614
+ * @param string $adClientId Ad client which contains the custom channel.
615
+ * @param string $customChannelId Custom channel for which to list ad units.
616
+ * @param array $optParams Optional parameters.
617
+ *
618
+ * @opt_param bool includeInactive Whether to include inactive ad units. Default: true.
619
+ * @opt_param string pageToken A continuation token, used to page through ad units. To retrieve the next page, set this parameter to the value of "nextPageToken" from the previous response.
620
+ * @opt_param int maxResults The maximum number of ad units to include in the response, used for paging.
621
+ * @return Google_AdUnits
622
+ */
623
+ public function listCustomchannelsAdunits($adClientId, $customChannelId, $optParams = array()) {
624
+ $params = array('adClientId' => $adClientId, 'customChannelId' => $customChannelId);
625
+ $params = array_merge($params, $optParams);
626
+ $data = $this->__call('list', array($params));
627
+ if ($this->useObjects()) {
628
+ return new Google_AdUnits($data);
629
+ } else {
630
+ return $data;
631
+ }
632
+ }
633
+ }
634
+
635
+ /**
636
+ * Service definition for Google_Adsense (v1.1).
637
+ *
638
+ * <p>
639
+ * Gives AdSense publishers access to their inventory and the ability to generate reports
640
+ * </p>
641
+ *
642
+ * <p>
643
+ * For more information about this service, see the
644
+ * <a href="https://code.google.com/apis/adsense/management/" target="_blank">API Documentation</a>
645
+ * </p>
646
+ *
647
+ * @author Google, Inc.
648
+ */
649
+ class Google_AdsenseService extends Google_Service {
650
+ public $urlchannels;
651
+ public $adunits;
652
+ public $adunits_customchannels;
653
+ public $adclients;
654
+ public $reports;
655
+ public $accounts;
656
+ public $accounts_urlchannels;
657
+ public $accounts_adunits;
658
+ public $accounts_adunits_customchannels;
659
+ public $accounts_adclients;
660
+ public $accounts_reports;
661
+ public $accounts_customchannels;
662
+ public $accounts_customchannels_adunits;
663
+ public $customchannels;
664
+ public $customchannels_adunits;
665
+ /**
666
+ * Constructs the internal representation of the Adsense service.
667
+ *
668
+ * @param Google_Client $client
669
+ */
670
+ public function __construct(Google_Client $client) {
671
+ $this->servicePath = 'adsense/v1.1/';
672
+ $this->version = 'v1.1';
673
+ $this->serviceName = 'adsense';
674
+
675
+ $client->addService($this->serviceName, $this->version);
676
+ $this->urlchannels = new Google_UrlchannelsServiceResource($this, $this->serviceName, 'urlchannels', json_decode('{"methods": {"list": {"scopes": ["https://www.googleapis.com/auth/adsense", "https://www.googleapis.com/auth/adsense.readonly"], "parameters": {"pageToken": {"type": "string", "location": "query"}, "adClientId": {"required": true, "type": "string", "location": "path"}, "maxResults": {"location": "query", "minimum": "0", "type": "integer", "maximum": "10000", "format": "int32"}}, "id": "adsense.urlchannels.list", "httpMethod": "GET", "path": "adclients/{adClientId}/urlchannels", "response": {"$ref": "UrlChannels"}}}}', true));
677
+ $this->adunits = new Google_AdunitsServiceResource($this, $this->serviceName, 'adunits', json_decode('{"methods": {"list": {"scopes": ["https://www.googleapis.com/auth/adsense", "https://www.googleapis.com/auth/adsense.readonly"], "parameters": {"includeInactive": {"type": "boolean", "location": "query"}, "pageToken": {"type": "string", "location": "query"}, "adClientId": {"required": true, "type": "string", "location": "path"}, "maxResults": {"location": "query", "minimum": "0", "type": "integer", "maximum": "10000", "format": "int32"}}, "id": "adsense.adunits.list", "httpMethod": "GET", "path": "adclients/{adClientId}/adunits", "response": {"$ref": "AdUnits"}}, "get": {"scopes": ["https://www.googleapis.com/auth/adsense", "https://www.googleapis.com/auth/adsense.readonly"], "parameters": {"adClientId": {"required": true, "type": "string", "location": "path"}, "adUnitId": {"required": true, "type": "string", "location": "path"}}, "id": "adsense.adunits.get", "httpMethod": "GET", "path": "adclients/{adClientId}/adunits/{adUnitId}", "response": {"$ref": "AdUnit"}}}}', true));
678
+ $this->adunits_customchannels = new Google_AdunitsCustomchannelsServiceResource($this, $this->serviceName, 'customchannels', json_decode('{"methods": {"list": {"scopes": ["https://www.googleapis.com/auth/adsense", "https://www.googleapis.com/auth/adsense.readonly"], "parameters": {"pageToken": {"type": "string", "location": "query"}, "adClientId": {"required": true, "type": "string", "location": "path"}, "maxResults": {"location": "query", "minimum": "0", "type": "integer", "maximum": "10000", "format": "int32"}, "adUnitId": {"required": true, "type": "string", "location": "path"}}, "id": "adsense.adunits.customchannels.list", "httpMethod": "GET", "path": "adclients/{adClientId}/adunits/{adUnitId}/customchannels", "response": {"$ref": "CustomChannels"}}}}', true));
679
+ $this->adclients = new Google_AdclientsServiceResource($this, $this->serviceName, 'adclients', json_decode('{"methods": {"list": {"scopes": ["https://www.googleapis.com/auth/adsense", "https://www.googleapis.com/auth/adsense.readonly"], "parameters": {"pageToken": {"type": "string", "location": "query"}, "maxResults": {"location": "query", "minimum": "0", "type": "integer", "maximum": "10000", "format": "int32"}}, "response": {"$ref": "AdClients"}, "httpMethod": "GET", "path": "adclients", "id": "adsense.adclients.list"}}}', true));
680
+ $this->reports = new Google_ReportsServiceResource($this, $this->serviceName, 'reports', json_decode('{"methods": {"generate": {"scopes": ["https://www.googleapis.com/auth/adsense", "https://www.googleapis.com/auth/adsense.readonly"], "parameters": {"sort": {"repeated": true, "type": "string", "location": "query"}, "startDate": {"required": true, "type": "string", "location": "query"}, "endDate": {"required": true, "type": "string", "location": "query"}, "locale": {"type": "string", "location": "query"}, "metric": {"repeated": true, "type": "string", "location": "query"}, "maxResults": {"location": "query", "minimum": "0", "type": "integer", "maximum": "50000", "format": "int32"}, "filter": {"repeated": true, "type": "string", "location": "query"}, "currency": {"type": "string", "location": "query"}, "startIndex": {"location": "query", "minimum": "0", "type": "integer", "maximum": "5000", "format": "int32"}, "dimension": {"repeated": true, "type": "string", "location": "query"}, "accountId": {"repeated": true, "type": "string", "location": "query"}}, "id": "adsense.reports.generate", "httpMethod": "GET", "supportsMediaDownload": true, "path": "reports", "response": {"$ref": "AdsenseReportsGenerateResponse"}}}}', true));
681
+ $this->accounts = new Google_AccountsServiceResource($this, $this->serviceName, 'accounts', json_decode('{"methods": {"list": {"scopes": ["https://www.googleapis.com/auth/adsense", "https://www.googleapis.com/auth/adsense.readonly"], "parameters": {"pageToken": {"type": "string", "location": "query"}, "maxResults": {"location": "query", "minimum": "0", "type": "integer", "maximum": "10000", "format": "int32"}}, "response": {"$ref": "Accounts"}, "httpMethod": "GET", "path": "accounts", "id": "adsense.accounts.list"}, "get": {"scopes": ["https://www.googleapis.com/auth/adsense", "https://www.googleapis.com/auth/adsense.readonly"], "parameters": {"tree": {"type": "boolean", "location": "query"}, "accountId": {"required": true, "type": "string", "location": "path"}}, "id": "adsense.accounts.get", "httpMethod": "GET", "path": "accounts/{accountId}", "response": {"$ref": "Account"}}}}', true));
682
+ $this->accounts_urlchannels = new Google_AccountsUrlchannelsServiceResource($this, $this->serviceName, 'urlchannels', json_decode('{"methods": {"list": {"scopes": ["https://www.googleapis.com/auth/adsense", "https://www.googleapis.com/auth/adsense.readonly"], "parameters": {"pageToken": {"type": "string", "location": "query"}, "adClientId": {"required": true, "type": "string", "location": "path"}, "maxResults": {"location": "query", "minimum": "0", "type": "integer", "maximum": "10000", "format": "int32"}, "accountId": {"required": true, "type": "string", "location": "path"}}, "id": "adsense.accounts.urlchannels.list", "httpMethod": "GET", "path": "accounts/{accountId}/adclients/{adClientId}/urlchannels", "response": {"$ref": "UrlChannels"}}}}', true));
683
+ $this->accounts_adunits = new Google_AccountsAdunitsServiceResource($this, $this->serviceName, 'adunits', json_decode('{"methods": {"list": {"scopes": ["https://www.googleapis.com/auth/adsense", "https://www.googleapis.com/auth/adsense.readonly"], "parameters": {"includeInactive": {"type": "boolean", "location": "query"}, "pageToken": {"type": "string", "location": "query"}, "adClientId": {"required": true, "type": "string", "location": "path"}, "maxResults": {"location": "query", "minimum": "0", "type": "integer", "maximum": "10000", "format": "int32"}, "accountId": {"required": true, "type": "string", "location": "path"}}, "id": "adsense.accounts.adunits.list", "httpMethod": "GET", "path": "accounts/{accountId}/adclients/{adClientId}/adunits", "response": {"$ref": "AdUnits"}}, "get": {"scopes": ["https://www.googleapis.com/auth/adsense", "https://www.googleapis.com/auth/adsense.readonly"], "parameters": {"adClientId": {"required": true, "type": "string", "location": "path"}, "adUnitId": {"required": true, "type": "string", "location": "path"}, "accountId": {"required": true, "type": "string", "location": "path"}}, "id": "adsense.accounts.adunits.get", "httpMethod": "GET", "path": "accounts/{accountId}/adclients/{adClientId}/adunits/{adUnitId}", "response": {"$ref": "AdUnit"}}}}', true));
684
+ $this->accounts_adunits_customchannels = new Google_AccountsAdunitsCustomchannelsServiceResource($this, $this->serviceName, 'customchannels', json_decode('{"methods": {"list": {"scopes": ["https://www.googleapis.com/auth/adsense", "https://www.googleapis.com/auth/adsense.readonly"], "parameters": {"pageToken": {"type": "string", "location": "query"}, "adClientId": {"required": true, "type": "string", "location": "path"}, "maxResults": {"location": "query", "minimum": "0", "type": "integer", "maximum": "10000", "format": "int32"}, "adUnitId": {"required": true, "type": "string", "location": "path"}, "accountId": {"required": true, "type": "string", "location": "path"}}, "id": "adsense.accounts.adunits.customchannels.list", "httpMethod": "GET", "path": "accounts/{accountId}/adclients/{adClientId}/adunits/{adUnitId}/customchannels", "response": {"$ref": "CustomChannels"}}}}', true));
685
+ $this->accounts_adclients = new Google_AccountsAdclientsServiceResource($this, $this->serviceName, 'adclients', json_decode('{"methods": {"list": {"scopes": ["https://www.googleapis.com/auth/adsense", "https://www.googleapis.com/auth/adsense.readonly"], "parameters": {"pageToken": {"type": "string", "location": "query"}, "maxResults": {"location": "query", "minimum": "0", "type": "integer", "maximum": "10000", "format": "int32"}, "accountId": {"required": true, "type": "string", "location": "path"}}, "id": "adsense.accounts.adclients.list", "httpMethod": "GET", "path": "accounts/{accountId}/adclients", "response": {"$ref": "AdClients"}}}}', true));
686
+ $this->accounts_reports = new Google_AccountsReportsServiceResource($this, $this->serviceName, 'reports', json_decode('{"methods": {"generate": {"scopes": ["https://www.googleapis.com/auth/adsense", "https://www.googleapis.com/auth/adsense.readonly"], "parameters": {"sort": {"repeated": true, "type": "string", "location": "query"}, "startDate": {"required": true, "type": "string", "location": "query"}, "endDate": {"required": true, "type": "string", "location": "query"}, "locale": {"type": "string", "location": "query"}, "metric": {"repeated": true, "type": "string", "location": "query"}, "maxResults": {"location": "query", "minimum": "0", "type": "integer", "maximum": "50000", "format": "int32"}, "filter": {"repeated": true, "type": "string", "location": "query"}, "currency": {"type": "string", "location": "query"}, "startIndex": {"location": "query", "minimum": "0", "type": "integer", "maximum": "5000", "format": "int32"}, "dimension": {"repeated": true, "type": "string", "location": "query"}, "accountId": {"required": true, "type": "string", "location": "path"}}, "id": "adsense.accounts.reports.generate", "httpMethod": "GET", "supportsMediaDownload": true, "path": "accounts/{accountId}/reports", "response": {"$ref": "AdsenseReportsGenerateResponse"}}}}', true));
687
+ $this->accounts_customchannels = new Google_AccountsCustomchannelsServiceResource($this, $this->serviceName, 'customchannels', json_decode('{"methods": {"list": {"scopes": ["https://www.googleapis.com/auth/adsense", "https://www.googleapis.com/auth/adsense.readonly"], "parameters": {"pageToken": {"type": "string", "location": "query"}, "adClientId": {"required": true, "type": "string", "location": "path"}, "maxResults": {"location": "query", "minimum": "0", "type": "integer", "maximum": "10000", "format": "int32"}, "accountId": {"required": true, "type": "string", "location": "path"}}, "id": "adsense.accounts.customchannels.list", "httpMethod": "GET", "path": "accounts/{accountId}/adclients/{adClientId}/customchannels", "response": {"$ref": "CustomChannels"}}, "get": {"scopes": ["https://www.googleapis.com/auth/adsense", "https://www.googleapis.com/auth/adsense.readonly"], "parameters": {"customChannelId": {"required": true, "type": "string", "location": "path"}, "adClientId": {"required": true, "type": "string", "location": "path"}, "accountId": {"required": true, "type": "string", "location": "path"}}, "id": "adsense.accounts.customchannels.get", "httpMethod": "GET", "path": "accounts/{accountId}/adclients/{adClientId}/customchannels/{customChannelId}", "response": {"$ref": "CustomChannel"}}}}', true));
688
+ $this->accounts_customchannels_adunits = new Google_AccountsCustomchannelsAdunitsServiceResource($this, $this->serviceName, 'adunits', json_decode('{"methods": {"list": {"scopes": ["https://www.googleapis.com/auth/adsense", "https://www.googleapis.com/auth/adsense.readonly"], "parameters": {"includeInactive": {"type": "boolean", "location": "query"}, "customChannelId": {"required": true, "type": "string", "location": "path"}, "adClientId": {"required": true, "type": "string", "location": "path"}, "maxResults": {"location": "query", "minimum": "0", "type": "integer", "maximum": "10000", "format": "int32"}, "pageToken": {"type": "string", "location": "query"}, "accountId": {"required": true, "type": "string", "location": "path"}}, "id": "adsense.accounts.customchannels.adunits.list", "httpMethod": "GET", "path": "accounts/{accountId}/adclients/{adClientId}/customchannels/{customChannelId}/adunits", "response": {"$ref": "AdUnits"}}}}', true));
689
+ $this->customchannels = new Google_CustomchannelsServiceResource($this, $this->serviceName, 'customchannels', json_decode('{"methods": {"list": {"scopes": ["https://www.googleapis.com/auth/adsense", "https://www.googleapis.com/auth/adsense.readonly"], "parameters": {"pageToken": {"type": "string", "location": "query"}, "adClientId": {"required": true, "type": "string", "location": "path"}, "maxResults": {"location": "query", "minimum": "0", "type": "integer", "maximum": "10000", "format": "int32"}}, "id": "adsense.customchannels.list", "httpMethod": "GET", "path": "adclients/{adClientId}/customchannels", "response": {"$ref": "CustomChannels"}}, "get": {"scopes": ["https://www.googleapis.com/auth/adsense", "https://www.googleapis.com/auth/adsense.readonly"], "parameters": {"customChannelId": {"required": true, "type": "string", "location": "path"}, "adClientId": {"required": true, "type": "string", "location": "path"}}, "id": "adsense.customchannels.get", "httpMethod": "GET", "path": "adclients/{adClientId}/customchannels/{customChannelId}", "response": {"$ref": "CustomChannel"}}}}', true));
690
+ $this->customchannels_adunits = new Google_CustomchannelsAdunitsServiceResource($this, $this->serviceName, 'adunits', json_decode('{"methods": {"list": {"scopes": ["https://www.googleapis.com/auth/adsense", "https://www.googleapis.com/auth/adsense.readonly"], "parameters": {"includeInactive": {"type": "boolean", "location": "query"}, "pageToken": {"type": "string", "location": "query"}, "customChannelId": {"required": true, "type": "string", "location": "path"}, "adClientId": {"required": true, "type": "string", "location": "path"}, "maxResults": {"location": "query", "minimum": "0", "type": "integer", "maximum": "10000", "format": "int32"}}, "id": "adsense.customchannels.adunits.list", "httpMethod": "GET", "path": "adclients/{adClientId}/customchannels/{customChannelId}/adunits", "response": {"$ref": "AdUnits"}}}}', true));
691
+
692
+ }
693
+ }
694
+
695
+ class Google_Account extends Google_Model {
696
+ public $kind;
697
+ public $id;
698
+ protected $__subAccountsType = 'Google_Account';
699
+ protected $__subAccountsDataType = 'array';
700
+ public $subAccounts;
701
+ public $name;
702
+ public function setKind($kind) {
703
+ $this->kind = $kind;
704
+ }
705
+ public function getKind() {
706
+ return $this->kind;
707
+ }
708
+ public function setId($id) {
709
+ $this->id = $id;
710
+ }
711
+ public function getId() {
712
+ return $this->id;
713
+ }
714
+ public function setSubAccounts(/* array(Google_Account) */ $subAccounts) {
715
+ $this->assertIsArray($subAccounts, 'Google_Account', __METHOD__);
716
+ $this->subAccounts = $subAccounts;
717
+ }
718
+ public function getSubAccounts() {
719
+ return $this->subAccounts;
720
+ }
721
+ public function setName($name) {
722
+ $this->name = $name;
723
+ }
724
+ public function getName() {
725
+ return $this->name;
726
+ }
727
+ }
728
+
729
+ class Google_Accounts extends Google_Model {
730
+ public $nextPageToken;
731
+ protected $__itemsType = 'Google_Account';
732
+ protected $__itemsDataType = 'array';
733
+ public $items;
734
+ public $kind;
735
+ public $etag;
736
+ public function setNextPageToken($nextPageToken) {
737
+ $this->nextPageToken = $nextPageToken;
738
+ }
739
+ public function getNextPageToken() {
740
+ return $this->nextPageToken;
741
+ }
742
+ public function setItems(/* array(Google_Account) */ $items) {
743
+ $this->assertIsArray($items, 'Google_Account', __METHOD__);
744
+ $this->items = $items;
745
+ }
746
+ public function getItems() {
747
+ return $this->items;
748
+ }
749
+ public function setKind($kind) {
750
+ $this->kind = $kind;
751
+ }
752
+ public function getKind() {
753
+ return $this->kind;
754
+ }
755
+ public function setEtag($etag) {
756
+ $this->etag = $etag;
757
+ }
758
+ public function getEtag() {
759
+ return $this->etag;
760
+ }
761
+ }
762
+
763
+ class Google_AdClient extends Google_Model {
764
+ public $productCode;
765
+ public $kind;
766
+ public $id;
767
+ public $supportsReporting;
768
+ public function setProductCode($productCode) {
769
+ $this->productCode = $productCode;
770
+ }
771
+ public function getProductCode() {
772
+ return $this->productCode;
773
+ }
774
+ public function setKind($kind) {
775
+ $this->kind = $kind;
776
+ }
777
+ public function getKind() {
778
+ return $this->kind;
779
+ }
780
+ public function setId($id) {
781
+ $this->id = $id;
782
+ }
783
+ public function getId() {
784
+ return $this->id;
785
+ }
786
+ public function setSupportsReporting($supportsReporting) {
787
+ $this->supportsReporting = $supportsReporting;
788
+ }
789
+ public function getSupportsReporting() {
790
+ return $this->supportsReporting;
791
+ }
792
+ }
793
+
794
+ class Google_AdClients extends Google_Model {
795
+ public $nextPageToken;
796
+ protected $__itemsType = 'Google_AdClient';
797
+ protected $__itemsDataType = 'array';
798
+ public $items;
799
+ public $kind;
800
+ public $etag;
801
+ public function setNextPageToken($nextPageToken) {
802
+ $this->nextPageToken = $nextPageToken;
803
+ }
804
+ public function getNextPageToken() {
805
+ return $this->nextPageToken;
806
+ }
807
+ public function setItems(/* array(Google_AdClient) */ $items) {
808
+ $this->assertIsArray($items, 'Google_AdClient', __METHOD__);
809
+ $this->items = $items;
810
+ }
811
+ public function getItems() {
812
+ return $this->items;
813
+ }
814
+ public function setKind($kind) {
815
+ $this->kind = $kind;
816
+ }
817
+ public function getKind() {
818
+ return $this->kind;
819
+ }
820
+ public function setEtag($etag) {
821
+ $this->etag = $etag;
822
+ }
823
+ public function getEtag() {
824
+ return $this->etag;
825
+ }
826
+ }
827
+
828
+ class Google_AdUnit extends Google_Model {
829
+ public $status;
830
+ public $kind;
831
+ public $code;
832
+ public $id;
833
+ public $name;
834
+ public function setStatus($status) {
835
+ $this->status = $status;
836
+ }
837
+ public function getStatus() {
838
+ return $this->status;
839
+ }
840
+ public function setKind($kind) {
841
+ $this->kind = $kind;
842
+ }
843
+ public function getKind() {
844
+ return $this->kind;
845
+ }
846
+ public function setCode($code) {
847
+ $this->code = $code;
848
+ }
849
+ public function getCode() {
850
+ return $this->code;
851
+ }
852
+ public function setId($id) {
853
+ $this->id = $id;
854
+ }
855
+ public function getId() {
856
+ return $this->id;
857
+ }
858
+ public function setName($name) {
859
+ $this->name = $name;
860
+ }
861
+ public function getName() {
862
+ return $this->name;
863
+ }
864
+ }
865
+
866
+ class Google_AdUnits extends Google_Model {
867
+ public $nextPageToken;
868
+ protected $__itemsType = 'Google_AdUnit';
869
+ protected $__itemsDataType = 'array';
870
+ public $items;
871
+ public $kind;
872
+ public $etag;
873
+ public function setNextPageToken($nextPageToken) {
874
+ $this->nextPageToken = $nextPageToken;
875
+ }
876
+ public function getNextPageToken() {
877
+ return $this->nextPageToken;
878
+ }
879
+ public function setItems(/* array(Google_AdUnit) */ $items) {
880
+ $this->assertIsArray($items, 'Google_AdUnit', __METHOD__);
881
+ $this->items = $items;
882
+ }
883
+ public function getItems() {
884
+ return $this->items;
885
+ }
886
+ public function setKind($kind) {
887
+ $this->kind = $kind;
888
+ }
889
+ public function getKind() {
890
+ return $this->kind;
891
+ }
892
+ public function setEtag($etag) {
893
+ $this->etag = $etag;
894
+ }
895
+ public function getEtag() {
896
+ return $this->etag;
897
+ }
898
+ }
899
+
900
+ class Google_AdsenseReportsGenerateResponse extends Google_Model {
901
+ public $kind;
902
+ public $rows;
903
+ public $warnings;
904
+ public $totals;
905
+ protected $__headersType = 'Google_AdsenseReportsGenerateResponseHeaders';
906
+ protected $__headersDataType = 'array';
907
+ public $headers;
908
+ public $totalMatchedRows;
909
+ public $averages;
910
+ public function setKind($kind) {
911
+ $this->kind = $kind;
912
+ }
913
+ public function getKind() {
914
+ return $this->kind;
915
+ }
916
+ public function setRows(/* array(Google_string) */ $rows) {
917
+ $this->assertIsArray($rows, 'Google_string', __METHOD__);
918
+ $this->rows = $rows;
919
+ }
920
+ public function getRows() {
921
+ return $this->rows;
922
+ }
923
+ public function setWarnings(/* array(Google_string) */ $warnings) {
924
+ $this->assertIsArray($warnings, 'Google_string', __METHOD__);
925
+ $this->warnings = $warnings;
926
+ }
927
+ public function getWarnings() {
928
+ return $this->warnings;
929
+ }
930
+ public function setTotals(/* array(Google_string) */ $totals) {
931
+ $this->assertIsArray($totals, 'Google_string', __METHOD__);
932
+ $this->totals = $totals;
933
+ }
934
+ public function getTotals() {
935
+ return $this->totals;
936
+ }
937
+ public function setHeaders(/* array(Google_AdsenseReportsGenerateResponseHeaders) */ $headers) {
938
+ $this->assertIsArray($headers, 'Google_AdsenseReportsGenerateResponseHeaders', __METHOD__);
939
+ $this->headers = $headers;
940
+ }
941
+ public function getHeaders() {
942
+ return $this->headers;
943
+ }
944
+ public function setTotalMatchedRows($totalMatchedRows) {
945
+ $this->totalMatchedRows = $totalMatchedRows;
946
+ }
947
+ public function getTotalMatchedRows() {
948
+ return $this->totalMatchedRows;
949
+ }
950
+ public function setAverages(/* array(Google_string) */ $averages) {
951
+ $this->assertIsArray($averages, 'Google_string', __METHOD__);
952
+ $this->averages = $averages;
953
+ }
954
+ public function getAverages() {
955
+ return $this->averages;
956
+ }
957
+ }
958
+
959
+ class Google_AdsenseReportsGenerateResponseHeaders extends Google_Model {
960
+ public $currency;
961
+ public $type;
962
+ public $name;
963
+ public function setCurrency($currency) {
964
+ $this->currency = $currency;
965
+ }
966
+ public function getCurrency() {
967
+ return $this->currency;
968
+ }
969
+ public function setType($type) {
970
+ $this->type = $type;
971
+ }
972
+ public function getType() {
973
+ return $this->type;
974
+ }
975
+ public function setName($name) {
976
+ $this->name = $name;
977
+ }
978
+ public function getName() {
979
+ return $this->name;
980
+ }
981
+ }
982
+
983
+ class Google_CustomChannel extends Google_Model {
984
+ public $kind;
985
+ public $code;
986
+ protected $__targetingInfoType = 'Google_CustomChannelTargetingInfo';
987
+ protected $__targetingInfoDataType = '';
988
+ public $targetingInfo;
989
+ public $id;
990
+ public $name;
991
+ public function setKind($kind) {
992
+ $this->kind = $kind;
993
+ }
994
+ public function getKind() {
995
+ return $this->kind;
996
+ }
997
+ public function setCode($code) {
998
+ $this->code = $code;
999
+ }
1000
+ public function getCode() {
1001
+ return $this->code;
1002
+ }
1003
+ public function setTargetingInfo(Google_CustomChannelTargetingInfo $targetingInfo) {
1004
+ $this->targetingInfo = $targetingInfo;
1005
+ }
1006
+ public function getTargetingInfo() {
1007
+ return $this->targetingInfo;
1008
+ }
1009
+ public function setId($id) {
1010
+ $this->id = $id;
1011
+ }
1012
+ public function getId() {
1013
+ return $this->id;
1014
+ }
1015
+ public function setName($name) {
1016
+ $this->name = $name;
1017
+ }
1018
+ public function getName() {
1019
+ return $this->name;
1020
+ }
1021
+ }
1022
+
1023
+ class Google_CustomChannelTargetingInfo extends Google_Model {
1024
+ public $location;
1025
+ public $adsAppearOn;
1026
+ public $siteLanguage;
1027
+ public $description;
1028
+ public function setLocation($location) {
1029
+ $this->location = $location;
1030
+ }
1031
+ public function getLocation() {
1032
+ return $this->location;
1033
+ }
1034
+ public function setAdsAppearOn($adsAppearOn) {
1035
+ $this->adsAppearOn = $adsAppearOn;
1036
+ }
1037
+ public function getAdsAppearOn() {
1038
+ return $this->adsAppearOn;
1039
+ }
1040
+ public function setSiteLanguage($siteLanguage) {
1041
+ $this->siteLanguage = $siteLanguage;
1042
+ }
1043
+ public function getSiteLanguage() {
1044
+ return $this->siteLanguage;
1045
+ }
1046
+ public function setDescription($description) {
1047
+ $this->description = $description;
1048
+ }
1049
+ public function getDescription() {
1050
+ return $this->description;
1051
+ }
1052
+ }
1053
+
1054
+ class Google_CustomChannels extends Google_Model {
1055
+ public $nextPageToken;
1056
+ protected $__itemsType = 'Google_CustomChannel';
1057
+ protected $__itemsDataType = 'array';
1058
+ public $items;
1059
+ public $kind;
1060
+ public $etag;
1061
+ public function setNextPageToken($nextPageToken) {
1062
+ $this->nextPageToken = $nextPageToken;
1063
+ }
1064
+ public function getNextPageToken() {
1065
+ return $this->nextPageToken;
1066
+ }
1067
+ public function setItems(/* array(Google_CustomChannel) */ $items) {
1068
+ $this->assertIsArray($items, 'Google_CustomChannel', __METHOD__);
1069
+ $this->items = $items;
1070
+ }
1071
+ public function getItems() {
1072
+ return $this->items;
1073
+ }
1074
+ public function setKind($kind) {
1075
+ $this->kind = $kind;
1076
+ }
1077
+ public function getKind() {
1078
+ return $this->kind;
1079
+ }
1080
+ public function setEtag($etag) {
1081
+ $this->etag = $etag;
1082
+ }
1083
+ public function getEtag() {
1084
+ return $this->etag;
1085
+ }
1086
+ }
1087
+
1088
+ class Google_UrlChannel extends Google_Model {
1089
+ public $kind;
1090
+ public $id;
1091
+ public $urlPattern;
1092
+ public function setKind($kind) {
1093
+ $this->kind = $kind;
1094
+ }
1095
+ public function getKind() {
1096
+ return $this->kind;
1097
+ }
1098
+ public function setId($id) {
1099
+ $this->id = $id;
1100
+ }
1101
+ public function getId() {
1102
+ return $this->id;
1103
+ }
1104
+ public function setUrlPattern($urlPattern) {
1105
+ $this->urlPattern = $urlPattern;
1106
+ }
1107
+ public function getUrlPattern() {
1108
+ return $this->urlPattern;
1109
+ }
1110
+ }
1111
+
1112
+ class Google_UrlChannels extends Google_Model {
1113
+ public $nextPageToken;
1114
+ protected $__itemsType = 'Google_UrlChannel';
1115
+ protected $__itemsDataType = 'array';
1116
+ public $items;
1117
+ public $kind;
1118
+ public $etag;
1119
+ public function setNextPageToken($nextPageToken) {
1120
+ $this->nextPageToken = $nextPageToken;
1121
+ }
1122
+ public function getNextPageToken() {
1123
+ return $this->nextPageToken;
1124
+ }
1125
+ public function setItems(/* array(Google_UrlChannel) */ $items) {
1126
+ $this->assertIsArray($items, 'Google_UrlChannel', __METHOD__);
1127
+ $this->items = $items;
1128
+ }
1129
+ public function getItems() {
1130
+ return $this->items;
1131
+ }
1132
+ public function setKind($kind) {
1133
+ $this->kind = $kind;
1134
+ }
1135
+ public function getKind() {
1136
+ return $this->kind;
1137
+ }
1138
+ public function setEtag($etag) {
1139
+ $this->etag = $etag;
1140
+ }
1141
+ public function getEtag() {
1142
+ return $this->etag;
1143
+ }
1144
+ }
google-api-php-client/src/contrib/Google_AnalyticsService.php ADDED
@@ -0,0 +1,1887 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
4
+ * use this file except in compliance with the License. You may obtain a copy of
5
+ * the License at
6
+ *
7
+ * http://www.apache.org/licenses/LICENSE-2.0
8
+ *
9
+ * Unless required by applicable law or agreed to in writing, software
10
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12
+ * License for the specific language governing permissions and limitations under
13
+ * the License.
14
+ */
15
+
16
+
17
+ /**
18
+ * The "management" collection of methods.
19
+ * Typical usage is:
20
+ * <code>
21
+ * $analyticsService = new Google_AnalyticsService(...);
22
+ * $management = $analyticsService->management;
23
+ * </code>
24
+ */
25
+ class Google_ManagementServiceResource extends Google_ServiceResource {
26
+
27
+
28
+ }
29
+
30
+ /**
31
+ * The "webproperties" collection of methods.
32
+ * Typical usage is:
33
+ * <code>
34
+ * $analyticsService = new Google_AnalyticsService(...);
35
+ * $webproperties = $analyticsService->webproperties;
36
+ * </code>
37
+ */
38
+ class Google_ManagementWebpropertiesServiceResource extends Google_ServiceResource {
39
+
40
+
41
+ /**
42
+ * Lists web properties to which the user has access. (webproperties.list)
43
+ *
44
+ * @param string $accountId Account ID to retrieve web properties for. Can either be a specific account ID or '~all', which refers to all the accounts that user has access to.
45
+ * @param array $optParams Optional parameters.
46
+ *
47
+ * @opt_param int max-results The maximum number of web properties to include in this response.
48
+ * @opt_param int start-index An index of the first entity to retrieve. Use this parameter as a pagination mechanism along with the max-results parameter.
49
+ * @return Google_Webproperties
50
+ */
51
+ public function listManagementWebproperties($accountId, $optParams = array()) {
52
+ $params = array('accountId' => $accountId);
53
+ $params = array_merge($params, $optParams);
54
+ $data = $this->__call('list', array($params));
55
+ if ($this->useObjects()) {
56
+ return new Google_Webproperties($data);
57
+ } else {
58
+ return $data;
59
+ }
60
+ }
61
+ }
62
+ /**
63
+ * The "segments" collection of methods.
64
+ * Typical usage is:
65
+ * <code>
66
+ * $analyticsService = new Google_AnalyticsService(...);
67
+ * $segments = $analyticsService->segments;
68
+ * </code>
69
+ */
70
+ class Google_ManagementSegmentsServiceResource extends Google_ServiceResource {
71
+
72
+
73
+ /**
74
+ * Lists advanced segments to which the user has access. (segments.list)
75
+ *
76
+ * @param array $optParams Optional parameters.
77
+ *
78
+ * @opt_param int max-results The maximum number of advanced segments to include in this response.
79
+ * @opt_param int start-index An index of the first advanced segment to retrieve. Use this parameter as a pagination mechanism along with the max-results parameter.
80
+ * @return Google_Segments
81
+ */
82
+ public function listManagementSegments($optParams = array()) {
83
+ $params = array();
84
+ $params = array_merge($params, $optParams);
85
+ $data = $this->__call('list', array($params));
86
+ if ($this->useObjects()) {
87
+ return new Google_Segments($data);
88
+ } else {
89
+ return $data;
90
+ }
91
+ }
92
+ }
93
+ /**
94
+ * The "accounts" collection of methods.
95
+ * Typical usage is:
96
+ * <code>
97
+ * $analyticsService = new Google_AnalyticsService(...);
98
+ * $accounts = $analyticsService->accounts;
99
+ * </code>
100
+ */
101
+ class Google_ManagementAccountsServiceResource extends Google_ServiceResource {
102
+
103
+
104
+ /**
105
+ * Lists all accounts to which the user has access. (accounts.list)
106
+ *
107
+ * @param array $optParams Optional parameters.
108
+ *
109
+ * @opt_param int max-results The maximum number of accounts to include in this response.
110
+ * @opt_param int start-index An index of the first account to retrieve. Use this parameter as a pagination mechanism along with the max-results parameter.
111
+ * @return Google_Accounts
112
+ */
113
+ public function listManagementAccounts($optParams = array()) {
114
+ $params = array();
115
+ $params = array_merge($params, $optParams);
116
+ $data = $this->__call('list', array($params));
117
+ if ($this->useObjects()) {
118
+ return new Google_Accounts($data);
119
+ } else {
120
+ return $data;
121
+ }
122
+ }
123
+ }
124
+ /**
125
+ * The "goals" collection of methods.
126
+ * Typical usage is:
127
+ * <code>
128
+ * $analyticsService = new Google_AnalyticsService(...);
129
+ * $goals = $analyticsService->goals;
130
+ * </code>
131
+ */
132
+ class Google_ManagementGoalsServiceResource extends Google_ServiceResource {
133
+
134
+
135
+ /**
136
+ * Lists goals to which the user has access. (goals.list)
137
+ *
138
+ * @param string $accountId Account ID to retrieve goals for. Can either be a specific account ID or '~all', which refers to all the accounts that user has access to.
139
+ * @param string $webPropertyId Web property ID to retrieve goals for. Can either be a specific web property ID or '~all', which refers to all the web properties that user has access to.
140
+ * @param string $profileId Profile ID to retrieve goals for. Can either be a specific profile ID or '~all', which refers to all the profiles that user has access to.
141
+ * @param array $optParams Optional parameters.
142
+ *
143
+ * @opt_param int max-results The maximum number of goals to include in this response.
144
+ * @opt_param int start-index An index of the first goal to retrieve. Use this parameter as a pagination mechanism along with the max-results parameter.
145
+ * @return Google_Goals
146
+ */
147
+ public function listManagementGoals($accountId, $webPropertyId, $profileId, $optParams = array()) {
148
+ $params = array('accountId' => $accountId, 'webPropertyId' => $webPropertyId, 'profileId' => $profileId);
149
+ $params = array_merge($params, $optParams);
150
+ $data = $this->__call('list', array($params));
151
+ if ($this->useObjects()) {
152
+ return new Google_Goals($data);
153
+ } else {
154
+ return $data;
155
+ }
156
+ }
157
+ }
158
+ /**
159
+ * The "profiles" collection of methods.
160
+ * Typical usage is:
161
+ * <code>
162
+ * $analyticsService = new Google_AnalyticsService(...);
163
+ * $profiles = $analyticsService->profiles;
164
+ * </code>
165
+ */
166
+ class Google_ManagementProfilesServiceResource extends Google_ServiceResource {
167
+
168
+
169
+ /**
170
+ * Lists profiles to which the user has access. (profiles.list)
171
+ *
172
+ * @param string $accountId Account ID for the profiles to retrieve. Can either be a specific account ID or '~all', which refers to all the accounts to which the user has access.
173
+ * @param string $webPropertyId Web property ID for the profiles to retrieve. Can either be a specific web property ID or '~all', which refers to all the web properties to which the user has access.
174
+ * @param array $optParams Optional parameters.
175
+ *
176
+ * @opt_param int max-results The maximum number of profiles to include in this response.
177
+ * @opt_param int start-index An index of the first entity to retrieve. Use this parameter as a pagination mechanism along with the max-results parameter.
178
+ * @return Google_Profiles
179
+ */
180
+ public function listManagementProfiles($accountId, $webPropertyId, $optParams = array()) {
181
+ $params = array('accountId' => $accountId, 'webPropertyId' => $webPropertyId);
182
+ $params = array_merge($params, $optParams);
183
+ $data = $this->__call('list', array($params));
184
+ if ($this->useObjects()) {
185
+ return new Google_Profiles($data);
186
+ } else {
187
+ return $data;
188
+ }
189
+ }
190
+ }
191
+
192
+ /**
193
+ * The "data" collection of methods.
194
+ * Typical usage is:
195
+ * <code>
196
+ * $analyticsService = new Google_AnalyticsService(...);
197
+ * $data = $analyticsService->data;
198
+ * </code>
199
+ */
200
+ class Google_DataServiceResource extends Google_ServiceResource {
201
+
202
+
203
+ }
204
+
205
+ /**
206
+ * The "mcf" collection of methods.
207
+ * Typical usage is:
208
+ * <code>
209
+ * $analyticsService = new Google_AnalyticsService(...);
210
+ * $mcf = $analyticsService->mcf;
211
+ * </code>
212
+ */
213
+ class Google_DataMcfServiceResource extends Google_ServiceResource {
214
+
215
+
216
+ /**
217
+ * Returns Analytics Multi-Channel Funnels data for a profile. (mcf.get)
218
+ *
219
+ * @param string $ids Unique table ID for retrieving Analytics data. Table ID is of the form ga:XXXX, where XXXX is the Analytics profile ID.
220
+ * @param string $start_date Start date for fetching Analytics data. All requests should specify a start date formatted as YYYY-MM-DD.
221
+ * @param string $end_date End date for fetching Analytics data. All requests should specify an end date formatted as YYYY-MM-DD.
222
+ * @param string $metrics A comma-separated list of Multi-Channel Funnels metrics. E.g., 'mcf:totalConversions,mcf:totalConversionValue'. At least one metric must be specified.
223
+ * @param array $optParams Optional parameters.
224
+ *
225
+ * @opt_param int max-results The maximum number of entries to include in this feed.
226
+ * @opt_param string sort A comma-separated list of dimensions or metrics that determine the sort order for the Analytics data.
227
+ * @opt_param string dimensions A comma-separated list of Multi-Channel Funnels dimensions. E.g., 'mcf:source,mcf:medium'.
228
+ * @opt_param int start-index An index of the first entity to retrieve. Use this parameter as a pagination mechanism along with the max-results parameter.
229
+ * @opt_param string filters A comma-separated list of dimension or metric filters to be applied to the Analytics data.
230
+ * @return Google_McfData
231
+ */
232
+ public function get($ids, $start_date, $end_date, $metrics, $optParams = array()) {
233
+ $params = array('ids' => $ids, 'start-date' => $start_date, 'end-date' => $end_date, 'metrics' => $metrics);
234
+ $params = array_merge($params, $optParams);
235
+ $data = $this->__call('get', array($params));
236
+ if ($this->useObjects()) {
237
+ return new Google_McfData($data);
238
+ } else {
239
+ return $data;
240
+ }
241
+ }
242
+ }
243
+ /**
244
+ * The "ga" collection of methods.
245
+ * Typical usage is:
246
+ * <code>
247
+ * $analyticsService = new Google_AnalyticsService(...);
248
+ * $ga = $analyticsService->ga;
249
+ * </code>
250
+ */
251
+ class Google_DataGaServiceResource extends Google_ServiceResource {
252
+
253
+
254
+ /**
255
+ * Returns Analytics data for a profile. (ga.get)
256
+ *
257
+ * @param string $ids Unique table ID for retrieving Analytics data. Table ID is of the form ga:XXXX, where XXXX is the Analytics profile ID.
258
+ * @param string $start_date Start date for fetching Analytics data. All requests should specify a start date formatted as YYYY-MM-DD.
259
+ * @param string $end_date End date for fetching Analytics data. All requests should specify an end date formatted as YYYY-MM-DD.
260
+ * @param string $metrics A comma-separated list of Analytics metrics. E.g., 'ga:visits,ga:pageviews'. At least one metric must be specified.
261
+ * @param array $optParams Optional parameters.
262
+ *
263
+ * @opt_param int max-results The maximum number of entries to include in this feed.
264
+ * @opt_param string sort A comma-separated list of dimensions or metrics that determine the sort order for Analytics data.
265
+ * @opt_param string dimensions A comma-separated list of Analytics dimensions. E.g., 'ga:browser,ga:city'.
266
+ * @opt_param int start-index An index of the first entity to retrieve. Use this parameter as a pagination mechanism along with the max-results parameter.
267
+ * @opt_param string segment An Analytics advanced segment to be applied to data.
268
+ * @opt_param string filters A comma-separated list of dimension or metric filters to be applied to Analytics data.
269
+ * @return Google_GaData
270
+ */
271
+ public function get($ids, $start_date, $end_date, $metrics, $optParams = array()) {
272
+ $params = array('ids' => $ids, 'start-date' => $start_date, 'end-date' => $end_date, 'metrics' => $metrics);
273
+ $params = array_merge($params, $optParams);
274
+ $data = $this->__call('get', array($params));
275
+ if ($this->useObjects()) {
276
+ return new Google_GaData($data);
277
+ } else {
278
+ return $data;
279
+ }
280
+ }
281
+ }
282
+
283
+ /**
284
+ * Service definition for Google_Analytics (v3).
285
+ *
286
+ * <p>
287
+ * View and manage your Google Analytics data
288
+ * </p>
289
+ *
290
+ * <p>
291
+ * For more information about this service, see the
292
+ * <a href="http://code.google.com/apis/analytics" target="_blank">API Documentation</a>
293
+ * </p>
294
+ *
295
+ * @author Google, Inc.
296
+ */
297
+ class Google_AnalyticsService extends Google_Service {
298
+ public $management_webproperties;
299
+ public $management_segments;
300
+ public $management_accounts;
301
+ public $management_goals;
302
+ public $management_profiles;
303
+ public $data_mcf;
304
+ public $data_ga;
305
+ /**
306
+ * Constructs the internal representation of the Analytics service.
307
+ *
308
+ * @param Google_Client $client
309
+ */
310
+ public function __construct(Google_Client $client) {
311
+ $this->servicePath = 'analytics/v3/';
312
+ $this->version = 'v3';
313
+ $this->serviceName = 'analytics';
314
+
315
+ $client->addService($this->serviceName, $this->version);
316
+ $this->management_webproperties = new Google_ManagementWebpropertiesServiceResource($this, $this->serviceName, 'webproperties', json_decode('{"methods": {"list": {"scopes": ["https://www.googleapis.com/auth/analytics.readonly"], "parameters": {"max-results": {"type": "integer", "location": "query", "format": "int32"}, "start-index": {"minimum": "1", "type": "integer", "location": "query", "format": "int32"}, "accountId": {"required": true, "type": "string", "location": "path"}}, "id": "analytics.management.webproperties.list", "httpMethod": "GET", "path": "management/accounts/{accountId}/webproperties", "response": {"$ref": "Webproperties"}}}}', true));
317
+ $this->management_segments = new Google_ManagementSegmentsServiceResource($this, $this->serviceName, 'segments', json_decode('{"methods": {"list": {"scopes": ["https://www.googleapis.com/auth/analytics.readonly"], "parameters": {"max-results": {"type": "integer", "location": "query", "format": "int32"}, "start-index": {"minimum": "1", "type": "integer", "location": "query", "format": "int32"}}, "response": {"$ref": "Segments"}, "httpMethod": "GET", "path": "management/segments", "id": "analytics.management.segments.list"}}}', true));
318
+ $this->management_accounts = new Google_ManagementAccountsServiceResource($this, $this->serviceName, 'accounts', json_decode('{"methods": {"list": {"scopes": ["https://www.googleapis.com/auth/analytics.readonly"], "parameters": {"max-results": {"type": "integer", "location": "query", "format": "int32"}, "start-index": {"minimum": "1", "type": "integer", "location": "query", "format": "int32"}}, "response": {"$ref": "Accounts"}, "httpMethod": "GET", "path": "management/accounts", "id": "analytics.management.accounts.list"}}}', true));
319
+ $this->management_goals = new Google_ManagementGoalsServiceResource($this, $this->serviceName, 'goals', json_decode('{"methods": {"list": {"scopes": ["https://www.googleapis.com/auth/analytics.readonly"], "parameters": {"max-results": {"type": "integer", "location": "query", "format": "int32"}, "profileId": {"required": true, "type": "string", "location": "path"}, "start-index": {"minimum": "1", "type": "integer", "location": "query", "format": "int32"}, "webPropertyId": {"required": true, "type": "string", "location": "path"}, "accountId": {"required": true, "type": "string", "location": "path"}}, "id": "analytics.management.goals.list", "httpMethod": "GET", "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/profiles/{profileId}/goals", "response": {"$ref": "Goals"}}}}', true));
320
+ $this->management_profiles = new Google_ManagementProfilesServiceResource($this, $this->serviceName, 'profiles', json_decode('{"methods": {"list": {"scopes": ["https://www.googleapis.com/auth/analytics.readonly"], "parameters": {"max-results": {"type": "integer", "location": "query", "format": "int32"}, "start-index": {"minimum": "1", "type": "integer", "location": "query", "format": "int32"}, "webPropertyId": {"required": true, "type": "string", "location": "path"}, "accountId": {"required": true, "type": "string", "location": "path"}}, "id": "analytics.management.profiles.list", "httpMethod": "GET", "path": "management/accounts/{accountId}/webproperties/{webPropertyId}/profiles", "response": {"$ref": "Profiles"}}}}', true));
321
+ $this->data_mcf = new Google_DataMcfServiceResource($this, $this->serviceName, 'mcf', json_decode('{"methods": {"get": {"scopes": ["https://www.googleapis.com/auth/analytics.readonly"], "parameters": {"max-results": {"type": "integer", "location": "query", "format": "int32"}, "sort": {"type": "string", "location": "query"}, "dimensions": {"type": "string", "location": "query"}, "start-date": {"required": true, "type": "string", "location": "query"}, "start-index": {"minimum": "1", "type": "integer", "location": "query", "format": "int32"}, "ids": {"required": true, "type": "string", "location": "query"}, "metrics": {"required": true, "type": "string", "location": "query"}, "filters": {"type": "string", "location": "query"}, "end-date": {"required": true, "type": "string", "location": "query"}}, "id": "analytics.data.mcf.get", "httpMethod": "GET", "path": "data/mcf", "response": {"$ref": "McfData"}}}}', true));
322
+ $this->data_ga = new Google_DataGaServiceResource($this, $this->serviceName, 'ga', json_decode('{"methods": {"get": {"scopes": ["https://www.googleapis.com/auth/analytics.readonly"], "parameters": {"max-results": {"type": "integer", "location": "query", "format": "int32"}, "sort": {"type": "string", "location": "query"}, "dimensions": {"type": "string", "location": "query"}, "start-date": {"required": true, "type": "string", "location": "query"}, "start-index": {"minimum": "1", "type": "integer", "location": "query", "format": "int32"}, "segment": {"type": "string", "location": "query"}, "ids": {"required": true, "type": "string", "location": "query"}, "metrics": {"required": true, "type": "string", "location": "query"}, "filters": {"type": "string", "location": "query"}, "end-date": {"required": true, "type": "string", "location": "query"}}, "id": "analytics.data.ga.get", "httpMethod": "GET", "path": "data/ga", "response": {"$ref": "GaData"}}}}', true));
323
+
324
+ }
325
+ }
326
+
327
+ class Google_Account extends Google_Model {
328
+ public $kind;
329
+ public $name;
330
+ public $created;
331
+ public $updated;
332
+ protected $__childLinkType = 'Google_AccountChildLink';
333
+ protected $__childLinkDataType = '';
334
+ public $childLink;
335
+ public $id;
336
+ public $selfLink;
337
+ public function setKind($kind) {
338
+ $this->kind = $kind;
339
+ }
340
+ public function getKind() {
341
+ return $this->kind;
342
+ }
343
+ public function setName($name) {
344
+ $this->name = $name;
345
+ }
346
+ public function getName() {
347
+ return $this->name;
348
+ }
349
+ public function setCreated($created) {
350
+ $this->created = $created;
351
+ }
352
+ public function getCreated() {
353
+ return $this->created;
354
+ }
355
+ public function setUpdated($updated) {
356
+ $this->updated = $updated;
357
+ }
358
+ public function getUpdated() {
359
+ return $this->updated;
360
+ }
361
+ public function setChildLink(Google_AccountChildLink $childLink) {
362
+ $this->childLink = $childLink;
363
+ }
364
+ public function getChildLink() {
365
+ return $this->childLink;
366
+ }
367
+ public function setId($id) {
368
+ $this->id = $id;
369
+ }
370
+ public function getId() {
371
+ return $this->id;
372
+ }
373
+ public function setSelfLink($selfLink) {
374
+ $this->selfLink = $selfLink;
375
+ }
376
+ public function getSelfLink() {
377
+ return $this->selfLink;
378
+ }
379
+ }
380
+
381
+ class Google_AccountChildLink extends Google_Model {
382
+ public $href;
383
+ public $type;
384
+ public function setHref($href) {
385
+ $this->href = $href;
386
+ }
387
+ public function getHref() {
388
+ return $this->href;
389
+ }
390
+ public function setType($type) {
391
+ $this->type = $type;
392
+ }
393
+ public function getType() {
394
+ return $this->type;
395
+ }
396
+ }
397
+
398
+ class Google_Accounts extends Google_Model {
399
+ public $username;
400
+ public $kind;
401
+ protected $__itemsType = 'Google_Account';
402
+ protected $__itemsDataType = 'array';
403
+ public $items;
404
+ public $itemsPerPage;
405
+ public $previousLink;
406
+ public $startIndex;
407
+ public $nextLink;
408
+ public $totalResults;
409
+ public function setUsername($username) {
410
+ $this->username = $username;
411
+ }
412
+ public function getUsername() {
413
+ return $this->username;
414
+ }
415
+ public function setKind($kind) {
416
+ $this->kind = $kind;
417
+ }
418
+ public function getKind() {
419
+ return $this->kind;
420
+ }
421
+ public function setItems(/* array(Google_Account) */ $items) {
422
+ $this->assertIsArray($items, 'Google_Account', __METHOD__);
423
+ $this->items = $items;
424
+ }
425
+ public function getItems() {
426
+ return $this->items;
427
+ }
428
+ public function setItemsPerPage($itemsPerPage) {
429
+ $this->itemsPerPage = $itemsPerPage;
430
+ }
431
+ public function getItemsPerPage() {
432
+ return $this->itemsPerPage;
433
+ }
434
+ public function setPreviousLink($previousLink) {
435
+ $this->previousLink = $previousLink;
436
+ }
437
+ public function getPreviousLink() {
438
+ return $this->previousLink;
439
+ }
440
+ public function setStartIndex($startIndex) {
441
+ $this->startIndex = $startIndex;
442
+ }
443
+ public function getStartIndex() {
444
+ return $this->startIndex;
445
+ }
446
+ public function setNextLink($nextLink) {
447
+ $this->nextLink = $nextLink;
448
+ }
449
+ public function getNextLink() {
450
+ return $this->nextLink;
451
+ }
452
+ public function setTotalResults($totalResults) {
453
+ $this->totalResults = $totalResults;
454
+ }
455
+ public function getTotalResults() {
456
+ return $this->totalResults;
457
+ }
458
+ }
459
+
460
+ class Google_GaData extends Google_Model {
461
+ public $kind;
462
+ public $rows;
463
+ public $containsSampledData;
464
+ public $totalResults;
465
+ public $itemsPerPage;
466
+ public $totalsForAllResults;
467
+ public $nextLink;
468
+ public $id;
469
+ protected $__queryType = 'Google_GaDataQuery';
470
+ protected $__queryDataType = '';
471
+ public $query;
472
+ public $previousLink;
473
+ protected $__profileInfoType = 'Google_GaDataProfileInfo';
474
+ protected $__profileInfoDataType = '';
475
+ public $profileInfo;
476
+ protected $__columnHeadersType = 'Google_GaDataColumnHeaders';
477
+ protected $__columnHeadersDataType = 'array';
478
+ public $columnHeaders;
479
+ public $selfLink;
480
+ public function setKind($kind) {
481
+ $this->kind = $kind;
482
+ }
483
+ public function getKind() {
484
+ return $this->kind;
485
+ }
486
+ public function setRows(/* array(Google_string) */ $rows) {
487
+ $this->assertIsArray($rows, 'Google_string', __METHOD__);
488
+ $this->rows = $rows;
489
+ }
490
+ public function getRows() {
491
+ return $this->rows;
492
+ }
493
+ public function setContainsSampledData($containsSampledData) {
494
+ $this->containsSampledData = $containsSampledData;
495
+ }
496
+ public function getContainsSampledData() {
497
+ return $this->containsSampledData;
498
+ }
499
+ public function setTotalResults($totalResults) {
500
+ $this->totalResults = $totalResults;
501
+ }
502
+ public function getTotalResults() {
503
+ return $this->totalResults;
504
+ }
505
+ public function setItemsPerPage($itemsPerPage) {
506
+ $this->itemsPerPage = $itemsPerPage;
507
+ }
508
+ public function getItemsPerPage() {
509
+ return $this->itemsPerPage;
510
+ }
511
+ public function setTotalsForAllResults($totalsForAllResults) {
512
+ $this->totalsForAllResults = $totalsForAllResults;
513
+ }
514
+ public function getTotalsForAllResults() {
515
+ return $this->totalsForAllResults;
516
+ }
517
+ public function setNextLink($nextLink) {
518
+ $this->nextLink = $nextLink;
519
+ }
520
+ public function getNextLink() {
521
+ return $this->nextLink;
522
+ }
523
+ public function setId($id) {
524
+ $this->id = $id;
525
+ }
526
+ public function getId() {
527
+ return $this->id;
528
+ }
529
+ public function setQuery(Google_GaDataQuery $query) {
530
+ $this->query = $query;
531
+ }
532
+ public function getQuery() {
533
+ return $this->query;
534
+ }
535
+ public function setPreviousLink($previousLink) {
536
+ $this->previousLink = $previousLink;
537
+ }
538
+ public function getPreviousLink() {
539
+ return $this->previousLink;
540
+ }
541
+ public function setProfileInfo(Google_GaDataProfileInfo $profileInfo) {
542
+ $this->profileInfo = $profileInfo;
543
+ }
544
+ public function getProfileInfo() {
545
+ return $this->profileInfo;
546
+ }
547
+ public function setColumnHeaders(/* array(Google_GaDataColumnHeaders) */ $columnHeaders) {
548
+ $this->assertIsArray($columnHeaders, 'Google_GaDataColumnHeaders', __METHOD__);
549
+ $this->columnHeaders = $columnHeaders;
550
+ }
551
+ public function getColumnHeaders() {
552
+ return $this->columnHeaders;
553
+ }
554
+ public function setSelfLink($selfLink) {
555
+ $this->selfLink = $selfLink;
556
+ }
557
+ public function getSelfLink() {
558
+ return $this->selfLink;
559
+ }
560
+ }
561
+
562
+ class Google_GaDataColumnHeaders extends Google_Model {
563
+ public $dataType;
564
+ public $columnType;
565
+ public $name;
566
+ public function setDataType($dataType) {
567
+ $this->dataType = $dataType;
568
+ }
569
+ public function getDataType() {
570
+ return $this->dataType;
571
+ }
572
+ public function setColumnType($columnType) {
573
+ $this->columnType = $columnType;
574
+ }
575
+ public function getColumnType() {
576
+ return $this->columnType;
577
+ }
578
+ public function setName($name) {
579
+ $this->name = $name;
580
+ }
581
+ public function getName() {
582
+ return $this->name;
583
+ }
584
+ }
585
+
586
+ class Google_GaDataProfileInfo extends Google_Model {
587
+ public $webPropertyId;
588
+ public $internalWebPropertyId;
589
+ public $tableId;
590
+ public $profileId;
591
+ public $profileName;
592
+ public $accountId;
593
+ public function setWebPropertyId($webPropertyId) {
594
+ $this->webPropertyId = $webPropertyId;
595
+ }
596
+ public function getWebPropertyId() {
597
+ return $this->webPropertyId;
598
+ }
599
+ public function setInternalWebPropertyId($internalWebPropertyId) {
600
+ $this->internalWebPropertyId = $internalWebPropertyId;
601
+ }
602
+ public function getInternalWebPropertyId() {
603
+ return $this->internalWebPropertyId;
604
+ }
605
+ public function setTableId($tableId) {
606
+ $this->tableId = $tableId;
607
+ }
608
+ public function getTableId() {
609
+ return $this->tableId;
610
+ }
611
+ public function setProfileId($profileId) {
612
+ $this->profileId = $profileId;
613
+ }
614
+ public function getProfileId() {
615
+ return $this->profileId;
616
+ }
617
+ public function setProfileName($profileName) {
618
+ $this->profileName = $profileName;
619
+ }
620
+ public function getProfileName() {
621
+ return $this->profileName;
622
+ }
623
+ public function setAccountId($accountId) {
624
+ $this->accountId = $accountId;
625
+ }
626
+ public function getAccountId() {
627
+ return $this->accountId;
628
+ }
629
+ }
630
+
631
+ class Google_GaDataQuery extends Google_Model {
632
+ public $max_results;
633
+ public $sort;
634
+ public $dimensions;
635
+ public $start_date;
636
+ public $start_index;
637
+ public $segment;
638
+ public $ids;
639
+ public $metrics;
640
+ public $filters;
641
+ public $end_date;
642
+ public function setMax_results($max_results) {
643
+ $this->max_results = $max_results;
644
+ }
645
+ public function getMax_results() {
646
+ return $this->max_results;
647
+ }
648
+ public function setSort(/* array(Google_string) */ $sort) {
649
+ $this->assertIsArray($sort, 'Google_string', __METHOD__);
650
+ $this->sort = $sort;
651
+ }
652
+ public function getSort() {
653
+ return $this->sort;
654
+ }
655
+ public function setDimensions($dimensions) {
656
+ $this->dimensions = $dimensions;
657
+ }
658
+ public function getDimensions() {
659
+ return $this->dimensions;
660
+ }
661
+ public function setStart_date($start_date) {
662
+ $this->start_date = $start_date;
663
+ }
664
+ public function getStart_date() {
665
+ return $this->start_date;
666
+ }
667
+ public function setStart_index($start_index) {
668
+ $this->start_index = $start_index;
669
+ }
670
+ public function getStart_index() {
671
+ return $this->start_index;
672
+ }
673
+ public function setSegment($segment) {
674
+ $this->segment = $segment;
675
+ }
676
+ public function getSegment() {
677
+ return $this->segment;
678
+ }
679
+ public function setIds($ids) {
680
+ $this->ids = $ids;
681
+ }
682
+ public function getIds() {
683
+ return $this->ids;
684
+ }
685
+ public function setMetrics(/* array(Google_string) */ $metrics) {
686
+ $this->assertIsArray($metrics, 'Google_string', __METHOD__);
687
+ $this->metrics = $metrics;
688
+ }
689
+ public function getMetrics() {
690
+ return $this->metrics;
691
+ }
692
+ public function setFilters($filters) {
693
+ $this->filters = $filters;
694
+ }
695
+ public function getFilters() {
696
+ return $this->filters;
697
+ }
698
+ public function setEnd_date($end_date) {
699
+ $this->end_date = $end_date;
700
+ }
701
+ public function getEnd_date() {
702
+ return $this->end_date;
703
+ }
704
+ }
705
+
706
+ class Google_Goal extends Google_Model {
707
+ public $kind;
708
+ protected $__visitTimeOnSiteDetailsType = 'Google_GoalVisitTimeOnSiteDetails';
709
+ protected $__visitTimeOnSiteDetailsDataType = '';
710
+ public $visitTimeOnSiteDetails;
711
+ public $name;
712
+ public $created;
713
+ protected $__urlDestinationDetailsType = 'Google_GoalUrlDestinationDetails';
714
+ protected $__urlDestinationDetailsDataType = '';
715
+ public $urlDestinationDetails;
716
+ public $updated;
717
+ public $value;
718
+ protected $__visitNumPagesDetailsType = 'Google_GoalVisitNumPagesDetails';
719
+ protected $__visitNumPagesDetailsDataType = '';
720
+ public $visitNumPagesDetails;
721
+ public $internalWebPropertyId;
722
+ protected $__eventDetailsType = 'Google_GoalEventDetails';
723
+ protected $__eventDetailsDataType = '';
724
+ public $eventDetails;
725
+ public $webPropertyId;
726
+ public $active;
727
+ public $profileId;
728
+ protected $__parentLinkType = 'Google_GoalParentLink';
729
+ protected $__parentLinkDataType = '';
730
+ public $parentLink;
731
+ public $type;
732
+ public $id;
733
+ public $selfLink;
734
+ public $accountId;
735
+ public function setKind($kind) {
736
+ $this->kind = $kind;
737
+ }
738
+ public function getKind() {
739
+ return $this->kind;
740
+ }
741
+ public function setVisitTimeOnSiteDetails(Google_GoalVisitTimeOnSiteDetails $visitTimeOnSiteDetails) {
742
+ $this->visitTimeOnSiteDetails = $visitTimeOnSiteDetails;
743
+ }
744
+ public function getVisitTimeOnSiteDetails() {
745
+ return $this->visitTimeOnSiteDetails;
746
+ }
747
+ public function setName($name) {
748
+ $this->name = $name;
749
+ }
750
+ public function getName() {
751
+ return $this->name;
752
+ }
753
+ public function setCreated($created) {
754
+ $this->created = $created;
755
+ }
756
+ public function getCreated() {
757
+ return $this->created;
758
+ }
759
+ public function setUrlDestinationDetails(Google_GoalUrlDestinationDetails $urlDestinationDetails) {
760
+ $this->urlDestinationDetails = $urlDestinationDetails;
761
+ }
762
+ public function getUrlDestinationDetails() {
763
+ return $this->urlDestinationDetails;
764
+ }
765
+ public function setUpdated($updated) {
766
+ $this->updated = $updated;
767
+ }
768
+ public function getUpdated() {
769
+ return $this->updated;
770
+ }
771
+ public function setValue($value) {
772
+ $this->value = $value;
773
+ }
774
+ public function getValue() {
775
+ return $this->value;
776
+ }
777
+ public function setVisitNumPagesDetails(Google_GoalVisitNumPagesDetails $visitNumPagesDetails) {
778
+ $this->visitNumPagesDetails = $visitNumPagesDetails;
779
+ }
780
+ public function getVisitNumPagesDetails() {
781
+ return $this->visitNumPagesDetails;
782
+ }
783
+ public function setInternalWebPropertyId($internalWebPropertyId) {
784
+ $this->internalWebPropertyId = $internalWebPropertyId;
785
+ }
786
+ public function getInternalWebPropertyId() {
787
+ return $this->internalWebPropertyId;
788
+ }
789
+ public function setEventDetails(Google_GoalEventDetails $eventDetails) {
790
+ $this->eventDetails = $eventDetails;
791
+ }
792
+ public function getEventDetails() {
793
+ return $this->eventDetails;
794
+ }
795
+ public function setWebPropertyId($webPropertyId) {
796
+ $this->webPropertyId = $webPropertyId;
797
+ }
798
+ public function getWebPropertyId() {
799
+ return $this->webPropertyId;
800
+ }
801
+ public function setActive($active) {
802
+ $this->active = $active;
803
+ }
804
+ public function getActive() {
805
+ return $this->active;
806
+ }
807
+ public function setProfileId($profileId) {
808
+ $this->profileId = $profileId;
809
+ }
810
+ public function getProfileId() {
811
+ return $this->profileId;
812
+ }
813
+ public function setParentLink(Google_GoalParentLink $parentLink) {
814
+ $this->parentLink = $parentLink;
815
+ }
816
+ public function getParentLink() {
817
+ return $this->parentLink;
818
+ }
819
+ public function setType($type) {
820
+ $this->type = $type;
821
+ }
822
+ public function getType() {
823
+ return $this->type;
824
+ }
825
+ public function setId($id) {
826
+ $this->id = $id;
827
+ }
828
+ public function getId() {
829
+ return $this->id;
830
+ }
831
+ public function setSelfLink($selfLink) {
832
+ $this->selfLink = $selfLink;
833
+ }
834
+ public function getSelfLink() {
835
+ return $this->selfLink;
836
+ }
837
+ public function setAccountId($accountId) {
838
+ $this->accountId = $accountId;
839
+ }
840
+ public function getAccountId() {
841
+ return $this->accountId;
842
+ }
843
+ }
844
+
845
+ class Google_GoalEventDetails extends Google_Model {
846
+ protected $__eventConditionsType = 'Google_GoalEventDetailsEventConditions';
847
+ protected $__eventConditionsDataType = 'array';
848
+ public $eventConditions;
849
+ public $useEventValue;
850
+ public function setEventConditions(/* array(Google_GoalEventDetailsEventConditions) */ $eventConditions) {
851
+ $this->assertIsArray($eventConditions, 'Google_GoalEventDetailsEventConditions', __METHOD__);
852
+ $this->eventConditions = $eventConditions;
853
+ }
854
+ public function getEventConditions() {
855
+ return $this->eventConditions;
856
+ }
857
+ public function setUseEventValue($useEventValue) {
858
+ $this->useEventValue = $useEventValue;
859
+ }
860
+ public function getUseEventValue() {
861
+ return $this->useEventValue;
862
+ }
863
+ }
864
+
865
+ class Google_GoalEventDetailsEventConditions extends Google_Model {
866
+ public $type;
867
+ public $matchType;
868
+ public $expression;
869
+ public $comparisonType;
870
+ public $comparisonValue;
871
+ public function setType($type) {
872
+ $this->type = $type;
873
+ }
874
+ public function getType() {
875
+ return $this->type;
876
+ }
877
+ public function setMatchType($matchType) {
878
+ $this->matchType = $matchType;
879
+ }
880
+ public function getMatchType() {
881
+ return $this->matchType;
882
+ }
883
+ public function setExpression($expression) {
884
+ $this->expression = $expression;
885
+ }
886
+ public function getExpression() {
887
+ return $this->expression;
888
+ }
889
+ public function setComparisonType($comparisonType) {
890
+ $this->comparisonType = $comparisonType;
891
+ }
892
+ public function getComparisonType() {
893
+ return $this->comparisonType;
894
+ }
895
+ public function setComparisonValue($comparisonValue) {
896
+ $this->comparisonValue = $comparisonValue;
897
+ }
898
+ public function getComparisonValue() {
899
+ return $this->comparisonValue;
900
+ }
901
+ }
902
+
903
+ class Google_GoalParentLink extends Google_Model {
904
+ public $href;
905
+ public $type;
906
+ public function setHref($href) {
907
+ $this->href = $href;
908
+ }
909
+ public function getHref() {
910
+ return $this->href;
911
+ }
912
+ public function setType($type) {
913
+ $this->type = $type;
914
+ }
915
+ public function getType() {
916
+ return $this->type;
917
+ }
918
+ }
919
+
920
+ class Google_GoalUrlDestinationDetails extends Google_Model {
921
+ public $url;
922
+ public $caseSensitive;
923
+ public $matchType;
924
+ protected $__stepsType = 'Google_GoalUrlDestinationDetailsSteps';
925
+ protected $__stepsDataType = 'array';
926
+ public $steps;
927
+ public $firstStepRequired;
928
+ public function setUrl($url) {
929
+ $this->url = $url;
930
+ }
931
+ public function getUrl() {
932
+ return $this->url;
933
+ }
934
+ public function setCaseSensitive($caseSensitive) {
935
+ $this->caseSensitive = $caseSensitive;
936
+ }
937
+ public function getCaseSensitive() {
938
+ return $this->caseSensitive;
939
+ }
940
+ public function setMatchType($matchType) {
941
+ $this->matchType = $matchType;
942
+ }
943
+ public function getMatchType() {
944
+ return $this->matchType;
945
+ }
946
+ public function setSteps(/* array(Google_GoalUrlDestinationDetailsSteps) */ $steps) {
947
+ $this->assertIsArray($steps, 'Google_GoalUrlDestinationDetailsSteps', __METHOD__);
948
+ $this->steps = $steps;
949
+ }
950
+ public function getSteps() {
951
+ return $this->steps;
952
+ }
953
+ public function setFirstStepRequired($firstStepRequired) {
954
+ $this->firstStepRequired = $firstStepRequired;
955
+ }
956
+ public function getFirstStepRequired() {
957
+ return $this->firstStepRequired;
958
+ }
959
+ }
960
+
961
+ class Google_GoalUrlDestinationDetailsSteps extends Google_Model {
962
+ public $url;
963
+ public $name;
964
+ public $number;
965
+ public function setUrl($url) {
966
+ $this->url = $url;
967
+ }
968
+ public function getUrl() {
969
+ return $this->url;
970
+ }
971
+ public function setName($name) {
972
+ $this->name = $name;
973
+ }
974
+ public function getName() {
975
+ return $this->name;
976
+ }
977
+ public function setNumber($number) {
978
+ $this->number = $number;
979
+ }
980
+ public function getNumber() {
981
+ return $this->number;
982
+ }
983
+ }
984
+
985
+ class Google_GoalVisitNumPagesDetails extends Google_Model {
986
+ public $comparisonType;
987
+ public $comparisonValue;
988
+ public function setComparisonType($comparisonType) {
989
+ $this->comparisonType = $comparisonType;
990
+ }
991
+ public function getComparisonType() {
992
+ return $this->comparisonType;
993
+ }
994
+ public function setComparisonValue($comparisonValue) {
995
+ $this->comparisonValue = $comparisonValue;
996
+ }
997
+ public function getComparisonValue() {
998
+ return $this->comparisonValue;
999
+ }
1000
+ }
1001
+
1002
+ class Google_GoalVisitTimeOnSiteDetails extends Google_Model {
1003
+ public $comparisonType;
1004
+ public $comparisonValue;
1005
+ public function setComparisonType($comparisonType) {
1006
+ $this->comparisonType = $comparisonType;
1007
+ }
1008
+ public function getComparisonType() {
1009
+ return $this->comparisonType;
1010
+ }
1011
+ public function setComparisonValue($comparisonValue) {
1012
+ $this->comparisonValue = $comparisonValue;
1013
+ }
1014
+ public function getComparisonValue() {
1015
+ return $this->comparisonValue;
1016
+ }
1017
+ }
1018
+
1019
+ class Google_Goals extends Google_Model {
1020
+ public $username;
1021
+ public $kind;
1022
+ protected $__itemsType = 'Google_Goal';
1023
+ protected $__itemsDataType = 'array';
1024
+ public $items;
1025
+ public $itemsPerPage;
1026
+ public $previousLink;
1027
+ public $startIndex;
1028
+ public $nextLink;
1029
+ public $totalResults;
1030
+ public function setUsername($username) {
1031
+ $this->username = $username;
1032
+ }
1033
+ public function getUsername() {
1034
+ return $this->username;
1035
+ }
1036
+ public function setKind($kind) {
1037
+ $this->kind = $kind;
1038
+ }
1039
+ public function getKind() {
1040
+ return $this->kind;
1041
+ }
1042
+ public function setItems(/* array(Google_Goal) */ $items) {
1043
+ $this->assertIsArray($items, 'Google_Goal', __METHOD__);
1044
+ $this->items = $items;
1045
+ }
1046
+ public function getItems() {
1047
+ return $this->items;
1048
+ }
1049
+ public function setItemsPerPage($itemsPerPage) {
1050
+ $this->itemsPerPage = $itemsPerPage;
1051
+ }
1052
+ public function getItemsPerPage() {
1053
+ return $this->itemsPerPage;
1054
+ }
1055
+ public function setPreviousLink($previousLink) {
1056
+ $this->previousLink = $previousLink;
1057
+ }
1058
+ public function getPreviousLink() {
1059
+ return $this->previousLink;
1060
+ }
1061
+ public function setStartIndex($startIndex) {
1062
+ $this->startIndex = $startIndex;
1063
+ }
1064
+ public function getStartIndex() {
1065
+ return $this->startIndex;
1066
+ }
1067
+ public function setNextLink($nextLink) {
1068
+ $this->nextLink = $nextLink;
1069
+ }
1070
+ public function getNextLink() {
1071
+ return $this->nextLink;
1072
+ }
1073
+ public function setTotalResults($totalResults) {
1074
+ $this->totalResults = $totalResults;
1075
+ }
1076
+ public function getTotalResults() {
1077
+ return $this->totalResults;
1078
+ }
1079
+ }
1080
+
1081
+ class Google_McfData extends Google_Model {
1082
+ public $kind;
1083
+ protected $__rowsType = 'Google_McfDataRows';
1084
+ protected $__rowsDataType = 'array';
1085
+ public $rows;
1086
+ public $containsSampledData;
1087
+ public $totalResults;
1088
+ public $itemsPerPage;
1089
+ public $totalsForAllResults;
1090
+ public $nextLink;
1091
+ public $id;
1092
+ protected $__queryType = 'Google_McfDataQuery';
1093
+ protected $__queryDataType = '';
1094
+ public $query;
1095
+ public $previousLink;
1096
+ protected $__profileInfoType = 'Google_McfDataProfileInfo';
1097
+ protected $__profileInfoDataType = '';
1098
+ public $profileInfo;
1099
+ protected $__columnHeadersType = 'Google_McfDataColumnHeaders';
1100
+ protected $__columnHeadersDataType = 'array';
1101
+ public $columnHeaders;
1102
+ public $selfLink;
1103
+ public function setKind($kind) {
1104
+ $this->kind = $kind;
1105
+ }
1106
+ public function getKind() {
1107
+ return $this->kind;
1108
+ }
1109
+ public function setRows(/* array(Google_McfDataRows) */ $rows) {
1110
+ $this->assertIsArray($rows, 'Google_McfDataRows', __METHOD__);
1111
+ $this->rows = $rows;
1112
+ }
1113
+ public function getRows() {
1114
+ return $this->rows;
1115
+ }
1116
+ public function setContainsSampledData($containsSampledData) {
1117
+ $this->containsSampledData = $containsSampledData;
1118
+ }
1119
+ public function getContainsSampledData() {
1120
+ return $this->containsSampledData;
1121
+ }
1122
+ public function setTotalResults($totalResults) {
1123
+ $this->totalResults = $totalResults;
1124
+ }
1125
+ public function getTotalResults() {
1126
+ return $this->totalResults;
1127
+ }
1128
+ public function setItemsPerPage($itemsPerPage) {
1129
+ $this->itemsPerPage = $itemsPerPage;
1130
+ }
1131
+ public function getItemsPerPage() {
1132
+ return $this->itemsPerPage;
1133
+ }
1134
+ public function setTotalsForAllResults($totalsForAllResults) {
1135
+ $this->totalsForAllResults = $totalsForAllResults;
1136
+ }
1137
+ public function getTotalsForAllResults() {
1138
+ return $this->totalsForAllResults;
1139
+ }
1140
+ public function setNextLink($nextLink) {
1141
+ $this->nextLink = $nextLink;
1142
+ }
1143
+ public function getNextLink() {
1144
+ return $this->nextLink;
1145
+ }
1146
+ public function setId($id) {
1147
+ $this->id = $id;
1148
+ }
1149
+ public function getId() {
1150
+ return $this->id;
1151
+ }
1152
+ public function setQuery(Google_McfDataQuery $query) {
1153
+ $this->query = $query;
1154
+ }
1155
+ public function getQuery() {
1156
+ return $this->query;
1157
+ }
1158
+ public function setPreviousLink($previousLink) {
1159
+ $this->previousLink = $previousLink;
1160
+ }
1161
+ public function getPreviousLink() {
1162
+ return $this->previousLink;
1163
+ }
1164
+ public function setProfileInfo(Google_McfDataProfileInfo $profileInfo) {
1165
+ $this->profileInfo = $profileInfo;
1166
+ }
1167
+ public function getProfileInfo() {
1168
+ return $this->profileInfo;
1169
+ }
1170
+ public function setColumnHeaders(/* array(Google_McfDataColumnHeaders) */ $columnHeaders) {
1171
+ $this->assertIsArray($columnHeaders, 'Google_McfDataColumnHeaders', __METHOD__);
1172
+ $this->columnHeaders = $columnHeaders;
1173
+ }
1174
+ public function getColumnHeaders() {
1175
+ return $this->columnHeaders;
1176
+ }
1177
+ public function setSelfLink($selfLink) {
1178
+ $this->selfLink = $selfLink;
1179
+ }
1180
+ public function getSelfLink() {
1181
+ return $this->selfLink;
1182
+ }
1183
+ }
1184
+
1185
+ class Google_McfDataColumnHeaders extends Google_Model {
1186
+ public $dataType;
1187
+ public $columnType;
1188
+ public $name;
1189
+ public function setDataType($dataType) {
1190
+ $this->dataType = $dataType;
1191
+ }
1192
+ public function getDataType() {
1193
+ return $this->dataType;
1194
+ }
1195
+ public function setColumnType($columnType) {
1196
+ $this->columnType = $columnType;
1197
+ }
1198
+ public function getColumnType() {
1199
+ return $this->columnType;
1200
+ }
1201
+ public function setName($name) {
1202
+ $this->name = $name;
1203
+ }
1204
+ public function getName() {
1205
+ return $this->name;
1206
+ }
1207
+ }
1208
+
1209
+ class Google_McfDataProfileInfo extends Google_Model {
1210
+ public $webPropertyId;
1211
+ public $internalWebPropertyId;
1212
+ public $tableId;
1213
+ public $profileId;
1214
+ public $profileName;
1215
+ public $accountId;
1216
+ public function setWebPropertyId($webPropertyId) {
1217
+ $this->webPropertyId = $webPropertyId;
1218
+ }
1219
+ public function getWebPropertyId() {
1220
+ return $this->webPropertyId;
1221
+ }
1222
+ public function setInternalWebPropertyId($internalWebPropertyId) {
1223
+ $this->internalWebPropertyId = $internalWebPropertyId;
1224
+ }
1225
+ public function getInternalWebPropertyId() {
1226
+ return $this->internalWebPropertyId;
1227
+ }
1228
+ public function setTableId($tableId) {
1229
+ $this->tableId = $tableId;
1230
+ }
1231
+ public function getTableId() {
1232
+ return $this->tableId;
1233
+ }
1234
+ public function setProfileId($profileId) {
1235
+ $this->profileId = $profileId;
1236
+ }
1237
+ public function getProfileId() {
1238
+ return $this->profileId;
1239
+ }
1240
+ public function setProfileName($profileName) {
1241
+ $this->profileName = $profileName;
1242
+ }
1243
+ public function getProfileName() {
1244
+ return $this->profileName;
1245
+ }
1246
+ public function setAccountId($accountId) {
1247
+ $this->accountId = $accountId;
1248
+ }
1249
+ public function getAccountId() {
1250
+ return $this->accountId;
1251
+ }
1252
+ }
1253
+
1254
+ class Google_McfDataQuery extends Google_Model {
1255
+ public $max_results;
1256
+ public $sort;
1257
+ public $dimensions;
1258
+ public $start_date;
1259
+ public $start_index;
1260
+ public $segment;
1261
+ public $ids;
1262
+ public $metrics;
1263
+ public $filters;
1264
+ public $end_date;
1265
+ public function setMax_results($max_results) {
1266
+ $this->max_results = $max_results;
1267
+ }
1268
+ public function getMax_results() {
1269
+ return $this->max_results;
1270
+ }
1271
+ public function setSort(/* array(Google_string) */ $sort) {
1272
+ $this->assertIsArray($sort, 'Google_string', __METHOD__);
1273
+ $this->sort = $sort;
1274
+ }
1275
+ public function getSort() {
1276
+ return $this->sort;
1277
+ }
1278
+ public function setDimensions($dimensions) {
1279
+ $this->dimensions = $dimensions;
1280
+ }
1281
+ public function getDimensions() {
1282
+ return $this->dimensions;
1283
+ }
1284
+ public function setStart_date($start_date) {
1285
+ $this->start_date = $start_date;
1286
+ }
1287
+ public function getStart_date() {
1288
+ return $this->start_date;
1289
+ }
1290
+ public function setStart_index($start_index) {
1291
+ $this->start_index = $start_index;
1292
+ }
1293
+ public function getStart_index() {
1294
+ return $this->start_index;
1295
+ }
1296
+ public function setSegment($segment) {
1297
+ $this->segment = $segment;
1298
+ }
1299
+ public function getSegment() {
1300
+ return $this->segment;
1301
+ }
1302
+ public function setIds($ids) {
1303
+ $this->ids = $ids;
1304
+ }
1305
+ public function getIds() {
1306
+ return $this->ids;
1307
+ }
1308
+ public function setMetrics(/* array(Google_string) */ $metrics) {
1309
+ $this->assertIsArray($metrics, 'Google_string', __METHOD__);
1310
+ $this->metrics = $metrics;
1311
+ }
1312
+ public function getMetrics() {
1313
+ return $this->metrics;
1314
+ }
1315
+ public function setFilters($filters) {
1316
+ $this->filters = $filters;
1317
+ }
1318
+ public function getFilters() {
1319
+ return $this->filters;
1320
+ }
1321
+ public function setEnd_date($end_date) {
1322
+ $this->end_date = $end_date;
1323
+ }
1324
+ public function getEnd_date() {
1325
+ return $this->end_date;
1326
+ }
1327
+ }
1328
+
1329
+ class Google_McfDataRows extends Google_Model {
1330
+ public $primitiveValue;
1331
+ protected $__conversionPathValueType = 'Google_McfDataRowsConversionPathValue';
1332
+ protected $__conversionPathValueDataType = 'array';
1333
+ public $conversionPathValue;
1334
+ public function setPrimitiveValue($primitiveValue) {
1335
+ $this->primitiveValue = $primitiveValue;
1336
+ }
1337
+ public function getPrimitiveValue() {
1338
+ return $this->primitiveValue;
1339
+ }
1340
+ public function setConversionPathValue(/* array(Google_McfDataRowsConversionPathValue) */ $conversionPathValue) {
1341
+ $this->assertIsArray($conversionPathValue, 'Google_McfDataRowsConversionPathValue', __METHOD__);
1342
+ $this->conversionPathValue = $conversionPathValue;
1343
+ }
1344
+ public function getConversionPathValue() {
1345
+ return $this->conversionPathValue;
1346
+ }
1347
+ }
1348
+
1349
+ class Google_McfDataRowsConversionPathValue extends Google_Model {
1350
+ public $nodeValue;
1351
+ public $interactionType;
1352
+ public function setNodeValue($nodeValue) {
1353
+ $this->nodeValue = $nodeValue;
1354
+ }
1355
+ public function getNodeValue() {
1356
+ return $this->nodeValue;
1357
+ }
1358
+ public function setInteractionType($interactionType) {
1359
+ $this->interactionType = $interactionType;
1360
+ }
1361
+ public function getInteractionType() {
1362
+ return $this->interactionType;
1363
+ }
1364
+ }
1365
+
1366
+ class Google_Profile extends Google_Model {
1367
+ public $defaultPage;
1368
+ public $kind;
1369
+ public $excludeQueryParameters;
1370
+ public $name;
1371
+ public $created;
1372
+ public $webPropertyId;
1373
+ public $updated;
1374
+ public $siteSearchQueryParameters;
1375
+ public $currency;
1376
+ public $internalWebPropertyId;
1377
+ protected $__childLinkType = 'Google_ProfileChildLink';
1378
+ protected $__childLinkDataType = '';
1379
+ public $childLink;
1380
+ public $timezone;
1381
+ public $siteSearchCategoryParameters;
1382
+ protected $__parentLinkType = 'Google_ProfileParentLink';
1383
+ protected $__parentLinkDataType = '';
1384
+ public $parentLink;
1385
+ public $id;
1386
+ public $selfLink;
1387
+ public $accountId;
1388
+ public function setDefaultPage($defaultPage) {
1389
+ $this->defaultPage = $defaultPage;
1390
+ }
1391
+ public function getDefaultPage() {
1392
+ return $this->defaultPage;
1393
+ }
1394
+ public function setKind($kind) {
1395
+ $this->kind = $kind;
1396
+ }
1397
+ public function getKind() {
1398
+ return $this->kind;
1399
+ }
1400
+ public function setExcludeQueryParameters($excludeQueryParameters) {
1401
+ $this->excludeQueryParameters = $excludeQueryParameters;
1402
+ }
1403
+ public function getExcludeQueryParameters() {
1404
+ return $this->excludeQueryParameters;
1405
+ }
1406
+ public function setName($name) {
1407
+ $this->name = $name;
1408
+ }
1409
+ public function getName() {
1410
+ return $this->name;
1411
+ }
1412
+ public function setCreated($created) {
1413
+ $this->created = $created;
1414
+ }
1415
+ public function getCreated() {
1416
+ return $this->created;
1417
+ }
1418
+ public function setWebPropertyId($webPropertyId) {
1419
+ $this->webPropertyId = $webPropertyId;
1420
+ }
1421
+ public function getWebPropertyId() {
1422
+ return $this->webPropertyId;
1423
+ }
1424
+ public function setUpdated($updated) {
1425
+ $this->updated = $updated;
1426
+ }
1427
+ public function getUpdated() {
1428
+ return $this->updated;
1429
+ }
1430
+ public function setSiteSearchQueryParameters($siteSearchQueryParameters) {
1431
+ $this->siteSearchQueryParameters = $siteSearchQueryParameters;
1432
+ }
1433
+ public function getSiteSearchQueryParameters() {
1434
+ return $this->siteSearchQueryParameters;
1435
+ }
1436
+ public function setCurrency($currency) {
1437
+ $this->currency = $currency;
1438
+ }
1439
+ public function getCurrency() {
1440
+ return $this->currency;
1441
+ }
1442
+ public function setInternalWebPropertyId($internalWebPropertyId) {
1443
+ $this->internalWebPropertyId = $internalWebPropertyId;
1444
+ }
1445
+ public function getInternalWebPropertyId() {
1446
+ return $this->internalWebPropertyId;
1447
+ }
1448
+ public function setChildLink(Google_ProfileChildLink $childLink) {
1449
+ $this->childLink = $childLink;
1450
+ }
1451
+ public function getChildLink() {
1452
+ return $this->childLink;
1453
+ }
1454
+ public function setTimezone($timezone) {
1455
+ $this->timezone = $timezone;
1456
+ }
1457
+ public function getTimezone() {
1458
+ return $this->timezone;
1459
+ }
1460
+ public function setSiteSearchCategoryParameters($siteSearchCategoryParameters) {
1461
+ $this->siteSearchCategoryParameters = $siteSearchCategoryParameters;
1462
+ }
1463
+ public function getSiteSearchCategoryParameters() {
1464
+ return $this->siteSearchCategoryParameters;
1465
+ }
1466
+ public function setParentLink(Google_ProfileParentLink $parentLink) {
1467
+ $this->parentLink = $parentLink;
1468
+ }
1469
+ public function getParentLink() {
1470
+ return $this->parentLink;
1471
+ }
1472
+ public function setId($id) {
1473
+ $this->id = $id;
1474
+ }
1475
+ public function getId() {
1476
+ return $this->id;
1477
+ }
1478
+ public function setSelfLink($selfLink) {
1479
+ $this->selfLink = $selfLink;
1480
+ }
1481
+ public function getSelfLink() {
1482
+ return $this->selfLink;
1483
+ }
1484
+ public function setAccountId($accountId) {
1485
+ $this->accountId = $accountId;
1486
+ }
1487
+ public function getAccountId() {
1488
+ return $this->accountId;
1489
+ }
1490
+ }
1491
+
1492
+ class Google_ProfileChildLink extends Google_Model {
1493
+ public $href;
1494
+ public $type;
1495
+ public function setHref($href) {
1496
+ $this->href = $href;
1497
+ }
1498
+ public function getHref() {
1499
+ return $this->href;
1500
+ }
1501
+ public function setType($type) {
1502
+ $this->type = $type;
1503
+ }
1504
+ public function getType() {
1505
+ return $this->type;
1506
+ }
1507
+ }
1508
+
1509
+ class Google_ProfileParentLink extends Google_Model {
1510
+ public $href;
1511
+ public $type;
1512
+ public function setHref($href) {
1513
+ $this->href = $href;
1514
+ }
1515
+ public function getHref() {
1516
+ return $this->href;
1517
+ }
1518
+ public function setType($type) {
1519
+ $this->type = $type;
1520
+ }
1521
+ public function getType() {
1522
+ return $this->type;
1523
+ }
1524
+ }
1525
+
1526
+ class Google_Profiles extends Google_Model {
1527
+ public $username;
1528
+ public $kind;
1529
+ protected $__itemsType = 'Google_Profile';
1530
+ protected $__itemsDataType = 'array';
1531
+ public $items;
1532
+ public $itemsPerPage;
1533
+ public $previousLink;
1534
+ public $startIndex;
1535
+ public $nextLink;
1536
+ public $totalResults;
1537
+ public function setUsername($username) {
1538
+ $this->username = $username;
1539
+ }
1540
+ public function getUsername() {
1541
+ return $this->username;
1542
+ }
1543
+ public function setKind($kind) {
1544
+ $this->kind = $kind;
1545
+ }
1546
+ public function getKind() {
1547
+ return $this->kind;
1548
+ }
1549
+ public function setItems(/* array(Google_Profile) */ $items) {
1550
+ $this->assertIsArray($items, 'Google_Profile', __METHOD__);
1551
+ $this->items = $items;
1552
+ }
1553
+ public function getItems() {
1554
+ return $this->items;
1555
+ }
1556
+ public function setItemsPerPage($itemsPerPage) {
1557
+ $this->itemsPerPage = $itemsPerPage;
1558
+ }
1559
+ public function getItemsPerPage() {
1560
+ return $this->itemsPerPage;
1561
+ }
1562
+ public function setPreviousLink($previousLink) {
1563
+ $this->previousLink = $previousLink;
1564
+ }
1565
+ public function getPreviousLink() {
1566
+ return $this->previousLink;
1567
+ }
1568
+ public function setStartIndex($startIndex) {
1569
+ $this->startIndex = $startIndex;
1570
+ }
1571
+ public function getStartIndex() {
1572
+ return $this->startIndex;
1573
+ }
1574
+ public function setNextLink($nextLink) {
1575
+ $this->nextLink = $nextLink;
1576
+ }
1577
+ public function getNextLink() {
1578
+ return $this->nextLink;
1579
+ }
1580
+ public function setTotalResults($totalResults) {
1581
+ $this->totalResults = $totalResults;
1582
+ }
1583
+ public function getTotalResults() {
1584
+ return $this->totalResults;
1585
+ }
1586
+ }
1587
+
1588
+ class Google_Segment extends Google_Model {
1589
+ public $definition;
1590
+ public $kind;
1591
+ public $segmentId;
1592
+ public $created;
1593
+ public $updated;
1594
+ public $id;
1595
+ public $selfLink;
1596
+ public $name;
1597
+ public function setDefinition($definition) {
1598
+ $this->definition = $definition;
1599
+ }
1600
+ public function getDefinition() {
1601
+ return $this->definition;
1602
+ }
1603
+ public function setKind($kind) {
1604
+ $this->kind = $kind;
1605
+ }
1606
+ public function getKind() {
1607
+ return $this->kind;
1608
+ }
1609
+ public function setSegmentId($segmentId) {
1610
+ $this->segmentId = $segmentId;
1611
+ }
1612
+ public function getSegmentId() {
1613
+ return $this->segmentId;
1614
+ }
1615
+ public function setCreated($created) {
1616
+ $this->created = $created;
1617
+ }
1618
+ public function getCreated() {
1619
+ return $this->created;
1620
+ }
1621
+ public function setUpdated($updated) {
1622
+ $this->updated = $updated;
1623
+ }
1624
+ public function getUpdated() {
1625
+ return $this->updated;
1626
+ }
1627
+ public function setId($id) {
1628
+ $this->id = $id;
1629
+ }
1630
+ public function getId() {
1631
+ return $this->id;
1632
+ }
1633
+ public function setSelfLink($selfLink) {
1634
+ $this->selfLink = $selfLink;
1635
+ }
1636
+ public function getSelfLink() {
1637
+ return $this->selfLink;
1638
+ }
1639
+ public function setName($name) {
1640
+ $this->name = $name;
1641
+ }
1642
+ public function getName() {
1643
+ return $this->name;
1644
+ }
1645
+ }
1646
+
1647
+ class Google_Segments extends Google_Model {
1648
+ public $username;
1649
+ public $kind;
1650
+ protected $__itemsType = 'Google_Segment';
1651
+ protected $__itemsDataType = 'array';
1652
+ public $items;
1653
+ public $itemsPerPage;
1654
+ public $previousLink;
1655
+ public $startIndex;
1656
+ public $nextLink;
1657
+ public $totalResults;
1658
+ public function setUsername($username) {
1659
+ $this->username = $username;
1660
+ }
1661
+ public function getUsername() {
1662
+ return $this->username;
1663
+ }
1664
+ public function setKind($kind) {
1665
+ $this->kind = $kind;
1666
+ }
1667
+ public function getKind() {
1668
+ return $this->kind;
1669
+ }
1670
+ public function setItems(/* array(Google_Segment) */ $items) {
1671
+ $this->assertIsArray($items, 'Google_Segment', __METHOD__);
1672
+ $this->items = $items;
1673
+ }
1674
+ public function getItems() {
1675
+ return $this->items;
1676
+ }
1677
+ public function setItemsPerPage($itemsPerPage) {
1678
+ $this->itemsPerPage = $itemsPerPage;
1679
+ }
1680
+ public function getItemsPerPage() {
1681
+ return $this->itemsPerPage;
1682
+ }
1683
+ public function setPreviousLink($previousLink) {
1684
+ $this->previousLink = $previousLink;
1685
+ }
1686
+ public function getPreviousLink() {
1687
+ return $this->previousLink;
1688
+ }
1689
+ public function setStartIndex($startIndex) {
1690
+ $this->startIndex = $startIndex;
1691
+ }
1692
+ public function getStartIndex() {
1693
+ return $this->startIndex;
1694
+ }
1695
+ public function setNextLink($nextLink) {
1696
+ $this->nextLink = $nextLink;
1697
+ }
1698
+ public function getNextLink() {
1699
+ return $this->nextLink;
1700
+ }
1701
+ public function setTotalResults($totalResults) {
1702
+ $this->totalResults = $totalResults;
1703
+ }
1704
+ public function getTotalResults() {
1705
+ return $this->totalResults;
1706
+ }
1707
+ }
1708
+
1709
+ class Google_Webproperties extends Google_Model {
1710
+ public $username;
1711
+ public $kind;
1712
+ protected $__itemsType = 'Google_Webproperty';
1713
+ protected $__itemsDataType = 'array';
1714
+ public $items;
1715
+ public $itemsPerPage;
1716
+ public $previousLink;
1717
+ public $startIndex;
1718
+ public $nextLink;
1719
+ public $totalResults;
1720
+ public function setUsername($username) {
1721
+ $this->username = $username;
1722
+ }
1723
+ public function getUsername() {
1724
+ return $this->username;
1725
+ }
1726
+ public function setKind($kind) {
1727
+ $this->kind = $kind;
1728
+ }
1729
+ public function getKind() {
1730
+ return $this->kind;
1731
+ }
1732
+ public function setItems(/* array(Google_Webproperty) */ $items) {
1733
+ $this->assertIsArray($items, 'Google_Webproperty', __METHOD__);
1734
+ $this->items = $items;
1735
+ }
1736
+ public function getItems() {
1737
+ return $this->items;
1738
+ }
1739
+ public function setItemsPerPage($itemsPerPage) {
1740
+ $this->itemsPerPage = $itemsPerPage;
1741
+ }
1742
+ public function getItemsPerPage() {
1743
+ return $this->itemsPerPage;
1744
+ }
1745
+ public function setPreviousLink($previousLink) {
1746
+ $this->previousLink = $previousLink;
1747
+ }
1748
+ public function getPreviousLink() {
1749
+ return $this->previousLink;
1750
+ }
1751
+ public function setStartIndex($startIndex) {
1752
+ $this->startIndex = $startIndex;
1753
+ }
1754
+ public function getStartIndex() {
1755
+ return $this->startIndex;
1756
+ }
1757
+ public function setNextLink($nextLink) {
1758
+ $this->nextLink = $nextLink;
1759
+ }
1760
+ public function getNextLink() {
1761
+ return $this->nextLink;
1762
+ }
1763
+ public function setTotalResults($totalResults) {
1764
+ $this->totalResults = $totalResults;
1765
+ }
1766
+ public function getTotalResults() {
1767
+ return $this->totalResults;
1768
+ }
1769
+ }
1770
+
1771
+ class Google_Webproperty extends Google_Model {
1772
+ public $kind;
1773
+ public $name;
1774
+ public $created;
1775
+ public $updated;
1776
+ public $websiteUrl;
1777
+ public $internalWebPropertyId;
1778
+ protected $__childLinkType = 'Google_WebpropertyChildLink';
1779
+ protected $__childLinkDataType = '';
1780
+ public $childLink;
1781
+ protected $__parentLinkType = 'Google_WebpropertyParentLink';
1782
+ protected $__parentLinkDataType = '';
1783
+ public $parentLink;
1784
+ public $id;
1785
+ public $selfLink;
1786
+ public $accountId;
1787
+ public function setKind($kind) {
1788
+ $this->kind = $kind;
1789
+ }
1790
+ public function getKind() {
1791
+ return $this->kind;
1792
+ }
1793
+ public function setName($name) {
1794
+ $this->name = $name;
1795
+ }
1796
+ public function getName() {
1797
+ return $this->name;
1798
+ }
1799
+ public function setCreated($created) {
1800
+ $this->created = $created;
1801
+ }
1802
+ public function getCreated() {
1803
+ return $this->created;
1804
+ }
1805
+ public function setUpdated($updated) {
1806
+ $this->updated = $updated;
1807
+ }
1808
+ public function getUpdated() {
1809
+ return $this->updated;
1810
+ }
1811
+ public function setWebsiteUrl($websiteUrl) {
1812
+ $this->websiteUrl = $websiteUrl;
1813
+ }
1814
+ public function getWebsiteUrl() {
1815
+ return $this->websiteUrl;
1816
+ }
1817
+ public function setInternalWebPropertyId($internalWebPropertyId) {
1818
+ $this->internalWebPropertyId = $internalWebPropertyId;
1819
+ }
1820
+ public function getInternalWebPropertyId() {
1821
+ return $this->internalWebPropertyId;
1822
+ }
1823
+ public function setChildLink(Google_WebpropertyChildLink $childLink) {
1824
+ $this->childLink = $childLink;
1825
+ }
1826
+ public function getChildLink() {
1827
+ return $this->childLink;
1828
+ }
1829
+ public function setParentLink(Google_WebpropertyParentLink $parentLink) {
1830
+ $this->parentLink = $parentLink;
1831
+ }
1832
+ public function getParentLink() {
1833
+ return $this->parentLink;
1834
+ }
1835
+ public function setId($id) {
1836
+ $this->id = $id;
1837
+ }
1838
+ public function getId() {
1839
+ return $this->id;
1840
+ }
1841
+ public function setSelfLink($selfLink) {
1842
+ $this->selfLink = $selfLink;
1843
+ }
1844
+ public function getSelfLink() {
1845
+ return $this->selfLink;
1846
+ }
1847
+ public function setAccountId($accountId) {
1848
+ $this->accountId = $accountId;
1849
+ }
1850
+ public function getAccountId() {
1851
+ return $this->accountId;
1852
+ }
1853
+ }
1854
+
1855
+ class Google_WebpropertyChildLink extends Google_Model {
1856
+ public $href;
1857
+ public $type;
1858
+ public function setHref($href) {
1859
+ $this->href = $href;
1860
+ }
1861
+ public function getHref() {
1862
+ return $this->href;
1863
+ }
1864
+ public function setType($type) {
1865
+ $this->type = $type;
1866
+ }
1867
+ public function getType() {
1868
+ return $this->type;
1869
+ }
1870
+ }
1871
+
1872
+ class Google_WebpropertyParentLink extends Google_Model {
1873
+ public $href;
1874
+ public $type;
1875
+ public function setHref($href) {
1876
+ $this->href = $href;
1877
+ }
1878
+ public function getHref() {
1879
+ return $this->href;
1880
+ }
1881
+ public function setType($type) {
1882
+ $this->type = $type;
1883
+ }
1884
+ public function getType() {
1885
+ return $this->type;
1886
+ }
1887
+ }
google-api-php-client/src/contrib/Google_Oauth2Service.php ADDED
@@ -0,0 +1,265 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
4
+ * use this file except in compliance with the License. You may obtain a copy of
5
+ * the License at
6
+ *
7
+ * http://www.apache.org/licenses/LICENSE-2.0
8
+ *
9
+ * Unless required by applicable law or agreed to in writing, software
10
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12
+ * License for the specific language governing permissions and limitations under
13
+ * the License.
14
+ */
15
+
16
+
17
+ /**
18
+ * The "userinfo" collection of methods.
19
+ * Typical usage is:
20
+ * <code>
21
+ * $oauth2Service = new Google_Oauth2Service(...);
22
+ * $userinfo = $oauth2Service->userinfo;
23
+ * </code>
24
+ */
25
+ class Google_UserinfoServiceResource extends Google_ServiceResource {
26
+
27
+
28
+ /**
29
+ * (userinfo.get)
30
+ *
31
+ * @param array $optParams Optional parameters.
32
+ * @return Google_Userinfo
33
+ */
34
+ public function get($optParams = array()) {
35
+ $params = array();
36
+ $params = array_merge($params, $optParams);
37
+ $data = $this->__call('get', array($params));
38
+ if ($this->useObjects()) {
39
+ return new Google_Userinfo($data);
40
+ } else {
41
+ return $data;
42
+ }
43
+ }
44
+ }
45
+
46
+ /**
47
+ * The "v2" collection of methods.
48
+ * Typical usage is:
49
+ * <code>
50
+ * $oauth2Service = new Google_Oauth2Service(...);
51
+ * $v2 = $oauth2Service->v2;
52
+ * </code>
53
+ */
54
+ class Google_UserinfoV2ServiceResource extends Google_ServiceResource {
55
+
56
+
57
+ }
58
+
59
+ /**
60
+ * The "me" collection of methods.
61
+ * Typical usage is:
62
+ * <code>
63
+ * $oauth2Service = new Google_Oauth2Service(...);
64
+ * $me = $oauth2Service->me;
65
+ * </code>
66
+ */
67
+ class Google_UserinfoV2MeServiceResource extends Google_ServiceResource {
68
+
69
+
70
+ /**
71
+ * (me.get)
72
+ *
73
+ * @param array $optParams Optional parameters.
74
+ * @return Google_Userinfo
75
+ */
76
+ public function get($optParams = array()) {
77
+ $params = array();
78
+ $params = array_merge($params, $optParams);
79
+ $data = $this->__call('get', array($params));
80
+ if ($this->useObjects()) {
81
+ return new Google_Userinfo($data);
82
+ } else {
83
+ return $data;
84
+ }
85
+ }
86
+ }
87
+
88
+ /**
89
+ * Service definition for Google_Oauth2 (v2).
90
+ *
91
+ * <p>
92
+ * OAuth2 API
93
+ * </p>
94
+ *
95
+ * <p>
96
+ * For more information about this service, see the
97
+ * <a href="" target="_blank">API Documentation</a>
98
+ * </p>
99
+ *
100
+ * @author Google, Inc.
101
+ */
102
+ class Google_Oauth2Service extends Google_Service {
103
+ public $userinfo;
104
+ public $userinfo_v2_me;
105
+ /**
106
+ * Constructs the internal representation of the Oauth2 service.
107
+ *
108
+ * @param Google_Client $client
109
+ */
110
+ public function __construct(Google_Client $client) {
111
+ $this->servicePath = '';
112
+ $this->version = 'v2';
113
+ $this->serviceName = 'oauth2';
114
+
115
+ $client->addService($this->serviceName, $this->version);
116
+ $this->userinfo = new Google_UserinfoServiceResource($this, $this->serviceName, 'userinfo', json_decode('{"methods": {"get": {"path": "oauth2/v2/userinfo", "scopes": ["https://www.googleapis.com/auth/userinfo.email", "https://www.googleapis.com/auth/userinfo.profile"], "id": "oauth2.userinfo.get", "httpMethod": "GET", "response": {"$ref": "Userinfo"}}}}', true));
117
+ $this->userinfo_v2_me = new Google_UserinfoV2MeServiceResource($this, $this->serviceName, 'me', json_decode('{"methods": {"get": {"path": "userinfo/v2/me", "scopes": ["https://www.googleapis.com/auth/userinfo.email", "https://www.googleapis.com/auth/userinfo.profile"], "id": "oauth2.userinfo.v2.me.get", "httpMethod": "GET", "response": {"$ref": "Userinfo"}}}}', true));
118
+ }
119
+ }
120
+
121
+ class Google_Tokeninfo extends Google_Model {
122
+ public $issued_to;
123
+ public $user_id;
124
+ public $expires_in;
125
+ public $access_type;
126
+ public $audience;
127
+ public $scope;
128
+ public $email;
129
+ public $verified_email;
130
+ public function setIssued_to($issued_to) {
131
+ $this->issued_to = $issued_to;
132
+ }
133
+ public function getIssued_to() {
134
+ return $this->issued_to;
135
+ }
136
+ public function setUser_id($user_id) {
137
+ $this->user_id = $user_id;
138
+ }
139
+ public function getUser_id() {
140
+ return $this->user_id;
141
+ }
142
+ public function setExpires_in($expires_in) {
143
+ $this->expires_in = $expires_in;
144
+ }
145
+ public function getExpires_in() {
146
+ return $this->expires_in;
147
+ }
148
+ public function setAccess_type($access_type) {
149
+ $this->access_type = $access_type;
150
+ }
151
+ public function getAccess_type() {
152
+ return $this->access_type;
153
+ }
154
+ public function setAudience($audience) {
155
+ $this->audience = $audience;
156
+ }
157
+ public function getAudience() {
158
+ return $this->audience;
159
+ }
160
+ public function setScope($scope) {
161
+ $this->scope = $scope;
162
+ }
163
+ public function getScope() {
164
+ return $this->scope;
165
+ }
166
+ public function setEmail($email) {
167
+ $this->email = $email;
168
+ }
169
+ public function getEmail() {
170
+ return $this->email;
171
+ }
172
+ public function setVerified_email($verified_email) {
173
+ $this->verified_email = $verified_email;
174
+ }
175
+ public function getVerified_email() {
176
+ return $this->verified_email;
177
+ }
178
+ }
179
+
180
+ class Google_Userinfo extends Google_Model {
181
+ public $family_name;
182
+ public $name;
183
+ public $picture;
184
+ public $locale;
185
+ public $gender;
186
+ public $email;
187
+ public $birthday;
188
+ public $link;
189
+ public $given_name;
190
+ public $timezone;
191
+ public $id;
192
+ public $verified_email;
193
+ public function setFamily_name($family_name) {
194
+ $this->family_name = $family_name;
195
+ }
196
+ public function getFamily_name() {
197
+ return $this->family_name;
198
+ }
199
+ public function setName($name) {
200
+ $this->name = $name;
201
+ }
202
+ public function getName() {
203
+ return $this->name;
204
+ }
205
+ public function setPicture($picture) {
206
+ $this->picture = $picture;
207
+ }
208
+ public function getPicture() {
209
+ return $this->picture;
210
+ }
211
+ public function setLocale($locale) {
212
+ $this->locale = $locale;
213
+ }
214
+ public function getLocale() {
215
+ return $this->locale;
216
+ }
217
+ public function setGender($gender) {
218
+ $this->gender = $gender;
219
+ }
220
+ public function getGender() {
221
+ return $this->gender;
222
+ }
223
+ public function setEmail($email) {
224
+ $this->email = $email;
225
+ }
226
+ public function getEmail() {
227
+ return $this->email;
228
+ }
229
+ public function setBirthday($birthday) {
230
+ $this->birthday = $birthday;
231
+ }
232
+ public function getBirthday() {
233
+ return $this->birthday;
234
+ }
235
+ public function setLink($link) {
236
+ $this->link = $link;
237
+ }
238
+ public function getLink() {
239
+ return $this->link;
240
+ }
241
+ public function setGiven_name($given_name) {
242
+ $this->given_name = $given_name;
243
+ }
244
+ public function getGiven_name() {
245
+ return $this->given_name;
246
+ }
247
+ public function setTimezone($timezone) {
248
+ $this->timezone = $timezone;
249
+ }
250
+ public function getTimezone() {
251
+ return $this->timezone;
252
+ }
253
+ public function setId($id) {
254
+ $this->id = $id;
255
+ }
256
+ public function getId() {
257
+ return $this->id;
258
+ }
259
+ public function setVerified_email($verified_email) {
260
+ $this->verified_email = $verified_email;
261
+ }
262
+ public function getVerified_email() {
263
+ return $this->verified_email;
264
+ }
265
+ }
google-api-php-client/src/external/URITemplateParser.php ADDED
@@ -0,0 +1,213 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ Copyright (c) 2010 Kevin M Burns Jr, http://kevburnsjr.com/
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
+ */
24
+
25
+ /**
26
+ * A URI Template Parser which is used by the apiREST class to resolve the REST requests
27
+ * Blogpost: http://lab.kevburnsjr.com/php-uri-template-parser
28
+ * Source: http://github.com/KevBurnsJr/php-uri-template-parser
29
+ */
30
+
31
+ if(!class_exists('URI_Template_Parser'))
32
+ {
33
+ class URI_Template_Parser {
34
+
35
+ public static $operators = array('+', ';', '?', '/', '.');
36
+ public static $reserved_operators = array('|', '!', '@');
37
+ public static $explode_modifiers = array('+', '*');
38
+ public static $partial_modifiers = array(':', '^');
39
+
40
+ public static $gen_delims = array(':', '/', '?', '#', '[', ']', '@');
41
+ public static $gen_delims_pct = array('%3A', '%2F', '%3F', '%23', '%5B', '%5D', '%40');
42
+ public static $sub_delims = array('!', '$', '&', '\'', '(', ')', '*', '+', ',', ';', '=');
43
+ public static $sub_delims_pct = array('%21', '%24', '%26', '%27', '%28', '%29', '%2A', '%2B', '%2C', '%3B', '%3D');
44
+ public static $reserved;
45
+ public static $reserved_pct;
46
+
47
+ public function __construct($template) {
48
+ self::$reserved = array_merge(self::$gen_delims, self::$sub_delims);
49
+ self::$reserved_pct = array_merge(self::$gen_delims_pct, self::$sub_delims_pct);
50
+ $this->template = $template;
51
+ }
52
+
53
+ public function expand($data) {
54
+ // Modification to make this a bit more performant (since gettype is very slow)
55
+ if (! is_array($data)) {
56
+ $data = (array)$data;
57
+ }
58
+ /*
59
+ // Original code, which uses a slow gettype() statement, kept in place for if the assumption that is_array always works here is incorrect
60
+ switch (gettype($data)) {
61
+ case "boolean":
62
+ case "integer":
63
+ case "double":
64
+ case "string":
65
+ case "object":
66
+ $data = (array)$data;
67
+ break;
68
+ }
69
+ */
70
+
71
+ // Resolve template vars
72
+ preg_match_all('/\{([^\}]*)\}/', $this->template, $em);
73
+
74
+ foreach ($em[1] as $i => $bare_expression) {
75
+ preg_match('/^([\+\;\?\/\.]{1})?(.*)$/', $bare_expression, $lm);
76
+ $exp = new StdClass();
77
+ $exp->expression = $em[0][$i];
78
+ $exp->operator = $lm[1];
79
+ $exp->variable_list = $lm[2];
80
+ $exp->varspecs = explode(',', $exp->variable_list);
81
+ $exp->vars = array();
82
+ foreach ($exp->varspecs as $varspec) {
83
+ preg_match('/^([a-zA-Z0-9_]+)([\*\+]{1})?([\:\^][0-9-]+)?(\=[^,]+)?$/', $varspec, $vm);
84
+ $var = new StdClass();
85
+ $var->name = $vm[1];
86
+ $var->modifier = isset($vm[2]) && $vm[2] ? $vm[2] : null;
87
+ $var->modifier = isset($vm[3]) && $vm[3] ? $vm[3] : $var->modifier;
88
+ $var->default = isset($vm[4]) ? substr($vm[4], 1) : null;
89
+ $exp->vars[] = $var;
90
+ }
91
+
92
+ // Add processing flags
93
+ $exp->reserved = false;
94
+ $exp->prefix = '';
95
+ $exp->delimiter = ',';
96
+ switch ($exp->operator) {
97
+ case '+':
98
+ $exp->reserved = 'true';
99
+ break;
100
+ case ';':
101
+ $exp->prefix = ';';
102
+ $exp->delimiter = ';';
103
+ break;
104
+ case '?':
105
+ $exp->prefix = '?';
106
+ $exp->delimiter = '&';
107
+ break;
108
+ case '/':
109
+ $exp->prefix = '/';
110
+ $exp->delimiter = '/';
111
+ break;
112
+ case '.':
113
+ $exp->prefix = '.';
114
+ $exp->delimiter = '.';
115
+ break;
116
+ }
117
+ $expressions[] = $exp;
118
+ }
119
+
120
+ // Expansion
121
+ $this->expansion = $this->template;
122
+
123
+ foreach ($expressions as $exp) {
124
+ $part = $exp->prefix;
125
+ $exp->one_var_defined = false;
126
+ foreach ($exp->vars as $var) {
127
+ $val = '';
128
+ if ($exp->one_var_defined && isset($data[$var->name])) {
129
+ $part .= $exp->delimiter;
130
+ }
131
+ // Variable present
132
+ if (isset($data[$var->name])) {
133
+ $exp->one_var_defined = true;
134
+ $var->data = $data[$var->name];
135
+
136
+ $val = self::val_from_var($var, $exp);
137
+
138
+ // Variable missing
139
+ } else {
140
+ if ($var->default) {
141
+ $exp->one_var_defined = true;
142
+ $val = $var->default;
143
+ }
144
+ }
145
+ $part .= $val;
146
+ }
147
+ if (! $exp->one_var_defined) $part = '';
148
+ $this->expansion = str_replace($exp->expression, $part, $this->expansion);
149
+ }
150
+
151
+ return $this->expansion;
152
+ }
153
+
154
+ private function val_from_var($var, $exp) {
155
+ $val = '';
156
+ if (is_array($var->data)) {
157
+ $i = 0;
158
+ if ($exp->operator == '?' && ! $var->modifier) {
159
+ $val .= $var->name . '=';
160
+ }
161
+ foreach ($var->data as $k => $v) {
162
+ $del = $var->modifier ? $exp->delimiter : ',';
163
+ $ek = rawurlencode($k);
164
+ $ev = rawurlencode($v);
165
+
166
+ // Array
167
+ if ($k !== $i) {
168
+ if ($var->modifier == '+') {
169
+ $val .= $var->name . '.';
170
+ }
171
+ if ($exp->operator == '?' && $var->modifier || $exp->operator == ';' && $var->modifier == '*' || $exp->operator == ';' && $var->modifier == '+') {
172
+ $val .= $ek . '=';
173
+ } else {
174
+ $val .= $ek . $del;
175
+ }
176
+
177
+ // List
178
+ } else {
179
+ if ($var->modifier == '+') {
180
+ if ($exp->operator == ';' && $var->modifier == '*' || $exp->operator == ';' && $var->modifier == '+' || $exp->operator == '?' && $var->modifier == '+') {
181
+ $val .= $var->name . '=';
182
+ } else {
183
+ $val .= $var->name . '.';
184
+ }
185
+ }
186
+ }
187
+ $val .= $ev . $del;
188
+ $i ++;
189
+ }
190
+ $val = trim($val, $del);
191
+
192
+ // Strings, numbers, etc.
193
+ } else {
194
+ if ($exp->operator == '?') {
195
+ $val = $var->name . (isset($var->data) ? '=' : '');
196
+ } else if ($exp->operator == ';') {
197
+ $val = $var->name . ($var->data ? '=' : '');
198
+ }
199
+ $val .= rawurlencode($var->data);
200
+ if ($exp->operator == '+') {
201
+ $val = str_replace(self::$reserved_pct, self::$reserved, $val);
202
+ }
203
+ }
204
+ return $val;
205
+ }
206
+
207
+ public function match($uri) {}
208
+
209
+ public function __toString() {
210
+ return $this->template;
211
+ }
212
+ }
213
+ }
google-api-php-client/src/io/Google_CacheParser.php ADDED
@@ -0,0 +1,173 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * Copyright 2012 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
+ * Implement the caching directives specified in rfc2616. This
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
+
26
+ private function __construct() {}
27
+
28
+ /**
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;
40
+ }
41
+
42
+ // Don't cache authorized requests/responses.
43
+ // [rfc2616-14.8] When a shared cache receives a request containing an
44
+ // Authorization field, it MUST NOT return the corresponding response
45
+ // as a reply to any other request...
46
+ if ($resp->getRequestHeader("authorization")) {
47
+ return false;
48
+ }
49
+
50
+ return true;
51
+ }
52
+
53
+ /**
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)) {
65
+ return false;
66
+ }
67
+
68
+ $code = $resp->getResponseHttpCode();
69
+ if (! in_array($code, self::$CACHEABLE_STATUS_CODES)) {
70
+ return false;
71
+ }
72
+
73
+ // The resource is uncacheable if the resource is already expired and
74
+ // the resource doesn't have an ETag for revalidation.
75
+ $etag = $resp->getResponseHeader("etag");
76
+ if (self::isExpired($resp) && $etag == false) {
77
+ return false;
78
+ }
79
+
80
+ // [rfc2616-14.9.2] If [no-store is] sent in a response, a cache MUST NOT
81
+ // store any part of either this response or the request that elicited it.
82
+ $cacheControl = $resp->getParsedCacheControl();
83
+ if (isset($cacheControl['no-store'])) {
84
+ return false;
85
+ }
86
+
87
+ // Pragma: no-cache is an http request directive, but is occasionally
88
+ // used as a response header incorrectly.
89
+ $pragma = $resp->getResponseHeader('pragma');
90
+ if ($pragma == 'no-cache' || strpos($pragma, 'no-cache') !== false) {
91
+ return false;
92
+ }
93
+
94
+ // [rfc2616-14.44] Vary: * is extremely difficult to cache. "It implies that
95
+ // a cache cannot determine from the request headers of a subsequent request
96
+ // whether this response is the appropriate representation."
97
+ // Given this, we deem responses with the Vary header as uncacheable.
98
+ $vary = $resp->getResponseHeader('vary');
99
+ if ($vary) {
100
+ return false;
101
+ }
102
+
103
+ return true;
104
+ }
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;
116
+ $responseHeaders = $resp->getResponseHeaders();
117
+ if (isset($responseHeaders['expires'])) {
118
+ $rawExpires = $responseHeaders['expires'];
119
+ // Check for a malformed expires header first.
120
+ if (empty($rawExpires) || (is_numeric($rawExpires) && $rawExpires <= 0)) {
121
+ return true;
122
+ }
123
+
124
+ // See if we can parse the expires header.
125
+ $parsedExpires = strtotime($rawExpires);
126
+ if (false == $parsedExpires || $parsedExpires <= 0) {
127
+ return true;
128
+ }
129
+ }
130
+
131
+ // Calculate the freshness of an http response.
132
+ $freshnessLifetime = false;
133
+ $cacheControl = $resp->getParsedCacheControl();
134
+ if (isset($cacheControl['max-age'])) {
135
+ $freshnessLifetime = $cacheControl['max-age'];
136
+ }
137
+
138
+ $rawDate = $resp->getResponseHeader('date');
139
+ $parsedDate = strtotime($rawDate);
140
+
141
+ if (empty($rawDate) || false == $parsedDate) {
142
+ $parsedDate = time();
143
+ }
144
+ if (false == $freshnessLifetime && isset($responseHeaders['expires'])) {
145
+ $freshnessLifetime = $parsedExpires - $parsedDate;
146
+ }
147
+
148
+ if (false == $freshnessLifetime) {
149
+ return true;
150
+ }
151
+
152
+ // Calculate the age of an http response.
153
+ $age = max(0, time() - $parsedDate);
154
+ if (isset($responseHeaders['age'])) {
155
+ $age = max($age, strtotime($responseHeaders['age']));
156
+ }
157
+
158
+ return $freshnessLifetime <= $age;
159
+ }
160
+
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.
171
+ return self::isExpired($response);
172
+ }
173
+ }
google-api-php-client/src/io/Google_CurlIO.php ADDED
@@ -0,0 +1,278 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ * Curl based implementation of apiIO.
20
+ *
21
+ * @author Chris Chabot <chabotc@google.com>
22
+ * @author Chirag Shah <chirags@google.com>
23
+ */
24
+
25
+ require_once 'Google_CacheParser.php';
26
+
27
+ class Google_CurlIO implements Google_IO {
28
+ const CONNECTION_ESTABLISHED = "HTTP/1.0 200 Connection established\r\n\r\n";
29
+ const FORM_URLENCODED = 'application/x-www-form-urlencoded';
30
+
31
+ private static $ENTITY_HTTP_METHODS = array("POST" => null, "PUT" => null);
32
+ private static $HOP_BY_HOP = array(
33
+ 'connection', 'keep-alive', 'proxy-authenticate', 'proxy-authorization',
34
+ 'te', 'trailers', 'transfer-encoding', 'upgrade');
35
+
36
+ private $curlParams = array (
37
+ CURLOPT_RETURNTRANSFER => true,
38
+ CURLOPT_FOLLOWLOCATION => 0,
39
+ CURLOPT_FAILONERROR => false,
40
+ CURLOPT_SSL_VERIFYPEER => true,
41
+ CURLOPT_HEADER => true,
42
+ CURLOPT_VERBOSE => false,
43
+ );
44
+
45
+ /**
46
+ * Perform an authenticated / signed apiHttpRequest.
47
+ * This function takes the apiHttpRequest, calls apiAuth->sign on it
48
+ * (which can modify the request in what ever way fits the auth mechanism)
49
+ * and then calls apiCurlIO::makeRequest on the signed request
50
+ *
51
+ * @param Google_HttpRequest $request
52
+ * @return Google_HttpRequest The resulting HTTP response including the
53
+ * responseHttpCode, responseHeaders and responseBody.
54
+ */
55
+ public function authenticatedRequest(Google_HttpRequest $request) {
56
+ $request = Google_Client::$auth->sign($request);
57
+ return $this->makeRequest($request);
58
+ }
59
+
60
+ /**
61
+ * Execute a apiHttpRequest
62
+ *
63
+ * @param Google_HttpRequest $request the http request to be executed
64
+ * @return Google_HttpRequest http request with the response http code, response
65
+ * headers and response body filled in
66
+ * @throws Google_IOException on curl or IO error
67
+ */
68
+ public function makeRequest(Google_HttpRequest $request) {
69
+ // First, check to see if we have a valid cached version.
70
+ $cached = $this->getCachedRequest($request);
71
+ if ($cached !== false) {
72
+ if (Google_CacheParser::mustRevalidate($cached)) {
73
+ $addHeaders = array();
74
+ if ($cached->getResponseHeader('etag')) {
75
+ // [13.3.4] If an entity tag has been provided by the origin server,
76
+ // we must use that entity tag in any cache-conditional request.
77
+ $addHeaders['If-None-Match'] = $cached->getResponseHeader('etag');
78
+ } elseif ($cached->getResponseHeader('date')) {
79
+ $addHeaders['If-Modified-Since'] = $cached->getResponseHeader('date');
80
+ }
81
+
82
+ $request->setRequestHeaders($addHeaders);
83
+ } else {
84
+ // No need to revalidate the request, return it directly
85
+ return $cached;
86
+ }
87
+ }
88
+
89
+ if (array_key_exists($request->getRequestMethod(),
90
+ self::$ENTITY_HTTP_METHODS)) {
91
+ $request = $this->processEntityRequest($request);
92
+ }
93
+
94
+ $ch = curl_init();
95
+ curl_setopt_array($ch, $this->curlParams);
96
+ curl_setopt($ch, CURLOPT_URL, $request->getUrl());
97
+ if ($request->getPostBody()) {
98
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $request->getPostBody());
99
+ }
100
+
101
+ $requestHeaders = $request->getRequestHeaders();
102
+ if ($requestHeaders && is_array($requestHeaders)) {
103
+ $parsed = array();
104
+ foreach ($requestHeaders as $k => $v) {
105
+ $parsed[] = "$k: $v";
106
+ }
107
+ curl_setopt($ch, CURLOPT_HTTPHEADER, $parsed);
108
+ }
109
+
110
+ curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $request->getRequestMethod());
111
+ curl_setopt($ch, CURLOPT_USERAGENT, $request->getUserAgent());
112
+ $respData = curl_exec($ch);
113
+
114
+ // Retry if certificates are missing.
115
+ if (curl_errno($ch) == CURLE_SSL_CACERT) {
116
+ error_log('SSL certificate problem, verify that the CA cert is OK.'
117
+ . ' Retrying with the CA cert bundle from google-api-php-client.');
118
+ curl_setopt($ch, CURLOPT_CAINFO, dirname(__FILE__) . '/cacerts.pem');
119
+ $respData = curl_exec($ch);
120
+ }
121
+
122
+ $respHeaderSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
123
+ $respHttpCode = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE);
124
+ $curlErrorNum = curl_errno($ch);
125
+ $curlError = curl_error($ch);
126
+ curl_close($ch);
127
+ if ($curlErrorNum != CURLE_OK) {
128
+ throw new Google_IOException("HTTP Error: ($respHttpCode) $curlError");
129
+ }
130
+
131
+ // Parse out the raw response into usable bits
132
+ list($responseHeaders, $responseBody) =
133
+ self::parseHttpResponse($respData, $respHeaderSize);
134
+
135
+ if ($respHttpCode == 304 && $cached) {
136
+ // If the server responded NOT_MODIFIED, return the cached request.
137
+ if (isset($responseHeaders['connection'])) {
138
+ $hopByHop = array_merge(
139
+ self::$HOP_BY_HOP,
140
+ explode(',', $responseHeaders['connection'])
141
+ );
142
+
143
+ $endToEnd = array();
144
+ foreach($hopByHop as $key) {
145
+ if (isset($responseHeaders[$key])) {
146
+ $endToEnd[$key] = $responseHeaders[$key];
147
+ }
148
+ }
149
+ $cached->setResponseHeaders($endToEnd);
150
+ }
151
+ return $cached;
152
+ }
153
+
154
+ // Fill in the apiHttpRequest with the response values
155
+ $request->setResponseHttpCode($respHttpCode);
156
+ $request->setResponseHeaders($responseHeaders);
157
+ $request->setResponseBody($responseBody);
158
+ // Store the request in cache (the function checks to see if the request
159
+ // can actually be cached)
160
+ $this->setCachedRequest($request);
161
+ // And finally return it
162
+ return $request;
163
+ }
164
+
165
+ /**
166
+ * @visible for testing.
167
+ * Cache the response to an HTTP request if it is cacheable.
168
+ * @param Google_HttpRequest $request
169
+ * @return bool Returns true if the insertion was successful.
170
+ * Otherwise, return false.
171
+ */
172
+ public function setCachedRequest(Google_HttpRequest $request) {
173
+ // Determine if the request is cacheable.
174
+ if (Google_CacheParser::isResponseCacheable($request)) {
175
+ Google_Client::$cache->set($request->getCacheKey(), $request);
176
+ return true;
177
+ }
178
+
179
+ return false;
180
+ }
181
+
182
+ /**
183
+ * @visible for testing.
184
+ * @param Google_HttpRequest $request
185
+ * @return Google_HttpRequest|bool Returns the cached object or
186
+ * false if the operation was unsuccessful.
187
+ */
188
+ public function getCachedRequest(Google_HttpRequest $request) {
189
+ if (false == Google_CacheParser::isRequestCacheable($request)) {
190
+ false;
191
+ }
192
+
193
+ return Google_Client::$cache->get($request->getCacheKey());
194
+ }
195
+
196
+ /**
197
+ * @param $respData
198
+ * @param $headerSize
199
+ * @return array
200
+ */
201
+ public static function parseHttpResponse($respData, $headerSize) {
202
+ if (stripos($respData, self::CONNECTION_ESTABLISHED) !== false) {
203
+ $respData = str_ireplace(self::CONNECTION_ESTABLISHED, '', $respData);
204
+ }
205
+
206
+ if ($headerSize) {
207
+ $responseBody = substr($respData, $headerSize);
208
+ $responseHeaders = substr($respData, 0, $headerSize);
209
+ } else {
210
+ list($responseHeaders, $responseBody) = explode("\r\n\r\n", $respData, 2);
211
+ }
212
+
213
+ $responseHeaders = self::parseResponseHeaders($responseHeaders);
214
+ return array($responseHeaders, $responseBody);
215
+ }
216
+
217
+ public static function parseResponseHeaders($rawHeaders) {
218
+ $responseHeaders = array();
219
+
220
+ $responseHeaderLines = explode("\r\n", $rawHeaders);
221
+ foreach ($responseHeaderLines as $headerLine) {
222
+ if ($headerLine && strpos($headerLine, ':') !== false) {
223
+ list($header, $value) = explode(': ', $headerLine, 2);
224
+ $header = strtolower($header);
225
+ if (isset($responseHeaders[$header])) {
226
+ $responseHeaders[$header] .= "\n" . $value;
227
+ } else {
228
+ $responseHeaders[$header] = $value;
229
+ }
230
+ }
231
+ }
232
+ return $responseHeaders;
233
+ }
234
+
235
+ /**
236
+ * @visible for testing
237
+ * Process an http request that contains an enclosed entity.
238
+ * @param Google_HttpRequest $request
239
+ * @return Google_HttpRequest Processed request with the enclosed entity.
240
+ */
241
+ public function processEntityRequest(Google_HttpRequest $request) {
242
+ $postBody = $request->getPostBody();
243
+ $contentType = $request->getRequestHeader("content-type");
244
+
245
+ // Set the default content-type as application/x-www-form-urlencoded.
246
+ if (false == $contentType) {
247
+ $contentType = self::FORM_URLENCODED;
248
+ $request->setRequestHeaders(array('content-type' => $contentType));
249
+ }
250
+
251
+ // Force the payload to match the content-type asserted in the header.
252
+ if ($contentType == self::FORM_URLENCODED && is_array($postBody)) {
253
+ $postBody = http_build_query($postBody, '', '&');
254
+ $request->setPostBody($postBody);
255
+ }
256
+
257
+ // Make sure the content-length header is set.
258
+ if (!$postBody || is_string($postBody)) {
259
+ $postsLength = strlen($postBody);
260
+ $request->setRequestHeaders(array('content-length' => $postsLength));
261
+ }
262
+
263
+ return $request;
264
+ }
265
+
266
+ /**
267
+ * Set options that update cURL's default behavior.
268
+ * The list of accepted options are:
269
+ * {@link http://php.net/manual/en/function.curl-setopt.php]
270
+ *
271
+ * @param array $optCurlParams Multiple options used by a cURL session.
272
+ */
273
+ public function setOptions($optCurlParams) {
274
+ foreach ($optCurlParams as $key => $val) {
275
+ $this->curlParams[$key] = $val;
276
+ }
277
+ }
278
+ }
google-api-php-client/src/io/Google_HttpRequest.php ADDED
@@ -0,0 +1,304 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ * HTTP Request to be executed by apiIO classes. Upon execution, the
20
+ * responseHttpCode, responseHeaders and responseBody will be filled in.
21
+ *
22
+ * @author Chris Chabot <chabotc@google.com>
23
+ * @author Chirag Shah <chirags@google.com>
24
+ *
25
+ */
26
+ class Google_HttpRequest {
27
+ const USER_AGENT_SUFFIX = "google-api-php-client/0.6.0";
28
+ private $batchHeaders = array(
29
+ 'Content-Type' => 'application/http',
30
+ 'Content-Transfer-Encoding' => 'binary',
31
+ 'MIME-Version' => '1.0',
32
+ 'Content-Length' => ''
33
+ );
34
+
35
+ protected $url;
36
+ protected $requestMethod;
37
+ protected $requestHeaders;
38
+ protected $postBody;
39
+ protected $userAgent;
40
+
41
+ protected $responseHttpCode;
42
+ protected $responseHeaders;
43
+ protected $responseBody;
44
+
45
+ public $accessKey;
46
+
47
+ public function __construct($url, $method = 'GET', $headers = array(), $postBody = null) {
48
+ $this->setUrl($url);
49
+ $this->setRequestMethod($method);
50
+ $this->setRequestHeaders($headers);
51
+ $this->setPostBody($postBody);
52
+
53
+ global $apiConfig;
54
+ if (empty($apiConfig['application_name'])) {
55
+ $this->userAgent = self::USER_AGENT_SUFFIX;
56
+ } else {
57
+ $this->userAgent = $apiConfig['application_name'] . " " . self::USER_AGENT_SUFFIX;
58
+ }
59
+ }
60
+
61
+ /**
62
+ * Misc function that returns the base url component of the $url
63
+ * used by the OAuth signing class to calculate the base string
64
+ * @return string The base url component of the $url.
65
+ * @see http://oauth.net/core/1.0a/#anchor13
66
+ */
67
+ public function getBaseUrl() {
68
+ if ($pos = strpos($this->url, '?')) {
69
+ return substr($this->url, 0, $pos);
70
+ }
71
+ return $this->url;
72
+ }
73
+
74
+ /**
75
+ * Misc function that returns an array of the query parameters of the current
76
+ * url used by the OAuth signing class to calculate the signature
77
+ * @return array Query parameters in the query string.
78
+ */
79
+ public function getQueryParams() {
80
+ if ($pos = strpos($this->url, '?')) {
81
+ $queryStr = substr($this->url, $pos + 1);
82
+ $params = array();
83
+ parse_str($queryStr, $params);
84
+ return $params;
85
+ }
86
+ return array();
87
+ }
88
+
89
+ /**
90
+ * @return string HTTP Response Code.
91
+ */
92
+ public function getResponseHttpCode() {
93
+ return (int) $this->responseHttpCode;
94
+ }
95
+
96
+ /**
97
+ * @param int $responseHttpCode HTTP Response Code.
98
+ */
99
+ public function setResponseHttpCode($responseHttpCode) {
100
+ $this->responseHttpCode = $responseHttpCode;
101
+ }
102
+
103
+ /**
104
+ * @return $responseHeaders (array) HTTP Response Headers.
105
+ */
106
+ public function getResponseHeaders() {
107
+ return $this->responseHeaders;
108
+ }
109
+
110
+ /**
111
+ * @return string HTTP Response Body
112
+ */
113
+ public function getResponseBody() {
114
+ return $this->responseBody;
115
+ }
116
+
117
+ /**
118
+ * @param array $headers The HTTP response headers
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
+ }
126
+
127
+ $this->responseHeaders = $headers;
128
+ }
129
+
130
+ /**
131
+ * @param string $key
132
+ * @return array|boolean Returns the requested HTTP header or
133
+ * false if unavailable.
134
+ */
135
+ public function getResponseHeader($key) {
136
+ return isset($this->responseHeaders[$key])
137
+ ? $this->responseHeaders[$key]
138
+ : false;
139
+ }
140
+
141
+ /**
142
+ * @param string $responseBody The HTTP response body.
143
+ */
144
+ public function setResponseBody($responseBody) {
145
+ $this->responseBody = $responseBody;
146
+ }
147
+
148
+ /**
149
+ * @return string $url The request URL.
150
+ */
151
+
152
+ public function getUrl() {
153
+ return $this->url;
154
+ }
155
+
156
+ /**
157
+ * @return string $method HTTP Request Method.
158
+ */
159
+ public function getRequestMethod() {
160
+ return $this->requestMethod;
161
+ }
162
+
163
+ /**
164
+ * @return array $headers HTTP Request Headers.
165
+ */
166
+ public function getRequestHeaders() {
167
+ return $this->requestHeaders;
168
+ }
169
+
170
+ /**
171
+ * @param string $key
172
+ * @return array|boolean Returns the requested HTTP header or
173
+ * false if unavailable.
174
+ */
175
+ public function getRequestHeader($key) {
176
+ return isset($this->requestHeaders[$key])
177
+ ? $this->requestHeaders[$key]
178
+ : false;
179
+ }
180
+
181
+ /**
182
+ * @return string $postBody HTTP Request Body.
183
+ */
184
+ public function getPostBody() {
185
+ return $this->postBody;
186
+ }
187
+
188
+ /**
189
+ * @param string $url the url to set
190
+ */
191
+ public function setUrl($url) {
192
+ if (substr($url, 0, 4) == 'http') {
193
+ $this->url = $url;
194
+ } else {
195
+ // Force the path become relative.
196
+ if (substr($url, 0, 1) !== '/') {
197
+ $url = '/' . $url;
198
+ }
199
+ global $apiConfig;
200
+ $this->url = $apiConfig['basePath'] . $url;
201
+ }
202
+ }
203
+
204
+ /**
205
+ * @param string $method Set he HTTP Method and normalize
206
+ * it to upper-case, as required by HTTP.
207
+ *
208
+ */
209
+ public function setRequestMethod($method) {
210
+ $this->requestMethod = strtoupper($method);
211
+ }
212
+
213
+ /**
214
+ * @param array $headers The HTTP request headers
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
+ }
222
+ $this->requestHeaders = $headers;
223
+ }
224
+
225
+ /**
226
+ * @param string $postBody the postBody to set
227
+ */
228
+ public function setPostBody($postBody) {
229
+ $this->postBody = $postBody;
230
+ }
231
+
232
+ /**
233
+ * Set the User-Agent Header.
234
+ * @param string $userAgent The User-Agent.
235
+ */
236
+ public function setUserAgent($userAgent) {
237
+ $this->userAgent = $userAgent;
238
+ }
239
+
240
+ /**
241
+ * @return string The User-Agent.
242
+ */
243
+ public function getUserAgent() {
244
+ return $this->userAgent;
245
+ }
246
+
247
+ /**
248
+ * Returns a cache key depending on if this was an OAuth signed request
249
+ * in which case it will use the non-signed url and access key to make this
250
+ * cache key unique per authenticated user, else use the plain request url
251
+ * @return string The md5 hash of the request cache key.
252
+ */
253
+ public function getCacheKey() {
254
+ $key = $this->getUrl();
255
+
256
+ if (isset($this->accessKey)) {
257
+ $key .= $this->accessKey;
258
+ }
259
+
260
+ if (isset($this->requestHeaders['authorization'])) {
261
+ $key .= $this->requestHeaders['authorization'];
262
+ }
263
+
264
+ return md5($key);
265
+ }
266
+
267
+ public function getParsedCacheControl() {
268
+ $parsed = array();
269
+ $rawCacheControl = $this->getResponseHeader('cache-control');
270
+ if ($rawCacheControl) {
271
+ $rawCacheControl = str_replace(', ', '&', $rawCacheControl);
272
+ parse_str($rawCacheControl, $parsed);
273
+ }
274
+
275
+ return $parsed;
276
+ }
277
+
278
+ /**
279
+ * @param string $id
280
+ * @return string A string representation of the HTTP Request.
281
+ */
282
+ public function toBatchString($id) {
283
+ $str = '';
284
+ foreach($this->batchHeaders as $key => $val) {
285
+ $str .= $key . ': ' . $val . "\n";
286
+ }
287
+
288
+ $str .= "Content-ID: $id\n";
289
+ $str .= "\n";
290
+
291
+ $path = parse_url($this->getUrl(), PHP_URL_PATH);
292
+ $str .= $this->getRequestMethod() . ' ' . $path . " HTTP/1.1\n";
293
+ foreach($this->getRequestHeaders() as $key => $val) {
294
+ $str .= $key . ': ' . $val . "\n";
295
+ }
296
+
297
+ if ($this->getPostBody()) {
298
+ $str .= "\n";
299
+ $str .= $this->getPostBody();
300
+ }
301
+
302
+ return $str;
303
+ }
304
+ }
google-api-php-client/src/io/Google_IO.php ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ require_once 'io/Google_HttpRequest.php';
19
+ require_once 'io/Google_CurlIO.php';
20
+ require_once 'io/Google_REST.php';
21
+
22
+ /**
23
+ * Abstract IO class
24
+ *
25
+ * @author Chris Chabot <chabotc@google.com>
26
+ */
27
+ interface Google_IO {
28
+ /**
29
+ * An utility function that first calls $this->auth->sign($request) and then executes makeRequest()
30
+ * on that signed request. Used for when a request should be authenticated
31
+ * @param Google_HttpRequest $request
32
+ * @return Google_HttpRequest $request
33
+ */
34
+ public function authenticatedRequest(Google_HttpRequest $request);
35
+
36
+ /**
37
+ * Executes a apIHttpRequest and returns the resulting populated httpRequest
38
+ * @param Google_HttpRequest $request
39
+ * @return Google_HttpRequest $request
40
+ */
41
+ public function makeRequest(Google_HttpRequest $request);
42
+
43
+ /**
44
+ * Set options that update the transport implementation's behavior.
45
+ * @param $options
46
+ */
47
+ public function setOptions($options);
48
+
49
+ }
google-api-php-client/src/io/Google_REST.php ADDED
@@ -0,0 +1,128 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ * This class implements the RESTful transport of apiServiceRequest()'s
20
+ *
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;
39
+ return $ret;
40
+ }
41
+
42
+
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) {
51
+ $code = $response->getResponseHttpCode();
52
+ $body = $response->getResponseBody();
53
+ $decoded = null;
54
+
55
+ if ($code != '200' && $code != '201' && $code != '204') {
56
+ $decoded = json_decode($body, true);
57
+ $err = 'Error calling ' . $response->getRequestMethod() . ' ' . $response->getUrl();
58
+ if ($decoded != null && isset($decoded['error']['message']) && isset($decoded['error']['code'])) {
59
+ // if we're getting a json encoded error definition, use that instead of the raw response
60
+ // body for improved readability
61
+ $err .= ": ({$decoded['error']['code']}) {$decoded['error']['message']}";
62
+ } else {
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;
77
+ }
78
+
79
+ /**
80
+ * Parse/expand request parameters and create a fully qualified
81
+ * request uri.
82
+ * @static
83
+ * @param string $servicePath
84
+ * @param string $restPath
85
+ * @param array $params
86
+ * @return string $requestUrl
87
+ */
88
+ static function createRequestUri($servicePath, $restPath, $params) {
89
+ $requestUrl = $servicePath . $restPath;
90
+ $uriTemplateVars = array();
91
+ $queryVars = array();
92
+ foreach ($params as $paramName => $paramSpec) {
93
+ // Discovery v1.0 puts the canonical location under the 'location' field.
94
+ if (! isset($paramSpec['location'])) {
95
+ $paramSpec['location'] = $paramSpec['restParameterType'];
96
+ }
97
+
98
+ if ($paramSpec['type'] == 'boolean') {
99
+ $paramSpec['value'] = ($paramSpec['value']) ? 'true' : 'false';
100
+ }
101
+ if ($paramSpec['location'] == 'path') {
102
+ $uriTemplateVars[$paramName] = $paramSpec['value'];
103
+ } else {
104
+ if (isset($paramSpec['repeated']) && is_array($paramSpec['value'])) {
105
+ foreach ($paramSpec['value'] as $value) {
106
+ $queryVars[] = $paramName . '=' . rawurlencode($value);
107
+ }
108
+ } else {
109
+ $queryVars[] = $paramName . '=' . rawurlencode($paramSpec['value']);
110
+ }
111
+ }
112
+ }
113
+
114
+ if (count($uriTemplateVars)) {
115
+ $uriTemplateParser = new URI_Template_Parser($requestUrl);
116
+ $requestUrl = $uriTemplateParser->expand($uriTemplateVars);
117
+ }
118
+ //FIXME work around for the the uri template lib which url encodes
119
+ // the @'s & confuses our servers.
120
+ $requestUrl = str_replace('%40', '@', $requestUrl);
121
+
122
+ if (count($queryVars)) {
123
+ $requestUrl .= '?' . implode($queryVars, '&');
124
+ }
125
+
126
+ return $requestUrl;
127
+ }
128
+ }
google-api-php-client/src/io/cacerts.pem ADDED
@@ -0,0 +1,714 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Certifcate Authority certificates for validating SSL connections.
2
+ #
3
+ # This file contains PEM format certificates generated from
4
+ # http://mxr.mozilla.org/seamonkey/source/security/nss/lib/ckfw/builtins/certdata.txt
5
+ #
6
+ # ***** BEGIN LICENSE BLOCK *****
7
+ # Version: MPL 1.1/GPL 2.0/LGPL 2.1
8
+ #
9
+ # The contents of this file are subject to the Mozilla Public License Version
10
+ # 1.1 (the "License"); you may not use this file except in compliance with
11
+ # the License. You may obtain a copy of the License at
12
+ # http://www.mozilla.org/MPL/
13
+ #
14
+ # Software distributed under the License is distributed on an "AS IS" basis,
15
+ # WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
16
+ # for the specific language governing rights and limitations under the
17
+ # License.
18
+ #
19
+ # The Original Code is the Netscape security libraries.
20
+ #
21
+ # The Initial Developer of the Original Code is
22
+ # Netscape Communications Corporation.
23
+ # Portions created by the Initial Developer are Copyright (C) 1994-2000
24
+ # the Initial Developer. All Rights Reserved.
25
+ #
26
+ # Contributor(s):
27
+ #
28
+ # Alternatively, the contents of this file may be used under the terms of
29
+ # either the GNU General Public License Version 2 or later (the "GPL"), or
30
+ # the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
31
+ # in which case the provisions of the GPL or the LGPL are applicable instead
32
+ # of those above. If you wish to allow use of your version of this file only
33
+ # under the terms of either the GPL or the LGPL, and not to allow others to
34
+ # use your version of this file under the terms of the MPL, indicate your
35
+ # decision by deleting the provisions above and replace them with the notice
36
+ # and other provisions required by the GPL or the LGPL. If you do not delete
37
+ # the provisions above, a recipient may use your version of this file under
38
+ # the terms of any one of the MPL, the GPL or the LGPL.
39
+ #
40
+ # ***** END LICENSE BLOCK *****
41
+
42
+ Verisign/RSA Secure Server CA
43
+ =============================
44
+
45
+ -----BEGIN CERTIFICATE-----
46
+ MIICNDCCAaECEAKtZn5ORf5eV288mBle3cAwDQYJKoZIhvcNAQECBQAwXzELMAkG
47
+ A1UEBhMCVVMxIDAeBgNVBAoTF1JTQSBEYXRhIFNlY3VyaXR5LCBJbmMuMS4wLAYD
48
+ VQQLEyVTZWN1cmUgU2VydmVyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk0
49
+ MTEwOTAwMDAwMFoXDTEwMDEwNzIzNTk1OVowXzELMAkGA1UEBhMCVVMxIDAeBgNV
50
+ BAoTF1JTQSBEYXRhIFNlY3VyaXR5LCBJbmMuMS4wLAYDVQQLEyVTZWN1cmUgU2Vy
51
+ dmVyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGbMA0GCSqGSIb3DQEBAQUAA4GJ
52
+ ADCBhQJ+AJLOesGugz5aqomDV6wlAXYMra6OLDfO6zV4ZFQD5YRAUcm/jwjiioII
53
+ 0haGN1XpsSECrXZogZoFokvJSyVmIlZsiAeP94FZbYQHZXATcXY+m3dM41CJVphI
54
+ uR2nKRoTLkoRWZweFdVJVCxzOmmCsZc5nG1wZ0jl3S3WyB57AgMBAAEwDQYJKoZI
55
+ hvcNAQECBQADfgBl3X7hsuyw4jrg7HFGmhkRuNPHoLQDQCYCPgmc4RKz0Vr2N6W3
56
+ YQO2WxZpO8ZECAyIUwxrl0nHPjXcbLm7qt9cuzovk2C2qUtN8iD3zV9/ZHuO3ABc
57
+ 1/p3yjkWWW8O6tO1g39NTUJWdrTJXwT4OPjr0l91X817/OWOgHz8UA==
58
+ -----END CERTIFICATE-----
59
+
60
+ Thawte Personal Basic CA
61
+ ========================
62
+
63
+ -----BEGIN CERTIFICATE-----
64
+ MIIDITCCAoqgAwIBAgIBADANBgkqhkiG9w0BAQQFADCByzELMAkGA1UEBhMCWkEx
65
+ FTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMRowGAYD
66
+ VQQKExFUaGF3dGUgQ29uc3VsdGluZzEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBT
67
+ ZXJ2aWNlcyBEaXZpc2lvbjEhMB8GA1UEAxMYVGhhd3RlIFBlcnNvbmFsIEJhc2lj
68
+ IENBMSgwJgYJKoZIhvcNAQkBFhlwZXJzb25hbC1iYXNpY0B0aGF3dGUuY29tMB4X
69
+ DTk2MDEwMTAwMDAwMFoXDTIwMTIzMTIzNTk1OVowgcsxCzAJBgNVBAYTAlpBMRUw
70
+ EwYDVQQIEwxXZXN0ZXJuIENhcGUxEjAQBgNVBAcTCUNhcGUgVG93bjEaMBgGA1UE
71
+ ChMRVGhhd3RlIENvbnN1bHRpbmcxKDAmBgNVBAsTH0NlcnRpZmljYXRpb24gU2Vy
72
+ dmljZXMgRGl2aXNpb24xITAfBgNVBAMTGFRoYXd0ZSBQZXJzb25hbCBCYXNpYyBD
73
+ QTEoMCYGCSqGSIb3DQEJARYZcGVyc29uYWwtYmFzaWNAdGhhd3RlLmNvbTCBnzAN
74
+ BgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAvLyTU23AUE+CFeZIlDWmWr5vQvoPR+53
75
+ dXLdjUmbllegeNTKP1GzaQuRdhciB5dqxFGTS+CN7zeVoQxN2jSQHReJl+A1OFdK
76
+ wPQIcOk8RHtQfmGakOMj04gRRif1CwcOu93RfyAKiLlWCy4cgNrx454p7xS9CkT7
77
+ G1sY0b8jkyECAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQQF
78
+ AAOBgQAt4plrsD16iddZopQBHyvdEktTwq1/qqcAXJFAVyVKOKqEcLnZgA+le1z7
79
+ c8a914phXAPjLSeoF+CEhULcXpvGt7Jtu3Sv5D/Lp7ew4F2+eIMllNLbgQ95B21P
80
+ 9DkVWlIBe94y1k049hJcBlDfBVu9FEuh3ym6O0GN92NWod8isQ==
81
+ -----END CERTIFICATE-----
82
+
83
+ Thawte Personal Premium CA
84
+ ==========================
85
+
86
+ -----BEGIN CERTIFICATE-----
87
+ MIIDKTCCApKgAwIBAgIBADANBgkqhkiG9w0BAQQFADCBzzELMAkGA1UEBhMCWkEx
88
+ FTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMRowGAYD
89
+ VQQKExFUaGF3dGUgQ29uc3VsdGluZzEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBT
90
+ ZXJ2aWNlcyBEaXZpc2lvbjEjMCEGA1UEAxMaVGhhd3RlIFBlcnNvbmFsIFByZW1p
91
+ dW0gQ0ExKjAoBgkqhkiG9w0BCQEWG3BlcnNvbmFsLXByZW1pdW1AdGhhd3RlLmNv
92
+ bTAeFw05NjAxMDEwMDAwMDBaFw0yMDEyMzEyMzU5NTlaMIHPMQswCQYDVQQGEwJa
93
+ QTEVMBMGA1UECBMMV2VzdGVybiBDYXBlMRIwEAYDVQQHEwlDYXBlIFRvd24xGjAY
94
+ BgNVBAoTEVRoYXd0ZSBDb25zdWx0aW5nMSgwJgYDVQQLEx9DZXJ0aWZpY2F0aW9u
95
+ IFNlcnZpY2VzIERpdmlzaW9uMSMwIQYDVQQDExpUaGF3dGUgUGVyc29uYWwgUHJl
96
+ bWl1bSBDQTEqMCgGCSqGSIb3DQEJARYbcGVyc29uYWwtcHJlbWl1bUB0aGF3dGUu
97
+ Y29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDJZtn4B0TPuYwu8KHvE0Vs
98
+ Bd/eJxZRNkERbGw77f4QfRKe5ZtCmv5gMcNmt3M6SK5O0DI3lIi1DbbZ8/JE2dWI
99
+ Et12TfIa/G8jHnrx2JhFTgcQ7xZC0EN1bUre4qrJMf8fAHB8Zs8QJQi6+u4A6UYD
100
+ ZicRFTuqW/KY3TZCstqIdQIDAQABoxMwETAPBgNVHRMBAf8EBTADAQH/MA0GCSqG
101
+ SIb3DQEBBAUAA4GBAGk2ifc0KjNyL2071CKyuG+axTZmDhs8obF1Wub9NdP4qPIH
102
+ b4Vnjt4rueIXsDqg8A6iAJrf8xQVbrvIhVqYgPn/vnQdPfP+MCXRNzRn+qVxeTBh
103
+ KXLA4CxM+1bkOqhv5TJZUtt1KFBZDPgLGeSs2a+WjS9Q2wfD6h+rM+D1KzGJ
104
+ -----END CERTIFICATE-----
105
+
106
+ Thawte Personal Freemail CA
107
+ ===========================
108
+
109
+ -----BEGIN CERTIFICATE-----
110
+ MIIDLTCCApagAwIBAgIBADANBgkqhkiG9w0BAQQFADCB0TELMAkGA1UEBhMCWkEx
111
+ FTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMRowGAYD
112
+ VQQKExFUaGF3dGUgQ29uc3VsdGluZzEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBT
113
+ ZXJ2aWNlcyBEaXZpc2lvbjEkMCIGA1UEAxMbVGhhd3RlIFBlcnNvbmFsIEZyZWVt
114
+ YWlsIENBMSswKQYJKoZIhvcNAQkBFhxwZXJzb25hbC1mcmVlbWFpbEB0aGF3dGUu
115
+ Y29tMB4XDTk2MDEwMTAwMDAwMFoXDTIwMTIzMTIzNTk1OVowgdExCzAJBgNVBAYT
116
+ AlpBMRUwEwYDVQQIEwxXZXN0ZXJuIENhcGUxEjAQBgNVBAcTCUNhcGUgVG93bjEa
117
+ MBgGA1UEChMRVGhhd3RlIENvbnN1bHRpbmcxKDAmBgNVBAsTH0NlcnRpZmljYXRp
118
+ b24gU2VydmljZXMgRGl2aXNpb24xJDAiBgNVBAMTG1RoYXd0ZSBQZXJzb25hbCBG
119
+ cmVlbWFpbCBDQTErMCkGCSqGSIb3DQEJARYccGVyc29uYWwtZnJlZW1haWxAdGhh
120
+ d3RlLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA1GnX1LCUZFtx6UfY
121
+ DFG26nKRsIRefS0Nj3sS34UldSh0OkIsYyeflXtL734Zhx2G6qPduc6WZBrCFG5E
122
+ rHzmj+hND3EfQDimAKOHePb5lIZererAXnbr2RSjXW56fAylS1V/Bhkpf56aJtVq
123
+ uzgkCGqYx7Hao5iR/Xnb5VrEHLkCAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zAN
124
+ BgkqhkiG9w0BAQQFAAOBgQDH7JJ+Tvj1lqVnYiqk8E0RYNBvjWBYYawmu1I1XAjP
125
+ MPuoSpaKH2JCI4wXD/S6ZJwXrEcp352YXtJsYHFcoqzceePnbgBHH7UNKOgCneSa
126
+ /RP0ptl8sfjcXyMmCZGAc9AUG95DqYMl8uacLxXK/qarigd1iwzdUYRr5PjRznei
127
+ gQ==
128
+ -----END CERTIFICATE-----
129
+
130
+ Thawte Server CA
131
+ ================
132
+
133
+ -----BEGIN CERTIFICATE-----
134
+ MIIDEzCCAnygAwIBAgIBATANBgkqhkiG9w0BAQQFADCBxDELMAkGA1UEBhMCWkEx
135
+ FTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYD
136
+ VQQKExRUaGF3dGUgQ29uc3VsdGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlv
137
+ biBTZXJ2aWNlcyBEaXZpc2lvbjEZMBcGA1UEAxMQVGhhd3RlIFNlcnZlciBDQTEm
138
+ MCQGCSqGSIb3DQEJARYXc2VydmVyLWNlcnRzQHRoYXd0ZS5jb20wHhcNOTYwODAx
139
+ MDAwMDAwWhcNMjAxMjMxMjM1OTU5WjCBxDELMAkGA1UEBhMCWkExFTATBgNVBAgT
140
+ DFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYDVQQKExRUaGF3
141
+ dGUgQ29uc3VsdGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNl
142
+ cyBEaXZpc2lvbjEZMBcGA1UEAxMQVGhhd3RlIFNlcnZlciBDQTEmMCQGCSqGSIb3
143
+ DQEJARYXc2VydmVyLWNlcnRzQHRoYXd0ZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQAD
144
+ gY0AMIGJAoGBANOkUG7I/1Zr5s9dtuoMaHVHoqrC2oQl/Kj0R1HahbUgdJSGHg91
145
+ yekIYfUGbTBuFRkC6VLAYttNmZ7iagxEOM3+vuNkCXDF/rFrKbYvScg71CcEJRCX
146
+ L+eQbcAoQpnXTEPew/UhbVSfXcNY4cDk2VuwuNy0e982OsK1ZiIS1ocNAgMBAAGj
147
+ EzARMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEEBQADgYEAB/pMaVz7lcxG
148
+ 7oWDTSEwjsrZqG9JGubaUeNgcGyEYRGhGshIPllDfU+VPaGLtwtimHp1it2ITk6e
149
+ QNuozDJ0uW8NxuOzRAvZim+aKZuZGCg70eNAKJpaPNW15yAbi8qkq43pUdniTCxZ
150
+ qdq5snUb9kLy78fyGPmJvKP/iiMucEc=
151
+ -----END CERTIFICATE-----
152
+
153
+ Thawte Premium Server CA
154
+ ========================
155
+
156
+ -----BEGIN CERTIFICATE-----
157
+ MIIDJzCCApCgAwIBAgIBATANBgkqhkiG9w0BAQQFADCBzjELMAkGA1UEBhMCWkEx
158
+ FTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYD
159
+ VQQKExRUaGF3dGUgQ29uc3VsdGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlv
160
+ biBTZXJ2aWNlcyBEaXZpc2lvbjEhMB8GA1UEAxMYVGhhd3RlIFByZW1pdW0gU2Vy
161
+ dmVyIENBMSgwJgYJKoZIhvcNAQkBFhlwcmVtaXVtLXNlcnZlckB0aGF3dGUuY29t
162
+ MB4XDTk2MDgwMTAwMDAwMFoXDTIwMTIzMTIzNTk1OVowgc4xCzAJBgNVBAYTAlpB
163
+ MRUwEwYDVQQIEwxXZXN0ZXJuIENhcGUxEjAQBgNVBAcTCUNhcGUgVG93bjEdMBsG
164
+ A1UEChMUVGhhd3RlIENvbnN1bHRpbmcgY2MxKDAmBgNVBAsTH0NlcnRpZmljYXRp
165
+ b24gU2VydmljZXMgRGl2aXNpb24xITAfBgNVBAMTGFRoYXd0ZSBQcmVtaXVtIFNl
166
+ cnZlciBDQTEoMCYGCSqGSIb3DQEJARYZcHJlbWl1bS1zZXJ2ZXJAdGhhd3RlLmNv
167
+ bTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA0jY2aovXwlue2oFBYo847kkE
168
+ VdbQ7xwblRZH7xhINTpS9CtqBo87L+pW46+GjZ4X9560ZXUCTe/LCaIhUdib0GfQ
169
+ ug2SBhRz1JPLlyoAnFxODLz6FVL88kRu2hFKbgifLy3j+ao6hnO2RlNYyIkFvYMR
170
+ uHM/qgeN9EJN50CdHDcCAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG
171
+ 9w0BAQQFAAOBgQAmSCwWwlj66BZ0DKqqX1Q/8tfJeGBeXm43YyJ3Nn6yF8Q0ufUI
172
+ hfzJATj/Tb7yFkJD57taRvvBxhEf8UqwKEbJw8RCfbz6q1lu1bdRiBHjpIUZa4JM
173
+ pAwSremkrj/xw0llmozFyD4lt5SZu5IycQfwhl7tUCemDaYj+bvLpgcUQg==
174
+ -----END CERTIFICATE-----
175
+
176
+ Equifax Secure CA
177
+ =================
178
+
179
+ -----BEGIN CERTIFICATE-----
180
+ MIIDIDCCAomgAwIBAgIENd70zzANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQGEwJV
181
+ UzEQMA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2Vy
182
+ dGlmaWNhdGUgQXV0aG9yaXR5MB4XDTk4MDgyMjE2NDE1MVoXDTE4MDgyMjE2NDE1
183
+ MVowTjELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0VxdWlmYXgxLTArBgNVBAsTJEVx
184
+ dWlmYXggU2VjdXJlIENlcnRpZmljYXRlIEF1dGhvcml0eTCBnzANBgkqhkiG9w0B
185
+ AQEFAAOBjQAwgYkCgYEAwV2xWGcIYu6gmi0fCG2RFGiYCh7+2gRvE4RiIcPRfM6f
186
+ BeC4AfBONOziipUEZKzxa1NfBbPLZ4C/QgKO/t0BCezhABRP/PvwDN1Dulsr4R+A
187
+ cJkVV5MW8Q+XarfCaCMczE1ZMKxRHjuvK9buY0V7xdlfUNLjUA86iOe/FP3gx7kC
188
+ AwEAAaOCAQkwggEFMHAGA1UdHwRpMGcwZaBjoGGkXzBdMQswCQYDVQQGEwJVUzEQ
189
+ MA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2VydGlm
190
+ aWNhdGUgQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMBoGA1UdEAQTMBGBDzIwMTgw
191
+ ODIyMTY0MTUxWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUSOZo+SvSspXXR9gj
192
+ IBBPM5iQn9QwHQYDVR0OBBYEFEjmaPkr0rKV10fYIyAQTzOYkJ/UMAwGA1UdEwQF
193
+ MAMBAf8wGgYJKoZIhvZ9B0EABA0wCxsFVjMuMGMDAgbAMA0GCSqGSIb3DQEBBQUA
194
+ A4GBAFjOKer89961zgK5F7WF0bnj4JXMJTENAKaSbn+2kmOeUJXRmm/kEd5jhW6Y
195
+ 7qj/WsjTVbJmcVfewCHrPSqnI0kBBIZCe/zuf6IWUrVnZ9NA2zsmWLIodz2uFHdh
196
+ 1voqZiegDfqnc1zqcPGUIWVEX/r87yloqaKHee9570+sB3c4
197
+ -----END CERTIFICATE-----
198
+
199
+ Verisign Class 1 Public Primary Certification Authority
200
+ =======================================================
201
+
202
+ -----BEGIN CERTIFICATE-----
203
+ MIICPTCCAaYCEQDNun9W8N/kvFT+IqyzcqpVMA0GCSqGSIb3DQEBAgUAMF8xCzAJ
204
+ BgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE3MDUGA1UECxMuQ2xh
205
+ c3MgMSBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw05
206
+ NjAxMjkwMDAwMDBaFw0yODA4MDEyMzU5NTlaMF8xCzAJBgNVBAYTAlVTMRcwFQYD
207
+ VQQKEw5WZXJpU2lnbiwgSW5jLjE3MDUGA1UECxMuQ2xhc3MgMSBQdWJsaWMgUHJp
208
+ bWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCBnzANBgkqhkiG9w0BAQEFAAOB
209
+ jQAwgYkCgYEA5Rm/baNWYS2ZSHH2Z965jeu3noaACpEO+jglr0aIguVzqKCbJF0N
210
+ H8xlbgyw0FaEGIeaBpsQoXPftFg5a27B9hXVqKg/qhIGjTGsf7A01480Z4gJzRQR
211
+ 4k5FVmkfeAKA2txHkSm7NsljXMXg1y2He6G3MrB7MLoqLzGq7qNn2tsCAwEAATAN
212
+ BgkqhkiG9w0BAQIFAAOBgQBMP7iLxmjf7kMzDl3ppssHhE16M/+SG/Q2rdiVIjZo
213
+ EWx8QszznC7EBz8UsA9P/5CSdvnivErpj82ggAr3xSnxgiJduLHdgSOjeyUVRjB5
214
+ FvjqBUuUfx3CHMjjt/QQQDwTw18fU+hI5Ia0e6E1sHslurjTjqs/OJ0ANACY89Fx
215
+ lA==
216
+ -----END CERTIFICATE-----
217
+
218
+ Verisign Class 2 Public Primary Certification Authority
219
+ =======================================================
220
+
221
+ -----BEGIN CERTIFICATE-----
222
+ MIICPDCCAaUCEC0b/EoXjaOR6+f/9YtFvgswDQYJKoZIhvcNAQECBQAwXzELMAkG
223
+ A1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFz
224
+ cyAyIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk2
225
+ MDEyOTAwMDAwMFoXDTI4MDgwMTIzNTk1OVowXzELMAkGA1UEBhMCVVMxFzAVBgNV
226
+ BAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAyIFB1YmxpYyBQcmlt
227
+ YXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUAA4GN
228
+ ADCBiQKBgQC2WoujDWojg4BrzzmH9CETMwZMJaLtVRKXxaeAufqDwSCg+i8VDXyh
229
+ YGt+eSz6Bg86rvYbb7HS/y8oUl+DfUvEerf4Zh+AVPy3wo5ZShRXRtGak75BkQO7
230
+ FYCTXOvnzAhsPz6zSvz/S2wj1VCCJkQZjiPDceoZJEcEnnW/yKYAHwIDAQABMA0G
231
+ CSqGSIb3DQEBAgUAA4GBAIobK/o5wXTXXtgZZKJYSi034DNHD6zt96rbHuSLBlxg
232
+ J8pFUs4W7z8GZOeUaHxgMxURaa+dYo2jA1Rrpr7l7gUYYAS/QoD90KioHgE796Nc
233
+ r6Pc5iaAIzy4RHT3Cq5Ji2F4zCS/iIqnDupzGUH9TQPwiNHleI2lKk/2lw0Xd8rY
234
+ -----END CERTIFICATE-----
235
+
236
+ Verisign Class 3 Public Primary Certification Authority
237
+ =======================================================
238
+
239
+ -----BEGIN CERTIFICATE-----
240
+ MIICPDCCAaUCEHC65B0Q2Sk0tjjKewPMur8wDQYJKoZIhvcNAQECBQAwXzELMAkG
241
+ A1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFz
242
+ cyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk2
243
+ MDEyOTAwMDAwMFoXDTI4MDgwMTIzNTk1OVowXzELMAkGA1UEBhMCVVMxFzAVBgNV
244
+ BAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAzIFB1YmxpYyBQcmlt
245
+ YXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUAA4GN
246
+ ADCBiQKBgQDJXFme8huKARS0EN8EQNvjV69qRUCPhAwL0TPZ2RHP7gJYHyX3KqhE
247
+ BarsAx94f56TuZoAqiN91qyFomNFx3InzPRMxnVx0jnvT0Lwdd8KkMaOIG+YD/is
248
+ I19wKTakyYbnsZogy1Olhec9vn2a/iRFM9x2Fe0PonFkTGUugWhFpwIDAQABMA0G
249
+ CSqGSIb3DQEBAgUAA4GBALtMEivPLCYATxQT3ab7/AoRhIzzKBxnki98tsX63/Do
250
+ lbwdj2wsqFHMc9ikwFPwTtYmwHYBV4GSXiHx0bH/59AhWM1pF+NEHJwZRDmJXNyc
251
+ AA9WjQKZ7aKQRUzkuxCkPfAyAw7xzvjoyVGM5mKf5p/AfbdynMk2OmufTqj/ZA1k
252
+ -----END CERTIFICATE-----
253
+
254
+ Verisign Class 1 Public Primary Certification Authority - G2
255
+ ============================================================
256
+
257
+ -----BEGIN CERTIFICATE-----
258
+ MIIDAjCCAmsCEEzH6qqYPnHTkxD4PTqJkZIwDQYJKoZIhvcNAQEFBQAwgcExCzAJ
259
+ BgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xh
260
+ c3MgMSBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcy
261
+ MTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3Jp
262
+ emVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMB4X
263
+ DTk4MDUxODAwMDAwMFoXDTI4MDgwMTIzNTk1OVowgcExCzAJBgNVBAYTAlVTMRcw
264
+ FQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xhc3MgMSBQdWJsaWMg
265
+ UHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMTowOAYDVQQLEzEo
266
+ YykgMTk5OCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5
267
+ MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMIGfMA0GCSqGSIb3DQEB
268
+ AQUAA4GNADCBiQKBgQCq0Lq+Fi24g9TK0g+8djHKlNgdk4xWArzZbxpvUjZudVYK
269
+ VdPfQ4chEWWKfo+9Id5rMj8bhDSVBZ1BNeuS65bdqlk/AVNtmU/t5eIqWpDBucSm
270
+ Fc/IReumXY6cPvBkJHalzasab7bYe1FhbqZ/h8jit+U03EGI6glAvnOSPWvndQID
271
+ AQABMA0GCSqGSIb3DQEBBQUAA4GBAKlPww3HZ74sy9mozS11534Vnjty637rXC0J
272
+ h9ZrbWB85a7FkCMMXErQr7Fd88e2CtvgFZMN3QO8x3aKtd1Pw5sTdbgBwObJW2ul
273
+ uIncrKTdcu1OofdPvAbT6shkdHvClUGcZXNY8ZCaPGqxmMnEh7zPRW1F4m4iP/68
274
+ DzFc6PLZ
275
+ -----END CERTIFICATE-----
276
+
277
+ Verisign Class 2 Public Primary Certification Authority - G2
278
+ ============================================================
279
+
280
+ -----BEGIN CERTIFICATE-----
281
+ MIIDAzCCAmwCEQC5L2DMiJ+hekYJuFtwbIqvMA0GCSqGSIb3DQEBBQUAMIHBMQsw
282
+ CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xPDA6BgNVBAsTM0Ns
283
+ YXNzIDIgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBH
284
+ MjE6MDgGA1UECxMxKGMpIDE5OTggVmVyaVNpZ24sIEluYy4gLSBGb3IgYXV0aG9y
285
+ aXplZCB1c2Ugb25seTEfMB0GA1UECxMWVmVyaVNpZ24gVHJ1c3QgTmV0d29yazAe
286
+ Fw05ODA1MTgwMDAwMDBaFw0yODA4MDEyMzU5NTlaMIHBMQswCQYDVQQGEwJVUzEX
287
+ MBUGA1UEChMOVmVyaVNpZ24sIEluYy4xPDA6BgNVBAsTM0NsYXNzIDIgUHVibGlj
288
+ IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMjE6MDgGA1UECxMx
289
+ KGMpIDE5OTggVmVyaVNpZ24sIEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25s
290
+ eTEfMB0GA1UECxMWVmVyaVNpZ24gVHJ1c3QgTmV0d29yazCBnzANBgkqhkiG9w0B
291
+ AQEFAAOBjQAwgYkCgYEAp4gBIXQs5xoD8JjhlzwPIQjxnNuX6Zr8wgQGE75fUsjM
292
+ HiwSViy4AWkszJkfrbCWrnkE8hM5wXuYuggs6MKEEyyqaekJ9MepAqRCwiNPStjw
293
+ DqL7MWzJ5m+ZJwf15vRMeJ5t60aG+rmGyVTyssSv1EYcWskVMP8NbPUtDm3Of3cC
294
+ AwEAATANBgkqhkiG9w0BAQUFAAOBgQByLvl/0fFx+8Se9sVeUYpAmLho+Jscg9ji
295
+ nb3/7aHmZuovCfTK1+qlK5X2JGCGTUQug6XELaDTrnhpb3LabK4I8GOSN+a7xDAX
296
+ rXfMSTWqz9iP0b63GJZHc2pUIjRkLbYWm1lbtFFZOrMLFPQS32eg9K0yZF6xRnIn
297
+ jBJ7xUS0rg==
298
+ -----END CERTIFICATE-----
299
+
300
+ Verisign Class 3 Public Primary Certification Authority - G2
301
+ ============================================================
302
+
303
+ -----BEGIN CERTIFICATE-----
304
+ MIIDAjCCAmsCEH3Z/gfPqB63EHln+6eJNMYwDQYJKoZIhvcNAQEFBQAwgcExCzAJ
305
+ BgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xh
306
+ c3MgMyBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcy
307
+ MTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3Jp
308
+ emVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMB4X
309
+ DTk4MDUxODAwMDAwMFoXDTI4MDgwMTIzNTk1OVowgcExCzAJBgNVBAYTAlVTMRcw
310
+ FQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xhc3MgMyBQdWJsaWMg
311
+ UHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMTowOAYDVQQLEzEo
312
+ YykgMTk5OCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5
313
+ MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMIGfMA0GCSqGSIb3DQEB
314
+ AQUAA4GNADCBiQKBgQDMXtERXVxp0KvTuWpMmR9ZmDCOFoUgRm1HP9SFIIThbbP4
315
+ pO0M8RcPO/mn+SXXwc+EY/J8Y8+iR/LGWzOOZEAEaMGAuWQcRXfH2G71lSk8UOg0
316
+ 13gfqLptQ5GVj0VXXn7F+8qkBOvqlzdUMG+7AUcyM83cV5tkaWH4mx0ciU9cZwID
317
+ AQABMA0GCSqGSIb3DQEBBQUAA4GBAFFNzb5cy5gZnBWyATl4Lk0PZ3BwmcYQWpSk
318
+ U01UbSuvDV1Ai2TT1+7eVmGSX6bEHRBhNtMsJzzoKQm5EWR0zLVznxxIqbxhAe7i
319
+ F6YM40AIOw7n60RzKprxaZLvcRTDOaxxp5EJb+RxBrO6WVcmeQD2+A2iMzAo1KpY
320
+ oJ2daZH9
321
+ -----END CERTIFICATE-----
322
+
323
+ Verisign Class 4 Public Primary Certification Authority - G2
324
+ ============================================================
325
+
326
+ -----BEGIN CERTIFICATE-----
327
+ MIIDAjCCAmsCEDKIjprS9esTR/h/xCA3JfgwDQYJKoZIhvcNAQEFBQAwgcExCzAJ
328
+ BgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xh
329
+ c3MgNCBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcy
330
+ MTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3Jp
331
+ emVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMB4X
332
+ DTk4MDUxODAwMDAwMFoXDTI4MDgwMTIzNTk1OVowgcExCzAJBgNVBAYTAlVTMRcw
333
+ FQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xhc3MgNCBQdWJsaWMg
334
+ UHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMTowOAYDVQQLEzEo
335
+ YykgMTk5OCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5
336
+ MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMIGfMA0GCSqGSIb3DQEB
337
+ AQUAA4GNADCBiQKBgQC68OTP+cSuhVS5B1f5j8V/aBH4xBewRNzjMHPVKmIquNDM
338
+ HO0oW369atyzkSTKQWI8/AIBvxwWMZQFl3Zuoq29YRdsTjCG8FE3KlDHqGKB3FtK
339
+ qsGgtG7rL+VXxbErQHDbWk2hjh+9Ax/YA9SPTJlxvOKCzFjomDqG04Y48wApHwID
340
+ AQABMA0GCSqGSIb3DQEBBQUAA4GBAIWMEsGnuVAVess+rLhDityq3RS6iYF+ATwj
341
+ cSGIL4LcY/oCRaxFWdcqWERbt5+BO5JoPeI3JPV7bI92NZYJqFmduc4jq3TWg/0y
342
+ cyfYaT5DdPauxYma51N86Xv2S/PBZYPejYqcPIiNOVn8qj8ijaHBZlCBckztImRP
343
+ T8qAkbYp
344
+ -----END CERTIFICATE-----
345
+
346
+ Verisign Class 1 Public Primary Certification Authority - G3
347
+ ============================================================
348
+
349
+ -----BEGIN CERTIFICATE-----
350
+ MIIEGjCCAwICEQCLW3VWhFSFCwDPrzhIzrGkMA0GCSqGSIb3DQEBBQUAMIHKMQsw
351
+ CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZl
352
+ cmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWdu
353
+ LCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlT
354
+ aWduIENsYXNzIDEgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3Jp
355
+ dHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQswCQYD
356
+ VQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlT
357
+ aWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJ
358
+ bmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWdu
359
+ IENsYXNzIDEgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg
360
+ LSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAN2E1Lm0+afY8wR4
361
+ nN493GwTFtl63SRRZsDHJlkNrAYIwpTRMx/wgzUfbhvI3qpuFU5UJ+/EbRrsC+MO
362
+ 8ESlV8dAWB6jRx9x7GD2bZTIGDnt/kIYVt/kTEkQeE4BdjVjEjbdZrwBBDajVWjV
363
+ ojYJrKshJlQGrT/KFOCsyq0GHZXi+J3x4GD/wn91K0zM2v6HmSHquv4+VNfSWXjb
364
+ PG7PoBMAGrgnoeS+Z5bKoMWznN3JdZ7rMJpfo83ZrngZPyPpXNspva1VyBtUjGP2
365
+ 6KbqxzcSXKMpHgLZ2x87tNcPVkeBFQRKr4Mn0cVYiMHd9qqnoxjaaKptEVHhv2Vr
366
+ n5Z20T0CAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAq2aN17O6x5q25lXQBfGfMY1a
367
+ qtmqRiYPce2lrVNWYgFHKkTp/j90CxObufRNG7LRX7K20ohcs5/Ny9Sn2WCVhDr4
368
+ wTcdYcrnsMXlkdpUpqwxga6X3s0IrLjAl4B/bnKk52kTlWUfxJM8/XmPBNQ+T+r3
369
+ ns7NZ3xPZQL/kYVUc8f/NveGLezQXk//EZ9yBta4GvFMDSZl4kSAHsef493oCtrs
370
+ pSCAaWihT37ha88HQfqDjrw43bAuEbFrskLMmrz5SCJ5ShkPshw+IHTZasO+8ih4
371
+ E1Z5T21Q6huwtVexN2ZYI/PcD98Kh8TvhgXVOBRgmaNL3gaWcSzy27YfpO8/7g==
372
+ -----END CERTIFICATE-----
373
+
374
+ Verisign Class 2 Public Primary Certification Authority - G3
375
+ ============================================================
376
+
377
+ -----BEGIN CERTIFICATE-----
378
+ MIIEGTCCAwECEGFwy0mMX5hFKeewptlQW3owDQYJKoZIhvcNAQEFBQAwgcoxCzAJ
379
+ BgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjEfMB0GA1UECxMWVmVy
380
+ aVNpZ24gVHJ1c3QgTmV0d29yazE6MDgGA1UECxMxKGMpIDE5OTkgVmVyaVNpZ24s
381
+ IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTFFMEMGA1UEAxM8VmVyaVNp
382
+ Z24gQ2xhc3MgMiBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0
383
+ eSAtIEczMB4XDTk5MTAwMTAwMDAwMFoXDTM2MDcxNjIzNTk1OVowgcoxCzAJBgNV
384
+ BAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjEfMB0GA1UECxMWVmVyaVNp
385
+ Z24gVHJ1c3QgTmV0d29yazE6MDgGA1UECxMxKGMpIDE5OTkgVmVyaVNpZ24sIElu
386
+ Yy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTFFMEMGA1UEAxM8VmVyaVNpZ24g
387
+ Q2xhc3MgMiBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAt
388
+ IEczMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArwoNwtUs22e5LeWU
389
+ J92lvuCwTY+zYVY81nzD9M0+hsuiiOLh2KRpxbXiv8GmR1BeRjmL1Za6tW8UvxDO
390
+ JxOeBUebMXoT2B/Z0wI3i60sR/COgQanDTAM6/c8DyAd3HJG7qUCyFvDyVZpTMUY
391
+ wZF7C9UTAJu878NIPkZgIIUq1ZC2zYugzDLdt/1AVbJQHFauzI13TccgTacxdu9o
392
+ koqQHgiBVrKtaaNS0MscxCM9H5n+TOgWY47GCI72MfbS+uV23bUckqNJzc0BzWjN
393
+ qWm6o+sdDZykIKbBoMXRRkwXbdKsZj+WjOCE1Db/IlnF+RFgqF8EffIa9iVCYQ/E
394
+ Srg+iQIDAQABMA0GCSqGSIb3DQEBBQUAA4IBAQA0JhU8wI1NQ0kdvekhktdmnLfe
395
+ xbjQ5F1fdiLAJvmEOjr5jLX77GDx6M4EsMjdpwOPMPOY36TmpDHf0xwLRtxyID+u
396
+ 7gU8pDM/CzmscHhzS5kr3zDCVLCoO1Wh/hYozUK9dG6A2ydEp85EXdQbkJgNHkKU
397
+ sQAsBNB0owIFImNjzYO1+8FtYmtpdf1dcEG59b98377BMnMiIYtYgXsVkXq642RI
398
+ sH/7NiXaldDxJBQX3RiAa0YjOVT1jmIJBB2UkKab5iXiQkWquJCtvgiPqQtCGJTP
399
+ cjnhsUPgKM+351psE2tJs//jGHyJizNdrDPXp/naOlXJWBD5qu9ats9LS98q
400
+ -----END CERTIFICATE-----
401
+
402
+ Verisign Class 3 Public Primary Certification Authority - G3
403
+ ============================================================
404
+
405
+ -----BEGIN CERTIFICATE-----
406
+ MIIEGjCCAwICEQCbfgZJoz5iudXukEhxKe9XMA0GCSqGSIb3DQEBBQUAMIHKMQsw
407
+ CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZl
408
+ cmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWdu
409
+ LCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlT
410
+ aWduIENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3Jp
411
+ dHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQswCQYD
412
+ VQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlT
413
+ aWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJ
414
+ bmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWdu
415
+ IENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg
416
+ LSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMu6nFL8eB8aHm8b
417
+ N3O9+MlrlBIwT/A2R/XQkQr1F8ilYcEWQE37imGQ5XYgwREGfassbqb1EUGO+i2t
418
+ KmFZpGcmTNDovFJbcCAEWNF6yaRpvIMXZK0Fi7zQWM6NjPXr8EJJC52XJ2cybuGu
419
+ kxUccLwgTS8Y3pKI6GyFVxEa6X7jJhFUokWWVYPKMIno3Nij7SqAP395ZVc+FSBm
420
+ CC+Vk7+qRy+oRpfwEuL+wgorUeZ25rdGt+INpsyow0xZVYnm6FNcHOqd8GIWC6fJ
421
+ Xwzw3sJ2zq/3avL6QaaiMxTJ5Xpj055iN9WFZZ4O5lMkdBteHRJTW8cs54NJOxWu
422
+ imi5V5cCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAERSWwauSCPc/L8my/uRan2Te
423
+ 2yFPhpk0djZX3dAVL8WtfxUfN2JzPtTnX84XA9s1+ivbrmAJXx5fj267Cz3qWhMe
424
+ DGBvtcC1IyIuBwvLqXTLR7sdwdela8wv0kL9Sd2nic9TutoAWii/gt/4uhMdUIaC
425
+ /Y4wjylGsB49Ndo4YhYYSq3mtlFs3q9i6wHQHiT+eo8SGhJouPtmmRQURVyu565p
426
+ F4ErWjfJXir0xuKhXFSbplQAz/DxwceYMBo7Nhbbo27q/a2ywtrvAkcTisDxszGt
427
+ TxzhT5yvDwyd93gN2PQ1VoDat20Xj50egWTh/sVFuq1ruQp6Tk9LhO5L8X3dEQ==
428
+ -----END CERTIFICATE-----
429
+
430
+ Verisign Class 4 Public Primary Certification Authority - G3
431
+ ============================================================
432
+
433
+ -----BEGIN CERTIFICATE-----
434
+ MIIEGjCCAwICEQDsoKeLbnVqAc/EfMwvlF7XMA0GCSqGSIb3DQEBBQUAMIHKMQsw
435
+ CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZl
436
+ cmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWdu
437
+ LCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlT
438
+ aWduIENsYXNzIDQgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3Jp
439
+ dHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQswCQYD
440
+ VQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlT
441
+ aWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJ
442
+ bmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWdu
443
+ IENsYXNzIDQgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg
444
+ LSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAK3LpRFpxlmr8Y+1
445
+ GQ9Wzsy1HyDkniYlS+BzZYlZ3tCD5PUPtbut8XzoIfzk6AzufEUiGXaStBO3IFsJ
446
+ +mGuqPKljYXCKtbeZjbSmwL0qJJgfJxptI8kHtCGUvYynEFYHiK9zUVilQhu0Gbd
447
+ U6LM8BDcVHOLBKFGMzNcF0C5nk3T875Vg+ixiY5afJqWIpA7iCXy0lOIAgwLePLm
448
+ NxdLMEYH5IBtptiWLugs+BGzOA1mppvqySNb247i8xOOGlktqgLw7KSHZtzBP/XY
449
+ ufTsgsbSPZUd5cBPhMnZo0QoBmrXRazwa2rvTl/4EYIeOGM0ZlDUPpNz+jDDZq3/
450
+ ky2X7wMCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAj/ola09b5KROJ1WrIhVZPMq1
451
+ CtRK26vdoV9TxaBXOcLORyu+OshWv8LZJxA6sQU8wHcxuzrTBXttmhwwjIDLk5Mq
452
+ g6sFUYICABFna/OIYUdfA5PVWw3g8dShMjWFsjrbsIKr0csKvE+MW8VLADsfKoKm
453
+ fjaF3H48ZwC15DtS4KjrXRX5xm3wrR0OhbepmnMUWluPQSjA1egtTaRezarZ7c7c
454
+ 2NU8Qh0XwRJdRTjDOPP8hS6DRkiy1yBfkjaP53kPmF6Z6PDQpLv1U70qzlmwr25/
455
+ bLvSHgCwIe34QWKCudiyxLtGUPMxxY8BqHTr9Xgn2uf3ZkPznoM+IKrDNWCRzg==
456
+ -----END CERTIFICATE-----
457
+
458
+ Equifax Secure Global eBusiness CA
459
+ ==================================
460
+
461
+ -----BEGIN CERTIFICATE-----
462
+ MIICkDCCAfmgAwIBAgIBATANBgkqhkiG9w0BAQQFADBaMQswCQYDVQQGEwJVUzEc
463
+ MBoGA1UEChMTRXF1aWZheCBTZWN1cmUgSW5jLjEtMCsGA1UEAxMkRXF1aWZheCBT
464
+ ZWN1cmUgR2xvYmFsIGVCdXNpbmVzcyBDQS0xMB4XDTk5MDYyMTA0MDAwMFoXDTIw
465
+ MDYyMTA0MDAwMFowWjELMAkGA1UEBhMCVVMxHDAaBgNVBAoTE0VxdWlmYXggU2Vj
466
+ dXJlIEluYy4xLTArBgNVBAMTJEVxdWlmYXggU2VjdXJlIEdsb2JhbCBlQnVzaW5l
467
+ c3MgQ0EtMTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAuucXkAJlsTRVPEnC
468
+ UdXfp9E3j9HngXNBUmCbnaEXJnitx7HoJpQytd4zjTov2/KaelpzmKNc6fuKcxtc
469
+ 58O/gGzNqfTWK8D3+ZmqY6KxRwIP1ORROhI8bIpaVIRw28HFkM9yRcuoWcDNM50/
470
+ o5brhTMhHD4ePmBudpxnhcXIw2ECAwEAAaNmMGQwEQYJYIZIAYb4QgEBBAQDAgAH
471
+ MA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUvqigdHJQa0S3ySPY+6j/s1dr
472
+ aGwwHQYDVR0OBBYEFL6ooHRyUGtEt8kj2Puo/7NXa2hsMA0GCSqGSIb3DQEBBAUA
473
+ A4GBADDiAVGqx+pf2rnQZQ8w1j7aDRRJbpGTJxQx78T3LUX47Me/okENI7SS+RkA
474
+ Z70Br83gcfxaz2TE4JaY0KNA4gGK7ycH8WUBikQtBmV1UsCGECAhX2xrD2yuCRyv
475
+ 8qIYNMR1pHMc8Y3c7635s3a0kr/clRAevsvIO1qEYBlWlKlV
476
+ -----END CERTIFICATE-----
477
+
478
+ Equifax Secure eBusiness CA 1
479
+ =============================
480
+
481
+ -----BEGIN CERTIFICATE-----
482
+ MIICgjCCAeugAwIBAgIBBDANBgkqhkiG9w0BAQQFADBTMQswCQYDVQQGEwJVUzEc
483
+ MBoGA1UEChMTRXF1aWZheCBTZWN1cmUgSW5jLjEmMCQGA1UEAxMdRXF1aWZheCBT
484
+ ZWN1cmUgZUJ1c2luZXNzIENBLTEwHhcNOTkwNjIxMDQwMDAwWhcNMjAwNjIxMDQw
485
+ MDAwWjBTMQswCQYDVQQGEwJVUzEcMBoGA1UEChMTRXF1aWZheCBTZWN1cmUgSW5j
486
+ LjEmMCQGA1UEAxMdRXF1aWZheCBTZWN1cmUgZUJ1c2luZXNzIENBLTEwgZ8wDQYJ
487
+ KoZIhvcNAQEBBQADgY0AMIGJAoGBAM4vGbwXt3fek6lfWg0XTzQaDJj0ItlZ1MRo
488
+ RvC0NcWFAyDGr0WlIVFFQesWWDYyb+JQYmT5/VGcqiTZ9J2DKocKIdMSODRsjQBu
489
+ WqDZQu4aIZX5UkxVWsUPOE9G+m34LjXWHXzr4vCwdYDIqROsvojvOm6rXyo4YgKw
490
+ Env+j6YDAgMBAAGjZjBkMBEGCWCGSAGG+EIBAQQEAwIABzAPBgNVHRMBAf8EBTAD
491
+ AQH/MB8GA1UdIwQYMBaAFEp4MlIR21kWNl7fwRQ2QGpHfEyhMB0GA1UdDgQWBBRK
492
+ eDJSEdtZFjZe38EUNkBqR3xMoTANBgkqhkiG9w0BAQQFAAOBgQB1W6ibAxHm6VZM
493
+ zfmpTMANmvPMZWnmJXbMWbfWVMMdzZmsGd20hdXgPfxiIKeES1hl8eL5lSE/9dR+
494
+ WB5Hh1Q+WKG1tfgq73HnvMP2sUlG4tega+VWeponmHxGYhTnyfxuAxJ5gDgdSIKN
495
+ /Bf+KpYrtWKmpj29f5JZzVoqgrI3eQ==
496
+ -----END CERTIFICATE-----
497
+
498
+ Equifax Secure eBusiness CA 2
499
+ =============================
500
+
501
+ -----BEGIN CERTIFICATE-----
502
+ MIIDIDCCAomgAwIBAgIEN3DPtTANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQGEwJV
503
+ UzEXMBUGA1UEChMORXF1aWZheCBTZWN1cmUxJjAkBgNVBAsTHUVxdWlmYXggU2Vj
504
+ dXJlIGVCdXNpbmVzcyBDQS0yMB4XDTk5MDYyMzEyMTQ0NVoXDTE5MDYyMzEyMTQ0
505
+ NVowTjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkVxdWlmYXggU2VjdXJlMSYwJAYD
506
+ VQQLEx1FcXVpZmF4IFNlY3VyZSBlQnVzaW5lc3MgQ0EtMjCBnzANBgkqhkiG9w0B
507
+ AQEFAAOBjQAwgYkCgYEA5Dk5kx5SBhsoNviyoynF7Y6yEb3+6+e0dMKP/wXn2Z0G
508
+ vxLIPw7y1tEkshHe0XMJitSxLJgJDR5QRrKDpkWNYmi7hRsgcDKqQM2mll/EcTc/
509
+ BPO3QSQ5BxoeLmFYoBIL5aXfxavqN3HMHMg3OrmXUqesxWoklE6ce8/AatbfIb0C
510
+ AwEAAaOCAQkwggEFMHAGA1UdHwRpMGcwZaBjoGGkXzBdMQswCQYDVQQGEwJVUzEX
511
+ MBUGA1UEChMORXF1aWZheCBTZWN1cmUxJjAkBgNVBAsTHUVxdWlmYXggU2VjdXJl
512
+ IGVCdXNpbmVzcyBDQS0yMQ0wCwYDVQQDEwRDUkwxMBoGA1UdEAQTMBGBDzIwMTkw
513
+ NjIzMTIxNDQ1WjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUUJ4L6q9euSBIplBq
514
+ y/3YIHqngnYwHQYDVR0OBBYEFFCeC+qvXrkgSKZQasv92CB6p4J2MAwGA1UdEwQF
515
+ MAMBAf8wGgYJKoZIhvZ9B0EABA0wCxsFVjMuMGMDAgbAMA0GCSqGSIb3DQEBBQUA
516
+ A4GBAAyGgq3oThr1jokn4jVYPSm0B482UJW/bsGe68SQsoWou7dC4A8HOd/7npCy
517
+ 0cE+U58DRLB+S/Rv5Hwf5+Kx5Lia78O9zt4LMjTZ3ijtM2vE1Nc9ElirfQkty3D1
518
+ E4qUoSek1nDFbZS1yX2doNLGCEnZZpum0/QL3MUmV+GRMOrN
519
+ -----END CERTIFICATE-----
520
+
521
+ Thawte Time Stamping CA
522
+ =======================
523
+
524
+ -----BEGIN CERTIFICATE-----
525
+ MIICoTCCAgqgAwIBAgIBADANBgkqhkiG9w0BAQQFADCBizELMAkGA1UEBhMCWkEx
526
+ FTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTEUMBIGA1UEBxMLRHVyYmFudmlsbGUxDzAN
527
+ BgNVBAoTBlRoYXd0ZTEdMBsGA1UECxMUVGhhd3RlIENlcnRpZmljYXRpb24xHzAd
528
+ BgNVBAMTFlRoYXd0ZSBUaW1lc3RhbXBpbmcgQ0EwHhcNOTcwMTAxMDAwMDAwWhcN
529
+ MjAxMjMxMjM1OTU5WjCBizELMAkGA1UEBhMCWkExFTATBgNVBAgTDFdlc3Rlcm4g
530
+ Q2FwZTEUMBIGA1UEBxMLRHVyYmFudmlsbGUxDzANBgNVBAoTBlRoYXd0ZTEdMBsG
531
+ A1UECxMUVGhhd3RlIENlcnRpZmljYXRpb24xHzAdBgNVBAMTFlRoYXd0ZSBUaW1l
532
+ c3RhbXBpbmcgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANYrWHhhRYZT
533
+ 6jR7UZztsOYuGA7+4F+oJ9O0yeB8WU4WDnNUYMF/9p8u6TqFJBU820cEY8OexJQa
534
+ Wt9MevPZQx08EHp5JduQ/vBR5zDWQQD9nyjfeb6Uu522FOMjhdepQeBMpHmwKxqL
535
+ 8vg7ij5FrHGSALSQQZj7X+36ty6K+Ig3AgMBAAGjEzARMA8GA1UdEwEB/wQFMAMB
536
+ Af8wDQYJKoZIhvcNAQEEBQADgYEAZ9viwuaHPUCDhjc1fR/OmsMMZiCouqoEiYbC
537
+ 9RAIDb/LogWK0E02PvTX72nGXuSwlG9KuefeW4i2e9vjJ+V2w/A1wcu1J5szedyQ
538
+ pgCed/r8zSeUQhac0xxo7L9c3eWpexAKMnRUEzGLhQOEkbdYATAUOK8oyvyxUBkZ
539
+ CayJSdM=
540
+ -----END CERTIFICATE-----
541
+
542
+ thawte Primary Root CA
543
+ ======================
544
+
545
+ -----BEGIN CERTIFICATE-----
546
+ MIIEIDCCAwigAwIBAgIQNE7VVyDV7exJ9C/ON9srbTANBgkqhkiG9w0BAQUFADCB
547
+ qTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMf
548
+ Q2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIw
549
+ MDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxHzAdBgNV
550
+ BAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwHhcNMDYxMTE3MDAwMDAwWhcNMzYw
551
+ NzE2MjM1OTU5WjCBqTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5j
552
+ LjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYG
553
+ A1UECxMvKGMpIDIwMDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl
554
+ IG9ubHkxHzAdBgNVBAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwggEiMA0GCSqG
555
+ SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCsoPD7gFnUnMekz52hWXMJEEUMDSxuaPFs
556
+ W0hoSVk3/AszGcJ3f8wQLZU0HObrTQmnHNK4yZc2AreJ1CRfBsDMRJSUjQJib+ta
557
+ 3RGNKJpchJAQeg29dGYvajig4tVUROsdB58Hum/u6f1OCyn1PoSgAfGcq/gcfomk
558
+ 6KHYcWUNo1F77rzSImANuVud37r8UVsLr5iy6S7pBOhih94ryNdOwUxkHt3Ph1i6
559
+ Sk/KaAcdHJ1KxtUvkcx8cXIcxcBn6zL9yZJclNqFwJu/U30rCfSMnZEfl2pSy94J
560
+ NqR32HuHUETVPm4pafs5SSYeCaWAe0At6+gnhcn+Yf1+5nyXHdWdAgMBAAGjQjBA
561
+ MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBR7W0XP
562
+ r87Lev0xkhpqtvNG61dIUDANBgkqhkiG9w0BAQUFAAOCAQEAeRHAS7ORtvzw6WfU
563
+ DW5FvlXok9LOAz/t2iWwHVfLHjp2oEzsUHboZHIMpKnxuIvW1oeEuzLlQRHAd9mz
564
+ YJ3rG9XRbkREqaYB7FViHXe4XI5ISXycO1cRrK1zN44veFyQaEfZYGDm/Ac9IiAX
565
+ xPcW6cTYcvnIc3zfFi8VqT79aie2oetaupgf1eNNZAqdE8hhuvU5HIe6uL17In/2
566
+ /qxAeeWsEG89jxt5dovEN7MhGITlNgDrYyCZuen+MwS7QcjBAvlEYyCegc5C09Y/
567
+ LHbTY5xZ3Y+m4Q6gLkH3LpVHz7z9M/P2C2F+fpErgUfCJzDupxBdN49cOSvkBPB7
568
+ jVaMaA==
569
+ -----END CERTIFICATE-----
570
+
571
+ VeriSign Class 3 Public Primary Certification Authority - G5
572
+ ============================================================
573
+
574
+ -----BEGIN CERTIFICATE-----
575
+ MIIE0zCCA7ugAwIBAgIQGNrRniZ96LtKIVjNzGs7SjANBgkqhkiG9w0BAQUFADCB
576
+ yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
577
+ ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJp
578
+ U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxW
579
+ ZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0
580
+ aG9yaXR5IC0gRzUwHhcNMDYxMTA4MDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCByjEL
581
+ MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZW
582
+ ZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2ln
583
+ biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJp
584
+ U2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9y
585
+ aXR5IC0gRzUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvJAgIKXo1
586
+ nmAMqudLO07cfLw8RRy7K+D+KQL5VwijZIUVJ/XxrcgxiV0i6CqqpkKzj/i5Vbex
587
+ t0uz/o9+B1fs70PbZmIVYc9gDaTY3vjgw2IIPVQT60nKWVSFJuUrjxuf6/WhkcIz
588
+ SdhDY2pSS9KP6HBRTdGJaXvHcPaz3BJ023tdS1bTlr8Vd6Gw9KIl8q8ckmcY5fQG
589
+ BO+QueQA5N06tRn/Arr0PO7gi+s3i+z016zy9vA9r911kTMZHRxAy3QkGSGT2RT+
590
+ rCpSx4/VBEnkjWNHiDxpg8v+R70rfk/Fla4OndTRQ8Bnc+MUCH7lP59zuDMKz10/
591
+ NIeWiu5T6CUVAgMBAAGjgbIwga8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8E
592
+ BAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2UvZ2lmMCEwHzAH
593
+ BgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVy
594
+ aXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFH/TZafC3ey78DAJ80M5+gKv
595
+ MzEzMA0GCSqGSIb3DQEBBQUAA4IBAQCTJEowX2LP2BqYLz3q3JktvXf2pXkiOOzE
596
+ p6B4Eq1iDkVwZMXnl2YtmAl+X6/WzChl8gGqCBpH3vn5fJJaCGkgDdk+bW48DW7Y
597
+ 5gaRQBi5+MHt39tBquCWIMnNZBU4gcmU7qKEKQsTb47bDN0lAtukixlE0kF6BWlK
598
+ WE9gyn6CagsCqiUXObXbf+eEZSqVir2G3l6BFoMtEMze/aiCKm0oHw0LxOXnGiYZ
599
+ 4fQRbxC1lfznQgUy286dUV4otp6F01vvpX1FQHKOtw5rDgb7MzVIcbidJ4vEZV8N
600
+ hnacRHr2lVz2XTIIM6RUthg/aFzyQkqFOFSDX9HoLPKsEdao7WNq
601
+ -----END CERTIFICATE-----
602
+
603
+ Entrust.net Secure Server Certification Authority
604
+ =================================================
605
+
606
+ -----BEGIN CERTIFICATE-----
607
+ MIIE2DCCBEGgAwIBAgIEN0rSQzANBgkqhkiG9w0BAQUFADCBwzELMAkGA1UEBhMC
608
+ VVMxFDASBgNVBAoTC0VudHJ1c3QubmV0MTswOQYDVQQLEzJ3d3cuZW50cnVzdC5u
609
+ ZXQvQ1BTIGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTElMCMGA1UECxMc
610
+ KGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDE6MDgGA1UEAxMxRW50cnVzdC5u
611
+ ZXQgU2VjdXJlIFNlcnZlciBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw05OTA1
612
+ MjUxNjA5NDBaFw0xOTA1MjUxNjM5NDBaMIHDMQswCQYDVQQGEwJVUzEUMBIGA1UE
613
+ ChMLRW50cnVzdC5uZXQxOzA5BgNVBAsTMnd3dy5lbnRydXN0Lm5ldC9DUFMgaW5j
614
+ b3JwLiBieSByZWYuIChsaW1pdHMgbGlhYi4pMSUwIwYDVQQLExwoYykgMTk5OSBF
615
+ bnRydXN0Lm5ldCBMaW1pdGVkMTowOAYDVQQDEzFFbnRydXN0Lm5ldCBTZWN1cmUg
616
+ U2VydmVyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGdMA0GCSqGSIb3DQEBAQUA
617
+ A4GLADCBhwKBgQDNKIM0VBuJ8w+vN5Ex/68xYMmo6LIQaO2f55M28Qpku0f1BBc/
618
+ I0dNxScZgSYMVHINiC3ZH5oSn7yzcdOAGT9HZnuMNSjSuQrfJNqc1lB5gXpa0zf3
619
+ wkrYKZImZNHkmGw6AIr1NJtl+O3jEP/9uElY3KDegjlrgbEWGWG5VLbmQwIBA6OC
620
+ AdcwggHTMBEGCWCGSAGG+EIBAQQEAwIABzCCARkGA1UdHwSCARAwggEMMIHeoIHb
621
+ oIHYpIHVMIHSMQswCQYDVQQGEwJVUzEUMBIGA1UEChMLRW50cnVzdC5uZXQxOzA5
622
+ BgNVBAsTMnd3dy5lbnRydXN0Lm5ldC9DUFMgaW5jb3JwLiBieSByZWYuIChsaW1p
623
+ dHMgbGlhYi4pMSUwIwYDVQQLExwoYykgMTk5OSBFbnRydXN0Lm5ldCBMaW1pdGVk
624
+ MTowOAYDVQQDEzFFbnRydXN0Lm5ldCBTZWN1cmUgU2VydmVyIENlcnRpZmljYXRp
625
+ b24gQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMCmgJ6AlhiNodHRwOi8vd3d3LmVu
626
+ dHJ1c3QubmV0L0NSTC9uZXQxLmNybDArBgNVHRAEJDAigA8xOTk5MDUyNTE2MDk0
627
+ MFqBDzIwMTkwNTI1MTYwOTQwWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAU8Bdi
628
+ E1U9s/8KAGv7UISX8+1i0BowHQYDVR0OBBYEFPAXYhNVPbP/CgBr+1CEl/PtYtAa
629
+ MAwGA1UdEwQFMAMBAf8wGQYJKoZIhvZ9B0EABAwwChsEVjQuMAMCBJAwDQYJKoZI
630
+ hvcNAQEFBQADgYEAkNwwAvpkdMKnCqV8IY00F6j7Rw7/JXyNEwr75Ji174z4xRAN
631
+ 95K+8cPV1ZVqBLssziY2ZcgxxufuP+NXdYR6Ee9GTxj005i7qIcyunL2POI9n9cd
632
+ 2cNgQ4xYDiKWL2KjLB+6rQXvqzJ4h6BUcxm1XAX5Uj5tLUUL9wqT6u0G+bI=
633
+ -----END CERTIFICATE-----
634
+
635
+ Go Daddy Certification Authority Root Certificate Bundle
636
+ ========================================================
637
+
638
+ -----BEGIN CERTIFICATE-----
639
+ MIIE3jCCA8agAwIBAgICAwEwDQYJKoZIhvcNAQEFBQAwYzELMAkGA1UEBhMCVVMx
640
+ ITAfBgNVBAoTGFRoZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28g
641
+ RGFkZHkgQ2xhc3MgMiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjExMTYw
642
+ MTU0MzdaFw0yNjExMTYwMTU0MzdaMIHKMQswCQYDVQQGEwJVUzEQMA4GA1UECBMH
643
+ QXJpem9uYTETMBEGA1UEBxMKU2NvdHRzZGFsZTEaMBgGA1UEChMRR29EYWRkeS5j
644
+ b20sIEluYy4xMzAxBgNVBAsTKmh0dHA6Ly9jZXJ0aWZpY2F0ZXMuZ29kYWRkeS5j
645
+ b20vcmVwb3NpdG9yeTEwMC4GA1UEAxMnR28gRGFkZHkgU2VjdXJlIENlcnRpZmlj
646
+ YXRpb24gQXV0aG9yaXR5MREwDwYDVQQFEwgwNzk2OTI4NzCCASIwDQYJKoZIhvcN
647
+ AQEBBQADggEPADCCAQoCggEBAMQt1RWMnCZM7DI161+4WQFapmGBWTtwY6vj3D3H
648
+ KrjJM9N55DrtPDAjhI6zMBS2sofDPZVUBJ7fmd0LJR4h3mUpfjWoqVTr9vcyOdQm
649
+ VZWt7/v+WIbXnvQAjYwqDL1CBM6nPwT27oDyqu9SoWlm2r4arV3aLGbqGmu75RpR
650
+ SgAvSMeYddi5Kcju+GZtCpyz8/x4fKL4o/K1w/O5epHBp+YlLpyo7RJlbmr2EkRT
651
+ cDCVw5wrWCs9CHRK8r5RsL+H0EwnWGu1NcWdrxcx+AuP7q2BNgWJCJjPOq8lh8BJ
652
+ 6qf9Z/dFjpfMFDniNoW1fho3/Rb2cRGadDAW/hOUoz+EDU8CAwEAAaOCATIwggEu
653
+ MB0GA1UdDgQWBBT9rGEyk2xF1uLuhV+auud2mWjM5zAfBgNVHSMEGDAWgBTSxLDS
654
+ kdRMEXGzYcs9of7dqGrU4zASBgNVHRMBAf8ECDAGAQH/AgEAMDMGCCsGAQUFBwEB
655
+ BCcwJTAjBggrBgEFBQcwAYYXaHR0cDovL29jc3AuZ29kYWRkeS5jb20wRgYDVR0f
656
+ BD8wPTA7oDmgN4Y1aHR0cDovL2NlcnRpZmljYXRlcy5nb2RhZGR5LmNvbS9yZXBv
657
+ c2l0b3J5L2dkcm9vdC5jcmwwSwYDVR0gBEQwQjBABgRVHSAAMDgwNgYIKwYBBQUH
658
+ AgEWKmh0dHA6Ly9jZXJ0aWZpY2F0ZXMuZ29kYWRkeS5jb20vcmVwb3NpdG9yeTAO
659
+ BgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQEFBQADggEBANKGwOy9+aG2Z+5mC6IG
660
+ OgRQjhVyrEp0lVPLN8tESe8HkGsz2ZbwlFalEzAFPIUyIXvJxwqoJKSQ3kbTJSMU
661
+ A2fCENZvD117esyfxVgqwcSeIaha86ykRvOe5GPLL5CkKSkB2XIsKd83ASe8T+5o
662
+ 0yGPwLPk9Qnt0hCqU7S+8MxZC9Y7lhyVJEnfzuz9p0iRFEUOOjZv2kWzRaJBydTX
663
+ RE4+uXR21aITVSzGh6O1mawGhId/dQb8vxRMDsxuxN89txJx9OjxUUAiKEngHUuH
664
+ qDTMBqLdElrRhjZkAzVvb3du6/KFUJheqwNTrZEjYx8WnM25sgVjOuH0aBsXBTWV
665
+ U+4=
666
+ -----END CERTIFICATE-----
667
+ -----BEGIN CERTIFICATE-----
668
+ MIIE+zCCBGSgAwIBAgICAQ0wDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1Zh
669
+ bGlDZXJ0IFZhbGlkYXRpb24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIElu
670
+ Yy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENsYXNzIDIgUG9saWN5IFZhbGlkYXRpb24g
671
+ QXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAe
672
+ BgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTA0MDYyOTE3MDYyMFoX
673
+ DTI0MDYyOTE3MDYyMFowYzELMAkGA1UEBhMCVVMxITAfBgNVBAoTGFRoZSBHbyBE
674
+ YWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28gRGFkZHkgQ2xhc3MgMiBDZXJ0
675
+ aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQADggENADCCAQgC
676
+ ggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCAPVYYYwhv
677
+ 2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6wwdhFJ2+q
678
+ N1j3hybX2C32qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXiEqITLdiO
679
+ r18SPaAIBQi2XKVlOARFmR6jYGB0xUGlcmIbYsUfb18aQr4CUWWoriMYavx4A6lN
680
+ f4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmYvLEHZ6IVDd2gWMZEewo+YihfukEH
681
+ U1jPEX44dMX4/7VpkI+EdOqXG68CAQOjggHhMIIB3TAdBgNVHQ4EFgQU0sSw0pHU
682
+ TBFxs2HLPaH+3ahq1OMwgdIGA1UdIwSByjCBx6GBwaSBvjCBuzEkMCIGA1UEBxMb
683
+ VmFsaUNlcnQgVmFsaWRhdGlvbiBOZXR3b3JrMRcwFQYDVQQKEw5WYWxpQ2VydCwg
684
+ SW5jLjE1MDMGA1UECxMsVmFsaUNlcnQgQ2xhc3MgMiBQb2xpY3kgVmFsaWRhdGlv
685
+ biBBdXRob3JpdHkxITAfBgNVBAMTGGh0dHA6Ly93d3cudmFsaWNlcnQuY29tLzEg
686
+ MB4GCSqGSIb3DQEJARYRaW5mb0B2YWxpY2VydC5jb22CAQEwDwYDVR0TAQH/BAUw
687
+ AwEB/zAzBggrBgEFBQcBAQQnMCUwIwYIKwYBBQUHMAGGF2h0dHA6Ly9vY3NwLmdv
688
+ ZGFkZHkuY29tMEQGA1UdHwQ9MDswOaA3oDWGM2h0dHA6Ly9jZXJ0aWZpY2F0ZXMu
689
+ Z29kYWRkeS5jb20vcmVwb3NpdG9yeS9yb290LmNybDBLBgNVHSAERDBCMEAGBFUd
690
+ IAAwODA2BggrBgEFBQcCARYqaHR0cDovL2NlcnRpZmljYXRlcy5nb2RhZGR5LmNv
691
+ bS9yZXBvc2l0b3J5MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOBgQC1
692
+ QPmnHfbq/qQaQlpE9xXUhUaJwL6e4+PrxeNYiY+Sn1eocSxI0YGyeR+sBjUZsE4O
693
+ WBsUs5iB0QQeyAfJg594RAoYC5jcdnplDQ1tgMQLARzLrUc+cb53S8wGd9D0Vmsf
694
+ SxOaFIqII6hR8INMqzW/Rn453HWkrugp++85j09VZw==
695
+ -----END CERTIFICATE-----
696
+ -----BEGIN CERTIFICATE-----
697
+ MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0
698
+ IFZhbGlkYXRpb24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAz
699
+ BgNVBAsTLFZhbGlDZXJ0IENsYXNzIDIgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9y
700
+ aXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG
701
+ 9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYyNjAwMTk1NFoXDTE5MDYy
702
+ NjAwMTk1NFowgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0d29y
703
+ azEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENs
704
+ YXNzIDIgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRw
705
+ Oi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNl
706
+ cnQuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDOOnHK5avIWZJV16vY
707
+ dA757tn2VUdZZUcOBVXc65g2PFxTXdMwzzjsvUGJ7SVCCSRrCl6zfN1SLUzm1NZ9
708
+ WlmpZdRJEy0kTRxQb7XBhVQ7/nHk01xC+YDgkRoKWzk2Z/M/VXwbP7RfZHM047QS
709
+ v4dk+NoS/zcnwbNDu+97bi5p9wIDAQABMA0GCSqGSIb3DQEBBQUAA4GBADt/UG9v
710
+ UJSZSWI4OB9L+KXIPqeCgfYrx+jFzug6EILLGACOTb2oWH+heQC1u+mNr0HZDzTu
711
+ IYEZoDJJKPTEjlbVUjP9UNV+mWwD5MlM/Mtsq2azSiGM5bUMMj4QssxsodyamEwC
712
+ W/POuZ6lcg5Ktz885hZo+L7tdEy8W9ViH0Pd
713
+ -----END CERTIFICATE-----
714
+
google-api-php-client/src/service/Google_BatchRequest.php ADDED
@@ -0,0 +1,110 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * Copyright 2012 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
+ * @author Chirag Shah <chirags@google.com>
20
+ */
21
+ class Google_BatchRequest {
22
+ /** @var string Multipart Boundary. */
23
+ private $boundary;
24
+
25
+ /** @var array service requests to be executed. */
26
+ private $requests = array();
27
+
28
+ public function __construct($boundary = false) {
29
+ $boundary = (false == $boundary) ? mt_rand() : $boundary;
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
+ }
37
+
38
+ $this->requests[$key] = $request;
39
+ }
40
+
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";
48
+ }
49
+
50
+ $body = rtrim($body);
51
+ $body .= "\n--{$this->boundary}--";
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;
70
+ foreach($contentType as $part) {
71
+ $part = (explode('=', $part, 2));
72
+ if (isset($part[0]) && 'boundary' == trim($part[0])) {
73
+ $boundary = $part[1];
74
+ }
75
+ }
76
+
77
+ $body = $response->getResponseBody();
78
+ if ($body) {
79
+ $body = str_replace("--$boundary--", "--$boundary", $body);
80
+ $parts = explode("--$boundary", $body);
81
+ $responses = array();
82
+
83
+ foreach($parts as $part) {
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;
102
+ }
103
+ }
104
+
105
+ return $responses;
106
+ }
107
+
108
+ return null;
109
+ }
110
+ }
google-api-php-client/src/service/Google_MediaFileUpload.php ADDED
@@ -0,0 +1,244 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright 2012 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
+ * @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';
26
+
27
+ /** @var string $mimeType */
28
+ public $mimeType;
29
+
30
+ /** @var string $data */
31
+ public $data;
32
+
33
+ /** @var bool $resumable */
34
+ public $resumable;
35
+
36
+ /** @var int $chunkSize */
37
+ public $chunkSize;
38
+
39
+ /** @var int $size */
40
+ public $size;
41
+
42
+ /** @var string $resumeUri */
43
+ public $resumeUri;
44
+
45
+ /** @var int $progress */
46
+ public $progress;
47
+
48
+ /**
49
+ * @param $mimeType string
50
+ * @param $data string The bytes you want to upload.
51
+ * @param $resumable bool
52
+ * @param bool $chunkSize File will be uploaded in chunks of this many bytes.
53
+ * only used if resumable=True
54
+ */
55
+ public function __construct($mimeType, $data, $resumable=false, $chunkSize=false) {
56
+ $this->mimeType = $mimeType;
57
+ $this->data = $data;
58
+ $this->size = strlen($this->data);
59
+ $this->resumable = $resumable;
60
+ if(!$chunkSize) {
61
+ $this->chunkSize = 256 * 1024;
62
+ }
63
+
64
+ $this->progress = 0;
65
+ }
66
+
67
+ /**
68
+ * @static
69
+ * @param $meta
70
+ * @param $params
71
+ * @return array|bool
72
+ */
73
+ public static function process($meta, &$params) {
74
+ $payload = array();
75
+ $meta = is_string($meta) ? json_decode($meta, true) : $meta;
76
+ $uploadType = self::getUploadType($meta, $payload, $params);
77
+ if (!$uploadType) {
78
+ // Process as a normal API request.
79
+ return false;
80
+ }
81
+
82
+ // Process as a media upload request.
83
+ $params['uploadType'] = array(
84
+ 'type' => 'string',
85
+ 'location' => 'query',
86
+ 'value' => $uploadType,
87
+ );
88
+
89
+ if (isset($params['file'])) {
90
+ // This is a standard file upload with curl.
91
+ $file = $params['file']['value'];
92
+ unset($params['file']);
93
+ return self::processFileUpload($file);
94
+ }
95
+
96
+ $mimeType = isset($params['mimeType'])
97
+ ? $params['mimeType']['value']
98
+ : false;
99
+ unset($params['mimeType']);
100
+
101
+ $data = isset($params['data'])
102
+ ? $params['data']['value']
103
+ : false;
104
+ unset($params['data']);
105
+
106
+ if (self::UPLOAD_RESUMABLE_TYPE == $uploadType) {
107
+ $payload['content-type'] = $mimeType;
108
+
109
+ } elseif (self::UPLOAD_MEDIA_TYPE == $uploadType) {
110
+ // This is a simple media upload.
111
+ $payload['content-type'] = $mimeType;
112
+ $payload['postBody'] = $data;
113
+ }
114
+
115
+ elseif (self::UPLOAD_MULTIPART_TYPE == $uploadType) {
116
+ // This is a multipart/related upload.
117
+ $boundary = isset($params['boundary']['value']) ? $params['boundary']['value'] : mt_rand();
118
+ $boundary = str_replace('"', '', $boundary);
119
+ $payload['content-type'] = 'multipart/related; boundary=' . $boundary;
120
+ $related = "--$boundary\r\n";
121
+ $related .= "Content-Type: application/json; charset=UTF-8\r\n";
122
+ $related .= "\r\n" . json_encode($meta) . "\r\n";
123
+ $related .= "--$boundary\r\n";
124
+ $related .= "Content-Type: $mimeType\r\n";
125
+ $related .= "Content-Transfer-Encoding: base64\r\n";
126
+ $related .= "\r\n" . base64_encode($data) . "\r\n";
127
+ $related .= "--$boundary--";
128
+ $payload['postBody'] = $related;
129
+ }
130
+
131
+ return $payload;
132
+ }
133
+
134
+ /**
135
+ * Process standard file uploads.
136
+ * @param $file
137
+ * @internal param $fileName
138
+ * @return array Inclues the processed file name.
139
+ * @visible For testing.
140
+ */
141
+ public static function processFileUpload($file) {
142
+ if (!$file) return array();
143
+ if (substr($file, 0, 1) != '@') {
144
+ $file = '@' . $file;
145
+ }
146
+
147
+ // This is a standard file upload with curl.
148
+ return array('postBody' => array('file' => $file));
149
+ }
150
+
151
+ /**
152
+ * Valid upload types:
153
+ * - resumable (UPLOAD_RESUMABLE_TYPE)
154
+ * - media (UPLOAD_MEDIA_TYPE)
155
+ * - multipart (UPLOAD_MULTIPART_TYPE)
156
+ * - none (false)
157
+ * @param $meta
158
+ * @param $payload
159
+ * @param $params
160
+ * @return bool|string
161
+ */
162
+ public static function getUploadType($meta, &$payload, &$params) {
163
+ if (isset($params['mediaUpload'])
164
+ && get_class($params['mediaUpload']['value']) == 'Google_MediaFileUpload') {
165
+ $upload = $params['mediaUpload']['value'];
166
+ unset($params['mediaUpload']);
167
+ $payload['content-type'] = $upload->mimeType;
168
+ if (isset($upload->resumable) && $upload->resumable) {
169
+ return self::UPLOAD_RESUMABLE_TYPE;
170
+ }
171
+ }
172
+
173
+ // Allow the developer to override the upload type.
174
+ if (isset($params['uploadType'])) {
175
+ return $params['uploadType']['value'];
176
+ }
177
+
178
+ $data = isset($params['data']['value'])
179
+ ? $params['data']['value'] : false;
180
+
181
+ if (false == $data && false == isset($params['file'])) {
182
+ // No upload data available.
183
+ return false;
184
+ }
185
+
186
+ if (isset($params['file'])) {
187
+ return self::UPLOAD_MEDIA_TYPE;
188
+ }
189
+
190
+ if (false == $meta) {
191
+ return self::UPLOAD_MEDIA_TYPE;
192
+ }
193
+
194
+ return self::UPLOAD_MULTIPART_TYPE;
195
+ }
196
+
197
+
198
+ public function nextChunk(Google_HttpRequest $req) {
199
+ if (false == $this->resumeUri) {
200
+ $this->resumeUri = $this->getResumeUri($req);
201
+ }
202
+
203
+ $data = substr($this->data, $this->progress, $this->chunkSize);
204
+ $lastBytePos = $this->progress + strlen($data) - 1;
205
+ $headers = array(
206
+ 'content-range' => "bytes $this->progress-$lastBytePos/$this->size",
207
+ 'content-type' => $req->getRequestHeader('content-type'),
208
+ 'content-length' => $this->chunkSize,
209
+ 'expect' => '',
210
+ );
211
+
212
+ $httpRequest = new Google_HttpRequest($this->resumeUri, 'PUT', $headers, $data);
213
+ $response = Google_Client::$io->authenticatedRequest($httpRequest);
214
+ $code = $response->getResponseHttpCode();
215
+ if (308 == $code) {
216
+ $range = explode('-', $response->getResponseHeader('range'));
217
+ $this->progress = $range[1] + 1;
218
+ return false;
219
+ } else {
220
+ return Google_REST::decodeHttpResponse($response);
221
+ }
222
+ }
223
+
224
+ private function getResumeUri(Google_HttpRequest $httpRequest) {
225
+ $result = null;
226
+ $body = $httpRequest->getPostBody();
227
+ if ($body) {
228
+ $httpRequest->setRequestHeaders(array(
229
+ 'content-type' => 'application/json; charset=UTF-8',
230
+ 'content-length' => Google_Utils::getStrLen($body),
231
+ 'x-upload-content-type' => $this->mimeType,
232
+ 'expect' => '',
233
+ ));
234
+ }
235
+
236
+ $response = Google_Client::$io->makeRequest($httpRequest);
237
+ $location = $response->getResponseHeader('location');
238
+ $code = $response->getResponseHttpCode();
239
+ if (200 == $code && true == $location) {
240
+ return $location;
241
+ }
242
+ throw new Google_Exception("Failed to start the resumable upload");
243
+ }
244
+ }
google-api-php-client/src/service/Google_Model.php ADDED
@@ -0,0 +1,115 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * Copyright 2011 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
+ * This class defines attributes, valid values, and usage which is generated from
20
+ * a given json schema. http://tools.ietf.org/html/draft-zyp-json-schema-03#section-5
21
+ *
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.
29
+ $array = func_get_arg(0);
30
+ $this->mapTypes($array);
31
+ }
32
+ }
33
+
34
+ /**
35
+ * Initialize this object's properties from an array.
36
+ *
37
+ * @param array $array Used to seed this object's properties.
38
+ * @return void
39
+ */
40
+ protected function mapTypes($array) {
41
+ foreach ($array as $key => $val) {
42
+ $this->$key = $val;
43
+
44
+ $keyTypeName = "__$key" . 'Type';
45
+ $keyDataType = "__$key" . 'DataType';
46
+ if ($this->useObjects() && property_exists($this, $keyTypeName)) {
47
+ if ($this->isAssociativeArray($val)) {
48
+ if (isset($this->$keyDataType) && 'map' == $this->$keyDataType) {
49
+ foreach($val as $arrayKey => $arrayItem) {
50
+ $val[$arrayKey] = $this->createObjectFromName($keyTypeName, $arrayItem);
51
+ }
52
+ $this->$key = $val;
53
+ } else {
54
+ $this->$key = $this->createObjectFromName($keyTypeName, $val);
55
+ }
56
+ } else if (is_array($val)) {
57
+ $arrayObject = array();
58
+ foreach ($val as $arrayIndex => $arrayItem) {
59
+ $arrayObject[$arrayIndex] = $this->createObjectFromName($keyTypeName, $arrayItem);
60
+ }
61
+ $this->$key = $arrayObject;
62
+ }
63
+ }
64
+ }
65
+ }
66
+
67
+ /**
68
+ * Returns true only if the array is associative.
69
+ * @param array $array
70
+ * @return bool True if the array is associative.
71
+ */
72
+ protected function isAssociativeArray($array) {
73
+ if (!is_array($array)) {
74
+ return false;
75
+ }
76
+ $keys = array_keys($array);
77
+ foreach($keys as $key) {
78
+ if (is_string($key)) {
79
+ return true;
80
+ }
81
+ }
82
+ return false;
83
+ }
84
+
85
+ /**
86
+ * Given a variable name, discover its type.
87
+ *
88
+ * @param $name
89
+ * @param $item
90
+ * @return object The object from the item.
91
+ */
92
+ private function createObjectFromName($name, $item) {
93
+ $type = $this->$name;
94
+ return new $type($item);
95
+ }
96
+
97
+ protected function useObjects() {
98
+ global $apiConfig;
99
+ return (isset($apiConfig['use_objects']) && $apiConfig['use_objects']);
100
+ }
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
+ }
115
+ }
google-api-php-client/src/service/Google_Service.php ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ class Google_Service {
19
+ public $version;
20
+ public $servicePath;
21
+ public $resource;
22
+ }
google-api-php-client/src/service/Google_ServiceResource.php ADDED
@@ -0,0 +1,196 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ * Implements the actual methods/resources of the discovered Google API using magic function
20
+ * calling overloading (__call()), which on call will see if the method name (plus.activities.list)
21
+ * is available in this service, and if so construct an apiHttpRequest representing it.
22
+ *
23
+ * @author Chris Chabot <chabotc@google.com>
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'),
31
+ 'boundary' => array('type' => 'string', 'location' => 'query'),
32
+ 'fields' => array('type' => 'string', 'location' => 'query'),
33
+ 'trace' => array('type' => 'string', 'location' => 'query'),
34
+ 'userIp' => array('type' => 'string', 'location' => 'query'),
35
+ 'userip' => array('type' => 'string', 'location' => 'query'),
36
+ 'file' => array('type' => 'complex', 'location' => 'body'),
37
+ 'data' => array('type' => 'string', 'location' => 'body'),
38
+ 'mimeType' => array('type' => 'string', 'location' => 'header'),
39
+ 'uploadType' => array('type' => 'string', 'location' => 'query'),
40
+ 'mediaUpload' => array('type' => 'complex', 'location' => 'query'),
41
+ );
42
+
43
+ /** @var Google_Service $service */
44
+ private $service;
45
+
46
+ /** @var string $serviceName */
47
+ private $serviceName;
48
+
49
+ /** @var string $resourceName */
50
+ private $resourceName;
51
+
52
+ /** @var array $methods */
53
+ private $methods;
54
+
55
+ public function __construct($service, $serviceName, $resourceName, $resource) {
56
+ $this->service = $service;
57
+ $this->serviceName = $serviceName;
58
+ $this->resourceName = $resourceName;
59
+ $this->methods = isset($resource['methods']) ? $resource['methods'] : array($resourceName => $resource);
60
+ }
61
+
62
+ /**
63
+ * @param $name
64
+ * @param $arguments
65
+ * @return Google_HttpRequest|array
66
+ * @throws Google_Exception
67
+ */
68
+ public function __call($name, $arguments) {
69
+ if (! isset($this->methods[$name])) {
70
+ throw new Google_Exception("Unknown function: {$this->serviceName}->{$this->resourceName}->{$name}()");
71
+ }
72
+ $method = $this->methods[$name];
73
+ $parameters = $arguments[0];
74
+
75
+ // postBody is a special case since it's not defined in the discovery document as parameter, but we abuse the param entry for storing it
76
+ $postBody = null;
77
+ if (isset($parameters['postBody'])) {
78
+ if (is_object($parameters['postBody'])) {
79
+ $this->stripNull($parameters['postBody']);
80
+ }
81
+
82
+ // Some APIs require the postBody to be set under the data key.
83
+ if (is_array($parameters['postBody']) && 'latitude' == $this->serviceName) {
84
+ if (!isset($parameters['postBody']['data'])) {
85
+ $rawBody = $parameters['postBody'];
86
+ unset($parameters['postBody']);
87
+ $parameters['postBody']['data'] = $rawBody;
88
+ }
89
+ }
90
+
91
+ $postBody = is_array($parameters['postBody']) || is_object($parameters['postBody'])
92
+ ? json_encode($parameters['postBody'])
93
+ : $parameters['postBody'];
94
+ unset($parameters['postBody']);
95
+
96
+ if (isset($parameters['optParams'])) {
97
+ $optParams = $parameters['optParams'];
98
+ unset($parameters['optParams']);
99
+ $parameters = array_merge($parameters, $optParams);
100
+ }
101
+ }
102
+
103
+ if (!isset($method['parameters'])) {
104
+ $method['parameters'] = array();
105
+ }
106
+
107
+ $method['parameters'] = array_merge($method['parameters'], $this->stackParameters);
108
+ foreach ($parameters as $key => $val) {
109
+ if ($key != 'postBody' && ! isset($method['parameters'][$key])) {
110
+ throw new Google_Exception("($name) unknown parameter: '$key'");
111
+ }
112
+ }
113
+ if (isset($method['parameters'])) {
114
+ foreach ($method['parameters'] as $paramName => $paramSpec) {
115
+ if (isset($paramSpec['required']) && $paramSpec['required'] && ! isset($parameters[$paramName])) {
116
+ throw new Google_Exception("($name) missing required param: '$paramName'");
117
+ }
118
+ if (isset($parameters[$paramName])) {
119
+ $value = $parameters[$paramName];
120
+ $parameters[$paramName] = $paramSpec;
121
+ $parameters[$paramName]['value'] = $value;
122
+ unset($parameters[$paramName]['required']);
123
+ } else {
124
+ unset($parameters[$paramName]);
125
+ }
126
+ }
127
+ }
128
+
129
+ // Discovery v1.0 puts the canonical method id under the 'id' field.
130
+ if (! isset($method['id'])) {
131
+ $method['id'] = $method['rpcMethod'];
132
+ }
133
+
134
+ // Discovery v1.0 puts the canonical path under the 'path' field.
135
+ if (! isset($method['path'])) {
136
+ $method['path'] = $method['restPath'];
137
+ }
138
+
139
+ $servicePath = $this->service->servicePath;
140
+
141
+ // Process Media Request
142
+ $contentType = false;
143
+ if (isset($method['mediaUpload'])) {
144
+ $media = Google_MediaFileUpload::process($postBody, $parameters);
145
+ if ($media) {
146
+ $contentType = isset($media['content-type']) ? $media['content-type']: null;
147
+ $postBody = isset($media['postBody']) ? $media['postBody'] : null;
148
+ $servicePath = $method['mediaUpload']['protocols']['simple']['path'];
149
+ $method['path'] = '';
150
+ }
151
+ }
152
+
153
+ $url = Google_REST::createRequestUri($servicePath, $method['path'], $parameters);
154
+ $httpRequest = new Google_HttpRequest($url, $method['httpMethod'], null, $postBody);
155
+ if ($postBody) {
156
+ $contentTypeHeader = array();
157
+ if (isset($contentType) && $contentType) {
158
+ $contentTypeHeader['content-type'] = $contentType;
159
+ } else {
160
+ $contentTypeHeader['content-type'] = 'application/json; charset=UTF-8';
161
+ $contentTypeHeader['content-length'] = Google_Utils::getStrLen($postBody);
162
+ }
163
+ $httpRequest->setRequestHeaders($contentTypeHeader);
164
+ }
165
+
166
+ $httpRequest = Google_Client::$auth->sign($httpRequest);
167
+ if (Google_Client::$useBatch) {
168
+ return $httpRequest;
169
+ }
170
+
171
+ // Terminate immediatly if this is a resumable request.
172
+ if (isset($parameters['uploadType']['value'])
173
+ && 'resumable' == $parameters['uploadType']['value']) {
174
+ return $httpRequest;
175
+ }
176
+
177
+ return Google_REST::execute($httpRequest);
178
+ }
179
+
180
+ public function useObjects() {
181
+ global $apiConfig;
182
+ return (isset($apiConfig['use_objects']) && $apiConfig['use_objects']);
183
+ }
184
+
185
+ protected function stripNull(&$o) {
186
+ $o = (array) $o;
187
+ foreach ($o as $k => $v) {
188
+ if ($v === null || strstr($k, "\0*\0__")) {
189
+ unset($o[$k]);
190
+ }
191
+ elseif (is_object($v) || is_array($v)) {
192
+ $this->stripNull($o[$k]);
193
+ }
194
+ }
195
+ }
196
+ }
google-api-php-client/src/service/Google_Utils.php ADDED
@@ -0,0 +1,117 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * Copyright 2011 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
+ * Collection of static utility methods used for convenience across
20
+ * the client library.
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', '='),
28
+ array('-', '_'),
29
+ $b64);
30
+ return $b64;
31
+ }
32
+
33
+ public static function urlSafeB64Decode($b64) {
34
+ $b64 = str_replace(array('-', '_'),
35
+ array('+', '/'),
36
+ $b64);
37
+ return base64_decode($b64);
38
+ }
39
+
40
+ /**
41
+ * Misc function used to count the number of bytes in a post body, in the world of multi-byte chars
42
+ * and the unpredictability of strlen/mb_strlen/sizeof, this is the only way to do that in a sane
43
+ * manner at the moment.
44
+ *
45
+ * This algorithm was originally developed for the
46
+ * Solar Framework by Paul M. Jones
47
+ *
48
+ * @link http://solarphp.com/
49
+ * @link http://svn.solarphp.com/core/trunk/Solar/Json.php
50
+ * @link http://framework.zend.com/svn/framework/standard/trunk/library/Zend/Json/Decoder.php
51
+ * @param string $str
52
+ * @return int The number of bytes in a string.
53
+ */
54
+ static public function getStrLen($str) {
55
+ $strlenVar = strlen($str);
56
+ $d = $ret = 0;
57
+ for ($count = 0; $count < $strlenVar; ++ $count) {
58
+ $ordinalValue = ord($str{$ret});
59
+ switch (true) {
60
+ case (($ordinalValue >= 0x20) && ($ordinalValue <= 0x7F)):
61
+ // characters U-00000000 - U-0000007F (same as ASCII)
62
+ $ret ++;
63
+ break;
64
+
65
+ case (($ordinalValue & 0xE0) == 0xC0):
66
+ // characters U-00000080 - U-000007FF, mask 110XXXXX
67
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
68
+ $ret += 2;
69
+ break;
70
+
71
+ case (($ordinalValue & 0xF0) == 0xE0):
72
+ // characters U-00000800 - U-0000FFFF, mask 1110XXXX
73
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
74
+ $ret += 3;
75
+ break;
76
+
77
+ case (($ordinalValue & 0xF8) == 0xF0):
78
+ // characters U-00010000 - U-001FFFFF, mask 11110XXX
79
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
80
+ $ret += 4;
81
+ break;
82
+
83
+ case (($ordinalValue & 0xFC) == 0xF8):
84
+ // characters U-00200000 - U-03FFFFFF, mask 111110XX
85
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
86
+ $ret += 5;
87
+ break;
88
+
89
+ case (($ordinalValue & 0xFE) == 0xFC):
90
+ // characters U-04000000 - U-7FFFFFFF, mask 1111110X
91
+ // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
92
+ $ret += 6;
93
+ break;
94
+ default:
95
+ $ret ++;
96
+ }
97
+ }
98
+ return $ret;
99
+ }
100
+
101
+ /**
102
+ * Normalize all keys in an array to lower-case.
103
+ * @param array $arr
104
+ * @return array Normalized array.
105
+ */
106
+ public static function normalize($arr) {
107
+ if (!is_array($arr)) {
108
+ return array();
109
+ }
110
+
111
+ $normalized = array();
112
+ foreach ($arr as $key => $val) {
113
+ $normalized[strtolower($key)] = $val;
114
+ }
115
+ return $normalized;
116
+ }
117
+ }
google-api-php-client/static/Credentials.png ADDED
Binary file
jquery.sparkline.min.js CHANGED
@@ -1,85 +1,85 @@
1
- /* jquery.sparkline 1.5.1 - http://omnipotent.net/jquery.sparkline/ */
2
-
3
- (function($){$.fn.simpledraw=function(width,height,use_existing){if(use_existing&&this[0].vcanvas)return this[0].vcanvas;if(width==undefined)width=$(this).innerWidth();if(height==undefined)height=$(this).innerHeight();if($.browser.hasCanvas){return new vcanvas_canvas(width,height,this);}else if($.browser.msie){return new vcanvas_vml(width,height,this);}else{return false;}};var pending=[];$.fn.sparkline=function(uservalues,options){var options=$.extend({type:'line',lineColor:'#00f',fillColor:'#cdf',defaultPixelsPerValue:3,width:'auto',height:'auto',composite:false},options?options:{});return this.each(function(){var render=function(){var values=(uservalues=='html'||uservalues==undefined)?$(this).text().split(','):uservalues;var width=options.width=='auto'?values.length*options.defaultPixelsPerValue:options.width;if(options.height=='auto'){if(!options.composite||!this.vcanvas){var tmp=document.createElement('span');tmp.innerHTML='a';$(this).html(tmp);height=$(tmp).innerHeight();$(tmp).remove();}}else{height=options.height;}
4
- $.fn.sparkline[options.type].call(this,values,options,width,height);}
5
- if(($(this).html()&&$(this).is(':hidden'))||($.fn.jquery<"1.3.0"&&$(this).parents().is(':hidden'))){pending.push([this,render]);}else{render.call(this);}});};$.sparkline_display_visible=function(){for(var i=pending.length-1;i>=0;i--){var el=pending[i][0];if($(el).is(':visible')&&!$(el).parents().is(':hidden')){pending[i][1].call(el);pending.splice(i,1);}}};$.fn.sparkline.line=function(values,options,width,height){var options=$.extend({spotColor:'#f80',spotRadius:1.5,minSpotColor:'#f80',maxSpotColor:'#f80',lineWidth:1,normalRangeMin:undefined,normalRangeMax:undefined,normalRangeColor:'#ccc',chartRangeMin:undefined,chartRangeMax:undefined,chartRangeMinX:undefined,chartRangeMaxX:undefined},options?options:{});var xvalues=[],yvalues=[],yminmax=[];for(i=0;i<values.length;i++){var v=values[i];var isstr=typeof(values[i])=='string';var isarray=typeof(values[i])=='object'&&values[i]instanceof Array;var sp=isstr&&values[i].split(':');if(isstr&&sp.length==2){xvalues.push(Number(sp[0]));yvalues.push(Number(sp[1]));yminmax.push(Number(sp[1]));}else if(isarray){xvalues.push(values[i][0]);yvalues.push(values[i][1]);yminmax.push(values[i][1]);}else{xvalues.push(i);if(values[i]===null||values[i]=='null'){yvalues.push(null);}else{yvalues.push(Number(values[i]));yminmax.push(Number(values[i]));}}}
6
- if(options.xvalues){xvalues=options.xvalues;}
7
- var maxy=Math.max.apply(Math,yminmax);var maxyval=maxy;var miny=Math.min.apply(Math,yminmax);var minyval=miny;var maxx=Math.max.apply(Math,xvalues);var maxxval=maxx;var minx=Math.min.apply(Math,xvalues);var minxval=minx;if(options.normalRangeMin!=undefined){if(options.normalRangeMin<miny)
8
- miny=options.normalRangeMin;if(options.normalRangeMax>maxy)
9
- maxy=options.normalRangeMax;}
10
- if(options.chartRangeMin!=undefined&&(options.chartRangeClip||options.chartRangeMin<miny)){miny=options.chartRangeMin;}
11
- if(options.chartRangeMax!=undefined&&(options.chartRangeClip||options.chartRangeMax>maxy)){maxy=options.chartRangeMax;}
12
- if(options.chartRangeMinX!=undefined&&(options.chartRangeClipX||options.chartRangeMinX<minx)){minx=options.chartRangeMinX;}
13
- if(options.chartRangeMaxX!=undefined&&(options.chartRangeClipX||options.chartRangeMaxX>maxx)){maxx=options.chartRangeMaxX;}
14
- var rangex=maxx-minx==0?1:maxx-minx;var rangey=maxy-miny==0?1:maxy-miny;var vl=yvalues.length-1;if(vl<1){this.innerHTML='';return;}
15
- var target=$(this).simpledraw(width,height,options.composite);if(target){var canvas_width=target.pixel_width;var canvas_height=target.pixel_height;var canvas_top=0;var canvas_left=0;if(options.spotRadius&&(canvas_width<(options.spotRadius*4)||canvas_height<(options.spotRadius*4))){options.spotRadius=0;}
16
- if(options.spotRadius){if(options.minSpotColor||(options.spotColor&&yvalues[vl]==miny))
17
- canvas_height-=Math.ceil(options.spotRadius);if(options.maxSpotColor||(options.spotColor&&yvalues[vl]==maxy)){canvas_height-=Math.ceil(options.spotRadius);canvas_top+=Math.ceil(options.spotRadius);}
18
- if(options.minSpotColor||options.maxSpotColor&&(yvalues[0]==miny||yvalues[0]==maxy)){canvas_left+=Math.ceil(options.spotRadius);canvas_width-=Math.ceil(options.spotRadius);}
19
- if(options.spotColor||(options.minSpotColor||options.maxSpotColor&&(yvalues[vl]==miny||yvalues[vl]==maxy)))
20
- canvas_width-=Math.ceil(options.spotRadius);}
21
- canvas_height--;if(options.normalRangeMin!=undefined){var ytop=canvas_top+Math.round(canvas_height-(canvas_height*((options.normalRangeMax-miny)/rangey)));var height=Math.round((canvas_height*(options.normalRangeMax-options.normalRangeMin))/rangey);target.drawRect(canvas_left,ytop,canvas_width,height,undefined,options.normalRangeColor);}
22
- var path=[];var paths=[path];for(var i=0,vlen=yvalues.length;i<vlen;i++){var x=xvalues[i],y=yvalues[i];if(y===null){if(i){if(yvalues[i-1]!==null){path=[];paths.push(path);}}}else{if(y<miny)y=miny;if(y>maxy)y=maxy;if(!path.length){path.push([canvas_left+Math.round((x-minx)*(canvas_width/rangex)),canvas_top+canvas_height]);}
23
- path.push([canvas_left+Math.round((x-minx)*(canvas_width/rangex)),canvas_top+Math.round(canvas_height-(canvas_height*((y-miny)/rangey)))]);}}
24
- for(var i=0,plen=paths.length;i<plen;i++){path=paths[i];if(!path.length)
25
- continue;if(options.fillColor){path.push([path[path.length-1][0],canvas_top+canvas_height-1]);target.drawShape(path,undefined,options.fillColor);path.pop();}
26
- if(path.length>2){path[0]=[path[0][0],path[1][1]];}
27
- target.drawShape(path,options.lineColor,undefined,options.lineWidth);}
28
- if(options.spotRadius&&options.spotColor){target.drawCircle(canvas_left+Math.round(xvalues[xvalues.length-1]*(canvas_width/rangex)),canvas_top+Math.round(canvas_height-(canvas_height*((yvalues[vl]-miny)/rangey))),options.spotRadius,undefined,options.spotColor);}
29
- if(maxy!=minyval){if(options.spotRadius&&options.minSpotColor){var x=xvalues[yvalues.indexOf(minyval)];target.drawCircle(canvas_left+Math.round((x-minx)*(canvas_width/rangex)),canvas_top+Math.round(canvas_height-(canvas_height*((minyval-miny)/rangey))),options.spotRadius,undefined,options.minSpotColor);}
30
- if(options.spotRadius&&options.maxSpotColor){var x=xvalues[yvalues.indexOf(maxyval)];target.drawCircle(canvas_left+Math.round((x-minx)*(canvas_width/rangex)),canvas_top+Math.round(canvas_height-(canvas_height*((maxyval-miny)/rangey))),options.spotRadius,undefined,options.maxSpotColor);}}}else{this.innerHTML='';}};$.fn.sparkline.bar=function(values,options,width,height){var options=$.extend({type:'bar',barColor:'#00f',negBarColor:'#f44',zeroColor:undefined,nullColor:undefined,zeroAxis:undefined,barWidth:4,barSpacing:1,chartRangeMax:undefined,chartRangeMin:undefined,chartRangeClip:false,colorMap:undefined},options?options:{});var width=(values.length*options.barWidth)+((values.length-1)*options.barSpacing);var num_values=[];for(var i=0,vlen=values.length;i<vlen;i++){if(values[i]=='null'||values[i]===null){values[i]=null;}else{values[i]=Number(values[i]);num_values.push(Number(values[i]));}}
31
- var max=Math.max.apply(Math,num_values);var min=Math.min.apply(Math,num_values);if(options.chartRangeMin!=undefined&&(options.chartRangeClip||options.chartRangeMin<min)){min=options.chartRangeMin;}
32
- if(options.chartRangeMax!=undefined&&(options.chartRangeClip||options.chartRangeMax>max)){max=options.chartRangeMax;}
33
- if(options.zeroAxis==undefined)options.zeroAxis=min<0;var range=max-min==0?1:max-min;if($.isArray(options.colorMap)){var colorMapByIndex=options.colorMap;var colorMapByValue=null;}else{var colorMapByIndex=null;var colorMapByValue=options.colorMap;}
34
- var target=$(this).simpledraw(width,height,options.composite);if(target){var canvas_width=target.pixel_width;var canvas_height=target.pixel_height;var yzero=min<0&&options.zeroAxis?canvas_height-Math.round(canvas_height*(Math.abs(min)/range))-1:canvas_height-1;for(var i=0,vlen=values.length;i<vlen;i++){var x=i*(options.barWidth+options.barSpacing);var val=values[i];if(val===null){if(options.nullColor){color=options.nullColor;val=(options.zeroAxis&&min<0)?0:min;var height=1;var y=(options.zeroAxis&&min<0)?yzero:canvas_height-height;}else{continue;}}else{if(val<min)val=min;if(val>max)val=max;var color=(val<0)?options.negBarColor:options.barColor;if(options.zeroAxis&&min<0){var height=Math.round(canvas_height*((Math.abs(val)/range)))+1;var y=(val<0)?yzero:yzero-height;}else{var height=Math.round(canvas_height*((val-min)/range))+1;var y=canvas_height-height;}
35
- if(val==0&&options.zeroColor!=undefined){color=options.zeroColor;}
36
- if(colorMapByValue&&colorMapByValue[val]){color=colorMapByValue[val];}else if(colorMapByIndex&&colorMapByIndex.length>i){color=colorMapByIndex[i];}
37
- if(color===null){continue;}}
38
- target.drawRect(x,y,options.barWidth-1,height-1,color,color);}}else{this.innerHTML='';}};$.fn.sparkline.tristate=function(values,options,width,height){values=$.map(values,Number);var options=$.extend({barWidth:4,barSpacing:1,posBarColor:'#6f6',negBarColor:'#f44',zeroBarColor:'#999',colorMap:{}},options);var width=(values.length*options.barWidth)+((values.length-1)*options.barSpacing);if($.isArray(options.colorMap)){var colorMapByIndex=options.colorMap;var colorMapByValue=null;}else{var colorMapByIndex=null;var colorMapByValue=options.colorMap;}
39
- var target=$(this).simpledraw(width,height,options.composite);if(target){var canvas_width=target.pixel_width;var canvas_height=target.pixel_height;var half_height=Math.round(canvas_height/2);for(var i=0,vlen=values.length;i<vlen;i++){var x=i*(options.barWidth+options.barSpacing);if(values[i]<0){var y=half_height;var height=half_height-1;var color=options.negBarColor;}else if(values[i]>0){var y=0;var height=half_height-1;var color=options.posBarColor;}else{var y=half_height-1;var height=2;var color=options.zeroBarColor;}
40
- if(colorMapByValue&&colorMapByValue[values[i]]){color=colorMapByValue[values[i]];}else if(colorMapByIndex&&colorMapByIndex.length>i){color=colorMapByIndex[i];}
41
- if(color===null){continue;}
42
- target.drawRect(x,y,options.barWidth-1,height-1,color,color);}}else{this.innerHTML='';}};$.fn.sparkline.discrete=function(values,options,width,height){values=$.map(values,Number);var options=$.extend({lineHeight:'auto',thresholdColor:undefined,thresholdValue:0,chartRangeMax:undefined,chartRangeMin:undefined,chartRangeClip:false},options);width=options.width=='auto'?values.length*2:width;var interval=Math.floor(width/values.length);var target=$(this).simpledraw(width,height,options.composite);if(target){var canvas_width=target.pixel_width;var canvas_height=target.pixel_height;var line_height=options.lineHeight=='auto'?Math.round(canvas_height*0.3):options.lineHeight;var pheight=canvas_height-line_height;var min=Math.min.apply(Math,values);var max=Math.max.apply(Math,values);if(options.chartRangeMin!=undefined&&(options.chartRangeClip||options.chartRangeMin<min)){min=options.chartRangeMin;}
43
- if(options.chartRangeMax!=undefined&&(options.chartRangeClip||options.chartRangeMax>max)){max=options.chartRangeMax;}
44
- var range=max-min;for(var i=0,vlen=values.length;i<vlen;i++){var val=values[i];if(val<min)val=min;if(val>max)val=max;var x=(i*interval);var ytop=Math.round(pheight-pheight*((val-min)/range));target.drawLine(x,ytop,x,ytop+line_height,(options.thresholdColor&&val<options.thresholdValue)?options.thresholdColor:options.lineColor);}}else{this.innerHTML='';}};$.fn.sparkline.bullet=function(values,options,width,height){values=$.map(values,Number);var options=$.extend({targetColor:'red',targetWidth:3,performanceColor:'blue',rangeColors:['#D3DAFE','#A8B6FF','#7F94FF'],base:undefined},options);width=options.width=='auto'?'4.0em':width;var target=$(this).simpledraw(width,height,options.composite);if(target&&values.length>1){var canvas_width=target.pixel_width-Math.ceil(options.targetWidth/2);var canvas_height=target.pixel_height;var min=Math.min.apply(Math,values);var max=Math.max.apply(Math,values);if(options.base==undefined){var min=min<0?min:0;}else{min=options.base;}
45
- var range=max-min;for(i=2,vlen=values.length;i<vlen;i++){var rangeval=parseInt(values[i]);var rangewidth=Math.round(canvas_width*((rangeval-min)/range));target.drawRect(0,0,rangewidth-1,canvas_height-1,options.rangeColors[i-2],options.rangeColors[i-2]);}
46
- var perfval=parseInt(values[1]);var perfwidth=Math.round(canvas_width*((perfval-min)/range));target.drawRect(0,Math.round(canvas_height*0.3),perfwidth-1,Math.round(canvas_height*0.4)-1,options.performanceColor,options.performanceColor);var targetval=parseInt(values[0]);var x=Math.round(canvas_width*((targetval-min)/range)-(options.targetWidth/2));var targettop=Math.round(canvas_height*0.10);var targetheight=canvas_height-(targettop*2);target.drawRect(x,targettop,options.targetWidth-1,targetheight-1,options.targetColor,options.targetColor);}else{this.innerHTML='';}};$.fn.sparkline.pie=function(values,options,width,height){values=$.map(values,Number);var options=$.extend({sliceColors:['#f00','#0f0','#00f']},options);width=options.width=='auto'?height:width;var target=$(this).simpledraw(width,height,options.composite);if(target&&values.length>1){var canvas_width=target.pixel_width;var canvas_height=target.pixel_height;var radius=Math.floor(Math.min(canvas_width,canvas_height)/2);var total=0;for(var i=0,vlen=values.length;i<vlen;i++)
47
- total+=values[i];var next=0;if(options.offset){next+=(2*Math.PI)*(options.offset/360);}
48
- var circle=2*Math.PI;for(var i=0,vlen=values.length;i<vlen;i++){var start=next;var end=next;if(total>0){end=next+(circle*(values[i]/total));}
49
- target.drawPieSlice(radius,radius,radius,start,end,undefined,options.sliceColors[i%options.sliceColors.length]);next=end;}}};function quartile(values,q){if(q==2){var vl2=Math.floor(values.length/2);return values.length%2?values[vl2]:(values[vl2]+values[vl2+1])/2;}else{var vl4=Math.floor(values.length/4);return values.length%2?(values[vl4*q]+values[vl4*q+1])/2:values[vl4*q];}};$.fn.sparkline.box=function(values,options,width,height){values=$.map(values,Number);var options=$.extend({raw:false,boxLineColor:'black',boxFillColor:'#cdf',whiskerColor:'black',outlierLineColor:'#333',outlierFillColor:'white',medianColor:'red',showOutliers:true,outlierIQR:1.5,spotRadius:1.5,target:undefined,targetColor:'#4a2',chartRangeMax:undefined,chartRangeMin:undefined},options);width=options.width=='auto'?'4.0em':width;minvalue=options.chartRangeMin==undefined?Math.min.apply(Math,values):options.chartRangeMin;maxvalue=options.chartRangeMax==undefined?Math.max.apply(Math,values):options.chartRangeMax;var target=$(this).simpledraw(width,height,options.composite);if(target&&values.length>1){var canvas_width=target.pixel_width;var canvas_height=target.pixel_height;if(options.raw){if(options.showOutliers&&values.length>5){var loutlier=values[0],lwhisker=values[1],q1=values[2],q2=values[3],q3=values[4],rwhisker=values[5],routlier=values[6];}else{var lwhisker=values[0],q1=values[1],q2=values[2],q3=values[3],rwhisker=values[4];}}else{values.sort(function(a,b){return a-b;});var q1=quartile(values,1);var q2=quartile(values,2);var q3=quartile(values,3);var iqr=q3-q1;if(options.showOutliers){var lwhisker=undefined,rwhisker=undefined;for(var i=0,vlen=values.length;i<vlen;i++){if(lwhisker==undefined&&values[i]>q1-(iqr*options.outlierIQR))
50
- lwhisker=values[i];if(values[i]<q3+(iqr*options.outlierIQR))
51
- rwhisker=values[i];}
52
- var loutlier=values[0];var routlier=values[values.length-1];}else{var lwhisker=values[0];var rwhisker=values[values.length-1];}}
53
- var unitsize=canvas_width/(maxvalue-minvalue+1);var canvas_left=0;if(options.showOutliers){canvas_left=Math.ceil(options.spotRadius);canvas_width-=2*Math.ceil(options.spotRadius);var unitsize=canvas_width/(maxvalue-minvalue+1);if(loutlier<lwhisker)
54
- target.drawCircle((loutlier-minvalue)*unitsize+canvas_left,canvas_height/2,options.spotRadius,options.outlierLineColor,options.outlierFillColor);if(routlier>rwhisker)
55
- target.drawCircle((routlier-minvalue)*unitsize+canvas_left,canvas_height/2,options.spotRadius,options.outlierLineColor,options.outlierFillColor);}
56
- target.drawRect(Math.round((q1-minvalue)*unitsize+canvas_left),Math.round(canvas_height*0.1),Math.round((q3-q1)*unitsize),Math.round(canvas_height*0.8),options.boxLineColor,options.boxFillColor);target.drawLine(Math.round((lwhisker-minvalue)*unitsize+canvas_left),Math.round(canvas_height/2),Math.round((q1-minvalue)*unitsize+canvas_left),Math.round(canvas_height/2),options.lineColor);target.drawLine(Math.round((lwhisker-minvalue)*unitsize+canvas_left),Math.round(canvas_height/4),Math.round((lwhisker-minvalue)*unitsize+canvas_left),Math.round(canvas_height-canvas_height/4),options.whiskerColor);target.drawLine(Math.round((rwhisker-minvalue)*unitsize+canvas_left),Math.round(canvas_height/2),Math.round((q3-minvalue)*unitsize+canvas_left),Math.round(canvas_height/2),options.lineColor);target.drawLine(Math.round((rwhisker-minvalue)*unitsize+canvas_left),Math.round(canvas_height/4),Math.round((rwhisker-minvalue)*unitsize+canvas_left),Math.round(canvas_height-canvas_height/4),options.whiskerColor);target.drawLine(Math.round((q2-minvalue)*unitsize+canvas_left),Math.round(canvas_height*0.1),Math.round((q2-minvalue)*unitsize+canvas_left),Math.round(canvas_height*0.9),options.medianColor);if(options.target){var size=Math.ceil(options.spotRadius);target.drawLine(Math.round((options.target-minvalue)*unitsize+canvas_left),Math.round((canvas_height/2)-size),Math.round((options.target-minvalue)*unitsize+canvas_left),Math.round((canvas_height/2)+size),options.targetColor);target.drawLine(Math.round((options.target-minvalue)*unitsize+canvas_left-size),Math.round(canvas_height/2),Math.round((options.target-minvalue)*unitsize+canvas_left+size),Math.round(canvas_height/2),options.targetColor);}}else{this.innerHTML='';}};if(!Array.prototype.indexOf){Array.prototype.indexOf=function(entry){for(var i=0,vlen=this.length;i<vlen;i++){if(this[i]==entry)
57
- return i;}
58
- return-1;}}
59
- if($.browser.msie&&!document.namespaces['v']){document.namespaces.add('v','urn:schemas-microsoft-com:vml','#default#VML');}
60
- if($.browser.hasCanvas==undefined){var t=document.createElement('canvas');$.browser.hasCanvas=t.getContext!=undefined;}
61
- var vcanvas_base=function(width,height,target){};vcanvas_base.prototype={init:function(width,height,target){this.width=width;this.height=height;this.target=target;if(target[0])target=target[0];target.vcanvas=this;},drawShape:function(path,lineColor,fillColor,lineWidth){alert('drawShape not implemented');},drawLine:function(x1,y1,x2,y2,lineColor,lineWidth){return this.drawShape([[x1,y1],[x2,y2]],lineColor,lineWidth);},drawCircle:function(x,y,radius,lineColor,fillColor){alert('drawCircle not implemented');},drawPieSlice:function(x,y,radius,startAngle,endAngle,lineColor,fillColor){alert('drawPieSlice not implemented');},drawRect:function(x,y,width,height,lineColor,fillColor){alert('drawRect not implemented');},getElement:function(){return this.canvas;},_insert:function(el,target){$(target).html(el);}};var vcanvas_canvas=function(width,height,target){return this.init(width,height,target);};vcanvas_canvas.prototype=$.extend(new vcanvas_base,{_super:vcanvas_base.prototype,init:function(width,height,target){this._super.init(width,height,target);this.canvas=document.createElement('canvas');if(target[0])target=target[0];target.vcanvas=this;$(this.canvas).css({display:'inline-block',width:width,height:height,verticalAlign:'top'});this._insert(this.canvas,target);this.pixel_height=$(this.canvas).height();this.pixel_width=$(this.canvas).width();this.canvas.width=this.pixel_width;this.canvas.height=this.pixel_height;$(this.canvas).css({width:this.pixel_width,height:this.pixel_height});},_getContext:function(lineColor,fillColor,lineWidth){var context=this.canvas.getContext('2d');if(lineColor!=undefined)
62
- context.strokeStyle=lineColor;context.lineWidth=lineWidth==undefined?1:lineWidth;if(fillColor!=undefined)
63
- context.fillStyle=fillColor;return context;},drawShape:function(path,lineColor,fillColor,lineWidth){var context=this._getContext(lineColor,fillColor,lineWidth);context.beginPath();context.moveTo(path[0][0]+0.5,path[0][1]+0.5);for(var i=1,plen=path.length;i<plen;i++){context.lineTo(path[i][0]+0.5,path[i][1]+0.5);}
64
- if(lineColor!=undefined){context.stroke();}
65
- if(fillColor!=undefined){context.fill();}},drawCircle:function(x,y,radius,lineColor,fillColor){var context=this._getContext(lineColor,fillColor);context.beginPath();context.arc(x,y,radius,0,2*Math.PI,false);if(lineColor!=undefined){context.stroke();}
66
- if(fillColor!=undefined){context.fill();}},drawPieSlice:function(x,y,radius,startAngle,endAngle,lineColor,fillColor){var context=this._getContext(lineColor,fillColor);context.beginPath();context.moveTo(x,y);context.arc(x,y,radius,startAngle,endAngle,false);context.lineTo(x,y);context.closePath();if(lineColor!=undefined){context.stroke();}
67
- if(fillColor){context.fill();}},drawRect:function(x,y,width,height,lineColor,fillColor){return this.drawShape([[x,y],[x+width,y],[x+width,y+height],[x,y+height],[x,y]],lineColor,fillColor);}});var vcanvas_vml=function(width,height,target){return this.init(width,height,target);};vcanvas_vml.prototype=$.extend(new vcanvas_base,{_super:vcanvas_base.prototype,init:function(width,height,target){this._super.init(width,height,target);if(target[0])target=target[0];target.vcanvas=this;this.canvas=document.createElement('span');$(this.canvas).css({display:'inline-block',position:'relative',overflow:'hidden',width:width,height:height,margin:'0px',padding:'0px',verticalAlign:'top'});this._insert(this.canvas,target);this.pixel_height=$(this.canvas).height();this.pixel_width=$(this.canvas).width();this.canvas.width=this.pixel_width;this.canvas.height=this.pixel_height;;var groupel='<v:group coordorigin="0 0" coordsize="'+this.pixel_width+' '+this.pixel_height+'"'
68
- +' style="position:absolute;top:0;left:0;width:'+this.pixel_width+'px;height='+this.pixel_height+'px;"></v:group>';this.canvas.insertAdjacentHTML('beforeEnd',groupel);this.group=$(this.canvas).children()[0];},drawShape:function(path,lineColor,fillColor,lineWidth){var vpath=[];for(var i=0,plen=path.length;i<plen;i++){vpath[i]=''+(path[i][0])+','+(path[i][1]);}
69
- var initial=vpath.splice(0,1);lineWidth=lineWidth==undefined?1:lineWidth;var stroke=lineColor==undefined?' stroked="false" ':' strokeWeight="'+lineWidth+'" strokeColor="'+lineColor+'" ';var fill=fillColor==undefined?' filled="false"':' fillColor="'+fillColor+'" filled="true" ';var closed=vpath[0]==vpath[vpath.length-1]?'x ':'';var vel='<v:shape coordorigin="0 0" coordsize="'+this.pixel_width+' '+this.pixel_height+'" '
70
- +stroke
71
- +fill
72
- +' style="position:absolute;left:0px;top:0px;height:'+this.pixel_height+'px;width:'+this.pixel_width+'px;padding:0px;margin:0px;" '
73
- +' path="m '+initial+' l '+vpath.join(', ')+' '+closed+'e">'
74
- +' </v:shape>';this.group.insertAdjacentHTML('beforeEnd',vel);},drawCircle:function(x,y,radius,lineColor,fillColor){x-=radius+1;y-=radius+1;var stroke=lineColor==undefined?' stroked="false" ':' strokeWeight="1" strokeColor="'+lineColor+'" ';var fill=fillColor==undefined?' filled="false"':' fillColor="'+fillColor+'" filled="true" ';var vel='<v:oval '
75
- +stroke
76
- +fill
77
- +' style="position:absolute;top:'+y+'px; left:'+x+'px; width:'+(radius*2)+'px; height:'+(radius*2)+'px"></v:oval>';this.group.insertAdjacentHTML('beforeEnd',vel);},drawPieSlice:function(x,y,radius,startAngle,endAngle,lineColor,fillColor){if(startAngle==endAngle){return;}
78
- if((endAngle-startAngle)==(2*Math.PI)){startAngle=0.0;endAngle=(2*Math.PI);}
79
- var startx=x+Math.round(Math.cos(startAngle)*radius);var starty=y+Math.round(Math.sin(startAngle)*radius);var endx=x+Math.round(Math.cos(endAngle)*radius);var endy=y+Math.round(Math.sin(endAngle)*radius);if(startx==endx&&starty==endy&&(endAngle-startAngle)<Math.PI)
80
- return;var vpath=[x-radius,y-radius,x+radius,y+radius,startx,starty,endx,endy];var stroke=lineColor==undefined?' stroked="false" ':' strokeWeight="1" strokeColor="'+lineColor+'" ';var fill=fillColor==undefined?' filled="false"':' fillColor="'+fillColor+'" filled="true" ';var vel='<v:shape coordorigin="0 0" coordsize="'+this.pixel_width+' '+this.pixel_height+'" '
81
- +stroke
82
- +fill
83
- +' style="position:absolute;left:0px;top:0px;height:'+this.pixel_height+'px;width:'+this.pixel_width+'px;padding:0px;margin:0px;" '
84
- +' path="m '+x+','+y+' wa '+vpath.join(', ')+' x e">'
85
  +' </v:shape>';this.group.insertAdjacentHTML('beforeEnd',vel);},drawRect:function(x,y,width,height,lineColor,fillColor){return this.drawShape([[x,y],[x,y+height],[x+width,y+height],[x+width,y],[x,y]],lineColor,fillColor);}});})(jQuery);
1
+ /* jquery.sparkline 1.5.1 - http://omnipotent.net/jquery.sparkline/ */
2
+
3
+ (function($){$.fn.simpledraw=function(width,height,use_existing){if(use_existing&&this[0].vcanvas)return this[0].vcanvas;if(width==undefined)width=$(this).innerWidth();if(height==undefined)height=$(this).innerHeight();if($.browser.hasCanvas){return new vcanvas_canvas(width,height,this);}else if($.browser.msie){return new vcanvas_vml(width,height,this);}else{return false;}};var pending=[];$.fn.sparkline=function(uservalues,options){var options=$.extend({type:'line',lineColor:'#00f',fillColor:'#cdf',defaultPixelsPerValue:3,width:'auto',height:'auto',composite:false},options?options:{});return this.each(function(){var render=function(){var values=(uservalues=='html'||uservalues==undefined)?$(this).text().split(','):uservalues;var width=options.width=='auto'?values.length*options.defaultPixelsPerValue:options.width;if(options.height=='auto'){if(!options.composite||!this.vcanvas){var tmp=document.createElement('span');tmp.innerHTML='a';$(this).html(tmp);height=$(tmp).innerHeight();$(tmp).remove();}}else{height=options.height;}
4
+ $.fn.sparkline[options.type].call(this,values,options,width,height);}
5
+ if(($(this).html()&&$(this).is(':hidden'))||($.fn.jquery<"1.3.0"&&$(this).parents().is(':hidden'))){pending.push([this,render]);}else{render.call(this);}});};$.sparkline_display_visible=function(){for(var i=pending.length-1;i>=0;i--){var el=pending[i][0];if($(el).is(':visible')&&!$(el).parents().is(':hidden')){pending[i][1].call(el);pending.splice(i,1);}}};$.fn.sparkline.line=function(values,options,width,height){var options=$.extend({spotColor:'#f80',spotRadius:1.5,minSpotColor:'#f80',maxSpotColor:'#f80',lineWidth:1,normalRangeMin:undefined,normalRangeMax:undefined,normalRangeColor:'#ccc',chartRangeMin:undefined,chartRangeMax:undefined,chartRangeMinX:undefined,chartRangeMaxX:undefined},options?options:{});var xvalues=[],yvalues=[],yminmax=[];for(i=0;i<values.length;i++){var v=values[i];var isstr=typeof(values[i])=='string';var isarray=typeof(values[i])=='object'&&values[i]instanceof Array;var sp=isstr&&values[i].split(':');if(isstr&&sp.length==2){xvalues.push(Number(sp[0]));yvalues.push(Number(sp[1]));yminmax.push(Number(sp[1]));}else if(isarray){xvalues.push(values[i][0]);yvalues.push(values[i][1]);yminmax.push(values[i][1]);}else{xvalues.push(i);if(values[i]===null||values[i]=='null'){yvalues.push(null);}else{yvalues.push(Number(values[i]));yminmax.push(Number(values[i]));}}}
6
+ if(options.xvalues){xvalues=options.xvalues;}
7
+ var maxy=Math.max.apply(Math,yminmax);var maxyval=maxy;var miny=Math.min.apply(Math,yminmax);var minyval=miny;var maxx=Math.max.apply(Math,xvalues);var maxxval=maxx;var minx=Math.min.apply(Math,xvalues);var minxval=minx;if(options.normalRangeMin!=undefined){if(options.normalRangeMin<miny)
8
+ miny=options.normalRangeMin;if(options.normalRangeMax>maxy)
9
+ maxy=options.normalRangeMax;}
10
+ if(options.chartRangeMin!=undefined&&(options.chartRangeClip||options.chartRangeMin<miny)){miny=options.chartRangeMin;}
11
+ if(options.chartRangeMax!=undefined&&(options.chartRangeClip||options.chartRangeMax>maxy)){maxy=options.chartRangeMax;}
12
+ if(options.chartRangeMinX!=undefined&&(options.chartRangeClipX||options.chartRangeMinX<minx)){minx=options.chartRangeMinX;}
13
+ if(options.chartRangeMaxX!=undefined&&(options.chartRangeClipX||options.chartRangeMaxX>maxx)){maxx=options.chartRangeMaxX;}
14
+ var rangex=maxx-minx==0?1:maxx-minx;var rangey=maxy-miny==0?1:maxy-miny;var vl=yvalues.length-1;if(vl<1){this.innerHTML='';return;}
15
+ var target=$(this).simpledraw(width,height,options.composite);if(target){var canvas_width=target.pixel_width;var canvas_height=target.pixel_height;var canvas_top=0;var canvas_left=0;if(options.spotRadius&&(canvas_width<(options.spotRadius*4)||canvas_height<(options.spotRadius*4))){options.spotRadius=0;}
16
+ if(options.spotRadius){if(options.minSpotColor||(options.spotColor&&yvalues[vl]==miny))
17
+ canvas_height-=Math.ceil(options.spotRadius);if(options.maxSpotColor||(options.spotColor&&yvalues[vl]==maxy)){canvas_height-=Math.ceil(options.spotRadius);canvas_top+=Math.ceil(options.spotRadius);}
18
+ if(options.minSpotColor||options.maxSpotColor&&(yvalues[0]==miny||yvalues[0]==maxy)){canvas_left+=Math.ceil(options.spotRadius);canvas_width-=Math.ceil(options.spotRadius);}
19
+ if(options.spotColor||(options.minSpotColor||options.maxSpotColor&&(yvalues[vl]==miny||yvalues[vl]==maxy)))
20
+ canvas_width-=Math.ceil(options.spotRadius);}
21
+ canvas_height--;if(options.normalRangeMin!=undefined){var ytop=canvas_top+Math.round(canvas_height-(canvas_height*((options.normalRangeMax-miny)/rangey)));var height=Math.round((canvas_height*(options.normalRangeMax-options.normalRangeMin))/rangey);target.drawRect(canvas_left,ytop,canvas_width,height,undefined,options.normalRangeColor);}
22
+ var path=[];var paths=[path];for(var i=0,vlen=yvalues.length;i<vlen;i++){var x=xvalues[i],y=yvalues[i];if(y===null){if(i){if(yvalues[i-1]!==null){path=[];paths.push(path);}}}else{if(y<miny)y=miny;if(y>maxy)y=maxy;if(!path.length){path.push([canvas_left+Math.round((x-minx)*(canvas_width/rangex)),canvas_top+canvas_height]);}
23
+ path.push([canvas_left+Math.round((x-minx)*(canvas_width/rangex)),canvas_top+Math.round(canvas_height-(canvas_height*((y-miny)/rangey)))]);}}
24
+ for(var i=0,plen=paths.length;i<plen;i++){path=paths[i];if(!path.length)
25
+ continue;if(options.fillColor){path.push([path[path.length-1][0],canvas_top+canvas_height-1]);target.drawShape(path,undefined,options.fillColor);path.pop();}
26
+ if(path.length>2){path[0]=[path[0][0],path[1][1]];}
27
+ target.drawShape(path,options.lineColor,undefined,options.lineWidth);}
28
+ if(options.spotRadius&&options.spotColor){target.drawCircle(canvas_left+Math.round(xvalues[xvalues.length-1]*(canvas_width/rangex)),canvas_top+Math.round(canvas_height-(canvas_height*((yvalues[vl]-miny)/rangey))),options.spotRadius,undefined,options.spotColor);}
29
+ if(maxy!=minyval){if(options.spotRadius&&options.minSpotColor){var x=xvalues[yvalues.indexOf(minyval)];target.drawCircle(canvas_left+Math.round((x-minx)*(canvas_width/rangex)),canvas_top+Math.round(canvas_height-(canvas_height*((minyval-miny)/rangey))),options.spotRadius,undefined,options.minSpotColor);}
30
+ if(options.spotRadius&&options.maxSpotColor){var x=xvalues[yvalues.indexOf(maxyval)];target.drawCircle(canvas_left+Math.round((x-minx)*(canvas_width/rangex)),canvas_top+Math.round(canvas_height-(canvas_height*((maxyval-miny)/rangey))),options.spotRadius,undefined,options.maxSpotColor);}}}else{this.innerHTML='';}};$.fn.sparkline.bar=function(values,options,width,height){var options=$.extend({type:'bar',barColor:'#00f',negBarColor:'#f44',zeroColor:undefined,nullColor:undefined,zeroAxis:undefined,barWidth:4,barSpacing:1,chartRangeMax:undefined,chartRangeMin:undefined,chartRangeClip:false,colorMap:undefined},options?options:{});var width=(values.length*options.barWidth)+((values.length-1)*options.barSpacing);var num_values=[];for(var i=0,vlen=values.length;i<vlen;i++){if(values[i]=='null'||values[i]===null){values[i]=null;}else{values[i]=Number(values[i]);num_values.push(Number(values[i]));}}
31
+ var max=Math.max.apply(Math,num_values);var min=Math.min.apply(Math,num_values);if(options.chartRangeMin!=undefined&&(options.chartRangeClip||options.chartRangeMin<min)){min=options.chartRangeMin;}
32
+ if(options.chartRangeMax!=undefined&&(options.chartRangeClip||options.chartRangeMax>max)){max=options.chartRangeMax;}
33
+ if(options.zeroAxis==undefined)options.zeroAxis=min<0;var range=max-min==0?1:max-min;if($.isArray(options.colorMap)){var colorMapByIndex=options.colorMap;var colorMapByValue=null;}else{var colorMapByIndex=null;var colorMapByValue=options.colorMap;}
34
+ var target=$(this).simpledraw(width,height,options.composite);if(target){var canvas_width=target.pixel_width;var canvas_height=target.pixel_height;var yzero=min<0&&options.zeroAxis?canvas_height-Math.round(canvas_height*(Math.abs(min)/range))-1:canvas_height-1;for(var i=0,vlen=values.length;i<vlen;i++){var x=i*(options.barWidth+options.barSpacing);var val=values[i];if(val===null){if(options.nullColor){color=options.nullColor;val=(options.zeroAxis&&min<0)?0:min;var height=1;var y=(options.zeroAxis&&min<0)?yzero:canvas_height-height;}else{continue;}}else{if(val<min)val=min;if(val>max)val=max;var color=(val<0)?options.negBarColor:options.barColor;if(options.zeroAxis&&min<0){var height=Math.round(canvas_height*((Math.abs(val)/range)))+1;var y=(val<0)?yzero:yzero-height;}else{var height=Math.round(canvas_height*((val-min)/range))+1;var y=canvas_height-height;}
35
+ if(val==0&&options.zeroColor!=undefined){color=options.zeroColor;}
36
+ if(colorMapByValue&&colorMapByValue[val]){color=colorMapByValue[val];}else if(colorMapByIndex&&colorMapByIndex.length>i){color=colorMapByIndex[i];}
37
+ if(color===null){continue;}}
38
+ target.drawRect(x,y,options.barWidth-1,height-1,color,color);}}else{this.innerHTML='';}};$.fn.sparkline.tristate=function(values,options,width,height){values=$.map(values,Number);var options=$.extend({barWidth:4,barSpacing:1,posBarColor:'#6f6',negBarColor:'#f44',zeroBarColor:'#999',colorMap:{}},options);var width=(values.length*options.barWidth)+((values.length-1)*options.barSpacing);if($.isArray(options.colorMap)){var colorMapByIndex=options.colorMap;var colorMapByValue=null;}else{var colorMapByIndex=null;var colorMapByValue=options.colorMap;}
39
+ var target=$(this).simpledraw(width,height,options.composite);if(target){var canvas_width=target.pixel_width;var canvas_height=target.pixel_height;var half_height=Math.round(canvas_height/2);for(var i=0,vlen=values.length;i<vlen;i++){var x=i*(options.barWidth+options.barSpacing);if(values[i]<0){var y=half_height;var height=half_height-1;var color=options.negBarColor;}else if(values[i]>0){var y=0;var height=half_height-1;var color=options.posBarColor;}else{var y=half_height-1;var height=2;var color=options.zeroBarColor;}
40
+ if(colorMapByValue&&colorMapByValue[values[i]]){color=colorMapByValue[values[i]];}else if(colorMapByIndex&&colorMapByIndex.length>i){color=colorMapByIndex[i];}
41
+ if(color===null){continue;}
42
+ target.drawRect(x,y,options.barWidth-1,height-1,color,color);}}else{this.innerHTML='';}};$.fn.sparkline.discrete=function(values,options,width,height){values=$.map(values,Number);var options=$.extend({lineHeight:'auto',thresholdColor:undefined,thresholdValue:0,chartRangeMax:undefined,chartRangeMin:undefined,chartRangeClip:false},options);width=options.width=='auto'?values.length*2:width;var interval=Math.floor(width/values.length);var target=$(this).simpledraw(width,height,options.composite);if(target){var canvas_width=target.pixel_width;var canvas_height=target.pixel_height;var line_height=options.lineHeight=='auto'?Math.round(canvas_height*0.3):options.lineHeight;var pheight=canvas_height-line_height;var min=Math.min.apply(Math,values);var max=Math.max.apply(Math,values);if(options.chartRangeMin!=undefined&&(options.chartRangeClip||options.chartRangeMin<min)){min=options.chartRangeMin;}
43
+ if(options.chartRangeMax!=undefined&&(options.chartRangeClip||options.chartRangeMax>max)){max=options.chartRangeMax;}
44
+ var range=max-min;for(var i=0,vlen=values.length;i<vlen;i++){var val=values[i];if(val<min)val=min;if(val>max)val=max;var x=(i*interval);var ytop=Math.round(pheight-pheight*((val-min)/range));target.drawLine(x,ytop,x,ytop+line_height,(options.thresholdColor&&val<options.thresholdValue)?options.thresholdColor:options.lineColor);}}else{this.innerHTML='';}};$.fn.sparkline.bullet=function(values,options,width,height){values=$.map(values,Number);var options=$.extend({targetColor:'red',targetWidth:3,performanceColor:'blue',rangeColors:['#D3DAFE','#A8B6FF','#7F94FF'],base:undefined},options);width=options.width=='auto'?'4.0em':width;var target=$(this).simpledraw(width,height,options.composite);if(target&&values.length>1){var canvas_width=target.pixel_width-Math.ceil(options.targetWidth/2);var canvas_height=target.pixel_height;var min=Math.min.apply(Math,values);var max=Math.max.apply(Math,values);if(options.base==undefined){var min=min<0?min:0;}else{min=options.base;}
45
+ var range=max-min;for(i=2,vlen=values.length;i<vlen;i++){var rangeval=parseInt(values[i]);var rangewidth=Math.round(canvas_width*((rangeval-min)/range));target.drawRect(0,0,rangewidth-1,canvas_height-1,options.rangeColors[i-2],options.rangeColors[i-2]);}
46
+ var perfval=parseInt(values[1]);var perfwidth=Math.round(canvas_width*((perfval-min)/range));target.drawRect(0,Math.round(canvas_height*0.3),perfwidth-1,Math.round(canvas_height*0.4)-1,options.performanceColor,options.performanceColor);var targetval=parseInt(values[0]);var x=Math.round(canvas_width*((targetval-min)/range)-(options.targetWidth/2));var targettop=Math.round(canvas_height*0.10);var targetheight=canvas_height-(targettop*2);target.drawRect(x,targettop,options.targetWidth-1,targetheight-1,options.targetColor,options.targetColor);}else{this.innerHTML='';}};$.fn.sparkline.pie=function(values,options,width,height){values=$.map(values,Number);var options=$.extend({sliceColors:['#f00','#0f0','#00f']},options);width=options.width=='auto'?height:width;var target=$(this).simpledraw(width,height,options.composite);if(target&&values.length>1){var canvas_width=target.pixel_width;var canvas_height=target.pixel_height;var radius=Math.floor(Math.min(canvas_width,canvas_height)/2);var total=0;for(var i=0,vlen=values.length;i<vlen;i++)
47
+ total+=values[i];var next=0;if(options.offset){next+=(2*Math.PI)*(options.offset/360);}
48
+ var circle=2*Math.PI;for(var i=0,vlen=values.length;i<vlen;i++){var start=next;var end=next;if(total>0){end=next+(circle*(values[i]/total));}
49
+ target.drawPieSlice(radius,radius,radius,start,end,undefined,options.sliceColors[i%options.sliceColors.length]);next=end;}}};function quartile(values,q){if(q==2){var vl2=Math.floor(values.length/2);return values.length%2?values[vl2]:(values[vl2]+values[vl2+1])/2;}else{var vl4=Math.floor(values.length/4);return values.length%2?(values[vl4*q]+values[vl4*q+1])/2:values[vl4*q];}};$.fn.sparkline.box=function(values,options,width,height){values=$.map(values,Number);var options=$.extend({raw:false,boxLineColor:'black',boxFillColor:'#cdf',whiskerColor:'black',outlierLineColor:'#333',outlierFillColor:'white',medianColor:'red',showOutliers:true,outlierIQR:1.5,spotRadius:1.5,target:undefined,targetColor:'#4a2',chartRangeMax:undefined,chartRangeMin:undefined},options);width=options.width=='auto'?'4.0em':width;minvalue=options.chartRangeMin==undefined?Math.min.apply(Math,values):options.chartRangeMin;maxvalue=options.chartRangeMax==undefined?Math.max.apply(Math,values):options.chartRangeMax;var target=$(this).simpledraw(width,height,options.composite);if(target&&values.length>1){var canvas_width=target.pixel_width;var canvas_height=target.pixel_height;if(options.raw){if(options.showOutliers&&values.length>5){var loutlier=values[0],lwhisker=values[1],q1=values[2],q2=values[3],q3=values[4],rwhisker=values[5],routlier=values[6];}else{var lwhisker=values[0],q1=values[1],q2=values[2],q3=values[3],rwhisker=values[4];}}else{values.sort(function(a,b){return a-b;});var q1=quartile(values,1);var q2=quartile(values,2);var q3=quartile(values,3);var iqr=q3-q1;if(options.showOutliers){var lwhisker=undefined,rwhisker=undefined;for(var i=0,vlen=values.length;i<vlen;i++){if(lwhisker==undefined&&values[i]>q1-(iqr*options.outlierIQR))
50
+ lwhisker=values[i];if(values[i]<q3+(iqr*options.outlierIQR))
51
+ rwhisker=values[i];}
52
+ var loutlier=values[0];var routlier=values[values.length-1];}else{var lwhisker=values[0];var rwhisker=values[values.length-1];}}
53
+ var unitsize=canvas_width/(maxvalue-minvalue+1);var canvas_left=0;if(options.showOutliers){canvas_left=Math.ceil(options.spotRadius);canvas_width-=2*Math.ceil(options.spotRadius);var unitsize=canvas_width/(maxvalue-minvalue+1);if(loutlier<lwhisker)
54
+ target.drawCircle((loutlier-minvalue)*unitsize+canvas_left,canvas_height/2,options.spotRadius,options.outlierLineColor,options.outlierFillColor);if(routlier>rwhisker)
55
+ target.drawCircle((routlier-minvalue)*unitsize+canvas_left,canvas_height/2,options.spotRadius,options.outlierLineColor,options.outlierFillColor);}
56
+ target.drawRect(Math.round((q1-minvalue)*unitsize+canvas_left),Math.round(canvas_height*0.1),Math.round((q3-q1)*unitsize),Math.round(canvas_height*0.8),options.boxLineColor,options.boxFillColor);target.drawLine(Math.round((lwhisker-minvalue)*unitsize+canvas_left),Math.round(canvas_height/2),Math.round((q1-minvalue)*unitsize+canvas_left),Math.round(canvas_height/2),options.lineColor);target.drawLine(Math.round((lwhisker-minvalue)*unitsize+canvas_left),Math.round(canvas_height/4),Math.round((lwhisker-minvalue)*unitsize+canvas_left),Math.round(canvas_height-canvas_height/4),options.whiskerColor);target.drawLine(Math.round((rwhisker-minvalue)*unitsize+canvas_left),Math.round(canvas_height/2),Math.round((q3-minvalue)*unitsize+canvas_left),Math.round(canvas_height/2),options.lineColor);target.drawLine(Math.round((rwhisker-minvalue)*unitsize+canvas_left),Math.round(canvas_height/4),Math.round((rwhisker-minvalue)*unitsize+canvas_left),Math.round(canvas_height-canvas_height/4),options.whiskerColor);target.drawLine(Math.round((q2-minvalue)*unitsize+canvas_left),Math.round(canvas_height*0.1),Math.round((q2-minvalue)*unitsize+canvas_left),Math.round(canvas_height*0.9),options.medianColor);if(options.target){var size=Math.ceil(options.spotRadius);target.drawLine(Math.round((options.target-minvalue)*unitsize+canvas_left),Math.round((canvas_height/2)-size),Math.round((options.target-minvalue)*unitsize+canvas_left),Math.round((canvas_height/2)+size),options.targetColor);target.drawLine(Math.round((options.target-minvalue)*unitsize+canvas_left-size),Math.round(canvas_height/2),Math.round((options.target-minvalue)*unitsize+canvas_left+size),Math.round(canvas_height/2),options.targetColor);}}else{this.innerHTML='';}};if(!Array.prototype.indexOf){Array.prototype.indexOf=function(entry){for(var i=0,vlen=this.length;i<vlen;i++){if(this[i]==entry)
57
+ return i;}
58
+ return-1;}}
59
+ if($.browser.msie&&!document.namespaces['v']){document.namespaces.add('v','urn:schemas-microsoft-com:vml','#default#VML');}
60
+ if($.browser.hasCanvas==undefined){var t=document.createElement('canvas');$.browser.hasCanvas=t.getContext!=undefined;}
61
+ var vcanvas_base=function(width,height,target){};vcanvas_base.prototype={init:function(width,height,target){this.width=width;this.height=height;this.target=target;if(target[0])target=target[0];target.vcanvas=this;},drawShape:function(path,lineColor,fillColor,lineWidth){alert('drawShape not implemented');},drawLine:function(x1,y1,x2,y2,lineColor,lineWidth){return this.drawShape([[x1,y1],[x2,y2]],lineColor,lineWidth);},drawCircle:function(x,y,radius,lineColor,fillColor){alert('drawCircle not implemented');},drawPieSlice:function(x,y,radius,startAngle,endAngle,lineColor,fillColor){alert('drawPieSlice not implemented');},drawRect:function(x,y,width,height,lineColor,fillColor){alert('drawRect not implemented');},getElement:function(){return this.canvas;},_insert:function(el,target){$(target).html(el);}};var vcanvas_canvas=function(width,height,target){return this.init(width,height,target);};vcanvas_canvas.prototype=$.extend(new vcanvas_base,{_super:vcanvas_base.prototype,init:function(width,height,target){this._super.init(width,height,target);this.canvas=document.createElement('canvas');if(target[0])target=target[0];target.vcanvas=this;$(this.canvas).css({display:'inline-block',width:width,height:height,verticalAlign:'top'});this._insert(this.canvas,target);this.pixel_height=$(this.canvas).height();this.pixel_width=$(this.canvas).width();this.canvas.width=this.pixel_width;this.canvas.height=this.pixel_height;$(this.canvas).css({width:this.pixel_width,height:this.pixel_height});},_getContext:function(lineColor,fillColor,lineWidth){var context=this.canvas.getContext('2d');if(lineColor!=undefined)
62
+ context.strokeStyle=lineColor;context.lineWidth=lineWidth==undefined?1:lineWidth;if(fillColor!=undefined)
63
+ context.fillStyle=fillColor;return context;},drawShape:function(path,lineColor,fillColor,lineWidth){var context=this._getContext(lineColor,fillColor,lineWidth);context.beginPath();context.moveTo(path[0][0]+0.5,path[0][1]+0.5);for(var i=1,plen=path.length;i<plen;i++){context.lineTo(path[i][0]+0.5,path[i][1]+0.5);}
64
+ if(lineColor!=undefined){context.stroke();}
65
+ if(fillColor!=undefined){context.fill();}},drawCircle:function(x,y,radius,lineColor,fillColor){var context=this._getContext(lineColor,fillColor);context.beginPath();context.arc(x,y,radius,0,2*Math.PI,false);if(lineColor!=undefined){context.stroke();}
66
+ if(fillColor!=undefined){context.fill();}},drawPieSlice:function(x,y,radius,startAngle,endAngle,lineColor,fillColor){var context=this._getContext(lineColor,fillColor);context.beginPath();context.moveTo(x,y);context.arc(x,y,radius,startAngle,endAngle,false);context.lineTo(x,y);context.closePath();if(lineColor!=undefined){context.stroke();}
67
+ if(fillColor){context.fill();}},drawRect:function(x,y,width,height,lineColor,fillColor){return this.drawShape([[x,y],[x+width,y],[x+width,y+height],[x,y+height],[x,y]],lineColor,fillColor);}});var vcanvas_vml=function(width,height,target){return this.init(width,height,target);};vcanvas_vml.prototype=$.extend(new vcanvas_base,{_super:vcanvas_base.prototype,init:function(width,height,target){this._super.init(width,height,target);if(target[0])target=target[0];target.vcanvas=this;this.canvas=document.createElement('span');$(this.canvas).css({display:'inline-block',position:'relative',overflow:'hidden',width:width,height:height,margin:'0px',padding:'0px',verticalAlign:'top'});this._insert(this.canvas,target);this.pixel_height=$(this.canvas).height();this.pixel_width=$(this.canvas).width();this.canvas.width=this.pixel_width;this.canvas.height=this.pixel_height;;var groupel='<v:group coordorigin="0 0" coordsize="'+this.pixel_width+' '+this.pixel_height+'"'
68
+ +' style="position:absolute;top:0;left:0;width:'+this.pixel_width+'px;height='+this.pixel_height+'px;"></v:group>';this.canvas.insertAdjacentHTML('beforeEnd',groupel);this.group=$(this.canvas).children()[0];},drawShape:function(path,lineColor,fillColor,lineWidth){var vpath=[];for(var i=0,plen=path.length;i<plen;i++){vpath[i]=''+(path[i][0])+','+(path[i][1]);}
69
+ var initial=vpath.splice(0,1);lineWidth=lineWidth==undefined?1:lineWidth;var stroke=lineColor==undefined?' stroked="false" ':' strokeWeight="'+lineWidth+'" strokeColor="'+lineColor+'" ';var fill=fillColor==undefined?' filled="false"':' fillColor="'+fillColor+'" filled="true" ';var closed=vpath[0]==vpath[vpath.length-1]?'x ':'';var vel='<v:shape coordorigin="0 0" coordsize="'+this.pixel_width+' '+this.pixel_height+'" '
70
+ +stroke
71
+ +fill
72
+ +' style="position:absolute;left:0px;top:0px;height:'+this.pixel_height+'px;width:'+this.pixel_width+'px;padding:0px;margin:0px;" '
73
+ +' path="m '+initial+' l '+vpath.join(', ')+' '+closed+'e">'
74
+ +' </v:shape>';this.group.insertAdjacentHTML('beforeEnd',vel);},drawCircle:function(x,y,radius,lineColor,fillColor){x-=radius+1;y-=radius+1;var stroke=lineColor==undefined?' stroked="false" ':' strokeWeight="1" strokeColor="'+lineColor+'" ';var fill=fillColor==undefined?' filled="false"':' fillColor="'+fillColor+'" filled="true" ';var vel='<v:oval '
75
+ +stroke
76
+ +fill
77
+ +' style="position:absolute;top:'+y+'px; left:'+x+'px; width:'+(radius*2)+'px; height:'+(radius*2)+'px"></v:oval>';this.group.insertAdjacentHTML('beforeEnd',vel);},drawPieSlice:function(x,y,radius,startAngle,endAngle,lineColor,fillColor){if(startAngle==endAngle){return;}
78
+ if((endAngle-startAngle)==(2*Math.PI)){startAngle=0.0;endAngle=(2*Math.PI);}
79
+ var startx=x+Math.round(Math.cos(startAngle)*radius);var starty=y+Math.round(Math.sin(startAngle)*radius);var endx=x+Math.round(Math.cos(endAngle)*radius);var endy=y+Math.round(Math.sin(endAngle)*radius);if(startx==endx&&starty==endy&&(endAngle-startAngle)<Math.PI)
80
+ return;var vpath=[x-radius,y-radius,x+radius,y+radius,startx,starty,endx,endy];var stroke=lineColor==undefined?' stroked="false" ':' strokeWeight="1" strokeColor="'+lineColor+'" ';var fill=fillColor==undefined?' filled="false"':' fillColor="'+fillColor+'" filled="true" ';var vel='<v:shape coordorigin="0 0" coordsize="'+this.pixel_width+' '+this.pixel_height+'" '
81
+ +stroke
82
+ +fill
83
+ +' style="position:absolute;left:0px;top:0px;height:'+this.pixel_height+'px;width:'+this.pixel_width+'px;padding:0px;margin:0px;" '
84
+ +' path="m '+x+','+y+' wa '+vpath.join(', ')+' x e">'
85
  +' </v:shape>';this.group.insertAdjacentHTML('beforeEnd',vel);},drawRect:function(x,y,width,height,lineColor,fillColor){return this.drawShape([[x,y],[x,y+height],[x+width,y+height],[x+width,y],[x,y]],lineColor,fillColor);}});})(jQuery);
privacy.png ADDED
Binary file
readme.txt CHANGED
@@ -1,16 +1,17 @@
1
  === Google Analyticator ===
2
- Contributors: cavemonkey50
3
- Donate link: http://ronaldheft.com/code/donate/
4
  Tags: stats, statistics, google, analytics, google analytics, tracking, widget
5
- Requires at least: 2.7
6
- Tested up to: 3.2
7
- Stable tag: 6.2
8
 
9
  Adds the necessary JavaScript code to enable Google Analytics. Includes widgets for Analytics data display.
10
 
11
  == Description ==
12
 
13
- Google Analyticator adds the necessary JavaScript code to enable Google Analytics logging on any WordPress blog. This eliminates the need to edit your template code to begin logging. Google Analyticator also includes several widgets for displaying Analytics data in the admin and on your blog.
 
 
14
 
15
  = Features =
16
 
@@ -22,22 +23,30 @@ Google Analyticator Has the Following Features:
22
  - Supports outbound link tracking of all links on the page, including links not managed by WordPress
23
  - Supports download link tracking
24
  - Supports event tracking with outbound links / downloads instead of the old pageview tracking method
25
- - **NEW!** Support site speed tracking
26
  - Allows hiding of Administrator visits without affecting Google Analytics' site overlay feature
27
  - Supports any advanced tracking code Google provides
28
  - Installs easily - unlike other plugins, the user doesn't even have to know their Analytics UID
29
  - Provides complete control over options; disable any feature if needed
30
  - Supports localization - get the settings page in your language of choice
31
 
32
- For more information, visit the [Google Analyticator plugin page](http://ronaldheft.com/code/analyticator/).
 
 
 
 
33
 
34
  == Installation ==
35
 
36
- Please visit [Google Analyticator's support forum](http://forums.ronaldheft.com/viewtopic.php?f=5&t=17) for installation information.
 
 
37
 
38
  == Frequently Asked Questions ==
39
 
40
- Please visit [Google Analyticator's support forum](http://forums.ronaldheft.com/viewforum.php?f=5) for the latest FAQ information.
 
 
41
 
42
  == Screenshots ==
43
 
@@ -50,6 +59,27 @@ Please visit [Google Analyticator's support forum](http://forums.ronaldheft.com/
50
 
51
  == Changelog ==
52
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
53
  = 6.2 =
54
  * Adds a new option for site speed tracking (enabled by default).
55
  * Replaces deprecated tracking code _setVar with _setCustomVar.
1
  === Google Analyticator ===
2
+ Contributors: VideoUserManuals, cavemonkey50
 
3
  Tags: stats, statistics, google, analytics, google analytics, tracking, widget
4
+ Requires at least: 3.2
5
+ Tested up to: 3.4.2
6
+ Stable tag: 6.3.4
7
 
8
  Adds the necessary JavaScript code to enable Google Analytics. Includes widgets for Analytics data display.
9
 
10
  == Description ==
11
 
12
+ Google Analyticator is back! Google Analyticator adds the necessary JavaScript code to enable Google Analytics logging on any WordPress blog. This eliminates the need to edit your template code to begin logging. Google Analyticator also includes several widgets for displaying Analytics data in the admin and on your blog.
13
+
14
+ For a video explaining the simple installation process, please [visit the new home of Google Analyticator](http://www.videousermanuals.com/google-analyticator/).
15
 
16
  = Features =
17
 
23
  - Supports outbound link tracking of all links on the page, including links not managed by WordPress
24
  - Supports download link tracking
25
  - Supports event tracking with outbound links / downloads instead of the old pageview tracking method
26
+ - Support site speed tracking
27
  - Allows hiding of Administrator visits without affecting Google Analytics' site overlay feature
28
  - Supports any advanced tracking code Google provides
29
  - Installs easily - unlike other plugins, the user doesn't even have to know their Analytics UID
30
  - Provides complete control over options; disable any feature if needed
31
  - Supports localization - get the settings page in your language of choice
32
 
33
+ For more information, visit the [Google Analyticator plugin page](http://www.videousermanuals.com/google-analyticator/).
34
+
35
+ If you have a great idea on how to improve the plugin, we would love to hear from you at the [Google Analyticator Feature Request page](http://www.videousermanuals.com/google-analyticator/feature-request/)
36
+
37
+ A big thank you from the whole community to [Ronald](http://ronaldheft.com/) for all the hard work he put into this plugin.
38
 
39
  == Installation ==
40
 
41
+ Please visit the new home of [Google Analyticator](http://www.videousermanuals.com/google-analyticator/) for installation information.
42
+
43
+ If you are updating, you will need to Authenticate your site again, so it will work with the new Google API
44
 
45
  == Frequently Asked Questions ==
46
 
47
+ If you receive an error after authenticating, refresh the page, and it will work properly. This is a known issue, and we are working with Google to resolve it.
48
+
49
+ For any support issues, please use the official WordPress support forums.
50
 
51
  == Screenshots ==
52
 
59
 
60
  == Changelog ==
61
 
62
+ = 6.3.4 =
63
+ * Missing admin_url() causing issues with sub-directory installs.
64
+ * Legacy code removed causing API errors with old ga_profileid variable conflicting.
65
+ * Added Google App ID To tracking ID as supplied by Google Analytics team. This is just for Google's own reporting. We do not get access to any of your data.
66
+ * Added support for users who wont want to authenticate with Google, but just use tracking code
67
+ = 6.3.3 =
68
+ * Using the admin_url() function for internal links. Should help people with WP installed in a sub directory.
69
+ * Added all vars to reset function to delete / deauthorize from Google.
70
+
71
+ = 6.3.2 =
72
+ * Based on user issues. Improved error handling from Google APIs (some more to go)
73
+ * Removed Javascript box on activation due to user issues
74
+ * Protected URITemplateParser class from being re-declared
75
+ * Added Reset option on plugin screen to allow re-authentication
76
+
77
+ = 6.3.1 =
78
+ * Small bug on upgrades patched
79
+
80
+ = 6.3 =
81
+ * Updated to authenticate with the new Google API
82
+
83
  = 6.2 =
84
  * Adds a new option for site speed tracking (enabled by default).
85
  * Replaces deprecated tracking code _setVar with _setCustomVar.
wlcms-plugin-advert.png ADDED
Binary file