ManageWP Worker - Version 4.9.9

Version Description

  • Fix: Resolved edge case compatibility issue with some sites
  • New: Added "Disconnect all" option in the Connection Management in wp-admin
  • Worker update tested to the latest version of WordPress
  • Minor wording changes
Download this release

Release Info

Developer freediver
Plugin Icon 128x128 ManageWP Worker
Version 4.9.9
Comparing to
See all releases

Code changes from version 4.1.0 to 4.9.9

Files changed (103) hide show
  1. functions.php +684 -1023
  2. index.html +0 -0
  3. index.php +2 -0
  4. init.php +538 -48
  5. publickeys/ManageWP_mt.pub +0 -9
  6. publickeys/godaddy_g2_root.cer +25 -0
  7. publickeys/index.php +2 -0
  8. readme.txt +158 -341
  9. src/Dropbox/AppInfo.php +0 -262
  10. src/Dropbox/AppInfoLoadException.php +0 -17
  11. src/Dropbox/ArrayEntryStore.php +0 -60
  12. src/Dropbox/AuthBase.php +0 -83
  13. src/Dropbox/AuthInfo.php +0 -85
  14. src/Dropbox/AuthInfoLoadException.php +0 -17
  15. src/Dropbox/Checker.php +0 -139
  16. src/Dropbox/Client.php +0 -1681
  17. src/Dropbox/Closure/ChunkedUploadContinueAction.php +0 -28
  18. src/Dropbox/Closure/ChunkedUploadFinishAction.php +0 -25
  19. src/Dropbox/Closure/ChunkedUploadStartAction.php +0 -22
  20. src/Dropbox/Closure/CurlConfigInStream.php +0 -24
  21. src/Dropbox/Closure/CurlConfigInterface.php +0 -6
  22. src/Dropbox/Closure/CurlConfigOctetStream.php +0 -18
  23. src/Dropbox/Closure/ReRunnableActionInterface.php +0 -6
  24. src/Dropbox/Curl.php +0 -116
  25. src/Dropbox/CurlStreamRelay.php +0 -44
  26. src/Dropbox/DeserializeException.php +0 -18
  27. src/Dropbox/DropboxMetadataHeaderCatcher.php +0 -88
  28. src/Dropbox/Exception.php +0 -31
  29. src/Dropbox/Exception/BadRequest.php +0 -16
  30. src/Dropbox/Exception/BadResponse.php +0 -16
  31. src/Dropbox/Exception/BadResponseCode.php +0 -32
  32. src/Dropbox/Exception/InvalidAccessToken.php +0 -17
  33. src/Dropbox/Exception/NetworkIO.php +0 -15
  34. src/Dropbox/Exception/ProtocolError.php +0 -16
  35. src/Dropbox/Exception/RetryLater.php +0 -16
  36. src/Dropbox/Exception/ServerError.php +0 -14
  37. src/Dropbox/Host.php +0 -115
  38. src/Dropbox/HttpResponse.php +0 -16
  39. src/Dropbox/OAuth1AccessToken.php +0 -68
  40. src/Dropbox/OAuth1Upgrader.php +0 -106
  41. src/Dropbox/Path.php +0 -201
  42. src/Dropbox/RequestUtil.php +0 -308
  43. src/Dropbox/SSLTester.php +0 -112
  44. src/Dropbox/Security.php +0 -71
  45. src/Dropbox/StreamReadException.php +0 -15
  46. src/Dropbox/ValueStore.php +0 -60
  47. src/Dropbox/WebAuth.php +0 -281
  48. src/Dropbox/WebAuthBase.php +0 -64
  49. src/Dropbox/WebAuthException/BadRequest.php +0 -19
  50. src/Dropbox/WebAuthException/BadState.php +0 -18
  51. src/Dropbox/WebAuthException/Csrf.php +0 -20
  52. src/Dropbox/WebAuthException/NotApproved.php +0 -17
  53. src/Dropbox/WebAuthException/Provider.php +0 -17
  54. src/Dropbox/WebAuthNoRedirect.php +0 -82
  55. src/Dropbox/WriteMode.php +0 -126
  56. src/Dropbox/certs/trusted-certs.crt +0 -1396
  57. src/Gelf/Publisher.php +55 -35
  58. src/Gelf/index.php +2 -0
  59. src/Google/ApiClient.php +0 -629
  60. src/Google/ApiException.php +0 -21
  61. src/Google/ApiModel.php +0 -257
  62. src/Google/ApiService.php +0 -41
  63. src/Google/ApiUtils.php +0 -146
  64. src/Google/Auth/Abstract.php +0 -46
  65. src/Google/Auth/AssertionCredentials.php +0 -135
  66. src/Google/Auth/Exception.php +0 -21
  67. src/Google/Auth/LoginTicket.php +0 -69
  68. src/Google/Auth/OAuth2.php +0 -592
  69. src/Google/Auth/Simple.php +0 -93
  70. src/Google/Cache/Abstract.php +0 -52
  71. src/Google/Cache/Apc.php +0 -73
  72. src/Google/Cache/Exception.php +0 -21
  73. src/Google/Cache/File.php +0 -147
  74. src/Google/Cache/Memcache.php +0 -139
  75. src/Google/Cache/Null.php +0 -53
  76. src/Google/Collection.php +0 -96
  77. src/Google/Config.php +0 -322
  78. src/Google/Http/Batch.php +0 -140
  79. src/Google/Http/CacheParser.php +0 -190
  80. src/Google/Http/MediaFileUpload.php +0 -280
  81. src/Google/Http/REST.php +0 -148
  82. src/Google/Http/Request.php +0 -488
  83. src/Google/IO/Abstract.php +0 -341
  84. src/Google/IO/Curl.php +0 -133
  85. src/Google/IO/Exception.php +0 -21
  86. src/Google/IO/Stream.php +0 -179
  87. src/Google/IO/cacerts.pem +0 -738
  88. src/Google/Service/Drive.php +0 -5888
  89. src/Google/Service/Exception.php +0 -52
  90. src/Google/Service/Oauth2.php +0 -411
  91. src/Google/Service/Resource.php +0 -209
  92. src/Google/Signer/Abstract.php +0 -29
  93. src/Google/Signer/P12.php +0 -88
  94. src/Google/Utils/URITemplate.php +0 -375
  95. src/Google/Verifier/Abstract.php +0 -30
  96. src/Google/Verifier/Pem.php +0 -74
  97. src/LICENSE +0 -260
  98. src/MMB/Backup.php +0 -4612
  99. src/MMB/Comment.php +0 -106
  100. src/MMB/Container.php +0 -72
  101. src/MMB/Core.php +193 -183
  102. src/MMB/Exception.php +0 -9
  103. src/MMB/Helper.php +0 -303
functions.php CHANGED
@@ -2,13 +2,11 @@
2
 
3
  function mwp_autoload($class)
4
  {
5
- if (substr($class, 0, 8) === 'Dropbox_'
6
- || substr($class, 0, 8) === 'Symfony_'
7
  || substr($class, 0, 8) === 'Monolog_'
8
  || substr($class, 0, 5) === 'Gelf_'
9
  || substr($class, 0, 4) === 'MWP_'
10
  || substr($class, 0, 4) === 'MMB_'
11
- || substr($class, 0, 3) === 'S3_'
12
  ) {
13
  $file = dirname(__FILE__).'/src/'.str_replace('_', '/', $class).'.php';
14
  if (file_exists($file)) {
@@ -17,33 +15,6 @@ function mwp_autoload($class)
17
  }
18
  }
19
 
20
- function mwp_register_autoload_google()
21
- {
22
- static $registered;
23
-
24
- if ($registered) {
25
- return;
26
- } else {
27
- $registered = true;
28
- }
29
-
30
- if (version_compare(PHP_VERSION, '5.3', '<')) {
31
- spl_autoload_register('mwp_autoload_google');
32
- } else {
33
- spl_autoload_register('mwp_autoload_google', true, true);
34
- }
35
- }
36
-
37
- function mwp_autoload_google($class)
38
- {
39
- if (substr($class, 0, 7) === 'Google_') {
40
- $file = dirname(__FILE__).'/src/'.str_replace('_', '/', $class).'.php';
41
- if (file_exists($file)) {
42
- include_once $file;
43
- }
44
- }
45
- }
46
-
47
  /**
48
  * @return Monolog_Psr_LoggerInterface
49
  */
@@ -60,30 +31,14 @@ function mwp_context()
60
  return mwp_container()->getWordPressContext();
61
  }
62
 
63
- /**
64
- * @param $appKey
65
- * @param $appSecret
66
- * @param $token
67
- * @param $tokenSecret
68
- *
69
- * @return Dropbox_Client
70
- */
71
- function mwp_dropbox_oauth_factory($appKey, $appSecret, $token, $tokenSecret = null)
72
  {
73
- if ($tokenSecret) {
74
- $oauthToken = 'OAuth oauth_version="1.0", oauth_signature_method="PLAINTEXT", oauth_consumer_key="'.$appKey.'", oauth_token="'.$token.'", oauth_signature="'.$appSecret.'&'.$tokenSecret.'"';
75
- $clientIdentifier = $token;
76
- } else {
77
- $oauthToken = 'Bearer '.$token;
78
- $clientIdentifier = 'PHP-ManageWp/1.0';
79
- }
80
-
81
- return new Dropbox_Client($oauthToken, $clientIdentifier);
82
  }
83
 
84
  function mwp_format_memory_limit($limit)
85
  {
86
- if ((string) (int) $limit === (string) $limit) {
87
  // The number is numeric.
88
  return mwp_format_bytes($limit);
89
  }
@@ -97,7 +52,7 @@ function mwp_format_memory_limit($limit)
97
 
98
  $number = substr($limit, 0, -1);
99
 
100
- if ((string) (int) $number !== $number) {
101
  // The number isn't numeric.
102
  return $number;
103
  }
@@ -117,7 +72,7 @@ function mwp_format_memory_limit($limit)
117
 
118
  function mwp_format_bytes($bytes)
119
  {
120
- $bytes = (int) $bytes;
121
 
122
  if ($bytes > 1024 * 1024 * 1024) {
123
  return round($bytes / 1024 / 1024 / 1024, 2).' GB';
@@ -130,39 +85,10 @@ function mwp_format_bytes($bytes)
130
  return $bytes.' B';
131
  }
132
 
133
- function mwp_log_warnings()
134
- {
135
- // If mbstring.func_overload is set, it changes the behavior of the standard string functions in
136
- // ways that makes external libraries like Dropbox break.
137
- $mbstring_func_overload = ini_get("mbstring.func_overload");
138
- if ($mbstring_func_overload & 2 == 2) {
139
- mwp_logger()->warning('"mbstring.func_overload" changes the behavior of the standard string functions in ways that makes external libraries like Dropbox break');
140
- }
141
-
142
- if (strlen((string) PHP_INT_MAX) < 19) {
143
- // Looks like we're running on a 32-bit build of PHP. This could cause problems because some of the numbers
144
- // we use (file sizes, quota, etc) can be larger than 32-bit ints can handle.
145
- mwp_logger()->warning("Some external libraries rely on 64-bit integers, but it looks like we're running on a version of PHP that doesn't support 64-bit integers (PHP_INT_MAX=".((string) PHP_INT_MAX).").");
146
- }
147
- }
148
-
149
- function mmb_get_extended_info($stats)
150
- {
151
- $params = get_option('mmb_stats_filter');
152
- $filter = isset($params['plugins']['cleanup']) ? $params['plugins']['cleanup'] : array();
153
- $stats['num_revisions'] = mmb_num_revisions($filter['revisions']);
154
- //$stats['num_revisions'] = 5;
155
- $stats['overhead'] = mmb_handle_overhead(false);
156
- $stats['num_spam_comments'] = mmb_num_spam_comments();
157
-
158
- return $stats;
159
- }
160
-
161
- /* Revisions */
162
  function cleanup_delete_worker($params = array())
163
  {
164
  $revision_params = get_option('mmb_stats_filter');
165
- $revision_filter = isset($revision_params['plugins']['cleanup']) ? $revision_params['plugins']['cleanup'] : array();
166
 
167
  $params_array = explode('_', $params['actions']);
168
  $return_array = array();
@@ -170,7 +96,7 @@ function cleanup_delete_worker($params = array())
170
  foreach ($params_array as $param) {
171
  switch ($param) {
172
  case 'revision':
173
- if (mmb_delete_all_revisions($revision_filter['revisions'])) {
174
  $return_array['revision'] = 'OK';
175
  } else {
176
  $return_array['revision_error'] = 'OK, nothing to do';
@@ -200,128 +126,86 @@ function cleanup_delete_worker($params = array())
200
  mmb_response($return_array, true);
201
  }
202
 
203
- function mmb_num_revisions($filter)
204
  {
205
  global $wpdb;
206
 
207
- $allRevisions = $wpdb->get_results("SELECT ID, post_name FROM {$wpdb->posts} WHERE post_type = 'revision'", ARRAY_A);
208
 
209
- $revisionsToDelete = 0;
210
- $revisionsToKeepCount = array();
211
-
212
- if (isset($filter['num_to_keep']) && !empty($filter['num_to_keep'])) {
213
- $num_rev = str_replace("r_", "", $filter['num_to_keep']);
214
-
215
- foreach ($allRevisions as $revision) {
216
- $revisionsToKeepCount[$revision['post_name']] = isset($revisionsToKeepCount[$revision['post_name']])
217
- ? $revisionsToKeepCount[$revision['post_name']] + 1
218
- : 1;
219
-
220
- if ($revisionsToKeepCount[$revision['post_name']] > $num_rev) {
221
- ++$revisionsToDelete;
222
- }
223
- }
224
- } else {
225
- $revisionsToDelete = count($allRevisions);
226
- }
227
-
228
- return $revisionsToDelete;
229
- }
230
-
231
- function mmb_select_all_revisions()
232
- {
233
- global $wpdb;
234
- $sql = "SELECT * FROM $wpdb->posts WHERE post_type = 'revision'";
235
- $revisions = $wpdb->get_results($sql);
236
-
237
- return $revisions;
238
  }
239
 
240
  function mmb_delete_all_revisions($filter)
241
  {
242
  global $wpdb;
243
- $where = '';
244
- $keep = isset($filter['num_to_keep']) ? $filter['num_to_keep'] : false;
245
- if ($keep) {
246
- $num_rev = str_replace("r_", "", $keep);
247
- $allRevisions = $wpdb->get_results("SELECT ID, post_name FROM {$wpdb->posts} WHERE post_type = 'revision' ORDER BY post_date DESC", ARRAY_A);
248
- $revisionsToKeep = array(0 => 0);
249
- $revisionsToKeepCount = array();
250
-
251
- foreach ($allRevisions as $revision) {
252
- $revisionsToKeepCount[$revision['post_name']] = isset($revisionsToKeepCount[$revision['post_name']])
253
- ? $revisionsToKeepCount[$revision['post_name']] + 1
254
- : 1;
255
-
256
- if ($revisionsToKeepCount[$revision['post_name']] <= $num_rev) {
257
- $revisionsToKeep[] = $revision['ID'];
258
- }
259
- }
260
 
261
- $notInQuery = join(', ', $revisionsToKeep);
 
 
262
 
263
- $where = "AND a.ID NOT IN ({$notInQuery})";
 
264
  }
265
 
266
- $sql = "DELETE a,b,c FROM $wpdb->posts a LEFT JOIN $wpdb->term_relationships b ON (a.ID = b.object_id) LEFT JOIN $wpdb->postmeta c ON (a.ID = c.post_id) WHERE a.post_type = 'revision' {$where}";
 
 
 
 
 
 
 
 
 
 
267
 
268
- $revisions = $wpdb->query($sql);
 
 
269
 
270
- return $revisions;
271
  }
272
 
273
  function mmb_handle_overhead($clear = false)
274
  {
275
  /** @var wpdb $wpdb */
276
  global $wpdb;
277
- $query = 'SHOW TABLE STATUS';
278
- $tables = $wpdb->get_results($query, ARRAY_A);
279
- $total_gain = 0;
280
- $table_string = '';
 
281
  foreach ($tables as $table) {
282
- if (isset($table['Engine']) && $table['Engine'] === 'MyISAM') {
283
- if ($wpdb->base_prefix != $wpdb->prefix) {
284
- if (preg_match('/^'.$wpdb->prefix.'*/Ui', $table['Name'])) {
285
- if ($table['Data_free'] > 0) {
286
- $total_gain += $table['Data_free'] / 1024;
287
- $table_string .= $table['Name'].",";
288
- }
289
- }
290
- } else {
291
- if (preg_match('/^'.$wpdb->prefix.'[0-9]{1,20}_*/Ui', $table['Name'])) {
292
- continue;
293
- } else {
294
- if ($table['Data_free'] > 0) {
295
- $total_gain += $table['Data_free'] / 1024;
296
- $table_string .= $table['Name'].",";
297
- }
298
- }
299
- }
300
- // @todo check if the cleanup was successful, if not, set a flag always skip innodb cleanup
301
- //} elseif (isset($table['Engine']) && $table['Engine'] == 'InnoDB') {
302
- // $innodb_file_per_table = $wpdb->get_results("SHOW VARIABLES LIKE 'innodb_file_per_table'");
303
- // if (isset($innodb_file_per_table[0]->Value) && $innodb_file_per_table[0]->Value === "ON") {
304
- // if ($table['Data_free'] > 0) {
305
- // $total_gain += $table['Data_free'] / 1024;
306
- // $table_string .= $table['Name'].",";
307
- // }
308
- // }
309
  }
 
 
 
 
 
 
 
 
 
 
 
310
  }
311
 
312
- if ($clear) {
313
- $table_string = substr($table_string, 0, strlen($table_string) - 1); //remove last ,
314
- $table_string = rtrim($table_string);
315
- $query = "OPTIMIZE TABLE $table_string";
316
- $optimize = $wpdb->query($query);
317
 
318
- return (bool) $optimize;
319
- } else {
320
- return round($total_gain, 3);
321
  }
 
 
322
  }
323
 
324
- /* Spam Comments */
325
  function mmb_num_spam_comments()
326
  {
327
  global $wpdb;
@@ -337,29 +221,37 @@ function mmb_delete_spam_comments()
337
  $spam = 1;
338
  $total = 0;
339
  while (!empty($spam)) {
340
- $getCommentIds = "SELECT comment_ID FROM $wpdb->comments WHERE comment_approved = 'spam' LIMIT 200";
341
- $spam = $wpdb->get_results($getCommentIds);
 
 
 
 
 
 
342
  foreach ($spam as $comment) {
343
- wp_delete_comment($comment->comment_ID, true);
 
 
 
 
 
 
344
  }
 
 
 
 
 
345
  $total += count($spam);
346
  if (!empty($spam)) {
347
- usleep(100000);
348
  }
349
  }
350
 
351
  return $total;
352
  }
353
 
354
- function mmb_get_spam_comments()
355
- {
356
- global $wpdb;
357
- $sql = "SELECT * FROM $wpdb->comments as a LEFT JOIN $wpdb->commentmeta as b WHERE a.comment_ID = b.comment_id AND a.comment_approved = 'spam'";
358
- $spams = $wpdb->get_results($sql);
359
-
360
- return $spams;
361
- }
362
-
363
  function mwp_is_nio_shell_available()
364
  {
365
  static $check;
@@ -390,13 +282,11 @@ function mwp_is_shell_available()
390
  return false;
391
  }
392
 
393
- if (extension_loaded('suhosin') && $suhosin = ini_get('suhosin.executor.func.blacklist')) {
394
- $suhosin = explode(',', $suhosin);
395
- $blacklist = array_map('trim', $suhosin);
396
- $blacklist = array_map('strtolower', $blacklist);
397
- if (in_array('proc_open', $blacklist)) {
398
- return false;
399
- }
400
  }
401
 
402
  if (!mwp_is_nio_shell_available()) {
@@ -419,101 +309,13 @@ function mwp_get_disabled_functions()
419
  function mwp_is_safe_mode()
420
  {
421
  $value = ini_get("safe_mode");
422
- if ((int) $value === 0 || strtolower($value) === "off") {
423
  return false;
424
  }
425
 
426
  return true;
427
  }
428
 
429
- // Everything below was moved from init.php
430
-
431
- function mmb_parse_request()
432
- {
433
- global $mmb_core, $wp_db_version, $_wp_using_ext_object_cache, $_mwp_data, $_mwp_auth;
434
- $_wp_using_ext_object_cache = false;
435
- @set_time_limit(1200);
436
-
437
- if (isset($_mwp_data['setting'])) {
438
- if (array_key_exists("dataown", $_mwp_data['setting'])) {
439
- $oldconfiguration = array("dataown" => $_mwp_data['setting']['dataown']);
440
- $mmb_core->save_options($oldconfiguration);
441
- unset($_mwp_data['setting']['dataown']);
442
- }
443
-
444
- $configurationService = new MWP_Configuration_Service();
445
- $configuration = new MWP_Configuration_Conf($_mwp_data['setting']);
446
- $configurationService->saveConfiguration($configuration);
447
- }
448
-
449
- if ($_mwp_data['action'] === 'add_site') {
450
- mmb_add_site($_mwp_data['params']);
451
- mmb_response('You should never see this.', false);
452
- }
453
-
454
- /* in case database upgrade required, do database backup and perform upgrade ( wordpress wp_upgrade() function ) */
455
- if (strlen(trim($wp_db_version)) && !defined('ACX_PLUGIN_DIR')) {
456
- if (get_option('db_version') != $wp_db_version) {
457
- /* in multisite network, please update database manualy */
458
- if (!is_multisite()) {
459
- if (!function_exists('wp_upgrade')) {
460
- include_once ABSPATH.'wp-admin/includes/upgrade.php';
461
- }
462
-
463
- ob_clean();
464
- @wp_upgrade();
465
- @do_action('after_db_upgrade');
466
- ob_end_clean();
467
- }
468
- }
469
- }
470
-
471
- if (isset($_mwp_data['params']['secure'])) {
472
- if (is_array($_mwp_data['params']['secure'])) {
473
- $secureParams = $_mwp_data['params']['secure'];
474
- foreach ($secureParams as $key => $value) {
475
- $secureParams[$key] = base64_decode($value);
476
- }
477
- $_mwp_data['params']['secure'] = $secureParams;
478
- } else {
479
- $_mwp_data['params']['secure'] = base64_decode($_mwp_data['params']['secure']);
480
- }
481
- if ($decrypted = $mmb_core->_secure_data($_mwp_data['params']['secure'])) {
482
- $decrypted = maybe_unserialize($decrypted);
483
- if (is_array($decrypted)) {
484
- foreach ($decrypted as $key => $val) {
485
- if (!is_numeric($key)) {
486
- $_mwp_data['params'][$key] = $val;
487
- }
488
- }
489
- unset($_mwp_data['params']['secure']);
490
- } else {
491
- $_mwp_data['params']['secure'] = $decrypted;
492
- }
493
- }
494
-
495
- if (!$decrypted && $mmb_core->get_random_signature() !== false) {
496
- require_once dirname(__FILE__).'/src/PHPSecLib/Crypt/AES.php';
497
- $cipher = new Crypt_AES(CRYPT_AES_MODE_ECB);
498
- $cipher->setKey($mmb_core->get_random_signature());
499
- $decrypted = $cipher->decrypt($_mwp_data['params']['secure']);
500
- $_mwp_data['params']['account_info'] = json_decode($decrypted, true);
501
- }
502
- }
503
-
504
- $logData = array(
505
- 'action' => $_mwp_data['action'],
506
- 'action_parameters' => $_mwp_data['params'],
507
- 'action_settings' => $_mwp_data['setting'],
508
- );
509
-
510
- if (!empty($_mwp_data['setting'])) {
511
- $logData['settings'] = $_mwp_data['setting'];
512
- }
513
-
514
- mwp_logger()->debug('Master request: "{action}"', $logData);
515
- }
516
-
517
  function mmb_response($response = false, $success = true)
518
  {
519
  if (!$success) {
@@ -528,975 +330,834 @@ function mmb_response($response = false, $success = true)
528
 
529
  function mmb_remove_site($params)
530
  {
531
- extract($params);
532
- global $mmb_core;
533
- $mmb_core->deactivate($deactivate);
534
-
535
- include_once ABSPATH.'wp-admin/includes/plugin.php';
536
- $plugin_slug = 'worker/init.php';
537
 
538
- if ($deactivate) {
539
- deactivate_plugins($plugin_slug, true);
540
- } else {
541
- // Prolong the worker deactivation upon site removal.
542
- update_option('mmb_worker_activation_time', time());
543
- }
544
-
545
- if (!is_plugin_active($plugin_slug)) {
546
- mmb_response(
547
- array(
548
- 'deactivated' => 'Site removed successfully. <br /><br />ManageWP Worker plugin successfully deactivated.',
549
- ),
550
- true
551
- );
552
- } else {
553
- mmb_response(
554
- array(
555
- 'removed_data' => 'Site removed successfully. <br /><br /><b>ManageWP Worker plugin was not deactivated.</b>',
556
- ),
557
- true
558
- );
559
- }
560
  }
561
 
562
- function mmb_stats_get($params)
563
  {
564
- global $mmb_core;
565
- $mmb_core->get_stats_instance();
566
-
567
  mwp_context()->requireWpRewrite();
568
  mwp_context()->requireTaxonomies();
569
  mwp_context()->requirePostTypes();
570
  mwp_context()->requireTheme();
571
 
572
- $data = array_merge(mmb_pre_init_stats($params), $mmb_core->stats_instance->get($params));
573
- mmb_response($data, true);
 
 
574
  }
575
 
576
- function mmb_worker_header()
577
  {
578
- global $mmb_core, $current_user;
579
-
580
- if (!headers_sent()) {
581
- if (isset($current_user->ID)) {
582
- $expiration = time() + apply_filters('auth_cookie_expiration', 10800, $current_user->ID, false);
583
- } else {
584
- $expiration = time() + 10800;
 
585
  }
586
-
587
- setcookie(MMB_XFRAME_COOKIE, md5(MMB_XFRAME_COOKIE), $expiration, COOKIEPATH, COOKIE_DOMAIN, false, true);
588
- $_COOKIE[MMB_XFRAME_COOKIE] = md5(MMB_XFRAME_COOKIE);
 
589
  }
590
  }
591
 
592
- function mmb_pre_init_stats($params)
593
  {
594
- global $mmb_core;
595
-
596
- mwp_context()->requireWpRewrite();
597
- mwp_context()->requireTaxonomies();
598
- mwp_context()->requirePostTypes();
599
  mwp_context()->requireTheme();
600
-
601
- $mmb_core->get_stats_instance();
602
-
603
- return $mmb_core->stats_instance->pre_init_stats($params);
604
  }
605
 
606
- function mwp_datasend($params = array())
607
  {
608
- global $mmb_core, $_mmb_item_filter, $_mmb_options;
609
-
610
- $_mmb_remoteurl = get_option('home');
611
- $_mmb_remoteown = isset($_mmb_options['dataown']) && !empty($_mmb_options['dataown']) ? $_mmb_options['dataown'] : false;
612
 
613
- if (empty($_mmb_remoteown)) {
614
- return;
 
 
 
 
 
615
  }
 
616
 
617
- $_mmb_item_filter['pre_init_stats'] = array('core_update', 'hit_counter', 'comments', 'backups', 'posts', 'drafts', 'scheduled', 'site_statistics');
618
- $_mmb_item_filter['get'] = array('updates', 'errors');
619
- $mmb_core->get_stats_instance();
620
-
621
- $filter = array(
622
- 'refresh' => 'transient',
623
- 'item_filter' => array(
624
- 'get_stats' => array(
625
- array('updates', array('plugins' => true, 'themes' => true, 'premium' => true)),
626
- array('core_update', array('core' => true)),
627
- array('posts', array('numberposts' => 5)),
628
- array('drafts', array('numberposts' => 5)),
629
- array('scheduled', array('numberposts' => 5)),
630
- array('hit_counter'),
631
- array('comments', array('numberposts' => 5)),
632
- array('backups'),
633
- 'plugins' => array(
634
- 'cleanup' => array(
635
- 'overhead' => array(),
636
- 'revisions' => array('num_to_keep' => 'r_5'),
637
- 'spam' => array(),
638
- ),
639
- ),
640
- ),
641
- ),
642
- );
643
-
644
- $pre_init_data = $mmb_core->stats_instance->pre_init_stats($filter);
645
- $init_data = $mmb_core->stats_instance->get($filter);
646
-
647
- $data = array_merge($init_data, $pre_init_data);
648
- $data['server_ip'] = $_SERVER['SERVER_ADDR'];
649
- $data['uhost'] = php_uname('n');
650
- $hash = $mmb_core->get_secure_hash();
651
-
652
- if (mwp_datasend_trigger($data)) { // adds trigger to check if really need to send something
653
- $configurationService = new MWP_Configuration_Service();
654
- $configuration = $configurationService->getConfiguration();
655
-
656
- set_transient("mwp_cache_notifications", $data);
657
- set_transient("mwp_cache_notifications_time", time());
658
-
659
- $datasend['datasend'] = $mmb_core->encrypt_data($data);
660
- $datasend['sitehome'] = base64_encode($_mmb_remoteown.'[]'.$_mmb_remoteurl);
661
- $datasend['sitehash'] = md5($hash.$_mmb_remoteown.$_mmb_remoteurl);
662
- $datasend['setting_checksum_order'] = implode(",", array_keys($configuration->getVariables()));
663
- $datasend['setting_checksum'] = md5(json_encode($configuration->toArray()));
664
- if (!class_exists('WP_Http')) {
665
- include_once ABSPATH.WPINC.'/class-http.php';
666
- }
667
-
668
- $remote = array();
669
- $remote['body'] = $datasend;
670
- $remote['timeout'] = 20;
671
-
672
- $result = wp_remote_post($configuration->getMasterCronUrl(), $remote);
673
- if (!is_wp_error($result)) {
674
- if (isset($result['body']) && !empty($result['body'])) {
675
- $settings = @unserialize($result['body']);
676
- /* rebrand worker or set default */
677
- $brand = '';
678
- if ($settings['worker_brand']) {
679
- $brand = $settings['worker_brand'];
680
- }
681
- update_option("mwp_worker_brand", $brand);
682
- /* change worker version */
683
- $w_version = @$settings['worker_updates']['version'];
684
- $w_url = @$settings['worker_updates']['url'];
685
- if (version_compare($GLOBALS['MMB_WORKER_VERSION'], $w_version, '<')) {
686
- //automatic update
687
- $mmb_core->update_worker_plugin(array("download_url" => $w_url));
688
- }
689
-
690
- if (!empty($settings['mwp_worker_configuration'])) {
691
- require_once dirname(__FILE__).'/src/PHPSecLib/Crypt/RSA.php';
692
- $rsa = new Crypt_RSA();
693
- $keyName = $configuration->getKeyName();
694
- $rsa->setSignatureMode(CRYPT_RSA_SIGNATURE_PKCS1);
695
- $rsa->loadKey(file_get_contents(dirname(__FILE__)."/publickeys/$keyName.pub")); // public key
696
- $signature = base64_decode($settings['mwp_worker_configuration_signature']);
697
- if ($rsa->verify(json_encode($settings['mwp_worker_configuration']), $signature)) {
698
- $configuration = new MWP_Configuration_Conf($settings['mwp_worker_configuration']);
699
- $configurationService->saveConfiguration($configuration);
700
- }
701
- }
702
- }
703
- } else {
704
- //$mmb_core->_log($result);
705
- }
706
  }
707
  }
708
 
709
- // trigger function, returns true if notifications should be sent
710
- function mwp_datasend_trigger($stats)
711
  {
712
- $configurationService = new MWP_Configuration_Service();
713
- $configuration = $configurationService->getConfiguration();
714
-
715
- $cachedData = get_transient("mwp_cache_notifications");
716
- $cacheTime = (int) get_transient("mwp_cache_notifications_time");
717
-
718
- $returnValue = false;
719
- if (false == $cachedData || empty($configuration)) {
720
- $returnValue = true;
721
- }
722
- /**
723
- * Cache lifetime check
724
- */
725
- if (!$returnValue) {
726
- $now = time();
727
- if ($now - $configuration->getNotiCacheLifeTime() >= $cacheTime) {
728
- $returnValue = true;
729
  }
730
  }
 
 
731
 
732
- /**
733
- * Themes difference check section
734
- * First check if array differ in size. If same size,then check values difference
735
- */
736
- if (!$returnValue && empty($stats['upgradable_themes']) != empty($cachedData['upgradable_themes'])) {
737
- $returnValue = true;
738
- }
739
- if (!$returnValue && !empty($stats['upgradable_themes'])) {
740
- $themesArr = mwp_std_to_array($stats['upgradable_themes']);
741
- $cachedThemesArr = mwp_std_to_array($cachedData['upgradable_themes']);
742
- if ($themesArr != $cachedThemesArr) {
743
- $returnValue = true;
744
- }
745
  }
746
 
747
- /**
748
- * Plugins difference check section
749
- * First check if array differ in size. If same size,then check values difference
750
- */
751
- if (!$returnValue && empty($stats['upgradable_plugins']) != empty($cachedData['upgradable_plugins'])) {
752
- $returnValue = true;
753
- }
754
 
755
- if (!$returnValue && !empty($stats['upgradable_plugins'])) { //we have hear stdclass
756
- $pluginsArr = mwp_std_to_array($stats['upgradable_plugins']);
757
- $cachedPluginsArr = mwp_std_to_array($cachedData['upgradable_plugins']);
758
- if ($pluginsArr != $cachedPluginsArr) {
759
- $returnValue = true;
760
- }
761
- }
762
 
763
- /**
764
- * Premium difference check section
765
- * First check if array differ in size. If same size,then check values difference
766
- */
767
- if (!$returnValue && empty($stats['premium_updates']) != empty($cachedData['premium_updates'])) {
768
- $returnValue = true;
769
- }
770
- if (!$returnValue && !empty($stats['premium_updates'])) {
771
- $premiumArr = mwp_std_to_array($stats['premium_updates']);
772
- $cachedPremiumArr = mwp_std_to_array($cachedData['premium_updates']);
773
- if ($premiumArr != $cachedPremiumArr) {
774
- $returnValue = true;
775
- }
776
- }
777
- /**
778
- * Comments
779
- * Check if we have configs first, then check trasholds
780
- */
781
- if (!$returnValue && (int) $stats['num_spam_comments'] >= $configuration->getNotiTresholdSpamComments() && $stats['num_spam_comments'] != (int) $cachedData['num_spam_comments']) {
782
- $returnValue = true;
783
- }
784
- if (!$returnValue && (int) $stats['num_spam_comments'] < (int) $cachedData['num_spam_comments']) {
785
- $returnValue = true;
786
  }
787
 
788
- if (!$returnValue && !empty($stats['comments'])) {
789
- if (!empty($stats['comments']['pending']) && count($stats['comments']['pending']) >= $configuration->getNotiTresholdPendingComments()) {
790
- $pendingArr = mwp_std_to_array($stats['comments']['pending']);
791
- $cachedPendingArr = mwp_std_to_array($cachedData['comments']['pending']);
792
- if ($pendingArr != $cachedPendingArr) {
793
- $returnValue = true;
794
- }
795
- }
796
 
797
- if (!empty($stats['comments']['approved']) && count($stats['comments']['approved']) >= $configuration->getNotiTresholdApprovedComments()) {
798
- $approvedArr = mwp_std_to_array($stats['comments']['approved']);
799
- $cachedApprovedArr = mwp_std_to_array($cachedData['comments']['approved']);
800
- if ($approvedArr != $cachedApprovedArr) {
801
- $returnValue = true;
802
- }
803
- }
804
  }
805
 
806
- /**
807
- * Drafts, posts
808
- */
809
 
810
- if (!$returnValue && !empty($stats['drafts']) && count($stats['drafts']) >= $configuration->getNotiTresholdDrafts()) {
811
- if (count($stats['drafts']) > $configuration->getNotiTresholdDrafts() && empty($cachedData['drafts'])) {
812
- $returnValue = true;
813
- } else {
814
- $draftsArr = mwp_std_to_array($stats['drafts']);
815
- $cachedDraftsArr = mwp_std_to_array($cachedData['drafts']);
816
- if ($draftsArr != $cachedDraftsArr) {
817
- $returnValue = true;
818
- }
819
- }
820
  }
821
 
822
- if (!$returnValue && !empty($stats['posts']) && count($stats['posts']) >= $configuration->getNotiTresholdPosts()) {
823
- if (count($stats['posts']) > $configuration->getNotiTresholdPosts() && empty($cachedData['posts'])) {
824
- $returnValue = true;
825
- } else {
826
- $postsArr = mwp_std_to_array($stats['posts']);
827
- $cachedPostsArr = mwp_std_to_array($cachedData['posts']);
828
- if ($postsArr != $cachedPostsArr) {
829
- $returnValue = true;
830
- }
831
- }
832
  }
833
 
834
- /**
835
- * Core updates & backups
836
- */
837
- if (!$returnValue && empty($stats['core_updates']) != empty($cachedData['core_updates'])) {
838
- $returnValue = true;
839
  }
840
- if (!$returnValue && !empty($stats['core_updates'])) {
841
- $coreArr = mwp_std_to_array($stats['core_updates']);
842
- $cachedCoreArr = mwp_std_to_array($cachedData['core_updates']);
843
- if ($coreArr != $cachedCoreArr) {
844
- $returnValue = true;
845
- }
846
  }
 
847
 
848
- if (!$returnValue && empty($stats['mwp_backups']) != empty($cachedData['mwp_backups'])) {
849
- $returnValue = true;
850
  }
851
- if (!$returnValue && !empty($stats['mwp_backups'])) {
852
- $backupArr = mwp_std_to_array($stats['mwp_backups']);
853
- $cachedBackupArr = mwp_std_to_array($cachedData['mwp_backups']);
854
- if ($backupArr != $cachedBackupArr) {
855
- $returnValue = true;
856
- }
857
  }
858
 
859
- return $returnValue;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
860
  }
861
 
862
- function mwp_std_to_array($obj)
863
  {
864
- if (is_object($obj)) {
865
- $objArr = clone $obj;
866
- } else {
867
- $objArr = $obj;
868
- }
869
- if (!empty($objArr)) {
870
- foreach ($objArr as &$element) {
871
- if ($element instanceof stdClass || is_array($element)) {
872
- $element = mwp_std_to_array($element);
873
- }
874
- }
875
- $objArr = (array) $objArr;
876
- }
877
-
878
- return $objArr;
879
  }
880
 
881
- function mmb_post_create($params)
882
  {
883
- global $mmb_core;
884
-
885
- mwp_context()->requireWpRewrite();
886
- mwp_context()->requireTaxonomies();
887
- mwp_context()->requirePostTypes();
888
 
889
- $mmb_core->get_post_instance();
890
- $return = $mmb_core->post_instance->create($params);
891
- if (is_int($return)) {
892
- mmb_response($return, true);
893
- } else {
894
- if (isset($return['error'])) {
895
- mmb_response($return['error'], false);
896
- } else {
897
- mmb_response($return, false);
898
- }
899
  }
900
- }
901
 
902
- function mmb_change_post_status($params)
903
- {
904
- global $mmb_core;
905
- $mmb_core->get_post_instance();
906
- $return = $mmb_core->post_instance->change_status($params);
907
- if (is_wp_error($return)) {
908
- mmb_response($return->get_error_message(), false);
909
- } elseif (empty($return)) {
910
- mmb_response("Post status can not be changed", false);
911
- } else {
912
- mmb_response($return, true);
913
- }
914
  }
915
 
916
- function mmb_backup_now($params)
917
  {
918
- global $mmb_core;
919
 
920
- $mmb_core->get_backup_instance();
921
- $return = $mmb_core->backup_instance->backup($params);
 
922
 
923
- if (is_array($return) && array_key_exists('error', $return)) {
924
- mmb_response($return['error'], false);
925
- } else {
926
- mmb_response($return, true);
927
  }
 
928
  }
929
 
930
- function mwp_ping_backup($params)
931
  {
932
- global $mmb_core;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
933
 
934
- $mmb_core->get_backup_instance();
935
- $return = $mmb_core->backup_instance->ping_backup($params);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
936
 
937
- if (is_array($return) && array_key_exists('error', $return)) {
938
- mmb_response($return['error'], false);
939
- } else {
940
- mmb_response($return, true);
941
  }
942
  }
943
 
944
- function mmb_run_task_now($params)
945
  {
946
- global $mmb_core;
947
- $mmb_core->get_backup_instance();
948
-
949
- $task_name = isset($params['task_name']) ? $params['task_name'] : false;
950
- $google_drive_token = isset($params['google_drive_token']) ? $params['google_drive_token'] : false;
951
- $resultUuid = !empty($params['resultUuid']) ? $params['resultUuid'] : false;
952
-
953
- if ($task_name) {
954
- $return = $mmb_core->backup_instance->task_now($task_name, $google_drive_token, $resultUuid);
955
- if (is_array($return) && array_key_exists('error', $return)) {
956
- mmb_response($return['error'], false);
957
- } else {
958
- mmb_response($return, true);
959
- }
960
- } else {
961
- mmb_response("Task name is not provided.", false);
962
  }
 
 
963
  }
964
 
965
- function mmb_get_backup_req($params)
966
  {
967
- global $mmb_core;
968
- $mmb_core->get_stats_instance();
969
- $return = $mmb_core->stats_instance->get_backup_req($params);
970
 
971
- mmb_response($return, true);
 
 
 
 
 
 
 
 
 
 
 
 
972
  }
973
 
974
- // Fires when Backup Now, or some backup task is saved.
975
- function mmb_scheduled_backup($params)
 
 
976
  {
977
- global $mmb_core;
978
- $mmb_core->get_backup_instance();
979
- $return = $mmb_core->backup_instance->set_backup_task($params);
980
- mmb_response($return, $return);
 
 
 
981
  }
982
 
983
- function mmm_delete_backup($params)
 
 
 
984
  {
985
- global $mmb_core;
986
- $mmb_core->get_backup_instance();
987
- $return = $mmb_core->backup_instance->delete_backup($params);
988
- mmb_response($return, $return);
 
 
 
 
989
  }
990
 
991
- function mmb_restore_now($params)
992
  {
993
- global $mmb_core;
994
- $mmb_core->get_backup_instance();
995
- $return = $mmb_core->backup_instance->restore($params);
996
- if (is_array($return) && array_key_exists('error', $return)) {
997
- mmb_response($return['error'], false);
998
- } else {
999
- mmb_response($return, true);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1000
  }
1001
  }
1002
 
1003
- function mmb_remote_backup_now($params)
1004
  {
1005
- global $mmb_core;
1006
- $backup_instance = $mmb_core->get_backup_instance();
1007
- $return = $mmb_core->backup_instance->remote_backup_now($params);
1008
- if (is_array($return) && array_key_exists('error', $return)) {
1009
- mmb_response($return['error'], false);
1010
- } else {
1011
- mmb_response($return, true);
1012
  }
 
 
1013
  }
1014
 
1015
- function mmb_run_forked_action()
1016
  {
1017
- if (!isset($_POST['mmb_fork_nonce'])) {
1018
- return false;
1019
- }
1020
 
1021
- $originalUser = wp_get_current_user();
1022
- $usernameUsed = array_key_exists('username', $_POST) ? $_POST : null;
 
 
1023
 
1024
- if ($usernameUsed && !is_user_logged_in()) {
1025
- $user = function_exists('get_user_by') ? get_user_by('login', $_POST['username']) : get_user_by('login', $_POST['username']);
 
 
 
1026
  }
1027
 
1028
- if (isset($user) && isset($user->ID)) {
1029
- wp_set_current_user($user->ID);
1030
- // Compatibility with All In One Security
1031
- update_user_meta($user->ID, 'last_login_time', current_time('mysql'));
1032
  }
1033
 
1034
- if (!wp_verify_nonce($_POST['mmb_fork_nonce'], 'mmb-fork-nonce')) {
1035
- wp_set_current_user($originalUser->ID);
 
1036
 
1037
- return false;
 
 
 
 
1038
  }
1039
 
1040
- $public_key = get_option('_worker_public_key');
1041
- if (!isset($_POST['public_key']) || $public_key !== $_POST['public_key']) {
1042
- wp_set_current_user($originalUser->ID);
1043
 
1044
- return false;
 
 
 
 
 
1045
  }
1046
- $args = @json_decode(stripslashes($_POST['args']), true);
1047
- $args['forked'] = true;
1048
 
1049
- if (!isset($args)) {
1050
- wp_set_current_user($originalUser->ID);
1051
 
1052
- return false;
1053
- }
1054
- $cron_action = isset($_POST['mwp_forked_action']) ? $_POST['mwp_forked_action'] : false;
1055
- if ($cron_action) {
1056
- do_action($cron_action, $args);
1057
  }
1058
- //unset($_POST['public_key']);
1059
- unset($_POST['mmb_fork_nonce']);
1060
- unset($_POST['args']);
1061
- unset($_POST['mwp_forked_action']);
1062
-
1063
- wp_set_current_user($originalUser->ID);
1064
 
1065
- return true;
1066
  }
1067
 
1068
- function mmb_update_worker_plugin($params)
1069
  {
1070
- global $mmb_core;
1071
- mmb_response($mmb_core->update_worker_plugin($params), true);
1072
- }
1073
 
1074
- function mmb_install_addon($params)
1075
- {
1076
- global $mmb_core;
1077
 
1078
- mwp_context()->requireTheme();
1079
- mwp_load_required_components();
1080
 
1081
- $mmb_core->get_installer_instance();
1082
- $return = $mmb_core->installer_instance->install_remote_file($params);
1083
- mmb_response($return, true);
 
 
 
 
1084
  }
1085
 
1086
- function mmb_do_upgrade($params)
1087
  {
1088
- global $mmb_core, $mmb_upgrading;
 
1089
 
1090
- mwp_context()->requireTheme();
 
1091
 
1092
- $mmb_core->get_installer_instance();
1093
- $return = $mmb_core->installer_instance->do_upgrade($params);
1094
- mmb_response($return, true);
1095
- }
1096
 
1097
- function mmb_get_comments($params)
1098
- {
1099
- global $mmb_core;
1100
- $mmb_core->get_comment_instance();
1101
- $return = $mmb_core->comment_instance->get_comments($params);
1102
- if (is_array($return) && array_key_exists('error', $return)) {
1103
- mmb_response($return['error'], false);
 
1104
  } else {
1105
- mmb_response($return, true);
1106
  }
1107
- }
1108
 
1109
- function mmb_bulk_action_comments($params)
1110
- {
1111
- global $mmb_core;
1112
- $mmb_core->get_comment_instance();
1113
 
1114
- $return = $mmb_core->comment_instance->bulk_action_comments($params);
1115
- if (is_array($return) && array_key_exists('error', $return)) {
1116
- mmb_response($return['error'], false);
1117
- } else {
1118
- mmb_response($return, true);
1119
- }
1120
  }
1121
 
1122
- function mmb_reply_comment($params)
1123
  {
1124
- global $mmb_core;
1125
- $mmb_core->get_comment_instance();
 
1126
 
1127
- $return = $mmb_core->comment_instance->reply_comment($params);
1128
- if (is_array($return) && array_key_exists('error', $return)) {
1129
- mmb_response($return['error'], false);
1130
- } else {
1131
- mmb_response($return, true);
1132
  }
1133
- }
1134
 
1135
- function mmb_add_user($params)
1136
- {
1137
- global $mmb_core;
1138
- $mmb_core->get_user_instance();
1139
- $return = $mmb_core->user_instance->add_user($params);
1140
- if (is_array($return) && array_key_exists('error', $return)) {
1141
- mmb_response($return['error'], false);
1142
- } else {
1143
- mmb_response($return, true);
1144
- }
1145
  }
1146
 
1147
- function mmb_get_users($params)
1148
  {
1149
- global $mmb_core;
1150
- $mmb_core->get_user_instance();
1151
- $return = $mmb_core->user_instance->get_users($params);
1152
- if (is_array($return) && array_key_exists('error', $return)) {
1153
- mmb_response($return['error'], false);
1154
- } else {
1155
- mmb_response($return, true);
1156
- }
1157
  }
1158
 
1159
- function mmb_edit_users($params)
1160
  {
1161
- global $mmb_core;
1162
- $mmb_core->get_user_instance();
1163
- $users = $mmb_core->user_instance->edit_users($params);
1164
- $response = 'User updated.';
1165
- $check_error = false;
1166
- foreach ($users as $username => $user) {
1167
- $check_error = array_key_exists('error', $user);
1168
- if ($check_error) {
1169
- $response = $username.': '.$user['error'];
1170
- }
1171
  }
1172
- mmb_response($response, !$check_error);
1173
- }
1174
 
1175
- function mmb_get_posts($params)
1176
- {
1177
- global $mmb_core;
1178
- $mmb_core->get_post_instance();
1179
 
1180
- $return = $mmb_core->post_instance->get_posts($params);
1181
- if (is_array($return) && array_key_exists('error', $return)) {
1182
- mmb_response($return['error'], false);
1183
- } else {
1184
- mmb_response($return, true);
1185
  }
 
 
 
 
 
1186
  }
1187
 
1188
- function mmb_delete_post($params)
1189
  {
1190
- global $mmb_core;
1191
- $mmb_core->get_post_instance();
 
 
1192
 
1193
- $return = $mmb_core->post_instance->delete_post($params);
1194
- if (is_array($return) && array_key_exists('error', $return)) {
1195
- mmb_response($return['error'], false);
1196
- } else {
1197
- mmb_response($return, true);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1198
  }
 
 
 
 
1199
  }
1200
 
1201
- function mmb_delete_posts($params)
1202
  {
1203
- global $mmb_core;
1204
- $mmb_core->get_post_instance();
 
 
1205
 
1206
- $return = $mmb_core->post_instance->delete_posts($params);
1207
- if (is_array($return) && array_key_exists('error', $return)) {
1208
- mmb_response($return['error'], false);
1209
- } else {
1210
- mmb_response($return, true);
1211
- }
1212
  }
1213
 
1214
- function mmb_get_pages($params)
1215
  {
1216
- global $mmb_core;
1217
- $mmb_core->get_post_instance();
 
 
1218
 
1219
- $return = $mmb_core->post_instance->get_pages($params);
1220
- if (is_array($return) && array_key_exists('error', $return)) {
1221
- mmb_response($return['error'], false);
1222
- } else {
1223
- mmb_response($return, true);
1224
  }
 
 
 
 
1225
  }
1226
 
1227
- function mmb_delete_page($params)
1228
  {
1229
- global $mmb_core;
1230
- $mmb_core->get_post_instance();
 
1231
 
1232
- $return = $mmb_core->post_instance->delete_page($params);
1233
- if (is_array($return) && array_key_exists('error', $return)) {
1234
- mmb_response($return['error'], false);
1235
- } else {
1236
- mmb_response($return, true);
 
 
 
 
 
1237
  }
1238
- }
1239
 
1240
- function mmb_iframe_plugins_fix($update_actions)
1241
- {
1242
- foreach ($update_actions as $key => $action) {
1243
- $update_actions[$key] = str_replace('target="_parent"', '', $action);
1244
  }
1245
 
1246
- return $update_actions;
 
 
 
1247
  }
1248
 
1249
- function mmb_execute_php_code($params)
1250
  {
1251
- ob_start();
1252
- $errorHandler = new MWP_Debug_EvalErrorHandler();
1253
- set_error_handler(array($errorHandler, 'handleError'));
1254
- $returnValue = eval($params['code']);
1255
- $errors = $errorHandler->getErrorMessages();
1256
- restore_error_handler();
1257
- $return = array('output' => ob_get_clean(), 'returnValue' => $returnValue);
1258
 
1259
- if (count($errors)) {
1260
- $return['errorLog'] = $errors;
 
 
 
1261
  }
1262
 
1263
- $lastError = error_get_last();
1264
- $fatalError = null;
1265
 
1266
- if (($lastError !== null)
1267
- && ($lastError['type'] & (E_PARSE | E_ERROR | E_CORE_ERROR | E_COMPILE_ERROR))
1268
- && (strpos($lastError['file'], __FILE__) !== false)
1269
- && (strpos($lastError['file'], 'eval()') !== false)
1270
- ) {
1271
- $return['fatalError'] = $lastError;
1272
  }
1273
 
1274
- mmb_response($return, true);
1275
- }
1276
 
1277
- function mmb_more_reccurences($schedules)
1278
- {
1279
- $schedules['halfminute'] = array('interval' => 30, 'display' => 'Once in a half minute');
1280
- $schedules['minutely'] = array('interval' => 60, 'display' => 'Once in a minute');
1281
- $schedules['fiveminutes'] = array('interval' => 300, 'display' => 'Once every five minutes');
1282
- $schedules['tenminutes'] = array('interval' => 600, 'display' => 'Once every ten minutes');
1283
- $schedules['sixhours'] = array('interval' => 21600, 'display' => 'Every six hours');
1284
- $schedules['fourhours'] = array('interval' => 14400, 'display' => 'Every four hours');
1285
- $schedules['threehours'] = array('interval' => 10800, 'display' => 'Every three hours');
1286
 
1287
- return $schedules;
 
 
 
1288
  }
1289
 
1290
- function mmb_call_scheduled_remote_upload($args)
1291
  {
1292
- global $mmb_core, $_wp_using_ext_object_cache;
1293
- $_wp_using_ext_object_cache = false;
1294
 
1295
- $mmb_core->get_backup_instance();
1296
- if (isset($args['task_name'])) {
1297
- $mmb_core->backup_instance->remote_backup_now($args);
1298
  }
1299
- }
1300
 
1301
- function mwp_check_notifications()
1302
- {
1303
- global $mmb_core, $_wp_using_ext_object_cache;
1304
- $_wp_using_ext_object_cache = false;
1305
-
1306
- $mmb_core->get_stats_instance();
1307
- $mmb_core->stats_instance->check_notifications();
1308
  }
1309
 
1310
- function mmb_get_plugins_themes($params)
1311
  {
1312
- global $mmb_core;
 
 
1313
 
1314
- mwp_context()->requireTheme();
 
1315
 
1316
- $mmb_core->get_installer_instance();
1317
- $return = $mmb_core->installer_instance->get($params);
1318
- mmb_response($return, true);
1319
- }
1320
 
1321
- function mmb_get_autoupdate_plugins_themes($params)
1322
- {
1323
- mwp_context()->requireTheme();
1324
 
1325
- $return = MMB_Updater::getSettings($params);
1326
- mmb_response($return, true);
1327
- }
 
 
 
1328
 
1329
- function mmb_edit_plugins_themes($params)
1330
- {
1331
- global $mmb_core;
1332
- $mmb_core->get_installer_instance();
1333
- $return = $mmb_core->installer_instance->edit($params);
1334
- mmb_response($return, true);
1335
- }
 
 
1336
 
1337
- function mmb_edit_autoupdate_plugins_themes($params)
1338
- {
1339
- $return = MMB_Updater::setSettings($params);
1340
- mmb_response($return, true);
1341
- }
 
1342
 
1343
- function mmb_worker_brand($params)
1344
- {
1345
- update_option("mwp_worker_brand", $params['brand']);
1346
- mmb_response(true, true);
1347
- }
 
 
 
 
 
1348
 
1349
- function mmb_maintenance_mode($params)
1350
- {
1351
- global $wp_object_cache;
1352
 
1353
- $default = get_option('mwp_maintenace_mode');
1354
- $params = empty($default) ? $params : array_merge($default, $params);
1355
- update_option("mwp_maintenace_mode", $params);
1356
 
1357
- if (!empty($wp_object_cache)) {
1358
- @$wp_object_cache->flush();
 
 
 
 
1359
  }
1360
- mmb_response(true, true);
 
1361
  }
1362
 
1363
- function mmb_plugin_actions()
1364
  {
1365
- global $pagenow, $current_user, $mmode;
1366
- if (!is_admin() && !in_array($pagenow, array('wp-login.php'))) {
1367
- $mmode = get_option('mwp_maintenace_mode');
1368
- if (!empty($mmode)) {
1369
- if (isset($mmode['active']) && $mmode['active'] == true) {
1370
- if (isset($current_user->data) && !empty($current_user->data) && isset($mmode['hidecaps']) && !empty($mmode['hidecaps'])) {
1371
- $usercaps = array();
1372
- if (isset($current_user->caps) && !empty($current_user->caps)) {
1373
- $usercaps = $current_user->caps;
1374
- }
1375
- foreach ($mmode['hidecaps'] as $cap => $hide) {
1376
- if (!$hide) {
1377
- continue;
1378
- }
1379
 
1380
- foreach ($usercaps as $ucap => $val) {
1381
- if ($ucap == $cap) {
1382
- ob_end_clean();
1383
- ob_end_flush();
1384
- die($mmode['template']);
1385
- }
1386
- }
1387
- }
1388
- } else {
1389
- die($mmode['template']);
1390
- }
1391
- }
1392
  }
1393
- }
1394
 
1395
- if (file_exists(dirname(__FILE__).'/log')) {
1396
- unlink(dirname(__FILE__).'/log');
1397
  }
 
 
1398
  }
1399
 
1400
- function mwp_return_core_reference()
1401
  {
1402
- global $mmb_core, $mmb_core_backup;
1403
- if (!$mmb_core instanceof MMB_Core) {
1404
- $mmb_core = $mmb_core_backup;
 
 
 
 
 
 
1405
  }
1406
- }
1407
 
1408
- function mwb_edit_redirect_override($location = false, $comment_id = false)
1409
- {
1410
- if (isset($_COOKIE[MMB_XFRAME_COOKIE])) {
1411
- $location = get_site_url().'/wp-admin/edit-comments.php';
 
 
 
 
 
1412
  }
1413
 
1414
- return $location;
 
 
 
1415
  }
1416
 
1417
- function mwp_set_plugin_priority()
1418
  {
1419
- $pluginBasename = 'worker/init.php';
1420
- $activePlugins = get_option('active_plugins');
1421
 
1422
- if (reset($activePlugins) === $pluginBasename) {
1423
- return;
1424
  }
1425
 
1426
- $workerKey = array_search($pluginBasename, $activePlugins);
1427
 
1428
- if ($workerKey === false) {
1429
- return;
1430
  }
1431
 
1432
- unset($activePlugins[$workerKey]);
1433
- array_unshift($activePlugins, $pluginBasename);
1434
- update_option('active_plugins', array_values($activePlugins));
1435
- }
 
1436
 
1437
- /**
1438
- * @return MMB_Core
1439
- */
1440
- function mwp_core()
1441
- {
1442
- static $core;
1443
 
1444
- global $mmb_core;
1445
 
1446
- if (!$mmb_core instanceof MMB_Core) {
1447
- $mmb_core = new MMB_Core();
1448
- $core = $mmb_core;
 
1449
  }
1450
 
1451
- return $core;
1452
- }
1453
 
1454
- /**
1455
- * Auto-loads classes that may not exists after this plugin's update.
1456
- */
1457
- function mwp_load_required_components()
1458
- {
1459
- class_exists('MWP_Http_ResponseInterface');
1460
- class_exists('MWP_Http_Response');
1461
- class_exists('MWP_Http_LegacyWorkerResponse');
1462
- class_exists('MWP_Http_JsonResponse');
1463
- class_exists('MWP_Worker_ActionResponse');
1464
- class_exists('MWP_Worker_Exception');
1465
- class_exists('MWP_Event_ActionResponse');
1466
- class_exists('MWP_Event_MasterResponse');
1467
- }
1468
-
1469
- function mmb_change_comment_status($params)
1470
- {
1471
- global $mmb_core;
1472
- $mmb_core->get_comment_instance();
1473
- $return = $mmb_core->comment_instance->change_status($params);
1474
- if ($return) {
1475
- $mmb_core->get_stats_instance();
1476
- mmb_response($mmb_core->stats_instance->get_comments_stats($params), true);
1477
- } else {
1478
- mmb_response('Comment not updated', false);
1479
  }
1480
- }
1481
 
1482
- function mwp_uninstall()
1483
- {
1484
- $loaderName = '0-worker.php';
1485
- try {
1486
- $mustUsePluginDir = rtrim(WPMU_PLUGIN_DIR, '/');
1487
- $loaderPath = $mustUsePluginDir.'/'.$loaderName;
1488
 
1489
- if (!file_exists($loaderPath)) {
1490
- return;
1491
- }
1492
 
1493
- $removed = @unlink($loaderPath);
1494
 
1495
- if (!$removed) {
1496
- $error = error_get_last();
1497
- throw new Exception(sprintf('Unable to remove loader: %s', $error['message']));
1498
- }
1499
- } catch (Exception $e) {
1500
- mwp_logger()->error('Unable to remove loader', array('exception' => $e));
1501
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1502
  }
2
 
3
  function mwp_autoload($class)
4
  {
5
+ if (substr($class, 0, 8) === 'Symfony_'
 
6
  || substr($class, 0, 8) === 'Monolog_'
7
  || substr($class, 0, 5) === 'Gelf_'
8
  || substr($class, 0, 4) === 'MWP_'
9
  || substr($class, 0, 4) === 'MMB_'
 
10
  ) {
11
  $file = dirname(__FILE__).'/src/'.str_replace('_', '/', $class).'.php';
12
  if (file_exists($file)) {
15
  }
16
  }
17
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
  /**
19
  * @return Monolog_Psr_LoggerInterface
20
  */
31
  return mwp_container()->getWordPressContext();
32
  }
33
 
34
+ function mwp_worker_configuration()
 
 
 
 
 
 
 
 
35
  {
36
+ return mwp_container()->getConfiguration();
 
 
 
 
 
 
 
 
37
  }
38
 
39
  function mwp_format_memory_limit($limit)
40
  {
41
+ if ((string)(int)$limit === (string)$limit) {
42
  // The number is numeric.
43
  return mwp_format_bytes($limit);
44
  }
52
 
53
  $number = substr($limit, 0, -1);
54
 
55
+ if ((string)(int)$number !== $number) {
56
  // The number isn't numeric.
57
  return $number;
58
  }
72
 
73
  function mwp_format_bytes($bytes)
74
  {
75
+ $bytes = (int)$bytes;
76
 
77
  if ($bytes > 1024 * 1024 * 1024) {
78
  return round($bytes / 1024 / 1024 / 1024, 2).' GB';
85
  return $bytes.' B';
86
  }
87
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
88
  function cleanup_delete_worker($params = array())
89
  {
90
  $revision_params = get_option('mmb_stats_filter');
91
+ $revision_limit = isset($revision_params['plugins']['cleanup']['revisions']) ? str_replace('r_', '', $revision_params['plugins']['cleanup']['revisions']) : 5;
92
 
93
  $params_array = explode('_', $params['actions']);
94
  $return_array = array();
96
  foreach ($params_array as $param) {
97
  switch ($param) {
98
  case 'revision':
99
+ if (mmb_delete_all_revisions($revision_limit)) {
100
  $return_array['revision'] = 'OK';
101
  } else {
102
  $return_array['revision_error'] = 'OK, nothing to do';
126
  mmb_response($return_array, true);
127
  }
128
 
129
+ function mmb_num_revisions($leaveRevsPerPost)
130
  {
131
  global $wpdb;
132
 
133
+ $query = "SELECT SUM(t.cnt) FROM (SELECT COUNT(ID) - {$leaveRevsPerPost} as cnt FROM {$wpdb->posts} WHERE post_type = 'revision' AND post_parent != 0 GROUP BY post_parent HAVING COUNT(ID) > {$leaveRevsPerPost}) as t";
134
 
135
+ return $wpdb->get_var($query);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
136
  }
137
 
138
  function mmb_delete_all_revisions($filter)
139
  {
140
  global $wpdb;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
141
 
142
+ $num_rev = isset($filter['num_to_keep']) ? (int)str_replace("r_", "", $filter['num_to_keep']) : 5;
143
+
144
+ $allRevisions = $wpdb->get_results("SELECT post_parent FROM {$wpdb->posts} WHERE post_type = 'revision' AND post_parent != 0 GROUP BY post_parent HAVING COUNT(ID) > {$num_rev}");
145
 
146
+ if (!is_array($allRevisions)) {
147
+ return false;
148
  }
149
 
150
+ foreach ($allRevisions as $revision) {
151
+ $toKeep = $wpdb->get_results("SELECT ID FROM {$wpdb->posts} WHERE post_type = 'revision' AND post_parent = '{$revision->post_parent}' ORDER BY post_date DESC LIMIT ".$num_rev);
152
+
153
+ $keepArray = array();
154
+ foreach ($toKeep as $keep) {
155
+ $keepArray[] = $keep->ID;
156
+ }
157
+
158
+ if (empty($keepArray)) {
159
+ continue;
160
+ }
161
 
162
+ $keepQuery = implode(', ', $keepArray);
163
+ $wpdb->query("DELETE FROM {$wpdb->posts} WHERE post_type = 'revision' AND post_parent = '{$revision->post_parent}' AND ID NOT IN ({$keepQuery})");
164
+ }
165
 
166
+ return true;
167
  }
168
 
169
  function mmb_handle_overhead($clear = false)
170
  {
171
  /** @var wpdb $wpdb */
172
  global $wpdb;
173
+ $query = 'SHOW TABLE STATUS';
174
+ $tables = $wpdb->get_results($query, ARRAY_A);
175
+ $tableOverhead = 0;
176
+ $tablesToOptimize = array();
177
+
178
  foreach ($tables as $table) {
179
+ if (!isset($table['Engine']) || $table['Engine'] !== 'MyISAM' || $table['Data_free'] == 0) {
180
+ continue;
181
+ }
182
+
183
+ if ($wpdb->base_prefix === $wpdb->prefix && !preg_match('/^'.preg_quote($wpdb->prefix).'/Ui', $table['Name'])) {
184
+ continue;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
185
  }
186
+
187
+ if ($wpdb->base_prefix !== $wpdb->prefix && !preg_match('/^'.preg_quote($wpdb->prefix).'\d+_/Ui', $table['Name'])) {
188
+ continue;
189
+ }
190
+
191
+ $tableOverhead += $table['Data_free'] / 1024;
192
+ $tablesToOptimize[] = $table['Name'];
193
+ }
194
+
195
+ if (!$clear) { // we should only return the overhead
196
+ return round($tableOverhead, 3);
197
  }
198
 
199
+ $optimize = true;
 
 
 
 
200
 
201
+ foreach ($tablesToOptimize as $tableToOptimize) {
202
+ $query = 'OPTIMIZE TABLE '.$tableToOptimize;
203
+ $optimize = ((bool)$wpdb->query($query)) && $optimize;
204
  }
205
+
206
+ return $optimize;
207
  }
208
 
 
209
  function mmb_num_spam_comments()
210
  {
211
  global $wpdb;
221
  $spam = 1;
222
  $total = 0;
223
  while (!empty($spam)) {
224
+ $getCommentsQuery = "SELECT * FROM $wpdb->comments WHERE comment_approved = 'spam' LIMIT 1000";
225
+ $spam = $wpdb->get_results($getCommentsQuery);
226
+
227
+ if (empty($spam)) {
228
+ break;
229
+ }
230
+
231
+ $commentIds = array();
232
  foreach ($spam as $comment) {
233
+ $commentIds[] = $comment->comment_ID;
234
+
235
+ // Avoid queries to comments by caching the comment.
236
+ // Plugins which hook to 'delete_comment' might call get_comment($id), which in turn returns the cached version.
237
+ wp_cache_add($comment->comment_ID, $comment, 'comment');
238
+ do_action('delete_comment', $comment->comment_ID);
239
+ wp_cache_delete($comment->comment_ID, 'comment');
240
  }
241
+
242
+ $commentIdsList = implode(', ', array_map('intval', $commentIds));
243
+ $wpdb->query("DELETE FROM {$wpdb->comments} WHERE comment_ID IN ($commentIdsList)");
244
+ $wpdb->query("DELETE FROM {$wpdb->commentmeta} WHERE comment_id IN ($commentIdsList)");
245
+
246
  $total += count($spam);
247
  if (!empty($spam)) {
248
+ usleep(10000);
249
  }
250
  }
251
 
252
  return $total;
253
  }
254
 
 
 
 
 
 
 
 
 
 
255
  function mwp_is_nio_shell_available()
256
  {
257
  static $check;
282
  return false;
283
  }
284
 
285
+ $neededFunction = array('proc_get_status', 'proc_open');
286
+ $disabledFunction = mwp_get_disabled_functions();
287
+
288
+ if (count(array_diff($neededFunction, $disabledFunction)) != count($neededFunction)) {
289
+ return false;
 
 
290
  }
291
 
292
  if (!mwp_is_nio_shell_available()) {
309
  function mwp_is_safe_mode()
310
  {
311
  $value = ini_get("safe_mode");
312
+ if ((int)$value === 0 || strtolower($value) === "off") {
313
  return false;
314
  }
315
 
316
  return true;
317
  }
318
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
319
  function mmb_response($response = false, $success = true)
320
  {
321
  if (!$success) {
330
 
331
  function mmb_remove_site($params)
332
  {
333
+ mwp_core()->deactivate(false, false);
334
+ mwp_remove_current_key();
 
 
 
 
335
 
336
+ mmb_response(
337
+ array(
338
+ 'removed_data' => 'Site removed successfully. <br /><br /><b>ManageWP Worker plugin was not deactivated.</b>',
339
+ ),
340
+ true
341
+ );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
342
  }
343
 
344
+ function mwp_get_stats(array $params)
345
  {
 
 
 
346
  mwp_context()->requireWpRewrite();
347
  mwp_context()->requireTaxonomies();
348
  mwp_context()->requirePostTypes();
349
  mwp_context()->requireTheme();
350
 
351
+ mwp_logger()->debug('Starting get_stats after everything was required');
352
+
353
+ $return = mwp_core()->get_stats_instance()->get_stats($params);
354
+ mmb_response($return);
355
  }
356
 
357
+ function mmb_update_worker_plugin($params)
358
  {
359
+ if (!empty($params['version'])) {
360
+ $recoveryKit = new MwpRecoveryKit();
361
+ update_option('mwp_incremental_update_active', time());
362
+ try {
363
+ $files = $recoveryKit->recover($params['version']);
364
+ } catch (Exception $e) {
365
+ update_option('mwp_incremental_update_active', '');
366
+ throw $e;
367
  }
368
+ update_option('mwp_incremental_update_active', '');
369
+ mmb_response(array('files' => $files, 'success' => 'ManageWP Worker plugin successfully updated'), true);
370
+ } else {
371
+ mmb_response(mwp_core()->update_worker_plugin($params), true);
372
  }
373
  }
374
 
375
+ function mmb_install_addon($params)
376
  {
 
 
 
 
 
377
  mwp_context()->requireTheme();
378
+ mwp_load_required_components();
379
+ $return = mwp_core()->get_installer_instance()->install_remote_file($params);
380
+ mmb_response($return, true);
 
381
  }
382
 
383
+ function mmb_do_upgrade($params)
384
  {
385
+ mwp_context()->requireTheme();
386
+ $return = mwp_core()->get_installer_instance()->do_upgrade($params);
387
+ mmb_response($return, true);
388
+ }
389
 
390
+ function mmb_bulk_action_comments($params)
391
+ {
392
+ $return = mwp_core()->get_comment_instance()->bulk_action_comments($params);
393
+ if (is_array($return) && array_key_exists('error', $return)) {
394
+ mmb_response($return['error'], false);
395
+ } else {
396
+ mmb_response($return, true);
397
  }
398
+ }
399
 
400
+ function mmb_add_user($params)
401
+ {
402
+ $return = mwp_core()->get_user_instance()->add_user($params);
403
+ if (is_array($return) && array_key_exists('error', $return)) {
404
+ mmb_response($return['error'], false);
405
+ } else {
406
+ mmb_response($return, true);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
407
  }
408
  }
409
 
410
+ function mmb_edit_users($params)
 
411
  {
412
+ $users = mwp_core()->get_user_instance()->edit_users($params);
413
+ $response = 'User updated.';
414
+ $check_error = false;
415
+ foreach ($users as $username => $user) {
416
+ $check_error = is_array($user) && array_key_exists('error', $user);
417
+ if ($check_error) {
418
+ $response = $username.': '.$user['error'];
 
 
 
 
 
 
 
 
 
 
419
  }
420
  }
421
+ mmb_response($response, !$check_error);
422
+ }
423
 
424
+ function mmb_iframe_plugins_fix($update_actions)
425
+ {
426
+ foreach ($update_actions as $key => $action) {
427
+ $update_actions[$key] = str_replace('target="_parent"', '', $action);
 
 
 
 
 
 
 
 
 
428
  }
429
 
430
+ return $update_actions;
431
+ }
 
 
 
 
 
432
 
433
+ function mmb_execute_php_code($params)
434
+ {
435
+ ob_start();
436
+ $errorHandler = new MWP_Debug_EvalErrorHandler();
437
+ set_error_handler(array($errorHandler, 'handleError'));
 
 
438
 
439
+ if (!empty($params['code64'])) {
440
+ $params['code'] = base64_decode(substr($params['code64'], 2));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
441
  }
442
 
443
+ $returnValue = eval($params['code']); // This code handles the "Execute PHP Snippet" functionality on ManageWP and is not a security issue.
444
+ $errors = $errorHandler->getErrorMessages();
445
+ restore_error_handler();
446
+ $return = array('output' => ob_get_clean(), 'returnValue' => $returnValue);
 
 
 
 
447
 
448
+ if (count($errors)) {
449
+ $return['errorLog'] = $errors;
 
 
 
 
 
450
  }
451
 
452
+ $lastError = error_get_last();
453
+ $fatalError = null;
 
454
 
455
+ if (($lastError !== null)
456
+ && ($lastError['type'] & (E_PARSE | E_ERROR | E_CORE_ERROR | E_COMPILE_ERROR))
457
+ && (strpos($lastError['file'], __FILE__) !== false)
458
+ && (strpos($lastError['file'], 'eval()') !== false)
459
+ ) {
460
+ $return['fatalError'] = $lastError;
 
 
 
 
461
  }
462
 
463
+ mmb_response($return, true);
464
+ }
465
+
466
+ function mmb_upload_file_action($params)
467
+ {
468
+ $transactions = getUploadMessages();
469
+
470
+ if (!file_exists($params['file_path'])) {
471
+ mmb_response(array('message' => $transactions['path_not_exist'], 'ok' => false), true);
 
472
  }
473
 
474
+ if (!is_writable($params['file_path'])) {
475
+ mmb_response(array('message' => $transactions['permissions_denied'], 'ok' => false), true);
 
 
 
476
  }
477
+
478
+ $pathName = $params['file_path'];
479
+ if (substr($pathName, -1) !== '/') {
480
+ $pathName = $pathName.'/';
 
 
481
  }
482
+ $filePath = $pathName.$params['file_name'];
483
 
484
+ if (file_exists($filePath) && !$params['overwrite']) {
485
+ mmb_response(array('message' => $transactions['file_exist'], 'ok' => false), true);
486
  }
487
+
488
+ $file = fopen($filePath, 'w');
489
+ if (!fwrite($file, base64_decode($params['content']))) {
490
+ mmb_response(array('message' => $transactions['upload_failed'], 'ok' => false), true);
 
 
491
  }
492
 
493
+ fclose($file);
494
+ $isWritable = is_writable($filePath);
495
+ $result = array(
496
+ 'pathName' => $filePath,
497
+ 'fileName' => basename($filePath),
498
+ 'date' => filemtime($filePath),
499
+ 'permissions' => substr(sprintf('%o', fileperms($filePath)), -4),
500
+ 'fileType' => pathinfo($filePath, PATHINFO_EXTENSION),
501
+ 'fileSize' => filesize($filePath),
502
+ 'hasSubDir' => false,
503
+ 'writable' => $isWritable,
504
+ 'editable' => $isWritable
505
+ );
506
+
507
+ mmb_response(array('message' => $transactions['upload_success'], 'ok' => true, 'result' => $result), true);
508
  }
509
 
510
+ function mmb_edit_plugins_themes($params)
511
  {
512
+ $return = mwp_core()->get_installer_instance()->edit($params);
513
+ mmb_response($return, true);
 
 
 
 
 
 
 
 
 
 
 
 
 
514
  }
515
 
516
+ function mmb_worker_brand($params)
517
  {
518
+ $worker_brand = get_option('mwp_worker_brand');
519
+ $current_from_orion = !empty($worker_brand['from_orion']) ? $worker_brand['from_orion'] : false;
520
+ $from_orion = !empty($params['brand']['from_orion']) ? $params['brand']['from_orion'] : false;
 
 
521
 
522
+ if ($from_orion === false && $current_from_orion !== $from_orion) {
523
+ mmb_response(true, true); //@TODO: Maybe return mmb_response(true, false)
524
+ return;
 
 
 
 
 
 
 
525
  }
 
526
 
527
+ update_option("mwp_worker_brand", $params['brand']);
528
+ mmb_response(true, true);
 
 
 
 
 
 
 
 
 
 
529
  }
530
 
531
+ function mmb_maintenance_mode($params)
532
  {
533
+ global $wp_object_cache;
534
 
535
+ $default = get_option('mwp_maintenace_mode');
536
+ $params = empty($default) ? $params : array_merge($default, $params);
537
+ update_option("mwp_maintenace_mode", $params);
538
 
539
+ if (!empty($wp_object_cache)) {
540
+ @$wp_object_cache->flush();
 
 
541
  }
542
+ mmb_response(true, true);
543
  }
544
 
545
+ function mmb_plugin_actions()
546
  {
547
+ global $pagenow, $current_user, $mmode;
548
+ if (!is_admin() && !(defined('WP_CLI') && WP_CLI) && !in_array($pagenow, array('wp-login.php'))) {
549
+ $mmode = get_option('mwp_maintenace_mode');
550
+ if (!empty($mmode)) {
551
+ if (isset($mmode['active']) && $mmode['active'] == true) {
552
+ $status_code = empty($mmode['status_code']) ? 503 : $mmode['status_code'];
553
+ if (!empty($current_user->ID) && !empty($mmode['hidecaps'])) {
554
+ $usercaps = array();
555
+ if (isset($current_user->caps) && !empty($current_user->caps)) {
556
+ $usercaps = $current_user->caps;
557
+ }
558
+ foreach ($mmode['hidecaps'] as $cap => $hide) {
559
+ if (!$hide) {
560
+ continue;
561
+ }
562
 
563
+ foreach ($usercaps as $ucap => $val) {
564
+ if ($ucap == $cap) {
565
+ ob_end_clean();
566
+ ob_end_flush();
567
+ if (!headers_sent()) {
568
+ if ($status_code == 503) {
569
+ header(sprintf('%s 503 Service Unavailable', isset($_SERVER['SERVER_PROTOCOL']) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.1'), true, $status_code);
570
+ } else {
571
+ header(sprintf('%s %d Service Unavailable', isset($_SERVER['SERVER_PROTOCOL']) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.1', $status_code), true, $status_code);
572
+ }
573
+ }
574
+ die($mmode['template']);
575
+ }
576
+ }
577
+ }
578
+ } else {
579
+ if (!headers_sent()) {
580
+ if ($status_code == 503) {
581
+ header(sprintf('%s 503 Service Unavailable', isset($_SERVER['SERVER_PROTOCOL']) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.1'), true, 503);
582
+ } else {
583
+ header(sprintf('%s %d Service Unavailable', isset($_SERVER['SERVER_PROTOCOL']) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.1', $status_code), true, $status_code);
584
+ }
585
+ }
586
+ die($mmode['template']);
587
+ }
588
+ }
589
+ }
590
+ }
591
 
592
+ if (file_exists(dirname(__FILE__).'/log')) {
593
+ unlink(dirname(__FILE__).'/log');
 
 
594
  }
595
  }
596
 
597
+ function mwb_edit_redirect_override($location = false, $comment_id = false)
598
  {
599
+ if (isset($_COOKIE[MMB_XFRAME_COOKIE])) {
600
+ $location = get_site_url().'/wp-admin/edit-comments.php';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
601
  }
602
+
603
+ return $location;
604
  }
605
 
606
+ function mwp_set_plugin_priority()
607
  {
608
+ $pluginBasename = 'worker/init.php';
609
+ $activePlugins = get_option('active_plugins');
 
610
 
611
+ if (!is_array($activePlugins) || reset($activePlugins) === $pluginBasename) {
612
+ return;
613
+ }
614
+
615
+ $workerKey = array_search($pluginBasename, $activePlugins);
616
+
617
+ if ($workerKey === false || $workerKey === null) {
618
+ return;
619
+ }
620
+
621
+ unset($activePlugins[$workerKey]);
622
+ array_unshift($activePlugins, $pluginBasename);
623
+ update_option('active_plugins', array_values($activePlugins));
624
  }
625
 
626
+ /**
627
+ * @return MMB_Core
628
+ */
629
+ function mwp_core()
630
  {
631
+ static $core;
632
+
633
+ if (!$core instanceof MMB_Core) {
634
+ $core = new MMB_Core();
635
+ }
636
+
637
+ return $core;
638
  }
639
 
640
+ /**
641
+ * Auto-loads classes that may not exists after this plugin's update.
642
+ */
643
+ function mwp_load_required_components()
644
  {
645
+ class_exists('MWP_Http_ResponseInterface');
646
+ class_exists('MWP_Http_Response');
647
+ class_exists('MWP_Http_LegacyWorkerResponse');
648
+ class_exists('MWP_Http_JsonResponse');
649
+ class_exists('MWP_Worker_ActionResponse');
650
+ class_exists('MWP_Worker_Exception');
651
+ class_exists('MWP_Event_ActionResponse');
652
+ class_exists('MWP_Event_MasterResponse');
653
  }
654
 
655
+ function mwp_uninstall()
656
  {
657
+ delete_option('mwp_core_autoupdate');
658
+ delete_option('mwp_recovering');
659
+ delete_option('mwp_container_parameters');
660
+ delete_option('mwp_container_site_parameters');
661
+ $loaderName = '0-worker.php';
662
+ try {
663
+ $mustUsePluginDir = rtrim(WPMU_PLUGIN_DIR, '/');
664
+ $loaderPath = $mustUsePluginDir.'/'.$loaderName;
665
+
666
+ if (!file_exists($loaderPath)) {
667
+ return;
668
+ }
669
+
670
+ $removed = @unlink($loaderPath);
671
+
672
+ if (!$removed) {
673
+ $error = error_get_last();
674
+ throw new Exception(sprintf('Unable to remove loader: %s', $error['message']));
675
+ }
676
+ } catch (Exception $e) {
677
+ mwp_logger()->error('Unable to remove loader', array('exception' => $e));
678
  }
679
  }
680
 
681
+ function mwp_get_service_key()
682
  {
683
+ $serviceKey = mwp_context()->optionGet('mwp_service_key');
684
+ if (empty($serviceKey)) {
685
+ $serviceKey = mwp_generate_uuid4();
686
+ mwp_context()->optionSet('mwp_service_key', $serviceKey, true);
 
 
 
687
  }
688
+
689
+ return $serviceKey;
690
  }
691
 
692
+ function mwp_get_communication_keys()
693
  {
694
+ return mwp_context()->optionGet('mwp_communication_keys', array());
695
+ }
 
696
 
697
+ function mwp_remove_current_key()
698
+ {
699
+ mwp_remove_communication_key(!empty($_SERVER['HTTP_MWP_SITE_ID']) ? $_SERVER['HTTP_MWP_SITE_ID'] : 'any');
700
+ }
701
 
702
+ function mwp_remove_communication_key($siteId)
703
+ {
704
+ if ($siteId === 'any') {
705
+ mwp_context()->optionDelete('mwp_communication_key');
706
+ return;
707
  }
708
 
709
+ $keys = mwp_context()->optionGet('mwp_communication_keys', array());
710
+
711
+ if (empty($keys[$siteId])) {
712
+ return;
713
  }
714
 
715
+ unset($keys[$siteId]);
716
+ mwp_context()->optionSet('mwp_communication_keys', $keys, true);
717
+ }
718
 
719
+ function mwp_get_basic_communication_key()
720
+ {
721
+ $key = mwp_context()->optionGet('mwp_communication_key');
722
+ if (!empty($key)) {
723
+ mwp_context()->optionSet('mwp_key_last_used_any', time(), true);
724
  }
725
 
726
+ return $key;
727
+ }
 
728
 
729
+ function mwp_add_as_site_communication_key($key)
730
+ {
731
+ $siteId = !empty($_SERVER['HTTP_MWP_SITE_ID']) ? $_SERVER['HTTP_MWP_SITE_ID'] : null;
732
+
733
+ if (empty($siteId)) {
734
+ return;
735
  }
 
 
736
 
737
+ $keys = mwp_context()->optionGet('mwp_communication_keys', array());
 
738
 
739
+ if (is_array($keys) && !empty($keys[$siteId])) {
740
+ return;
 
 
 
741
  }
 
 
 
 
 
 
742
 
743
+ mwp_accept_potential_key($key);
744
  }
745
 
746
+ function mwp_get_communication_key($id = null)
747
  {
748
+ $siteId = !empty($_SERVER['HTTP_MWP_SITE_ID']) ? $_SERVER['HTTP_MWP_SITE_ID'] : $id;
 
 
749
 
750
+ if (empty($siteId)) {
751
+ return mwp_get_basic_communication_key();
752
+ }
753
 
754
+ $keys = mwp_context()->optionGet('mwp_communication_keys', array());
 
755
 
756
+ if (is_array($keys) && !empty($keys[$siteId])) {
757
+ mwp_context()->optionSet('mwp_key_last_used_'.$siteId, time(), true);
758
+
759
+ return $keys[$siteId]['key'];
760
+ }
761
+
762
+ return mwp_get_basic_communication_key();
763
  }
764
 
765
+ function mwp_accept_potential_key($keyToAccept = '')
766
  {
767
+ $siteId = !empty($_SERVER['HTTP_MWP_SITE_ID']) ? $_SERVER['HTTP_MWP_SITE_ID'] : null;
768
+ $addKey = !empty($keyToAccept) ? $keyToAccept : mwp_get_potential_key();
769
 
770
+ if (!empty($siteId)) {
771
+ $keys = mwp_context()->optionGet('mwp_communication_keys', array());
772
 
773
+ if (empty($keys) || !is_array($keys)) {
774
+ $keys = array();
775
+ }
 
776
 
777
+ $time = time();
778
+ $keys[$siteId] = array(
779
+ 'key' => $addKey,
780
+ 'added' => $time,
781
+ );
782
+
783
+ mwp_context()->optionSet('mwp_communication_keys', $keys, true);
784
+ mwp_context()->optionSet('mwp_key_last_used_'.$addKey, $time, true);
785
  } else {
786
+ mwp_context()->optionSet('mwp_communication_key', $addKey, true);
787
  }
 
788
 
789
+ mwp_context()->optionDelete('mwp_potential_key', true);
790
+ mwp_context()->optionDelete('mwp_potential_key_time', true);
 
 
791
 
792
+ return $addKey;
 
 
 
 
 
793
  }
794
 
795
+ function mwp_get_potential_key()
796
  {
797
+ $potentialKey = mwp_context()->optionGet('mwp_potential_key', null);
798
+ $potentialKeyTime = mwp_context()->optionGet('mwp_potential_key_time', 0);
799
+ $now = time();
800
 
801
+ if (empty($potentialKey) || empty($potentialKeyTime) || !is_numeric($potentialKeyTime) || ($now - $potentialKeyTime) > 86400) {
802
+ $potentialKey = mwp_generate_uuid4();
803
+ $potentialKeyTime = $now;
804
+ mwp_context()->optionSet('mwp_potential_key', $potentialKey, true);
805
+ mwp_context()->optionSet('mwp_potential_key_time', $potentialKeyTime, true);
806
  }
 
807
 
808
+ return $potentialKey;
 
 
 
 
 
 
 
 
 
809
  }
810
 
811
+ function mwp_provision_keys()
812
  {
813
+ mwp_get_service_key();
814
+ mwp_get_potential_key();
 
 
 
 
 
 
815
  }
816
 
817
+ function mwp_add_post_to_link_monitor_check($postId)
818
  {
819
+ if (wp_get_post_parent_id($postId) !== 0) {
820
+ return;
 
 
 
 
 
 
 
 
821
  }
 
 
822
 
823
+ $postsToSendToLinkMonitor = mwp_context()->transientGet('mwp_link_monitor_posts');
824
+ if ($postsToSendToLinkMonitor === false) {
825
+ $postsToSendToLinkMonitor = array();
826
+ }
827
 
828
+ if (in_array($postId, $postsToSendToLinkMonitor)) {
829
+ return;
 
 
 
830
  }
831
+
832
+ $postsToSendToLinkMonitor[] = $postId;
833
+
834
+ //transient will expire after 30 days from time of update
835
+ mwp_context()->transientSet('link_monitor_posts', $postsToSendToLinkMonitor, 2592000);
836
  }
837
 
838
+ function mwp_send_posts_to_link_monitor()
839
  {
840
+ $postsToSendToLinkMonitor = mwp_context()->transientGet('link_monitor_posts');
841
+ if ($postsToSendToLinkMonitor === false) {
842
+ return;
843
+ }
844
 
845
+ $siteIds = array_keys(mwp_context()->optionGet('mwp_communication_keys', array()));
846
+
847
+ foreach ($siteIds as $siteId) {
848
+ $body = array(
849
+ 'qName' => 'ha.link_monitor',
850
+ 'content' => array(
851
+ 'postIds' => $postsToSendToLinkMonitor,
852
+ 'siteId' => $siteId
853
+ ),
854
+ 'delay' => 0
855
+ );
856
+
857
+ // Queue the scan
858
+ $url = 'https://link-monitor-produce.managewp.com/produce';
859
+ $headers['content-type'] = 'application/json';
860
+ wp_remote_post($url, array(
861
+ 'method' => 'POST',
862
+ 'timeout' => 5,
863
+ 'headers' => $headers,
864
+ 'body' => json_encode($body),
865
+ )
866
+ );
867
  }
868
+
869
+
870
+ // Clear transient
871
+ mwp_context()->transientDelete('link_monitor_posts');
872
  }
873
 
874
+ function mwp_link_monitor_cron_recurrence_interval($schedules)
875
  {
876
+ $schedules['every_five_minutes'] = array(
877
+ 'interval' => 300,
878
+ 'display' => __('Every 5 Minutes')
879
+ );
880
 
881
+ return $schedules;
 
 
 
 
 
882
  }
883
 
884
+ function mwp_generate_uuid4()
885
  {
886
+ $data = null;
887
+ if (function_exists('openssl_random_pseudo_bytes')) {
888
+ $data = @openssl_random_pseudo_bytes(16);
889
+ }
890
 
891
+ if (empty($data)) {
892
+ $data = '';
893
+ for ($i = 0; $i < 16; ++$i) {
894
+ $data .= chr(mt_rand(0, 255));
895
+ }
896
  }
897
+
898
+ $data[6] = chr(ord($data[6]) & 0x0f | 0x40); // set version to 0100
899
+ $data[8] = chr(ord($data[8]) & 0x3f | 0x80); // set bits 6-7 to 10
900
+ return vsprintf('%s%s-%s-%s-%s-%s%s%s', str_split(bin2hex($data), 4));
901
  }
902
 
903
+ function mwp_refresh_live_public_keys($params = array())
904
  {
905
+ $liveKeys = null;
906
+ $lastResponse = null;
907
+ $servers = array('cdn.managewp.com', 'keys.managewp.com');
908
 
909
+ foreach ($servers as $server) {
910
+ if (!empty($liveKeys)) {
911
+ continue;
912
+ }
913
+
914
+ $lastResponse = mwp_get_and_decode_public_keys($server);
915
+
916
+ if (is_array($lastResponse) && !empty($lastResponse['keys']) && !empty($lastResponse['success'])) {
917
+ $liveKeys = $lastResponse['keys'];
918
+ }
919
  }
 
920
 
921
+ if (empty($liveKeys)) {
922
+ return $lastResponse;
 
 
923
  }
924
 
925
+ mwp_context()->optionSet('mwp_public_keys_refresh_time', time(), true);
926
+ mwp_context()->optionSet('mwp_public_keys', $liveKeys, true);
927
+
928
+ return $lastResponse;
929
  }
930
 
931
+ function mwp_get_and_decode_public_keys($domain)
932
  {
933
+ $liveContent = mwp_get_public_keys_from_live($domain);
 
 
 
 
 
 
934
 
935
+ if ($liveContent['success'] === false) {
936
+ return array(
937
+ 'success' => false,
938
+ 'message' => $liveContent['message'],
939
+ );
940
  }
941
 
942
+ $liveContent = $liveContent['result'];
 
943
 
944
+ if (empty($liveContent)) {
945
+ return array(
946
+ 'success' => false,
947
+ 'message' => 'Empty content received from live.',
948
+ );
 
949
  }
950
 
951
+ $liveKeys = @json_decode($liveContent, true);
 
952
 
953
+ if (empty($liveKeys)) {
954
+ return array(
955
+ 'success' => false,
956
+ 'message' => 'Could not json decode the received keys. Received: '.$liveKeys,
957
+ );
958
+ }
 
 
 
959
 
960
+ return array(
961
+ 'success' => true,
962
+ 'keys' => $liveKeys,
963
+ );
964
  }
965
 
966
+ function mwp_get_public_keys_from_live($domain)
967
  {
968
+ $result = wp_remote_get("https://$domain/public-keys");
 
969
 
970
+ if (!is_array($result) || empty($result['body'])) {
971
+ return mwp_get_public_keys_from_live_fallback($domain);
 
972
  }
 
973
 
974
+ return array(
975
+ 'success' => true,
976
+ 'result' => $result['body'],
977
+ );
 
 
 
978
  }
979
 
980
+ function mwp_get_public_keys_from_live_fallback($domain)
981
  {
982
+ $fixedDomainMap = array(
983
+ 'keys.managewp.com' => '216.69.138.218',
984
+ );
985
 
986
+ $originalDomain = $domain;
987
+ $domain = dns_resolve_key_domain($domain);
988
 
989
+ if (preg_match('/^\d+\.\d+\.\d+\.\d+$/', $domain) !== 1 && !empty($fixedDomainMap[$domain])) {
990
+ $domain = $fixedDomainMap[$domain];
991
+ }
 
992
 
993
+ $transportToUse = get_secure_protocol();
 
 
994
 
995
+ if ($transportToUse == null) {
996
+ return array(
997
+ 'success' => false,
998
+ 'message' => 'Could not find a transport to use.',
999
+ );
1000
+ }
1001
 
1002
+ $socket = @stream_socket_client("$transportToUse://$domain:443", $errno, $errstr, 30, STREAM_CLIENT_CONNECT, @stream_context_create(array(
1003
+ 'ssl' => array(
1004
+ 'peer_name' => $originalDomain,
1005
+ 'verify_peer' => true,
1006
+ 'verify_peer_name' => true,
1007
+ 'allow_self_signed' => false,
1008
+ 'cafile' => dirname(__FILE__).'/publickeys/godaddy_g2_root.cer',
1009
+ ),
1010
+ )));
1011
 
1012
+ if (!$socket) {
1013
+ return array(
1014
+ 'success' => false,
1015
+ 'message' => 'Failed opening a socket to ManageWP keys (on '.$domain.'). Error: '.$errstr.', Error number: '.$errno,
1016
+ );
1017
+ }
1018
 
1019
+ $requestContent = <<<EOL
1020
+ GET /public-keys HTTP/1.1
1021
+ Host: cdn.managewp.com
1022
+ Accept-Language: en-US,en;q=0.9,hr;q=0.8,sr;q=0.7
1023
+ Upgrade-Insecure-Requests: 1
1024
+ User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36
1025
+ Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
1026
+ Cache-Control: max-age=0
1027
+ Authority: cdn.managewp.com
1028
+ Connection: close
1029
 
 
 
 
1030
 
1031
+ EOL;
 
 
1032
 
1033
+
1034
+ if (@fwrite($socket, $requestContent) === false) {
1035
+ return array(
1036
+ 'success' => false,
1037
+ 'message' => 'Could not write the public-key request to the socket.',
1038
+ );
1039
  }
1040
+
1041
+ return read_stream_response($socket);
1042
  }
1043
 
1044
+ function get_secure_protocol()
1045
  {
1046
+ $transports = array_flip(stream_get_transports());
1047
+ $preferredTransport = array(
1048
+ 'tls',
1049
+ 'tlsv1.2',
1050
+ 'tlsv1.1',
1051
+ 'tlsv1.0',
1052
+ );
 
 
 
 
 
 
 
1053
 
1054
+ $transportToUse = null;
1055
+
1056
+ foreach ($preferredTransport as $transport) {
1057
+ if (!empty($transportToUse) || !isset($transports[$transport])) {
1058
+ continue;
 
 
 
 
 
 
 
1059
  }
 
1060
 
1061
+ $transportToUse = $transport;
 
1062
  }
1063
+
1064
+ return $transportToUse;
1065
  }
1066
 
1067
+ function read_stream_response($socket)
1068
  {
1069
+ do {
1070
+ $line = @fgets($socket);
1071
+ } while ($line !== false && $line !== "\n" && $line !== "\r\n");
1072
+
1073
+ if ($line === false) {
1074
+ return array(
1075
+ 'success' => false,
1076
+ 'message' => 'No response received from the public-key server.',
1077
+ );
1078
  }
 
1079
 
1080
+ $content = @stream_get_contents($socket);
1081
+
1082
+ @fclose($socket);
1083
+
1084
+ if ($content === false || !is_string($content)) {
1085
+ return array(
1086
+ 'success' => false,
1087
+ 'message' => 'Invalid response received from the public-key server.',
1088
+ );
1089
  }
1090
 
1091
+ return array(
1092
+ 'success' => true,
1093
+ 'result' => $content,
1094
+ );
1095
  }
1096
 
1097
+ function dns_resolve_key_domain($domain)
1098
  {
1099
+ $transportToUse = get_secure_protocol();
 
1100
 
1101
+ if ($transportToUse == null) {
1102
+ return $domain;
1103
  }
1104
 
1105
+ $socket = @stream_socket_client("$transportToUse://1.1.1.1:443", $errno, $errstr, 30, STREAM_CLIENT_CONNECT);
1106
 
1107
+ if (!$socket) {
1108
+ return $domain;
1109
  }
1110
 
1111
+ $requestContent = <<<PHP
1112
+ GET /dns-query?name=[DOMAIN]&type=A HTTP/1.1
1113
+ Host: 1.1.1.1
1114
+ Accept: application/dns-json
1115
+ Connection: close
1116
 
 
 
 
 
 
 
1117
 
1118
+ PHP;
1119
 
1120
+ $requestContent = str_replace('[DOMAIN]', $domain, $requestContent);
1121
+
1122
+ if (@fwrite($socket, $requestContent) === false) {
1123
+ return $domain;
1124
  }
1125
 
1126
+ $result = read_stream_response($socket);
 
1127
 
1128
+ if ($result['success'] === false || empty($result['result'])) {
1129
+ return $domain;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1130
  }
 
1131
 
1132
+ $content = @json_decode($result['result'], true);
 
 
 
 
 
1133
 
1134
+ if (empty($content['Answer']) || !is_array($content['Answer'])) {
1135
+ return $domain;
1136
+ }
1137
 
1138
+ $record = $content['Answer'][count($content['Answer']) - 1];
1139
 
1140
+ if (empty($record['data']) || preg_match('/^\d+\.\d+\.\d+\.\d+$/', $record['data']) !== 1) {
1141
+ return $domain;
 
 
 
 
1142
  }
1143
+
1144
+ return $record['data'];
1145
+ }
1146
+
1147
+ function site_in_mwp_maintenance_mode()
1148
+ {
1149
+ $class = 'notice notice-warning is-dismissible';
1150
+ $message = esc_html__('The site is currently in maintenance mode.', 'worker');
1151
+ printf('<div class="%1$s"><p>%2$s</p></div>', esc_attr($class), esc_html($message));
1152
+ }
1153
+
1154
+ function getUploadMessages()
1155
+ {
1156
+ return array(
1157
+ 'path_not_exist' => 8,
1158
+ 'file_exist' => 9,
1159
+ 'upload_failed' => 10,
1160
+ 'upload_success' => 11,
1161
+ 'permissions_denied' => 13,
1162
+ );
1163
  }
index.html DELETED
File without changes
index.php ADDED
@@ -0,0 +1,2 @@
 
 
1
+ <?php
2
+ // Silence is golden.
init.php CHANGED
@@ -2,11 +2,13 @@
2
  /*
3
  Plugin Name: ManageWP - Worker
4
  Plugin URI: https://managewp.com
5
- Description: ManageWP Worker plugin allows you to manage your WordPress sites from one dashboard. Visit <a href="https://managewp.com">ManageWP.com</a> for more information.
6
- Version: 4.1.0
7
- Author: ManageWP
8
- Author URI: https://managewp.com
9
  License: GPL2
 
 
10
  */
11
 
12
  /*
@@ -18,10 +20,14 @@ License: GPL2
18
  * file that was distributed with this source code.
19
  */
20
 
21
- if (!defined('ABSPATH')) {
22
  exit;
23
  }
24
 
 
 
 
 
25
  /**
26
  * Handler for incomplete plugin installations.
27
  */
@@ -40,7 +46,12 @@ if (!function_exists('mwp_fail_safe')):
40
 
41
  $lastError = error_get_last();
42
 
43
- if (!$lastError || $lastError['type'] !== E_ERROR) {
 
 
 
 
 
44
  return;
45
  }
46
 
@@ -58,7 +69,10 @@ if (!function_exists('mwp_fail_safe')):
58
  }
59
 
60
  // The only fatal error that we would get would be a 'Class 'X' not found in ...', so look out only for those messages.
61
- if (!preg_match('/^Class \'[^\']+\' not found$/', $lastError['message'])) {
 
 
 
62
  return;
63
  }
64
 
@@ -68,29 +82,22 @@ if (!function_exists('mwp_fail_safe')):
68
  return;
69
  }
70
 
71
- unset($activePlugins[$workerIndex]);
72
- // Reset indexes.
73
- $activePlugins = array_values($activePlugins);
74
- update_option('active_plugins', $activePlugins);
75
 
76
- // We probably won't have access to the wp_mail function.
77
- $mailFn = function_exists('wp_mail') ? 'wp_mail' : 'mail';
78
  $siteUrl = get_option('siteurl');
79
- $title = sprintf("ManageWP Worker deactivated on %s", $siteUrl);
 
80
  $to = get_option('admin_email');
81
  $brand = get_option('mwp_worker_brand');
82
  if (!empty($brand['admin_email'])) {
83
  $to = $brand['admin_email'];
84
  }
85
 
86
- $fullError = print_r($lastError, 1);
87
- $workerSettings = get_option('wrksettings');
88
- $userID = 0;
89
- if (!empty($workerSettings['dataown'])) {
90
- $userID = (int) $workerSettings['dataown'];
91
- }
92
- $body = sprintf("Worker deactivation due to an error. The site that was affected - %s. User email - %s (User ID: %s). Worker version: %s (%s). The error that caused this:\n<pre>%s</pre>", $siteUrl, $to, $userID, $GLOBALS['MMB_WORKER_VERSION'], $GLOBALS['MMB_WORKER_REVISION'], $fullError);
93
- $mailFn('dev@managewp.com', $title, $body);
94
 
95
  // If we're inside a cron scope, don't attempt to hide this error.
96
  if (defined('DOING_CRON') && DOING_CRON) {
@@ -99,9 +106,21 @@ if (!function_exists('mwp_fail_safe')):
99
 
100
  // If we're inside a normal request scope retry the request so user doesn't have to see an ugly error page.
101
  if (!empty($_SERVER['REQUEST_URI'])) {
102
- $siteUrl .= $_SERVER['REQUEST_URI'];
103
  }
104
- if (headers_sent()) {
 
 
 
 
 
 
 
 
 
 
 
 
105
  // The headers are probably sent if the PHP configuration has the 'display_errors' directive enabled. In that case try a meta redirect.
106
  printf('<meta http-equiv="refresh" content="0; url=%s">', htmlspecialchars($siteUrl, ENT_QUOTES));
107
  } else {
@@ -130,7 +149,13 @@ if (!class_exists('MwpWorkerResponder', false)):
130
  $this->container = $container;
131
  }
132
 
133
- function callback(Exception $e = null, MWP_Http_ResponseInterface $response = null)
 
 
 
 
 
 
134
  {
135
  if ($response !== null) {
136
  $responseEvent = new MWP_Event_MasterResponse($response);
@@ -175,12 +200,14 @@ if (!function_exists('mwp_container')):
175
  static $container;
176
 
177
  if ($container === null) {
178
- $parameters = (array) get_option('mwp_container_parameters', array());
 
179
  $container = new MWP_ServiceContainer_Production(array(
180
  'worker_realpath' => __FILE__,
181
  'worker_basename' => 'worker/init.php',
182
  'worker_version' => $GLOBALS['MMB_WORKER_VERSION'],
183
  'worker_revision' => $GLOBALS['MMB_WORKER_REVISION'],
 
184
  ) + $parameters);
185
  }
186
 
@@ -188,16 +215,468 @@ if (!function_exists('mwp_container')):
188
  }
189
  endif;
190
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
191
  if (!function_exists('mwp_init')):
192
  function mwp_init()
193
  {
 
 
 
 
 
 
 
 
 
194
  // Ensure PHP version compatibility.
195
  if (version_compare(PHP_VERSION, '5.2', '<')) {
196
  trigger_error("ManageWP Worker plugin requires PHP 5.2 or higher.", E_USER_ERROR);
197
  exit;
198
  }
199
 
200
- // Register the autoloader that loads everything except the Google namespace.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
201
  if (version_compare(PHP_VERSION, '5.3', '<')) {
202
  spl_autoload_register('mwp_autoload');
203
  } else {
@@ -205,11 +684,9 @@ if (!function_exists('mwp_init')):
205
  spl_autoload_register('mwp_autoload', true, true);
206
  }
207
 
208
- $GLOBALS['MMB_WORKER_VERSION'] = '4.1.0';
209
- $GLOBALS['MMB_WORKER_REVISION'] = '2015-04-23 00:00:00';
210
- $GLOBALS['mmb_plugin_dir'] = WP_PLUGIN_DIR.'/'.basename(dirname(__FILE__));
211
- $GLOBALS['_mmb_item_filter'] = array();
212
- $GLOBALS['mmb_core'] = $core = $GLOBALS['mmb_core_backup'] = new MMB_Core();
213
 
214
  $siteUrl = function_exists('get_site_option') ? get_site_option('siteurl') : get_option('siteurl');
215
  define('MMB_XFRAME_COOKIE', 'wordpress_'.md5($siteUrl).'_xframe');
@@ -217,25 +694,29 @@ if (!function_exists('mwp_init')):
217
  define('MWP_BACKUP_DIR', WP_CONTENT_DIR.'/managewp/backups');
218
  define('MWP_DB_DIR', MWP_BACKUP_DIR.'/mwp_db');
219
 
220
- add_filter('mmb_stats_filter', 'mmb_get_extended_info');
221
- add_action('plugins_loaded', 'mwp_return_core_reference', 1);
222
- add_filter('cron_schedules', 'mmb_more_reccurences');
223
- add_action('mmb_remote_upload', 'mmb_call_scheduled_remote_upload');
224
- add_action('mwp_datasend', 'mwp_datasend');
225
  add_action('init', 'mmb_plugin_actions', 99999);
226
  add_filter('install_plugin_complete_actions', 'mmb_iframe_plugins_fix');
227
  add_filter('comment_edit_redirect', 'mwb_edit_redirect_override');
 
 
228
 
229
- // Datasend cron.
230
- if (!wp_next_scheduled('mwp_datasend')) {
231
- wp_schedule_event(time(), 'threehours', 'mwp_datasend');
232
- }
 
233
 
234
- // Register updater hooks.
235
- MMB_Updater::register();
 
 
 
 
 
 
236
 
237
- // Plugin management hooks.
238
- register_activation_hook(__FILE__, array($core, 'install'));
239
  register_deactivation_hook(__FILE__, array($core, 'deactivate'));
240
  register_uninstall_hook(dirname(__FILE__).'/functions.php', 'mwp_uninstall');
241
 
@@ -249,7 +730,7 @@ if (!function_exists('mwp_init')):
249
  if (wp_next_scheduled('mwp_backup_tasks')) {
250
  wp_clear_scheduled_hook('mwp_backup_tasks');
251
  }
252
-
253
  mwp_set_plugin_priority();
254
 
255
  $request = MWP_Worker_Request::createFromGlobals();
@@ -258,9 +739,18 @@ if (!function_exists('mwp_init')):
258
 
259
  $kernel = new MWP_Worker_Kernel($container);
260
  $kernel->handleRequest($request, $responder->getCallback(), true);
 
 
 
 
 
261
  }
262
 
263
- require_once dirname(__FILE__).'/functions.php';
 
 
 
264
 
265
- mwp_init();
 
266
  endif;
2
  /*
3
  Plugin Name: ManageWP - Worker
4
  Plugin URI: https://managewp.com
5
+ Description: We help you efficiently manage all your WordPress websites. <strong>Updates, backups, 1-click login, migrations, security</strong> and more, on one dashboard. This service comes in two versions: standalone <a href="https://managewp.com">ManageWP</a> service that focuses on website management, and <a href="https://godaddy.com/pro">GoDaddy Pro</a> that includes additional tools for hosting, client management, lead generation, and more.
6
+ Version: 4.9.9
7
+ Author: GoDaddy
8
+ Author URI: https://godaddy.com
9
  License: GPL2
10
+ Text Domain: worker
11
+ Network: true
12
  */
13
 
14
  /*
20
  * file that was distributed with this source code.
21
  */
22
 
23
+ if (!defined('ABSPATH') && (!defined('MWP_SKIP_BOOTSTRAP') || !MWP_SKIP_BOOTSTRAP)) {
24
  exit;
25
  }
26
 
27
+ if (!defined('MAX_PRIORITY_HOOK')) {
28
+ define('MAX_PRIORITY_HOOK', 2147483647);
29
+ }
30
+
31
  /**
32
  * Handler for incomplete plugin installations.
33
  */
46
 
47
  $lastError = error_get_last();
48
 
49
+ $acceptedErrorTypes = array(
50
+ E_ERROR,
51
+ E_COMPILE_ERROR,
52
+ );
53
+
54
+ if (!$lastError || !in_array($lastError['type'], $acceptedErrorTypes)) {
55
  return;
56
  }
57
 
69
  }
70
 
71
  // The only fatal error that we would get would be a 'Class 'X' not found in ...', so look out only for those messages.
72
+ if (!preg_match('/^(Uncaught Error: )?Class \'[^\']+\' not found/', $lastError['message']) &&
73
+ !preg_match('/^(Uncaught Error: )?Call to undefined method /', $lastError['message']) &&
74
+ !preg_match('/^require_once\(\): Failed opening required \'[^\']+\'/', $lastError['message'])
75
+ ) {
76
  return;
77
  }
78
 
82
  return;
83
  }
84
 
85
+ // Signal ourselves that the installation is corrupt.
86
+ update_option('mwp_recovering', time());
 
 
87
 
 
 
88
  $siteUrl = get_option('siteurl');
89
+ $path = (string)parse_url($siteUrl, PHP_URL_PATH);
90
+ $title = sprintf("ManageWP Worker corrupt on %s", $siteUrl);
91
  $to = get_option('admin_email');
92
  $brand = get_option('mwp_worker_brand');
93
  if (!empty($brand['admin_email'])) {
94
  $to = $brand['admin_email'];
95
  }
96
 
97
+ $fullError = print_r($lastError, 1);
98
+ $serviceID = (string)get_option('mwp_service_key');
99
+ $body = sprintf("Corrupt ManageWP Worker v%s installation detected. Site URL in question is %s. User email is %s (service ID: %s). Attempting recovery process at %s. The error that caused this:\n\n<pre>%s</pre>", $GLOBALS['MMB_WORKER_VERSION'], $siteUrl, $to, $serviceID, date('Y-m-d H:i:s'), $fullError);
100
+ mail('recovery@managewp.com', $title, $body, "Content-Type: text/html");
 
 
 
 
101
 
102
  // If we're inside a cron scope, don't attempt to hide this error.
103
  if (defined('DOING_CRON') && DOING_CRON) {
106
 
107
  // If we're inside a normal request scope retry the request so user doesn't have to see an ugly error page.
108
  if (!empty($_SERVER['REQUEST_URI'])) {
109
+ $siteUrl .= substr($_SERVER['REQUEST_URI'], strlen($path));
110
  }
111
+ if (isset($_SERVER['HTTP_MWP_ACTION'])) {
112
+ echo "\nMWP_RETRY_ME: 1\n", json_encode(array('error' => 'Worker recover started', 'exception' => array(
113
+ 'class' => 'Exception',
114
+ 'message' => 'Worker recover started',
115
+ 'code' => 10038,
116
+ 'file' => __FILE__,
117
+ 'line' => __LINE__,
118
+ 'traceString' => '',
119
+ 'context' => array(),
120
+ 'type' => 'WORKER_RECOVER_STARTED',
121
+ ))), "\n";
122
+ exit;
123
+ } elseif (headers_sent()) {
124
  // The headers are probably sent if the PHP configuration has the 'display_errors' directive enabled. In that case try a meta redirect.
125
  printf('<meta http-equiv="refresh" content="0; url=%s">', htmlspecialchars($siteUrl, ENT_QUOTES));
126
  } else {
149
  $this->container = $container;
150
  }
151
 
152
+ /**
153
+ * @param Exception|Error $e
154
+ * @param MWP_Http_ResponseInterface|null $response
155
+ *
156
+ * @throws null
157
+ */
158
+ function callback($e = null, MWP_Http_ResponseInterface $response = null)
159
  {
160
  if ($response !== null) {
161
  $responseEvent = new MWP_Event_MasterResponse($response);
200
  static $container;
201
 
202
  if ($container === null) {
203
+ $parameters = (array)get_option('mwp_container_parameters', array()) + (array)get_option('mwp_container_site_parameters', array());
204
+ $requestId = isset($_GET['mwprid']) && is_string($_GET['mwprid']) ? $_GET['mwprid'] : null;
205
  $container = new MWP_ServiceContainer_Production(array(
206
  'worker_realpath' => __FILE__,
207
  'worker_basename' => 'worker/init.php',
208
  'worker_version' => $GLOBALS['MMB_WORKER_VERSION'],
209
  'worker_revision' => $GLOBALS['MMB_WORKER_REVISION'],
210
+ 'request_id' => $requestId,
211
  ) + $parameters);
212
  }
213
 
215
  }
216
  endif;
217
 
218
+ if (!class_exists('MwpRecoveryKit', false)):
219
+ /**
220
+ * This class must be isolated from the rest of the ManageWP Worker library, because
221
+ * we're counting that we have only this file and WordPress bootstrapped.
222
+ */
223
+ class MwpRecoveryKit
224
+ {
225
+ const MAX_LOGGED_ERRORS = 5;
226
+
227
+ private static $errorLog = array();
228
+
229
+ private static function requestJson($url)
230
+ {
231
+ $response = wp_remote_get($url, array('timeout' => 60));
232
+ if ($response instanceof WP_Error) {
233
+ throw new Exception('Unable to download checksum.json: '.$response->get_error_message());
234
+ }
235
+ if ($response['response']['code'] !== 200) {
236
+ throw new Exception('Unable to download checksum.json: invalid status code ('.$response['response']['code'].')');
237
+ }
238
+
239
+ $responseJson = json_decode($response['body'], true);
240
+
241
+ if (empty($responseJson) || !is_array($responseJson)) {
242
+ throw new Exception('Error while parsing checksum.json.');
243
+ }
244
+
245
+ return $responseJson;
246
+ }
247
+
248
+ public function recover($version)
249
+ {
250
+ global $wpdb;
251
+ $lockTime = $wpdb->get_var("SELECT option_value FROM $wpdb->options WHERE option_name = 'mwp_incremental_recover_lock' LIMIT 1");
252
+
253
+
254
+ if ($lockTime && time() - (int)$lockTime < 1200) { // lock for 20 minutes
255
+ throw new Exception('Another incremental update or recovery process is already active', 1337);
256
+ }
257
+
258
+ register_shutdown_function(array($this, 'releaseLock'));
259
+
260
+ update_option('mwp_incremental_recover_lock', time());
261
+
262
+ ignore_user_abort(true);
263
+ $dirName = realpath(dirname(__FILE__));
264
+ $filesAndChecksums = $this->requestJson(sprintf('http://s3-us-west-2.amazonaws.com/mwp-orion-public/worker/raw/%s/checksum.json', $version));
265
+
266
+ try {
267
+ $files = $this->recoverFiles($dirName, $filesAndChecksums, $version);
268
+ } catch (Exception $e) {
269
+ $this->releaseLock();
270
+ throw $e;
271
+ }
272
+
273
+ $this->releaseLock();
274
+
275
+ return $files;
276
+ }
277
+
278
+ public function releaseLock()
279
+ {
280
+ delete_option('mwp_incremental_recover_lock');
281
+ }
282
+
283
+ public static function selfUpdate()
284
+ {
285
+ if (get_option('mwp_recovering')) {
286
+ return false;
287
+ }
288
+
289
+ try {
290
+ $response = self::requestJson('http://s3-us-west-2.amazonaws.com/mwp-orion-public/worker/latest.json');
291
+ $response += array('version' => '0.0.0', 'schedule' => 86400, 'autoUpdate' => false, 'checksum' => array());
292
+ wp_clear_scheduled_hook('mwp_auto_update');
293
+ wp_schedule_single_event(current_time('timestamp') + $response['schedule'], 'mwp_auto_update');
294
+ if (!$response['autoUpdate']) {
295
+ return false;
296
+ }
297
+ if (version_compare($response['version'], $GLOBALS['MMB_WORKER_VERSION'], '<')) {
298
+ return false;
299
+ }
300
+ self::recoverFiles(dirname(__FILE__), $response['checksum'], $response['version']);
301
+ } catch (Exception $e) {
302
+ mwp_logger()->error("Self-update failed.", array('exception' => $e));
303
+
304
+ return false;
305
+ }
306
+
307
+ return true;
308
+ }
309
+
310
+ private static function clearUnknownFiles($filesAndChecksums, $fs)
311
+ {
312
+ /** @var WP_Filesystem_Base $fs */
313
+ $base = dirname(__FILE__);
314
+ if (version_compare(phpversion(), '5.3', '<')) {
315
+ $directory = new RecursiveDirectoryIterator($base);
316
+ } else {
317
+ /** @handled constant */
318
+ $directory = new RecursiveDirectoryIterator($base, RecursiveDirectoryIterator::SKIP_DOTS);
319
+ }
320
+
321
+ $ignoreDelete = array(
322
+ 'log.html' => 1,
323
+ 'worker.json' => 1,
324
+ 'init.php' => 1, // safe-guard
325
+ 'functions.php' => 1, // safe-guard
326
+ );
327
+
328
+ $files = array_keys(iterator_to_array(new RecursiveIteratorIterator($directory, RecursiveIteratorIterator::SELF_FIRST, RecursiveIteratorIterator::CATCH_GET_CHILD)));
329
+
330
+ foreach ($files as $file) {
331
+ $file = preg_replace('/^'.preg_quote($base, '/').'/', '', $file, 1, $count);
332
+
333
+ if (!$count) {
334
+ continue;
335
+ }
336
+
337
+ $file = strtr($file, '\\', '/');
338
+ $file = ltrim($file, '/');
339
+
340
+ if (isset($filesAndChecksums[$file]) || isset($ignoreDelete[$file])) {
341
+ continue;
342
+ }
343
+
344
+ $fs->delete($fs->find_folder(WP_PLUGIN_DIR).'worker/'.$file, false, 'f');
345
+ }
346
+ }
347
+
348
+ public static function recoverFiles($dirName, array $filesAndChecksums, $version)
349
+ {
350
+ set_error_handler(array(__CLASS__, 'logError'));
351
+ require_once ABSPATH.'wp-admin/includes/file.php';
352
+ require_once ABSPATH.'wp-admin/includes/template.php';
353
+
354
+ $options = array();
355
+
356
+ $fsMethod = get_filesystem_method();
357
+ if ($fsMethod !== 'direct') {
358
+ ob_start();
359
+ $options = request_filesystem_credentials('');
360
+ ob_end_clean();
361
+ }
362
+
363
+ /** @var WP_Filesystem_Base $fs */
364
+ WP_Filesystem($options);
365
+ $fs = $GLOBALS['wp_filesystem'];
366
+
367
+ if (!$fs->connect()) {
368
+ $lastError = error_get_last();
369
+ $errorMessage = $lastError ? $lastError['message'] : '(no error logged)';
370
+ throw new Exception('Unable to connect to the file system: '.$errorMessage);
371
+ }
372
+
373
+ $cachedFilesAndChecksums = $filesAndChecksums;
374
+
375
+ // First create directories and remove them from the array.
376
+ // Must be done before shuffling because of nesting.
377
+ foreach ($filesAndChecksums as $relativePath => $checksum) {
378
+ if ($checksum !== '') {
379
+ continue;
380
+ }
381
+ unset ($filesAndChecksums[$relativePath]);
382
+ $absolutePath = $dirName.'/'.$relativePath;
383
+ // Directories are ordered first.
384
+ if (!is_dir($absolutePath)) {
385
+ $fs->mkdir($fs->find_folder(WP_PLUGIN_DIR).'worker/'.$relativePath);
386
+ }
387
+ }
388
+
389
+ // Check and recreate files. Shuffle them so multiple running instances have a smaller collision.
390
+ $recoveredFiles = array();
391
+ $filesAndChecksums = self::shuffleAssoc($filesAndChecksums);
392
+ $retryCount = 0;
393
+ $retryUpTo = 5;
394
+ $lastError = null;
395
+ while ($checksum = current($filesAndChecksums)) {
396
+ if ($retryCount >= $retryUpTo) {
397
+ restore_error_handler();
398
+ throw new Exception($lastError);
399
+ }
400
+ $relativePath = key($filesAndChecksums);
401
+ $absolutePath = $dirName.'/'.$relativePath;
402
+ if (file_exists($absolutePath) && md5_file($absolutePath) === $checksum) {
403
+ next($filesAndChecksums);
404
+ continue;
405
+ }
406
+ $fileUrl = sprintf('http://s3-us-west-2.amazonaws.com/mwp-orion-public/worker/raw/%s/%s', $version, $relativePath);
407
+ $response = wp_remote_get($fileUrl, array('timeout' => 60));
408
+ if ($response instanceof WP_Error) {
409
+ $lastError = 'Unable to download file '.$fileUrl.': '.$response->get_error_message();
410
+ $retryCount++;
411
+ continue;
412
+ }
413
+ if ($response['response']['code'] !== 200) {
414
+ $lastError = 'Unable to download file '.$fileUrl.': invalid status code ('.$response['response']['code'].')';
415
+ $retryCount++;
416
+ continue;
417
+ }
418
+ $saved = $fs->put_contents($fs->find_folder(WP_PLUGIN_DIR).'worker/'.$relativePath, $response['body']);
419
+
420
+ if (!$saved) {
421
+ if (is_callable(array($fs, '__destruct'))) {
422
+ $fs->__destruct();
423
+ }
424
+ $fs->connect();
425
+ $lastError = 'File saving failed.';
426
+ if (count(self::$errorLog)) {
427
+ $lastError .= sprintf(" Last %d logged errors:%s", min(self::MAX_LOGGED_ERRORS, count(self::$errorLog)), "\n - ".implode("\n - ", self::$errorLog));
428
+ }
429
+ $retryCount++;
430
+ continue;
431
+ }
432
+
433
+ $lastError = null;
434
+ $retryCount = 0;
435
+ $recoveredFiles[] = $relativePath;
436
+ next($filesAndChecksums);
437
+ }
438
+
439
+ self::clearUnknownFiles($cachedFilesAndChecksums, $fs);
440
+
441
+ if (function_exists('opcache_reset')) {
442
+ @opcache_reset();
443
+ }
444
+
445
+ restore_error_handler();
446
+
447
+ return $recoveredFiles;
448
+ }
449
+
450
+ public static function logError($code, $message, $file = 'Unknown', $line = 0)
451
+ {
452
+ self::$errorLog[] = sprintf('Error [%d]: %s in %s on line %d', $code, $message, $file, $line);
453
+
454
+ if (count(self::$errorLog) > self::MAX_LOGGED_ERRORS) {
455
+ array_shift(self::$errorLog);
456
+ }
457
+ }
458
+
459
+ private static function shuffleAssoc($array)
460
+ {
461
+ $keys = array_keys($array);
462
+ shuffle($keys);
463
+ $shuffled = array();
464
+ foreach ($keys as $key) {
465
+ $shuffled[$key] = $array[$key];
466
+ }
467
+
468
+ return $shuffled;
469
+ }
470
+
471
+ public function selfDeactivate($reason)
472
+ {
473
+ if (isset($_SERVER['MWP2_VERSION_ID'])) {
474
+ return;
475
+ }
476
+
477
+ $activePlugins = get_option('active_plugins');
478
+ $workerIndex = array_search(plugin_basename(__FILE__), $activePlugins);
479
+ if ($workerIndex === false) {
480
+ // Plugin is not yet enabled, possibly in activation context.
481
+ return;
482
+ }
483
+ unset($activePlugins[$workerIndex]);
484
+ // Reset indexes.
485
+ $activePlugins = array_values($activePlugins);
486
+
487
+ delete_option('mwp_recovering');
488
+ update_option('active_plugins', $activePlugins);
489
+
490
+ $lastErrorMessage = '';
491
+ if ($lastError = error_get_last()) {
492
+ $lastErrorMessage = "\n\nLast error: ".$lastError['message'];
493
+ }
494
+ mail('recovery@managewp.com', sprintf("ManageWP Worker recovery aborted on %s", get_option('siteurl')), sprintf("ManageWP Worker v%s. Reason: %s%s", $GLOBALS['MMB_WORKER_VERSION'], $reason, $lastErrorMessage));
495
+ }
496
+ }
497
+ endif;
498
+
499
+ if (!function_exists('mwp_activation_hook')) {
500
+ function mwp_activation_hook()
501
+ {
502
+ update_option('mwp_incremental_update_active', '');
503
+
504
+ if (get_option('mwp_recovering')) {
505
+ update_option('mwp_recovering', '');
506
+ // Run the checksum one last time.
507
+ $recoveryKit = new MwpRecoveryKit();
508
+ try {
509
+ $recoveryKit->recover($GLOBALS['MMB_WORKER_VERSION']);
510
+ } catch (Exception $e) {
511
+ // Deactivating the plugin in activation hook wouldn't work, prevent the activation by triggering an error.
512
+ trigger_error($e->getMessage(), E_USER_ERROR);
513
+ }
514
+ }
515
+
516
+ mwp_core()->install();
517
+ }
518
+ }
519
+
520
+ if (!function_exists('mwp_try_recovery')):
521
+ function mwp_try_recovery()
522
+ {
523
+ global $wpdb;
524
+ $recoveringTime = $wpdb->get_var("SELECT option_value FROM $wpdb->options WHERE option_name = 'mwp_recovering' LIMIT 1");
525
+
526
+ if (empty($recoveringTime)) {
527
+ return true;
528
+ }
529
+
530
+ delete_transient('mwp_recovery_key');
531
+ $recoveryKit = new MwpRecoveryKit();
532
+ try {
533
+ $recoveredFiles = $recoveryKit->recover($GLOBALS['MMB_WORKER_VERSION']);
534
+
535
+ // Recovery complete.
536
+ update_option('mwp_recovering', '');
537
+ mail('recovery@managewp.com', sprintf("ManageWP Worker recovered on %s", get_option('siteurl')), sprintf("%d files successfully recovered in this recovery fork of ManageWP Worker v%s. Filesystem method used was <code>%s</code>.\n\n<pre>%s</pre>", count($recoveredFiles), $GLOBALS['MMB_WORKER_VERSION'], get_filesystem_method(), implode("\n", $recoveredFiles)), 'Content-Type: text/html');
538
+ } catch (Exception $e) {
539
+ if ($e->getCode() === 1337) {
540
+ return false;
541
+ }
542
+
543
+ if (time() - $recoveringTime > 3600) {
544
+ // If the recovery process does not complete after an hour, deactivate the Worker for safety
545
+ $recoveryKit->selfDeactivate($e->getMessage());
546
+ }
547
+
548
+ return false;
549
+ }
550
+
551
+ return true;
552
+ }
553
+ endif;
554
+
555
+ if (!function_exists('add_worker_update_info')):
556
+ function add_worker_update_info()
557
+ {
558
+ echo ' The plugin is going to update itself automatically in the next few days.';
559
+ }
560
+ endif;
561
+
562
  if (!function_exists('mwp_init')):
563
  function mwp_init()
564
  {
565
+ // When the plugin deactivates due to a corrupt installation, (de)activation hooks
566
+ // will never get executed, so the 'mwp_recovering' option will never be deleted,
567
+ // making the plugin always force the recovery mode , which may always fail for any
568
+ // reason (eg. the site can't ping itself). Handle that case early.
569
+ register_activation_hook(__FILE__, 'mwp_activation_hook');
570
+
571
+ $GLOBALS['MMB_WORKER_VERSION'] = '4.9.9';
572
+ $GLOBALS['MMB_WORKER_REVISION'] = '2021-07-27 00:00:00';
573
+
574
  // Ensure PHP version compatibility.
575
  if (version_compare(PHP_VERSION, '5.2', '<')) {
576
  trigger_error("ManageWP Worker plugin requires PHP 5.2 or higher.", E_USER_ERROR);
577
  exit;
578
  }
579
 
580
+ if ($incrementalUpdateTime = get_option('mwp_incremental_update_active')) {
581
+ if (time() - $incrementalUpdateTime > 600) { // lock for a maximum of 10 minutes for incremental update
582
+ update_option('mwp_incremental_update_active', '');
583
+ } else {
584
+ if (!isset($_SERVER['HTTP_MWP_ACTION'])) {
585
+ return;
586
+ }
587
+
588
+ global $wpdb;
589
+
590
+ $tries = 0;
591
+ $lastResult = true;
592
+
593
+ while ($tries < 60 && ($lastResult = $wpdb->get_var("SELECT option_value FROM $wpdb->options WHERE option_name = 'mwp_incremental_update_active' LIMIT 1"))) {
594
+ sleep(1);
595
+ ++$tries;
596
+ }
597
+
598
+ if (!$lastResult) {
599
+ echo "\nMWP_RETRY_ME: 1\n";
600
+ }
601
+
602
+ echo "\n", json_encode(array('error' => 'Worker is currently updating; please retry this action in a few seconds.', 'exception' => array(
603
+ 'class' => 'Exception',
604
+ 'message' => 'Worker is currently updating; please retry this action in a few seconds.',
605
+ 'code' => 10037,
606
+ 'file' => __FILE__,
607
+ 'line' => __LINE__,
608
+ 'traceString' => '',
609
+ 'context' => array(),
610
+ 'type' => 'WORKER_UPDATING',
611
+ ))), "\n";
612
+ exit;
613
+ }
614
+ }
615
+
616
+ if ($recoveringTime = get_option('mwp_recovering')) {
617
+ if (isset($_SERVER['HTTP_MWP_ACTION'])) {
618
+ $tries = 0;
619
+ $lastResult = false;
620
+
621
+ while ($tries < 60 && !($lastResult = mwp_try_recovery())) {
622
+ sleep(1);
623
+ ++$tries;
624
+ }
625
+
626
+ if ($lastResult) {
627
+ echo "\nMWP_RETRY_ME: 1\n";
628
+ }
629
+
630
+ echo "\n", json_encode(array('error' => 'Worker is currently recovering; please retry this action in a few seconds.', 'exception' => array(
631
+ 'class' => 'Exception',
632
+ 'message' => 'Worker is currently recovering; please retry this action in a few seconds.',
633
+ 'code' => 10036,
634
+ 'file' => __FILE__,
635
+ 'line' => __LINE__,
636
+ 'traceString' => '',
637
+ 'context' => array(),
638
+ 'type' => 'WORKER_RECOVERING',
639
+ ))), "\n";
640
+
641
+ exit;
642
+ } else {
643
+ $recoveryKey = get_transient('mwp_recovery_key');
644
+ if (!$passedRecoveryKey = filter_input(INPUT_POST, 'mwp_recovery_key')) {
645
+ $recoveryKey = md5(uniqid('', true));
646
+ set_transient('mwp_recovery_key', $recoveryKey, time() + 604800); // 1 week.
647
+
648
+ $headers = array();
649
+ if (isset($_SERVER['HTTP_AUTHORIZATION'])) {
650
+ $headers['AUTHORIZATION'] = $_SERVER['HTTP_AUTHORIZATION'];
651
+ }
652
+
653
+ // fork only once, so we do not make too many parallel requests to the website
654
+ $lockTime = get_option('mwp_incremental_recover_lock');
655
+
656
+ if ($lockTime && time() - $lockTime < 1200) { // lock for 20 minutes
657
+ return;
658
+ }
659
+
660
+ wp_remote_post(get_bloginfo('wpurl'), array(
661
+ 'reject_unsafe_urls' => false,
662
+ 'headers' => $headers,
663
+ 'body' => array(
664
+ 'mwp_recovery_key' => $recoveryKey,
665
+ ),
666
+ 'timeout' => 0.01,
667
+ ));
668
+ } else {
669
+ if ($recoveryKey !== $passedRecoveryKey) {
670
+ return;
671
+ }
672
+
673
+ mwp_try_recovery();
674
+ }
675
+
676
+ return;
677
+ }
678
+ }
679
+
680
  if (version_compare(PHP_VERSION, '5.3', '<')) {
681
  spl_autoload_register('mwp_autoload');
682
  } else {
684
  spl_autoload_register('mwp_autoload', true, true);
685
  }
686
 
687
+ $GLOBALS['mmb_plugin_dir'] = WP_PLUGIN_DIR.'/'.basename(dirname(__FILE__));
688
+ $GLOBALS['_mmb_item_filter'] = array();
689
+ $core = mwp_core();
 
 
690
 
691
  $siteUrl = function_exists('get_site_option') ? get_site_option('siteurl') : get_option('siteurl');
692
  define('MMB_XFRAME_COOKIE', 'wordpress_'.md5($siteUrl).'_xframe');
694
  define('MWP_BACKUP_DIR', WP_CONTENT_DIR.'/managewp/backups');
695
  define('MWP_DB_DIR', MWP_BACKUP_DIR.'/mwp_db');
696
 
697
+ add_filter('deprecated_function_trigger_error', '__return_false');
698
+ add_action('mwp_update_public_keys', 'mwp_refresh_live_public_keys');
 
 
 
699
  add_action('init', 'mmb_plugin_actions', 99999);
700
  add_filter('install_plugin_complete_actions', 'mmb_iframe_plugins_fix');
701
  add_filter('comment_edit_redirect', 'mwb_edit_redirect_override');
702
+ add_action('mwp_auto_update', 'MwpRecoveryKit::selfUpdate');
703
+ add_action('in_plugin_update_message-'.plugin_basename(__FILE__), 'add_worker_update_info');
704
 
705
+ add_filter('cron_schedules', 'mwp_link_monitor_cron_recurrence_interval');
706
+ add_action('mwp_check_for_post_update', 'mwp_send_posts_to_link_monitor');
707
+ if (mwp_context()->optionGet('mwp_link_monitor_enabled')) {
708
+ add_action('save_post', 'mwp_add_post_to_link_monitor_check');
709
+ add_action('delete_post', 'mwp_add_post_to_link_monitor_check');
710
 
711
+ if (!wp_next_scheduled('mwp_check_for_post_update')) {
712
+ wp_schedule_event(time(), 'every_five_minutes', 'mwp_check_for_post_update');
713
+ }
714
+ }
715
+ // Public key updating cron.
716
+ if (!wp_next_scheduled('mwp_update_public_keys')) {
717
+ wp_schedule_event(time(), 'daily', 'mwp_update_public_keys');
718
+ }
719
 
 
 
720
  register_deactivation_hook(__FILE__, array($core, 'deactivate'));
721
  register_uninstall_hook(dirname(__FILE__).'/functions.php', 'mwp_uninstall');
722
 
730
  if (wp_next_scheduled('mwp_backup_tasks')) {
731
  wp_clear_scheduled_hook('mwp_backup_tasks');
732
  }
733
+ mwp_provision_keys();
734
  mwp_set_plugin_priority();
735
 
736
  $request = MWP_Worker_Request::createFromGlobals();
739
 
740
  $kernel = new MWP_Worker_Kernel($container);
741
  $kernel->handleRequest($request, $responder->getCallback(), true);
742
+
743
+ $mwpMM = get_option('mwp_maintenace_mode');
744
+ if (!empty($mwpMM) && $mwpMM['active']) {
745
+ add_action('admin_notices', 'site_in_mwp_maintenance_mode');
746
+ }
747
  }
748
 
749
+ if (!defined('MWP_SKIP_BOOTSTRAP') || !MWP_SKIP_BOOTSTRAP) {
750
+ if (!get_option('mwp_recovering')) {
751
+ require_once dirname(__FILE__).'/functions.php';
752
+ }
753
 
754
+ mwp_init();
755
+ }
756
  endif;
publickeys/ManageWP_mt.pub DELETED
@@ -1,9 +0,0 @@
1
- -----BEGIN PUBLIC KEY-----
2
- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1Osn7/ZLiz3+Of/puyJn
3
- zk0bKLEhLUvKoSn+qLOM+Q1XfOzuAAn9Kwj0JopyqoCPxI5Df3eWEdjQDhG+B7+4
4
- 36o12yq99krg7t79Ez/gy2xJoZM6oIT3eqnh8UO3OFQ8rkvpS7OR+ZWWc1W3/iiH
5
- uVmOpeR2JDM0h7w749+V9Dp3toYLvj84NSmvI2OrtPHS/BIfGBnyk1sEsdT6Gbrz
6
- PBDhO4yTXTetIoLsJsoAIhvXg6OQFYN+QXosftLUcS2PrTJcuX2LN4U8OSSdgtTA
7
- NazcUSeJ7jlmrL1DYuhDUbAvxhT4cWTnATTmAcZPY5n/4h2Ya6XvMvO2AAcpshVK
8
- 2QIDAQAB
9
- -----END PUBLIC KEY-----
 
 
 
 
 
 
 
 
 
publickeys/godaddy_g2_root.cer ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Go Daddy Root Certificate Authority - G2
2
+ ========================================
3
+ -----BEGIN CERTIFICATE-----
4
+ MIIDxTCCAq2gAwIBAgIBADANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMx
5
+ EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoT
6
+ EUdvRGFkZHkuY29tLCBJbmMuMTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRp
7
+ ZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIz
8
+ NTk1OVowgYMxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQH
9
+ EwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjExMC8GA1UE
10
+ AxMoR28gRGFkZHkgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIw
11
+ DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL9xYgjx+lk09xvJGKP3gElY6SKD
12
+ E6bFIEMBO4Tx5oVJnyfq9oQbTqC023CYxzIBsQU+B07u9PpPL1kwIuerGVZr4oAH
13
+ /PMWdYA5UXvl+TW2dE6pjYIT5LY/qQOD+qK+ihVqf94Lw7YZFAXK6sOoBJQ7Rnwy
14
+ DfMAZiLIjWltNowRGLfTshxgtDj6AozO091GB94KPutdfMh8+7ArU6SSYmlRJQVh
15
+ GkSBjCypQ5Yj36w6gZoOKcUcqeldHraenjAKOc7xiID7S13MMuyFYkMlNAJWJwGR
16
+ tDtwKj9useiciAF9n9T521NtYJ2/LOdYq7hfRvzOxBsDPAnrSTFcaUaz4EcCAwEA
17
+ AaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE
18
+ FDqahQcQZyi27/a9BUFuIMGU2g/eMA0GCSqGSIb3DQEBCwUAA4IBAQCZ21151fmX
19
+ WWcDYfF+OwYxdS2hII5PZYe096acvNjpL9DbWu7PdIxztDhC2gV7+AJ1uP2lsdeu
20
+ 9tfeE8tTEH6KRtGX+rcuKxGrkLAngPnon1rpN5+r5N9ss4UXnT3ZJE95kTXWXwTr
21
+ gIOrmgIttRD02JDHBHNA7XIloKmf7J6raBKZV8aPEjoJpL1E/QYVN8Gb5DKj7Tjo
22
+ 2GTzLH4U/ALqn83/B2gX2yKQOC16jdFU8WnjXzPKej17CuPKf1855eJ1usV2GDPO
23
+ LPAvTK33sefOT6jEm0pUBsV/fdUID+Ic/n4XuKxe9tQWskMJDE32p2u0mYRlynqI
24
+ 4uJEvlz36hz1
25
+ -----END CERTIFICATE-----
publickeys/index.php ADDED
@@ -0,0 +1,2 @@
 
 
1
+ <?php
2
+ // Silence is golden.
readme.txt CHANGED
@@ -1,397 +1,203 @@
1
  === ManageWP Worker ===
2
- Contributors: freediver
3
- Donate link: https://www.networkforgood.org/donation/MakeDonation.aspx?ORGID2=520781390
4
- Tags: administration, admin,amazon, analytics, api, automate, automatic, backup, comments, clone, dashboard, database, debug, dropbox, duplicate, events, google analytics, google drive, google, integration, login, manage, managewp, migrate, multiple, multisite, mysql, page, performance, plugin, post, remote, s3, security, seo, spam, speed, stats
5
- Requires at least: 3.0
6
- Tested up to: 4.1
7
  Stable tag: trunk
8
  License: GPLv3 or later
9
  License URI: http://www.gnu.org/licenses/quick-guide-gplv3.html
10
 
11
- ManageWP is the ultimate WordPress productivity tool, allowing you to efficiently manage your websites.
12
 
13
  == Description ==
14
 
15
- [ManageWP](https://managewp.com/ "Manage Multiple WordPress Websites") is a revolutionary service designed to automate most of your daily tasks when managing multiple WordPress websites, allowing you to use your time on more important matters.
16
 
17
  = Everything in One Place =
18
- Just the hassle of logging into each of your websites is enough to ruin your day. With ManageWP the data from all of your sites is compiled and shown on a single easy to use dashboard, allowing you to check up on your websites in a single glance.
19
 
20
- = One-click Management =
21
- With all the data on a single dashboard, all it takes is one click to perform plugin and theme updates on multiple websites. Got comments? Everything is on one single list. Or maybe you want to clean spam comments, table overhead or post revisions from all of your websites? It takes a single click.
22
 
23
- = Backup & Restore =
24
- Never leave home without a backup. With the scheduled backup tasks to remote destinations such as Amazon S3, Dropbox and Google Drive you will always have an up-to-date backup which you can use to restore your website if something happened to it (yeah, we know it was YOU who messed up the CSS!)
25
 
26
- = Quick and Easy Migration =
27
- Want to know how easy is to migrate a website with ManageWP? Pick a source website, pick a destination website, click Go. Yeah, it's that easy.
 
28
 
29
- = Uptime Monitoring =
30
- Be the first to know when your website is down with both email and SMS notifications, and get your website back online before anyone else notices.
31
 
32
- = SEO & Keyword Ranking =
33
- Be on top of your website rankings and figure out which keywords work best for you.
34
 
35
- = Client Reports =
36
- Keep track of what you're doing for your clients and dazzle them with a summary of your hard work.
37
 
38
- = Is This All? =
39
- No way! We've got a bunch of other awesome features, both free and premium, you can check out on our [ManageWP Features & Pricing Page](https://managewp.com/plans-and-pricing "ManageWP Plans & Pricing")
 
 
 
 
 
 
 
 
 
40
 
41
- Check out the [ManageWP promo video](https://www.youtube.com/watch?v=C5nBQJQIfH4).
 
42
 
43
- https://www.youtube.com/watch?v=C5nBQJQIfH4
44
 
45
- ManageWP is also the creator of [ManageWP.org](https://managewp.org/ "WordPress news site"), community project capturing the pulse of the WordPress community.
46
 
47
  == Changelog ==
 
48
 
49
- = 4.1.0 =
 
 
 
50
 
51
- - New: Incremental backup capability for [ManageWP Orion](http://managewp.com/managewp-orion-official-announcement "ManageWP Orion Official Announcement").
52
 
53
- = 4.0.15 =
54
 
55
- - Fix: Improve compatibility with some plugin updates in [ManageWP Orion](http://managewp.com/managewp-orion-official-announcement "ManageWP Orion Official Announcement").
56
 
57
- = 4.0.14 =
 
 
58
 
59
- - Fix: Show custom message when the plugin can not destroy active [ManageWP Orion](http://managewp.com/managewp-orion-official-announcement "ManageWP Orion Official Announcement") sessions when logging out.
60
 
61
- = 4.0.13 =
 
62
 
63
- - New: Destroy all admin sessions started from [ManageWP Orion](http://managewp.com/managewp-orion-official-announcement "ManageWP Orion Official Announcement") when a user logs out from the dashboard.
64
- - Fix: Improve update detection.
65
 
66
- = 4.0.12 =
 
67
 
68
- - Fix: Improve white-labeling.
69
- - Fix: Better compatibility with development builds of WordPress.
70
- - Fix: Improve one-click restore functionality on non-English installations of WordPress.
71
 
72
- = 4.0.11 =
73
 
74
- - Fix: Better detect available updates
75
- - Fix: Improve compatibility with other plugins
76
 
77
- = 4.0.10 =
 
78
 
79
- - Fix: Fix update functionality on some installations that use FTP credentials
80
- - Fix: Fix Google Drive uploading on installations without cURL PHP extension
81
 
82
- = 4.0.9 =
83
 
84
- - New: Make the ManageWP Worker plugin upgradable through the dashboard widget
85
- - Fix: Improve auto-connect functionality with [ManageWP Orion](http://managewp.com/managewp-orion-official-announcement "ManageWP Orion Official Announcement")
86
 
87
- = 4.0.8 =
88
 
89
- - Fix: Fix single-click restore functionality
90
 
91
- = 4.0.7 =
92
 
93
- - Fix: Fix issues related to cloning and backup restoration
94
- - Fix: Improve precision of the hit counter
95
- - Fix: Improve compatibility with other plugins
96
- - Fix: Numerous small improvements and fixes
97
 
98
- = 4.0.5 =
99
 
100
- - Fix: Misc bug fixes and performance improvements
101
 
102
- = 4.0.1 =
103
 
104
- - New: New features for the [ManageWP Orion release](http://managewp.com/managewp-orion-official-announcement "ManageWP Orion Official Announcement")
105
- - Fix: Misc bug fixes and performance improvements
106
 
107
- = 3.9.30 =
 
108
 
109
- - New: Fully compatible with WordPress 4.0
110
- - New: Adding websites to your ManageWP Dashboard is now easier than ever
111
- - Fix: Backup tool improvements (especially for websites located on Rackspace)
112
- - Fix: Various Clone/Migration tool improvements and fixes
113
- - Fix: SEO PDF report visual enhancement
114
- - Fix: Various interface improvements and fixes
115
 
116
- = 3.9.29 =
117
 
118
- - New: Worker plugin is now 36% faster and uses 83% less memory
119
- - New: Backup no longer relies on WordPress cron
120
- - New: New Server-Client communication fixing some of the previous issues
121
- - New: Notes and Recent backups widgets
122
- - New: Refreshed app interface :)
123
 
124
- = 3.9.28 =
125
- - New: Control WordPress Automatic Background Updates for plugins and themes!
126
- - Fix: Tweaks to SFTP support for backups and clone
127
- - Fix: Enhancements to Backup and Branding features
128
 
 
129
 
130
- = 3.9.27 =
131
- - New: SFTP support for backups and clone!
132
- - Fix: Database dump for backup tasks with defined socket path or port number in wp-config.php
133
- - Fix: Optimize WordPress tables before backup
134
- - Fix: Compatibility with Better WP Security
135
- - Fix: Not adding jQuery on front page while using branding option
136
-
137
- = 3.9.26 =
138
- - New: Improved branding feature
139
- - New: Disable Plugin and Theme changes for your clients
140
- - New: Support Page for non-Admin Users
141
- - New: Manage biographical info of user
142
- - Fix: Restore backup action keeps all backup tasks and backups
143
- - Fix: Add/delete post action uses WordPress hook
144
- - Fix: Delete user action was not functioning properly
145
-
146
- = 3.9.25 =
147
- - New: Improved Worker branding feature
148
- - Fix: Traffic alerts feature was not functioning properly
149
- - Fix: Backup information was sometimes incorrectly displayed
150
- - Fix: DB Table overhead was not shown on the dashboard
151
-
152
- = 3.9.24 =
153
- - New: Better support for large database dumps
154
- - Fix: PHP notice for WordPress 3.5
155
- - Fix: Support for automatic backup reports
156
- - Fix: Incorrect backup result message for S3 large files
157
-
158
- = 3.9.23 =
159
- - New: SEO reports can be branded and viewed by sharing an URL
160
- - New: Set custom database prefix for new clone destination
161
- - New: Automatic change all URL paths for new clone destination
162
- - New: Success and fail email notifications for scheduled backup tasks
163
- - Fix: Improved scheduled backups for limited server resources
164
- - Fix: Improved backup to Dropbox (now supporting larger backup files)
165
- - Fix: Handling of external images with bulk posting
166
- - Fix: Display plugin versions on manage plugins
167
- - Fix: Deprecated get_themes function
168
- - Fix: Special characters support for notes
169
-
170
- = 3.9.22 =
171
- - New: Backup support for Google Drive
172
- - New: Keyword tracking limit increased from 5 to 20 times the website limit (ie. with 25 website account you can now track the ranking for 500 keywords!)
173
- - New: Support for Google Analytics API 3.0
174
- - New: Website preview screenshot
175
- - New: Ability to assign a newly added website to existing Backup tasks (under "advanced" in add website dialogue)
176
- - Fix: Clone tool now supports special characters and localized WP installs
177
- - Fix: Backup history preserved on website re-add
178
-
179
- = 3.9.21 =
180
- * New: Continuous updates! Read more at http://managewp.com/continuous-updates
181
-
182
- = 3.9.20 =
183
- * New: ManageWP iOS app compatibility
184
- * New: Perform security and performance test as you add websites
185
- * New: New comment handling screen
186
-
187
- = 3.9.19 =
188
- * New: Improved mechanism for refreshing website stats. You should have fresh information every 4 hours without refreshing now
189
- * Fix: Categories now showing properly in Manage posts
190
- * Fix: Website stats now ignore uptime monitoring pings
191
-
192
- = 3.9.18 =
193
- * New: Pagelines themes added to the list of partners
194
- * New: Comprehensive website performance scan tool
195
- * New: You can now bulk edit posts/pages (updating that contact info will become piece of cake)
196
- * New: Upload and save your premium plugins/themes in your personal repository for quick installation
197
- * New: Run code snippets now get a repository. Save your snippets and share them with other users
198
- * New: SEO reports can now be sorted. Export as CSV and PDF reports.
199
- * New: Manage Blogroll links
200
- * New: Clean post revisions now has an option to save last x revisions when cleaning
201
- * New: Bulk delete na posts/pages/links
202
- * Fix: Amazon S3 backups failing
203
-
204
- = 3.9.17 =
205
- * New: Add your favorite sites to the Favorites bar (just drag&drop them to the small heart on the top)
206
- * New: Entirely new website menu loaded with features and tools
207
- * New: Manage Posts and Pages across all sites in a more efficient way
208
- * New: Support for all WPMU.org premium plugin updates
209
- * New: Complete Dropbox integration through Oauth which allows us to restore/delete Dropbox backups directly
210
- * New: We have the user guide as PDF now. [Download] (http://managewp.com/files/ManageWP_User_Guide.zip)
211
-
212
-
213
- = 3.9.16 =
214
- * New: Option to "Run now" backup tasks
215
- * New: Traffic alerts functionality
216
- * New: Support for Genesis premium theme updates
217
- * Fix: In some circutmsances .htaccess was not correctly zipped in the backup archive
218
-
219
- = 3.9.15 =
220
- * New: Full range of SEO Statistics now trackable for your websites (Google Page Rank and Page Speed, Backlinks and 20+ more)
221
- * New: Google keyword rank tracking with history
222
- * New: Uptime monitoring (5 min interval with email/SMS notification)
223
- * New: Insights into server PHP error logs right in your dashboard
224
- * New: Remote maintenance mode for your websites
225
- * Fix: A bug when a completed backup was reported as failed
226
-
227
- = 3.9.14 =
228
- * Two factor authentication
229
- * Run code tool
230
- * Quick access to security check and broken link tools
231
- * More accurate pageview statistics
232
- * You can now opt to completely hide the Worker plugin from the list of plugins (part of Worker branding features)
233
- * We improved the backups for folks running Windows servers
234
- * Amazon S3 directory name now "ManageWP" by default
235
- * Read more on ManageWP.com http://managewp.com/update-two-factor-authentication-run-code-tool-sucuri-security-check-more-accurate-pageview-statistics
236
-
237
- = 3.9.13 =
238
- * Added bucket location for Amazon S3 backups
239
- * Better backup feature for larger sites
240
- * Added Disable compression to further help with larger sites
241
- * Backing up wp-admin, wp-includes and wp-content by default now, other folders can be included manually
242
-
243
- = 3.9.12 =
244
- * Minor bug fixes
245
- * Backup, clone, favorites functionality improved
246
-
247
- = 3.9.10 =
248
- * Supporting updates for more premium plugins/themes
249
- * Backup notifications (users can now get notices when the backup succeeds or fails)
250
- * Support for WordPress 3.3
251
- * Worker Branding (useful for web agencies, add your own Name/Description)
252
- * Manage Groups screen
253
- * Specify wp-admin path if your site uses a custom one
254
- * Amazon S3 backups support for mixed case bucket names
255
- * Bulk Add Links has additional options
256
- * Better Multisite support
257
- * Option to set the number of items for Google Analytics
258
- * ManageWP backup folder changed to wp-content/managewp/backups
259
-
260
- = 3.9.9 =
261
- * New widget on the dashboard - Backup status
262
- * New screen for managing plugins and themes (activate, deactivate, delete, add to favorites, install) across all sites
263
- * New screen for managing users (change role or password, delete user) across all sites
264
- * Option to overwrite old plugins and themes during bulk installation
265
- * Your website admin now loads faster in ManageWP
266
- * Added API for premium theme and plugin updates
267
-
268
- = 3.9.8 =
269
- * Conversion goals integration
270
- * Update notifications
271
- * Enhanced security for your account
272
- * Better backups
273
- * Better update interface
274
- * [Full changelog](http://managewp.com/update-goals-and-adsense-analytics-integration-update-notifications-login-by-ip-better-backups "Full changelog")
275
-
276
- = 3.9.7 =
277
- * Fixed problem with cron schedules
278
-
279
- = 3.9.6 =
280
- * Improved dashboard performance
281
- * Fixed bug with W3TC, we hope it is fully comptabile now
282
- * Improved backup feature
283
- * Various other fixes and improvements
284
-
285
- = 3.9.5 =
286
- * Now supporting scheduled backups to Amazon S3 and Dropbox
287
- * Revamped cloning procedure
288
- * You can now have sites in different colors
289
- * W3 Total Cache comptability improved
290
-
291
- = 3.9.3 =
292
- * Included support for WordPress 3.2 partial updates
293
-
294
- = 3.9.2 =
295
- * Fixed problem with full backups
296
- * Fixed problem with wordpress dev version upgrades
297
-
298
- = 3.9.1 =
299
- * Support for sub-users (limited access users)
300
- * Bulk add user
301
- * 'Select all' feature for bulk posting
302
- * Featured image support for bulk posting
303
- * Reload button on the dashboard (on the top of the Right now widget) will now refresh information about available updates
304
- * Fixed a problem with the import tool
305
- * Fixed a problem when remote dashboard would not work for some servers
306
-
307
- = 3.9.0 =
308
- * New feature: Up to 50% faster dashboard loading
309
- * New feature: You can now ignore WordPress/plugin/theme updates
310
- * New feature: Setting 'Show favicon' for websites in the dashboad
311
- * New feature: Full backups now include WordPress and other folders in the root of the site
312
- * Fixed: Bug with W3 TotalCache object cache causing weird behaviour in the dashboard
313
- * Fixed: All groups now show when adding a site
314
-
315
- = 3.8.8 =
316
- * New feature: Bulk add links to blogroll
317
- * New feature: Manual backups to email address
318
- * New feature: Backup requirements check (under Manage Backups)
319
- * New feature: Popup menu for groups allowing to show dashboard for that group only
320
- * New feature: Favorite list for plugins and themes for later quick installation to multiple blogs
321
- * New feature: Invite friends
322
- * Fixed: problem with backups and write permissions when upload dir was wrongly set
323
- * Fixed: problem adding sites where WordPress is installed in a folder
324
- * Fixed: 408 error message problem when adding site
325
- * Fixed: site time out problems when adding site
326
- * Fixed: problems with some WP plugins (WP Sentinel)
327
- * Fixed: problems with upgrade notifications
328
-
329
- = 3.8.7 =
330
- * Fixed 408 error when adding sites
331
- * Added support for IDN domains
332
- * Fixed bug with WordPress updates
333
- * Added comment moderation to the dashboard
334
- * Added quick links for sites (menu appears on hover)
335
-
336
-
337
- = 3.8.6 =
338
- * Added seach websites feature
339
- * Enhanced dashboard actions (spam comments, post revisions, table overhead)
340
- * Added developer [API] (http://managewp.com/api "ManageWP API")
341
- * Improved Migrate/Clone site feature
342
-
343
- = 3.8.4 =
344
- * Fixed remote dashboard problems for sites with redirects
345
- * Fixed IE7 issues in the dashboard
346
-
347
- = 3.8.3 =
348
- * Fixed problem with capabilities
349
-
350
- = 3.8.2 =
351
- * New interface
352
- * SSL security protocol
353
- * No passwords required
354
- * Improved clone/backup
355
-
356
- = 3.6.3 =
357
- * Initial public release
358
 
359
- == Installation ==
360
 
361
- 1. Upload the plugin folder to your `/wp-content/plugins/` folder
362
- 2. Go to the Plugins page in your website's WP-admin area and activate ManageWP Worker
363
- 3. Visit [ManageWP.com](https://managewp.com/ "ManageWP")
364
- 4. Sign up and add your website
365
 
366
- Alternatively
367
 
368
- 1. Visit [ManageWP.com](https://managewp.com/ "Manage Multiple WordPress Sites") and sign up
369
- 2. ManageWP will notify you the Worker plugin is not installed and offer a link for quick installation
370
 
371
- For detailed instructions, you can read our [User Guide](http://managewp.com/user-guide/how-to-use-managewp/getting-started/adding-your-website-to-managewp/ "Add your website to ManageWP")
372
 
373
- == Screenshots ==
 
 
 
374
 
375
- 1. ManageWP dashboard with available upgrades, site statistics and management functions
376
 
 
377
 
378
- == Upgrade Notice ==
379
 
380
- = 3.9.30 =
381
- Worker plugin is now fully compatible with WordPress 4.0, adding websites is now easier and we have made fixes and improvements in Backup and Clone tools
382
 
 
383
 
384
- = 3.9.29 =
385
- Worker plugin is 36% faster and uses 83% less memory. Backup tool no longer relies on WordPress cron
386
 
 
 
 
387
 
388
- = 3.9.28 =
389
- It is now possible to control WordPress automatic background updates for plugins and themes!
390
 
 
 
391
 
392
- = 3.9.27 =
393
- We have added compatibility with Better WP Security. Also, it is now possible to backup and clone to SFTP
 
 
 
 
 
 
 
 
 
 
 
 
 
394
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
395
 
396
  == License ==
397
 
@@ -401,47 +207,58 @@ ManageWP Worker is free software: you can redistribute it and/or modify it under
401
 
402
  ManageWP Worker is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
403
 
404
- You should have received a copy of the GNU General Public License along with ManageWP Worker. If not, see <http://www.gnu.org/licenses/>.
405
 
406
 
407
  == Frequently Asked Questions ==
408
 
 
 
 
 
 
 
 
 
 
 
 
 
409
  = Is ManageWP secure? =
410
 
411
- Yes. We invest heavilly in our security and in four years and serving over quarter a million websites we did not have a single security incident. Also we invest in a [white hat security program](https://managewp.com/white-hat-reward) with the purpose of preventing security issues.
 
 
412
 
413
- = Will ManageWP work with sites spread on different hosting accounts? =
414
 
415
- Yes.
 
 
416
 
417
  = Does ManageWP work with WordPress.com sites? =
418
 
419
  No. ManageWP works only with self-hosted WordPress sites.
420
 
421
- = Can I try all features for free? =
422
 
423
- Absolutely. The first month is on us.
424
 
425
  = I have problems adding my site =
426
 
427
- Make sure you use the latest version of the Worker plugin on the site you are trying to add. If you still have problems, check our dedicated [FAQ page](http://managewp.com/user-guide/faq/my-sites-fail-to-addload-to-managewp "Add site FAQ") or [contact us](http://managewp.com/contact "ManageWP Contact").
428
 
429
  = How does ManageWP compare to backup plugins like BackupBuddy, Backwpup, UpdraftPlus, WP-DB-Backup ? =
430
 
431
- There is a limit to what a PHP based backup can do (as are all these plugins) but we believe that our backup system is one of if not the most robust solution on the market.
432
 
433
  = How does ManageWP compare with clone plugins like Duplicator, WP Migrate DB, All-in-One WP Migration, XCloner ? =
434
 
435
- We are confident that our clone system is the most reliable one on the market featuring highly sophisticated technology allowing for the easiest and most efficient site clone/migration on the market.
436
-
437
- = Does ManageWP work with caching plugins like W3 Total Cache or WP Super Cache =
438
-
439
- Yes.
440
 
441
- = Does ManageWP work with all popular plugins like WordPress SEO by Yoast, WPTouch, Google XML Sitemaps, NextGEN Gallery, Contact Form 7, WooCommerce, iThemes Security, WordPres importer, Wordfence Security and others? =
442
 
443
- Yes. In most cases where there are conflicts we document them on our [known issues](https://managewp.com/user-guide/known-issues) page.
444
 
445
- = How does ManageWP compare to services like InfiniteWP, MainWP, CMS Commander, IControlWP ? =
446
 
447
- We believe that our product is technologically more advanced and more mature. In some cases ManageWP has been the inspiration for these services, and we continue to innovate. For more information please refer to [this comment](http://wpchat.com/t/security-and-centralized-wordpress-management-ie-managewp-jetpack-etc/505/6?u=vprelovac)
1
  === ManageWP Worker ===
2
+ Contributors: managewp,freediver
3
+ Tags: manage multiple sites, backup, security, migrate, performance, analytics, Manage WordPress, Managed WordPress, WordPress management, WordPress manager, WordPress management, site management, control multiple sites, WordPress management dashboard, administration, automate, automatic, comments, clone, dashboard, duplicate, google analytics, login, manage, managewp, multiple, multisite, remote, seo, spam
4
+ Requires at least: 3.1
5
+ Tested up to: 5.8
 
6
  Stable tag: trunk
7
  License: GPLv3 or later
8
  License URI: http://www.gnu.org/licenses/quick-guide-gplv3.html
9
 
10
+ A better way to manage dozens of WordPress websites.
11
 
12
  == Description ==
13
 
14
+ So you're looking for a better way to manage WordPress websites? We have you covered! [ManageWP](https://managewp.com/ "Manage Multiple WordPress Websites") is a dashboard that helps you save time and nerves by automating your workflow, so you could focus on things that matter. It is fast, secure and free for an unlimited number of websites.
15
 
16
  = Everything in One Place =
17
+ Just the hassle of logging into each of your websites is enough to ruin your day. ManageWP compiles the data from all of your sites on one dashboard, so you can check up on your websites in a single glance. And if you need to take a better look at a particular website, you're just a click away. [Read more](https://managewp.com/features/1-click-login "1-click login")
18
 
19
+ = Bulk actions =
20
+ 57 updates on 12 sites? Update them all with a single click. And it's not just updates. Clean spam, database overhead, run security checks and more - with just one click you can do these things on all your websites at once. [Read more](https://managewp.com/features/manage-plugins-and-themes "Manage plugins & themes")
21
 
22
+ = Cloud Backup that just works =
23
+ A reliable backup is the backbone of any business. And we have a free monthly backup for all of your websites. It's, incremental, reliable, and works where other backup solutions fail. The free Backup includes monthly scheduled backup, off-site storage, 1-click restore, US/EU storage choice and the option to exclude files and folders. The premium Backup gives you on-demand backups, weekly/daily/hourly backup cycles & [more](https://managewp.com/features/backup "ManageWP Backup").
24
 
25
+ = Safe updates =
26
+ Updating plugins & themes is a huge pain, so we came with this: a backup is automatically created before each update. After the update, the system checks the website and rolls back automatically if something's wrong. And the best part is that you can set these updates to run at 3am, when the website traffic as its lowest.
27
+ [Read more](https://managewp.com/features/safe-updates "Safe Updates").
28
 
29
+ = Client Report =
30
+ Summarize your hard work in a professional looking report and send it to your clients to showcase your work. The free Client Report includes basic customization and on-demand reports. The premium Client Report lets you white label and automate your reports. [Read more](https://managewp.com/features/backup "Client Report")
31
 
32
+ = Performance and Security Checks =
33
+ Slow or infected websites are bad for business. Luckily, you can now keep tabs on your websites with regular performance & security checks. The free [Security Check](https://managewp.com/features/security-check "security check") & [Performance Check](https://managewp.com/features/performance-scan "performance check") come with fully functional checks and logging. Premium versions let you fully automate the checks, and get an SMS or an email if something's wrong.
34
 
35
+ = Google Analytics integration =
36
+ Connect multiple Google Analytics accounts, and keep track of all the important metrics from one place. [Read more](https://managewp.com/features/analytics "Google Analytics integration")
37
 
38
+ = Uptime Monitor (premium add-on) =
39
+ Be the first to know when your website is down with both email and SMS notifications, and get your website back online before anyone else notices. [Read more](https://managewp.com/features/uptime-monitor "Uptime Monitor")
40
+
41
+ = Cloning & Migration (bundled with premium Backup add-on) =
42
+ What used to take you hours of work and nerves of steel is now a one-click operation. Pick a source website, pick a destination website, click Go. Within minutes, youw website will be alive and kicking on a new server. Yeah, it's that easy. [Read more](https://managewp.com/features/clone "Cloning & migration")
43
+
44
+ = SEO Ranking (premium add-on) =
45
+ Be on top of your website rankings and figure out which keywords work best for you, as well as keeping on eye on your competitors. This way you will know how well you stack up against them. [Read more](https://managewp.com/features/seo-ranking "SEO Ranking")
46
+
47
+ = White Label (premium add-on) =
48
+ Rename or completely hide the ManageWP Worker plugin. Clients don’t need to know what you are using to manage their websites. [Read more](https://managewp.com/features/white-label "White Label")
49
 
50
+ = Is This All? =
51
+ No way! We've got a bunch of other awesome features, both free and premium, you can check out on our [ManageWP features page](https://managewp.com/features "ManageWP Features")
52
 
53
+ Check out the [ManageWP promo video](https://vimeo.com/220647227).
54
 
55
+ https://vimeo.com/220647227
56
 
57
  == Changelog ==
58
+ = 4.9.9 =
59
 
60
+ - Fix: Resolved edge case compatibility issue with some sites
61
+ - New: Added "Disconnect all" option in the Connection Management in wp-admin
62
+ - Worker update tested to the latest version of WordPress
63
+ - Minor wording changes
64
 
65
+ = 4.9.7 =
66
 
67
+ - Update logic for calculating table overhead
68
 
69
+ = 4.9.6 =
70
 
71
+ - Updated logic for generating archive name for File Manager tool.
72
+ - Update tested up to version for the plugin.
73
+ - Fix: Edge case where a backup might fail due to root WP paths.
74
 
75
+ = 4.9.3 =
76
 
77
+ - Update tested up to version for the plugin.
78
+ - Fix: Potential crash when the hit count option is not defined.
79
 
80
+ = 4.9.2 =
 
81
 
82
+ - Added fallback for downloading/archiving files for the File Manager tool, when zip extension is not available
83
+ - Fix: Worker plugin branding within WP 5.2 Admin Site Health page plugins list
84
 
85
+ = 4.9.1 =
 
 
86
 
87
+ - Fix: Handle updates on WP Engine hosted websites properly.
88
 
89
+ = 4.9.0 =
 
90
 
91
+ - New: Support for a future release of file management.
92
+ - We will stop supporting PHP 5.2 in the next version.
93
 
94
+ = 4.8.1 =
 
95
 
96
+ - Fix: Edge case where a backup might fail due to API call payload.
97
 
98
+ = 4.8.0 =
 
99
 
100
+ - New: Support for automatic detection of post content changes for Link Monitoring.
101
 
102
+ = 4.7.8 =
103
 
104
+ - Fix: Edge case when there are no plugins active, the plugin would cause a fatal error.
105
 
106
+ = 4.7.7 =
 
 
 
107
 
108
+ - Fix: Edge cases where one click login might fail due to the Host header changing.
109
 
110
+ = 4.7.5 =
111
 
112
+ - Fix: Edge cases where key fetching might fail and cause the connection to stop working.
113
 
114
+ = 4.7.0 =
 
115
 
116
+ - Improvement: Translations for the new Connection Management dialog.
117
+ - Fix: An error that might occur when activating the Worker plugin.
118
 
119
+ = 4.6.6 =
 
 
 
 
 
120
 
121
+ - Fix: Omit extra query parameters for One Click Login after a successful login.
122
 
123
+ = 4.6.5 =
 
 
 
 
124
 
125
+ - Fix: Edge cases where the Worker plugin might not be able to communicate with our system.
 
 
 
126
 
127
+ = 4.6.4 =
128
 
129
+ - New: Allow multiple ManageWP/Pro Sites accounts to connect to a single Worker plugin.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
130
 
131
+ = 4.6.3 =
132
 
133
+ - Fix: Edge cases when Local Sync was unsuccessful.
134
+ - Fix: WooCommerce database upgrade not showing up on the ManageWP/Pro Sites dashboard.
 
 
135
 
136
+ = 4.6.2 =
137
 
138
+ - Fix: Local Sync tool improvements.
 
139
 
140
+ = 4.6.1 =
141
 
142
+ - Fix: Worker auto-recovery on PHP 7.
143
+ - Fix: Replaced eval function that triggered false positives with some security plugins.
144
+
145
+ = 4.6.0 =
146
 
147
+ - New: Localhost Sync has reached the closed beta stage. Stay tuned for more info!
148
 
149
+ = 4.5.0 =
150
 
151
+ - Improvement: Removed deprecated ManageWP Classic code.
152
 
153
+ = 4.4.0 =
 
154
 
155
+ - Fix: Communication failing with a website behind CloudFlare, that has warnings turned on, and currently has warnings.
156
 
157
+ = 4.3.4 =
 
158
 
159
+ - Improvement: The Worker plugin can now only be activated network wide on multisite installs.
160
+ - Fix: Edge cases where the connection key was not visible.
161
+ - Fix: Edge cases with Multisite communication failure.
162
 
163
+ = 4.3.3 =
 
164
 
165
+ - Improvement: Always force the correct charset for database backups.
166
+ - Improvement: The Worker plugin is now fully compatible with WordPress 4.9.
167
 
168
+ = 4.3.2 =
169
+
170
+ - Fix: The Worker plugin threw an exception while recovering from failed update.
171
+
172
+ = 4.3.1 =
173
+
174
+ - Fix: The Worker plugin could not fetch keys for the new communication system in some cases.
175
+
176
+ = 4.3.0 =
177
+
178
+ - New: Ability to install/update Envato plugins and themes.
179
+ - New: WooCommerce database upgrade support.
180
+ - New: More secure and flexible communication between the Worker plugin and the ManageWP servers.
181
+
182
+ == Installation ==
183
 
184
+ 1. Create an account on [ManageWP.com](https://managewp.com/ "Manage Multiple WordPress Sites")
185
+ 2. Follow the steps to add your first website
186
+ 3. Celebrate!
187
+
188
+ Seriously, it's that easy! If you want more detailed instructions, check out our [User Guide](https://managewp.com/guide/getting-started/add-website-managewp-dashboard "Add your website to ManageWP")
189
+
190
+ == Screenshots ==
191
+
192
+ 1. ManageWP dashboard with a thumbnail view of 20 websites
193
+ 2. Tags and stars help you organize your websites
194
+ 3. A summary of available updates and health of all your websites
195
+ 4. Track your website performance regularly, so you could know right away if something goes wrong
196
+ 5. Managing plugins and themes is just as easy with 100 websites as with 3 websites
197
+ 6. Client Report is an executive summary of everything you've done for your client
198
+ 7. Cloud backups with detailed information about each restore point
199
+ 8. Uptime Monitor logs up and down events, and notifies you via email and SMS
200
+ 9. Aside from being able to white label the ManageWP Worker plugin, you can also add a support form on the client's website
201
 
202
  == License ==
203
 
207
 
208
  ManageWP Worker is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
209
 
210
+ You should have received a copy of the GNU General Public License along with ManageWP Worker. If not, see <https://www.gnu.org/licenses/>.
211
 
212
 
213
  == Frequently Asked Questions ==
214
 
215
+ = Is ManageWP free? =
216
+
217
+ ManageWP is using the freemium model. All the core features are free for an unlimited number of websites. And for those of you who need more, we have a set of premium features to help you out.
218
+
219
+ = Do you offer support for free users? =
220
+
221
+ Yes. No matter if you're free or premium user, we are here for you 24/7. Expect a 1h average response time and a 65% answer resolution in the first reply.
222
+
223
+ = How much do premium ManageWP features cost? =
224
+
225
+ Our pricing is highly flexible, we don't charge anything upfront. The usage is calculated on a per-website, per-addon basis, like Amazon Web Services. Check out our [pricing page](https://managewp.com/pricing "ManageWP pricing page") for more info.
226
+
227
  = Is ManageWP secure? =
228
 
229
+ Yes. All of our code is developed in-house and we have a top notch security team. With half a million websites managed since 2012 we did not have a single security incident. We've accomplished this through high standards, vigilance and the help of security researchers, through our [white hat security program](https://managewp.com/white-hat-reward).
230
+
231
+ = I have websites on several different hosts. Will ManageWP work all of them? =
232
 
233
+ Yes. ManageWP plays nice with all major hosts, and 99% of the small ones.
234
 
235
+ = Does ManageWP work with multisites? =
236
+
237
+ Yes, multisite networks are fully supported, including the ability to backup and clone a multisite network.
238
 
239
  = Does ManageWP work with WordPress.com sites? =
240
 
241
  No. ManageWP works only with self-hosted WordPress sites.
242
 
243
+ = Worker plugin can connect to ManageWP and Pro Sites. What is the difference between the two? =
244
 
245
+ [ManageWP](https://managewp.com "ManageWP website") is focused on the hosting-agnostic WordPress website management. [Pro Sites](https://www.godaddy.com/pro "GoDaddy Pro Sites website") is the GoDaddy version of the service. It's part of the GoDaddy Pro program, which incorporates different tools for website & client management, lead generation, and tighter integration with other GoDaddy products.
246
 
247
  = I have problems adding my site =
248
 
249
+ Make sure you use the latest version of the Worker plugin on the site you are trying to add. If you still have problems, check our dedicated [FAQ page](https://managewp.com/troubleshooting/site-connection/why-cant-i-add-some-of-my-sites "Add site FAQ") or [contact us](https://managewp.com/contact "ManageWP Contact").
250
 
251
  = How does ManageWP compare to backup plugins like BackupBuddy, Backwpup, UpdraftPlus, WP-DB-Backup ? =
252
 
253
+ There is a limit to what a PHP based backup can do, that's why we've built a completely different backup - cloud based, incremental, it keeps working long after others have failed.
254
 
255
  = How does ManageWP compare with clone plugins like Duplicator, WP Migrate DB, All-in-One WP Migration, XCloner ? =
256
 
257
+ These solutions are simple A-B cloning solutions that tend to break in critical moments. ManageWP does it more intelligently. We first upload the backup archive to a cloud infrastructure that we control, and then we transfer it to the destination website. This effectively compartmentalizes the process into two separate steps, making the whole cloning experience much more robust and stress free.
 
 
 
 
258
 
259
+ = Is Worker PHP7 compatible? =
260
 
261
+ Yes, ManageWP Worker is fully compatible with PHP7. We also have chunks of backward compatible code, that triggers in case you're still running PHP5.x - if your code check comes up with a compatibility flag, just ignore it.
262
 
 
263
 
264
+ Got more questions? [Contact us!](https://managewp.com/contact "ManageWP Contact")
src/Dropbox/AppInfo.php DELETED
@@ -1,262 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * Your app's API key and secret.
5
- */
6
- final class Dropbox_AppInfo
7
- {
8
- /**
9
- * Your Dropbox <em>app key</em> (OAuth calls this the <em>consumer key</em>). You can
10
- * create an app key and secret on the <a href="http://dropbox.com/developers/apps">Dropbox developer website</a>.
11
- *
12
- * @return string
13
- */
14
- public function getKey()
15
- {
16
- return $this->key;
17
- }
18
-
19
- /** @var string */
20
- private $key;
21
-
22
- /**
23
- * Your Dropbox <em>app secret</em> (OAuth calls this the <em>consumer secret</em>). You can
24
- * create an app key and secret on the <a href="http://dropbox.com/developers/apps">Dropbox developer website</a>.
25
- *
26
- * Make sure that this is kept a secret. Someone with your app secret can impesonate your
27
- * application. People sometimes ask for help on the Dropbox API forums and
28
- * copy/paste code that includes their app secret. Do not do that.
29
- *
30
- * @return string
31
- */
32
- public function getSecret()
33
- {
34
- return $this->secret;
35
- }
36
-
37
- /** @var string */
38
- private $secret;
39
-
40
- /**
41
- * The set of servers your app will use. This defaults to the standard Dropbox servers
42
- * {@link Host::getDefault}.
43
- *
44
- * @return Dropbox_Host
45
- *
46
- * @internal
47
- */
48
- public function getHost()
49
- {
50
- return $this->host;
51
- }
52
-
53
- /** @var Dropbox_Host */
54
- private $host;
55
-
56
- /**
57
- * Constructor.
58
- *
59
- * @param string $key
60
- * See {@link getKey()}
61
- * @param string $secret
62
- * See {@link getSecret()}
63
- */
64
- public function __construct($key, $secret)
65
- {
66
- self::checkKeyArg($key);
67
- self::checkSecretArg($secret);
68
-
69
- $this->key = $key;
70
- $this->secret = $secret;
71
-
72
- // The $host parameter is sort of internal. We don't include it in the param list because
73
- // we don't want it to be included in the documentation. Use PHP arg list hacks to get at
74
- // it.
75
- $host = null;
76
- if (func_num_args() == 3) {
77
- $host = func_get_arg(2);
78
- Dropbox_Host::checkArgOrNull("host", $host);
79
- }
80
- if ($host === null) {
81
- $host = Dropbox_Host::getDefault();
82
- }
83
- $this->host = $host;
84
- }
85
-
86
- /**
87
- * Loads a JSON file containing information about your app. At a minimum, the file must include
88
- * the "key" and "secret" fields. Run 'php authorize.php' in the examples directory
89
- * for details about what this file should look like.
90
- *
91
- * @param string $path
92
- * Path to a JSON file
93
- *
94
- * @return Dropbox_AppInfo
95
- *
96
- * @throws Dropbox_AppInfoLoadException
97
- */
98
- public static function loadFromJsonFile($path)
99
- {
100
- list($rawJson, $appInfo) = self::loadFromJsonFileWithRaw($path);
101
-
102
- return $appInfo;
103
- }
104
-
105
- /**
106
- * Loads a JSON file containing information about your app. At a minimum, the file must include
107
- * the "key" and "secret" fields. Run 'php authorize.php' in the examples directory
108
- * for details about what this file should look like.
109
- *
110
- * @param string $path
111
- * Path to a JSON file
112
- *
113
- * @return array
114
- * A list of two items. The first is a PHP array representation of the raw JSON, the second
115
- * is an AppInfo object that is the parsed version of the JSON.
116
- *
117
- * @throws Dropbox_AppInfoLoadException
118
- *
119
- * @internal
120
- */
121
- public static function loadFromJsonFileWithRaw($path)
122
- {
123
- if (!file_exists($path)) {
124
- throw new Dropbox_AppInfoLoadException("File doesn't exist: \"$path\"");
125
- }
126
-
127
- $str = file_get_contents($path);
128
- $jsonArr = json_decode($str, true);
129
-
130
- if (is_null($jsonArr)) {
131
- throw new Dropbox_AppInfoLoadException("JSON parse error: \"$path\"");
132
- }
133
-
134
- $appInfo = self::loadFromJson($jsonArr);
135
-
136
- return array($jsonArr, $appInfo);
137
- }
138
-
139
- /**
140
- * Parses a JSON object to build an AppInfo object. If you would like to load this from a file,
141
- * use the loadFromJsonFile() method.
142
- *
143
- * @param array $jsonArr Output from json_decode($str, TRUE)
144
- *
145
- * @return Dropbox_AppInfo
146
- *
147
- * @throws Dropbox_AppInfoLoadException
148
- */
149
- public static function loadFromJson($jsonArr)
150
- {
151
- if (!is_array($jsonArr)) {
152
- throw new Dropbox_AppInfoLoadException("Expecting JSON object, got something else");
153
- }
154
-
155
- $requiredKeys = array("key", "secret");
156
- foreach ($requiredKeys as $key) {
157
- if (!array_key_exists($key, $jsonArr)) {
158
- throw new Dropbox_AppInfoLoadException("Missing field \"$key\"");
159
- }
160
-
161
- if (!is_string($jsonArr[$key])) {
162
- throw new Dropbox_AppInfoLoadException("Expecting field \"$key\" to be a string");
163
- }
164
- }
165
-
166
- // Check app_key and app_secret
167
- $appKey = $jsonArr["key"];
168
- $appSecret = $jsonArr["secret"];
169
-
170
- $tokenErr = self::getTokenPartError($appKey);
171
- if (!is_null($tokenErr)) {
172
- throw new Dropbox_AppInfoLoadException("Field \"key\" doesn't look like a valid app key: $tokenErr");
173
- }
174
-
175
- $tokenErr = self::getTokenPartError($appSecret);
176
- if (!is_null($tokenErr)) {
177
- throw new Dropbox_AppInfoLoadException("Field \"secret\" doesn't look like a valid app secret: $tokenErr");
178
- }
179
-
180
- // Check for the optional 'host' field
181
- if (!array_key_exists('host', $jsonArr)) {
182
- $host = null;
183
- } else {
184
- $baseHost = $jsonArr["host"];
185
- if (!is_string($baseHost)) {
186
- throw new Dropbox_AppInfoLoadException("Optional field \"host\" must be a string");
187
- }
188
-
189
- $api = "api-$baseHost";
190
- $content = "api-content-$baseHost";
191
- $web = "meta-$baseHost";
192
-
193
- $host = new Dropbox_Host($api, $content, $web);
194
- }
195
-
196
- return new Dropbox_AppInfo($appKey, $appSecret, $host);
197
- }
198
-
199
- /**
200
- * Use this to check that a function argument is of type <code>AppInfo</code>
201
- *
202
- * @internal
203
- */
204
- public static function checkArg($argName, $argValue)
205
- {
206
- if (!($argValue instanceof self)) {
207
- Dropbox_Checker::throwError($argName, $argValue, __CLASS__);
208
- }
209
- }
210
-
211
- /**
212
- * Use this to check that a function argument is either <code>null</code> or of type
213
- * <code>AppInfo</code>.
214
- *
215
- * @internal
216
- */
217
- public static function checkArgOrNull($argName, $argValue)
218
- {
219
- if ($argValue === null) {
220
- return;
221
- }
222
- if (!($argValue instanceof self)) {
223
- Dropbox_Checker::throwError($argName, $argValue, __CLASS__);
224
- }
225
- }
226
-
227
- /** @internal */
228
- public static function getTokenPartError($s)
229
- {
230
- if ($s === null) {
231
- return "can't be null";
232
- }
233
- if (strlen($s) === 0) {
234
- return "can't be empty";
235
- }
236
- if (strstr($s, ' ')) {
237
- return "can't contain a space";
238
- }
239
-
240
- return null; // 'null' means "no error"
241
- }
242
-
243
- /** @internal */
244
- public static function checkKeyArg($key)
245
- {
246
- $error = self::getTokenPartError($key);
247
- if ($error === null) {
248
- return;
249
- }
250
- throw new InvalidArgumentException("Bad 'key': \"$key\": $error.");
251
- }
252
-
253
- /** @internal */
254
- public static function checkSecretArg($secret)
255
- {
256
- $error = self::getTokenPartError($secret);
257
- if ($error === null) {
258
- return;
259
- }
260
- throw new InvalidArgumentException("Bad 'secret': \"$secret\": $error.");
261
- }
262
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Dropbox/AppInfoLoadException.php DELETED
@@ -1,17 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * Thrown by the <code>AppInfo::loadXXX</code> methods if something goes wrong.
5
- */
6
- final class Dropbox_AppInfoLoadException extends Dropbox_Exception
7
- {
8
- /**
9
- * @param string $message
10
- *
11
- * @internal
12
- */
13
- public function __construct($message)
14
- {
15
- parent::__construct($message);
16
- }
17
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Dropbox/ArrayEntryStore.php DELETED
@@ -1,60 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * A class that gives get/put/clear access to a single entry in an array.
5
- */
6
- class Dropbox_ArrayEntryStore implements Dropbox_ValueStore
7
- {
8
- /** @var array */
9
- private $array;
10
-
11
- /** @var mixed */
12
- private $key;
13
-
14
- /**
15
- * Constructor.
16
- *
17
- * @param array $array
18
- * The array that we'll be accessing.
19
- *
20
- * @param mixed $key
21
- * The key for the array element we'll be accessing.
22
- */
23
- public function __construct(&$array, $key)
24
- {
25
- $this->array = &$array;
26
- $this->key = $key;
27
- }
28
-
29
- /**
30
- * Returns the entry's current value or <code>null</code> if nothing is set.
31
- *
32
- * @return object
33
- */
34
- public function get()
35
- {
36
- if (isset($this->array[$this->key])) {
37
- return $this->array[$this->key];
38
- } else {
39
- return null;
40
- }
41
- }
42
-
43
- /**
44
- * Set the array entry to the given value.
45
- *
46
- * @param object $value
47
- */
48
- public function set($value)
49
- {
50
- $this->array[$this->key] = $value;
51
- }
52
-
53
- /**
54
- * Clear the entry.
55
- */
56
- public function clear()
57
- {
58
- unset($this->array[$this->key]);
59
- }
60
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Dropbox/AuthBase.php DELETED
@@ -1,83 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * Base class for API authorization-related classes.
5
- */
6
- class Dropbox_AuthBase
7
- {
8
- /**
9
- * Whatever AppInfo was passed into the constructor.
10
- *
11
- * @return Dropbox_AppInfo
12
- */
13
- public function getAppInfo()
14
- {
15
- return $this->appInfo;
16
- }
17
-
18
- /** @var Dropbox_AppInfo */
19
- protected $appInfo;
20
-
21
- /**
22
- * An identifier for the API client, typically of the form "Name/Version".
23
- * This is used to set the HTTP <code>User-Agent</code> header when making API requests.
24
- * Example: <code>"PhotoEditServer/1.3"</code>
25
- *
26
- * If you're the author a higher-level library on top of the basic SDK, and the
27
- * "Photo Edit" app's server code is using your library to access Dropbox, you should append
28
- * your library's name and version to form the full identifier. For example,
29
- * if your library is called "File Picker", you might set this field to:
30
- * <code>"PhotoEditServer/1.3 FilePicker/0.1-beta"</code>
31
- *
32
- * The exact format of the <code>User-Agent</code> header is described in
33
- * <a href="http://tools.ietf.org/html/rfc2616#section-3.8">section 3.8 of the HTTP specification</a>.
34
- *
35
- * Note that underlying HTTP client may append other things to the <code>User-Agent</code>, such as
36
- * the name of the library being used to actually make the HTTP request (such as cURL).
37
- *
38
- * @return string
39
- */
40
- public function getClientIdentifier()
41
- {
42
- return $this->clientIdentifier;
43
- }
44
-
45
- /** @var string */
46
- protected $clientIdentifier;
47
-
48
- /**
49
- * The locale of the user of your application. Some API calls return localized
50
- * data and error messages; this "user locale" setting determines which locale
51
- * the server should use to localize those strings.
52
- *
53
- * @return null|string
54
- */
55
- public function getUserLocale()
56
- {
57
- return $this->userLocale;
58
- }
59
-
60
- /** @var string */
61
- protected $userLocale;
62
-
63
- /**
64
- * Constructor.
65
- *
66
- * @param Dropbox_AppInfo $appInfo
67
- * See {@link getAppInfo()}
68
- * @param string $clientIdentifier
69
- * See {@link getClientIdentifier()}
70
- * @param null|string $userLocale
71
- * See {@link getUserLocale()}
72
- */
73
- public function __construct($appInfo, $clientIdentifier, $userLocale = null)
74
- {
75
- Dropbox_AppInfo::checkArg("appInfo", $appInfo);
76
- Dropbox_Client::checkClientIdentifierArg("clientIdentifier", $clientIdentifier);
77
- Dropbox_Checker::argStringNonEmptyOrNull("userLocale", $userLocale);
78
-
79
- $this->appInfo = $appInfo;
80
- $this->clientIdentifier = $clientIdentifier;
81
- $this->userLocale = $userLocale;
82
- }
83
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Dropbox/AuthInfo.php DELETED
@@ -1,85 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * This class contains methods to load an AppInfo and AccessToken from a JSON file.
5
- * This can help simplify simple scripts (such as the example programs that come with the
6
- * SDK) but is probably not useful in typical Dropbox API apps.
7
- *
8
- */
9
- final class Dropbox_AuthInfo
10
- {
11
- /**
12
- * Loads a JSON file containing authorization information for your app. 'php authorize.php'
13
- * in the examples directory for details about what this file should look like.
14
- *
15
- * @param string $path
16
- * Path to a JSON file
17
- *
18
- * @return array
19
- * A <code>list(string $accessToken, Host $host)</code>.
20
- *
21
- * @throws Dropbox_AuthInfoLoadException
22
- */
23
- public static function loadFromJsonFile($path)
24
- {
25
- if (!file_exists($path)) {
26
- throw new Dropbox_AuthInfoLoadException("File doesn't exist: \"$path\"");
27
- }
28
-
29
- $str = file_get_contents($path);
30
- $jsonArr = json_decode($str, true);
31
-
32
- if (is_null($jsonArr)) {
33
- throw new Dropbox_AuthInfoLoadException("JSON parse error: \"$path\"");
34
- }
35
-
36
- return self::loadFromJson($jsonArr);
37
- }
38
-
39
- /**
40
- * Parses a JSON object to build an AuthInfo object. If you would like to load this from a file,
41
- * please use the @see loadFromJsonFile method.
42
- *
43
- * @param array $jsonArr
44
- * A parsed JSON object, typcally the result of json_decode(..., TRUE).
45
- *
46
- * @return array
47
- * A <code>list(string $accessToken, Host $host)</code>.
48
- *
49
- * @throws Dropbox_AuthInfoLoadException
50
- */
51
- private static function loadFromJson($jsonArr)
52
- {
53
- if (!is_array($jsonArr)) {
54
- throw new Dropbox_AuthInfoLoadException("Expecting JSON object, found something else");
55
- }
56
-
57
- // Check access_token
58
- if (!array_key_exists('access_token', $jsonArr)) {
59
- throw new Dropbox_AuthInfoLoadException("Missing field \"access_token\"");
60
- }
61
-
62
- $accessToken = $jsonArr['access_token'];
63
- if (!is_string($accessToken)) {
64
- throw new Dropbox_AuthInfoLoadException("Expecting field \"access_token\" to be a string");
65
- }
66
-
67
- // Check for the optional 'host' field
68
- if (!array_key_exists('host', $jsonArr)) {
69
- $host = null;
70
- } else {
71
- $baseHost = $jsonArr["host"];
72
- if (!is_string($baseHost)) {
73
- throw new Dropbox_AuthInfoLoadException("Optional field \"host\" must be a string");
74
- }
75
-
76
- $api = "api-$baseHost";
77
- $content = "api-content-$baseHost";
78
- $web = "meta-$baseHost";
79
-
80
- $host = new Dropbox_Host($api, $content, $web);
81
- }
82
-
83
- return array($accessToken, $host);
84
- }
85
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Dropbox/AuthInfoLoadException.php DELETED
@@ -1,17 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * Thrown by the <code>AuthInfo::loadXXX</code> methods if something goes wrong.
5
- */
6
- final class Dropbox_AuthInfoLoadException extends Dropbox_Exception
7
- {
8
- /**
9
- * @param string $message
10
- *
11
- * @internal
12
- */
13
- public function __construct($message)
14
- {
15
- parent::__construct($message);
16
- }
17
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Dropbox/Checker.php DELETED
@@ -1,139 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * Helper functions to validate arguments.
5
- *
6
- * @internal
7
- */
8
- class Dropbox_Checker
9
- {
10
- public static function throwError($argName, $argValue, $expectedTypeName)
11
- {
12
- if ($argValue === null) {
13
- throw new InvalidArgumentException("'$argName' must not be null");
14
- }
15
-
16
- if (is_object($argValue)) {
17
- // Class type.
18
- $argTypeName = get_class($argValue);
19
- } else {
20
- // Built-in type.
21
- $argTypeName = gettype($argValue);
22
- }
23
- throw new InvalidArgumentException("'$argName' has bad type; expecting $expectedTypeName, got $argTypeName");
24
- }
25
-
26
- public static function argResource($argName, $argValue)
27
- {
28
- if (!is_resource($argValue)) {
29
- self::throwError($argName, $argValue, "resource");
30
- }
31
- }
32
-
33
- public static function argCallable($argName, $argValue)
34
- {
35
- if (!is_callable($argValue)) {
36
- self::throwError($argName, $argValue, "callable");
37
- }
38
- }
39
-
40
- public static function argBool($argName, $argValue)
41
- {
42
- if (!is_bool($argValue)) {
43
- self::throwError($argName, $argValue, "boolean");
44
- }
45
- }
46
-
47
- public static function argArray($argName, $argValue)
48
- {
49
- if (!is_array($argValue)) {
50
- self::throwError($argName, $argValue, "array");
51
- }
52
- }
53
-
54
- public static function argString($argName, $argValue)
55
- {
56
- if (!is_string($argValue)) {
57
- self::throwError($argName, $argValue, "string");
58
- }
59
- }
60
-
61
- public static function argStringOrNull($argName, $argValue)
62
- {
63
- if ($argValue === null) {
64
- return;
65
- }
66
- if (!is_string($argValue)) {
67
- self::throwError($argName, $argValue, "string");
68
- }
69
- }
70
-
71
- public static function argStringNonEmpty($argName, $argValue)
72
- {
73
- if (!is_string($argValue)) {
74
- self::throwError($argName, $argValue, "string");
75
- }
76
- if (strlen($argValue) === 0) {
77
- throw new InvalidArgumentException("'$argName' must be non-empty");
78
- }
79
- }
80
-
81
- public static function argStringNonEmptyOrNull($argName, $argValue)
82
- {
83
- if ($argValue === null) {
84
- return;
85
- }
86
- if (!is_string($argValue)) {
87
- self::throwError($argName, $argValue, "string");
88
- }
89
- if (strlen($argValue) === 0) {
90
- throw new InvalidArgumentException("'$argName' must be non-empty");
91
- }
92
- }
93
-
94
- public static function argNat($argName, $argValue)
95
- {
96
- if (!is_int($argValue)) {
97
- self::throwError($argName, $argValue, "int");
98
- }
99
- if ($argValue < 0) {
100
- throw new InvalidArgumentException("'$argName' must be non-negative (you passed in $argValue)");
101
- }
102
- }
103
-
104
- public static function argNatOrNull($argName, $argValue)
105
- {
106
- if ($argValue === null) {
107
- return;
108
- }
109
- if (!is_int($argValue)) {
110
- self::throwError($argName, $argValue, "int");
111
- }
112
- if ($argValue < 0) {
113
- throw new InvalidArgumentException("'$argName' must be non-negative (you passed in $argValue)");
114
- }
115
- }
116
-
117
- public static function argIntPositive($argName, $argValue)
118
- {
119
- if (!is_int($argValue)) {
120
- self::throwError($argName, $argValue, "int");
121
- }
122
- if ($argValue < 1) {
123
- throw new InvalidArgumentException("'$argName' must be positive (you passed in $argValue)");
124
- }
125
- }
126
-
127
- public static function argIntPositiveOrNull($argName, $argValue)
128
- {
129
- if ($argValue === null) {
130
- return;
131
- }
132
- if (!is_int($argValue)) {
133
- self::throwError($argName, $argValue, "int");
134
- }
135
- if ($argValue < 1) {
136
- throw new InvalidArgumentException("'$argName' must be positive (you passed in $argValue)");
137
- }
138
- }
139
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Dropbox/Client.php DELETED
@@ -1,1681 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * The class used to make most Dropbox API calls. You can use this once you've gotten an
5
- * {@link AccessToken} via {@link WebAuth}.
6
- *
7
- * This class is stateless so it can be shared/reused.
8
- */
9
- class Dropbox_Client
10
- {
11
- /**
12
- * The access token used by this client to make authenticated API calls. You can get an
13
- * access token via {@link WebAuth}.
14
- *
15
- * @return string AccessToken
16
- */
17
- public function getAccessToken()
18
- {
19
- return $this->accessToken;
20
- }
21
-
22
- /** @var string AccessToken */
23
- private $accessToken;
24
-
25
- /**
26
- * An identifier for the API client, typically of the form "Name/Version".
27
- * This is used to set the HTTP <code>User-Agent</code> header when making API requests.
28
- * Example: <code>"PhotoEditServer/1.3"</code>
29
- *
30
- * If you're the author a higher-level library on top of the basic SDK, and the
31
- * "Photo Edit" app's server code is using your library to access Dropbox, you should append
32
- * your library's name and version to form the full identifier. For example,
33
- * if your library is called "File Picker", you might set this field to:
34
- * <code>"PhotoEditServer/1.3 FilePicker/0.1-beta"</code>
35
- *
36
- * The exact format of the <code>User-Agent</code> header is described in
37
- * <a href="http://tools.ietf.org/html/rfc2616#section-3.8">section 3.8 of the HTTP specification</a>.
38
- *
39
- * Note that underlying HTTP client may append other things to the <code>User-Agent</code>, such as
40
- * the name of the library being used to actually make the HTTP request (such as cURL).
41
- *
42
- * @return string
43
- */
44
- public function getClientIdentifier()
45
- {
46
- return $this->clientIdentifier;
47
- }
48
-
49
- /** @var string */
50
- private $clientIdentifier;
51
-
52
- /**
53
- * The locale of the user of your application. Some API calls return localized
54
- * data and error messages; this "user locale" setting determines which locale
55
- * the server should use to localize those strings.
56
- *
57
- * @return null|string
58
- */
59
- public function getUserLocale()
60
- {
61
- return $this->userLocale;
62
- }
63
-
64
- /** @var null|string */
65
- private $userLocale;
66
-
67
- /**
68
- * The {@link Host} object that determines the hostnames we make requests to.
69
- *
70
- * @return Dropbox_Host
71
- */
72
- public function getHost()
73
- {
74
- return $this->host;
75
- }
76
-
77
- /**
78
- * Constructor.
79
- *
80
- * @param string $accessToken
81
- * See {@link getAccessToken()}
82
- * @param string $clientIdentifier
83
- * See {@link getClientIdentifier()}
84
- * @param null|string $userLocale
85
- * See {@link getUserLocale()}
86
- */
87
- public function __construct($accessToken, $clientIdentifier, $userLocale = null)
88
- {
89
- self::checkAccessTokenArg("accessToken", $accessToken);
90
- self::checkClientIdentifierArg("clientIdentifier", $clientIdentifier);
91
- Dropbox_Checker::argStringNonEmptyOrNull("userLocale", $userLocale);
92
-
93
- $this->accessToken = $accessToken;
94
- $this->clientIdentifier = $clientIdentifier;
95
- $this->userLocale = $userLocale;
96
-
97
- // The $host parameter is sort of internal. We don't include it in the param list because
98
- // we don't want it to be included in the documentation. Use PHP arg list hacks to get at
99
- // it.
100
- $host = null;
101
- if (func_num_args() == 4) {
102
- $host = func_get_arg(3);
103
- Dropbox_Host::checkArgOrNull("host", $host);
104
- }
105
- if ($host === null) {
106
- $host = Dropbox_Host::getDefault();
107
- }
108
- $this->host = $host;
109
-
110
- // These fields are redundant, but it makes these values a little more convenient
111
- // to access.
112
- $this->apiHost = $host->getApi();
113
- $this->contentHost = $host->getContent();
114
- }
115
-
116
- /** @var string */
117
- private $apiHost;
118
- /** @var string */
119
- private $contentHost;
120
-
121
- /**
122
- * Given a <code>$base</code> path for an API endpoint (for example, "/files"), append
123
- * a Dropbox API file path to the end of that URL. Special characters in the file will
124
- * be encoded properly.
125
- *
126
- * This is for endpoints like "/files" takes the path on the URL and not as a separate
127
- * query or POST parameter.
128
- *
129
- * @param string $base
130
- * @param string $path
131
- *
132
- * @return string
133
- */
134
- public function appendFilePath($base, $path)
135
- {
136
- return $base."/auto/".rawurlencode(substr($path, 1));
137
- }
138
-
139
- /**
140
- * Make an API call to disable the access token that you constructed this <code>Client</code>
141
- * with. After calling this, API calls made with this <code>Client</code> will fail.
142
- *
143
- * See <a href="https://www.dropbox.com/developers/core/docs#disable-token">/disable_access_token</a>.
144
- *
145
- * @throws Dropbox_Exception
146
- */
147
- public function disableAccessToken()
148
- {
149
- $response = $this->doPost($this->apiHost, "1/disable_access_token");
150
- if ($response->statusCode !== 200) {
151
- throw Dropbox_RequestUtil::unexpectedStatus($response);
152
- }
153
- }
154
-
155
- /**
156
- * Make an API call to get basic account and quota information.
157
- *
158
- * <code>
159
- * $client = ...
160
- * $accountInfo = $client->getAccountInfo();
161
- * print_r($accountInfo);
162
- * </code>
163
- *
164
- * @return array
165
- * See <a href="https://www.dropbox.com/developers/core/docs#account-info">/account/info</a>.
166
- *
167
- * @throws Dropbox_Exception
168
- */
169
- public function getAccountInfo()
170
- {
171
- $response = $this->doGet($this->apiHost, "1/account/info");
172
- if ($response->statusCode !== 200) {
173
- throw Dropbox_RequestUtil::unexpectedStatus($response);
174
- }
175
-
176
- return Dropbox_RequestUtil::parseResponseJson($response->body);
177
- }
178
-
179
- /**
180
- * Downloads a file from Dropbox. The file's contents are written to the
181
- * given <code>$outStream</code> and the file's metadata is returned.
182
- *
183
- * <code>
184
- * $client = ...;
185
- * $fd = fopen("./Frog.jpeg", "wb");
186
- * $metadata = $client->getFile("/Photos/Frog.jpeg", $fd);
187
- * fclose($fd);
188
- * print_r($metadata);
189
- * </code>
190
- *
191
- * @param string $path
192
- * The path to the file on Dropbox (UTF-8).
193
- *
194
- * @param resource $outStream
195
- * If the file exists, the file contents will be written to this stream.
196
- *
197
- * @param string|null $rev
198
- * If you want the latest revision of the file at the given path, pass in <code>null</code>.
199
- * If you want a specific version of a file, pass in value of the file metadata's "rev" field.
200
- *
201
- * @return null|array
202
- * The <a href="https://www.dropbox.com/developers/core/docs#metadata-details">metadata
203
- * object</a> for the file at the given $path and $rev, or <code>null</code> if the file
204
- * doesn't exist,
205
- *
206
- * @throws Dropbox_Exception
207
- */
208
- public function getFile($path, $outStream, $rev = null)
209
- {
210
- Dropbox_Path::checkArgNonRoot("path", $path);
211
- Dropbox_Checker::argResource("outStream", $outStream);
212
- Dropbox_Checker::argStringNonEmptyOrNull("rev", $rev);
213
-
214
- $url = $this->buildUrlForGetOrPut(
215
- $this->contentHost,
216
- $this->appendFilePath("1/files", $path),
217
- array("rev" => $rev));
218
-
219
- $curl = $this->mkCurl($url);
220
- $metadataCatcher = new Dropbox_DropboxMetadataHeaderCatcher($curl->handle);
221
- $streamRelay = new Dropbox_CurlStreamRelay($curl->handle, $outStream);
222
-
223
- $response = $curl->exec();
224
-
225
- if ($response->statusCode === 404) {
226
- return null;
227
- }
228
-
229
- if ($response->statusCode !== 200) {
230
- $response->body = $streamRelay->getErrorBody();
231
- throw Dropbox_RequestUtil::unexpectedStatus($response);
232
- }
233
-
234
- return $metadataCatcher->getMetadata();
235
- }
236
-
237
- /**
238
- * Calling 'uploadFile' with <code>$numBytes</code> less than this value, will cause this SDK
239
- * to use the standard /files_put endpoint. When <code>$numBytes</code> is greater than this
240
- * value, we'll use the /chunked_upload endpoint.
241
- *
242
- * @var int
243
- */
244
- public static $AUTO_CHUNKED_UPLOAD_THRESHOLD = 9863168; // 8 MB
245
-
246
- /**
247
- * @var int
248
- */
249
- public static $DEFAULT_CHUNK_SIZE = 4194304; // 4 MB
250
-
251
- /**
252
- * Creates a file on Dropbox, using the data from <code>$inStream</code> for the file contents.
253
- *
254
- * <code>
255
- * use \Dropbox as dbx;
256
- * $client = ...;
257
- * $fd = fopen("./frog.jpeg", "rb");
258
- * $md1 = $client->uploadFile("/Photos/Frog.jpeg",
259
- * dbx\WriteMode::add(), $fd);
260
- * fclose($fd);
261
- * print_r($md1);
262
- * $rev = $md1["rev"];
263
- *
264
- * // Re-upload with WriteMode::update(...), which will overwrite the
265
- * // file if it hasn't been modified from our original upload.
266
- * $fd = fopen("./frog-new.jpeg", "rb");
267
- * $md2 = $client->uploadFile("/Photos/Frog.jpeg",
268
- * dbx\WriteMode::update($rev), $fd);
269
- * fclose($fd);
270
- * print_r($md2);
271
- * </code>
272
- *
273
- * @param string $path
274
- * The Dropbox path to save the file to (UTF-8).
275
- *
276
- * @param Dropbox_WriteMode $writeMode
277
- * What to do if there's already a file at the given path.
278
- *
279
- * @param resource $inStream
280
- * The data to use for the file contents.
281
- *
282
- * @param int|null $numBytes
283
- * You can pass in <code>null</code> if you don't know. If you do provide the size, we can
284
- * perform a slightly more efficient upload (fewer network round-trips) for files smaller
285
- * than 8 MB.
286
- *
287
- * @param Callable|null $callback
288
- * Curl progress callback.
289
- *
290
- * @return mixed
291
- * The <a href="https://www.dropbox.com/developers/core/docs#metadata-details>metadata
292
- * object</a> for the newly-added file.
293
- *
294
- * @throws Dropbox_Exception
295
- */
296
- public function uploadFile($path, $writeMode, $inStream, $numBytes = null, $callback = null)
297
- {
298
- Dropbox_Path::checkArgNonRoot("path", $path);
299
- Dropbox_WriteMode::checkArg("writeMode", $writeMode);
300
- Dropbox_Checker::argResource("inStream", $inStream);
301
- Dropbox_Checker::argNatOrNull("numBytes", $numBytes);
302
-
303
- if ($callback !== null) {
304
- Dropbox_Checker::argCallable("callback", $callback);
305
- }
306
-
307
- // If we don't know how many bytes are coming, we have to use chunked upload.
308
- // If $numBytes is large, we elect to use chunked upload.
309
- // In all other cases, use regular upload.
310
- if ($numBytes === null || $numBytes > self::$AUTO_CHUNKED_UPLOAD_THRESHOLD) {
311
- $metadata = $this->_uploadFileChunked($path, $writeMode, $inStream, $numBytes,
312
- self::$DEFAULT_CHUNK_SIZE, $callback);
313
- } else {
314
- $config = new Dropbox_Closure_CurlConfigInStream($inStream, $numBytes);
315
- $metadata = $this->_uploadFile($path, $writeMode, $config, $callback);
316
- }
317
-
318
- return $metadata;
319
- }
320
-
321
- /**
322
- * Creates a file on Dropbox, using the given $data string as the file contents.
323
- *
324
- * <code>
325
- * use \Dropbox as dbx;
326
- * $client = ...;
327
- * $md = $client->uploadFileFromString("/Grocery List.txt",
328
- * dbx\WriteMode::add(),
329
- * "1. Coke\n2. Popcorn\n3. Toothpaste\n");
330
- * print_r($md);
331
- * </code>
332
- *
333
- * @param string $path
334
- * The Dropbox path to save the file to (UTF-8).
335
- *
336
- * @param Dropbox_WriteMode $writeMode
337
- * What to do if there's already a file at the given path.
338
- *
339
- * @param string $data
340
- * The data to use for the contents of the file.
341
- *
342
- * @return mixed
343
- * The <a href="https://www.dropbox.com/developers/core/docs#metadata-details>metadata
344
- * object</a> for the newly-added file.
345
- *
346
- * @throws Dropbox_Exception
347
- */
348
- public function uploadFileFromString($path, $writeMode, $data)
349
- {
350
- Dropbox_Path::checkArgNonRoot("path", $path);
351
- Dropbox_WriteMode::checkArg("writeMode", $writeMode);
352
- Dropbox_Checker::argString("data", $data);
353
-
354
- $config = new Dropbox_Closure_CurlConfigOctetStream($data);
355
-
356
- return $this->_uploadFile($path, $writeMode, $config);
357
- }
358
-
359
- /**
360
- * Creates a file on Dropbox, using the data from $inStream as the file contents.
361
- *
362
- * This version of <code>uploadFile</code> splits uploads the file ~4MB chunks at a time and
363
- * will retry a few times if one chunk fails to upload. Uses {@link chunkedUploadStart()},
364
- * {@link chunkedUploadContinue()}, and {@link chunkedUploadFinish()}.
365
- *
366
- * @param string $path
367
- * The Dropbox path to save the file to (UTF-8).
368
- *
369
- * @param Dropbox_WriteMode $writeMode
370
- * What to do if there's already a file at the given path.
371
- *
372
- * @param resource $inStream
373
- * The data to use for the file contents.
374
- *
375
- * @param int|null $numBytes
376
- * The number of bytes available from $inStream.
377
- * You can pass in <code>null</code> if you don't know.
378
- *
379
- * @param int|null $chunkSize
380
- * The number of bytes to upload in each chunk. You can omit this (or pass in
381
- * <code>null</code> and the library will use a reasonable default.
382
- *
383
- * @return mixed
384
- * The <a href="https://www.dropbox.com/developers/core/docs#metadata-details>metadata
385
- * object</a> for the newly-added file.
386
- *
387
- * @throws Dropbox_Exception
388
- */
389
- public function uploadFileChunked($path, $writeMode, $inStream, $numBytes = null, $chunkSize = null)
390
- {
391
- if ($chunkSize === null) {
392
- $chunkSize = self::$DEFAULT_CHUNK_SIZE;
393
- }
394
-
395
- Dropbox_Path::checkArgNonRoot("path", $path);
396
- Dropbox_WriteMode::checkArg("writeMode", $writeMode);
397
- Dropbox_Checker::argResource("inStream", $inStream);
398
- Dropbox_Checker::argNatOrNull("numBytes", $numBytes);
399
- Dropbox_Checker::argIntPositive("chunkSize", $chunkSize);
400
-
401
- return $this->_uploadFileChunked($path, $writeMode, $inStream, $numBytes, $chunkSize);
402
- }
403
-
404
- /**
405
- * @param string $path
406
- *
407
- * @param Dropbox_WriteMode $writeMode
408
- * What to do if there's already a file at the given path (UTF-8).
409
- *
410
- * @param resource $inStream
411
- * The source of data to upload.
412
- *
413
- * @param int|null $numBytes
414
- * You can pass in <code>null</code>. But if you know how many bytes you expect, pass in
415
- * that value and this function will do a sanity check at the end to make sure the number of
416
- * bytes read from $inStream matches up.
417
- *
418
- * @param int $chunkSize
419
- *
420
- * @return array
421
- * The <a href="https://www.dropbox.com/developers/core/docs#metadata-details>metadata
422
- * object</a> for the newly-added file.
423
- *
424
- * @throws InvalidArgumentException
425
- * @throws Dropbox_Exception_BadResponse
426
- */
427
- private function _uploadFileChunked($path, $writeMode, $inStream, $numBytes, $chunkSize, $callback = null)
428
- {
429
- Dropbox_Path::checkArg("path", $path);
430
- Dropbox_WriteMode::checkArg("writeMode", $writeMode);
431
- Dropbox_Checker::argResource("inStream", $inStream);
432
- Dropbox_Checker::argNatOrNull("numBytes", $numBytes);
433
- Dropbox_Checker::argNat("chunkSize", $chunkSize);
434
-
435
- if ($callback !== null) {
436
- Dropbox_Checker::argCallable("callback", $callback);
437
- }
438
-
439
- // NOTE: This function performs 3 retries on every call. This is maybe not the right
440
- // layer to make retry decisions. It's also awkward because none of the other calls
441
- // perform retries.
442
-
443
- assert($chunkSize > 0);
444
-
445
- $data = self::readFully($inStream, $chunkSize);
446
- $len = strlen($data);
447
-
448
- $client = $this;
449
- $uploadStart = new Dropbox_Closure_ChunkedUploadStartAction($client, $data, $callback);
450
- $uploadId = Dropbox_RequestUtil::runWithRetry(3, $uploadStart);
451
- unset($uploadStart);
452
-
453
- $byteOffset = $len;
454
-
455
- while (!feof($inStream)) {
456
- unset($data);
457
- $data = self::readFully($inStream, $chunkSize);
458
- $len = strlen($data);
459
-
460
- while (true) {
461
- $uploadContinue = new Dropbox_Closure_ChunkedUploadContinueAction($client, $uploadId, $byteOffset, $data, $callback);
462
- $r = Dropbox_RequestUtil::runWithRetry(3, $uploadContinue);
463
- unset($uploadContinue);
464
-
465
- if ($r === true) { // Chunk got uploaded!
466
- $byteOffset += $len;
467
- break;
468
- }
469
- if ($r === false) { // Server didn't recognize our upload ID
470
- // This is very unlikely since we're uploading all the chunks in sequence.
471
- throw new Dropbox_Exception_BadResponse("Server forgot our uploadId");
472
- }
473
-
474
- // Otherwise, the server is at a different byte offset from us.
475
- $serverByteOffset = $r;
476
- assert($serverByteOffset !== $byteOffset); // chunkedUploadContinue ensures this.
477
- // An earlier byte offset means the server has lost data we sent earlier.
478
- if ($serverByteOffset < $byteOffset) {
479
- throw new Dropbox_Exception_BadResponse(
480
- "Server is at an ealier byte offset: us=$byteOffset, server=$serverByteOffset");
481
- }
482
- $diff = $serverByteOffset - $byteOffset;
483
- // If the server is past where we think it could possibly be, something went wrong.
484
- if ($diff > $len) {
485
- throw new Dropbox_Exception_BadResponse(
486
- "Server is more than a chunk ahead: us=$byteOffset, server=$serverByteOffset");
487
- }
488
- // The normal case is that the server is a bit further along than us because of a
489
- // partially-uploaded chunk. Finish it off.
490
- $byteOffset += $diff;
491
- if ($diff === $len) {
492
- break;
493
- } // If the server is at the end, we're done.
494
- $data = substr($data, $diff);
495
- }
496
- }
497
-
498
- if ($numBytes !== null && $byteOffset !== $numBytes) {
499
- throw new InvalidArgumentException(
500
- "You passed numBytes=$numBytes but the stream had $byteOffset bytes.");
501
- }
502
-
503
- $uploadFinish = new Dropbox_Closure_ChunkedUploadFinishAction($client, $uploadId, $path, $writeMode);
504
- $metadata = Dropbox_RequestUtil::runWithRetry(3, $uploadFinish);
505
-
506
- return $metadata;
507
- }
508
-
509
- /**
510
- * Sometimes fread() returns less than the request number of bytes (for example, when reading
511
- * from network streams). This function repeatedly calls fread until the requested number of
512
- * bytes have been read or we've reached EOF.
513
- *
514
- * @param resource $inStream
515
- * @param int $numBytes
516
- *
517
- * @throws Dropbox_StreamReadException
518
- * @return string
519
- */
520
- private static function readFully($inStream, $numBytes)
521
- {
522
- Dropbox_Checker::argNat("numBytes", $numBytes);
523
-
524
- $full = '';
525
- $bytesRemaining = $numBytes;
526
- while (!feof($inStream) && $bytesRemaining > 0) {
527
- $part = fread($inStream, $bytesRemaining);
528
- if ($part === false) {
529
- throw new Dropbox_StreamReadException("Error reading from \$inStream.");
530
- }
531
- if ($full === '') {
532
- $full = $part;
533
- } else {
534
- $full .= $part;
535
- }
536
- $bytesRemaining -= strlen($part);
537
- }
538
-
539
- return $full;
540
- }
541
-
542
- /**
543
- * @param string $path
544
- * @param Dropbox_WriteMode $writeMode
545
- * @param Dropbox_Closure_CurlConfigInterface $curlConfigClosure
546
- *
547
- * @return array
548
- *
549
- * @throws Dropbox_Exception
550
- */
551
- private function _uploadFile($path, $writeMode, Dropbox_Closure_CurlConfigInterface $curlConfigClosure, $callback = null)
552
- {
553
- Dropbox_Path::checkArg("path", $path);
554
- Dropbox_WriteMode::checkArg("writeMode", $writeMode);
555
-
556
- $url = $this->buildUrlForGetOrPut(
557
- $this->contentHost,
558
- $this->appendFilePath("1/files_put", $path),
559
- $writeMode->getExtraParams());
560
-
561
- $curl = $this->mkCurl($url);
562
-
563
- $curlConfigClosure->configure($curl);
564
-
565
- if ($callback) {
566
- $curl->set(CURLOPT_NOPROGRESS, false);
567
- $curl->set(CURLOPT_PROGRESSFUNCTION, $callback);
568
- }
569
-
570
- $curl->set(CURLOPT_RETURNTRANSFER, true);
571
- $response = $curl->exec();
572
-
573
- if ($response->statusCode !== 200) {
574
- throw Dropbox_RequestUtil::unexpectedStatus($response);
575
- }
576
-
577
- return Dropbox_RequestUtil::parseResponseJson($response->body);
578
- }
579
-
580
- /**
581
- * Start a new chunked upload session and upload the first chunk of data.
582
- *
583
- * @param string $data
584
- * The data to start off the chunked upload session.
585
- *
586
- * @return array
587
- * A pair of <code>(string $uploadId, int $byteOffset)</code>. <code>$uploadId</code>
588
- * is a unique identifier for this chunked upload session. You pass this in to
589
- * {@link chunkedUploadContinue} and {@link chuunkedUploadFinish}. <code>$byteOffset</code>
590
- * is the number of bytes that were successfully uploaded.
591
- *
592
- * @throws Dropbox_Exception
593
- */
594
- public function chunkedUploadStart($data, $callback = null)
595
- {
596
- Dropbox_Checker::argString("data", $data);
597
-
598
- $response = $this->_chunkedUpload(array(), $data, $callback);
599
-
600
- if ($response->statusCode === 404) {
601
- throw new Dropbox_Exception_BadResponse("Got a 404, but we didn't send up an 'upload_id'");
602
- }
603
-
604
- $correction = self::_chunkedUploadCheckForOffsetCorrection($response);
605
- if ($correction !== null) {
606
- throw new Dropbox_Exception_BadResponse(
607
- "Got an offset-correcting 400 response, but we didn't send an offset");
608
- }
609
-
610
- if ($response->statusCode !== 200) {
611
- throw Dropbox_RequestUtil::unexpectedStatus($response);
612
- }
613
-
614
- list($uploadId, $byteOffset) = self::_chunkedUploadParse200Response($response->body);
615
- $len = strlen($data);
616
- if ($byteOffset !== $len) {
617
- throw new Dropbox_Exception_BadResponse(
618
- "We sent $len bytes, but server returned an offset of $byteOffset");
619
- }
620
-
621
- return $uploadId;
622
- }
623
-
624
- /**
625
- * Append another chunk data to a previously-started chunked upload session.
626
- *
627
- * @param string $uploadId
628
- * The unique identifier for the chunked upload session. This is obtained via
629
- * {@link chunkedUploadStart}.
630
- *
631
- * @param int $byteOffset
632
- * The number of bytes you think you've already uploaded to the given chunked upload
633
- * session. The server will append the new chunk of data after that point.
634
- *
635
- * @param string $data
636
- * The data to append to the existing chunked upload session.
637
- *
638
- * @param Callable $callback
639
- *
640
- * @return int|bool
641
- * If <code>false</code>, it means the server didn't know about the given
642
- * <code>$uploadId</code>. This may be because the chunked upload session has expired
643
- * (they last around 24 hours).
644
- * If <code>true</code>, the chunk was successfully uploaded. If an integer, it means
645
- * you and the server don't agree on the current <code>$byteOffset</code>. The returned
646
- * integer is the server's internal byte offset for the chunked upload session. You need
647
- * to adjust your input to match.
648
- *
649
- * @throws Dropbox_Exception
650
- */
651
- public function chunkedUploadContinue($uploadId, $byteOffset, $data, $callback = null)
652
- {
653
- Dropbox_Checker::argStringNonEmpty("uploadId", $uploadId);
654
- Dropbox_Checker::argNat("byteOffset", $byteOffset);
655
- Dropbox_Checker::argString("data", $data);
656
-
657
- $response = $this->_chunkedUpload(
658
- array("upload_id" => $uploadId, "offset" => $byteOffset), $data, $callback);
659
-
660
- if ($response->statusCode === 404) {
661
- // The server doesn't know our upload ID. Maybe it expired?
662
- return false;
663
- }
664
-
665
- $correction = self::_chunkedUploadCheckForOffsetCorrection($response);
666
- if ($correction !== null) {
667
- list($correctedUploadId, $correctedByteOffset) = $correction;
668
- if ($correctedUploadId !== $uploadId) {
669
- throw new Dropbox_Exception_BadResponse(
670
- "Corrective 400 upload_id mismatch: us=".
671
- self::q($uploadId)." server=".self::q($correctedUploadId));
672
- }
673
- if ($correctedByteOffset === $byteOffset) {
674
- throw new Dropbox_Exception_BadResponse(
675
- "Corrective 400 offset is the same as ours: $byteOffset");
676
- }
677
-
678
- return $correctedByteOffset;
679
- }
680
-
681
- if ($response->statusCode !== 200) {
682
- throw Dropbox_RequestUtil::unexpectedStatus($response);
683
- }
684
- list($retUploadId, $retByteOffset) = self::_chunkedUploadParse200Response($response->body);
685
-
686
- $nextByteOffset = $byteOffset + strlen($data);
687
- if ($uploadId !== $retUploadId) {
688
- throw new Dropbox_Exception_BadResponse(
689
- "upload_id mismatch: us=".self::q($uploadId).", server=".self::q($uploadId));
690
- }
691
- if ($nextByteOffset !== $retByteOffset) {
692
- throw new Dropbox_Exception_BadResponse(
693
- "next-offset mismatch: us=$nextByteOffset, server=$retByteOffset");
694
- }
695
-
696
- return true;
697
- }
698
-
699
- /**
700
- * @param string $body
701
- *
702
- * @return array
703
- */
704
- private static function _chunkedUploadParse200Response($body)
705
- {
706
- $j = Dropbox_RequestUtil::parseResponseJson($body);
707
- $uploadId = self::getField($j, "upload_id");
708
- $byteOffset = self::getField($j, "offset");
709
-
710
- return array($uploadId, $byteOffset);
711
- }
712
-
713
- /**
714
- * @param Dropbox_HttpResponse $response
715
- *
716
- * @return array|null
717
- */
718
- private static function _chunkedUploadCheckForOffsetCorrection($response)
719
- {
720
- if ($response->statusCode !== 400) {
721
- return null;
722
- }
723
- $j = json_decode($response->body, true);
724
- if ($j === null) {
725
- return null;
726
- }
727
- if (!array_key_exists("upload_id", $j) || !array_key_exists("offset", $j)) {
728
- return null;
729
- }
730
- $uploadId = $j["upload_id"];
731
- $byteOffset = $j["offset"];
732
-
733
- return array($uploadId, $byteOffset);
734
- }
735
-
736
- /**
737
- * Creates a file on Dropbox using the accumulated contents of the given chunked upload session.
738
- *
739
- * See <a href="https://www.dropbox.com/developers/core/docs#commit-chunked-upload">/commit_chunked_upload</a>.
740
- *
741
- * @param string $uploadId
742
- * The unique identifier for the chunked upload session. This is obtained via
743
- * {@link chunkedUploadStart}.
744
- *
745
- * @param string $path
746
- * The Dropbox path to save the file to ($path).
747
- *
748
- * @param Dropbox_WriteMode $writeMode
749
- * What to do if there's already a file at the given path.
750
- *
751
- * @return array|null
752
- * If <code>null</code>, it means the Dropbox server wasn't aware of the
753
- * <code>$uploadId</code> you gave it.
754
- * Otherwise, you get back the
755
- * <a href="https://www.dropbox.com/developers/core/docs#metadata-details">metadata object</a>
756
- * for the newly-created file.
757
- *
758
- * @throws Dropbox_Exception
759
- */
760
- public function chunkedUploadFinish($uploadId, $path, $writeMode)
761
- {
762
- Dropbox_Checker::argStringNonEmpty("uploadId", $uploadId);
763
- Dropbox_Path::checkArgNonRoot("path", $path);
764
- Dropbox_WriteMode::checkArg("writeMode", $writeMode);
765
-
766
- $params = array_merge(array("upload_id" => $uploadId), $writeMode->getExtraParams());
767
-
768
- $response = $this->doPost(
769
- $this->contentHost,
770
- $this->appendFilePath("1/commit_chunked_upload", $path),
771
- $params);
772
-
773
- if ($response->statusCode === 404) {
774
- return null;
775
- }
776
- if ($response->statusCode !== 200) {
777
- throw Dropbox_RequestUtil::unexpectedStatus($response);
778
- }
779
-
780
- return Dropbox_RequestUtil::parseResponseJson($response->body);
781
- }
782
-
783
- /**
784
- * @param array $params
785
- * @param string $data
786
- * @param callable $callback
787
- *
788
- * @return Dropbox_HttpResponse
789
- */
790
- protected function _chunkedUpload($params, $data, $callback = null)
791
- {
792
- $url = $this->buildUrlForGetOrPut(
793
- $this->contentHost, "1/chunked_upload", $params);
794
-
795
- $curl = $this->mkCurl($url);
796
-
797
- // We can't use CURLOPT_PUT because it wants a stream, but we already have $data in memory.
798
- $curl->set(CURLOPT_CUSTOMREQUEST, "PUT");
799
- $curl->set(CURLOPT_POSTFIELDS, $data);
800
- $curl->addHeader("Content-Type: application/octet-stream");
801
-
802
- if ($callback) {
803
- $curl->set(CURLOPT_NOPROGRESS, false);
804
- $curl->set(CURLOPT_PROGRESSFUNCTION, $callback);
805
- }
806
-
807
- $curl->set(CURLOPT_RETURNTRANSFER, true);
808
-
809
- return $curl->exec();
810
- }
811
-
812
- /**
813
- * Returns the metadata for whatever file or folder is at the given path.
814
- *
815
- * <code>
816
- * $client = ...;
817
- * $md = $client->getMetadata("/Photos/Frog.jpeg");
818
- * print_r($md);
819
- * </code>
820
- *
821
- * @param string $path
822
- * The Dropbox path to a file or folder (UTF-8).
823
- *
824
- * @return array|null
825
- * If there is a file or folder at the given path, you'll get back the
826
- * <a href="https://www.dropbox.com/developers/core/docs#metadata-details">metadata object</a>
827
- * for that file or folder. If not, you'll get back <code>null</code>.
828
- *
829
- * @throws Dropbox_Exception
830
- */
831
- public function getMetadata($path)
832
- {
833
- Dropbox_Path::checkArg("path", $path);
834
-
835
- return $this->_getMetadata($path, array("list" => "false"));
836
- }
837
-
838
- /**
839
- * Returns the metadata for whatever file or folder is at the given path and, if it's a folder,
840
- * also include the metadata for all the immediate children of that folder.
841
- *
842
- * <code>
843
- * $client = ...;
844
- * $md = $client->getMetadataWithChildren("/Photos");
845
- * print_r($md);
846
- * </code>
847
- *
848
- * @param string $path
849
- * The Dropbox path to a file or folder (UTF-8).
850
- *
851
- * @return array|null
852
- * If there is a file or folder at the given path, you'll get back the
853
- * <a href="https://www.dropbox.com/developers/core/docs#metadata-details">metadata object</a>
854
- * for that file or folder, along with all immediate children if it's a folder. If not,
855
- * you'll get back <code>null</code>.
856
- *
857
- * @throws Dropbox_Exception
858
- */
859
- public function getMetadataWithChildren($path)
860
- {
861
- Dropbox_Path::checkArg("path", $path);
862
-
863
- return $this->_getMetadata($path, array("list" => "true", "file_limit" => "25000"));
864
- }
865
-
866
- /**
867
- * @param string $path
868
- * @param array $params
869
- *
870
- * @return array
871
- *
872
- * @throws Dropbox_Exception
873
- */
874
- private function _getMetadata($path, $params)
875
- {
876
- $response = $this->doGet(
877
- $this->apiHost,
878
- $this->appendFilePath("1/metadata", $path),
879
- $params);
880
-
881
- if ($response->statusCode === 404) {
882
- return null;
883
- }
884
- if ($response->statusCode !== 200) {
885
- throw Dropbox_RequestUtil::unexpectedStatus($response);
886
- }
887
-
888
- $metadata = Dropbox_RequestUtil::parseResponseJson($response->body);
889
- if (array_key_exists("is_deleted", $metadata) && $metadata["is_deleted"]) {
890
- return null;
891
- }
892
-
893
- return $metadata;
894
- }
895
-
896
- /**
897
- * If you've previously retrieved the metadata for a folder and its children, this method will
898
- * retrieve updated metadata only if something has changed. This is more efficient than
899
- * calling {@link getMetadataWithChildren} if you have a cache of previous results.
900
- *
901
- * <code>
902
- * $client = ...;
903
- * $md = $client->getMetadataWithChildren("/Photos");
904
- * print_r($md);
905
- * assert($md["is_dir"], "expecting \"/Photos\" to be a folder");
906
- *
907
- * sleep(10);
908
- *
909
- * // Now see if anything changed...
910
- * list($changed, $new_md) = $client->getMetadataWithChildrenIfChanged(
911
- * "/Photos", $md["hash"]);
912
- * if ($changed) {
913
- * echo "Folder changed.\n";
914
- * print_r($new_md);
915
- * } else {
916
- * echo "Folder didn't change.\n";
917
- * }
918
- * </code>
919
- *
920
- * @param string $path
921
- * The Dropbox path to a folder (UTF-8).
922
- *
923
- * @param string $previousFolderHash
924
- * The "hash" field from the previously retrieved folder metadata.
925
- *
926
- * @return array
927
- * A <code>list(boolean $changed, array $metadata)</code>. If the metadata hasn't changed,
928
- * you'll get <code>list(false, null)</code>. If the metadata of the folder or any of its
929
- * children has changed, you'll get <code>list(true, $newMetadata)</code>. $metadata is a
930
- * <a href="https://www.dropbox.com/developers/core/docs#metadata-details">metadata object</a>.
931
- *
932
- * @throws Dropbox_Exception
933
- */
934
- public function getMetadataWithChildrenIfChanged($path, $previousFolderHash)
935
- {
936
- Dropbox_Path::checkArg("path", $path);
937
- Dropbox_Checker::argStringNonEmpty("previousFolderHash", $previousFolderHash);
938
-
939
- $params = array("list" => "true", "file_limit" => "25000", "hash" => $previousFolderHash);
940
-
941
- $response = $this->doGet(
942
- $this->apiHost,
943
- $this->appendFilePath("1/metadata", $path),
944
- $params);
945
-
946
- if ($response->statusCode === 304) {
947
- return array(false, null);
948
- }
949
- if ($response->statusCode === 404) {
950
- return array(true, null);
951
- }
952
- if ($response->statusCode !== 200) {
953
- throw Dropbox_RequestUtil::unexpectedStatus($response);
954
- }
955
-
956
- $metadata = Dropbox_RequestUtil::parseResponseJson($response->body);
957
- if (array_key_exists("is_deleted", $metadata) && $metadata["is_deleted"]) {
958
- return array(true, null);
959
- }
960
-
961
- return array(true, $metadata);
962
- }
963
-
964
- /**
965
- * A way of letting you keep up with changes to files and folders in a user's Dropbox.
966
- *
967
- * @param string|null $cursor
968
- * If this is the first time you're calling this, pass in <code>null</code>. Otherwise,
969
- * pass in whatever cursor was returned by the previous call.
970
- *
971
- * @param string|null $pathPrefix
972
- * If <code>null</code>, you'll get results for the entire folder (either the user's
973
- * entire Dropbox or your App Folder). If you set <code>$path_prefix</code> to
974
- * "/Photos/Vacation", you'll only get results for that path and any files and folders
975
- * under it.
976
- *
977
- * @return array
978
- * A <a href="https://www.dropbox.com/developers/core/docs#delta">delta page</a>, which
979
- * contains a list of changes to apply along with a new "cursor" that should be passed into
980
- * future <code>getDelta</code> calls. If the "reset" field is <code>true</code>, you
981
- * should clear your local state before applying the changes. If the "has_more" field is
982
- * <code>true</code>, call <code>getDelta</code> immediately to get more results, otherwise
983
- * wait a while (at least 5 minutes) before calling <code>getDelta</code> again.
984
- *
985
- * @throws Dropbox_Exception
986
- */
987
- public function getDelta($cursor = null, $pathPrefix = null)
988
- {
989
- Dropbox_Checker::argStringNonEmptyOrNull("cursor", $cursor);
990
- Dropbox_Path::checkArgOrNull("pathPrefix", $pathPrefix);
991
-
992
- $response = $this->doPost($this->apiHost, "1/delta", array(
993
- "cursor" => $cursor,
994
- "path_prefix" => $pathPrefix, ));
995
-
996
- if ($response->statusCode !== 200) {
997
- throw Dropbox_RequestUtil::unexpectedStatus($response);
998
- }
999
-
1000
- return Dropbox_RequestUtil::parseResponseJson($response->body);
1001
- }
1002
-
1003
- /**
1004
- * Gets the metadata for all the file revisions (up to a limit) for a given path.
1005
- *
1006
- * See <a href="https://www.dropbox.com/developers/core/docs#revisions">/revisions</a>.
1007
- *
1008
- * @param string $path
1009
- * The Dropbox path that you want file revision metadata for (UTF-8).
1010
- *
1011
- * @param int|null limit
1012
- * The maximum number of revisions to return.
1013
- *
1014
- * @return array|null
1015
- * A list of <a href="https://www.dropbox.com/developers/core/docs#metadata-details>metadata
1016
- * objects</a>, one for each file revision. The later revisions appear first in the list.
1017
- * If <code>null</code>, then there were too many revisions at that path.
1018
- *
1019
- * @throws Dropbox_Exception
1020
- */
1021
- public function getRevisions($path, $limit = null)
1022
- {
1023
- Dropbox_Path::checkArgNonRoot("path", $path);
1024
- Dropbox_Checker::argIntPositiveOrNull("limit", $limit);
1025
-
1026
- $response = $this->doGet(
1027
- $this->apiHost,
1028
- $this->appendFilePath("1/revisions", $path),
1029
- array("rev_limit" => $limit));
1030
-
1031
- if ($response->statusCode === 406) {
1032
- return null;
1033
- }
1034
- if ($response->statusCode !== 200) {
1035
- throw Dropbox_RequestUtil::unexpectedStatus($response);
1036
- }
1037
-
1038
- return Dropbox_RequestUtil::parseResponseJson($response->body);
1039
- }
1040
-
1041
- /**
1042
- * Takes a copy of the file at the given revision and saves it over the current copy. This
1043
- * will create a new revision, but the file contents will match the revision you specified.
1044
- *
1045
- * See <a href="https://www.dropbox.com/developers/core/docs#restore">/restore</a>.
1046
- *
1047
- * @param string $path
1048
- * The Dropbox path of the file to restore (UTF-8).
1049
- *
1050
- * @param string $rev
1051
- * The revision to restore the contents to.
1052
- *
1053
- * @return mixed
1054
- * The <a href="https://www.dropbox.com/developers/core/docs#metadata-details">metadata
1055
- * object</a>
1056
- *
1057
- * @throws Dropbox_Exception
1058
- */
1059
- public function restoreFile($path, $rev)
1060
- {
1061
- Dropbox_Path::checkArgNonRoot("path", $path);
1062
- Dropbox_Checker::argStringNonEmpty("rev", $rev);
1063
-
1064
- $response = $this->doPost(
1065
- $this->apiHost,
1066
- $this->appendFilePath("1/restore", $path),
1067
- array("rev" => $rev));
1068
-
1069
- if ($response->statusCode === 404) {
1070
- return null;
1071
- }
1072
- if ($response->statusCode !== 200) {
1073
- throw Dropbox_RequestUtil::unexpectedStatus($response);
1074
- }
1075
-
1076
- return Dropbox_RequestUtil::parseResponseJson($response->body);
1077
- }
1078
-
1079
- /**
1080
- * Returns metadata for all files and folders whose filename matches the query string.
1081
- *
1082
- * See <a href="https://www.dropbox.com/developers/core/docs#search">/search</a>.
1083
- *
1084
- * @param string $basePath
1085
- * The path to limit the search to (UTF-8). Pass in "/" to search everything.
1086
- *
1087
- * @param string $query
1088
- * A space-separated list of substrings to search for. A file matches only if it contains
1089
- * all the substrings.
1090
- *
1091
- * @param int|null $limit
1092
- * The maximum number of results to return.
1093
- *
1094
- * @param bool $includeDeleted
1095
- * Whether to include deleted files in the results.
1096
- *
1097
- * @return mixed
1098
- * A list of <a href="https://www.dropbox.com/developers/core/docs#metadata-details>metadata
1099
- * objects</a> of files that match the search query.
1100
- *
1101
- * @throws Dropbox_Exception
1102
- */
1103
- public function searchFileNames($basePath, $query, $limit = null, $includeDeleted = false)
1104
- {
1105
- Dropbox_Path::checkArg("basePath", $basePath);
1106
- Dropbox_Checker::argStringNonEmpty("query", $query);
1107
- Dropbox_Checker::argNatOrNull("limit", $limit);
1108
- Dropbox_Checker::argBool("includeDeleted", $includeDeleted);
1109
-
1110
- $response = $this->doPost(
1111
- $this->apiHost,
1112
- $this->appendFilePath("1/search", $basePath),
1113
- array(
1114
- "query" => $query,
1115
- "file_limit" => $limit,
1116
- "include_deleted" => $includeDeleted,
1117
- ));
1118
-
1119
- if ($response->statusCode !== 200) {
1120
- throw Dropbox_RequestUtil::unexpectedStatus($response);
1121
- }
1122
-
1123
- return Dropbox_RequestUtil::parseResponseJson($response->body);
1124
- }
1125
-
1126
- /**
1127
- * Creates and returns a public link to a file or folder's "preview page". This link can be
1128
- * used without authentication. The preview page may contain a thumbnail or some other
1129
- * preview of the file, along with a download link to download the actual file.
1130
- *
1131
- * See <a href="https://www.dropbox.com/developers/core/docs#shares">/shares</a>.
1132
- *
1133
- * @param string $path
1134
- * The Dropbox path to the file or folder you want to create a shareable link to (UTF-8).
1135
- *
1136
- * @return string
1137
- * The URL of the preview page.
1138
- *
1139
- * @throws Dropbox_Exception
1140
- */
1141
- public function createShareableLink($path)
1142
- {
1143
- Dropbox_Path::checkArg("path", $path);
1144
-
1145
- $response = $this->doPost(
1146
- $this->apiHost,
1147
- $this->appendFilePath("1/shares", $path),
1148
- array(
1149
- "short_url" => "false",
1150
- ));
1151
-
1152
- if ($response->statusCode === 404) {
1153
- return null;
1154
- }
1155
- if ($response->statusCode !== 200) {
1156
- throw Dropbox_RequestUtil::unexpectedStatus($response);
1157
- }
1158
-
1159
- $j = Dropbox_RequestUtil::parseResponseJson($response->body);
1160
-
1161
- return self::getField($j, "url");
1162
- }
1163
-
1164
- /**
1165
- * Creates and returns a direct link to a file. This link can be used without authentication.
1166
- * This link will expire in a few hours.
1167
- *
1168
- * See <a href="https://www.dropbox.com/developers/core/docs#media">/media</a>.
1169
- *
1170
- * @param string $path
1171
- * The Dropbox path to a file or folder (UTF-8).
1172
- *
1173
- * @return array
1174
- * A <code>list(string $url, \DateTime $expires)</code> where <code>$url</code> is a direct
1175
- * link to the requested file and <code>$expires</code> is a standard PHP
1176
- * <code>\DateTime</code> representing when <code>$url</code> will stop working.
1177
- *
1178
- * @throws Dropbox_Exception
1179
- */
1180
- public function createTemporaryDirectLink($path)
1181
- {
1182
- Dropbox_Path::checkArgNonRoot("path", $path);
1183
-
1184
- $response = $this->doPost(
1185
- $this->apiHost,
1186
- $this->appendFilePath("1/media", $path));
1187
-
1188
- if ($response->statusCode === 404) {
1189
- return null;
1190
- }
1191
- if ($response->statusCode !== 200) {
1192
- throw Dropbox_RequestUtil::unexpectedStatus($response);
1193
- }
1194
-
1195
- $j = Dropbox_RequestUtil::parseResponseJson($response->body);
1196
- $url = self::getField($j, "url");
1197
- $expires = self::parseDateTime(self::getField($j, "expires"));
1198
-
1199
- return array($url, $expires);
1200
- }
1201
-
1202
- /**
1203
- * Creates and returns a "copy ref" to a file. A copy ref can be used to copy a file across
1204
- * different Dropbox accounts without downloading and re-uploading.
1205
- *
1206
- * For example: Create a <code>Client</code> using the access token from one account and call
1207
- * <code>createCopyRef</code>. Then, create a <code>Client</code> using the access token for
1208
- * another account and call <code>copyFromCopyRef</code> using the copy ref. (You need to use
1209
- * the same app key both times.)
1210
- *
1211
- * See <a href="https://www.dropbox.com/developers/core/docs#copy_ref">/copy_ref</a>.
1212
- *
1213
- * @param string $path
1214
- * The Dropbox path of the file or folder you want to create a copy ref for (UTF-8).
1215
- *
1216
- * @return string
1217
- * The copy ref (just a string that you keep track of).
1218
- *
1219
- * @throws Dropbox_Exception
1220
- */
1221
- public function createCopyRef($path)
1222
- {
1223
- Dropbox_Path::checkArg("path", $path);
1224
-
1225
- $response = $this->doGet(
1226
- $this->apiHost,
1227
- $this->appendFilePath("1/copy_ref", $path));
1228
-
1229
- if ($response->statusCode === 404) {
1230
- return null;
1231
- }
1232
- if ($response->statusCode !== 200) {
1233
- throw Dropbox_RequestUtil::unexpectedStatus($response);
1234
- }
1235
-
1236
- $j = Dropbox_RequestUtil::parseResponseJson($response->body);
1237
-
1238
- return self::getField($j, "copy_ref");
1239
- }
1240
-
1241
- /**
1242
- * Gets a thumbnail image representation of the file at the given path.
1243
- *
1244
- * See <a href="https://www.dropbox.com/developers/core/docs#thumbnails">/thumbnails</a>.
1245
- *
1246
- * @param string $path
1247
- * The path to the file you want a thumbnail for (UTF-8).
1248
- *
1249
- * @param string $format
1250
- * One of the two image formats: "jpeg" or "png".
1251
- *
1252
- * @param string $size
1253
- * One of the predefined image size names, as a string:
1254
- * <ul>
1255
- * <li>"xs" - 32x32</li>
1256
- * <li>"s" - 64x64</li>
1257
- * <li>"m" - 128x128</li>
1258
- * <li>"l" - 640x480</li>
1259
- * <li>"xl" - 1024x768</li>
1260
- * </ul>
1261
- *
1262
- * @return array|null
1263
- * If the file exists, you'll get <code>list(array $metadata, string $data)</code> where
1264
- * <code>$metadata</code> is the file's
1265
- * <a href="https://www.dropbox.com/developers/core/docs#metadata-details">metadata object</a>
1266
- * and $data is the raw data for the thumbnail image. If the file doesn't exist, you'll
1267
- * get <code>null</code>.
1268
- *
1269
- * @throws Dropbox_Exception
1270
- * @throws InvalidArgumentException
1271
- */
1272
- public function getThumbnail($path, $format, $size)
1273
- {
1274
- Dropbox_Path::checkArgNonRoot("path", $path);
1275
- Dropbox_Checker::argString("format", $format);
1276
- Dropbox_Checker::argString("size", $size);
1277
- if (!in_array($format, array("jpeg", "png"))) {
1278
- throw new InvalidArgumentException("Invalid 'format': ".self::q($format));
1279
- }
1280
- if (!in_array($size, array("xs", "s", "m", "l", "xl"))) {
1281
- throw new InvalidArgumentException("Invalid 'size': ".self::q($format));
1282
- }
1283
-
1284
- $url = $this->buildUrlForGetOrPut(
1285
- $this->contentHost,
1286
- $this->appendFilePath("1/thumbnails", $path),
1287
- array("size" => $size, "format" => $format));
1288
-
1289
- $curl = $this->mkCurl($url);
1290
- $metadataCatcher = new Dropbox_DropboxMetadataHeaderCatcher($curl->handle);
1291
-
1292
- $curl->set(CURLOPT_RETURNTRANSFER, true);
1293
- $response = $curl->exec();
1294
-
1295
- if ($response->statusCode === 404) {
1296
- return null;
1297
- }
1298
- if ($response->statusCode !== 200) {
1299
- throw Dropbox_RequestUtil::unexpectedStatus($response);
1300
- }
1301
-
1302
- $metadata = $metadataCatcher->getMetadata();
1303
-
1304
- return array($metadata, $response->body);
1305
- }
1306
-
1307
- /**
1308
- * Copies a file or folder to a new location
1309
- *
1310
- * See <a href="https://www.dropbox.com/developers/core/docs#fileops-copy">/fileops/copy</a>.
1311
- *
1312
- * @param string $fromPath
1313
- * The Dropbox path of the file or folder you want to copy (UTF-8).
1314
- *
1315
- * @param string $toPath
1316
- * The destination Dropbox path (UTF-8).
1317
- *
1318
- * @return mixed
1319
- * The <a href="https://www.dropbox.com/developers/core/docs#metadata-details">metadata
1320
- * object</a> for the new file or folder.
1321
- *
1322
- * @throws Dropbox_Exception
1323
- */
1324
- public function copy($fromPath, $toPath)
1325
- {
1326
- Dropbox_Path::checkArg("fromPath", $fromPath);
1327
- Dropbox_Path::checkArgNonRoot("toPath", $toPath);
1328
-
1329
- $response = $this->doPost(
1330
- $this->apiHost,
1331
- "1/fileops/copy",
1332
- array(
1333
- "root" => "auto",
1334
- "from_path" => $fromPath,
1335
- "to_path" => $toPath,
1336
- ));
1337
-
1338
- if ($response->statusCode !== 200) {
1339
- throw Dropbox_RequestUtil::unexpectedStatus($response);
1340
- }
1341
-
1342
- return Dropbox_RequestUtil::parseResponseJson($response->body);
1343
- }
1344
-
1345
- /**
1346
- * Creates a file or folder based on an existing copy ref (possibly from a different Dropbox
1347
- * account).
1348
- *
1349
- * See <a href="https://www.dropbox.com/developers/core/docs#fileops-copy">/fileops/copy</a>.
1350
- *
1351
- * @param string $copyRef
1352
- * A copy ref obtained via the {@link createCopyRef()} call.
1353
- *
1354
- * @param string $toPath
1355
- * The Dropbox path you want to copy the file or folder to (UTF-8).
1356
- *
1357
- * @return mixed
1358
- * The <a href="https://www.dropbox.com/developers/core/docs#metadata-details">metadata
1359
- * object</a> for the new file or folder.
1360
- *
1361
- * @throws Dropbox_Exception
1362
- */
1363
- public function copyFromCopyRef($copyRef, $toPath)
1364
- {
1365
- Dropbox_Checker::argStringNonEmpty("copyRef", $copyRef);
1366
- Dropbox_Path::checkArgNonRoot("toPath", $toPath);
1367
-
1368
- $response = $this->doPost(
1369
- $this->apiHost,
1370
- "1/fileops/copy",
1371
- array(
1372
- "root" => "auto",
1373
- "from_copy_ref" => $copyRef,
1374
- "to_path" => $toPath,
1375
- )
1376
- );
1377
-
1378
- if ($response->statusCode !== 200) {
1379
- throw Dropbox_RequestUtil::unexpectedStatus($response);
1380
- }
1381
-
1382
- return Dropbox_RequestUtil::parseResponseJson($response->body);
1383
- }
1384
-
1385
- /**
1386
- * Creates a folder.
1387
- *
1388
- * See <a href="https://www.dropbox.com/developers/core/docs#fileops-create-folder">/fileops/create_folder</a>.
1389
- *
1390
- * @param string $path
1391
- * The Dropbox path at which to create the folder (UTF-8).
1392
- *
1393
- * @return array|null
1394
- * If successful, you'll get back the
1395
- * <a href="https://www.dropbox.com/developers/core/docs#metadata-details">metadata object</a>
1396
- * for the newly-created folder. If not successful, you'll get <code>null</code>.
1397
- *
1398
- * @throws Dropbox_Exception
1399
- */
1400
- public function createFolder($path)
1401
- {
1402
- Dropbox_Path::checkArgNonRoot("path", $path);
1403
-
1404
- $response = $this->doPost(
1405
- $this->apiHost,
1406
- "1/fileops/create_folder",
1407
- array(
1408
- "root" => "auto",
1409
- "path" => $path,
1410
- ));
1411
-
1412
- if ($response->statusCode === 403) {
1413
- return null;
1414
- }
1415
- if ($response->statusCode !== 200) {
1416
- throw Dropbox_RequestUtil::unexpectedStatus($response);
1417
- }
1418
-
1419
- return Dropbox_RequestUtil::parseResponseJson($response->body);
1420
- }
1421
-
1422
- /**
1423
- * Deletes a file or folder
1424
- *
1425
- * See <a href="https://www.dropbox.com/developers/core/docs#fileops-delete">/fileops/delete</a>.
1426
- *
1427
- * @param string $path
1428
- * The Dropbox path of the file or folder to delete (UTF-8).
1429
- *
1430
- * @return mixed
1431
- * The <a href="https://www.dropbox.com/developers/core/docs#metadata-details">metadata
1432
- * object</a> for the deleted file or folder.
1433
- *
1434
- * @throws Dropbox_Exception
1435
- */
1436
- public function delete($path)
1437
- {
1438
- Dropbox_Path::checkArgNonRoot("path", $path);
1439
-
1440
- $response = $this->doPost(
1441
- $this->apiHost,
1442
- "1/fileops/delete",
1443
- array(
1444
- "root" => "auto",
1445
- "path" => $path,
1446
- ));
1447
-
1448
- if ($response->statusCode !== 200) {
1449
- throw Dropbox_RequestUtil::unexpectedStatus($response);
1450
- }
1451
-
1452
- return Dropbox_RequestUtil::parseResponseJson($response->body);
1453
- }
1454
-
1455
- /**
1456
- * Moves a file or folder to a new location.
1457
- *
1458
- * See <a href="https://www.dropbox.com/developers/core/docs#fileops-move">/fileops/move</a>.
1459
- *
1460
- * @param string $fromPath
1461
- * The source Dropbox path (UTF-8).
1462
- *
1463
- * @param string $toPath
1464
- * The destination Dropbox path (UTF-8).
1465
- *
1466
- * @return mixed
1467
- * The <a href="https://www.dropbox.com/developers/core/docs#metadata-details">metadata
1468
- * object</a> for the destination file or folder.
1469
- *
1470
- * @throws Dropbox_Exception
1471
- */
1472
- public function move($fromPath, $toPath)
1473
- {
1474
- Dropbox_Path::checkArgNonRoot("fromPath", $fromPath);
1475
- Dropbox_Path::checkArgNonRoot("toPath", $toPath);
1476
-
1477
- $response = $this->doPost(
1478
- $this->apiHost,
1479
- "1/fileops/move",
1480
- array(
1481
- "root" => "auto",
1482
- "from_path" => $fromPath,
1483
- "to_path" => $toPath,
1484
- ));
1485
-
1486
- if ($response->statusCode !== 200) {
1487
- throw Dropbox_RequestUtil::unexpectedStatus($response);
1488
- }
1489
-
1490
- return Dropbox_RequestUtil::parseResponseJson($response->body);
1491
- }
1492
-
1493
- /**
1494
- * Build a URL for making a GET or PUT request. Will add the "locale"
1495
- * parameter.
1496
- *
1497
- * @param $host
1498
- * Either the "API" or "API content" hostname from {@link getHost()}.
1499
- * @param $path
1500
- * The "path" part of the URL. For example, "/account/info".
1501
- * @param null $params
1502
- * URL parameters. For POST requests, do not put the parameters here.
1503
- * Include them in the request body instead.
1504
- *
1505
- * @return string
1506
- */
1507
- public function buildUrlForGetOrPut($host, $path, $params = null)
1508
- {
1509
- return Dropbox_RequestUtil::buildUrlForGetOrPut($this->userLocale, $host, $path, $params);
1510
- }
1511
-
1512
- /**
1513
- * Perform an OAuth-2-authorized GET request to the Dropbox API. Will automatically
1514
- * fill in "User-Agent" and "locale" as well.
1515
- *
1516
- * @param string $host
1517
- * Either the "API" or "API content" hostname from {@link getHost()}.
1518
- * @param string $path
1519
- * The "path" part of the URL. For example, "/account/info".
1520
- * @param array|null $params
1521
- * GET parameters.
1522
- *
1523
- * @return Dropbox_HttpResponse
1524
- *
1525
- * @throws Dropbox_Exception
1526
- */
1527
- public function doGet($host, $path, $params = null)
1528
- {
1529
- Dropbox_Checker::argString("host", $host);
1530
- Dropbox_Checker::argString("path", $path);
1531
-
1532
- return Dropbox_RequestUtil::doGet($this->clientIdentifier, $this->accessToken, $this->userLocale,
1533
- $host, $path, $params);
1534
- }
1535
-
1536
- /**
1537
- * Perform an OAuth-2-authorized POST request to the Dropbox API. Will automatically
1538
- * fill in "User-Agent" and "locale" as well.
1539
- *
1540
- * @param string $host
1541
- * Either the "API" or "API content" hostname from {@link getHost()}.
1542
- * @param string $path
1543
- * The "path" part of the URL. For example, "/commit_chunked_upload".
1544
- * @param array|null $params
1545
- * POST parameters.
1546
- *
1547
- * @return Dropbox_HttpResponse
1548
- *
1549
- * @throws Dropbox_Exception
1550
- */
1551
- public function doPost($host, $path, $params = null)
1552
- {
1553
- Dropbox_Checker::argString("host", $host);
1554
- Dropbox_Checker::argString("path", $path);
1555
-
1556
- return Dropbox_RequestUtil::doPost($this->clientIdentifier, $this->accessToken, $this->userLocale,
1557
- $host, $path, $params);
1558
- }
1559
-
1560
- /**
1561
- * Create a {@link Curl} object that is pre-configured with {@link getClientIdentifier()},
1562
- * and the proper OAuth 2 "Authorization" header.
1563
- *
1564
- * @param string $url
1565
- * Generate this URL using {@link buildUrl()}.
1566
- *
1567
- * @return Dropbox_Curl
1568
- */
1569
- public function mkCurl($url)
1570
- {
1571
- return Dropbox_RequestUtil::mkCurlWithOAuth($this->clientIdentifier, $url, $this->accessToken);
1572
- }
1573
-
1574
- /**
1575
- * Parses date/time strings returned by the Dropbox API. The Dropbox API returns date/times
1576
- * formatted like: <code>"Sat, 21 Aug 2010 22:31:20 +0000"</code>.
1577
- *
1578
- * @param string $apiDateTimeString
1579
- * A date/time string returned by the API.
1580
- *
1581
- * @return \DateTime
1582
- * A standard PHP <code>\DateTime</code> instance.
1583
- *
1584
- * @throws Dropbox_Exception_BadResponse
1585
- * Thrown if <code>$apiDateTimeString</code> isn't correctly formatted.
1586
- */
1587
- public static function parseDateTime($apiDateTimeString)
1588
- {
1589
- $dt = DateTime::createFromFormat(self::$dateTimeFormat, $apiDateTimeString);
1590
- if ($dt === false) {
1591
- throw new Dropbox_Exception_BadResponse(
1592
- "Bad date/time from server: ".self::q($apiDateTimeString));
1593
- }
1594
-
1595
- return $dt;
1596
- }
1597
-
1598
- private static $dateTimeFormat = "D, d M Y H:i:s T";
1599
-
1600
- /**
1601
- * @internal
1602
- */
1603
- public static function q($object)
1604
- {
1605
- return var_export($object, true);
1606
- }
1607
-
1608
- /**
1609
- * @internal
1610
- */
1611
- public static function getField($j, $fieldName)
1612
- {
1613
- if (!array_key_exists($fieldName, $j)) {
1614
- throw new Dropbox_Exception_BadResponse(
1615
- "missing field \"$fieldName\" in ".self::q($j));
1616
- }
1617
-
1618
- return $j[$fieldName];
1619
- }
1620
-
1621
- /**
1622
- * Given an OAuth 2 access token, returns <code>null</code> if it is well-formed (though
1623
- * not necessarily valid). Otherwise, returns a string describing what's wrong with it.
1624
- *
1625
- * @param string $s
1626
- *
1627
- * @return string
1628
- */
1629
- public static function getAccessTokenError($s)
1630
- {
1631
- if ($s === null) {
1632
- return "can't be null";
1633
- }
1634
- if (strlen($s) === 0) {
1635
- return "can't be empty";
1636
- }
1637
-
1638
- // if (preg_match('@[^-=_~/A-Za-z0-9\.\+]@', $s) === 1) return "contains invalid character";
1639
- return null;
1640
- }
1641
-
1642
- /**
1643
- * @internal
1644
- */
1645
- public static function checkAccessTokenArg($argName, $accessToken)
1646
- {
1647
- $error = self::getAccessTokenError($accessToken);
1648
- if ($error !== null) {
1649
- throw new InvalidArgumentException("'$argName' invalid: $error");
1650
- }
1651
- }
1652
-
1653
- /**
1654
- * @internal
1655
- */
1656
- public static function getClientIdentifierError($s)
1657
- {
1658
- if ($s === null) {
1659
- return "can't be null";
1660
- }
1661
- if (strlen($s) === 0) {
1662
- return "can't be empty";
1663
- }
1664
- if (preg_match('@[\x00-\x1f\x7f]@', $s) === 1) {
1665
- return "contains control character";
1666
- }
1667
-
1668
- return null;
1669
- }
1670
-
1671
- /**
1672
- * @internal
1673
- */
1674
- public static function checkClientIdentifierArg($argName, $accessToken)
1675
- {
1676
- $error = self::getClientIdentifierError($accessToken);
1677
- if ($error !== null) {
1678
- throw new InvalidArgumentException("'$argName' invalid: $error");
1679
- }
1680
- }
1681
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Dropbox/Closure/ChunkedUploadContinueAction.php DELETED
@@ -1,28 +0,0 @@
1
- <?php
2
-
3
- class Dropbox_Closure_ChunkedUploadContinueAction implements Dropbox_Closure_ReRunnableActionInterface
4
- {
5
- private $client;
6
-
7
- private $uploadId;
8
-
9
- private $byteOffset;
10
-
11
- private $data;
12
-
13
- private $callback;
14
-
15
- public function __construct(Dropbox_Client $client, $uploadId, $byteOffset, $data, $callback = null)
16
- {
17
- $this->client = $client;
18
- $this->uploadId = $uploadId;
19
- $this->byteOffset = $byteOffset;
20
- $this->data = $data;
21
- $this->callback = $callback;
22
- }
23
-
24
- public function run()
25
- {
26
- return $this->client->chunkedUploadContinue($this->uploadId, $this->byteOffset, $this->data, $this->callback);
27
- }
28
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Dropbox/Closure/ChunkedUploadFinishAction.php DELETED
@@ -1,25 +0,0 @@
1
- <?php
2
-
3
- class Dropbox_Closure_ChunkedUploadFinishAction implements Dropbox_Closure_ReRunnableActionInterface
4
- {
5
- private $client;
6
-
7
- private $uploadId;
8
-
9
- private $path;
10
-
11
- private $writeMode;
12
-
13
- public function __construct(Dropbox_Client $client, $uploadId, $path, $writeMode)
14
- {
15
- $this->client = $client;
16
- $this->uploadId = $uploadId;
17
- $this->path = $path;
18
- $this->writeMode = $writeMode;
19
- }
20
-
21
- public function run()
22
- {
23
- return $this->client->chunkedUploadFinish($this->uploadId, $this->path, $this->writeMode);
24
- }
25
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Dropbox/Closure/ChunkedUploadStartAction.php DELETED
@@ -1,22 +0,0 @@
1
- <?php
2
-
3
- class Dropbox_Closure_ChunkedUploadStartAction implements Dropbox_Closure_ReRunnableActionInterface
4
- {
5
- private $client;
6
-
7
- private $data;
8
-
9
- private $callback;
10
-
11
- public function __construct(Dropbox_Client $client, $data, $callback = null)
12
- {
13
- $this->client = $client;
14
- $this->data = $data;
15
- $this->callback = $callback;
16
- }
17
-
18
- public function run()
19
- {
20
- return $this->client->chunkedUploadStart($this->data, $this->callback);
21
- }
22
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Dropbox/Closure/CurlConfigInStream.php DELETED
@@ -1,24 +0,0 @@
1
- <?php
2
-
3
- class Dropbox_Closure_CurlConfigInStream implements Dropbox_Closure_CurlConfigInterface
4
- {
5
- private $inStream;
6
-
7
- private $numBytes;
8
-
9
- private $callback;
10
-
11
- public function __construct($inStream, $numBytes, $callback = null)
12
- {
13
- $this->inStream = $inStream;
14
- $this->numBytes = $numBytes;
15
- $this->callback = $callback;
16
- }
17
-
18
- public function configure(Dropbox_Curl $curl)
19
- {
20
- $curl->set(CURLOPT_PUT, true);
21
- $curl->set(CURLOPT_INFILE, $this->inStream);
22
- $curl->set(CURLOPT_INFILESIZE, $this->numBytes);
23
- }
24
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Dropbox/Closure/CurlConfigInterface.php DELETED
@@ -1,6 +0,0 @@
1
- <?php
2
-
3
- interface Dropbox_Closure_CurlConfigInterface
4
- {
5
- public function configure(Dropbox_Curl $curl);
6
- }
 
 
 
 
 
 
src/Dropbox/Closure/CurlConfigOctetStream.php DELETED
@@ -1,18 +0,0 @@
1
- <?php
2
-
3
- class Dropbox_Closure_CurlConfigOctetStream implements Dropbox_Closure_CurlConfigInterface
4
- {
5
- private $data;
6
-
7
- public function __construct($data)
8
- {
9
- $this->data = $data;
10
- }
11
-
12
- public function configure(Dropbox_Curl $curl)
13
- {
14
- $curl->set(CURLOPT_CUSTOMREQUEST, "PUT");
15
- $curl->set(CURLOPT_POSTFIELDS, $this->data);
16
- $curl->addHeader("Content-Type: application/octet-stream");
17
- }
18
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Dropbox/Closure/ReRunnableActionInterface.php DELETED
@@ -1,6 +0,0 @@
1
- <?php
2
-
3
- interface Dropbox_Closure_ReRunnableActionInterface
4
- {
5
- public function run();
6
- }
 
 
 
 
 
 
src/Dropbox/Curl.php DELETED
@@ -1,116 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * A minimal wrapper around a cURL handle.
5
- *
6
- * @internal
7
- */
8
- final class Dropbox_Curl
9
- {
10
- /** @var resource */
11
- public $handle;
12
-
13
- /** @var string[] */
14
- private $headers = array();
15
-
16
- /**
17
- * @param string $url
18
- */
19
- public function __construct($url)
20
- {
21
- // Make sure there aren't any spaces in the URL (i.e. the caller forgot to URL-encode).
22
- if (strpos($url, ' ') !== false) {
23
- throw new InvalidArgumentException("Found space in \$url; it should be encoded");
24
- }
25
-
26
- $this->handle = curl_init($url);
27
-
28
- // NOTE: Though we turn on all the correct SSL settings, many PHP installations
29
- // don't respect these settings. Run "examples/test-ssl.php" to run some basic
30
- // SSL tests to see how well your PHP implementation behaves.
31
-
32
- // Force SSL and use our own certificate list.
33
- $this->set(CURLOPT_SSL_VERIFYPEER, true); // Enforce certificate validation
34
- $this->set(CURLOPT_SSL_VERIFYHOST, 2); // Enforce hostname validation
35
- $this->set(CURLOPT_SSLVERSION, 1); // Enforce TLS.
36
-
37
- // Only allow ciphersuites supported by Dropbox
38
- $curlVersion = curl_version();
39
- $curlSslBackend = $curlVersion['ssl_version'];
40
- if (substr_compare($curlSslBackend, "NSS/", 0, strlen("NSS/")) !== 0) {
41
- // Can't figure out how to reliably set ciphersuites for NSS.
42
- $sslCiphersuiteList = null;
43
- $this->set(CURLOPT_SSL_CIPHER_LIST,
44
- 'ECDHE-RSA-AES256-GCM-SHA384:'.
45
- 'ECDHE-RSA-AES128-GCM-SHA256:'.
46
- 'ECDHE-RSA-AES256-SHA384:'.
47
- 'ECDHE-RSA-AES128-SHA256:'.
48
- 'ECDHE-RSA-AES256-SHA:'.
49
- 'ECDHE-RSA-AES128-SHA:'.
50
- 'ECDHE-RSA-RC4-SHA:'.
51
- 'DHE-RSA-AES256-GCM-SHA384:'.
52
- 'DHE-RSA-AES128-GCM-SHA256:'.
53
- 'DHE-RSA-AES256-SHA256:'.
54
- 'DHE-RSA-AES128-SHA256:'.
55
- 'DHE-RSA-AES256-SHA:'.
56
- 'DHE-RSA-AES128-SHA:'.
57
- 'AES256-GCM-SHA384:'.
58
- 'AES128-GCM-SHA256:'.
59
- 'AES256-SHA256:'.
60
- 'AES128-SHA256:'.
61
- 'AES256-SHA:'.
62
- 'AES128-SHA'
63
- );
64
- }
65
-
66
- // Certificate file.
67
- $this->set(CURLOPT_CAINFO, dirname(__FILE__).'/certs/trusted-certs.crt');
68
- // Certificate folder. If not specified, some PHP installations will use
69
- // the system default, even when CURLOPT_CAINFO is specified.
70
- $this->set(CURLOPT_CAPATH, dirname(__FILE__).'/certs/');
71
-
72
- // Limit vulnerability surface area. Supported in cURL 7.19.4+
73
- if (defined('CURLOPT_PROTOCOLS')) {
74
- $this->set(CURLOPT_PROTOCOLS, CURLPROTO_HTTPS);
75
- }
76
- if (defined('CURLOPT_REDIR_PROTOCOLS')) {
77
- $this->set(CURLOPT_REDIR_PROTOCOLS, CURLPROTO_HTTPS);
78
- }
79
- }
80
-
81
- /**
82
- * @param string $header
83
- */
84
- public function addHeader($header)
85
- {
86
- $this->headers[] = $header;
87
- }
88
-
89
- public function exec()
90
- {
91
- $this->set(CURLOPT_HTTPHEADER, $this->headers);
92
-
93
- $body = curl_exec($this->handle);
94
- if ($body === false) {
95
- throw new Dropbox_Exception_NetworkIO("Error executing HTTP request: ".curl_error($this->handle));
96
- }
97
-
98
- $statusCode = curl_getinfo($this->handle, CURLINFO_HTTP_CODE);
99
-
100
- return new Dropbox_HttpResponse($statusCode, $body);
101
- }
102
-
103
- /**
104
- * @param int $option
105
- * @param mixed $value
106
- */
107
- public function set($option, $value)
108
- {
109
- curl_setopt($this->handle, $option, $value);
110
- }
111
-
112
- public function __destruct()
113
- {
114
- curl_close($this->handle);
115
- }
116
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Dropbox/CurlStreamRelay.php DELETED
@@ -1,44 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * A CURLOPT_WRITEFUNCTION that will write HTTP response data to $outStream if
5
- * it's an HTTP 200 response. For all other HTTP status codes, it'll save the
6
- * output in a string, which you can retrieve it via {@link getErrorBody}.
7
- *
8
- * @internal
9
- */
10
- class Dropbox_CurlStreamRelay
11
- {
12
- public $outStream;
13
- public $errorData;
14
- public $isError;
15
-
16
- public function __construct($ch, $outStream)
17
- {
18
- $this->outStream = $outStream;
19
- $this->errorData = array();
20
- $isError = null;
21
- curl_setopt($ch, CURLOPT_WRITEFUNCTION, array($this, 'writeData'));
22
- }
23
-
24
- public function writeData($ch, $data)
25
- {
26
- if ($this->isError === null) {
27
- $statusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
28
- $this->isError = ($statusCode !== 200);
29
- }
30
-
31
- if ($this->isError) {
32
- $this->errorData[] = $data;
33
- } else {
34
- fwrite($this->outStream, $data);
35
- }
36
-
37
- return strlen($data);
38
- }
39
-
40
- public function getErrorBody()
41
- {
42
- return implode($this->errorData);
43
- }
44
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Dropbox/DeserializeException.php DELETED
@@ -1,18 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * If, when loading a serialized {@link RequestToken} or {@link AccessToken}, the input string is
5
- * malformed, this exception will be thrown.
6
- */
7
- final class Dropbox_DeserializeException extends Dropbox_Exception
8
- {
9
- /**
10
- * @param string $message
11
- *
12
- * @internal
13
- */
14
- public function __construct($message)
15
- {
16
- parent::__construct($message);
17
- }
18
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Dropbox/DropboxMetadataHeaderCatcher.php DELETED
@@ -1,88 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * @internal
5
- */
6
- final class Dropbox_DropboxMetadataHeaderCatcher
7
- {
8
- /**
9
- * @var mixed
10
- */
11
- public $metadata = null;
12
-
13
- /**
14
- * @var string
15
- */
16
- public $error = null;
17
-
18
- /**
19
- * @var bool
20
- */
21
- public $skippedFirstLine = false;
22
-
23
- /**
24
- * @param resource $ch
25
- */
26
- public function __construct($ch)
27
- {
28
- curl_setopt($ch, CURLOPT_HEADERFUNCTION, array($this, 'headerFunction'));
29
- }
30
-
31
- /**
32
- * @param resource $ch
33
- * @param string $header
34
- *
35
- * @return int
36
- * @throws Dropbox_Exception_BadResponse
37
- */
38
- public function headerFunction($ch, $header)
39
- {
40
- // The first line is the HTTP status line (Ex: "HTTP/1.1 200 OK").
41
- if (!$this->skippedFirstLine) {
42
- $this->skippedFirstLine = true;
43
-
44
- return strlen($header);
45
- }
46
-
47
- // If we've encountered an error on a previous callback, then there's nothing left to do.
48
- if ($this->error !== null) {
49
- return strlen($header);
50
- }
51
-
52
- // case-insensitive starts-with check.
53
- if (strlen($header) < 19 || substr_compare($header, "x-dropbox-metadata:", 0, 19, true) !== 0) {
54
- return strlen($header);
55
- }
56
-
57
- if ($this->metadata !== null) {
58
- $this->error = "Duplicate X-Dropbox-Metadata header";
59
-
60
- return strlen($header);
61
- }
62
-
63
- $headerValue = substr($header, 19);
64
- $parsed = json_decode($headerValue, true);
65
-
66
- if ($parsed === null) {
67
- $this->error = "Bad JSON in X-Dropbox-Metadata header";
68
-
69
- return strlen($header);
70
- }
71
-
72
- $this->metadata = $parsed;
73
-
74
- return strlen($header);
75
- }
76
-
77
- public function getMetadata()
78
- {
79
- if ($this->error !== null) {
80
- throw new Dropbox_Exception_BadResponse($this->error);
81
- }
82
- if ($this->metadata === null) {
83
- throw new Dropbox_Exception_BadResponse("Missing X-Dropbox-Metadata header");
84
- }
85
-
86
- return $this->metadata;
87
- }
88
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Dropbox/Exception.php DELETED
@@ -1,31 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * The base class for all API call exceptions.
5
- */
6
- class Dropbox_Exception extends Exception
7
- {
8
- public $previousException;
9
-
10
- /**
11
- * @internal
12
- */
13
- public function __construct($message, $cause = null)
14
- {
15
- if (version_compare(PHP_VERSION, '5.3', '<')) {
16
- $this->previousException = $cause;
17
- parent::__construct($message, 0);
18
-
19
- return;
20
- }
21
- parent::__construct($message, 0, $cause);
22
- }
23
-
24
- /**
25
- * @return mixed
26
- */
27
- public function getPreviousException()
28
- {
29
- return $this->previousException;
30
- }
31
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Dropbox/Exception/BadRequest.php DELETED
@@ -1,16 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * Thrown when the server tells us that our request was invalid. This is typically due to an
5
- * HTTP 400 response from the server.
6
- */
7
- final class Dropbox_Exception_BadRequest extends Dropbox_Exception_ProtocolError
8
- {
9
- /**
10
- * @internal
11
- */
12
- public function __construct($message = "")
13
- {
14
- parent::__construct($message);
15
- }
16
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Dropbox/Exception/BadResponse.php DELETED
@@ -1,16 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * When this SDK can't understand the response from the server. This could be due to a bug in this
5
- * SDK or a buggy response from the Dropbox server.
6
- */
7
- class Dropbox_Exception_BadResponse extends Dropbox_Exception_ProtocolError
8
- {
9
- /**
10
- * @internal
11
- */
12
- public function __construct($message)
13
- {
14
- parent::__construct($message);
15
- }
16
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Dropbox/Exception/BadResponseCode.php DELETED
@@ -1,32 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * Thrown when the the Dropbox server responds with an HTTP status code we didn't expect.
5
- */
6
- final class Dropbox_Exception_BadResponseCode extends Dropbox_Exception_BadResponse
7
- {
8
- /** @var int */
9
- private $statusCode;
10
-
11
- /**
12
- * @param string $message
13
- * @param int $statusCode
14
- *
15
- * @internal
16
- */
17
- public function __construct($message, $statusCode)
18
- {
19
- parent::__construct($message);
20
- $this->statusCode = $statusCode;
21
- }
22
-
23
- /**
24
- * The HTTP status code returned by the Dropbox server.
25
- *
26
- * @return int
27
- */
28
- public function getStatusCode()
29
- {
30
- return $this->statusCode;
31
- }
32
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Dropbox/Exception/InvalidAccessToken.php DELETED
@@ -1,17 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * The Dropbox server said that the access token you used is invalid or expired. You should
5
- * probably ask the user to go through the OAuth authorization flow again to get a new access
6
- * token.
7
- */
8
- final class Dropbox_Exception_InvalidAccessToken extends Dropbox_Exception
9
- {
10
- /**
11
- * @internal
12
- */
13
- public function __construct($message = "")
14
- {
15
- parent::__construct($message);
16
- }
17
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Dropbox/Exception/NetworkIO.php DELETED
@@ -1,15 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * There was a network I/O error when making the request.
5
- */
6
- final class Dropbox_Exception_NetworkIO extends Dropbox_Exception
7
- {
8
- /**
9
- * @internal
10
- */
11
- public function __construct($message, $cause = null)
12
- {
13
- parent::__construct($message, $cause);
14
- }
15
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Dropbox/Exception/ProtocolError.php DELETED
@@ -1,16 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * There was an protocol misunderstanding between this SDK and the server. One of us didn't
5
- * understand what the other one was saying.
6
- */
7
- class Dropbox_Exception_ProtocolError extends Dropbox_Exception
8
- {
9
- /**
10
- * @internal
11
- */
12
- public function __construct($message)
13
- {
14
- parent::__construct($message);
15
- }
16
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Dropbox/Exception/RetryLater.php DELETED
@@ -1,16 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * The Dropbox server said it couldn't fulfil our request right now, but that we should try
5
- * again later.
6
- */
7
- final class Dropbox_Exception_RetryLater extends Dropbox_Exception
8
- {
9
- /**
10
- * @internal
11
- */
12
- public function __construct($message)
13
- {
14
- parent::__construct($message);
15
- }
16
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Dropbox/Exception/ServerError.php DELETED
@@ -1,14 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * The Dropbox server said that there was an internal error when trying to fulfil our request.
5
- * This usually corresponds to an HTTP 500 response.
6
- */
7
- final class Dropbox_Exception_ServerError extends Dropbox_Exception
8
- {
9
- /** @internal */
10
- public function __construct($message = "")
11
- {
12
- parent::__construct($message);
13
- }
14
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Dropbox/Host.php DELETED
@@ -1,115 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * The Dropbox web API accesses three hosts; this structure holds the
5
- * names of those three hosts. This is primarily for mocking things out
6
- * during testing. Most of the time you won't have to deal with this class
7
- * directly, and even when you do, you'll just use the default
8
- * value: {@link Host::getDefault()}.
9
- *
10
- * @internal
11
- */
12
- final class Dropbox_Host
13
- {
14
- /**
15
- * Returns a Host object configured with the three standard Dropbox host: "api.dropbox.com",
16
- * "api-content.dropbox.com", and "www.dropbox.com"
17
- *
18
- * @return Dropbox_Host
19
- */
20
- public static function getDefault()
21
- {
22
- if (!self::$defaultValue) {
23
- self::$defaultValue = new self("api.dropbox.com", "api-content.dropbox.com", "www.dropbox.com");
24
- }
25
-
26
- return self::$defaultValue;
27
- }
28
-
29
- private static $defaultValue;
30
-
31
- /** @var string */
32
- private $api;
33
- /** @var string */
34
- private $content;
35
- /** @var string */
36
- private $web;
37
-
38
- /**
39
- * Constructor.
40
- *
41
- * @param string $api
42
- * See {@link getApi()}
43
- * @param string $content
44
- * See {@link getContent()}
45
- * @param string $web
46
- * See {@link getWeb()}
47
- */
48
- public function __construct($api, $content, $web)
49
- {
50
- $this->api = $api;
51
- $this->content = $content;
52
- $this->web = $web;
53
- }
54
-
55
- /**
56
- * Returns the host name of the main Dropbox API server.
57
- * The default is "api.dropbox.com".
58
- *
59
- * @return string
60
- */
61
- public function getApi()
62
- {
63
- return $this->api;
64
- }
65
-
66
- /**
67
- * Returns the host name of the Dropbox API content server.
68
- * The default is "api-content.dropbox.com".
69
- *
70
- * @return string
71
- */
72
- public function getContent()
73
- {
74
- return $this->content;
75
- }
76
-
77
- /**
78
- * Returns the host name of the Dropbox web server. Used during user authorization.
79
- * The default is "www.dropbox.com".
80
- *
81
- * @return string
82
- */
83
- public function getWeb()
84
- {
85
- return $this->web;
86
- }
87
-
88
- /**
89
- * Check that a function argument is of type <code>Host</code>.
90
- *
91
- * @internal
92
- */
93
- public static function checkArg($argName, $argValue)
94
- {
95
- if (!($argValue instanceof self)) {
96
- Dropbox_Checker::throwError($argName, $argValue, __CLASS__);
97
- }
98
- }
99
-
100
- /**
101
- * Check that a function argument is either <code>null</code> or of type
102
- * <code>Host</code>.
103
- *
104
- * @internal
105
- */
106
- public static function checkArgOrNull($argName, $argValue)
107
- {
108
- if ($argValue === null) {
109
- return;
110
- }
111
- if (!($argValue instanceof self)) {
112
- Dropbox_Checker::throwError($argName, $argValue, __CLASS__);
113
- }
114
- }
115
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Dropbox/HttpResponse.php DELETED
@@ -1,16 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * @internal
5
- */
6
- final class Dropbox_HttpResponse
7
- {
8
- public $statusCode;
9
- public $body;
10
-
11
- public function __construct($statusCode, $body)
12
- {
13
- $this->statusCode = $statusCode;
14
- $this->body = $body;
15
- }
16
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Dropbox/OAuth1AccessToken.php DELETED
@@ -1,68 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * Use with {@link OAuth1Upgrader} to convert old OAuth 1 access tokens
5
- * to OAuth 2 access tokens. This SDK doesn't support using OAuth 1
6
- * access tokens for regular API calls.
7
- */
8
- class Dropbox_OAuth1AccessToken
9
- {
10
- /**
11
- * The OAuth 1 access token key.
12
- *
13
- * @return string
14
- */
15
- public function getKey()
16
- {
17
- return $this->key;
18
- }
19
-
20
- /** @var string */
21
- private $key;
22
-
23
- /**
24
- * The OAuth 1 access token secret.
25
- *
26
- * Make sure that this is kept a secret. Someone with your app secret can impesonate your
27
- * application. People sometimes ask for help on the Dropbox API forums and
28
- * copy/paste code that includes their app secret. Do not do that.
29
- *
30
- * @return string
31
- */
32
- public function getSecret()
33
- {
34
- return $this->secret;
35
- }
36
-
37
- /** @var string */
38
- private $secret;
39
-
40
- /**
41
- * Constructor.
42
- *
43
- * @param string $key
44
- * {@link getKey()}
45
- * @param string $secret
46
- * {@link getSecret()}
47
- */
48
- public function __construct($key, $secret)
49
- {
50
- Dropbox_AppInfo::checkKeyArg($key);
51
- Dropbox_AppInfo::checkSecretArg($secret);
52
-
53
- $this->key = $key;
54
- $this->secret = $secret;
55
- }
56
-
57
- /**
58
- * Use this to check that a function argument is of type <code>AppInfo</code>
59
- *
60
- * @internal
61
- */
62
- public static function checkArg($argName, $argValue)
63
- {
64
- if (!($argValue instanceof self)) {
65
- Dropbox_Checker::throwError($argName, $argValue, __CLASS__);
66
- }
67
- }
68
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Dropbox/OAuth1Upgrader.php DELETED
@@ -1,106 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * Lets you convert OAuth 1 access tokens to OAuth 2 access tokens. First call {@link
5
- * OAuth1AccessTokenUpgrader::createOAuth2AccessToken()} to get an OAuth 2 access token.
6
- * If that succeeds, call {@link OAuth1AccessTokenUpgrader::disableOAuth1AccessToken()}
7
- * to disable the OAuth 1 access token.
8
- *
9
- * <code>
10
- * use \Dropbox as dbx;
11
- * $appInfo = dbx\AppInfo::loadFromJsonFile(...);
12
- * $clientIdentifier = "my-app/1.0";
13
- * $oauth1AccessToken = dbx\OAuth1AccessToken(...);
14
- *
15
- * $upgrader = new dbx\OAuth1AccessTokenUpgrader($appInfo, $clientIdentifier, ...);
16
- * $oauth2AccessToken = $upgrader->getOAuth2AccessToken($oauth1AccessToken);
17
- * $upgrader->disableOAuth1AccessToken($oauth1AccessToken);
18
- * </code>
19
- */
20
- class Dropbox_OAuth1Upgrader extends Dropbox_AuthBase
21
- {
22
- /**
23
- * Given an existing active OAuth 1 access token, make a Dropbox API call to get a new OAuth 2
24
- * access token that represents the same user and app.
25
- *
26
- * See <a href="https://www.dropbox.com/developers/core/docs#oa1-from-oa1">/oauth2/token_from_oauth1</a>.
27
- *
28
- * @param Dropbox_OAuth1AccessToken $oauth1AccessToken
29
- *
30
- * @return string
31
- * The OAuth 2 access token.
32
- *
33
- * @throws Dropbox_Exception
34
- */
35
- public function createOAuth2AccessToken($oauth1AccessToken)
36
- {
37
- Dropbox_OAuth1AccessToken::checkArg("oauth1AccessToken", $oauth1AccessToken);
38
-
39
- $response = self::doPost($oauth1AccessToken, "1/oauth2/token_from_oauth1");
40
-
41
- if ($response->statusCode !== 200) {
42
- throw Dropbox_RequestUtil::unexpectedStatus($response);
43
- }
44
-
45
- $parts = Dropbox_RequestUtil::parseResponseJson($response->body);
46
-
47
- if (!array_key_exists('token_type', $parts) or !is_string($parts['token_type'])) {
48
- throw new Dropbox_Exception_BadResponse("Missing \"token_type\" field.");
49
- }
50
- $tokenType = $parts['token_type'];
51
- if (!array_key_exists('access_token', $parts) or !is_string($parts['access_token'])) {
52
- throw new Dropbox_Exception_BadResponse("Missing \"access_token\" field.");
53
- }
54
- $accessToken = $parts['access_token'];
55
-
56
- if ($tokenType !== "Bearer" && $tokenType !== "bearer") {
57
- throw new Dropbox_Exception_BadResponse("Unknown \"token_type\"; expecting \"Bearer\", got "
58
- .Dropbox_Client::q($tokenType));
59
- }
60
-
61
- return $accessToken;
62
- }
63
-
64
- /**
65
- * Make a Dropbox API call to disable the given OAuth 1 access token.
66
- *
67
- * See <a href="https://www.dropbox.com/developers/core/docs#disable-token">/disable_access_token</a>.
68
- *
69
- * @param Dropbox_OAuth1AccessToken $oauth1AccessToken
70
- *
71
- * @throws Dropbox_Exception
72
- */
73
- public function disableOAuth1AccessToken($oauth1AccessToken)
74
- {
75
- Dropbox_OAuth1AccessToken::checkArg("oauth1AccessToken", $oauth1AccessToken);
76
-
77
- $response = self::doPost($oauth1AccessToken, "1/disable_access_token");
78
-
79
- if ($response->statusCode !== 200) {
80
- throw Dropbox_RequestUtil::unexpectedStatus($response);
81
- }
82
- }
83
-
84
- /**
85
- * @param Dropbox_OAuth1AccessToken $oauth1AccessToken
86
- * @param string $path
87
- *
88
- * @return Dropbox_HttpResponse
89
- *
90
- * @throws Dropbox_Exception
91
- */
92
- private function doPost($oauth1AccessToken, $path)
93
- {
94
- // Construct the OAuth 1 header.
95
- $authHeaderValue = "OAuth oauth_signature_method=\"PLAINTEXT\""
96
- .", oauth_consumer_key=\"".rawurlencode($this->appInfo->getKey())."\""
97
- .", oauth_token=\"".rawurlencode($oauth1AccessToken->getKey())."\""
98
- .", oauth_signature=\"".rawurlencode($this->appInfo->getSecret())."&".rawurlencode($oauth1AccessToken->getSecret())."\"";
99
-
100
- return Dropbox_RequestUtil::doPostWithSpecificAuth(
101
- $this->clientIdentifier, $authHeaderValue, $this->userLocale,
102
- $this->appInfo->getHost()->getApi(),
103
- $path,
104
- null);
105
- }
106
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Dropbox/Path.php DELETED
@@ -1,201 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * Path validation functions.
5
- */
6
- final class Dropbox_Path
7
- {
8
- /**
9
- * Return whether the given path is a valid Dropbox path.
10
- *
11
- * @param string $path
12
- * The path you want to check for validity.
13
- *
14
- * @return bool
15
- * Whether the path was valid or not.
16
- */
17
- public static function isValid($path)
18
- {
19
- $error = self::findError($path);
20
-
21
- return ($error === null);
22
- }
23
-
24
- /**
25
- * Return whether the given path is a valid non-root Dropbox path.
26
- * This is the same as {@link isValid} except <code>"/"</code> is not allowed.
27
- *
28
- * @param string $path
29
- * The path you want to check for validity.
30
- *
31
- * @return bool
32
- * Whether the path was valid or not.
33
- */
34
- public static function isValidNonRoot($path)
35
- {
36
- $error = self::findErrorNonRoot($path);
37
-
38
- return ($error === null);
39
- }
40
-
41
- /**
42
- * If the given path is a valid Dropbox path, return <code>null</code>,
43
- * otherwise return an English string error message describing what is wrong with the path.
44
- *
45
- * @param string $path
46
- * The path you want to check for validity.
47
- *
48
- * @return string|null
49
- * If the path was valid, return <code>null</code>. Otherwise, returns
50
- * an English string describing the problem.
51
- */
52
- public static function findError($path)
53
- {
54
- Dropbox_Checker::argString("path", $path);
55
-
56
- $matchResult = preg_match('%^(?:
57
- [\x09\x0A\x0D\x20-\x7E] # ASCII
58
- | [\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte
59
- | \xE0[\xA0-\xBF][\x80-\xBD] # excluding overlongs, FFFE, and FFFF
60
- | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte
61
- | \xED[\x80-\x9F][\x80-\xBF] # excluding surrogates
62
- )*$%xs', $path);
63
-
64
- if ($matchResult !== 1) {
65
- return "must be valid UTF-8; BMP only, no surrogates, no U+FFFE or U+FFFF";
66
- }
67
-
68
- if (substr_compare($path, "/", 0, 1) !== 0) {
69
- return "must start with \"/\"";
70
- }
71
- $l = strlen($path);
72
- if ($l === 1) {
73
- return null;
74
- } // Special case for "/"
75
-
76
- if ($path[$l - 1] === "/") {
77
- return "must not end with \"/\"";
78
- }
79
-
80
- // TODO: More checks.
81
-
82
- return null;
83
- }
84
-
85
- /**
86
- * If the given path is a valid non-root Dropbox path, return <code>null</code>,
87
- * otherwise return an English string error message describing what is wrong with the path.
88
- * This is the same as {@link findError} except <code>"/"</code> will yield an error message.
89
- *
90
- * @param string $path
91
- * The path you want to check for validity.
92
- *
93
- * @return string|null
94
- * If the path was valid, return <code>null</code>. Otherwise, returns
95
- * an English string describing the problem.
96
- */
97
- public static function findErrorNonRoot($path)
98
- {
99
- if ($path == "/") {
100
- return "root path not allowed";
101
- }
102
-
103
- return self::findError($path);
104
- }
105
-
106
- /**
107
- * Return the last component of a path (the file or folder name).
108
- *
109
- * <code>
110
- * Path::getName("/Misc/Notes.txt") // "Notes.txt"
111
- * Path::getName("/Misc") // "Misc"
112
- * Path::getName("/") // null
113
- * </code>
114
- *
115
- * @param string $path
116
- * The full path you want to get the last component of.
117
- *
118
- * @return null|string
119
- * The last component of <code>$path</code> or <code>null</code> if the given
120
- * <code>$path</code> was <code>"/"<code>.
121
- */
122
- public static function getName($path)
123
- {
124
- Dropbox_Checker::argString("path", $path);
125
-
126
- if (substr_compare($path, "/", 0, 1) !== 0) {
127
- throw new InvalidArgumentException("'path' must start with \"/\"");
128
- }
129
- $l = strlen($path);
130
- if ($l === 1) {
131
- return null;
132
- }
133
- if ($path[$l - 1] === "/") {
134
- throw new InvalidArgumentException("'path' must not end with \"/\"");
135
- }
136
-
137
- $lastSlash = strrpos($path, "/");
138
-
139
- return substr($path, $lastSlash + 1);
140
- }
141
-
142
- /**
143
- * @internal
144
- *
145
- * @param string $argName
146
- * @param mixed $value
147
- *
148
- * @throws InvalidArgumentException
149
- */
150
- public static function checkArg($argName, $value)
151
- {
152
- if ($value === null) {
153
- throw new InvalidArgumentException("'$argName' must not be null");
154
- }
155
- if (!is_string($value)) {
156
- throw new InvalidArgumentException("'$argName' must be a string");
157
- }
158
- $error = self::findError($value);
159
- if ($error !== null) {
160
- throw new InvalidArgumentException("'$argName'': bad path: $error: ".var_export($value, true));
161
- }
162
- }
163
-
164
- /**
165
- * @internal
166
- *
167
- * @param string $argName
168
- * @param mixed $value
169
- *
170
- * @throws InvalidArgumentException
171
- */
172
- public static function checkArgOrNull($argName, $value)
173
- {
174
- if ($value === null) {
175
- return;
176
- }
177
- self::checkArg($argName, $value);
178
- }
179
-
180
- /**
181
- * @internal
182
- *
183
- * @param string $argName
184
- * @param mixed $value
185
- *
186
- * @throws InvalidArgumentException
187
- */
188
- public static function checkArgNonRoot($argName, $value)
189
- {
190
- if ($value === null) {
191
- throw new InvalidArgumentException("'$argName' must not be null");
192
- }
193
- if (!is_string($value)) {
194
- throw new InvalidArgumentException("'$argName' must be a string");
195
- }
196
- $error = self::findErrorNonRoot($value);
197
- if ($error !== null) {
198
- throw new InvalidArgumentException("'$argName'': bad path: $error: ".var_export($value, true));
199
- }
200
- }
201
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Dropbox/RequestUtil.php DELETED
@@ -1,308 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * @internal
5
- */
6
- final class Dropbox_RequestUtil
7
- {
8
- /**
9
- * @param string $userLocale
10
- * @param string $host
11
- * @param string $path
12
- * @param array $params
13
- *
14
- * @return string
15
- */
16
- public static function buildUrlForGetOrPut($userLocale, $host, $path, $params = null)
17
- {
18
- $url = self::buildUri($host, $path);
19
- $url .= "?locale=".rawurlencode($userLocale);
20
-
21
- if ($params !== null) {
22
- foreach ($params as $key => $value) {
23
- Dropbox_Checker::argStringNonEmpty("key in 'params'", $key);
24
- if ($value !== null) {
25
- if (is_bool($value)) {
26
- $value = $value ? "true" : "false";
27
- } elseif (is_int($value)) {
28
- $value = (string) $value;
29
- } elseif (!is_string($value)) {
30
- throw new InvalidArgumentException("params['$key'] is not a string, int, or bool");
31
- }
32
- $url .= "&".rawurlencode($key)."=".rawurlencode($value);
33
- }
34
- }
35
- }
36
-
37
- return $url;
38
- }
39
-
40
- /**
41
- * @param string $host
42
- * @param string $path
43
- *
44
- * @return string
45
- */
46
- public static function buildUri($host, $path)
47
- {
48
- Dropbox_Checker::argStringNonEmpty("host", $host);
49
- Dropbox_Checker::argStringNonEmpty("path", $path);
50
-
51
- return "https://".$host."/".$path;
52
- }
53
-
54
- /**
55
- * @param string $clientIdentifier
56
- * @param string $url
57
- *
58
- * @return Dropbox_Curl
59
- */
60
- public static function mkCurl($clientIdentifier, $url)
61
- {
62
- $curl = new Dropbox_Curl($url);
63
-
64
- $curl->set(CURLOPT_CONNECTTIMEOUT, 10);
65
-
66
- // If the transfer speed is below 1kB/sec for 10 sec, abort.
67
- $curl->set(CURLOPT_LOW_SPEED_LIMIT, 1024);
68
- $curl->set(CURLOPT_LOW_SPEED_TIME, 10);
69
-
70
- //$curl->set(CURLOPT_VERBOSE, true); // For debugging.
71
- // TODO: Figure out how to encode clientIdentifier (urlencode?)
72
- $curl->addHeader("User-Agent: ".$clientIdentifier." Dropbox-PHP-SDK");
73
-
74
- return $curl;
75
- }
76
-
77
- /**
78
- * @param string $clientIdentifier
79
- * @param string $url
80
- * @param string $authHeaderValue
81
- *
82
- * @return Dropbox_Curl
83
- */
84
- public static function mkCurlWithAuth($clientIdentifier, $url, $authHeaderValue)
85
- {
86
- $curl = self::mkCurl($clientIdentifier, $url);
87
- $curl->addHeader("Authorization: $authHeaderValue");
88
-
89
- return $curl;
90
- }
91
-
92
- /**
93
- * @param string $clientIdentifier
94
- * @param string $url
95
- * @param string $accessToken
96
- *
97
- * @return Dropbox_Curl
98
- */
99
- public static function mkCurlWithOAuth($clientIdentifier, $url, $accessToken)
100
- {
101
- return self::mkCurlWithAuth($clientIdentifier, $url, $accessToken);
102
- }
103
-
104
- public static function buildPostBody($params)
105
- {
106
- if ($params === null) {
107
- return "";
108
- }
109
-
110
- $pairs = array();
111
- foreach ($params as $key => $value) {
112
- Dropbox_Checker::argStringNonEmpty("key in 'params'", $key);
113
- if ($value !== null) {
114
- if (is_bool($value)) {
115
- $value = $value ? "true" : "false";
116
- } elseif (is_int($value)) {
117
- $value = (string) $value;
118
- } elseif (!is_string($value)) {
119
- throw new InvalidArgumentException("params['$key'] is not a string, int, or bool");
120
- }
121
- $pairs[] = rawurlencode($key)."=".rawurlencode((string) $value);
122
- }
123
- }
124
-
125
- return implode("&", $pairs);
126
- }
127
-
128
- /**
129
- * @param string $clientIdentifier
130
- * @param string $accessToken
131
- * @param string $userLocale
132
- * @param string $host
133
- * @param string $path
134
- * @param array|null $params
135
- *
136
- * @return Dropbox_HttpResponse
137
- *
138
- * @throws Dropbox_Exception
139
- */
140
- public static function doPost($clientIdentifier, $accessToken, $userLocale, $host, $path, $params = null)
141
- {
142
- Dropbox_Checker::argStringNonEmpty("accessToken", $accessToken);
143
-
144
- $url = self::buildUri($host, $path);
145
-
146
- if ($params === null) {
147
- $params = array();
148
- }
149
- $params['locale'] = $userLocale;
150
-
151
- $curl = self::mkCurlWithOAuth($clientIdentifier, $url, $accessToken);
152
- $curl->set(CURLOPT_POST, true);
153
- $curl->set(CURLOPT_POSTFIELDS, self::buildPostBody($params));
154
-
155
- $curl->set(CURLOPT_RETURNTRANSFER, true);
156
-
157
- return $curl->exec();
158
- }
159
-
160
- /**
161
- * @param string $clientIdentifier
162
- * @param string $authHeaderValue
163
- * @param string $userLocale
164
- * @param string $host
165
- * @param string $path
166
- * @param array|null $params
167
- *
168
- * @return Dropbox_HttpResponse
169
- *
170
- * @throws Dropbox_Exception
171
- */
172
- public static function doPostWithSpecificAuth($clientIdentifier, $authHeaderValue, $userLocale, $host, $path, $params = null)
173
- {
174
- Dropbox_Checker::argStringNonEmpty("authHeaderValue", $authHeaderValue);
175
-
176
- $url = self::buildUri($host, $path);
177
-
178
- if ($params === null) {
179
- $params = array();
180
- }
181
- $params['locale'] = $userLocale;
182
-
183
- $curl = self::mkCurlWithAuth($clientIdentifier, $url, $authHeaderValue);
184
- $curl->set(CURLOPT_POST, true);
185
- $curl->set(CURLOPT_POSTFIELDS, self::buildPostBody($params));
186
-
187
- $curl->set(CURLOPT_RETURNTRANSFER, true);
188
-
189
- return $curl->exec();
190
- }
191
-
192
- /**
193
- * @param string $clientIdentifier
194
- * @param string $accessToken
195
- * @param string $userLocale
196
- * @param string $host
197
- * @param string $path
198
- * @param array|null $params
199
- *
200
- * @return Dropbox_HttpResponse
201
- *
202
- * @throws Dropbox_Exception
203
- */
204
- public static function doGet($clientIdentifier, $accessToken, $userLocale, $host, $path, $params = null)
205
- {
206
- Dropbox_Checker::argStringNonEmpty("accessToken", $accessToken);
207
-
208
- $url = self::buildUrlForGetOrPut($userLocale, $host, $path, $params);
209
-
210
- $curl = self::mkCurlWithOAuth($clientIdentifier, $url, $accessToken);
211
- $curl->set(CURLOPT_HTTPGET, true);
212
- $curl->set(CURLOPT_RETURNTRANSFER, true);
213
-
214
- return $curl->exec();
215
- }
216
-
217
- /**
218
- * @param string $responseBody
219
- *
220
- * @return mixed
221
- * @throws Dropbox_Exception_BadResponse
222
- */
223
- public static function parseResponseJson($responseBody)
224
- {
225
- $obj = json_decode($responseBody, true);
226
- if ($obj === null) {
227
- throw new Dropbox_Exception_BadResponse("Got bad JSON from server: $responseBody");
228
- }
229
-
230
- return $obj;
231
- }
232
-
233
- /**
234
- * @param Dropbox_HttpResponse $httpResponse
235
- *
236
- * @return Dropbox_Exception
237
- */
238
- public static function unexpectedStatus($httpResponse)
239
- {
240
- $sc = $httpResponse->statusCode;
241
-
242
- $message = "HTTP status $sc";
243
- if (is_string($httpResponse->body)) {
244
- if (($info = json_decode($httpResponse->body, true)) && isset($info['error'])) {
245
- $message .= ' '.$info['error'];
246
- } else {
247
- $message .= "\n".$httpResponse->body;
248
- }
249
- }
250
-
251
- if ($sc === 400) {
252
- return new Dropbox_Exception_BadRequest($message);
253
- }
254
- if ($sc === 401) {
255
- return new Dropbox_Exception_InvalidAccessToken($message);
256
- }
257
- if ($sc === 500 || $sc === 502) {
258
- return new Dropbox_Exception_ServerError($message);
259
- }
260
- if ($sc === 503) {
261
- return new Dropbox_Exception_RetryLater($message);
262
- }
263
-
264
- return new Dropbox_Exception_BadResponseCode("Unexpected $message", $sc);
265
- }
266
-
267
- /**
268
- * @param int $maxRetries
269
- * The number of times to retry it the action if it fails with one of the transient
270
- * API errors. A value of 1 means we'll try the action once and if it fails, we
271
- * will retry once.
272
- *
273
- * @param callable $action
274
- * The the action you want to retry.
275
- *
276
- * @return mixed
277
- * Whatever is returned by the $action callable.
278
- */
279
- public static function runWithRetry($maxRetries, Dropbox_Closure_ReRunnableActionInterface $action)
280
- {
281
- Dropbox_Checker::argNat("maxRetries", $maxRetries);
282
-
283
- $retryDelay = 1;
284
- $numRetries = 0;
285
- while (true) {
286
- try {
287
- return $action->run();
288
- } // These exception types are the ones we think are possibly transient errors.
289
- catch (Dropbox_Exception_NetworkIO $ex) {
290
- $savedEx = $ex;
291
- } catch (Dropbox_Exception_ServerError $ex) {
292
- $savedEx = $ex;
293
- } catch (Dropbox_Exception_RetryLater $ex) {
294
- $savedEx = $ex;
295
- }
296
-
297
- // We maxed out our retries. Propagate the last exception we got.
298
- if ($numRetries >= $maxRetries) {
299
- throw $savedEx;
300
- }
301
-
302
- $numRetries++;
303
- sleep($retryDelay);
304
- $retryDelay *= 2; // Exponential back-off.
305
- }
306
- throw new RuntimeException("unreachable");
307
- }
308
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Dropbox/SSLTester.php DELETED
@@ -1,112 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * Peforms a few basic checks of your PHP installation's SSL implementation to see
5
- * if it insecure in an obvious way.
6
- */
7
- class Dropbox_SSLTester
8
- {
9
- public static function test()
10
- {
11
- echo "Testing your PHP installation's SSL implementation for a few obvious problems...\n";
12
-
13
- echo "-----------------------------------------------------------------------------\n";
14
- echo "Basic SSL tests\n";
15
- $basicFailures = self::testMulti(array(
16
- array("www.dropbox.com", 'testAllowed'),
17
- array("www.digicert.com", 'testAllowed'),
18
- array("www.v.dropbox.com", 'testHostnameMismatch'),
19
- array("testssl-expire.disig.sk", 'testUntrustedCert'),
20
- ));
21
-
22
- echo "Pinned certificate tests\n";
23
- $pinnedCertFailures = self::testMulti(array(
24
- array("www.verisign.com", 'testUntrustedCert'),
25
- array("www.globalsign.fr", 'testUntrustedCert'),
26
- ));
27
-
28
- if ($basicFailures) {
29
- echo "-----------------------------------------------------------------------------\n";
30
- echo "WARNING: Your PHP installation's SSL support is COMPLETELY INSECURE.\n";
31
- echo "Your app's communication with the Dropbox API servers can be viewed and\n";
32
- echo "manipulated by others. Try upgrading your version of PHP.\n";
33
- echo "-----------------------------------------------------------------------------\n";
34
-
35
- return false;
36
- } elseif ($pinnedCertFailures) {
37
- echo "-----------------------------------------------------------------------------\n";
38
- echo "WARNING: Your PHP installation's SSL implementation doesn't support\n";
39
- echo "certificate pinning, which is an important security feature of the Dropbox\n";
40
- echo "SDK. The root certificates embedded in the SDK are being silently ignored,\n";
41
- echo "which reduces the security of the communication with the Dropbox API servers.\n";
42
- echo "\n";
43
- echo "More information:\n";
44
- echo "https://www.owasp.org/index.php/Certificate_and_Public_Key_Pinning#What_Is_Pinning.3F\n";
45
- echo "-----------------------------------------------------------------------------\n";
46
-
47
- return false;
48
- } else {
49
- return true;
50
- }
51
- }
52
-
53
- public static function testMulti($tests)
54
- {
55
- $anyFailed = false;
56
- foreach ($tests as $test) {
57
- list($host, $testType) = $test;
58
-
59
- echo " - ".str_pad("$testType ($host) ", 50, ".");
60
- $url = "https://$host/";
61
- $passed = self::$testType($url);
62
- if ($passed) {
63
- echo " ok\n";
64
- } else {
65
- echo " FAILED\n";
66
- $anyFailed = true;
67
- }
68
- }
69
-
70
- return $anyFailed;
71
- }
72
-
73
- public static function testPinnedCert()
74
- {
75
- }
76
-
77
- public static function testAllowed($url)
78
- {
79
- $curl = Dropbox_RequestUtil::mkCurl("test-ssl", $url);
80
- $curl->set(CURLOPT_RETURNTRANSFER, true);
81
- $curl->exec();
82
-
83
- return true;
84
- }
85
-
86
- public static function testUntrustedCert($url)
87
- {
88
- return self::testDisallowed($url, 'Error executing HTTP request: SSL certificate problem, verify that the CA cert is OK');
89
- }
90
-
91
- public static function testHostnameMismatch($url)
92
- {
93
- return self::testDisallowed($url, 'Error executing HTTP request: SSL certificate problem: Invalid certificate chain');
94
- }
95
-
96
- public static function testDisallowed($url, $expectedExceptionMessage)
97
- {
98
- $curl = Dropbox_RequestUtil::mkCurl("test-ssl", $url);
99
- $curl->set(CURLOPT_RETURNTRANSFER, true);
100
- try {
101
- $curl->exec();
102
- } catch (Dropbox_Exception_NetworkIO $ex) {
103
- if (strpos($ex->getMessage(), $expectedExceptionMessage) == 0) {
104
- return true;
105
- } else {
106
- throw $ex;
107
- }
108
- }
109
-
110
- return false;
111
- }
112
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Dropbox/Security.php DELETED
@@ -1,71 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * Helper functions for security-related things.
5
- */
6
- class Dropbox_Security
7
- {
8
- /**
9
- * A string equality function that compares strings in a way that isn't suceptible to timing
10
- * attacks. An attacker can figure out the length of the string, but not the string's value.
11
- *
12
- * Use this when comparing two strings where:
13
- * - one string could be influenced by an attacker
14
- * - the other string contains data an attacker shouldn't know
15
- *
16
- * @param string $a
17
- * @param string $b
18
- *
19
- * @return bool
20
- */
21
- public static function stringEquals($a, $b)
22
- {
23
- // Be strict with arguments. PHP's liberal types could get us pwned.
24
- if (func_num_args() !== 2) {
25
- throw new InvalidArgumentException("Expecting 2 args, got ".func_num_args().".");
26
- }
27
- Dropbox_Checker::argString("a", $a);
28
- Dropbox_Checker::argString("b", $b);
29
-
30
- if (strlen($a) !== strlen($b)) {
31
- return false;
32
- }
33
- $result = 0;
34
- for ($i = 0; $i < strlen($a); $i++) {
35
- $result |= ord($a[$i]) ^ ord($b[$i]);
36
- }
37
-
38
- return $result === 0;
39
- }
40
-
41
- /**
42
- * Returns cryptographically strong secure random bytes (as a PHP string).
43
- *
44
- * @param int $numBytes
45
- * The number of bytes of random data to return.
46
- *
47
- * @return string
48
- */
49
- public static function getRandomBytes($numBytes)
50
- {
51
- Dropbox_Checker::argIntPositive("numBytes", $numBytes);
52
-
53
- // openssl_random_pseudo_bytes had some issues prior to PHP 5.3.4
54
- if (function_exists('openssl_random_pseudo_bytes')
55
- && version_compare(PHP_VERSION, '5.3.4') >= 0
56
- ) {
57
- $s = openssl_random_pseudo_bytes($numBytes, $isCryptoStrong);
58
- if ($isCryptoStrong) {
59
- return $s;
60
- }
61
- }
62
-
63
- if (function_exists('mcrypt_create_iv')) {
64
- return mcrypt_create_iv($numBytes);
65
- }
66
-
67
- // Hopefully the above two options cover all our users. But if not, there are
68
- // other platform-specific options we could add.
69
- throw new Exception("no suitable random number source available");
70
- }
71
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Dropbox/StreamReadException.php DELETED
@@ -1,15 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * Thrown when there's an error reading from a stream that was passed in by the caller.
5
- */
6
- class Dropbox_StreamReadException extends Dropbox_Exception
7
- {
8
- /**
9
- * @internal
10
- */
11
- public function __construct($message, $cause = null)
12
- {
13
- parent::__construct($message, 0, $cause);
14
- }
15
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Dropbox/ValueStore.php DELETED
@@ -1,60 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * A contract for a class which provides simple get/set/clear access to a single string
5
- * value. {@link ArrayEntryStore} provides an implementation of this for storing a value
6
- * in a single array element.
7
- *
8
- * Example implementation for a Memcache-based backing store:
9
- *
10
- * <code>
11
- * class MemcacheValueStore implements ValueStore
12
- * {
13
- * private $key;
14
- * private $memcache;
15
- *
16
- * function __construct($memcache, $key)
17
- * {
18
- * $this->memcache = $memcache;
19
- * $this->key = $key;
20
- * }
21
- *
22
- * function get()
23
- * {
24
- * $value = $this->memcache->get($this->getKey());
25
- * return $value === false ? null : base64_decode($value);
26
- * }
27
- *
28
- * function set($value)
29
- * {
30
- * $this->memcache->set($this->key, base64_encode($value));
31
- * }
32
- *
33
- * function clear()
34
- * {
35
- * $this->memcache->delete($this->key);
36
- * }
37
- * }
38
- * </code>
39
- */
40
- interface Dropbox_ValueStore
41
- {
42
- /**
43
- * Returns the entry's current value or <code>null</code> if nothing is set.
44
- *
45
- * @return string
46
- */
47
- public function get();
48
-
49
- /**
50
- * Set the entry to the given value.
51
- *
52
- * @param string $value
53
- */
54
- public function set($value);
55
-
56
- /**
57
- * Remove the value.
58
- */
59
- public function clear();
60
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Dropbox/WebAuth.php DELETED
@@ -1,281 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * OAuth 2 "authorization code" flow. (This SDK does not support the "token" flow.)
5
- *
6
- * Use {@link WebAuth::start()} and {@link WebAuth::finish()} to guide your
7
- * user through the process of giving your app access to their Dropbox account.
8
- * At the end, you will have an access token, which you can pass to {@link Client}
9
- * and start making API calls.
10
- *
11
- * Example:
12
- *
13
- * <code>
14
- * use \Dropbox as dbx;
15
- *
16
- * function getWebAuth()
17
- * {
18
- * $appInfo = dbx\AppInfo::loadFromJsonFile(...);
19
- * $clientIdentifier = "my-app/1.0";
20
- * $redirectUri = "https://example.org/dropbox-auth-finish";
21
- * $csrfTokenStore = new dbx\ArrayEntryStore($_SESSION, 'dropbox-auth-csrf-token');
22
- * return new dbx\WebAuth($appInfo, $clientIdentifier, $redirectUri, $csrfTokenStore, ...);
23
- * }
24
- *
25
- * // ----------------------------------------------------------
26
- * // In the URL handler for "/dropbox-auth-start"
27
- *
28
- * $authorizeUrl = getWebAuth()->start();
29
- * header("Location: $authorizeUrl");
30
- *
31
- * // ----------------------------------------------------------
32
- * // In the URL handler for "/dropbox-auth-finish"
33
- *
34
- * try {
35
- * list($accessToken, $userId, $urlState) = getWebAuth()->finish($_GET);
36
- * assert($urlState === null); // Since we didn't pass anything in start()
37
- * }
38
- * catch (dbx\WebAuthException_BadRequest $ex) {
39
- * error_log("/dropbox-auth-finish: bad request: " . $ex->getMessage());
40
- * // Respond with an HTTP 400 and display error page...
41
- * }
42
- * catch (dbx\WebAuthException_BadState $ex) {
43
- * // Auth session expired. Restart the auth process.
44
- * header('Location: /dropbox-auth-start');
45
- * }
46
- * catch (dbx\WebAuthException_Csrf $ex) {
47
- * error_log("/dropbox-auth-finish: CSRF mismatch: " . $ex->getMessage());
48
- * // Respond with HTTP 403 and display error page...
49
- * }
50
- * catch (dbx\WebAuthException_NotApproved $ex) {
51
- * error_log("/dropbox-auth-finish: not approved: " . $ex->getMessage());
52
- * }
53
- * catch (dbx\WebAuthException_Provider $ex) {
54
- * error_log("/dropbox-auth-finish: error redirect from Dropbox: " . $ex->getMessage());
55
- * }
56
- * catch (dbx\Exception $ex) {
57
- * error_log("/dropbox-auth-finish: error communicating with Dropbox API: " . $ex->getMessage());
58
- * }
59
- *
60
- * // We can now use $accessToken to make API requests.
61
- * $client = dbx\Client($accessToken, ...);
62
- * </code>
63
- *
64
- */
65
- class Dropbox_WebAuth extends Dropbox_WebAuthBase
66
- {
67
- /**
68
- * The URI that the Dropbox server will redirect the user to after the user finishes
69
- * authorizing your app. This URI must be HTTPS-based and
70
- * <a href="https://www.dropbox.com/developers/apps">pre-registered with Dropbox</a>,
71
- * though "localhost"-based and "127.0.0.1"-based URIs are allowed without pre-registration
72
- * and can be either HTTP or HTTPS.
73
- *
74
- * @return string
75
- */
76
- public function getRedirectUri()
77
- {
78
- return $this->redirectUri;
79
- }
80
-
81
- /** @var string */
82
- private $redirectUri;
83
-
84
- /**
85
- * A object that lets us save CSRF token string to the user's session. If you're using the
86
- * standard PHP <code>$_SESSION</code>, you can pass in something like
87
- * <code>new ArrayEntryStore($_SESSION, 'dropbox-auth-csrf-token')</code>.
88
- *
89
- * If you're not using $_SESSION, you might have to create your own class that provides
90
- * the same <code>get()</code>/<code>set()</code>/<code>clear()</code> methods as
91
- * {@link ArrayEntryStore}.
92
- *
93
- * @return Dropbox_ValueStore
94
- */
95
- public function getCsrfTokenStore()
96
- {
97
- return $this->csrfTokenStore;
98
- }
99
-
100
- /** @var object */
101
- private $csrfTokenStore;
102
-
103
- /**
104
- * Constructor.
105
- *
106
- * @param Dropbox_AppInfo $appInfo
107
- * See {@link getAppInfo()}
108
- * @param string $clientIdentifier
109
- * See {@link getClientIdentifier()}
110
- * @param null|string $redirectUri
111
- * See {@link getRedirectUri()}
112
- * @param null|Dropbox_ValueStore $csrfTokenStore
113
- * See {@link getCsrfTokenStore()}
114
- * @param null|string $userLocale
115
- * See {@link getUserLocale()}
116
- */
117
- public function __construct($appInfo, $clientIdentifier, $redirectUri, $csrfTokenStore, $userLocale = null)
118
- {
119
- parent::__construct($appInfo, $clientIdentifier, $userLocale);
120
-
121
- Dropbox_Checker::argStringNonEmpty("redirectUri", $redirectUri);
122
-
123
- $this->csrfTokenStore = $csrfTokenStore;
124
- $this->redirectUri = $redirectUri;
125
- }
126
-
127
- /**
128
- * Starts the OAuth 2 authorization process, which involves redirecting the user to the
129
- * returned authorization URL (a URL on the Dropbox website). When the user then
130
- * either approves or denies your app access, Dropbox will redirect them to the
131
- * <code>$redirectUri</code> given to constructor, at which point you should
132
- * call {@link finish()} to complete the authorization process.
133
- *
134
- * This function will also save a CSRF token using the <code>$csrfTokenStore</code> given to
135
- * the constructor. This CSRF token will be checked on {@link finish()} to prevent
136
- * request forgery.
137
- *
138
- * See <a href="https://www.dropbox.com/developers/core/docs#oa2-authorize">/oauth2/authorize</a>.
139
- *
140
- * @param string|null $urlState
141
- * Any data you would like to keep in the URL through the authorization process.
142
- * This exact state will be returned to you by {@link finish()}.
143
- *
144
- * @return array
145
- * The URL to redirect the user to.
146
- *
147
- * @throws Dropbox_Exception
148
- */
149
- public function start($urlState = null)
150
- {
151
- Dropbox_Checker::argStringOrNull("urlState", $urlState);
152
-
153
- $csrfToken = self::encodeCsrfToken(Dropbox_Security::getRandomBytes(16));
154
- $state = $csrfToken;
155
- if ($urlState !== null) {
156
- $state .= "|";
157
- $state .= $urlState;
158
- }
159
- $this->csrfTokenStore->set($csrfToken);
160
-
161
- return $this->_getAuthorizeUrl($this->redirectUri, $state);
162
- }
163
-
164
- private static function encodeCsrfToken($string)
165
- {
166
- return strtr(base64_encode($string), '+/', '-_');
167
- }
168
-
169
- /**
170
- * Call this after the user has visited the authorize URL ({@link start()}), approved your app,
171
- * and was redirected to your redirect URI.
172
- *
173
- * See <a href="https://www.dropbox.com/developers/core/docs#oa2-token">/oauth2/token</a>.
174
- *
175
- * @param array $queryParams
176
- * The query parameters on the GET request to your redirect URI.
177
- *
178
- * @return array
179
- * A <code>list(string $accessToken, string $userId, string $urlState)</code>, where
180
- * <code>$accessToken</code> can be used to construct a {@link Client}, <code>$userId</code>
181
- * is the user ID of the user's Dropbox account, and <code>$urlState</code> is the
182
- * value you originally passed in to {@link start()}.
183
- *
184
- * @throws Dropbox_Exception
185
- * Thrown if there's an error getting the access token from Dropbox.
186
- * @throws Dropbox_WebAuthException_BadRequest
187
- * @throws Dropbox_WebAuthException_BadState
188
- * @throws Dropbox_WebAuthException_Csrf
189
- * @throws Dropbox_WebAuthException_NotApproved
190
- * @throws Dropbox_WebAuthException_Provider
191
- *
192
- *
193
- */
194
- public function finish($queryParams)
195
- {
196
- Dropbox_Checker::argArray("queryParams", $queryParams);
197
-
198
- $csrfTokenFromSession = $this->csrfTokenStore->get();
199
- Dropbox_Checker::argStringOrNull("this->csrfTokenStore->get()", $csrfTokenFromSession);
200
-
201
- // Check well-formedness of request.
202
-
203
- if (!isset($queryParams['state'])) {
204
- throw new Dropbox_WebAuthException_BadRequest("Missing query parameter 'state'.");
205
- }
206
- $state = $queryParams['state'];
207
- Dropbox_Checker::argString("queryParams['state']", $state);
208
-
209
- $error = null;
210
- $errorDescription = null;
211
- if (isset($queryParams['error'])) {
212
- $error = $queryParams['error'];
213
- Dropbox_Checker::argString("queryParams['error']", $error);
214
- if (isset($queryParams['error_description'])) {
215
- $errorDescription = $queryParams['error_description'];
216
- Dropbox_Checker::argString("queryParams['error_description']", $errorDescription);
217
- }
218
- }
219
-
220
- $code = null;
221
- if (isset($queryParams['code'])) {
222
- $code = $queryParams['code'];
223
- Dropbox_Checker::argString("queryParams['code']", $code);
224
- }
225
-
226
- if ($code !== null && $error !== null) {
227
- throw new Dropbox_WebAuthException_BadRequest("Query parameters 'code' and 'error' are both set;".
228
- " only one must be set.");
229
- }
230
- if ($code === null && $error === null) {
231
- throw new Dropbox_WebAuthException_BadRequest("Neither query parameter 'code' or 'error' is set.");
232
- }
233
-
234
- // Check CSRF token
235
-
236
- if ($csrfTokenFromSession === null) {
237
- throw new Dropbox_WebAuthException_BadState();
238
- }
239
-
240
- $splitPos = strpos($state, "|");
241
- if ($splitPos === false) {
242
- $givenCsrfToken = $state;
243
- $urlState = null;
244
- } else {
245
- $givenCsrfToken = substr($state, 0, $splitPos);
246
- $urlState = substr($state, $splitPos + 1);
247
- }
248
- if (!Dropbox_Security::stringEquals($csrfTokenFromSession, $givenCsrfToken)) {
249
- throw new Dropbox_WebAuthException_Csrf("Expected ".Dropbox_Client::q($csrfTokenFromSession).
250
- ", got ".Dropbox_Client::q($givenCsrfToken).".");
251
- }
252
- $this->csrfTokenStore->clear();
253
-
254
- // Check for error identifier
255
-
256
- if ($error !== null) {
257
- if ($error === 'access_denied') {
258
- // When the user clicks "Deny".
259
- if ($errorDescription === null) {
260
- throw new Dropbox_WebAuthException_NotApproved("No additional description from Dropbox.");
261
- } else {
262
- throw new Dropbox_WebAuthException_NotApproved("Additional description from Dropbox: $errorDescription");
263
- }
264
- } else {
265
- // All other errors.
266
- $fullMessage = $error;
267
- if ($errorDescription !== null) {
268
- $fullMessage .= ": ";
269
- $fullMessage .= $errorDescription;
270
- }
271
- throw new Dropbox_WebAuthException_Provider($fullMessage);
272
- }
273
- }
274
-
275
- // If everything went ok, make the network call to get an access token.
276
-
277
- list($accessToken, $userId) = $this->_finish($code, $this->redirectUri);
278
-
279
- return array($accessToken, $userId, $urlState);
280
- }
281
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Dropbox/WebAuthBase.php DELETED
@@ -1,64 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * The base class for the two auth options.
5
- */
6
- class Dropbox_WebAuthBase extends Dropbox_AuthBase
7
- {
8
- protected function _getAuthorizeUrl($redirectUri, $state)
9
- {
10
- return Dropbox_RequestUtil::buildUrlForGetOrPut(
11
- $this->userLocale,
12
- $this->appInfo->getHost()->getWeb(),
13
- "1/oauth2/authorize",
14
- array(
15
- "client_id" => $this->appInfo->getKey(),
16
- "response_type" => "code",
17
- "redirect_uri" => $redirectUri,
18
- "state" => $state,
19
- ));
20
- }
21
-
22
- protected function _finish($code, $originalRedirectUri)
23
- {
24
- // This endpoint requires "Basic" auth.
25
- $clientCredentials = $this->appInfo->getKey().":".$this->appInfo->getSecret();
26
- $authHeaderValue = "Basic ".base64_encode($clientCredentials);
27
-
28
- $response = Dropbox_RequestUtil::doPostWithSpecificAuth(
29
- $this->clientIdentifier, $authHeaderValue, $this->userLocale,
30
- $this->appInfo->getHost()->getApi(),
31
- "1/oauth2/token",
32
- array(
33
- "grant_type" => "authorization_code",
34
- "code" => $code,
35
- "redirect_uri" => $originalRedirectUri,
36
- ));
37
-
38
- if ($response->statusCode !== 200) {
39
- throw Dropbox_RequestUtil::unexpectedStatus($response);
40
- }
41
-
42
- $parts = Dropbox_RequestUtil::parseResponseJson($response->body);
43
-
44
- if (!array_key_exists('token_type', $parts) or !is_string($parts['token_type'])) {
45
- throw new Dropbox_Exception_BadResponse("Missing \"token_type\" field.");
46
- }
47
- $tokenType = $parts['token_type'];
48
- if (!array_key_exists('access_token', $parts) or !is_string($parts['access_token'])) {
49
- throw new Dropbox_Exception_BadResponse("Missing \"access_token\" field.");
50
- }
51
- $accessToken = $parts['access_token'];
52
- if (!array_key_exists('uid', $parts) or !is_string($parts['uid'])) {
53
- throw new Dropbox_Exception_BadResponse("Missing \"uid\" string field.");
54
- }
55
- $userId = $parts['uid'];
56
-
57
- if ($tokenType !== "Bearer" && $tokenType !== "bearer") {
58
- throw new Dropbox_Exception_BadResponse("Unknown \"token_type\"; expecting \"Bearer\", got "
59
- .Dropbox_Client::q($tokenType));
60
- }
61
-
62
- return array($accessToken, $userId);
63
- }
64
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Dropbox/WebAuthException/BadRequest.php DELETED
@@ -1,19 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * Thrown if the redirect URL was missing parameters or if the given parameters were not valid.
5
- *
6
- * The recommended action is to show an HTTP 400 error page.
7
- */
8
- class Dropbox_WebAuthException_BadRequest extends Dropbox_Exception
9
- {
10
- /**
11
- * @param string $message
12
- *
13
- * @internal
14
- */
15
- public function __construct($message)
16
- {
17
- parent::__construct($message);
18
- }
19
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Dropbox/WebAuthException/BadState.php DELETED
@@ -1,18 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * Thrown if all the parameters are correct, but there's no CSRF token in the session. This
5
- * probably means that the session expired.
6
- *
7
- * The recommended action is to redirect the user's browser to try the approval process again.
8
- */
9
- class Dropbox_WebAuthException_BadState extends Dropbox_Exception
10
- {
11
- /**
12
- * @internal
13
- */
14
- public function __construct()
15
- {
16
- parent::__construct("Missing CSRF token in session.");
17
- }
18
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Dropbox/WebAuthException/Csrf.php DELETED
@@ -1,20 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * Thrown if the given 'state' parameter doesn't contain the CSRF token from the user's session.
5
- * This is blocked to prevent CSRF attacks.
6
- *
7
- * The recommended action is to respond with an HTTP 403 error page.
8
- */
9
- class Dropbox_WebAuthException_Csrf extends Dropbox_Exception
10
- {
11
- /**
12
- * @param string $message
13
- *
14
- * @internal
15
- */
16
- public function __construct($message)
17
- {
18
- parent::__construct($message);
19
- }
20
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Dropbox/WebAuthException/NotApproved.php DELETED
@@ -1,17 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * Thrown if the user chose not to grant your app access to their Dropbox account.
5
- */
6
- class Dropbox_WebAuthException_NotApproved extends Dropbox_Exception
7
- {
8
- /**
9
- * @param string $message
10
- *
11
- * @internal
12
- */
13
- public function __construct($message)
14
- {
15
- parent::__construct($message);
16
- }
17
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Dropbox/WebAuthException/Provider.php DELETED
@@ -1,17 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * Thrown if Dropbox returns some other error about the authorization request.
5
- */
6
- class Dropbox_WebAuthException_Provider extends Dropbox_Exception
7
- {
8
- /**
9
- * @param string $message
10
- *
11
- * @internal
12
- */
13
- public function __construct($message)
14
- {
15
- parent::__construct($message);
16
- }
17
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Dropbox/WebAuthNoRedirect.php DELETED
@@ -1,82 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * OAuth 2 code-based authorization for apps that can't provide a redirect URI, typically
5
- * command-line example apps.
6
- *
7
- * Use {@link WebAuth::start()} and {@link WebAuth::getToken()} to guide your
8
- * user through the process of giving your app access to their Dropbox account. At the end, you
9
- * will have an {@link AccessToken}, which you can pass to {@link Client} and start making
10
- * API calls.
11
- *
12
- * Example:
13
- *
14
- * <code>
15
- * use \Dropbox as dbx;
16
- * $appInfo = dbx\AppInfo::loadFromJsonFile(...);
17
- * $clientIdentifier = "my-app/1.0";
18
- * $webAuth = new dbx\WebAuthNoRedirect($appInfo, $clientIdentifier, ...);
19
- *
20
- * $authorizeUrl = $webAuth->start();
21
- *
22
- * print("1. Go to: $authorizeUrl\n");
23
- * print("2. Click "Allow" (you might have to log in first).\n");
24
- * print("3. Copy the authorization code.\n");
25
- * print("Enter the authorization code here: ");
26
- * $code = \trim(\fgets(STDIN));
27
- *
28
- * try {
29
- * list($accessToken, $userId) = $webAuth->finish($code);
30
- * }
31
- * catch (dbx\Exception $ex) {
32
- * print("Error communicating with Dropbox API: " . $ex->getMessage() . "\n");
33
- * }
34
- *
35
- * $client = dbx\Client($accessToken, $clientIdentifier, ...);
36
- * </code>
37
- */
38
- class Dropbox_WebAuthNoRedirect extends Dropbox_WebAuthBase
39
- {
40
- /**
41
- * Returns the URL of the authorization page the user must visit. If the user approves
42
- * your app, they will be shown the authorization code on the web page. They will need to
43
- * copy/paste that code into your application so your app can pass it to
44
- * {@link finish}.
45
- *
46
- * See <a href="https://www.dropbox.com/developers/core/docs#oa2-authorize">/oauth2/authorize</a>.
47
- *
48
- * @return string
49
- * An authorization URL. Direct the user's browser to this URL. After the user decides
50
- * whether to authorize your app or not, Dropbox will show the user an authorization code,
51
- * which the user will need to give to your application (e.g. via copy/paste).
52
- */
53
- public function start()
54
- {
55
- return $this->_getAuthorizeUrl(null, null);
56
- }
57
-
58
- /**
59
- * Call this after the user has visited the authorize URL returned by {@link start()},
60
- * approved your app, was presented with an authorization code by Dropbox, and has copy/paste'd
61
- * that authorization code into your app.
62
- *
63
- * See <a href="https://www.dropbox.com/developers/core/docs#oa2-token">/oauth2/token</a>.
64
- *
65
- * @param string $code
66
- * The authorization code provided to the user by Dropbox.
67
- *
68
- * @return array
69
- * A <code>list(string $accessToken, string $userId)</code>, where
70
- * <code>$accessToken</code> can be used to construct a {@link Client} and
71
- * <code>$userId</code> is the user ID of the user's Dropbox account.
72
- *
73
- * @throws Dropbox_Exception
74
- * Thrown if there's an error getting the access token from Dropbox.
75
- */
76
- public function finish($code)
77
- {
78
- Dropbox_Checker::argStringNonEmpty("code", $code);
79
-
80
- return $this->_finish($code, null);
81
- }
82
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Dropbox/WriteMode.php DELETED
@@ -1,126 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * Describes how a file should be saved when it is written to Dropbox.
5
- */
6
- final class Dropbox_WriteMode
7
- {
8
- /**
9
- * The URL parameters to pass to the file uploading endpoint to achieve the
10
- * desired write mode.
11
- *
12
- * @var array
13
- */
14
- private $extraParams;
15
-
16
- /**
17
- * @internal
18
- */
19
- private function __construct($extraParams)
20
- {
21
- $this->extraParams = $extraParams;
22
- }
23
-
24
- /**
25
- * @internal
26
- */
27
- public function getExtraParams()
28
- {
29
- return $this->extraParams;
30
- }
31
-
32
- /**
33
- * Returns a {@link WriteMode} for adding a new file. If a file at the specified path already
34
- * exists, the new file will be renamed automatically.
35
- *
36
- * For example, if you're trying to upload a file to "/Notes/Groceries.txt", but there's
37
- * already a file there, your file will be written to "/Notes/Groceries (1).txt".
38
- *
39
- * You can determine whether your file was renamed by checking the "path" field of the
40
- * metadata object returned by the API call.
41
- *
42
- * @return Dropbox_WriteMode
43
- */
44
- public static function add()
45
- {
46
- if (self::$addInstance === null) {
47
- self::$addInstance = new Dropbox_WriteMode(array("overwrite" => "false"));
48
- }
49
-
50
- return self::$addInstance;
51
- }
52
-
53
- private static $addInstance = null;
54
-
55
- /**
56
- * Returns a {@link WriteMode} for forcing a file to be at a certain path. If there's already
57
- * a file at that path, the existing file will be overwritten. If there's a folder at that
58
- * path, however, it will not be overwritten and the API call will fail.
59
- *
60
- * @return Dropbox_WriteMode
61
- */
62
- public static function force()
63
- {
64
- if (self::$forceInstance === null) {
65
- self::$forceInstance = new Dropbox_WriteMode(array("overwrite" => "true"));
66
- }
67
-
68
- return self::$forceInstance;
69
- }
70
-
71
- private static $forceInstance = null;
72
-
73
- /**
74
- * Returns a {@link WriteMode} for updating an existing file. This is useful for when you
75
- * have downloaded a file, made modifications, and want to save your modifications back to
76
- * Dropbox. You need to specify the revision of the copy of the file you downloaded (it's
77
- * the "rev" parameter of the file's metadata object).
78
- *
79
- * If, when you attempt to save, the revision of the file currently on Dropbox matches
80
- * $revToReplace, the file on Dropbox will be overwritten with the new contents you provide.
81
- *
82
- * If the revision of the file currently on Dropbox doesn't match $revToReplace, Dropbox will
83
- * create a new file and save your contents to that file. For example, if the original file
84
- * path is "/Notes/Groceries.txt", the new file's path might be
85
- * "/Notes/Groceries (conflicted copy).txt".
86
- *
87
- * You can determine whether your file was renamed by checking the "path" field of the
88
- * metadata object returned by the API call.
89
- *
90
- * @param string $revToReplace
91
- *
92
- * @return Dropbox_WriteMode
93
- */
94
- public static function update($revToReplace)
95
- {
96
- return new Dropbox_WriteMode(array("parent_rev" => $revToReplace));
97
- }
98
-
99
- /**
100
- * Check that a function argument is of type <code>WriteMode</code>.
101
- *
102
- * @internal
103
- */
104
- public static function checkArg($argName, $argValue)
105
- {
106
- if (!($argValue instanceof self)) {
107
- Dropbox_Checker::throwError($argName, $argValue, __CLASS__);
108
- }
109
- }
110
-
111
- /**
112
- * Check that a function argument is either <code>null</code> or of type
113
- * <code>WriteMode</code>.
114
- *
115
- * @internal
116
- */
117
- public static function checkArgOrNull($argName, $argValue)
118
- {
119
- if ($argValue === null) {
120
- return;
121
- }
122
- if (!($argValue instanceof self)) {
123
- Dropbox_Checker::throwError($argName, $argValue, __CLASS__);
124
- }
125
- }
126
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Dropbox/certs/trusted-certs.crt DELETED
@@ -1,1396 +0,0 @@
1
- # DigiCert Assured ID Root CA.pem
2
- # Certificate:
3
- # Data:
4
- # Version: 3 (0x2)
5
- # Serial Number:
6
- # 0c:e7:e0:e5:17:d8:46:fe:8f:e5:60:fc:1b:f0:30:39
7
- # Signature Algorithm: sha1WithRSAEncryption
8
- # Issuer: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert Assured ID Root CA
9
- # Validity
10
- # Not Before: Nov 10 00:00:00 2006 GMT
11
- # Not After : Nov 10 00:00:00 2031 GMT
12
- # Subject: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert Assured ID Root CA
13
- # Subject Public Key Info:
14
- # Public Key Algorithm: rsaEncryption
15
- # Public-Key: (2048 bit)
16
- # Modulus:
17
- # 00:ad:0e:15:ce:e4:43:80:5c:b1:87:f3:b7:60:f9:
18
- # 71:12:a5:ae:dc:26:94:88:aa:f4:ce:f5:20:39:28:
19
- # 58:60:0c:f8:80:da:a9:15:95:32:61:3c:b5:b1:28:
20
- # 84:8a:8a:dc:9f:0a:0c:83:17:7a:8f:90:ac:8a:e7:
21
- # 79:53:5c:31:84:2a:f6:0f:98:32:36:76:cc:de:dd:
22
- # 3c:a8:a2:ef:6a:fb:21:f2:52:61:df:9f:20:d7:1f:
23
- # e2:b1:d9:fe:18:64:d2:12:5b:5f:f9:58:18:35:bc:
24
- # 47:cd:a1:36:f9:6b:7f:d4:b0:38:3e:c1:1b:c3:8c:
25
- # 33:d9:d8:2f:18:fe:28:0f:b3:a7:83:d6:c3:6e:44:
26
- # c0:61:35:96:16:fe:59:9c:8b:76:6d:d7:f1:a2:4b:
27
- # 0d:2b:ff:0b:72:da:9e:60:d0:8e:90:35:c6:78:55:
28
- # 87:20:a1:cf:e5:6d:0a:c8:49:7c:31:98:33:6c:22:
29
- # e9:87:d0:32:5a:a2:ba:13:82:11:ed:39:17:9d:99:
30
- # 3a:72:a1:e6:fa:a4:d9:d5:17:31:75:ae:85:7d:22:
31
- # ae:3f:01:46:86:f6:28:79:c8:b1:da:e4:57:17:c4:
32
- # 7e:1c:0e:b0:b4:92:a6:56:b3:bd:b2:97:ed:aa:a7:
33
- # f0:b7:c5:a8:3f:95:16:d0:ff:a1:96:eb:08:5f:18:
34
- # 77:4f
35
- # Exponent: 65537 (0x10001)
36
- # X509v3 extensions:
37
- # X509v3 Key Usage: critical
38
- # Digital Signature, Certificate Sign, CRL Sign
39
- # X509v3 Basic Constraints: critical
40
- # CA:TRUE
41
- # X509v3 Subject Key Identifier:
42
- # 45:EB:A2:AF:F4:92:CB:82:31:2D:51:8B:A7:A7:21:9D:F3:6D:C8:0F
43
- # X509v3 Authority Key Identifier:
44
- # keyid:45:EB:A2:AF:F4:92:CB:82:31:2D:51:8B:A7:A7:21:9D:F3:6D:C8:0F
45
- #
46
- # Signature Algorithm: sha1WithRSAEncryption
47
- # a2:0e:bc:df:e2:ed:f0:e3:72:73:7a:64:94:bf:f7:72:66:d8:
48
- # 32:e4:42:75:62:ae:87:eb:f2:d5:d9:de:56:b3:9f:cc:ce:14:
49
- # 28:b9:0d:97:60:5c:12:4c:58:e4:d3:3d:83:49:45:58:97:35:
50
- # 69:1a:a8:47:ea:56:c6:79:ab:12:d8:67:81:84:df:7f:09:3c:
51
- # 94:e6:b8:26:2c:20:bd:3d:b3:28:89:f7:5f:ff:22:e2:97:84:
52
- # 1f:e9:65:ef:87:e0:df:c1:67:49:b3:5d:eb:b2:09:2a:eb:26:
53
- # ed:78:be:7d:3f:2b:f3:b7:26:35:6d:5f:89:01:b6:49:5b:9f:
54
- # 01:05:9b:ab:3d:25:c1:cc:b6:7f:c2:f1:6f:86:c6:fa:64:68:
55
- # eb:81:2d:94:eb:42:b7:fa:8c:1e:dd:62:f1:be:50:67:b7:6c:
56
- # bd:f3:f1:1f:6b:0c:36:07:16:7f:37:7c:a9:5b:6d:7a:f1:12:
57
- # 46:60:83:d7:27:04:be:4b:ce:97:be:c3:67:2a:68:11:df:80:
58
- # e7:0c:33:66:bf:13:0d:14:6e:f3:7f:1f:63:10:1e:fa:8d:1b:
59
- # 25:6d:6c:8f:a5:b7:61:01:b1:d2:a3:26:a1:10:71:9d:ad:e2:
60
- # c3:f9:c3:99:51:b7:2b:07:08:ce:2e:e6:50:b2:a7:fa:0a:45:
61
- # 2f:a2:f0:f2
62
- -----BEGIN CERTIFICATE-----
63
- MIIDtzCCAp+gAwIBAgIQDOfg5RfYRv6P5WD8G/AwOTANBgkqhkiG9w0BAQUFADBl
64
- MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
65
- d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv
66
- b3QgQ0EwHhcNMDYxMTEwMDAwMDAwWhcNMzExMTEwMDAwMDAwWjBlMQswCQYDVQQG
67
- EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl
68
- cnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0EwggEi
69
- MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtDhXO5EOAXLGH87dg+XESpa7c
70
- JpSIqvTO9SA5KFhgDPiA2qkVlTJhPLWxKISKityfCgyDF3qPkKyK53lTXDGEKvYP
71
- mDI2dsze3Tyoou9q+yHyUmHfnyDXH+Kx2f4YZNISW1/5WBg1vEfNoTb5a3/UsDg+
72
- wRvDjDPZ2C8Y/igPs6eD1sNuRMBhNZYW/lmci3Zt1/GiSw0r/wty2p5g0I6QNcZ4
73
- VYcgoc/lbQrISXwxmDNsIumH0DJaoroTghHtORedmTpyoeb6pNnVFzF1roV9Iq4/
74
- AUaG9ih5yLHa5FcXxH4cDrC0kqZWs72yl+2qp/C3xag/lRbQ/6GW6whfGHdPAgMB
75
- AAGjYzBhMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW
76
- BBRF66Kv9JLLgjEtUYunpyGd823IDzAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYun
77
- pyGd823IDzANBgkqhkiG9w0BAQUFAAOCAQEAog683+Lt8ONyc3pklL/3cmbYMuRC
78
- dWKuh+vy1dneVrOfzM4UKLkNl2BcEkxY5NM9g0lFWJc1aRqoR+pWxnmrEthngYTf
79
- fwk8lOa4JiwgvT2zKIn3X/8i4peEH+ll74fg38FnSbNd67IJKusm7Xi+fT8r87cm
80
- NW1fiQG2SVufAQWbqz0lwcy2f8Lxb4bG+mRo64EtlOtCt/qMHt1i8b5QZ7dsvfPx
81
- H2sMNgcWfzd8qVttevESRmCD1ycEvkvOl77DZypoEd+A5wwzZr8TDRRu838fYxAe
82
- +o0bJW1sj6W3YQGx0qMmoRBxna3iw/nDmVG3KwcIzi7mULKn+gpFL6Lw8g==
83
- -----END CERTIFICATE-----
84
- # DigiCert Global Root CA.pem
85
- # Certificate:
86
- # Data:
87
- # Version: 3 (0x2)
88
- # Serial Number:
89
- # 08:3b:e0:56:90:42:46:b1:a1:75:6a:c9:59:91:c7:4a
90
- # Signature Algorithm: sha1WithRSAEncryption
91
- # Issuer: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert Global Root CA
92
- # Validity
93
- # Not Before: Nov 10 00:00:00 2006 GMT
94
- # Not After : Nov 10 00:00:00 2031 GMT
95
- # Subject: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert Global Root CA
96
- # Subject Public Key Info:
97
- # Public Key Algorithm: rsaEncryption
98
- # Public-Key: (2048 bit)
99
- # Modulus:
100
- # 00:e2:3b:e1:11:72:de:a8:a4:d3:a3:57:aa:50:a2:
101
- # 8f:0b:77:90:c9:a2:a5:ee:12:ce:96:5b:01:09:20:
102
- # cc:01:93:a7:4e:30:b7:53:f7:43:c4:69:00:57:9d:
103
- # e2:8d:22:dd:87:06:40:00:81:09:ce:ce:1b:83:bf:
104
- # df:cd:3b:71:46:e2:d6:66:c7:05:b3:76:27:16:8f:
105
- # 7b:9e:1e:95:7d:ee:b7:48:a3:08:da:d6:af:7a:0c:
106
- # 39:06:65:7f:4a:5d:1f:bc:17:f8:ab:be:ee:28:d7:
107
- # 74:7f:7a:78:99:59:85:68:6e:5c:23:32:4b:bf:4e:
108
- # c0:e8:5a:6d:e3:70:bf:77:10:bf:fc:01:f6:85:d9:
109
- # a8:44:10:58:32:a9:75:18:d5:d1:a2:be:47:e2:27:
110
- # 6a:f4:9a:33:f8:49:08:60:8b:d4:5f:b4:3a:84:bf:
111
- # a1:aa:4a:4c:7d:3e:cf:4f:5f:6c:76:5e:a0:4b:37:
112
- # 91:9e:dc:22:e6:6d:ce:14:1a:8e:6a:cb:fe:cd:b3:
113
- # 14:64:17:c7:5b:29:9e:32:bf:f2:ee:fa:d3:0b:42:
114
- # d4:ab:b7:41:32:da:0c:d4:ef:f8:81:d5:bb:8d:58:
115
- # 3f:b5:1b:e8:49:28:a2:70:da:31:04:dd:f7:b2:16:
116
- # f2:4c:0a:4e:07:a8:ed:4a:3d:5e:b5:7f:a3:90:c3:
117
- # af:27
118
- # Exponent: 65537 (0x10001)
119
- # X509v3 extensions:
120
- # X509v3 Key Usage: critical
121
- # Digital Signature, Certificate Sign, CRL Sign
122
- # X509v3 Basic Constraints: critical
123
- # CA:TRUE
124
- # X509v3 Subject Key Identifier:
125
- # 03:DE:50:35:56:D1:4C:BB:66:F0:A3:E2:1B:1B:C3:97:B2:3D:D1:55
126
- # X509v3 Authority Key Identifier:
127
- # keyid:03:DE:50:35:56:D1:4C:BB:66:F0:A3:E2:1B:1B:C3:97:B2:3D:D1:55
128
- #
129
- # Signature Algorithm: sha1WithRSAEncryption
130
- # cb:9c:37:aa:48:13:12:0a:fa:dd:44:9c:4f:52:b0:f4:df:ae:
131
- # 04:f5:79:79:08:a3:24:18:fc:4b:2b:84:c0:2d:b9:d5:c7:fe:
132
- # f4:c1:1f:58:cb:b8:6d:9c:7a:74:e7:98:29:ab:11:b5:e3:70:
133
- # a0:a1:cd:4c:88:99:93:8c:91:70:e2:ab:0f:1c:be:93:a9:ff:
134
- # 63:d5:e4:07:60:d3:a3:bf:9d:5b:09:f1:d5:8e:e3:53:f4:8e:
135
- # 63:fa:3f:a7:db:b4:66:df:62:66:d6:d1:6e:41:8d:f2:2d:b5:
136
- # ea:77:4a:9f:9d:58:e2:2b:59:c0:40:23:ed:2d:28:82:45:3e:
137
- # 79:54:92:26:98:e0:80:48:a8:37:ef:f0:d6:79:60:16:de:ac:
138
- # e8:0e:cd:6e:ac:44:17:38:2f:49:da:e1:45:3e:2a:b9:36:53:
139
- # cf:3a:50:06:f7:2e:e8:c4:57:49:6c:61:21:18:d5:04:ad:78:
140
- # 3c:2c:3a:80:6b:a7:eb:af:15:14:e9:d8:89:c1:b9:38:6c:e2:
141
- # 91:6c:8a:ff:64:b9:77:25:57:30:c0:1b:24:a3:e1:dc:e9:df:
142
- # 47:7c:b5:b4:24:08:05:30:ec:2d:bd:0b:bf:45:bf:50:b9:a9:
143
- # f3:eb:98:01:12:ad:c8:88:c6:98:34:5f:8d:0a:3c:c6:e9:d5:
144
- # 95:95:6d:de
145
- -----BEGIN CERTIFICATE-----
146
- MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh
147
- MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
148
- d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD
149
- QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT
150
- MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j
151
- b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG
152
- 9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB
153
- CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97
154
- nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt
155
- 43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P
156
- T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4
157
- gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO
158
- BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR
159
- TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw
160
- DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr
161
- hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg
162
- 06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF
163
- PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls
164
- YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk
165
- CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4=
166
- -----END CERTIFICATE-----
167
- # DigiCert High Assurance EV Root CA.pem
168
- # Certificate:
169
- # Data:
170
- # Version: 3 (0x2)
171
- # Serial Number:
172
- # 02:ac:5c:26:6a:0b:40:9b:8f:0b:79:f2:ae:46:25:77
173
- # Signature Algorithm: sha1WithRSAEncryption
174
- # Issuer: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert High Assurance EV Root CA
175
- # Validity
176
- # Not Before: Nov 10 00:00:00 2006 GMT
177
- # Not After : Nov 10 00:00:00 2031 GMT
178
- # Subject: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert High Assurance EV Root CA
179
- # Subject Public Key Info:
180
- # Public Key Algorithm: rsaEncryption
181
- # Public-Key: (2048 bit)
182
- # Modulus:
183
- # 00:c6:cc:e5:73:e6:fb:d4:bb:e5:2d:2d:32:a6:df:
184
- # e5:81:3f:c9:cd:25:49:b6:71:2a:c3:d5:94:34:67:
185
- # a2:0a:1c:b0:5f:69:a6:40:b1:c4:b7:b2:8f:d0:98:
186
- # a4:a9:41:59:3a:d3:dc:94:d6:3c:db:74:38:a4:4a:
187
- # cc:4d:25:82:f7:4a:a5:53:12:38:ee:f3:49:6d:71:
188
- # 91:7e:63:b6:ab:a6:5f:c3:a4:84:f8:4f:62:51:be:
189
- # f8:c5:ec:db:38:92:e3:06:e5:08:91:0c:c4:28:41:
190
- # 55:fb:cb:5a:89:15:7e:71:e8:35:bf:4d:72:09:3d:
191
- # be:3a:38:50:5b:77:31:1b:8d:b3:c7:24:45:9a:a7:
192
- # ac:6d:00:14:5a:04:b7:ba:13:eb:51:0a:98:41:41:
193
- # 22:4e:65:61:87:81:41:50:a6:79:5c:89:de:19:4a:
194
- # 57:d5:2e:e6:5d:1c:53:2c:7e:98:cd:1a:06:16:a4:
195
- # 68:73:d0:34:04:13:5c:a1:71:d3:5a:7c:55:db:5e:
196
- # 64:e1:37:87:30:56:04:e5:11:b4:29:80:12:f1:79:
197
- # 39:88:a2:02:11:7c:27:66:b7:88:b7:78:f2:ca:0a:
198
- # a8:38:ab:0a:64:c2:bf:66:5d:95:84:c1:a1:25:1e:
199
- # 87:5d:1a:50:0b:20:12:cc:41:bb:6e:0b:51:38:b8:
200
- # 4b:cb
201
- # Exponent: 65537 (0x10001)
202
- # X509v3 extensions:
203
- # X509v3 Key Usage: critical
204
- # Digital Signature, Certificate Sign, CRL Sign
205
- # X509v3 Basic Constraints: critical
206
- # CA:TRUE
207
- # X509v3 Subject Key Identifier:
208
- # B1:3E:C3:69:03:F8:BF:47:01:D4:98:26:1A:08:02:EF:63:64:2B:C3
209
- # X509v3 Authority Key Identifier:
210
- # keyid:B1:3E:C3:69:03:F8:BF:47:01:D4:98:26:1A:08:02:EF:63:64:2B:C3
211
- #
212
- # Signature Algorithm: sha1WithRSAEncryption
213
- # 1c:1a:06:97:dc:d7:9c:9f:3c:88:66:06:08:57:21:db:21:47:
214
- # f8:2a:67:aa:bf:18:32:76:40:10:57:c1:8a:f3:7a:d9:11:65:
215
- # 8e:35:fa:9e:fc:45:b5:9e:d9:4c:31:4b:b8:91:e8:43:2c:8e:
216
- # b3:78:ce:db:e3:53:79:71:d6:e5:21:94:01:da:55:87:9a:24:
217
- # 64:f6:8a:66:cc:de:9c:37:cd:a8:34:b1:69:9b:23:c8:9e:78:
218
- # 22:2b:70:43:e3:55:47:31:61:19:ef:58:c5:85:2f:4e:30:f6:
219
- # a0:31:16:23:c8:e7:e2:65:16:33:cb:bf:1a:1b:a0:3d:f8:ca:
220
- # 5e:8b:31:8b:60:08:89:2d:0c:06:5c:52:b7:c4:f9:0a:98:d1:
221
- # 15:5f:9f:12:be:7c:36:63:38:bd:44:a4:7f:e4:26:2b:0a:c4:
222
- # 97:69:0d:e9:8c:e2:c0:10:57:b8:c8:76:12:91:55:f2:48:69:
223
- # d8:bc:2a:02:5b:0f:44:d4:20:31:db:f4:ba:70:26:5d:90:60:
224
- # 9e:bc:4b:17:09:2f:b4:cb:1e:43:68:c9:07:27:c1:d2:5c:f7:
225
- # ea:21:b9:68:12:9c:3c:9c:bf:9e:fc:80:5c:9b:63:cd:ec:47:
226
- # aa:25:27:67:a0:37:f3:00:82:7d:54:d7:a9:f8:e9:2e:13:a3:
227
- # 77:e8:1f:4a
228
- -----BEGIN CERTIFICATE-----
229
- MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBs
230
- MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
231
- d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j
232
- ZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTMxMTExMDAwMDAwMFowbDEL
233
- MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3
234
- LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug
235
- RVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm
236
- +9S75S0tMqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTW
237
- PNt0OKRKzE0lgvdKpVMSOO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEM
238
- xChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFB
239
- Ik5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQNAQTXKFx01p8VdteZOE3
240
- hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUeh10aUAsg
241
- EsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQF
242
- MAMBAf8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaA
243
- FLE+w2kD+L9HAdSYJhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3Nec
244
- nzyIZgYIVyHbIUf4KmeqvxgydkAQV8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6z
245
- eM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFpmyPInngiK3BD41VHMWEZ71jF
246
- hS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkKmNEVX58Svnw2
247
- Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe
248
- vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep
249
- +OkuE6N36B9K
250
- -----END CERTIFICATE-----
251
- # Entrust Root Certification Authority - EC1.pem
252
- # Certificate:
253
- # Data:
254
- # Version: 3 (0x2)
255
- # Serial Number:
256
- # a6:8b:79:29:00:00:00:00:50:d0:91:f9
257
- # Signature Algorithm: ecdsa-with-SHA384
258
- # Issuer: C=US, O=Entrust, Inc., OU=See www.entrust.net/legal-terms, OU=(c) 2012 Entrust, Inc. - for authorized use only, CN=Entrust Root Certification Authority - EC1
259
- # Validity
260
- # Not Before: Dec 18 15:25:36 2012 GMT
261
- # Not After : Dec 18 15:55:36 2037 GMT
262
- # Subject: C=US, O=Entrust, Inc., OU=See www.entrust.net/legal-terms, OU=(c) 2012 Entrust, Inc. - for authorized use only, CN=Entrust Root Certification Authority - EC1
263
- # Subject Public Key Info:
264
- # Public Key Algorithm: id-ecPublicKey
265
- # Public-Key: (384 bit)
266
- # pub:
267
- # 04:84:13:c9:d0:ba:6d:41:7b:e2:6c:d0:eb:55:5f:
268
- # 66:02:1a:24:f4:5b:89:69:47:e3:b8:c2:7d:f1:f2:
269
- # 02:c5:9f:a0:f6:5b:d5:8b:06:19:86:4f:53:10:6d:
270
- # 07:24:27:a1:a0:f8:d5:47:19:61:4c:7d:ca:93:27:
271
- # ea:74:0c:ef:6f:96:09:fe:63:ec:70:5d:36:ad:67:
272
- # 77:ae:c9:9d:7c:55:44:3a:a2:63:51:1f:f5:e3:62:
273
- # d4:a9:47:07:3e:cc:20
274
- # ASN1 OID: secp384r1
275
- # X509v3 extensions:
276
- # X509v3 Key Usage: critical
277
- # Certificate Sign, CRL Sign
278
- # X509v3 Basic Constraints: critical
279
- # CA:TRUE
280
- # X509v3 Subject Key Identifier:
281
- # B7:63:E7:1A:DD:8D:E9:08:A6:55:83:A4:E0:6A:50:41:65:11:42:49
282
- # Signature Algorithm: ecdsa-with-SHA384
283
- # 30:64:02:30:61:79:d8:e5:42:47:df:1c:ae:53:99:17:b6:6f:
284
- # 1c:7d:e1:bf:11:94:d1:03:88:75:e4:8d:89:a4:8a:77:46:de:
285
- # 6d:61:ef:02:f5:fb:b5:df:cc:fe:4e:ff:fe:a9:e6:a7:02:30:
286
- # 5b:99:d7:85:37:06:b5:7b:08:fd:eb:27:8b:4a:94:f9:e1:fa:
287
- # a7:8e:26:08:e8:7c:92:68:6d:73:d8:6f:26:ac:21:02:b8:99:
288
- # b7:26:41:5b:25:60:ae:d0:48:1a:ee:06
289
- -----BEGIN CERTIFICATE-----
290
- MIIC+TCCAoCgAwIBAgINAKaLeSkAAAAAUNCR+TAKBggqhkjOPQQDAzCBvzELMAkG
291
- A1UEBhMCVVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3
292
- d3cuZW50cnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDEyIEVu
293
- dHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25seTEzMDEGA1UEAxMq
294
- RW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRUMxMB4XDTEy
295
- MTIxODE1MjUzNloXDTM3MTIxODE1NTUzNlowgb8xCzAJBgNVBAYTAlVTMRYwFAYD
296
- VQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1c3QubmV0
297
- L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxMiBFbnRydXN0LCBJbmMuIC0g
298
- Zm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxMzAxBgNVBAMTKkVudHJ1c3QgUm9vdCBD
299
- ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEVDMTB2MBAGByqGSM49AgEGBSuBBAAi
300
- A2IABIQTydC6bUF74mzQ61VfZgIaJPRbiWlH47jCffHyAsWfoPZb1YsGGYZPUxBt
301
- ByQnoaD41UcZYUx9ypMn6nQM72+WCf5j7HBdNq1nd67JnXxVRDqiY1Ef9eNi1KlH
302
- Bz7MIKNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0O
303
- BBYEFLdj5xrdjekIplWDpOBqUEFlEUJJMAoGCCqGSM49BAMDA2cAMGQCMGF52OVC
304
- R98crlOZF7ZvHH3hvxGU0QOIdeSNiaSKd0bebWHvAvX7td/M/k7//qnmpwIwW5nX
305
- hTcGtXsI/esni0qU+eH6p44mCOh8kmhtc9hvJqwhAriZtyZBWyVgrtBIGu4G
306
- -----END CERTIFICATE-----
307
- # Entrust Root Certification Authority - G2.pem
308
- # Certificate:
309
- # Data:
310
- # Version: 3 (0x2)
311
- # Serial Number: 1246989352 (0x4a538c28)
312
- # Signature Algorithm: sha256WithRSAEncryption
313
- # Issuer: C=US, O=Entrust, Inc., OU=See www.entrust.net/legal-terms, OU=(c) 2009 Entrust, Inc. - for authorized use only, CN=Entrust Root Certification Authority - G2
314
- # Validity
315
- # Not Before: Jul 7 17:25:54 2009 GMT
316
- # Not After : Dec 7 17:55:54 2030 GMT
317
- # Subject: C=US, O=Entrust, Inc., OU=See www.entrust.net/legal-terms, OU=(c) 2009 Entrust, Inc. - for authorized use only, CN=Entrust Root Certification Authority - G2
318
- # Subject Public Key Info:
319
- # Public Key Algorithm: rsaEncryption
320
- # Public-Key: (2048 bit)
321
- # Modulus:
322
- # 00:ba:84:b6:72:db:9e:0c:6b:e2:99:e9:30:01:a7:
323
- # 76:ea:32:b8:95:41:1a:c9:da:61:4e:58:72:cf:fe:
324
- # f6:82:79:bf:73:61:06:0a:a5:27:d8:b3:5f:d3:45:
325
- # 4e:1c:72:d6:4e:32:f2:72:8a:0f:f7:83:19:d0:6a:
326
- # 80:80:00:45:1e:b0:c7:e7:9a:bf:12:57:27:1c:a3:
327
- # 68:2f:0a:87:bd:6a:6b:0e:5e:65:f3:1c:77:d5:d4:
328
- # 85:8d:70:21:b4:b3:32:e7:8b:a2:d5:86:39:02:b1:
329
- # b8:d2:47:ce:e4:c9:49:c4:3b:a7:de:fb:54:7d:57:
330
- # be:f0:e8:6e:c2:79:b2:3a:0b:55:e2:50:98:16:32:
331
- # 13:5c:2f:78:56:c1:c2:94:b3:f2:5a:e4:27:9a:9f:
332
- # 24:d7:c6:ec:d0:9b:25:82:e3:cc:c2:c4:45:c5:8c:
333
- # 97:7a:06:6b:2a:11:9f:a9:0a:6e:48:3b:6f:db:d4:
334
- # 11:19:42:f7:8f:07:bf:f5:53:5f:9c:3e:f4:17:2c:
335
- # e6:69:ac:4e:32:4c:62:77:ea:b7:e8:e5:bb:34:bc:
336
- # 19:8b:ae:9c:51:e7:b7:7e:b5:53:b1:33:22:e5:6d:
337
- # cf:70:3c:1a:fa:e2:9b:67:b6:83:f4:8d:a5:af:62:
338
- # 4c:4d:e0:58:ac:64:34:12:03:f8:b6:8d:94:63:24:
339
- # a4:71
340
- # Exponent: 65537 (0x10001)
341
- # X509v3 extensions:
342
- # X509v3 Key Usage: critical
343
- # Certificate Sign, CRL Sign
344
- # X509v3 Basic Constraints: critical
345
- # CA:TRUE
346
- # X509v3 Subject Key Identifier:
347
- # 6A:72:26:7A:D0:1E:EF:7D:E7:3B:69:51:D4:6C:8D:9F:90:12:66:AB
348
- # Signature Algorithm: sha256WithRSAEncryption
349
- # 79:9f:1d:96:c6:b6:79:3f:22:8d:87:d3:87:03:04:60:6a:6b:
350
- # 9a:2e:59:89:73:11:ac:43:d1:f5:13:ff:8d:39:2b:c0:f2:bd:
351
- # 4f:70:8c:a9:2f:ea:17:c4:0b:54:9e:d4:1b:96:98:33:3c:a8:
352
- # ad:62:a2:00:76:ab:59:69:6e:06:1d:7e:c4:b9:44:8d:98:af:
353
- # 12:d4:61:db:0a:19:46:47:f3:eb:f7:63:c1:40:05:40:a5:d2:
354
- # b7:f4:b5:9a:36:bf:a9:88:76:88:04:55:04:2b:9c:87:7f:1a:
355
- # 37:3c:7e:2d:a5:1a:d8:d4:89:5e:ca:bd:ac:3d:6c:d8:6d:af:
356
- # d5:f3:76:0f:cd:3b:88:38:22:9d:6c:93:9a:c4:3d:bf:82:1b:
357
- # 65:3f:a6:0f:5d:aa:fc:e5:b2:15:ca:b5:ad:c6:bc:3d:d0:84:
358
- # e8:ea:06:72:b0:4d:39:32:78:bf:3e:11:9c:0b:a4:9d:9a:21:
359
- # f3:f0:9b:0b:30:78:db:c1:dc:87:43:fe:bc:63:9a:ca:c5:c2:
360
- # 1c:c9:c7:8d:ff:3b:12:58:08:e6:b6:3d:ec:7a:2c:4e:fb:83:
361
- # 96:ce:0c:3c:69:87:54:73:a4:73:c2:93:ff:51:10:ac:15:54:
362
- # 01:d8:fc:05:b1:89:a1:7f:74:83:9a:49:d7:dc:4e:7b:8a:48:
363
- # 6f:8b:45:f6
364
- -----BEGIN CERTIFICATE-----
365
- MIIEPjCCAyagAwIBAgIESlOMKDANBgkqhkiG9w0BAQsFADCBvjELMAkGA1UEBhMC
366
- VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50
367
- cnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3Qs
368
- IEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25seTEyMDAGA1UEAxMpRW50cnVz
369
- dCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzIwHhcNMDkwNzA3MTcy
370
- NTU0WhcNMzAxMjA3MTc1NTU0WjCBvjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUVu
371
- dHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVnYWwt
372
- dGVybXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0
373
- aG9yaXplZCB1c2Ugb25seTEyMDAGA1UEAxMpRW50cnVzdCBSb290IENlcnRpZmlj
374
- YXRpb24gQXV0aG9yaXR5IC0gRzIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
375
- AoIBAQC6hLZy254Ma+KZ6TABp3bqMriVQRrJ2mFOWHLP/vaCeb9zYQYKpSfYs1/T
376
- RU4cctZOMvJyig/3gxnQaoCAAEUesMfnmr8SVycco2gvCoe9amsOXmXzHHfV1IWN
377
- cCG0szLni6LVhjkCsbjSR87kyUnEO6fe+1R9V77w6G7CebI6C1XiUJgWMhNcL3hW
378
- wcKUs/Ja5CeanyTXxuzQmyWC48zCxEXFjJd6BmsqEZ+pCm5IO2/b1BEZQvePB7/1
379
- U1+cPvQXLOZprE4yTGJ36rfo5bs0vBmLrpxR57d+tVOxMyLlbc9wPBr64ptntoP0
380
- jaWvYkxN4FisZDQSA/i2jZRjJKRxAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAP
381
- BgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqciZ60B7vfec7aVHUbI2fkBJmqzAN
382
- BgkqhkiG9w0BAQsFAAOCAQEAeZ8dlsa2eT8ijYfThwMEYGprmi5ZiXMRrEPR9RP/
383
- jTkrwPK9T3CMqS/qF8QLVJ7UG5aYMzyorWKiAHarWWluBh1+xLlEjZivEtRh2woZ
384
- Rkfz6/djwUAFQKXSt/S1mja/qYh2iARVBCuch38aNzx+LaUa2NSJXsq9rD1s2G2v
385
- 1fN2D807iDginWyTmsQ9v4IbZT+mD12q/OWyFcq1rca8PdCE6OoGcrBNOTJ4vz4R
386
- nAuknZoh8/CbCzB428Hch0P+vGOaysXCHMnHjf87ElgI5rY97HosTvuDls4MPGmH
387
- VHOkc8KT/1EQrBVUAdj8BbGJoX90g5pJ19xOe4pIb4tF9g==
388
- -----END CERTIFICATE-----
389
- # Entrust Root Certification Authority.pem
390
- # Certificate:
391
- # Data:
392
- # Version: 3 (0x2)
393
- # Serial Number: 1164660820 (0x456b5054)
394
- # Signature Algorithm: sha1WithRSAEncryption
395
- # Issuer: C=US, O=Entrust, Inc., OU=www.entrust.net/CPS is incorporated by reference, OU=(c) 2006 Entrust, Inc., CN=Entrust Root Certification Authority
396
- # Validity
397
- # Not Before: Nov 27 20:23:42 2006 GMT
398
- # Not After : Nov 27 20:53:42 2026 GMT
399
- # Subject: C=US, O=Entrust, Inc., OU=www.entrust.net/CPS is incorporated by reference, OU=(c) 2006 Entrust, Inc., CN=Entrust Root Certification Authority
400
- # Subject Public Key Info:
401
- # Public Key Algorithm: rsaEncryption
402
- # Public-Key: (2048 bit)
403
- # Modulus:
404
- # 00:b6:95:b6:43:42:fa:c6:6d:2a:6f:48:df:94:4c:
405
- # 39:57:05:ee:c3:79:11:41:68:36:ed:ec:fe:9a:01:
406
- # 8f:a1:38:28:fc:f7:10:46:66:2e:4d:1e:1a:b1:1a:
407
- # 4e:c6:d1:c0:95:88:b0:c9:ff:31:8b:33:03:db:b7:
408
- # 83:7b:3e:20:84:5e:ed:b2:56:28:a7:f8:e0:b9:40:
409
- # 71:37:c5:cb:47:0e:97:2a:68:c0:22:95:62:15:db:
410
- # 47:d9:f5:d0:2b:ff:82:4b:c9:ad:3e:de:4c:db:90:
411
- # 80:50:3f:09:8a:84:00:ec:30:0a:3d:18:cd:fb:fd:
412
- # 2a:59:9a:23:95:17:2c:45:9e:1f:6e:43:79:6d:0c:
413
- # 5c:98:fe:48:a7:c5:23:47:5c:5e:fd:6e:e7:1e:b4:
414
- # f6:68:45:d1:86:83:5b:a2:8a:8d:b1:e3:29:80:fe:
415
- # 25:71:88:ad:be:bc:8f:ac:52:96:4b:aa:51:8d:e4:
416
- # 13:31:19:e8:4e:4d:9f:db:ac:b3:6a:d5:bc:39:54:
417
- # 71:ca:7a:7a:7f:90:dd:7d:1d:80:d9:81:bb:59:26:
418
- # c2:11:fe:e6:93:e2:f7:80:e4:65:fb:34:37:0e:29:
419
- # 80:70:4d:af:38:86:2e:9e:7f:57:af:9e:17:ae:eb:
420
- # 1c:cb:28:21:5f:b6:1c:d8:e7:a2:04:22:f9:d3:da:
421
- # d8:cb
422
- # Exponent: 65537 (0x10001)
423
- # X509v3 extensions:
424
- # X509v3 Key Usage: critical
425
- # Certificate Sign, CRL Sign
426
- # X509v3 Basic Constraints: critical
427
- # CA:TRUE
428
- # X509v3 Private Key Usage Period:
429
- # Not Before: Nov 27 20:23:42 2006 GMT, Not After: Nov 27 20:53:42 2026 GMT
430
- # X509v3 Authority Key Identifier:
431
- # keyid:68:90:E4:67:A4:A6:53:80:C7:86:66:A4:F1:F7:4B:43:FB:84:BD:6D
432
- #
433
- # X509v3 Subject Key Identifier:
434
- # 68:90:E4:67:A4:A6:53:80:C7:86:66:A4:F1:F7:4B:43:FB:84:BD:6D
435
- # 1.2.840.113533.7.65.0:
436
- # 0...V7.1:4.0....
437
- # Signature Algorithm: sha1WithRSAEncryption
438
- # 93:d4:30:b0:d7:03:20:2a:d0:f9:63:e8:91:0c:05:20:a9:5f:
439
- # 19:ca:7b:72:4e:d4:b1:db:d0:96:fb:54:5a:19:2c:0c:08:f7:
440
- # b2:bc:85:a8:9d:7f:6d:3b:52:b3:2a:db:e7:d4:84:8c:63:f6:
441
- # 0f:cb:26:01:91:50:6c:f4:5f:14:e2:93:74:c0:13:9e:30:3a:
442
- # 50:e3:b4:60:c5:1c:f0:22:44:8d:71:47:ac:c8:1a:c9:e9:9b:
443
- # 9a:00:60:13:ff:70:7e:5f:11:4d:49:1b:b3:15:52:7b:c9:54:
444
- # da:bf:9d:95:af:6b:9a:d8:9e:e9:f1:e4:43:8d:e2:11:44:3a:
445
- # bf:af:bd:83:42:73:52:8b:aa:bb:a7:29:cf:f5:64:1c:0a:4d:
446
- # d1:bc:aa:ac:9f:2a:d0:ff:7f:7f:da:7d:ea:b1:ed:30:25:c1:
447
- # 84:da:34:d2:5b:78:83:56:ec:9c:36:c3:26:e2:11:f6:67:49:
448
- # 1d:92:ab:8c:fb:eb:ff:7a:ee:85:4a:a7:50:80:f0:a7:5c:4a:
449
- # 94:2e:5f:05:99:3c:52:41:e0:cd:b4:63:cf:01:43:ba:9c:83:
450
- # dc:8f:60:3b:f3:5a:b4:b4:7b:ae:da:0b:90:38:75:ef:81:1d:
451
- # 66:d2:f7:57:70:36:b3:bf:fc:28:af:71:25:85:5b:13:fe:1e:
452
- # 7f:5a:b4:3c
453
- -----BEGIN CERTIFICATE-----
454
- MIIEkTCCA3mgAwIBAgIERWtQVDANBgkqhkiG9w0BAQUFADCBsDELMAkGA1UEBhMC
455
- VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xOTA3BgNVBAsTMHd3dy5lbnRydXN0
456
- Lm5ldC9DUFMgaXMgaW5jb3Jwb3JhdGVkIGJ5IHJlZmVyZW5jZTEfMB0GA1UECxMW
457
- KGMpIDIwMDYgRW50cnVzdCwgSW5jLjEtMCsGA1UEAxMkRW50cnVzdCBSb290IENl
458
- cnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA2MTEyNzIwMjM0MloXDTI2MTEyNzIw
459
- NTM0MlowgbAxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMTkw
460
- NwYDVQQLEzB3d3cuZW50cnVzdC5uZXQvQ1BTIGlzIGluY29ycG9yYXRlZCBieSBy
461
- ZWZlcmVuY2UxHzAdBgNVBAsTFihjKSAyMDA2IEVudHJ1c3QsIEluYy4xLTArBgNV
462
- BAMTJEVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASIwDQYJ
463
- KoZIhvcNAQEBBQADggEPADCCAQoCggEBALaVtkNC+sZtKm9I35RMOVcF7sN5EUFo
464
- Nu3s/poBj6E4KPz3EEZmLk0eGrEaTsbRwJWIsMn/MYszA9u3g3s+IIRe7bJWKKf4
465
- 4LlAcTfFy0cOlypowCKVYhXbR9n10Cv/gkvJrT7eTNuQgFA/CYqEAOwwCj0Yzfv9
466
- KlmaI5UXLEWeH25DeW0MXJj+SKfFI0dcXv1u5x609mhF0YaDW6KKjbHjKYD+JXGI
467
- rb68j6xSlkuqUY3kEzEZ6E5Nn9uss2rVvDlUccp6en+Q3X0dgNmBu1kmwhH+5pPi
468
- 94DkZfs0Nw4pgHBNrziGLp5/V6+eF67rHMsoIV+2HNjnogQi+dPa2MsCAwEAAaOB
469
- sDCBrTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zArBgNVHRAEJDAi
470
- gA8yMDA2MTEyNzIwMjM0MlqBDzIwMjYxMTI3MjA1MzQyWjAfBgNVHSMEGDAWgBRo
471
- kORnpKZTgMeGZqTx90tD+4S9bTAdBgNVHQ4EFgQUaJDkZ6SmU4DHhmak8fdLQ/uE
472
- vW0wHQYJKoZIhvZ9B0EABBAwDhsIVjcuMTo0LjADAgSQMA0GCSqGSIb3DQEBBQUA
473
- A4IBAQCT1DCw1wMgKtD5Y+iRDAUgqV8ZyntyTtSx29CW+1RaGSwMCPeyvIWonX9t
474
- O1KzKtvn1ISMY/YPyyYBkVBs9F8U4pN0wBOeMDpQ47RgxRzwIkSNcUesyBrJ6Zua
475
- AGAT/3B+XxFNSRuzFVJ7yVTav52Vr2ua2J7p8eRDjeIRRDq/r72DQnNSi6q7pynP
476
- 9WQcCk3RvKqsnyrQ/39/2n3qse0wJcGE2jTSW3iDVuycNsMm4hH2Z0kdkquM++v/
477
- eu6FSqdQgPCnXEqULl8FmTxSQeDNtGPPAUO6nIPcj2A781q0tHuu2guQOHXvgR1m
478
- 0vdXcDazv/wor3ElhVsT/h5/WrQ8
479
- -----END CERTIFICATE-----
480
- # Entrust.net Certification Authority (2048).pem
481
- # Certificate:
482
- # Data:
483
- # Version: 3 (0x2)
484
- # Serial Number: 946069240 (0x3863def8)
485
- # Signature Algorithm: sha1WithRSAEncryption
486
- # Issuer: O=Entrust.net, OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.), OU=(c) 1999 Entrust.net Limited, CN=Entrust.net Certification Authority (2048)
487
- # Validity
488
- # Not Before: Dec 24 17:50:51 1999 GMT
489
- # Not After : Jul 24 14:15:12 2029 GMT
490
- # Subject: O=Entrust.net, OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.), OU=(c) 1999 Entrust.net Limited, CN=Entrust.net Certification Authority (2048)
491
- # Subject Public Key Info:
492
- # Public Key Algorithm: rsaEncryption
493
- # Public-Key: (2048 bit)
494
- # Modulus:
495
- # 00:ad:4d:4b:a9:12:86:b2:ea:a3:20:07:15:16:64:
496
- # 2a:2b:4b:d1:bf:0b:4a:4d:8e:ed:80:76:a5:67:b7:
497
- # 78:40:c0:73:42:c8:68:c0:db:53:2b:dd:5e:b8:76:
498
- # 98:35:93:8b:1a:9d:7c:13:3a:0e:1f:5b:b7:1e:cf:
499
- # e5:24:14:1e:b1:81:a9:8d:7d:b8:cc:6b:4b:03:f1:
500
- # 02:0c:dc:ab:a5:40:24:00:7f:74:94:a1:9d:08:29:
501
- # b3:88:0b:f5:87:77:9d:55:cd:e4:c3:7e:d7:6a:64:
502
- # ab:85:14:86:95:5b:97:32:50:6f:3d:c8:ba:66:0c:
503
- # e3:fc:bd:b8:49:c1:76:89:49:19:fd:c0:a8:bd:89:
504
- # a3:67:2f:c6:9f:bc:71:19:60:b8:2d:e9:2c:c9:90:
505
- # 76:66:7b:94:e2:af:78:d6:65:53:5d:3c:d6:9c:b2:
506
- # cf:29:03:f9:2f:a4:50:b2:d4:48:ce:05:32:55:8a:
507
- # fd:b2:64:4c:0e:e4:98:07:75:db:7f:df:b9:08:55:
508
- # 60:85:30:29:f9:7b:48:a4:69:86:e3:35:3f:1e:86:
509
- # 5d:7a:7a:15:bd:ef:00:8e:15:22:54:17:00:90:26:
510
- # 93:bc:0e:49:68:91:bf:f8:47:d3:9d:95:42:c1:0e:
511
- # 4d:df:6f:26:cf:c3:18:21:62:66:43:70:d6:d5:c0:
512
- # 07:e1
513
- # Exponent: 65537 (0x10001)
514
- # X509v3 extensions:
515
- # X509v3 Key Usage: critical
516
- # Certificate Sign, CRL Sign
517
- # X509v3 Basic Constraints: critical
518
- # CA:TRUE
519
- # X509v3 Subject Key Identifier:
520
- # 55:E4:81:D1:11:80:BE:D8:89:B9:08:A3:31:F9:A1:24:09:16:B9:70
521
- # Signature Algorithm: sha1WithRSAEncryption
522
- # 3b:9b:8f:56:9b:30:e7:53:99:7c:7a:79:a7:4d:97:d7:19:95:
523
- # 90:fb:06:1f:ca:33:7c:46:63:8f:96:66:24:fa:40:1b:21:27:
524
- # ca:e6:72:73:f2:4f:fe:31:99:fd:c8:0c:4c:68:53:c6:80:82:
525
- # 13:98:fa:b6:ad:da:5d:3d:f1:ce:6e:f6:15:11:94:82:0c:ee:
526
- # 3f:95:af:11:ab:0f:d7:2f:de:1f:03:8f:57:2c:1e:c9:bb:9a:
527
- # 1a:44:95:eb:18:4f:a6:1f:cd:7d:57:10:2f:9b:04:09:5a:84:
528
- # b5:6e:d8:1d:3a:e1:d6:9e:d1:6c:79:5e:79:1c:14:c5:e3:d0:
529
- # 4c:93:3b:65:3c:ed:df:3d:be:a6:e5:95:1a:c3:b5:19:c3:bd:
530
- # 5e:5b:bb:ff:23:ef:68:19:cb:12:93:27:5c:03:2d:6f:30:d0:
531
- # 1e:b6:1a:ac:de:5a:f7:d1:aa:a8:27:a6:fe:79:81:c4:79:99:
532
- # 33:57:ba:12:b0:a9:e0:42:6c:93:ca:56:de:fe:6d:84:0b:08:
533
- # 8b:7e:8d:ea:d7:98:21:c6:f3:e7:3c:79:2f:5e:9c:d1:4c:15:
534
- # 8d:e1:ec:22:37:cc:9a:43:0b:97:dc:80:90:8d:b3:67:9b:6f:
535
- # 48:08:15:56:cf:bf:f1:2b:7c:5e:9a:76:e9:59:90:c5:7c:83:
536
- # 35:11:65:51
537
- -----BEGIN CERTIFICATE-----
538
- MIIEKjCCAxKgAwIBAgIEOGPe+DANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UEChML
539
- RW50cnVzdC5uZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNfMjA0OCBp
540
- bmNvcnAuIGJ5IHJlZi4gKGxpbWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAxOTk5
541
- IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNVBAMTKkVudHJ1c3QubmV0IENlcnRp
542
- ZmljYXRpb24gQXV0aG9yaXR5ICgyMDQ4KTAeFw05OTEyMjQxNzUwNTFaFw0yOTA3
543
- MjQxNDE1MTJaMIG0MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDFAMD4GA1UECxQ3d3d3
544
- LmVudHJ1c3QubmV0L0NQU18yMDQ4IGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxp
545
- YWIuKTElMCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEG
546
- A1UEAxMqRW50cnVzdC5uZXQgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgKDIwNDgp
547
- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArU1LqRKGsuqjIAcVFmQq
548
- K0vRvwtKTY7tgHalZ7d4QMBzQshowNtTK91euHaYNZOLGp18EzoOH1u3Hs/lJBQe
549
- sYGpjX24zGtLA/ECDNyrpUAkAH90lKGdCCmziAv1h3edVc3kw37XamSrhRSGlVuX
550
- MlBvPci6Zgzj/L24ScF2iUkZ/cCovYmjZy/Gn7xxGWC4LeksyZB2ZnuU4q941mVT
551
- XTzWnLLPKQP5L6RQstRIzgUyVYr9smRMDuSYB3Xbf9+5CFVghTAp+XtIpGmG4zU/
552
- HoZdenoVve8AjhUiVBcAkCaTvA5JaJG/+EfTnZVCwQ5N328mz8MYIWJmQ3DW1cAH
553
- 4QIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV
554
- HQ4EFgQUVeSB0RGAvtiJuQijMfmhJAkWuXAwDQYJKoZIhvcNAQEFBQADggEBADub
555
- j1abMOdTmXx6eadNl9cZlZD7Bh/KM3xGY4+WZiT6QBshJ8rmcnPyT/4xmf3IDExo
556
- U8aAghOY+rat2l098c5u9hURlIIM7j+VrxGrD9cv3h8Dj1csHsm7mhpElesYT6Yf
557
- zX1XEC+bBAlahLVu2B064dae0Wx5XnkcFMXj0EyTO2U87d89vqbllRrDtRnDvV5b
558
- u/8j72gZyxKTJ1wDLW8w0B62GqzeWvfRqqgnpv55gcR5mTNXuhKwqeBCbJPKVt7+
559
- bYQLCIt+jerXmCHG8+c8eS9enNFMFY3h7CI3zJpDC5fcgJCNs2ebb0gIFVbPv/Er
560
- fF6adulZkMV8gzURZVE=
561
- -----END CERTIFICATE-----
562
- # GeoTrust Global CA.pem
563
- # Certificate:
564
- # Data:
565
- # Version: 3 (0x2)
566
- # Serial Number: 144470 (0x23456)
567
- # Signature Algorithm: sha1WithRSAEncryption
568
- # Issuer: C=US, O=GeoTrust Inc., CN=GeoTrust Global CA
569
- # Validity
570
- # Not Before: May 21 04:00:00 2002 GMT
571
- # Not After : May 21 04:00:00 2022 GMT
572
- # Subject: C=US, O=GeoTrust Inc., CN=GeoTrust Global CA
573
- # Subject Public Key Info:
574
- # Public Key Algorithm: rsaEncryption
575
- # Public-Key: (2048 bit)
576
- # Modulus:
577
- # 00:da:cc:18:63:30:fd:f4:17:23:1a:56:7e:5b:df:
578
- # 3c:6c:38:e4:71:b7:78:91:d4:bc:a1:d8:4c:f8:a8:
579
- # 43:b6:03:e9:4d:21:07:08:88:da:58:2f:66:39:29:
580
- # bd:05:78:8b:9d:38:e8:05:b7:6a:7e:71:a4:e6:c4:
581
- # 60:a6:b0:ef:80:e4:89:28:0f:9e:25:d6:ed:83:f3:
582
- # ad:a6:91:c7:98:c9:42:18:35:14:9d:ad:98:46:92:
583
- # 2e:4f:ca:f1:87:43:c1:16:95:57:2d:50:ef:89:2d:
584
- # 80:7a:57:ad:f2:ee:5f:6b:d2:00:8d:b9:14:f8:14:
585
- # 15:35:d9:c0:46:a3:7b:72:c8:91:bf:c9:55:2b:cd:
586
- # d0:97:3e:9c:26:64:cc:df:ce:83:19:71:ca:4e:e6:
587
- # d4:d5:7b:a9:19:cd:55:de:c8:ec:d2:5e:38:53:e5:
588
- # 5c:4f:8c:2d:fe:50:23:36:fc:66:e6:cb:8e:a4:39:
589
- # 19:00:b7:95:02:39:91:0b:0e:fe:38:2e:d1:1d:05:
590
- # 9a:f6:4d:3e:6f:0f:07:1d:af:2c:1e:8f:60:39:e2:
591
- # fa:36:53:13:39:d4:5e:26:2b:db:3d:a8:14:bd:32:
592
- # eb:18:03:28:52:04:71:e5:ab:33:3d:e1:38:bb:07:
593
- # 36:84:62:9c:79:ea:16:30:f4:5f:c0:2b:e8:71:6b:
594
- # e4:f9
595
- # Exponent: 65537 (0x10001)
596
- # X509v3 extensions:
597
- # X509v3 Basic Constraints: critical
598
- # CA:TRUE
599
- # X509v3 Subject Key Identifier:
600
- # C0:7A:98:68:8D:89:FB:AB:05:64:0C:11:7D:AA:7D:65:B8:CA:CC:4E
601
- # X509v3 Authority Key Identifier:
602
- # keyid:C0:7A:98:68:8D:89:FB:AB:05:64:0C:11:7D:AA:7D:65:B8:CA:CC:4E
603
- #
604
- # Signature Algorithm: sha1WithRSAEncryption
605
- # 35:e3:29:6a:e5:2f:5d:54:8e:29:50:94:9f:99:1a:14:e4:8f:
606
- # 78:2a:62:94:a2:27:67:9e:d0:cf:1a:5e:47:e9:c1:b2:a4:cf:
607
- # dd:41:1a:05:4e:9b:4b:ee:4a:6f:55:52:b3:24:a1:37:0a:eb:
608
- # 64:76:2a:2e:2c:f3:fd:3b:75:90:bf:fa:71:d8:c7:3d:37:d2:
609
- # b5:05:95:62:b9:a6:de:89:3d:36:7b:38:77:48:97:ac:a6:20:
610
- # 8f:2e:a6:c9:0c:c2:b2:99:45:00:c7:ce:11:51:22:22:e0:a5:
611
- # ea:b6:15:48:09:64:ea:5e:4f:74:f7:05:3e:c7:8a:52:0c:db:
612
- # 15:b4:bd:6d:9b:e5:c6:b1:54:68:a9:e3:69:90:b6:9a:a5:0f:
613
- # b8:b9:3f:20:7d:ae:4a:b5:b8:9c:e4:1d:b6:ab:e6:94:a5:c1:
614
- # c7:83:ad:db:f5:27:87:0e:04:6c:d5:ff:dd:a0:5d:ed:87:52:
615
- # b7:2b:15:02:ae:39:a6:6a:74:e9:da:c4:e7:bc:4d:34:1e:a9:
616
- # 5c:4d:33:5f:92:09:2f:88:66:5d:77:97:c7:1d:76:13:a9:d5:
617
- # e5:f1:16:09:11:35:d5:ac:db:24:71:70:2c:98:56:0b:d9:17:
618
- # b4:d1:e3:51:2b:5e:75:e8:d5:d0:dc:4f:34:ed:c2:05:66:80:
619
- # a1:cb:e6:33
620
- -----BEGIN CERTIFICATE-----
621
- MIIDVDCCAjygAwIBAgIDAjRWMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVT
622
- MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i
623
- YWwgQ0EwHhcNMDIwNTIxMDQwMDAwWhcNMjIwNTIxMDQwMDAwWjBCMQswCQYDVQQG
624
- EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEbMBkGA1UEAxMSR2VvVHJ1c3Qg
625
- R2xvYmFsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2swYYzD9
626
- 9BcjGlZ+W988bDjkcbd4kdS8odhM+KhDtgPpTSEHCIjaWC9mOSm9BXiLnTjoBbdq
627
- fnGk5sRgprDvgOSJKA+eJdbtg/OtppHHmMlCGDUUna2YRpIuT8rxh0PBFpVXLVDv
628
- iS2Aelet8u5fa9IAjbkU+BQVNdnARqN7csiRv8lVK83Qlz6cJmTM386DGXHKTubU
629
- 1XupGc1V3sjs0l44U+VcT4wt/lAjNvxm5suOpDkZALeVAjmRCw7+OC7RHQWa9k0+
630
- bw8HHa8sHo9gOeL6NlMTOdReJivbPagUvTLrGAMoUgRx5aszPeE4uwc2hGKceeoW
631
- MPRfwCvocWvk+QIDAQABo1MwUTAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTA
632
- ephojYn7qwVkDBF9qn1luMrMTjAfBgNVHSMEGDAWgBTAephojYn7qwVkDBF9qn1l
633
- uMrMTjANBgkqhkiG9w0BAQUFAAOCAQEANeMpauUvXVSOKVCUn5kaFOSPeCpilKIn
634
- Z57QzxpeR+nBsqTP3UEaBU6bS+5Kb1VSsyShNwrrZHYqLizz/Tt1kL/6cdjHPTfS
635
- tQWVYrmm3ok9Nns4d0iXrKYgjy6myQzCsplFAMfOEVEiIuCl6rYVSAlk6l5PdPcF
636
- PseKUgzbFbS9bZvlxrFUaKnjaZC2mqUPuLk/IH2uSrW4nOQdtqvmlKXBx4Ot2/Un
637
- hw4EbNX/3aBd7YdStysVAq45pmp06drE57xNNB6pXE0zX5IJL4hmXXeXxx12E6nV
638
- 5fEWCRE11azbJHFwLJhWC9kXtNHjUStedejV0NxPNO3CBWaAocvmMw==
639
- -----END CERTIFICATE-----
640
- # GeoTrust Primary Certification Authority - G2.pem
641
- # Certificate:
642
- # Data:
643
- # Version: 3 (0x2)
644
- # Serial Number:
645
- # 3c:b2:f4:48:0a:00:e2:fe:eb:24:3b:5e:60:3e:c3:6b
646
- # Signature Algorithm: ecdsa-with-SHA384
647
- # Issuer: C=US, O=GeoTrust Inc., OU=(c) 2007 GeoTrust Inc. - For authorized use only, CN=GeoTrust Primary Certification Authority - G2
648
- # Validity
649
- # Not Before: Nov 5 00:00:00 2007 GMT
650
- # Not After : Jan 18 23:59:59 2038 GMT
651
- # Subject: C=US, O=GeoTrust Inc., OU=(c) 2007 GeoTrust Inc. - For authorized use only, CN=GeoTrust Primary Certification Authority - G2
652
- # Subject Public Key Info:
653
- # Public Key Algorithm: id-ecPublicKey
654
- # Public-Key: (384 bit)
655
- # pub:
656
- # 04:15:b1:e8:fd:03:15:43:e5:ac:eb:87:37:11:62:
657
- # ef:d2:83:36:52:7d:45:57:0b:4a:8d:7b:54:3b:3a:
658
- # 6e:5f:15:02:c0:50:a6:cf:25:2f:7d:ca:48:b8:c7:
659
- # 50:63:1c:2a:21:08:7c:9a:36:d8:0b:fe:d1:26:c5:
660
- # 58:31:30:28:25:f3:5d:5d:a3:b8:b6:a5:b4:92:ed:
661
- # 6c:2c:9f:eb:dd:43:89:a2:3c:4b:48:91:1d:50:ec:
662
- # 26:df:d6:60:2e:bd:21
663
- # ASN1 OID: secp384r1
664
- # X509v3 extensions:
665
- # X509v3 Basic Constraints: critical
666
- # CA:TRUE
667
- # X509v3 Key Usage: critical
668
- # Certificate Sign, CRL Sign
669
- # X509v3 Subject Key Identifier:
670
- # 15:5F:35:57:51:55:FB:25:B2:AD:03:69:FC:01:A3:FA:BE:11:55:D5
671
- # Signature Algorithm: ecdsa-with-SHA384
672
- # 30:64:02:30:64:96:59:a6:e8:09:de:8b:ba:fa:5a:88:88:f0:
673
- # 1f:91:d3:46:a8:f2:4a:4c:02:63:fb:6c:5f:38:db:2e:41:93:
674
- # a9:0e:e6:9d:dc:31:1c:b2:a0:a7:18:1c:79:e1:c7:36:02:30:
675
- # 3a:56:af:9a:74:6c:f6:fb:83:e0:33:d3:08:5f:a1:9c:c2:5b:
676
- # 9f:46:d6:b6:cb:91:06:63:a2:06:e7:33:ac:3e:a8:81:12:d0:
677
- # cb:ba:d0:92:0b:b6:9e:96:aa:04:0f:8a
678
- -----BEGIN CERTIFICATE-----
679
- MIICrjCCAjWgAwIBAgIQPLL0SAoA4v7rJDteYD7DazAKBggqhkjOPQQDAzCBmDEL
680
- MAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsTMChj
681
- KSAyMDA3IEdlb1RydXN0IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTE2
682
- MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0
683
- eSAtIEcyMB4XDTA3MTEwNTAwMDAwMFoXDTM4MDExODIzNTk1OVowgZgxCzAJBgNV
684
- BAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAoYykgMjAw
685
- NyBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0BgNV
686
- BAMTLUdlb1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBH
687
- MjB2MBAGByqGSM49AgEGBSuBBAAiA2IABBWx6P0DFUPlrOuHNxFi79KDNlJ9RVcL
688
- So17VDs6bl8VAsBQps8lL33KSLjHUGMcKiEIfJo22Av+0SbFWDEwKCXzXV2juLal
689
- tJLtbCyf691DiaI8S0iRHVDsJt/WYC69IaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAO
690
- BgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBVfNVdRVfslsq0DafwBo/q+EVXVMAoG
691
- CCqGSM49BAMDA2cAMGQCMGSWWaboCd6LuvpaiIjwH5HTRqjySkwCY/tsXzjbLkGT
692
- qQ7mndwxHLKgpxgceeHHNgIwOlavmnRs9vuD4DPTCF+hnMJbn0bWtsuRBmOiBucz
693
- rD6ogRLQy7rQkgu2npaqBA+K
694
- -----END CERTIFICATE-----
695
- # GeoTrust Primary Certification Authority - G3.pem
696
- # Certificate:
697
- # Data:
698
- # Version: 3 (0x2)
699
- # Serial Number:
700
- # 15:ac:6e:94:19:b2:79:4b:41:f6:27:a9:c3:18:0f:1f
701
- # Signature Algorithm: sha256WithRSAEncryption
702
- # Issuer: C=US, O=GeoTrust Inc., OU=(c) 2008 GeoTrust Inc. - For authorized use only, CN=GeoTrust Primary Certification Authority - G3
703
- # Validity
704
- # Not Before: Apr 2 00:00:00 2008 GMT
705
- # Not After : Dec 1 23:59:59 2037 GMT
706
- # Subject: C=US, O=GeoTrust Inc., OU=(c) 2008 GeoTrust Inc. - For authorized use only, CN=GeoTrust Primary Certification Authority - G3
707
- # Subject Public Key Info:
708
- # Public Key Algorithm: rsaEncryption
709
- # Public-Key: (2048 bit)
710
- # Modulus:
711
- # 00:dc:e2:5e:62:58:1d:33:57:39:32:33:fa:eb:cb:
712
- # 87:8c:a7:d4:4a:dd:06:88:ea:64:8e:31:98:a5:38:
713
- # 90:1e:98:cf:2e:63:2b:f0:46:bc:44:b2:89:a1:c0:
714
- # 28:0c:49:70:21:95:9f:64:c0:a6:93:12:02:65:26:
715
- # 86:c6:a5:89:f0:fa:d7:84:a0:70:af:4f:1a:97:3f:
716
- # 06:44:d5:c9:eb:72:10:7d:e4:31:28:fb:1c:61:e6:
717
- # 28:07:44:73:92:22:69:a7:03:88:6c:9d:63:c8:52:
718
- # da:98:27:e7:08:4c:70:3e:b4:c9:12:c1:c5:67:83:
719
- # 5d:33:f3:03:11:ec:6a:d0:53:e2:d1:ba:36:60:94:
720
- # 80:bb:61:63:6c:5b:17:7e:df:40:94:1e:ab:0d:c2:
721
- # 21:28:70:88:ff:d6:26:6c:6c:60:04:25:4e:55:7e:
722
- # 7d:ef:bf:94:48:de:b7:1d:dd:70:8d:05:5f:88:a5:
723
- # 9b:f2:c2:ee:ea:d1:40:41:6d:62:38:1d:56:06:c5:
724
- # 03:47:51:20:19:fc:7b:10:0b:0e:62:ae:76:55:bf:
725
- # 5f:77:be:3e:49:01:53:3d:98:25:03:76:24:5a:1d:
726
- # b4:db:89:ea:79:e5:b6:b3:3b:3f:ba:4c:28:41:7f:
727
- # 06:ac:6a:8e:c1:d0:f6:05:1d:7d:e6:42:86:e3:a5:
728
- # d5:47
729
- # Exponent: 65537 (0x10001)
730
- # X509v3 extensions:
731
- # X509v3 Basic Constraints: critical
732
- # CA:TRUE
733
- # X509v3 Key Usage: critical
734
- # Certificate Sign, CRL Sign
735
- # X509v3 Subject Key Identifier:
736
- # C4:79:CA:8E:A1:4E:03:1D:1C:DC:6B:DB:31:5B:94:3E:3F:30:7F:2D
737
- # Signature Algorithm: sha256WithRSAEncryption
738
- # 2d:c5:13:cf:56:80:7b:7a:78:bd:9f:ae:2c:99:e7:ef:da:df:
739
- # 94:5e:09:69:a7:e7:6e:68:8c:bd:72:be:47:a9:0e:97:12:b8:
740
- # 4a:f1:64:d3:39:df:25:34:d4:c1:cd:4e:81:f0:0f:04:c4:24:
741
- # b3:34:96:c6:a6:aa:30:df:68:61:73:d7:f9:8e:85:89:ef:0e:
742
- # 5e:95:28:4a:2a:27:8f:10:8e:2e:7c:86:c4:02:9e:da:0c:77:
743
- # 65:0e:44:0d:92:fd:fd:b3:16:36:fa:11:0d:1d:8c:0e:07:89:
744
- # 6a:29:56:f7:72:f4:dd:15:9c:77:35:66:57:ab:13:53:d8:8e:
745
- # c1:40:c5:d7:13:16:5a:72:c7:b7:69:01:c4:7a:b1:83:01:68:
746
- # 7d:8d:41:a1:94:18:c1:25:5c:fc:f0:fe:83:02:87:7c:0d:0d:
747
- # cf:2e:08:5c:4a:40:0d:3e:ec:81:61:e6:24:db:ca:e0:0e:2d:
748
- # 07:b2:3e:56:dc:8d:f5:41:85:07:48:9b:0c:0b:cb:49:3f:7d:
749
- # ec:b7:fd:cb:8d:67:89:1a:ab:ed:bb:1e:a3:00:08:08:17:2a:
750
- # 82:5c:31:5d:46:8a:2d:0f:86:9b:74:d9:45:fb:d4:40:b1:7a:
751
- # aa:68:2d:86:b2:99:22:e1:c1:2b:c7:9c:f8:f3:5f:a8:82:12:
752
- # eb:19:11:2d
753
- -----BEGIN CERTIFICATE-----
754
- MIID/jCCAuagAwIBAgIQFaxulBmyeUtB9iepwxgPHzANBgkqhkiG9w0BAQsFADCB
755
- mDELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsT
756
- MChjKSAyMDA4IEdlb1RydXN0IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25s
757
- eTE2MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhv
758
- cml0eSAtIEczMB4XDTA4MDQwMjAwMDAwMFoXDTM3MTIwMTIzNTk1OVowgZgxCzAJ
759
- BgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAoYykg
760
- MjAwOCBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0
761
- BgNVBAMTLUdlb1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg
762
- LSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANziXmJYHTNXOTIz
763
- +uvLh4yn1ErdBojqZI4xmKU4kB6Yzy5jK/BGvESyiaHAKAxJcCGVn2TAppMSAmUm
764
- hsalifD614SgcK9PGpc/BkTVyetyEH3kMSj7HGHmKAdEc5IiaacDiGydY8hS2pgn
765
- 5whMcD60yRLBxWeDXTPzAxHsatBT4tG6NmCUgLthY2xbF37fQJQeqw3CIShwiP/W
766
- JmxsYAQlTlV+fe+/lEjetx3dcI0FX4ilm/LC7urRQEFtYjgdVgbFA0dRIBn8exAL
767
- DmKudlW/X3e+PkkBUz2YJQN2JFodtNuJ6nnltrM7P7pMKEF/BqxqjsHQ9gUdfeZC
768
- huOl1UcCAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYw
769
- HQYDVR0OBBYEFMR5yo6hTgMdHNxr2zFblD4/MH8tMA0GCSqGSIb3DQEBCwUAA4IB
770
- AQAtxRPPVoB7eni9n64smefv2t+UXglpp+duaIy9cr5HqQ6XErhK8WTTOd8lNNTB
771
- zU6B8A8ExCSzNJbGpqow32hhc9f5joWJ7w5elShKKiePEI4ufIbEAp7aDHdlDkQN
772
- kv39sxY2+hENHYwOB4lqKVb3cvTdFZx3NWZXqxNT2I7BQMXXExZacse3aQHEerGD
773
- AWh9jUGhlBjBJVz88P6DAod8DQ3PLghcSkANPuyBYeYk28rgDi0Hsj5W3I31QYUH
774
- SJsMC8tJP33st/3LjWeJGqvtux6jAAgIFyqCXDFdRootD4abdNlF+9RAsXqqaC2G
775
- spki4cErx5z481+oghLrGREt
776
- -----END CERTIFICATE-----
777
- # GeoTrust Primary Certification Authority.pem
778
- # Certificate:
779
- # Data:
780
- # Version: 3 (0x2)
781
- # Serial Number:
782
- # 18:ac:b5:6a:fd:69:b6:15:3a:63:6c:af:da:fa:c4:a1
783
- # Signature Algorithm: sha1WithRSAEncryption
784
- # Issuer: C=US, O=GeoTrust Inc., CN=GeoTrust Primary Certification Authority
785
- # Validity
786
- # Not Before: Nov 27 00:00:00 2006 GMT
787
- # Not After : Jul 16 23:59:59 2036 GMT
788
- # Subject: C=US, O=GeoTrust Inc., CN=GeoTrust Primary Certification Authority
789
- # Subject Public Key Info:
790
- # Public Key Algorithm: rsaEncryption
791
- # Public-Key: (2048 bit)
792
- # Modulus:
793
- # 00:be:b8:15:7b:ff:d4:7c:7d:67:ad:83:64:7b:c8:
794
- # 42:53:2d:df:f6:84:08:20:61:d6:01:59:6a:9c:44:
795
- # 11:af:ef:76:fd:95:7e:ce:61:30:bb:7a:83:5f:02:
796
- # bd:01:66:ca:ee:15:8d:6f:a1:30:9c:bd:a1:85:9e:
797
- # 94:3a:f3:56:88:00:31:cf:d8:ee:6a:96:02:d9:ed:
798
- # 03:8c:fb:75:6d:e7:ea:b8:55:16:05:16:9a:f4:e0:
799
- # 5e:b1:88:c0:64:85:5c:15:4d:88:c7:b7:ba:e0:75:
800
- # e9:ad:05:3d:9d:c7:89:48:e0:bb:28:c8:03:e1:30:
801
- # 93:64:5e:52:c0:59:70:22:35:57:88:8a:f1:95:0a:
802
- # 83:d7:bc:31:73:01:34:ed:ef:46:71:e0:6b:02:a8:
803
- # 35:72:6b:97:9b:66:e0:cb:1c:79:5f:d8:1a:04:68:
804
- # 1e:47:02:e6:9d:60:e2:36:97:01:df:ce:35:92:df:
805
- # be:67:c7:6d:77:59:3b:8f:9d:d6:90:15:94:bc:42:
806
- # 34:10:c1:39:f9:b1:27:3e:7e:d6:8a:75:c5:b2:af:
807
- # 96:d3:a2:de:9b:e4:98:be:7d:e1:e9:81:ad:b6:6f:
808
- # fc:d7:0e:da:e0:34:b0:0d:1a:77:e7:e3:08:98:ef:
809
- # 58:fa:9c:84:b7:36:af:c2:df:ac:d2:f4:10:06:70:
810
- # 71:35
811
- # Exponent: 65537 (0x10001)
812
- # X509v3 extensions:
813
- # X509v3 Basic Constraints: critical
814
- # CA:TRUE
815
- # X509v3 Key Usage: critical
816
- # Certificate Sign, CRL Sign
817
- # X509v3 Subject Key Identifier:
818
- # 2C:D5:50:41:97:15:8B:F0:8F:36:61:5B:4A:FB:6B:D9:99:C9:33:92
819
- # Signature Algorithm: sha1WithRSAEncryption
820
- # 5a:70:7f:2c:dd:b7:34:4f:f5:86:51:a9:26:be:4b:b8:aa:f1:
821
- # 71:0d:dc:61:c7:a0:ea:34:1e:7a:77:0f:04:35:e8:27:8f:6c:
822
- # 90:bf:91:16:24:46:3e:4a:4e:ce:2b:16:d5:0b:52:1d:fc:1f:
823
- # 67:a2:02:45:31:4f:ce:f3:fa:03:a7:79:9d:53:6a:d9:da:63:
824
- # 3a:f8:80:d7:d3:99:e1:a5:e1:be:d4:55:71:98:35:3a:be:93:
825
- # ea:ae:ad:42:b2:90:6f:e0:fc:21:4d:35:63:33:89:49:d6:9b:
826
- # 4e:ca:c7:e7:4e:09:00:f7:da:c7:ef:99:62:99:77:b6:95:22:
827
- # 5e:8a:a0:ab:f4:b8:78:98:ca:38:19:99:c9:72:9e:78:cd:4b:
828
- # ac:af:19:a0:73:12:2d:fc:c2:41:ba:81:91:da:16:5a:31:b7:
829
- # f9:b4:71:80:12:48:99:72:73:5a:59:53:c1:63:52:33:ed:a7:
830
- # c9:d2:39:02:70:fa:e0:b1:42:66:29:aa:9b:51:ed:30:54:22:
831
- # 14:5f:d9:ab:1d:c1:e4:94:f0:f8:f5:2b:f7:ea:ca:78:46:d6:
832
- # b8:91:fd:a6:0d:2b:1a:14:01:3e:80:f0:42:a0:95:07:5e:6d:
833
- # cd:cc:4b:a4:45:8d:ab:12:e8:b3:de:5a:e5:a0:7c:e8:0f:22:
834
- # 1d:5a:e9:59
835
- -----BEGIN CERTIFICATE-----
836
- MIIDfDCCAmSgAwIBAgIQGKy1av1pthU6Y2yv2vrEoTANBgkqhkiG9w0BAQUFADBY
837
- MQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjExMC8GA1UEAxMo
838
- R2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjEx
839
- MjcwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMFgxCzAJBgNVBAYTAlVTMRYwFAYDVQQK
840
- Ew1HZW9UcnVzdCBJbmMuMTEwLwYDVQQDEyhHZW9UcnVzdCBQcmltYXJ5IENlcnRp
841
- ZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
842
- AQEAvrgVe//UfH1nrYNke8hCUy3f9oQIIGHWAVlqnEQRr+92/ZV+zmEwu3qDXwK9
843
- AWbK7hWNb6EwnL2hhZ6UOvNWiAAxz9juapYC2e0DjPt1befquFUWBRaa9OBesYjA
844
- ZIVcFU2Ix7e64HXprQU9nceJSOC7KMgD4TCTZF5SwFlwIjVXiIrxlQqD17wxcwE0
845
- 7e9GceBrAqg1cmuXm2bgyxx5X9gaBGgeRwLmnWDiNpcB3841kt++Z8dtd1k7j53W
846
- kBWUvEI0EME5+bEnPn7WinXFsq+W06Lem+SYvn3h6YGttm/81w7a4DSwDRp35+MI
847
- mO9Y+pyEtzavwt+s0vQQBnBxNQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4G
848
- A1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQULNVQQZcVi/CPNmFbSvtr2ZnJM5IwDQYJ
849
- KoZIhvcNAQEFBQADggEBAFpwfyzdtzRP9YZRqSa+S7iq8XEN3GHHoOo0Hnp3DwQ1
850
- 6CePbJC/kRYkRj5KTs4rFtULUh38H2eiAkUxT87z+gOneZ1TatnaYzr4gNfTmeGl
851
- 4b7UVXGYNTq+k+qurUKykG/g/CFNNWMziUnWm07Kx+dOCQD32sfvmWKZd7aVIl6K
852
- oKv0uHiYyjgZmclynnjNS6yvGaBzEi38wkG6gZHaFloxt/m0cYASSJlyc1pZU8Fj
853
- UjPtp8nSOQJw+uCxQmYpqptR7TBUIhRf2asdweSU8Pj1K/fqynhG1riR/aYNKxoU
854
- AT6A8EKglQdebc3MS6RFjasS6LPeWuWgfOgPIh1a6Vk=
855
- -----END CERTIFICATE-----
856
- # Go Daddy Class 2 Certification Authority.pem
857
- # Certificate:
858
- # Data:
859
- # Version: 3 (0x2)
860
- # Serial Number: 0 (0x0)
861
- # Signature Algorithm: sha1WithRSAEncryption
862
- # Issuer: C=US, O=The Go Daddy Group, Inc., OU=Go Daddy Class 2 Certification Authority
863
- # Validity
864
- # Not Before: Jun 29 17:06:20 2004 GMT
865
- # Not After : Jun 29 17:06:20 2034 GMT
866
- # Subject: C=US, O=The Go Daddy Group, Inc., OU=Go Daddy Class 2 Certification Authority
867
- # Subject Public Key Info:
868
- # Public Key Algorithm: rsaEncryption
869
- # Public-Key: (2048 bit)
870
- # Modulus:
871
- # 00:de:9d:d7:ea:57:18:49:a1:5b:eb:d7:5f:48:86:
872
- # ea:be:dd:ff:e4:ef:67:1c:f4:65:68:b3:57:71:a0:
873
- # 5e:77:bb:ed:9b:49:e9:70:80:3d:56:18:63:08:6f:
874
- # da:f2:cc:d0:3f:7f:02:54:22:54:10:d8:b2:81:d4:
875
- # c0:75:3d:4b:7f:c7:77:c3:3e:78:ab:1a:03:b5:20:
876
- # 6b:2f:6a:2b:b1:c5:88:7e:c4:bb:1e:b0:c1:d8:45:
877
- # 27:6f:aa:37:58:f7:87:26:d7:d8:2d:f6:a9:17:b7:
878
- # 1f:72:36:4e:a6:17:3f:65:98:92:db:2a:6e:5d:a2:
879
- # fe:88:e0:0b:de:7f:e5:8d:15:e1:eb:cb:3a:d5:e2:
880
- # 12:a2:13:2d:d8:8e:af:5f:12:3d:a0:08:05:08:b6:
881
- # 5c:a5:65:38:04:45:99:1e:a3:60:60:74:c5:41:a5:
882
- # 72:62:1b:62:c5:1f:6f:5f:1a:42:be:02:51:65:a8:
883
- # ae:23:18:6a:fc:78:03:a9:4d:7f:80:c3:fa:ab:5a:
884
- # fc:a1:40:a4:ca:19:16:fe:b2:c8:ef:5e:73:0d:ee:
885
- # 77:bd:9a:f6:79:98:bc:b1:07:67:a2:15:0d:dd:a0:
886
- # 58:c6:44:7b:0a:3e:62:28:5f:ba:41:07:53:58:cf:
887
- # 11:7e:38:74:c5:f8:ff:b5:69:90:8f:84:74:ea:97:
888
- # 1b:af
889
- # Exponent: 3 (0x3)
890
- # X509v3 extensions:
891
- # X509v3 Subject Key Identifier:
892
- # D2:C4:B0:D2:91:D4:4C:11:71:B3:61:CB:3D:A1:FE:DD:A8:6A:D4:E3
893
- # X509v3 Authority Key Identifier:
894
- # keyid:D2:C4:B0:D2:91:D4:4C:11:71:B3:61:CB:3D:A1:FE:DD:A8:6A:D4:E3
895
- # DirName:/C=US/O=The Go Daddy Group, Inc./OU=Go Daddy Class 2 Certification Authority
896
- # serial:00
897
- #
898
- # X509v3 Basic Constraints:
899
- # CA:TRUE
900
- # Signature Algorithm: sha1WithRSAEncryption
901
- # 32:4b:f3:b2:ca:3e:91:fc:12:c6:a1:07:8c:8e:77:a0:33:06:
902
- # 14:5c:90:1e:18:f7:08:a6:3d:0a:19:f9:87:80:11:6e:69:e4:
903
- # 96:17:30:ff:34:91:63:72:38:ee:cc:1c:01:a3:1d:94:28:a4:
904
- # 31:f6:7a:c4:54:d7:f6:e5:31:58:03:a2:cc:ce:62:db:94:45:
905
- # 73:b5:bf:45:c9:24:b5:d5:82:02:ad:23:79:69:8d:b8:b6:4d:
906
- # ce:cf:4c:ca:33:23:e8:1c:88:aa:9d:8b:41:6e:16:c9:20:e5:
907
- # 89:9e:cd:3b:da:70:f7:7e:99:26:20:14:54:25:ab:6e:73:85:
908
- # e6:9b:21:9d:0a:6c:82:0e:a8:f8:c2:0c:fa:10:1e:6c:96:ef:
909
- # 87:0d:c4:0f:61:8b:ad:ee:83:2b:95:f8:8e:92:84:72:39:eb:
910
- # 20:ea:83:ed:83:cd:97:6e:08:bc:eb:4e:26:b6:73:2b:e4:d3:
911
- # f6:4c:fe:26:71:e2:61:11:74:4a:ff:57:1a:87:0f:75:48:2e:
912
- # cf:51:69:17:a0:02:12:61:95:d5:d1:40:b2:10:4c:ee:c4:ac:
913
- # 10:43:a6:a5:9e:0a:d5:95:62:9a:0d:cf:88:82:c5:32:0c:e4:
914
- # 2b:9f:45:e6:0d:9f:28:9c:b1:b9:2a:5a:57:ad:37:0f:af:1d:
915
- # 7f:db:bd:9f
916
- -----BEGIN CERTIFICATE-----
917
- MIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEh
918
- MB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBE
919
- YWRkeSBDbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA0MDYyOTE3
920
- MDYyMFoXDTM0MDYyOTE3MDYyMFowYzELMAkGA1UEBhMCVVMxITAfBgNVBAoTGFRo
921
- ZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28gRGFkZHkgQ2xhc3Mg
922
- MiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQADggEN
923
- ADCCAQgCggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCA
924
- PVYYYwhv2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6w
925
- wdhFJ2+qN1j3hybX2C32qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXi
926
- EqITLdiOr18SPaAIBQi2XKVlOARFmR6jYGB0xUGlcmIbYsUfb18aQr4CUWWoriMY
927
- avx4A6lNf4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmYvLEHZ6IVDd2gWMZEewo+
928
- YihfukEHU1jPEX44dMX4/7VpkI+EdOqXG68CAQOjgcAwgb0wHQYDVR0OBBYEFNLE
929
- sNKR1EwRcbNhyz2h/t2oatTjMIGNBgNVHSMEgYUwgYKAFNLEsNKR1EwRcbNhyz2h
930
- /t2oatTjoWekZTBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYVGhlIEdvIERhZGR5
931
- IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRpZmlj
932
- YXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQAD
933
- ggEBADJL87LKPpH8EsahB4yOd6AzBhRckB4Y9wimPQoZ+YeAEW5p5JYXMP80kWNy
934
- OO7MHAGjHZQopDH2esRU1/blMVgDoszOYtuURXO1v0XJJLXVggKtI3lpjbi2Tc7P
935
- TMozI+gciKqdi0FuFskg5YmezTvacPd+mSYgFFQlq25zheabIZ0KbIIOqPjCDPoQ
936
- HmyW74cNxA9hi63ugyuV+I6ShHI56yDqg+2DzZduCLzrTia2cyvk0/ZM/iZx4mER
937
- dEr/VxqHD3VILs9RaRegAhJhldXRQLIQTO7ErBBDpqWeCtWVYpoNz4iCxTIM5Cuf
938
- ReYNnyicsbkqWletNw+vHX/bvZ8=
939
- -----END CERTIFICATE-----
940
- # Go Daddy Root Certificate Authority - G2.pem
941
- # Certificate:
942
- # Data:
943
- # Version: 3 (0x2)
944
- # Serial Number: 0 (0x0)
945
- # Signature Algorithm: sha256WithRSAEncryption
946
- # Issuer: C=US, ST=Arizona, L=Scottsdale, O=GoDaddy.com, Inc., CN=Go Daddy Root Certificate Authority - G2
947
- # Validity
948
- # Not Before: Sep 1 00:00:00 2009 GMT
949
- # Not After : Dec 31 23:59:59 2037 GMT
950
- # Subject: C=US, ST=Arizona, L=Scottsdale, O=GoDaddy.com, Inc., CN=Go Daddy Root Certificate Authority - G2
951
- # Subject Public Key Info:
952
- # Public Key Algorithm: rsaEncryption
953
- # Public-Key: (2048 bit)
954
- # Modulus:
955
- # 00:bf:71:62:08:f1:fa:59:34:f7:1b:c9:18:a3:f7:
956
- # 80:49:58:e9:22:83:13:a6:c5:20:43:01:3b:84:f1:
957
- # e6:85:49:9f:27:ea:f6:84:1b:4e:a0:b4:db:70:98:
958
- # c7:32:01:b1:05:3e:07:4e:ee:f4:fa:4f:2f:59:30:
959
- # 22:e7:ab:19:56:6b:e2:80:07:fc:f3:16:75:80:39:
960
- # 51:7b:e5:f9:35:b6:74:4e:a9:8d:82:13:e4:b6:3f:
961
- # a9:03:83:fa:a2:be:8a:15:6a:7f:de:0b:c3:b6:19:
962
- # 14:05:ca:ea:c3:a8:04:94:3b:46:7c:32:0d:f3:00:
963
- # 66:22:c8:8d:69:6d:36:8c:11:18:b7:d3:b2:1c:60:
964
- # b4:38:fa:02:8c:ce:d3:dd:46:07:de:0a:3e:eb:5d:
965
- # 7c:c8:7c:fb:b0:2b:53:a4:92:62:69:51:25:05:61:
966
- # 1a:44:81:8c:2c:a9:43:96:23:df:ac:3a:81:9a:0e:
967
- # 29:c5:1c:a9:e9:5d:1e:b6:9e:9e:30:0a:39:ce:f1:
968
- # 88:80:fb:4b:5d:cc:32:ec:85:62:43:25:34:02:56:
969
- # 27:01:91:b4:3b:70:2a:3f:6e:b1:e8:9c:88:01:7d:
970
- # 9f:d4:f9:db:53:6d:60:9d:bf:2c:e7:58:ab:b8:5f:
971
- # 46:fc:ce:c4:1b:03:3c:09:eb:49:31:5c:69:46:b3:
972
- # e0:47
973
- # Exponent: 65537 (0x10001)
974
- # X509v3 extensions:
975
- # X509v3 Basic Constraints: critical
976
- # CA:TRUE
977
- # X509v3 Key Usage: critical
978
- # Certificate Sign, CRL Sign
979
- # X509v3 Subject Key Identifier:
980
- # 3A:9A:85:07:10:67:28:B6:EF:F6:BD:05:41:6E:20:C1:94:DA:0F:DE
981
- # Signature Algorithm: sha256WithRSAEncryption
982
- # 99:db:5d:79:d5:f9:97:59:67:03:61:f1:7e:3b:06:31:75:2d:
983
- # a1:20:8e:4f:65:87:b4:f7:a6:9c:bc:d8:e9:2f:d0:db:5a:ee:
984
- # cf:74:8c:73:b4:38:42:da:05:7b:f8:02:75:b8:fd:a5:b1:d7:
985
- # ae:f6:d7:de:13:cb:53:10:7e:8a:46:d1:97:fa:b7:2e:2b:11:
986
- # ab:90:b0:27:80:f9:e8:9f:5a:e9:37:9f:ab:e4:df:6c:b3:85:
987
- # 17:9d:3d:d9:24:4f:79:91:35:d6:5f:04:eb:80:83:ab:9a:02:
988
- # 2d:b5:10:f4:d8:90:c7:04:73:40:ed:72:25:a0:a9:9f:ec:9e:
989
- # ab:68:12:99:57:c6:8f:12:3a:09:a4:bd:44:fd:06:15:37:c1:
990
- # 9b:e4:32:a3:ed:38:e8:d8:64:f3:2c:7e:14:fc:02:ea:9f:cd:
991
- # ff:07:68:17:db:22:90:38:2d:7a:8d:d1:54:f1:69:e3:5f:33:
992
- # ca:7a:3d:7b:0a:e3:ca:7f:5f:39:e5:e2:75:ba:c5:76:18:33:
993
- # ce:2c:f0:2f:4c:ad:f7:b1:e7:ce:4f:a8:c4:9b:4a:54:06:c5:
994
- # 7f:7d:d5:08:0f:e2:1c:fe:7e:17:b8:ac:5e:f6:d4:16:b2:43:
995
- # 09:0c:4d:f6:a7:6b:b4:99:84:65:ca:7a:88:e2:e2:44:be:5c:
996
- # f7:ea:1c:f5
997
- -----BEGIN CERTIFICATE-----
998
- MIIDxTCCAq2gAwIBAgIBADANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMx
999
- EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoT
1000
- EUdvRGFkZHkuY29tLCBJbmMuMTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRp
1001
- ZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIz
1002
- NTk1OVowgYMxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQH
1003
- EwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjExMC8GA1UE
1004
- AxMoR28gRGFkZHkgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIw
1005
- DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL9xYgjx+lk09xvJGKP3gElY6SKD
1006
- E6bFIEMBO4Tx5oVJnyfq9oQbTqC023CYxzIBsQU+B07u9PpPL1kwIuerGVZr4oAH
1007
- /PMWdYA5UXvl+TW2dE6pjYIT5LY/qQOD+qK+ihVqf94Lw7YZFAXK6sOoBJQ7Rnwy
1008
- DfMAZiLIjWltNowRGLfTshxgtDj6AozO091GB94KPutdfMh8+7ArU6SSYmlRJQVh
1009
- GkSBjCypQ5Yj36w6gZoOKcUcqeldHraenjAKOc7xiID7S13MMuyFYkMlNAJWJwGR
1010
- tDtwKj9useiciAF9n9T521NtYJ2/LOdYq7hfRvzOxBsDPAnrSTFcaUaz4EcCAwEA
1011
- AaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE
1012
- FDqahQcQZyi27/a9BUFuIMGU2g/eMA0GCSqGSIb3DQEBCwUAA4IBAQCZ21151fmX
1013
- WWcDYfF+OwYxdS2hII5PZYe096acvNjpL9DbWu7PdIxztDhC2gV7+AJ1uP2lsdeu
1014
- 9tfeE8tTEH6KRtGX+rcuKxGrkLAngPnon1rpN5+r5N9ss4UXnT3ZJE95kTXWXwTr
1015
- gIOrmgIttRD02JDHBHNA7XIloKmf7J6raBKZV8aPEjoJpL1E/QYVN8Gb5DKj7Tjo
1016
- 2GTzLH4U/ALqn83/B2gX2yKQOC16jdFU8WnjXzPKej17CuPKf1855eJ1usV2GDPO
1017
- LPAvTK33sefOT6jEm0pUBsV/fdUID+Ic/n4XuKxe9tQWskMJDE32p2u0mYRlynqI
1018
- 4uJEvlz36hz1
1019
- -----END CERTIFICATE-----
1020
- # Go Daddy Secure Certification Authority serialNumber=07969287.pem
1021
- # Certificate:
1022
- # Data:
1023
- # Version: 3 (0x2)
1024
- # Serial Number: 769 (0x301)
1025
- # Signature Algorithm: sha1WithRSAEncryption
1026
- # Issuer: C=US, O=The Go Daddy Group, Inc., OU=Go Daddy Class 2 Certification Authority
1027
- # Validity
1028
- # Not Before: Nov 16 01:54:37 2006 GMT
1029
- # Not After : Nov 16 01:54:37 2026 GMT
1030
- # Subject: C=US, ST=Arizona, L=Scottsdale, O=GoDaddy.com, Inc., OU=http://certificates.godaddy.com/repository, CN=Go Daddy Secure Certification Authority/serialNumber=07969287
1031
- # Subject Public Key Info:
1032
- # Public Key Algorithm: rsaEncryption
1033
- # Public-Key: (2048 bit)
1034
- # Modulus:
1035
- # 00:c4:2d:d5:15:8c:9c:26:4c:ec:32:35:eb:5f:b8:
1036
- # 59:01:5a:a6:61:81:59:3b:70:63:ab:e3:dc:3d:c7:
1037
- # 2a:b8:c9:33:d3:79:e4:3a:ed:3c:30:23:84:8e:b3:
1038
- # 30:14:b6:b2:87:c3:3d:95:54:04:9e:df:99:dd:0b:
1039
- # 25:1e:21:de:65:29:7e:35:a8:a9:54:eb:f6:f7:32:
1040
- # 39:d4:26:55:95:ad:ef:fb:fe:58:86:d7:9e:f4:00:
1041
- # 8d:8c:2a:0c:bd:42:04:ce:a7:3f:04:f6:ee:80:f2:
1042
- # aa:ef:52:a1:69:66:da:be:1a:ad:5d:da:2c:66:ea:
1043
- # 1a:6b:bb:e5:1a:51:4a:00:2f:48:c7:98:75:d8:b9:
1044
- # 29:c8:ee:f8:66:6d:0a:9c:b3:f3:fc:78:7c:a2:f8:
1045
- # a3:f2:b5:c3:f3:b9:7a:91:c1:a7:e6:25:2e:9c:a8:
1046
- # ed:12:65:6e:6a:f6:12:44:53:70:30:95:c3:9c:2b:
1047
- # 58:2b:3d:08:74:4a:f2:be:51:b0:bf:87:d0:4c:27:
1048
- # 58:6b:b5:35:c5:9d:af:17:31:f8:0b:8f:ee:ad:81:
1049
- # 36:05:89:08:98:cf:3a:af:25:87:c0:49:ea:a7:fd:
1050
- # 67:f7:45:8e:97:cc:14:39:e2:36:85:b5:7e:1a:37:
1051
- # fd:16:f6:71:11:9a:74:30:16:fe:13:94:a3:3f:84:
1052
- # 0d:4f
1053
- # Exponent: 65537 (0x10001)
1054
- # X509v3 extensions:
1055
- # X509v3 Subject Key Identifier:
1056
- # FD:AC:61:32:93:6C:45:D6:E2:EE:85:5F:9A:BA:E7:76:99:68:CC:E7
1057
- # X509v3 Authority Key Identifier:
1058
- # keyid:D2:C4:B0:D2:91:D4:4C:11:71:B3:61:CB:3D:A1:FE:DD:A8:6A:D4:E3
1059
- #
1060
- # X509v3 Basic Constraints: critical
1061
- # CA:TRUE, pathlen:0
1062
- # Authority Information Access:
1063
- # OCSP - URI:http://ocsp.godaddy.com
1064
- #
1065
- # X509v3 CRL Distribution Points:
1066
- #
1067
- # Full Name:
1068
- # URI:http://certificates.godaddy.com/repository/gdroot.crl
1069
- #
1070
- # X509v3 Certificate Policies:
1071
- # Policy: X509v3 Any Policy
1072
- # CPS: http://certificates.godaddy.com/repository
1073
- #
1074
- # X509v3 Key Usage: critical
1075
- # Certificate Sign, CRL Sign
1076
- # Signature Algorithm: sha1WithRSAEncryption
1077
- # d2:86:c0:ec:bd:f9:a1:b6:67:ee:66:0b:a2:06:3a:04:50:8e:
1078
- # 15:72:ac:4a:74:95:53:cb:37:cb:44:49:ef:07:90:6b:33:d9:
1079
- # 96:f0:94:56:a5:13:30:05:3c:85:32:21:7b:c9:c7:0a:a8:24:
1080
- # a4:90:de:46:d3:25:23:14:03:67:c2:10:d6:6f:0f:5d:7b:7a:
1081
- # cc:9f:c5:58:2a:c1:c4:9e:21:a8:5a:f3:ac:a4:46:f3:9e:e4:
1082
- # 63:cb:2f:90:a4:29:29:01:d9:72:2c:29:df:37:01:27:bc:4f:
1083
- # ee:68:d3:21:8f:c0:b3:e4:f5:09:ed:d2:10:aa:53:b4:be:f0:
1084
- # cc:59:0b:d6:3b:96:1c:95:24:49:df:ce:ec:fd:a7:48:91:14:
1085
- # 45:0e:3a:36:6f:da:45:b3:45:a2:41:c9:d4:d7:44:4e:3e:b9:
1086
- # 74:76:d5:a2:13:55:2c:c6:87:a3:b5:99:ac:06:84:87:7f:75:
1087
- # 06:fc:bf:14:4c:0e:cc:6e:c4:df:3d:b7:12:71:f4:e8:f1:51:
1088
- # 40:22:28:49:e0:1d:4b:87:a8:34:cc:06:a2:dd:12:5a:d1:86:
1089
- # 36:64:03:35:6f:6f:77:6e:eb:f2:85:50:98:5e:ab:03:53:ad:
1090
- # 91:23:63:1f:16:9c:cd:b9:b2:05:63:3a:e1:f4:68:1b:17:05:
1091
- # 35:95:53:ee
1092
- -----BEGIN CERTIFICATE-----
1093
- MIIE3jCCA8agAwIBAgICAwEwDQYJKoZIhvcNAQEFBQAwYzELMAkGA1UEBhMCVVMx
1094
- ITAfBgNVBAoTGFRoZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28g
1095
- RGFkZHkgQ2xhc3MgMiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjExMTYw
1096
- MTU0MzdaFw0yNjExMTYwMTU0MzdaMIHKMQswCQYDVQQGEwJVUzEQMA4GA1UECBMH
1097
- QXJpem9uYTETMBEGA1UEBxMKU2NvdHRzZGFsZTEaMBgGA1UEChMRR29EYWRkeS5j
1098
- b20sIEluYy4xMzAxBgNVBAsTKmh0dHA6Ly9jZXJ0aWZpY2F0ZXMuZ29kYWRkeS5j
1099
- b20vcmVwb3NpdG9yeTEwMC4GA1UEAxMnR28gRGFkZHkgU2VjdXJlIENlcnRpZmlj
1100
- YXRpb24gQXV0aG9yaXR5MREwDwYDVQQFEwgwNzk2OTI4NzCCASIwDQYJKoZIhvcN
1101
- AQEBBQADggEPADCCAQoCggEBAMQt1RWMnCZM7DI161+4WQFapmGBWTtwY6vj3D3H
1102
- KrjJM9N55DrtPDAjhI6zMBS2sofDPZVUBJ7fmd0LJR4h3mUpfjWoqVTr9vcyOdQm
1103
- VZWt7/v+WIbXnvQAjYwqDL1CBM6nPwT27oDyqu9SoWlm2r4arV3aLGbqGmu75RpR
1104
- SgAvSMeYddi5Kcju+GZtCpyz8/x4fKL4o/K1w/O5epHBp+YlLpyo7RJlbmr2EkRT
1105
- cDCVw5wrWCs9CHRK8r5RsL+H0EwnWGu1NcWdrxcx+AuP7q2BNgWJCJjPOq8lh8BJ
1106
- 6qf9Z/dFjpfMFDniNoW1fho3/Rb2cRGadDAW/hOUoz+EDU8CAwEAAaOCATIwggEu
1107
- MB0GA1UdDgQWBBT9rGEyk2xF1uLuhV+auud2mWjM5zAfBgNVHSMEGDAWgBTSxLDS
1108
- kdRMEXGzYcs9of7dqGrU4zASBgNVHRMBAf8ECDAGAQH/AgEAMDMGCCsGAQUFBwEB
1109
- BCcwJTAjBggrBgEFBQcwAYYXaHR0cDovL29jc3AuZ29kYWRkeS5jb20wRgYDVR0f
1110
- BD8wPTA7oDmgN4Y1aHR0cDovL2NlcnRpZmljYXRlcy5nb2RhZGR5LmNvbS9yZXBv
1111
- c2l0b3J5L2dkcm9vdC5jcmwwSwYDVR0gBEQwQjBABgRVHSAAMDgwNgYIKwYBBQUH
1112
- AgEWKmh0dHA6Ly9jZXJ0aWZpY2F0ZXMuZ29kYWRkeS5jb20vcmVwb3NpdG9yeTAO
1113
- BgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQEFBQADggEBANKGwOy9+aG2Z+5mC6IG
1114
- OgRQjhVyrEp0lVPLN8tESe8HkGsz2ZbwlFalEzAFPIUyIXvJxwqoJKSQ3kbTJSMU
1115
- A2fCENZvD117esyfxVgqwcSeIaha86ykRvOe5GPLL5CkKSkB2XIsKd83ASe8T+5o
1116
- 0yGPwLPk9Qnt0hCqU7S+8MxZC9Y7lhyVJEnfzuz9p0iRFEUOOjZv2kWzRaJBydTX
1117
- RE4+uXR21aITVSzGh6O1mawGhId/dQb8vxRMDsxuxN89txJx9OjxUUAiKEngHUuH
1118
- qDTMBqLdElrRhjZkAzVvb3du6/KFUJheqwNTrZEjYx8WnM25sgVjOuH0aBsXBTWV
1119
- U+4=
1120
- -----END CERTIFICATE-----
1121
- # Thawte Premium Server CA.pem
1122
- # Certificate:
1123
- # Data:
1124
- # Version: 3 (0x2)
1125
- # Serial Number: 1 (0x1)
1126
- # Signature Algorithm: md5WithRSAEncryption
1127
- # Issuer: C=ZA, ST=Western Cape, L=Cape Town, O=Thawte Consulting cc, OU=Certification Services Division, CN=Thawte Premium Server CA/emailAddress=premium-server@thawte.com
1128
- # Validity
1129
- # Not Before: Aug 1 00:00:00 1996 GMT
1130
- # Not After : Dec 31 23:59:59 2020 GMT
1131
- # Subject: C=ZA, ST=Western Cape, L=Cape Town, O=Thawte Consulting cc, OU=Certification Services Division, CN=Thawte Premium Server CA/emailAddress=premium-server@thawte.com
1132
- # Subject Public Key Info:
1133
- # Public Key Algorithm: rsaEncryption
1134
- # Public-Key: (1024 bit)
1135
- # Modulus:
1136
- # 00:d2:36:36:6a:8b:d7:c2:5b:9e:da:81:41:62:8f:
1137
- # 38:ee:49:04:55:d6:d0:ef:1c:1b:95:16:47:ef:18:
1138
- # 48:35:3a:52:f4:2b:6a:06:8f:3b:2f:ea:56:e3:af:
1139
- # 86:8d:9e:17:f7:9e:b4:65:75:02:4d:ef:cb:09:a2:
1140
- # 21:51:d8:9b:d0:67:d0:ba:0d:92:06:14:73:d4:93:
1141
- # cb:97:2a:00:9c:5c:4e:0c:bc:fa:15:52:fc:f2:44:
1142
- # 6e:da:11:4a:6e:08:9f:2f:2d:e3:f9:aa:3a:86:73:
1143
- # b6:46:53:58:c8:89:05:bd:83:11:b8:73:3f:aa:07:
1144
- # 8d:f4:42:4d:e7:40:9d:1c:37
1145
- # Exponent: 65537 (0x10001)
1146
- # X509v3 extensions:
1147
- # X509v3 Basic Constraints: critical
1148
- # CA:TRUE
1149
- # Signature Algorithm: md5WithRSAEncryption
1150
- # 26:48:2c:16:c2:58:fa:e8:16:74:0c:aa:aa:5f:54:3f:f2:d7:
1151
- # c9:78:60:5e:5e:6e:37:63:22:77:36:7e:b2:17:c4:34:b9:f5:
1152
- # 08:85:fc:c9:01:38:ff:4d:be:f2:16:42:43:e7:bb:5a:46:fb:
1153
- # c1:c6:11:1f:f1:4a:b0:28:46:c9:c3:c4:42:7d:bc:fa:ab:59:
1154
- # 6e:d5:b7:51:88:11:e3:a4:85:19:6b:82:4c:a4:0c:12:ad:e9:
1155
- # a4:ae:3f:f1:c3:49:65:9a:8c:c5:c8:3e:25:b7:94:99:bb:92:
1156
- # 32:71:07:f0:86:5e:ed:50:27:a6:0d:a6:23:f9:bb:cb:a6:07:
1157
- # 14:42
1158
- -----BEGIN CERTIFICATE-----
1159
- MIIDJzCCApCgAwIBAgIBATANBgkqhkiG9w0BAQQFADCBzjELMAkGA1UEBhMCWkEx
1160
- FTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYD
1161
- VQQKExRUaGF3dGUgQ29uc3VsdGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlv
1162
- biBTZXJ2aWNlcyBEaXZpc2lvbjEhMB8GA1UEAxMYVGhhd3RlIFByZW1pdW0gU2Vy
1163
- dmVyIENBMSgwJgYJKoZIhvcNAQkBFhlwcmVtaXVtLXNlcnZlckB0aGF3dGUuY29t
1164
- MB4XDTk2MDgwMTAwMDAwMFoXDTIwMTIzMTIzNTk1OVowgc4xCzAJBgNVBAYTAlpB
1165
- MRUwEwYDVQQIEwxXZXN0ZXJuIENhcGUxEjAQBgNVBAcTCUNhcGUgVG93bjEdMBsG
1166
- A1UEChMUVGhhd3RlIENvbnN1bHRpbmcgY2MxKDAmBgNVBAsTH0NlcnRpZmljYXRp
1167
- b24gU2VydmljZXMgRGl2aXNpb24xITAfBgNVBAMTGFRoYXd0ZSBQcmVtaXVtIFNl
1168
- cnZlciBDQTEoMCYGCSqGSIb3DQEJARYZcHJlbWl1bS1zZXJ2ZXJAdGhhd3RlLmNv
1169
- bTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA0jY2aovXwlue2oFBYo847kkE
1170
- VdbQ7xwblRZH7xhINTpS9CtqBo87L+pW46+GjZ4X9560ZXUCTe/LCaIhUdib0GfQ
1171
- ug2SBhRz1JPLlyoAnFxODLz6FVL88kRu2hFKbgifLy3j+ao6hnO2RlNYyIkFvYMR
1172
- uHM/qgeN9EJN50CdHDcCAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG
1173
- 9w0BAQQFAAOBgQAmSCwWwlj66BZ0DKqqX1Q/8tfJeGBeXm43YyJ3Nn6yF8Q0ufUI
1174
- hfzJATj/Tb7yFkJD57taRvvBxhEf8UqwKEbJw8RCfbz6q1lu1bdRiBHjpIUZa4JM
1175
- pAwSremkrj/xw0llmozFyD4lt5SZu5IycQfwhl7tUCemDaYj+bvLpgcUQg==
1176
- -----END CERTIFICATE-----
1177
- # Thawte Primary Root CA - G2.pem
1178
- # Certificate:
1179
- # Data:
1180
- # Version: 3 (0x2)
1181
- # Serial Number:
1182
- # 35:fc:26:5c:d9:84:4f:c9:3d:26:3d:57:9b:ae:d7:56
1183
- # Signature Algorithm: ecdsa-with-SHA384
1184
- # Issuer: C=US, O=thawte, Inc., OU=(c) 2007 thawte, Inc. - For authorized use only, CN=thawte Primary Root CA - G2
1185
- # Validity
1186
- # Not Before: Nov 5 00:00:00 2007 GMT
1187
- # Not After : Jan 18 23:59:59 2038 GMT
1188
- # Subject: C=US, O=thawte, Inc., OU=(c) 2007 thawte, Inc. - For authorized use only, CN=thawte Primary Root CA - G2
1189
- # Subject Public Key Info:
1190
- # Public Key Algorithm: id-ecPublicKey
1191
- # Public-Key: (384 bit)
1192
- # pub:
1193
- # 04:a2:d5:9c:82:7b:95:9d:f1:52:78:87:fe:8a:16:
1194
- # bf:05:e6:df:a3:02:4f:0d:07:c6:00:51:ba:0c:02:
1195
- # 52:2d:22:a4:42:39:c4:fe:8f:ea:c9:c1:be:d4:4d:
1196
- # ff:9f:7a:9e:e2:b1:7c:9a:ad:a7:86:09:73:87:d1:
1197
- # e7:9a:e3:7a:a5:aa:6e:fb:ba:b3:70:c0:67:88:a2:
1198
- # 35:d4:a3:9a:b1:fd:ad:c2:ef:31:fa:a8:b9:f3:fb:
1199
- # 08:c6:91:d1:fb:29:95
1200
- # ASN1 OID: secp384r1
1201
- # X509v3 extensions:
1202
- # X509v3 Basic Constraints: critical
1203
- # CA:TRUE
1204
- # X509v3 Key Usage: critical
1205
- # Certificate Sign, CRL Sign
1206
- # X509v3 Subject Key Identifier:
1207
- # 9A:D8:00:30:00:E7:6B:7F:85:18:EE:8B:B6:CE:8A:0C:F8:11:E1:BB
1208
- # Signature Algorithm: ecdsa-with-SHA384
1209
- # 30:66:02:31:00:dd:f8:e0:57:47:5b:a7:e6:0a:c3:bd:f5:80:
1210
- # 8a:97:35:0d:1b:89:3c:54:86:77:28:ca:a1:f4:79:de:b5:e6:
1211
- # 38:b0:f0:65:70:8c:7f:02:54:c2:bf:ff:d8:a1:3e:d9:cf:02:
1212
- # 31:00:c4:8d:94:fc:dc:53:d2:dc:9d:78:16:1f:15:33:23:53:
1213
- # 52:e3:5a:31:5d:9d:ca:ae:bd:13:29:44:0d:27:5b:a8:e7:68:
1214
- # 9c:12:f7:58:3f:2e:72:02:57:a3:8f:a1:14:2e
1215
- -----BEGIN CERTIFICATE-----
1216
- MIICiDCCAg2gAwIBAgIQNfwmXNmET8k9Jj1Xm67XVjAKBggqhkjOPQQDAzCBhDEL
1217
- MAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjE4MDYGA1UECxMvKGMp
1218
- IDIwMDcgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxJDAi
1219
- BgNVBAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EgLSBHMjAeFw0wNzExMDUwMDAw
1220
- MDBaFw0zODAxMTgyMzU5NTlaMIGEMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhh
1221
- d3RlLCBJbmMuMTgwNgYDVQQLEy8oYykgMjAwNyB0aGF3dGUsIEluYy4gLSBGb3Ig
1222
- YXV0aG9yaXplZCB1c2Ugb25seTEkMCIGA1UEAxMbdGhhd3RlIFByaW1hcnkgUm9v
1223
- dCBDQSAtIEcyMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEotWcgnuVnfFSeIf+iha/
1224
- BebfowJPDQfGAFG6DAJSLSKkQjnE/o/qycG+1E3/n3qe4rF8mq2nhglzh9HnmuN6
1225
- papu+7qzcMBniKI11KOasf2twu8x+qi58/sIxpHR+ymVo0IwQDAPBgNVHRMBAf8E
1226
- BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUmtgAMADna3+FGO6Lts6K
1227
- DPgR4bswCgYIKoZIzj0EAwMDaQAwZgIxAN344FdHW6fmCsO99YCKlzUNG4k8VIZ3
1228
- KMqh9HneteY4sPBlcIx/AlTCv//YoT7ZzwIxAMSNlPzcU9LcnXgWHxUzI1NS41ox
1229
- XZ3Krr0TKUQNJ1uo52icEvdYPy5yAlejj6EULg==
1230
- -----END CERTIFICATE-----
1231
- # Thawte Primary Root CA - G3.pem
1232
- # Certificate:
1233
- # Data:
1234
- # Version: 3 (0x2)
1235
- # Serial Number:
1236
- # 60:01:97:b7:46:a7:ea:b4:b4:9a:d6:4b:2f:f7:90:fb
1237
- # Signature Algorithm: sha256WithRSAEncryption
1238
- # Issuer: C=US, O=thawte, Inc., OU=Certification Services Division, OU=(c) 2008 thawte, Inc. - For authorized use only, CN=thawte Primary Root CA - G3
1239
- # Validity
1240
- # Not Before: Apr 2 00:00:00 2008 GMT
1241
- # Not After : Dec 1 23:59:59 2037 GMT
1242
- # Subject: C=US, O=thawte, Inc., OU=Certification Services Division, OU=(c) 2008 thawte, Inc. - For authorized use only, CN=thawte Primary Root CA - G3
1243
- # Subject Public Key Info:
1244
- # Public Key Algorithm: rsaEncryption
1245
- # Public-Key: (2048 bit)
1246
- # Modulus:
1247
- # 00:b2:bf:27:2c:fb:db:d8:5b:dd:78:7b:1b:9e:77:
1248
- # 66:81:cb:3e:bc:7c:ae:f3:a6:27:9a:34:a3:68:31:
1249
- # 71:38:33:62:e4:f3:71:66:79:b1:a9:65:a3:a5:8b:
1250
- # d5:8f:60:2d:3f:42:cc:aa:6b:32:c0:23:cb:2c:41:
1251
- # dd:e4:df:fc:61:9c:e2:73:b2:22:95:11:43:18:5f:
1252
- # c4:b6:1f:57:6c:0a:05:58:22:c8:36:4c:3a:7c:a5:
1253
- # d1:cf:86:af:88:a7:44:02:13:74:71:73:0a:42:59:
1254
- # 02:f8:1b:14:6b:42:df:6f:5f:ba:6b:82:a2:9d:5b:
1255
- # e7:4a:bd:1e:01:72:db:4b:74:e8:3b:7f:7f:7d:1f:
1256
- # 04:b4:26:9b:e0:b4:5a:ac:47:3d:55:b8:d7:b0:26:
1257
- # 52:28:01:31:40:66:d8:d9:24:bd:f6:2a:d8:ec:21:
1258
- # 49:5c:9b:f6:7a:e9:7f:55:35:7e:96:6b:8d:93:93:
1259
- # 27:cb:92:bb:ea:ac:40:c0:9f:c2:f8:80:cf:5d:f4:
1260
- # 5a:dc:ce:74:86:a6:3e:6c:0b:53:ca:bd:92:ce:19:
1261
- # 06:72:e6:0c:5c:38:69:c7:04:d6:bc:6c:ce:5b:f6:
1262
- # f7:68:9c:dc:25:15:48:88:a1:e9:a9:f8:98:9c:e0:
1263
- # f3:d5:31:28:61:11:6c:67:96:8d:39:99:cb:c2:45:
1264
- # 24:39
1265
- # Exponent: 65537 (0x10001)
1266
- # X509v3 extensions:
1267
- # X509v3 Basic Constraints: critical
1268
- # CA:TRUE
1269
- # X509v3 Key Usage: critical
1270
- # Certificate Sign, CRL Sign
1271
- # X509v3 Subject Key Identifier:
1272
- # AD:6C:AA:94:60:9C:ED:E4:FF:FA:3E:0A:74:2B:63:03:F7:B6:59:BF
1273
- # Signature Algorithm: sha256WithRSAEncryption
1274
- # 1a:40:d8:95:65:ac:09:92:89:c6:39:f4:10:e5:a9:0e:66:53:
1275
- # 5d:78:de:fa:24:91:bb:e7:44:51:df:c6:16:34:0a:ef:6a:44:
1276
- # 51:ea:2b:07:8a:03:7a:c3:eb:3f:0a:2c:52:16:a0:2b:43:b9:
1277
- # 25:90:3f:70:a9:33:25:6d:45:1a:28:3b:27:cf:aa:c3:29:42:
1278
- # 1b:df:3b:4c:c0:33:34:5b:41:88:bf:6b:2b:65:af:28:ef:b2:
1279
- # f5:c3:aa:66:ce:7b:56:ee:b7:c8:cb:67:c1:c9:9c:1a:18:b8:
1280
- # c4:c3:49:03:f1:60:0e:50:cd:46:c5:f3:77:79:f7:b6:15:e0:
1281
- # 38:db:c7:2f:28:a0:0c:3f:77:26:74:d9:25:12:da:31:da:1a:
1282
- # 1e:dc:29:41:91:22:3c:69:a7:bb:02:f2:b6:5c:27:03:89:f4:
1283
- # 06:ea:9b:e4:72:82:e3:a1:09:c1:e9:00:19:d3:3e:d4:70:6b:
1284
- # ba:71:a6:aa:58:ae:f4:bb:e9:6c:b6:ef:87:cc:9b:bb:ff:39:
1285
- # e6:56:61:d3:0a:a7:c4:5c:4c:60:7b:05:77:26:7a:bf:d8:07:
1286
- # 52:2c:62:f7:70:63:d9:39:bc:6f:1c:c2:79:dc:76:29:af:ce:
1287
- # c5:2c:64:04:5e:88:36:6e:31:d4:40:1a:62:34:36:3f:35:01:
1288
- # ae:ac:63:a0
1289
- -----BEGIN CERTIFICATE-----
1290
- MIIEKjCCAxKgAwIBAgIQYAGXt0an6rS0mtZLL/eQ+zANBgkqhkiG9w0BAQsFADCB
1291
- rjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMf
1292
- Q2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIw
1293
- MDggdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxJDAiBgNV
1294
- BAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EgLSBHMzAeFw0wODA0MDIwMDAwMDBa
1295
- Fw0zNzEyMDEyMzU5NTlaMIGuMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhhd3Rl
1296
- LCBJbmMuMSgwJgYDVQQLEx9DZXJ0aWZpY2F0aW9uIFNlcnZpY2VzIERpdmlzaW9u
1297
- MTgwNgYDVQQLEy8oYykgMjAwOCB0aGF3dGUsIEluYy4gLSBGb3IgYXV0aG9yaXpl
1298
- ZCB1c2Ugb25seTEkMCIGA1UEAxMbdGhhd3RlIFByaW1hcnkgUm9vdCBDQSAtIEcz
1299
- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsr8nLPvb2FvdeHsbnndm
1300
- gcs+vHyu86YnmjSjaDFxODNi5PNxZnmxqWWjpYvVj2AtP0LMqmsywCPLLEHd5N/8
1301
- YZzic7IilRFDGF/Eth9XbAoFWCLINkw6fKXRz4aviKdEAhN0cXMKQlkC+BsUa0Lf
1302
- b1+6a4KinVvnSr0eAXLbS3ToO39/fR8EtCab4LRarEc9VbjXsCZSKAExQGbY2SS9
1303
- 9irY7CFJXJv2eul/VTV+lmuNk5Mny5K76qxAwJ/C+IDPXfRa3M50hqY+bAtTyr2S
1304
- zhkGcuYMXDhpxwTWvGzOW/b3aJzcJRVIiKHpqfiYnODz1TEoYRFsZ5aNOZnLwkUk
1305
- OQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNV
1306
- HQ4EFgQUrWyqlGCc7eT/+j4KdCtjA/e2Wb8wDQYJKoZIhvcNAQELBQADggEBABpA
1307
- 2JVlrAmSicY59BDlqQ5mU1143vokkbvnRFHfxhY0Cu9qRFHqKweKA3rD6z8KLFIW
1308
- oCtDuSWQP3CpMyVtRRooOyfPqsMpQhvfO0zAMzRbQYi/aytlryjvsvXDqmbOe1bu
1309
- t8jLZ8HJnBoYuMTDSQPxYA5QzUbF83d597YV4Djbxy8ooAw/dyZ02SUS2jHaGh7c
1310
- KUGRIjxpp7sC8rZcJwOJ9Abqm+RyguOhCcHpABnTPtRwa7pxpqpYrvS76Wy274fM
1311
- m7v/OeZWYdMKp8RcTGB7BXcmer/YB1IsYvdwY9k5vG8cwnncdimvzsUsZAReiDZu
1312
- MdRAGmI0Nj81Aa6sY6A=
1313
- -----END CERTIFICATE-----
1314
- # Thawte Primary Root CA.pem
1315
- # Certificate:
1316
- # Data:
1317
- # Version: 3 (0x2)
1318
- # Serial Number:
1319
- # 34:4e:d5:57:20:d5:ed:ec:49:f4:2f:ce:37:db:2b:6d
1320
- # Signature Algorithm: sha1WithRSAEncryption
1321
- # Issuer: C=US, O=thawte, Inc., OU=Certification Services Division, OU=(c) 2006 thawte, Inc. - For authorized use only, CN=thawte Primary Root CA
1322
- # Validity
1323
- # Not Before: Nov 17 00:00:00 2006 GMT
1324
- # Not After : Jul 16 23:59:59 2036 GMT
1325
- # Subject: C=US, O=thawte, Inc., OU=Certification Services Division, OU=(c) 2006 thawte, Inc. - For authorized use only, CN=thawte Primary Root CA
1326
- # Subject Public Key Info:
1327
- # Public Key Algorithm: rsaEncryption
1328
- # Public-Key: (2048 bit)
1329
- # Modulus:
1330
- # 00:ac:a0:f0:fb:80:59:d4:9c:c7:a4:cf:9d:a1:59:
1331
- # 73:09:10:45:0c:0d:2c:6e:68:f1:6c:5b:48:68:49:
1332
- # 59:37:fc:0b:33:19:c2:77:7f:cc:10:2d:95:34:1c:
1333
- # e6:eb:4d:09:a7:1c:d2:b8:c9:97:36:02:b7:89:d4:
1334
- # 24:5f:06:c0:cc:44:94:94:8d:02:62:6f:eb:5a:dd:
1335
- # 11:8d:28:9a:5c:84:90:10:7a:0d:bd:74:66:2f:6a:
1336
- # 38:a0:e2:d5:54:44:eb:1d:07:9f:07:ba:6f:ee:e9:
1337
- # fd:4e:0b:29:f5:3e:84:a0:01:f1:9c:ab:f8:1c:7e:
1338
- # 89:a4:e8:a1:d8:71:65:0d:a3:51:7b:ee:bc:d2:22:
1339
- # 60:0d:b9:5b:9d:df:ba:fc:51:5b:0b:af:98:b2:e9:
1340
- # 2e:e9:04:e8:62:87:de:2b:c8:d7:4e:c1:4c:64:1e:
1341
- # dd:cf:87:58:ba:4a:4f:ca:68:07:1d:1c:9d:4a:c6:
1342
- # d5:2f:91:cc:7c:71:72:1c:c5:c0:67:eb:32:fd:c9:
1343
- # 92:5c:94:da:85:c0:9b:bf:53:7d:2b:09:f4:8c:9d:
1344
- # 91:1f:97:6a:52:cb:de:09:36:a4:77:d8:7b:87:50:
1345
- # 44:d5:3e:6e:29:69:fb:39:49:26:1e:09:a5:80:7b:
1346
- # 40:2d:eb:e8:27:85:c9:fe:61:fd:7e:e6:7c:97:1d:
1347
- # d5:9d
1348
- # Exponent: 65537 (0x10001)
1349
- # X509v3 extensions:
1350
- # X509v3 Basic Constraints: critical
1351
- # CA:TRUE
1352
- # X509v3 Key Usage: critical
1353
- # Certificate Sign, CRL Sign
1354
- # X509v3 Subject Key Identifier:
1355
- # 7B:5B:45:CF:AF:CE:CB:7A:FD:31:92:1A:6A:B6:F3:46:EB:57:48:50
1356
- # Signature Algorithm: sha1WithRSAEncryption
1357
- # 79:11:c0:4b:b3:91:b6:fc:f0:e9:67:d4:0d:6e:45:be:55:e8:
1358
- # 93:d2:ce:03:3f:ed:da:25:b0:1d:57:cb:1e:3a:76:a0:4c:ec:
1359
- # 50:76:e8:64:72:0c:a4:a9:f1:b8:8b:d6:d6:87:84:bb:32:e5:
1360
- # 41:11:c0:77:d9:b3:60:9d:eb:1b:d5:d1:6e:44:44:a9:a6:01:
1361
- # ec:55:62:1d:77:b8:5c:8e:48:49:7c:9c:3b:57:11:ac:ad:73:
1362
- # 37:8e:2f:78:5c:90:68:47:d9:60:60:e6:fc:07:3d:22:20:17:
1363
- # c4:f7:16:e9:c4:d8:72:f9:c8:73:7c:df:16:2f:15:a9:3e:fd:
1364
- # 6a:27:b6:a1:eb:5a:ba:98:1f:d5:e3:4d:64:0a:9d:13:c8:61:
1365
- # ba:f5:39:1c:87:ba:b8:bd:7b:22:7f:f6:fe:ac:40:79:e5:ac:
1366
- # 10:6f:3d:8f:1b:79:76:8b:c4:37:b3:21:18:84:e5:36:00:eb:
1367
- # 63:20:99:b9:e9:fe:33:04:bb:41:c8:c1:02:f9:44:63:20:9e:
1368
- # 81:ce:42:d3:d6:3f:2c:76:d3:63:9c:59:dd:8f:a6:e1:0e:a0:
1369
- # 2e:41:f7:2e:95:47:cf:bc:fd:33:f3:f6:0b:61:7e:7e:91:2b:
1370
- # 81:47:c2:27:30:ee:a7:10:5d:37:8f:5c:39:2b:e4:04:f0:7b:
1371
- # 8d:56:8c:68
1372
- -----BEGIN CERTIFICATE-----
1373
- MIIEIDCCAwigAwIBAgIQNE7VVyDV7exJ9C/ON9srbTANBgkqhkiG9w0BAQUFADCB
1374
- qTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMf
1375
- Q2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIw
1376
- MDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxHzAdBgNV
1377
- BAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwHhcNMDYxMTE3MDAwMDAwWhcNMzYw
1378
- NzE2MjM1OTU5WjCBqTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5j
1379
- LjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYG
1380
- A1UECxMvKGMpIDIwMDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl
1381
- IG9ubHkxHzAdBgNVBAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwggEiMA0GCSqG
1382
- SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCsoPD7gFnUnMekz52hWXMJEEUMDSxuaPFs
1383
- W0hoSVk3/AszGcJ3f8wQLZU0HObrTQmnHNK4yZc2AreJ1CRfBsDMRJSUjQJib+ta
1384
- 3RGNKJpchJAQeg29dGYvajig4tVUROsdB58Hum/u6f1OCyn1PoSgAfGcq/gcfomk
1385
- 6KHYcWUNo1F77rzSImANuVud37r8UVsLr5iy6S7pBOhih94ryNdOwUxkHt3Ph1i6
1386
- Sk/KaAcdHJ1KxtUvkcx8cXIcxcBn6zL9yZJclNqFwJu/U30rCfSMnZEfl2pSy94J
1387
- NqR32HuHUETVPm4pafs5SSYeCaWAe0At6+gnhcn+Yf1+5nyXHdWdAgMBAAGjQjBA
1388
- MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBR7W0XP
1389
- r87Lev0xkhpqtvNG61dIUDANBgkqhkiG9w0BAQUFAAOCAQEAeRHAS7ORtvzw6WfU
1390
- DW5FvlXok9LOAz/t2iWwHVfLHjp2oEzsUHboZHIMpKnxuIvW1oeEuzLlQRHAd9mz
1391
- YJ3rG9XRbkREqaYB7FViHXe4XI5ISXycO1cRrK1zN44veFyQaEfZYGDm/Ac9IiAX
1392
- xPcW6cTYcvnIc3zfFi8VqT79aie2oetaupgf1eNNZAqdE8hhuvU5HIe6uL17In/2
1393
- /qxAeeWsEG89jxt5dovEN7MhGITlNgDrYyCZuen+MwS7QcjBAvlEYyCegc5C09Y/
1394
- LHbTY5xZ3Y+m4Q6gLkH3LpVHz7z9M/P2C2F+fpErgUfCJzDupxBdN49cOSvkBPB7
1395
- jVaMaA==
1396
- -----END CERTIFICATE-----
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Gelf/Publisher.php CHANGED
@@ -2,77 +2,85 @@
2
 
3
  class Gelf_Publisher
4
  {
5
- /**
6
- * @var integer
7
- */
8
  const CHUNK_SIZE_WAN = 1420;
9
 
10
- /**
11
- * @var integer
12
- */
13
  const CHUNK_SIZE_LAN = 8154;
14
 
15
- /**
16
- * @var integer
17
- */
18
  const GRAYLOG2_DEFAULT_PORT = 12201;
19
 
 
 
20
  /**
21
  * @var string
22
  */
23
- const GRAYLOG2_PROTOCOL_VERSION = '1.0';
24
 
25
  /**
26
- * @var string
27
  */
28
- protected $hostname = null;
29
 
30
  /**
31
- * @var integer
32
  */
33
- protected $port = null;
34
 
35
  /**
36
- * @var integer
37
  */
38
- protected $chunkSize = null;
39
 
40
  /**
41
- * @var resource
42
  */
43
  protected $streamSocketClient = null;
44
 
 
 
 
 
 
45
  /**
46
  * Creates a new publisher that sends errors to a Graylog2 server via UDP
47
  *
48
  * @throws InvalidArgumentException
49
  *
50
- * @param string $hostname
51
- * @param integer $port
52
- * @param integer $chunkSize
 
53
  */
54
- public function __construct($hostname, $port = self::GRAYLOG2_DEFAULT_PORT, $chunkSize = self::CHUNK_SIZE_WAN)
55
  {
56
  // Check whether the parameters are set correctly
57
  if (!$hostname) {
58
  throw new InvalidArgumentException('$hostname must be set');
59
  }
60
 
61
- if (!is_numeric($port)) {
 
 
62
  throw new InvalidArgumentException('$port must be an integer');
63
  }
64
 
65
- if (!is_numeric($chunkSize)) {
 
 
 
 
 
 
66
  throw new InvalidArgumentException('$chunkSize must be an integer');
67
  }
68
 
69
- $this->hostname = $hostname;
70
- $this->port = $port;
71
- $this->chunkSize = $chunkSize;
 
72
  }
73
 
74
  /**
75
- * Publishes a Gelf_Message, returns false if an error occured during write
76
  *
77
  * @throws UnexpectedValueException
78
  *
@@ -82,6 +90,9 @@ class Gelf_Publisher
82
  */
83
  public function publish(Gelf_Message $message)
84
  {
 
 
 
85
  // Check if required message parameters are set
86
  if (!$message->getShortMessage() || !$message->getHost()) {
87
  throw new UnexpectedValueException(
@@ -95,19 +106,26 @@ class Gelf_Publisher
95
  // Encode the message as json string and compress it using gzip
96
  $preparedMessage = $this->getPreparedMessage($message);
97
 
98
- // Open a udp connection to graylog server
 
 
99
  $socket = $this->getSocketConnection();
100
 
 
 
 
 
 
101
  // Several udp writes are required to publish the message
102
  if ($this->isMessageSizeGreaterChunkSize($preparedMessage)) {
103
  // A unique id which consists of the microtime and a random value
104
  $messageId = $this->getMessageId();
105
 
106
- // Split the message into chunks
107
  $messageChunks = $this->getMessageChunks($preparedMessage);
108
  $messageChunksCount = count($messageChunks);
109
 
110
- // Send chunks to graylog server
111
  foreach (array_values($messageChunks) as $messageChunkIndex => $messageChunk) {
112
  $bytesWritten = $this->writeMessageChunkToSocket(
113
  $socket,
@@ -149,14 +167,16 @@ class Gelf_Publisher
149
  }
150
 
151
  /**
152
- * @return resource
153
  */
154
  protected function getSocketConnection()
155
  {
156
  if (!$this->streamSocketClient) {
157
- $this->streamSocketClient = stream_socket_client(sprintf('udp://%s:%d',
158
- gethostbyname($this->hostname),
159
- $this->port));
 
 
160
  }
161
 
162
  return $this->streamSocketClient;
@@ -177,7 +197,7 @@ class Gelf_Publisher
177
  */
178
  protected function getMessageId()
179
  {
180
- return (float) (microtime(true).mt_rand(0, 10000));
181
  }
182
 
183
  /**
2
 
3
  class Gelf_Publisher
4
  {
 
 
 
5
  const CHUNK_SIZE_WAN = 1420;
6
 
 
 
 
7
  const CHUNK_SIZE_LAN = 8154;
8
 
 
 
 
9
  const GRAYLOG2_DEFAULT_PORT = 12201;
10
 
11
+ const GRAYLOG2_PROTOCOL_VERSION = '1.0';
12
+
13
  /**
14
  * @var string
15
  */
16
+ protected $hostname;
17
 
18
  /**
19
+ * @var int
20
  */
21
+ protected $port;
22
 
23
  /**
24
+ * @var int|null
25
  */
26
+ protected $fallbackPort;
27
 
28
  /**
29
+ * @var int
30
  */
31
+ protected $chunkSize;
32
 
33
  /**
34
+ * @var resource|null
35
  */
36
  protected $streamSocketClient = null;
37
 
38
+ /**
39
+ * @var bool
40
+ */
41
+ private static $brokenSocket = false;
42
+
43
  /**
44
  * Creates a new publisher that sends errors to a Graylog2 server via UDP
45
  *
46
  * @throws InvalidArgumentException
47
  *
48
+ * @param string $hostname
49
+ * @param integer $port
50
+ * @param integer|null $fallbackPort
51
+ * @param integer $chunkSize
52
  */
53
+ public function __construct($hostname, $port = null, $fallbackPort = null, $chunkSize = null)
54
  {
55
  // Check whether the parameters are set correctly
56
  if (!$hostname) {
57
  throw new InvalidArgumentException('$hostname must be set');
58
  }
59
 
60
+ if ($port === null) {
61
+ $port = self::GRAYLOG2_DEFAULT_PORT;
62
+ } elseif (!is_numeric($port)) {
63
  throw new InvalidArgumentException('$port must be an integer');
64
  }
65
 
66
+ if ($fallbackPort !== null && !is_numeric($fallbackPort)) {
67
+ throw new InvalidArgumentException('$fallbackPort must be an integer');
68
+ }
69
+
70
+ if ($chunkSize === null) {
71
+ $chunkSize = self::CHUNK_SIZE_WAN;
72
+ } elseif (!is_numeric($chunkSize)) {
73
  throw new InvalidArgumentException('$chunkSize must be an integer');
74
  }
75
 
76
+ $this->hostname = $hostname;
77
+ $this->port = $port;
78
+ $this->fallbackPort = $fallbackPort;
79
+ $this->chunkSize = $chunkSize;
80
  }
81
 
82
  /**
83
+ * Publishes a Gelf_Message, returns false if an error occurred during write.
84
  *
85
  * @throws UnexpectedValueException
86
  *
90
  */
91
  public function publish(Gelf_Message $message)
92
  {
93
+ if (self::$brokenSocket) {
94
+ return false;
95
+ }
96
  // Check if required message parameters are set
97
  if (!$message->getShortMessage() || !$message->getHost()) {
98
  throw new UnexpectedValueException(
106
  // Encode the message as json string and compress it using gzip
107
  $preparedMessage = $this->getPreparedMessage($message);
108
 
109
+ // Infinite-loop break.
110
+ self::$brokenSocket = true;
111
+ // Open a connection to GrayLog server.
112
  $socket = $this->getSocketConnection();
113
 
114
+ if (!$socket) {
115
+ return false;
116
+ }
117
+ self::$brokenSocket = false;
118
+
119
  // Several udp writes are required to publish the message
120
  if ($this->isMessageSizeGreaterChunkSize($preparedMessage)) {
121
  // A unique id which consists of the microtime and a random value
122
  $messageId = $this->getMessageId();
123
 
124
+ // Split the message into chunks.
125
  $messageChunks = $this->getMessageChunks($preparedMessage);
126
  $messageChunksCount = count($messageChunks);
127
 
128
+ // Send chunks to GrayLog server.
129
  foreach (array_values($messageChunks) as $messageChunkIndex => $messageChunk) {
130
  $bytesWritten = $this->writeMessageChunkToSocket(
131
  $socket,
167
  }
168
 
169
  /**
170
+ * @return resource|false
171
  */
172
  protected function getSocketConnection()
173
  {
174
  if (!$this->streamSocketClient) {
175
+ $hostname = gethostbyname($this->hostname);
176
+ $this->streamSocketClient = stream_socket_client(sprintf('udp://%s:%d', $hostname, $this->port));
177
+ if ($this->streamSocketClient === false && $this->fallbackPort) {
178
+ $this->streamSocketClient = stream_socket_client(sprintf('tcp://%s:%d', $hostname, $this->fallbackPort));
179
+ }
180
  }
181
 
182
  return $this->streamSocketClient;
197
  */
198
  protected function getMessageId()
199
  {
200
+ return (float)(microtime(true).mt_rand(0, 10000));
201
  }
202
 
203
  /**
src/Gelf/index.php ADDED
@@ -0,0 +1,2 @@
 
 
1
+ <?php
2
+ // Silence is golden.
src/Google/ApiClient.php DELETED
@@ -1,629 +0,0 @@
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
- * The Google API Client
20
- * http://code.google.com/p/google-api-php-client/
21
- *
22
- * @author Chris Chabot <chabotc@google.com>
23
- * @author Chirag Shah <chirags@google.com>
24
- */
25
- class Google_ApiClient
26
- {
27
- const LIBVER = "1.0.3-beta";
28
- const USER_AGENT_SUFFIX = "google-api-php-client/";
29
- /**
30
- * @var Google_Auth_Abstract $auth
31
- */
32
- private $auth;
33
-
34
- /**
35
- * @var Google_IO_Abstract $io
36
- */
37
- private $io;
38
-
39
- /**
40
- * @var Google_Cache_Abstract $cache
41
- */
42
- private $cache;
43
-
44
- /**
45
- * @var Google_Config $config
46
- */
47
- private $config;
48
-
49
- /**
50
- * @var boolean $deferExecution
51
- */
52
- private $deferExecution = false;
53
-
54
- /** @var array $scopes */
55
- // Scopes requested by the client
56
- protected $requestedScopes = array();
57
-
58
- // definitions of services that are discovered.
59
- protected $services = array();
60
-
61
- // Used to track authenticated state, can't discover services after doing authenticate()
62
- private $authenticated = false;
63
-
64
- /**
65
- * Construct the Google Client.
66
- *
67
- * @param $config Google_Config or string for the ini file to load
68
- */
69
- public function __construct($config = null)
70
- {
71
- if (!ini_get('date.timezone') &&
72
- function_exists('date_default_timezone_set')
73
- ) {
74
- date_default_timezone_set('UTC');
75
- }
76
-
77
- if (is_string($config) && strlen($config)) {
78
- $config = new Google_Config($config);
79
- } elseif (!($config instanceof Google_Config)) {
80
- $config = new Google_Config();
81
-
82
- if ($this->isAppEngine()) {
83
- // Automatically use Memcache if we're in AppEngine.
84
- $config->setCacheClass('Google_Cache_Memcache');
85
- }
86
-
87
- if (version_compare(phpversion(), "5.3.4", "<=") || $this->isAppEngine()) {
88
- // Automatically disable compress.zlib, as currently unsupported.
89
- $config->setClassConfig('Google_Http_Request', 'disable_gzip', true);
90
- }
91
- }
92
-
93
- if ($config->getIoClass() == Google_Config::USE_AUTO_IO_SELECTION) {
94
- if (function_exists('curl_version')) {
95
- $config->setIoClass("Google_IO_Curl");
96
- } else {
97
- $config->setIoClass("Google_IO_Stream");
98
- }
99
- }
100
-
101
- $this->config = $config;
102
- }
103
-
104
- /**
105
- * Get a string containing the version of the library.
106
- *
107
- * @return string
108
- */
109
- public function getLibraryVersion()
110
- {
111
- return self::LIBVER;
112
- }
113
-
114
- /**
115
- * Attempt to exchange a code for an valid authentication token.
116
- * Helper wrapped around the OAuth 2.0 implementation.
117
- *
118
- * @param $code string code from accounts.google.com
119
- *
120
- * @return string token
121
- */
122
- public function authenticate($code)
123
- {
124
- $this->authenticated = true;
125
-
126
- return $this->getAuth()->authenticate($code);
127
- }
128
-
129
- /**
130
- * Set the auth config from the JSON string provided.
131
- * This structure should match the file downloaded from
132
- * the "Download JSON" button on in the Google Developer
133
- * Console.
134
- *
135
- * @param string $json the configuration json
136
- */
137
- public function setAuthConfig($json)
138
- {
139
- $data = json_decode($json);
140
- $key = isset($data->installed) ? 'installed' : 'web';
141
- if (!isset($data->$key)) {
142
- throw new Google_ApiException("Invalid client secret JSON file.");
143
- }
144
- $this->setClientId($data->$key->client_id);
145
- $this->setClientSecret($data->$key->client_secret);
146
- if (isset($data->$key->redirect_uris)) {
147
- $this->setRedirectUri($data->$key->redirect_uris[0]);
148
- }
149
- }
150
-
151
- /**
152
- * Set the auth config from the JSON file in the path
153
- * provided. This should match the file downloaded from
154
- * the "Download JSON" button on in the Google Developer
155
- * Console.
156
- *
157
- * @param string $file the file location of the client json
158
- */
159
- public function setAuthConfigFile($file)
160
- {
161
- $this->setAuthConfig(file_get_contents($file));
162
- }
163
-
164
- /**
165
- * @return array
166
- * @visible For Testing
167
- */
168
- public function prepareScopes()
169
- {
170
- if (empty($this->requestedScopes)) {
171
- throw new Google_Auth_Exception("No scopes specified");
172
- }
173
- $scopes = implode(' ', $this->requestedScopes);
174
-
175
- return $scopes;
176
- }
177
-
178
- /**
179
- * Set the OAuth 2.0 access token using the string that resulted from calling createAuthUrl()
180
- * or Google_ApiClient#getAccessToken().
181
- *
182
- * @param string $accessToken JSON encoded string containing in the following format:
183
- * {"access_token":"TOKEN", "refresh_token":"TOKEN", "token_type":"Bearer",
184
- * "expires_in":3600, "id_token":"TOKEN", "created":1320790426}
185
- */
186
- public function setAccessToken($accessToken)
187
- {
188
- if ($accessToken == 'null') {
189
- $accessToken = null;
190
- }
191
- $this->getAuth()->setAccessToken($accessToken);
192
- }
193
-
194
- /**
195
- * Set the authenticator object
196
- *
197
- * @param Google_Auth_Abstract $auth
198
- */
199
- public function setAuth(Google_Auth_Abstract $auth)
200
- {
201
- $this->config->setAuthClass(get_class($auth));
202
- $this->auth = $auth;
203
- }
204
-
205
- /**
206
- * Set the IO object
207
- *
208
- * @param Google_Io_Abstract $auth
209
- */
210
- public function setIo(Google_Io_Abstract $io)
211
- {
212
- $this->config->setIoClass(get_class($io));
213
- $this->io = $io;
214
- }
215
-
216
- /**
217
- * Set the Cache object
218
- *
219
- * @param Google_Cache_Abstract $auth
220
- */
221
- public function setCache(Google_Cache_Abstract $cache)
222
- {
223
- $this->config->setCacheClass(get_class($cache));
224
- $this->cache = $cache;
225
- }
226
-
227
- /**
228
- * Construct the OAuth 2.0 authorization request URI.
229
- * @return string
230
- */
231
- public function createAuthUrl()
232
- {
233
- $scopes = $this->prepareScopes();
234
-
235
- return $this->getAuth()->createAuthUrl($scopes);
236
- }
237
-
238
- /**
239
- * Get the OAuth 2.0 access token.
240
- * @return string $accessToken JSON encoded string in the following format:
241
- * {"access_token":"TOKEN", "refresh_token":"TOKEN", "token_type":"Bearer",
242
- * "expires_in":3600,"id_token":"TOKEN", "created":1320790426}
243
- */
244
- public function getAccessToken()
245
- {
246
- $token = $this->getAuth()->getAccessToken();
247
- // The response is json encoded, so could be the string null.
248
- // It is arguable whether this check should be here or lower
249
- // in the library.
250
- return (null == $token || 'null' == $token) ? null : $token;
251
- }
252
-
253
- /**
254
- * Returns if the access_token is expired.
255
- * @return bool Returns True if the access_token is expired.
256
- */
257
- public function isAccessTokenExpired()
258
- {
259
- return $this->getAuth()->isAccessTokenExpired();
260
- }
261
-
262
- /**
263
- * Set OAuth 2.0 "state" parameter to achieve per-request customization.
264
- * @see http://tools.ietf.org/html/draft-ietf-oauth-v2-22#section-3.1.2.2
265
- *
266
- * @param string $state
267
- */
268
- public function setState($state)
269
- {
270
- $this->getAuth()->setState($state);
271
- }
272
-
273
- /**
274
- * @param string $accessType Possible values for access_type include:
275
- * {@code "offline"} to request offline access from the user.
276
- * {@code "online"} to request online access from the user.
277
- */
278
- public function setAccessType($accessType)
279
- {
280
- $this->config->setAccessType($accessType);
281
- }
282
-
283
- /**
284
- * @param string $approvalPrompt Possible values for approval_prompt include:
285
- * {@code "force"} to force the approval UI to appear. (This is the default value)
286
- * {@code "auto"} to request auto-approval when possible.
287
- */
288
- public function setApprovalPrompt($approvalPrompt)
289
- {
290
- $this->config->setApprovalPrompt($approvalPrompt);
291
- }
292
-
293
- /**
294
- * Set the application name, this is included in the User-Agent HTTP header.
295
- *
296
- * @param string $applicationName
297
- */
298
- public function setApplicationName($applicationName)
299
- {
300
- $this->config->setApplicationName($applicationName);
301
- }
302
-
303
- /**
304
- * Set the OAuth 2.0 Client ID.
305
- *
306
- * @param string $clientId
307
- */
308
- public function setClientId($clientId)
309
- {
310
- $this->config->setClientId($clientId);
311
- }
312
-
313
- /**
314
- * Set the OAuth 2.0 Client Secret.
315
- *
316
- * @param string $clientSecret
317
- */
318
- public function setClientSecret($clientSecret)
319
- {
320
- $this->config->setClientSecret($clientSecret);
321
- }
322
-
323
- /**
324
- * Set the OAuth 2.0 Redirect URI.
325
- *
326
- * @param string $redirectUri
327
- */
328
- public function setRedirectUri($redirectUri)
329
- {
330
- $this->config->setRedirectUri($redirectUri);
331
- }
332
-
333
- /**
334
- * If 'plus.login' is included in the list of requested scopes, you can use
335
- * this method to define types of app activities that your app will write.
336
- * You can find a list of available types here:
337
- * @link https://developers.google.com/+/api/moment-types
338
- *
339
- * @param array $requestVisibleActions Array of app activity types
340
- */
341
- public function setRequestVisibleActions($requestVisibleActions)
342
- {
343
- if (is_array($requestVisibleActions)) {
344
- $requestVisibleActions = join(" ", $requestVisibleActions);
345
- }
346
- $this->config->setRequestVisibleActions($requestVisibleActions);
347
- }
348
-
349
- /**
350
- * Set the developer key to use, these are obtained through the API Console.
351
- * @see http://code.google.com/apis/console-help/#generatingdevkeys
352
- *
353
- * @param string $developerKey
354
- */
355
- public function setDeveloperKey($developerKey)
356
- {
357
- $this->config->setDeveloperKey($developerKey);
358
- }
359
-
360
- /**
361
- * Fetches a fresh OAuth 2.0 access token with the given refresh token.
362
- *
363
- * @param string $refreshToken
364
- *
365
- * @return void
366
- */
367
- public function refreshToken($refreshToken)
368
- {
369
- return $this->getAuth()->refreshToken($refreshToken);
370
- }
371
-
372
- /**
373
- * Revoke an OAuth2 access token or refresh token. This method will revoke the current access
374
- * token, if a token isn't provided.
375
- * @throws Google_Auth_Exception
376
- *
377
- * @param string|null $token The token (access token or a refresh token) that should be revoked.
378
- *
379
- * @return boolean Returns True if the revocation was successful, otherwise False.
380
- */
381
- public function revokeToken($token = null)
382
- {
383
- return $this->getAuth()->revokeToken($token);
384
- }
385
-
386
- /**
387
- * Verify an id_token. This method will verify the current id_token, if one
388
- * isn't provided.
389
- * @throws Google_Auth_Exception
390
- *
391
- * @param string|null $token The token (id_token) that should be verified.
392
- *
393
- * @return Google_Auth_LoginTicket Returns an apiLoginTicket if the verification was
394
- * successful.
395
- */
396
- public function verifyIdToken($token = null)
397
- {
398
- return $this->getAuth()->verifyIdToken($token);
399
- }
400
-
401
- /**
402
- * Verify a JWT that was signed with your own certificates.
403
- *
404
- * @param $jwt the token
405
- * @param $certs array of certificates
406
- * @param $required_audience the expected consumer of the token
407
- * @param [$issuer] the expected issues, defaults to Google
408
- * @param [$max_expiry] the max lifetime of a token, defaults to MAX_TOKEN_LIFETIME_SECS
409
- *
410
- * @return token information if valid, false if not
411
- */
412
- public function verifySignedJwt($id_token, $cert_location, $audience, $issuer, $max_expiry = null)
413
- {
414
- $auth = new Google_Auth_OAuth2($this);
415
- $certs = $auth->retrieveCertsFromLocation($cert_location);
416
-
417
- return $auth->verifySignedJwtWithCerts($id_token, $certs, $audience, $issuer, $max_expiry);
418
- }
419
-
420
- /**
421
- * @param Google_Auth_AssertionCredentials $creds
422
- *
423
- * @return void
424
- */
425
- public function setAssertionCredentials(Google_Auth_AssertionCredentials $creds)
426
- {
427
- $this->getAuth()->setAssertionCredentials($creds);
428
- }
429
-
430
- /**
431
- * Set the scopes to be requested. Must be called before createAuthUrl().
432
- * Will remove any previously configured scopes.
433
- *
434
- * @param array $scopes , ie: array('https://www.googleapis.com/auth/plus.login',
435
- * 'https://www.googleapis.com/auth/moderator')
436
- */
437
- public function setScopes($scopes)
438
- {
439
- $this->requestedScopes = array();
440
- $this->addScope($scopes);
441
- }
442
-
443
- /**
444
- * This functions adds a scope to be requested as part of the OAuth2.0 flow.
445
- * Will append any scopes not previously requested to the scope parameter.
446
- * A single string will be treated as a scope to request. An array of strings
447
- * will each be appended.
448
- *
449
- * @param $scope_or_scopes string|array e.g. "profile"
450
- */
451
- public function addScope($scope_or_scopes)
452
- {
453
- if (is_string($scope_or_scopes) && !in_array($scope_or_scopes, $this->requestedScopes)) {
454
- $this->requestedScopes[] = $scope_or_scopes;
455
- } elseif (is_array($scope_or_scopes)) {
456
- foreach ($scope_or_scopes as $scope) {
457
- $this->addScope($scope);
458
- }
459
- }
460
- }
461
-
462
- /**
463
- * Returns the list of scopes requested by the client
464
- * @return array the list of scopes
465
- *
466
- */
467
- public function getScopes()
468
- {
469
- return $this->requestedScopes;
470
- }
471
-
472
- /**
473
- * Declare whether batch calls should be used. This may increase throughput
474
- * by making multiple requests in one connection.
475
- *
476
- * @param boolean $useBatch True if the batch support should
477
- * be enabled. Defaults to False.
478
- */
479
- public function setUseBatch($useBatch)
480
- {
481
- // This is actually an alias for setDefer.
482
- $this->setDefer($useBatch);
483
- }
484
-
485
- /**
486
- * Declare whether making API calls should make the call immediately, or
487
- * return a request which can be called with ->execute();
488
- *
489
- * @param boolean $defer True if calls should not be executed right away.
490
- */
491
- public function setDefer($defer)
492
- {
493
- $this->deferExecution = $defer;
494
- }
495
-
496
- /**
497
- * Helper method to execute deferred HTTP requests.
498
- *
499
- * @returns object of the type of the expected class or array.
500
- */
501
- public function execute($request)
502
- {
503
- if ($request instanceof Google_Http_Request) {
504
- $request->setUserAgent(
505
- $this->getApplicationName()
506
- ." ".self::USER_AGENT_SUFFIX
507
- .$this->getLibraryVersion()
508
- );
509
- if (!$this->getClassConfig("Google_Http_Request", "disable_gzip")) {
510
- $request->enableGzip();
511
- }
512
- $request->maybeMoveParametersToBody();
513
-
514
- return Google_Http_REST::execute($this, $request);
515
- } elseif ($request instanceof Google_Http_Batch) {
516
- return $request->execute();
517
- } else {
518
- throw new Google_ApiException("Do not know how to execute this type of object.");
519
- }
520
- }
521
-
522
- /**
523
- * Whether or not to return raw requests
524
- * @return boolean
525
- */
526
- public function shouldDefer()
527
- {
528
- return $this->deferExecution;
529
- }
530
-
531
- /**
532
- * @return Google_Auth_Abstract Authentication implementation
533
- */
534
- public function getAuth()
535
- {
536
- if (!isset($this->auth)) {
537
- $class = $this->config->getAuthClass();
538
- $this->auth = new $class($this);
539
- }
540
-
541
- return $this->auth;
542
- }
543
-
544
- /**
545
- * @return Google_IO_Abstract IO implementation
546
- */
547
- public function getIo()
548
- {
549
- if (!isset($this->io)) {
550
- $class = $this->config->getIoClass();
551
- $this->io = new $class($this);
552
- }
553
-
554
- return $this->io;
555
- }
556
-
557
- /**
558
- * @return Google_Cache_Abstract Cache implementation
559
- */
560
- public function getCache()
561
- {
562
- if (!isset($this->cache)) {
563
- $class = $this->config->getCacheClass();
564
- $this->cache = new $class($this);
565
- }
566
-
567
- return $this->cache;
568
- }
569
-
570
- /**
571
- * Retrieve custom configuration for a specific class.
572
- *
573
- * @param $class string|object - class or instance of class to retrieve
574
- * @param $key string optional - key to retrieve
575
- */
576
- public function getClassConfig($class, $key = null)
577
- {
578
- if (!is_string($class)) {
579
- $class = get_class($class);
580
- }
581
-
582
- return $this->config->getClassConfig($class, $key);
583
- }
584
-
585
- /**
586
- * Set configuration specific to a given class.
587
- * $config->setClassConfig('Google_Cache_File',
588
- * array('directory' => '/tmp/cache'));
589
- *
590
- * @param $class The class name for the configuration
591
- * @param $config string key or an array of configuration values
592
- * @param $value optional - if $config is a key, the value
593
- *
594
- */
595
- public function setClassConfig($class, $config, $value = null)
596
- {
597
- if (!is_string($class)) {
598
- $class = get_class($class);
599
- }
600
-
601
- return $this->config->setClassConfig($class, $config, $value);
602
- }
603
-
604
- /**
605
- * @return string the base URL to use for calls to the APIs
606
- */
607
- public function getBasePath()
608
- {
609
- return $this->config->getBasePath();
610
- }
611
-
612
- /**
613
- * @return string the name of the application
614
- */
615
- public function getApplicationName()
616
- {
617
- return $this->config->getApplicationName();
618
- }
619
-
620
- /**
621
- * Are we running in Google AppEngine?
622
- * return bool
623
- */
624
- public function isAppEngine()
625
- {
626
- return (isset($_SERVER['SERVER_SOFTWARE']) &&
627
- strpos($_SERVER['SERVER_SOFTWARE'], 'Google App Engine') !== false);
628
- }
629
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Google/ApiException.php DELETED
@@ -1,21 +0,0 @@
1
- <?php
2
-
3
- /*
4
- * Copyright 2013 Google Inc.
5
- *
6
- * Licensed under the Apache License, Version 2.0 (the "License");
7
- * you may not use this file except in compliance with the License.
8
- * You may obtain a copy of the License at
9
- *
10
- * http://www.apache.org/licenses/LICENSE-2.0
11
- *
12
- * Unless required by applicable law or agreed to in writing, software
13
- * distributed under the License is distributed on an "AS IS" BASIS,
14
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
- * See the License for the specific language governing permissions and
16
- * limitations under the License.
17
- */
18
-
19
- class Google_ApiException extends Exception
20
- {
21
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Google/ApiModel.php DELETED
@@ -1,257 +0,0 @@
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
20
- * from a given json schema.
21
- * http://tools.ietf.org/html/draft-zyp-json-schema-03#section-5
22
- *
23
- * @author Chirag Shah <chirags@google.com>
24
- *
25
- */
26
- class Google_ApiModel implements ArrayAccess
27
- {
28
- protected $data = array();
29
- protected $processed = array();
30
-
31
- /**
32
- * Polymorphic - accepts a variable number of arguments dependent
33
- * on the type of the model subclass.
34
- */
35
- public function __construct()
36
- {
37
- if (func_num_args() == 1 && is_array(func_get_arg(0))) {
38
- // Initialize the model with the array's contents.
39
- $array = func_get_arg(0);
40
- $this->mapTypes($array);
41
- }
42
- }
43
-
44
- public function __get($key)
45
- {
46
- $keyTypeName = $this->keyType($key);
47
- $keyDataType = $this->dataType($key);
48
- if (isset($this->$keyTypeName) && !isset($this->processed[$key])) {
49
- if (isset($this->data[$key])) {
50
- $val = $this->data[$key];
51
- } else {
52
- $val = null;
53
- }
54
-
55
- if ($this->isAssociativeArray($val)) {
56
- if (isset($this->$keyDataType) && 'map' == $this->$keyDataType) {
57
- foreach ($val as $arrayKey => $arrayItem) {
58
- $this->data[$key][$arrayKey] =
59
- $this->createObjectFromName($keyTypeName, $arrayItem);
60
- }
61
- } else {
62
- $this->data[$key] = $this->createObjectFromName($keyTypeName, $val);
63
- }
64
- } elseif (is_array($val)) {
65
- $arrayObject = array();
66
- foreach ($val as $arrayIndex => $arrayItem) {
67
- $arrayObject[$arrayIndex] =
68
- $this->createObjectFromName($keyTypeName, $arrayItem);
69
- }
70
- $this->data[$key] = $arrayObject;
71
- }
72
- $this->processed[$key] = true;
73
- }
74
-
75
- return $this->data[$key];
76
- }
77
-
78
- /**
79
- * Initialize this object's properties from an array.
80
- *
81
- * @param array $array Used to seed this object's properties.
82
- *
83
- * @return void
84
- */
85
- protected function mapTypes($array)
86
- {
87
- // Hard initilise simple types, lazy load more complex ones.
88
- foreach ($array as $key => $val) {
89
- if (!property_exists($this, $this->keyType($key)) &&
90
- property_exists($this, $key)
91
- ) {
92
- $this->$key = $val;
93
- unset($array[$key]);
94
- } elseif (property_exists($this, $camelKey = Google_ApiUtils::camelCase($key))) {
95
- // This checks if property exists as camelCase, leaving it in array as snake_case
96
- // in case of backwards compatibility issues.
97
- $this->$camelKey = $val;
98
- }
99
- }
100
- $this->data = $array;
101
- }
102
-
103
- /**
104
- * Create a simplified object suitable for straightforward
105
- * conversion to JSON. This is relatively expensive
106
- * due to the usage of reflection, but shouldn't be called
107
- * a whole lot, and is the most straightforward way to filter.
108
- */
109
- public function toSimpleObject()
110
- {
111
- $object = new stdClass();
112
-
113
- // Process all other data.
114
- foreach ($this->data as $key => $val) {
115
- $result = $this->getSimpleValue($val);
116
- if ($result != null) {
117
- $object->$key = $result;
118
- }
119
- }
120
-
121
- // Process all public properties.
122
- $reflect = new ReflectionObject($this);
123
- $props = $reflect->getProperties(ReflectionProperty::IS_PUBLIC);
124
- foreach ($props as $member) {
125
- $name = $member->getName();
126
- $result = $this->getSimpleValue($this->$name);
127
- if ($result != null) {
128
- $object->$name = $result;
129
- }
130
- }
131
-
132
- return $object;
133
- }
134
-
135
- /**
136
- * Handle different types of values, primarily
137
- * other objects and map and array data types.
138
- */
139
- private function getSimpleValue($value)
140
- {
141
- if ($value instanceof Google_ApiModel) {
142
- return $value->toSimpleObject();
143
- } elseif (is_array($value)) {
144
- $return = array();
145
- foreach ($value as $key => $a_value) {
146
- $a_value = $this->getSimpleValue($a_value);
147
- if ($a_value != null) {
148
- $return[$key] = $a_value;
149
- }
150
- }
151
-
152
- return $return;
153
- }
154
-
155
- return $value;
156
- }
157
-
158
- /**
159
- * Returns true only if the array is associative.
160
- *
161
- * @param array $array
162
- *
163
- * @return bool True if the array is associative.
164
- */
165
- protected function isAssociativeArray($array)
166
- {
167
- if (!is_array($array)) {
168
- return false;
169
- }
170
- $keys = array_keys($array);
171
- foreach ($keys as $key) {
172
- if (is_string($key)) {
173
- return true;
174
- }
175
- }
176
-
177
- return false;
178
- }
179
-
180
- /**
181
- * Given a variable name, discover its type.
182
- *
183
- * @param $name
184
- * @param $item
185
- *
186
- * @return object The object from the item.
187
- */
188
- private function createObjectFromName($name, $item)
189
- {
190
- $type = $this->$name;
191
-
192
- return new $type($item);
193
- }
194
-
195
- /**
196
- * Verify if $obj is an array.
197
- * @throws Google_ApiException Thrown if $obj isn't an array.
198
- *
199
- * @param array $obj Items that should be validated.
200
- * @param string $method Method expecting an array as an argument.
201
- */
202
- public function assertIsArray($obj, $method)
203
- {
204
- if ($obj && !is_array($obj)) {
205
- throw new Google_ApiException(
206
- "Incorrect parameter type passed to $method(). Expected an array."
207
- );
208
- }
209
- }
210
-
211
- public function offsetExists($offset)
212
- {
213
- return isset($this->$offset) || isset($this->data[$offset]);
214
- }
215
-
216
- public function offsetGet($offset)
217
- {
218
- return isset($this->$offset) ?
219
- $this->$offset :
220
- $this->__get($offset);
221
- }
222
-
223
- public function offsetSet($offset, $value)
224
- {
225
- if (property_exists($this, $offset)) {
226
- $this->$offset = $value;
227
- } else {
228
- $this->data[$offset] = $value;
229
- $this->processed[$offset] = true;
230
- }
231
- }
232
-
233
- public function offsetUnset($offset)
234
- {
235
- unset($this->data[$offset]);
236
- }
237
-
238
- protected function keyType($key)
239
- {
240
- return $key."Type";
241
- }
242
-
243
- protected function dataType($key)
244
- {
245
- return $key."DataType";
246
- }
247
-
248
- public function __isset($key)
249
- {
250
- return isset($this->data[$key]);
251
- }
252
-
253
- public function __unset($key)
254
- {
255
- unset($this->data[$key]);
256
- }
257
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Google/ApiService.php DELETED
@@ -1,41 +0,0 @@
1
- <?php
2
-
3
- /*
4
- * Copyright 2010 Google Inc.
5
- *
6
- * Licensed under the Apache License, Version 2.0 (the "License");
7
- * you may not use this file except in compliance with the License.
8
- * You may obtain a copy of the License at
9
- *
10
- * http://www.apache.org/licenses/LICENSE-2.0
11
- *
12
- * Unless required by applicable law or agreed to in writing, software
13
- * distributed under the License is distributed on an "AS IS" BASIS,
14
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
- * See the License for the specific language governing permissions and
16
- * limitations under the License.
17
- */
18
-
19
- class Google_ApiService
20
- {
21
- public $version;
22
- public $servicePath;
23
- public $availableScopes;
24
- public $resource;
25
- private $client;
26
-
27
- public function __construct(Google_ApiClient $client)
28
- {
29
- $this->client = $client;
30
- }
31
-
32
- /**
33
- * Return the associated Google_ApiClient class.
34
- *
35
- * @return Google_ApiClient
36
- */
37
- public function getClient()
38
- {
39
- return $this->client;
40
- }
41
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Google/ApiUtils.php DELETED
@@ -1,146 +0,0 @@
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_ApiUtils
25
- {
26
- public static function urlSafeB64Encode($data)
27
- {
28
- $b64 = base64_encode($data);
29
- $b64 = str_replace(
30
- array('+', '/', '\r', '\n', '='),
31
- array('-', '_'),
32
- $b64
33
- );
34
-
35
- return $b64;
36
- }
37
-
38
- public static function urlSafeB64Decode($b64)
39
- {
40
- $b64 = str_replace(
41
- array('-', '_'),
42
- array('+', '/'),
43
- $b64
44
- );
45
-
46
- return base64_decode($b64);
47
- }
48
-
49
- /**
50
- * Misc function used to count the number of bytes in a post body, in the
51
- * world of multi-byte chars and the unpredictability of
52
- * strlen/mb_strlen/sizeof, this is the only way to do that in a sane
53
- * manner at the moment.
54
- *
55
- * This algorithm was originally developed for the
56
- * Solar Framework by Paul M. Jones
57
- *
58
- * @link http://solarphp.com/
59
- * @link http://svn.solarphp.com/core/trunk/Solar/Json.php
60
- * @link http://framework.zend.com/svn/framework/standard/trunk/library/Zend/Json/Decoder.php
61
- *
62
- * @param string $str
63
- *
64
- * @return int The number of bytes in a string.
65
- */
66
- public static function getStrLen($str)
67
- {
68
- $strlenVar = strlen($str);
69
- $d = $ret = 0;
70
- for ($count = 0; $count < $strlenVar; ++$count) {
71
- $ordinalValue = ord($str{$ret});
72
- switch (true) {
73
- case (($ordinalValue >= 0x20) && ($ordinalValue <= 0x7F)):
74
- // characters U-00000000 - U-0000007F (same as ASCII)
75
- $ret++;
76
- break;
77
- case (($ordinalValue & 0xE0) == 0xC0):
78
- // characters U-00000080 - U-000007FF, mask 110XXXXX
79
- // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
80
- $ret += 2;
81
- break;
82
- case (($ordinalValue & 0xF0) == 0xE0):
83
- // characters U-00000800 - U-0000FFFF, mask 1110XXXX
84
- // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
85
- $ret += 3;
86
- break;
87
- case (($ordinalValue & 0xF8) == 0xF0):
88
- // characters U-00010000 - U-001FFFFF, mask 11110XXX
89
- // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
90
- $ret += 4;
91
- break;
92
- case (($ordinalValue & 0xFC) == 0xF8):
93
- // characters U-00200000 - U-03FFFFFF, mask 111110XX
94
- // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
95
- $ret += 5;
96
- break;
97
- case (($ordinalValue & 0xFE) == 0xFC):
98
- // characters U-04000000 - U-7FFFFFFF, mask 1111110X
99
- // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
100
- $ret += 6;
101
- break;
102
- default:
103
- $ret++;
104
- }
105
- }
106
-
107
- return $ret;
108
- }
109
-
110
- /**
111
- * Normalize all keys in an array to lower-case.
112
- *
113
- * @param array $arr
114
- *
115
- * @return array Normalized array.
116
- */
117
- public static function normalize($arr)
118
- {
119
- if (!is_array($arr)) {
120
- return array();
121
- }
122
-
123
- $normalized = array();
124
- foreach ($arr as $key => $val) {
125
- $normalized[strtolower($key)] = $val;
126
- }
127
-
128
- return $normalized;
129
- }
130
-
131
- /**
132
- * Convert a string to camelCase
133
- *
134
- * @param string $value
135
- *
136
- * @return string
137
- */
138
- public static function camelCase($value)
139
- {
140
- $value = ucwords(str_replace(array('-', '_'), ' ', $value));
141
- $value = str_replace(' ', '', $value);
142
- $value[0] = strtolower($value[0]);
143
-
144
- return $value;
145
- }
146
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Google/Auth/Abstract.php DELETED
@@ -1,46 +0,0 @@
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
- * Abstract class for the Authentication in the API client
20
- *
21
- * @author Chris Chabot <chabotc@google.com>
22
- *
23
- */
24
- abstract class Google_Auth_Abstract
25
- {
26
- /**
27
- * An utility function that first calls $this->auth->sign($request) and then
28
- * executes makeRequest() on that signed request. Used for when a request
29
- * should be authenticated
30
- *
31
- * @param Google_Http_Request $request
32
- *
33
- * @return Google_Http_Request $request
34
- */
35
- abstract public function authenticatedRequest(Google_Http_Request $request);
36
-
37
- abstract public function authenticate($code);
38
-
39
- abstract public function sign(Google_Http_Request $request);
40
-
41
- abstract public function createAuthUrl($scope);
42
-
43
- abstract public function refreshToken($refreshToken);
44
-
45
- abstract public function revokeToken();
46
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Google/Auth/AssertionCredentials.php DELETED
@@ -1,135 +0,0 @@
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_Auth_AssertionCredentials
24
- {
25
- const MAX_TOKEN_LIFETIME_SECS = 3600;
26
-
27
- public $serviceAccountName;
28
- public $scopes;
29
- public $privateKey;
30
- public $privateKeyPassword;
31
- public $assertionType;
32
- public $sub;
33
- /**
34
- * @deprecated
35
- * @link http://tools.ietf.org/html/draft-ietf-oauth-json-web-token-06
36
- */
37
- public $prn;
38
- private $useCache;
39
-
40
- /**
41
- * @param $serviceAccountName
42
- * @param $scopes array List of scopes
43
- * @param $privateKey
44
- * @param string $privateKeyPassword
45
- * @param string $assertionType
46
- * @param bool|string $sub The email address of the user for which the
47
- * application is requesting delegated access.
48
- * @param bool useCache Whether to generate a cache key and allow
49
- * automatic caching of the generated token.
50
- */
51
- public function __construct(
52
- $serviceAccountName,
53
- $scopes,
54
- $privateKey,
55
- $privateKeyPassword = 'notasecret',
56
- $assertionType = 'http://oauth.net/grant_type/jwt/1.0/bearer',
57
- $sub = false,
58
- $useCache = true
59
- ) {
60
- $this->serviceAccountName = $serviceAccountName;
61
- $this->scopes = is_string($scopes) ? $scopes : implode(' ', $scopes);
62
- $this->privateKey = $privateKey;
63
- $this->privateKeyPassword = $privateKeyPassword;
64
- $this->assertionType = $assertionType;
65
- $this->sub = $sub;
66
- $this->prn = $sub;
67
- $this->useCache = $useCache;
68
- }
69
-
70
- /**
71
- * Generate a unique key to represent this credential.
72
- *
73
- * @return string
74
- */
75
- public function getCacheKey()
76
- {
77
- if (!$this->useCache) {
78
- return false;
79
- }
80
- $h = $this->sub;
81
- $h .= $this->assertionType;
82
- $h .= $this->privateKey;
83
- $h .= $this->scopes;
84
- $h .= $this->serviceAccountName;
85
-
86
- return md5($h);
87
- }
88
-
89
- public function generateAssertion()
90
- {
91
- $now = time();
92
-
93
- $jwtParams = array(
94
- 'aud' => Google_Auth_OAuth2::OAUTH2_TOKEN_URI,
95
- 'scope' => $this->scopes,
96
- 'iat' => $now,
97
- 'exp' => $now + self::MAX_TOKEN_LIFETIME_SECS,
98
- 'iss' => $this->serviceAccountName,
99
- );
100
-
101
- if ($this->sub !== false) {
102
- $jwtParams['sub'] = $this->sub;
103
- } else {
104
- if ($this->prn !== false) {
105
- $jwtParams['prn'] = $this->prn;
106
- }
107
- }
108
-
109
- return $this->makeSignedJwt($jwtParams);
110
- }
111
-
112
- /**
113
- * Creates a signed JWT.
114
- *
115
- * @param array $payload
116
- *
117
- * @return string The signed JWT.
118
- */
119
- private function makeSignedJwt($payload)
120
- {
121
- $header = array('typ' => 'JWT', 'alg' => 'RS256');
122
-
123
- $segments = array(
124
- Google_ApiUtils::urlSafeB64Encode(json_encode($header)),
125
- Google_ApiUtils::urlSafeB64Encode(json_encode($payload)),
126
- );
127
-
128
- $signingInput = implode('.', $segments);
129
- $signer = new Google_Signer_P12($this->privateKey, $this->privateKeyPassword);
130
- $signature = $signer->sign($signingInput);
131
- $segments[] = Google_ApiUtils::urlSafeB64Encode($signature);
132
-
133
- return implode(".", $segments);
134
- }
135
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Google/Auth/Exception.php DELETED
@@ -1,21 +0,0 @@
1
- <?php
2
-
3
- /*
4
- * Copyright 2013 Google Inc.
5
- *
6
- * Licensed under the Apache License, Version 2.0 (the "License");
7
- * you may not use this file except in compliance with the License.
8
- * You may obtain a copy of the License at
9
- *
10
- * http://www.apache.org/licenses/LICENSE-2.0
11
- *
12
- * Unless required by applicable law or agreed to in writing, software
13
- * distributed under the License is distributed on an "AS IS" BASIS,
14
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
- * See the License for the specific language governing permissions and
16
- * limitations under the License.
17
- */
18
-
19
- class Google_Auth_Exception extends Google_ApiException
20
- {
21
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Google/Auth/LoginTicket.php DELETED
@@ -1,69 +0,0 @@
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_Auth_LoginTicket
24
- {
25
- const USER_ATTR = "sub";
26
-
27
- // Information from id token envelope.
28
- private $envelope;
29
-
30
- // Information from id token payload.
31
- private $payload;
32
-
33
- /**
34
- * Creates a user based on the supplied token.
35
- *
36
- * @param string $envelope Header from a verified authentication token.
37
- * @param string $payload Information from a verified authentication token.
38
- */
39
- public function __construct($envelope, $payload)
40
- {
41
- $this->envelope = $envelope;
42
- $this->payload = $payload;
43
- }
44
-
45
- /**
46
- * Returns the numeric identifier for the user.
47
- *
48
- * @throws Google_Auth_Exception
49
- * @return
50
- */
51
- public function getUserId()
52
- {
53
- if (array_key_exists(self::USER_ATTR, $this->payload)) {
54
- return $this->payload[self::USER_ATTR];
55
- }
56
- throw new Google_Auth_Exception("No user_id in token");
57
- }
58
-
59
- /**
60
- * Returns attributes from the login ticket. This can contain
61
- * various information about the user session.
62
- *
63
- * @return array
64
- */
65
- public function getAttributes()
66
- {
67
- return array("envelope" => $this->envelope, "payload" => $this->payload);
68
- }
69
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Google/Auth/OAuth2.php DELETED
@@ -1,592 +0,0 @@
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
- * Authentication class that deals with the OAuth 2 web-server authentication flow
20
- *
21
- * @author Chris Chabot <chabotc@google.com>
22
- * @author Chirag Shah <chirags@google.com>
23
- *
24
- */
25
- class Google_Auth_OAuth2 extends Google_Auth_Abstract
26
- {
27
- const OAUTH2_REVOKE_URI = 'https://accounts.google.com/o/oauth2/revoke';
28
- const OAUTH2_TOKEN_URI = 'https://accounts.google.com/o/oauth2/token';
29
- const OAUTH2_AUTH_URL = 'https://accounts.google.com/o/oauth2/auth';
30
- const CLOCK_SKEW_SECS = 300; // five minutes in seconds
31
- const AUTH_TOKEN_LIFETIME_SECS = 300; // five minutes in seconds
32
- const MAX_TOKEN_LIFETIME_SECS = 86400; // one day in seconds
33
- const OAUTH2_ISSUER = 'accounts.google.com';
34
-
35
- /** @var Google_Auth_AssertionCredentials $assertionCredentials */
36
- private $assertionCredentials;
37
-
38
- /**
39
- * @var string The state parameters for CSRF and other forgery protection.
40
- */
41
- private $state;
42
-
43
- /**
44
- * @var string The token bundle.
45
- */
46
- private $token;
47
-
48
- /**
49
- * @var Google_Client the base client
50
- */
51
- private $client;
52
-
53
- /**
54
- * Instantiates the class, but does not initiate the login flow, leaving it
55
- * to the discretion of the caller.
56
- */
57
- public function __construct(Google_ApiClient $client)
58
- {
59
- $this->client = $client;
60
- }
61
-
62
- /**
63
- * Perform an authenticated / signed apiHttpRequest.
64
- * This function takes the apiHttpRequest, calls apiAuth->sign on it
65
- * (which can modify the request in what ever way fits the auth mechanism)
66
- * and then calls apiCurlIO::makeRequest on the signed request
67
- *
68
- * @param Google_Http_Request $request
69
- *
70
- * @return Google_Http_Request The resulting HTTP response including the
71
- * responseHttpCode, responseHeaders and responseBody.
72
- */
73
- public function authenticatedRequest(Google_Http_Request $request)
74
- {
75
- $request = $this->sign($request);
76
-
77
- return $this->client->getIo()->makeRequest($request);
78
- }
79
-
80
- /**
81
- * @param string $code
82
- *
83
- * @throws Google_Auth_Exception
84
- * @return string
85
- */
86
- public function authenticate($code)
87
- {
88
- if (strlen($code) == 0) {
89
- throw new Google_Auth_Exception("Invalid code");
90
- }
91
-
92
- // We got here from the redirect from a successful authorization grant,
93
- // fetch the access token
94
- $request = new Google_Http_Request(
95
- self::OAUTH2_TOKEN_URI,
96
- 'POST',
97
- array(),
98
- array(
99
- 'code' => $code,
100
- 'grant_type' => 'authorization_code',
101
- 'redirect_uri' => $this->client->getClassConfig($this, 'redirect_uri'),
102
- 'client_id' => $this->client->getClassConfig($this, 'client_id'),
103
- 'client_secret' => $this->client->getClassConfig($this, 'client_secret'),
104
- )
105
- );
106
- $request->disableGzip();
107
- $response = $this->client->getIo()->makeRequest($request);
108
-
109
- if ($response->getResponseHttpCode() == 200) {
110
- $this->setAccessToken($response->getResponseBody());
111
- $this->token['created'] = time();
112
-
113
- return $this->getAccessToken();
114
- } else {
115
- $decodedResponse = json_decode($response->getResponseBody(), true);
116
- if ($decodedResponse != null && $decodedResponse['error']) {
117
- $decodedResponse = $decodedResponse['error'];
118
- }
119
- throw new Google_Auth_Exception(
120
- sprintf(
121
- "Error fetching OAuth2 access token, message: '%s'",
122
- $decodedResponse
123
- ),
124
- $response->getResponseHttpCode()
125
- );
126
- }
127
- }
128
-
129
- /**
130
- * Create a URL to obtain user authorization.
131
- * The authorization endpoint allows the user to first
132
- * authenticate, and then grant/deny the access request.
133
- *
134
- * @param string $scope The scope is expressed as a list of space-delimited strings.
135
- *
136
- * @return string
137
- */
138
- public function createAuthUrl($scope)
139
- {
140
- $params = array(
141
- 'response_type' => 'code',
142
- 'redirect_uri' => $this->client->getClassConfig($this, 'redirect_uri'),
143
- 'client_id' => $this->client->getClassConfig($this, 'client_id'),
144
- 'scope' => $scope,
145
- 'access_type' => $this->client->getClassConfig($this, 'access_type'),
146
- 'approval_prompt' => $this->client->getClassConfig($this, 'approval_prompt'),
147
- );
148
-
149
- // If the list of scopes contains plus.login, add request_visible_actions
150
- // to auth URL.
151
- $rva = $this->client->getClassConfig($this, 'request_visible_actions');
152
- if (strpos($scope, 'plus.login') && strlen($rva) > 0) {
153
- $params['request_visible_actions'] = $rva;
154
- }
155
-
156
- if (isset($this->state)) {
157
- $params['state'] = $this->state;
158
- }
159
-
160
- return self::OAUTH2_AUTH_URL."?".http_build_query($params, '', '&');
161
- }
162
-
163
- /**
164
- * @param string $token
165
- *
166
- * @throws Google_Auth_Exception
167
- */
168
- public function setAccessToken($token)
169
- {
170
- $token = json_decode($token, true);
171
- if ($token == null) {
172
- throw new Google_Auth_Exception('Could not json decode the token');
173
- }
174
- if (!isset($token['access_token'])) {
175
- throw new Google_Auth_Exception("Invalid token format");
176
- }
177
- $this->token = $token;
178
- }
179
-
180
- public function getAccessToken()
181
- {
182
- return json_encode($this->token);
183
- }
184
-
185
- public function setState($state)
186
- {
187
- $this->state = $state;
188
- }
189
-
190
- public function setAssertionCredentials(Google_Auth_AssertionCredentials $creds)
191
- {
192
- $this->assertionCredentials = $creds;
193
- }
194
-
195
- /**
196
- * Include an accessToken in a given apiHttpRequest.
197
- *
198
- * @param Google_Http_Request $request
199
- *
200
- * @return Google_Http_Request
201
- * @throws Google_Auth_Exception
202
- */
203
- public function sign(Google_Http_Request $request)
204
- {
205
- // add the developer key to the request before signing it
206
- if ($this->client->getClassConfig($this, 'developer_key')) {
207
- $request->setQueryParam('key', $this->client->getClassConfig($this, 'developer_key'));
208
- }
209
-
210
- // Cannot sign the request without an OAuth access token.
211
- if (null == $this->token && null == $this->assertionCredentials) {
212
- return $request;
213
- }
214
-
215
- // Check if the token is set to expire in the next 30 seconds
216
- // (or has already expired).
217
- if ($this->isAccessTokenExpired()) {
218
- if ($this->assertionCredentials) {
219
- $this->refreshTokenWithAssertion();
220
- } else {
221
- if (!array_key_exists('refresh_token', $this->token)) {
222
- throw new Google_Auth_Exception(
223
- "The OAuth 2.0 access token has expired,"
224
- ." and a refresh token is not available. Refresh tokens"
225
- ." are not returned for responses that were auto-approved."
226
- );
227
- }
228
- $this->refreshToken($this->token['refresh_token']);
229
- }
230
- }
231
-
232
- // Add the OAuth2 header to the request
233
- $request->setRequestHeaders(
234
- array('Authorization' => 'Bearer '.$this->token['access_token'])
235
- );
236
-
237
- return $request;
238
- }
239
-
240
- /**
241
- * Fetches a fresh access token with the given refresh token.
242
- *
243
- * @param string $refreshToken
244
- *
245
- * @return void
246
- */
247
- public function refreshToken($refreshToken)
248
- {
249
- $this->refreshTokenRequest(
250
- array(
251
- 'client_id' => $this->client->getClassConfig($this, 'client_id'),
252
- 'client_secret' => $this->client->getClassConfig($this, 'client_secret'),
253
- 'refresh_token' => $refreshToken,
254
- 'grant_type' => 'refresh_token',
255
- )
256
- );
257
- }
258
-
259
- /**
260
- * Fetches a fresh access token with a given assertion token.
261
- *
262
- * @param Google_Auth_AssertionCredentials $assertionCredentials optional.
263
- *
264
- * @return void
265
- */
266
- public function refreshTokenWithAssertion($assertionCredentials = null)
267
- {
268
- if (!$assertionCredentials) {
269
- $assertionCredentials = $this->assertionCredentials;
270
- }
271
-
272
- $cacheKey = $assertionCredentials->getCacheKey();
273
-
274
- if ($cacheKey) {
275
- // We can check whether we have a token available in the
276
- // cache. If it is expired, we can retrieve a new one from
277
- // the assertion.
278
- $token = $this->client->getCache()->get($cacheKey);
279
- if ($token) {
280
- $this->setAccessToken($token);
281
- }
282
- if (!$this->isAccessTokenExpired()) {
283
- return;
284
- }
285
- }
286
-
287
- $this->refreshTokenRequest(
288
- array(
289
- 'grant_type' => 'assertion',
290
- 'assertion_type' => $assertionCredentials->assertionType,
291
- 'assertion' => $assertionCredentials->generateAssertion(),
292
- )
293
- );
294
-
295
- if ($cacheKey) {
296
- // Attempt to cache the token.
297
- $this->client->getCache()->set(
298
- $cacheKey,
299
- $this->getAccessToken()
300
- );
301
- }
302
- }
303
-
304
- private function refreshTokenRequest($params)
305
- {
306
- $http = new Google_Http_Request(
307
- self::OAUTH2_TOKEN_URI,
308
- 'POST',
309
- array(),
310
- $params
311
- );
312
- $http->disableGzip();
313
- $request = $this->client->getIo()->makeRequest($http);
314
-
315
- $code = $request->getResponseHttpCode();
316
- $body = $request->getResponseBody();
317
- if (200 == $code) {
318
- $token = json_decode($body, true);
319
- if ($token == null) {
320
- throw new Google_Auth_Exception("Could not json decode the access token");
321
- }
322
-
323
- if (!isset($token['access_token']) || !isset($token['expires_in'])) {
324
- throw new Google_Auth_Exception("Invalid token format");
325
- }
326
-
327
- $this->token['access_token'] = $token['access_token'];
328
- $this->token['expires_in'] = $token['expires_in'];
329
- $this->token['created'] = time();
330
- } else {
331
- throw new Google_Auth_Exception("Error refreshing the OAuth2 token, message: '$body'", $code);
332
- }
333
- }
334
-
335
- /**
336
- * Revoke an OAuth2 access token or refresh token. This method will revoke the current access
337
- * token, if a token isn't provided.
338
- * @throws Google_Auth_Exception
339
- *
340
- * @param string|null $token The token (access token or a refresh token) that should be revoked.
341
- *
342
- * @return boolean Returns True if the revocation was successful, otherwise False.
343
- */
344
- public function revokeToken($token = null)
345
- {
346
- if (!$token) {
347
- $token = $this->token['access_token'];
348
- }
349
- $request = new Google_Http_Request(
350
- self::OAUTH2_REVOKE_URI,
351
- 'POST',
352
- array(),
353
- "token=$token"
354
- );
355
- $request->disableGzip();
356
- $response = $this->client->getIo()->makeRequest($request);
357
- $code = $response->getResponseHttpCode();
358
- if ($code == 200) {
359
- $this->token = null;
360
-
361
- return true;
362
- }
363
-
364
- return false;
365
- }
366
-
367
- /**
368
- * Returns if the access_token is expired.
369
- * @return bool Returns True if the access_token is expired.
370
- */
371
- public function isAccessTokenExpired()
372
- {
373
- if (!$this->token) {
374
- return true;
375
- }
376
-
377
- // If the token is set to expire in the next 30 seconds.
378
- $expired = ($this->token['created']
379
- + ($this->token['expires_in'] - 30)) < time();
380
-
381
- return $expired;
382
- }
383
-
384
- // Gets federated sign-on certificates to use for verifying identity tokens.
385
- // Returns certs as array structure, where keys are key ids, and values
386
- // are PEM encoded certificates.
387
- private function getFederatedSignOnCerts()
388
- {
389
- return $this->retrieveCertsFromLocation(
390
- $this->client->getClassConfig($this, 'federated_signon_certs_url')
391
- );
392
- }
393
-
394
- /**
395
- * Retrieve and cache a certificates file.
396
- *
397
- * @param $url location
398
- *
399
- * @return array certificates
400
- */
401
- public function retrieveCertsFromLocation($url)
402
- {
403
- // If we're retrieving a local file, just grab it.
404
- if ("http" != substr($url, 0, 4)) {
405
- $file = file_get_contents($url);
406
- if ($file) {
407
- return json_decode($file, true);
408
- } else {
409
- throw new Google_Auth_Exception(
410
- "Failed to retrieve verification certificates: '".
411
- $url."'."
412
- );
413
- }
414
- }
415
-
416
- // This relies on makeRequest caching certificate responses.
417
- $request = $this->client->getIo()->makeRequest(
418
- new Google_Http_Request(
419
- $url
420
- )
421
- );
422
- if ($request->getResponseHttpCode() == 200) {
423
- $certs = json_decode($request->getResponseBody(), true);
424
- if ($certs) {
425
- return $certs;
426
- }
427
- }
428
- throw new Google_Auth_Exception(
429
- "Failed to retrieve verification certificates: '".
430
- $request->getResponseBody()."'.",
431
- $request->getResponseHttpCode()
432
- );
433
- }
434
-
435
- /**
436
- * Verifies an id token and returns the authenticated apiLoginTicket.
437
- * Throws an exception if the id token is not valid.
438
- * The audience parameter can be used to control which id tokens are
439
- * accepted. By default, the id token must have been issued to this OAuth2 client.
440
- *
441
- * @param $id_token
442
- * @param $audience
443
- *
444
- * @return Google_Auth_LoginTicket
445
- */
446
- public function verifyIdToken($id_token = null, $audience = null)
447
- {
448
- if (!$id_token) {
449
- $id_token = $this->token['id_token'];
450
- }
451
- $certs = $this->getFederatedSignonCerts();
452
- if (!$audience) {
453
- $audience = $this->client->getClassConfig($this, 'client_id');
454
- }
455
-
456
- return $this->verifySignedJwtWithCerts($id_token, $certs, $audience, self::OAUTH2_ISSUER);
457
- }
458
-
459
- /**
460
- * Verifies the id token, returns the verified token contents.
461
- *
462
- * @param $jwt the token
463
- * @param $certs array of certificates
464
- * @param $required_audience the expected consumer of the token
465
- * @param [$issuer] the expected issues, defaults to Google
466
- * @param [$max_expiry] the max lifetime of a token, defaults to MAX_TOKEN_LIFETIME_SECS
467
- *
468
- * @return token information if valid, false if not
469
- */
470
- public function verifySignedJwtWithCerts(
471
- $jwt,
472
- $certs,
473
- $required_audience,
474
- $issuer = null,
475
- $max_expiry = null
476
- ) {
477
- if (!$max_expiry) {
478
- // Set the maximum time we will accept a token for.
479
- $max_expiry = self::MAX_TOKEN_LIFETIME_SECS;
480
- }
481
-
482
- $segments = explode(".", $jwt);
483
- if (count($segments) != 3) {
484
- throw new Google_Auth_Exception("Wrong number of segments in token: $jwt");
485
- }
486
- $signed = $segments[0].".".$segments[1];
487
- $signature = Google_ApiUtils::urlSafeB64Decode($segments[2]);
488
-
489
- // Parse envelope.
490
- $envelope = json_decode(Google_ApiUtils::urlSafeB64Decode($segments[0]), true);
491
- if (!$envelope) {
492
- throw new Google_Auth_Exception("Can't parse token envelope: ".$segments[0]);
493
- }
494
-
495
- // Parse token
496
- $json_body = Google_ApiUtils::urlSafeB64Decode($segments[1]);
497
- $payload = json_decode($json_body, true);
498
- if (!$payload) {
499
- throw new Google_Auth_Exception("Can't parse token payload: ".$segments[1]);
500
- }
501
-
502
- // Check signature
503
- $verified = false;
504
- foreach ($certs as $keyName => $pem) {
505
- // @todo make a fallback using PHPSecLib, since it's completely trivial; this is the only part of the Worker plugin that requires openssl extension.
506
- $public_key = new Google_Verifier_Pem($pem);
507
- if ($public_key->verify($signed, $signature)) {
508
- $verified = true;
509
- break;
510
- }
511
- }
512
-
513
- if (!$verified) {
514
- throw new Google_Auth_Exception("Invalid token signature: $jwt");
515
- }
516
-
517
- // Check issued-at timestamp
518
- $iat = 0;
519
- if (array_key_exists("iat", $payload)) {
520
- $iat = $payload["iat"];
521
- }
522
- if (!$iat) {
523
- throw new Google_Auth_Exception("No issue time in token: $json_body");
524
- }
525
- $earliest = $iat - self::CLOCK_SKEW_SECS;
526
-
527
- // Check expiration timestamp
528
- $now = time();
529
- $exp = 0;
530
- if (array_key_exists("exp", $payload)) {
531
- $exp = $payload["exp"];
532
- }
533
- if (!$exp) {
534
- throw new Google_Auth_Exception("No expiration time in token: $json_body");
535
- }
536
- if ($exp >= $now + $max_expiry) {
537
- throw new Google_Auth_Exception(
538
- sprintf("Expiration time too far in future: %s", $json_body)
539
- );
540
- }
541
-
542
- $latest = $exp + self::CLOCK_SKEW_SECS;
543
- if ($now < $earliest) {
544
- throw new Google_Auth_Exception(
545
- sprintf(
546
- "Token used too early, %s < %s: %s",
547
- $now,
548
- $earliest,
549
- $json_body
550
- )
551
- );
552
- }
553
- if ($now > $latest) {
554
- throw new Google_Auth_Exception(
555
- sprintf(
556
- "Token used too late, %s > %s: %s",
557
- $now,
558
- $latest,
559
- $json_body
560
- )
561
- );
562
- }
563
-
564
- $iss = $payload['iss'];
565
- if ($issuer && $iss != $issuer) {
566
- throw new Google_Auth_Exception(
567
- sprintf(
568
- "Invalid issuer, %s != %s: %s",
569
- $iss,
570
- $issuer,
571
- $json_body
572
- )
573
- );
574
- }
575
-
576
- // Check audience
577
- $aud = $payload["aud"];
578
- if ($aud != $required_audience) {
579
- throw new Google_Auth_Exception(
580
- sprintf(
581
- "Wrong recipient, %s != %s:",
582
- $aud,
583
- $required_audience,
584
- $json_body
585
- )
586
- );
587
- }
588
-
589
- // All good.
590
- return new Google_Auth_LoginTicket($envelope, $payload);
591
- }
592
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Google/Auth/Simple.php DELETED
@@ -1,93 +0,0 @@
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
- * Simple API access implementation. Can either be used to make requests
20
- * completely unauthenticated, or by using a Simple API Access developer
21
- * key.
22
- *
23
- * @author Chris Chabot <chabotc@google.com>
24
- * @author Chirag Shah <chirags@google.com>
25
- */
26
- class Google_Auth_Simple extends Google_Auth_Abstract
27
- {
28
- private $key = null;
29
- private $client;
30
-
31
- public function __construct(Google_ApiClient $client, $config = null)
32
- {
33
- $this->client = $client;
34
- }
35
-
36
- /**
37
- * Perform an authenticated / signed apiHttpRequest.
38
- * This function takes the apiHttpRequest, calls apiAuth->sign on it
39
- * (which can modify the request in what ever way fits the auth mechanism)
40
- * and then calls apiCurlIO::makeRequest on the signed request
41
- *
42
- * @param Google_Http_Request $request
43
- *
44
- * @return Google_Http_Request The resulting HTTP response including the
45
- * responseHttpCode, responseHeaders and responseBody.
46
- */
47
- public function authenticatedRequest(Google_Http_Request $request)
48
- {
49
- $request = $this->sign($request);
50
-
51
- return $this->io->makeRequest($request);
52
- }
53
-
54
- public function authenticate($code)
55
- {
56
- throw new Google_Auth_Exception("Simple auth does not exchange tokens.");
57
- }
58
-
59
- public function setAccessToken($accessToken)
60
- {
61
- /* noop*/
62
- }
63
-
64
- public function getAccessToken()
65
- {
66
- return null;
67
- }
68
-
69
- public function createAuthUrl($scope)
70
- {
71
- return null;
72
- }
73
-
74
- public function refreshToken($refreshToken)
75
- {
76
- /* noop*/
77
- }
78
-
79
- public function revokeToken()
80
- {
81
- /* noop*/
82
- }
83
-
84
- public function sign(Google_Http_Request $request)
85
- {
86
- $key = $this->client->getClassConfig($this, 'developer_key');
87
- if ($key) {
88
- $request->setQueryParam('key', $key);
89
- }
90
-
91
- return $request;
92
- }
93
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Google/Cache/Abstract.php DELETED
@@ -1,52 +0,0 @@
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
- * Abstract storage class
20
- *
21
- * @author Chris Chabot <chabotc@google.com>
22
- */
23
- abstract class Google_Cache_Abstract
24
- {
25
- abstract public function __construct(Google_ApiClient $client);
26
-
27
- /**
28
- * Retrieves the data for the given key, or false if they
29
- * key is unknown or expired
30
- *
31
- * @param String $key The key who's data to retrieve
32
- * @param boolean|int $expiration Expiration time in seconds
33
- *
34
- */
35
- abstract public function get($key, $expiration = false);
36
-
37
- /**
38
- * Store the key => $value set. The $value is serialized
39
- * by this function so can be of any type
40
- *
41
- * @param string $key Key of the data
42
- * @param string $value data
43
- */
44
- abstract public function set($key, $value);
45
-
46
- /**
47
- * Removes the key/data pair for the given $key
48
- *
49
- * @param String $key
50
- */
51
- abstract public function delete($key);
52
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Google/Cache/Apc.php DELETED
@@ -1,73 +0,0 @@
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, and cache is a lot cheaper then storage.
23
- *
24
- * @author Chris Chabot <chabotc@google.com>
25
- */
26
- class Google_Cache_Apc extends Google_Cache_Abstract
27
- {
28
- public function __construct(Google_ApiClient $client)
29
- {
30
- if (!function_exists('apc_add')) {
31
- throw new Google_Cache_Exception("Apc functions not available");
32
- }
33
- }
34
-
35
- /**
36
- * @inheritDoc
37
- */
38
- public function get($key, $expiration = false)
39
- {
40
- $ret = apc_fetch($key);
41
- if ($ret === false) {
42
- return false;
43
- }
44
- if (is_numeric($expiration) && (time() - $ret['time'] > $expiration)) {
45
- $this->delete($key);
46
-
47
- return false;
48
- }
49
-
50
- return $ret['data'];
51
- }
52
-
53
- /**
54
- * @inheritDoc
55
- */
56
- public function set($key, $value)
57
- {
58
- $rc = apc_store($key, array('time' => time(), 'data' => $value));
59
- if ($rc == false) {
60
- throw new Google_Cache_Exception("Couldn't store data");
61
- }
62
- }
63
-
64
- /**
65
- * @inheritDoc
66
- *
67
- * @param String $key
68
- */
69
- public function delete($key)
70
- {
71
- apc_delete($key);
72
- }
73
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Google/Cache/Exception.php DELETED
@@ -1,21 +0,0 @@
1
- <?php
2
-
3
- /*
4
- * Copyright 2013 Google Inc.
5
- *
6
- * Licensed under the Apache License, Version 2.0 (the "License");
7
- * you may not use this file except in compliance with the License.
8
- * You may obtain a copy of the License at
9
- *
10
- * http://www.apache.org/licenses/LICENSE-2.0
11
- *
12
- * Unless required by applicable law or agreed to in writing, software
13
- * distributed under the License is distributed on an "AS IS" BASIS,
14
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
- * See the License for the specific language governing permissions and
16
- * limitations under the License.
17
- */
18
-
19
- class Google_Cache_Exception extends Google_ApiException
20
- {
21
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Google/Cache/File.php DELETED
@@ -1,147 +0,0 @@
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.
23
- *
24
- * @author Chris Chabot <chabotc@google.com>
25
- */
26
-
27
- class Google_Cache_File extends Google_Cache_Abstract
28
- {
29
- const MAX_LOCK_RETRIES = 10;
30
- private $path;
31
- private $fh;
32
-
33
- public function __construct(Google_ApiClient $client)
34
- {
35
- $this->path = $client->getClassConfig($this, 'directory');
36
- }
37
-
38
- public function get($key, $expiration = false)
39
- {
40
- $storageFile = $this->getCacheFile($key);
41
- $data = false;
42
-
43
- if (!file_exists($storageFile)) {
44
- return false;
45
- }
46
-
47
- if ($expiration) {
48
- $mtime = filemtime($storageFile);
49
- if (($now - $mtime) >= $expiration) {
50
- $this->delete($key);
51
-
52
- return false;
53
- }
54
- }
55
-
56
- if ($this->acquireReadLock($storageFile)) {
57
- $data = fread($this->fh, filesize($storageFile));
58
- $data = unserialize($data);
59
- $this->unlock($storageFile);
60
- }
61
-
62
- return $data;
63
- }
64
-
65
- public function set($key, $value)
66
- {
67
- $storageFile = $this->getWriteableCacheFile($key);
68
- if ($this->acquireWriteLock($storageFile)) {
69
- // We serialize the whole request object, since we don't only want the
70
- // responseContent but also the postBody used, headers, size, etc.
71
- $data = serialize($value);
72
- $result = fwrite($this->fh, $data);
73
- $this->unlock($storageFile);
74
- }
75
- }
76
-
77
- public function delete($key)
78
- {
79
- $file = $this->getCacheFile($key);
80
- if (file_exists($file) && !unlink($file)) {
81
- throw new Google_Cache_Exception("Cache file could not be deleted");
82
- }
83
- }
84
-
85
- private function getWriteableCacheFile($file)
86
- {
87
- return $this->getCacheFile($file, true);
88
- }
89
-
90
- private function getCacheFile($file, $forWrite = false)
91
- {
92
- return $this->getCacheDir($file, $forWrite).'/'.md5($file);
93
- }
94
-
95
- private function getCacheDir($file, $forWrite)
96
- {
97
- // use the first 2 characters of the hash as a directory prefix
98
- // this should prevent slowdowns due to huge directory listings
99
- // and thus give some basic amount of scalability
100
- $storageDir = $this->path.'/'.substr(md5($file), 0, 2);
101
- if ($forWrite && !is_dir($storageDir)) {
102
- if (!mkdir($storageDir, 0755, true)) {
103
- throw new Google_Cache_Exception("Could not create storage directory: $storageDir");
104
- }
105
- }
106
-
107
- return $storageDir;
108
- }
109
-
110
- private function acquireReadLock($storageFile)
111
- {
112
- return $this->acquireLock(LOCK_SH, $storageFile);
113
- }
114
-
115
- private function acquireWriteLock($storageFile)
116
- {
117
- $rc = $this->acquireLock(LOCK_EX, $storageFile);
118
- if (!$rc) {
119
- $this->delete($storageFile);
120
- }
121
-
122
- return $rc;
123
- }
124
-
125
- private function acquireLock($type, $storageFile)
126
- {
127
- $mode = $type == LOCK_EX ? "w" : "r";
128
- $this->fh = fopen($storageFile, $mode);
129
- $count = 0;
130
- while (!flock($this->fh, $type | LOCK_NB)) {
131
- // Sleep for 10ms.
132
- usleep(10000);
133
- if (++$count < self::MAX_LOCK_RETRIES) {
134
- return false;
135
- }
136
- }
137
-
138
- return true;
139
- }
140
-
141
- public function unlock($storageFile)
142
- {
143
- if ($this->fh) {
144
- flock($this->fh, LOCK_UN);
145
- }
146
- }
147
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Google/Cache/Memcache.php DELETED
@@ -1,139 +0,0 @@
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.
22
- *
23
- * Will use either the memcache or memcached extensions, preferring
24
- * memcached.
25
- *
26
- * @author Chris Chabot <chabotc@google.com>
27
- */
28
- class Google_Cache_Memcache extends Google_Cache_Abstract
29
- {
30
- private $connection = false;
31
- private $mc = false;
32
- private $host;
33
- private $port;
34
-
35
- public function __construct(Google_ApiClient $client)
36
- {
37
- if (!function_exists('memcache_connect') && !class_exists("Memcached")) {
38
- throw new Google_Cache_Exception("Memcache functions not available");
39
- }
40
- if ($client->isAppEngine()) {
41
- // No credentials needed for GAE.
42
- $this->mc = new Memcached();
43
- $this->connection = true;
44
- } else {
45
- $this->host = $client->getClassConfig($this, 'host');
46
- $this->port = $client->getClassConfig($this, 'port');
47
- if (empty($this->host) || empty($this->port)) {
48
- throw new Google_Cache_Exception("You need to supply a valid memcache host and port");
49
- }
50
- }
51
- }
52
-
53
- /**
54
- * @inheritDoc
55
- */
56
- public function get($key, $expiration = false)
57
- {
58
- $this->connect();
59
- $ret = false;
60
- if ($this->mc) {
61
- $ret = $this->mc->get($key);
62
- } else {
63
- $ret = memcache_get($this->connection, $key);
64
- }
65
- if ($ret === false) {
66
- return false;
67
- }
68
- if (is_numeric($expiration) && (time() - $ret['time'] > $expiration)) {
69
- $this->delete($key);
70
-
71
- return false;
72
- }
73
-
74
- return $ret['data'];
75
- }
76
-
77
- /**
78
- * @inheritDoc
79
- *
80
- * @param string $key
81
- * @param string $value
82
- *
83
- * @throws Google_Cache_Exception
84
- */
85
- public function set($key, $value)
86
- {
87
- $this->connect();
88
- // we store it with the cache_time default expiration so objects will at
89
- // least get cleaned eventually.
90
- $data = array('time' => time(), 'data' => $value);
91
- $rc = false;
92
- if ($this->mc) {
93
- $rc = $this->mc->set($key, $data);
94
- } else {
95
- $rc = memcache_set($this->connection, $key, $data, false);
96
- }
97
- if ($rc == false) {
98
- throw new Google_Cache_Exception("Couldn't store data in cache");
99
- }
100
- }
101
-
102
- /**
103
- * @inheritDoc
104
- *
105
- * @param String $key
106
- */
107
- public function delete($key)
108
- {
109
- $this->connect();
110
- if ($this->mc) {
111
- $this->mc->delete($key, 0);
112
- } else {
113
- memcache_delete($this->connection, $key, 0);
114
- }
115
- }
116
-
117
- /**
118
- * Lazy initialiser for memcache connection. Uses pconnect for to take
119
- * advantage of the persistence pool where possible.
120
- */
121
- private function connect()
122
- {
123
- if ($this->connection) {
124
- return;
125
- }
126
-
127
- if (class_exists("Memcached")) {
128
- $this->mc = new Memcached();
129
- $this->mc->addServer($this->host, $this->port);
130
- $this->connection = true;
131
- } else {
132
- $this->connection = memcache_pconnect($this->host, $this->port);
133
- }
134
-
135
- if (!$this->connection) {
136
- throw new Google_Cache_Exception("Couldn't connect to memcache server");
137
- }
138
- }
139
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Google/Cache/Null.php DELETED
@@ -1,53 +0,0 @@
1
- <?php
2
- /*
3
- * Copyright 2014 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 blank storage class, for cases where caching is not
20
- * required.
21
- */
22
- class Google_Cache_Null extends Google_Cache_Abstract
23
- {
24
- public function __construct(Google_ApiClient $client)
25
- {
26
- }
27
-
28
- /**
29
- * @inheritDoc
30
- */
31
- public function get($key, $expiration = false)
32
- {
33
- return false;
34
- }
35
-
36
- /**
37
- * @inheritDoc
38
- */
39
- public function set($key, $value)
40
- {
41
- // Nop.
42
- }
43
-
44
- /**
45
- * @inheritDoc
46
- *
47
- * @param String $key
48
- */
49
- public function delete($key)
50
- {
51
- // Nop.
52
- }
53
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Google/Collection.php DELETED
@@ -1,96 +0,0 @@
1
- <?php
2
-
3
-
4
- /**
5
- * Extension to the regular Google_ApiModel that automatically
6
- * exposes the items array for iteration, so you can just
7
- * iterate over the object rather than a reference inside.
8
- */
9
- class Google_Collection extends Google_ApiModel implements Iterator, Countable
10
- {
11
- protected $collection_key = 'items';
12
-
13
- public function rewind()
14
- {
15
- if (is_array($this->data[$this->collection_key])) {
16
- reset($this->data[$this->collection_key]);
17
- }
18
- }
19
-
20
- public function current()
21
- {
22
- $this->coerceType($this->key());
23
- if (is_array($this->data[$this->collection_key])) {
24
- return current($this->data[$this->collection_key]);
25
- }
26
- }
27
-
28
- public function key()
29
- {
30
- if (is_array($this->data[$this->collection_key])) {
31
- return key($this->data[$this->collection_key]);
32
- }
33
- }
34
-
35
- public function next()
36
- {
37
- return next($this->data[$this->collection_key]);
38
- }
39
-
40
- public function valid()
41
- {
42
- $key = $this->key();
43
-
44
- return $key !== null && $key !== false;
45
- }
46
-
47
- public function count()
48
- {
49
- return count($this->data[$this->collection_key]);
50
- }
51
-
52
- public function offsetExists($offset)
53
- {
54
- if (!is_numeric($offset)) {
55
- return parent::offsetExists($offset);
56
- }
57
-
58
- return isset($this->data[$this->collection_key][$offset]);
59
- }
60
-
61
- public function offsetGet($offset)
62
- {
63
- if (!is_numeric($offset)) {
64
- return parent::offsetGet($offset);
65
- }
66
- $this->coerceType($offset);
67
-
68
- return $this->data[$this->collection_key][$offset];
69
- }
70
-
71
- public function offsetSet($offset, $value)
72
- {
73
- if (!is_numeric($offset)) {
74
- return parent::offsetSet($offset, $value);
75
- }
76
- $this->data[$this->collection_key][$offset] = $value;
77
- }
78
-
79
- public function offsetUnset($offset)
80
- {
81
- if (!is_numeric($offset)) {
82
- return parent::offsetUnset($offset);
83
- }
84
- unset($this->data[$this->collection_key][$offset]);
85
- }
86
-
87
- private function coerceType($offset)
88
- {
89
- $typeKey = $this->keyType($this->collection_key);
90
- if (isset($this->$typeKey) && !is_object($this->data[$this->collection_key][$offset])) {
91
- $type = $this->$typeKey;
92
- $this->data[$this->collection_key][$offset] =
93
- new $type($this->data[$this->collection_key][$offset]);
94
- }
95
- }
96
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Google/Config.php DELETED
@@ -1,322 +0,0 @@
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 class to contain the library configuration for the Google API client.
20
- */
21
- class Google_Config
22
- {
23
- const GZIP_DISABLED = true;
24
- const GZIP_ENABLED = false;
25
- const GZIP_UPLOADS_ENABLED = true;
26
- const GZIP_UPLOADS_DISABLED = false;
27
- const USE_AUTO_IO_SELECTION = "auto";
28
- private $configuration;
29
-
30
- /**
31
- * Create a new Google_Config. Can accept an ini file location with the
32
- * local configuration. For example:
33
- * application_name: "My App";
34
- *
35
- * @param [$ini_file_location] - optional - The location of the ini file to load
36
- */
37
- public function __construct($ini_file_location = null)
38
- {
39
- $this->configuration = array(
40
- // The application_name is included in the User-Agent HTTP header.
41
- 'application_name' => '',
42
- // Which Authentication, Storage and HTTP IO classes to use.
43
- 'auth_class' => 'Google_Auth_OAuth2',
44
- 'io_class' => self::USE_AUTO_IO_SELECTION,
45
- 'cache_class' => 'Google_Cache_File',
46
- // Don't change these unless you're working against a special development
47
- // or testing environment.
48
- 'base_path' => 'https://www.googleapis.com',
49
- // Definition of class specific values, like file paths and so on.
50
- 'classes' => array(
51
- 'Google_IO_Abstract' => array(
52
- 'request_timeout_seconds' => 100,
53
- ),
54
- 'Google_Http_Request' => array(
55
- // Disable the use of gzip on calls if set to true. Defaults to false.
56
- 'disable_gzip' => self::GZIP_ENABLED,
57
- // We default gzip to disabled on uploads even if gzip is otherwise
58
- // enabled, due to some issues seen with small packet sizes for uploads.
59
- // Please test with this option before enabling gzip for uploads in
60
- // a production environment.
61
- 'enable_gzip_for_uploads' => self::GZIP_UPLOADS_DISABLED,
62
- ),
63
- // If you want to pass in OAuth 2.0 settings, they will need to be
64
- // structured like this.
65
- 'Google_Auth_OAuth2' => array(
66
- // Keys for OAuth 2.0 access, see the API console at
67
- // https://developers.google.com/console
68
- 'client_id' => '',
69
- 'client_secret' => '',
70
- 'redirect_uri' => '',
71
- // Simple API access key, also from the API console. Ensure you get
72
- // a Server key, and not a Browser key.
73
- 'developer_key' => '',
74
- // Other parameters.
75
- 'access_type' => 'online',
76
- 'approval_prompt' => 'auto',
77
- 'request_visible_actions' => '',
78
- 'federated_signon_certs_url' => 'https://www.googleapis.com/oauth2/v1/certs',
79
- ),
80
- // Set a default directory for the file cache.
81
- 'Google_Cache_File' => array(
82
- 'directory' => sys_get_temp_dir().'/Google_ApiClient',
83
- ),
84
- ),
85
- // Definition of service specific values like scopes, oauth token URLs,
86
- // etc. Example:
87
- 'services' => array(),
88
- );
89
- if ($ini_file_location) {
90
- $ini = parse_ini_file($ini_file_location, true);
91
- if (is_array($ini) && count($ini)) {
92
- $this->configuration = array_merge($this->configuration, $ini);
93
- }
94
- }
95
- }
96
-
97
- /**
98
- * Set configuration specific to a given class.
99
- * $config->setClassConfig('Google_Cache_File',
100
- * array('directory' => '/tmp/cache'));
101
- *
102
- * @param $class The class name for the configuration
103
- * @param $config string key or an array of configuration values
104
- * @param $value optional - if $config is a key, the value
105
- */
106
- public function setClassConfig($class, $config, $value = null)
107
- {
108
- if (!is_array($config)) {
109
- if (!isset($this->configuration['classes'][$class])) {
110
- $this->configuration['classes'][$class] = array();
111
- }
112
- $this->configuration['classes'][$class][$config] = $value;
113
- } else {
114
- $this->configuration['classes'][$class] = $config;
115
- }
116
- }
117
-
118
- public function getClassConfig($class, $key = null)
119
- {
120
- if (!isset($this->configuration['classes'][$class])) {
121
- return null;
122
- }
123
- if ($key === null) {
124
- return $this->configuration['classes'][$class];
125
- } else {
126
- return $this->configuration['classes'][$class][$key];
127
- }
128
- }
129
-
130
- /**
131
- * Return the configured cache class.
132
- *
133
- * @return string
134
- */
135
- public function getCacheClass()
136
- {
137
- return $this->configuration['cache_class'];
138
- }
139
-
140
- /**
141
- * Return the configured Auth class.
142
- *
143
- * @return string
144
- */
145
- public function getAuthClass()
146
- {
147
- return $this->configuration['auth_class'];
148
- }
149
-
150
- /**
151
- * Set the auth class.
152
- *
153
- * @param $class the class name to set
154
- */
155
- public function setAuthClass($class)
156
- {
157
- $prev = $this->configuration['auth_class'];
158
- if (!isset($this->configuration['classes'][$class]) &&
159
- isset($this->configuration['classes'][$prev])
160
- ) {
161
- $this->configuration['classes'][$class] =
162
- $this->configuration['classes'][$prev];
163
- }
164
- $this->configuration['auth_class'] = $class;
165
- }
166
-
167
- /**
168
- * Set the IO class.
169
- *
170
- * @param $class the class name to set
171
- */
172
- public function setIoClass($class)
173
- {
174
- $prev = $this->configuration['io_class'];
175
- if (!isset($this->configuration['classes'][$class]) &&
176
- isset($this->configuration['classes'][$prev])
177
- ) {
178
- $this->configuration['classes'][$class] =
179
- $this->configuration['classes'][$prev];
180
- }
181
- $this->configuration['io_class'] = $class;
182
- }
183
-
184
- /**
185
- * Set the cache class.
186
- *
187
- * @param $class the class name to set
188
- */
189
- public function setCacheClass($class)
190
- {
191
- $prev = $this->configuration['cache_class'];
192
- if (!isset($this->configuration['classes'][$class]) &&
193
- isset($this->configuration['classes'][$prev])
194
- ) {
195
- $this->configuration['classes'][$class] =
196
- $this->configuration['classes'][$prev];
197
- }
198
- $this->configuration['cache_class'] = $class;
199
- }
200
-
201
- /**
202
- * Return the configured IO class.
203
- *
204
- * @return string
205
- */
206
- public function getIoClass()
207
- {
208
- return $this->configuration['io_class'];
209
- }
210
-
211
- /**
212
- * Set the application name, this is included in the User-Agent HTTP header.
213
- *
214
- * @param string $name
215
- */
216
- public function setApplicationName($name)
217
- {
218
- $this->configuration['application_name'] = $name;
219
- }
220
-
221
- /**
222
- * @return string the name of the application
223
- */
224
- public function getApplicationName()
225
- {
226
- return $this->configuration['application_name'];
227
- }
228
-
229
- /**
230
- * Set the client ID for the auth class.
231
- *
232
- * @param $key string - the API console client ID
233
- */
234
- public function setClientId($clientId)
235
- {
236
- $this->setAuthConfig('client_id', $clientId);
237
- }
238
-
239
- /**
240
- * Set the client secret for the auth class.
241
- *
242
- * @param $key string - the API console client secret
243
- */
244
- public function setClientSecret($secret)
245
- {
246
- $this->setAuthConfig('client_secret', $secret);
247
- }
248
-
249
- /**
250
- * Set the redirect uri for the auth class. Note that if using the
251
- * Javascript based sign in flow, this should be the string 'postmessage'.
252
- *
253
- * @param $key string - the URI that users should be redirected to
254
- */
255
- public function setRedirectUri($uri)
256
- {
257
- $this->setAuthConfig('redirect_uri', $uri);
258
- }
259
-
260
- /**
261
- * Set the app activities for the auth class.
262
- *
263
- * @param $rva string a space separated list of app activity types
264
- */
265
- public function setRequestVisibleActions($rva)
266
- {
267
- $this->setAuthConfig('request_visible_actions', $rva);
268
- }
269
-
270
- /**
271
- * Set the the access type requested (offline or online.)
272
- *
273
- * @param $access string - the access type
274
- */
275
- public function setAccessType($access)
276
- {
277
- $this->setAuthConfig('access_type', $access);
278
- }
279
-
280
- /**
281
- * Set when to show the approval prompt (auto or force)
282
- *
283
- * @param $approval string - the approval request
284
- */
285
- public function setApprovalPrompt($approval)
286
- {
287
- $this->setAuthConfig('approval_prompt', $approval);
288
- }
289
-
290
- /**
291
- * Set the developer key for the auth class. Note that this is separate value
292
- * from the client ID - if it looks like a URL, its a client ID!
293
- *
294
- * @param $key string - the API console developer key
295
- */
296
- public function setDeveloperKey($key)
297
- {
298
- $this->setAuthConfig('developer_key', $key);
299
- }
300
-
301
- /**
302
- * @return string the base URL to use for API calls
303
- */
304
- public function getBasePath()
305
- {
306
- return $this->configuration['base_path'];
307
- }
308
-
309
- /**
310
- * Set the auth configuration for the current auth class.
311
- *
312
- * @param $key - the key to set
313
- * @param $value - the parameter value
314
- */
315
- private function setAuthConfig($key, $value)
316
- {
317
- if (!isset($this->configuration['classes'][$this->getAuthClass()])) {
318
- $this->configuration['classes'][$this->getAuthClass()] = array();
319
- }
320
- $this->configuration['classes'][$this->getAuthClass()][$key] = $value;
321
- }
322
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Google/Http/Batch.php DELETED
@@ -1,140 +0,0 @@
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_Http_Batch
22
- {
23
- /** @var string Multipart Boundary. */
24
- private $boundary;
25
-
26
- /** @var array service requests to be executed. */
27
- private $requests = array();
28
-
29
- /** @var Google_ApiClient */
30
- private $client;
31
-
32
- private $expected_classes = array();
33
-
34
- private $base_path;
35
-
36
- public function __construct(Google_ApiClient $client, $boundary = false)
37
- {
38
- $this->client = $client;
39
- $this->base_path = $this->client->getBasePath();
40
- $this->expected_classes = array();
41
- $boundary = (false == $boundary) ? mt_rand() : $boundary;
42
- $this->boundary = str_replace('"', '', $boundary);
43
- }
44
-
45
- public function add(Google_Http_Request $request, $key = false)
46
- {
47
- if (false == $key) {
48
- $key = mt_rand();
49
- }
50
-
51
- $this->requests[$key] = $request;
52
- }
53
-
54
- public function execute()
55
- {
56
- $body = '';
57
-
58
- /** @var Google_Http_Request $req */
59
- foreach ($this->requests as $key => $req) {
60
- $body .= "--{$this->boundary}\n";
61
- $body .= $req->toBatchString($key)."\n";
62
- $this->expected_classes["response-".$key] = $req->getExpectedClass();
63
- }
64
-
65
- $body = rtrim($body);
66
- $body .= "\n--{$this->boundary}--";
67
-
68
- $url = $this->base_path.'/batch';
69
- $httpRequest = new Google_Http_Request($url, 'POST');
70
- $httpRequest->setRequestHeaders(
71
- array('Content-Type' => 'multipart/mixed; boundary='.$this->boundary)
72
- );
73
-
74
- $httpRequest->setPostBody($body);
75
- $response = $this->client->getIo()->makeRequest($httpRequest);
76
-
77
- return $this->parseResponse($response);
78
- }
79
-
80
- public function parseResponse(Google_Http_Request $response)
81
- {
82
- $contentType = $response->getResponseHeader('content-type');
83
- $contentType = explode(';', $contentType);
84
- $boundary = false;
85
- foreach ($contentType as $part) {
86
- $part = (explode('=', $part, 2));
87
- if (isset($part[0]) && 'boundary' == trim($part[0])) {
88
- $boundary = $part[1];
89
- }
90
- }
91
-
92
- $body = $response->getResponseBody();
93
- if ($body) {
94
- $body = str_replace("--$boundary--", "--$boundary", $body);
95
- $parts = explode("--$boundary", $body);
96
- $responses = array();
97
-
98
- foreach ($parts as $part) {
99
- $part = trim($part);
100
- if (!empty($part)) {
101
- list($metaHeaders, $part) = explode("\r\n\r\n", $part, 2);
102
- $metaHeaders = $this->client->getIo()->getHttpResponseHeaders($metaHeaders);
103
-
104
- $status = substr($part, 0, strpos($part, "\n"));
105
- $status = explode(" ", $status);
106
- $status = $status[1];
107
-
108
- list($partHeaders, $partBody) = $this->client->getIo()->ParseHttpResponse($part, false);
109
- $response = new Google_Http_Request("");
110
- $response->setResponseHttpCode($status);
111
- $response->setResponseHeaders($partHeaders);
112
- $response->setResponseBody($partBody);
113
-
114
- // Need content id.
115
- $key = $metaHeaders['content-id'];
116
-
117
- if (isset($this->expected_classes[$key]) &&
118
- strlen($this->expected_classes[$key]) > 0
119
- ) {
120
- $class = $this->expected_classes[$key];
121
- $response->setExpectedClass($class);
122
- }
123
-
124
- try {
125
- $response = Google_Http_REST::decodeHttpResponse($response);
126
- $responses[$key] = $response;
127
- } catch (Google_Service_Exception $e) {
128
- // Store the exception as the response, so succesful responses
129
- // can be processed.
130
- $responses[$key] = $e;
131
- }
132
- }
133
- }
134
-
135
- return $responses;
136
- }
137
-
138
- return null;
139
- }
140
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Google/Http/CacheParser.php DELETED
@@ -1,190 +0,0 @@
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
- * Implement the caching directives specified in rfc2616. This
20
- * implementation is guided by the guidance offered in rfc2616-sec13.
21
- *
22
- * @author Chirag Shah <chirags@google.com>
23
- */
24
- class Google_Http_CacheParser
25
- {
26
- public static $CACHEABLE_HTTP_METHODS = array('GET', 'HEAD');
27
- public static $CACHEABLE_STATUS_CODES = array('200', '203', '300', '301');
28
-
29
- /**
30
- * Check if an HTTP request can be cached by a private local cache.
31
- *
32
- * @static
33
- *
34
- * @param Google_Http_Request $resp
35
- *
36
- * @return bool True if the request is cacheable.
37
- * False if the request is uncacheable.
38
- */
39
- public static function isRequestCacheable(Google_Http_Request $resp)
40
- {
41
- $method = $resp->getRequestMethod();
42
- if (!in_array($method, self::$CACHEABLE_HTTP_METHODS)) {
43
- return false;
44
- }
45
-
46
- // Don't cache authorized requests/responses.
47
- // [rfc2616-14.8] When a shared cache receives a request containing an
48
- // Authorization field, it MUST NOT return the corresponding response
49
- // as a reply to any other request...
50
- if ($resp->getRequestHeader("authorization")) {
51
- return false;
52
- }
53
-
54
- return true;
55
- }
56
-
57
- /**
58
- * Check if an HTTP response can be cached by a private local cache.
59
- *
60
- * @static
61
- *
62
- * @param Google_Http_Request $resp
63
- *
64
- * @return bool True if the response is cacheable.
65
- * False if the response is un-cacheable.
66
- */
67
- public static function isResponseCacheable(Google_Http_Request $resp)
68
- {
69
- // First, check if the HTTP request was cacheable before inspecting the
70
- // HTTP response.
71
- if (false == self::isRequestCacheable($resp)) {
72
- return false;
73
- }
74
-
75
- $code = $resp->getResponseHttpCode();
76
- if (!in_array($code, self::$CACHEABLE_STATUS_CODES)) {
77
- return false;
78
- }
79
-
80
- // The resource is uncacheable if the resource is already expired and
81
- // the resource doesn't have an ETag for revalidation.
82
- $etag = $resp->getResponseHeader("etag");
83
- if (self::isExpired($resp) && $etag == false) {
84
- return false;
85
- }
86
-
87
- // [rfc2616-14.9.2] If [no-store is] sent in a response, a cache MUST NOT
88
- // store any part of either this response or the request that elicited it.
89
- $cacheControl = $resp->getParsedCacheControl();
90
- if (isset($cacheControl['no-store'])) {
91
- return false;
92
- }
93
-
94
- // Pragma: no-cache is an http request directive, but is occasionally
95
- // used as a response header incorrectly.
96
- $pragma = $resp->getResponseHeader('pragma');
97
- if ($pragma == 'no-cache' || strpos($pragma, 'no-cache') !== false) {
98
- return false;
99
- }
100
-
101
- // [rfc2616-14.44] Vary: * is extremely difficult to cache. "It implies that
102
- // a cache cannot determine from the request headers of a subsequent request
103
- // whether this response is the appropriate representation."
104
- // Given this, we deem responses with the Vary header as uncacheable.
105
- $vary = $resp->getResponseHeader('vary');
106
- if ($vary) {
107
- return false;
108
- }
109
-
110
- return true;
111
- }
112
-
113
- /**
114
- * @static
115
- *
116
- * @param Google_Http_Request $resp
117
- *
118
- * @return bool True if the HTTP response is considered to be expired.
119
- * False if it is considered to be fresh.
120
- */
121
- public static function isExpired(Google_Http_Request $resp)
122
- {
123
- // HTTP/1.1 clients and caches MUST treat other invalid date formats,
124
- // especially including the value “0”, as in the past.
125
- $parsedExpires = false;
126
- $responseHeaders = $resp->getResponseHeaders();
127
-
128
- if (isset($responseHeaders['expires'])) {
129
- $rawExpires = $responseHeaders['expires'];
130
- // Check for a malformed expires header first.
131
- if (empty($rawExpires) || (is_numeric($rawExpires) && $rawExpires <= 0)) {
132
- return true;
133
- }
134
-
135
- // See if we can parse the expires header.
136
- $parsedExpires = strtotime($rawExpires);
137
- if (false == $parsedExpires || $parsedExpires <= 0) {
138
- return true;
139
- }
140
- }
141
-
142
- // Calculate the freshness of an http response.
143
- $freshnessLifetime = false;
144
- $cacheControl = $resp->getParsedCacheControl();
145
- if (isset($cacheControl['max-age'])) {
146
- $freshnessLifetime = $cacheControl['max-age'];
147
- }
148
-
149
- $rawDate = $resp->getResponseHeader('date');
150
- $parsedDate = strtotime($rawDate);
151
-
152
- if (empty($rawDate) || false == $parsedDate) {
153
- // We can't default this to now, as that means future cache reads
154
- // will always pass with the logic below, so we will require a
155
- // date be injected if not supplied.
156
- throw new Google_ApiException("All cacheable requests must have creation dates.");
157
- }
158
-
159
- if (false == $freshnessLifetime && isset($responseHeaders['expires'])) {
160
- $freshnessLifetime = $parsedExpires - $parsedDate;
161
- }
162
-
163
- if (false == $freshnessLifetime) {
164
- return true;
165
- }
166
-
167
- // Calculate the age of an http response.
168
- $age = max(0, time() - $parsedDate);
169
- if (isset($responseHeaders['age'])) {
170
- $age = max($age, strtotime($responseHeaders['age']));
171
- }
172
-
173
- return $freshnessLifetime <= $age;
174
- }
175
-
176
- /**
177
- * Determine if a cache entry should be revalidated with by the origin.
178
- *
179
- * @param Google_Http_Request $response
180
- *
181
- * @return bool True if the entry is expired, else return false.
182
- */
183
- public static function mustRevalidate(Google_Http_Request $response)
184
- {
185
- // [13.3] When a cache has a stale entry that it would like to use as a
186
- // response to a client's request, it first has to check with the origin
187
- // server to see if its cached entry is still usable.
188
- return self::isExpired($response);
189
- }
190
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Google/Http/MediaFileUpload.php DELETED
@@ -1,280 +0,0 @@
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_Http_MediaFileUpload
23
- {
24
- const UPLOAD_MEDIA_TYPE = 'media';
25
- const UPLOAD_MULTIPART_TYPE = 'multipart';
26
- const UPLOAD_RESUMABLE_TYPE = 'resumable';
27
-
28
- /** @var string $mimeType */
29
- private $mimeType;
30
-
31
- /** @var string $data */
32
- private $data;
33
-
34
- /** @var bool $resumable */
35
- private $resumable;
36
-
37
- /** @var int $chunkSize */
38
- private $chunkSize;
39
-
40
- /** @var int $size */
41
- private $size;
42
-
43
- /** @var string $resumeUri */
44
- private $resumeUri;
45
-
46
- /** @var int $progress */
47
- private $progress;
48
-
49
- /** @var Google_ApiClient */
50
- private $client;
51
-
52
- /** @var Google_Http_Request */
53
- private $request;
54
-
55
- /** @var string */
56
- private $boundary;
57
-
58
- /**
59
- * @param $mimeType string
60
- * @param $data string The bytes you want to upload.
61
- * @param $resumable bool
62
- * @param bool $chunkSize File will be uploaded in chunks of this many bytes.
63
- * only used if resumable=True
64
- */
65
- public function __construct(
66
- Google_ApiClient $client,
67
- Google_Http_Request $request,
68
- $mimeType,
69
- $data,
70
- $resumable = false,
71
- $chunkSize = false,
72
- $boundary = false
73
- ) {
74
- $this->client = $client;
75
- $this->request = $request;
76
- $this->mimeType = $mimeType;
77
- $this->data = $data;
78
- $this->size = strlen($this->data);
79
- $this->resumable = $resumable;
80
- if (!$chunkSize) {
81
- $chunkSize = 256 * 1024;
82
- }
83
- $this->chunkSize = $chunkSize;
84
- $this->progress = 0;
85
- $this->boundary = $boundary;
86
-
87
- // Process Media Request
88
- $this->process();
89
- }
90
-
91
- /**
92
- * Set the size of the file that is being uploaded.
93
- *
94
- * @param $size - int file size in bytes
95
- */
96
- public function setFileSize($size)
97
- {
98
- $this->size = $size;
99
- }
100
-
101
- /**
102
- * Return the progress on the upload
103
- *
104
- * @return int progress in bytes uploaded.
105
- */
106
- public function getProgress()
107
- {
108
- return $this->progress;
109
- }
110
-
111
- /**
112
- * Send the next part of the file to upload.
113
- *
114
- * @param [$chunk] the next set of bytes to send. If false will used $data passed
115
- * at construct time.
116
- */
117
- public function nextChunk($chunk = false)
118
- {
119
- if (false == $this->resumeUri) {
120
- $this->resumeUri = $this->getResumeUri();
121
- }
122
-
123
- if (false == $chunk) {
124
- $chunk = substr($this->data, $this->progress, $this->chunkSize);
125
- }
126
-
127
- $lastBytePos = $this->progress + strlen($chunk) - 1;
128
- $headers = array(
129
- 'content-range' => "bytes $this->progress-$lastBytePos/$this->size",
130
- 'content-type' => $this->request->getRequestHeader('content-type'),
131
- 'content-length' => $this->chunkSize,
132
- 'expect' => '',
133
- );
134
-
135
- $httpRequest = new Google_Http_Request(
136
- $this->resumeUri,
137
- 'PUT',
138
- $headers,
139
- $chunk
140
- );
141
-
142
- if ($this->client->getClassConfig("Google_Http_Request", "enable_gzip_for_uploads")) {
143
- $httpRequest->enableGzip();
144
- } else {
145
- $httpRequest->disableGzip();
146
- }
147
-
148
- $response = $this->client->getIo()->makeRequest($httpRequest);
149
- $response->setExpectedClass($this->request->getExpectedClass());
150
- $code = $response->getResponseHttpCode();
151
-
152
- if (308 == $code) {
153
- // Track the amount uploaded.
154
- $range = explode('-', $response->getResponseHeader('range'));
155
- $this->progress = $range[1] + 1;
156
-
157
- // Allow for changing upload URLs.
158
- $location = $response->getResponseHeader('location');
159
- if ($location) {
160
- $this->resumeUri = $location;
161
- }
162
-
163
- // No problems, but upload not complete.
164
- return false;
165
- } else {
166
- return Google_Http_REST::decodeHttpResponse($response);
167
- }
168
- }
169
-
170
- /**
171
- * @param $meta
172
- * @param $params
173
- *
174
- * @return array|bool
175
- * @visible for testing
176
- */
177
- private function process()
178
- {
179
- $postBody = false;
180
- $contentType = false;
181
-
182
- $meta = $this->request->getPostBody();
183
- $meta = is_string($meta) ? json_decode($meta, true) : $meta;
184
-
185
- $uploadType = $this->getUploadType($meta);
186
- $this->request->setQueryParam('uploadType', $uploadType);
187
- $this->transformToUploadUrl();
188
- $mimeType = $this->mimeType ?
189
- $this->mimeType :
190
- $this->request->getRequestHeader('content-type');
191
-
192
- if (self::UPLOAD_RESUMABLE_TYPE == $uploadType) {
193
- $contentType = $mimeType;
194
- $postBody = is_string($meta) ? $meta : json_encode($meta);
195
- } else {
196
- if (self::UPLOAD_MEDIA_TYPE == $uploadType) {
197
- $contentType = $mimeType;
198
- $postBody = $this->data;
199
- } else {
200
- if (self::UPLOAD_MULTIPART_TYPE == $uploadType) {
201
- // This is a multipart/related upload.
202
- $boundary = $this->boundary ? $this->boundary : mt_rand();
203
- $boundary = str_replace('"', '', $boundary);
204
- $contentType = 'multipart/related; boundary='.$boundary;
205
- $related = "--$boundary\r\n";
206
- $related .= "Content-Type: application/json; charset=UTF-8\r\n";
207
- $related .= "\r\n".json_encode($meta)."\r\n";
208
- $related .= "--$boundary\r\n";
209
- $related .= "Content-Type: $mimeType\r\n";
210
- $related .= "Content-Transfer-Encoding: base64\r\n";
211
- $related .= "\r\n".base64_encode($this->data)."\r\n";
212
- $related .= "--$boundary--";
213
- $postBody = $related;
214
- }
215
- }
216
- }
217
-
218
- $this->request->setPostBody($postBody);
219
-
220
- if (isset($contentType) && $contentType) {
221
- $contentTypeHeader['content-type'] = $contentType;
222
- $this->request->setRequestHeaders($contentTypeHeader);
223
- }
224
- }
225
-
226
- private function transformToUploadUrl()
227
- {
228
- $base = $this->request->getBaseComponent();
229
- $this->request->setBaseComponent($base.'/upload');
230
- }
231
-
232
- /**
233
- * Valid upload types:
234
- * - resumable (UPLOAD_RESUMABLE_TYPE)
235
- * - media (UPLOAD_MEDIA_TYPE)
236
- * - multipart (UPLOAD_MULTIPART_TYPE)
237
- *
238
- * @param $meta
239
- *
240
- * @return string
241
- * @visible for testing
242
- */
243
- public function getUploadType($meta)
244
- {
245
- if ($this->resumable) {
246
- return self::UPLOAD_RESUMABLE_TYPE;
247
- }
248
-
249
- if (false == $meta && $this->data) {
250
- return self::UPLOAD_MEDIA_TYPE;
251
- }
252
-
253
- return self::UPLOAD_MULTIPART_TYPE;
254
- }
255
-
256
- private function getResumeUri()
257
- {
258
- $result = null;
259
- $body = $this->request->getPostBody();
260
- if ($body) {
261
- $headers = array(
262
- 'content-type' => 'application/json; charset=UTF-8',
263
- 'content-length' => Google_ApiUtils::getStrLen($body),
264
- 'x-upload-content-type' => $this->mimeType,
265
- 'x-upload-content-length' => $this->size,
266
- 'expect' => '',
267
- );
268
- $this->request->setRequestHeaders($headers);
269
- }
270
-
271
- $response = $this->client->getIo()->makeRequest($this->request);
272
- $location = $response->getResponseHeader('location');
273
- $code = $response->getResponseHttpCode();
274
-
275
- if (200 == $code && true == $location) {
276
- return $location;
277
- }
278
- throw new Google_ApiException("Failed to start the resumable upload");
279
- }
280
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Google/Http/REST.php DELETED
@@ -1,148 +0,0 @@
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_Http_REST
25
- {
26
- /**
27
- * Executes a Google_Http_Request
28
- *
29
- * @param Google_ApiClient $client
30
- * @param Google_Http_Request $req
31
- *
32
- * @return array decoded result
33
- * @throws Google_Service_Exception on server side error (ie: not authenticated,
34
- * invalid or malformed post body, invalid url)
35
- */
36
- public static function execute(Google_ApiClient $client, Google_Http_Request $req)
37
- {
38
- $httpRequest = $client->getIo()->makeRequest($req);
39
- $httpRequest->setExpectedClass($req->getExpectedClass());
40
-
41
- return self::decodeHttpResponse($httpRequest);
42
- }
43
-
44
- /**
45
- * Decode an HTTP Response.
46
- *
47
- * @static
48
- * @throws Google_Service_Exception
49
- *
50
- * @param Google_Http_Request $response The http response to be decoded.
51
- *
52
- * @return mixed|null
53
- */
54
- public static function decodeHttpResponse($response)
55
- {
56
- $code = $response->getResponseHttpCode();
57
- $body = $response->getResponseBody();
58
- $decoded = null;
59
-
60
- if ((intVal($code)) >= 300) {
61
- $decoded = json_decode($body, true);
62
- $err = 'Error calling '.$response->getRequestMethod().' '.$response->getUrl();
63
- if (isset($decoded['error']) &&
64
- isset($decoded['error']['message']) &&
65
- isset($decoded['error']['code'])
66
- ) {
67
- // if we're getting a json encoded error definition, use that instead of the raw response
68
- // body for improved readability
69
- $err .= ": ({$decoded['error']['code']}) {$decoded['error']['message']}";
70
- } else {
71
- $err .= ": ($code) $body";
72
- }
73
-
74
- $errors = null;
75
- // Specific check for APIs which don't return error details, such as Blogger.
76
- if (isset($decoded['error']) && isset($decoded['error']['errors'])) {
77
- $errors = $decoded['error']['errors'];
78
- }
79
-
80
- throw new Google_Service_Exception($err, $code, null, $errors);
81
- }
82
-
83
- // Only attempt to decode the response, if the response code wasn't (204) 'no content'
84
- if ($code != '204') {
85
- $decoded = json_decode($body, true);
86
- if ($decoded === null || $decoded === "") {
87
- throw new Google_Service_Exception("Invalid json in service response: $body");
88
- }
89
-
90
- $decoded = isset($decoded['data']) ? $decoded['data'] : $decoded;
91
-
92
- if ($response->getExpectedClass()) {
93
- $class = $response->getExpectedClass();
94
- $decoded = new $class($decoded);
95
- }
96
- }
97
-
98
- return $decoded;
99
- }
100
-
101
- /**
102
- * Parse/expand request parameters and create a fully qualified
103
- * request uri.
104
- *
105
- * @static
106
- *
107
- * @param string $servicePath
108
- * @param string $restPath
109
- * @param array $params
110
- *
111
- * @return string $requestUrl
112
- */
113
- public static function createRequestUri($servicePath, $restPath, $params)
114
- {
115
- $requestUrl = $servicePath.$restPath;
116
- $uriTemplateVars = array();
117
- $queryVars = array();
118
- foreach ($params as $paramName => $paramSpec) {
119
- if ($paramSpec['type'] == 'boolean') {
120
- $paramSpec['value'] = ($paramSpec['value']) ? 'true' : 'false';
121
- }
122
- if ($paramSpec['location'] == 'path') {
123
- $uriTemplateVars[$paramName] = $paramSpec['value'];
124
- } else {
125
- if ($paramSpec['location'] == 'query') {
126
- if (isset($paramSpec['repeated']) && is_array($paramSpec['value'])) {
127
- foreach ($paramSpec['value'] as $value) {
128
- $queryVars[] = $paramName.'='.rawurlencode($value);
129
- }
130
- } else {
131
- $queryVars[] = $paramName.'='.rawurlencode($paramSpec['value']);
132
- }
133
- }
134
- }
135
- }
136
-
137
- if (count($uriTemplateVars)) {
138
- $uriTemplateParser = new Google_Utils_URITemplate();
139
- $requestUrl = $uriTemplateParser->parse($requestUrl, $uriTemplateVars);
140
- }
141
-
142
- if (count($queryVars)) {
143
- $requestUrl .= '?'.implode($queryVars, '&');
144
- }
145
-
146
- return $requestUrl;
147
- }
148
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Google/Http/Request.php DELETED
@@ -1,488 +0,0 @@
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 IO 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_Http_Request
27
- {
28
- const GZIP_UA = " (gzip)";
29
-
30
- private $batchHeaders = array(
31
- 'Content-Type' => 'application/http',
32
- 'Content-Transfer-Encoding' => 'binary',
33
- 'MIME-Version' => '1.0',
34
- );
35
-
36
- protected $queryParams;
37
- protected $requestMethod;
38
- protected $requestHeaders;
39
- protected $baseComponent = null;
40
- protected $path;
41
- protected $postBody;
42
- protected $userAgent;
43
- protected $canGzip = null;
44
-
45
- protected $responseHttpCode;
46
- protected $responseHeaders;
47
- protected $responseBody;
48
-
49
- protected $expectedClass;
50
-
51
- public $accessKey;
52
-
53
- public function __construct(
54
- $url,
55
- $method = 'GET',
56
- $headers = array(),
57
- $postBody = null
58
- ) {
59
- $this->setUrl($url);
60
- $this->setRequestMethod($method);
61
- $this->setRequestHeaders($headers);
62
- $this->setPostBody($postBody);
63
- }
64
-
65
- /**
66
- * Misc function that returns the base url component of the $url
67
- * used by the OAuth signing class to calculate the base string
68
- *
69
- * @return string The base url component of the $url.
70
- */
71
- public function getBaseComponent()
72
- {
73
- return $this->baseComponent;
74
- }
75
-
76
- /**
77
- * Set the base URL that path and query parameters will be added to.
78
- *
79
- * @param $baseComponent string
80
- */
81
- public function setBaseComponent($baseComponent)
82
- {
83
- $this->baseComponent = $baseComponent;
84
- }
85
-
86
- /**
87
- * Enable support for gzipped responses with this request.
88
- */
89
- public function enableGzip()
90
- {
91
- $this->setRequestHeaders(array("Accept-Encoding" => "gzip"));
92
- $this->canGzip = true;
93
- $this->setUserAgent($this->userAgent);
94
- }
95
-
96
- /**
97
- * Disable support for gzip responses with this request.
98
- */
99
- public function disableGzip()
100
- {
101
- if (
102
- isset($this->requestHeaders['accept-encoding']) &&
103
- $this->requestHeaders['accept-encoding'] == "gzip"
104
- ) {
105
- unset($this->requestHeaders['accept-encoding']);
106
- }
107
- $this->canGzip = false;
108
- $this->userAgent = str_replace(self::GZIP_UA, "", $this->userAgent);
109
- }
110
-
111
- /**
112
- * Can this request accept a gzip response?
113
- *
114
- * @return bool
115
- */
116
- public function canGzip()
117
- {
118
- return $this->canGzip;
119
- }
120
-
121
- /**
122
- * Misc function that returns an array of the query parameters of the current
123
- * url used by the OAuth signing class to calculate the signature
124
- *
125
- * @return array Query parameters in the query string.
126
- */
127
- public function getQueryParams()
128
- {
129
- return $this->queryParams;
130
- }
131
-
132
- /**
133
- * Set a new query parameter.
134
- *
135
- * @param $key - string to set, does not need to be URL encoded
136
- * @param $value - string to set, does not need to be URL encoded
137
- */
138
- public function setQueryParam($key, $value)
139
- {
140
- $this->queryParams[$key] = $value;
141
- }
142
-
143
- /**
144
- * @return string HTTP Response Code.
145
- */
146
- public function getResponseHttpCode()
147
- {
148
- return (int) $this->responseHttpCode;
149
- }
150
-
151
- /**
152
- * @param int $responseHttpCode HTTP Response Code.
153
- */
154
- public function setResponseHttpCode($responseHttpCode)
155
- {
156
- $this->responseHttpCode = $responseHttpCode;
157
- }
158
-
159
- /**
160
- * @return $responseHeaders (array) HTTP Response Headers.
161
- */
162
- public function getResponseHeaders()
163
- {
164
- return $this->responseHeaders;
165
- }
166
-
167
- /**
168
- * @return string HTTP Response Body
169
- */
170
- public function getResponseBody()
171
- {
172
- return $this->responseBody;
173
- }
174
-
175
- /**
176
- * Set the class the response to this request should expect.
177
- *
178
- * @param $class string the class name
179
- */
180
- public function setExpectedClass($class)
181
- {
182
- $this->expectedClass = $class;
183
- }
184
-
185
- /**
186
- * Retrieve the expected class the response should expect.
187
- *
188
- * @return string class name
189
- */
190
- public function getExpectedClass()
191
- {
192
- return $this->expectedClass;
193
- }
194
-
195
- /**
196
- * @param array $headers The HTTP response headers
197
- * to be normalized.
198
- */
199
- public function setResponseHeaders($headers)
200
- {
201
- $headers = Google_ApiUtils::normalize($headers);
202
- if ($this->responseHeaders) {
203
- $headers = array_merge($this->responseHeaders, $headers);
204
- }
205
-
206
- $this->responseHeaders = $headers;
207
- }
208
-
209
- /**
210
- * @param string $key
211
- *
212
- * @return array|boolean Returns the requested HTTP header or
213
- * false if unavailable.
214
- */
215
- public function getResponseHeader($key)
216
- {
217
- return isset($this->responseHeaders[$key])
218
- ? $this->responseHeaders[$key]
219
- : false;
220
- }
221
-
222
- /**
223
- * @param string $responseBody The HTTP response body.
224
- */
225
- public function setResponseBody($responseBody)
226
- {
227
- $this->responseBody = $responseBody;
228
- }
229
-
230
- /**
231
- * @return string $url The request URL.
232
- */
233
- public function getUrl()
234
- {
235
- return $this->baseComponent.$this->path.
236
- (count($this->queryParams) ?
237
- "?".$this->buildQuery($this->queryParams) :
238
- '');
239
- }
240
-
241
- /**
242
- * @return string $method HTTP Request Method.
243
- */
244
- public function getRequestMethod()
245
- {
246
- return $this->requestMethod;
247
- }
248
-
249
- /**
250
- * @return array $headers HTTP Request Headers.
251
- */
252
- public function getRequestHeaders()
253
- {
254
- return $this->requestHeaders;
255
- }
256
-
257
- /**
258
- * @param string $key
259
- *
260
- * @return array|boolean Returns the requested HTTP header or
261
- * false if unavailable.
262
- */
263
- public function getRequestHeader($key)
264
- {
265
- return isset($this->requestHeaders[$key])
266
- ? $this->requestHeaders[$key]
267
- : false;
268
- }
269
-
270
- /**
271
- * @return string $postBody HTTP Request Body.
272
- */
273
- public function getPostBody()
274
- {
275
- return $this->postBody;
276
- }
277
-
278
- /**
279
- * @param string $url the url to set
280
- */
281
- public function setUrl($url)
282
- {
283
- if (substr($url, 0, 4) != 'http') {
284
- // Force the path become relative.
285
- if (substr($url, 0, 1) !== '/') {
286
- $url = '/'.$url;
287
- }
288
- }
289
- $parts = parse_url($url);
290
- if (isset($parts['host'])) {
291
- $this->baseComponent = sprintf(
292
- "%s%s%s",
293
- isset($parts['scheme']) ? $parts['scheme']."://" : '',
294
- isset($parts['host']) ? $parts['host'] : '',
295
- isset($parts['port']) ? ":".$parts['port'] : ''
296
- );
297
- }
298
- $this->path = isset($parts['path']) ? $parts['path'] : '';
299
- $this->queryParams = array();
300
- if (isset($parts['query'])) {
301
- $this->queryParams = $this->parseQuery($parts['query']);
302
- }
303
- }
304
-
305
- /**
306
- * @param string $method Set he HTTP Method and normalize
307
- * it to upper-case, as required by HTTP.
308
- *
309
- */
310
- public function setRequestMethod($method)
311
- {
312
- $this->requestMethod = strtoupper($method);
313
- }
314
-
315
- /**
316
- * @param array $headers The HTTP request headers
317
- * to be set and normalized.
318
- */
319
- public function setRequestHeaders($headers)
320
- {
321
- $headers = Google_ApiUtils::normalize($headers);
322
- if ($this->requestHeaders) {
323
- $headers = array_merge($this->requestHeaders, $headers);
324
- }
325
- $this->requestHeaders = $headers;
326
- }
327
-
328
- /**
329
- * @param string $postBody the postBody to set
330
- */
331
- public function setPostBody($postBody)
332
- {
333
- $this->postBody = $postBody;
334
- }
335
-
336
- /**
337
- * Set the User-Agent Header.
338
- *
339
- * @param string $userAgent The User-Agent.
340
- */
341
- public function setUserAgent($userAgent)
342
- {
343
- $this->userAgent = $userAgent;
344
- if ($this->canGzip) {
345
- $this->userAgent = $userAgent.self::GZIP_UA;
346
- }
347
- }
348
-
349
- /**
350
- * @return string The User-Agent.
351
- */
352
- public function getUserAgent()
353
- {
354
- return $this->userAgent;
355
- }
356
-
357
- /**
358
- * Returns a cache key depending on if this was an OAuth signed request
359
- * in which case it will use the non-signed url and access key to make this
360
- * cache key unique per authenticated user, else use the plain request url
361
- *
362
- * @return string The md5 hash of the request cache key.
363
- */
364
- public function getCacheKey()
365
- {
366
- $key = $this->getUrl();
367
-
368
- if (isset($this->accessKey)) {
369
- $key .= $this->accessKey;
370
- }
371
-
372
- if (isset($this->requestHeaders['authorization'])) {
373
- $key .= $this->requestHeaders['authorization'];
374
- }
375
-
376
- return md5($key);
377
- }
378
-
379
- public function getParsedCacheControl()
380
- {
381
- $parsed = array();
382
- $rawCacheControl = $this->getResponseHeader('cache-control');
383
- if ($rawCacheControl) {
384
- $rawCacheControl = str_replace(', ', '&', $rawCacheControl);
385
- parse_str($rawCacheControl, $parsed);
386
- }
387
-
388
- return $parsed;
389
- }
390
-
391
- /**
392
- * @param string $id
393
- *
394
- * @return string A string representation of the HTTP Request.
395
- */
396
- public function toBatchString($id)
397
- {
398
- $str = '';
399
- $path = parse_url($this->getUrl(), PHP_URL_PATH)."?".
400
- http_build_query($this->queryParams);
401
- $str .= $this->getRequestMethod().' '.$path." HTTP/1.1\n";
402
-
403
- foreach ($this->getRequestHeaders() as $key => $val) {
404
- $str .= $key.': '.$val."\n";
405
- }
406
-
407
- if ($this->getPostBody()) {
408
- $str .= "\n";
409
- $str .= $this->getPostBody();
410
- }
411
-
412
- $headers = '';
413
- foreach ($this->batchHeaders as $key => $val) {
414
- $headers .= $key.': '.$val."\n";
415
- }
416
-
417
- $headers .= "Content-ID: $id\n";
418
- $str = $headers."\n".$str;
419
-
420
- return $str;
421
- }
422
-
423
- /**
424
- * Our own version of parse_str that allows for multiple variables
425
- * with the same name.
426
- *
427
- * @param $string - the query string to parse
428
- */
429
- private function parseQuery($string)
430
- {
431
- $return = array();
432
- $parts = explode("&", $string);
433
- foreach ($parts as $part) {
434
- list($key, $value) = explode('=', $part, 2);
435
- $value = urldecode($value);
436
- if (isset($return[$key])) {
437
- if (!is_array($return[$key])) {
438
- $return[$key] = array($return[$key]);
439
- }
440
- $return[$key][] = $value;
441
- } else {
442
- $return[$key] = $value;
443
- }
444
- }
445
-
446
- return $return;
447
- }
448
-
449
- /**
450
- * A version of build query that allows for multiple
451
- * duplicate keys.
452
- *
453
- * @param $parts array of key value pairs
454
- */
455
- private function buildQuery($parts)
456
- {
457
- $return = array();
458
- foreach ($parts as $key => $value) {
459
- if (is_array($value)) {
460
- foreach ($value as $v) {
461
- $return[] = urlencode($key)."=".urlencode($v);
462
- }
463
- } else {
464
- $return[] = urlencode($key)."=".urlencode($value);
465
- }
466
- }
467
-
468
- return implode('&', $return);
469
- }
470
-
471
- /**
472
- * If we're POSTing and have no body to send, we can send the query
473
- * parameters in there, which avoids length issues with longer query
474
- * params.
475
- */
476
- public function maybeMoveParametersToBody()
477
- {
478
- if ($this->getRequestMethod() == "POST" && empty($this->postBody)) {
479
- $this->setRequestHeaders(
480
- array(
481
- "content-type" => "application/x-www-form-urlencoded; charset=UTF-8",
482
- )
483
- );
484
- $this->setPostBody($this->buildQuery($this->queryParams));
485
- $this->queryParams = array();
486
- }
487
- }
488
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Google/IO/Abstract.php DELETED
@@ -1,341 +0,0 @@
1
- <?php
2
- /*
3
- * Copyright 2013 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
- * Abstract IO base class
20
- */
21
- abstract class Google_IO_Abstract
22
- {
23
- const UNKNOWN_CODE = 0;
24
- const FORM_URLENCODED = 'application/x-www-form-urlencoded';
25
- const CONNECTION_ESTABLISHED = "HTTP/1.0 200 Connection established\r\n\r\n";
26
-
27
- private static $ENTITY_HTTP_METHODS = array("POST" => null, "PUT" => null);
28
-
29
- /** @var Google_ApiClient */
30
- protected $client;
31
-
32
- public function __construct(Google_ApiClient $client)
33
- {
34
- $this->client = $client;
35
- $timeout = $client->getClassConfig('Google_IO_Abstract', 'request_timeout_seconds');
36
- if ($timeout > 0) {
37
- $this->setTimeout($timeout);
38
- }
39
- }
40
-
41
- /**
42
- * Executes a Google_Http_Request and returns the resulting populated Google_Http_Request
43
- *
44
- * @param Google_Http_Request $request
45
- *
46
- * @return Google_Http_Request $request
47
- */
48
- abstract public function executeRequest(Google_Http_Request $request);
49
-
50
- /**
51
- * Set options that update the transport implementation's behavior.
52
- *
53
- * @param $options
54
- */
55
- abstract public function setOptions($options);
56
-
57
- /**
58
- * Set the maximum request time in seconds.
59
- *
60
- * @param $timeout in seconds
61
- */
62
- abstract public function setTimeout($timeout);
63
-
64
- /**
65
- * Get the maximum request time in seconds.
66
- *
67
- * @return timeout in seconds
68
- */
69
- abstract public function getTimeout();
70
-
71
- /**
72
- * Test for the presence of a cURL header processing bug
73
- *
74
- * The cURL bug was present in versions prior to 7.30.0 and caused the header
75
- * length to be miscalculated when a "Connection established" header added by
76
- * some proxies was present.
77
- *
78
- * @return boolean
79
- */
80
- abstract protected function needsQuirk();
81
-
82
- /**
83
- * @visible for testing.
84
- * Cache the response to an HTTP request if it is cacheable.
85
- *
86
- * @param Google_Http_Request $request
87
- *
88
- * @return bool Returns true if the insertion was successful.
89
- * Otherwise, return false.
90
- */
91
- public function setCachedRequest(Google_Http_Request $request)
92
- {
93
- // Determine if the request is cacheable.
94
- if (Google_Http_CacheParser::isResponseCacheable($request)) {
95
- $this->client->getCache()->set($request->getCacheKey(), $request);
96
-
97
- return true;
98
- }
99
-
100
- return false;
101
- }
102
-
103
- /**
104
- * Execute an HTTP Request
105
- *
106
- * @param Google_HttpRequest $request the http request to be executed
107
- *
108
- * @return Google_HttpRequest http request with the response http code,
109
- * response headers and response body filled in
110
- * @throws Google_IO_Exception on curl or IO error
111
- */
112
- public function makeRequest(Google_Http_Request $request)
113
- {
114
- // First, check to see if we have a valid cached version.
115
- $cached = $this->getCachedRequest($request);
116
- if ($cached !== false && $cached instanceof Google_Http_Request) {
117
- if (!$this->checkMustRevalidateCachedRequest($cached, $request)) {
118
- return $cached;
119
- }
120
- }
121
-
122
- if (array_key_exists($request->getRequestMethod(), self::$ENTITY_HTTP_METHODS)) {
123
- $request = $this->processEntityRequest($request);
124
- }
125
-
126
- list($responseData, $responseHeaders, $respHttpCode) = $this->executeRequest($request);
127
-
128
- if ($respHttpCode == 304 && $cached) {
129
- // If the server responded NOT_MODIFIED, return the cached request.
130
- $this->updateCachedRequest($cached, $responseHeaders);
131
-
132
- return $cached;
133
- }
134
-
135
- if (!isset($responseHeaders['Date']) && !isset($responseHeaders['date'])) {
136
- $responseHeaders['Date'] = date("r");
137
- }
138
-
139
- $request->setResponseHttpCode($respHttpCode);
140
- $request->setResponseHeaders($responseHeaders);
141
- $request->setResponseBody($responseData);
142
- // Store the request in cache (the function checks to see if the request
143
- // can actually be cached)
144
- $this->setCachedRequest($request);
145
-
146
- return $request;
147
- }
148
-
149
- /**
150
- * @visible for testing.
151
- *
152
- * @param Google_Http_Request $request
153
- *
154
- * @return Google_Http_Request|bool Returns the cached object or
155
- * false if the operation was unsuccessful.
156
- */
157
- public function getCachedRequest(Google_Http_Request $request)
158
- {
159
- if (false === Google_Http_CacheParser::isRequestCacheable($request)) {
160
- return false;
161
- }
162
-
163
- return $this->client->getCache()->get($request->getCacheKey());
164
- }
165
-
166
- /**
167
- * @visible for testing
168
- * Process an http request that contains an enclosed entity.
169
- *
170
- * @param Google_Http_Request $request
171
- *
172
- * @return Google_Http_Request Processed request with the enclosed entity.
173
- */
174
- public function processEntityRequest(Google_Http_Request $request)
175
- {
176
- $postBody = $request->getPostBody();
177
- $contentType = $request->getRequestHeader("content-type");
178
-
179
- // Set the default content-type as application/x-www-form-urlencoded.
180
- if (false == $contentType) {
181
- $contentType = self::FORM_URLENCODED;
182
- $request->setRequestHeaders(array('content-type' => $contentType));
183
- }
184
-
185
- // Force the payload to match the content-type asserted in the header.
186
- if ($contentType == self::FORM_URLENCODED && is_array($postBody)) {
187
- $postBody = http_build_query($postBody, '', '&');
188
- $request->setPostBody($postBody);
189
- }
190
-
191
- // Make sure the content-length header is set.
192
- if (!$postBody || is_string($postBody)) {
193
- $postsLength = strlen($postBody);
194
- $request->setRequestHeaders(array('content-length' => $postsLength));
195
- }
196
-
197
- return $request;
198
- }
199
-
200
- /**
201
- * Check if an already cached request must be revalidated, and if so update
202
- * the request with the correct ETag headers.
203
- *
204
- * @param Google_Http_Request $cached A previously cached response.
205
- * @param Google_Http_Request $request The outbound request.
206
- * return bool If the cached object needs to be revalidated, false if it is
207
- * still current and can be re-used.
208
- */
209
- protected function checkMustRevalidateCachedRequest($cached, $request)
210
- {
211
- if (Google_Http_CacheParser::mustRevalidate($cached)) {
212
- $addHeaders = array();
213
- if ($cached->getResponseHeader('etag')) {
214
- // [13.3.4] If an entity tag has been provided by the origin server,
215
- // we must use that entity tag in any cache-conditional request.
216
- $addHeaders['If-None-Match'] = $cached->getResponseHeader('etag');
217
- } elseif ($cached->getResponseHeader('date')) {
218
- $addHeaders['If-Modified-Since'] = $cached->getResponseHeader('date');
219
- }
220
-
221
- $request->setRequestHeaders($addHeaders);
222
-
223
- return true;
224
- } else {
225
- return false;
226
- }
227
- }
228
-
229
- /**
230
- * Update a cached request, using the headers from the last response.
231
- *
232
- * @param Google_HttpRequest $cached A previously cached response.
233
- * @param mixed Associative array of response headers from the last request.
234
- */
235
- protected function updateCachedRequest($cached, $responseHeaders)
236
- {
237
- if (isset($responseHeaders['connection'])) {
238
- $hopByHop = array_merge(
239
- self::$HOP_BY_HOP,
240
- explode(
241
- ',',
242
- $responseHeaders['connection']
243
- )
244
- );
245
-
246
- $endToEnd = array();
247
- foreach ($hopByHop as $key) {
248
- if (isset($responseHeaders[$key])) {
249
- $endToEnd[$key] = $responseHeaders[$key];
250
- }
251
- }
252
- $cached->setResponseHeaders($endToEnd);
253
- }
254
- }
255
-
256
- /**
257
- * Used by the IO lib and also the batch processing.
258
- *
259
- * @param $respData
260
- * @param $headerSize
261
- *
262
- * @return array
263
- */
264
- public function parseHttpResponse($respData, $headerSize)
265
- {
266
- if (stripos($respData, self::CONNECTION_ESTABLISHED) !== false) {
267
- $respData = str_ireplace(self::CONNECTION_ESTABLISHED, '', $respData);
268
-
269
- // Subtract the proxy header size unless the cURL bug prior to 7.30.0
270
- // is present which prevented the proxy header size from being taken into
271
- // account.
272
- if (!$this->needsQuirk()) {
273
- $headerSize -= strlen(self::CONNECTION_ESTABLISHED);
274
- }
275
- }
276
-
277
- if ($headerSize) {
278
- $responseBody = substr($respData, $headerSize);
279
- $responseHeaders = substr($respData, 0, $headerSize);
280
- } else {
281
- list($responseHeaders, $responseBody) = explode("\r\n\r\n", $respData, 2);
282
- }
283
-
284
- $responseHeaders = $this->getHttpResponseHeaders($responseHeaders);
285
-
286
- return array($responseHeaders, $responseBody);
287
- }
288
-
289
- /**
290
- * Parse out headers from raw headers
291
- *
292
- * @param rawHeaders array or string
293
- *
294
- * @return array
295
- */
296
- public function getHttpResponseHeaders($rawHeaders)
297
- {
298
- if (is_array($rawHeaders)) {
299
- return $this->parseArrayHeaders($rawHeaders);
300
- } else {
301
- return $this->parseStringHeaders($rawHeaders);
302
- }
303
- }
304
-
305
- private function parseStringHeaders($rawHeaders)
306
- {
307
- $headers = array();
308
-
309
- $responseHeaderLines = explode("\r\n", $rawHeaders);
310
- foreach ($responseHeaderLines as $headerLine) {
311
- if ($headerLine && strpos($headerLine, ':') !== false) {
312
- list($header, $value) = explode(': ', $headerLine, 2);
313
- $header = strtolower($header);
314
- if (isset($responseHeaders[$header])) {
315
- $headers[$header] .= "\n".$value;
316
- } else {
317
- $headers[$header] = $value;
318
- }
319
- }
320
- }
321
-
322
- return $headers;
323
- }
324
-
325
- private function parseArrayHeaders($rawHeaders)
326
- {
327
- $header_count = count($rawHeaders);
328
- $headers = array();
329
-
330
- for ($i = 0; $i < $header_count; $i++) {
331
- $header = $rawHeaders[$i];
332
- // Times will have colons in - so we just want the first match.
333
- $header_parts = explode(': ', $header, 2);
334
- if (count($header_parts) == 2) {
335
- $headers[$header_parts[0]] = $header_parts[1];
336
- }
337
- }
338
-
339
- return $headers;
340
- }
341
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Google/IO/Curl.php DELETED
@@ -1,133 +0,0 @@
1
- <?php
2
- /*
3
- * Copyright 2014 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 Google_IO.
20
- *
21
- * @author Stuart Langley <slangley@google.com>
22
- */
23
- class Google_IO_Curl extends Google_IO_Abstract
24
- {
25
- // cURL hex representation of version 7.30.0
26
- const NO_QUIRK_VERSION = 0x071E00;
27
-
28
- private $options = array();
29
-
30
- /**
31
- * Execute an HTTP Request
32
- *
33
- * @param Google_HttpRequest $request the http request to be executed
34
- *
35
- * @return Google_HttpRequest http request with the response http code,
36
- * response headers and response body filled in
37
- * @throws Google_IO_Exception on curl or IO error
38
- */
39
- public function executeRequest(Google_Http_Request $request)
40
- {
41
- $curl = curl_init();
42
-
43
- if ($request->getPostBody()) {
44
- curl_setopt($curl, CURLOPT_POSTFIELDS, $request->getPostBody());
45
- }
46
-
47
- $requestHeaders = $request->getRequestHeaders();
48
- if ($requestHeaders && is_array($requestHeaders)) {
49
- $curlHeaders = array();
50
- foreach ($requestHeaders as $k => $v) {
51
- $curlHeaders[] = "$k: $v";
52
- }
53
- curl_setopt($curl, CURLOPT_HTTPHEADER, $curlHeaders);
54
- }
55
-
56
- curl_setopt($curl, CURLOPT_URL, $request->getUrl());
57
-
58
- curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $request->getRequestMethod());
59
- curl_setopt($curl, CURLOPT_USERAGENT, $request->getUserAgent());
60
-
61
- curl_setopt($curl, CURLOPT_FOLLOWLOCATION, false);
62
- curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, true);
63
- curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
64
- curl_setopt($curl, CURLOPT_HEADER, true);
65
-
66
- if ($request->canGzip()) {
67
- curl_setopt($curl, CURLOPT_ENCODING, 'gzip,deflate');
68
- }
69
-
70
- foreach ($this->options as $key => $var) {
71
- curl_setopt($curl, $key, $var);
72
- }
73
-
74
- if (!isset($this->options[CURLOPT_CAINFO])) {
75
- curl_setopt($curl, CURLOPT_CAINFO, dirname(__FILE__).'/cacerts.pem');
76
- }
77
-
78
- $response = curl_exec($curl);
79
- if ($response === false) {
80
- throw new Google_IO_Exception(curl_error($curl));
81
- }
82
- $headerSize = curl_getinfo($curl, CURLINFO_HEADER_SIZE);
83
-
84
- list($responseHeaders, $responseBody) = $this->parseHttpResponse($response, $headerSize);
85
-
86
- $responseCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
87
-
88
- return array($responseBody, $responseHeaders, $responseCode);
89
- }
90
-
91
- /**
92
- * Set options that update the transport implementation's behavior.
93
- *
94
- * @param $options
95
- */
96
- public function setOptions($options)
97
- {
98
- $this->options = array_merge($this->options, $options);
99
- }
100
-
101
- /**
102
- * Set the maximum request time in seconds.
103
- *
104
- * @param $timeout in seconds
105
- */
106
- public function setTimeout($timeout)
107
- {
108
- // Since this timeout is really for putting a bound on the time
109
- // we'll set them both to the same. If you need to specify a longer
110
- // CURLOPT_TIMEOUT, or a tigher CONNECTTIMEOUT, the best thing to
111
- // do is use the setOptions method for the values individually.
112
- $this->options[CURLOPT_CONNECTTIMEOUT] = $timeout;
113
- $this->options[CURLOPT_TIMEOUT] = $timeout;
114
- }
115
-
116
- /**
117
- * Get the maximum request time in seconds.
118
- *
119
- * @return timeout in seconds
120
- */
121
- public function getTimeout()
122
- {
123
- return $this->options[CURLOPT_TIMEOUT];
124
- }
125
-
126
- protected function needsQuirk()
127
- {
128
- $ver = curl_version();
129
- $versionNum = $ver['version_number'];
130
-
131
- return $versionNum < Google_IO_Curl::NO_QUIRK_VERSION;
132
- }
133
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Google/IO/Exception.php DELETED
@@ -1,21 +0,0 @@
1
- <?php
2
-
3
- /*
4
- * Copyright 2013 Google Inc.
5
- *
6
- * Licensed under the Apache License, Version 2.0 (the "License");
7
- * you may not use this file except in compliance with the License.
8
- * You may obtain a copy of the License at
9
- *
10
- * http://www.apache.org/licenses/LICENSE-2.0
11
- *
12
- * Unless required by applicable law or agreed to in writing, software
13
- * distributed under the License is distributed on an "AS IS" BASIS,
14
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
- * See the License for the specific language governing permissions and
16
- * limitations under the License.
17
- */
18
-
19
- class Google_IO_Exception extends Google_ApiException
20
- {
21
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Google/IO/Stream.php DELETED
@@ -1,179 +0,0 @@
1
- <?php
2
- /*
3
- * Copyright 2013 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 Streams based implementation of Google_IO.
20
- *
21
- * @author Stuart Langley <slangley@google.com>
22
- */
23
- class Google_IO_Stream extends Google_IO_Abstract
24
- {
25
- const TIMEOUT = "timeout";
26
- const ZLIB = "compress.zlib://";
27
- private $options = array();
28
-
29
- private static $DEFAULT_HTTP_CONTEXT = array(
30
- "follow_location" => 0,
31
- "ignore_errors" => 1,
32
- );
33
-
34
- private static $DEFAULT_SSL_CONTEXT = array(
35
- "verify_peer" => true,
36
- );
37
-
38
- /**
39
- * Execute an HTTP Request
40
- *
41
- * @param Google_HttpRequest $request the http request to be executed
42
- *
43
- * @return Google_HttpRequest http request with the response http code,
44
- * response headers and response body filled in
45
- * @throws Google_IO_Exception on curl or IO error
46
- */
47
- public function executeRequest(Google_Http_Request $request)
48
- {
49
- $default_options = stream_context_get_options(stream_context_get_default());
50
-
51
- $requestHttpContext = array_key_exists('http', $default_options) ?
52
- $default_options['http'] : array();
53
-
54
- if ($request->getPostBody()) {
55
- $requestHttpContext["content"] = $request->getPostBody();
56
- }
57
-
58
- $requestHeaders = $request->getRequestHeaders();
59
- if ($requestHeaders && is_array($requestHeaders)) {
60
- $headers = "";
61
- foreach ($requestHeaders as $k => $v) {
62
- $headers .= "$k: $v\r\n";
63
- }
64
- $requestHttpContext["header"] = $headers;
65
- }
66
-
67
- $requestHttpContext["method"] = $request->getRequestMethod();
68
- $requestHttpContext["user_agent"] = $request->getUserAgent();
69
-
70
- $requestSslContext = array_key_exists('ssl', $default_options) ?
71
- $default_options['ssl'] : array();
72
-
73
- if (!array_key_exists("cafile", $requestSslContext)) {
74
- $requestSslContext["cafile"] = dirname(__FILE__).'/cacerts.pem';
75
- }
76
-
77
- $options = array(
78
- "http" => array_merge(
79
- self::$DEFAULT_HTTP_CONTEXT,
80
- $requestHttpContext
81
- ),
82
- "ssl" => array_merge(
83
- self::$DEFAULT_SSL_CONTEXT,
84
- $requestSslContext
85
- ),
86
- );
87
-
88
- $context = stream_context_create($options);
89
-
90
- $url = $request->getUrl();
91
-
92
- if ($request->canGzip()) {
93
- $url = self::ZLIB.$url;
94
- }
95
-
96
- // Not entirely happy about this, but supressing the warning from the
97
- // fopen seems like the best situation here - we can't do anything
98
- // useful with it, and failure to connect is a legitimate run
99
- // time situation.
100
- @$fh = fopen($url, 'r', false, $context);
101
-
102
- $response_data = false;
103
- $respHttpCode = self::UNKNOWN_CODE;
104
- if ($fh) {
105
- if (isset($this->options[self::TIMEOUT])) {
106
- stream_set_timeout($fh, $this->options[self::TIMEOUT]);
107
- }
108
-
109
- $response_data = stream_get_contents($fh);
110
- fclose($fh);
111
-
112
- $respHttpCode = $this->getHttpResponseCode($http_response_header);
113
- }
114
-
115
- if (false === $response_data) {
116
- throw new Google_IO_Exception(
117
- sprintf(
118
- "HTTP Error: Unable to connect: '%s'",
119
- $respHttpCode
120
- ),
121
- $respHttpCode
122
- );
123
- }
124
-
125
- $responseHeaders = $this->getHttpResponseHeaders($http_response_header);
126
-
127
- return array($response_data, $responseHeaders, $respHttpCode);
128
- }
129
-
130
- /**
131
- * Set options that update the transport implementation's behavior.
132
- *
133
- * @param $options
134
- */
135
- public function setOptions($options)
136
- {
137
- $this->options = array_merge($this->options, $options);
138
- }
139
-
140
- /**
141
- * Set the maximum request time in seconds.
142
- *
143
- * @param $timeout in seconds
144
- */
145
- public function setTimeout($timeout)
146
- {
147
- $this->options[self::TIMEOUT] = $timeout;
148
- }
149
-
150
- /**
151
- * Get the maximum request time in seconds.
152
- * @return timeout in seconds
153
- */
154
- public function getTimeout()
155
- {
156
- return $this->options[self::TIMEOUT];
157
- }
158
-
159
- protected function getHttpResponseCode($response_headers)
160
- {
161
- $header_count = count($response_headers);
162
-
163
- for ($i = 0; $i < $header_count; $i++) {
164
- $header = $response_headers[$i];
165
- if (strncasecmp("HTTP", $header, strlen("HTTP")) == 0) {
166
- $response = explode(' ', $header);
167
-
168
- return $response[1];
169
- }
170
- }
171
-
172
- return self::UNKNOWN_CODE;
173
- }
174
-
175
- protected function needsQuirk()
176
- {
177
- return false;
178
- }
179
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Google/IO/cacerts.pem DELETED
@@ -1,738 +0,0 @@
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
-
715
- GeoTrust Global CA
716
- ==================
717
-
718
- -----BEGIN CERTIFICATE-----
719
- MIIDfTCCAuagAwIBAgIDErvmMA0GCSqGSIb3DQEBBQUAME4xCzAJBgNVBAYTAlVT
720
- MRAwDgYDVQQKEwdFcXVpZmF4MS0wKwYDVQQLEyRFcXVpZmF4IFNlY3VyZSBDZXJ0
721
- aWZpY2F0ZSBBdXRob3JpdHkwHhcNMDIwNTIxMDQwMDAwWhcNMTgwODIxMDQwMDAw
722
- WjBCMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEbMBkGA1UE
723
- AxMSR2VvVHJ1c3QgR2xvYmFsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
724
- CgKCAQEA2swYYzD99BcjGlZ+W988bDjkcbd4kdS8odhM+KhDtgPpTSEHCIjaWC9m
725
- OSm9BXiLnTjoBbdqfnGk5sRgprDvgOSJKA+eJdbtg/OtppHHmMlCGDUUna2YRpIu
726
- T8rxh0PBFpVXLVDviS2Aelet8u5fa9IAjbkU+BQVNdnARqN7csiRv8lVK83Qlz6c
727
- JmTM386DGXHKTubU1XupGc1V3sjs0l44U+VcT4wt/lAjNvxm5suOpDkZALeVAjmR
728
- Cw7+OC7RHQWa9k0+bw8HHa8sHo9gOeL6NlMTOdReJivbPagUvTLrGAMoUgRx5asz
729
- PeE4uwc2hGKceeoWMPRfwCvocWvk+QIDAQABo4HwMIHtMB8GA1UdIwQYMBaAFEjm
730
- aPkr0rKV10fYIyAQTzOYkJ/UMB0GA1UdDgQWBBTAephojYn7qwVkDBF9qn1luMrM
731
- TjAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjA6BgNVHR8EMzAxMC+g
732
- LaArhilodHRwOi8vY3JsLmdlb3RydXN0LmNvbS9jcmxzL3NlY3VyZWNhLmNybDBO
733
- BgNVHSAERzBFMEMGBFUdIAAwOzA5BggrBgEFBQcCARYtaHR0cHM6Ly93d3cuZ2Vv
734
- dHJ1c3QuY29tL3Jlc291cmNlcy9yZXBvc2l0b3J5MA0GCSqGSIb3DQEBBQUAA4GB
735
- AHbhEm5OSxYShjAGsoEIz/AIx8dxfmbuwu3UOx//8PDITtZDOLC5MH0Y0FWDomrL
736
- NhGc6Ehmo21/uBPUR/6LWlxz/K7ZGzIZOKuXNBSqltLroxwUCEm2u+WR74M26x1W
737
- b8ravHNjkOR/ez4iyz0H7V84dJzjA1BOoa+Y7mHyhD8S
738
- -----END CERTIFICATE-----
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Google/Service/Drive.php DELETED
@@ -1,5888 +0,0 @@
1
- <?php
2
- /*
3
- * Copyright 2010 Google Inc.
4
- *
5
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
6
- * use this file except in compliance with the License. You may obtain a copy of
7
- * 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, WITHOUT
13
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14
- * License for the specific language governing permissions and limitations under
15
- * the License.
16
- */
17
-
18
- /**
19
- * Service definition for Drive (v2).
20
- *
21
- * <p>
22
- * The API to interact with Drive.
23
- * </p>
24
- *
25
- * <p>
26
- * For more information about this service, see the API
27
- * <a href="https://developers.google.com/drive/" target="_blank">Documentation</a>
28
- * </p>
29
- *
30
- * @author Google, Inc.
31
- */
32
- class Google_Service_Drive extends Google_ApiService
33
- {
34
- /** View and manage the files and documents in your Google Drive. */
35
- const DRIVE = "https://www.googleapis.com/auth/drive";
36
- /** View and manage its own configuration data in your Google Drive. */
37
- const DRIVE_APPDATA = "https://www.googleapis.com/auth/drive.appdata";
38
- /** View your Google Drive apps. */
39
- const DRIVE_APPS_READONLY = "https://www.googleapis.com/auth/drive.apps.readonly";
40
- /** View and manage Google Drive files that you have opened or created with this app. */
41
- const DRIVE_FILE = "https://www.googleapis.com/auth/drive.file";
42
- /** View metadata for files and documents in your Google Drive. */
43
- const DRIVE_METADATA_READONLY = "https://www.googleapis.com/auth/drive.metadata.readonly";
44
- /** View the files and documents in your Google Drive. */
45
- const DRIVE_READONLY = "https://www.googleapis.com/auth/drive.readonly";
46
- /** Modify your Google Apps Script scripts' behavior. */
47
- const DRIVE_SCRIPTS = "https://www.googleapis.com/auth/drive.scripts";
48
-
49
- public $about;
50
- public $apps;
51
- public $changes;
52
- public $channels;
53
- public $children;
54
- public $comments;
55
- public $files;
56
- public $parents;
57
- public $permissions;
58
- public $properties;
59
- public $realtime;
60
- public $replies;
61
- public $revisions;
62
-
63
- /**
64
- * Constructs the internal representation of the Drive service.
65
- *
66
- * @param Google_ApiClient $client
67
- */
68
- public function __construct(Google_ApiClient $client)
69
- {
70
- parent::__construct($client);
71
- $this->servicePath = 'drive/v2/';
72
- $this->version = 'v2';
73
- $this->serviceName = 'drive';
74
-
75
- $this->about = new Google_Service_Drive_About_Resource(
76
- $this,
77
- $this->serviceName,
78
- 'about',
79
- array(
80
- 'methods' => array(
81
- 'get' => array(
82
- 'path' => 'about',
83
- 'httpMethod' => 'GET',
84
- 'parameters' => array(
85
- 'includeSubscribed' => array(
86
- 'location' => 'query',
87
- 'type' => 'boolean',
88
- ),
89
- 'maxChangeIdCount' => array(
90
- 'location' => 'query',
91
- 'type' => 'string',
92
- ),
93
- 'startChangeId' => array(
94
- 'location' => 'query',
95
- 'type' => 'string',
96
- ),
97
- ),
98
- ),
99
- ),
100
- )
101
- );
102
- $this->apps = new Google_Service_Drive_Apps_Resource(
103
- $this,
104
- $this->serviceName,
105
- 'apps',
106
- array(
107
- 'methods' => array(
108
- 'get' => array(
109
- 'path' => 'apps/{appId}',
110
- 'httpMethod' => 'GET',
111
- 'parameters' => array(
112
- 'appId' => array(
113
- 'location' => 'path',
114
- 'type' => 'string',
115
- 'required' => true,
116
- ),
117
- ),
118
- ),
119
- 'list' => array(
120
- 'path' => 'apps',
121
- 'httpMethod' => 'GET',
122
- 'parameters' => array(),
123
- ),
124
- ),
125
- )
126
- );
127
- $this->changes = new Google_Service_Drive_Changes_Resource(
128
- $this,
129
- $this->serviceName,
130
- 'changes',
131
- array(
132
- 'methods' => array(
133
- 'get' => array(
134
- 'path' => 'changes/{changeId}',
135
- 'httpMethod' => 'GET',
136
- 'parameters' => array(
137
- 'changeId' => array(
138
- 'location' => 'path',
139
- 'type' => 'string',
140
- 'required' => true,
141
- ),
142
- ),
143
- ),
144
- 'list' => array(
145
- 'path' => 'changes',
146
- 'httpMethod' => 'GET',
147
- 'parameters' => array(
148
- 'includeSubscribed' => array(
149
- 'location' => 'query',
150
- 'type' => 'boolean',
151
- ),
152
- 'startChangeId' => array(
153
- 'location' => 'query',
154
- 'type' => 'string',
155
- ),
156
- 'includeDeleted' => array(
157
- 'location' => 'query',
158
- 'type' => 'boolean',
159
- ),
160
- 'maxResults' => array(
161
- 'location' => 'query',
162
- 'type' => 'integer',
163
- ),
164
- 'pageToken' => array(
165
- 'location' => 'query',
166
- 'type' => 'string',
167
- ),
168
- ),
169
- ),
170
- 'watch' => array(
171
- 'path' => 'changes/watch',
172
- 'httpMethod' => 'POST',
173
- 'parameters' => array(
174
- 'includeSubscribed' => array(
175
- 'location' => 'query',
176
- 'type' => 'boolean',
177
- ),
178
- 'startChangeId' => array(
179
- 'location' => 'query',
180
- 'type' => 'string',
181
- ),
182
- 'includeDeleted' => array(
183
- 'location' => 'query',
184
- 'type' => 'boolean',
185
- ),
186
- 'maxResults' => array(
187
- 'location' => 'query',
188
- 'type' => 'integer',
189
- ),
190
- 'pageToken' => array(
191
- 'location' => 'query',
192
- 'type' => 'string',
193
- ),
194
- ),
195
- ),
196
- ),
197
- )
198
- );
199
- $this->channels = new Google_Service_Drive_Channels_Resource(
200
- $this,
201
- $this->serviceName,
202
- 'channels',
203
- array(
204
- 'methods' => array(
205
- 'stop' => array(
206
- 'path' => 'channels/stop',
207
- 'httpMethod' => 'POST',
208
- 'parameters' => array(),
209
- ),
210
- ),
211
- )
212
- );
213
- $this->children = new Google_Service_Drive_Children_Resource(
214
- $this,
215
- $this->serviceName,
216
- 'children',
217
- array(
218
- 'methods' => array(
219
- 'delete' => array(
220
- 'path' => 'files/{folderId}/children/{childId}',
221
- 'httpMethod' => 'DELETE',
222
- 'parameters' => array(
223
- 'folderId' => array(
224
- 'location' => 'path',
225
- 'type' => 'string',
226
- 'required' => true,
227
- ),
228
- 'childId' => array(
229
- 'location' => 'path',
230
- 'type' => 'string',
231
- 'required' => true,
232
- ),
233
- ),
234
- ),
235
- 'get' => array(
236
- 'path' => 'files/{folderId}/children/{childId}',
237
- 'httpMethod' => 'GET',
238
- 'parameters' => array(
239
- 'folderId' => array(
240
- 'location' => 'path',
241
- 'type' => 'string',
242
- 'required' => true,
243
- ),
244
- 'childId' => array(
245
- 'location' => 'path',
246
- 'type' => 'string',
247
- 'required' => true,
248
- ),
249
- ),
250
- ),
251
- 'insert' => array(
252
- 'path' => 'files/{folderId}/children',
253
- 'httpMethod' => 'POST',
254
- 'parameters' => array(
255
- 'folderId' => array(
256
- 'location' => 'path',
257
- 'type' => 'string',
258
- 'required' => true,
259
- ),
260
- ),
261
- ),
262
- 'list' => array(
263
- 'path' => 'files/{folderId}/children',
264
- 'httpMethod' => 'GET',
265
- 'parameters' => array(
266
- 'folderId' => array(
267
- 'location' => 'path',
268
- 'type' => 'string',
269
- 'required' => true,
270
- ),
271
- 'q' => array(
272
- 'location' => 'query',
273
- 'type' => 'string',
274
- ),
275
- 'pageToken' => array(
276
- 'location' => 'query',
277
- 'type' => 'string',
278
- ),
279
- 'maxResults' => array(
280
- 'location' => 'query',
281
- 'type' => 'integer',
282
- ),
283
- ),
284
- ),
285
- ),
286
- )
287
- );
288
- $this->comments = new Google_Service_Drive_Comments_Resource(
289
- $this,
290
- $this->serviceName,
291
- 'comments',
292
- array(
293
- 'methods' => array(
294
- 'delete' => array(
295
- 'path' => 'files/{fileId}/comments/{commentId}',
296
- 'httpMethod' => 'DELETE',
297
- 'parameters' => array(
298
- 'fileId' => array(
299
- 'location' => 'path',
300
- 'type' => 'string',
301
- 'required' => true,
302
- ),
303
- 'commentId' => array(
304
- 'location' => 'path',
305
- 'type' => 'string',
306
- 'required' => true,
307
- ),
308
- ),
309
- ),
310
- 'get' => array(
311
- 'path' => 'files/{fileId}/comments/{commentId}',
312
- 'httpMethod' => 'GET',
313
- 'parameters' => array(
314
- 'fileId' => array(
315
- 'location' => 'path',
316
- 'type' => 'string',
317
- 'required' => true,
318
- ),
319
- 'commentId' => array(
320
- 'location' => 'path',
321
- 'type' => 'string',
322
- 'required' => true,
323
- ),
324
- 'includeDeleted' => array(
325
- 'location' => 'query',
326
- 'type' => 'boolean',
327
- ),
328
- ),
329
- ),
330
- 'insert' => array(
331
- 'path' => 'files/{fileId}/comments',
332
- 'httpMethod' => 'POST',
333
- 'parameters' => array(
334
- 'fileId' => array(
335
- 'location' => 'path',
336
- 'type' => 'string',
337
- 'required' => true,
338
- ),
339
- ),
340
- ),
341
- 'list' => array(
342
- 'path' => 'files/{fileId}/comments',
343
- 'httpMethod' => 'GET',
344
- 'parameters' => array(
345
- 'fileId' => array(
346
- 'location' => 'path',
347
- 'type' => 'string',
348
- 'required' => true,
349
- ),
350
- 'pageToken' => array(
351
- 'location' => 'query',
352
- 'type' => 'string',
353
- ),
354
- 'updatedMin' => array(
355
- 'location' => 'query',
356
- 'type' => 'string',
357
- ),
358
- 'includeDeleted' => array(
359
- 'location' => 'query',
360
- 'type' => 'boolean',
361
- ),
362
- 'maxResults' => array(
363
- 'location' => 'query',
364
- 'type' => 'integer',
365
- ),
366
- ),
367
- ),
368
- 'patch' => array(
369
- 'path' => 'files/{fileId}/comments/{commentId}',
370
- 'httpMethod' => 'PATCH',
371
- 'parameters' => array(
372
- 'fileId' => array(
373
- 'location' => 'path',
374
- 'type' => 'string',
375
- 'required' => true,
376
- ),
377
- 'commentId' => array(
378
- 'location' => 'path',
379
- 'type' => 'string',
380
- 'required' => true,
381
- ),
382
- ),
383
- ),
384
- 'update' => array(
385
- 'path' => 'files/{fileId}/comments/{commentId}',
386
- 'httpMethod' => 'PUT',
387
- 'parameters' => array(
388
- 'fileId' => array(
389
- 'location' => 'path',
390
- 'type' => 'string',
391
- 'required' => true,
392
- ),
393
- 'commentId' => array(
394
- 'location' => 'path',
395
- 'type' => 'string',
396
- 'required' => true,
397
- ),
398
- ),
399
- ),
400
- ),
401
- )
402
- );
403
- $this->files = new Google_Service_Drive_Files_Resource(
404
- $this,
405
- $this->serviceName,
406
- 'files',
407
- array(
408
- 'methods' => array(
409
- 'copy' => array(
410
- 'path' => 'files/{fileId}/copy',
411
- 'httpMethod' => 'POST',
412
- 'parameters' => array(
413
- 'fileId' => array(
414
- 'location' => 'path',
415
- 'type' => 'string',
416
- 'required' => true,
417
- ),
418
- 'convert' => array(
419
- 'location' => 'query',
420
- 'type' => 'boolean',
421
- ),
422
- 'ocrLanguage' => array(
423
- 'location' => 'query',
424
- 'type' => 'string',
425
- ),
426
- 'visibility' => array(
427
- 'location' => 'query',
428
- 'type' => 'string',
429
- ),
430
- 'pinned' => array(
431
- 'location' => 'query',
432
- 'type' => 'boolean',
433
- ),
434
- 'ocr' => array(
435
- 'location' => 'query',
436
- 'type' => 'boolean',
437
- ),
438
- 'timedTextTrackName' => array(
439
- 'location' => 'query',
440
- 'type' => 'string',
441
- ),
442
- 'timedTextLanguage' => array(
443
- 'location' => 'query',
444
- 'type' => 'string',
445
- ),
446
- ),
447
- ),
448
- 'delete' => array(
449
- 'path' => 'files/{fileId}',
450
- 'httpMethod' => 'DELETE',
451
- 'parameters' => array(
452
- 'fileId' => array(
453
- 'location' => 'path',
454
- 'type' => 'string',
455
- 'required' => true,
456
- ),
457
- ),
458
- ),
459
- 'get' => array(
460
- 'path' => 'files/{fileId}',
461
- 'httpMethod' => 'GET',
462
- 'parameters' => array(
463
- 'fileId' => array(
464
- 'location' => 'path',
465
- 'type' => 'string',
466
- 'required' => true,
467
- ),
468
- 'updateViewedDate' => array(
469
- 'location' => 'query',
470
- 'type' => 'boolean',
471
- ),
472
- 'projection' => array(
473
- 'location' => 'query',
474
- 'type' => 'string',
475
- ),
476
- ),
477
- ),
478
- 'insert' => array(
479
- 'path' => 'files',
480
- 'httpMethod' => 'POST',
481
- 'parameters' => array(
482
- 'convert' => array(
483
- 'location' => 'query',
484
- 'type' => 'boolean',
485
- ),
486
- 'useContentAsIndexableText' => array(
487
- 'location' => 'query',
488
- 'type' => 'boolean',
489
- ),
490
- 'ocrLanguage' => array(
491
- 'location' => 'query',
492
- 'type' => 'string',
493
- ),
494
- 'visibility' => array(
495
- 'location' => 'query',
496
- 'type' => 'string',
497
- ),
498
- 'pinned' => array(
499
- 'location' => 'query',
500
- 'type' => 'boolean',
501
- ),
502
- 'ocr' => array(
503
- 'location' => 'query',
504
- 'type' => 'boolean',
505
- ),
506
- 'timedTextTrackName' => array(
507
- 'location' => 'query',
508
- 'type' => 'string',
509
- ),
510
- 'timedTextLanguage' => array(
511
- 'location' => 'query',
512
- 'type' => 'string',
513
- ),
514
- ),
515
- ),
516
- 'list' => array(
517
- 'path' => 'files',
518
- 'httpMethod' => 'GET',
519
- 'parameters' => array(
520
- 'q' => array(
521
- 'location' => 'query',
522
- 'type' => 'string',
523
- ),
524
- 'pageToken' => array(
525
- 'location' => 'query',
526
- 'type' => 'string',
527
- ),
528
- 'projection' => array(
529
- 'location' => 'query',
530
- 'type' => 'string',
531
- ),
532
- 'maxResults' => array(
533
- 'location' => 'query',
534
- 'type' => 'integer',
535
- ),
536
- ),
537
- ),
538
- 'patch' => array(
539
- 'path' => 'files/{fileId}',
540
- 'httpMethod' => 'PATCH',
541
- 'parameters' => array(
542
- 'fileId' => array(
543
- 'location' => 'path',
544
- 'type' => 'string',
545
- 'required' => true,
546
- ),
547
- 'convert' => array(
548
- 'location' => 'query',
549
- 'type' => 'boolean',
550
- ),
551
- 'updateViewedDate' => array(
552
- 'location' => 'query',
553
- 'type' => 'boolean',
554
- ),
555
- 'setModifiedDate' => array(
556
- 'location' => 'query',
557
- 'type' => 'boolean',
558
- ),
559
- 'useContentAsIndexableText' => array(
560
- 'location' => 'query',
561
- 'type' => 'boolean',
562
- ),
563
- 'ocrLanguage' => array(
564
- 'location' => 'query',
565
- 'type' => 'string',
566
- ),
567
- 'pinned' => array(
568
- 'location' => 'query',
569
- 'type' => 'boolean',
570
- ),
571
- 'newRevision' => array(
572
- 'location' => 'query',
573
- 'type' => 'boolean',
574
- ),
575
- 'ocr' => array(
576
- 'location' => 'query',
577
- 'type' => 'boolean',
578
- ),
579
- 'timedTextLanguage' => array(
580
- 'location' => 'query',
581
- 'type' => 'string',
582
- ),
583
- 'timedTextTrackName' => array(
584
- 'location' => 'query',
585
- 'type' => 'string',
586
- ),
587
- ),
588
- ),
589
- 'touch' => array(
590
- 'path' => 'files/{fileId}/touch',
591
- 'httpMethod' => 'POST',
592
- 'parameters' => array(
593
- 'fileId' => array(
594
- 'location' => 'path',
595
- 'type' => 'string',
596
- 'required' => true,
597
- ),
598
- ),
599
- ),
600
- 'trash' => array(
601
- 'path' => 'files/{fileId}/trash',
602
- 'httpMethod' => 'POST',
603
- 'parameters' => array(
604
- 'fileId' => array(
605
- 'location' => 'path',
606
- 'type' => 'string',
607
- 'required' => true,
608
- ),
609
- ),
610
- ),
611
- 'untrash' => array(
612
- 'path' => 'files/{fileId}/untrash',
613
- 'httpMethod' => 'POST',
614
- 'parameters' => array(
615
- 'fileId' => array(
616
- 'location' => 'path',
617
- 'type' => 'string',
618
- 'required' => true,
619
- ),
620
- ),
621
- ),
622
- 'update' => array(
623
- 'path' => 'files/{fileId}',
624
- 'httpMethod' => 'PUT',
625
- 'parameters' => array(
626
- 'fileId' => array(
627
- 'location' => 'path',
628
- 'type' => 'string',
629
- 'required' => true,
630
- ),
631
- 'convert' => array(
632
- 'location' => 'query',
633
- 'type' => 'boolean',
634
- ),
635
- 'updateViewedDate' => array(
636
- 'location' => 'query',
637
- 'type' => 'boolean',
638
- ),
639
- 'setModifiedDate' => array(
640
- 'location' => 'query',
641
- 'type' => 'boolean',
642
- ),
643
- 'useContentAsIndexableText' => array(
644
- 'location' => 'query',
645
- 'type' => 'boolean',
646
- ),
647
- 'ocrLanguage' => array(
648
- 'location' => 'query',
649
- 'type' => 'string',
650
- ),
651
- 'pinned' => array(
652
- 'location' => 'query',
653
- 'type' => 'boolean',
654
- ),
655
- 'newRevision' => array(
656
- 'location' => 'query',
657
- 'type' => 'boolean',
658
- ),
659
- 'ocr' => array(
660
- 'location' => 'query',
661
- 'type' => 'boolean',
662
- ),
663
- 'timedTextLanguage' => array(
664
- 'location' => 'query',
665
- 'type' => 'string',
666
- ),
667
- 'timedTextTrackName' => array(
668
- 'location' => 'query',
669
- 'type' => 'string',
670
- ),
671
- ),
672
- ),
673
- 'watch' => array(
674
- 'path' => 'files/{fileId}/watch',
675
- 'httpMethod' => 'POST',
676
- 'parameters' => array(
677
- 'fileId' => array(
678
- 'location' => 'path',
679
- 'type' => 'string',
680
- 'required' => true,
681
- ),
682
- 'updateViewedDate' => array(
683
- 'location' => 'query',
684
- 'type' => 'boolean',
685
- ),
686
- 'projection' => array(
687
- 'location' => 'query',
688
- 'type' => 'string',
689
- ),
690
- ),
691
- ),
692
- ),
693
- )
694
- );
695
- $this->parents = new Google_Service_Drive_Parents_Resource(
696
- $this,
697
- $this->serviceName,
698
- 'parents',
699
- array(
700
- 'methods' => array(
701
- 'delete' => array(
702
- 'path' => 'files/{fileId}/parents/{parentId}',
703
- 'httpMethod' => 'DELETE',
704
- 'parameters' => array(
705
- 'fileId' => array(
706
- 'location' => 'path',
707
- 'type' => 'string',
708
- 'required' => true,
709
- ),
710
- 'parentId' => array(
711
- 'location' => 'path',
712
- 'type' => 'string',
713
- 'required' => true,
714
- ),
715
- ),
716
- ),
717
- 'get' => array(
718
- 'path' => 'files/{fileId}/parents/{parentId}',
719
- 'httpMethod' => 'GET',
720
- 'parameters' => array(
721
- 'fileId' => array(
722
- 'location' => 'path',
723
- 'type' => 'string',
724
- 'required' => true,
725
- ),
726
- 'parentId' => array(
727
- 'location' => 'path',
728
- 'type' => 'string',
729
- 'required' => true,
730
- ),
731
- ),
732
- ),
733
- 'insert' => array(
734
- 'path' => 'files/{fileId}/parents',
735
- 'httpMethod' => 'POST',
736
- 'parameters' => array(
737
- 'fileId' => array(
738
- 'location' => 'path',
739
- 'type' => 'string',
740
- 'required' => true,
741
- ),
742
- ),
743
- ),
744
- 'list' => array(
745
- 'path' => 'files/{fileId}/parents',
746
- 'httpMethod' => 'GET',
747
- 'parameters' => array(
748
- 'fileId' => array(
749
- 'location' => 'path',
750
- 'type' => 'string',
751
- 'required' => true,
752
- ),
753
- ),
754
- ),
755
- ),
756
- )
757
- );
758
- $this->permissions = new Google_Service_Drive_Permissions_Resource(
759
- $this,
760
- $this->serviceName,
761
- 'permissions',
762
- array(
763
- 'methods' => array(
764
- 'delete' => array(
765
- 'path' => 'files/{fileId}/permissions/{permissionId}',
766
- 'httpMethod' => 'DELETE',
767
- 'parameters' => array(
768
- 'fileId' => array(
769
- 'location' => 'path',
770
- 'type' => 'string',
771
- 'required' => true,
772
- ),
773
- 'permissionId' => array(
774
- 'location' => 'path',
775
- 'type' => 'string',
776
- 'required' => true,
777
- ),
778
- ),
779
- ),
780
- 'get' => array(
781
- 'path' => 'files/{fileId}/permissions/{permissionId}',
782
- 'httpMethod' => 'GET',
783
- 'parameters' => array(
784
- 'fileId' => array(
785
- 'location' => 'path',
786
- 'type' => 'string',
787
- 'required' => true,
788
- ),
789
- 'permissionId' => array(
790
- 'location' => 'path',
791
- 'type' => 'string',
792
- 'required' => true,
793
- ),
794
- ),
795
- ),
796
- 'getIdForEmail' => array(
797
- 'path' => 'permissionIds/{email}',
798
- 'httpMethod' => 'GET',
799
- 'parameters' => array(
800
- 'email' => array(
801
- 'location' => 'path',
802
- 'type' => 'string',
803
- 'required' => true,
804
- ),
805
- ),
806
- ),
807
- 'insert' => array(
808
- 'path' => 'files/{fileId}/permissions',
809
- 'httpMethod' => 'POST',
810
- 'parameters' => array(
811
- 'fileId' => array(
812
- 'location' => 'path',
813
- 'type' => 'string',
814
- 'required' => true,
815
- ),
816
- 'emailMessage' => array(
817
- 'location' => 'query',
818
- 'type' => 'string',
819
- ),
820
- 'sendNotificationEmails' => array(
821
- 'location' => 'query',
822
- 'type' => 'boolean',
823
- ),
824
- ),
825
- ),
826
- 'list' => array(
827
- 'path' => 'files/{fileId}/permissions',
828
- 'httpMethod' => 'GET',
829
- 'parameters' => array(
830
- 'fileId' => array(
831
- 'location' => 'path',
832
- 'type' => 'string',
833
- 'required' => true,
834
- ),
835
- ),
836
- ),
837
- 'patch' => array(
838
- 'path' => 'files/{fileId}/permissions/{permissionId}',
839
- 'httpMethod' => 'PATCH',
840
- 'parameters' => array(
841
- 'fileId' => array(
842
- 'location' => 'path',
843
- 'type' => 'string',
844
- 'required' => true,
845
- ),
846
- 'permissionId' => array(
847
- 'location' => 'path',
848
- 'type' => 'string',
849
- 'required' => true,
850
- ),
851
- 'transferOwnership' => array(
852
- 'location' => 'query',
853
- 'type' => 'boolean',
854
- ),
855
- ),
856
- ),
857
- 'update' => array(
858
- 'path' => 'files/{fileId}/permissions/{permissionId}',
859
- 'httpMethod' => 'PUT',
860
- 'parameters' => array(
861
- 'fileId' => array(
862
- 'location' => 'path',
863
- 'type' => 'string',
864
- 'required' => true,
865
- ),
866
- 'permissionId' => array(
867
- 'location' => 'path',
868
- 'type' => 'string',
869
- 'required' => true,
870
- ),
871
- 'transferOwnership' => array(
872
- 'location' => 'query',
873
- 'type' => 'boolean',
874
- ),
875
- ),
876
- ),
877
- ),
878
- )
879
- );
880
- $this->properties = new Google_Service_Drive_Properties_Resource(
881
- $this,
882
- $this->serviceName,
883
- 'properties',
884
- array(
885
- 'methods' => array(
886
- 'delete' => array(
887
- 'path' => 'files/{fileId}/properties/{propertyKey}',
888
- 'httpMethod' => 'DELETE',
889
- 'parameters' => array(
890
- 'fileId' => array(
891
- 'location' => 'path',
892
- 'type' => 'string',
893
- 'required' => true,
894
- ),
895
- 'propertyKey' => array(
896
- 'location' => 'path',
897
- 'type' => 'string',
898
- 'required' => true,
899
- ),
900
- 'visibility' => array(
901
- 'location' => 'query',
902
- 'type' => 'string',
903
- ),
904
- ),
905
- ),
906
- 'get' => array(
907
- 'path' => 'files/{fileId}/properties/{propertyKey}',
908
- 'httpMethod' => 'GET',
909
- 'parameters' => array(
910
- 'fileId' => array(
911
- 'location' => 'path',
912
- 'type' => 'string',
913
- 'required' => true,
914
- ),
915
- 'propertyKey' => array(
916
- 'location' => 'path',
917
- 'type' => 'string',
918
- 'required' => true,
919
- ),
920
- 'visibility' => array(
921
- 'location' => 'query',
922
- 'type' => 'string',
923
- ),
924
- ),
925
- ),
926
- 'insert' => array(
927
- 'path' => 'files/{fileId}/properties',
928
- 'httpMethod' => 'POST',
929
- 'parameters' => array(
930
- 'fileId' => array(
931
- 'location' => 'path',
932
- 'type' => 'string',
933
- 'required' => true,
934
- ),
935
- ),
936
- ),
937
- 'list' => array(
938
- 'path' => 'files/{fileId}/properties',
939
- 'httpMethod' => 'GET',
940
- 'parameters' => array(
941
- 'fileId' => array(
942
- 'location' => 'path',
943
- 'type' => 'string',
944
- 'required' => true,
945
- ),
946
- ),
947
- ),
948
- 'patch' => array(
949
- 'path' => 'files/{fileId}/properties/{propertyKey}',
950
- 'httpMethod' => 'PATCH',
951
- 'parameters' => array(
952
- 'fileId' => array(
953
- 'location' => 'path',
954
- 'type' => 'string',
955
- 'required' => true,
956
- ),
957
- 'propertyKey' => array(
958
- 'location' => 'path',
959
- 'type' => 'string',
960
- 'required' => true,
961
- ),
962
- 'visibility' => array(
963
- 'location' => 'query',
964
- 'type' => 'string',
965
- ),
966
- ),
967
- ),
968
- 'update' => array(
969
- 'path' => 'files/{fileId}/properties/{propertyKey}',
970
- 'httpMethod' => 'PUT',
971
- 'parameters' => array(
972
- 'fileId' => array(
973
- 'location' => 'path',
974
- 'type' => 'string',
975
- 'required' => true,
976
- ),
977
- 'propertyKey' => array(
978
- 'location' => 'path',
979
- 'type' => 'string',
980
- 'required' => true,
981
- ),
982
- 'visibility' => array(
983
- 'location' => 'query',
984
- 'type' => 'string',
985
- ),
986
- ),
987
- ),
988
- ),
989
- )
990
- );
991
- $this->realtime = new Google_Service_Drive_Realtime_Resource(
992
- $this,
993
- $this->serviceName,
994
- 'realtime',
995
- array(
996
- 'methods' => array(
997
- 'get' => array(
998
- 'path' => 'files/{fileId}/realtime',
999
- 'httpMethod' => 'GET',
1000
- 'parameters' => array(
1001
- 'fileId' => array(
1002
- 'location' => 'path',
1003
- 'type' => 'string',
1004
- 'required' => true,
1005
- ),
1006
- ),
1007
- ),
1008
- 'update' => array(
1009
- 'path' => 'files/{fileId}/realtime',
1010
- 'httpMethod' => 'PUT',
1011
- 'parameters' => array(
1012
- 'fileId' => array(
1013
- 'location' => 'path',
1014
- 'type' => 'string',
1015
- 'required' => true,
1016
- ),
1017
- 'baseRevision' => array(
1018
- 'location' => 'query',
1019
- 'type' => 'string',
1020
- ),
1021
- ),
1022
- ),
1023
- ),
1024
- )
1025
- );
1026
- $this->replies = new Google_Service_Drive_Replies_Resource(
1027
- $this,
1028
- $this->serviceName,
1029
- 'replies',
1030
- array(
1031
- 'methods' => array(
1032
- 'delete' => array(
1033
- 'path' => 'files/{fileId}/comments/{commentId}/replies/{replyId}',
1034
- 'httpMethod' => 'DELETE',
1035
- 'parameters' => array(
1036
- 'fileId' => array(
1037
- 'location' => 'path',
1038
- 'type' => 'string',
1039
- 'required' => true,
1040
- ),
1041
- 'commentId' => array(
1042
- 'location' => 'path',
1043
- 'type' => 'string',
1044
- 'required' => true,
1045
- ),
1046
- 'replyId' => array(
1047
- 'location' => 'path',
1048
- 'type' => 'string',
1049
- 'required' => true,
1050
- ),
1051
- ),
1052
- ),
1053
- 'get' => array(
1054
- 'path' => 'files/{fileId}/comments/{commentId}/replies/{replyId}',
1055
- 'httpMethod' => 'GET',
1056
- 'parameters' => array(
1057
- 'fileId' => array(
1058
- 'location' => 'path',
1059
- 'type' => 'string',
1060
- 'required' => true,
1061
- ),
1062
- 'commentId' => array(
1063
- 'location' => 'path',
1064
- 'type' => 'string',
1065
- 'required' => true,
1066
- ),
1067
- 'replyId' => array(
1068
- 'location' => 'path',
1069
- 'type' => 'string',
1070
- 'required' => true,
1071
- ),
1072
- 'includeDeleted' => array(
1073
- 'location' => 'query',
1074
- 'type' => 'boolean',
1075
- ),
1076
- ),
1077
- ),
1078
- 'insert' => array(
1079
- 'path' => 'files/{fileId}/comments/{commentId}/replies',
1080
- 'httpMethod' => 'POST',
1081
- 'parameters' => array(
1082
- 'fileId' => array(
1083
- 'location' => 'path',
1084
- 'type' => 'string',
1085
- 'required' => true,
1086
- ),
1087
- 'commentId' => array(
1088
- 'location' => 'path',
1089
- 'type' => 'string',
1090
- 'required' => true,
1091
- ),
1092
- ),
1093
- ),
1094
- 'list' => array(
1095
- 'path' => 'files/{fileId}/comments/{commentId}/replies',
1096
- 'httpMethod' => 'GET',
1097
- 'parameters' => array(
1098
- 'fileId' => array(
1099
- 'location' => 'path',
1100
- 'type' => 'string',
1101
- 'required' => true,
1102
- ),
1103
- 'commentId' => array(
1104
- 'location' => 'path',
1105
- 'type' => 'string',
1106
- 'required' => true,
1107
- ),
1108
- 'pageToken' => array(
1109
- 'location' => 'query',
1110
- 'type' => 'string',
1111
- ),
1112
- 'includeDeleted' => array(
1113
- 'location' => 'query',
1114
- 'type' => 'boolean',
1115
- ),
1116
- 'maxResults' => array(
1117
- 'location' => 'query',
1118
- 'type' => 'integer',
1119
- ),
1120
- ),
1121
- ),
1122
- 'patch' => array(
1123
- 'path' => 'files/{fileId}/comments/{commentId}/replies/{replyId}',
1124
- 'httpMethod' => 'PATCH',
1125
- 'parameters' => array(
1126
- 'fileId' => array(
1127
- 'location' => 'path',
1128
- 'type' => 'string',
1129
- 'required' => true,
1130
- ),
1131
- 'commentId' => array(
1132
- 'location' => 'path',
1133
- 'type' => 'string',
1134
- 'required' => true,
1135
- ),
1136
- 'replyId' => array(
1137
- 'location' => 'path',
1138
- 'type' => 'string',
1139
- 'required' => true,
1140
- ),
1141
- ),
1142
- ),
1143
- 'update' => array(
1144
- 'path' => 'files/{fileId}/comments/{commentId}/replies/{replyId}',
1145
- 'httpMethod' => 'PUT',
1146
- 'parameters' => array(
1147
- 'fileId' => array(
1148
- 'location' => 'path',
1149
- 'type' => 'string',
1150
- 'required' => true,
1151
- ),
1152
- 'commentId' => array(
1153
- 'location' => 'path',
1154
- 'type' => 'string',
1155
- 'required' => true,
1156
- ),
1157
- 'replyId' => array(
1158
- 'location' => 'path',
1159
- 'type' => 'string',
1160
- 'required' => true,
1161
- ),
1162
- ),
1163
- ),
1164
- ),
1165
- )
1166
- );
1167
- $this->revisions = new Google_Service_Drive_Revisions_Resource(
1168
- $this,
1169
- $this->serviceName,
1170
- 'revisions',
1171
- array(
1172
- 'methods' => array(
1173
- 'delete' => array(
1174
- 'path' => 'files/{fileId}/revisions/{revisionId}',
1175
- 'httpMethod' => 'DELETE',
1176
- 'parameters' => array(
1177
- 'fileId' => array(
1178
- 'location' => 'path',
1179
- 'type' => 'string',
1180
- 'required' => true,
1181
- ),
1182
- 'revisionId' => array(
1183
- 'location' => 'path',
1184
- 'type' => 'string',
1185
- 'required' => true,
1186
- ),
1187
- ),
1188
- ),
1189
- 'get' => array(
1190
- 'path' => 'files/{fileId}/revisions/{revisionId}',
1191
- 'httpMethod' => 'GET',
1192
- 'parameters' => array(
1193
- 'fileId' => array(
1194
- 'location' => 'path',
1195
- 'type' => 'string',
1196
- 'required' => true,
1197
- ),
1198
- 'revisionId' => array(
1199
- 'location' => 'path',
1200
- 'type' => 'string',
1201
- 'required' => true,
1202
- ),
1203
- ),
1204
- ),
1205
- 'list' => array(
1206
- 'path' => 'files/{fileId}/revisions',
1207
- 'httpMethod' => 'GET',
1208
- 'parameters' => array(
1209
- 'fileId' => array(
1210
- 'location' => 'path',
1211
- 'type' => 'string',
1212
- 'required' => true,
1213
- ),
1214
- ),
1215
- ),
1216
- 'patch' => array(
1217
- 'path' => 'files/{fileId}/revisions/{revisionId}',
1218
- 'httpMethod' => 'PATCH',
1219
- 'parameters' => array(
1220
- 'fileId' => array(
1221
- 'location' => 'path',
1222
- 'type' => 'string',
1223
- 'required' => true,
1224
- ),
1225
- 'revisionId' => array(
1226
- 'location' => 'path',
1227
- 'type' => 'string',
1228
- 'required' => true,
1229
- ),
1230
- ),
1231
- ),
1232
- 'update' => array(
1233
- 'path' => 'files/{fileId}/revisions/{revisionId}',
1234
- 'httpMethod' => 'PUT',
1235
- 'parameters' => array(
1236
- 'fileId' => array(
1237
- 'location' => 'path',
1238
- 'type' => 'string',
1239
- 'required' => true,
1240
- ),
1241
- 'revisionId' => array(
1242
- 'location' => 'path',
1243
- 'type' => 'string',
1244
- 'required' => true,
1245
- ),
1246
- ),
1247
- ),
1248
- ),
1249
- )
1250
- );
1251
- }
1252
- }
1253
-
1254
- /**
1255
- * The "about" collection of methods.
1256
- * Typical usage is:
1257
- * <code>
1258
- * $driveService = new Google_Service_Drive(...);
1259
- * $about = $driveService->about;
1260
- * </code>
1261
- */
1262
- class Google_Service_Drive_About_Resource extends Google_Service_Resource
1263
- {
1264
- /**
1265
- * Gets the information about the current user along with Drive API settings
1266
- * (about.get)
1267
- *
1268
- * @param array $optParams Optional parameters.
1269
- *
1270
- * @opt_param bool includeSubscribed
1271
- * When calculating the number of remaining change IDs, whether to include shared files and public
1272
- * files the user has opened. When set to false, this counts only change IDs for owned files and
1273
- * any shared or public files that the user has explictly added to a folder in Drive.
1274
- * @opt_param string maxChangeIdCount
1275
- * Maximum number of remaining change IDs to count
1276
- * @opt_param string startChangeId
1277
- * Change ID to start counting from when calculating number of remaining change IDs
1278
- * @return Google_Service_Drive_About
1279
- */
1280
- public function get($optParams = array())
1281
- {
1282
- $params = array();
1283
- $params = array_merge($params, $optParams);
1284
-
1285
- return $this->call('get', array($params), "Google_Service_Drive_About");
1286
- }
1287
- }
1288
-
1289
- /**
1290
- * The "apps" collection of methods.
1291
- * Typical usage is:
1292
- * <code>
1293
- * $driveService = new Google_Service_Drive(...);
1294
- * $apps = $driveService->apps;
1295
- * </code>
1296
- */
1297
- class Google_Service_Drive_Apps_Resource extends Google_Service_Resource
1298
- {
1299
- /**
1300
- * Gets a specific app. (apps.get)
1301
- *
1302
- * @param string $appId
1303
- * The ID of the app.
1304
- * @param array $optParams Optional parameters.
1305
- *
1306
- * @return Google_Service_Drive_App
1307
- */
1308
- public function get($appId, $optParams = array())
1309
- {
1310
- $params = array('appId' => $appId);
1311
- $params = array_merge($params, $optParams);
1312
-
1313
- return $this->call('get', array($params), "Google_Service_Drive_App");
1314
- }
1315
-
1316
- /**
1317
- * Lists a user's installed apps. (apps.listApps)
1318
- *
1319
- * @param array $optParams Optional parameters.
1320
- *
1321
- * @return Google_Service_Drive_AppList
1322
- */
1323
- public function listApps($optParams = array())
1324
- {
1325
- $params = array();
1326
- $params = array_merge($params, $optParams);
1327
-
1328
- return $this->call('list', array($params), "Google_Service_Drive_AppList");
1329
- }
1330
- }
1331
-
1332
- /**
1333
- * The "changes" collection of methods.
1334
- * Typical usage is:
1335
- * <code>
1336
- * $driveService = new Google_Service_Drive(...);
1337
- * $changes = $driveService->changes;
1338
- * </code>
1339
- */
1340
- class Google_Service_Drive_Changes_Resource extends Google_Service_Resource
1341
- {
1342
- /**
1343
- * Gets a specific change. (changes.get)
1344
- *
1345
- * @param string $changeId
1346
- * The ID of the change.
1347
- * @param array $optParams Optional parameters.
1348
- *
1349
- * @return Google_Service_Drive_Change
1350
- */
1351
- public function get($changeId, $optParams = array())
1352
- {
1353
- $params = array('changeId' => $changeId);
1354
- $params = array_merge($params, $optParams);
1355
-
1356
- return $this->call('get', array($params), "Google_Service_Drive_Change");
1357
- }
1358
-
1359
- /**
1360
- * Lists the changes for a user. (changes.listChanges)
1361
- *
1362
- * @param array $optParams Optional parameters.
1363
- *
1364
- * @opt_param bool includeSubscribed
1365
- * Whether to include shared files and public files the user has opened. When set to false, the
1366
- * list will include owned files plus any shared or public files the user has explictly added to a
1367
- * folder in Drive.
1368
- * @opt_param string startChangeId
1369
- * Change ID to start listing changes from.
1370
- * @opt_param bool includeDeleted
1371
- * Whether to include deleted items.
1372
- * @opt_param int maxResults
1373
- * Maximum number of changes to return.
1374
- * @opt_param string pageToken
1375
- * Page token for changes.
1376
- * @return Google_Service_Drive_ChangeList
1377
- */
1378
- public function listChanges($optParams = array())
1379
- {
1380
- $params = array();
1381
- $params = array_merge($params, $optParams);
1382
-
1383
- return $this->call('list', array($params), "Google_Service_Drive_ChangeList");
1384
- }
1385
-
1386
- /**
1387
- * Subscribe to changes for a user. (changes.watch)
1388
- *
1389
- * @param Google_Channel $postBody
1390
- * @param array $optParams Optional parameters.
1391
- *
1392
- * @opt_param bool includeSubscribed
1393
- * Whether to include shared files and public files the user has opened. When set to false, the
1394
- * list will include owned files plus any shared or public files the user has explictly added to a
1395
- * folder in Drive.
1396
- * @opt_param string startChangeId
1397
- * Change ID to start listing changes from.
1398
- * @opt_param bool includeDeleted
1399
- * Whether to include deleted items.
1400
- * @opt_param int maxResults
1401
- * Maximum number of changes to return.
1402
- * @opt_param string pageToken
1403
- * Page token for changes.
1404
- * @return Google_Service_Drive_Channel
1405
- */
1406
- public function watch(Google_Service_Drive_Channel $postBody, $optParams = array())
1407
- {
1408
- $params = array('postBody' => $postBody);
1409
- $params = array_merge($params, $optParams);
1410
-
1411
- return $this->call('watch', array($params), "Google_Service_Drive_Channel");
1412
- }
1413
- }
1414
-
1415
- /**
1416
- * The "channels" collection of methods.
1417
- * Typical usage is:
1418
- * <code>
1419
- * $driveService = new Google_Service_Drive(...);
1420
- * $channels = $driveService->channels;
1421
- * </code>
1422
- */
1423
- class Google_Service_Drive_Channels_Resource extends Google_Service_Resource
1424
- {
1425
- /**
1426
- * Stop watching resources through this channel (channels.stop)
1427
- *
1428
- * @param Google_Channel $postBody
1429
- * @param array $optParams Optional parameters.
1430
- */
1431
- public function stop(Google_Service_Drive_Channel $postBody, $optParams = array())
1432
- {
1433
- $params = array('postBody' => $postBody);
1434
- $params = array_merge($params, $optParams);
1435
-
1436
- return $this->call('stop', array($params));
1437
- }
1438
- }
1439
-
1440
- /**
1441
- * The "children" collection of methods.
1442
- * Typical usage is:
1443
- * <code>
1444
- * $driveService = new Google_Service_Drive(...);
1445
- * $children = $driveService->children;
1446
- * </code>
1447
- */
1448
- class Google_Service_Drive_Children_Resource extends Google_Service_Resource
1449
- {
1450
- /**
1451
- * Removes a child from a folder. (children.delete)
1452
- *
1453
- * @param string $folderId
1454
- * The ID of the folder.
1455
- * @param string $childId
1456
- * The ID of the child.
1457
- * @param array $optParams Optional parameters.
1458
- */
1459
- public function delete($folderId, $childId, $optParams = array())
1460
- {
1461
- $params = array('folderId' => $folderId, 'childId' => $childId);
1462
- $params = array_merge($params, $optParams);
1463
-
1464
- return $this->call('delete', array($params));
1465
- }
1466
-
1467
- /**
1468
- * Gets a specific child reference. (children.get)
1469
- *
1470
- * @param string $folderId
1471
- * The ID of the folder.
1472
- * @param string $childId
1473
- * The ID of the child.
1474
- * @param array $optParams Optional parameters.
1475
- *
1476
- * @return Google_Service_Drive_ChildReference
1477
- */
1478
- public function get($folderId, $childId, $optParams = array())
1479
- {
1480
- $params = array('folderId' => $folderId, 'childId' => $childId);
1481
- $params = array_merge($params, $optParams);
1482
-
1483
- return $this->call('get', array($params), "Google_Service_Drive_ChildReference");
1484
- }
1485
-
1486
- /**
1487
- * Inserts a file into a folder. (children.insert)
1488
- *
1489
- * @param string $folderId
1490
- * The ID of the folder.
1491
- * @param Google_ChildReference $postBody
1492
- * @param array $optParams Optional parameters.
1493
- *
1494
- * @return Google_Service_Drive_ChildReference
1495
- */
1496
- public function insert($folderId, Google_Service_Drive_ChildReference $postBody, $optParams = array())
1497
- {
1498
- $params = array('folderId' => $folderId, 'postBody' => $postBody);
1499
- $params = array_merge($params, $optParams);
1500
-
1501
- return $this->call('insert', array($params), "Google_Service_Drive_ChildReference");
1502
- }
1503
-
1504
- /**
1505
- * Lists a folder's children. (children.listChildren)
1506
- *
1507
- * @param string $folderId
1508
- * The ID of the folder.
1509
- * @param array $optParams Optional parameters.
1510
- *
1511
- * @opt_param string q
1512
- * Query string for searching children.
1513
- * @opt_param string pageToken
1514
- * Page token for children.
1515
- * @opt_param int maxResults
1516
- * Maximum number of children to return.
1517
- * @return Google_Service_Drive_ChildList
1518
- */
1519
- public function listChildren($folderId, $optParams = array())
1520
- {
1521
- $params = array('folderId' => $folderId);
1522
- $params = array_merge($params, $optParams);
1523
-
1524
- return $this->call('list', array($params), "Google_Service_Drive_ChildList");
1525
- }
1526
- }
1527
-
1528
- /**
1529
- * The "comments" collection of methods.
1530
- * Typical usage is:
1531
- * <code>
1532
- * $driveService = new Google_Service_Drive(...);
1533
- * $comments = $driveService->comments;
1534
- * </code>
1535
- */
1536
- class Google_Service_Drive_Comments_Resource extends Google_Service_Resource
1537
- {
1538
- /**
1539
- * Deletes a comment. (comments.delete)
1540
- *
1541
- * @param string $fileId
1542
- * The ID of the file.
1543
- * @param string $commentId
1544
- * The ID of the comment.
1545
- * @param array $optParams Optional parameters.
1546
- */
1547
- public function delete($fileId, $commentId, $optParams = array())
1548
- {
1549
- $params = array('fileId' => $fileId, 'commentId' => $commentId);
1550
- $params = array_merge($params, $optParams);
1551
-
1552
- return $this->call('delete', array($params));
1553
- }
1554
-
1555
- /**
1556
- * Gets a comment by ID. (comments.get)
1557
- *
1558
- * @param string $fileId
1559
- * The ID of the file.
1560
- * @param string $commentId
1561
- * The ID of the comment.
1562
- * @param array $optParams Optional parameters.
1563
- *
1564
- * @opt_param bool includeDeleted
1565
- * If set, this will succeed when retrieving a deleted comment, and will include any deleted
1566
- * replies.
1567
- * @return Google_Service_Drive_Comment
1568
- */
1569
- public function get($fileId, $commentId, $optParams = array())
1570
- {
1571
- $params = array('fileId' => $fileId, 'commentId' => $commentId);
1572
- $params = array_merge($params, $optParams);
1573
-
1574
- return $this->call('get', array($params), "Google_Service_Drive_Comment");
1575
- }
1576
-
1577
- /**
1578
- * Creates a new comment on the given file. (comments.insert)
1579
- *
1580
- * @param string $fileId
1581
- * The ID of the file.
1582
- * @param Google_Comment $postBody
1583
- * @param array $optParams Optional parameters.
1584
- *
1585
- * @return Google_Service_Drive_Comment
1586
- */
1587
- public function insert($fileId, Google_Service_Drive_Comment $postBody, $optParams = array())
1588
- {
1589
- $params = array('fileId' => $fileId, 'postBody' => $postBody);
1590
- $params = array_merge($params, $optParams);
1591
-
1592
- return $this->call('insert', array($params), "Google_Service_Drive_Comment");
1593
- }
1594
-
1595
- /**
1596
- * Lists a file's comments. (comments.listComments)
1597
- *
1598
- * @param string $fileId
1599
- * The ID of the file.
1600
- * @param array $optParams Optional parameters.
1601
- *
1602
- * @opt_param string pageToken
1603
- * The continuation token, used to page through large result sets. To get the next page of results,
1604
- * set this parameter to the value of "nextPageToken" from the previous response.
1605
- * @opt_param string updatedMin
1606
- * Only discussions that were updated after this timestamp will be returned. Formatted as an RFC
1607
- * 3339 timestamp.
1608
- * @opt_param bool includeDeleted
1609
- * If set, all comments and replies, including deleted comments and replies (with content stripped)
1610
- * will be returned.
1611
- * @opt_param int maxResults
1612
- * The maximum number of discussions to include in the response, used for paging.
1613
- * @return Google_Service_Drive_CommentList
1614
- */
1615
- public function listComments($fileId, $optParams = array())
1616
- {
1617
- $params = array('fileId' => $fileId);
1618
- $params = array_merge($params, $optParams);
1619
-
1620
- return $this->call('list', array($params), "Google_Service_Drive_CommentList");
1621
- }
1622
-
1623
- /**
1624
- * Updates an existing comment. This method supports patch semantics.
1625
- * (comments.patch)
1626
- *
1627
- * @param string $fileId
1628
- * The ID of the file.
1629
- * @param string $commentId
1630
- * The ID of the comment.
1631
- * @param Google_Comment $postBody
1632
- * @param array $optParams Optional parameters.
1633
- *
1634
- * @return Google_Service_Drive_Comment
1635
- */
1636
- public function patch($fileId, $commentId, Google_Service_Drive_Comment $postBody, $optParams = array())
1637
- {
1638
- $params = array('fileId' => $fileId, 'commentId' => $commentId, 'postBody' => $postBody);
1639
- $params = array_merge($params, $optParams);
1640
-
1641
- return $this->call('patch', array($params), "Google_Service_Drive_Comment");
1642
- }
1643
-
1644
- /**
1645
- * Updates an existing comment. (comments.update)
1646
- *
1647
- * @param string $fileId
1648
- * The ID of the file.
1649
- * @param string $commentId
1650
- * The ID of the comment.
1651
- * @param Google_Comment $postBody
1652
- * @param array $optParams Optional parameters.
1653
- *
1654
- * @return Google_Service_Drive_Comment
1655
- */
1656
- public function update($fileId, $commentId, Google_Service_Drive_Comment $postBody, $optParams = array())
1657
- {
1658
- $params = array('fileId' => $fileId, 'commentId' => $commentId, 'postBody' => $postBody);
1659
- $params = array_merge($params, $optParams);
1660
-
1661
- return $this->call('update', array($params), "Google_Service_Drive_Comment");
1662
- }
1663
- }
1664
-
1665
- /**
1666
- * The "files" collection of methods.
1667
- * Typical usage is:
1668
- * <code>
1669
- * $driveService = new Google_Service_Drive(...);
1670
- * $files = $driveService->files;
1671
- * </code>
1672
- */
1673
- class Google_Service_Drive_Files_Resource extends Google_Service_Resource
1674
- {
1675
- /**
1676
- * Creates a copy of the specified file. (files.copy)
1677
- *
1678
- * @param string $fileId
1679
- * The ID of the file to copy.
1680
- * @param Google_DriveFile $postBody
1681
- * @param array $optParams Optional parameters.
1682
- *
1683
- * @opt_param bool convert
1684
- * Whether to convert this file to the corresponding Google Docs format.
1685
- * @opt_param string ocrLanguage
1686
- * If ocr is true, hints at the language to use. Valid values are ISO 639-1 codes.
1687
- * @opt_param string visibility
1688
- * The visibility of the new file. This parameter is only relevant when the source is not a native
1689
- * Google Doc and convert=false.
1690
- * @opt_param bool pinned
1691
- * Whether to pin the head revision of the new copy.
1692
- * @opt_param bool ocr
1693
- * Whether to attempt OCR on .jpg, .png, .gif, or .pdf uploads.
1694
- * @opt_param string timedTextTrackName
1695
- * The timed text track name.
1696
- * @opt_param string timedTextLanguage
1697
- * The language of the timed text.
1698
- * @return Google_Service_Drive_DriveFile
1699
- */
1700
- public function copy($fileId, Google_Service_Drive_DriveFile $postBody, $optParams = array())
1701
- {
1702
- $params = array('fileId' => $fileId, 'postBody' => $postBody);
1703
- $params = array_merge($params, $optParams);
1704
-
1705
- return $this->call('copy', array($params), "Google_Service_Drive_DriveFile");
1706
- }
1707
-
1708
- /**
1709
- * Permanently deletes a file by ID. Skips the trash. (files.delete)
1710
- *
1711
- * @param string $fileId
1712
- * The ID of the file to delete.
1713
- * @param array $optParams Optional parameters.
1714
- */
1715
- public function delete($fileId, $optParams = array())
1716
- {
1717
- $params = array('fileId' => $fileId);
1718
- $params = array_merge($params, $optParams);
1719
-
1720
- return $this->call('delete', array($params));
1721
- }
1722
-
1723
- /**
1724
- * Gets a file's metadata by ID. (files.get)
1725
- *
1726
- * @param string $fileId
1727
- * The ID for the file in question.
1728
- * @param array $optParams Optional parameters.
1729
- *
1730
- * @opt_param bool updateViewedDate
1731
- * Whether to update the view date after successfully retrieving the file.
1732
- * @opt_param string projection
1733
- * This parameter is deprecated and has no function.
1734
- * @return Google_Service_Drive_DriveFile
1735
- */
1736
- public function get($fileId, $optParams = array())
1737
- {
1738
- $params = array('fileId' => $fileId);
1739
- $params = array_merge($params, $optParams);
1740
-
1741
- return $this->call('get', array($params), "Google_Service_Drive_DriveFile");
1742
- }
1743
-
1744
- /**
1745
- * Insert a new file. (files.insert)
1746
- *
1747
- * @param Google_DriveFile $postBody
1748
- * @param array $optParams Optional parameters.
1749
- *
1750
- * @opt_param bool convert
1751
- * Whether to convert this file to the corresponding Google Docs format.
1752
- * @opt_param bool useContentAsIndexableText
1753
- * Whether to use the content as indexable text.
1754
- * @opt_param string ocrLanguage
1755
- * If ocr is true, hints at the language to use. Valid values are ISO 639-1 codes.
1756
- * @opt_param string visibility
1757
- * The visibility of the new file. This parameter is only relevant when convert=false.
1758
- * @opt_param bool pinned
1759
- * Whether to pin the head revision of the uploaded file.
1760
- * @opt_param bool ocr
1761
- * Whether to attempt OCR on .jpg, .png, .gif, or .pdf uploads.
1762
- * @opt_param string timedTextTrackName
1763
- * The timed text track name.
1764
- * @opt_param string timedTextLanguage
1765
- * The language of the timed text.
1766
- * @return Google_Service_Drive_DriveFile
1767
- */
1768
- public function insert(Google_Service_Drive_DriveFile $postBody, $optParams = array())
1769
- {
1770
- $params = array('postBody' => $postBody);
1771
- $params = array_merge($params, $optParams);
1772
-
1773
- return $this->call('insert', array($params), "Google_Service_Drive_DriveFile");
1774
- }
1775
-
1776
- /**
1777
- * Lists the user's files. (files.listFiles)
1778
- *
1779
- * @param array $optParams Optional parameters.
1780
- *
1781
- * @opt_param string q
1782
- * Query string for searching files.
1783
- * @opt_param string pageToken
1784
- * Page token for files.
1785
- * @opt_param string projection
1786
- * This parameter is deprecated and has no function.
1787
- * @opt_param int maxResults
1788
- * Maximum number of files to return.
1789
- * @return Google_Service_Drive_FileList
1790
- */
1791
- public function listFiles($optParams = array())
1792
- {
1793
- $params = array();
1794
- $params = array_merge($params, $optParams);
1795
-
1796
- return $this->call('list', array($params), "Google_Service_Drive_FileList");
1797
- }
1798
-
1799
- /**
1800
- * Updates file metadata and/or content. This method supports patch semantics.
1801
- * (files.patch)
1802
- *
1803
- * @param string $fileId
1804
- * The ID of the file to update.
1805
- * @param Google_DriveFile $postBody
1806
- * @param array $optParams Optional parameters.
1807
- *
1808
- * @opt_param bool convert
1809
- * Whether to convert this file to the corresponding Google Docs format.
1810
- * @opt_param bool updateViewedDate
1811
- * Whether to update the view date after successfully updating the file.
1812
- * @opt_param bool setModifiedDate
1813
- * Whether to set the modified date with the supplied modified date.
1814
- * @opt_param bool useContentAsIndexableText
1815
- * Whether to use the content as indexable text.
1816
- * @opt_param string ocrLanguage
1817
- * If ocr is true, hints at the language to use. Valid values are ISO 639-1 codes.
1818
- * @opt_param bool pinned
1819
- * Whether to pin the new revision.
1820
- * @opt_param bool newRevision
1821
- * Whether a blob upload should create a new revision. If false, the blob data in the current head
1822
- * revision is replaced. If not set or true, a new blob is created as head revision, and previous
1823
- * revisions are preserved (causing increased use of the user's data storage quota).
1824
- * @opt_param bool ocr
1825
- * Whether to attempt OCR on .jpg, .png, .gif, or .pdf uploads.
1826
- * @opt_param string timedTextLanguage
1827
- * The language of the timed text.
1828
- * @opt_param string timedTextTrackName
1829
- * The timed text track name.
1830
- * @return Google_Service_Drive_DriveFile
1831
- */
1832
- public function patch($fileId, Google_Service_Drive_DriveFile $postBody, $optParams = array())
1833
- {
1834
- $params = array('fileId' => $fileId, 'postBody' => $postBody);
1835
- $params = array_merge($params, $optParams);
1836
-
1837
- return $this->call('patch', array($params), "Google_Service_Drive_DriveFile");
1838
- }
1839
-
1840
- /**
1841
- * Set the file's updated time to the current server time. (files.touch)
1842
- *
1843
- * @param string $fileId
1844
- * The ID of the file to update.
1845
- * @param array $optParams Optional parameters.
1846
- *
1847
- * @return Google_Service_Drive_DriveFile
1848
- */
1849
- public function touch($fileId, $optParams = array())
1850
- {
1851
- $params = array('fileId' => $fileId);
1852
- $params = array_merge($params, $optParams);
1853
-
1854
- return $this->call('touch', array($params), "Google_Service_Drive_DriveFile");
1855
- }
1856
-
1857
- /**
1858
- * Moves a file to the trash. (files.trash)
1859
- *
1860
- * @param string $fileId
1861
- * The ID of the file to trash.
1862
- * @param array $optParams Optional parameters.
1863
- *
1864
- * @return Google_Service_Drive_DriveFile
1865
- */
1866
- public function trash($fileId, $optParams = array())
1867
- {
1868
- $params = array('fileId' => $fileId);
1869
- $params = array_merge($params, $optParams);
1870
-
1871
- return $this->call('trash', array($params), "Google_Service_Drive_DriveFile");
1872
- }
1873
-
1874
- /**
1875
- * Restores a file from the trash. (files.untrash)
1876
- *
1877
- * @param string $fileId
1878
- * The ID of the file to untrash.
1879
- * @param array $optParams Optional parameters.
1880
- *
1881
- * @return Google_Service_Drive_DriveFile
1882
- */
1883
- public function untrash($fileId, $optParams = array())
1884
- {
1885
- $params = array('fileId' => $fileId);
1886
- $params = array_merge($params, $optParams);
1887
-
1888
- return $this->call('untrash', array($params), "Google_Service_Drive_DriveFile");
1889
- }
1890
-
1891
- /**
1892
- * Updates file metadata and/or content. (files.update)
1893
- *
1894
- * @param string $fileId
1895
- * The ID of the file to update.
1896
- * @param Google_DriveFile $postBody
1897
- * @param array $optParams Optional parameters.
1898
- *
1899
- * @opt_param bool convert
1900
- * Whether to convert this file to the corresponding Google Docs format.
1901
- * @opt_param bool updateViewedDate
1902
- * Whether to update the view date after successfully updating the file.
1903
- * @opt_param bool setModifiedDate
1904
- * Whether to set the modified date with the supplied modified date.
1905
- * @opt_param bool useContentAsIndexableText
1906
- * Whether to use the content as indexable text.
1907
- * @opt_param string ocrLanguage
1908
- * If ocr is true, hints at the language to use. Valid values are ISO 639-1 codes.
1909
- * @opt_param bool pinned
1910
- * Whether to pin the new revision.
1911
- * @opt_param bool newRevision
1912
- * Whether a blob upload should create a new revision. If false, the blob data in the current head
1913
- * revision is replaced. If not set or true, a new blob is created as head revision, and previous
1914
- * revisions are preserved (causing increased use of the user's data storage quota).
1915
- * @opt_param bool ocr
1916
- * Whether to attempt OCR on .jpg, .png, .gif, or .pdf uploads.
1917
- * @opt_param string timedTextLanguage
1918
- * The language of the timed text.
1919
- * @opt_param string timedTextTrackName
1920
- * The timed text track name.
1921
- * @return Google_Service_Drive_DriveFile
1922
- */
1923
- public function update($fileId, Google_Service_Drive_DriveFile $postBody, $optParams = array())
1924
- {
1925
- $params = array('fileId' => $fileId, 'postBody' => $postBody);
1926
- $params = array_merge($params, $optParams);
1927
-
1928
- return $this->call('update', array($params), "Google_Service_Drive_DriveFile");
1929
- }
1930
-
1931
- /**
1932
- * Subscribe to changes on a file (files.watch)
1933
- *
1934
- * @param string $fileId
1935
- * The ID for the file in question.
1936
- * @param Google_Channel $postBody
1937
- * @param array $optParams Optional parameters.
1938
- *
1939
- * @opt_param bool updateViewedDate
1940
- * Whether to update the view date after successfully retrieving the file.
1941
- * @opt_param string projection
1942
- * This parameter is deprecated and has no function.
1943
- * @return Google_Service_Drive_Channel
1944
- */
1945
- public function watch($fileId, Google_Service_Drive_Channel $postBody, $optParams = array())
1946
- {
1947
- $params = array('fileId' => $fileId, 'postBody' => $postBody);
1948
- $params = array_merge($params, $optParams);
1949
-
1950
- return $this->call('watch', array($params), "Google_Service_Drive_Channel");
1951
- }
1952
- }
1953
-
1954
- /**
1955
- * The "parents" collection of methods.
1956
- * Typical usage is:
1957
- * <code>
1958
- * $driveService = new Google_Service_Drive(...);
1959
- * $parents = $driveService->parents;
1960
- * </code>
1961
- */
1962
- class Google_Service_Drive_Parents_Resource extends Google_Service_Resource
1963
- {
1964
- /**
1965
- * Removes a parent from a file. (parents.delete)
1966
- *
1967
- * @param string $fileId
1968
- * The ID of the file.
1969
- * @param string $parentId
1970
- * The ID of the parent.
1971
- * @param array $optParams Optional parameters.
1972
- */
1973
- public function delete($fileId, $parentId, $optParams = array())
1974
- {
1975
- $params = array('fileId' => $fileId, 'parentId' => $parentId);
1976
- $params = array_merge($params, $optParams);
1977
-
1978
- return $this->call('delete', array($params));
1979
- }
1980
-
1981
- /**
1982
- * Gets a specific parent reference. (parents.get)
1983
- *
1984
- * @param string $fileId
1985
- * The ID of the file.
1986
- * @param string $parentId
1987
- * The ID of the parent.
1988
- * @param array $optParams Optional parameters.
1989
- *
1990
- * @return Google_Service_Drive_ParentReference
1991
- */
1992
- public function get($fileId, $parentId, $optParams = array())
1993
- {
1994
- $params = array('fileId' => $fileId, 'parentId' => $parentId);
1995
- $params = array_merge($params, $optParams);
1996
-
1997
- return $this->call('get', array($params), "Google_Service_Drive_ParentReference");
1998
- }
1999
-
2000
- /**
2001
- * Adds a parent folder for a file. (parents.insert)
2002
- *
2003
- * @param string $fileId
2004
- * The ID of the file.
2005
- * @param Google_ParentReference $postBody
2006
- * @param array $optParams Optional parameters.
2007
- *
2008
- * @return Google_Service_Drive_ParentReference
2009
- */
2010
- public function insert($fileId, Google_Service_Drive_ParentReference $postBody, $optParams = array())
2011
- {
2012
- $params = array('fileId' => $fileId, 'postBody' => $postBody);
2013
- $params = array_merge($params, $optParams);
2014
-
2015
- return $this->call('insert', array($params), "Google_Service_Drive_ParentReference");
2016
- }
2017
-
2018
- /**
2019
- * Lists a file's parents. (parents.listParents)
2020
- *
2021
- * @param string $fileId
2022
- * The ID of the file.
2023
- * @param array $optParams Optional parameters.
2024
- *
2025
- * @return Google_Service_Drive_ParentList
2026
- */
2027
- public function listParents($fileId, $optParams = array())
2028
- {
2029
- $params = array('fileId' => $fileId);
2030
- $params = array_merge($params, $optParams);
2031
-
2032
- return $this->call('list', array($params), "Google_Service_Drive_ParentList");
2033
- }
2034
- }
2035
-
2036
- /**
2037
- * The "permissions" collection of methods.
2038
- * Typical usage is:
2039
- * <code>
2040
- * $driveService = new Google_Service_Drive(...);
2041
- * $permissions = $driveService->permissions;
2042
- * </code>
2043
- */
2044
- class Google_Service_Drive_Permissions_Resource extends Google_Service_Resource
2045
- {
2046
- /**
2047
- * Deletes a permission from a file. (permissions.delete)
2048
- *
2049
- * @param string $fileId
2050
- * The ID for the file.
2051
- * @param string $permissionId
2052
- * The ID for the permission.
2053
- * @param array $optParams Optional parameters.
2054
- */
2055
- public function delete($fileId, $permissionId, $optParams = array())
2056
- {
2057
- $params = array('fileId' => $fileId, 'permissionId' => $permissionId);
2058
- $params = array_merge($params, $optParams);
2059
-
2060
- return $this->call('delete', array($params));
2061
- }
2062
-
2063
- /**
2064
- * Gets a permission by ID. (permissions.get)
2065
- *
2066
- * @param string $fileId
2067
- * The ID for the file.
2068
- * @param string $permissionId
2069
- * The ID for the permission.
2070
- * @param array $optParams Optional parameters.
2071
- *
2072
- * @return Google_Service_Drive_Permission
2073
- */
2074
- public function get($fileId, $permissionId, $optParams = array())
2075
- {
2076
- $params = array('fileId' => $fileId, 'permissionId' => $permissionId);
2077
- $params = array_merge($params, $optParams);
2078
-
2079
- return $this->call('get', array($params), "Google_Service_Drive_Permission");
2080
- }
2081
-
2082
- /**
2083
- * Returns the permission ID for an email address. (permissions.getIdForEmail)
2084
- *
2085
- * @param string $email
2086
- * The email address for which to return a permission ID
2087
- * @param array $optParams Optional parameters.
2088
- *
2089
- * @return Google_Service_Drive_PermissionId
2090
- */
2091
- public function getIdForEmail($email, $optParams = array())
2092
- {
2093
- $params = array('email' => $email);
2094
- $params = array_merge($params, $optParams);
2095
-
2096
- return $this->call('getIdForEmail', array($params), "Google_Service_Drive_PermissionId");
2097
- }
2098
-
2099
- /**
2100
- * Inserts a permission for a file. (permissions.insert)
2101
- *
2102
- * @param string $fileId
2103
- * The ID for the file.
2104
- * @param Google_Permission $postBody
2105
- * @param array $optParams Optional parameters.
2106
- *
2107
- * @opt_param string emailMessage
2108
- * A custom message to include in notification emails.
2109
- * @opt_param bool sendNotificationEmails
2110
- * Whether to send notification emails when sharing to users or groups.
2111
- * @return Google_Service_Drive_Permission
2112
- */
2113
- public function insert($fileId, Google_Service_Drive_Permission $postBody, $optParams = array())
2114
- {
2115
- $params = array('fileId' => $fileId, 'postBody' => $postBody);
2116
- $params = array_merge($params, $optParams);
2117
-
2118
- return $this->call('insert', array($params), "Google_Service_Drive_Permission");
2119
- }
2120
-
2121
- /**
2122
- * Lists a file's permissions. (permissions.listPermissions)
2123
- *
2124
- * @param string $fileId
2125
- * The ID for the file.
2126
- * @param array $optParams Optional parameters.
2127
- *
2128
- * @return Google_Service_Drive_PermissionList
2129
- */
2130
- public function listPermissions($fileId, $optParams = array())
2131
- {
2132
- $params = array('fileId' => $fileId);
2133
- $params = array_merge($params, $optParams);
2134
-
2135
- return $this->call('list', array($params), "Google_Service_Drive_PermissionList");
2136
- }
2137
-
2138
- /**
2139
- * Updates a permission. This method supports patch semantics.
2140
- * (permissions.patch)
2141
- *
2142
- * @param string $fileId
2143
- * The ID for the file.
2144
- * @param string $permissionId
2145
- * The ID for the permission.
2146
- * @param Google_Permission $postBody
2147
- * @param array $optParams Optional parameters.
2148
- *
2149
- * @opt_param bool transferOwnership
2150
- * Whether changing a role to 'owner' should also downgrade the current owners to writers.
2151
- * @return Google_Service_Drive_Permission
2152
- */
2153
- public function patch($fileId, $permissionId, Google_Service_Drive_Permission $postBody, $optParams = array())
2154
- {
2155
- $params = array('fileId' => $fileId, 'permissionId' => $permissionId, 'postBody' => $postBody);
2156
- $params = array_merge($params, $optParams);
2157
-
2158
- return $this->call('patch', array($params), "Google_Service_Drive_Permission");
2159
- }
2160
-
2161
- /**
2162
- * Updates a permission. (permissions.update)
2163
- *
2164
- * @param string $fileId
2165
- * The ID for the file.
2166
- * @param string $permissionId
2167
- * The ID for the permission.
2168
- * @param Google_Permission $postBody
2169
- * @param array $optParams Optional parameters.
2170
- *
2171
- * @opt_param bool transferOwnership
2172
- * Whether changing a role to 'owner' should also downgrade the current owners to writers.
2173
- * @return Google_Service_Drive_Permission
2174
- */
2175
- public function update($fileId, $permissionId, Google_Service_Drive_Permission $postBody, $optParams = array())
2176
- {
2177
- $params = array('fileId' => $fileId, 'permissionId' => $permissionId, 'postBody' => $postBody);
2178
- $params = array_merge($params, $optParams);
2179
-
2180
- return $this->call('update', array($params), "Google_Service_Drive_Permission");
2181
- }
2182
- }
2183
-
2184
- /**
2185
- * The "properties" collection of methods.
2186
- * Typical usage is:
2187
- * <code>
2188
- * $driveService = new Google_Service_Drive(...);
2189
- * $properties = $driveService->properties;
2190
- * </code>
2191
- */
2192
- class Google_Service_Drive_Properties_Resource extends Google_Service_Resource
2193
- {
2194
- /**
2195
- * Deletes a property. (properties.delete)
2196
- *
2197
- * @param string $fileId
2198
- * The ID of the file.
2199
- * @param string $propertyKey
2200
- * The key of the property.
2201
- * @param array $optParams Optional parameters.
2202
- *
2203
- * @opt_param string visibility
2204
- * The visibility of the property.
2205
- */
2206
- public function delete($fileId, $propertyKey, $optParams = array())
2207
- {
2208
- $params = array('fileId' => $fileId, 'propertyKey' => $propertyKey);
2209
- $params = array_merge($params, $optParams);
2210
-
2211
- return $this->call('delete', array($params));
2212
- }
2213
-
2214
- /**
2215
- * Gets a property by its key. (properties.get)
2216
- *
2217
- * @param string $fileId
2218
- * The ID of the file.
2219
- * @param string $propertyKey
2220
- * The key of the property.
2221
- * @param array $optParams Optional parameters.
2222
- *
2223
- * @opt_param string visibility
2224
- * The visibility of the property.
2225
- * @return Google_Service_Drive_Property
2226
- */
2227
- public function get($fileId, $propertyKey, $optParams = array())
2228
- {
2229
- $params = array('fileId' => $fileId, 'propertyKey' => $propertyKey);
2230
- $params = array_merge($params, $optParams);
2231
-
2232
- return $this->call('get', array($params), "Google_Service_Drive_Property");
2233
- }
2234
-
2235
- /**
2236
- * Adds a property to a file. (properties.insert)
2237
- *
2238
- * @param string $fileId
2239
- * The ID of the file.
2240
- * @param Google_Property $postBody
2241
- * @param array $optParams Optional parameters.
2242
- *
2243
- * @return Google_Service_Drive_Property
2244
- */
2245
- public function insert($fileId, Google_Service_Drive_Property $postBody, $optParams = array())
2246
- {
2247
- $params = array('fileId' => $fileId, 'postBody' => $postBody);
2248
- $params = array_merge($params, $optParams);
2249
-
2250
- return $this->call('insert', array($params), "Google_Service_Drive_Property");
2251
- }
2252
-
2253
- /**
2254
- * Lists a file's properties. (properties.listProperties)
2255
- *
2256
- * @param string $fileId
2257
- * The ID of the file.
2258
- * @param array $optParams Optional parameters.
2259
- *
2260
- * @return Google_Service_Drive_PropertyList
2261
- */
2262
- public function listProperties($fileId, $optParams = array())
2263
- {
2264
- $params = array('fileId' => $fileId);
2265
- $params = array_merge($params, $optParams);
2266
-
2267
- return $this->call('list', array($params), "Google_Service_Drive_PropertyList");
2268
- }
2269
-
2270
- /**
2271
- * Updates a property. This method supports patch semantics. (properties.patch)
2272
- *
2273
- * @param string $fileId
2274
- * The ID of the file.
2275
- * @param string $propertyKey
2276
- * The key of the property.
2277
- * @param Google_Property $postBody
2278
- * @param array $optParams Optional parameters.
2279
- *
2280
- * @opt_param string visibility
2281
- * The visibility of the property.
2282
- * @return Google_Service_Drive_Property
2283
- */
2284
- public function patch($fileId, $propertyKey, Google_Service_Drive_Property $postBody, $optParams = array())
2285
- {
2286
- $params = array('fileId' => $fileId, 'propertyKey' => $propertyKey, 'postBody' => $postBody);
2287
- $params = array_merge($params, $optParams);
2288
-
2289
- return $this->call('patch', array($params), "Google_Service_Drive_Property");
2290
- }
2291
-
2292
- /**
2293
- * Updates a property. (properties.update)
2294
- *
2295
- * @param string $fileId
2296
- * The ID of the file.
2297
- * @param string $propertyKey
2298
- * The key of the property.
2299
- * @param Google_Property $postBody
2300
- * @param array $optParams Optional parameters.
2301
- *
2302
- * @opt_param string visibility
2303
- * The visibility of the property.
2304
- * @return Google_Service_Drive_Property
2305
- */
2306
- public function update($fileId, $propertyKey, Google_Service_Drive_Property $postBody, $optParams = array())
2307
- {
2308
- $params = array('fileId' => $fileId, 'propertyKey' => $propertyKey, 'postBody' => $postBody);
2309
- $params = array_merge($params, $optParams);
2310
-
2311
- return $this->call('update', array($params), "Google_Service_Drive_Property");
2312
- }
2313
- }
2314
-
2315
- /**
2316
- * The "realtime" collection of methods.
2317
- * Typical usage is:
2318
- * <code>
2319
- * $driveService = new Google_Service_Drive(...);
2320
- * $realtime = $driveService->realtime;
2321
- * </code>
2322
- */
2323
- class Google_Service_Drive_Realtime_Resource extends Google_Service_Resource
2324
- {
2325
- /**
2326
- * Exports the contents of the Realtime API data model associated with this file
2327
- * as JSON. (realtime.get)
2328
- *
2329
- * @param string $fileId
2330
- * The ID of the file that the Realtime API data model is associated with.
2331
- * @param array $optParams Optional parameters.
2332
- */
2333
- public function get($fileId, $optParams = array())
2334
- {
2335
- $params = array('fileId' => $fileId);
2336
- $params = array_merge($params, $optParams);
2337
-
2338
- return $this->call('get', array($params));
2339
- }
2340
-
2341
- /**
2342
- * Overwrites the Realtime API data model associated with this file with the
2343
- * provided JSON data model. (realtime.update)
2344
- *
2345
- * @param string $fileId
2346
- * The ID of the file that the Realtime API data model is associated with.
2347
- * @param array $optParams Optional parameters.
2348
- *
2349
- * @opt_param string baseRevision
2350
- * The revision of the model to diff the uploaded model against. If set, the uploaded model is
2351
- * diffed against the provided revision and those differences are merged with any changes made to
2352
- * the model after the provided revision. If not set, the uploaded model replaces the current model
2353
- * on the server.
2354
- */
2355
- public function update($fileId, $optParams = array())
2356
- {
2357
- $params = array('fileId' => $fileId);
2358
- $params = array_merge($params, $optParams);
2359
-
2360
- return $this->call('update', array($params));
2361
- }
2362
- }
2363
-
2364
- /**
2365
- * The "replies" collection of methods.
2366
- * Typical usage is:
2367
- * <code>
2368
- * $driveService = new Google_Service_Drive(...);
2369
- * $replies = $driveService->replies;
2370
- * </code>
2371
- */
2372
- class Google_Service_Drive_Replies_Resource extends Google_Service_Resource
2373
- {
2374
- /**
2375
- * Deletes a reply. (replies.delete)
2376
- *
2377
- * @param string $fileId
2378
- * The ID of the file.
2379
- * @param string $commentId
2380
- * The ID of the comment.
2381
- * @param string $replyId
2382
- * The ID of the reply.
2383
- * @param array $optParams Optional parameters.
2384
- */
2385
- public function delete($fileId, $commentId, $replyId, $optParams = array())
2386
- {
2387
- $params = array('fileId' => $fileId, 'commentId' => $commentId, 'replyId' => $replyId);
2388
- $params = array_merge($params, $optParams);
2389
-
2390
- return $this->call('delete', array($params));
2391
- }
2392
-
2393
- /**
2394
- * Gets a reply. (replies.get)
2395
- *
2396
- * @param string $fileId
2397
- * The ID of the file.
2398
- * @param string $commentId
2399
- * The ID of the comment.
2400
- * @param string $replyId
2401
- * The ID of the reply.
2402
- * @param array $optParams Optional parameters.
2403
- *
2404
- * @opt_param bool includeDeleted
2405
- * If set, this will succeed when retrieving a deleted reply.
2406
- * @return Google_Service_Drive_CommentReply
2407
- */
2408
- public function get($fileId, $commentId, $replyId, $optParams = array())
2409
- {
2410
- $params = array('fileId' => $fileId, 'commentId' => $commentId, 'replyId' => $replyId);
2411
- $params = array_merge($params, $optParams);
2412
-
2413
- return $this->call('get', array($params), "Google_Service_Drive_CommentReply");
2414
- }
2415
-
2416
- /**
2417
- * Creates a new reply to the given comment. (replies.insert)
2418
- *
2419
- * @param string $fileId
2420
- * The ID of the file.
2421
- * @param string $commentId
2422
- * The ID of the comment.
2423
- * @param Google_CommentReply $postBody
2424
- * @param array $optParams Optional parameters.
2425
- *
2426
- * @return Google_Service_Drive_CommentReply
2427
- */
2428
- public function insert($fileId, $commentId, Google_Service_Drive_CommentReply $postBody, $optParams = array())
2429
- {
2430
- $params = array('fileId' => $fileId, 'commentId' => $commentId, 'postBody' => $postBody);
2431
- $params = array_merge($params, $optParams);
2432
-
2433
- return $this->call('insert', array($params), "Google_Service_Drive_CommentReply");
2434
- }
2435
-
2436
- /**
2437
- * Lists all of the replies to a comment. (replies.listReplies)
2438
- *
2439
- * @param string $fileId
2440
- * The ID of the file.
2441
- * @param string $commentId
2442
- * The ID of the comment.
2443
- * @param array $optParams Optional parameters.
2444
- *
2445
- * @opt_param string pageToken
2446
- * The continuation token, used to page through large result sets. To get the next page of results,
2447
- * set this parameter to the value of "nextPageToken" from the previous response.
2448
- * @opt_param bool includeDeleted
2449
- * If set, all replies, including deleted replies (with content stripped) will be returned.
2450
- * @opt_param int maxResults
2451
- * The maximum number of replies to include in the response, used for paging.
2452
- * @return Google_Service_Drive_CommentReplyList
2453
- */
2454
- public function listReplies($fileId, $commentId, $optParams = array())
2455
- {
2456
- $params = array('fileId' => $fileId, 'commentId' => $commentId);
2457
- $params = array_merge($params, $optParams);
2458
-
2459
- return $this->call('list', array($params), "Google_Service_Drive_CommentReplyList");
2460
- }
2461
-
2462
- /**
2463
- * Updates an existing reply. This method supports patch semantics.
2464
- * (replies.patch)
2465
- *
2466
- * @param string $fileId
2467
- * The ID of the file.
2468
- * @param string $commentId
2469
- * The ID of the comment.
2470
- * @param string $replyId
2471
- * The ID of the reply.
2472
- * @param Google_CommentReply $postBody
2473
- * @param array $optParams Optional parameters.
2474
- *
2475
- * @return Google_Service_Drive_CommentReply
2476
- */
2477
- public function patch($fileId, $commentId, $replyId, Google_Service_Drive_CommentReply $postBody, $optParams = array())
2478
- {
2479
- $params = array('fileId' => $fileId, 'commentId' => $commentId, 'replyId' => $replyId, 'postBody' => $postBody);
2480
- $params = array_merge($params, $optParams);
2481
-
2482
- return $this->call('patch', array($params), "Google_Service_Drive_CommentReply");
2483
- }
2484
-
2485
- /**
2486
- * Updates an existing reply. (replies.update)
2487
- *
2488
- * @param string $fileId
2489
- * The ID of the file.
2490
- * @param string $commentId
2491
- * The ID of the comment.
2492
- * @param string $replyId
2493
- * The ID of the reply.
2494
- * @param Google_CommentReply $postBody
2495
- * @param array $optParams Optional parameters.
2496
- *
2497
- * @return Google_Service_Drive_CommentReply
2498
- */
2499
- public function update($fileId, $commentId, $replyId, Google_Service_Drive_CommentReply $postBody, $optParams = array())
2500
- {
2501
- $params = array('fileId' => $fileId, 'commentId' => $commentId, 'replyId' => $replyId, 'postBody' => $postBody);
2502
- $params = array_merge($params, $optParams);
2503
-
2504
- return $this->call('update', array($params), "Google_Service_Drive_CommentReply");
2505
- }
2506
- }
2507
-
2508
- /**
2509
- * The "revisions" collection of methods.
2510
- * Typical usage is:
2511
- * <code>
2512
- * $driveService = new Google_Service_Drive(...);
2513
- * $revisions = $driveService->revisions;
2514
- * </code>
2515
- */
2516
- class Google_Service_Drive_Revisions_Resource extends Google_Service_Resource
2517
- {
2518
- /**
2519
- * Removes a revision. (revisions.delete)
2520
- *
2521
- * @param string $fileId
2522
- * The ID of the file.
2523
- * @param string $revisionId
2524
- * The ID of the revision.
2525
- * @param array $optParams Optional parameters.
2526
- */
2527
- public function delete($fileId, $revisionId, $optParams = array())
2528
- {
2529
- $params = array('fileId' => $fileId, 'revisionId' => $revisionId);
2530
- $params = array_merge($params, $optParams);
2531
-
2532
- return $this->call('delete', array($params));
2533
- }
2534
-
2535
- /**
2536
- * Gets a specific revision. (revisions.get)
2537
- *
2538
- * @param string $fileId
2539
- * The ID of the file.
2540
- * @param string $revisionId
2541
- * The ID of the revision.
2542
- * @param array $optParams Optional parameters.
2543
- *
2544
- * @return Google_Service_Drive_Revision
2545
- */
2546
- public function get($fileId, $revisionId, $optParams = array())
2547
- {
2548
- $params = array('fileId' => $fileId, 'revisionId' => $revisionId);
2549
- $params = array_merge($params, $optParams);
2550
-
2551
- return $this->call('get', array($params), "Google_Service_Drive_Revision");
2552
- }
2553
-
2554
- /**
2555
- * Lists a file's revisions. (revisions.listRevisions)
2556
- *
2557
- * @param string $fileId
2558
- * The ID of the file.
2559
- * @param array $optParams Optional parameters.
2560
- *
2561
- * @return Google_Service_Drive_RevisionList
2562
- */
2563
- public function listRevisions($fileId, $optParams = array())
2564
- {
2565
- $params = array('fileId' => $fileId);
2566
- $params = array_merge($params, $optParams);
2567
-
2568
- return $this->call('list', array($params), "Google_Service_Drive_RevisionList");
2569
- }
2570
-
2571
- /**
2572
- * Updates a revision. This method supports patch semantics. (revisions.patch)
2573
- *
2574
- * @param string $fileId
2575
- * The ID for the file.
2576
- * @param string $revisionId
2577
- * The ID for the revision.
2578
- * @param Google_Revision $postBody
2579
- * @param array $optParams Optional parameters.
2580
- *
2581
- * @return Google_Service_Drive_Revision
2582
- */
2583
- public function patch($fileId, $revisionId, Google_Service_Drive_Revision $postBody, $optParams = array())
2584
- {
2585
- $params = array('fileId' => $fileId, 'revisionId' => $revisionId, 'postBody' => $postBody);
2586
- $params = array_merge($params, $optParams);
2587
-
2588
- return $this->call('patch', array($params), "Google_Service_Drive_Revision");
2589
- }
2590
-
2591
- /**
2592
- * Updates a revision. (revisions.update)
2593
- *
2594
- * @param string $fileId
2595
- * The ID for the file.
2596
- * @param string $revisionId
2597
- * The ID for the revision.
2598
- * @param Google_Revision $postBody
2599
- * @param array $optParams Optional parameters.
2600
- *
2601
- * @return Google_Service_Drive_Revision
2602
- */
2603
- public function update($fileId, $revisionId, Google_Service_Drive_Revision $postBody, $optParams = array())
2604
- {
2605
- $params = array('fileId' => $fileId, 'revisionId' => $revisionId, 'postBody' => $postBody);
2606
- $params = array_merge($params, $optParams);
2607
-
2608
- return $this->call('update', array($params), "Google_Service_Drive_Revision");
2609
- }
2610
- }
2611
-
2612
- class Google_Service_Drive_About extends Google_Collection
2613
- {
2614
- protected $additionalRoleInfoType = 'Google_Service_Drive_AboutAdditionalRoleInfo';
2615
- protected $additionalRoleInfoDataType = 'array';
2616
- public $domainSharingPolicy;
2617
- public $etag;
2618
- protected $exportFormatsType = 'Google_Service_Drive_AboutExportFormats';
2619
- protected $exportFormatsDataType = 'array';
2620
- protected $featuresType = 'Google_Service_Drive_AboutFeatures';
2621
- protected $featuresDataType = 'array';
2622
- protected $importFormatsType = 'Google_Service_Drive_AboutImportFormats';
2623
- protected $importFormatsDataType = 'array';
2624
- public $isCurrentAppInstalled;
2625
- public $kind;
2626
- public $largestChangeId;
2627
- protected $maxUploadSizesType = 'Google_Service_Drive_AboutMaxUploadSizes';
2628
- protected $maxUploadSizesDataType = 'array';
2629
- public $name;
2630
- public $permissionId;
2631
- public $quotaBytesTotal;
2632
- public $quotaBytesUsed;
2633
- public $quotaBytesUsedAggregate;
2634
- public $quotaBytesUsedInTrash;
2635
- public $remainingChangeIds;
2636
- public $rootFolderId;
2637
- public $selfLink;
2638
- protected $userType = 'Google_Service_Drive_User';
2639
- protected $userDataType = '';
2640
-
2641
- public function setAdditionalRoleInfo($additionalRoleInfo)
2642
- {
2643
- $this->additionalRoleInfo = $additionalRoleInfo;
2644
- }
2645
-
2646
- public function getAdditionalRoleInfo()
2647
- {
2648
- return $this->additionalRoleInfo;
2649
- }
2650
-
2651
- public function setDomainSharingPolicy($domainSharingPolicy)
2652
- {
2653
- $this->domainSharingPolicy = $domainSharingPolicy;
2654
- }
2655
-
2656
- public function getDomainSharingPolicy()
2657
- {
2658
- return $this->domainSharingPolicy;
2659
- }
2660
-
2661
- public function setEtag($etag)
2662
- {
2663
- $this->etag = $etag;
2664
- }
2665
-
2666
- public function getEtag()
2667
- {
2668
- return $this->etag;
2669
- }
2670
-
2671
- public function setExportFormats($exportFormats)
2672
- {
2673
- $this->exportFormats = $exportFormats;
2674
- }
2675
-
2676
- public function getExportFormats()
2677
- {
2678
- return $this->exportFormats;
2679
- }
2680
-
2681
- public function setFeatures($features)
2682
- {
2683
- $this->features = $features;
2684
- }
2685
-
2686
- public function getFeatures()
2687
- {
2688
- return $this->features;
2689
- }
2690
-
2691
- public function setImportFormats($importFormats)
2692
- {
2693
- $this->importFormats = $importFormats;
2694
- }
2695
-
2696
- public function getImportFormats()
2697
- {
2698
- return $this->importFormats;
2699
- }
2700
-
2701
- public function setIsCurrentAppInstalled($isCurrentAppInstalled)
2702
- {
2703
- $this->isCurrentAppInstalled = $isCurrentAppInstalled;
2704
- }
2705
-
2706
- public function getIsCurrentAppInstalled()
2707
- {
2708
- return $this->isCurrentAppInstalled;
2709
- }
2710
-
2711
- public function setKind($kind)
2712
- {
2713
- $this->kind = $kind;
2714
- }
2715
-
2716
- public function getKind()
2717
- {
2718
- return $this->kind;
2719
- }
2720
-
2721
- public function setLargestChangeId($largestChangeId)
2722
- {
2723
- $this->largestChangeId = $largestChangeId;
2724
- }
2725
-
2726
- public function getLargestChangeId()
2727
- {
2728
- return $this->largestChangeId;
2729
- }
2730
-
2731
- public function setMaxUploadSizes($maxUploadSizes)
2732
- {
2733
- $this->maxUploadSizes = $maxUploadSizes;
2734
- }
2735
-
2736
- public function getMaxUploadSizes()
2737
- {
2738
- return $this->maxUploadSizes;
2739
- }
2740
-
2741
- public function setName($name)
2742
- {
2743
- $this->name = $name;
2744
- }
2745
-
2746
- public function getName()
2747
- {
2748
- return $this->name;
2749
- }
2750
-
2751
- public function setPermissionId($permissionId)
2752
- {
2753
- $this->permissionId = $permissionId;
2754
- }
2755
-
2756
- public function getPermissionId()
2757
- {
2758
- return $this->permissionId;
2759
- }
2760
-
2761
- public function setQuotaBytesTotal($quotaBytesTotal)
2762
- {
2763
- $this->quotaBytesTotal = $quotaBytesTotal;
2764
- }
2765
-
2766
- public function getQuotaBytesTotal()
2767
- {
2768
- return $this->quotaBytesTotal;
2769
- }
2770
-
2771
- public function setQuotaBytesUsed($quotaBytesUsed)
2772
- {
2773
- $this->quotaBytesUsed = $quotaBytesUsed;
2774
- }
2775
-
2776
- public function getQuotaBytesUsed()
2777
- {
2778
- return $this->quotaBytesUsed;
2779
- }
2780
-
2781
- public function setQuotaBytesUsedAggregate($quotaBytesUsedAggregate)
2782
- {
2783
- $this->quotaBytesUsedAggregate = $quotaBytesUsedAggregate;
2784
- }
2785
-
2786
- public function getQuotaBytesUsedAggregate()
2787
- {
2788
- return $this->quotaBytesUsedAggregate;
2789
- }
2790
-
2791
- public function setQuotaBytesUsedInTrash($quotaBytesUsedInTrash)
2792
- {
2793
- $this->quotaBytesUsedInTrash = $quotaBytesUsedInTrash;
2794
- }
2795
-
2796
- public function getQuotaBytesUsedInTrash()
2797
- {
2798
- return $this->quotaBytesUsedInTrash;
2799
- }
2800
-
2801
- public function setRemainingChangeIds($remainingChangeIds)
2802
- {
2803
- $this->remainingChangeIds = $remainingChangeIds;
2804
- }
2805
-
2806
- public function getRemainingChangeIds()
2807
- {
2808
- return $this->remainingChangeIds;
2809
- }
2810
-
2811
- public function setRootFolderId($rootFolderId)
2812
- {
2813
- $this->rootFolderId = $rootFolderId;
2814
- }
2815
-
2816
- public function getRootFolderId()
2817
- {
2818
- return $this->rootFolderId;
2819
- }
2820
-
2821
- public function setSelfLink($selfLink)
2822
- {
2823
- $this->selfLink = $selfLink;
2824
- }
2825
-
2826
- public function getSelfLink()
2827
- {
2828
- return $this->selfLink;
2829
- }
2830
-
2831
- public function setUser(Google_Service_Drive_User $user)
2832
- {
2833
- $this->user = $user;
2834
- }
2835
-
2836
- public function getUser()
2837
- {
2838
- return $this->user;
2839
- }
2840
- }
2841
-
2842
- class Google_Service_Drive_AboutAdditionalRoleInfo extends Google_Collection
2843
- {
2844
- protected $roleSetsType = 'Google_Service_Drive_AboutAdditionalRoleInfoRoleSets';
2845
- protected $roleSetsDataType = 'array';
2846
- public $type;
2847
-
2848
- public function setRoleSets($roleSets)
2849
- {
2850
- $this->roleSets = $roleSets;
2851
- }
2852
-
2853
- public function getRoleSets()
2854
- {
2855
- return $this->roleSets;
2856
- }
2857
-
2858
- public function setType($type)
2859
- {
2860
- $this->type = $type;
2861
- }
2862
-
2863
- public function getType()
2864
- {
2865
- return $this->type;
2866
- }
2867
- }
2868
-
2869
- class Google_Service_Drive_AboutAdditionalRoleInfoRoleSets extends Google_Collection
2870
- {
2871
- public $additionalRoles;
2872
- public $primaryRole;
2873
-
2874
- public function setAdditionalRoles($additionalRoles)
2875
- {
2876
- $this->additionalRoles = $additionalRoles;
2877
- }
2878
-
2879
- public function getAdditionalRoles()
2880
- {
2881
- return $this->additionalRoles;
2882
- }
2883
-
2884
- public function setPrimaryRole($primaryRole)
2885
- {
2886
- $this->primaryRole = $primaryRole;
2887
- }
2888
-
2889
- public function getPrimaryRole()
2890
- {
2891
- return $this->primaryRole;
2892
- }
2893
- }
2894
-
2895
- class Google_Service_Drive_AboutExportFormats extends Google_Collection
2896
- {
2897
- public $source;
2898
- public $targets;
2899
-
2900
- public function setSource($source)
2901
- {
2902
- $this->source = $source;
2903
- }
2904
-
2905
- public function getSource()
2906
- {
2907
- return $this->source;
2908
- }
2909
-
2910
- public function setTargets($targets)
2911
- {
2912
- $this->targets = $targets;
2913
- }
2914
-
2915
- public function getTargets()
2916
- {
2917
- return $this->targets;
2918
- }
2919
- }
2920
-
2921
- class Google_Service_Drive_AboutFeatures extends Google_ApiModel
2922
- {
2923
- public $featureName;
2924
- public $featureRate;
2925
-
2926
- public function setFeatureName($featureName)
2927
- {
2928
- $this->featureName = $featureName;
2929
- }
2930
-
2931
- public function getFeatureName()
2932
- {
2933
- return $this->featureName;
2934
- }
2935
-
2936
- public function setFeatureRate($featureRate)
2937
- {
2938
- $this->featureRate = $featureRate;
2939
- }
2940
-
2941
- public function getFeatureRate()
2942
- {
2943
- return $this->featureRate;
2944
- }
2945
- }
2946
-
2947
- class Google_Service_Drive_AboutImportFormats extends Google_Collection
2948
- {
2949
- public $source;
2950
- public $targets;
2951
-
2952
- public function setSource($source)
2953
- {
2954
- $this->source = $source;
2955
- }
2956
-
2957
- public function getSource()
2958
- {
2959
- return $this->source;
2960
- }
2961
-
2962
- public function setTargets($targets)
2963
- {
2964
- $this->targets = $targets;
2965
- }
2966
-
2967
- public function getTargets()
2968
- {
2969
- return $this->targets;
2970
- }
2971
- }
2972
-
2973
- class Google_Service_Drive_AboutMaxUploadSizes extends Google_ApiModel
2974
- {
2975
- public $size;
2976
- public $type;
2977
-
2978
- public function setSize($size)
2979
- {
2980
- $this->size = $size;
2981
- }
2982
-
2983
- public function getSize()
2984
- {
2985
- return $this->size;
2986
- }
2987
-
2988
- public function setType($type)
2989
- {
2990
- $this->type = $type;
2991
- }
2992
-
2993
- public function getType()
2994
- {
2995
- return $this->type;
2996
- }
2997
- }
2998
-
2999
- class Google_Service_Drive_App extends Google_Collection
3000
- {
3001
- public $authorized;
3002
- public $createInFolderTemplate;
3003
- public $createUrl;
3004
- protected $iconsType = 'Google_Service_Drive_AppIcons';
3005
- protected $iconsDataType = 'array';
3006
- public $id;
3007
- public $installed;
3008
- public $kind;
3009
- public $longDescription;
3010
- public $name;
3011
- public $objectType;
3012
- public $openUrlTemplate;
3013
- public $primaryFileExtensions;
3014
- public $primaryMimeTypes;
3015
- public $productId;
3016
- public $productUrl;
3017
- public $secondaryFileExtensions;
3018
- public $secondaryMimeTypes;
3019
- public $shortDescription;
3020
- public $supportsCreate;
3021
- public $supportsImport;
3022
- public $supportsMultiOpen;
3023
- public $useByDefault;
3024
-
3025
- public function setAuthorized($authorized)
3026
- {
3027
- $this->authorized = $authorized;
3028
- }
3029
-
3030
- public function getAuthorized()
3031
- {
3032
- return $this->authorized;
3033
- }
3034
-
3035
- public function setCreateInFolderTemplate($createInFolderTemplate)
3036
- {
3037
- $this->createInFolderTemplate = $createInFolderTemplate;
3038
- }
3039
-
3040
- public function getCreateInFolderTemplate()
3041
- {
3042
- return $this->createInFolderTemplate;
3043
- }
3044
-
3045
- public function setCreateUrl($createUrl)
3046
- {
3047
- $this->createUrl = $createUrl;
3048
- }
3049
-
3050
- public function getCreateUrl()
3051
- {
3052
- return $this->createUrl;
3053
- }
3054
-
3055
- public function setIcons($icons)
3056
- {
3057
- $this->icons = $icons;
3058
- }
3059
-
3060
- public function getIcons()
3061
- {
3062
- return $this->icons;
3063
- }
3064
-
3065
- public function setId($id)
3066
- {
3067
- $this->id = $id;
3068
- }
3069
-
3070
- public function getId()
3071
- {
3072
- return $this->id;
3073
- }
3074
-
3075
- public function setInstalled($installed)
3076
- {
3077
- $this->installed = $installed;
3078
- }
3079
-
3080
- public function getInstalled()
3081
- {
3082
- return $this->installed;
3083
- }
3084
-
3085
- public function setKind($kind)
3086
- {
3087
- $this->kind = $kind;
3088
- }
3089
-
3090
- public function getKind()
3091
- {
3092
- return $this->kind;
3093
- }
3094
-
3095
- public function setLongDescription($longDescription)
3096
- {
3097
- $this->longDescription = $longDescription;
3098
- }
3099
-
3100
- public function getLongDescription()
3101
- {
3102
- return $this->longDescription;
3103
- }
3104
-
3105
- public function setName($name)
3106
- {
3107
- $this->name = $name;
3108
- }
3109
-
3110
- public function getName()
3111
- {
3112
- return $this->name;
3113
- }
3114
-
3115
- public function setObjectType($objectType)
3116
- {
3117
- $this->objectType = $objectType;
3118
- }
3119
-
3120
- public function getObjectType()
3121
- {
3122
- return $this->objectType;
3123
- }
3124
-
3125
- public function setOpenUrlTemplate($openUrlTemplate)
3126
- {
3127
- $this->openUrlTemplate = $openUrlTemplate;
3128
- }
3129
-
3130
- public function getOpenUrlTemplate()
3131
- {
3132
- return $this->openUrlTemplate;
3133
- }
3134
-
3135
- public function setPrimaryFileExtensions($primaryFileExtensions)
3136
- {
3137
- $this->primaryFileExtensions = $primaryFileExtensions;
3138
- }
3139
-
3140
- public function getPrimaryFileExtensions()
3141
- {
3142
- return $this->primaryFileExtensions;
3143
- }
3144
-
3145
- public function setPrimaryMimeTypes($primaryMimeTypes)
3146
- {
3147
- $this->primaryMimeTypes = $primaryMimeTypes;
3148
- }
3149
-
3150
- public function getPrimaryMimeTypes()
3151
- {
3152
- return $this->primaryMimeTypes;
3153
- }
3154
-
3155
- public function setProductId($productId)
3156
- {
3157
- $this->productId = $productId;
3158
- }
3159
-
3160
- public function getProductId()
3161
- {
3162
- return $this->productId;
3163
- }
3164
-
3165
- public function setProductUrl($productUrl)
3166
- {
3167
- $this->productUrl = $productUrl;
3168
- }
3169
-
3170
- public function getProductUrl()
3171
- {
3172
- return $this->productUrl;
3173
- }
3174
-
3175
- public function setSecondaryFileExtensions($secondaryFileExtensions)
3176
- {
3177
- $this->secondaryFileExtensions = $secondaryFileExtensions;
3178
- }
3179
-
3180
- public function getSecondaryFileExtensions()
3181
- {
3182
- return $this->secondaryFileExtensions;
3183
- }
3184
-
3185
- public function setSecondaryMimeTypes($secondaryMimeTypes)
3186
- {
3187
- $this->secondaryMimeTypes = $secondaryMimeTypes;
3188
- }
3189
-
3190
- public function getSecondaryMimeTypes()
3191
- {
3192
- return $this->secondaryMimeTypes;
3193
- }
3194
-
3195
- public function setShortDescription($shortDescription)
3196
- {
3197
- $this->shortDescription = $shortDescription;
3198
- }
3199
-
3200
- public function getShortDescription()
3201
- {
3202
- return $this->shortDescription;
3203
- }
3204
-
3205
- public function setSupportsCreate($supportsCreate)
3206
- {
3207
- $this->supportsCreate = $supportsCreate;
3208
- }
3209
-
3210
- public function getSupportsCreate()
3211
- {
3212
- return $this->supportsCreate;
3213
- }
3214
-
3215
- public function setSupportsImport($supportsImport)
3216
- {
3217
- $this->supportsImport = $supportsImport;
3218
- }
3219
-
3220
- public function getSupportsImport()
3221
- {
3222
- return $this->supportsImport;
3223
- }
3224
-
3225
- public function setSupportsMultiOpen($supportsMultiOpen)
3226
- {
3227
- $this->supportsMultiOpen = $supportsMultiOpen;
3228
- }
3229
-
3230
- public function getSupportsMultiOpen()
3231
- {
3232
- return $this->supportsMultiOpen;
3233
- }
3234
-
3235
- public function setUseByDefault($useByDefault)
3236
- {
3237
- $this->useByDefault = $useByDefault;
3238
- }
3239
-
3240
- public function getUseByDefault()
3241
- {
3242
- return $this->useByDefault;
3243
- }
3244
- }
3245
-
3246
- class Google_Service_Drive_AppIcons extends Google_ApiModel
3247
- {
3248
- public $category;
3249
- public $iconUrl;
3250
- public $size;
3251
-
3252
- public function setCategory($category)
3253
- {
3254
- $this->category = $category;
3255
- }
3256
-
3257
- public function getCategory()
3258
- {
3259
- return $this->category;
3260
- }
3261
-
3262
- public function setIconUrl($iconUrl)
3263
- {
3264
- $this->iconUrl = $iconUrl;
3265
- }
3266
-
3267
- public function getIconUrl()
3268
- {
3269
- return $this->iconUrl;
3270
- }
3271
-
3272
- public function setSize($size)
3273
- {
3274
- $this->size = $size;
3275
- }
3276
-
3277
- public function getSize()
3278
- {
3279
- return $this->size;
3280
- }
3281
- }
3282
-
3283
- class Google_Service_Drive_AppList extends Google_Collection
3284
- {
3285
- public $etag;
3286
- protected $itemsType = 'Google_Service_Drive_App';
3287
- protected $itemsDataType = 'array';
3288
- public $kind;
3289
- public $selfLink;
3290
-
3291
- public function setEtag($etag)
3292
- {
3293
- $this->etag = $etag;
3294
- }
3295
-
3296
- public function getEtag()
3297
- {
3298
- return $this->etag;
3299
- }
3300
-
3301
- public function setItems($items)
3302
- {
3303
- $this->items = $items;
3304
- }
3305
-
3306
- public function getItems()
3307
- {
3308
- return $this->items;
3309
- }
3310
-
3311
- public function setKind($kind)
3312
- {
3313
- $this->kind = $kind;
3314
- }
3315
-
3316
- public function getKind()
3317
- {
3318
- return $this->kind;
3319
- }
3320
-
3321
- public function setSelfLink($selfLink)
3322
- {
3323
- $this->selfLink = $selfLink;
3324
- }
3325
-
3326
- public function getSelfLink()
3327
- {
3328
- return $this->selfLink;
3329
- }
3330
- }
3331
-
3332
- class Google_Service_Drive_Change extends Google_ApiModel
3333
- {
3334
- public $deleted;
3335
- protected $fileType = 'Google_Service_Drive_DriveFile';
3336
- protected $fileDataType = '';
3337
- public $fileId;
3338
- public $id;
3339
- public $kind;
3340
- public $modificationDate;
3341
- public $selfLink;
3342
-
3343
- public function setDeleted($deleted)
3344
- {
3345
- $this->deleted = $deleted;
3346
- }
3347
-
3348
- public function getDeleted()
3349
- {
3350
- return $this->deleted;
3351
- }
3352
-
3353
- public function setFile(Google_Service_Drive_DriveFile $file)
3354
- {
3355
- $this->file = $file;
3356
- }
3357
-
3358
- public function getFile()
3359
- {
3360
- return $this->file;
3361
- }
3362
-
3363
- public function setFileId($fileId)
3364
- {
3365
- $this->fileId = $fileId;
3366
- }
3367
-
3368
- public function getFileId()
3369
- {
3370
- return $this->fileId;
3371
- }
3372
-
3373
- public function setId($id)
3374
- {
3375
- $this->id = $id;
3376
- }
3377
-
3378
- public function getId()
3379
- {
3380
- return $this->id;
3381
- }
3382
-
3383
- public function setKind($kind)
3384
- {
3385
- $this->kind = $kind;
3386
- }
3387
-
3388
- public function getKind()
3389
- {
3390
- return $this->kind;
3391
- }
3392
-
3393
- public function setModificationDate($modificationDate)
3394
- {
3395
- $this->modificationDate = $modificationDate;
3396
- }
3397
-
3398
- public function getModificationDate()
3399
- {
3400
- return $this->modificationDate;
3401
- }
3402
-
3403
- public function setSelfLink($selfLink)
3404
- {
3405
- $this->selfLink = $selfLink;
3406
- }
3407
-
3408
- public function getSelfLink()
3409
- {
3410
- return $this->selfLink;
3411
- }
3412
- }
3413
-
3414
- class Google_Service_Drive_ChangeList extends Google_Collection
3415
- {
3416
- public $etag;
3417
- protected $itemsType = 'Google_Service_Drive_Change';
3418
- protected $itemsDataType = 'array';
3419
- public $kind;
3420
- public $largestChangeId;
3421
- public $nextLink;
3422
- public $nextPageToken;
3423
- public $selfLink;
3424
-
3425
- public function setEtag($etag)
3426
- {
3427
- $this->etag = $etag;
3428
- }
3429
-
3430
- public function getEtag()
3431
- {
3432
- return $this->etag;
3433
- }
3434
-
3435
- public function setItems($items)
3436
- {
3437
- $this->items = $items;
3438
- }
3439
-
3440
- public function getItems()
3441
- {
3442
- return $this->items;
3443
- }
3444
-
3445
- public function setKind($kind)
3446
- {
3447
- $this->kind = $kind;
3448
- }
3449
-
3450
- public function getKind()
3451
- {
3452
- return $this->kind;
3453
- }
3454
-
3455
- public function setLargestChangeId($largestChangeId)
3456
- {
3457
- $this->largestChangeId = $largestChangeId;
3458
- }
3459
-
3460
- public function getLargestChangeId()
3461
- {
3462
- return $this->largestChangeId;
3463
- }
3464
-
3465
- public function setNextLink($nextLink)
3466
- {
3467
- $this->nextLink = $nextLink;
3468
- }
3469
-
3470
- public function getNextLink()
3471
- {
3472
- return $this->nextLink;
3473
- }
3474
-
3475
- public function setNextPageToken($nextPageToken)
3476
- {
3477
- $this->nextPageToken = $nextPageToken;
3478
- }
3479
-
3480
- public function getNextPageToken()
3481
- {
3482
- return $this->nextPageToken;
3483
- }
3484
-
3485
- public function setSelfLink($selfLink)
3486
- {
3487
- $this->selfLink = $selfLink;
3488
- }
3489
-
3490
- public function getSelfLink()
3491
- {
3492
- return $this->selfLink;
3493
- }
3494
- }
3495
-
3496
- class Google_Service_Drive_Channel extends Google_ApiModel
3497
- {
3498
- public $address;
3499
- public $expiration;
3500
- public $id;
3501
- public $kind;
3502
- public $params;
3503
- public $payload;
3504
- public $resourceId;
3505
- public $resourceUri;
3506
- public $token;
3507
- public $type;
3508
-
3509
- public function setAddress($address)
3510
- {
3511
- $this->address = $address;
3512
- }
3513
-
3514
- public function getAddress()
3515
- {
3516
- return $this->address;
3517
- }
3518
-
3519
- public function setExpiration($expiration)
3520
- {
3521
- $this->expiration = $expiration;
3522
- }
3523
-
3524
- public function getExpiration()
3525
- {
3526
- return $this->expiration;
3527
- }
3528
-
3529
- public function setId($id)
3530
- {
3531
- $this->id = $id;
3532
- }
3533
-
3534
- public function getId()
3535
- {
3536
- return $this->id;
3537
- }
3538
-
3539
- public function setKind($kind)
3540
- {
3541
- $this->kind = $kind;
3542
- }
3543
-
3544
- public function getKind()
3545
- {
3546
- return $this->kind;
3547
- }
3548
-
3549
- public function setParams($params)
3550
- {
3551
- $this->params = $params;
3552
- }
3553
-
3554
- public function getParams()
3555
- {
3556
- return $this->params;
3557
- }
3558
-
3559
- public function setPayload($payload)
3560
- {
3561
- $this->payload = $payload;
3562
- }
3563
-
3564
- public function getPayload()
3565
- {
3566
- return $this->payload;
3567
- }
3568
-
3569
- public function setResourceId($resourceId)
3570
- {
3571
- $this->resourceId = $resourceId;
3572
- }
3573
-
3574
- public function getResourceId()
3575
- {
3576
- return $this->resourceId;
3577
- }
3578
-
3579
- public function setResourceUri($resourceUri)
3580
- {
3581
- $this->resourceUri = $resourceUri;
3582
- }
3583
-
3584
- public function getResourceUri()
3585
- {
3586
- return $this->resourceUri;
3587
- }
3588
-
3589
- public function setToken($token)
3590
- {
3591
- $this->token = $token;
3592
- }
3593
-
3594
- public function getToken()
3595
- {
3596
- return $this->token;
3597
- }
3598
-
3599
- public function setType($type)
3600
- {
3601
- $this->type = $type;
3602
- }
3603
-
3604
- public function getType()
3605
- {
3606
- return $this->type;
3607
- }
3608
- }
3609
-
3610
- class Google_Service_Drive_ChildList extends Google_Collection
3611
- {
3612
- public $etag;
3613
- protected $itemsType = 'Google_Service_Drive_ChildReference';
3614
- protected $itemsDataType = 'array';
3615
- public $kind;
3616
- public $nextLink;
3617
- public $nextPageToken;
3618
- public $selfLink;
3619
-
3620
- public function setEtag($etag)
3621
- {
3622
- $this->etag = $etag;
3623
- }
3624
-
3625
- public function getEtag()
3626
- {
3627
- return $this->etag;
3628
- }
3629
-
3630
- public function setItems($items)
3631
- {
3632
- $this->items = $items;
3633
- }
3634
-
3635
- public function getItems()
3636
- {
3637
- return $this->items;
3638
- }
3639
-
3640
- public function setKind($kind)
3641
- {
3642
- $this->kind = $kind;
3643
- }
3644
-
3645
- public function getKind()
3646
- {
3647
- return $this->kind;
3648
- }
3649
-
3650
- public function setNextLink($nextLink)
3651
- {
3652
- $this->nextLink = $nextLink;
3653
- }
3654
-
3655
- public function getNextLink()
3656
- {
3657
- return $this->nextLink;
3658
- }
3659
-
3660
- public function setNextPageToken($nextPageToken)
3661
- {
3662
- $this->nextPageToken = $nextPageToken;
3663
- }
3664
-
3665
- public function getNextPageToken()
3666
- {
3667
- return $this->nextPageToken;
3668
- }
3669
-
3670
- public function setSelfLink($selfLink)
3671
- {
3672
- $this->selfLink = $selfLink;
3673
- }
3674
-
3675
- public function getSelfLink()
3676
- {
3677
- return $this->selfLink;
3678
- }
3679
- }
3680
-
3681
- class Google_Service_Drive_ChildReference extends Google_ApiModel
3682
- {
3683
- public $childLink;
3684
- public $id;
3685
- public $kind;
3686
- public $selfLink;
3687
-
3688
- public function setChildLink($childLink)
3689
- {
3690
- $this->childLink = $childLink;
3691
- }
3692
-
3693
- public function getChildLink()
3694
- {
3695
- return $this->childLink;
3696
- }
3697
-
3698
- public function setId($id)
3699
- {
3700
- $this->id = $id;
3701
- }
3702
-
3703
- public function getId()
3704
- {
3705
- return $this->id;
3706
- }
3707
-
3708
- public function setKind($kind)
3709
- {
3710
- $this->kind = $kind;
3711
- }
3712
-
3713
- public function getKind()
3714
- {
3715
- return $this->kind;
3716
- }
3717
-
3718
- public function setSelfLink($selfLink)
3719
- {
3720
- $this->selfLink = $selfLink;
3721
- }
3722
-
3723
- public function getSelfLink()
3724
- {
3725
- return $this->selfLink;
3726
- }
3727
- }
3728
-
3729
- class Google_Service_Drive_Comment extends Google_Collection
3730
- {
3731
- public $anchor;
3732
- protected $authorType = 'Google_Service_Drive_User';
3733
- protected $authorDataType = '';
3734
- public $commentId;
3735
- public $content;
3736
- protected $contextType = 'Google_Service_Drive_CommentContext';
3737
- protected $contextDataType = '';
3738
- public $createdDate;
3739
- public $deleted;
3740
- public $fileId;
3741
- public $fileTitle;
3742
- public $htmlContent;
3743
- public $kind;
3744
- public $modifiedDate;
3745
- protected $repliesType = 'Google_Service_Drive_CommentReply';
3746
- protected $repliesDataType = 'array';
3747
- public $selfLink;
3748
- public $status;
3749
-
3750
- public function setAnchor($anchor)
3751
- {
3752
- $this->anchor = $anchor;
3753
- }
3754
-
3755
- public function getAnchor()
3756
- {
3757
- return $this->anchor;
3758
- }
3759
-
3760
- public function setAuthor(Google_Service_Drive_User $author)
3761
- {
3762
- $this->author = $author;
3763
- }
3764
-
3765
- public function getAuthor()
3766
- {
3767
- return $this->author;
3768
- }
3769
-
3770
- public function setCommentId($commentId)
3771
- {
3772
- $this->commentId = $commentId;
3773
- }
3774
-
3775
- public function getCommentId()
3776
- {
3777
- return $this->commentId;
3778
- }
3779
-
3780
- public function setContent($content)
3781
- {
3782
- $this->content = $content;
3783
- }
3784
-
3785
- public function getContent()
3786
- {
3787
- return $this->content;
3788
- }
3789
-
3790
- public function setContext(Google_Service_Drive_CommentContext $context)
3791
- {
3792
- $this->context = $context;
3793
- }
3794
-
3795
- public function getContext()
3796
- {
3797
- return $this->context;
3798
- }
3799
-
3800
- public function setCreatedDate($createdDate)
3801
- {
3802
- $this->createdDate = $createdDate;
3803
- }
3804
-
3805
- public function getCreatedDate()
3806
- {
3807
- return $this->createdDate;
3808
- }
3809
-
3810
- public function setDeleted($deleted)
3811
- {
3812
- $this->deleted = $deleted;
3813
- }
3814
-
3815
- public function getDeleted()
3816
- {
3817
- return $this->deleted;
3818
- }
3819
-
3820
- public function setFileId($fileId)
3821
- {
3822
- $this->fileId = $fileId;
3823
- }
3824
-
3825
- public function getFileId()
3826
- {
3827
- return $this->fileId;
3828
- }
3829
-
3830
- public function setFileTitle($fileTitle)
3831
- {
3832
- $this->fileTitle = $fileTitle;
3833
- }
3834
-
3835
- public function getFileTitle()
3836
- {
3837
- return $this->fileTitle;
3838
- }
3839
-
3840
- public function setHtmlContent($htmlContent)
3841
- {
3842
- $this->htmlContent = $htmlContent;
3843
- }
3844
-
3845
- public function getHtmlContent()
3846
- {
3847
- return $this->htmlContent;
3848
- }
3849
-
3850
- public function setKind($kind)
3851
- {
3852
- $this->kind = $kind;
3853
- }
3854
-
3855
- public function getKind()
3856
- {
3857
- return $this->kind;
3858
- }
3859
-
3860
- public function setModifiedDate($modifiedDate)
3861
- {
3862
- $this->modifiedDate = $modifiedDate;
3863
- }
3864
-
3865
- public function getModifiedDate()
3866
- {
3867
- return $this->modifiedDate;
3868
- }
3869
-
3870
- public function setReplies($replies)
3871
- {
3872
- $this->replies = $replies;
3873
- }
3874
-
3875
- public function getReplies()
3876
- {
3877
- return $this->replies;
3878
- }
3879
-
3880
- public function setSelfLink($selfLink)
3881
- {
3882
- $this->selfLink = $selfLink;
3883
- }
3884
-
3885
- public function getSelfLink()
3886
- {
3887
- return $this->selfLink;
3888
- }
3889
-
3890
- public function setStatus($status)
3891
- {
3892
- $this->status = $status;
3893
- }
3894
-
3895
- public function getStatus()
3896
- {
3897
- return $this->status;
3898
- }
3899
- }
3900
-
3901
- class Google_Service_Drive_CommentContext extends Google_ApiModel
3902
- {
3903
- public $type;
3904
- public $value;
3905
-
3906
- public function setType($type)
3907
- {
3908
- $this->type = $type;
3909
- }
3910
-
3911
- public function getType()
3912
- {
3913
- return $this->type;
3914
- }
3915
-
3916
- public function setValue($value)
3917
- {
3918
- $this->value = $value;
3919
- }
3920
-
3921
- public function getValue()
3922
- {
3923
- return $this->value;
3924
- }
3925
- }
3926
-
3927
- class Google_Service_Drive_CommentList extends Google_Collection
3928
- {
3929
- protected $itemsType = 'Google_Service_Drive_Comment';
3930
- protected $itemsDataType = 'array';
3931
- public $kind;
3932
- public $nextLink;
3933
- public $nextPageToken;
3934
- public $selfLink;
3935
-
3936
- public function setItems($items)
3937
- {
3938
- $this->items = $items;
3939
- }
3940
-
3941
- public function getItems()
3942
- {
3943
- return $this->items;
3944
- }
3945
-
3946
- public function setKind($kind)
3947
- {
3948
- $this->kind = $kind;
3949
- }
3950
-
3951
- public function getKind()
3952
- {
3953
- return $this->kind;
3954
- }
3955
-
3956
- public function setNextLink($nextLink)
3957
- {
3958
- $this->nextLink = $nextLink;
3959
- }
3960
-
3961
- public function getNextLink()
3962
- {
3963
- return $this->nextLink;
3964
- }
3965
-
3966
- public function setNextPageToken($nextPageToken)
3967
- {
3968
- $this->nextPageToken = $nextPageToken;
3969
- }
3970
-
3971
- public function getNextPageToken()
3972
- {
3973
- return $this->nextPageToken;
3974
- }
3975
-
3976
- public function setSelfLink($selfLink)
3977
- {
3978
- $this->selfLink = $selfLink;
3979
- }
3980
-
3981
- public function getSelfLink()
3982
- {
3983
- return $this->selfLink;
3984
- }
3985
- }
3986
-
3987
- class Google_Service_Drive_CommentReply extends Google_ApiModel
3988
- {
3989
- protected $authorType = 'Google_Service_Drive_User';
3990
- protected $authorDataType = '';
3991
- public $content;
3992
- public $createdDate;
3993
- public $deleted;
3994
- public $htmlContent;
3995
- public $kind;
3996
- public $modifiedDate;
3997
- public $replyId;
3998
- public $verb;
3999
-
4000
- public function setAuthor(Google_Service_Drive_User $author)
4001
- {
4002
- $this->author = $author;
4003
- }
4004
-
4005
- public function getAuthor()
4006
- {
4007
- return $this->author;
4008
- }
4009
-
4010
- public function setContent($content)
4011
- {
4012
- $this->content = $content;
4013
- }
4014
-
4015
- public function getContent()
4016
- {
4017
- return $this->content;
4018
- }
4019
-
4020
- public function setCreatedDate($createdDate)
4021
- {
4022
- $this->createdDate = $createdDate;
4023
- }
4024
-
4025
- public function getCreatedDate()
4026
- {
4027
- return $this->createdDate;
4028
- }
4029
-
4030
- public function setDeleted($deleted)
4031
- {
4032
- $this->deleted = $deleted;
4033
- }
4034
-
4035
- public function getDeleted()
4036
- {
4037
- return $this->deleted;
4038
- }
4039
-
4040
- public function setHtmlContent($htmlContent)
4041
- {
4042
- $this->htmlContent = $htmlContent;
4043
- }
4044
-
4045
- public function getHtmlContent()
4046
- {
4047
- return $this->htmlContent;
4048
- }
4049
-
4050
- public function setKind($kind)
4051
- {
4052
- $this->kind = $kind;
4053
- }
4054
-
4055
- public function getKind()
4056
- {
4057
- return $this->kind;
4058
- }
4059
-
4060
- public function setModifiedDate($modifiedDate)
4061
- {
4062
- $this->modifiedDate = $modifiedDate;
4063
- }
4064
-
4065
- public function getModifiedDate()
4066
- {
4067
- return $this->modifiedDate;
4068
- }
4069
-
4070
- public function setReplyId($replyId)
4071
- {
4072
- $this->replyId = $replyId;
4073
- }
4074
-
4075
- public function getReplyId()
4076
- {
4077
- return $this->replyId;
4078
- }
4079
-
4080
- public function setVerb($verb)
4081
- {
4082
- $this->verb = $verb;
4083
- }
4084
-
4085
- public function getVerb()
4086
- {
4087
- return $this->verb;
4088
- }
4089
- }
4090
-
4091
- class Google_Service_Drive_CommentReplyList extends Google_Collection
4092
- {
4093
- protected $itemsType = 'Google_Service_Drive_CommentReply';
4094
- protected $itemsDataType = 'array';
4095
- public $kind;
4096
- public $nextLink;
4097
- public $nextPageToken;
4098
- public $selfLink;
4099
-
4100
- public function setItems($items)
4101
- {
4102
- $this->items = $items;
4103
- }
4104
-
4105
- public function getItems()
4106
- {
4107
- return $this->items;
4108
- }
4109
-
4110
- public function setKind($kind)
4111
- {
4112
- $this->kind = $kind;
4113
- }
4114
-
4115
- public function getKind()
4116
- {
4117
- return $this->kind;
4118
- }
4119
-
4120
- public function setNextLink($nextLink)
4121
- {
4122
- $this->nextLink = $nextLink;
4123
- }
4124
-
4125
- public function getNextLink()
4126
- {
4127
- return $this->nextLink;
4128
- }
4129
-
4130
- public function setNextPageToken($nextPageToken)
4131
- {
4132
- $this->nextPageToken = $nextPageToken;
4133
- }
4134
-
4135
- public function getNextPageToken()
4136
- {
4137
- return $this->nextPageToken;
4138
- }
4139
-
4140
- public function setSelfLink($selfLink)
4141
- {
4142
- $this->selfLink = $selfLink;
4143
- }
4144
-
4145
- public function getSelfLink()
4146
- {
4147
- return $this->selfLink;
4148
- }
4149
- }
4150
-
4151
- class Google_Service_Drive_DriveFile extends Google_Collection
4152
- {
4153
- public $alternateLink;
4154
- public $appDataContents;
4155
- public $copyable;
4156
- public $createdDate;
4157
- public $defaultOpenWithLink;
4158
- public $description;
4159
- public $downloadUrl;
4160
- public $editable;
4161
- public $embedLink;
4162
- public $etag;
4163
- public $explicitlyTrashed;
4164
- public $exportLinks;
4165
- public $fileExtension;
4166
- public $fileSize;
4167
- public $headRevisionId;
4168
- public $iconLink;
4169
- public $id;
4170
- protected $imageMediaMetadataType = 'Google_Service_Drive_DriveFileImageMediaMetadata';
4171
- protected $imageMediaMetadataDataType = '';
4172
- protected $indexableTextType = 'Google_Service_Drive_DriveFileIndexableText';
4173
- protected $indexableTextDataType = '';
4174
- public $kind;
4175
- protected $labelsType = 'Google_Service_Drive_DriveFileLabels';
4176
- protected $labelsDataType = '';
4177
- protected $lastModifyingUserType = 'Google_Service_Drive_User';
4178
- protected $lastModifyingUserDataType = '';
4179
- public $lastModifyingUserName;
4180
- public $lastViewedByMeDate;
4181
- public $md5Checksum;
4182
- public $mimeType;
4183
- public $modifiedByMeDate;
4184
- public $modifiedDate;
4185
- public $openWithLinks;
4186
- public $originalFilename;
4187
- public $ownerNames;
4188
- protected $ownersType = 'Google_Service_Drive_User';
4189
- protected $ownersDataType = 'array';
4190
- protected $parentsType = 'Google_Service_Drive_ParentReference';
4191
- protected $parentsDataType = 'array';
4192
- protected $propertiesType = 'Google_Service_Drive_Property';
4193
- protected $propertiesDataType = 'array';
4194
- public $quotaBytesUsed;
4195
- public $selfLink;
4196
- public $shared;
4197
- public $sharedWithMeDate;
4198
- protected $thumbnailType = 'Google_Service_Drive_DriveFileThumbnail';
4199
- protected $thumbnailDataType = '';
4200
- public $thumbnailLink;
4201
- public $title;
4202
- protected $userPermissionType = 'Google_Service_Drive_Permission';
4203
- protected $userPermissionDataType = '';
4204
- public $webContentLink;
4205
- public $webViewLink;
4206
- public $writersCanShare;
4207
-
4208
- public function setAlternateLink($alternateLink)
4209
- {
4210
- $this->alternateLink = $alternateLink;
4211
- }
4212
-
4213
- public function getAlternateLink()
4214
- {
4215
- return $this->alternateLink;
4216
- }
4217
-
4218
- public function setAppDataContents($appDataContents)
4219
- {
4220
- $this->appDataContents = $appDataContents;
4221
- }
4222
-
4223
- public function getAppDataContents()
4224
- {
4225
- return $this->appDataContents;
4226
- }
4227
-
4228
- public function setCopyable($copyable)
4229
- {
4230
- $this->copyable = $copyable;
4231
- }
4232
-
4233
- public function getCopyable()
4234
- {
4235
- return $this->copyable;
4236
- }
4237
-
4238
- public function setCreatedDate($createdDate)
4239
- {
4240
- $this->createdDate = $createdDate;
4241
- }
4242
-
4243
- public function getCreatedDate()
4244
- {
4245
- return $this->createdDate;
4246
- }
4247
-
4248
- public function setDefaultOpenWithLink($defaultOpenWithLink)
4249
- {
4250
- $this->defaultOpenWithLink = $defaultOpenWithLink;
4251
- }
4252
-
4253
- public function getDefaultOpenWithLink()
4254
- {
4255
- return $this->defaultOpenWithLink;
4256
- }
4257
-
4258
- public function setDescription($description)
4259
- {
4260
- $this->description = $description;
4261
- }
4262
-
4263
- public function getDescription()
4264
- {
4265
- return $this->description;
4266
- }
4267
-
4268
- public function setDownloadUrl($downloadUrl)
4269
- {
4270
- $this->downloadUrl = $downloadUrl;
4271
- }
4272
-
4273
- public function getDownloadUrl()
4274
- {
4275
- return $this->downloadUrl;
4276
- }
4277
-
4278
- public function setEditable($editable)
4279
- {
4280
- $this->editable = $editable;
4281
- }
4282
-
4283
- public function getEditable()
4284
- {
4285
- return $this->editable;
4286
- }
4287
-
4288
- public function setEmbedLink($embedLink)
4289
- {
4290
- $this->embedLink = $embedLink;
4291
- }
4292
-
4293
- public function getEmbedLink()
4294
- {
4295
- return $this->embedLink;
4296
- }
4297
-
4298
- public function setEtag($etag)
4299
- {
4300
- $this->etag = $etag;
4301
- }
4302
-
4303
- public function getEtag()
4304
- {
4305
- return $this->etag;
4306
- }
4307
-
4308
- public function setExplicitlyTrashed($explicitlyTrashed)
4309
- {
4310
- $this->explicitlyTrashed = $explicitlyTrashed;
4311
- }
4312
-
4313
- public function getExplicitlyTrashed()
4314
- {
4315
- return $this->explicitlyTrashed;
4316
- }
4317
-
4318
- public function setExportLinks($exportLinks)
4319
- {
4320
- $this->exportLinks = $exportLinks;
4321
- }
4322
-
4323
- public function getExportLinks()
4324
- {
4325
- return $this->exportLinks;
4326
- }
4327
-
4328
- public function setFileExtension($fileExtension)
4329
- {
4330
- $this->fileExtension = $fileExtension;
4331
- }
4332
-
4333
- public function getFileExtension()
4334
- {
4335
- return $this->fileExtension;
4336
- }
4337
-
4338
- public function setFileSize($fileSize)
4339
- {
4340
- $this->fileSize = $fileSize;
4341
- }
4342
-
4343
- public function getFileSize()
4344
- {
4345
- return $this->fileSize;
4346
- }
4347
-
4348
- public function setHeadRevisionId($headRevisionId)
4349
- {
4350
- $this->headRevisionId = $headRevisionId;
4351
- }
4352
-
4353
- public function getHeadRevisionId()
4354
- {
4355
- return $this->headRevisionId;
4356
- }
4357
-
4358
- public function setIconLink($iconLink)
4359
- {
4360
- $this->iconLink = $iconLink;
4361
- }
4362
-
4363
- public function getIconLink()
4364
- {
4365
- return $this->iconLink;
4366
- }
4367
-
4368
- public function setId($id)
4369
- {
4370
- $this->id = $id;
4371
- }
4372
-
4373
- public function getId()
4374
- {
4375
- return $this->id;
4376
- }
4377
-
4378
- public function setImageMediaMetadata(Google_Service_Drive_DriveFileImageMediaMetadata $imageMediaMetadata)
4379
- {
4380
- $this->imageMediaMetadata = $imageMediaMetadata;
4381
- }
4382
-
4383
- public function getImageMediaMetadata()
4384
- {
4385
- return $this->imageMediaMetadata;
4386
- }
4387
-
4388
- public function setIndexableText(Google_Service_Drive_DriveFileIndexableText $indexableText)
4389
- {
4390
- $this->indexableText = $indexableText;
4391
- }
4392
-
4393
- public function getIndexableText()
4394
- {
4395
- return $this->indexableText;
4396
- }
4397
-
4398
- public function setKind($kind)
4399
- {
4400
- $this->kind = $kind;
4401
- }
4402
-
4403
- public function getKind()
4404
- {
4405
- return $this->kind;
4406
- }
4407
-
4408
- public function setLabels(Google_Service_Drive_DriveFileLabels $labels)
4409
- {
4410
- $this->labels = $labels;
4411
- }
4412
-
4413
- public function getLabels()
4414
- {
4415
- return $this->labels;
4416
- }
4417
-
4418
- public function setLastModifyingUser(Google_Service_Drive_User $lastModifyingUser)
4419
- {
4420
- $this->lastModifyingUser = $lastModifyingUser;
4421
- }
4422
-
4423
- public function getLastModifyingUser()
4424
- {
4425
- return $this->lastModifyingUser;
4426
- }
4427
-
4428
- public function setLastModifyingUserName($lastModifyingUserName)
4429
- {
4430
- $this->lastModifyingUserName = $lastModifyingUserName;
4431
- }
4432
-
4433
- public function getLastModifyingUserName()
4434
- {
4435
- return $this->lastModifyingUserName;
4436
- }
4437
-
4438
- public function setLastViewedByMeDate($lastViewedByMeDate)
4439
- {
4440
- $this->lastViewedByMeDate = $lastViewedByMeDate;
4441
- }
4442
-
4443
- public function getLastViewedByMeDate()
4444
- {
4445
- return $this->lastViewedByMeDate;
4446
- }
4447
-
4448
- public function setMd5Checksum($md5Checksum)
4449
- {
4450
- $this->md5Checksum = $md5Checksum;
4451
- }
4452
-
4453
- public function getMd5Checksum()
4454
- {
4455
- return $this->md5Checksum;
4456
- }
4457
-
4458
- public function setMimeType($mimeType)
4459
- {
4460
- $this->mimeType = $mimeType;
4461
- }
4462
-
4463
- public function getMimeType()
4464
- {
4465
- return $this->mimeType;
4466
- }
4467
-
4468
- public function setModifiedByMeDate($modifiedByMeDate)
4469
- {
4470
- $this->modifiedByMeDate = $modifiedByMeDate;
4471
- }
4472
-
4473
- public function getModifiedByMeDate()
4474
- {
4475
- return $this->modifiedByMeDate;
4476
- }
4477
-
4478
- public function setModifiedDate($modifiedDate)
4479
- {
4480
- $this->modifiedDate = $modifiedDate;
4481
- }
4482
-
4483
- public function getModifiedDate()
4484
- {
4485
- return $this->modifiedDate;
4486
- }
4487
-
4488
- public function setOpenWithLinks($openWithLinks)
4489
- {
4490
- $this->openWithLinks = $openWithLinks;
4491
- }
4492
-
4493
- public function getOpenWithLinks()
4494
- {
4495
- return $this->openWithLinks;
4496
- }
4497
-
4498
- public function setOriginalFilename($originalFilename)
4499
- {
4500
- $this->originalFilename = $originalFilename;
4501
- }
4502
-
4503
- public function getOriginalFilename()
4504
- {
4505
- return $this->originalFilename;
4506
- }
4507
-
4508
- public function setOwnerNames($ownerNames)
4509
- {
4510
- $this->ownerNames = $ownerNames;
4511
- }
4512
-
4513
- public function getOwnerNames()
4514
- {
4515
- return $this->ownerNames;
4516
- }
4517
-
4518
- public function setOwners($owners)
4519
- {
4520
- $this->owners = $owners;
4521
- }
4522
-
4523
- public function getOwners()
4524
- {
4525
- return $this->owners;
4526
- }
4527
-
4528
- public function setParents($parents)
4529
- {
4530
- $this->parents = $parents;
4531
- }
4532
-
4533
- public function getParents()
4534
- {
4535
- return $this->parents;
4536
- }
4537
-
4538
- public function setProperties($properties)
4539
- {
4540
- $this->properties = $properties;
4541
- }
4542
-
4543
- public function getProperties()
4544
- {
4545
- return $this->properties;
4546
- }
4547
-
4548
- public function setQuotaBytesUsed($quotaBytesUsed)
4549
- {
4550
- $this->quotaBytesUsed = $quotaBytesUsed;
4551
- }
4552
-
4553
- public function getQuotaBytesUsed()
4554
- {
4555
- return $this->quotaBytesUsed;
4556
- }
4557
-
4558
- public function setSelfLink($selfLink)
4559
- {
4560
- $this->selfLink = $selfLink;
4561
- }
4562
-
4563
- public function getSelfLink()
4564
- {
4565
- return $this->selfLink;
4566
- }
4567
-
4568
- public function setShared($shared)
4569
- {
4570
- $this->shared = $shared;
4571
- }
4572
-
4573
- public function getShared()
4574
- {
4575
- return $this->shared;
4576
- }
4577
-
4578
- public function setSharedWithMeDate($sharedWithMeDate)
4579
- {
4580
- $this->sharedWithMeDate = $sharedWithMeDate;
4581
- }
4582
-
4583
- public function getSharedWithMeDate()
4584
- {
4585
- return $this->sharedWithMeDate;
4586
- }
4587
-
4588
- public function setThumbnail(Google_Service_Drive_DriveFileThumbnail $thumbnail)
4589
- {
4590
- $this->thumbnail = $thumbnail;
4591
- }
4592
-
4593
- public function getThumbnail()
4594
- {
4595
- return $this->thumbnail;
4596
- }
4597
-
4598
- public function setThumbnailLink($thumbnailLink)
4599
- {
4600
- $this->thumbnailLink = $thumbnailLink;
4601
- }
4602
-
4603
- public function getThumbnailLink()
4604
- {
4605
- return $this->thumbnailLink;
4606
- }
4607
-
4608
- public function setTitle($title)
4609
- {
4610
- $this->title = $title;
4611
- }
4612
-
4613
- public function getTitle()
4614
- {
4615
- return $this->title;
4616
- }
4617
-
4618
- public function setUserPermission(Google_Service_Drive_Permission $userPermission)
4619
- {
4620
- $this->userPermission = $userPermission;
4621
- }
4622
-
4623
- public function getUserPermission()
4624
- {
4625
- return $this->userPermission;
4626
- }
4627
-
4628
- public function setWebContentLink($webContentLink)
4629
- {
4630
- $this->webContentLink = $webContentLink;
4631
- }
4632
-
4633
- public function getWebContentLink()
4634
- {
4635
- return $this->webContentLink;
4636
- }
4637
-
4638
- public function setWebViewLink($webViewLink)
4639
- {
4640
- $this->webViewLink = $webViewLink;
4641
- }
4642
-
4643
- public function getWebViewLink()
4644
- {
4645
- return $this->webViewLink;
4646
- }
4647
-
4648
- public function setWritersCanShare($writersCanShare)
4649
- {
4650
- $this->writersCanShare = $writersCanShare;
4651
- }
4652
-
4653
- public function getWritersCanShare()
4654
- {
4655
- return $this->writersCanShare;
4656
- }
4657
- }
4658
-
4659
- class Google_Service_Drive_DriveFileImageMediaMetadata extends Google_ApiModel
4660
- {
4661
- public $aperture;
4662
- public $cameraMake;
4663
- public $cameraModel;
4664
- public $colorSpace;
4665
- public $date;
4666
- public $exposureBias;
4667
- public $exposureMode;
4668
- public $exposureTime;
4669
- public $flashUsed;
4670
- public $focalLength;
4671
- public $height;
4672
- public $isoSpeed;
4673
- public $lens;
4674
- protected $locationType = 'Google_Service_Drive_DriveFileImageMediaMetadataLocation';
4675
- protected $locationDataType = '';
4676
- public $maxApertureValue;
4677
- public $meteringMode;
4678
- public $rotation;
4679
- public $sensor;
4680
- public $subjectDistance;
4681
- public $whiteBalance;
4682
- public $width;
4683
-
4684
- public function setAperture($aperture)
4685
- {
4686
- $this->aperture = $aperture;
4687
- }
4688
-
4689
- public function getAperture()
4690
- {
4691
- return $this->aperture;
4692
- }
4693
-
4694
- public function setCameraMake($cameraMake)
4695
- {
4696
- $this->cameraMake = $cameraMake;
4697
- }
4698
-
4699
- public function getCameraMake()
4700
- {
4701
- return $this->cameraMake;
4702
- }
4703
-
4704
- public function setCameraModel($cameraModel)
4705
- {
4706
- $this->cameraModel = $cameraModel;
4707
- }
4708
-
4709
- public function getCameraModel()
4710
- {
4711
- return $this->cameraModel;
4712
- }
4713
-
4714
- public function setColorSpace($colorSpace)
4715
- {
4716
- $this->colorSpace = $colorSpace;
4717
- }
4718
-
4719
- public function getColorSpace()
4720
- {
4721
- return $this->colorSpace;
4722
- }
4723
-
4724
- public function setDate($date)
4725
- {
4726
- $this->date = $date;
4727
- }
4728
-
4729
- public function getDate()
4730
- {
4731
- return $this->date;
4732
- }
4733
-
4734
- public function setExposureBias($exposureBias)
4735
- {
4736
- $this->exposureBias = $exposureBias;
4737
- }
4738
-
4739
- public function getExposureBias()
4740
- {
4741
- return $this->exposureBias;
4742
- }
4743
-
4744
- public function setExposureMode($exposureMode)
4745
- {
4746
- $this->exposureMode = $exposureMode;
4747
- }
4748
-
4749
- public function getExposureMode()
4750
- {
4751
- return $this->exposureMode;
4752
- }
4753
-
4754
- public function setExposureTime($exposureTime)
4755
- {
4756
- $this->exposureTime = $exposureTime;
4757
- }
4758
-
4759
- public function getExposureTime()
4760
- {
4761
- return $this->exposureTime;
4762
- }
4763
-
4764
- public function setFlashUsed($flashUsed)
4765
- {
4766
- $this->flashUsed = $flashUsed;
4767
- }
4768
-
4769
- public function getFlashUsed()
4770
- {
4771
- return $this->flashUsed;
4772
- }
4773
-
4774
- public function setFocalLength($focalLength)
4775
- {
4776
- $this->focalLength = $focalLength;
4777
- }
4778
-
4779
- public function getFocalLength()
4780
- {
4781
- return $this->focalLength;
4782
- }
4783
-
4784
- public function setHeight($height)
4785
- {
4786
- $this->height = $height;
4787
- }
4788
-
4789
- public function getHeight()
4790
- {
4791
- return $this->height;
4792
- }
4793
-
4794
- public function setIsoSpeed($isoSpeed)
4795
- {
4796
- $this->isoSpeed = $isoSpeed;
4797
- }
4798
-
4799
- public function getIsoSpeed()
4800
- {
4801
- return $this->isoSpeed;
4802
- }
4803
-
4804
- public function setLens($lens)
4805
- {
4806
- $this->lens = $lens;
4807
- }
4808
-
4809
- public function getLens()
4810
- {
4811
- return $this->lens;
4812
- }
4813
-
4814
- public function setLocation(Google_Service_Drive_DriveFileImageMediaMetadataLocation $location)
4815
- {
4816
- $this->location = $location;
4817
- }
4818
-
4819
- public function getLocation()
4820
- {
4821
- return $this->location;
4822
- }
4823
-
4824
- public function setMaxApertureValue($maxApertureValue)
4825
- {
4826
- $this->maxApertureValue = $maxApertureValue;
4827
- }
4828
-
4829
- public function getMaxApertureValue()
4830
- {
4831
- return $this->maxApertureValue;
4832
- }
4833
-
4834
- public function setMeteringMode($meteringMode)
4835
- {
4836
- $this->meteringMode = $meteringMode;
4837
- }
4838
-
4839
- public function getMeteringMode()
4840
- {
4841
- return $this->meteringMode;
4842
- }
4843
-
4844
- public function setRotation($rotation)
4845
- {
4846
- $this->rotation = $rotation;
4847
- }
4848
-
4849
- public function getRotation()
4850
- {
4851
- return $this->rotation;
4852
- }
4853
-
4854
- public function setSensor($sensor)
4855
- {
4856
- $this->sensor = $sensor;
4857
- }
4858
-
4859
- public function getSensor()
4860
- {
4861
- return $this->sensor;
4862
- }
4863
-
4864
- public function setSubjectDistance($subjectDistance)
4865
- {
4866
- $this->subjectDistance = $subjectDistance;
4867
- }
4868
-
4869
- public function getSubjectDistance()
4870
- {
4871
- return $this->subjectDistance;
4872
- }
4873
-
4874
- public function setWhiteBalance($whiteBalance)
4875
- {
4876
- $this->whiteBalance = $whiteBalance;
4877
- }
4878
-
4879
- public function getWhiteBalance()
4880
- {
4881
- return $this->whiteBalance;
4882
- }
4883
-
4884
- public function setWidth($width)
4885
- {
4886
- $this->width = $width;
4887
- }
4888
-
4889
- public function getWidth()
4890
- {
4891
- return $this->width;
4892
- }
4893
- }
4894
-
4895
- class Google_Service_Drive_DriveFileImageMediaMetadataLocation extends Google_ApiModel
4896
- {
4897
- public $altitude;
4898
- public $latitude;
4899
- public $longitude;
4900
-
4901
- public function setAltitude($altitude)
4902
- {
4903
- $this->altitude = $altitude;
4904
- }
4905
-
4906
- public function getAltitude()
4907
- {
4908
- return $this->altitude;
4909
- }
4910
-
4911
- public function setLatitude($latitude)
4912
- {
4913
- $this->latitude = $latitude;
4914
- }
4915
-
4916
- public function getLatitude()
4917
- {
4918
- return $this->latitude;
4919
- }
4920
-
4921
- public function setLongitude($longitude)
4922
- {
4923
- $this->longitude = $longitude;
4924
- }
4925
-
4926
- public function getLongitude()
4927
- {
4928
- return $this->longitude;
4929
- }
4930
- }
4931
-
4932
- class Google_Service_Drive_DriveFileIndexableText extends Google_ApiModel
4933
- {
4934
- public $text;
4935
-
4936
- public function setText($text)
4937
- {
4938
- $this->text = $text;
4939
- }
4940
-
4941
- public function getText()
4942
- {
4943
- return $this->text;
4944
- }
4945
- }
4946
-
4947
- class Google_Service_Drive_DriveFileLabels extends Google_ApiModel
4948
- {
4949
- public $hidden;
4950
- public $restricted;
4951
- public $starred;
4952
- public $trashed;
4953
- public $viewed;
4954
-
4955
- public function setHidden($hidden)
4956
- {
4957
- $this->hidden = $hidden;
4958
- }
4959
-
4960
- public function getHidden()
4961
- {
4962
- return $this->hidden;
4963
- }
4964
-
4965
- public function setRestricted($restricted)
4966
- {
4967
- $this->restricted = $restricted;
4968
- }
4969
-
4970
- public function getRestricted()
4971
- {
4972
- return $this->restricted;
4973
- }
4974
-
4975
- public function setStarred($starred)
4976
- {
4977
- $this->starred = $starred;
4978
- }
4979
-
4980
- public function getStarred()
4981
- {
4982
- return $this->starred;
4983
- }
4984
-
4985
- public function setTrashed($trashed)
4986
- {
4987
- $this->trashed = $trashed;
4988
- }
4989
-
4990
- public function getTrashed()
4991
- {
4992
- return $this->trashed;
4993
- }
4994
-
4995
- public function setViewed($viewed)
4996
- {
4997
- $this->viewed = $viewed;
4998
- }
4999
-
5000
- public function getViewed()
5001
- {
5002
- return $this->viewed;
5003
- }
5004
- }
5005
-
5006
- class Google_Service_Drive_DriveFileThumbnail extends Google_ApiModel
5007
- {
5008
- public $image;
5009
- public $mimeType;
5010
-
5011
- public function setImage($image)
5012
- {
5013
- $this->image = $image;
5014
- }
5015
-
5016
- public function getImage()
5017
- {
5018
- return $this->image;
5019
- }
5020
-
5021
- public function setMimeType($mimeType)
5022
- {
5023
- $this->mimeType = $mimeType;
5024
- }
5025
-
5026
- public function getMimeType()
5027
- {
5028
- return $this->mimeType;
5029
- }
5030
- }
5031
-
5032
- class Google_Service_Drive_FileList extends Google_Collection
5033
- {
5034
- public $etag;
5035
- protected $itemsType = 'Google_Service_Drive_DriveFile';
5036
- protected $itemsDataType = 'array';
5037
- public $kind;
5038
- public $nextLink;
5039
- public $nextPageToken;
5040
- public $selfLink;
5041
-
5042
- public function setEtag($etag)
5043
- {
5044
- $this->etag = $etag;
5045
- }
5046
-
5047
- public function getEtag()
5048
- {
5049
- return $this->etag;
5050
- }
5051
-
5052
- public function setItems($items)
5053
- {
5054
- $this->items = $items;
5055
- }
5056
-
5057
- public function getItems()
5058
- {
5059
- return $this->items;
5060
- }
5061
-
5062
- public function setKind($kind)
5063
- {
5064
- $this->kind = $kind;
5065
- }
5066
-
5067
- public function getKind()
5068
- {
5069
- return $this->kind;
5070
- }
5071
-
5072
- public function setNextLink($nextLink)
5073
- {
5074
- $this->nextLink = $nextLink;
5075
- }
5076
-
5077
- public function getNextLink()
5078
- {
5079
- return $this->nextLink;
5080
- }
5081
-
5082
- public function setNextPageToken($nextPageToken)
5083
- {
5084
- $this->nextPageToken = $nextPageToken;
5085
- }
5086
-
5087
- public function getNextPageToken()
5088
- {
5089
- return $this->nextPageToken;
5090
- }
5091
-
5092
- public function setSelfLink($selfLink)
5093
- {
5094
- $this->selfLink = $selfLink;
5095
- }
5096
-
5097
- public function getSelfLink()
5098
- {
5099
- return $this->selfLink;
5100
- }
5101
- }
5102
-
5103
- class Google_Service_Drive_ParentList extends Google_Collection
5104
- {
5105
- public $etag;
5106
- protected $itemsType = 'Google_Service_Drive_ParentReference';
5107
- protected $itemsDataType = 'array';
5108
- public $kind;
5109
- public $selfLink;
5110
-
5111
- public function setEtag($etag)
5112
- {
5113
- $this->etag = $etag;
5114
- }
5115
-
5116
- public function getEtag()
5117
- {
5118
- return $this->etag;
5119
- }
5120
-
5121
- public function setItems($items)
5122
- {
5123
- $this->items = $items;
5124
- }
5125
-
5126
- public function getItems()
5127
- {
5128
- return $this->items;
5129
- }
5130
-
5131
- public function setKind($kind)
5132
- {
5133
- $this->kind = $kind;
5134
- }
5135
-
5136
- public function getKind()
5137
- {
5138
- return $this->kind;
5139
- }
5140
-
5141
- public function setSelfLink($selfLink)
5142
- {
5143
- $this->selfLink = $selfLink;
5144
- }
5145
-
5146
- public function getSelfLink()
5147
- {
5148
- return $this->selfLink;
5149
- }
5150
- }
5151
-
5152
- class Google_Service_Drive_ParentReference extends Google_ApiModel
5153
- {
5154
- public $id;
5155
- public $isRoot;
5156
- public $kind;
5157
- public $parentLink;
5158
- public $selfLink;
5159
-
5160
- public function setId($id)
5161
- {
5162
- $this->id = $id;
5163
- }
5164
-
5165
- public function getId()
5166
- {
5167
- return $this->id;
5168
- }
5169
-
5170
- public function setIsRoot($isRoot)
5171
- {
5172
- $this->isRoot = $isRoot;
5173
- }
5174
-
5175
- public function getIsRoot()
5176
- {
5177
- return $this->isRoot;
5178
- }
5179
-
5180
- public function setKind($kind)
5181
- {
5182
- $this->kind = $kind;
5183
- }
5184
-
5185
- public function getKind()
5186
- {
5187
- return $this->kind;
5188
- }
5189
-
5190
- public function setParentLink($parentLink)
5191
- {
5192
- $this->parentLink = $parentLink;
5193
- }
5194
-
5195
- public function getParentLink()
5196
- {
5197
- return $this->parentLink;
5198
- }
5199
-
5200
- public function setSelfLink($selfLink)
5201
- {
5202
- $this->selfLink = $selfLink;
5203
- }
5204
-
5205
- public function getSelfLink()
5206
- {
5207
- return $this->selfLink;
5208
- }
5209
- }
5210
-
5211
- class Google_Service_Drive_Permission extends Google_Collection
5212
- {
5213
- public $additionalRoles;
5214
- public $authKey;
5215
- public $domain;
5216
- public $emailAddress;
5217
- public $etag;
5218
- public $id;
5219
- public $kind;
5220
- public $name;
5221
- public $photoLink;
5222
- public $role;
5223
- public $selfLink;
5224
- public $type;
5225
- public $value;
5226
- public $withLink;
5227
-
5228
- public function setAdditionalRoles($additionalRoles)
5229
- {
5230
- $this->additionalRoles = $additionalRoles;
5231
- }
5232
-
5233
- public function getAdditionalRoles()
5234
- {
5235
- return $this->additionalRoles;
5236
- }
5237
-
5238
- public function setAuthKey($authKey)
5239
- {
5240
- $this->authKey = $authKey;
5241
- }
5242
-
5243
- public function getAuthKey()
5244
- {
5245
- return $this->authKey;
5246
- }
5247
-
5248
- public function setDomain($domain)
5249
- {
5250
- $this->domain = $domain;
5251
- }
5252
-
5253
- public function getDomain()
5254
- {
5255
- return $this->domain;
5256
- }
5257
-
5258
- public function setEmailAddress($emailAddress)
5259
- {
5260
- $this->emailAddress = $emailAddress;
5261
- }
5262
-
5263
- public function getEmailAddress()
5264
- {
5265
- return $this->emailAddress;
5266
- }
5267
-
5268
- public function setEtag($etag)
5269
- {
5270
- $this->etag = $etag;
5271
- }
5272
-
5273
- public function getEtag()
5274
- {
5275
- return $this->etag;
5276
- }
5277
-
5278
- public function setId($id)
5279
- {
5280
- $this->id = $id;
5281
- }
5282
-
5283
- public function getId()
5284
- {
5285
- return $this->id;
5286
- }
5287
-
5288
- public function setKind($kind)
5289
- {
5290
- $this->kind = $kind;
5291
- }
5292
-
5293
- public function getKind()
5294
- {
5295
- return $this->kind;
5296
- }
5297
-
5298
- public function setName($name)
5299
- {
5300
- $this->name = $name;
5301
- }
5302
-
5303
- public function getName()
5304
- {
5305
- return $this->name;
5306
- }
5307
-
5308
- public function setPhotoLink($photoLink)
5309
- {
5310
- $this->photoLink = $photoLink;
5311
- }
5312
-
5313
- public function getPhotoLink()
5314
- {
5315
- return $this->photoLink;
5316
- }
5317
-
5318
- public function setRole($role)
5319
- {
5320
- $this->role = $role;
5321
- }
5322
-
5323
- public function getRole()
5324
- {
5325
- return $this->role;
5326
- }
5327
-
5328
- public function setSelfLink($selfLink)
5329
- {
5330
- $this->selfLink = $selfLink;
5331
- }
5332
-
5333
- public function getSelfLink()
5334
- {
5335
- return $this->selfLink;
5336
- }
5337
-
5338
- public function setType($type)
5339
- {
5340
- $this->type = $type;
5341
- }
5342
-
5343
- public function getType()
5344
- {
5345
- return $this->type;
5346
- }
5347
-
5348
- public function setValue($value)
5349
- {
5350
- $this->value = $value;
5351
- }
5352
-
5353
- public function getValue()
5354
- {
5355
- return $this->value;
5356
- }
5357
-
5358
- public function setWithLink($withLink)
5359
- {
5360
- $this->withLink = $withLink;
5361
- }
5362
-
5363
- public function getWithLink()
5364
- {
5365
- return $this->withLink;
5366
- }
5367
- }
5368
-
5369
- class Google_Service_Drive_PermissionId extends Google_ApiModel
5370
- {
5371
- public $id;
5372
- public $kind;
5373
-
5374
- public function setId($id)
5375
- {
5376
- $this->id = $id;
5377
- }
5378
-
5379
- public function getId()
5380
- {
5381
- return $this->id;
5382
- }
5383
-
5384
- public function setKind($kind)
5385
- {
5386
- $this->kind = $kind;
5387
- }
5388
-
5389
- public function getKind()
5390
- {
5391
- return $this->kind;
5392
- }
5393
- }
5394
-
5395
- class Google_Service_Drive_PermissionList extends Google_Collection
5396
- {
5397
- public $etag;
5398
- protected $itemsType = 'Google_Service_Drive_Permission';
5399
- protected $itemsDataType = 'array';
5400
- public $kind;
5401
- public $selfLink;
5402
-
5403
- public function setEtag($etag)
5404
- {
5405
- $this->etag = $etag;
5406
- }
5407
-
5408
- public function getEtag()
5409
- {
5410
- return $this->etag;
5411
- }
5412
-
5413
- public function setItems($items)
5414
- {
5415
- $this->items = $items;
5416
- }
5417
-
5418
- public function getItems()
5419
- {
5420
- return $this->items;
5421
- }
5422
-
5423
- public function setKind($kind)
5424
- {
5425
- $this->kind = $kind;
5426
- }
5427
-
5428
- public function getKind()
5429
- {
5430
- return $this->kind;
5431
- }
5432
-
5433
- public function setSelfLink($selfLink)
5434
- {
5435
- $this->selfLink = $selfLink;
5436
- }
5437
-
5438
- public function getSelfLink()
5439
- {
5440
- return $this->selfLink;
5441
- }
5442
- }
5443
-
5444
- class Google_Service_Drive_Property extends Google_ApiModel
5445
- {
5446
- public $etag;
5447
- public $key;
5448
- public $kind;
5449
- public $selfLink;
5450
- public $value;
5451
- public $visibility;
5452
-
5453
- public function setEtag($etag)
5454
- {
5455
- $this->etag = $etag;
5456
- }
5457
-
5458
- public function getEtag()
5459
- {
5460
- return $this->etag;
5461
- }
5462
-
5463
- public function setKey($key)
5464
- {
5465
- $this->key = $key;
5466
- }
5467
-
5468
- public function getKey()
5469
- {
5470
- return $this->key;
5471
- }
5472
-
5473
- public function setKind($kind)
5474
- {
5475
- $this->kind = $kind;
5476
- }
5477
-
5478
- public function getKind()
5479
- {
5480
- return $this->kind;
5481
- }
5482
-
5483
- public function setSelfLink($selfLink)
5484
- {
5485
- $this->selfLink = $selfLink;
5486
- }
5487
-
5488
- public function getSelfLink()
5489
- {
5490
- return $this->selfLink;
5491
- }
5492
-
5493
- public function setValue($value)
5494
- {
5495
- $this->value = $value;
5496
- }
5497
-
5498
- public function getValue()
5499
- {
5500
- return $this->value;
5501
- }
5502
-
5503
- public function setVisibility($visibility)
5504
- {
5505
- $this->visibility = $visibility;
5506
- }
5507
-
5508
- public function getVisibility()
5509
- {
5510
- return $this->visibility;
5511
- }
5512
- }
5513
-
5514
- class Google_Service_Drive_PropertyList extends Google_Collection
5515
- {
5516
- public $etag;
5517
- protected $itemsType = 'Google_Service_Drive_Property';
5518
- protected $itemsDataType = 'array';
5519
- public $kind;
5520
- public $selfLink;
5521
-
5522
- public function setEtag($etag)
5523
- {
5524
- $this->etag = $etag;
5525
- }
5526
-
5527
- public function getEtag()
5528
- {
5529
- return $this->etag;
5530
- }
5531
-
5532
- public function setItems($items)
5533
- {
5534
- $this->items = $items;
5535
- }
5536
-
5537
- public function getItems()
5538
- {
5539
- return $this->items;
5540
- }
5541
-
5542
- public function setKind($kind)
5543
- {
5544
- $this->kind = $kind;
5545
- }
5546
-
5547
- public function getKind()
5548
- {
5549
- return $this->kind;
5550
- }
5551
-
5552
- public function setSelfLink($selfLink)
5553
- {
5554
- $this->selfLink = $selfLink;
5555
- }
5556
-
5557
- public function getSelfLink()
5558
- {
5559
- return $this->selfLink;
5560
- }
5561
- }
5562
-
5563
- class Google_Service_Drive_Revision extends Google_ApiModel
5564
- {
5565
- public $downloadUrl;
5566
- public $etag;
5567
- public $exportLinks;
5568
- public $fileSize;
5569
- public $id;
5570
- public $kind;
5571
- protected $lastModifyingUserType = 'Google_Service_Drive_User';
5572
- protected $lastModifyingUserDataType = '';
5573
- public $lastModifyingUserName;
5574
- public $md5Checksum;
5575
- public $mimeType;
5576
- public $modifiedDate;
5577
- public $originalFilename;
5578
- public $pinned;
5579
- public $publishAuto;
5580
- public $published;
5581
- public $publishedLink;
5582
- public $publishedOutsideDomain;
5583
- public $selfLink;
5584
-
5585
- public function setDownloadUrl($downloadUrl)
5586
- {
5587
- $this->downloadUrl = $downloadUrl;
5588
- }
5589
-
5590
- public function getDownloadUrl()
5591
- {
5592
- return $this->downloadUrl;
5593
- }
5594
-
5595
- public function setEtag($etag)
5596
- {
5597
- $this->etag = $etag;
5598
- }
5599
-
5600
- public function getEtag()
5601
- {
5602
- return $this->etag;
5603
- }
5604
-
5605
- public function setExportLinks($exportLinks)
5606
- {
5607
- $this->exportLinks = $exportLinks;
5608
- }
5609
-
5610
- public function getExportLinks()
5611
- {
5612
- return $this->exportLinks;
5613
- }
5614
-
5615
- public function setFileSize($fileSize)
5616
- {
5617
- $this->fileSize = $fileSize;
5618
- }
5619
-
5620
- public function getFileSize()
5621
- {
5622
- return $this->fileSize;
5623
- }
5624
-
5625
- public function setId($id)
5626
- {
5627
- $this->id = $id;
5628
- }
5629
-
5630
- public function getId()
5631
- {
5632
- return $this->id;
5633
- }
5634
-
5635
- public function setKind($kind)
5636
- {
5637
- $this->kind = $kind;
5638
- }
5639
-
5640
- public function getKind()
5641
- {
5642
- return $this->kind;
5643
- }
5644
-
5645
- public function setLastModifyingUser(Google_Service_Drive_User $lastModifyingUser)
5646
- {
5647
- $this->lastModifyingUser = $lastModifyingUser;
5648
- }
5649
-
5650
- public function getLastModifyingUser()
5651
- {
5652
- return $this->lastModifyingUser;
5653
- }
5654
-
5655
- public function setLastModifyingUserName($lastModifyingUserName)
5656
- {
5657
- $this->lastModifyingUserName = $lastModifyingUserName;
5658
- }
5659
-
5660
- public function getLastModifyingUserName()
5661
- {
5662
- return $this->lastModifyingUserName;
5663
- }
5664
-
5665
- public function setMd5Checksum($md5Checksum)
5666
- {
5667
- $this->md5Checksum = $md5Checksum;
5668
- }
5669
-
5670
- public function getMd5Checksum()
5671
- {
5672
- return $this->md5Checksum;
5673
- }
5674
-
5675
- public function setMimeType($mimeType)
5676
- {
5677
- $this->mimeType = $mimeType;
5678
- }
5679
-
5680
- public function getMimeType()
5681
- {
5682
- return $this->mimeType;
5683
- }
5684
-
5685
- public function setModifiedDate($modifiedDate)
5686
- {
5687
- $this->modifiedDate = $modifiedDate;
5688
- }
5689
-
5690
- public function getModifiedDate()
5691
- {
5692
- return $this->modifiedDate;
5693
- }
5694
-
5695
- public function setOriginalFilename($originalFilename)
5696
- {
5697
- $this->originalFilename = $originalFilename;
5698
- }
5699
-
5700
- public function getOriginalFilename()
5701
- {
5702
- return $this->originalFilename;
5703
- }
5704
-
5705
- public function setPinned($pinned)
5706
- {
5707
- $this->pinned = $pinned;
5708
- }
5709
-
5710
- public function getPinned()
5711
- {
5712
- return $this->pinned;
5713
- }
5714
-
5715
- public function setPublishAuto($publishAuto)
5716
- {
5717
- $this->publishAuto = $publishAuto;
5718
- }
5719
-
5720
- public function getPublishAuto()
5721
- {
5722
- return $this->publishAuto;
5723
- }
5724
-
5725
- public function setPublished($published)
5726
- {
5727
- $this->published = $published;
5728
- }
5729
-
5730
- public function getPublished()
5731
- {
5732
- return $this->published;
5733
- }
5734
-
5735
- public function setPublishedLink($publishedLink)
5736
- {
5737
- $this->publishedLink = $publishedLink;
5738
- }
5739
-
5740
- public function getPublishedLink()
5741
- {
5742
- return $this->publishedLink;
5743
- }
5744
-
5745
- public function setPublishedOutsideDomain($publishedOutsideDomain)
5746
- {
5747
- $this->publishedOutsideDomain = $publishedOutsideDomain;
5748
- }
5749
-
5750
- public function getPublishedOutsideDomain()
5751
- {
5752
- return $this->publishedOutsideDomain;
5753
- }
5754
-
5755
- public function setSelfLink($selfLink)
5756
- {
5757
- $this->selfLink = $selfLink;
5758
- }
5759
-
5760
- public function getSelfLink()
5761
- {
5762
- return $this->selfLink;
5763
- }
5764
- }
5765
-
5766
- class Google_Service_Drive_RevisionList extends Google_Collection
5767
- {
5768
- public $etag;
5769
- protected $itemsType = 'Google_Service_Drive_Revision';
5770
- protected $itemsDataType = 'array';
5771
- public $kind;
5772
- public $selfLink;
5773
-
5774
- public function setEtag($etag)
5775
- {
5776
- $this->etag = $etag;
5777
- }
5778
-
5779
- public function getEtag()
5780
- {
5781
- return $this->etag;
5782
- }
5783
-
5784
- public function setItems($items)
5785
- {
5786
- $this->items = $items;
5787
- }
5788
-
5789
- public function getItems()
5790
- {
5791
- return $this->items;
5792
- }
5793
-
5794
- public function setKind($kind)
5795
- {
5796
- $this->kind = $kind;
5797
- }
5798
-
5799
- public function getKind()
5800
- {
5801
- return $this->kind;
5802
- }
5803
-
5804
- public function setSelfLink($selfLink)
5805
- {
5806
- $this->selfLink = $selfLink;
5807
- }
5808
-
5809
- public function getSelfLink()
5810
- {
5811
- return $this->selfLink;
5812
- }
5813
- }
5814
-
5815
- class Google_Service_Drive_User extends Google_ApiModel
5816
- {
5817
- public $displayName;
5818
- public $isAuthenticatedUser;
5819
- public $kind;
5820
- public $permissionId;
5821
- protected $pictureType = 'Google_Service_Drive_UserPicture';
5822
- protected $pictureDataType = '';
5823
-
5824
- public function setDisplayName($displayName)
5825
- {
5826
- $this->displayName = $displayName;
5827
- }
5828
-
5829
- public function getDisplayName()
5830
- {
5831
- return $this->displayName;
5832
- }
5833
-
5834
- public function setIsAuthenticatedUser($isAuthenticatedUser)
5835
- {
5836
- $this->isAuthenticatedUser = $isAuthenticatedUser;
5837
- }
5838
-
5839
- public function getIsAuthenticatedUser()
5840
- {
5841
- return $this->isAuthenticatedUser;
5842
- }
5843
-
5844
- public function setKind($kind)
5845
- {
5846
- $this->kind = $kind;
5847
- }
5848
-
5849
- public function getKind()
5850
- {
5851
- return $this->kind;
5852
- }
5853
-
5854
- public function setPermissionId($permissionId)
5855
- {
5856
- $this->permissionId = $permissionId;
5857
- }
5858
-
5859
- public function getPermissionId()
5860
- {
5861
- return $this->permissionId;
5862
- }
5863
-
5864
- public function setPicture(Google_Service_Drive_UserPicture $picture)
5865
- {
5866
- $this->picture = $picture;
5867
- }
5868
-
5869
- public function getPicture()
5870
- {
5871
- return $this->picture;
5872
- }
5873
- }
5874
-
5875
- class Google_Service_Drive_UserPicture extends Google_ApiModel
5876
- {
5877
- public $url;
5878
-
5879
- public function setUrl($url)
5880
- {
5881
- $this->url = $url;
5882
- }
5883
-
5884
- public function getUrl()
5885
- {
5886
- return $this->url;
5887
- }
5888
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Google/Service/Exception.php DELETED
@@ -1,52 +0,0 @@
1
- <?php
2
-
3
-
4
- class Google_Service_Exception extends Google_ApiException
5
- {
6
- /**
7
- * Optional list of errors returned in a JSON body of an HTTP error response.
8
- */
9
- protected $errors = array();
10
-
11
- /**
12
- * Override default constructor to add ability to set $errors.
13
- *
14
- * @param string $message
15
- * @param int $code
16
- * @param Exception|null $previous
17
- * @param [{string, string}] errors List of errors returned in an HTTP
18
- * response. Defaults to [].
19
- */
20
- public function __construct(
21
- $message,
22
- $code = 0,
23
- Exception $previous = null,
24
- $errors = array()
25
- ) {
26
- if (version_compare(PHP_VERSION, '5.3.0') >= 0) {
27
- parent::__construct($message, $code, $previous);
28
- } else {
29
- parent::__construct($message, $code);
30
- }
31
-
32
- $this->errors = $errors;
33
- }
34
-
35
- /**
36
- * An example of the possible errors returned.
37
- *
38
- * {
39
- * "domain": "global",
40
- * "reason": "authError",
41
- * "message": "Invalid Credentials",
42
- * "locationType": "header",
43
- * "location": "Authorization",
44
- * }
45
- *
46
- * @return [{string, string}] List of errors return in an HTTP response or [].
47
- */
48
- public function getErrors()
49
- {
50
- return $this->errors;
51
- }
52
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Google/Service/Oauth2.php DELETED
@@ -1,411 +0,0 @@
1
- <?php
2
- /*
3
- * Copyright 2010 Google Inc.
4
- *
5
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
6
- * use this file except in compliance with the License. You may obtain a copy of
7
- * 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, WITHOUT
13
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14
- * License for the specific language governing permissions and limitations under
15
- * the License.
16
- */
17
-
18
- /**
19
- * Service definition for Oauth2 (v2).
20
- *
21
- * <p>
22
- * Lets you access OAuth2 protocol related APIs.
23
- * </p>
24
- *
25
- * <p>
26
- * For more information about this service, see the API
27
- * <a href="https://developers.google.com/accounts/docs/OAuth2" target="_blank">Documentation</a>
28
- * </p>
29
- *
30
- * @author Google, Inc.
31
- */
32
- class Google_Service_Oauth2 extends Google_ApiService
33
- {
34
- /** Know your basic profile info and list of people in your circles.. */
35
- const PLUS_LOGIN = "https://www.googleapis.com/auth/plus.login";
36
- /** Know who you are on Google. */
37
- const PLUS_ME = "https://www.googleapis.com/auth/plus.me";
38
- /** View your email address. */
39
- const USERINFO_EMAIL = "https://www.googleapis.com/auth/userinfo.email";
40
- /** View basic information about your account. */
41
- const USERINFO_PROFILE = "https://www.googleapis.com/auth/userinfo.profile";
42
-
43
- public $userinfo;
44
- public $userinfo_v2_me;
45
- private $base_methods;
46
-
47
- /**
48
- * Constructs the internal representation of the Oauth2 service.
49
- *
50
- * @param Google_ApiClient $client
51
- */
52
- public function __construct(Google_ApiClient $client)
53
- {
54
- parent::__construct($client);
55
- $this->servicePath = '';
56
- $this->version = 'v2';
57
- $this->serviceName = 'oauth2';
58
-
59
- $this->userinfo = new Google_Service_Oauth2_Userinfo_Resource(
60
- $this,
61
- $this->serviceName,
62
- 'userinfo',
63
- array(
64
- 'methods' => array(
65
- 'get' => array(
66
- 'path' => 'oauth2/v2/userinfo',
67
- 'httpMethod' => 'GET',
68
- 'parameters' => array(),
69
- ),
70
- ),
71
- )
72
- );
73
- $this->userinfo_v2_me = new Google_Service_Oauth2_UserinfoV2Me_Resource(
74
- $this,
75
- $this->serviceName,
76
- 'me',
77
- array(
78
- 'methods' => array(
79
- 'get' => array(
80
- 'path' => 'userinfo/v2/me',
81
- 'httpMethod' => 'GET',
82
- 'parameters' => array(),
83
- ),
84
- ),
85
- )
86
- );
87
- $this->base_methods = new Google_Service_Resource(
88
- $this,
89
- $this->serviceName,
90
- '',
91
- array(
92
- 'methods' => array(
93
- 'tokeninfo' => array(
94
- 'path' => 'oauth2/v2/tokeninfo',
95
- 'httpMethod' => 'POST',
96
- 'parameters' => array(
97
- 'access_token' => array(
98
- 'location' => 'query',
99
- 'type' => 'string',
100
- ),
101
- 'id_token' => array(
102
- 'location' => 'query',
103
- 'type' => 'string',
104
- ),
105
- ),
106
- ),
107
- ),
108
- )
109
- );
110
- }
111
-
112
- /**
113
- * (tokeninfo)
114
- *
115
- * @param array $optParams Optional parameters.
116
- *
117
- * @opt_param string accessToken
118
- *
119
- * @opt_param string idToken
120
- *
121
- * @return Google_Service_Oauth2_Tokeninfo
122
- */
123
- public function tokeninfo($optParams = array())
124
- {
125
- $params = array();
126
- $params = array_merge($params, $optParams);
127
-
128
- return $this->base_methods->call('tokeninfo', array($params), "Google_Service_Oauth2_Tokeninfo");
129
- }
130
- }
131
-
132
- /**
133
- * The "userinfo" collection of methods.
134
- * Typical usage is:
135
- * <code>
136
- * $oauth2Service = new Google_Service_Oauth2(...);
137
- * $userinfo = $oauth2Service->userinfo;
138
- * </code>
139
- */
140
- class Google_Service_Oauth2_Userinfo_Resource extends Google_Service_Resource
141
- {
142
- /**
143
- * (userinfo.get)
144
- *
145
- * @param array $optParams Optional parameters.
146
- *
147
- * @return Google_Service_Oauth2_Userinfoplus
148
- */
149
- public function get($optParams = array())
150
- {
151
- $params = array();
152
- $params = array_merge($params, $optParams);
153
-
154
- return $this->call('get', array($params), "Google_Service_Oauth2_Userinfoplus");
155
- }
156
- }
157
-
158
- /**
159
- * The "v2" collection of methods.
160
- * Typical usage is:
161
- * <code>
162
- * $oauth2Service = new Google_Service_Oauth2(...);
163
- * $v2 = $oauth2Service->v2;
164
- * </code>
165
- */
166
- class Google_Service_Oauth2_UserinfoV2_Resource extends Google_Service_Resource
167
- {
168
- }
169
-
170
- /**
171
- * The "me" collection of methods.
172
- * Typical usage is:
173
- * <code>
174
- * $oauth2Service = new Google_Service_Oauth2(...);
175
- * $me = $oauth2Service->me;
176
- * </code>
177
- */
178
- class Google_Service_Oauth2_UserinfoV2Me_Resource extends Google_Service_Resource
179
- {
180
- /**
181
- * (me.get)
182
- *
183
- * @param array $optParams Optional parameters.
184
- *
185
- * @return Google_Service_Oauth2_Userinfoplus
186
- */
187
- public function get($optParams = array())
188
- {
189
- $params = array();
190
- $params = array_merge($params, $optParams);
191
-
192
- return $this->call('get', array($params), "Google_Service_Oauth2_Userinfoplus");
193
- }
194
- }
195
-
196
- class Google_Service_Oauth2_Tokeninfo extends Google_ApiModel
197
- {
198
- public $accessType;
199
- public $audience;
200
- public $email;
201
- public $expiresIn;
202
- public $issuedTo;
203
- public $scope;
204
- public $userId;
205
- public $verifiedEmail;
206
-
207
- public function setAccessType($accessType)
208
- {
209
- $this->accessType = $accessType;
210
- }
211
-
212
- public function getAccessType()
213
- {
214
- return $this->accessType;
215
- }
216
-
217
- public function setAudience($audience)
218
- {
219
- $this->audience = $audience;
220
- }
221
-
222
- public function getAudience()
223
- {
224
- return $this->audience;
225
- }
226
-
227
- public function setEmail($email)
228
- {
229
- $this->email = $email;
230
- }
231
-
232
- public function getEmail()
233
- {
234
- return $this->email;
235
- }
236
-
237
- public function setExpiresIn($expiresIn)
238
- {
239
- $this->expiresIn = $expiresIn;
240
- }
241
-
242
- public function getExpiresIn()
243
- {
244
- return $this->expiresIn;
245
- }
246
-
247
- public function setIssuedTo($issuedTo)
248
- {
249
- $this->issuedTo = $issuedTo;
250
- }
251
-
252
- public function getIssuedTo()
253
- {
254
- return $this->issuedTo;
255
- }
256
-
257
- public function setScope($scope)
258
- {
259
- $this->scope = $scope;
260
- }
261
-
262
- public function getScope()
263
- {
264
- return $this->scope;
265
- }
266
-
267
- public function setUserId($userId)
268
- {
269
- $this->userId = $userId;
270
- }
271
-
272
- public function getUserId()
273
- {
274
- return $this->userId;
275
- }
276
-
277
- public function setVerifiedEmail($verifiedEmail)
278
- {
279
- $this->verifiedEmail = $verifiedEmail;
280
- }
281
-
282
- public function getVerifiedEmail()
283
- {
284
- return $this->verifiedEmail;
285
- }
286
- }
287
-
288
- class Google_Service_Oauth2_Userinfoplus extends Google_ApiModel
289
- {
290
- public $email;
291
- public $familyName;
292
- public $gender;
293
- public $givenName;
294
- public $hd;
295
- public $id;
296
- public $link;
297
- public $locale;
298
- public $name;
299
- public $picture;
300
- public $verifiedEmail;
301
-
302
- public function setEmail($email)
303
- {
304
- $this->email = $email;
305
- }
306
-
307
- public function getEmail()
308
- {
309
- return $this->email;
310
- }
311
-
312
- public function setFamilyName($familyName)
313
- {
314
- $this->familyName = $familyName;
315
- }
316
-
317
- public function getFamilyName()
318
- {
319
- return $this->familyName;
320
- }
321
-
322
- public function setGender($gender)
323
- {
324
- $this->gender = $gender;
325
- }
326
-
327
- public function getGender()
328
- {
329
- return $this->gender;
330
- }
331
-
332
- public function setGivenName($givenName)
333
- {
334
- $this->givenName = $givenName;
335
- }
336
-
337
- public function getGivenName()
338
- {
339
- return $this->givenName;
340
- }
341
-
342
- public function setHd($hd)
343
- {
344
- $this->hd = $hd;
345
- }
346
-
347
- public function getHd()
348
- {
349
- return $this->hd;
350
- }
351
-
352
- public function setId($id)
353
- {
354
- $this->id = $id;
355
- }
356
-
357
- public function getId()
358
- {
359
- return $this->id;
360
- }
361
-
362
- public function setLink($link)
363
- {
364
- $this->link = $link;
365
- }
366
-
367
- public function getLink()
368
- {
369
- return $this->link;
370
- }
371
-
372
- public function setLocale($locale)
373
- {
374
- $this->locale = $locale;
375
- }
376
-
377
- public function getLocale()
378
- {
379
- return $this->locale;
380
- }
381
-
382
- public function setName($name)
383
- {
384
- $this->name = $name;
385
- }
386
-
387
- public function getName()
388
- {
389
- return $this->name;
390
- }
391
-
392
- public function setPicture($picture)
393
- {
394
- $this->picture = $picture;
395
- }
396
-
397
- public function getPicture()
398
- {
399
- return $this->picture;
400
- }
401
-
402
- public function setVerifiedEmail($verifiedEmail)
403
- {
404
- $this->verifiedEmail = $verifiedEmail;
405
- }
406
-
407
- public function getVerifiedEmail()
408
- {
409
- return $this->verifiedEmail;
410
- }
411
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Google/Service/Resource.php DELETED
@@ -1,209 +0,0 @@
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_Service_Resource
28
- {
29
- // Valid query parameters that work, but don't appear in discovery.
30
- private $stackParameters = array(
31
- 'alt' => 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
- 'quotaUser' => array('type' => 'string', 'location' => 'query'),
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_ApiService $service */
44
- private $service;
45
-
46
- /** @var Google_ApiClient $client */
47
- private $client;
48
-
49
- /** @var string $serviceName */
50
- private $serviceName;
51
-
52
- /** @var string $resourceName */
53
- private $resourceName;
54
-
55
- /** @var array $methods */
56
- private $methods;
57
-
58
- public function __construct($service, $serviceName, $resourceName, $resource)
59
- {
60
- $this->service = $service;
61
- $this->client = $service->getClient();
62
- $this->serviceName = $serviceName;
63
- $this->resourceName = $resourceName;
64
- $this->methods = isset($resource['methods']) ?
65
- $resource['methods'] :
66
- array($resourceName => $resource);
67
- }
68
-
69
- /**
70
- * TODO(ianbarber): This function needs simplifying.
71
- *
72
- * @param $name
73
- * @param $arguments
74
- * @param $expected_class - optional, the expected class name
75
- *
76
- * @return Google_Http_Request|expected_class
77
- * @throws Google_ApiException
78
- */
79
- public function call($name, $arguments, $expected_class = null)
80
- {
81
- if (!isset($this->methods[$name])) {
82
- throw new Google_ApiException(
83
- "Unknown function: ".
84
- "{$this->serviceName}->{$this->resourceName}->{$name}()"
85
- );
86
- }
87
- $method = $this->methods[$name];
88
- $parameters = $arguments[0];
89
-
90
- // postBody is a special case since it's not defined in the discovery
91
- // document as parameter, but we abuse the param entry for storing it.
92
- $postBody = null;
93
- if (isset($parameters['postBody'])) {
94
- if ($parameters['postBody'] instanceof Google_ApiModel) {
95
- // In the cases the post body is an existing object, we want
96
- // to use the smart method to create a simple object for
97
- // for JSONification.
98
- $parameters['postBody'] = $parameters['postBody']->toSimpleObject();
99
- } else {
100
- if (is_object($parameters['postBody'])) {
101
- // If the post body is another kind of object, we will try and
102
- // wrangle it into a sensible format.
103
- $parameters['postBody'] =
104
- $this->convertToArrayAndStripNulls($parameters['postBody']);
105
- }
106
- }
107
- $postBody = json_encode($parameters['postBody']);
108
- unset($parameters['postBody']);
109
- }
110
-
111
- // TODO(ianbarber): optParams here probably should have been
112
- // handled already - this may well be redundant code.
113
- if (isset($parameters['optParams'])) {
114
- $optParams = $parameters['optParams'];
115
- unset($parameters['optParams']);
116
- $parameters = array_merge($parameters, $optParams);
117
- }
118
-
119
- if (!isset($method['parameters'])) {
120
- $method['parameters'] = array();
121
- }
122
-
123
- $method['parameters'] = array_merge(
124
- $method['parameters'],
125
- $this->stackParameters
126
- );
127
- foreach ($parameters as $key => $val) {
128
- if ($key != 'postBody' && !isset($method['parameters'][$key])) {
129
- throw new Google_ApiException("($name) unknown parameter: '$key'");
130
- }
131
- }
132
-
133
- foreach ($method['parameters'] as $paramName => $paramSpec) {
134
- if (isset($paramSpec['required']) &&
135
- $paramSpec['required'] &&
136
- !isset($parameters[$paramName])
137
- ) {
138
- throw new Google_ApiException("($name) missing required param: '$paramName'");
139
- }
140
- if (isset($parameters[$paramName])) {
141
- $value = $parameters[$paramName];
142
- $parameters[$paramName] = $paramSpec;
143
- $parameters[$paramName]['value'] = $value;
144
- unset($parameters[$paramName]['required']);
145
- } else {
146
- // Ensure we don't pass nulls.
147
- unset($parameters[$paramName]);
148
- }
149
- }
150
-
151
- $servicePath = $this->service->servicePath;
152
-
153
- $url = Google_Http_REST::createRequestUri(
154
- $servicePath,
155
- $method['path'],
156
- $parameters
157
- );
158
- $httpRequest = new Google_Http_Request(
159
- $url,
160
- $method['httpMethod'],
161
- null,
162
- $postBody
163
- );
164
- $httpRequest->setBaseComponent($this->client->getBasePath());
165
-
166
- if ($postBody) {
167
- $contentTypeHeader = array();
168
- $contentTypeHeader['content-type'] = 'application/json; charset=UTF-8';
169
- $httpRequest->setRequestHeaders($contentTypeHeader);
170
- $httpRequest->setPostBody($postBody);
171
- }
172
-
173
- $httpRequest = $this->client->getAuth()->sign($httpRequest);
174
- $httpRequest->setExpectedClass($expected_class);
175
-
176
- if (isset($parameters['data']) &&
177
- ($parameters['uploadType']['value'] == 'media' || $parameters['uploadType']['value'] == 'multipart')
178
- ) {
179
- // If we are doing a simple media upload, trigger that as a convenience.
180
- $mfu = new Google_Http_MediaFileUpload(
181
- $this->client,
182
- $httpRequest,
183
- isset($parameters['mimeType']) ? $parameters['mimeType']['value'] : 'application/octet-stream',
184
- $parameters['data']['value']
185
- );
186
- }
187
-
188
- if ($this->client->shouldDefer()) {
189
- // If we are in batch or upload mode, return the raw request.
190
- return $httpRequest;
191
- }
192
-
193
- return $this->client->execute($httpRequest);
194
- }
195
-
196
- protected function convertToArrayAndStripNulls($o)
197
- {
198
- $o = (array) $o;
199
- foreach ($o as $k => $v) {
200
- if ($v === null) {
201
- unset($o[$k]);
202
- } elseif (is_object($v) || is_array($v)) {
203
- $o[$k] = $this->convertToArrayAndStripNulls($o[$k]);
204
- }
205
- }
206
-
207
- return $o;
208
- }
209
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Google/Signer/Abstract.php DELETED
@@ -1,29 +0,0 @@
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
- * @author Brian Eaton <beaton@google.com>
22
- */
23
- abstract class Google_Signer_Abstract
24
- {
25
- /**
26
- * Signs data, returns the signature as binary data.
27
- */
28
- abstract public function sign($data);
29
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Google/Signer/P12.php DELETED
@@ -1,88 +0,0 @@
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_Signer_P12 extends Google_Signer_Abstract
26
- {
27
- // OpenSSL private key resource
28
- private $privateKey;
29
-
30
- // Creates a new signer from a .p12 file.
31
- public function __construct($p12, $password)
32
- {
33
- if (!function_exists('openssl_x509_read')) {
34
- throw new Google_ApiException(
35
- 'The Google PHP API library needs the openssl PHP extension'
36
- );
37
- }
38
-
39
- // If the private key is provided directly, then this isn't in the p12
40
- // format. Different versions of openssl support different p12 formats
41
- // and the key from google wasn't being accepted by the version available
42
- // at the time.
43
- if (!$password && strpos($p12, "-----BEGIN RSA PRIVATE KEY-----") !== false) {
44
- $this->privateKey = openssl_pkey_get_private($p12);
45
- } else {
46
- // This throws on error
47
- $certs = array();
48
- if (!openssl_pkcs12_read($p12, $certs, $password)) {
49
- throw new Google_Auth_Exception(
50
- "Unable to parse the p12 file. ".
51
- "Is this a .p12 file? Is the password correct? OpenSSL error: ".
52
- openssl_error_string()
53
- );
54
- }
55
- // TODO(beaton): is this part of the contract for the openssl_pkcs12_read
56
- // method? What happens if there are multiple private keys? Do we care?
57
- if (!array_key_exists("pkey", $certs) || !$certs["pkey"]) {
58
- throw new Google_Auth_Exception("No private key found in p12 file.");
59
- }
60
- $this->privateKey = openssl_pkey_get_private($certs['pkey']);
61
- }
62
-
63
- if (!$this->privateKey) {
64
- throw new Google_Auth_Exception("Unable to load private key");
65
- }
66
- }
67
-
68
- public function __destruct()
69
- {
70
- if ($this->privateKey) {
71
- openssl_pkey_free($this->privateKey);
72
- }
73
- }
74
-
75
- public function sign($data)
76
- {
77
- if (version_compare(PHP_VERSION, '5.3.0') < 0) {
78
- throw new Google_Auth_Exception(
79
- "PHP 5.3.0 or higher is required to use service accounts."
80
- );
81
- }
82
- if (!openssl_sign($data, $signature, $this->privateKey, "sha256")) {
83
- throw new Google_Auth_Exception("Unable to sign data");
84
- }
85
-
86
- return $signature;
87
- }
88
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Google/Utils/URITemplate.php DELETED
@@ -1,375 +0,0 @@
1
- <?php
2
- /*
3
- * Copyright 2013 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
- * Implementation of levels 1-3 of the URI Template spec.
20
- *
21
- * @see http://tools.ietf.org/html/rfc6570
22
- */
23
- class Google_Utils_URITemplate
24
- {
25
- const TYPE_MAP = "1";
26
- const TYPE_LIST = "2";
27
- const TYPE_SCALAR = "4";
28
-
29
- /**
30
- * @var $operators array
31
- * These are valid at the start of a template block to
32
- * modify the way in which the variables inside are
33
- * processed.
34
- */
35
- private $operators = array(
36
- "+" => "reserved",
37
- "/" => "segments",
38
- "." => "dotprefix",
39
- "#" => "fragment",
40
- ";" => "semicolon",
41
- "?" => "form",
42
- "&" => "continuation",
43
- );
44
-
45
- /**
46
- * @var reserved array
47
- * These are the characters which should not be URL encoded in reserved
48
- * strings.
49
- */
50
- private $reserved = array(
51
- "=",
52
- ",",
53
- "!",
54
- "@",
55
- "|",
56
- ":",
57
- "/",
58
- "?",
59
- "#",
60
- "[",
61
- "]",
62
- "$",
63
- "&",
64
- "'",
65
- "(",
66
- ")",
67
- "*",
68
- "+",
69
- ";",
70
- );
71
- private $reservedEncoded = array(
72
- "%3D",
73
- "%2C",
74
- "%21",
75
- "%40",
76
- "%7C",
77
- "%3A",
78
- "%2F",
79
- "%3F",
80
- "%23",
81
- "%5B",
82
- "%5D",
83
- "%24",
84
- "%26",
85
- "%27",
86
- "%28",
87
- "%29",
88
- "%2A",
89
- "%2B",
90
- "%3B",
91
- );
92
-
93
- public function parse($string, array $parameters)
94
- {
95
- return $this->resolveNextSection($string, $parameters);
96
- }
97
-
98
- /**
99
- * This function finds the first matching {...} block and
100
- * executes the replacement. It then calls itself to find
101
- * subsequent blocks, if any.
102
- */
103
- private function resolveNextSection($string, $parameters)
104
- {
105
- $start = strpos($string, "{");
106
- if ($start === false) {
107
- return $string;
108
- }
109
- $end = strpos($string, "}");
110
- if ($end === false) {
111
- return $string;
112
- }
113
- $string = $this->replace($string, $start, $end, $parameters);
114
-
115
- return $this->resolveNextSection($string, $parameters);
116
- }
117
-
118
- private function replace($string, $start, $end, $parameters)
119
- {
120
- // We know a data block will have {} round it, so we can strip that.
121
- $data = substr($string, $start + 1, $end - $start - 1);
122
-
123
- // If the first character is one of the reserved operators, it effects
124
- // the processing of the stream.
125
- if (isset($this->operators[$data[0]])) {
126
- $op = $this->operators[$data[0]];
127
- $data = substr($data, 1);
128
- $prefix = "";
129
- $prefix_on_missing = false;
130
-
131
- switch ($op) {
132
- case "reserved":
133
- // Reserved means certain characters should not be URL encoded
134
- $data = $this->replaceVars($data, $parameters, ",", null, true);
135
- break;
136
- case "fragment":
137
- // Comma separated with fragment prefix. Bare values only.
138
- $prefix = "#";
139
- $prefix_on_missing = true;
140
- $data = $this->replaceVars($data, $parameters, ",", null, true);
141
- break;
142
- case "segments":
143
- // Slash separated data. Bare values only.
144
- $prefix = "/";
145
- $data = $this->replaceVars($data, $parameters, "/");
146
- break;
147
- case "dotprefix":
148
- // Dot separated data. Bare values only.
149
- $prefix = ".";
150
- $prefix_on_missing = true;
151
- $data = $this->replaceVars($data, $parameters, ".");
152
- break;
153
- case "semicolon":
154
- // Semicolon prefixed and separated. Uses the key name
155
- $prefix = ";";
156
- $data = $this->replaceVars($data, $parameters, ";", "=", false, true, false);
157
- break;
158
- case "form":
159
- // Standard URL format. Uses the key name
160
- $prefix = "?";
161
- $data = $this->replaceVars($data, $parameters, "&", "=");
162
- break;
163
- case "continuation":
164
- // Standard URL, but with leading ampersand. Uses key name.
165
- $prefix = "&";
166
- $data = $this->replaceVars($data, $parameters, "&", "=");
167
- break;
168
- }
169
-
170
- // Add the initial prefix character if data is valid.
171
- if ($data || ($data !== false && $prefix_on_missing)) {
172
- $data = $prefix.$data;
173
- }
174
- } else {
175
- // If no operator we replace with the defaults.
176
- $data = $this->replaceVars($data, $parameters);
177
- }
178
-
179
- // This is chops out the {...} and replaces with the new section.
180
- return substr($string, 0, $start).$data.substr($string, $end + 1);
181
- }
182
-
183
- private function replaceVars(
184
- $section,
185
- $parameters,
186
- $sep = ",",
187
- $combine = null,
188
- $reserved = false,
189
- $tag_empty = false,
190
- $combine_on_empty = true
191
- ) {
192
- if (strpos($section, ",") === false) {
193
- // If we only have a single value, we can immediately process.
194
- return $this->combine(
195
- $section,
196
- $parameters,
197
- $sep,
198
- $combine,
199
- $reserved,
200
- $tag_empty,
201
- $combine_on_empty
202
- );
203
- } else {
204
- // If we have multiple values, we need to split and loop over them.
205
- // Each is treated individually, then glued together with the
206
- // separator character.
207
- $vars = explode(",", $section);
208
-
209
- return $this->combineList(
210
- $vars,
211
- $sep,
212
- $parameters,
213
- $combine,
214
- $reserved,
215
- false, // Never emit empty strings in multi-param replacements
216
- $combine_on_empty
217
- );
218
- }
219
- }
220
-
221
- public function combine(
222
- $key,
223
- $parameters,
224
- $sep,
225
- $combine,
226
- $reserved,
227
- $tag_empty,
228
- $combine_on_empty
229
- ) {
230
- $length = false;
231
- $explode = false;
232
- $skip_final_combine = false;
233
- $value = false;
234
-
235
- // Check for length restriction.
236
- if (strpos($key, ":") !== false) {
237
- list($key, $length) = explode(":", $key);
238
- }
239
-
240
- // Check for explode parameter.
241
- if ($key[strlen($key) - 1] == "*") {
242
- $explode = true;
243
- $key = substr($key, 0, -1);
244
- $skip_final_combine = true;
245
- }
246
-
247
- // Define the list separator.
248
- $list_sep = $explode ? $sep : ",";
249
-
250
- if (isset($parameters[$key])) {
251
- $data_type = $this->getDataType($parameters[$key]);
252
- switch ($data_type) {
253
- case self::TYPE_SCALAR:
254
- $value = $this->getValue($parameters[$key], $length);
255
- break;
256
- case self::TYPE_LIST:
257
- $values = array();
258
- foreach ($parameters[$key] as $pkey => $pvalue) {
259
- $pvalue = $this->getValue($pvalue, $length);
260
- if ($combine && $explode) {
261
- $values[$pkey] = $key.$combine.$pvalue;
262
- } else {
263
- $values[$pkey] = $pvalue;
264
- }
265
- }
266
- $value = implode($list_sep, $values);
267
- if ($value == '') {
268
- return '';
269
- }
270
- break;
271
- case self::TYPE_MAP:
272
- $values = array();
273
- foreach ($parameters[$key] as $pkey => $pvalue) {
274
- $pvalue = $this->getValue($pvalue, $length);
275
- if ($explode) {
276
- $pkey = $this->getValue($pkey, $length);
277
- $values[] = $pkey."=".$pvalue; // Explode triggers = combine.
278
- } else {
279
- $values[] = $pkey;
280
- $values[] = $pvalue;
281
- }
282
- }
283
- $value = implode($list_sep, $values);
284
- if ($value == '') {
285
- return false;
286
- }
287
- break;
288
- }
289
- } else {
290
- if ($tag_empty) {
291
- // If we are just indicating empty values with their key name, return that.
292
- return $key;
293
- } else {
294
- // Otherwise we can skip this variable due to not being defined.
295
- return false;
296
- }
297
- }
298
-
299
- if ($reserved) {
300
- $value = str_replace($this->reservedEncoded, $this->reserved, $value);
301
- }
302
-
303
- // If we do not need to include the key name, we just return the raw
304
- // value.
305
- if (!$combine || $skip_final_combine) {
306
- return $value;
307
- }
308
-
309
- // Else we combine the key name: foo=bar, if value is not the empty string.
310
- return $key.($value != '' || $combine_on_empty ? $combine.$value : '');
311
- }
312
-
313
- /**
314
- * Return the type of a passed in value
315
- */
316
- private function getDataType($data)
317
- {
318
- if (is_array($data)) {
319
- reset($data);
320
- if (key($data) !== 0) {
321
- return self::TYPE_MAP;
322
- }
323
-
324
- return self::TYPE_LIST;
325
- }
326
-
327
- return self::TYPE_SCALAR;
328
- }
329
-
330
- /**
331
- * Utility function that merges multiple combine calls
332
- * for multi-key templates.
333
- */
334
- private function combineList(
335
- $vars,
336
- $sep,
337
- $parameters,
338
- $combine,
339
- $reserved,
340
- $tag_empty,
341
- $combine_on_empty
342
- ) {
343
- $ret = array();
344
- foreach ($vars as $var) {
345
- $response = $this->combine(
346
- $var,
347
- $parameters,
348
- $sep,
349
- $combine,
350
- $reserved,
351
- $tag_empty,
352
- $combine_on_empty
353
- );
354
- if ($response === false) {
355
- continue;
356
- }
357
- $ret[] = $response;
358
- }
359
-
360
- return implode($sep, $ret);
361
- }
362
-
363
- /**
364
- * Utility function to encode and trim values
365
- */
366
- private function getValue($value, $length)
367
- {
368
- if ($length) {
369
- $value = substr($value, 0, $length);
370
- }
371
- $value = rawurlencode($value);
372
-
373
- return $value;
374
- }
375
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Google/Verifier/Abstract.php DELETED
@@ -1,30 +0,0 @@
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.
20
- *
21
- * @author Brian Eaton <beaton@google.com>
22
- */
23
- abstract class Google_Verifier_Abstract
24
- {
25
- /**
26
- * Checks a signature, returns true if the signature is correct,
27
- * false otherwise.
28
- */
29
- abstract public function verify($data, $signature);
30
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/Google/Verifier/Pem.php DELETED
@@ -1,74 +0,0 @@
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_Verifier_Pem extends Google_Verifier_Abstract
24
- {
25
- private $publicKey;
26
-
27
- /**
28
- * Constructs a verifier from the supplied PEM-encoded certificate.
29
- * $pem: a PEM encoded certificate (not a file).
30
- *
31
- * @param $pem
32
- *
33
- * @throws Google_Auth_Exception
34
- * @throws Google_ApiException
35
- */
36
- public function __construct($pem)
37
- {
38
- if (!function_exists('openssl_x509_read')) {
39
- throw new Google_ApiException('Google API PHP client needs the openssl PHP extension');
40
- }
41
- $this->publicKey = openssl_x509_read($pem);
42
- if (!$this->publicKey) {
43
- throw new Google_Auth_Exception("Unable to parse PEM: $pem");
44
- }
45
- }
46
-
47
- public function __destruct()
48
- {
49
- if ($this->publicKey) {
50
- openssl_x509_free($this->publicKey);
51
- }
52
- }
53
-
54
- /**
55
- * Verifies the signature on data.
56
- *
57
- * Returns true if the signature is valid, false otherwise.
58
- *
59
- * @param $data
60
- * @param $signature
61
- *
62
- * @throws Google_Auth_Exception
63
- * @return bool
64
- */
65
- public function verify($data, $signature)
66
- {
67
- $status = openssl_verify($data, $signature, $this->publicKey, "sha256");
68
- if ($status === -1) {
69
- throw new Google_Auth_Exception('Signature verification error: '.openssl_error_string());
70
- }
71
-
72
- return $status === 1;
73
- }
74
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/LICENSE CHANGED
@@ -24,31 +24,6 @@ THE SOFTWARE.
24
 
25
  ===============================================================================
26
 
27
- Dropbox PHP SDK license:
28
-
29
- Copyright (c) 2013 Dropbox Inc., http://www.dropbox.com/
30
-
31
- Permission is hereby granted, free of charge, to any person obtaining
32
- a copy of this software and associated documentation files (the
33
- "Software"), to deal in the Software without restriction, including
34
- without limitation the rights to use, copy, modify, merge, publish,
35
- distribute, sublicense, and/or sell copies of the Software, and to
36
- permit persons to whom the Software is furnished to do so, subject to
37
- the following conditions:
38
-
39
- The above copyright notice and this permission notice shall be
40
- included in all copies or substantial portions of the Software.
41
-
42
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
43
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
44
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
45
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
46
- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
47
- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
48
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
49
-
50
- ===============================================================================
51
-
52
  gelf-php license:
53
 
54
  Copyright (c) 2010-2012 Lennart Koopmann
@@ -98,241 +73,6 @@ THE SOFTWARE.
98
 
99
  ===============================================================================
100
 
101
- Amazon S3 PHP Class license:
102
-
103
- Copyright (c) 2013, Donovan Schönknecht. All rights reserved.
104
-
105
- Redistribution and use in source and binary forms, with or without
106
- modification, are permitted provided that the following conditions are met:
107
-
108
- - Redistributions of source code must retain the above copyright notice,
109
- this list of conditions and the following disclaimer.
110
- - Redistributions in binary form must reproduce the above copyright
111
- notice, this list of conditions and the following disclaimer in the
112
- documentation and/or other materials provided with the distribution.
113
-
114
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
115
- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
116
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
117
- ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
118
- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
119
- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
120
- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
121
- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
122
- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
123
- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
124
- POSSIBILITY OF SUCH DAMAGE.
125
-
126
- Amazon S3 is a trademark of Amazon.com, Inc. or its affiliates.
127
-
128
- ===============================================================================
129
-
130
- Google APIs Client Library for PHP license:
131
-
132
- Apache License
133
- Version 2.0, January 2004
134
- http://www.apache.org/licenses/
135
-
136
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
137
-
138
- 1. Definitions.
139
-
140
- "License" shall mean the terms and conditions for use, reproduction,
141
- and distribution as defined by Sections 1 through 9 of this document.
142
-
143
- "Licensor" shall mean the copyright owner or entity authorized by
144
- the copyright owner that is granting the License.
145
-
146
- "Legal Entity" shall mean the union of the acting entity and all
147
- other entities that control, are controlled by, or are under common
148
- control with that entity. For the purposes of this definition,
149
- "control" means (i) the power, direct or indirect, to cause the
150
- direction or management of such entity, whether by contract or
151
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
152
- outstanding shares, or (iii) beneficial ownership of such entity.
153
-
154
- "You" (or "Your") shall mean an individual or Legal Entity
155
- exercising permissions granted by this License.
156
-
157
- "Source" form shall mean the preferred form for making modifications,
158
- including but not limited to software source code, documentation
159
- source, and configuration files.
160
-
161
- "Object" form shall mean any form resulting from mechanical
162
- transformation or translation of a Source form, including but
163
- not limited to compiled object code, generated documentation,
164
- and conversions to other media types.
165
-
166
- "Work" shall mean the work of authorship, whether in Source or
167
- Object form, made available under the License, as indicated by a
168
- copyright notice that is included in or attached to the work
169
- (an example is provided in the Appendix below).
170
-
171
- "Derivative Works" shall mean any work, whether in Source or Object
172
- form, that is based on (or derived from) the Work and for which the
173
- editorial revisions, annotations, elaborations, or other modifications
174
- represent, as a whole, an original work of authorship. For the purposes
175
- of this License, Derivative Works shall not include works that remain
176
- separable from, or merely link (or bind by name) to the interfaces of,
177
- the Work and Derivative Works thereof.
178
-
179
- "Contribution" shall mean any work of authorship, including
180
- the original version of the Work and any modifications or additions
181
- to that Work or Derivative Works thereof, that is intentionally
182
- submitted to Licensor for inclusion in the Work by the copyright owner
183
- or by an individual or Legal Entity authorized to submit on behalf of
184
- the copyright owner. For the purposes of this definition, "submitted"
185
- means any form of electronic, verbal, or written communication sent
186
- to the Licensor or its representatives, including but not limited to
187
- communication on electronic mailing lists, source code control systems,
188
- and issue tracking systems that are managed by, or on behalf of, the
189
- Licensor for the purpose of discussing and improving the Work, but
190
- excluding communication that is conspicuously marked or otherwise
191
- designated in writing by the copyright owner as "Not a Contribution."
192
-
193
- "Contributor" shall mean Licensor and any individual or Legal Entity
194
- on behalf of whom a Contribution has been received by Licensor and
195
- subsequently incorporated within the Work.
196
-
197
- 2. Grant of Copyright License. Subject to the terms and conditions of
198
- this License, each Contributor hereby grants to You a perpetual,
199
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
200
- copyright license to reproduce, prepare Derivative Works of,
201
- publicly display, publicly perform, sublicense, and distribute the
202
- Work and such Derivative Works in Source or Object form.
203
-
204
- 3. Grant of Patent License. Subject to the terms and conditions of
205
- this License, each Contributor hereby grants to You a perpetual,
206
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
207
- (except as stated in this section) patent license to make, have made,
208
- use, offer to sell, sell, import, and otherwise transfer the Work,
209
- where such license applies only to those patent claims licensable
210
- by such Contributor that are necessarily infringed by their
211
- Contribution(s) alone or by combination of their Contribution(s)
212
- with the Work to which such Contribution(s) was submitted. If You
213
- institute patent litigation against any entity (including a
214
- cross-claim or counterclaim in a lawsuit) alleging that the Work
215
- or a Contribution incorporated within the Work constitutes direct
216
- or contributory patent infringement, then any patent licenses
217
- granted to You under this License for that Work shall terminate
218
- as of the date such litigation is filed.
219
-
220
- 4. Redistribution. You may reproduce and distribute copies of the
221
- Work or Derivative Works thereof in any medium, with or without
222
- modifications, and in Source or Object form, provided that You
223
- meet the following conditions:
224
-
225
- (a) You must give any other recipients of the Work or
226
- Derivative Works a copy of this License; and
227
-
228
- (b) You must cause any modified files to carry prominent notices
229
- stating that You changed the files; and
230
-
231
- (c) You must retain, in the Source form of any Derivative Works
232
- that You distribute, all copyright, patent, trademark, and
233
- attribution notices from the Source form of the Work,
234
- excluding those notices that do not pertain to any part of
235
- the Derivative Works; and
236
-
237
- (d) If the Work includes a "NOTICE" text file as part of its
238
- distribution, then any Derivative Works that You distribute must
239
- include a readable copy of the attribution notices contained
240
- within such NOTICE file, excluding those notices that do not
241
- pertain to any part of the Derivative Works, in at least one
242
- of the following places: within a NOTICE text file distributed
243
- as part of the Derivative Works; within the Source form or
244
- documentation, if provided along with the Derivative Works; or,
245
- within a display generated by the Derivative Works, if and
246
- wherever such third-party notices normally appear. The contents
247
- of the NOTICE file are for informational purposes only and
248
- do not modify the License. You may add Your own attribution
249
- notices within Derivative Works that You distribute, alongside
250
- or as an addendum to the NOTICE text from the Work, provided
251
- that such additional attribution notices cannot be construed
252
- as modifying the License.
253
-
254
- You may add Your own copyright statement to Your modifications and
255
- may provide additional or different license terms and conditions
256
- for use, reproduction, or distribution of Your modifications, or
257
- for any such Derivative Works as a whole, provided Your use,
258
- reproduction, and distribution of the Work otherwise complies with
259
- the conditions stated in this License.
260
-
261
- 5. Submission of Contributions. Unless You explicitly state otherwise,
262
- any Contribution intentionally submitted for inclusion in the Work
263
- by You to the Licensor shall be under the terms and conditions of
264
- this License, without any additional terms or conditions.
265
- Notwithstanding the above, nothing herein shall supersede or modify
266
- the terms of any separate license agreement you may have executed
267
- with Licensor regarding such Contributions.
268
-
269
- 6. Trademarks. This License does not grant permission to use the trade
270
- names, trademarks, service marks, or product names of the Licensor,
271
- except as required for reasonable and customary use in describing the
272
- origin of the Work and reproducing the content of the NOTICE file.
273
-
274
- 7. Disclaimer of Warranty. Unless required by applicable law or
275
- agreed to in writing, Licensor provides the Work (and each
276
- Contributor provides its Contributions) on an "AS IS" BASIS,
277
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
278
- implied, including, without limitation, any warranties or conditions
279
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
280
- PARTICULAR PURPOSE. You are solely responsible for determining the
281
- appropriateness of using or redistributing the Work and assume any
282
- risks associated with Your exercise of permissions under this License.
283
-
284
- 8. Limitation of Liability. In no event and under no legal theory,
285
- whether in tort (including negligence), contract, or otherwise,
286
- unless required by applicable law (such as deliberate and grossly
287
- negligent acts) or agreed to in writing, shall any Contributor be
288
- liable to You for damages, including any direct, indirect, special,
289
- incidental, or consequential damages of any character arising as a
290
- result of this License or out of the use or inability to use the
291
- Work (including but not limited to damages for loss of goodwill,
292
- work stoppage, computer failure or malfunction, or any and all
293
- other commercial damages or losses), even if such Contributor
294
- has been advised of the possibility of such damages.
295
-
296
- 9. Accepting Warranty or Additional Liability. While redistributing
297
- the Work or Derivative Works thereof, You may choose to offer,
298
- and charge a fee for, acceptance of support, warranty, indemnity,
299
- or other liability obligations and/or rights consistent with this
300
- License. However, in accepting such obligations, You may act only
301
- on Your own behalf and on Your sole responsibility, not on behalf
302
- of any other Contributor, and only if You agree to indemnify,
303
- defend, and hold each Contributor harmless for any liability
304
- incurred by, or claims asserted against, such Contributor by reason
305
- of your accepting any such warranty or additional liability.
306
-
307
- END OF TERMS AND CONDITIONS
308
-
309
- APPENDIX: How to apply the Apache License to your work.
310
-
311
- To apply the Apache License to your work, attach the following
312
- boilerplate notice, with the fields enclosed by brackets "[]"
313
- replaced with your own identifying information. (Don't include
314
- the brackets!) The text should be enclosed in the appropriate
315
- comment syntax for the file format. We also recommend that a
316
- file or class name and description of purpose be included on the
317
- same "printed page" as the copyright notice for easier
318
- identification within third-party archives.
319
-
320
- Copyright [yyyy] [name of copyright owner]
321
-
322
- Licensed under the Apache License, Version 2.0 (the "License");
323
- you may not use this file except in compliance with the License.
324
- You may obtain a copy of the License at
325
-
326
- http://www.apache.org/licenses/LICENSE-2.0
327
-
328
- Unless required by applicable law or agreed to in writing, software
329
- distributed under the License is distributed on an "AS IS" BASIS,
330
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
331
- See the License for the specific language governing permissions and
332
- limitations under the License.
333
-
334
- ===============================================================================
335
-
336
  PHPSecLib license:
337
 
338
  Copyright 2007-2013 TerraFrost and other contributors
24
 
25
  ===============================================================================
26
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
27
  gelf-php license:
28
 
29
  Copyright (c) 2010-2012 Lennart Koopmann
73
 
74
  ===============================================================================
75
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
76
  PHPSecLib license:
77
 
78
  Copyright 2007-2013 TerraFrost and other contributors
src/MMB/Backup.php DELETED
@@ -1,4612 +0,0 @@
1
- <?php
2
- /*************************************************************
3
- * backup.class.php
4
- * Manage Backups
5
- * Copyright (c) 2011-2014 Prelovac Media
6
- * www.prelovac.com
7
- **************************************************************/
8
-
9
- /**
10
- * The main class for processing database and full backups on ManageWP worker.
11
- *
12
- * @copyright 2011-2014 Prelovac Media
13
- * @version 3.9.30
14
- * @package ManageWP
15
- * @subpackage backup
16
- */
17
- class MMB_Backup extends MMB_Core
18
- {
19
-
20
- public $site_name;
21
-
22
- public $statuses;
23
-
24
- public $tasks;
25
-
26
- public $s3;
27
-
28
- public $ftp;
29
-
30
- public $dropbox;
31
-
32
- public $google_drive;
33
-
34
- private static $zip_errors = array(
35
- 0 => 'No error',
36
- 1 => 'No error',
37
- 2 => 'Unexpected end of zip file',
38
- 3 => 'A generic error in the zipfile format was detected',
39
- 4 => 'zip was unable to allocate itself memory',
40
- 5 => 'A severe error in the zipfile format was detected',
41
- 6 => 'Entry too large to be split with zipsplit',
42
- 7 => 'Invalid comment format',
43
- 8 => 'zip -T failed or out of memory',
44
- 9 => 'The user aborted zip prematurely',
45
- 10 => 'zip encountered an error while using a temp file. Please check if there is enough disk space',
46
- 11 => 'Read or seek error',
47
- 12 => 'zip has nothing to do',
48
- 13 => 'Missing or empty zip file',
49
- 14 => 'Error writing to a file. Please check if there is enough disk space',
50
- 15 => 'zip was unable to create a file to write to',
51
- 16 => 'bad command line parameters',
52
- 17 => 'no error',
53
- 18 => 'zip could not open a specified file to read',
54
- 159 => 'File size limit exceeded',
55
- );
56
-
57
- private static $unzip_errors = array(
58
- 0 => 'No error',
59
- 1 => 'One or more warning errors were encountered, but processing completed successfully anyway',
60
- 2 => 'A generic error in the zipfile format was detected',
61
- 3 => 'A severe error in the zipfile format was detected.',
62
- 4 => 'unzip was unable to allocate itself memory.',
63
- 5 => 'unzip was unable to allocate memory, or encountered an encryption error',
64
- 6 => 'unzip was unable to allocate memory during decompression to disk',
65
- 7 => 'unzip was unable allocate memory during in-memory decompression',
66
- 8 => 'unused',
67
- 9 => 'The specified zipfiles were not found',
68
- 10 => 'Bad command line parameters',
69
- 11 => 'No matching files were found',
70
- 50 => 'The disk is (or was) full during extraction',
71
- 51 => 'The end of the ZIP archive was encountered prematurely.',
72
- 80 => 'The user aborted unzip prematurely.',
73
- 81 => 'Testing or extraction of one or more files failed due to unsupported compression methods or unsupported decryption.',
74
- 82 => 'No files were found due to bad decryption password(s)',
75
- );
76
-
77
- /**
78
- * Initializes site_name, statuses, and tasks attributes.
79
- */
80
- public function __construct()
81
- {
82
- parent::__construct();
83
- $this->site_name = str_replace(array("_", "/", "~", ":"), array("", "-", "-", "-"), rtrim($this->remove_http(get_bloginfo('url')), "/"));
84
- $this->statuses = array(
85
- 'db_dump' => 1,
86
- 'db_zip' => 2,
87
- 'files_zip' => 3,
88
- 's3' => 4,
89
- 'dropbox' => 5,
90
- 'ftp' => 6,
91
- 'email' => 7,
92
- 'google_drive' => 8,
93
- 'sftp' => 9,
94
- 'finished' => 100,
95
- );
96
-
97
- $this->w3tc_flush();
98
-
99
- $this->tasks = get_option('mwp_backup_tasks');
100
- }
101
-
102
- /**
103
- * Tries to increase memory limit to 384M and execution time to 600s.
104
- *
105
- * @return array an array with two keys for execution time and memory limit (0 - if not changed, 1 - if succesfully)
106
- */
107
- public function set_memory()
108
- {
109
- $changed = array('execution_time' => 0, 'memory_limit' => 0);
110
- ignore_user_abort(true);
111
- $tryLimit = 384;
112
-
113
- $limit = mwp_format_memory_limit(ini_get('memory_limit'));
114
-
115
- $matched = preg_match('/^(\d+) ([KMG]?B)$/', $limit, $match);
116
-
117
- if ($matched
118
- && (
119
- ($match[2] === 'GB')
120
- || ($match[2] === 'MB' && (int) $match[1] >= $tryLimit)
121
- )
122
- ) {
123
- // Memory limits are satisfied.
124
- } else {
125
- ini_set('memory_limit', $tryLimit.'M');
126
- $changed['memory_limit'] = 1;
127
- }
128
- if (!mwp_is_safe_mode() && ((int) ini_get('max_execution_time') < 4000) && (ini_get('max_execution_time') !== '0')) {
129
- ini_set('max_execution_time', 4000);
130
- set_time_limit(4000);
131
- $changed['execution_time'] = 1;
132
- }
133
-
134
- return $changed;
135
- }
136
-
137
- /**
138
- * Returns backup settings from local database for all tasks
139
- *
140
- * @return mixed|boolean
141
- */
142
- public function get_backup_settings()
143
- {
144
- $backup_settings = get_option('mwp_backup_tasks');
145
-
146
- if (!empty($backup_settings)) {
147
- return $backup_settings;
148
- } else {
149
- return false;
150
- }
151
- }
152
-
153
- /**
154
- * Sets backup task defined from master, if task name is "Backup Now" this function fires processing backup.
155
- *
156
- * @param mixed $params parameters sent from master
157
- *
158
- * @return mixed|boolean $this->tasks variable if success, array with error message if error has ocurred, false if $params are empty
159
- */
160
- public function set_backup_task($params)
161
- {
162
- //$params => [$task_name, $args, $error]
163
- if (!empty($params)) {
164
- if (!empty($params['secure'])) {
165
- $secure = (array) $params['secure'];
166
- $secure = array_map('base64_decode', $secure);
167
- if ($secureKey = mwp_container()->getConfiguration()->getSecureKey()) {
168
- $secure = implode('', $secure);
169
- require_once dirname(__FILE__).'/../PHPSecLib/Crypt/AES.php';
170
- $cipher = new Crypt_AES(CRYPT_AES_MODE_ECB);
171
- $cipher->setKey($secureKey);
172
- $decrypted = array('account_info' => json_decode($cipher->decrypt($secure), true));
173
- } else {
174
- $decrypted = '';
175
- $publicKey = mwp_container()->getConfiguration()->getPublicKey();
176
- $crypter = mwp_container()->getCrypter();
177
- foreach ($secure as $segment) {
178
- $decrypted .= $crypter->publicDecrypt($segment, $publicKey);
179
- }
180
- $decrypted = unserialize($decrypted);
181
- }
182
- $params = array_merge($params, (array) $decrypted);
183
- }
184
- extract($params);
185
-
186
- //$before = $this->get_backup_settings();
187
- $before = $this->tasks;
188
- if (!$before || empty($before)) {
189
- $before = array();
190
- }
191
-
192
- if (isset($args['remove'])) {
193
- unset($before[$task_name]);
194
- $return = array(
195
- 'removed' => true,
196
- );
197
- } else {
198
- if (isset($params['account_info']) && is_array($params['account_info'])) { //only if sends from master first time(secure data)
199
- $args['account_info'] = $account_info;
200
- }
201
-
202
- $before[$task_name]['task_args'] = $args;
203
- $return = $before[$task_name];
204
- }
205
-
206
- //Update with error
207
- if (isset($error)) {
208
- if (is_array($error)) {
209
- $before[$task_name]['task_results'][count($before[$task_name]['task_results']) - 1]['error'] = $error['error'];
210
- } else {
211
- $before[$task_name]['task_results'][count($before[$task_name]['task_results']) - 1]['error'] = $error;
212
- }
213
- }
214
-
215
- if (isset($time) && $time) { //set next result time before backup
216
- if (is_array($before[$task_name]['task_results'])) {
217
- $before[$task_name]['task_results'] = array_values($before[$task_name]['task_results']);
218
- }
219
- $before[$task_name]['task_results'][count($before[$task_name]['task_results'])]['time'] = $time;
220
- }
221
-
222
- $this->update_tasks($before);
223
-
224
- if ($task_name == 'Backup Now') {
225
- $resultUuid = !empty($params['resultUuid']) ? $params['resultUuid'] : false;
226
- $result = $this->backup($args, $task_name, $resultUuid);
227
- $backup_settings = $this->tasks;
228
-
229
- if (is_array($result) && array_key_exists('error', $result)) {
230
- $return = $result;
231
- } else {
232
- $return = $backup_settings[$task_name];
233
- }
234
- }
235
-
236
- return $return;
237
- }
238
-
239
- return false;
240
- }
241
-
242
- /**
243
- * Runs backup task invoked from ManageWP master.
244
- *
245
- * @param string $task_name name of backup task
246
- * @param string|bool[optional] $google_drive_token false if backup destination is not Google Drive, json of Google Drive token if it is remote destination (default: false)
247
- * @param bool $resultUuid
248
- *
249
- * @return mixed array with backup statistics if successful, array with error message if not
250
- */
251
- public function task_now($task_name, $google_drive_token = false, $resultUuid = false)
252
- {
253
- if ($google_drive_token) {
254
- $this->tasks[$task_name]['task_args']['account_info']['mwp_google_drive']['google_drive_token'] = $google_drive_token;
255
- }
256
-
257
- $settings = $this->tasks;
258
- if (!array_key_exists($task_name, $settings)) {
259
- return array('error' => $task_name." does not exist.");
260
- } else {
261
- $setting = $settings[$task_name];
262
- }
263
-
264
- $this->set_backup_task(array(
265
- 'task_name' => $task_name,
266
- 'args' => $settings[$task_name]['task_args'],
267
- 'time' => time(),
268
- ));
269
-
270
- //Run backup
271
- $result = $this->backup($setting['task_args'], $task_name, $resultUuid);
272
-
273
- //Check for error
274
- if (is_array($result) && array_key_exists('error', $result)) {
275
- $this->set_backup_task(array(
276
- 'task_name' => $task_name,
277
- 'args' => $settings[$task_name]['task_args'],
278
- 'error' => $result['error'],
279
- ));
280
-
281
- return $result;
282
- } else {
283
- return $this->get_backup_stats();
284
- }
285
- }
286
-
287
- /**
288
- * Backup a full wordpress instance, including a database dump, which is placed in mwp_db dir in root folder.
289
- * All backups are compressed by zip and placed in wp-content/managewp/backups folder.
290
- *
291
- * @param string $args arguments passed from master
292
- * [type] -> db, full
293
- * [what] -> daily, weekly, monthly
294
- * [account_info] -> remote destinations ftp, amazons3, dropbox, google_drive, email with their parameters
295
- * [include] -> array of folders from site root which are included to backup (wp-admin, wp-content, wp-includes are default)
296
- * [exclude] -> array of files of folders to exclude, relative to site's root
297
- * @param bool|string[optional] $task_name the name of backup task, which backup is done (default: false)
298
- * @param bool $resultUuid unique identifier for backup result
299
- *
300
- * @return bool|array false if $args are missing, array with error if error has occured, ture if is successful
301
- */
302
- public function backup($args, $task_name = false, $resultUuid = false)
303
- {
304
- if (!$args || empty($args)) {
305
- return false;
306
- }
307
-
308
- extract($args); //extract settings
309
-
310
- if (!empty($account_info)) {
311
- $found = false;
312
- $destinations = array('mwp_ftp', 'mwp_sftp', 'mwp_amazon_s3', 'mwp_dropbox', 'mwp_google_drive', 'mwp_email');
313
- foreach ($destinations as $dest) {
314
- $found = $found || (isset($account_info[$dest]));
315
- }
316
- if (!$found) {
317
- $error_message = 'Remote destination is not supported, please update your client plugin.';
318
-
319
- return array(
320
- 'error' => $error_message,
321
- );
322
- }
323
- }
324
-
325
- //Try increase memory limit and execution time
326
- $this->set_memory();
327
-
328
- //Remove old backup(s)
329
- $removed = $this->remove_old_backups($task_name);
330
- if (is_array($removed) && isset($removed['error'])) {
331
- $error_message = $removed['error'];
332
-
333
- return $removed;
334
- }
335
-
336
- $new_file_path = MWP_BACKUP_DIR;
337
-
338
- if (!file_exists($new_file_path)) {
339
- if (!mkdir($new_file_path, 0755, true)) {
340
- return array(
341
- 'error' => 'Permission denied, make sure you have write permissions to the wp-content folder.',
342
- );
343
- }
344
- }
345
-
346
- @file_put_contents($new_file_path.'/index.php', ''); //safe
347
-
348
- //Prepare .zip file name
349
- $hash = md5(time());
350
- $label = !empty($type) ? $type : 'manual';
351
- $backup_file = $new_file_path.'/'.$this->site_name.'_'.$label.'_'.$what.'_'.date('Y-m-d').'_'.$hash.'.zip';
352
- $backup_url = WP_CONTENT_URL.'/managewp/backups/'.$this->site_name.'_'.$label.'_'.$what.'_'.date('Y-m-d').'_'.$hash.'.zip';
353
-
354
- $begin_compress = microtime(true);
355
-
356
- //Optimize tables?
357
- if (isset($optimize_tables) && !empty($optimize_tables)) {
358
- $this->optimize_tables();
359
- }
360
-
361
- //What to backup - db or full?
362
- if (trim($what) == 'db') {
363
- $db_backup = $this->backup_db_compress($task_name, $backup_file);
364
- if (is_array($db_backup) && array_key_exists('error', $db_backup)) {
365
- $error_message = $db_backup['error'];
366
-
367
- return array(
368
- 'error' => $error_message,
369
- );
370
- }
371
- } elseif (trim($what) == 'full') {
372
- if (!$exclude) {
373
- $exclude = array();
374
- }
375
- if (!$include) {
376
- $include = array();
377
- }
378
- $content_backup = $this->backup_full($task_name, $backup_file, $exclude, $include);
379
- if (is_array($content_backup) && array_key_exists('error', $content_backup)) {
380
- $error_message = $content_backup['error'];
381
-
382
- return array(
383
- 'error' => $error_message,
384
- );
385
- }
386
- }
387
-
388
- $end_compress = microtime(true);
389
-
390
- //Update backup info
391
- if ($task_name) {
392
- //backup task (scheduled)
393
- $backup_settings = $this->tasks;
394
- $paths = array();
395
- $size = ceil(filesize($backup_file) / 1024);
396
- $duration = round($end_compress - $begin_compress, 2);
397
-
398
- if ($size > 1000) {
399
- $paths['size'] = ceil($size / 1024)."MB";
400
- } else {
401
- $paths['size'] = $size.'KB';
402
- }
403
-
404
- $paths['duration'] = $duration.'s';
405
- if ($resultUuid) {
406
- $paths['resultUuid'] = $resultUuid;
407
- }
408
-
409
- if ($task_name != 'Backup Now') {
410
- $paths['server'] = array(
411
- 'file_path' => $backup_file,
412
- 'file_url' => $backup_url,
413
- );
414
- } else {
415
- $paths['server'] = array(
416
- 'file_path' => $backup_file,
417
- 'file_url' => $backup_url,
418
- );
419
- }
420
-
421
- if (isset($backup_settings[$task_name]['task_args']['account_info']['mwp_ftp'])) {
422
- $paths['ftp'] = basename($backup_url);
423
- }
424
-
425
- if (isset($backup_settings[$task_name]['task_args']['account_info']['mwp_sftp'])) {
426
- $paths['sftp'] = basename($backup_url);
427
- }
428
- if (isset($backup_settings[$task_name]['task_args']['account_info']['mwp_amazon_s3'])) {
429
- $paths['amazons3'] = basename($backup_url);
430
- }
431
-
432
- if (isset($backup_settings[$task_name]['task_args']['account_info']['mwp_dropbox'])) {
433
- $paths['dropbox'] = basename($backup_url);
434
- }
435
-
436
- if (isset($backup_settings[$task_name]['task_args']['account_info']['mwp_email'])) {
437
- $paths['email'] = basename($backup_url);
438
- }
439
-
440
- if (isset($backup_settings[$task_name]['task_args']['account_info']['mwp_google_drive'])) {
441
- $paths['google_drive'] = array(
442
- 'file' => basename($backup_url),
443
- 'file_id' => ''
444
- );
445
- }
446
-
447
- $temp = $backup_settings[$task_name]['task_results'];
448
- $temp = @array_values($temp);
449
- $paths['time'] = time();
450
-
451
- if ($task_name != 'Backup Now') {
452
- $paths['status'] = $temp[count($temp) - 1]['status'];
453
- $temp[count($temp) - 1] = $paths;
454
- } else {
455
- $temp[count($temp)] = $paths;
456
- }
457
-
458
- $backup_settings[$task_name]['task_results'] = $temp;
459
- $this->update_tasks($backup_settings);
460
- }
461
-
462
- // If there are not remote destination, set up task status to finished
463
- if (@count($backup_settings[$task_name]['task_args']['account_info']) == 0) {
464
- $this->update_status($task_name, $this->statuses['finished'], true);
465
- }
466
-
467
- return true;
468
- }
469
-
470
- /**
471
- * Backup a full wordpress instance, including a database dump, which is placed in mwp_db dir in root folder.
472
- * All backups are compressed by zip and placed in wp-content/managewp/backups folder.
473
- *
474
- * @param string $task_name the name of backup task, which backup is done
475
- * @param string $backup_file relative path to file which backup is stored
476
- * @param array [optional] $exclude the list of files and folders, which are excluded from backup (default: array())
477
- * @param array [optional] $include the list of folders in wordpress root which are included to backup, expect wp-admin, wp-content, wp-includes, which are default (default: array())
478
- *
479
- * @return bool|array true if backup is successful, or an array with error message if is failed
480
- */
481
- public function backup_full($task_name, $backup_file, $exclude = array(), $include = array())
482
- {
483
- $this->update_status($task_name, $this->statuses['db_dump']);
484
- $db_result = $this->backup_db();
485
-
486
- if ($db_result == false) {
487
- return array(
488
- 'error' => 'Failed to backup database.',
489
- );
490
- } else {
491
- if (is_array($db_result) && isset($db_result['error'])) {
492
- return array(
493
- 'error' => $db_result['error'],
494
- );
495
- }
496
- }
497
-
498
- $this->update_status($task_name, $this->statuses['db_dump'], true);
499
- $this->update_status($task_name, $this->statuses['db_zip']);
500
-
501
- @file_put_contents(MWP_BACKUP_DIR.'/mwp_db/index.php', '');
502
- $zip_db_result = $this->zip_backup_db($task_name, $backup_file);
503
-
504
- if (!$zip_db_result) {
505
- $zip_archive_db_result = false;
506
- if (class_exists("ZipArchive")) {
507
- mwp_logger()->debug('DB zip, fallback to ZipArchive');
508
- $zip_archive_db_result = $this->zip_archive_backup_db($task_name, $db_result, $backup_file);
509
- }
510
-
511
- if (!$zip_archive_db_result) {
512
- mwp_logger()->debug('DB zip, fallback to PclZip');
513
- $pclzip_db_result = $this->pclzip_backup_db($task_name, $backup_file);
514
- if (!$pclzip_db_result) {
515
- @unlink(MWP_BACKUP_DIR.'/mwp_db/index.php');
516
- @unlink(MWP_BACKUP_DIR.'/mwp_db/info.json');
517
- @unlink($db_result);
518
- @rmdir(MWP_DB_DIR);
519
-
520
- if ($archive->error_code != '') {
521
- $archive->error_code = 'pclZip error ('.$archive->error_code.'): .';
522
- }
523
-
524
- return array(
525
- 'error' => 'Failed to zip database. '.$archive->error_code.$archive->error_string,
526
- );
527
- }
528
- }
529
- }
530
-
531
- @unlink(MWP_BACKUP_DIR.'/mwp_db/index.php');
532
- @unlink(MWP_BACKUP_DIR.'/mwp_db/info.json');
533
- @unlink($db_result);
534
- @rmdir(MWP_DB_DIR);
535
-
536
- $remove = array(
537
- trim(basename(WP_CONTENT_DIR))."/managewp/backups",
538
- trim(basename(WP_CONTENT_DIR))."/infinitewp/backups",
539
- trim(basename(WP_CONTENT_DIR))."/".md5('mmb-worker')."/mwp_backups",
540
- trim(basename(WP_CONTENT_DIR))."/backupwordpress",
541
- trim(basename(WP_CONTENT_DIR))."/contents/cache",
542
- trim(basename(WP_CONTENT_DIR))."/content/cache",
543
- trim(basename(WP_CONTENT_DIR))."/cache",
544
- trim(basename(WP_CONTENT_DIR))."/old-cache",
545
- trim(basename(WP_CONTENT_DIR))."/uploads/backupbuddy_backups",
546
- trim(basename(WP_CONTENT_DIR))."/w3tc",
547
- "error_log",
548
- "dbcache",
549
- "pgcache",
550
- "objectcache",
551
- );
552
- $exclude = array_merge($exclude, $remove);
553
-
554
- $this->update_status($task_name, $this->statuses['db_zip'], true);
555
- $this->update_status($task_name, $this->statuses['files_zip']);
556
-
557
- if (function_exists('proc_open') && $this->zipExists()) {
558
- $zip_result = $this->zip_backup($task_name, $backup_file, $exclude, $include);
559
- } else {
560
- $zip_result = false;
561
- }
562
-
563
- if (isset($zip_result['error'])) {
564
- return $zip_result;
565
- }
566
-
567
- if (!$zip_result) {
568
- $zip_archive_result = false;
569
- if (class_exists("ZipArchive")) {
570
- mwp_logger()->debug('Files zip fallback to ZipArchive');
571
- $zip_archive_result = $this->zip_archive_backup($task_name, $backup_file, $exclude, $include);
572
- }
573
-
574
- if (!$zip_archive_result) {
575
- mwp_logger()->debug('Files zip fallback to PclZip');
576
- $pclzip_result = $this->pclzip_backup($task_name, $backup_file, $exclude, $include);
577
- if (!$pclzip_result) {
578
- @unlink(MWP_BACKUP_DIR.'/mwp_db/index.php');
579
- @unlink($db_result);
580
- @rmdir(MWP_DB_DIR);
581
-
582
- if (!$pclzip_result) {
583
- @unlink($backup_file);
584
-
585
- return array(
586
- 'error' => 'Failed to zip files. pclZip error ('.$archive->error_code.'): .'.$archive->error_string,
587
- );
588
- }
589
- }
590
- }
591
- }
592
-
593
- //Reconnect
594
- $this->wpdb_reconnect();
595
-
596
- $this->update_status($task_name, $this->statuses['files_zip'], true);
597
-
598
- return true;
599
- }
600
-
601
- /**
602
- * Zipping database dump and index.php in folder mwp_db by system zip command, requires zip installed on OS.
603
- *
604
- * @param string $taskName the name of backup task
605
- * @param string $backupFile absolute path to zip file
606
- *
607
- * @return bool is compress successful or not
608
- * @todo report errors back to the user
609
- * @todo report error if DB dump is not found
610
- */
611
- public function zip_backup_db($taskName, $backupFile)
612
- {
613
- $disableCompression = $this->tasks[$taskName]['task_args']['disable_comp'];
614
-
615
- $compressionLevel = $disableCompression ? '-0' : '-1'; // -0 - store files (no compression); -1 to -9 compress fastest to compress best (default is 6)
616
-
617
- $zip = mwp_container()->getExecutableFinder()->find('zip', 'zip');
618
-
619
- $processBuilder = Symfony_Process_ProcessBuilder::create()
620
- ->setWorkingDirectory(untrailingslashit(MWP_BACKUP_DIR))
621
- ->setTimeout(3600)
622
- ->setPrefix($zip)
623
- ->add('-q')// quiet operation
624
- ->add('-r')// recurse paths, include files in subdirs: zip -r a path path ...
625
- ->add($compressionLevel)
626
- ->add($backupFile)// zipfile to write to
627
- ->add('mwp_db') // file/directory list
628
- ;
629
-
630
- try {
631
- if (!mwp_is_shell_available()) {
632
- throw new MMB_Exception("Shell is not available");
633
- }
634
- $process = $processBuilder->getProcess();
635
- mwp_logger()->debug('Database compression process started', array(
636
- 'executable_location' => $zip,
637
- 'command_line' => $process->getCommandLine(),
638
- ));
639
- $process->start();
640
- while ($process->isRunning()) {
641
- sleep(1);
642
- echo ".";
643
- flush();
644
- mwp_logger()->debug('Compressing...');
645
- }
646
-
647
- if (!$process->isSuccessful()) {
648
- throw new Symfony_Process_Exception_ProcessFailedException($process);
649
- }
650
- mwp_logger()->info('Database compression process finished');
651
-
652
- return true;
653
- } catch (Symfony_Process_Exception_ProcessFailedException $e) {
654
- mwp_logger()->error('Database compression process failed', array(
655
- 'process' => $e->getProcess(),
656
- ));
657
- } catch (Exception $e) {
658
- mwp_logger()->error('Error while trying to execute database compression process', array(
659
- 'exception' => $e,
660
- ));
661
- }
662
-
663
- return false;
664
- }
665
-
666
- /**
667
- * Zipping database dump and index.php in folder mwp_db by ZipArchive class, requires php zip extension.
668
- *
669
- * @param string $task_name the name of backup task
670
- * @param string $db_result relative path to database dump file
671
- * @param string $backup_file absolute path to zip file
672
- *
673
- * @return bool is compress successful or not
674
- */
675
- public function zip_archive_backup_db($task_name, $db_result, $backup_file)
676
- {
677
- $disable_comp = $this->tasks[$task_name]['task_args']['disable_comp'];
678
- $zip = new ZipArchive();
679
- $result = $zip->open($backup_file, ZIPARCHIVE::OVERWRITE); // Tries to open $backup_file for acrhiving
680
- if ($result === true) {
681
- $result = $result && $zip->addFile(MWP_BACKUP_DIR.'/mwp_db/index.php', "mwp_db/index.php"); // Tries to add mwp_db/index.php to $backup_file
682
- $result = $result && $zip->addFile($db_result, "mwp_db/".basename($db_result)); // Tries to add db dump form mwp_db dir to $backup_file
683
- $result = $result && $zip->close(); // Tries to close $backup_file
684
- } else {
685
- $result = false;
686
- }
687
- if ($result) {
688
- mwp_logger()->info('ZipArchive database compression process finished');
689
- } else {
690
- mwp_logger()->error('Error while trying to zip DB with ZipArchive');
691
- }
692
-
693
- return $result; // true if $backup_file iz zipped successfully, false if error is occured in zip process
694
- }
695
-
696
- /**
697
- * Zipping database dump and index.php in folder mwp_db by PclZip library.
698
- *
699
- * @param string $task_name the name of backup task
700
- * @param string $backup_file absolute path to zip file
701
- *
702
- * @return bool is compress successful or not
703
- */
704
- public function pclzip_backup_db($task_name, $backup_file)
705
- {
706
- $disable_comp = $this->tasks[$task_name]['task_args']['disable_comp'];
707
- define('PCLZIP_TEMPORARY_DIR', MWP_BACKUP_DIR.'/');
708
- require_once ABSPATH.'/wp-admin/includes/class-pclzip.php';
709
- $zip = new PclZip($backup_file);
710
-
711
- if ($disable_comp) {
712
- $result = $zip->add(MWP_BACKUP_DIR."/mwp_db/", PCLZIP_OPT_REMOVE_PATH, MWP_BACKUP_DIR, PCLZIP_OPT_NO_COMPRESSION) !== 0;
713
- } else {
714
- $result = $zip->add(MWP_BACKUP_DIR."/mwp_db/", PCLZIP_OPT_REMOVE_PATH, MWP_BACKUP_DIR) !== 0;
715
- }
716
-
717
- return $result;
718
- }
719
-
720
- /**
721
- * Zipping whole site root folder and append to backup file with database dump
722
- * by system zip command, requires zip installed on OS.
723
- *
724
- * @param string $task_name the name of backup task
725
- * @param string $backupFile absolute path to zip file
726
- * @param array $exclude array of files of folders to exclude, relative to site's root
727
- * @param array $include array of folders from site root which are included to backup (wp-admin, wp-content, wp-includes are default)
728
- *
729
- * @return array|bool true if successful or an array with error message if not
730
- */
731
- public function zip_backup($task_name, $backupFile, $exclude, $include)
732
- {
733
- $compressionLevel = $this->tasks[$task_name]['task_args']['disable_comp'] ? 0 : 1;
734
-
735
- try {
736
- $this->backupRootFiles($compressionLevel, $backupFile, $exclude);
737
- } catch (Exception $e) {
738
- return array(
739
- 'error' => $e->getMessage(),
740
- );
741
- }
742
- try {
743
- $this->backupDirectories($compressionLevel, $backupFile, $exclude, $include);
744
- } catch (Exception $e) {
745
- return array(
746
- 'error' => $e->getMessage(),
747
- );
748
- }
749
-
750
- return true;
751
- }
752
-
753
- private function backupRootFiles($compressionLevel, $backupFile, $exclude)
754
- {
755
- $zip = mwp_container()->getExecutableFinder()->find('zip', 'zip');
756
- $arguments = array($zip, '-q', '-j', '-'.$compressionLevel, $backupFile);
757
- $fileExclusions = array('../', 'error_log');
758
- foreach ($exclude as $exclusion) {
759
- if (is_file(ABSPATH.$exclusion)) {
760
- $fileExclusions[] = $exclusion;
761
- }
762
- }
763
-
764
- $parentWpConfig = '';
765
- if (!file_exists(ABSPATH.'wp-config.php')
766
- && file_exists(dirname(ABSPATH).'/wp-config.php')
767
- && !file_exists(dirname(ABSPATH).'/wp-settings.php')
768
- ) {
769
- $parentWpConfig = '../wp-config.php';
770
- }
771
-
772
- $command = implode(' ', array_map(array('Symfony_Process_ProcessUtils', 'escapeArgument'), $arguments))." .* ./* $parentWpConfig";
773
-
774
- if ($fileExclusions) {
775
- $command .= ' '.implode(' ', array_map(array('Symfony_Process_ProcessUtils', 'escapeArgument'), array_merge(array('-x'), $fileExclusions)));
776
- }
777
-
778
- try {
779
- if (!mwp_is_shell_available()) {
780
- throw new MMB_Exception("Shell is not available");
781
- }
782
- $process = new Symfony_Process_Process($command, untrailingslashit(ABSPATH), null, null, 3600);
783
- mwp_logger()->debug('Root files compression process started', array(
784
- 'executable_location' => $zip,
785
- 'command_line' => $process->getCommandLine(),
786
- ));
787
- $process->start();
788
- while ($process->isRunning()) {
789
- sleep(1);
790
- echo ".";
791
- flush();
792
- mwp_logger()->debug('Compressing...');
793
- }
794
-
795
- if ($process->isSuccessful()) {
796
- mwp_logger()->info('Root files compression process finished');
797
- } elseif ($process->getExitCode() === 18) {
798
- mwp_logger()->notice('Root files compression process finished with warnings; some files could not be read', array(
799
- 'process' => $process,
800
- ));
801
- } else {
802
- throw new Symfony_Process_Exception_ProcessFailedException($process);
803
- }
804
- } catch (Symfony_Process_Exception_ProcessFailedException $e) {
805
- mwp_logger()->error('Root files compression process failed', array(
806
- 'process' => $e->getProcess(),
807
- ));
808
- throw $e;
809
- } catch (Exception $e) {
810
- mwp_logger()->error('Error while trying to execute root files compression process', array(
811
- 'exception' => $e,
812
- ));
813
- throw $e;
814
- }
815
- }
816
-
817
- private function backupDirectories($compressionLevel, $backupFile, $exclude, $include)
818
- {
819
- $zip = mwp_container()->getExecutableFinder()->find('zip', 'zip');
820
-
821
- $processBuilder = Symfony_Process_ProcessBuilder::create()
822
- ->setWorkingDirectory(untrailingslashit(ABSPATH))
823
- ->setTimeout(3600)
824
- ->setPrefix($zip)
825
- ->add('-q')
826
- ->add('-r')
827
- ->add('-'.$compressionLevel)
828
- ->add($backupFile)
829
- ->add('.');
830
-
831
- $uploadDir = wp_upload_dir();
832
-
833
- $inclusions = array(
834
- WPINC,
835
- basename(WP_CONTENT_DIR),
836
- 'wp-admin',
837
- );
838
-
839
- $path = wp_upload_dir();
840
- $path = $path['path'];
841
- if (strpos($path, WP_CONTENT_DIR) === false && strpos($path, ABSPATH) === 0) {
842
- $inclusions[] = ltrim(substr($path, strlen(ABSPATH)), ' /');
843
- }
844
-
845
- $include = array_merge($include, $inclusions);
846
- $include = array_map('untrailingslashit', $include);
847
- foreach ($include as $inclusion) {
848
- if (is_dir(ABSPATH.$inclusion)) {
849
- $inclusions[] = $inclusion.'/*';
850
- } else {
851
- $inclusions[] = $inclusion;
852
- }
853
- }
854
-
855
- $processBuilder->add('-i');
856
- foreach ($inclusions as $inclusion) {
857
- $processBuilder->add($inclusion);
858
- }
859
-
860
- $exclusions = array();
861
- $exclude = array_map('untrailingslashit', $exclude);
862
- foreach ($exclude as $exclusion) {
863
- if (is_dir(ABSPATH.$exclusion)) {
864
- $exclusions[] = $exclusion.'/*';
865
- } else {
866
- $exclusions[] = $exclusion;
867
- }
868
- }
869
-
870
- if ($exclusions) {
871
- $processBuilder->add('-x');
872
- foreach ($exclusions as $exclusion) {
873
- $processBuilder->add($exclusion);
874
- }
875
- }
876
-
877
- try {
878
- if (!mwp_is_shell_available()) {
879
- throw new MMB_Exception("Shell is not available");
880
- }
881
- $process = $processBuilder->getProcess();
882
- mwp_logger()->info('Directory compression process started', array(
883
- 'executable_location' => $zip,
884
- 'command_line' => $process->getCommandLine(),
885
- ));
886
- $process->start();
887
- while ($process->isRunning()) {
888
- sleep(1);
889
- echo ".";
890
- flush();
891
- mwp_logger()->debug('Compressing...');
892
- }
893
-
894
- if ($process->isSuccessful()) {
895
- mwp_logger()->info('Directory compression process successfully completed');
896
- } elseif ($process->getExitCode() === 18) {
897
- mwp_logger()->notice('Directory compression process finished with warnings; some files could not be read', array(
898
- 'process' => $process,
899
- ));
900
- } else {
901
- throw new Symfony_Process_Exception_ProcessFailedException($process);
902
- }
903
- } catch (Symfony_Process_Exception_ProcessFailedException $e) {
904
- mwp_logger()->error('Directory compression process failed', array(
905
- 'process' => $e->getProcess(),
906
- ));
907
- throw $e;
908
- } catch (Exception $e) {
909
- mwp_logger()->error('Error while trying to execute directory compression process', array(
910
- 'exception' => $e,
911
- ));
912
- throw $e;
913
- }
914
- }
915
-
916
- /**
917
- * Zipping whole site root folder and append to backup file with database dump
918
- * by ZipArchive class, requires php zip extension.
919
- *
920
- * @param string $task_name the name of backup task
921
- * @param string $backup_file absolute path to zip file
922
- * @param array $exclude array of files of folders to exclude, relative to site's root
923
- * @param array $include array of folders from site root which are included to backup (wp-admin, wp-content, wp-includes are default)
924
- *
925
- * @return array|bool true if successful or an array with error message if not
926
- */
927
- public function zip_archive_backup($task_name, $backup_file, $exclude, $include, $overwrite = false)
928
- {
929
- $filelist = $this->get_backup_files($exclude, $include);
930
- $disable_comp = $this->tasks[$task_name]['task_args']['disable_comp'];
931
- if (!$disable_comp) {
932
- mwp_logger()->warning('Compression is not supported by ZipArchive');
933
- }
934
-
935
- $zip = new ZipArchive();
936
- if ($overwrite) {
937
- $result = $zip->open($backup_file, ZipArchive::OVERWRITE); // Tries to open $backup_file for archiving
938
- } else {
939
- $result = $zip->open($backup_file); // Tries to open $backup_file for archiving
940
- }
941
- if ($result === true) {
942
- foreach ($filelist as $file) {
943
- $pathInZip = strpos($file, ABSPATH) === false ? basename($file) : str_replace(ABSPATH, '', $file);
944
- $result = $result && $zip->addFile($file, $pathInZip); // Tries to add a new file to $backup_file
945
- }
946
- $result = $result && $zip->close(); // Tries to close $backup_file
947
- } else {
948
- $result = false;
949
- }
950
- if ($result) {
951
- mwp_logger()->info('ZipArchive files compression process finished');
952
- } else {
953
- mwp_logger()->error('Error while trying to zip files with ZipArchive');
954
- }
955
-
956
- return $result; // true if $backup_file iz zipped successfully, false if error is occured in zip process
957
- }
958
-
959
- /**
960
- * Zipping whole site root folder and append to backup file with database dump
961
- * by PclZip library.
962
- *
963
- * @param string $task_name the name of backup task
964
- * @param string $backup_file absolute path to zip file
965
- * @param array $exclude array of files of folders to exclude, relative to site's root
966
- * @param array $include array of folders from site root which are included to backup (wp-admin, wp-content, wp-includes are default)
967
- *
968
- * @return array|bool true if successful or an array with error message if not
969
- */
970
- public function pclzip_backup($task_name, $backup_file, $exclude, $include)
971
- {
972
- define('PCLZIP_TEMPORARY_DIR', MWP_BACKUP_DIR.'/');
973
- require_once ABSPATH.'/wp-admin/includes/class-pclzip.php';
974
- $zip = new PclZip($backup_file);
975
- $add = array(
976
- trim(WPINC),
977
- trim(basename(WP_CONTENT_DIR)),
978
- 'wp-admin',
979
- );
980
-
981
- if (!file_exists(ABSPATH.'wp-config.php')
982
- && file_exists(dirname(ABSPATH).'/wp-config.php')
983
- && !file_exists(dirname(ABSPATH).'/wp-settings.php')
984
- ) {
985
- $include[] = '../wp-config.php';
986
- }
987
-
988
- $path = wp_upload_dir();
989
- $path = $path['path'];
990
- if (strpos($path, WP_CONTENT_DIR) === false && strpos($path, ABSPATH) === 0) {
991
- $add[] = ltrim(substr($path, strlen(ABSPATH)), ' /');
992
- }
993
-
994
- $include_data = array();
995
- if (!empty($include)) {
996
- foreach ($include as $data) {
997
- if ($data && file_exists(ABSPATH.$data)) {
998
- $include_data[] = ABSPATH.$data.'/';
999
- }
1000
- }
1001
- }
1002
- $include_data = array_merge($add, $include_data);
1003
-
1004
- if ($handle = opendir(ABSPATH)) {
1005
- while (false !== ($file = readdir($handle))) {
1006
- if ($file != "." && $file != ".." && !is_dir($file) && file_exists(ABSPATH.$file)) {
1007
- $include_data[] = ABSPATH.$file;
1008
- }
1009
- }
1010
- closedir($handle);
1011
- }
1012
-
1013
- $disable_comp = $this->tasks[$task_name]['task_args']['disable_comp'];
1014
-
1015
- if ($disable_comp) {
1016
- $result = $zip->add($include_data, PCLZIP_OPT_REMOVE_PATH, ABSPATH, PCLZIP_OPT_NO_COMPRESSION) !== 0;
1017
- } else {
1018
- $result = $zip->add($include_data, PCLZIP_OPT_REMOVE_PATH, ABSPATH) !== 0;
1019
- }
1020
-
1021
- $exclude_data = array();
1022
- if (!empty($exclude)) {
1023
- foreach ($exclude as $data) {
1024
- if (file_exists(ABSPATH.$data)) {
1025
- if (is_dir(ABSPATH.$data)) {
1026
- $exclude_data[] = $data.'/';
1027
- } else {
1028
- $exclude_data[] = $data;
1029
- }
1030
- }
1031
- }
1032
- }
1033
- $result = $result && $zip->delete(PCLZIP_OPT_BY_NAME, $exclude_data);
1034
-
1035
- return $result;
1036
- }
1037
-
1038
- /**
1039
- * Gets an array of relative paths of all files in site root recursively.
1040
- * By default, there are all files from root folder, all files from folders wp-admin, wp-content, wp-includes recursively.
1041
- * Parameter $include adds other folders from site root, and excludes any file or folder by relative path to site's root.
1042
- *
1043
- * @param array $exclude array of files of folders to exclude, relative to site's root
1044
- * @param array $include array of folders from site root which are included to backup (wp-admin, wp-content, wp-includes are default)
1045
- *
1046
- * @return array array with all files in site root dir
1047
- */
1048
- public function get_backup_files($exclude, $include)
1049
- {
1050
- $add = array(
1051
- trim(WPINC),
1052
- trim(basename(WP_CONTENT_DIR)),
1053
- "wp-admin",
1054
- );
1055
-
1056
- $include = array_merge($add, $include);
1057
- foreach ($include as &$value) {
1058
- $value = rtrim($value, '/');
1059
- }
1060
-
1061
- $filelist = array();
1062
- if ($handle = opendir(ABSPATH)) {
1063
- while (false !== ($file = readdir($handle))) {
1064
- if ($file !== '..' && is_dir($file) && file_exists(ABSPATH.$file) && !(in_array($file, $include))) {
1065
- $exclude[] = $file;
1066
- }
1067
- }
1068
- closedir($handle);
1069
- }
1070
- $exclude[] = 'error_log';
1071
-
1072
- $filelist = get_all_files_from_dir(ABSPATH, $exclude);
1073
-
1074
- if (!file_exists(ABSPATH.'wp-config.php')
1075
- && file_exists(dirname(ABSPATH).'/wp-config.php')
1076
- && !file_exists(dirname(ABSPATH).'/wp-settings.php')
1077
- ) {
1078
- $filelist[] = dirname(ABSPATH).'/wp-config.php';
1079
- }
1080
-
1081
- $path = wp_upload_dir();
1082
- $path = $path['path'];
1083
- if (strpos($path, WP_CONTENT_DIR) === false && strpos($path, ABSPATH) === 0) {
1084
- $mediaDir = ABSPATH.ltrim(substr($path, strlen(ABSPATH)), ' /');
1085
- if (is_dir($mediaDir)) {
1086
- $allMediaFiles = get_all_files_from_dir($mediaDir);
1087
- $filelist = array_merge($filelist, $allMediaFiles);
1088
- }
1089
- }
1090
-
1091
- return $filelist;
1092
- }
1093
-
1094
- /**
1095
- * Backup a database dump of WordPress site.
1096
- * All backups are compressed by zip and placed in wp-content/managewp/backups folder.
1097
- *
1098
- * @param string $task_name the name of backup task, which backup is done
1099
- * @param string $backup_file relative path to file which backup is stored
1100
- *
1101
- * @return bool|array true if backup is successful, or an array with error message if is failed
1102
- */
1103
- public function backup_db_compress($task_name, $backup_file)
1104
- {
1105
- $this->update_status($task_name, $this->statuses['db_dump']);
1106
- $db_result = $this->backup_db();
1107
-
1108
- if ($db_result == false) {
1109
- return array(
1110
- 'error' => 'Failed to backup database.',
1111
- );
1112
- } else {
1113
- if (is_array($db_result) && isset($db_result['error'])) {
1114
- return array(
1115
- 'error' => $db_result['error'],
1116
- );
1117
- }
1118
- }
1119
-
1120
- $this->update_status($task_name, $this->statuses['db_dump'], true);
1121
- $this->update_status($task_name, $this->statuses['db_zip']);
1122
- @file_put_contents(MWP_BACKUP_DIR.'/mwp_db/index.php', '');
1123
- $zip_db_result = $this->zip_backup_db($task_name, $backup_file);
1124
-
1125
- if (!$zip_db_result) {
1126
- $zip_archive_db_result = false;
1127
- if (class_exists("ZipArchive")) {
1128
- $zip_archive_db_result = $this->zip_archive_backup_db($task_name, $db_result, $backup_file);
1129
- }
1130
-
1131
- if (!$zip_archive_db_result) {
1132
- $pclzip_db_result = $this->pclzip_backup_db($task_name, $backup_file);
1133
- if (!$pclzip_db_result) {
1134
- @unlink(MWP_BACKUP_DIR.'/mwp_db/index.php');
1135
- @unlink($db_result);
1136
- @rmdir(MWP_DB_DIR);
1137
-
1138
- return array(
1139
- 'error' => 'Failed to zip database. pclZip error ('.$archive->error_code.'): .'.$archive->error_string,
1140
- );
1141
- }
1142
- }
1143
- }
1144
-
1145
- @unlink(MWP_BACKUP_DIR.'/mwp_db/index.php');
1146
- @unlink($db_result);
1147
- @rmdir(MWP_DB_DIR);
1148
-
1149
- $this->update_status($task_name, $this->statuses['db_zip'], true);
1150
-
1151
- return true;
1152
- }
1153
-
1154
- /**
1155
- * Creates database dump and places it in mwp_db folder in site's root.
1156
- * This function dispatches if OS mysql command does not work calls a php alternative.
1157
- *
1158
- * @return string|array path to dump file if successful, or an array with error message if is failed
1159
- */
1160
- public function backup_db()
1161
- {
1162
- $db_folder = MWP_DB_DIR.'/';
1163
- if (!file_exists($db_folder)) {
1164
- if (!mkdir($db_folder, 0755, true)) {
1165
- return array(
1166
- 'error' => 'Error creating database backup folder ('.$db_folder.'). Make sure you have correct write permissions.',
1167
- );
1168
- }
1169
- }
1170
-
1171
- $file = $db_folder.DB_NAME.'.sql';
1172
- $result = $this->backup_db_dump($file); // try mysqldump always then fallback to php dump
1173
- return $result;
1174
- }
1175
-
1176
- public function file_get_size($file)
1177
- {
1178
- if (!extension_loaded('bcmath')) {
1179
- return filesize($file);
1180
- }
1181
-
1182
- //open file
1183
- $fh = fopen($file, "r");
1184
- //declare some variables
1185
- $size = "0";
1186
- $char = "";
1187
- //set file pointer to 0; I'm a little bit paranoid, you can remove this
1188
- fseek($fh, 0, SEEK_SET);
1189
- //set multiplicator to zero
1190
- $count = 0;
1191
- while (true) {
1192
- //jump 1 MB forward in file
1193
- fseek($fh, 1048576, SEEK_CUR);
1194
- //check if we actually left the file
1195
- if (($char = fgetc($fh)) !== false) {
1196
- //if not, go on
1197
- $count++;
1198
- } else {
1199
- //else jump back where we were before leaving and exit loop
1200
- fseek($fh, -1048576, SEEK_CUR);
1201
- break;
1202
- }
1203
- }
1204
- //we could make $count jumps, so the file is at least $count * 1.000001 MB large
1205
- //1048577 because we jump 1 MB and fgetc goes 1 B forward too
1206
- $size = bcmul("1048577", $count);
1207
- //now count the last few bytes; they're always less than 1048576 so it's quite fast
1208
- $fine = 0;
1209
- while (false !== ($char = fgetc($fh))) {
1210
- $fine++;
1211
- }
1212
- //and add them
1213
- $size = bcadd($size, $fine);
1214
- fclose($fh);
1215
-
1216
- return $size;
1217
- }
1218
-
1219
- /**
1220
- * Creates database dump by system mysql command.
1221
- *
1222
- * @param string $file absolute path to file in which dump should be placed
1223
- *
1224
- * @return string|array path to dump file if successful, or an array with error message if is failed
1225
- */
1226
- public function backup_db_dump($file)
1227
- {
1228
- $mysqldump = mwp_container()->getExecutableFinder()->find('mysqldump', 'mysqldump');
1229
-
1230
- $processBuilder = Symfony_Process_ProcessBuilder::create()
1231
- ->setWorkingDirectory(untrailingslashit(ABSPATH))
1232
- ->setTimeout(3600)
1233
- ->setPrefix($mysqldump)
1234
- ->add('--force')// Continue even if we get an SQL error.
1235
- ->add('--user='.DB_USER)// User for login if not current user.
1236
- ->add('--password='.DB_PASSWORD)// Password to use when connecting to server. If password is not given it's solicited on the tty.
1237
- ->add('--add-drop-table')// Add a DROP TABLE before each create.
1238
- ->add('--lock-tables=false')// Don't lock all tables for read.
1239
- ->add(DB_NAME)
1240
- ->add('--result-file='.$file);
1241
-
1242
- $port = 0;
1243
- $host = DB_HOST;
1244
-
1245
- if (strpos($host, ':') !== false) {
1246
- list($host, $port) = explode(':', $host);
1247
- }
1248
- $socket = false;
1249
-
1250
- if (strpos(DB_HOST, '/') !== false || strpos(DB_HOST, '\\') !== false) {
1251
- $socket = true;
1252
- $host = end(explode(':', DB_HOST));
1253
- }
1254
-
1255
- if ($socket) {
1256
- $processBuilder->add('--socket='.$host);
1257
- } else {
1258
- $processBuilder->add('--host='.$host);
1259
- if (!empty($port)) {
1260
- $processBuilder->add('--port='.$port);
1261
- }
1262
- }
1263
-
1264
- try {
1265
- if (!mwp_is_shell_available()) {
1266
- throw new MMB_Exception("Shell is not available");
1267
- }
1268
- $process = $processBuilder->getProcess();
1269
- mwp_logger()->info('Database dumping process started', array(
1270
- 'executable_location' => $mysqldump,
1271
- 'command_line' => $process->getCommandLine(),
1272
- ));
1273
- $process->run();
1274
-
1275
- if (!$process->isSuccessful()) {
1276
- throw new Symfony_Process_Exception_ProcessFailedException($process);
1277
- }
1278
- } catch (Exception $e) {
1279
- if ($e instanceof Symfony_Process_Exception_ProcessFailedException) {
1280
- mwp_logger()->error('Database dumping process failed', array(
1281
- 'process' => $e->getProcess(),
1282
- ));
1283
- } else {
1284
- mwp_logger()->error('Error while trying to execute database dumping process', array(
1285
- 'exception' => $e,
1286
- ));
1287
- }
1288
-
1289
- if (class_exists('PDO') && extension_loaded('pdo_mysql')) {
1290
- mwp_logger()->info('Using PHP dumper v2');
1291
- try {
1292
- $config = array(
1293
- 'username' => DB_USER,
1294
- 'password' => DB_PASSWORD,
1295
- 'database' => DB_NAME,
1296
- );
1297
-
1298
- if ($socket) {
1299
- $config['socket'] = $host;
1300
- } else {
1301
- $config['host'] = $host;
1302
-
1303
- if ($port) {
1304
- $config['port'] = $port;
1305
- }
1306
- }
1307
- MWP_Backup_Database::dump($config, array(
1308
- 'force_method' => 'sequential',
1309
- 'save_path' => $file,
1310
- ));
1311
- } catch (Exception $e) {
1312
- mwp_logger()->error('PHP dumper v2 has failed', array(
1313
- 'exception' => $e,
1314
- ));
1315
-
1316
- return false;
1317
- }
1318
- } else {
1319
- mwp_logger()->info('Using PHP dumper v1');
1320
- $result = $this->backup_db_php($file);
1321
-
1322
- if (!$result) {
1323
- mwp_logger()->error('PHP dumper v1 has failed');
1324
-
1325
- return false;
1326
- }
1327
- }
1328
- }
1329
-
1330
- if (filesize($file) === 0) {
1331
- unlink($file);
1332
- mwp_logger()->error('Database dumping process failed with unknown reason', array(
1333
- 'database_file' => $file,
1334
- ));
1335
-
1336
- return false;
1337
- } else {
1338
- mwp_logger()->info('Database dumping process finished, file size is {backup_size}', array(
1339
- 'backup_size' => mwp_format_bytes(filesize($file)),
1340
- ));
1341
-
1342
- file_put_contents(dirname($file).'/info.json', json_encode(array('table-prefix' => $GLOBALS['wpdb']->prefix, 'site-url' => get_option('siteurl'))));
1343
-
1344
- return $file;
1345
- }
1346
- }
1347
-
1348
- /**
1349
- * Creates database dump by php functions.
1350
- *
1351
- * @param string $file absolute path to file in which dump should be placed
1352
- *
1353
- * @return string|array path to dump file if successful, or an array with error message if is failed
1354
- */
1355
- public function backup_db_php($file)
1356
- {
1357
- global $wpdb;
1358
- $tables = $wpdb->get_results('SHOW TABLES', ARRAY_N);
1359
- foreach ($tables as $table) {
1360
- //drop existing table
1361
- $dump_data = "DROP TABLE IF EXISTS $table[0];";
1362
- file_put_contents($file, $dump_data, FILE_APPEND);
1363
- //create table
1364
- $create_table = $wpdb->get_row("SHOW CREATE TABLE $table[0]", ARRAY_N);
1365
- $dump_data = "\n\n".$create_table[1].";\n\n";
1366
- file_put_contents($file, $dump_data, FILE_APPEND);
1367
-
1368
- $count = $wpdb->get_var("SELECT count(*) FROM $table[0]");
1369
- if ($count > 100) {
1370
- $count = ceil($count / 100);
1371
- } else {
1372
- if ($count > 0) {
1373
- $count = 1;
1374
- }
1375
- }
1376
-
1377
- for ($i = 0; $i < $count; $i++) {
1378
- $low_limit = $i * 100;
1379
- $qry = "SELECT * FROM $table[0] LIMIT $low_limit, 100";
1380
- $rows = $wpdb->get_results($qry, ARRAY_A);
1381
- if (is_array($rows)) {
1382
- foreach ($rows as $row) {
1383
- //insert single row
1384
- $dump_data = "INSERT INTO $table[0] VALUES(";
1385
- $num_values = count($row);
1386
- $j = 1;
1387
- foreach ($row as $value) {
1388
- $value = addslashes($value);
1389
- $value = preg_replace("/\n/Ui", "\\n", $value);
1390
- $num_values == $j ? $dump_data .= "'".$value."'" : $dump_data .= "'".$value."', ";
1391
- $j++;
1392
- unset($value);
1393
- }
1394
- $dump_data .= ");\n";
1395
- file_put_contents($file, $dump_data, FILE_APPEND);
1396
- }
1397
- }
1398
- }
1399
- $dump_data = "\n\n\n";
1400
- file_put_contents($file, $dump_data, FILE_APPEND);
1401
-
1402
- unset($rows);
1403
- unset($dump_data);
1404
- }
1405
-
1406
- if (filesize($file) == 0 || !is_file($file)) {
1407
- @unlink($file);
1408
-
1409
- return array(
1410
- 'error' => 'Database backup failed. Try to enable MySQL dump on your server.',
1411
- );
1412
- }
1413
-
1414
- return $file;
1415
- }
1416
-
1417
- public function restore($params)
1418
- {
1419
- global $wpdb;
1420
- if (empty($params)) {
1421
- return false;
1422
- }
1423
-
1424
- $task = $this->tasks[$params['task_name']];
1425
- $backups = $task['task_results'];
1426
- $result_id = isset($params['result_id']) ? $params['result_id'] : null;
1427
- $backup = !empty($backups[$result_id]) ? $backups[$result_id] : false;
1428
-
1429
- if (!empty($params['resultUuid'])) {
1430
- foreach ($backups as $key => $result) {
1431
- if ($result['resultUuid'] == $params['resultUuid']) {
1432
- $backup = $result;
1433
- $result_id = $key;
1434
- break;
1435
- }
1436
- }
1437
- }
1438
-
1439
- if (!$backup && empty($params['backup_url'])) {
1440
- return array(
1441
- 'error' => 'Unknown result UUID or backup URL.',
1442
- );
1443
- }
1444
-
1445
- if (isset($params['google_drive_token'])) {
1446
- $this->tasks[$params['task_name']]['task_args']['account_info']['mwp_google_drive']['google_drive_token'] = $params['google_drive_token'];
1447
- }
1448
- if (!empty($params['backup_url']) || !isset($this->tasks[$params['task_name']]['task_results'][$result_id]['server'])) {
1449
- /* If it is on server don't delete zipped file file after restore */
1450
- $deleteBackupAfterRestore = true;
1451
- }
1452
-
1453
- $this->set_memory();
1454
- /* Get backup file*/
1455
- try {
1456
- $backupFile = $this->getBackup(stripslashes($params['task_name']), $result_id, $params['backup_url']);
1457
- } catch (Exception $e) {
1458
- return array(
1459
- 'error' => $e->getMessage(),
1460
- );
1461
- }
1462
-
1463
- try {
1464
- $oldCredentialsAndOptions = $this->keepOldCredentialsAndOptions($params['overwrite'], $params['clone_from_url'], $params['mwp_clone']);
1465
- $home = untrailingslashit(get_option('home'));
1466
- } catch (Exception $e) {
1467
- $this->deleteTempBackupFile($backupFile, $deleteBackupAfterRestore);
1468
-
1469
- return array(
1470
- 'error' => $e->getMessage(),
1471
- );
1472
- }
1473
-
1474
- $unzipFailed = false;
1475
- try {
1476
- $this->unzipBackup($backupFile);
1477
- } catch (Exception $e) {
1478
- $unzipFailed = true;
1479
- }
1480
-
1481
- if ($unzipFailed && class_exists("ZipArchive")) {
1482
- $unzipFailed = false;
1483
- try {
1484
- $this->unzipWithZipArchive($backupFile);
1485
- } catch (Exception $e) {
1486
- $unzipFailed = true;
1487
- }
1488
- }
1489
-
1490
- if ($unzipFailed) {
1491
- try {
1492
- /* Fallback to PclZip Module */
1493
- $this->pclUnzipIt($backupFile);
1494
- } catch (Exception $e) {
1495
- $this->deleteTempBackupFile($backupFile, $deleteBackupAfterRestore);
1496
-
1497
- return array(
1498
- 'error' => $e->getMessage(),
1499
- );
1500
- }
1501
- }
1502
-
1503
- $this->deleteTempBackupFile($backupFile, $deleteBackupAfterRestore);
1504
- $filePath = ABSPATH.'mwp_db';
1505
-
1506
- @chmod($filePath, 0755);
1507
- $fileName = glob($filePath.'/*.sql');
1508
- $fileName = $fileName[0];
1509
-
1510
- $restoreDbFailed = false;
1511
-
1512
- try {
1513
- $this->restore_db($fileName);
1514
- } catch (Exception $e) {
1515
- mwp_logger()->notice('Shell restore failed, error: {message} file was: {file_name}', array(
1516
- 'message' => $e->getMessage(),
1517
- 'file_name' => $fileName,
1518
- ));
1519
- $restoreDbFailed = true;
1520
- }
1521
- if ($restoreDbFailed) {
1522
- try {
1523
- $this->restore_db_php($fileName);
1524
- } catch (Exception $e) {
1525
- @unlink($filePath.'/index.php');
1526
- @unlink($filePath.'/info.json');
1527
- @rmdir($filePath);
1528
-
1529
- return array(
1530
- 'error' => $e->getMessage(),
1531
- );
1532
- }
1533
- } else {
1534
- @unlink($fileName);
1535
- }
1536
- @unlink($filePath.'/index.php');
1537
- @rmdir($filePath);
1538
- mwp_logger()->info('Restore successfully completed');
1539
-
1540
- // Try to fetch old home and site url, as well as new ones for usage later in database updates
1541
- // Take fresh options
1542
- $homeOpt = $wpdb->get_row($wpdb->prepare("SELECT option_value FROM $wpdb->options WHERE option_name = %s LIMIT 1", 'home'));
1543
- $siteUrlOpt = $wpdb->get_row($wpdb->prepare("SELECT option_value FROM $wpdb->options WHERE option_name = %s LIMIT 1", 'siteurl'));
1544
- global $restoreParams;
1545
- $restoreParams = array(
1546
- 'oldUrl' => is_object($homeOpt) ? $homeOpt->option_value : null,
1547
- 'oldSiteUrl' => is_object($siteUrlOpt) ? $siteUrlOpt->option_value : null,
1548
- 'tablePrefix' => $this->get_table_prefix(),
1549
- 'newUrl' => '',
1550
- );
1551
-
1552
- /* Replace options and content urls */
1553
- $this->replaceOptionsAndUrls($params['overwrite'], $params['new_user'], $params['new_password'], $params['old_user'], $params['clone_from_url'], $params['admin_email'], $params['mwp_clone'], $oldCredentialsAndOptions, $home);
1554
-
1555
- $newUrl = $wpdb->get_row($wpdb->prepare("SELECT option_value FROM $wpdb->options WHERE option_name = %s LIMIT 1", 'home'));
1556
- $restoreParams['newUrl'] = is_object($newUrl) ? $newUrl->option_value : null;
1557
- restore_migrate_urls();
1558
- restore_htaccess();
1559
- $this->w3tc_flush(true);
1560
- global $configDiff;
1561
- $result = array(
1562
- 'status' => true,
1563
- 'admins' => $this->getAdminUsers(),
1564
- );
1565
- if (isset($configDiff)
1566
- && is_array($configDiff)
1567
- ) {
1568
- $result['configDiff'] = $configDiff;
1569
- }
1570
-
1571
- return $result;
1572
- }
1573
-
1574
- /**
1575
- * @return array An array of stdClass-es with the single property 'user_login' (string). Example: [ (object) ['user_login' => 'admin' ] ]
1576
- */
1577
- private function getAdminUsers()
1578
- {
1579
- $users = get_users(array(
1580
- 'role' => array('administrator'),
1581
- 'fields' => array('user_login'),
1582
- ));
1583
-
1584
- if (!count($users)) {
1585
- // @todo Investigate why the above doesn't work on PHP 5.2.
1586
- $users = get_users(array('role' => 'administrator', 'number' => 1, 'orderby' => 'ID'));
1587
- if (!empty($users[0]->user_login)) {
1588
- $users = array(
1589
- (object) array(
1590
- 'user_login' => $users[0]->user_login,
1591
- ),
1592
- );
1593
- }
1594
- }
1595
-
1596
- return $users;
1597
- }
1598
-
1599
- private function getBackup($taskName, $resultId, $backupUrl = null)
1600
- {
1601
- if (!empty($backupUrl)) {
1602
- /* When cloning (overwrite) */
1603
- include_once ABSPATH.'wp-admin/includes/file.php';
1604
- /* Use WordPress function to download file that is used to replace current WP installation */
1605
- $backupFile = download_url($backupUrl);
1606
- if (is_wp_error($backupFile)) {
1607
- throw new Exception('Unable to download backup file ('.$backupFile->get_error_message().')');
1608
- }
1609
- } else {
1610
- /* When doing restore of MWP Backup*/
1611
- $task = $this->tasks[$taskName];
1612
- if (isset($task['task_results'][$resultId]['server'])) {
1613
- $backupFile = $task['task_results'][$resultId]['server']['file_path'];
1614
- } elseif (isset($task['task_results'][$resultId]['ftp'])) {
1615
- $ftp_file = $task['task_results'][$resultId]['ftp'];
1616
- $params = $task['task_args']['account_info']['mwp_ftp'];
1617
- $params['backup_file'] = $ftp_file;
1618
- $backupFile = $this->get_ftp_backup($params);
1619
-
1620
- if ($backupFile == false) {
1621
- throw new Exception('Failed to download file from FTP.');
1622
- }
1623
- } elseif (isset($task['task_results'][$resultId]['sftp'])) {
1624
- $ftp_file = $task['task_results'][$resultId]['sftp'];
1625
- $params = $task['task_args']['account_info']['mwp_sftp'];
1626
- $params['backup_file'] = $ftp_file;
1627
- $backupFile = $this->get_sftp_backup($params);
1628
-
1629
- if ($backupFile == false) {
1630
- throw new Exception('Failed to download file from SFTP.');
1631
- }
1632
- } elseif (isset($task['task_results'][$resultId]['amazons3'])) {
1633
- $amazons3File = $task['task_results'][$resultId]['amazons3'];
1634
- $params = $task['task_args']['account_info']['mwp_amazon_s3'];
1635
- $params['backup_file'] = $amazons3File;
1636
- $backupFile = $this->get_amazons3_backup($params);
1637
-
1638
- if ($backupFile == false) {
1639
- throw new Exception('Failed to download file from Amazon S3.');
1640
- }
1641
- } elseif (isset($task['task_results'][$resultId]['dropbox'])) {
1642
- $dropboxFile = $task['task_results'][$resultId]['dropbox'];
1643
- $params = $task['task_args']['account_info']['mwp_dropbox'];
1644
- $params['backup_file'] = $dropboxFile;
1645
- $backupFile = $this->get_dropbox_backup($params);
1646
-
1647
- if ($backupFile == false) {
1648
- throw new Exception('Failed to download file from Dropbox.');
1649
- }
1650
- } elseif (isset($task['task_results'][$resultId]['google_drive'])) {
1651
- if (is_array($task['task_results'][$resultId]['google_drive'])) {
1652
- $googleDriveFile = $task['task_results'][$resultId]['google_drive']['file'];
1653
- $googleDriveFileId = $task['task_results'][$resultId]['google_drive']['file_id'];
1654
- } else {
1655
- $googleDriveFile = $task['task_results'][$resultId]['google_drive'];
1656
- $googleDriveFileId = "";
1657
- }
1658
- $params = $task['task_args']['account_info']['mwp_google_drive'];
1659
- $params['backup_file'] = $googleDriveFile;
1660
- $params['file_id'] = $googleDriveFileId;
1661
- $backupFile = $this->get_google_drive_backup($params);
1662
-
1663
- if (is_array($backupFile) && isset($backupFile['error'])) {
1664
- throw new Exception('Failed to download file from Google Drive, reason: '.$backupFile['error']);
1665
- } elseif ($backupFile == false) {
1666
- throw new Exception('Failed to download file from Google Drive.');
1667
- }
1668
- }
1669
- }
1670
-
1671
- if (is_array($backupFile) && isset($backupFile['error'])) {
1672
- throw new Exception('Error restoring: '.$backupFile['error']);
1673
- }
1674
-
1675
- if (!($backupFile && file_exists($backupFile))) {
1676
- throw new Exception('Error restoring. Cannot find backup file.');
1677
- }
1678
- mwp_logger()->info('Download of backup file successfully completed.');
1679
-
1680
- return $backupFile;
1681
- }
1682
-
1683
- private function keepOldCredentialsAndOptions($overwrite = false, $cloneFromUrl, $mwpClone)
1684
- {
1685
- $oldOptions = array();
1686
- $oldOptions['clone_options'] = array();
1687
- $oldOptions['restore_options'] = array();
1688
- $this->wpdb_reconnect();
1689
-
1690
- if ($overwrite) {
1691
- /* Keep old db credentials before overwrite */
1692
- if (!copy(ABSPATH.'wp-config.php', ABSPATH.'mwp-temp-wp-config.php')) {
1693
- throw new Exception('Error creating wp-config file.
1694
- Please check if your WordPress installation folder has correct permissions to allow writing files.
1695
- In most cases permissions should be 755 but occasionally it\'s required to put 777.
1696
- If you are unsure on how to do this yourself, you can ask your hosting provider for help.');
1697
- }
1698
- if (trim($cloneFromUrl) || trim($mwpClone)) {
1699
- $oldOptions['clone_options']['_worker_nossl_key'] = get_option('_worker_nossl_key');
1700
- $oldOptions['clone_options']['_worker_public_key'] = get_option('_worker_public_key');
1701
- $oldOptions['clone_options']['_worker_orion_key'] = get_option('_worker_orion_key');
1702
- $oldOptions['clone_options']['_action_message_id'] = get_option('_action_message_id');
1703
- }
1704
- $oldOptions['clone_options']['upload_path'] = get_option('upload_path');
1705
- $oldOptions['clone_options']['upload_url_path'] = get_option('upload_url_path');
1706
-
1707
- $oldOptions['clone_options']['mwp_backup_tasks'] = maybe_serialize(get_option('mwp_backup_tasks'));
1708
- $oldOptions['clone_options']['mwp_notifications'] = maybe_serialize(get_option('mwp_notifications'));
1709
- $oldOptions['clone_options']['mwp_pageview_alerts'] = maybe_serialize(get_option('mwp_pageview_alerts'));
1710
- } else {
1711
- $oldOptions['restore_options']['mwp_notifications'] = get_option('mwp_notifications');
1712
- $oldOptions['restore_options']['mwp_pageview_alerts'] = get_option('mwp_pageview_alerts');
1713
- $oldOptions['restore_options']['user_hit_count'] = get_option('user_hit_count');
1714
- $oldOptions['restore_options']['mwp_backup_tasks'] = get_option('mwp_backup_tasks');
1715
- }
1716
-
1717
- return $oldOptions;
1718
- }
1719
-
1720
- private function unzipBackup($backupFile)
1721
- {
1722
- $unzip = mwp_container()->getExecutableFinder()->find('unzip', 'unzip');
1723
- $processBuilder = Symfony_Process_ProcessBuilder::create()
1724
- ->setWorkingDirectory(untrailingslashit(ABSPATH))
1725
- ->setTimeout(3600)
1726
- ->setPrefix($unzip)
1727
- ->add('-o')
1728
- ->add($backupFile);
1729
- try {
1730
- if (!mwp_is_shell_available()) {
1731
- throw new MMB_Exception("Shell is not available");
1732
- }
1733
- $process = $processBuilder->getProcess();
1734
- mwp_logger()->info('Backup extraction process started', array(
1735
- 'executable_location' => $unzip,
1736
- 'command_line' => $process->getCommandLine(),
1737
- ));
1738
- $process->run();
1739
- if (!$process->isSuccessful()) {
1740
- throw new Symfony_Process_Exception_ProcessFailedException($process);
1741
- }
1742
- mwp_logger()->info('Backup extraction process finished');
1743
- } catch (Symfony_Process_Exception_ProcessFailedException $e) {
1744
- mwp_logger()->error('Backup extraction process failed', array(
1745
- 'process' => $e->getProcess(),
1746
- ));
1747
- throw $e;
1748
- } catch (Exception $e) {
1749
- mwp_logger()->error('Error while trying to execute backup extraction process', array(
1750
- 'exception' => $e,
1751
- ));
1752
- throw $e;
1753
- }
1754
- }
1755
-
1756
- private function unzipWithZipArchive($backupFile)
1757
- {
1758
- mwp_logger()->info('Falling back to ZipArchive Module');
1759
- $result = false;
1760
- $zipArchive = new ZipArchive();
1761
- $zipOpened = $zipArchive->open($backupFile);
1762
- if ($zipOpened === true) {
1763
- $result = $zipArchive->extractTo(ABSPATH);
1764
- $zipArchive->close();
1765
- }
1766
- if ($result === false) {
1767
- throw new Exception('Failed to unzip files with ZipArchive. Message: '.$zipArchive->getStatusString());
1768
- }
1769
- }
1770
-
1771
- private function pclUnzipIt($backupFile)
1772
- {
1773
- mwp_logger()->info('Falling back to PclZip Module');
1774
- define('PCLZIP_TEMPORARY_DIR', MWP_BACKUP_DIR.'/');
1775
- require_once ABSPATH.'/wp-admin/includes/class-pclzip.php';
1776
- $archive = new PclZip($backupFile);
1777
- $result = $archive->extract(PCLZIP_OPT_PATH, ABSPATH, PCLZIP_OPT_REPLACE_NEWER);
1778
-
1779
- if (!$result) {
1780
- throw new Exception('Failed to unzip files. pclZip error ('.$archive->error_code.'): .'.$archive->error_string);
1781
- }
1782
- }
1783
-
1784
- private function deleteTempBackupFile($backupFile, $deleteBackupAfterRestore)
1785
- {
1786
- if ($deleteBackupAfterRestore) {
1787
- @unlink($backupFile);
1788
- }
1789
- }
1790
-
1791
- private function replaceOptionsAndUrls($overwrite, $newUser, $newPassword, $oldUser, $cloneFromUrl, $adminEmail, $mwpClone, $oldCredentialsAndOptions, $home)
1792
- {
1793
- global $wpdb;
1794
- $this->wpdb_reconnect();
1795
-
1796
- if ($overwrite) {
1797
- /* Get New Table prefix */
1798
- $new_table_prefix = trim($this->get_table_prefix());
1799
-
1800
- $configPath = ABSPATH.'wp-config.php';
1801
- $sourceConfigCopyPath = ABSPATH.'wp-config.source.php';
1802
- $destinationConfigPath = ABSPATH.'mwp-temp-wp-config.php';
1803
-
1804
- @rename($configPath, $sourceConfigCopyPath);
1805
-
1806
- /* Config keys diff */
1807
- $tokenizer = new MWP_Parser_DefinitionTokenizer();
1808
- $destinationConfigContent = @file_get_contents($destinationConfigPath);
1809
- $sourceConfigContent = @file_get_contents($sourceConfigCopyPath);
1810
-
1811
- if (is_string($destinationConfigContent) && is_string($sourceConfigContent)) {
1812
- $sourceTokens = $tokenizer->getDefinitions($sourceConfigContent);
1813
- $destinationTokens = $tokenizer->getDefinitions($destinationConfigContent);
1814
-
1815
- if (is_array($sourceTokens) && is_array($destinationTokens)) {
1816
- // First declaration of $configDiff
1817
- global $configDiff;
1818
- $configDiff = array(
1819
- 'additions' => array_values(array_diff($sourceTokens, $destinationTokens)),
1820
- 'subtractions' => array_values(array_diff($destinationTokens, $sourceTokens)),
1821
- );
1822
- }
1823
- }
1824
- @unlink($sourceConfigCopyPath);
1825
-
1826
- /* Retrieve old wp_config */
1827
- $lines = file($destinationConfigPath);
1828
-
1829
- /* Replace table prefix */
1830
- foreach ($lines as $line) {
1831
- if (strstr($line, '$table_prefix')) {
1832
- $line = '$table_prefix = "'.$new_table_prefix.'";'.PHP_EOL;
1833
- }
1834
- file_put_contents($configPath, $line, FILE_APPEND);
1835
- }
1836
-
1837
- @unlink($destinationConfigPath);
1838
-
1839
- /* Replace options */
1840
- $query = "SELECT option_value FROM ".$new_table_prefix."options WHERE option_name = 'home'";
1841
- $old = $wpdb->get_var($query);
1842
- $old = rtrim($old, "/");
1843
- $query = "UPDATE ".$new_table_prefix."options SET option_value = %s WHERE option_name = 'home'";
1844
- $wpdb->query($wpdb->prepare($query, $home));
1845
- $query = "UPDATE ".$new_table_prefix."options SET option_value = %s WHERE option_name = 'siteurl'";
1846
- $wpdb->query($wpdb->prepare($query, $home));
1847
-
1848
- /* Replace content urls */
1849
- $regexp1 = 'src="(.*)$old(.*)"';
1850
- $regexp2 = 'href="(.*)$old(.*)"';
1851
- $query = "UPDATE ".$new_table_prefix."posts SET post_content = REPLACE (post_content, %s,%s) WHERE post_content REGEXP %s OR post_content REGEXP %s";
1852
- $wpdb->query($wpdb->prepare($query, array($old, $home, $regexp1, $regexp2)));
1853
-
1854
- if (trim($newPassword)) {
1855
- $newPassword = wp_hash_password($newPassword);
1856
- }
1857
- if (!trim($newPassword) && !trim($mwpClone)) {
1858
- if ($newUser && $newPassword) {
1859
- $query = "UPDATE ".$new_table_prefix."users SET user_login = %s, user_pass = %s WHERE user_login = %s";
1860
- $wpdb->query($wpdb->prepare($query, $newUser, $newPassword, $oldUser));
1861
- }
1862
- } else {
1863
- if ($cloneFromUrl) {
1864
- if ($newUser && $newPassword) {
1865
- $query = "UPDATE ".$new_table_prefix."users SET user_pass = %s WHERE user_login = %s";
1866
- $wpdb->query($wpdb->prepare($query, $newPassword, $newUser));
1867
- }
1868
- }
1869
-
1870
- if ($mwpClone) {
1871
- if ($adminEmail) {
1872
- /* Clean Install */
1873
- $query = "UPDATE ".$new_table_prefix."options SET option_value = %s WHERE option_name = 'admin_email'";
1874
- $wpdb->query($wpdb->prepare($query, $adminEmail));
1875
- $query = "SELECT * FROM ".$new_table_prefix."users LIMIT 1";
1876
- $temp_user = $wpdb->get_row($query);
1877
- if (!empty($temp_user)) {
1878
- $query = "UPDATE ".$new_table_prefix."users SET user_email=%s, user_login = %s, user_pass = %s WHERE user_login = %s";
1879
- $wpdb->query($wpdb->prepare($query, $adminEmail, $newUser, $newPassword, $temp_user->user_login));
1880
- }
1881
- }
1882
- }
1883
- }
1884
-
1885
- if (is_array($oldCredentialsAndOptions['clone_options']) && !empty($oldCredentialsAndOptions['clone_options'])) {
1886
- foreach ($oldCredentialsAndOptions['clone_options'] as $key => $option) {
1887
- if (!empty($key)) {
1888
- $query = "SELECT option_value FROM ".$new_table_prefix."options WHERE option_name = %s";
1889
- $res = $wpdb->get_var($wpdb->prepare($query, $key));
1890
- if ($res === false) {
1891
- $query = "INSERT INTO ".$new_table_prefix."options (option_value,option_name) VALUES(%s,%s)";
1892
- $wpdb->query($wpdb->prepare($query, $option, $key));
1893
- } else {
1894
- $query = "UPDATE ".$new_table_prefix."options SET option_value = %s WHERE option_name = %s";
1895
- $wpdb->query($wpdb->prepare($query, $option, $key));
1896
- }
1897
- }
1898
- }
1899
- }
1900
-
1901
- /* Remove hit count */
1902
- $query = "DELETE FROM ".$new_table_prefix."options WHERE option_name = 'user_hit_count'";
1903
- $wpdb->query($query);
1904
-
1905
- /* Check for .htaccess permalinks update */
1906
- $this->replace_htaccess($home);
1907
- } else {
1908
- /* restore worker options */
1909
- if (is_array($oldCredentialsAndOptions['restore_options']) && !empty($oldCredentialsAndOptions['restore_options'])) {
1910
- foreach ($oldCredentialsAndOptions['restore_options'] as $key => $option) {
1911
- $wpdb->update($wpdb->options, array('option_value' => maybe_serialize($option)), array('option_name' => $key));
1912
- }
1913
- }
1914
- }
1915
- }
1916
-
1917
- public function restore_db($fileName)
1918
- {
1919
- if (!$fileName) {
1920
- throw new Exception('Cannot access database file.');
1921
- }
1922
-
1923
- $port = 0;
1924
- $host = DB_HOST;
1925
-
1926
- if (strpos(DB_HOST, ':') !== false) {
1927
- list($host, $port) = explode(':', DB_HOST);
1928
- }
1929
- $socket = false;
1930
-
1931
- if (strpos(DB_HOST, '/') !== false || strpos(DB_HOST, '\\') !== false) {
1932
- $socket = true;
1933
- $host = end(explode(':', DB_HOST));
1934
- }
1935
-
1936
- if ($socket) {
1937
- $connection = array('--socket='.$host);
1938
- } else {
1939
- $connection = array('--host='.$host);
1940
- if (!empty($port)) {
1941
- $connection[] = '--port='.$port;
1942
- }
1943
- }
1944
-
1945
- $mysql = mwp_container()->getExecutableFinder()->find('mysql', 'mysql');
1946
- $arguments = array_merge(array($mysql, '--user='.DB_USER, '--password='.DB_PASSWORD, '--default-character-set=utf8', DB_NAME), $connection);
1947
- $command = implode(' ', array_map(array('Symfony_Process_ProcessUtils', 'escapeArgument'), $arguments)).' < '.Symfony_Process_ProcessUtils::escapeArgument($fileName);
1948
-
1949
- try {
1950
- if (!mwp_is_shell_available()) {
1951
- throw new MMB_Exception("Shell is not available");
1952
- }
1953
- $process = new Symfony_Process_Process($command, untrailingslashit(ABSPATH), $this->getEnv(), null, 3600);
1954
- mwp_logger()->info('Database import process started', array(
1955
- 'executable_location' => $mysql,
1956
- 'command_line' => $process->getCommandLine(),
1957
- ));
1958
- $process->run();
1959
-
1960
- if (!$process->isSuccessful()) {
1961
- throw new Symfony_Process_Exception_ProcessFailedException($process);
1962
- }
1963
- } catch (Symfony_Process_Exception_ProcessFailedException $e) {
1964
- //unlink($fileName);
1965
- mwp_logger()->error('Database import process failed', array(
1966
- 'process' => $e->getProcess(),
1967
- ));
1968
- throw $e;
1969
- } catch (Exception $e) {
1970
- //unlink($fileName);
1971
- mwp_logger()->error('Error while trying to execute database import process', array(
1972
- 'exception' => $e,
1973
- ));
1974
- throw $e;
1975
- }
1976
- mwp_logger()->info('Database import process finished');
1977
- // unlink($fileName);
1978
- }
1979
-
1980
- /**
1981
- * Restores database dump by php functions.
1982
- *
1983
- * @param string $file_name relative path to database dump, which should be restored
1984
- *
1985
- * @return bool is successful or not
1986
- */
1987
- public function restore_db_php($file_name)
1988
- {
1989
- global $wpdb;
1990
-
1991
- $current_query = '';
1992
- mwp_logger()->info('PHP DB import process started');
1993
- // Read in entire file
1994
- // $lines = file($file_name);
1995
- $fp = @fopen($file_name, 'r');
1996
- if (!$fp) {
1997
- throw new Exception("Failed restoring database: could not open dump file ($file_name)");
1998
- }
1999
- while (!feof($fp)) {
2000
- $line = fgets($fp);
2001
-
2002
- // Skip it if it's a comment
2003
- if (substr($line, 0, 2) == '--' || $line == '') {
2004
- continue;
2005
- }
2006
-
2007
- // Add this line to the current query
2008
- $current_query .= $line;
2009
- // If it has a semicolon at the end, it's the end of the query
2010
- if (substr(trim($line), -1, 1) == ';') {
2011
- // Perform the query
2012
- $trimmed = trim($current_query, " ;\n");
2013
- if (!empty($trimmed)) {
2014
- $result = $wpdb->query($current_query);
2015
- if ($result === false) {
2016
- @fclose($fp);
2017
- @unlink($file_name);
2018
- throw new Exception("Error while restoring database on ($current_query) $wpdb->last_error");
2019
- }
2020
- }
2021
- // Reset temp variable to empty
2022
- $current_query = '';
2023
- }
2024
- }
2025
- @fclose($fp);
2026
- @unlink($file_name);
2027
- }
2028
-
2029
- /**
2030
- * Retruns table_prefix for this WordPress installation.
2031
- * It is used by restore.
2032
- *
2033
- * @return string table prefix from wp-config.php file, (default: wp_)
2034
- */
2035
- public function get_table_prefix()
2036
- {
2037
- $lines = file(ABSPATH.'wp-config.php');
2038
- foreach ($lines as $line) {
2039
- if (strstr($line, '$table_prefix')) {
2040
- $pattern = "/(\'|\")[^(\'|\")]*/";
2041
- preg_match($pattern, $line, $matches);
2042
- $prefix = substr($matches[0], 1);
2043
-
2044
- return $prefix;
2045
- break;
2046
- }
2047
- }
2048
-
2049
- return 'wp_'; //default
2050
- }
2051
-
2052
- /**
2053
- * Change all tables to InnoDB engine, and executes mysql OPTIMIZE TABLE for each table.
2054
- *
2055
- * @return bool optimized successfully or not
2056
- */
2057
- public function optimize_tables()
2058
- {
2059
- global $wpdb;
2060
- $query = 'SHOW TABLE STATUS';
2061
- $tables = $wpdb->get_results($query, ARRAY_A);
2062
- $table_string = '';
2063
- foreach ($tables as $table) {
2064
- $table_string .= $table['Name'].",";
2065
- }
2066
- $table_string = rtrim($table_string, ",");
2067
- $optimize = $wpdb->query("OPTIMIZE TABLE $table_string");
2068
-
2069
- return (bool) $optimize;
2070
- }
2071
-
2072
- public function getServerInformationForStats()
2073
- {
2074
- $serverInfo = array();
2075
- $serverInfo['zip'] = $this->zipExists();
2076
- $serverInfo['unzip'] = $this->unzipExists();
2077
- $serverInfo['proc'] = $this->procOpenExists();
2078
- $serverInfo['mysql'] = $this->mySqlExists();
2079
- $serverInfo['mysqldump'] = $this->mySqlDumpExists();
2080
- $serverInfo['curl'] = false;
2081
- $serverInfo['shell'] = mwp_is_shell_available();
2082
-
2083
- if (function_exists('curl_init') && function_exists('curl_exec')) {
2084
- $serverInfo['curl'] = true;
2085
- }
2086
-
2087
- return $serverInfo;
2088
- }
2089
-
2090
- /**
2091
- * Check if proc_open exists
2092
- *
2093
- * @return string|bool exec if exists, then system, then passthru, then false if no one exist
2094
- */
2095
- private function procOpenExists()
2096
- {
2097
- if ($this->mmb_function_exists('proc_open') && $this->mmb_function_exists('escapeshellarg')) {
2098
- return true;
2099
- }
2100
-
2101
- return false;
2102
- }
2103
-
2104
- private function zipExists()
2105
- {
2106
- $zip = mwp_container()->getExecutableFinder()->find('zip', 'zip');
2107
- $processBuilder = Symfony_Process_ProcessBuilder::create()
2108
- ->setWorkingDirectory(untrailingslashit(ABSPATH))
2109
- ->setPrefix($zip);
2110
- try {
2111
- if (!mwp_is_shell_available()) {
2112
- throw new MMB_Exception("Shell is not available");
2113
- }
2114
- $process = $processBuilder->getProcess();
2115
- $process->run();
2116
-
2117
- return $process->isSuccessful();
2118
- } catch (Exception $e) {
2119
- return false;
2120
- }
2121
- }
2122
-
2123
- private function unzipExists()
2124
- {
2125
- $unzip = mwp_container()->getExecutableFinder()->find('unzip', 'unzip');
2126
- $processBuilder = Symfony_Process_ProcessBuilder::create()
2127
- ->setWorkingDirectory(untrailingslashit(ABSPATH))
2128
- ->setPrefix($unzip)
2129
- ->add('-h');
2130
- try {
2131
- if (!mwp_is_shell_available()) {
2132
- throw new MMB_Exception("Shell is not available");
2133
- }
2134
- $process = $processBuilder->getProcess();
2135
- $process->run();
2136
-
2137
- return $process->isSuccessful();
2138
- } catch (Exception $e) {
2139
- return false;
2140
- }
2141
- }
2142
-
2143
- private function mySqlDumpExists()
2144
- {
2145
- $mysqldump = mwp_container()->getExecutableFinder()->find('mysqldump', 'mysqldump');
2146
- $processBuilder = Symfony_Process_ProcessBuilder::create()
2147
- ->setWorkingDirectory(untrailingslashit(ABSPATH))
2148
- ->setPrefix($mysqldump)
2149
- ->add('--version');
2150
- try {
2151
- if (!mwp_is_shell_available()) {
2152
- throw new MMB_Exception("Shell is not available");
2153
- }
2154
- $process = $processBuilder->getProcess();
2155
- $process->run();
2156
-
2157
- return $process->isSuccessful();
2158
- } catch (Exception $e) {
2159
- return false;
2160
- }
2161
- }
2162
-
2163
- private function mySqlExists()
2164
- {
2165
- $mysql = mwp_container()->getExecutableFinder()->find('mysql', 'mysql');
2166
- $processBuilder = Symfony_Process_ProcessBuilder::create()
2167
- ->setWorkingDirectory(untrailingslashit(ABSPATH))
2168
- ->setPrefix($mysql)
2169
- ->add('--version');
2170
- try {
2171
- if (!mwp_is_shell_available()) {
2172
- throw new MMB_Exception("Shell is not available");
2173
- }
2174
- $process = $processBuilder->getProcess();
2175
- $process->run();
2176
-
2177
- return $process->isSuccessful();
2178
- } catch (Exception $e) {
2179
- return false;
2180
- }
2181
- }
2182
-
2183
- private function is32Bits()
2184
- {
2185
- return strlen(decbin(~0)) == 32;
2186
- }
2187
-
2188
- /**
2189
- * Returns all important information of worker's system status to master.
2190
- *
2191
- * @return mixed associative array with information of server OS, php version, is backup folder writable, execute function, zip and unzip command, execution time, memory limit and path to error log if exists
2192
- */
2193
- public function check_backup_compat()
2194
- {
2195
- $reqs = array();
2196
- if (strpos($_SERVER['DOCUMENT_ROOT'], '/') === 0) {
2197
- $reqs['Server OS']['status'] = 'Linux (or compatible)';
2198
- $reqs['Server OS']['pass'] = true;
2199
- } else {
2200
- $reqs['Server OS']['status'] = 'Windows';
2201
- $reqs['Server OS']['pass'] = true;
2202
- $pass = false;
2203
- }
2204
- $reqs['Process architecture']['status'] = '64bit';
2205
- $reqs['Process architecture']['pass'] = true;
2206
- if ($this->is32Bits()) {
2207
- $reqs['Process architecture']['status'] = '';
2208
- $reqs['Process architecture']['info'] = '32bit';
2209
- $reqs['Process architecture']['pass'] = false;
2210
- }
2211
- $reqs['PHP Version']['status'] = PHP_VERSION;
2212
- if (version_compare(PHP_VERSION, '5.3', '>=')) {
2213
- $reqs['PHP Version']['pass'] = true;
2214
- } else {
2215
- $reqs['PHP Version']['status'] = '';
2216
- $reqs['PHP Version']['info'] = PHP_VERSION;
2217
- $reqs['PHP Version']['pass'] = false;
2218
- $pass = false;
2219
- }
2220
-
2221
- if (mwp_is_safe_mode()) {
2222
- $reqs['Safe Mode']['status'] = 'on';
2223
- $reqs['Safe Mode']['pass'] = false;
2224
- } else {
2225
- $reqs['Safe Mode']['status'] = 'off';
2226
- $reqs['Safe Mode']['pass'] = true;
2227
- }
2228
-
2229
- if (is_writable(WP_CONTENT_DIR)) {
2230
- $reqs['Backup Folder']['status'] = "writable";
2231
- $reqs['Backup Folder']['pass'] = true;
2232
- } else {
2233
- $reqs['Backup Folder']['status'] = "not writable";
2234
- $reqs['Backup Folder']['pass'] = false;
2235
- }
2236
-
2237
- if (is_writable(ABSPATH)) {
2238
- $reqs['Root Folder']['status'] = "writable";
2239
- $reqs['Root Folder']['pass'] = true;
2240
- } else {
2241
- $reqs['Root Folder']['status'] = "not writable";
2242
- $reqs['Root Folder']['pass'] = false;
2243
- }
2244
-
2245
- $file_path = MWP_BACKUP_DIR;
2246
- $reqs['Backup Folder']['status'] .= ' ('.$file_path.')';
2247
-
2248
- $reqs['Function `proc_open`']['status'] = 'exists';
2249
- $reqs['Function `proc_open`']['pass'] = true;
2250
- if (!$this->procOpenExists()) {
2251
- $reqs['Function `proc_open`']['status'] = "not found";
2252
- $reqs['Function `proc_open`']['pass'] = false;
2253
- }
2254
-
2255
- $reqs['Zip']['status'] = 'exists';
2256
- $reqs['Zip']['pass'] = true;
2257
- if (!$this->zipExists()) {
2258
- $reqs['Zip']['status'] = 'not found';
2259
- //$reqs['Zip']['info'] = 'We\'ll use ZipArchive replacement';
2260
- $reqs['Zip']['pass'] = false;
2261
-
2262
- $reqs['ZipArchive']['status'] = 'exists';
2263
- $reqs['ZipArchive']['pass'] = true;
2264
- if (!class_exists('ZipArchive')) {
2265
- $reqs['ZipArchive']['status'] = 'not found';
2266
- $reqs['ZipArchive']['info'] = 'We\'ll use PclZip replacement (PclZip takes up the memory that is equal to size of your site)';
2267
- $reqs['ZipArchive']['pass'] = false;
2268
- }
2269
- }
2270
-
2271
- $reqs['Unzip']['status'] = 'exists';
2272
- $reqs['Unzip']['pass'] = true;
2273
- if (!$this->unzipExists()) {
2274
- $reqs['Unzip']['status'] = 'not found';
2275
- $reqs['Unzip']['info'] = 'We\'ll use PclZip replacement (PclZip takes up the memory that is equal to size of your site)';
2276
- $reqs['Unzip']['pass'] = false;
2277
- }
2278
-
2279
- $reqs['MySQL Dump']['status'] = 'exists';
2280
- $reqs['MySQL Dump']['pass'] = true;
2281
- if (!$this->mySqlDumpExists()) {
2282
- $reqs['MySQL Dump']['status'] = "not found";
2283
- $reqs['MySQL Dump']['info'] = "(we'll use PHP replacement)";
2284
- $reqs['MySQL Dump']['pass'] = false;
2285
- }
2286
-
2287
- $reqs['MySQL']['status'] = 'exists';
2288
- $reqs['MySQL']['pass'] = true;
2289
- if (!$this->mySqlExists()) {
2290
- $reqs['MySQL']['status'] = "not found";
2291
- $reqs['MySQL']['info'] = "(we'll use PHP replacement)";
2292
- $reqs['MySQL']['pass'] = false;
2293
- }
2294
- $reqs['Curl']['status'] = 'not found';
2295
- $reqs['Curl']['pass'] = false;
2296
- if (function_exists('curl_init') && function_exists('curl_exec')) {
2297
- $reqs['Curl']['status'] = 'exists';
2298
- $reqs['Curl']['pass'] = true;
2299
- }
2300
- $exec_time = ini_get('max_execution_time');
2301
- $exec_unlimited = ($exec_time === '0');
2302
- $reqs['PHP Execution time']['status'] = ($exec_unlimited ? 'unlimited' : ($exec_time ? $exec_time."s" : 'unknown'));
2303
- $reqs['PHP Execution time']['pass'] = true;
2304
-
2305
- $mem_limit = ini_get('memory_limit');
2306
- $mem_limit = mwp_format_memory_limit($mem_limit);
2307
- $reqs['PHP Memory limit']['status'] = $mem_limit ? $mem_limit : 'unknown';
2308
- $reqs['PHP Memory limit']['pass'] = true;
2309
-
2310
- $changed = $this->set_memory();
2311
- if ($changed['execution_time']) {
2312
- $exec_time = ini_get('max_execution_time');
2313
- $reqs['PHP Execution time']['status'] .= $exec_time ? ' (will try '.$exec_time.'s)' : ' (unknown)';
2314
- }
2315
- if ($changed['memory_limit']) {
2316
- $mem_limit = ini_get('memory_limit');
2317
- $mem_limit = mwp_format_memory_limit($mem_limit);
2318
- $reqs['PHP Memory limit']['status'] .= $mem_limit ? ' (will try '.$mem_limit.')' : ' (unknown)';
2319
- }
2320
-
2321
- $reqs['Worker Version']['status'] = $GLOBALS['MMB_WORKER_VERSION'];
2322
- $reqs['Worker Version']['pass'] = true;
2323
-
2324
- $reqs['Worker Revision']['status'] = $GLOBALS['MMB_WORKER_REVISION'];
2325
- $reqs['Worker Revision']['pass'] = true;
2326
-
2327
- return $reqs;
2328
- }
2329
-
2330
- /**
2331
- * Uploads backup file from server to email.
2332
- * A lot of email service have limitation to 10mb.
2333
- *
2334
- * @param array $args arguments passed to the function
2335
- * [email] -> email address which backup should send to
2336
- * [task_name] -> name of backup task
2337
- * [file_path] -> absolute path of backup file on local server
2338
- *
2339
- * @return bool|array true is successful, array with error message if not
2340
- */
2341
- public function email_backup($args)
2342
- {
2343
- $email = $args['email'];
2344
-
2345
- if (!is_email($email)) {
2346
- return array(
2347
- 'error' => 'Your email ('.$email.') is not correct',
2348
- );
2349
- }
2350
- $backup_file = $args['file_path'];
2351
- $task_name = isset($args['task_name']) ? $args['task_name'] : '';
2352
- if (file_exists($backup_file)) {
2353
- $attachments = array(
2354
- $backup_file,
2355
- );
2356
- $headers = 'From: ManageWP <no-reply@managewp.com>'."\r\n";
2357
- $subject = "ManageWP - ".$task_name." - ".$this->site_name;
2358
- ob_start();
2359
- $result = wp_mail($email, $subject, $subject, $headers, $attachments);
2360
- ob_end_clean();
2361
- } else {
2362
- return array(
2363
- 'error' => 'The backup file ('.$backup_file.') does not exist.',
2364
- );
2365
- }
2366
-
2367
- if (!$result) {
2368
- return array(
2369
- 'error' => 'Email not sent. Maybe your backup is too big for email or email server is not available on your website.',
2370
- );
2371
- }
2372
-
2373
- return true;
2374
- }
2375
-
2376
- /**
2377
- * Uploads backup file from server to remote sftp server.
2378
- *
2379
- * @param array $args arguments passed to the function
2380
- * [sftp_username] -> sftp username on remote server
2381
- * [sftp_password] -> sftp password on remote server
2382
- * [sftp_hostname] -> sftp hostname of remote host
2383
- * [sftp_remote_folder] -> folder on remote site which backup file should be upload to
2384
- * [sftp_site_folder] -> subfolder with site name in ftp_remote_folder which backup file should be upload to
2385
- * [sftp_passive] -> passive mode or not
2386
- * [sftp_ssl] -> ssl or not
2387
- * [sftp_port] -> number of port for ssl protocol
2388
- * [backup_file] -> absolute path of backup file on local server
2389
- *
2390
- * @return bool|array true is successful, array with error message if not
2391
- */
2392
- public function sftp_backup($args)
2393
- {
2394
- $port = $args['sftp_port'] ? (int) $args['sftp_port'] : 22; //default port is 22
2395
- $sftp_hostname = $args['sftp_hostname'];
2396
- $sftp_username = $args['sftp_username'];
2397
- $sftp_password = $args['sftp_password'];
2398
- $sftp_remote_folder = untrailingslashit($args['sftp_remote_folder']);
2399
- $sftp_site_folder = (bool) $args['sftp_site_folder'];
2400
- $backup_file = $args['backup_file'];
2401
- $errorCatcher = new MWP_Debug_ErrorCatcher();
2402
-
2403
- if ($sftp_site_folder) {
2404
- $sftp_remote_folder .= ($sftp_remote_folder ? '/' : '').$this->site_name;
2405
- }
2406
-
2407
- try {
2408
- $sftp = $this->sftpFactory($sftp_username, $sftp_password, $sftp_hostname, $port);
2409
- } catch (Exception $e) {
2410
- return array(
2411
- 'error' => $e->getMessage(),
2412
- 'partial' => 1,
2413
- );
2414
- }
2415
-
2416
- mwp_logger()->info('Creating backup directory {sftp_directory}', array(
2417
- 'sftp_directory' => $sftp_remote_folder,
2418
- ));
2419
-
2420
- $errorCatcher->register();
2421
- $directoryCreated = $sftp->mkdir($sftp_remote_folder, -1, true);
2422
- $errorCatcher->unRegister();
2423
-
2424
- if (!$directoryCreated && ($caughtError = $errorCatcher->yieldErrorMessage())) {
2425
- mwp_logger()->error('Unable to create SFTP directory {sftp_directory} (error message: {error_message})', array(
2426
- 'sftp_directory' => $sftp_remote_folder,
2427
- 'error_message' => $caughtError,
2428
- ));
2429
-
2430
- return array(
2431
- 'error' => sprintf('Could not create backup directory (%s). Error message: %s.', $sftp_remote_folder, $caughtError),
2432
- 'partial' => 1,
2433
- );
2434
- }
2435
-
2436
- mwp_logger()->info('Uploading backup file "{backup_file}" (size: {backup_size}) to SFTP server', array(
2437
- 'backup_file' => $backup_file,
2438
- 'backup_size' => mwp_format_bytes(filesize($backup_file)),
2439
- ));
2440
-
2441
- $started = microtime(true);
2442
-
2443
- $errorCatcher->register();
2444
- $fileUploaded = $sftp->put($sftp_remote_folder.'/'.basename($backup_file), $backup_file, NET_SFTP_LOCAL_FILE);
2445
- $errorCatcher->unRegister();
2446
-
2447
- if (!$fileUploaded) {
2448
- if ($caughtError = $errorCatcher->yieldErrorMessage()) {
2449
- $errorMessage = sprintf(' Error message: %s.', $caughtError);
2450
- } else {
2451
- $errorMessage = sprintf(' Are you sure you have permissions to write to the directory "%s"?', $sftp_remote_folder);
2452
- }
2453
- mwp_logger()->error('Error while uploading the backup file to SFTP (error message: {error_message})', array(
2454
- 'error_message' => empty($caughtError) ? 'empty' : $caughtError,
2455
- ));
2456
-
2457
- return array(
2458
- 'error' => 'Unable to upload backup file.'.$errorMessage,
2459
- );
2460
- }
2461
- mwp_logger()->info('SFTP upload successfully completed; average speed is {speed}/s', array(
2462
- 'speed' => mwp_format_bytes(round(filesize($backup_file) / (microtime(true) - $started))),
2463
- ));
2464
-
2465
- $sftp->disconnect();
2466
-
2467
- return true;
2468
- }
2469
-
2470
- private function ftpErrorMessage($message, $additionalMessage = null)
2471
- {
2472
- if ($additionalMessage) {
2473
- $message .= ' Message: '.$additionalMessage.'.';
2474
- }
2475
-
2476
- return $message;
2477
- }
2478
-
2479
- private function ftpFactory($username, $password, $host, $port = 21, $ssl = false, $passive = false, $timeout = 10)
2480
- {
2481
- $errorCatcher = new MWP_Debug_ErrorCatcher();
2482
- if ($ssl) {
2483
- if (!function_exists('ftp_ssl_connect')) {
2484
- throw new Exception('FTPS disabled: Please enable ftp_ssl_connect in PHP.');
2485
- }
2486
- $errorCatcher->register('ftp_ssl_connect');
2487
- $ftp = ftp_ssl_connect($host, $port, $timeout);
2488
- $errorCatcher->unRegister();
2489
- } else {
2490
- if (!function_exists('ftp_connect')) {
2491
- throw new Exception('FTP disabled: Please enable ftp_connect in PHP.');
2492
- }
2493
- $errorCatcher->register('ftp_connect');
2494
- $ftp = ftp_connect($host, $port, $timeout);
2495
- $errorCatcher->unRegister();
2496
- }
2497
-
2498
- if ($ftp === false) {
2499
- throw new Exception($this->ftpErrorMessage('Failed connecting to the FTP server, please check FTP host and port.', $errorCatcher->yieldErrorMessage()));
2500
- }
2501
-
2502
- $errorCatcher->register('ftp_login');
2503
- $login = ftp_login($ftp, $username, $password);
2504
- $errorCatcher->unRegister();
2505
-
2506
- if ($login === false) {
2507
- throw new Exception($this->ftpErrorMessage('FTP login failed, please check your FTP login details.', $errorCatcher->yieldErrorMessage()));
2508
- }
2509
-
2510
- if ($passive) {
2511
- ftp_pasv($ftp, true);
2512
- }
2513
-
2514
- return $ftp;
2515
- }
2516
-
2517
- /**
2518
- * Uploads backup file from server to remote ftp server.
2519
- *
2520
- * @param array $args arguments passed to the function
2521
- * [ftp_username] -> ftp username on remote server
2522
- * [ftp_password] -> ftp password on remote server
2523
- * [ftp_hostname] -> ftp hostname of remote host
2524
- * [ftp_remote_folder] -> folder on remote site which backup file should be upload to
2525
- * [ftp_site_folder] -> subfolder with site name in ftp_remote_folder which backup file should be upload to
2526
- * [ftp_passive] -> passive mode or not
2527
- * [ftp_ssl] -> ssl or not
2528
- * [ftp_port] -> number of port for ssl protocol
2529
- * [backup_file] -> absolute path of backup file on local server
2530
- *
2531
- * @return bool|array true is successful, array with error message if not
2532
- */
2533
- public function ftp_backup($args)
2534
- {
2535
- $port = $args['ftp_port'] ? $args['ftp_port'] : 21;
2536
- $ftp_hostname = $args['ftp_hostname'];
2537
- $ftp_password = $args['ftp_password'];
2538
- $ftp_username = $args['ftp_username'];
2539
- $ftp_ssl = (bool) $args['ftp_ssl'];
2540
- $ftp_passive = (bool) $args['ftp_passive'];
2541
- $ftp_site_folder = (bool) $args['ftp_site_folder'];
2542
- $backup_file = $args['backup_file'];
2543
- $ftp_remote_folder = untrailingslashit($args['ftp_remote_folder']);
2544
-
2545
- if ($ftp_site_folder) {
2546
- $ftp_remote_folder .= ($ftp_remote_folder ? '/' : '').$this->site_name;
2547
- }
2548
-
2549
- $errorCatcher = new MWP_Debug_ErrorCatcher();
2550
-
2551
- try {
2552
- $ftp = $this->ftpFactory($ftp_username, $ftp_password, $ftp_hostname, $port, $ftp_ssl, $ftp_passive);
2553
- } catch (Exception $e) {
2554
- return array(
2555
- 'error' => $e->getMessage(),
2556
- );
2557
- }
2558
-
2559
- try {
2560
- $this->ftpMkdir($ftp, $ftp_remote_folder);
2561
- } catch (Exception $e) {
2562
- return array(
2563
- 'error' => $e->getMessage(),
2564
- );
2565
- }
2566
-
2567
- $errorCatcher->register('ftp_put');
2568
- $uploaded = ftp_put($ftp, $ftp_remote_folder.'/'.basename($backup_file), $backup_file, FTP_BINARY);
2569
- $errorCatcher->unRegister();
2570
-
2571
- if (!$uploaded) {
2572
- $errorMessage = 'Failed to upload the backup file.';
2573
- $caughtError = $errorCatcher->yieldErrorMessage();
2574
-
2575
- if (!(bool) $args['ftp_passive'] && $caughtError && (strpos($caughtError, 'I won\'t open a connection to') !== false)) {
2576
- $errorMessage .= ' Have you tried enabling the passive mode?';
2577
- }
2578
-
2579
- return array(
2580
- 'error' => $this->ftpErrorMessage($errorMessage, $errorCatcher->yieldErrorMessage()),
2581
- );
2582
- }
2583
-
2584
- ftp_close($ftp);
2585
-
2586
- return true;
2587
- }
2588
-
2589
- private function ftpMkdir($ftp, $path)
2590
- {
2591
- $errorCatcher = new MWP_Debug_ErrorCatcher();
2592
- $path = str_replace('\\', '/', $path);
2593
- $path = str_replace('//', '/', $path);
2594
-
2595
- if (substr($path, 0, 1) === '/') {
2596
- $currentPath = '/';
2597
- $path = substr($path, 1);
2598
- } else {
2599
- $currentPath = '';
2600
- }
2601
-
2602
- $path = rtrim($path, '/');
2603
- $paths = explode('/', $path);
2604
- while ($directory = array_shift($paths)) {
2605
- $errorCatcher->register('ftp_nlist');
2606
- $dirList = ftp_nlist($ftp, $currentPath);
2607
- $errorCatcher->unRegister();
2608
- $currentPath .= $directory;
2609
-
2610
- if ($dirList === false) {
2611
- throw new Exception($this->ftpErrorMessage(sprintf('Unable to list FTP directory content (directory: "%s").', $currentPath), $errorCatcher->yieldErrorMessage()));
2612
- }
2613
-
2614
- $dirList = array_map('basename', $dirList);
2615
-
2616
- $dirExists = in_array($directory, $dirList);
2617
-
2618
- if (!$dirExists) {
2619
- $errorCatcher->register('ftp_mkdir');
2620
- $dirMade = ftp_mkdir($ftp, $currentPath);
2621
- $errorCatcher->unRegister();
2622
-
2623
- if (!$dirMade) {
2624
- throw new Exception($this->ftpErrorMessage(sprintf('Unable to make directory %s.', $currentPath), $errorCatcher->yieldErrorMessage()));
2625
- }
2626
- }
2627
-
2628
- $currentPath .= '/';
2629
- }
2630
- }
2631
-
2632
- /**
2633
- * Deletes backup file from remote ftp server.
2634
- *
2635
- * @param array $args arguments passed to the function
2636
- * [ftp_username] -> ftp username on remote server
2637
- * [ftp_password] -> ftp password on remote server
2638
- * [ftp_hostname] -> ftp hostname of remote host
2639
- * [ftp_remote_folder] -> folder on remote site which backup file should be deleted from
2640
- * [ftp_site_folder] -> subfolder with site name in ftp_remote_folder which backup file should be deleted from
2641
- * [backup_file] -> absolute path of backup file on local server
2642
- *
2643
- * @return void
2644
- */
2645
- public function remove_ftp_backup($args)
2646
- {
2647
- $port = $args['ftp_port'] ? (int) $args['ftp_port'] : 21;
2648
- $ftp_remote_folder = untrailingslashit($args['ftp_remote_folder']);
2649
- $errorCatcher = new MWP_Debug_ErrorCatcher();
2650
-
2651
- if ($args['ftp_site_folder']) {
2652
- $ftp_remote_folder .= ($ftp_remote_folder ? '/' : '').$this->site_name;
2653
- }
2654
-
2655
- try {
2656
- $ftp = $this->ftpFactory($args['ftp_username'], $args['ftp_password'], $args['ftp_hostname'], $port, (bool) $args['ftp_ssl'], (bool) $args['ftp_passive']);
2657
- } catch (Exception $e) {
2658
- mwp_logger()->error('Unable to connect to FTP server at {ftp_user}@{ftp_host}:{ftp_port}', array(
2659
- 'ftp_user' => $args['ftp_username'],
2660
- 'ftp_host' => $args['ftp_hostname'],
2661
- 'ftp_port' => $port,
2662
- 'error_message' => $e->getMessage(),
2663
- ));
2664
-
2665
- return;
2666
- }
2667
-
2668
- $errorCatcher->register('ftp_delete');
2669
- $delete = ftp_delete($ftp, $ftp_remote_folder.'/'.$args['backup_file']);
2670
- $errorCatcher->unRegister();
2671
-
2672
- if (!$delete) {
2673
- $caughtError = $errorCatcher->yieldErrorMessage();
2674
- mwp_logger()->error('Error while deleting backup file from FTP; error message: {error_message}', array(
2675
- 'error_message' => empty($caughtError) ? 'empty' : $caughtError,
2676
- ));
2677
- }
2678
-
2679
- ftp_close($ftp);
2680
- }
2681
-
2682
- /**
2683
- * Deletes backup file from remote sftp server.
2684
- *
2685
- * @param array $args arguments passed to the function
2686
- * [sftp_username] -> sftp username on remote server
2687
- * [sftp_password] -> sftp password on remote server
2688
- * [sftp_hostname] -> sftp hostname of remote host
2689
- * [sftp_remote_folder] -> folder on remote site which backup file should be deleted from
2690
- * [sftp_site_folder] -> subfolder with site name in ftp_remote_folder which backup file should be deleted from
2691
- * [backup_file] -> absolute path of backup file on local server
2692
- *
2693
- * @return void
2694
- */
2695
- public function remove_sftp_backup($args)
2696
- {
2697
- $port = $args['sftp_port'] ? (int) $args['sftp_port'] : 22; //default port is 22
2698
- $sftp_hostname = $args['sftp_hostname'];
2699
- $sftp_username = $args['sftp_username'];
2700
- $sftp_password = $args['sftp_password'];
2701
- $backup_file = $args['backup_file'];
2702
-
2703
- $sftp_remote_folder = untrailingslashit($args['sftp_remote_folder']);
2704
-
2705
- if ($args['sftp_site_folder']) {
2706
- $sftp_remote_folder .= ($sftp_remote_folder ? '/' : '').$this->site_name;
2707
- }
2708
-
2709
- try {
2710
- $sftp = $this->sftpFactory($sftp_username, $sftp_password, $sftp_hostname, $port);
2711
- } catch (Exception $e) {
2712
- return;
2713
- }
2714
-
2715
- $sftp->delete($sftp_remote_folder.'/'.$backup_file, false);
2716
-
2717
- $sftp->disconnect();
2718
- }
2719
-
2720
- /**
2721
- * Downloads backup file from server from remote ftp server to root folder on local server.
2722
- *
2723
- * @param array $args arguments passed to the function
2724
- * [ftp_username] -> ftp username on remote server
2725
- * [ftp_password] -> ftp password on remote server
2726
- * [ftp_hostname] -> ftp hostname of remote host
2727
- * [ftp_remote_folder] -> folder on remote site which backup file should be downloaded from
2728
- * [ftp_site_folder] -> subfolder with site name in ftp_remote_folder which backup file should be downloaded from
2729
- * [backup_file] -> absolute path of backup file on local server
2730
- *
2731
- * @return string|array absolute path to downloaded file is successful, array with error message if not
2732
- */
2733
- public function get_ftp_backup($args)
2734
- {
2735
- $port = $args['ftp_port'] ? (int) $args['ftp_port'] : 21;
2736
- $ftp_remote_folder = untrailingslashit($args['ftp_remote_folder']);
2737
- $backup_file = $args['backup_file'];
2738
-
2739
- if ($args['ftp_site_folder']) {
2740
- $ftp_remote_folder .= ($ftp_remote_folder ? '/' : '').$this->site_name;
2741
- }
2742
-
2743
- try {
2744
- $ftp = $this->ftpFactory($args['ftp_username'], $args['ftp_password'], $args['ftp_hostname'], $port, (bool) $args['ftp_ssl'], $args['ftp_passive']);
2745
- } catch (Exception $e) {
2746
- mwp_logger()->error('Unable to connect to FTP server at {ftp_user}@{ftp_host}:{ftp_port}', array(
2747
- 'ftp_user' => $args['ftp_username'],
2748
- 'ftp_host' => $args['ftp_hostname'],
2749
- 'ftp_port' => $port,
2750
- 'error_message' => $e->getMessage(),
2751
- ));
2752
-
2753
- return array(
2754
- 'error' => $e->getMessage(),
2755
- );
2756
- }
2757
-
2758
- $errorCatcher = new MWP_Debug_ErrorCatcher();
2759
-
2760
- $temp = ABSPATH.'mwp_temp_backup.zip';
2761
-
2762
- $errorCatcher->register('ftp_get');
2763
- $fileDownloaded = ftp_get($ftp, $temp, $ftp_remote_folder.'/'.$backup_file, FTP_BINARY);
2764
- $errorCatcher->unRegister();
2765
-
2766
- if ($fileDownloaded === false) {
2767
- $caughtError = $errorCatcher->yieldErrorMessage();
2768
- mwp_logger()->error('Error while deleting backup file from FTP; error message: {error_message}', array(
2769
- 'error_message' => empty($caughtError) ? 'empty' : $caughtError,
2770
- ));
2771
-
2772
- return array(
2773
- 'error' => $this->ftpErrorMessage('Error while downloading the backup file.', $caughtError),
2774
- );
2775
- }
2776
-
2777
- ftp_close($ftp);
2778
-
2779
- return $temp;
2780
- }
2781
-
2782
- /**
2783
- * Downloads backup file from server from remote ftp server to root folder on local server.
2784
- *
2785
- * @param array $args arguments passed to the function
2786
- * [sftp_username] -> ftp username on remote server
2787
- * [sftp_password] -> ftp password on remote server
2788
- * [sftp_hostname] -> ftp hostname of remote host
2789
- * [sftp_remote_folder] -> folder on remote site which backup file should be downloaded from
2790
- * [sftp_site_folder] -> subfolder with site name in ftp_remote_folder which backup file should be downloaded from
2791
- * [backup_file] -> absolute path of backup file on local server
2792
- *
2793
- * @return string|array absolute path to downloaded file is successful, array with error message if not
2794
- */
2795
- public function get_sftp_backup($args)
2796
- {
2797
- $port = $args['sftp_port'] ? (int) $args['sftp_port'] : 22;
2798
- $sftp_hostname = $args['sftp_hostname'];
2799
- $sftp_username = $args['sftp_username'];
2800
- $sftp_password = $args['sftp_password'];
2801
- $backup_file = $args['backup_file'];
2802
- $errorCatcher = new MWP_Debug_ErrorCatcher();
2803
-
2804
- $sftp_remote_folder = untrailingslashit($args['sftp_remote_folder']);
2805
-
2806
- if ($args['sftp_site_folder']) {
2807
- $sftp_remote_folder .= ($sftp_remote_folder ? '/' : '').$this->site_name;
2808
- }
2809
-
2810
- try {
2811
- $sftp = $this->sftpFactory($sftp_username, $sftp_password, $sftp_hostname, $port);
2812
- } catch (Exception $e) {
2813
- return array(
2814
- 'error' => $e->getMessage(),
2815
- );
2816
- }
2817
-
2818
- $temp = ABSPATH.'mwp_temp_backup.zip';
2819
- $started = microtime(true);
2820
-
2821
- mwp_logger()->info('Attempting to download the backup file from SFTP to a temporary location', array(
2822
- 'backup_file' => $sftp_remote_folder.'/'.$backup_file,
2823
- 'temporary_path' => $temp,
2824
- ));
2825
-
2826
- $errorCatcher->register();
2827
- $fileDownloaded = $sftp->get($sftp_remote_folder.'/'.$backup_file, $temp);
2828
- $errorCatcher->unRegister();
2829
-
2830
- if (!$fileDownloaded) {
2831
- $caughtError = $errorCatcher->yieldErrorMessage();
2832
- mwp_logger()->error('Error while attempting to download backup file; error message: {error_message}', array(
2833
- 'error_message' => empty($caughtError) ? 'empty' : $caughtError,
2834
- ));
2835
-
2836
- return array(
2837
- 'error' => $this->ftpErrorMessage('Error while attempting to download the backup file.', $caughtError),
2838
- );
2839
- }
2840
-
2841
- $speed = mwp_format_bytes(filesize($temp) / (round(microtime(true) - $started)));
2842
- mwp_logger()->info('Backup file successfully downloaded from SFTP; average speed is {speed}/s', array(
2843
- 'speed' => $speed,
2844
- ));
2845
-
2846
- $sftp->disconnect();
2847
-
2848
- return $temp;
2849
- }
2850
-
2851
- private function sftpFactory($username, $password, $host, $port = 22)
2852
- {
2853
- $errorCatcher = new MWP_Debug_ErrorCatcher();
2854
-
2855
- mwp_logger()->info('Connecting to SFTP host {sftp_host}:{sftp_port}', array(
2856
- 'sftp_host' => $host,
2857
- 'sftp_port' => $port,
2858
- ));
2859
-
2860
- require_once dirname(__FILE__).'/../PHPSecLib/Net/SFTP.php';
2861
- $errorCatcher->register();
2862
- $sftp = new Net_SFTP($host, $port);
2863
- $errorCatcher->unRegister();
2864
-
2865
- if ($caughtError = $errorCatcher->yieldErrorMessage()) {
2866
- mwp_logger()->error('Error while connecting to SFTP: {error_message}', array(
2867
- 'error_message' => $caughtError,
2868
- ));
2869
-
2870
- throw new Exception('Host did not respond to the SFTP connection request. Error message: '.$caughtError);
2871
- }
2872
-
2873
- mwp_logger()->info('Logging in to SFTP host {sftp_user}@{sftp_host}:{sftp_port} (using password: {using_password})', array(
2874
- 'sftp_user' => $username,
2875
- 'sftp_host' => $host,
2876
- 'sftp_port' => $port,
2877
- 'using_password' => empty($password) ? 'no' : 'yes',
2878
- ));
2879
-
2880
- $errorCatcher->register();
2881
- $login = $sftp->login($username, $password);
2882
- $errorCatcher->unRegister();
2883
-
2884
- if (!$login) {
2885
- $errorMessage = '';
2886
-
2887
- if ($caughtError = $errorCatcher->yieldErrorMessage()) {
2888
- $errorMessage = sprintf(' Error message: %s.', $caughtError);
2889
- }
2890
-
2891
- mwp_logger()->error('Unable to login to SFTP host {sftp_host}:{sftp_port} (error message: {error_message})', array(
2892
- 'sftp_host' => $host,
2893
- 'sftp_port' => $port,
2894
- 'error_message' => empty($caughtError) ? 'empty' : $caughtError,
2895
- ));
2896
-
2897
- throw new Exception('SFTP server has rejected the provided credentials.'.$errorMessage);
2898
- }
2899
-
2900
- return $sftp;
2901
- }
2902
-
2903
- /**
2904
- * Uploads backup file from server to Dropbox.
2905
- *
2906
- * @param array $args arguments passed to the function
2907
- * [consumer_key] -> consumer key of ManageWP Dropbox application
2908
- * [consumer_secret] -> consumer secret of ManageWP Dropbox application
2909
- * [oauth_token] -> oauth token of user on ManageWP Dropbox application
2910
- * [oauth_token_secret] -> oauth token secret of user on ManageWP Dropbox application
2911
- * [dropbox_destination] -> folder on user's Dropbox account which backup file should be upload to
2912
- * [dropbox_site_folder] -> subfolder with site name in dropbox_destination which backup file should be upload to
2913
- * [backup_file] -> absolute path of backup file on local server
2914
- *
2915
- * @return bool|array true is successful, array with error message if not
2916
- */
2917
- public function dropbox_backup($args)
2918
- {
2919
- mwp_logger()->info('Acquiring Dropbox token to start uploading the backup file');
2920
- try {
2921
- $dropbox = mwp_dropbox_oauth_factory($args['consumer_key'], $args['consumer_secret'], $args['oauth_token'], $args['oauth_token_secret']);
2922
- } catch (Exception $e) {
2923
- mwp_logger()->error('Error while acquiring Dropbox token', array(
2924
- 'exception' => $e,
2925
- ));
2926
-
2927
- return array(
2928
- 'error' => $e->getMessage(),
2929
- 'partial' => 1,
2930
- );
2931
- }
2932
-
2933
- $args['dropbox_destination'] = '/'.ltrim($args['dropbox_destination'], '/');
2934
-
2935
- if ($args['dropbox_site_folder'] == true) {
2936
- $args['dropbox_destination'] .= '/'.$this->site_name.'/'.basename($args['backup_file']);
2937
- } else {
2938
- $args['dropbox_destination'] .= '/'.basename($args['backup_file']);
2939
- }
2940
-
2941
- $fileSize = filesize($args['backup_file']);
2942
- $start = microtime(true);
2943
-
2944
- try {
2945
- mwp_logger()->info('Uploading backup file to Dropbox; file size is {backup_size} (progress support: {progress_support})', array(
2946
- 'backup_file' => $args['backup_file'],
2947
- 'backup_size' => mwp_format_bytes($fileSize),
2948
- 'directory' => $args['dropbox_destination'],
2949
- 'progress_support' => version_compare(PHP_VERSION, '5.3', '>=') ? 'enabled' : 'disabled',
2950
- ));
2951
- $callback = null;
2952
-
2953
- if (version_compare(PHP_VERSION, '5.3', '>=')) {
2954
- $progress = new MWP_Progress_Upload($fileSize, 3, mwp_logger());
2955
- $callback = $progress->getCallback();
2956
- }
2957
- $dropbox->uploadFile($args['dropbox_destination'], Dropbox_WriteMode::force(), fopen($args['backup_file'], 'r'), $fileSize, $callback);
2958
- } catch (Exception $e) {
2959
- mwp_logger()->error('Error while uploading the file to Dropbox', array(
2960
- 'exception' => $e,
2961
- ));
2962
-
2963
- return array(
2964
- 'error' => $e->getMessage(),
2965
- 'partial' => 1,
2966
- );
2967
- }
2968
-
2969
- mwp_logger()->info('Backup to Dropbox completed; average speed is {speed}/s', array(
2970
- 'speed' => mwp_format_bytes($fileSize / (microtime(true) - $start)),
2971
- ));
2972
-
2973
- return true;
2974
- }
2975
-
2976
- /**
2977
- * Deletes backup file from Dropbox to root folder on local server.
2978
- *
2979
- * @param array $args arguments passed to the function
2980
- * [consumer_key] -> consumer key of ManageWP Dropbox application
2981
- * [consumer_secret] -> consumer secret of ManageWP Dropbox application
2982
- * [oauth_token] -> oauth token of user on ManageWP Dropbox application
2983
- * [oauth_token_secret] -> oauth token secret of user on ManageWP Dropbox application
2984
- * [dropbox_destination] -> folder on user's Dropbox account which backup file should be downloaded from
2985
- * [dropbox_site_folder] -> subfolder with site name in dropbox_destination which backup file should be downloaded from
2986
- * [backup_file] -> absolute path of backup file on local server
2987
- *
2988
- * @return void
2989
- */
2990
- public function remove_dropbox_backup($args)
2991
- {
2992
- mwp_logger()->info('Acquiring Dropbox token to remove a backup file');
2993
- try {
2994
- $dropbox = mwp_dropbox_oauth_factory($args['consumer_key'], $args['consumer_secret'], $args['oauth_token'], $args['oauth_token_secret']);
2995
- } catch (Exception $e) {
2996
- mwp_logger()->error('Error while acquiring Dropbox token', array(
2997
- 'exception' => $e,
2998
- ));
2999
-
3000
- return;
3001
- }
3002
-
3003
- $args['dropbox_destination'] = '/'.ltrim($args['dropbox_destination'], '/');
3004
-
3005
- if ($args['dropbox_site_folder'] == true) {
3006
- $args['dropbox_destination'] .= '/'.$this->site_name;
3007
- }
3008
-
3009
- mwp_logger()->info('Removing backup file from Dropbox', array(
3010
- 'backup_file' => $args['backup_file'],
3011
- ));
3012
- try {
3013
- $dropbox->delete($args['dropbox_destination'].'/'.$args['backup_file']);
3014
- } catch (Exception $e) {
3015
- mwp_logger()->error('Error while acquiring Dropbox token: [{class}] {message}', array(
3016
- 'exception' => $e,
3017
- ));
3018
- }
3019
- }
3020
-
3021
- /**
3022
- * Downloads backup file from Dropbox to root folder on local server.
3023
- *
3024
- * @param array $args arguments passed to the function
3025
- * [consumer_key] -> consumer key of ManageWP Dropbox application
3026
- * [consumer_secret] -> consumer secret of ManageWP Dropbox application
3027
- * [oauth_token] -> oauth token of user on ManageWP Dropbox application
3028
- * [oauth_token_secret] -> oauth token secret of user on ManageWP Dropbox application
3029
- * [dropbox_destination] -> folder on user's Dropbox account which backup file should be deleted from
3030
- * [dropbox_site_folder] -> subfolder with site name in dropbox_destination which backup file should be deleted from
3031
- * [backup_file] -> absolute path of backup file on local server
3032
- *
3033
- * @return bool|array absolute path to downloaded file is successful, array with error message if not
3034
- */
3035
- public function get_dropbox_backup($args)
3036
- {
3037
- mwp_logger()->info('Acquiring Dropbox token to download the backup file');
3038
- try {
3039
- $dropbox = mwp_dropbox_oauth_factory($args['consumer_key'], $args['consumer_secret'], $args['oauth_token'], $args['oauth_token_secret']);
3040
- } catch (Exception $e) {
3041
- mwp_logger()->error('Error while acquiring Dropbox token', array(
3042
- 'exception' => $e,
3043
- ));
3044
-
3045
- return array(
3046
- 'error' => $e->getMessage(),
3047
- 'partial' => 1,
3048
- );
3049
- }
3050
-
3051
- $args['dropbox_destination'] = '/'.ltrim($args['dropbox_destination'], '/');
3052
-
3053
- if ($args['dropbox_site_folder'] == true) {
3054
- $args['dropbox_destination'] .= '/'.$this->site_name;
3055
- }
3056
-
3057
- $file = $args['dropbox_destination'].'/'.$args['backup_file'];
3058
- $temp = ABSPATH.'mwp_temp_backup.zip';
3059
-
3060
- mwp_logger()->info('Downloading backup file from Dropbox to a temporary path', array(
3061
- 'backup_file' => $file,
3062
- 'temp_path' => $temp,
3063
- ));
3064
-
3065
- $start = microtime(true);
3066
- try {
3067
- $fh = fopen($temp, 'wb');
3068
-
3069
- if (!$fh) {
3070
- throw new RuntimeException(sprintf('Temporary file (%s) is not writable', $temp));
3071
- }
3072
-
3073
- $dropbox->getFile($file, $fh);
3074
- $result = fclose($fh);
3075
-
3076
- if (!$result) {
3077
- throw new Exception('Unable to close file handle.');
3078
- }
3079
- } catch (Exception $e) {
3080
- mwp_logger()->error('Downloading backup file from Dropbox failed', array(
3081
- 'exception' => $e,
3082
- ));
3083
-
3084
- return array(
3085
- 'error' => $e->getMessage(),
3086
- 'partial' => 1,
3087
- );
3088
- }
3089
-
3090
- $fileSize = filesize($temp);
3091
- mwp_logger()->info('Downloading backup file from Dropbox completed; file size is {backup_size}; average speed is {speed}', array(
3092
- 'backup_size' => mwp_format_bytes($fileSize),
3093
- 'speed' => mwp_format_bytes($fileSize / (microtime(true) - $start)),
3094
- ));
3095
-
3096
- return $temp;
3097
- }
3098
-
3099
- /**
3100
- * Uploads backup file from server to Amazon S3.
3101
- *
3102
- * @param array $args arguments passed to the function
3103
- * [as3_bucket_region] -> Amazon S3 bucket region
3104
- * [as3_bucket] -> Amazon S3 bucket
3105
- * [as3_access_key] -> Amazon S3 access key
3106
- * [as3_secure_key] -> Amazon S3 secure key
3107
- * [as3_directory] -> folder on user's Amazon S3 account which backup file should be upload to
3108
- * [as3_site_folder] -> subfolder with site name in as3_directory which backup file should be upload to
3109
- * [backup_file] -> absolute path of backup file on local server
3110
- *
3111
- * @return bool|array true is successful, array with error message if not
3112
- */
3113
- public function amazons3_backup($args)
3114
- {
3115
- if ($args['as3_site_folder'] == true) {
3116
- $args['as3_directory'] .= '/'.$this->site_name;
3117
- }
3118
- $endpoint = isset($args['as3_bucket_region']) ? $args['as3_bucket_region'] : 's3.amazonaws.com';
3119
- $fileSize = filesize($args['backup_file']);
3120
- $progressSupport = version_compare(PHP_VERSION, '5.3', '>=');
3121
- $start = microtime(true);
3122
-
3123
- mwp_logger()->info('Uploading backup file to Amazon S3)', array(
3124
- 'directory' => $args['as3_directory'],
3125
- 'bucket' => $args['as3_bucket'],
3126
- 'endpoint' => $endpoint,
3127
- 'backup_file' => $args['backup_file'],
3128
- 'backup_size' => $fileSize,
3129
- 'progress_support' => ($progressSupport ? 'enabled' : 'disabled'),
3130
- ));
3131
-
3132
- try {
3133
- $s3 = new S3_Client(trim($args['as3_access_key']), trim(str_replace(' ', '+', $args['as3_secure_key'])), false, $endpoint);
3134
- $s3->setExceptions(true);
3135
-
3136
- if ($progressSupport) {
3137
- $progress = new MWP_Progress_Upload(filesize($args['backup_file']), 3, mwp_logger());
3138
- $s3->setProgressCallback($progress->getCallback());
3139
- }
3140
-
3141
- $s3->putObjectFile($args['backup_file'], $args['as3_bucket'], $args['as3_directory'].'/'.basename($args['backup_file']), S3_Client::ACL_PRIVATE);
3142
- } catch (Exception $e) {
3143
- mwp_logger()->error('Upload to Amazon S3 failed', array(
3144
- 'exception' => $e,
3145
- ));
3146
-
3147
- return array(
3148
- 'error' => 'Failed to upload to Amazon S3 ('.$e->getMessage().').',
3149
- );
3150
- }
3151
-
3152
- mwp_logger()->info('Upload to Amazon S3 completed; average speed is {speed}/s', array(
3153
- 'speed' => mwp_format_bytes($fileSize / (microtime(true) - $start)),
3154
- ));
3155
-
3156
- return true;
3157
- }
3158
-
3159
- /**
3160
- * Deletes backup file from Amazon S3.
3161
- *
3162
- * @param array $args arguments passed to the function
3163
- * [as3_bucket_region] -> Amazon S3 bucket region
3164
- * [as3_bucket] -> Amazon S3 bucket
3165
- * [as3_access_key] -> Amazon S3 access key
3166
- * [as3_secure_key] -> Amazon S3 secure key
3167
- * [as3_directory] -> folder on user's Amazon S3 account which backup file should be deleted from
3168
- * [as3_site_folder] -> subfolder with site name in as3_directory which backup file should be deleted from
3169
- * [backup_file] -> absolute path of backup file on local server
3170
- *
3171
- * @return void
3172
- */
3173
- public function remove_amazons3_backup($args)
3174
- {
3175
- if ($args['as3_site_folder'] == true) {
3176
- $args['as3_directory'] .= '/'.$this->site_name;
3177
- }
3178
- $endpoint = isset($args['as3_bucket_region']) ? $args['as3_bucket_region'] : 's3.amazonaws.com';
3179
-
3180
- mwp_logger()->info('Removing the backup file from Amazon S3', array(
3181
- 'directory' => $args['as3_directory'],
3182
- 'bucket' => $args['as3_bucket'],
3183
- 'endpoint' => $endpoint,
3184
- 'backup_file' => $args['backup_file'],
3185
- ));
3186
-
3187
- try {
3188
- $s3 = new S3_Client(trim($args['as3_access_key']), trim(str_replace(' ', '+', $args['as3_secure_key'])), false, $endpoint);
3189
- $s3->setExceptions(true);
3190
- $s3->deleteObject($args['as3_bucket'], $args['as3_directory'].'/'.$args['backup_file']);
3191
- } catch (Exception $e) {
3192
- // @todo what now?
3193
- }
3194
- }
3195
-
3196
- /**
3197
- * Downloads backup file from Amazon S3 to root folder on local server.
3198
- *
3199
- * @param array $args arguments passed to the function
3200
- * [as3_bucket_region] -> Amazon S3 bucket region
3201
- * [as3_bucket] -> Amazon S3 bucket
3202
- * [as3_access_key] -> Amazon S3 access key
3203
- * [as3_secure_key] -> Amazon S3 secure key
3204
- * [as3_directory] -> folder on user's Amazon S3 account which backup file should be downloaded from
3205
- * [as3_site_folder] -> subfolder with site name in as3_directory which backup file should be downloaded from
3206
- * [backup_file] -> absolute path of backup file on local server
3207
- *
3208
- * @return bool|array absolute path to downloaded file is successful, array with error message if not
3209
- */
3210
- public function get_amazons3_backup($args)
3211
- {
3212
- $endpoint = isset($args['as3_bucket_region']) ? $args['as3_bucket_region'] : 's3.amazonaws.com';
3213
-
3214
- mwp_logger()->info('Downloading the backup file from Amazon S3', array(
3215
- 'directory' => $args['as3_directory'],
3216
- 'bucket' => $args['as3_bucket'],
3217
- 'endpoint' => $args['endpoint'],
3218
- 'backup_file' => $args['backup_file'],
3219
- ));
3220
-
3221
- if ($args['as3_site_folder'] == true) {
3222
- $args['as3_directory'] .= '/'.$this->site_name;
3223
- }
3224
- $start = microtime(true);
3225
- try {
3226
- $s3 = new S3_Client($args['as3_access_key'], str_replace(' ', '+', $args['as3_secure_key']), false, $endpoint);
3227
- $s3->setExceptions(true);
3228
- $temp = ABSPATH.'mwp_temp_backup.zip';
3229
-
3230
- if (version_compare(PHP_VERSION, '5.3', '>=')) {
3231
- $progress = new MWP_Progress_Download(3, mwp_logger());
3232
- $s3->setProgressCallback($progress->getCallback());
3233
- }
3234
- $s3->getObject($args['as3_bucket'], $args['as3_directory'].'/'.$args['backup_file'], $temp);
3235
- } catch (Exception $e) {
3236
- mwp_logger()->error('Error while downloading the backup file', array(
3237
- 'exception' => $e,
3238
- ));
3239
-
3240
- return array(
3241
- 'error' => 'Error while downloading the backup file from Amazon S3: '.$e->getMessage(),
3242
- );
3243
- }
3244
-
3245
- $fileSize = filesize($temp);
3246
- mwp_logger()->info('Downloading backup file from Amazon S3 completed; file size is {backup_size}; average speed is {speed}', array(
3247
- 'backup_size' => mwp_format_bytes($fileSize),
3248
- 'speed' => mwp_format_bytes($fileSize / (microtime(true) - $start)),
3249
- ));
3250
-
3251
- return $temp;
3252
- }
3253
-
3254
- /**
3255
- * Uploads backup file from server to Google Drive.
3256
- *
3257
- * @param array $args arguments passed to the function
3258
- * [task_name] -> Task name for wich we are uploading
3259
- * [task_result_key] -> Result key that we are uploading
3260
- * [google_drive_token] -> user's Google drive token in json form
3261
- * [google_drive_directory] -> folder on user's Google Drive account which backup file should be upload to
3262
- * [google_drive_site_folder] -> subfolder with site name in google_drive_directory which backup file should be upload to
3263
- * [backup_file] -> absolute path of backup file on local server
3264
- *
3265
- * @return bool|array true is successful, array with error message if not
3266
- */
3267
- public function google_drive_backup($args)
3268
- {
3269
- mwp_register_autoload_google();
3270
- $googleClient = new Google_ApiClient();
3271
- $googleClient->setAccessToken($args['google_drive_token']);
3272
-
3273
- $googleDrive = new Google_Service_Drive($googleClient);
3274
-
3275
- mwp_logger()->info('Fetching Google Drive root folder ID');
3276
- try {
3277
- $about = $googleDrive->about->get();
3278
- $rootFolderId = $about->getRootFolderId();
3279
- } catch (Exception $e) {
3280
- mwp_logger()->error('Error while fetching Google Drive root folder ID', array(
3281
- 'exception' => $e,
3282
- ));
3283
-
3284
- return array(
3285
- 'error' => 'Error while fetching Google Drive root folder ID: '.$e->getMessage(),
3286
- );
3287
- }
3288
-
3289
- mwp_logger()->info('Loading Google Drive backup directory');
3290
- try {
3291
- $rootFiles = $googleDrive->files->listFiles(array("q" => "title='".addslashes($args['google_drive_directory'])."' and '$rootFolderId' in parents and trashed = false"));
3292
- } catch (Exception $e) {
3293
- mwp_logger()->error('Error while loading Google Drive backup directory', array(
3294
- 'exception' => $e,
3295
- ));
3296
-
3297
- return array(
3298
- 'error' => 'Error while loading Google Drive backup directory: '.$e->getMessage(),
3299
- );
3300
- }
3301
-
3302
- if ($rootFiles->offsetExists(0)) {
3303
- $backupFolder = $rootFiles->offsetGet(0);
3304
- } else {
3305
- try {
3306
- mwp_logger()->info('Creating Google Drive backup directory');
3307
- $newBackupFolder = new Google_Service_Drive_DriveFile();
3308
- $newBackupFolder->setTitle($args['google_drive_directory']);
3309
- $newBackupFolder->setMimeType('application/vnd.google-apps.folder');
3310
-
3311
- if ($rootFolderId) {
3312
- $parent = new Google_Service_Drive_ParentReference();
3313
- $parent->setId($rootFolderId);
3314
- $newBackupFolder->setParents(array($parent));
3315
- }
3316
-
3317
- $backupFolder = $googleDrive->files->insert($newBackupFolder);
3318
- } catch (Exception $e) {
3319
- mwp_logger()->info('Error while creating Google Drive backup directory', array(
3320
- 'exception' => $e,
3321
- ));
3322
-
3323
- return array(
3324
- 'error' => 'Error while creating Google Drive backup directory: '.$e->getMessage(),
3325
- );
3326
- }
3327
- }
3328
-
3329
- if ($args['google_drive_site_folder']) {
3330
- try {
3331
- mwp_logger()->info('Fetching Google Drive site directory');
3332
- $siteFolderTitle = $this->site_name;
3333
- $backupFolderId = $backupFolder->getId();
3334
- $driveFiles = $googleDrive->files->listFiles(array("q" => "title='".addslashes($siteFolderTitle)."' and '$backupFolderId' in parents and trashed = false"));
3335
- } catch (Exception $e) {
3336
- mwp_logger()->info('Error while fetching Google Drive site directory', array(
3337
- 'exception' => $e,
3338
- ));
3339
-
3340
- return array(
3341
- 'error' => 'Error while fetching Google Drive site directory: '.$e->getMessage(),
3342
- );
3343
- }
3344
- if ($driveFiles->offsetExists(0)) {
3345
- $siteFolder = $driveFiles->offsetGet(0);
3346
- } else {
3347
- try {
3348
- mwp_logger()->info('Creating Google Drive site directory');
3349
- $_backup_folder = new Google_Service_Drive_DriveFile();
3350
- $_backup_folder->setTitle($siteFolderTitle);
3351
- $_backup_folder->setMimeType('application/vnd.google-apps.folder');
3352
-
3353
- if (isset($backupFolder)) {
3354
- $_backup_folder->setParents(array($backupFolder));
3355
- }
3356
-
3357
- $siteFolder = $googleDrive->files->insert($_backup_folder, array());
3358
- } catch (Exception $e) {
3359
- mwp_logger()->info('Error while creating Google Drive site directory', array(
3360
- 'exception' => $e,
3361
- ));
3362
-
3363
- return array(
3364
- 'error' => 'Error while creating Google Drive site directory: '.$e->getMessage(),
3365
- );
3366
- }
3367
- }
3368
- } else {
3369
- $siteFolder = $backupFolder;
3370
- }
3371
-
3372
- $file_path = explode('/', $args['backup_file']);
3373
- $backupFile = new Google_Service_Drive_DriveFile();
3374
- $backupFile->setTitle(end($file_path));
3375
- $backupFile->setDescription('Backup file of site: '.$this->site_name.'.');
3376
-
3377
- if ($siteFolder != null) {
3378
- $backupFile->setParents(array($siteFolder));
3379
- }
3380
- $googleClient->setDefer(true);
3381
- // Deferred client returns request object.
3382
- /** @var Google_Http_Request $request */
3383
- $request = $googleDrive->files->insert($backupFile);
3384
- $chunkSize = 1024 * 1024 * 4;
3385
-
3386
- $media = new Google_Http_MediaFileUpload($googleClient, $request, 'application/zip', null, true, $chunkSize);
3387
- $fileSize = filesize($args['backup_file']);
3388
- $media->setFileSize($fileSize);
3389
-
3390
- mwp_logger()->info('Uploading backup file to Google Drive; file size is {backup_size}', array(
3391
- 'backup_size' => mwp_format_bytes($fileSize),
3392
- ));
3393
-
3394
- // Upload the various chunks. $status will be false until the process is
3395
- // complete.
3396
- $status = false;
3397
- $handle = fopen($args['backup_file'], 'rb');
3398
- $started = microtime(true);
3399
- $lastNotification = $started;
3400
- $lastProgress = 0;
3401
- $threshold = 1;
3402
- $uploaded = 0;
3403
- $started = microtime(true);
3404
- while (!$status && !feof($handle)) {
3405
- $chunk = fread($handle, $chunkSize);
3406
- $newChunkSize = strlen($chunk);
3407
-
3408
- if (($elapsed = microtime(true) - $lastNotification) > $threshold) {
3409
- $lastNotification = microtime(true);
3410
- mwp_logger()->info('Upload progress: {progress}% (speed: {speed}/s)', array(
3411
- 'progress' => round($uploaded / $fileSize * 100, 2),
3412
- 'speed' => mwp_format_bytes(($uploaded - $lastProgress) / $elapsed),
3413
- ));
3414
- $lastProgress = $uploaded;
3415
- echo ".";
3416
- flush();
3417
- }
3418
- $uploaded += $newChunkSize;
3419
- $status = $media->nextChunk($chunk);
3420
- }
3421
- fclose($handle);
3422
-
3423
- if (!$status instanceof Google_Service_Drive_DriveFile) {
3424
- mwp_logger()->error('Upload to Google Drive failed', array(
3425
- 'status' => $status,
3426
- ));
3427
-
3428
- return array(
3429
- 'error' => 'Upload to Google Drive was not successful.',
3430
- );
3431
- }
3432
- $this->tasks[$args['task_name']]['task_results'][$args['task_result_key']]['google_drive']['file_id'] = $status->getId();
3433
-
3434
- mwp_logger()->info('Upload to Google Drive completed; average speed is {speed}/s', array(
3435
- 'speed' => mwp_format_bytes(round($fileSize / (microtime(true) - $started))),
3436
- ));
3437
-
3438
- return true;
3439
- }
3440
-
3441
- /**
3442
- * Deletes backup file from Google Drive.
3443
- *
3444
- * @param array $args arguments passed to the function
3445
- * [google_drive_token] -> user's Google drive token in json form
3446
- * [google_drive_directory] -> folder on user's Google Drive account which backup file should be deleted from
3447
- * [google_drive_site_folder] -> subfolder with site name in google_drive_directory which backup file should be deleted from
3448
- * [backup_file] -> absolute path of backup file on local server
3449
- *
3450
- * @return void
3451
- */
3452
- public function remove_google_drive_backup($args)
3453
- {
3454
- mwp_register_autoload_google();
3455
- mwp_logger()->info('Removing Google Drive backup file', array(
3456
- 'google_drive_directory' => $args['google_drive_directory'],
3457
- 'google_drive_site_folder' => $args['google_drive_site_folder'],
3458
- 'backup_file' => $args['backup_file'],
3459
- ));
3460
- try {
3461
- $googleClient = new Google_ApiClient();
3462
- $googleClient->setAccessToken($args['google_drive_token']);
3463
- } catch (Exception $e) {
3464
- mwp_logger()->error('Google Drive file removal failed', array(
3465
- 'exception' => $e,
3466
- ));
3467
-
3468
- return;
3469
- }
3470
-
3471
- $driveService = new Google_Service_Drive($googleClient);
3472
-
3473
- if (!empty($args['file_id'])) {
3474
- mwp_logger()->info('Deleting Google file by id');
3475
- try {
3476
- $driveService->files->delete($args['file_id']);
3477
- } catch (Exception $e) {
3478
- mwp_logger()->error('Error deleting google file by id', array('file_id' => $args['file_id']));
3479
- }
3480
-
3481
- return;
3482
- }
3483
- mwp_logger()->info('Fetching Google Drive root folder ID');
3484
- try {
3485
- $about = $driveService->about->get();
3486
- $root_folder_id = $about->getRootFolderId();
3487
- } catch (Exception $e) {
3488
- mwp_logger()->info('Error fetching Google Drive root folder ID', array(
3489
- 'exception' => $e,
3490
- ));
3491
-
3492
- return;
3493
- }
3494
-
3495
- mwp_logger()->info('Listing Google Drive files');
3496
- try {
3497
- $listFiles = $driveService->files->listFiles(array("q" => "title='".addslashes($args['google_drive_directory'])."' and '$root_folder_id' in parents and trashed = false"));
3498
- /** @var Google_Service_Drive_DriveFile[] $files */
3499
- $files = $listFiles->getItems();
3500
- } catch (Exception $e) {
3501
- mwp_logger()->error('Error while listing Google Drive files', array(
3502
- 'exception' => $e,
3503
- ));
3504
-
3505
- return;
3506
- }
3507
- if (isset($files[0])) {
3508
- $managewpFolder = $files[0];
3509
- } else {
3510
- return;
3511
- }
3512
-
3513
- if ($args['google_drive_site_folder']) {
3514
- try {
3515
- $subFolderTitle = $this->site_name;
3516
- $managewpFolderId = $managewpFolder->getId();
3517
- $listFiles = $driveService->files->listFiles(array("q" => "title='".addslashes($subFolderTitle)."' and '$managewpFolderId' in parents and trashed = false"));
3518
- $files = $listFiles->getItems();
3519
- } catch (Exception $e) {
3520
- /*return array(
3521
- 'error' => $e->getMessage(),
3522
- );*/
3523
- }
3524
- if (isset($files[0])) {
3525
- $backup_folder = $files[0];
3526
- }
3527
- } else {
3528
- /** @var Google_Service_Drive_DriveFile $backup_folder */
3529
- $backup_folder = $managewpFolder;
3530
- }
3531
-
3532
- if (isset($backup_folder)) {
3533
- try {
3534
- $backup_folder_id = $backup_folder->getId();
3535
- $listFiles = $driveService->files->listFiles(array("q" => "title='".addslashes($args['backup_file'])."' and '$backup_folder_id' in parents and trashed = false"));
3536
- $files = $listFiles->getItems();
3537
- } catch (Exception $e) {
3538
- /*return array(
3539
- 'error' => $e->getMessage(),
3540
- );*/
3541
- }
3542
- if (isset($files[0])) {
3543
- try {
3544
- $driveService->files->delete($files[0]->getId());
3545
- } catch (Exception $e) {
3546
- }
3547
- } else {
3548
- }
3549
- } else {
3550
- }
3551
- }
3552
-
3553
- /**
3554
- * Downloads backup file from Google Drive to root folder on local server.
3555
- *
3556
- * @param array $args arguments passed to the function
3557
- * [google_drive_token] -> user's Google drive token in json form
3558
- * [google_drive_directory] -> folder on user's Google Drive account which backup file should be downloaded from
3559
- * [google_drive_site_folder] -> subfolder with site name in google_drive_directory which backup file should be downloaded from
3560
- * [backup_file] -> absolute path of backup file on local server
3561
- * [file_id] -> google file id
3562
- *
3563
- * @return bool|array absolute path to downloaded file is successful, array with error message if not
3564
- */
3565
- public function get_google_drive_backup($args)
3566
- {
3567
- mwp_register_autoload_google();
3568
- $googleClient = new Google_ApiClient();
3569
- $googleClient->setAccessToken($args['google_drive_token']);
3570
- $driveService = new Google_Service_Drive($googleClient);
3571
-
3572
- mwp_logger()->info('Connecting to Google Drive');
3573
- try {
3574
- $about = $driveService->about->get();
3575
- $rootFolderId = $about->getRootFolderId();
3576
- } catch (Exception $e) {
3577
- mwp_logger()->error('Error while connecting to Google Drive', array(
3578
- 'exception' => $e,
3579
- ));
3580
-
3581
- return array(
3582
- 'error' => 'Error while connecting to Google Drive: '.$e->getMessage(),
3583
- );
3584
- }
3585
- if (empty($args['file_id'])) {
3586
- mwp_logger()->info('Looking for backup directory');
3587
- try {
3588
- $backupFolderFiles = $driveService->files->listFiles(array(
3589
- 'q' => sprintf("title='%s' and '%s' in parents and trashed = false", addslashes($args['google_drive_directory']), $rootFolderId),
3590
- ));
3591
- } catch (Exception $e) {
3592
- mwp_logger()->error('Error while looking for backup directory', array(
3593
- 'exception' => $e,
3594
- ));
3595
-
3596
- return array(
3597
- 'error' => 'Error while looking for backup directory: '.$e->getMessage(),
3598
- );
3599
- }
3600
-
3601
- if (!$backupFolderFiles->offsetExists(0)) {
3602
- mwp_logger()->error('Backup directory ("{directory}") does not exist', array(
3603
- 'directory' => $args['google_drive_directory'],
3604
- ));
3605
-
3606
- return array(
3607
- 'error' => sprintf("The backup directory (%s) does not exist.", $args['google_drive_directory']),
3608
- );
3609
- }
3610
-
3611
- /** @var Google_Service_Drive_DriveFile $backupFolder */
3612
- $backupFolder = $backupFolderFiles->offsetGet(0);
3613
-
3614
- if ($args['google_drive_site_folder']) {
3615
- mwp_logger()->info('Looking into the site folder');
3616
- try {
3617
- $siteFolderFiles = $driveService->files->listFiles(array(
3618
- 'q' => sprintf("title='%s' and '%s' in parents and trashed = false", addslashes($this->site_name), $backupFolder->getId()),
3619
- ));
3620
- } catch (Exception $e) {
3621
- mwp_logger()->error('Error while looking for the site folder', array(
3622
- 'exception' => $e,
3623
- ));
3624
-
3625
- return array(
3626
- 'error' => 'Error while looking for the site folder: '.$e->getMessage(),
3627
- );
3628
- }
3629
-
3630
- if ($siteFolderFiles->offsetExists(0)) {
3631
- $backupFolder = $siteFolderFiles->offsetGet(0);
3632
- }
3633
- }
3634
-
3635
- try {
3636
- $backupFiles = $driveService->files->listFiles(array(
3637
- 'q' => sprintf("title='%s' and '%s' in parents and trashed = false", addslashes($args['backup_file']), $backupFolder->getId()),
3638
- ));
3639
- } catch (Exception $e) {
3640
- mwp_logger()->error('Error while fetching Google Drive backup file', array(
3641
- 'file_name' => $args['backup_file'],
3642
- 'exception' => $e,
3643
- ));
3644
-
3645
- return array(
3646
- 'error' => 'Error while fetching Google Drive backup file: '.$e->getMessage(),
3647
- );
3648
- }
3649
-
3650
- if (!$backupFiles->offsetExists(0)) {
3651
- return array(
3652
- 'error' => sprintf('Backup file "%s" was not found on your Google Drive account.', $args['backup_file']),
3653
- );
3654
- }
3655
- /** @var Google_Service_Drive_DriveFile $backupFile */
3656
- $backupFile = $backupFiles->offsetGet(0);
3657
- } else {
3658
- try {
3659
- /** @var Google_Service_Drive_DriveFile $backupFile */
3660
- $backupFile = $driveService->files->get($args['file_id']);
3661
- } catch (Exception $e) {
3662
- mwp_logger()->error('Error while fetching Google Drive backup file by id', array(
3663
- 'file_id' => $args['file_id'],
3664
- 'exception' => $e,
3665
- ));
3666
-
3667
- return array(
3668
- 'error' => 'Error while fetching Google Drive backup file: '.$e->getMessage(),
3669
- );
3670
- }
3671
- }
3672
-
3673
- $downloadUrl = $backupFile->getDownloadUrl();
3674
- $downloadLocation = ABSPATH.'mwp_temp_backup.zip';
3675
- $fileSize = $backupFile->getFileSize();
3676
- $downloaded = 0;
3677
- $chunkSize = 1024 * 1024 * 4;
3678
- $fh = fopen($downloadLocation, 'w+');
3679
-
3680
- if (!is_resource($fh)) {
3681
- return array(
3682
- 'error' => 'Temporary backup download location is not writable (location: "%s").',
3683
- $downloadLocation,
3684
- );
3685
- }
3686
- while ($downloaded < $fileSize) {
3687
- $request = new Google_Http_Request($downloadUrl);
3688
- $googleClient->getAuth()->sign($request);
3689
- $toDownload = min($chunkSize, $fileSize - $downloaded);
3690
- mwp_logger()->info('Downloading: {downloaded}/{size}', array(
3691
- 'downloaded' => mwp_format_bytes($downloaded),
3692
- 'size' => mwp_format_bytes($fileSize),
3693
- ));
3694
- $request->setRequestHeaders($request->getRequestHeaders() + array('Range' => 'bytes='.$downloaded.'-'.($downloaded + $toDownload - 1)));
3695
- $googleClient->getIo()->makeRequest($request);
3696
- if ($request->getResponseHttpCode() !== 206) {
3697
- mwp_logger()->error('Google Drive has returned an invalid response', array(
3698
- 'response_headers' => $request->getResponseHeaders(),
3699
- 'response_body' => $request->getResponseBody(),
3700
- ));
3701
-
3702
- return array(
3703
- 'error' => sprintf('Google Drive service has returned an invalid response code (%s)', $request->getResponseHttpCode()),
3704
- );
3705
- }
3706
- fwrite($fh, $request->getResponseBody());
3707
- $downloaded += $toDownload;
3708
- }
3709
- fclose($fh);
3710
-
3711
- $fileMd5 = md5_file($downloadLocation);
3712
- if ($backupFile->getMd5Checksum() !== $fileMd5) {
3713
- mwp_logger()->error('File checksum does not match, downloaded file is corrupted.', array(
3714
- 'original' => $backupFile->getMd5Checksum(),
3715
- 'downloaded' => $fileMd5,
3716
- ));
3717
-
3718
- return array(
3719
- 'error' => 'File downloaded was corrupted.',
3720
- );
3721
- }
3722
-
3723
- return $downloadLocation;
3724
- }
3725
-
3726
- /**
3727
- * Parse task arguments for info on master.
3728
- *
3729
- * @return mixed associative array with stats for every backup task or error if backup is manually deleted on server
3730
- */
3731
- public function get_backup_stats()
3732
- {
3733
- $stats = array();
3734
- $tasks = $this->tasks;
3735
- if (is_array($tasks) && !empty($tasks)) {
3736
- foreach ($tasks as $task_name => $info) {
3737
- if (!empty($info['task_results']) && is_array($info['task_results'])) {
3738
- foreach ($info['task_results'] as $key => $result) {
3739
- if (isset($result['server']) && !isset($result['error'])) {
3740
- if (isset($result['server']['file_path']) && !$info['task_args']['del_host_file']) {
3741
- if (!file_exists($result['server']['file_path'])) {
3742
- $info['task_results'][$key]['error'] = 'Backup created but manually removed from server.';
3743
- }
3744
- }
3745
- }
3746
- }
3747
- $stats[$task_name] = $info['task_results'];
3748
- }
3749
- }
3750
- }
3751
-
3752
- return $stats;
3753
- }
3754
-
3755
- /**
3756
- * Deletes all old backups from local server.
3757
- * It depends on configuration on master (Number of backups to keep).
3758
- *
3759
- * @param string $task_name name of backup task
3760
- *
3761
- * @return bool|void true if there are backups for deletion, void if not
3762
- */
3763
- public function remove_old_backups($task_name)
3764
- {
3765
- //Check for previous failed backups first
3766
- $this->cleanup();
3767
-
3768
- //Remove by limit
3769
- $backups = $this->tasks;
3770
- if ($task_name == 'Backup Now') {
3771
- $num = 0;
3772
- } else {
3773
- $num = 1;
3774
- }
3775
-
3776
- if ((count($backups[$task_name]['task_results']) - $num) >= $backups[$task_name]['task_args']['limit']) {
3777
- //how many to remove ?
3778
- $remove_num = (count($backups[$task_name]['task_results']) - $num - $backups[$task_name]['task_args']['limit']) + 1;
3779
- for ($i = 0; $i < $remove_num; $i++) {
3780
- //Remove from the server
3781
- if (isset($backups[$task_name]['task_results'][$i]['server'])) {
3782
- @unlink($backups[$task_name]['task_results'][$i]['server']['file_path']);
3783
- }
3784
-
3785
- //Remove from ftp
3786
- if (isset($backups[$task_name]['task_results'][$i]['ftp']) && isset($backups[$task_name]['task_args']['account_info']['mwp_ftp'])) {
3787
- $ftp_file = $backups[$task_name]['task_results'][$i]['ftp'];
3788
- $args = $backups[$task_name]['task_args']['account_info']['mwp_ftp'];
3789
- $args['backup_file'] = $ftp_file;
3790
- $this->remove_ftp_backup($args);
3791
- }
3792
- if (isset($backups[$task_name]['task_results'][$i]['sftp']) && isset($backups[$task_name]['task_args']['account_info']['mwp_sftp'])) {
3793
- $sftp_file = $backups[$task_name]['task_results'][$i]['sftp'];
3794
- $args = $backups[$task_name]['task_args']['account_info']['mwp_sftp'];
3795
- $args['backup_file'] = $sftp_file;
3796
- $this->remove_sftp_backup($args);
3797
- }
3798
-
3799
- if (isset($backups[$task_name]['task_results'][$i]['amazons3']) && isset($backups[$task_name]['task_args']['account_info']['mwp_amazon_s3'])) {
3800
- $amazons3_file = $backups[$task_name]['task_results'][$i]['amazons3'];
3801
- $args = $backups[$task_name]['task_args']['account_info']['mwp_amazon_s3'];
3802
- $args['backup_file'] = $amazons3_file;
3803
- $this->remove_amazons3_backup($args);
3804
- }
3805
-
3806
- if (isset($backups[$task_name]['task_results'][$i]['dropbox']) && isset($backups[$task_name]['task_args']['account_info']['mwp_dropbox'])) {
3807
- //To do: dropbox remove
3808
- $dropbox_file = $backups[$task_name]['task_results'][$i]['dropbox'];
3809
- $args = $backups[$task_name]['task_args']['account_info']['mwp_dropbox'];
3810
- $args['backup_file'] = $dropbox_file;
3811
- $this->remove_dropbox_backup($args);
3812
- }
3813
-
3814
- if (isset($backups[$task_name]['task_results'][$i]['google_drive']) && isset($backups[$task_name]['task_args']['account_info']['mwp_google_drive'])) {
3815
- if (is_array($backups[$task_name]['task_results'][$i]['google_drive'])) {
3816
- $google_drive_file = $backups[$task_name]['task_results'][$i]['google_drive']['file'];
3817
- $google_file_id = $backups[$task_name]['task_results'][$i]['google_drive']['file_id'];
3818
- } else {
3819
- $google_drive_file = $backups[$task_name]['task_results'][$i]['google_drive'];
3820
- $google_file_id = "";
3821
- }
3822
- $args = $backups[$task_name]['task_args']['account_info']['mwp_google_drive'];
3823
- $args['backup_file'] = $google_drive_file;
3824
- $args['file_id'] = $google_file_id;
3825
- $this->remove_google_drive_backup($args);
3826
- }
3827
-
3828
- //Remove database backup info
3829
- unset($backups[$task_name]['task_results'][$i]);
3830
- } //end foreach
3831
-
3832
- if (is_array($backups[$task_name]['task_results'])) {
3833
- $backups[$task_name]['task_results'] = array_values($backups[$task_name]['task_results']);
3834
- } else {
3835
- $backups[$task_name]['task_results'] = array();
3836
- }
3837
-
3838
- $this->update_tasks($backups);
3839
-
3840
- return true;
3841
- }
3842
- }
3843
-
3844
- /**
3845
- * Deletes specified backup.
3846
- *
3847
- * @param array $args arguments passed to function
3848
- * [task_name] -> name of backup task
3849
- * [result_id] -> id of baskup task result, which should be restored (deprecated, use result Uuid now)
3850
- * [google_drive_token] -> json of Google Drive token, if it is remote destination
3851
- * [resultUuid] -> unique backup identifier
3852
- *
3853
- * @return bool true if successful, false if not
3854
- */
3855
- public function delete_backup($args)
3856
- {
3857
- if (empty($args)) {
3858
- return false;
3859
- }
3860
- extract($args);
3861
- $task_name = stripslashes($task_name);
3862
- if (isset($google_drive_token)) {
3863
- $this->tasks[$task_name]['task_args']['account_info']['mwp_google_drive']['google_drive_token'] = $google_drive_token;
3864
- }
3865
-
3866
- $tasks = $this->tasks;
3867
-
3868
- $task = $tasks[$task_name];
3869
- $backups = $task['task_results'];
3870
- $result_id = !empty($args['result_id']) ? $args['result_id'] : null;
3871
- $backup = !empty($backups[$result_id]) ? $backups[$result_id] : false;
3872
- foreach ($backups as $key => $result) {
3873
- if ($result['resultUuid'] == $args['resultUuid']) {
3874
- $backup = $result;
3875
- $result_id = $key;
3876
- break;
3877
- }
3878
- }
3879
-
3880
- if (!$backup) {
3881
- return false;
3882
- }
3883
-
3884
- if (isset($backup['server'])) {
3885
- @unlink($backup['server']['file_path']);
3886
- }
3887
-
3888
- //Remove from ftp
3889
- if (isset($backup['ftp'])) {
3890
- $ftp_file = $backup['ftp'];
3891
- $args = $tasks[$task_name]['task_args']['account_info']['mwp_ftp'];
3892
- $args['backup_file'] = $ftp_file;
3893
- $this->remove_ftp_backup($args);
3894
- }
3895
- if (isset($backup['sftp'])) {
3896
- $sftp_file = $backup['sftp'];
3897
- $args = $tasks[$task_name]['task_args']['account_info']['mwp_sftp'];
3898
- $args['backup_file'] = $sftp_file;
3899
- $this->remove_sftp_backup($args);
3900
- }
3901
-
3902
- if (isset($backup['amazons3'])) {
3903
- $amazons3_file = $backup['amazons3'];
3904
- $args = $tasks[$task_name]['task_args']['account_info']['mwp_amazon_s3'];
3905
- $args['backup_file'] = $amazons3_file;
3906
- $this->remove_amazons3_backup($args);
3907
- }
3908
-
3909
- if (isset($backup['dropbox'])) {
3910
- $dropbox_file = $backup['dropbox'];
3911
- $args = $tasks[$task_name]['task_args']['account_info']['mwp_dropbox'];
3912
- $args['backup_file'] = $dropbox_file;
3913
- $this->remove_dropbox_backup($args);
3914
- }
3915
-
3916
- if (isset($backup['google_drive'])) {
3917
- if (is_array($backup['google_drive'])) {
3918
- $google_drive_file = $backup['google_drive']['file'];
3919
- $google_file_id = $backup['google_drive']['file_id'];
3920
- } else {
3921
- $google_drive_file = $backup['google_drive'];
3922
- $google_file_id = "";
3923
- }
3924
- $args = $tasks[$task_name]['task_args']['account_info']['mwp_google_drive'];
3925
- $args['backup_file'] = $google_drive_file;
3926
- $args['file_id'] = $google_file_id;
3927
- $this->remove_google_drive_backup($args);
3928
- }
3929
-
3930
- unset($backups[$result_id]);
3931
-
3932
- if (count($backups)) {
3933
- $tasks[$task_name]['task_results'] = $backups;
3934
- } else {
3935
- unset($tasks[$task_name]['task_results']);
3936
- }
3937
-
3938
- $this->update_tasks($tasks);
3939
-
3940
- return true;
3941
- }
3942
-
3943
- /**
3944
- * Deletes all unneeded files produced by backup process.
3945
- *
3946
- * @return array array of deleted files
3947
- */
3948
- public function cleanup()
3949
- {
3950
- $tasks = $this->tasks;
3951
- $backup_folder = WP_CONTENT_DIR.'/'.md5('mmb-worker').'/mwp_backups/';
3952
- $backup_folder_new = MWP_BACKUP_DIR.'/';
3953
- $files = glob($backup_folder."*");
3954
- $new = glob($backup_folder_new."*");
3955
-
3956
- //Failed db files first
3957
- $db_folder = MWP_DB_DIR.'/';
3958
- $db_files = glob($db_folder."*");
3959
- if (is_array($db_files) && !empty($db_files)) {
3960
- foreach ($db_files as $file) {
3961
- @unlink($file);
3962
- }
3963
- @unlink(MWP_BACKUP_DIR.'/mwp_db/index.php');
3964
- @unlink(MWP_BACKUP_DIR.'/mwp_db/info.json');
3965
- @rmdir(MWP_DB_DIR);
3966
- }
3967
-
3968
- //clean_old folder?
3969
- if ((isset($files[0]) && basename($files[0]) == 'index.php' && count($files) == 1) || (empty($files))) {
3970
- if (!empty($files)) {
3971
- foreach ($files as $file) {
3972
- @unlink($file);
3973
- }
3974
- }
3975
- @rmdir(WP_CONTENT_DIR.'/'.md5('mmb-worker').'/mwp_backups');
3976
- @rmdir(WP_CONTENT_DIR.'/'.md5('mmb-worker'));
3977
- }
3978
-
3979
- if (!empty($new)) {
3980
- foreach ($new as $b) {
3981
- $files[] = $b;
3982
- }
3983
- }
3984
- $deleted = array();
3985
-
3986
- if (is_array($files) && count($files)) {
3987
- $results = array();
3988
- if (!empty($tasks)) {
3989
- foreach ((array) $tasks as $task) {
3990
- if (isset($task['task_results']) && count($task['task_results'])) {
3991
- foreach ($task['task_results'] as $backup) {
3992
- if (isset($backup['server'])) {
3993
- $results[] = $backup['server']['file_path'];
3994
- }
3995
- }
3996
- }
3997
- }
3998
- }
3999
-
4000
- $num_deleted = 0;
4001
- foreach ($files as $file) {
4002
- if (!in_array($file, $results) && basename($file) != 'index.php') {
4003
- @unlink($file);
4004
- $deleted[] = basename($file);
4005
- $num_deleted++;
4006
- }
4007
- }
4008
- }
4009
-
4010
- return $deleted;
4011
- }
4012
-
4013
- /**
4014
- * Uploads to remote destination in the second step, invoked from master.
4015
- *
4016
- * @param array $args arguments passed to function
4017
- * [task_name] -> name of backup task
4018
- *
4019
- * @return array|void void if success, array with error message if not
4020
- */
4021
- public function remote_backup_now($args)
4022
- {
4023
- /**
4024
- * Remember if this is called as a forked http request, or a connection to the dasboard is persistent
4025
- */
4026
- global $forkedRequest;
4027
- $forkedRequest = isset($args['forked']) ? $args['forked'] : false;
4028
-
4029
- $this->set_memory();
4030
- if (!empty($args)) {
4031
- extract($args);
4032
- }
4033
-
4034
- $tasks = $this->tasks;
4035
- $task_name = stripslashes($task_name);
4036
- $task = $tasks[$task_name];
4037
-
4038
- if (!empty($task)) {
4039
- extract($task['task_args']);
4040
- }
4041
-
4042
- $results = $task['task_results'];
4043
- $taskResultKey = null;
4044
- $backup_file = false;
4045
-
4046
- if (is_array($results) && count($results)) {
4047
- foreach ($results as $key => $result) {
4048
- if (array_key_exists('resultUuid', $result) && $result['resultUuid'] == $args['resultUuid']) {
4049
- $backup_file = $result['server']['file_path'];
4050
- $taskResultKey = $key;
4051
- break;
4052
- }
4053
- }
4054
- if (!$backup_file) {
4055
- $backup_file = $results[count($results) - 1]['server']['file_path'];
4056
- $taskResultKey = count($results) - 1;
4057
- }
4058
- }
4059
-
4060
- if ($backup_file && file_exists($backup_file)) {
4061
- //FTP, Amazon S3, Dropbox or Google Drive
4062
- if (isset($account_info['mwp_ftp']) && !empty($account_info['mwp_ftp'])) {
4063
- $this->update_status($task_name, $this->statuses['ftp']);
4064
- $account_info['mwp_ftp']['backup_file'] = $backup_file;
4065
- $return = $this->ftp_backup($account_info['mwp_ftp']);
4066
- $this->wpdb_reconnect();
4067
-
4068
- if (!(is_array($return) && isset($return['error']))) {
4069
- $this->update_status($task_name, $this->statuses['ftp'], true);
4070
- $this->update_status($task_name, $this->statuses['finished'], true);
4071
- }
4072
- }
4073
-
4074
- if (isset($account_info['mwp_sftp']) && !empty($account_info['mwp_sftp'])) {
4075
- $this->update_status($task_name, $this->statuses['sftp']);
4076
- $account_info['mwp_sftp']['backup_file'] = $backup_file;
4077
- $return = $this->sftp_backup($account_info['mwp_sftp']);
4078
- $this->wpdb_reconnect();
4079
-
4080
- if (!(is_array($return) && isset($return['error']))) {
4081
- $this->update_status($task_name, $this->statuses['sftp'], true);
4082
- $this->update_status($task_name, $this->statuses['finished'], true);
4083
- }
4084
- }
4085
-
4086
- if (isset($account_info['mwp_amazon_s3']) && !empty($account_info['mwp_amazon_s3'])) {
4087
- $this->update_status($task_name, $this->statuses['s3']);
4088
- $account_info['mwp_amazon_s3']['backup_file'] = $backup_file;
4089
- $return = $this->amazons3_backup($account_info['mwp_amazon_s3']);
4090
- $this->wpdb_reconnect();
4091
-
4092
- if (!(is_array($return) && isset($return['error']))) {
4093
- $this->update_status($task_name, $this->statuses['s3'], true);
4094
- $this->update_status($task_name, $this->statuses['finished'], true);
4095
- }
4096
- }
4097
-
4098
- if (isset($account_info['mwp_dropbox']) && !empty($account_info['mwp_dropbox'])) {
4099
- $this->update_status($task_name, $this->statuses['dropbox']);
4100
- $account_info['mwp_dropbox']['backup_file'] = $backup_file;
4101
- $return = $this->dropbox_backup($account_info['mwp_dropbox']);
4102
- $this->wpdb_reconnect();
4103
-
4104
- if (!(is_array($return) && isset($return['error']))) {
4105
- $this->update_status($task_name, $this->statuses['dropbox'], true);
4106
- $this->update_status($task_name, $this->statuses['finished'], true);
4107
- }
4108
- }
4109
-
4110
- if (isset($account_info['mwp_email']) && !empty($account_info['mwp_email'])) {
4111
- $this->update_status($task_name, $this->statuses['email']);
4112
- $account_info['mwp_email']['task_name'] = $task_name;
4113
- $account_info['mwp_email']['file_path'] = $backup_file;
4114
- $return = $this->email_backup($account_info['mwp_email']);
4115
- $this->wpdb_reconnect();
4116
-
4117
- if (!(is_array($return) && isset($return['error']))) {
4118
- $this->update_status($task_name, $this->statuses['email'], true);
4119
- $this->update_status($task_name, $this->statuses['finished'], true);
4120
- }
4121
- }
4122
-
4123
- if (isset($account_info['mwp_google_drive']) && !empty($account_info['mwp_google_drive'])) {
4124
- $this->update_status($task_name, $this->statuses['google_drive']);
4125
- $account_info['mwp_google_drive']['backup_file'] = $backup_file;
4126
- $account_info['mwp_google_drive']['task_name'] = $task_name;
4127
- $account_info['mwp_google_drive']['task_result_key'] = $taskResultKey;
4128
-
4129
- $return = $this->google_drive_backup($account_info['mwp_google_drive']);
4130
- $this->wpdb_reconnect();
4131
-
4132
- if (!isset($return['error'])) {
4133
- $this->update_status($task_name, $this->statuses['google_drive'], true);
4134
- $this->update_status($task_name, $this->statuses['finished'], true);
4135
- }
4136
- }
4137
-
4138
- $tasks = $this->tasks;
4139
- @file_put_contents(MWP_BACKUP_DIR.'/mwp_db/index.php', '');
4140
- if ($return === true && $del_host_file) {
4141
- @unlink($backup_file);
4142
- unset($tasks[$task_name]['task_results'][count($tasks[$task_name]['task_results']) - 1]['server']);
4143
- }
4144
- $this->update_tasks($tasks);
4145
- if (!isset($return['error'])) {
4146
- $return = $this->tasks[$task_name]['task_results'][$taskResultKey];
4147
- }
4148
- } else {
4149
- $return = array(
4150
- 'error' => 'Backup file not found on your server. Please try again.',
4151
- );
4152
- }
4153
- $this->sendDataToMaster();
4154
-
4155
- return $return;
4156
- }
4157
-
4158
- /**
4159
- * Updates status of backup task.
4160
- * Positive number if completed, negative if not.
4161
- *
4162
- * @param string $task_name name of backup task
4163
- * @param int $status status which tasks should be updated to
4164
- * (
4165
- * 0 - Backup started,
4166
- * 1 - DB dump,
4167
- * 2 - DB ZIP,
4168
- * 3 - Files ZIP,
4169
- * 4 - Amazon S3,
4170
- * 5 - Dropbox,
4171
- * 6 - FTP,
4172
- * 7 - Email,
4173
- * 8 - Google Drive,
4174
- * 100 - Finished
4175
- * )
4176
- * @param bool $completed completed or not
4177
- *
4178
- * @return void
4179
- */
4180
- public function update_status($task_name, $status, $completed = false)
4181
- {
4182
- if ($task_name != 'Backup Now') {
4183
- $tasks = $this->tasks;
4184
- $index = count($tasks[$task_name]['task_results']) - 1;
4185
- if (!is_array($tasks[$task_name]['task_results'][$index]['status'])) {
4186
- $tasks[$task_name]['task_results'][$index]['status'] = array();
4187
- }
4188
- if (!$completed) {
4189
- $tasks[$task_name]['task_results'][$index]['status'][] = (int) $status * (-1);
4190
- } else {
4191
- $status_index = count($tasks[$task_name]['task_results'][$index]['status']) - 1;
4192
- $tasks[$task_name]['task_results'][$index]['status'][$status_index] = abs($tasks[$task_name]['task_results'][$index]['status'][$status_index]);
4193
- }
4194
-
4195
- $this->update_tasks($tasks);
4196
- }
4197
- }
4198
-
4199
- /**
4200
- * Update $this->tasks attribute and save it to wp_options with key mwp_backup_tasks.
4201
- *
4202
- * @param mixed $tasks associative array with all tasks data
4203
- *
4204
- * @return void
4205
- */
4206
- public function update_tasks($tasks)
4207
- {
4208
- $this->tasks = $tasks;
4209
- update_option('mwp_backup_tasks', $tasks);
4210
- }
4211
-
4212
- /**
4213
- * Reconnects to database to avoid timeout problem after ZIP files.
4214
- *
4215
- * @return void
4216
- */
4217
- public function wpdb_reconnect()
4218
- {
4219
- /** @var wpdb $wpdb */
4220
- global $wpdb;
4221
-
4222
- if (is_callable(array($wpdb, 'check_connection'))) {
4223
- $wpdb->check_connection();
4224
-
4225
- return;
4226
- }
4227
-
4228
- if (class_exists('wpdb') && function_exists('wp_set_wpdb_vars')) {
4229
- @mysql_close($wpdb->dbh);
4230
- $wpdb = new wpdb(DB_USER, DB_PASSWORD, DB_NAME, DB_HOST);
4231
- wp_set_wpdb_vars();
4232
- if (function_exists('is_multisite')) {
4233
- if (is_multisite()) {
4234
- $wpdb->set_blog_id(get_current_blog_id());
4235
- }
4236
- }
4237
- }
4238
- }
4239
-
4240
- /**
4241
- * Replaces .htaccess file in process of restoring WordPress site.
4242
- *
4243
- * @param string $url url of current site
4244
- *
4245
- * @return void
4246
- */
4247
- public function replace_htaccess($url)
4248
- {
4249
- $file = @file_get_contents(ABSPATH.'.htaccess');
4250
- if ($file && strlen($file)) {
4251
- $args = parse_url($url);
4252
- $string = rtrim($args['path'], "/");
4253
- $regex = "/BEGIN WordPress(.*?)RewriteBase(.*?)\n(.*?)RewriteRule \.(.*?)index\.php(.*?)END WordPress/sm";
4254
- $replace = "BEGIN WordPress$1RewriteBase ".$string."/ \n$3RewriteRule . ".$string."/index.php$5END WordPress";
4255
- $file = preg_replace($regex, $replace, $file);
4256
- @file_put_contents(ABSPATH.'.htaccess', $file);
4257
- }
4258
- }
4259
-
4260
- /**
4261
- * Start backup process. Invoked from remote ping
4262
- *
4263
- * @param array $args arguments passed to function
4264
- * [task_name] -> name of backup task
4265
- *
4266
- * @return array array with error message or if success task results
4267
- */
4268
- public function ping_backup($args)
4269
- {
4270
- // Belows code follows logic from check_backup
4271
- $return = "PONG";
4272
- $task_name = $args['task_name'];
4273
- $sendDataToMaster = false;
4274
- if (is_array($this->tasks) && !empty($this->tasks) && !empty($this->tasks[$task_name])) {
4275
- $task = $this->tasks[$task_name];
4276
- $sendDataToMaster = isset($task['task_args']['account_info']) ? false : true;
4277
- if ($task['task_args']['task_id'] && $task['task_args']['site_key']) {
4278
- $potential_token = !empty($args['google_drive_token']) ? $args['google_drive_token'] : false;
4279
- if ($potential_token) {
4280
- $this->tasks[$task_name]['task_args']['account_info']['mwp_google_drive']['google_drive_token'] = $potential_token;
4281
- $task['task_args']['account_info']['mwp_google_drive']['google_drive_token'] = $potential_token;
4282
- }
4283
- $resultUuid = !empty($args['resultUuid']) ? $args['resultUuid'] : false;
4284
- /**
4285
- * From this point I am simulating previous way of working. In order to fix this,
4286
- * I need to refactor greater part, and release is tomorrow morning
4287
- */
4288
- $update = array(
4289
- 'task_name' => $task_name,
4290
- 'args' => $task['task_args'],
4291
- );
4292
- $update['time'] = time();
4293
- $this->set_backup_task($update);
4294
- $this->tasks = get_option('mwp_backup_tasks');
4295
- $task = $this->tasks[$task_name];
4296
-
4297
- $result = $this->backup($task['task_args'], $task_name, $resultUuid);
4298
-
4299
- if (is_array($result) && array_key_exists('error', $result)) {
4300
- $return = $result;
4301
- $this->set_backup_task(
4302
- array(
4303
- 'task_name' => $task_name,
4304
- 'args' => $task['task_args'],
4305
- 'error' => $return,
4306
- )
4307
- );
4308
- } else {
4309
- if (!empty($task['task_args']['account_info'])) {
4310
- $this->mwp_remote_upload($task_name);
4311
- }
4312
- $return = $this->tasks[$task_name]['task_results'];
4313
- }
4314
- }
4315
- } else {
4316
- $return = array("error" => "Unknown task name");
4317
- }
4318
- if ($sendDataToMaster) {
4319
- $this->sendDataToMaster();
4320
- }
4321
-
4322
- return $return;
4323
- }
4324
-
4325
- public function sendDataToMaster()
4326
- {
4327
- $this->notifyMyself('mwp_datasend');
4328
- }
4329
-
4330
- public function mwp_remote_upload($task_name)
4331
- {
4332
- $backup_file = $this->tasks[$task_name]['task_results'][count($this->tasks[$task_name]['task_results']) - 1]['server']['file_url'];
4333
- $del_host_file = $this->tasks[$task_name]['task_args']['del_host_file'];
4334
- $args = array('task_name' => $task_name, 'backup_file' => $backup_file, 'del_host_file' => $del_host_file);
4335
-
4336
- $this->notifyMyself('mmb_remote_upload', $args);
4337
- }
4338
-
4339
- /**
4340
- * @return array|null
4341
- */
4342
- private function getEnv()
4343
- {
4344
- $lang = getenv('LANG');
4345
-
4346
- if (preg_match('{^.*\.UTF-?8$}i', $lang)) {
4347
- // Allow the environment to be inherited.
4348
- return null;
4349
- }
4350
-
4351
- if (!$lang) {
4352
- $lang = 'en_US';
4353
- }
4354
-
4355
- $langParts = explode('.', $lang);
4356
-
4357
- if (!isset($langParts[1]) || $langParts[1] !== 'UTF-8') {
4358
- $lang = $langParts[0].'.UTF-8';
4359
- }
4360
-
4361
- return array('LANG' => $lang);
4362
- }
4363
- }
4364
-
4365
- if (!function_exists('get_all_files_from_dir')) {
4366
- /**
4367
- * Get all files in directory
4368
- *
4369
- * @param string $path Relative or absolute path to folder
4370
- * @param array $exclude List of excluded files or folders, relative to $path
4371
- *
4372
- * @return array List of all files in folder $path, exclude all files in $exclude array
4373
- */
4374
- function get_all_files_from_dir($path, $exclude = array())
4375
- {
4376
- if ($path[strlen($path) - 1] === "/") {
4377
- $path = substr($path, 0, -1);
4378
- }
4379
- global $directory_tree, $ignore_array;
4380
- $directory_tree = array();
4381
- foreach ($exclude as $file) {
4382
- if (!in_array($file, array('.', '..'))) {
4383
- if ($file[0] === "/") {
4384
- $path = substr($file, 1);
4385
- }
4386
- $ignore_array[] = "$path/$file";
4387
- }
4388
- }
4389
- get_all_files_from_dir_recursive($path);
4390
-
4391
- return $directory_tree;
4392
- }
4393
- }
4394
-
4395
- if (!function_exists('get_all_files_from_dir_recursive')) {
4396
- /**
4397
- * Get all files in directory,
4398
- * wrapped function which writes in global variable
4399
- * and exclued files or folders are read from global variable
4400
- *
4401
- * @param string $path Relative or absolute path to folder
4402
- *
4403
- * @return void
4404
- */
4405
- function get_all_files_from_dir_recursive($path)
4406
- {
4407
- if ($path[strlen($path) - 1] === "/") {
4408
- $path = substr($path, 0, -1);
4409
- }
4410
- global $directory_tree, $ignore_array;
4411
- $directory_tree_temp = array();
4412
- $dh = @opendir($path);
4413
-
4414
- while (false !== ($file = @readdir($dh))) {
4415
- if (!in_array($file, array('.', '..'))) {
4416
- if (empty($ignore_array) || !in_array("$path/$file", $ignore_array)) {
4417
- if (!is_dir("$path/$file")) {
4418
- $directory_tree[] = "$path/$file";
4419
- } else {
4420
- get_all_files_from_dir_recursive("$path/$file");
4421
- }
4422
- }
4423
- }
4424
- }
4425
- @closedir($dh);
4426
- }
4427
- }
4428
-
4429
- /**
4430
- * Retrieves a value from an array by key, or a specified default if given key doesn't exist
4431
- *
4432
- * @param array $array
4433
- * @param $key
4434
- * @param null $default
4435
- *
4436
- * @return mixed
4437
- */
4438
- function getKey($key, array $array, $default = null)
4439
- {
4440
- return array_key_exists($key, $array) ? $array[$key] : $default;
4441
- }
4442
-
4443
- function recursiveUrlReplacement(&$value, $index, $data)
4444
- {
4445
- if (is_string($value)) {
4446
- if (is_string($data['regex'])) {
4447
- $expressions = array($data['regex']);
4448
- } elseif (is_array($data['regex'])) {
4449
- $expressions = $data['regex'];
4450
- } else {
4451
- return;
4452
- }
4453
-
4454
- foreach ($expressions as $exp) {
4455
- $value = preg_replace($exp, $data['newUrl'], $value);
4456
- }
4457
- }
4458
- }
4459
-
4460
- /**
4461
- * This should mirror database replacements in cloner.php
4462
- */
4463
- function restore_migrate_urls()
4464
- {
4465
- // ----- DATABASE REPLACEMENTS
4466
-
4467
- /**
4468
- * Finds all urls that begin with $oldSiteUrl AND
4469
- * end either with OPTIONAL slash OR with MANDATORY slash following any number of any characters
4470
- */
4471
-
4472
- // Get all options that contain old urls, then check if we can replace them safely
4473
- // Now check for old urls without WWW
4474
- global $restoreParams, $wpdb;
4475
- $oldSiteUrl = $restoreParams['oldSiteUrl'];
4476
- $oldUrl = $restoreParams['oldUrl'];
4477
- $tablePrefix = $restoreParams['tablePrefix'];
4478
- $newUrl = $restoreParams['newUrl'];
4479
-
4480
- if (!isset($oldSiteUrl) || !isset($oldUrl)) {
4481
- return false;
4482
- }
4483
-
4484
- $parsedOldSiteUrl = parse_url(strpos($oldSiteUrl, '://') === false ? "http://$oldSiteUrl" : $oldSiteUrl);
4485
- $parsedOldUrl = parse_url(strpos($oldUrl, '://') === false ? "http://$oldUrl" : $oldUrl);
4486
- $host = getKey('host', $parsedOldSiteUrl, '');
4487
- $path = getKey('path', $parsedOldSiteUrl, '');
4488
- $oldSiteUrlNoWww = preg_replace('#^www\.(.+\.)#i', '$1', $host).$path;
4489
- $parsedOldSiteUrlNoWww = parse_url(strpos($oldSiteUrlNoWww, '://') === false
4490
- ? "http://$oldSiteUrlNoWww"
4491
- : $oldSiteUrlNoWww
4492
- );
4493
- if (isset($parse['scheme'])) {
4494
- $oldSiteUrlNoWww = "{$parse['scheme']}://$oldSiteUrlNoWww";
4495
- }
4496
-
4497
- // Modify the database for two variants of url, one with and one without WWW
4498
- $oldUrls = array('oldSiteUrl' => $oldSiteUrl);
4499
- $tmp1 = @"{$parsedOldUrl['host']}/{$parsedOldUrl['path']}";
4500
- $tmp2 = @"{$parsedOldSiteUrlNoWww['host']}/{$parsedOldSiteUrlNoWww['path']}";
4501
- if ($oldSiteUrlNoWww != $oldSiteUrl && $tmp1 != $tmp2) {
4502
- $oldUrls['oldSiteUrlNoWww'] = $oldSiteUrlNoWww;
4503
- }
4504
- if (strpos($oldSiteUrl, $oldUrl
4505
- ) !== false && $oldSiteUrl != $oldUrl && $parsedOldUrl['host'] != $parsedOldSiteUrl['host']
4506
- ) {
4507
- $oldUrls['oldUrl'] = $oldUrl;
4508
- }
4509
- foreach ($oldUrls as $key => $url) {
4510
- if (empty($url) || strlen($url) <= 1) {
4511
- continue;
4512
- }
4513
-
4514
- if ($key == 'oldSiteUrlNoWww') {
4515
- $amazingRegex = "~http://{$url}(?=(((/.*)+)|(/?$)))~";
4516
- } else {
4517
- $amazingRegex = "~{$url}(?=(((/.*)+)|(/?$)))~";
4518
- }
4519
- // Check options
4520
- $query = "SELECT option_id, option_value FROM {$tablePrefix}options WHERE option_value LIKE '%{$url}%';";
4521
- $selection = $wpdb->get_results($query, ARRAY_A);
4522
- foreach ($selection as $row) {
4523
- // Set a default value untouched
4524
- $replaced = $row['option_value'];
4525
-
4526
- if (is_serialized($row['option_value'])) {
4527
- $unserialized = unserialize($row['option_value']);
4528
- if (is_array($unserialized)) {
4529
- array_walk_recursive($unserialized, 'recursiveUrlReplacement', array(
4530
- 'newUrl' => $newUrl,
4531
- 'regex' => $amazingRegex,
4532
- )
4533
- );
4534
- $replaced = serialize($unserialized);
4535
- }
4536
- } else {
4537
- $replaced = preg_replace($amazingRegex, $newUrl, $replaced);
4538
- }
4539
-
4540
- $escapedReplacement = $wpdb->_escape($replaced);
4541
-
4542
- $optId = $row['option_id'];
4543
- if ($row['option_value'] != $replaced) {
4544
- $query = "UPDATE {$tablePrefix}options SET option_value = '{$escapedReplacement}' WHERE option_id = {$optId}";
4545
- $wpdb->query($query);
4546
- }
4547
- }
4548
-
4549
- // Check post meta
4550
- $query = "SELECT meta_id, meta_value FROM {$tablePrefix}postmeta WHERE meta_value LIKE '%{$url}%'";
4551
- $selection = $wpdb->get_results($query, ARRAY_A);
4552
- foreach ($selection as $row) {
4553
- $replacement = $row['meta_value'];
4554
- if (is_serialized($replacement)) {
4555
- $unserialized = unserialize($replacement);
4556
- if (is_array($unserialized)) {
4557
- array_walk_recursive($unserialized, 'recursiveUrlReplacement', array(
4558
- 'newUrl' => $newUrl,
4559
- 'regex' => $amazingRegex,
4560
- )
4561
- );
4562
- }
4563
- $replacement = serialize($unserialized);
4564
- } else {
4565
- $replacement = preg_replace($amazingRegex, $newUrl, $replacement);
4566
- }
4567
-
4568
- if ($replacement != $row['meta_value']) {
4569
- $escapedReplacement = $wpdb->_escape($replacement);
4570
- $id = $row['meta_id'];
4571
- $query = "UPDATE {$tablePrefix}postmeta SET meta_value = '{$escapedReplacement}' WHERE meta_id = '$id'";
4572
- $wpdb->query($query);
4573
- }
4574
- }
4575
-
4576
- // Do the same with posts
4577
- $query = "SELECT ID, post_content, guid FROM {$tablePrefix}posts WHERE post_content LIKE '%{$url}%' OR guid LIKE '%{$url}%'";
4578
- $selection = $wpdb->get_results($query, ARRAY_A);
4579
- foreach ($selection as &$row) {
4580
- $postContent = preg_replace($amazingRegex, $newUrl, $row['post_content']);
4581
- $guid = preg_replace($amazingRegex, $newUrl, $row['guid']);
4582
-
4583
- if ($postContent != $row['post_content'] || $guid != $row['guid']) {
4584
- $postContent = $wpdb->_escape($postContent);
4585
- $guid = $wpdb->_escape($guid);
4586
- $postId = $row['ID'];
4587
- $q = "UPDATE {$tablePrefix}posts SET post_content = '$postContent', guid = '$guid' WHERE ID = {$postId}";
4588
- $wpdb->query($q);
4589
- }
4590
- }
4591
- }
4592
- }
4593
-
4594
- function restore_htaccess()
4595
- {
4596
- // This has to be done because it contains the function save_mod_rewrite_rules().
4597
- include_once ABSPATH.'wp-admin/includes/admin.php';
4598
-
4599
- $htaccessRealpath = realpath(ABSPATH.'.htaccess');
4600
-
4601
- if ($htaccessRealpath) {
4602
- @rename($htaccessRealpath, "$htaccessRealpath.old");
4603
- }
4604
-
4605
- if (isset($GLOBALS['wp_rewrite'])) {
4606
- $wpRewrite = $GLOBALS['wp_rewrite'];
4607
- } else {
4608
- $wpRewrite = $GLOBALS['wp_rewrite'] = new WP_Rewrite();
4609
- }
4610
-
4611
- $wpRewrite->flush_rules(true);
4612
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/MMB/Comment.php CHANGED
@@ -8,24 +8,6 @@
8
  **************************************************************/
9
  class MMB_Comment extends MMB_Core
10
  {
11
- public function change_status($args)
12
- {
13
- $comment_id = $args['comment_id'];
14
- $status = $args['status'];
15
-
16
- if ('approve' == $status) {
17
- wp_set_comment_status($comment_id, 'approve');
18
- } elseif ('unapprove' == $status) {
19
- wp_set_comment_status($comment_id, 'hold');
20
- } elseif ('spam' == $status) {
21
- wp_set_comment_status($comment_id, 'spam');
22
- } elseif ('trash' == $status) {
23
- wp_set_comment_status($comment_id, 'trash');
24
- }
25
-
26
- return true;
27
- }
28
-
29
  public function get_comments($args)
30
  {
31
  /** @var wpdb $wpdb */
@@ -125,31 +107,6 @@ class MMB_Comment extends MMB_Core
125
  return $totals;
126
  }
127
 
128
- public function action_comment($args)
129
- {
130
- $docomaction = $args['docomaction'];
131
- $comment_id = $args['comment_id'];
132
-
133
- if (!empty($comment_id) && is_numeric($comment_id)) {
134
- if ($docomaction == 'delete') {
135
- wp_delete_comment($comment_id, true);
136
- delete_comment_meta($comment_id);
137
- } elseif ($docomaction == 'unapprove' || $docomaction == 'untrash' || $docomaction == 'unspam') {
138
- wp_set_comment_status($comment_id, 'hold');
139
- } elseif ($docomaction == 'approve') {
140
- wp_set_comment_status($comment_id, 'approve');
141
- } elseif ($docomaction == 'spam') {
142
- wp_set_comment_status($comment_id, 'spam');
143
- } elseif ($docomaction == 'trash') {
144
- wp_set_comment_status($comment_id, 'trash');
145
- }
146
-
147
- return 'Comment updated.';
148
- } else {
149
- return 'No ID...';
150
- }
151
- }
152
-
153
  public function bulk_action_comments($args)
154
  {
155
  $docomaction = $args['docomaction'];
@@ -172,67 +129,4 @@ class MMB_Comment extends MMB_Core
172
 
173
  return "comments updated";
174
  }
175
-
176
- public function reply_comment($args)
177
- {
178
- /** @var wpdb $wpdb */
179
- global $wpdb, $current_user;
180
-
181
- $post_id = $args['post_id'];
182
- $comment_id = $args['comment_id'];
183
- $reply_text = $args['reply_text'];
184
-
185
- $comments = array();
186
-
187
- if (!empty($comment_id) && !empty($reply_text)) {
188
- $admins = get_userdata($current_user->ID);
189
- $now = time();
190
- $insert_reply = "INSERT INTO $wpdb->comments(comment_post_ID, comment_author, comment_author_email, comment_author_url, comment_author_IP, comment_date, comment_date_gmt, comment_content, comment_karma, comment_approved, comment_agent, comment_parent, user_id) VALUES(".$post_id.", '".$admins->user_login."', '".$admins->user_email."', '".$admins->user_url."', '".$_SERVER['REMOTE_ADDR']."', NOW(), NOW(), '%s', 0, 1, '".$_SERVER['HTTP_USER_AGENT']."', ".$comment_id.", ".$current_user->ID.")";
191
- $insert_reply_res = $wpdb->query($wpdb->prepare($insert_reply, base64_decode($reply_text)));
192
- $lastid = $wpdb->insert_id;
193
-
194
- $comments_approved = $this->comment_total();
195
-
196
- $comment_total_approved = 0;
197
- if (isset($comments_approved[$post_id]['approved'])) {
198
- $comment_total_approved = $comments_approved[$post_id]['approved'];
199
- }
200
- $comment_total_pending = 0;
201
- if (isset($comments_approved[$post_id]['pending'])) {
202
- $comment_total_pending = $comments_approved[$post_id]['pending'];
203
- }
204
-
205
- $comment_parent_author = '';
206
- if ($comment_id > 0) {
207
- $select_parent_author = "SELECT c.comment_author, p.post_title, p.post_type, p.guid FROM $wpdb->comments as c, $wpdb->posts as p WHERE c.comment_post_ID = p.ID AND c.comment_ID = ".$comment_id;
208
- $select_parent_author_res = $wpdb->get_row($select_parent_author);
209
- $comment_parent_author = $select_parent_author_res->comment_author;
210
- }
211
-
212
- $comments[$lastid] = array(
213
- "comment_post_ID" => $post_id,
214
- "comment_author" => $admins->user_login,
215
- "comment_author_email" => $admins->user_email,
216
- "comment_author_url" => $admins->user_url,
217
- "comment_author_IP" => $_SERVER['REMOTE_ADDR'],
218
- "comment_date" => $now,
219
- "comment_content" => htmlspecialchars($reply_text),
220
- "comment_approved" => '1',
221
- "comment_parent" => $comment_id,
222
- "comment_parent_author" => $comment_parent_author,
223
- "comment_total_approved" => $comment_total_approved,
224
- "comment_total_pending" => $comment_total_pending,
225
- );
226
-
227
- if (!empty($select_parent_author_res)) {
228
- $comments[$lastid] += array(
229
- "post_title" => htmlspecialchars($select_parent_author_res->post_title),
230
- "post_type" => $select_parent_author_res->post_type,
231
- "guid" => $select_parent_author_res->guid,
232
- );
233
- }
234
- }
235
-
236
- return $comments;
237
- }
238
  }
8
  **************************************************************/
9
  class MMB_Comment extends MMB_Core
10
  {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11
  public function get_comments($args)
12
  {
13
  /** @var wpdb $wpdb */
107
  return $totals;
108
  }
109
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
110
  public function bulk_action_comments($args)
111
  {
112
  $docomaction = $args['docomaction'];
129
 
130
  return "comments updated";
131
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
132
  }
src/MMB/Container.php DELETED
@@ -1,72 +0,0 @@
1
- <?php
2
-
3
- class MMB_Container
4
- {
5
- private $executableFinder;
6
- private $logger;
7
-
8
- private $parameters = array();
9
-
10
- public function __construct(array $parameters = array())
11
- {
12
- $parameters += array(
13
- 'gelf_server' => null,
14
- 'gelf_port' => null,
15
- 'log_file' => null,
16
- );
17
-
18
- $this->parameters = $parameters;
19
- }
20
-
21
- public function getExecutableFinder()
22
- {
23
- if ($this->executableFinder === null) {
24
- global $wpdb;
25
- $this->executableFinder = new Symfony_Process_ExecutableFinder();
26
-
27
- if (is_callable(array($wpdb, 'get_var'))) {
28
- /** @var wpdb $wpdb */
29
- $basePath = rtrim($wpdb->get_var('select @@basedir'), '/\\');
30
- if ($basePath) {
31
- $basePath .= '/bin';
32
- $this->executableFinder->addExtraDir($basePath);
33
- }
34
- }
35
- }
36
-
37
- return $this->executableFinder;
38
- }
39
-
40
- public function getLogger()
41
- {
42
- if ($this->logger === null) {
43
- $processors = array(
44
- array(new Monolog_Processor_MemoryUsageProcessor(), 'callback'),
45
- array(new Monolog_Processor_MemoryPeakUsageProcessor(), 'callback'),
46
- array(new Monolog_Processor_IntrospectionProcessor(), 'callback'),
47
- array(new Monolog_Processor_PsrLogMessageProcessor(), 'callback'),
48
- array(new Monolog_Processor_UidProcessor(), 'callback'),
49
- array(new Monolog_Processor_WebProcessor(), 'callback'),
50
- array(new MWP_Monolog_Processor_TimeUsageProcessor(), 'callback'),
51
- array(new MWP_Monolog_Processor_ExceptionProcessor(), 'callback'),
52
- array(new MWP_Monolog_Processor_ProcessProcessor(), 'callback'),
53
- );
54
- $handlers = array();
55
-
56
- if (!empty($this->parameters['log_file'])) {
57
- $fileHandler = new Monolog_Handler_StreamHandler(fopen(dirname(dirname(dirname(__FILE__))).'/'.$this->parameters['log_file'], 'a'));
58
- $fileHandler->setFormatter(new Monolog_Formatter_HtmlFormatter());
59
- $handlers[] = $fileHandler;
60
- } elseif (!empty($this->parameters['gelf_server'])) {
61
- $publisher = new Gelf_Publisher($this->parameters['gelf_server'], $this->parameters['gelf_port'] ? $this->parameters['gelf_port'] : Gelf_Publisher::GRAYLOG2_DEFAULT_PORT);
62
- $handlers[] = new Monolog_Handler_LegacyGelfHandler($publisher);
63
- } else {
64
- $handlers[] = new Monolog_Handler_NullHandler();
65
- }
66
-
67
- $this->logger = new Monolog_Logger('worker', $handlers, $processors);
68
- }
69
-
70
- return $this->logger;
71
- }
72
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/MMB/Core.php CHANGED
@@ -6,58 +6,33 @@
6
  * Copyright (c) 2011 Prelovac Media
7
  * www.prelovac.com
8
  **************************************************************/
9
- class MMB_Core extends MMB_Helper
10
  {
 
 
11
 
12
- public $slug;
 
13
 
14
- public $settings;
 
15
 
16
- public $remote_client;
 
17
 
18
- public $comment_instance;
19
 
20
- public $plugin_instance;
21
-
22
- public $theme_instance;
23
-
24
- public $wp_instance;
25
-
26
- public $post_instance;
27
-
28
- public $stats_instance;
29
-
30
- public $search_instance;
31
-
32
- public $user_instance;
33
-
34
- public $backup_instance;
35
-
36
- public $installer_instance;
37
-
38
- public $mmb_multisite;
39
-
40
- public $network_admin_install;
41
-
42
- private $action_call;
43
-
44
- private $action_params;
45
-
46
- private $mmb_init_actions;
47
 
48
  public function __construct()
49
  {
50
- global $blog_id, $_mmb_item_filter, $_mmb_options;
51
-
52
- $_mmb_options = get_option('wrksettings');
53
- $_mmb_options = !empty($_mmb_options) ? $_mmb_options : array();
54
 
55
  if (is_multisite()) {
56
  $this->mmb_multisite = $blog_id;
57
  $this->network_admin_install = get_option('mmb_network_admin_install');
58
- } else {
59
- $this->mmb_multisite = false;
60
- $this->network_admin_install = null;
61
  }
62
 
63
  // admin notices
@@ -77,79 +52,41 @@ class MMB_Core extends MMB_Helper
77
  add_action('admin_notices', array(&$this, 'admin_notice'));
78
  }
79
  }
80
-
81
- $_mmb_item_filter['pre_init_stats'] = array('core_update', 'hit_counter', 'comments', 'backups', 'posts', 'drafts', 'scheduled', 'site_statistics');
82
- $_mmb_item_filter['get'] = array('updates', 'errors');
83
-
84
- $this->mmb_init_actions = array();
85
-
86
- add_action('init', array(&$this, 'mmb_remote_action'), 9999);
87
- add_action('setup_theme', 'mmb_run_forked_action', 1);
88
-
89
- if (!get_option('_worker_nossl_key') && !get_option('_worker_public_key')) {
90
- add_action('init', array(&$this, 'deactivateWorkerIfNotAddedAfterTenMinutes'));
91
- }
92
  }
93
 
94
- public function mmb_remote_action()
95
  {
96
- if ($this->action_call != null) {
97
- $params = isset($this->action_params) && $this->action_params != null ? $this->action_params : array();
98
- call_user_func($this->action_call, $params);
 
99
  }
100
- }
101
 
102
- /**
103
- * Add notice to network admin dashboard for security reasons
104
- */
105
- public function network_admin_notice()
106
- {
107
- global $status, $page, $s;
108
- $context = $status;
109
- $plugin = 'worker/init.php';
110
- $nonce = wp_create_nonce('deactivate-plugin_'.$plugin);
111
- $actions = 'plugins.php?action=deactivate&amp;plugin='.urlencode($plugin).'&amp;plugin_status='.$context.'&amp;paged='.$page.'&amp;s='.$s.'&amp;_wpnonce='.$nonce;
112
  $configurationService = new MWP_Configuration_Service();
113
  $configuration = $configurationService->getConfiguration();
114
  $notice = $configuration->getNetworkNotice();
115
- $notice = str_replace("{deactivate_url}", $actions, $notice);
116
  echo $notice;
117
  }
118
 
119
- /**
120
- * Add notice to admin dashboard for security reasons
121
- */
122
  public function admin_notice()
123
  {
124
- global $status, $page, $s;
125
- $context = $status;
126
- $plugin = 'worker/init.php';
127
- $nonce = wp_create_nonce('deactivate-plugin_'.$plugin);
128
- $actions = 'plugins.php?action=deactivate&amp;plugin='.urlencode($plugin).'&amp;plugin_status='.$context.'&amp;paged='.$page.'&amp;s='.$s.'&amp;_wpnonce='.$nonce;
 
129
  $configurationService = new MWP_Configuration_Service();
130
  $configuration = $configurationService->getConfiguration();
131
- $notice = $configuration->getNotice();
132
- $deactivateText = $configuration->getDeactivateText();
133
- if ($this->mmb_multisite && $this->network_admin_install != '1') {
134
- $deactivateTextLink = ''.$deactivateText;
135
- } else {
136
- $deactivateTextLink = '<a href="'.$actions.'" class="mwp_text_notice">'.$deactivateText.'</a>';
137
- }
138
- $notice = str_replace("{deactivate_text}", $deactivateTextLink, $notice);
139
 
140
  echo $notice;
141
  }
142
 
143
- public function mwp_send_ajax_response($success = true, $message = '')
144
  {
145
- $response = json_encode(
146
- array(
147
- 'success' => $success,
148
- 'message' => $message,
149
- )
150
- );
151
- print $response;
152
- exit;
153
  }
154
 
155
  /**
@@ -165,7 +102,7 @@ class MMB_Core extends MMB_Helper
165
  }
166
 
167
  /**
168
- * Gets an instance of the Comment class
169
  */
170
  public function get_comment_instance()
171
  {
@@ -177,19 +114,7 @@ class MMB_Core extends MMB_Helper
177
  }
178
 
179
  /**
180
- * Gets an instance of MMB_Post class
181
- */
182
- public function get_post_instance()
183
- {
184
- if (!isset($this->post_instance)) {
185
- $this->post_instance = new MMB_Post();
186
- }
187
-
188
- return $this->post_instance;
189
- }
190
-
191
- /**
192
- * Gets an instance of User
193
  */
194
  public function get_user_instance()
195
  {
@@ -201,7 +126,7 @@ class MMB_Core extends MMB_Helper
201
  }
202
 
203
  /**
204
- * Gets an instance of stats class
205
  */
206
  public function get_stats_instance()
207
  {
@@ -213,17 +138,8 @@ class MMB_Core extends MMB_Helper
213
  }
214
 
215
  /**
216
- * Gets an instance of stats class
217
  */
218
- public function get_backup_instance()
219
- {
220
- if (!isset($this->backup_instance)) {
221
- $this->backup_instance = new MMB_Backup();
222
- }
223
-
224
- return $this->backup_instance;
225
- }
226
-
227
  public function get_installer_instance()
228
  {
229
  if (!isset($this->installer_instance)) {
@@ -242,9 +158,10 @@ class MMB_Core extends MMB_Helper
242
  Plugin Name: ManageWP - Worker Loader
243
  Plugin URI: https://managewp.com
244
  Description: This is automatically generated by the ManageWP Worker plugin to increase performance and reliability. It is automatically disabled when disabling the main plugin.
245
- Author: ManageWP
246
- Author URI: https://managewp.com
247
  License: GPL2
 
248
  */
249
 
250
  if (!function_exists('untrailingslashit') || !defined('WP_PLUGIN_DIR')) {
@@ -253,7 +170,8 @@ if (!function_exists('untrailingslashit') || !defined('WP_PLUGIN_DIR')) {
253
  }
254
 
255
  if (file_exists(untrailingslashit(WP_PLUGIN_DIR).'/$pluginBasename')) {
256
- if (in_array('$pluginBasename', (array) get_option('active_plugins'))) {
 
257
  \$GLOBALS['mwp_is_mu'] = true;
258
  include_once untrailingslashit(WP_PLUGIN_DIR).'/$pluginBasename';
259
  }
@@ -282,6 +200,10 @@ EOF;
282
  }
283
  }
284
 
 
 
 
 
285
  $loaderWritten = @file_put_contents($loaderPath, $loaderContent);
286
 
287
  if (!$loaderWritten) {
@@ -296,6 +218,13 @@ EOF;
296
  */
297
  public function install()
298
  {
 
 
 
 
 
 
 
299
  try {
300
  $this->registerMustUse('0-worker.php', $this->buildLoaderContent('worker/init.php'));
301
  } catch (Exception $e) {
@@ -303,8 +232,7 @@ EOF;
303
  }
304
 
305
  /** @var wpdb $wpdb */
306
- global $wpdb, $_wp_using_ext_object_cache;
307
- $_wp_using_ext_object_cache = false;
308
 
309
  //delete plugin options, just in case
310
  if ($this->mmb_multisite != false) {
@@ -312,33 +240,33 @@ EOF;
312
  if (!empty($network_blogs)) {
313
  if (is_network_admin()) {
314
  update_option('mmb_network_admin_install', 1);
 
315
  foreach ($network_blogs as $details) {
316
- if ($details->site_id == $details->blog_id) {
317
  update_blog_option($details->blog_id, 'mmb_network_admin_install', 1);
318
  } else {
319
  update_blog_option($details->blog_id, 'mmb_network_admin_install', -1);
320
  }
321
 
322
- delete_blog_option($details->blog_id, '_worker_nossl_key');
323
- delete_blog_option($details->blog_id, '_worker_public_key');
324
  delete_blog_option($details->blog_id, '_action_message_id');
325
  }
326
  } else {
327
  update_option('mmb_network_admin_install', -1);
328
- delete_option('_worker_nossl_key');
329
- delete_option('_worker_public_key');
330
  delete_option('_action_message_id');
331
  }
332
  }
333
  } else {
334
- delete_option('_worker_nossl_key');
335
- delete_option('_worker_public_key');
336
  delete_option('_action_message_id');
337
  }
338
 
339
  delete_option('mwp_notifications');
340
  delete_option('mwp_worker_brand');
341
- delete_option('mwp_pageview_alerts');
342
  delete_option('mwp_worker_configuration');
343
  $path = realpath(dirname(__FILE__)."/../../worker.json");
344
  if (file_exists($path)) {
@@ -348,51 +276,38 @@ EOF;
348
  update_option("mwp_worker_configuration", $jsonConfiguration);
349
  }
350
  }
351
- update_option('mmb_worker_activation_time', time());
352
  }
353
 
354
- /**
355
- * Saves the (modified) options into the database
356
- * Deprecated
357
- */
358
- public function save_options($options = array())
359
  {
360
- global $_mmb_options;
361
-
362
- $_mmb_options = array_merge($_mmb_options, $options);
363
- update_option('wrksettings', $options);
364
- }
365
 
366
- /**
367
- * Deletes options for communication with master
368
- */
369
- public function deactivate($deactivate = false)
370
- {
371
  /** @var wpdb $wpdb */
372
- mwp_uninstall();
373
- global $current_user, $wpdb, $_wp_using_ext_object_cache;
374
- $_wp_using_ext_object_cache = false;
375
 
376
- if ($this->mmb_multisite != false) {
377
  $network_blogs = $wpdb->get_col("select `blog_id` from `{$wpdb->blogs}`");
378
  if (!empty($network_blogs)) {
379
  if (is_network_admin()) {
380
- if ($deactivate) {
381
  delete_option('mmb_network_admin_install');
382
  foreach ($network_blogs as $blog_id) {
383
  delete_blog_option($blog_id, 'mmb_network_admin_install');
384
  delete_blog_option($blog_id, '_worker_nossl_key');
385
  delete_blog_option($blog_id, '_worker_public_key');
386
  delete_blog_option($blog_id, '_action_message_id');
387
- delete_blog_option($blog_id, 'mwp_maintenace_mode');
388
  delete_blog_option($blog_id, 'mwp_notifications');
389
- delete_blog_option($blog_id, 'mwp_worker_brand');
390
- delete_blog_option($blog_id, 'mwp_pageview_alerts');
391
- delete_blog_option($blog_id, 'mwp_pageview_alerts');
 
 
392
  }
393
  }
394
  } else {
395
- if ($deactivate) {
396
  delete_option('mmb_network_admin_install');
397
  }
398
 
@@ -408,30 +323,15 @@ EOF;
408
  }
409
 
410
  //Delete options
411
- delete_option('mwp_maintenace_mode');
412
  delete_option('mwp_notifications');
413
- delete_option('mwp_worker_brand');
414
- delete_option('mwp_pageview_alerts');
415
- wp_clear_scheduled_hook('mwp_backup_tasks');
416
  wp_clear_scheduled_hook('mwp_notifications');
417
  wp_clear_scheduled_hook('mwp_datasend');
418
- delete_option('mwp_worker_configuration');
419
- delete_option('mmb_worker_activation_time');
420
- }
421
 
422
- /**
423
- * Constructs a url (for ajax purpose)
424
- *
425
- * @param mixed $base_page
426
- */
427
- public function construct_url($params = array(), $base_page = 'index.php')
428
- {
429
- $url = "$base_page?_wpnonce=".wp_create_nonce($this->slug);
430
- foreach ($params as $key => $value) {
431
- $url .= "&$key=$value";
432
  }
433
-
434
- return $url;
435
  }
436
 
437
  /**
@@ -457,6 +357,7 @@ EOF;
457
 
458
  ob_start();
459
  @unlink(dirname(__FILE__));
 
460
  $upgrader = new Plugin_Upgrader(mwp_container()->getUpdaterSkin());
461
  $result = $upgrader->run(
462
  array(
@@ -486,18 +387,127 @@ EOF;
486
  );
487
  }
488
 
489
- public function deactivateWorkerIfNotAddedAfterTenMinutes()
490
  {
491
- $workerActivationTime = get_option("mmb_worker_activation_time");
492
- if ((int) $workerActivationTime + 600 > time()) {
 
 
 
 
 
 
 
493
  return;
494
  }
495
- $activated_plugins = get_option('active_plugins');
496
- $keyWorker = array_search("worker/init.php", $activated_plugins, true);
497
- if ($keyWorker === false) {
 
498
  return;
499
  }
500
- unset($activated_plugins[$keyWorker]);
501
- update_option('active_plugins', $activated_plugins);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
502
  }
503
  }
6
  * Copyright (c) 2011 Prelovac Media
7
  * www.prelovac.com
8
  **************************************************************/
9
+ class MMB_Core
10
  {
11
+ /** @var MMB_Comment */
12
+ private $comment_instance;
13
 
14
+ /** @var MMB_Stats */
15
+ private $stats_instance;
16
 
17
+ /** @var MMB_User */
18
+ private $user_instance;
19
 
20
+ /** @var MMB_Installer */
21
+ private $installer_instance;
22
 
23
+ protected $mmb_multisite = false;
24
 
25
+ protected $network_admin_install;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
26
 
27
  public function __construct()
28
  {
29
+ global $blog_id;
 
 
 
30
 
31
  if (is_multisite()) {
32
  $this->mmb_multisite = $blog_id;
33
  $this->network_admin_install = get_option('mmb_network_admin_install');
34
+
35
+ add_action('wpmu_new_blog', array(&$this, 'updateKeys'));
 
36
  }
37
 
38
  // admin notices
52
  add_action('admin_notices', array(&$this, 'admin_notice'));
53
  }
54
  }
 
 
 
 
 
 
 
 
 
 
 
 
55
  }
56
 
57
+ public function network_admin_notice()
58
  {
59
+ $enabledNotice = $this->isNoticeEnabled();
60
+
61
+ if (count(mwp_get_communication_keys()) > 0 || !$enabledNotice) {
62
+ return;
63
  }
 
64
 
 
 
 
 
 
 
 
 
 
 
65
  $configurationService = new MWP_Configuration_Service();
66
  $configuration = $configurationService->getConfiguration();
67
  $notice = $configuration->getNetworkNotice();
68
+
69
  echo $notice;
70
  }
71
 
 
 
 
72
  public function admin_notice()
73
  {
74
+ $enabledNotice = $this->isNoticeEnabled();
75
+
76
+ if (count(mwp_get_communication_keys()) > 0 || !$enabledNotice) {
77
+ return;
78
+ }
79
+
80
  $configurationService = new MWP_Configuration_Service();
81
  $configuration = $configurationService->getConfiguration();
82
+ $notice = is_multisite() ? $configuration->getNetworkNotice() : $configuration->getNotice();
 
 
 
 
 
 
 
83
 
84
  echo $notice;
85
  }
86
 
87
+ private function isNoticeEnabled()
88
  {
89
+ return apply_filters('mwp_admin_notice_enabled', true);
 
 
 
 
 
 
 
90
  }
91
 
92
  /**
102
  }
103
 
104
  /**
105
+ * @return MMB_Comment
106
  */
107
  public function get_comment_instance()
108
  {
114
  }
115
 
116
  /**
117
+ * @return MMB_User
 
 
 
 
 
 
 
 
 
 
 
 
118
  */
119
  public function get_user_instance()
120
  {
126
  }
127
 
128
  /**
129
+ * @return MMB_Stats
130
  */
131
  public function get_stats_instance()
132
  {
138
  }
139
 
140
  /**
141
+ * @return MMB_Installer
142
  */
 
 
 
 
 
 
 
 
 
143
  public function get_installer_instance()
144
  {
145
  if (!isset($this->installer_instance)) {
158
  Plugin Name: ManageWP - Worker Loader
159
  Plugin URI: https://managewp.com
160
  Description: This is automatically generated by the ManageWP Worker plugin to increase performance and reliability. It is automatically disabled when disabling the main plugin.
161
+ Author: GoDaddy
162
+ Author URI: https://godaddy.com
163
  License: GPL2
164
+ Network: true
165
  */
166
 
167
  if (!function_exists('untrailingslashit') || !defined('WP_PLUGIN_DIR')) {
170
  }
171
 
172
  if (file_exists(untrailingslashit(WP_PLUGIN_DIR).'/$pluginBasename')) {
173
+ if (in_array('$pluginBasename', (array) get_option('active_plugins')) ||
174
+ (function_exists('get_site_option') && array_key_exists('worker/init.php', (array) get_site_option('active_sitewide_plugins')))) {
175
  \$GLOBALS['mwp_is_mu'] = true;
176
  include_once untrailingslashit(WP_PLUGIN_DIR).'/$pluginBasename';
177
  }
200
  }
201
  }
202
 
203
+ if (!is_writable($mustUsePluginDir)) {
204
+ throw new Exception('MU-plugin directory is not writable.');
205
+ }
206
+
207
  $loaderWritten = @file_put_contents($loaderPath, $loaderContent);
208
 
209
  if (!$loaderWritten) {
218
  */
219
  public function install()
220
  {
221
+ update_option('mwp_recovering', '');
222
+ update_option('mwp_incremental_update_active', '');
223
+ update_option('mwp_core_autoupdate', '');
224
+ update_option('mwp_container_parameters', array());
225
+ update_option('mwp_container_site_parameters', array());
226
+ update_option('mwp_maintenace_mode', array());
227
+ mwp_container()->getMigration()->migrate();
228
  try {
229
  $this->registerMustUse('0-worker.php', $this->buildLoaderContent('worker/init.php'));
230
  } catch (Exception $e) {
232
  }
233
 
234
  /** @var wpdb $wpdb */
235
+ global $wpdb;
 
236
 
237
  //delete plugin options, just in case
238
  if ($this->mmb_multisite != false) {
240
  if (!empty($network_blogs)) {
241
  if (is_network_admin()) {
242
  update_option('mmb_network_admin_install', 1);
243
+ $mainBlogId = defined('BLOG_ID_CURRENT_SITE') ? BLOG_ID_CURRENT_SITE : false;
244
  foreach ($network_blogs as $details) {
245
+ if (($mainBlogId !== false && $details->blog_id == $mainBlogId) || ($mainBlogId === false && $details->site_id == $details->blog_id)) {
246
  update_blog_option($details->blog_id, 'mmb_network_admin_install', 1);
247
  } else {
248
  update_blog_option($details->blog_id, 'mmb_network_admin_install', -1);
249
  }
250
 
251
+ update_blog_option($details->blog_id, '_worker_nossl_key', '');
252
+ update_blog_option($details->blog_id, '_worker_public_key', '');
253
  delete_blog_option($details->blog_id, '_action_message_id');
254
  }
255
  } else {
256
  update_option('mmb_network_admin_install', -1);
257
+ update_option('_worker_nossl_key', '');
258
+ update_option('_worker_public_key', '');
259
  delete_option('_action_message_id');
260
  }
261
  }
262
  } else {
263
+ update_option('_worker_nossl_key', '');
264
+ update_option('_worker_public_key', '');
265
  delete_option('_action_message_id');
266
  }
267
 
268
  delete_option('mwp_notifications');
269
  delete_option('mwp_worker_brand');
 
270
  delete_option('mwp_worker_configuration');
271
  $path = realpath(dirname(__FILE__)."/../../worker.json");
272
  if (file_exists($path)) {
276
  update_option("mwp_worker_configuration", $jsonConfiguration);
277
  }
278
  }
 
279
  }
280
 
281
+ public function deactivate($networkDeactivation = false, $workerDeactivation = true)
 
 
 
 
282
  {
283
+ if ($workerDeactivation) {
284
+ mwp_uninstall();
285
+ }
 
 
286
 
 
 
 
 
 
287
  /** @var wpdb $wpdb */
288
+ global $current_user, $wpdb;
 
 
289
 
290
+ if ($this->mmb_multisite !== false) {
291
  $network_blogs = $wpdb->get_col("select `blog_id` from `{$wpdb->blogs}`");
292
  if (!empty($network_blogs)) {
293
  if (is_network_admin()) {
294
+ if ($networkDeactivation) {
295
  delete_option('mmb_network_admin_install');
296
  foreach ($network_blogs as $blog_id) {
297
  delete_blog_option($blog_id, 'mmb_network_admin_install');
298
  delete_blog_option($blog_id, '_worker_nossl_key');
299
  delete_blog_option($blog_id, '_worker_public_key');
300
  delete_blog_option($blog_id, '_action_message_id');
 
301
  delete_blog_option($blog_id, 'mwp_notifications');
302
+
303
+ if ($workerDeactivation) {
304
+ delete_blog_option($blog_id, 'mwp_maintenace_mode');
305
+ delete_blog_option($blog_id, 'mwp_worker_brand');
306
+ }
307
  }
308
  }
309
  } else {
310
+ if ($networkDeactivation) {
311
  delete_option('mmb_network_admin_install');
312
  }
313
 
323
  }
324
 
325
  //Delete options
 
326
  delete_option('mwp_notifications');
 
 
 
327
  wp_clear_scheduled_hook('mwp_notifications');
328
  wp_clear_scheduled_hook('mwp_datasend');
 
 
 
329
 
330
+ if ($workerDeactivation) {
331
+ delete_option('mwp_maintenace_mode');
332
+ delete_option('mwp_worker_brand');
333
+ delete_option('mwp_worker_configuration');
 
 
 
 
 
 
334
  }
 
 
335
  }
336
 
337
  /**
357
 
358
  ob_start();
359
  @unlink(dirname(__FILE__));
360
+ /** @handled class */
361
  $upgrader = new Plugin_Upgrader(mwp_container()->getUpdaterSkin());
362
  $result = $upgrader->run(
363
  array(
387
  );
388
  }
389
 
390
+ public function updateKeys()
391
  {
392
+ if (!$this->mmb_multisite) {
393
+ return;
394
+ }
395
+
396
+ global $wpdb;
397
+
398
+ $publicKey = $this->get_parent_blog_option('_worker_public_key');
399
+
400
+ if (empty($publicKey)) {
401
  return;
402
  }
403
+
404
+ $networkBlogs = $wpdb->get_results("select `blog_id` from `{$wpdb->blogs}`");
405
+
406
+ if (empty($networkBlogs)) {
407
  return;
408
  }
409
+
410
+ foreach ($networkBlogs as $details) {
411
+ update_blog_option($details->blog_id, '_worker_public_key', $publicKey);
412
+ }
413
+
414
+ return;
415
+ }
416
+
417
+ public function mmb_get_user_info($user_info = false, $info = 'login')
418
+ {
419
+ if ($user_info === false) {
420
+ return false;
421
+ }
422
+
423
+ if (strlen(trim($user_info)) == 0) {
424
+ return false;
425
+ }
426
+
427
+ return get_user_by($info, $user_info);
428
+ }
429
+
430
+ public function mmb_get_transient($option_name)
431
+ {
432
+ global $wp_version;
433
+
434
+ if (trim($option_name) == '') {
435
+ return false;
436
+ }
437
+
438
+ if (version_compare($wp_version, '3.4', '>')) {
439
+ return get_site_transient($option_name);
440
+ }
441
+
442
+ if (!empty($this->mmb_multisite)) {
443
+ return $this->mmb_get_sitemeta_transient($option_name);
444
+ }
445
+
446
+ $transient = get_option('_site_transient_'.$option_name);
447
+
448
+ return apply_filters("site_transient_".$option_name, $transient);
449
+ }
450
+
451
+ public function mmb_get_sitemeta_transient($option_name)
452
+ {
453
+ /** @var wpdb $wpdb */
454
+ global $wpdb;
455
+ $option_name = '_site_transient_'.$option_name;
456
+
457
+ $result = $wpdb->get_var($wpdb->prepare("SELECT `meta_value` FROM `{$wpdb->sitemeta}` WHERE meta_key = '%s' AND `site_id` = '%s'", $option_name, $this->mmb_multisite));
458
+ $result = maybe_unserialize($result);
459
+
460
+ return $result;
461
+ }
462
+
463
+ public function get_master_public_key()
464
+ {
465
+ if (!get_option('_worker_public_key')) {
466
+ return false;
467
+ }
468
+
469
+ return base64_decode(get_option('_worker_public_key'));
470
+ }
471
+
472
+ public function mmb_get_error($error_object)
473
+ {
474
+ if (!is_wp_error($error_object)) {
475
+ return $error_object != '' ? $error_object : '';
476
+ } else {
477
+ $errors = array();
478
+ if (!empty($error_object->error_data)) {
479
+ foreach ($error_object->error_data as $error_key => $error_string) {
480
+ $errors[] = str_replace('_', ' ', ucfirst($error_key)).': '.$error_string;
481
+ }
482
+ } elseif (!empty($error_object->errors)) {
483
+ foreach ($error_object->errors as $error_key => $err) {
484
+ $errors[] = 'Error: '.str_replace('_', ' ', strtolower($error_key));
485
+ }
486
+ }
487
+
488
+ return implode('<br />', $errors);
489
+ }
490
+ }
491
+
492
+ public function check_if_pantheon()
493
+ {
494
+ return !empty($_ENV['PANTHEON_ENVIRONMENT']) && $_ENV['PANTHEON_ENVIRONMENT'] !== 'dev';
495
+ }
496
+
497
+ public function is_server_writable()
498
+ {
499
+ if ($this->check_if_pantheon()) {
500
+ return false;
501
+ }
502
+
503
+ if (!function_exists('get_filesystem_method')) {
504
+ include_once ABSPATH.'wp-admin/includes/file.php';
505
+ }
506
+
507
+ if ((!defined('FTP_HOST') || !defined('FTP_USER')) && (get_filesystem_method(array(), false) != 'direct')) {
508
+ return false;
509
+ } else {
510
+ return true;
511
+ }
512
  }
513
  }
src/MMB/Exception.php DELETED
@@ -1,9 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * Created by miljenko.rebernisak@prelovac.com
5
- * Date: 3/7/14
6
- */
7
- class MMB_Exception extends Exception
8
- {
9
- }
 
 
 
 
 
 
 
 
 
src/MMB/Helper.php DELETED
@@ -1,374 +0,0 @@
1
- <?php
2
-
3
- /*************************************************************
4
- * helper.class.php
5
- * Utility functions
6
- * Copyright (c) 2011 Prelovac Media
7
- * www.prelovac.com
8
- **************************************************************/
9
- class MMB_Helper
10
- {
11
-
12
- public $mmb_multisite;
13
-
14
- public function mmb_get_user_info($user_info = false, $info = 'login')
15
- {
16
- if ($user_info === false) {
17
- return false;
18
- }
19
-
20
- if (strlen(trim($user_info)) == 0) {
21
- return false;
22
- }
23
-
24
- return get_user_by($info, $user_info);
25
- }
26
-
27
- /**
28
- * Call action item filters
29
- */
30
- public function mmb_parse_action_params($key = '', $params = null, $call_object = null)
31
- {
32
- global $_mmb_item_filter;
33
- $call_object = $call_object !== null ? $call_object : $this;
34
- $return = array();
35
-
36
- if (isset($_mmb_item_filter[$key]) && !empty($_mmb_item_filter[$key])) {
37
- if (isset($params['item_filter']) && !empty($params['item_filter'])) {
38
- foreach ($params['item_filter'] as $_items) {
39
- if (!empty($_items)) {
40
- foreach ($_items as $_item) {
41
- if (isset($_item[0]) && in_array($_item[0], $_mmb_item_filter[$key])) {
42
- $_item[1] = isset($_item[1]) ? $_item[1] : array();
43
- $return = call_user_func(array(&$call_object, 'get_'.$_item[0]), $return, $_item[1]);
44
- }
45
- }
46
- }
47
- }
48
- }
49
- }
50
-
51
- return $return;
52
- }
53
-
54
- /**
55
- * Check if function exists or not on `suhosin` black list
56
- */
57
- public function mmb_function_exists($function_callback)
58
- {
59
- if (!function_exists($function_callback)) {
60
- return false;
61
- }
62
-
63
- $disabled = explode(', ', @ini_get('disable_functions'));
64
- if (in_array($function_callback, $disabled)) {
65
- return false;
66
- }
67
-
68
- if (extension_loaded('suhosin')) {
69
- $suhosin = @ini_get("suhosin.executor.func.blacklist");
70
- if (empty($suhosin) == false) {
71
- $suhosin = explode(',', $suhosin);
72
- $blacklist = array_map('trim', $suhosin);
73
- $blacklist = array_map('strtolower', $blacklist);
74
- if (in_array($function_callback, $blacklist)) {
75
- return false;
76
- }
77
- }
78
- }
79
-
80
- return true;
81
- }
82
-
83
- public function mmb_get_transient($option_name)
84
- {
85
- if (trim($option_name) == '') {
86
- return false;
87
- }
88
- if (!empty($this->mmb_multisite)) {
89
- return $this->mmb_get_sitemeta_transient($option_name);
90
- }
91
-
92
- $transient = get_option('_site_transient_'.$option_name);
93
-
94
- return apply_filters("site_transient_".$option_name, $transient);
95
- }
96
-
97
- public function mmb_delete_transient($option_name)
98
- {
99
- if (trim($option_name) == '') {
100
- return;
101
- }
102
-
103
- delete_option('_site_transient_'.$option_name);
104
- }
105
-
106
- public function mmb_get_sitemeta_transient($option_name)
107
- {
108
- /** @var wpdb $wpdb */
109
- global $wpdb;
110
- $option_name = '_site_transient_'.$option_name;
111
-
112
- $result = $wpdb->get_var($wpdb->prepare("SELECT `meta_value` FROM `{$wpdb->sitemeta}` WHERE meta_key = '%s' AND `site_id` = '%s'", $option_name, $this->mmb_multisite));
113
- $result = maybe_unserialize($result);
114
-
115
- return $result;
116
- }
117
-
118
- public function mmb_set_sitemeta_transient($option_name, $option_value)
119
- {
120
- /** @var wpdb $wpdb */
121
- global $wpdb;
122
- $option_name = '_site_transient_'.$option_name;
123
-
124
- if ($this->mmb_get_sitemeta_transient($option_name)) {
125
- $result = $wpdb->update(
126
- $wpdb->sitemeta,
127
- array(
128
- 'meta_value' => maybe_serialize($option_value),
129
- ),
130
- array(
131
- 'meta_key' => $option_name,
132
- 'site_id' => $this->mmb_multisite,
133
- )
134
- );
135
- } else {
136
- $result = $wpdb->insert(
137
- $wpdb->sitemeta,
138
- array(
139
- 'meta_key' => $option_name,
140
- 'meta_value' => maybe_serialize($option_value),
141
- 'site_id' => $this->mmb_multisite,
142
- )
143
- );
144
- }
145
-
146
- return $result;
147
- }
148
-
149
- public function delete_temp_dir($directory)
150
- {
151
- if (substr($directory, -1) == "/") {
152
- $directory = substr($directory, 0, -1);
153
- }
154
- if (!file_exists($directory) || !is_dir($directory)) {
155
- return false;
156
- } elseif (!is_readable($directory)) {
157
- return false;
158
- } else {
159
- $directoryHandle = opendir($directory);
160
-
161
- while ($contents = readdir($directoryHandle)) {
162
- if ($contents != '.' && $contents != '..') {
163
- $path = $directory."/".$contents;
164
-
165
- if (is_dir($path)) {
166
- $this->delete_temp_dir($path);
167
- } else {
168
- unlink($path);
169
- }
170
- }
171
- }
172
- closedir($directoryHandle);
173
- rmdir($directory);
174
-
175
- return true;
176
- }
177
- }
178
-
179
- public function set_worker_message_id($message_id = false)
180
- {
181
- if ($message_id) {
182
- add_option('_action_message_id', $message_id) or update_option('_action_message_id', $message_id);
183
-
184
- return $message_id;
185
- }
186
-
187
- return false;
188
- }
189
-
190
- public function get_master_public_key()
191
- {
192
- if (!get_option('_worker_public_key')) {
193
- return false;
194
- }
195
-
196
- return base64_decode(get_option('_worker_public_key'));
197
- }
198
-
199
- public function get_random_signature()
200
- {
201
- if (!get_option('_worker_nossl_key')) {
202
- return false;
203
- }
204
-
205
- return base64_decode(get_option('_worker_nossl_key'));
206
- }
207
-
208
- public function get_secure_hash()
209
- {
210
- $pl_key = $this->get_master_public_key();
211
- if (empty($pl_key) || $this->get_random_signature() !== false) {
212
- $pl_key = $this->get_random_signature();
213
- }
214
-
215
- if (!empty($pl_key)) {
216
- return md5(base64_encode($pl_key));
217
- }
218
-
219
- return false;
220
- }
221
-
222
- public function _secure_data($data = false)
223
- {
224
- if ($data == false) {
225
- return false;
226
- }
227
-
228
- $pl_key = $this->get_master_public_key();
229
- if (!$pl_key) {
230
- return false;
231
- }
232
-
233
- $secure = '';
234
- if (function_exists('openssl_public_decrypt') && !$this->get_random_signature()) {
235
- if (is_array($data) && !empty($data)) {
236
- foreach ($data as $input) {
237
- openssl_public_decrypt($input, $decrypted, $pl_key);
238
- $secure .= $decrypted;
239
- }
240
- } else {
241
- if (is_string($data)) {
242
- openssl_public_decrypt($data, $decrypted, $pl_key);
243
- $secure = $decrypted;
244
- } else {
245
- $secure = $data;
246
- }
247
- }
248
-
249
- return $secure;
250
- }
251
-
252
- return false;
253
- }
254
-
255
- public function encrypt_data($data = false)
256
- {
257
- if (empty($data)) {
258
- return $data;
259
- }
260
-
261
- $pl_key = $this->get_master_public_key();
262
- if (!$pl_key) {
263
- return false;
264
- }
265
-
266
- $data = serialize($data);
267
- $crypted = '';
268
- if (function_exists('openssl_public_encrypt') && !$this->get_random_signature()) {
269
- $length = strlen($data);
270
- if ($length > 100) {
271
- for ($i = 0; $i <= $length + 100; $i = $i + 100) {
272
- $input = substr($data, $i, 100);
273
- openssl_public_encrypt($input, $crypt, $pl_key);
274
- $crypted .= base64_encode($crypt).'::';
275
- }
276
- } else {
277
- openssl_public_encrypt($data, $crypted, $pl_key);
278
- }
279
- } else {
280
- $crypted = base64_encode($data);
281
- }
282
-
283
- return $crypted;
284
- }
285
-
286
- public function remove_http($url = '')
287
- {
288
- if ($url == 'http://' or $url == 'https://') {
289
- return $url;
290
- }
291
-
292
- return preg_replace('/^(http|https)\:\/\/(www.)?/i', '', $url);
293
- }
294
-
295
- public function mmb_get_error($error_object)
296
- {
297
- if (!is_wp_error($error_object)) {
298
- return $error_object != '' ? $error_object : '';
299
- } else {
300
- $errors = array();
301
- if (!empty($error_object->error_data)) {
302
- foreach ($error_object->error_data as $error_key => $error_string) {
303
- $errors[] = str_replace('_', ' ', ucfirst($error_key)).': '.$error_string