ManageWP Worker - Version 3.9.30

Version Description

  • New: Fully compatible with WordPress 4.0
  • New: Adding websites to your ManageWP Dashboard is now easier than ever
  • Fix: Backup tool improvements (especially for websites located on Rackspace)
  • Fix: Various Clone/Migration tool improvements and fixes
  • Fix: SEO PDF report visual enhancement
  • Fix: Various interface improvements and fixes
Download this release

Release Info

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

Code changes from version 3.9.29 to 3.9.30

Files changed (116) hide show
  1. functions.php +576 -570
  2. init.php +2071 -2043
  3. publickeys/ManageWP_mt.pub +9 -9
  4. publickeys/managewp_d.pub +9 -9
  5. publickeys/managewp_t.pub +9 -9
  6. publickeys/partner1.pub +9 -9
  7. publickeys/partner10.pub +9 -9
  8. publickeys/partner11.pub +9 -9
  9. publickeys/partner12.pub +9 -9
  10. publickeys/partner13.pub +9 -9
  11. publickeys/partner14.pub +9 -9
  12. publickeys/partner15.pub +9 -9
  13. publickeys/partner16.pub +9 -9
  14. publickeys/partner17.pub +9 -9
  15. publickeys/partner2.pub +9 -9
  16. publickeys/partner3.pub +9 -9
  17. publickeys/partner4.pub +8 -8
  18. publickeys/partner5.pub +9 -9
  19. publickeys/partner6.pub +9 -9
  20. publickeys/partner7.pub +9 -9
  21. publickeys/partner8.pub +9 -9
  22. publickeys/partner9.pub +9 -9
  23. readme.txt +380 -315
  24. screenshot-1.png +0 -0
  25. src/Dropbox/AppInfo.php +262 -237
  26. src/Dropbox/AppInfoLoadException.php +17 -17
  27. src/Dropbox/ArrayEntryStore.php +60 -60
  28. src/Dropbox/AuthBase.php +83 -74
  29. src/Dropbox/AuthInfo.php +85 -84
  30. src/Dropbox/AuthInfoLoadException.php +17 -17
  31. src/Dropbox/Checker.php +139 -93
  32. src/Dropbox/Client.php +1681 -1525
  33. src/Dropbox/Closure/ChunkedUploadContinueAction.php +28 -29
  34. src/Dropbox/Closure/ChunkedUploadFinishAction.php +25 -25
  35. src/Dropbox/Closure/ChunkedUploadStartAction.php +22 -22
  36. src/Dropbox/Closure/CurlConfigInStream.php +24 -24
  37. src/Dropbox/Closure/CurlConfigInterface.php +6 -6
  38. src/Dropbox/Closure/CurlConfigOctetStream.php +18 -18
  39. src/Dropbox/Closure/ReRunnableActionInterface.php +6 -6
  40. src/Dropbox/Curl.php +116 -112
  41. src/Dropbox/CurlStreamRelay.php +44 -45
  42. src/Dropbox/DeserializeException.php +18 -18
  43. src/Dropbox/DropboxMetadataHeaderCatcher.php +88 -82
  44. src/Dropbox/Exception.php +31 -31
  45. src/Dropbox/Exception/BadRequest.php +16 -16
  46. src/Dropbox/Exception/BadResponse.php +16 -16
  47. src/Dropbox/Exception/BadResponseCode.php +32 -32
  48. src/Dropbox/Exception/InvalidAccessToken.php +17 -17
  49. src/Dropbox/Exception/NetworkIO.php +15 -15
  50. src/Dropbox/Exception/ProtocolError.php +16 -16
  51. src/Dropbox/Exception/RetryLater.php +16 -16
  52. src/Dropbox/Exception/ServerError.php +14 -14
  53. src/Dropbox/Host.php +115 -98
  54. src/Dropbox/HttpResponse.php +16 -16
  55. src/Dropbox/OAuth1AccessToken.php +68 -60
  56. src/Dropbox/OAuth1Upgrader.php +106 -102
  57. src/Dropbox/Path.php +201 -170
  58. src/Dropbox/RequestUtil.php +308 -287
  59. src/Dropbox/SSLTester.php +112 -110
  60. src/Dropbox/Security.php +71 -64
  61. src/Dropbox/StreamReadException.php +15 -15
  62. src/Dropbox/ValueStore.php +60 -60
  63. src/Dropbox/WebAuth.php +281 -274
  64. src/Dropbox/WebAuthBase.php +64 -62
  65. src/Dropbox/WebAuthException/BadRequest.php +19 -19
  66. src/Dropbox/WebAuthException/BadState.php +18 -18
  67. src/Dropbox/WebAuthException/Csrf.php +20 -20
  68. src/Dropbox/WebAuthException/NotApproved.php +17 -17
  69. src/Dropbox/WebAuthException/Provider.php +17 -17
  70. src/Dropbox/WebAuthNoRedirect.php +82 -82
  71. src/Dropbox/WriteMode.php +126 -115
  72. src/Gelf/Message.php +294 -294
  73. src/Gelf/Publisher.php +250 -250
  74. src/Google/ApiClient.php +68 -36
  75. src/Google/ApiModel.php +26 -16
  76. src/Google/ApiUtils.php +25 -14
  77. src/Google/Auth/Abstract.php +0 -1
  78. src/Google/Auth/AssertionCredentials.php +18 -19
  79. src/Google/Auth/Exception.php +0 -1
  80. src/Google/Auth/LoginTicket.php +0 -1
  81. src/Google/Auth/OAuth2.php +126 -107
  82. src/Google/Auth/Simple.php +1 -2
  83. src/Google/Cache/Abstract.php +0 -1
  84. src/Google/Cache/Apc.php +0 -1
  85. src/Google/Cache/Exception.php +0 -1
  86. src/Google/Cache/File.php +0 -1
  87. src/Google/Cache/Memcache.php +1 -2
  88. src/Google/Cache/Null.php +1 -2
  89. src/Google/Collection.php +1 -1
  90. src/Google/Config.php +46 -47
  91. src/Google/Http/Batch.php +2 -3
  92. src/Google/Http/CacheParser.php +3 -4
  93. src/Google/Http/MediaFileUpload.php +22 -23
  94. src/Google/Http/REST.php +4 -6
  95. src/Google/Http/Request.php +26 -28
  96. src/Google/IO/Abstract.php +7 -7
  97. src/Google/IO/Curl.php +2 -2
  98. src/Google/IO/Exception.php +0 -1
  99. src/Google/IO/Stream.php +30 -27
  100. src/Google/IO/cacerts.pem +738 -738
  101. src/Google/Service/Drive.php +1213 -1229
  102. src/Google/Service/Exception.php +5 -5
  103. src/Google/Service/Oauth2.php +43 -48
  104. src/Google/Service/Resource.php +32 -33
  105. src/Google/Signer/P12.php +6 -6
  106. src/Google/Utils/URITemplate.php +87 -88
  107. src/Google/Verifier/Pem.php +0 -1
  108. src/MMB/Backup.php +405 -417
  109. src/MMB/Comment.php +9 -13
  110. src/MMB/Container.php +1 -1
  111. src/MMB/Core.php +69 -71
  112. src/MMB/Exception.php +5 -5
  113. src/MMB/Helper.php +45 -57
  114. src/MMB/Installer.php +107 -100
  115. src/MMB/Link.php +9 -13
  116. src/MMB/Post.php +33 -59
functions.php CHANGED
@@ -1,570 +1,576 @@
1
- <?php
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)) {
15
- include_once $file;
16
- }
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
- function mwp_container()
48
- {
49
- static $container;
50
-
51
- if ($container === null) {
52
- $parameters = get_option('mwp_container_parameters', array());
53
- $container = new MMB_Container($parameters);
54
- }
55
-
56
- return $container;
57
- }
58
-
59
- /**
60
- * @return Monolog_Psr_LoggerInterface
61
- */
62
- function mwp_logger()
63
- {
64
- static $mwp_logger;
65
- if (!get_option('mwp_debug_enable', false)) {
66
- if ($mwp_logger === null) {
67
- $mwp_logger = new Monolog_Logger('worker', array(new Monolog_Handler_NullHandler()));
68
- }
69
-
70
- return $mwp_logger;
71
- }
72
- if ($mwp_logger instanceof Monolog_Logger) {
73
- return $mwp_logger;
74
- }
75
- if ($mwp_logger === null) {
76
- $mwp_logger = true;
77
- $logger = mwp_container()->getLogger();
78
- Monolog_Registry::addLogger($logger, 'worker');
79
-
80
- $errorHandler = new Monolog_ErrorHandler($logger);
81
- $errorHandler->registerErrorHandler();
82
- $errorHandler->registerExceptionHandler();
83
- $errorHandler->registerFatalHandler(null, 1024);
84
- }
85
-
86
- return Monolog_Registry::getInstance('worker');
87
- }
88
-
89
- /**
90
- * @param $appKey
91
- * @param $appSecret
92
- * @param $token
93
- * @param $tokenSecret
94
- *
95
- * @return Dropbox_Client
96
- */
97
- function mwp_dropbox_oauth1_factory($appKey, $appSecret, $token, $tokenSecret)
98
- {
99
- $oauthToken ='OAuth oauth_version="1.0", oauth_signature_method="PLAINTEXT", oauth_consumer_key="'.$appKey.'", oauth_token="'.$token.'", oauth_signature="'.$appSecret.'&'.$tokenSecret.'"';
100
- $client = new Dropbox_Client($oauthToken, $token);
101
-
102
- return $client;
103
- }
104
-
105
- function mwp_format_memory_limit($limit)
106
- {
107
- if ((string) (int) $limit === (string) $limit) {
108
- // The number is numeric.
109
- return mwp_format_bytes($limit);
110
- }
111
-
112
- $units = strtolower(substr($limit, -1));
113
-
114
- if (!in_array($units, array('b', 'k', 'm', 'g'))) {
115
- // Invalid size unit.
116
- return $limit;
117
- }
118
-
119
- $number = substr($limit, 0, -1);
120
-
121
- if ((string) (int) $number !== $number) {
122
- // The number isn't numeric.
123
- return $number;
124
- }
125
-
126
- switch ($units) {
127
- case 'g':
128
- return $number.' GB';
129
- case 'm':
130
- return $number.' MB';
131
- case 'k':
132
- return $number.' KB';
133
- case 'b':
134
- default:
135
- return $number.' B';
136
- }
137
- }
138
-
139
-
140
- function mwp_format_bytes($bytes)
141
- {
142
- $bytes = (int) $bytes;
143
-
144
- if ($bytes > 1024 * 1024 * 1024) {
145
- return round($bytes / 1024 / 1024 / 1024, 2).' GB';
146
- } elseif ($bytes > 1024 * 1024) {
147
- return round($bytes / 1024 / 1024, 2).' MB';
148
- } elseif ($bytes > 1024) {
149
- return round($bytes / 1024, 2).' KB';
150
- }
151
-
152
- return $bytes.' B';
153
- }
154
-
155
- function mwp_log_warnings()
156
- {
157
- // If mbstring.func_overload is set, it changes the behavior of the standard string functions in
158
- // ways that makes external libraries like Dropbox break.
159
- $mbstring_func_overload = ini_get("mbstring.func_overload");
160
- if ($mbstring_func_overload & 2 == 2) {
161
- mwp_logger()->warning('"mbstring.func_overload" changes the behavior of the standard string functions in ways that makes external libraries like Dropbox break');
162
- }
163
-
164
- if (strlen((string) PHP_INT_MAX) < 19) {
165
- // Looks like we're running on a 32-bit build of PHP. This could cause problems because some of the numbers
166
- // we use (file sizes, quota, etc) can be larger than 32-bit ints can handle.
167
- 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).").");
168
- }
169
- }
170
-
171
- function search_posts_by_term($params = false)
172
- {
173
-
174
- global $wpdb, $current_user;
175
-
176
- $search_type = trim($params['search_type']);
177
- $search_term = strtolower(trim($params['search_term']));
178
- switch ($search_type) {
179
- case 'page_post':
180
- $num_posts = 10;
181
- $num_content_char = 30;
182
-
183
- $term_orig = trim($params['search_term']);
184
-
185
- $term_base = addslashes(trim($params['search_term']));
186
-
187
- $query = "SELECT *
188
- FROM $wpdb->posts
189
- WHERE $wpdb->posts.post_status = 'publish'
190
- AND ($wpdb->posts.post_title LIKE '%$term_base%'
191
- OR $wpdb->posts.post_content LIKE '%$term_base%')
192
- ORDER BY $wpdb->posts.post_modified DESC
193
- LIMIT 0, $num_posts
194
- ";
195
-
196
- $posts_array = $wpdb->get_results($query);
197
-
198
- $ret_posts = array();
199
-
200
- foreach ($posts_array as $post) {
201
- //highlight searched term
202
-
203
- if (substr_count(strtolower($post->post_title), strtolower($term_orig))) {
204
- $str_position_start = strpos(strtolower($post->post_title), strtolower($term_orig));
205
-
206
- $post->post_title = substr($post->post_title, 0, $str_position_start).'<b>'.
207
- substr($post->post_title, $str_position_start, strlen($term_orig)).'</b>'.
208
- substr($post->post_title, $str_position_start + strlen($term_orig));
209
-
210
- }
211
- $post->post_content = html_entity_decode($post->post_content);
212
-
213
- $post->post_content = strip_tags($post->post_content);
214
-
215
-
216
- if (substr_count(strtolower($post->post_content), strtolower($term_orig))) {
217
- $str_position_start = strpos(strtolower($post->post_content), strtolower($term_orig));
218
-
219
- $start = $str_position_start > $num_content_char ? $str_position_start - $num_content_char : 0;
220
- $first_len = $str_position_start > $num_content_char ? $num_content_char : $str_position_start;
221
-
222
- $start_substring = $start > 0 ? '...' : '';
223
- $post->post_content = $start_substring.substr($post->post_content, $start, $first_len).'<b>'.
224
- substr($post->post_content, $str_position_start, strlen($term_orig)).'</b>'.
225
- substr($post->post_content, $str_position_start + strlen($term_orig), $num_content_char).'...';
226
-
227
-
228
- } else {
229
- $post->post_content = substr($post->post_content, 0, 50).'...';
230
- }
231
-
232
- $ret_posts[] = array(
233
- 'ID' => $post->ID,
234
- 'post_permalink' => get_permalink($post->ID),
235
- 'post_date' => $post->post_date,
236
- 'post_title' => $post->post_title,
237
- 'post_content' => $post->post_content,
238
- 'post_modified' => $post->post_modified,
239
- 'comment_count' => $post->comment_count,
240
- );
241
- }
242
- mmb_response($ret_posts, true);
243
- break;
244
-
245
- case 'plugin':
246
- $plugins = get_option('active_plugins');
247
-
248
- if (!function_exists('get_plugin_data')) {
249
- include_once(ABSPATH.'/wp-admin/includes/plugin.php');
250
- }
251
-
252
- $have_plugin = array();
253
- foreach ($plugins as $plugin) {
254
- $pl = WP_PLUGIN_DIR.'/'.$plugin;
255
- $pl_extended = get_plugin_data($pl);
256
- $pl_name = $pl_extended['Name'];
257
- if (strpos(strtolower($pl_name), $search_term) > -1) {
258
-
259
- $have_plugin[] = $pl_name;
260
- }
261
- }
262
- if ($have_plugin) {
263
- mmb_response($have_plugin, true);
264
- } else {
265
- mmb_response('Not found', false);
266
- }
267
- break;
268
- case 'theme':
269
- $theme = strtolower(get_option('stylesheet'));
270
- $tm = ABSPATH.'wp-content/themes/'.$theme.'/style.css';
271
- $tm_extended = get_theme_data($tm);
272
- $tm_name = $tm_extended['Name'];
273
- $have_theme = array();
274
- if (strpos(strtolower($tm_name), $search_term) > -1) {
275
- $have_theme[] = $tm_name;
276
- mmb_response($have_theme, true);
277
- } else {
278
- mmb_response('Not found', false);
279
- }
280
- break;
281
- default:
282
- mmb_response('Not found', false);
283
- }
284
- }
285
-
286
- function mmb_add_action($action = false, $callback = false)
287
- {
288
- if (!$action || !$callback) {
289
- return;
290
- }
291
-
292
- global $mmb_actions;
293
-
294
- if (!is_callable($callback)) {
295
- wp_die('The provided argument is not a valid callback');
296
- }
297
-
298
- if (isset($mmb_actions[$action])) {
299
- wp_die('Cannot redeclare ManageWP action "'.$action.'".');
300
- }
301
-
302
- $mmb_actions[$action] = $callback;
303
- }
304
-
305
- function mmb_get_extended_info($stats)
306
- {
307
- $params = get_option('mmb_stats_filter');
308
- $filter = isset($params['plugins']['cleanup']) ? $params['plugins']['cleanup'] : array();
309
- $stats['num_revisions'] = mmb_num_revisions($filter['revisions']);
310
- //$stats['num_revisions'] = 5;
311
- $stats['overhead'] = mmb_handle_overhead(false);
312
- $stats['num_spam_comments'] = mmb_num_spam_comments();
313
-
314
- return $stats;
315
- }
316
-
317
- /* Revisions */
318
- function cleanup_delete_worker($params = array())
319
- {
320
- $revision_params = get_option('mmb_stats_filter');
321
- $revision_filter = isset($revision_params['plugins']['cleanup']) ? $revision_params['plugins']['cleanup'] : array();
322
-
323
- $params_array = explode('_', $params['actions']);
324
- $return_array = array();
325
-
326
- foreach ($params_array as $param) {
327
- switch ($param) {
328
- case 'revision':
329
- if (mmb_delete_all_revisions($revision_filter['revisions'])) {
330
- $return_array['revision'] = 'OK';
331
- } else {
332
- $return_array['revision_error'] = 'OK, nothing to do';
333
- }
334
- break;
335
- case 'overhead':
336
- if (mmb_handle_overhead(true)) {
337
- $return_array['overhead'] = 'OK';
338
- } else {
339
- $return_array['overhead_error'] = 'OK, nothing to do';
340
- }
341
- break;
342
- case 'comment':
343
- if (mmb_delete_spam_comments()) {
344
- $return_array['comment'] = 'OK';
345
- } else {
346
- $return_array['comment_error'] = 'OK, nothing to do';
347
- }
348
- break;
349
- default:
350
- break;
351
- }
352
-
353
- }
354
-
355
- unset($params);
356
-
357
- mmb_response($return_array, true);
358
- }
359
-
360
- function mmb_num_revisions($filter)
361
- {
362
- global $wpdb;
363
-
364
- $allRevisions = $wpdb->get_results("SELECT ID, post_name FROM {$wpdb->posts} WHERE post_type = 'revision'", ARRAY_A);
365
-
366
- $revisionsToDelete = 0;
367
- $revisionsToKeepCount = array();
368
-
369
- if (isset($filter['num_to_keep']) && !empty($filter['num_to_keep'])) {
370
- $num_rev = str_replace("r_", "", $filter['num_to_keep']);
371
-
372
- foreach ($allRevisions as $revision) {
373
- $revisionsToKeepCount[$revision['post_name']] = isset($revisionsToKeepCount[$revision['post_name']])
374
- ? $revisionsToKeepCount[$revision['post_name']] + 1
375
- : 1;
376
-
377
- if ($revisionsToKeepCount[$revision['post_name']] > $num_rev) {
378
- ++$revisionsToDelete;
379
- }
380
- }
381
- } else {
382
- $revisionsToDelete = count($allRevisions);
383
- }
384
-
385
- return $revisionsToDelete;
386
- }
387
-
388
- function mmb_select_all_revisions()
389
- {
390
- global $wpdb;
391
- $sql = "SELECT * FROM $wpdb->posts WHERE post_type = 'revision'";
392
- $revisions = $wpdb->get_results($sql);
393
-
394
- return $revisions;
395
- }
396
-
397
- function mmb_delete_all_revisions($filter)
398
- {
399
- global $wpdb;
400
- $where = '';
401
- $keep = isset($filter['num_to_keep']) ? $filter['num_to_keep'] : false;
402
- if ($keep) {
403
- $num_rev = str_replace("r_", "", $keep);
404
- $allRevisions = $wpdb->get_results("SELECT ID, post_name FROM {$wpdb->posts} WHERE post_type = 'revision' ORDER BY post_date DESC", ARRAY_A);
405
- $revisionsToKeep = array(0 => 0);
406
- $revisionsToKeepCount = array();
407
-
408
- foreach ($allRevisions as $revision) {
409
- $revisionsToKeepCount[$revision['post_name']] = isset($revisionsToKeepCount[$revision['post_name']])
410
- ? $revisionsToKeepCount[$revision['post_name']] + 1
411
- : 1;
412
-
413
- if ($revisionsToKeepCount[$revision['post_name']] <= $num_rev) {
414
- $revisionsToKeep[] = $revision['ID'];
415
- }
416
- }
417
-
418
- $notInQuery = join(', ', $revisionsToKeep);
419
-
420
- $where = "AND a.ID NOT IN ({$notInQuery})";
421
- }
422
-
423
- $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}";
424
-
425
- $revisions = $wpdb->query($sql);
426
-
427
- return $revisions;
428
- }
429
-
430
- function mmb_handle_overhead($clear = false)
431
- {
432
- /** @var wpdb $wpdb */
433
- global $wpdb;
434
- $query = 'SHOW TABLE STATUS';
435
- $tables = $wpdb->get_results($query, ARRAY_A);
436
- $total_gain = 0;
437
- $table_string = '';
438
- foreach ($tables as $table) {
439
- if (isset($table['Engine']) && $table['Engine'] === 'MyISAM') {
440
- if ($wpdb->base_prefix != $wpdb->prefix) {
441
- if (preg_match('/^'.$wpdb->prefix.'*/Ui', $table['Name'])) {
442
- if ($table['Data_free'] > 0) {
443
- $total_gain += $table['Data_free'] / 1024;
444
- $table_string .= $table['Name'].",";
445
- }
446
- }
447
- } else {
448
- if (preg_match('/^'.$wpdb->prefix.'[0-9]{1,20}_*/Ui', $table['Name'])) {
449
- continue;
450
- } else {
451
- if ($table['Data_free'] > 0) {
452
- $total_gain += $table['Data_free'] / 1024;
453
- $table_string .= $table['Name'].",";
454
- }
455
- }
456
- }
457
- // @todo check if the cleanup was successful, if not, set a flag always skip innodb cleanup
458
- //} elseif (isset($table['Engine']) && $table['Engine'] == 'InnoDB') {
459
- // $innodb_file_per_table = $wpdb->get_results("SHOW VARIABLES LIKE 'innodb_file_per_table'");
460
- // if (isset($innodb_file_per_table[0]->Value) && $innodb_file_per_table[0]->Value === "ON") {
461
- // if ($table['Data_free'] > 0) {
462
- // $total_gain += $table['Data_free'] / 1024;
463
- // $table_string .= $table['Name'].",";
464
- // }
465
- // }
466
- }
467
- }
468
-
469
- if ($clear) {
470
- $table_string = substr($table_string, 0, strlen($table_string) - 1); //remove last ,
471
- $table_string = rtrim($table_string);
472
- $query = "OPTIMIZE TABLE $table_string";
473
- $optimize = $wpdb->query($query);
474
-
475
- return (bool)$optimize;
476
- } else {
477
- return round($total_gain, 3);
478
- }
479
- }
480
-
481
-
482
- /* Spam Comments */
483
- function mmb_num_spam_comments()
484
- {
485
- global $wpdb;
486
- $sql = "SELECT COUNT(*) FROM $wpdb->comments WHERE comment_approved = 'spam'";
487
- $num_spams = $wpdb->get_var($sql);
488
-
489
- return $num_spams;
490
- }
491
-
492
- function mmb_delete_spam_comments()
493
- {
494
- global $wpdb;
495
- $spam = 1;
496
- $total = 0;
497
- while (!empty($spam)) {
498
- $getCommentIds = "SELECT comment_ID FROM $wpdb->comments WHERE comment_approved = 'spam' LIMIT 200";
499
- $spam = $wpdb->get_results($getCommentIds);
500
- foreach ($spam as $comment) {
501
- wp_delete_comment($comment->comment_ID, true);
502
- }
503
- $total += count($spam);
504
- if (!empty($spam)) {
505
- usleep(100000);
506
- }
507
- }
508
-
509
- return $total;
510
- }
511
-
512
- function mmb_get_spam_comments()
513
- {
514
- global $wpdb;
515
- $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'";
516
- $spams = $wpdb->get_results($sql);
517
-
518
- return $spams;
519
- }
520
-
521
- function mwp_is_nio_shell_available()
522
- {
523
- static $check;
524
- if(isset($check)){
525
- return $check;
526
- }
527
- try {
528
- $process = new Symfony_Process_Process("cd .", dirname(__FILE__), array(), null, 1);
529
- $process->run();
530
- $check = $process->isSuccessful();
531
- } catch (Exception $e) {
532
- $check = false;
533
- }
534
- return $check;
535
- }
536
-
537
- function mwp_is_shell_available()
538
- {
539
- if (mwp_is_safe_mode()) {
540
- return false;
541
- }
542
- if (!function_exists('proc_open') || !function_exists('escapeshellarg')) {
543
- return false;
544
- }
545
-
546
- if (extension_loaded('suhosin') && $suhosin = ini_get('suhosin.executor.func.blacklist')) {
547
- $suhosin = explode(',', $suhosin);
548
- $blacklist = array_map('trim', $suhosin);
549
- $blacklist = array_map('strtolower', $blacklist);
550
- if (in_array('proc_open', $blacklist)) {
551
- return false;
552
- }
553
- }
554
-
555
- if (!mwp_is_nio_shell_available()) {
556
- return false;
557
- }
558
-
559
- return true;
560
- }
561
-
562
- function mwp_is_safe_mode()
563
- {
564
- $value = ini_get("safe_mode");
565
- if ((int) $value === 0 || strtolower($value) === "off") {
566
- return false;
567
- }
568
-
569
- return true;
570
- }
 
 
 
 
 
 
1
+ <?php
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)) {
15
+ include_once $file;
16
+ }
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
+ function mwp_container()
48
+ {
49
+ static $container;
50
+
51
+ if ($container === null) {
52
+ $parameters = get_option('mwp_container_parameters', array());
53
+ $container = new MMB_Container($parameters);
54
+ }
55
+
56
+ return $container;
57
+ }
58
+
59
+ /**
60
+ * @return Monolog_Psr_LoggerInterface
61
+ */
62
+ function mwp_logger()
63
+ {
64
+ static $mwp_logger;
65
+ if (!get_option('mwp_debug_enable', false)) {
66
+ if ($mwp_logger === null) {
67
+ $mwp_logger = new Monolog_Logger('worker', array(new Monolog_Handler_NullHandler()));
68
+ }
69
+
70
+ return $mwp_logger;
71
+ }
72
+ if ($mwp_logger instanceof Monolog_Logger) {
73
+ return $mwp_logger;
74
+ }
75
+ if ($mwp_logger === null) {
76
+ $mwp_logger = true;
77
+ $logger = mwp_container()->getLogger();
78
+ Monolog_Registry::addLogger($logger, 'worker');
79
+
80
+ $errorHandler = new Monolog_ErrorHandler($logger);
81
+ $errorHandler->registerErrorHandler();
82
+ $errorHandler->registerExceptionHandler();
83
+ $errorHandler->registerFatalHandler(null, 1024);
84
+ }
85
+
86
+ return Monolog_Registry::getInstance('worker');
87
+ }
88
+
89
+ /**
90
+ * @param $appKey
91
+ * @param $appSecret
92
+ * @param $token
93
+ * @param $tokenSecret
94
+ *
95
+ * @return Dropbox_Client
96
+ */
97
+ function mwp_dropbox_oauth_factory($appKey, $appSecret, $token, $tokenSecret = null)
98
+ {
99
+ if ($tokenSecret) {
100
+ $oauthToken = 'OAuth oauth_version="1.0", oauth_signature_method="PLAINTEXT", oauth_consumer_key="'.$appKey.'", oauth_token="'.$token.'", oauth_signature="'.$appSecret.'&'.$tokenSecret.'"';
101
+ $clientIdentifier = $token;
102
+ } else {
103
+ $oauthToken = 'Bearer '.$token;
104
+ $clientIdentifier = 'PHP-ManageWp/1.0';
105
+ }
106
+
107
+ return new Dropbox_Client($oauthToken, $clientIdentifier);
108
+ }
109
+
110
+ function mwp_format_memory_limit($limit)
111
+ {
112
+ if ((string) (int) $limit === (string) $limit) {
113
+ // The number is numeric.
114
+ return mwp_format_bytes($limit);
115
+ }
116
+
117
+ $units = strtolower(substr($limit, -1));
118
+
119
+ if (!in_array($units, array('b', 'k', 'm', 'g'))) {
120
+ // Invalid size unit.
121
+ return $limit;
122
+ }
123
+
124
+ $number = substr($limit, 0, -1);
125
+
126
+ if ((string) (int) $number !== $number) {
127
+ // The number isn't numeric.
128
+ return $number;
129
+ }
130
+
131
+ switch ($units) {
132
+ case 'g':
133
+ return $number.' GB';
134
+ case 'm':
135
+ return $number.' MB';
136
+ case 'k':
137
+ return $number.' KB';
138
+ case 'b':
139
+ default:
140
+ return $number.' B';
141
+ }
142
+ }
143
+
144
+
145
+ function mwp_format_bytes($bytes)
146
+ {
147
+ $bytes = (int) $bytes;
148
+
149
+ if ($bytes > 1024 * 1024 * 1024) {
150
+ return round($bytes / 1024 / 1024 / 1024, 2).' GB';
151
+ } elseif ($bytes > 1024 * 1024) {
152
+ return round($bytes / 1024 / 1024, 2).' MB';
153
+ } elseif ($bytes > 1024) {
154
+ return round($bytes / 1024, 2).' KB';
155
+ }
156
+
157
+ return $bytes.' B';
158
+ }
159
+
160
+ function mwp_log_warnings()
161
+ {
162
+ // If mbstring.func_overload is set, it changes the behavior of the standard string functions in
163
+ // ways that makes external libraries like Dropbox break.
164
+ $mbstring_func_overload = ini_get("mbstring.func_overload");
165
+ if ($mbstring_func_overload & 2 == 2) {
166
+ mwp_logger()->warning('"mbstring.func_overload" changes the behavior of the standard string functions in ways that makes external libraries like Dropbox break');
167
+ }
168
+
169
+ if (strlen((string) PHP_INT_MAX) < 19) {
170
+ // Looks like we're running on a 32-bit build of PHP. This could cause problems because some of the numbers
171
+ // we use (file sizes, quota, etc) can be larger than 32-bit ints can handle.
172
+ 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).").");
173
+ }
174
+ }
175
+
176
+ function search_posts_by_term($params = false)
177
+ {
178
+
179
+ global $wpdb, $current_user;
180
+
181
+ $search_type = trim($params['search_type']);
182
+ $search_term = strtolower(trim($params['search_term']));
183
+ switch ($search_type) {
184
+ case 'page_post':
185
+ $num_posts = 10;
186
+ $num_content_char = 30;
187
+
188
+ $term_orig = trim($params['search_term']);
189
+
190
+ $term_base = addslashes(trim($params['search_term']));
191
+
192
+ $query = "SELECT *
193
+ FROM $wpdb->posts
194
+ WHERE $wpdb->posts.post_status = 'publish'
195
+ AND ($wpdb->posts.post_title LIKE '%$term_base%'
196
+ OR $wpdb->posts.post_content LIKE '%$term_base%')
197
+ ORDER BY $wpdb->posts.post_modified DESC
198
+ LIMIT 0, $num_posts
199
+ ";
200
+
201
+ $posts_array = $wpdb->get_results($query);
202
+
203
+ $ret_posts = array();
204
+
205
+ foreach ($posts_array as $post) {
206
+ //highlight searched term
207
+
208
+ if (substr_count(strtolower($post->post_title), strtolower($term_orig))) {
209
+ $str_position_start = strpos(strtolower($post->post_title), strtolower($term_orig));
210
+
211
+ $post->post_title = substr($post->post_title, 0, $str_position_start).'<b>'.
212
+ substr($post->post_title, $str_position_start, strlen($term_orig)).'</b>'.
213
+ substr($post->post_title, $str_position_start + strlen($term_orig));
214
+
215
+ }
216
+ $post->post_content = html_entity_decode($post->post_content);
217
+
218
+ $post->post_content = strip_tags($post->post_content);
219
+
220
+
221
+ if (substr_count(strtolower($post->post_content), strtolower($term_orig))) {
222
+ $str_position_start = strpos(strtolower($post->post_content), strtolower($term_orig));
223
+
224
+ $start = $str_position_start > $num_content_char ? $str_position_start - $num_content_char : 0;
225
+ $first_len = $str_position_start > $num_content_char ? $num_content_char : $str_position_start;
226
+
227
+ $start_substring = $start > 0 ? '...' : '';
228
+ $post->post_content = $start_substring.substr($post->post_content, $start, $first_len).'<b>'.
229
+ substr($post->post_content, $str_position_start, strlen($term_orig)).'</b>'.
230
+ substr($post->post_content, $str_position_start + strlen($term_orig), $num_content_char).'...';
231
+
232
+
233
+ } else {
234
+ $post->post_content = substr($post->post_content, 0, 50).'...';
235
+ }
236
+
237
+ $ret_posts[] = array(
238
+ 'ID' => $post->ID,
239
+ 'post_permalink' => get_permalink($post->ID),
240
+ 'post_date' => $post->post_date,
241
+ 'post_title' => $post->post_title,
242
+ 'post_content' => $post->post_content,
243
+ 'post_modified' => $post->post_modified,
244
+ 'comment_count' => $post->comment_count,
245
+ );
246
+ }
247
+ mmb_response($ret_posts, true);
248
+ break;
249
+
250
+ case 'plugin':
251
+ $plugins = get_option('active_plugins');
252
+
253
+ if (!function_exists('get_plugin_data')) {
254
+ include_once(ABSPATH.'/wp-admin/includes/plugin.php');
255
+ }
256
+
257
+ $have_plugin = array();
258
+ foreach ($plugins as $plugin) {
259
+ $pl = WP_PLUGIN_DIR.'/'.$plugin;
260
+ $pl_extended = get_plugin_data($pl);
261
+ $pl_name = $pl_extended['Name'];
262
+ if (strpos(strtolower($pl_name), $search_term) > -1) {
263
+
264
+ $have_plugin[] = $pl_name;
265
+ }
266
+ }
267
+ if ($have_plugin) {
268
+ mmb_response($have_plugin, true);
269
+ } else {
270
+ mmb_response('Not found', false);
271
+ }
272
+ break;
273
+ case 'theme':
274
+ $theme = strtolower(get_option('stylesheet'));
275
+ $tm = ABSPATH.'wp-content/themes/'.$theme.'/style.css';
276
+ $tm_extended = get_theme_data($tm);
277
+ $tm_name = $tm_extended['Name'];
278
+ $have_theme = array();
279
+ if (strpos(strtolower($tm_name), $search_term) > -1) {
280
+ $have_theme[] = $tm_name;
281
+ mmb_response($have_theme, true);
282
+ } else {
283
+ mmb_response('Not found', false);
284
+ }
285
+ break;
286
+ default:
287
+ mmb_response('Not found', false);
288
+ }
289
+ }
290
+
291
+ function mmb_add_action($action = false, $callback = false)
292
+ {
293
+ if (!$action || !$callback) {
294
+ return;
295
+ }
296
+
297
+ global $mmb_actions;
298
+
299
+ if (!is_callable($callback)) {
300
+ wp_die('The provided argument is not a valid callback');
301
+ }
302
+
303
+ if (isset($mmb_actions[$action])) {
304
+ wp_die('Cannot redeclare ManageWP action "'.$action.'".');
305
+ }
306
+
307
+ $mmb_actions[$action] = $callback;
308
+ }
309
+
310
+ function mmb_get_extended_info($stats)
311
+ {
312
+ $params = get_option('mmb_stats_filter');
313
+ $filter = isset($params['plugins']['cleanup']) ? $params['plugins']['cleanup'] : array();
314
+ $stats['num_revisions'] = mmb_num_revisions($filter['revisions']);
315
+ //$stats['num_revisions'] = 5;
316
+ $stats['overhead'] = mmb_handle_overhead(false);
317
+ $stats['num_spam_comments'] = mmb_num_spam_comments();
318
+
319
+ return $stats;
320
+ }
321
+
322
+ /* Revisions */
323
+ function cleanup_delete_worker($params = array())
324
+ {
325
+ $revision_params = get_option('mmb_stats_filter');
326
+ $revision_filter = isset($revision_params['plugins']['cleanup']) ? $revision_params['plugins']['cleanup'] : array();
327
+
328
+ $params_array = explode('_', $params['actions']);
329
+ $return_array = array();
330
+
331
+ foreach ($params_array as $param) {
332
+ switch ($param) {
333
+ case 'revision':
334
+ if (mmb_delete_all_revisions($revision_filter['revisions'])) {
335
+ $return_array['revision'] = 'OK';
336
+ } else {
337
+ $return_array['revision_error'] = 'OK, nothing to do';
338
+ }
339
+ break;
340
+ case 'overhead':
341
+ if (mmb_handle_overhead(true)) {
342
+ $return_array['overhead'] = 'OK';
343
+ } else {
344
+ $return_array['overhead_error'] = 'OK, nothing to do';
345
+ }
346
+ break;
347
+ case 'comment':
348
+ if (mmb_delete_spam_comments()) {
349
+ $return_array['comment'] = 'OK';
350
+ } else {
351
+ $return_array['comment_error'] = 'OK, nothing to do';
352
+ }
353
+ break;
354
+ default:
355
+ break;
356
+ }
357
+
358
+ }
359
+
360
+ unset($params);
361
+
362
+ mmb_response($return_array, true);
363
+ }
364
+
365
+ function mmb_num_revisions($filter)
366
+ {
367
+ global $wpdb;
368
+
369
+ $allRevisions = $wpdb->get_results("SELECT ID, post_name FROM {$wpdb->posts} WHERE post_type = 'revision'", ARRAY_A);
370
+
371
+ $revisionsToDelete = 0;
372
+ $revisionsToKeepCount = array();
373
+
374
+ if (isset($filter['num_to_keep']) && !empty($filter['num_to_keep'])) {
375
+ $num_rev = str_replace("r_", "", $filter['num_to_keep']);
376
+
377
+ foreach ($allRevisions as $revision) {
378
+ $revisionsToKeepCount[$revision['post_name']] = isset($revisionsToKeepCount[$revision['post_name']])
379
+ ? $revisionsToKeepCount[$revision['post_name']] + 1
380
+ : 1;
381
+
382
+ if ($revisionsToKeepCount[$revision['post_name']] > $num_rev) {
383
+ ++$revisionsToDelete;
384
+ }
385
+ }
386
+ } else {
387
+ $revisionsToDelete = count($allRevisions);
388
+ }
389
+
390
+ return $revisionsToDelete;
391
+ }
392
+
393
+ function mmb_select_all_revisions()
394
+ {
395
+ global $wpdb;
396
+ $sql = "SELECT * FROM $wpdb->posts WHERE post_type = 'revision'";
397
+ $revisions = $wpdb->get_results($sql);
398
+
399
+ return $revisions;
400
+ }
401
+
402
+ function mmb_delete_all_revisions($filter)
403
+ {
404
+ global $wpdb;
405
+ $where = '';
406
+ $keep = isset($filter['num_to_keep']) ? $filter['num_to_keep'] : false;
407
+ if ($keep) {
408
+ $num_rev = str_replace("r_", "", $keep);
409
+ $allRevisions = $wpdb->get_results("SELECT ID, post_name FROM {$wpdb->posts} WHERE post_type = 'revision' ORDER BY post_date DESC", ARRAY_A);
410
+ $revisionsToKeep = array(0 => 0);
411
+ $revisionsToKeepCount = array();
412
+
413
+ foreach ($allRevisions as $revision) {
414
+ $revisionsToKeepCount[$revision['post_name']] = isset($revisionsToKeepCount[$revision['post_name']])
415
+ ? $revisionsToKeepCount[$revision['post_name']] + 1
416
+ : 1;
417
+
418
+ if ($revisionsToKeepCount[$revision['post_name']] <= $num_rev) {
419
+ $revisionsToKeep[] = $revision['ID'];
420
+ }
421
+ }
422
+
423
+ $notInQuery = join(', ', $revisionsToKeep);
424
+
425
+ $where = "AND a.ID NOT IN ({$notInQuery})";
426
+ }
427
+
428
+ $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}";
429
+
430
+ $revisions = $wpdb->query($sql);
431
+
432
+ return $revisions;
433
+ }
434
+
435
+ function mmb_handle_overhead($clear = false)
436
+ {
437
+ /** @var wpdb $wpdb */
438
+ global $wpdb;
439
+ $query = 'SHOW TABLE STATUS';
440
+ $tables = $wpdb->get_results($query, ARRAY_A);
441
+ $total_gain = 0;
442
+ $table_string = '';
443
+ foreach ($tables as $table) {
444
+ if (isset($table['Engine']) && $table['Engine'] === 'MyISAM') {
445
+ if ($wpdb->base_prefix != $wpdb->prefix) {
446
+ if (preg_match('/^'.$wpdb->prefix.'*/Ui', $table['Name'])) {
447
+ if ($table['Data_free'] > 0) {
448
+ $total_gain += $table['Data_free'] / 1024;
449
+ $table_string .= $table['Name'].",";
450
+ }
451
+ }
452
+ } else {
453
+ if (preg_match('/^'.$wpdb->prefix.'[0-9]{1,20}_*/Ui', $table['Name'])) {
454
+ continue;
455
+ } else {
456
+ if ($table['Data_free'] > 0) {
457
+ $total_gain += $table['Data_free'] / 1024;
458
+ $table_string .= $table['Name'].",";
459
+ }
460
+ }
461
+ }
462
+ // @todo check if the cleanup was successful, if not, set a flag always skip innodb cleanup
463
+ //} elseif (isset($table['Engine']) && $table['Engine'] == 'InnoDB') {
464
+ // $innodb_file_per_table = $wpdb->get_results("SHOW VARIABLES LIKE 'innodb_file_per_table'");
465
+ // if (isset($innodb_file_per_table[0]->Value) && $innodb_file_per_table[0]->Value === "ON") {
466
+ // if ($table['Data_free'] > 0) {
467
+ // $total_gain += $table['Data_free'] / 1024;
468
+ // $table_string .= $table['Name'].",";
469
+ // }
470
+ // }
471
+ }
472
+ }
473
+
474
+ if ($clear) {
475
+ $table_string = substr($table_string, 0, strlen($table_string) - 1); //remove last ,
476
+ $table_string = rtrim($table_string);
477
+ $query = "OPTIMIZE TABLE $table_string";
478
+ $optimize = $wpdb->query($query);
479
+
480
+ return (bool) $optimize;
481
+ } else {
482
+ return round($total_gain, 3);
483
+ }
484
+ }
485
+
486
+
487
+ /* Spam Comments */
488
+ function mmb_num_spam_comments()
489
+ {
490
+ global $wpdb;
491
+ $sql = "SELECT COUNT(*) FROM $wpdb->comments WHERE comment_approved = 'spam'";
492
+ $num_spams = $wpdb->get_var($sql);
493
+
494
+ return $num_spams;
495
+ }
496
+
497
+ function mmb_delete_spam_comments()
498
+ {
499
+ global $wpdb;
500
+ $spam = 1;
501
+ $total = 0;
502
+ while (!empty($spam)) {
503
+ $getCommentIds = "SELECT comment_ID FROM $wpdb->comments WHERE comment_approved = 'spam' LIMIT 200";
504
+ $spam = $wpdb->get_results($getCommentIds);
505
+ foreach ($spam as $comment) {
506
+ wp_delete_comment($comment->comment_ID, true);
507
+ }
508
+ $total += count($spam);
509
+ if (!empty($spam)) {
510
+ usleep(100000);
511
+ }
512
+ }
513
+
514
+ return $total;
515
+ }
516
+
517
+ function mmb_get_spam_comments()
518
+ {
519
+ global $wpdb;
520
+ $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'";
521
+ $spams = $wpdb->get_results($sql);
522
+
523
+ return $spams;
524
+ }
525
+
526
+ function mwp_is_nio_shell_available()
527
+ {
528
+ static $check;
529
+ if (isset($check)) {
530
+ return $check;
531
+ }
532
+ try {
533
+ $process = new Symfony_Process_Process("cd .", dirname(__FILE__), array(), null, 1);
534
+ $process->run();
535
+ $check = $process->isSuccessful();
536
+ } catch (Exception $e) {
537
+ $check = false;
538
+ }
539
+
540
+ return $check;
541
+ }
542
+
543
+ function mwp_is_shell_available()
544
+ {
545
+ if (mwp_is_safe_mode()) {
546
+ return false;
547
+ }
548
+ if (!function_exists('proc_open') || !function_exists('escapeshellarg')) {
549
+ return false;
550
+ }
551
+
552
+ if (extension_loaded('suhosin') && $suhosin = ini_get('suhosin.executor.func.blacklist')) {
553
+ $suhosin = explode(',', $suhosin);
554
+ $blacklist = array_map('trim', $suhosin);
555
+ $blacklist = array_map('strtolower', $blacklist);
556
+ if (in_array('proc_open', $blacklist)) {
557
+ return false;
558
+ }
559
+ }
560
+
561
+ if (!mwp_is_nio_shell_available()) {
562
+ return false;
563
+ }
564
+
565
+ return true;
566
+ }
567
+
568
+ function mwp_is_safe_mode()
569
+ {
570
+ $value = ini_get("safe_mode");
571
+ if ((int) $value === 0 || strtolower($value) === "off") {
572
+ return false;
573
+ }
574
+
575
+ return true;
576
+ }
init.php CHANGED
@@ -1,2043 +1,2071 @@
1
- <?php
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: 3.9.29
7
- Author: ManageWP
8
- Author URI: https://managewp.com
9
- License: GPL2
10
- */
11
-
12
- /*************************************************************
13
- * init.php
14
- * Initialize the communication with master
15
- * Copyright (c) 2011 Prelovac Media
16
- * www.prelovac.com
17
- **************************************************************/
18
- if (!defined('ABSPATH')) {
19
- exit;
20
- }
21
-
22
- if (!defined('MMB_WORKER_VERSION')) {
23
- define('MMB_WORKER_VERSION', '3.9.29');
24
- }
25
-
26
- $GLOBALS['MMB_WORKER_VERSION'] = '3.9.29';
27
- $GLOBALS['MMB_WORKER_REVISION'] = '2014-08-27 00:00:00';
28
-
29
- /**
30
- * Reserved memory for fatal error handling execution context.
31
- */
32
- $GLOBALS['mwp_reserved_memory'] = str_repeat(' ', 1024 * 20);
33
- /**
34
- * If we ever get only partially upgraded due to a server error or misconfiguration,
35
- * attempt to disable the plugin and notify the site's administrator via email.
36
- */
37
- function mwp_fail_safe()
38
- {
39
- $GLOBALS['mwp_reserved_memory'] = null;
40
-
41
- $lastError = error_get_last();
42
-
43
- if (!$lastError || $lastError['type'] !== E_ERROR) {
44
- return;
45
- }
46
-
47
- $activePlugins = get_option('active_plugins');
48
- $workerIndex = array_search(plugin_basename(__FILE__), $activePlugins);
49
- if ($workerIndex === false) {
50
- // Plugin is not yet enabled, possibly in activation context.
51
- return;
52
- }
53
-
54
- $errorSource = realpath($lastError['file']);
55
- // We might be in eval() context.
56
- if (!$errorSource) {
57
- return;
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
-
65
- // Only look for files that belong to this plugin.
66
- $pluginBase = realpath(dirname(__FILE__));
67
- if (strpos($errorSource, $pluginBase) !== 0) {
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
- $reason = "You received this e-mail because you are listed as the site's administrator.";
81
- $to = get_option('admin_email');
82
- $brand = get_option('mwp_worker_brand');
83
- if (!empty($brand['admin_email'])) {
84
- $to = $brand['admin_email'];
85
- $reason = "You received this e-mail because you are listed as the site's manager.";
86
- }
87
- $body = sprintf("Due to an unsuccessful (possibly automatic) update, the ManageWP Worker plugin has deactivated itself on your site %s.
88
-
89
- This was done as a precaution to prevent any problems to your site. %s
90
-
91
- We apologize for the inconvenience. Please reinstall the plugin manually and re-add the website to your ManageWP dashboard.", $siteUrl, $reason);
92
- $mailFn($to.',support@managewp.com', $title, $body);
93
-
94
- // If we're inside a cron scope, don't attempt to hide this error.
95
- if (defined('DOING_CRON') && DOING_CRON) {
96
- return;
97
- }
98
-
99
- // If we're inside a normal request scope, we apologize. Retry the request so user doesn't have to see an ugly error page.
100
- if (!empty($_SERVER['REQUEST_URI'])) {
101
- $siteUrl .= $_SERVER['REQUEST_URI'];
102
- }
103
- if (headers_sent()) {
104
- // The headers are probably sent if the PHP configuration has the 'display_errors' directive enabled. In that case try a meta redirect.
105
- echo sprintf('<meta http-equiv="refresh" content="0; url=%s">', htmlspecialchars($siteUrl, ENT_QUOTES));
106
- } else {
107
- header('Location: '.htmlspecialchars($siteUrl, ENT_QUOTES));
108
- }
109
- exit;
110
- }
111
-
112
- register_shutdown_function('mwp_fail_safe');
113
-
114
- require_once dirname(__FILE__).'/functions.php';
115
-
116
- if (!defined('MMB_XFRAME_COOKIE')) {
117
- $siteurl = function_exists('get_site_option') ? get_site_option('siteurl') : get_option('siteurl');
118
- define('MMB_XFRAME_COOKIE', $xframe = 'wordpress_'.md5($siteurl).'_xframe');
119
- }
120
-
121
- global $wpdb, $mmb_plugin_dir, $mmb_plugin_url, $wp_version, $mmb_filters, $_mmb_item_filter;
122
- if (version_compare(PHP_VERSION, '5.2.0', '<')) // min version 5 supported
123
- {
124
- exit("<p>ManageWP Worker plugin requires PHP 5.2 or higher.</p>");
125
- }
126
-
127
- if (version_compare(PHP_VERSION, '5.3', '<')) {
128
- spl_autoload_register('mwp_autoload');
129
- } else {
130
- // The prepend parameter was added in PHP 5.3.0
131
- spl_autoload_register('mwp_autoload', true, true);
132
- }
133
-
134
- // Will register the logger as the error handler.
135
- mwp_logger();
136
-
137
- $mmb_wp_version = $wp_version;
138
- $mmb_plugin_dir = WP_PLUGIN_DIR.'/'.basename(dirname(__FILE__));
139
- $mmb_plugin_url = WP_PLUGIN_URL.'/'.basename(dirname(__FILE__));
140
-
141
- define('MWP_SHOW_LOG', false);
142
- // <stats.class.php>
143
- add_filter('mwp_website_add', 'MMB_Stats::readd_alerts');
144
- // <backup.class.php>
145
- define('MWP_BACKUP_DIR', WP_CONTENT_DIR.'/managewp/backups');
146
- define('MWP_DB_DIR', MWP_BACKUP_DIR.'/mwp_db');
147
-
148
- mmb_add_action('search_posts_by_term', 'search_posts_by_term');
149
- add_filter('mmb_stats_filter', 'mmb_get_extended_info');
150
- mmb_add_action('cleanup_delete', 'cleanup_delete_worker');
151
-
152
- // <widget.class.php>
153
- $mwp_worker_brand = get_option("mwp_worker_brand");
154
- $worker_brand = 0;
155
- if (is_array($mwp_worker_brand)) {
156
- if ($mwp_worker_brand['name'] || $mwp_worker_brand['desc'] || $mwp_worker_brand['author'] || $mwp_worker_brand['author_url']) {
157
- $worker_brand = 1;
158
- }
159
- }
160
- if (!$worker_brand) {
161
- add_action('widgets_init', create_function('', 'return register_widget("MMB_Widget");'));
162
- }
163
-
164
- if (!function_exists('mmb_parse_data')) {
165
- function mmb_parse_data($data = array())
166
- {
167
- if (empty($data)) {
168
- return $data;
169
- }
170
-
171
- $data = (array) $data;
172
- if (isset($data['params'])) {
173
- $data['params'] = mmb_filter_params($data['params']);
174
- }
175
-
176
- $postkeys = array('action', 'params', 'id', 'signature', 'setting', 'add_site_signature_id', 'add_site_signature');
177
-
178
- if (!empty($data)) {
179
- foreach ($data as $key => $items) {
180
- if (!in_array($key, $postkeys)) {
181
- unset($data[$key]);
182
- }
183
- }
184
- }
185
-
186
- return $data;
187
- }
188
- }
189
-
190
- if (!function_exists('mmb_filter_params')) {
191
- function mmb_filter_params($array = array())
192
- {
193
-
194
- $filter = array('current_user', 'wpdb');
195
- $return = array();
196
- foreach ($array as $key => $val) {
197
- if (!is_int($key) && in_array($key, $filter)) {
198
- continue;
199
- }
200
-
201
- if (is_array($val)) {
202
- $return[$key] = mmb_filter_params($val);
203
- } else {
204
- $return[$key] = $val;
205
- }
206
- }
207
-
208
- return $return;
209
- }
210
- }
211
- if (!function_exists('mmb_authenticate')) {
212
- function mmb_authenticate()
213
- {
214
- global $_mwp_data, $_mwp_auth, $mmb_core, $HTTP_RAW_POST_DATA;
215
- if (!isset($HTTP_RAW_POST_DATA)) {
216
- $HTTP_RAW_POST_DATA = file_get_contents('php://input');
217
- }
218
- $compat = false;
219
- $compatActive = false;
220
- $contentType = empty($_SERVER['CONTENT_TYPE']) ? false : $_SERVER['CONTENT_TYPE'];
221
-
222
- if ($compat && empty($_SERVER['HTTP_MWP_ACTION']) && $contentType === 'application/json') {
223
- $compatActive = true;
224
- }
225
-
226
- if (empty($_SERVER['HTTP_MWP_ACTION']) && !$compatActive) {
227
- return;
228
- }
229
- $_mwp_data = json_decode($HTTP_RAW_POST_DATA, true);
230
-
231
- if (!$_mwp_data) {
232
- return;
233
- }
234
- $_mwp_data = mmb_parse_data($_mwp_data);
235
-
236
- if ($compatActive) {
237
- if (empty($_mwp_data['action'])) {
238
- return;
239
- }
240
- $_mwp_data['signature'] = base64_decode($_mwp_data['signature']);
241
- } else {
242
- $_mwp_data['action'] = $_SERVER['HTTP_MWP_ACTION'];
243
- $_mwp_data['id'] = isset($_SERVER['HTTP_MWP_MESSAGE_ID']) ? $_SERVER['HTTP_MWP_MESSAGE_ID'] : "";
244
- $_mwp_data['signature'] = isset($_SERVER['HTTP_MWP_SIGNATURE']) ? base64_decode($_SERVER['HTTP_MWP_SIGNATURE']) : '';
245
- }
246
-
247
- $usernameUsed = array_key_exists('username', $_mwp_data['params']) ? $_mwp_data['params']['username'] : null;
248
- if (empty($_mwp_data['params']['username']) || !$mmb_core->check_if_user_exists($_mwp_data['params']['username'])) {
249
- $filter = array(
250
- 'user_roles' => array(
251
- 'administrator'
252
- ),
253
- 'username'=>'',
254
- 'username_filter'=>'',
255
- );
256
- $users = $mmb_core->get_user_instance()->get_users($filter);
257
-
258
- if (empty($users['users'])) {
259
- mmb_response('We could not find an administrator user to use. Please contact support.', false);
260
- }
261
-
262
- $_mwp_data['params']['username'] = $users['users'][0]['user_login'];
263
- }
264
-
265
- if (isset($_mwp_data['params']['username']) && !is_user_logged_in()) {
266
- $user = function_exists('get_user_by') ? get_user_by('login', $_mwp_data['params']['username']) : get_user_by('login', $_mwp_data['params']['username']);
267
- }
268
-
269
- if ($_mwp_data['action'] === 'add_site') {
270
- $_mwp_auth = mwp_add_site_verify_signature($_mwp_data, $usernameUsed);
271
- if(isset($user)){
272
- $GLOBALS['mwp_user_id'] = $user->ID;
273
- }
274
-
275
- return;
276
- } else {
277
- $_mwp_auth = $mmb_core->authenticate_message($_mwp_data['action'].$_mwp_data['id'], $_mwp_data['signature'], $_mwp_data['id']);
278
- }
279
-
280
- if ($_mwp_auth !== true) {
281
- mmb_response($_mwp_auth['error'], false);
282
- }
283
-
284
-
285
- //$this->w3tc_flush();
286
-
287
- if (isset($user)) {
288
- wp_set_current_user($user->ID);
289
- if (@getenv('IS_WPE')) {
290
- wp_set_auth_cookie($user->ID);
291
- }
292
- }
293
-
294
-
295
- /*if (!defined('WP_ADMIN')) {
296
- define('WP_ADMIN', true);
297
- }*/
298
-
299
- if(defined('ALTERNATE_WP_CRON') && !defined('DOING_AJAX') && ALTERNATE_WP_CRON === true ){
300
- define('DOING_AJAX', true);
301
- }
302
- }
303
- }
304
-
305
- if (!function_exists("mwp_add_site_verify_signature")) {
306
- function mwp_add_site_verify_signature($_mwp_data, $posted_username = null)
307
- {
308
- global $mmb_plugin_dir;
309
-
310
- $nonce = new MWP_Security_HashNonce();
311
- $nonce->setValue($_mwp_data['id']);
312
- if (!$nonce->verify()) {
313
- $_mwp_auth = array(
314
- 'error' => 'Invalid nonce used. Please contact support'
315
- );
316
- mmb_response($_mwp_auth['error'], false);
317
- } else {
318
-
319
- if (!empty($_mwp_data['add_site_signature']) && !empty($_mwp_data['add_site_signature_id'])) {
320
- $signature = base64_decode($_mwp_data['add_site_signature']);
321
- $signature_id = $_mwp_data['add_site_signature_id'];
322
- $plaintext = array();
323
- $plaintext['setting'] = $_mwp_data['setting'];
324
- $plaintext['params'] = $_mwp_data['params'];
325
- if (isset($posted_username)) {
326
- $plaintext['params']['username'] = $posted_username;
327
- }
328
- if (file_exists($mmb_plugin_dir.'/publickeys/'.$signature_id.'.pub')) {
329
- $plaintext = json_encode($plaintext);
330
- require_once dirname(__FILE__).'/src/PHPSecLib/Crypt/RSA.php';
331
- $rsa = new Crypt_RSA();
332
- $rsa->setSignatureMode(CRYPT_RSA_SIGNATURE_PKCS1);
333
- $rsa->loadKey(file_get_contents($mmb_plugin_dir.'/publickeys/'.$signature_id.'.pub')); // public key
334
- $_mwp_auth = $rsa->verify($plaintext, $signature);
335
- } else {
336
- $_mwp_auth = false; // we don't have key
337
- }
338
- } else {
339
- $_mwp_auth = false;
340
- }
341
-
342
- if ($_mwp_auth !== true) {
343
- $_mwp_auth = array(
344
- 'error' => 'Invalid message signature. Deactivate and activate the ManageWP Worker plugin on this site, then re-add it to your ManageWP account.'
345
- );
346
- mmb_response($_mwp_auth['error'], false);
347
- }
348
- }
349
-
350
- return $_mwp_auth;
351
- }
352
- }
353
-
354
- if (!function_exists('mmb_parse_request')) {
355
- function mmb_parse_request()
356
- {
357
- global $mmb_core, $wp_db_version, $wpmu_version, $_wp_using_ext_object_cache, $_mwp_data, $_mwp_auth;
358
- if (empty($_mwp_auth)) {
359
- MMB_Stats::set_hit_count();
360
-
361
- return;
362
- }
363
- ob_start();
364
- $_wp_using_ext_object_cache = false;
365
- @set_time_limit(1200);
366
-
367
- if (isset($_mwp_data['setting'])) {
368
- if(array_key_exists("dataown",$_mwp_data['setting'])){
369
- $oldconfiguration = array("dataown" => $_mwp_data['setting']['dataown']);
370
- $mmb_core->save_options($oldconfiguration);
371
- unset($_mwp_data['setting']['dataown']);
372
- }
373
-
374
- $configurationService = new MWP_Configuration_Service();
375
- $configuration = new MWP_Configuration_Conf($_mwp_data['setting']);
376
- $configurationService->saveConfiguration($configuration);
377
- }
378
-
379
- if ($_mwp_data['action'] === 'add_site') {
380
- mmb_add_site($_mwp_data['params']);
381
- mmb_response('You should never see this.', false);
382
- }
383
-
384
- /* in case database upgrade required, do database backup and perform upgrade ( wordpress wp_upgrade() function ) */
385
- if (strlen(trim($wp_db_version)) && !defined('ACX_PLUGIN_DIR')) {
386
- if (get_option('db_version') != $wp_db_version) {
387
- /* in multisite network, please update database manualy */
388
- if (empty($wpmu_version) || (function_exists('is_multisite') && !is_multisite())) {
389
- if (!function_exists('wp_upgrade')) {
390
- include_once(ABSPATH.'wp-admin/includes/upgrade.php');
391
- }
392
-
393
- ob_clean();
394
- @wp_upgrade();
395
- @do_action('after_db_upgrade');
396
- ob_end_clean();
397
- }
398
- }
399
- }
400
-
401
- if (isset($_mwp_data['params']['secure'])) {
402
- if (is_array($_mwp_data['params']['secure'])) {
403
- $secureParams = $_mwp_data['params']['secure'];
404
- foreach ($secureParams as $key => $value) {
405
- $secureParams[$key] = base64_decode($value);
406
- }
407
- $_mwp_data['params']['secure'] = $secureParams;
408
- } else {
409
- $_mwp_data['params']['secure'] = base64_decode($_mwp_data['params']['secure']);
410
- }
411
- if ($decrypted = $mmb_core->_secure_data($_mwp_data['params']['secure'])) {
412
- $decrypted = maybe_unserialize($decrypted);
413
- if (is_array($decrypted)) {
414
- foreach ($decrypted as $key => $val) {
415
- if (!is_numeric($key)) {
416
- $_mwp_data['params'][$key] = $val;
417
- }
418
- }
419
- unset($_mwp_data['params']['secure']);
420
- } else {
421
- $_mwp_data['params']['secure'] = $decrypted;
422
- }
423
- }
424
-
425
- if (!$decrypted && $mmb_core->get_random_signature() !== false) {
426
- require_once dirname(__FILE__).'/src/PHPSecLib/Crypt/AES.php';
427
- $cipher = new Crypt_AES(CRYPT_AES_MODE_ECB);
428
- $cipher->setKey($mmb_core->get_random_signature());
429
- $decrypted = $cipher->decrypt($_mwp_data['params']['secure']);
430
- $_mwp_data['params']['account_info'] = json_decode($decrypted, true);
431
- }
432
-
433
- }
434
-
435
- $logData = array(
436
- 'action' => $_mwp_data['action'],
437
- 'action_parameters' => $_mwp_data['params'],
438
- 'action_settings' => $_mwp_data['setting'],
439
- );
440
-
441
- if (!empty( $_mwp_data['setting'])) {
442
- $logData['settings'] = $_mwp_data['setting'];
443
- }
444
-
445
- mwp_logger()->debug('Master request: "{action}"', $logData);
446
-
447
- if (!$mmb_core->register_action_params($_mwp_data['action'], $_mwp_data['params'])) {
448
- global $_mmb_plugin_actions;
449
- $_mmb_plugin_actions[$_mwp_data['action']] = $_mwp_data['params'];
450
- }
451
-
452
- ob_end_clean();
453
- }
454
- }
455
- /* Main response function */
456
- if (!function_exists('mmb_response')) {
457
-
458
- function mmb_response($response = false, $success = true)
459
- {
460
- $return = array();
461
-
462
- if ((is_array($response) && empty($response)) || (!is_array($response) && strlen($response) == 0)) {
463
- $return['error'] = 'Empty response.';
464
- } else {
465
- if ($success) {
466
- $return['success'] = $response;
467
- } else {
468
- $return['error'] = $response;
469
- }
470
- }
471
-
472
- if (!headers_sent()) {
473
- header('HTTP/1.0 200 OK');
474
- header('Content-Type: text/plain');
475
- }
476
-
477
- mwp_logger()->debug('Master response: {action_response_status}', array(
478
- 'action_response_status' => $success ? 'success' : 'error',
479
- 'action_response' => $return,
480
- 'headers_sent' => headers_sent(),
481
- ));
482
-
483
- exit("<MWPHEADER>".base64_encode(serialize($return))."<ENDMWPHEADER>");
484
- }
485
- }
486
-
487
-
488
- if (!function_exists('mmb_add_site')) {
489
- function mmb_add_site($params)
490
- {
491
- global $mmb_core;
492
- $num = extract($params);
493
-
494
- if ($num) {
495
- if (!get_option('_worker_public_key')) {
496
- $public_key = base64_decode($public_key);
497
-
498
- if (function_exists('openssl_verify')) {
499
- $verify = openssl_verify($action.$id, base64_decode($signature), $public_key);
500
- if ($verify == 1) {
501
- $mmb_core->set_master_public_key($public_key);
502
- //$mmb_core->set_worker_message_id($id);
503
-
504
-
505
- $mmb_core->get_stats_instance();
506
- if (isset($notifications) && is_array($notifications) && !empty($notifications)) {
507
- $mmb_core->stats_instance->set_notifications($notifications);
508
- }
509
- if (isset($brand) && is_array($brand) && !empty($brand)) {
510
- update_option('mwp_worker_brand', $brand);
511
- }
512
-
513
- if (isset($add_settigns) && is_array($add_settigns) && !empty($add_settigns)) {
514
- apply_filters('mwp_website_add', $add_settigns);
515
- }
516
-
517
- mmb_response($mmb_core->stats_instance->get_initial_stats(), true);
518
- } else {
519
- if ($verify == 0) {
520
-
521
- //mmb_response('Site could not be added. OpenSSL verification error: "'.openssl_error_string().'". Contact your hosting support to check the OpenSSL configuration.', false);
522
-
523
- } else {
524
- mmb_response('Command not successful. Please try again.', false);
525
- }
526
- }
527
- }
528
-
529
- if (!get_option('_worker_nossl_key')) {
530
- srand();
531
-
532
- $random_key = md5(base64_encode($public_key).rand(0, getrandmax()));
533
-
534
- $mmb_core->set_random_signature($random_key);
535
- //$mmb_core->set_worker_message_id($id);
536
- $mmb_core->set_master_public_key($public_key);
537
-
538
-
539
- $mmb_core->get_stats_instance();
540
- if (is_array($notifications) && !empty($notifications)) {
541
- $mmb_core->stats_instance->set_notifications($notifications);
542
- }
543
-
544
- if (is_array($brand) && !empty($brand)) {
545
- update_option('mwp_worker_brand', $brand);
546
- }
547
-
548
- mmb_response($mmb_core->stats_instance->get_initial_stats(), true);
549
- } else {
550
- mmb_response('Sorry, we were unable to communicate with your website. Please deactivate, then activate ManageWP Worker plugin on your website and try again or contact our support.', false);
551
- }
552
-
553
- } else {
554
- mmb_response('Sorry, we were unable to communicate with your website. Please deactivate, then activate ManageWP Worker plugin on your website and try again or contact our support.', false);
555
- }
556
- } else {
557
- mmb_response('Invalid parameters received. Please try again.', false);
558
- }
559
- }
560
- }
561
-
562
- if (!function_exists('mmb_remove_site')) {
563
- function mmb_remove_site($params)
564
- {
565
- extract($params);
566
- global $mmb_core;
567
- $mmb_core->uninstall($deactivate);
568
-
569
- include_once(ABSPATH.'wp-admin/includes/plugin.php');
570
- $plugin_slug = basename(dirname(__FILE__)).'/'.basename(__FILE__);
571
-
572
- if ($deactivate) {
573
- deactivate_plugins($plugin_slug, true);
574
- } else {
575
- // Prolong the worker deactivation upon site removal.
576
- update_option('mmb_worker_activation_time', time());
577
- }
578
-
579
- if (!is_plugin_active($plugin_slug)) {
580
- mmb_response(
581
- array(
582
- 'deactivated' => 'Site removed successfully. <br /><br />ManageWP Worker plugin successfully deactivated.'
583
- ),
584
- true
585
- );
586
- } else {
587
- mmb_response(
588
- array(
589
- 'removed_data' => 'Site removed successfully. <br /><br /><b>ManageWP Worker plugin was not deactivated.</b>'
590
- ),
591
- true
592
- );
593
- }
594
-
595
- }
596
- }
597
- if (!function_exists('mmb_stats_get')) {
598
- function mmb_stats_get($params)
599
- {
600
- global $mmb_core;
601
- $mmb_core->get_stats_instance();
602
- mmb_response($mmb_core->stats_instance->get($params), true);
603
- }
604
- }
605
-
606
- if (!function_exists('mmb_worker_header')) {
607
- function mmb_worker_header()
608
- {
609
- global $mmb_core, $current_user;
610
-
611
- if (!headers_sent()) {
612
- if (isset($current_user->ID)) {
613
- $expiration = time() + apply_filters('auth_cookie_expiration', 10800, $current_user->ID, false);
614
- } else {
615
- $expiration = time() + 10800;
616
- }
617
-
618
- setcookie(MMB_XFRAME_COOKIE, md5(MMB_XFRAME_COOKIE), $expiration, COOKIEPATH, COOKIE_DOMAIN, false, true);
619
- $_COOKIE[MMB_XFRAME_COOKIE] = md5(MMB_XFRAME_COOKIE);
620
- }
621
- }
622
- }
623
-
624
- if (!function_exists('mmb_pre_init_stats')) {
625
- function mmb_pre_init_stats($params)
626
- {
627
- global $mmb_core;
628
- $mmb_core->get_stats_instance();
629
-
630
- return $mmb_core->stats_instance->pre_init_stats($params);
631
- }
632
- }
633
-
634
- if (!function_exists('mwp_datasend')) {
635
- function mwp_datasend($params = array())
636
- {
637
- global $mmb_core, $_mmb_item_filter, $_mmb_options;
638
-
639
-
640
- $_mmb_remoteurl = get_option('home');
641
- $_mmb_remoteown = isset($_mmb_options['dataown']) && !empty($_mmb_options['dataown']) ? $_mmb_options['dataown'] : false;
642
-
643
- if (empty($_mmb_remoteown)) {
644
- return;
645
- }
646
-
647
- $_mmb_item_filter['pre_init_stats'] = array('core_update', 'hit_counter', 'comments', 'backups', 'posts', 'drafts', 'scheduled');
648
- $_mmb_item_filter['get'] = array('updates', 'errors');
649
- $mmb_core->get_stats_instance();
650
-
651
- $filter = array(
652
- 'refresh' => 'transient',
653
- 'item_filter' => array(
654
- 'get_stats' => array(
655
- array('updates', array('plugins' => true, 'themes' => true, 'premium' => true)),
656
- array('core_update', array('core' => true)),
657
- array('posts', array('numberposts' => 5)),
658
- array('drafts', array('numberposts' => 5)),
659
- array('scheduled', array('numberposts' => 5)),
660
- array('hit_counter'),
661
- array('comments', array('numberposts' => 5)),
662
- array('backups'),
663
- 'plugins' => array(
664
- 'cleanup' => array(
665
- 'overhead' => array(),
666
- 'revisions' => array('num_to_keep' => 'r_5'),
667
- 'spam' => array(),
668
- )
669
- ),
670
- ),
671
- )
672
- );
673
-
674
- $pre_init_data = $mmb_core->stats_instance->pre_init_stats($filter);
675
- $init_data = $mmb_core->stats_instance->get($filter);
676
-
677
- $data = array_merge($init_data, $pre_init_data);
678
- $data['server_ip'] = $_SERVER['SERVER_ADDR'];
679
- $data['uhost'] = php_uname('n');
680
- $hash = $mmb_core->get_secure_hash();
681
-
682
- if (mwp_datasend_trigger($data)) { // adds trigger to check if really need to send something
683
- $configurationService = new MWP_Configuration_Service();
684
- $configuration = $configurationService->getConfiguration();
685
-
686
- set_transient("mwp_cache_notifications", $data);
687
- set_transient("mwp_cache_notifications_time", time());
688
-
689
- $datasend['datasend'] = $mmb_core->encrypt_data($data);
690
- $datasend['sitehome'] = base64_encode($_mmb_remoteown.'[]'.$_mmb_remoteurl);
691
- $datasend['sitehash'] = md5($hash.$_mmb_remoteown.$_mmb_remoteurl);
692
- $datasend['setting_checksum_order'] = implode(",", array_keys($configuration->getVariables()));
693
- $datasend['setting_checksum'] = md5(json_encode($configuration->toArray()));
694
- if (!class_exists('WP_Http')) {
695
- include_once(ABSPATH.WPINC.'/class-http.php');
696
- }
697
-
698
- $remote = array();
699
- $remote['body'] = $datasend;
700
-
701
- $result = wp_remote_post($configuration->getMasterCronUrl(), $remote);
702
- if (!is_wp_error($result)) {
703
- if (isset($result['body']) && !empty($result['body'])) {
704
- $settings = @unserialize($result['body']);
705
- /* rebrand worker or set default */
706
- $brand = '';
707
- if ($settings['worker_brand']) {
708
- $brand = $settings['worker_brand'];
709
- }
710
- update_option("mwp_worker_brand", $brand);
711
- /* change worker version */
712
- $w_version = $settings['worker_updates']['version'];
713
- $w_url = $settings['worker_updates']['url'];
714
- if (version_compare($GLOBALS['MMB_WORKER_VERSION'], $w_version, '<')) {
715
- //automatic update
716
- $mmb_core->update_worker_plugin(array("download_url" => $w_url));
717
- }
718
-
719
- if (!empty($settings['mwp_worker_configuration'])) {
720
- require_once dirname(__FILE__).'/src/PHPSecLib/Crypt/RSA.php';
721
- $rsa = new Crypt_RSA();
722
- $keyName = $configuration->getKeyName();
723
- $rsa->setSignatureMode(CRYPT_RSA_SIGNATURE_PKCS1);
724
- $rsa->loadKey(file_get_contents(dirname(__FILE__)."/publickeys/$keyName.pub")); // public key
725
- $signature = base64_decode($settings['mwp_worker_configuration_signature']);
726
- if ($rsa->verify(json_encode($settings['mwp_worker_configuration']), $signature)) {
727
- $configuration = new MWP_Configuration_Conf($settings['mwp_worker_configuration']);
728
- $configurationService->saveConfiguration($configuration);
729
- }
730
- }
731
- }
732
- } else {
733
- //$mmb_core->_log($result);
734
- }
735
-
736
- }
737
-
738
- }
739
-
740
- }
741
-
742
- if (!function_exists("mwp_datasend_trigger")) {
743
- // trigger function, returns true if notifications should be sent
744
- function mwp_datasend_trigger($stats)
745
- {
746
-
747
- $configurationService = new MWP_Configuration_Service();
748
- $configuration = $configurationService->getConfiguration();
749
-
750
- $cachedData = get_transient("mwp_cache_notifications");
751
- $cacheTime = (int) get_transient("mwp_cache_notifications_time");
752
-
753
- $returnValue = false;
754
- if (false == $cachedData || empty($configuration)) {
755
- $returnValue = true;
756
- }
757
- /**
758
- * Cache lifetime check
759
- */
760
- if (!$returnValue) {
761
- $now = time();
762
- if ($now - $configuration->getNotiCacheLifeTime() >= $cacheTime) {
763
- $returnValue = true;
764
- }
765
- }
766
-
767
- /**
768
- * Themes difference check section
769
- * First check if array differ in size. If same size,then check values difference
770
- */
771
- if (!$returnValue && empty($stats['upgradable_themes']) != empty($cachedData['upgradable_themes'])) {
772
- $returnValue = true;
773
- }
774
- if (!$returnValue && !empty($stats['upgradable_themes'])) {
775
- $themesArr = mwp_std_to_array($stats['upgradable_themes']);
776
- $cachedThemesArr = mwp_std_to_array($cachedData['upgradable_themes']);
777
- if ($themesArr != $cachedThemesArr) {
778
- $returnValue = true;
779
- }
780
- }
781
-
782
- /**
783
- * Plugins difference check section
784
- * First check if array differ in size. If same size,then check values difference
785
- */
786
- if (!$returnValue && empty($stats['upgradable_plugins']) != empty($cachedData['upgradable_plugins'])) {
787
- $returnValue = true;
788
- }
789
-
790
- if (!$returnValue && !empty($stats['upgradable_plugins'])) { //we have hear stdclass
791
- $pluginsArr = mwp_std_to_array($stats['upgradable_plugins']);
792
- $cachedPluginsArr = mwp_std_to_array($cachedData['upgradable_plugins']);
793
- if ($pluginsArr != $cachedPluginsArr) {
794
- $returnValue = true;
795
- }
796
- }
797
-
798
- /**
799
- * Premium difference check section
800
- * First check if array differ in size. If same size,then check values difference
801
- */
802
- if (!$returnValue && empty($stats['premium_updates']) != empty($cachedData['premium_updates'])) {
803
- $returnValue = true;
804
- }
805
- if (!$returnValue && !empty($stats['premium_updates'])) {
806
- $premiumArr = mwp_std_to_array($stats['premium_updates']);
807
- $cachedPremiumArr = mwp_std_to_array($cachedData['premium_updates']);
808
- if ($premiumArr != $cachedPremiumArr) {
809
- $returnValue = true;
810
- }
811
- }
812
- /**
813
- * Comments
814
- * Check if we have configs first, then check trasholds
815
- */
816
- if (!$returnValue && (int) $stats['num_spam_comments'] >= $configuration->getNotiTresholdSpamComments() && $stats['num_spam_comments'] != (int) $cachedData['num_spam_comments']) {
817
- $returnValue = true;
818
- }
819
- if (!$returnValue && (int) $stats['num_spam_comments'] < (int) $cachedData['num_spam_comments']) {
820
- $returnValue = true;
821
- }
822
-
823
- if (!$returnValue && !empty($stats['comments'])) {
824
- if (!empty($stats['comments']['pending']) && count($stats['comments']['pending']) >= $configuration->getNotiTresholdPendingComments()) {
825
- $pendingArr = mwp_std_to_array($stats['comments']['pending']);
826
- $cachedPendingArr = mwp_std_to_array($cachedData['comments']['pending']);
827
- if ($pendingArr != $cachedPendingArr) {
828
- $returnValue = true;
829
- }
830
- }
831
-
832
- if (!empty($stats['comments']['approved']) && count($stats['comments']['approved']) >= $configuration->getNotiTresholdApprovedComments()) {
833
- $approvedArr = mwp_std_to_array($stats['comments']['approved']);
834
- $cachedApprovedArr = mwp_std_to_array($cachedData['comments']['approved']);
835
- if ($approvedArr != $cachedApprovedArr) {
836
- $returnValue = true;
837
- }
838
- }
839
- }
840
-
841
- /**
842
- * Drafts, posts
843
- */
844
-
845
- if (!$returnValue && !empty($stats['drafts']) && count($stats['drafts']) >= $configuration->getNotiTresholdDrafts()) {
846
- if (count($stats['drafts']) > $configuration->getNotiTresholdDrafts() && empty($cachedData['drafts'])) {
847
- $returnValue = true;
848
- } else {
849
- $draftsArr = mwp_std_to_array($stats['drafts']);
850
- $cachedDraftsArr = mwp_std_to_array($cachedData['drafts']);
851
- if ($draftsArr != $cachedDraftsArr) {
852
- $returnValue = true;
853
- }
854
- }
855
-
856
- }
857
-
858
- if (!$returnValue && !empty($stats['posts']) && count($stats['posts']) >= $configuration->getNotiTresholdPosts()) {
859
- if (count($stats['posts']) > $configuration->getNotiTresholdPosts() && empty($cachedData['posts'])) {
860
- $returnValue = true;
861
- } else {
862
- $postsArr = mwp_std_to_array($stats['posts']);
863
- $cachedPostsArr = mwp_std_to_array($cachedData['posts']);
864
- if ($postsArr != $cachedPostsArr) {
865
- $returnValue = true;
866
- }
867
- }
868
- }
869
-
870
- /**
871
- * Core updates & backups
872
- */
873
- if (!$returnValue && empty($stats['core_updates']) != empty($cachedData['core_updates'])) {
874
- $returnValue = true;
875
- }
876
- if (!$returnValue && !empty($stats['core_updates'])) {
877
- $coreArr = mwp_std_to_array($stats['core_updates']);
878
- $cachedCoreArr = mwp_std_to_array($cachedData['core_updates']);
879
- if ($coreArr != $cachedCoreArr) {
880
- $returnValue = true;
881
- }
882
- }
883
-
884
- if (!$returnValue && empty($stats['mwp_backups']) != empty($cachedData['mwp_backups'])) {
885
- $returnValue = true;
886
- }
887
- if (!$returnValue && !empty($stats['mwp_backups'])) {
888
- $backupArr = mwp_std_to_array($stats['mwp_backups']);
889
- $cachedBackupArr = mwp_std_to_array($cachedData['mwp_backups']);
890
- if ($backupArr != $cachedBackupArr) {
891
- $returnValue = true;
892
- }
893
- }
894
-
895
- return $returnValue;
896
- }
897
- }
898
-
899
- if (!function_exists("mwp_std_to_array")) {
900
- function mwp_std_to_array($obj)
901
- {
902
- if (is_object($obj)) {
903
- $objArr = clone $obj;
904
- } else {
905
- $objArr = $obj;
906
- }
907
- if (!empty($objArr)) {
908
- foreach ($objArr as &$element) {
909
- if ($element instanceof stdClass || is_array($element)) {
910
- $element = mwp_std_to_array($element);
911
- }
912
- }
913
- $objArr = (array) $objArr;
914
- }
915
-
916
- return $objArr;
917
- }
918
- }
919
-
920
-
921
- //post
922
- if (!function_exists('mmb_post_create')) {
923
- function mmb_post_create($params)
924
- {
925
- global $mmb_core;
926
- $mmb_core->get_post_instance();
927
- $return = $mmb_core->post_instance->create($params);
928
- if (is_int($return)) {
929
- mmb_response($return, true);
930
- } else {
931
- if (isset($return['error'])) {
932
- mmb_response($return['error'], false);
933
- } else {
934
- mmb_response($return, false);
935
- }
936
- }
937
- }
938
- }
939
-
940
- if (!function_exists('mmb_change_post_status')) {
941
- function mmb_change_post_status($params)
942
- {
943
- global $mmb_core;
944
- $mmb_core->get_post_instance();
945
- $return = $mmb_core->post_instance->change_status($params);
946
- if (is_wp_error($return)){
947
- mmb_response($return->get_error_message(), false);
948
- } elseif (empty($return)) {
949
- mmb_response("Post status can not be changed", false);
950
- } else {
951
- mmb_response($return, true);
952
- }
953
- }
954
- }
955
-
956
- //comments
957
- if (!function_exists('mmb_change_comment_status')) {
958
- function mmb_change_comment_status($params)
959
- {
960
- global $mmb_core;
961
- $mmb_core->get_comment_instance();
962
- $return = $mmb_core->comment_instance->change_status($params);
963
- //mmb_response($return, true);
964
- if ($return) {
965
- $mmb_core->get_stats_instance();
966
- mmb_response($mmb_core->stats_instance->get_comments_stats($params), true);
967
- } else {
968
- mmb_response('Comment not updated', false);
969
- }
970
- }
971
-
972
- }
973
- if (!function_exists('mmb_comment_stats_get')) {
974
- function mmb_comment_stats_get($params)
975
- {
976
- global $mmb_core;
977
- $mmb_core->get_stats_instance();
978
- mmb_response($mmb_core->stats_instance->get_comments_stats($params), true);
979
- }
980
- }
981
-
982
- if (!function_exists('mmb_backup_now')) {
983
- //backup
984
- function mmb_backup_now($params)
985
- {
986
- global $mmb_core;
987
-
988
- $mmb_core->get_backup_instance();
989
- $return = $mmb_core->backup_instance->backup($params);
990
-
991
- if (is_array($return) && array_key_exists('error', $return)) {
992
- mmb_response($return['error'], false);
993
- } else {
994
- mmb_response($return, true);
995
- }
996
- }
997
- }
998
-
999
- if (!function_exists('mwp_ping_backup')) {
1000
- //ping backup
1001
- function mwp_ping_backup($params)
1002
- {
1003
- global $mmb_core;
1004
-
1005
- $mmb_core->get_backup_instance();
1006
- $return = $mmb_core->backup_instance->ping_backup($params);
1007
-
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
-
1016
- if (!function_exists('mmb_run_task_now')) {
1017
- function mmb_run_task_now($params)
1018
- {
1019
- global $mmb_core;
1020
- $mmb_core->get_backup_instance();
1021
-
1022
- $task_name = isset($params['task_name']) ? $params['task_name'] : false;
1023
- $google_drive_token = isset($params['google_drive_token']) ? $params['google_drive_token'] : false;
1024
-
1025
- if ($task_name) {
1026
- $return = $mmb_core->backup_instance->task_now($task_name, $google_drive_token);
1027
- if (is_array($return) && array_key_exists('error', $return)) {
1028
- mmb_response($return['error'], false);
1029
- } else {
1030
- mmb_response($return, true);
1031
- }
1032
- } else {
1033
- mmb_response("Task name is not provided.", false);
1034
- }
1035
-
1036
- }
1037
- }
1038
-
1039
- if (!function_exists('mmb_email_backup')) {
1040
- function mmb_email_backup($params)
1041
- {
1042
- global $mmb_core;
1043
- $mmb_core->get_backup_instance();
1044
- $return = $mmb_core->backup_instance->email_backup($params);
1045
-
1046
- if (is_array($return) && array_key_exists('error', $return)) {
1047
- mmb_response($return['error'], false);
1048
- } else {
1049
- mmb_response($return, true);
1050
- }
1051
- }
1052
- }
1053
-
1054
- if (!function_exists('mmb_check_backup_compat')) {
1055
- function mmb_check_backup_compat($params)
1056
- {
1057
- global $mmb_core;
1058
- $mmb_core->get_backup_instance();
1059
- $return = $mmb_core->backup_instance->check_backup_compat($params);
1060
-
1061
- if (is_array($return) && array_key_exists('error', $return)) {
1062
- mmb_response($return['error'], false);
1063
- } else {
1064
- mmb_response($return, true);
1065
- }
1066
- }
1067
- }
1068
-
1069
- if (!function_exists('mmb_get_backup_req')) {
1070
- function mmb_get_backup_req($params)
1071
- {
1072
- global $mmb_core;
1073
- $mmb_core->get_stats_instance();
1074
- $return = $mmb_core->stats_instance->get_backup_req($params);
1075
-
1076
- mmb_response($return, true);
1077
- }
1078
- }
1079
-
1080
- // Fires when Backup Now, or some backup task is saved.
1081
- if (!function_exists('mmb_scheduled_backup')) {
1082
- function mmb_scheduled_backup($params)
1083
- {
1084
- global $mmb_core;
1085
- $mmb_core->get_backup_instance();
1086
- $return = $mmb_core->backup_instance->set_backup_task($params);
1087
- mmb_response($return, $return);
1088
- }
1089
- }
1090
-
1091
- if (!function_exists('mmm_delete_backup')) {
1092
- function mmm_delete_backup($params)
1093
- {
1094
- global $mmb_core;
1095
- $mmb_core->get_backup_instance();
1096
- $return = $mmb_core->backup_instance->delete_backup($params);
1097
- mmb_response($return, $return);
1098
- }
1099
- }
1100
-
1101
- if (!function_exists('mmb_optimize_tables')) {
1102
- function mmb_optimize_tables($params)
1103
- {
1104
- global $mmb_core;
1105
- $mmb_core->get_backup_instance();
1106
- $return = $mmb_core->backup_instance->optimize_tables();
1107
- if ($return) {
1108
- mmb_response($return, true);
1109
- } else {
1110
- mmb_response(false, false);
1111
- }
1112
- }
1113
- }
1114
- if (!function_exists('mmb_restore_now')) {
1115
- function mmb_restore_now($params)
1116
- {
1117
- global $mmb_core;
1118
- $mmb_core->get_backup_instance();
1119
- $return = $mmb_core->backup_instance->restore($params);
1120
- if (is_array($return) && array_key_exists('error', $return)) {
1121
- mmb_response($return['error'], false);
1122
- } else {
1123
- mmb_response($return, true);
1124
- }
1125
-
1126
- }
1127
- }
1128
-
1129
- if (!function_exists('mmb_remote_backup_now')) {
1130
- function mmb_remote_backup_now($params)
1131
- {
1132
- global $mmb_core;
1133
- $backup_instance = $mmb_core->get_backup_instance();
1134
- $return = $mmb_core->backup_instance->remote_backup_now($params);
1135
- if (is_array($return) && array_key_exists('error', $return)) {
1136
- mmb_response($return['error'], false);
1137
- } else {
1138
- mmb_response($return, true);
1139
- }
1140
- }
1141
- }
1142
-
1143
-
1144
- if (!function_exists('mmb_clean_orphan_backups')) {
1145
- function mmb_clean_orphan_backups()
1146
- {
1147
- global $mmb_core;
1148
- $backup_instance = $mmb_core->get_backup_instance();
1149
- $return = $mmb_core->backup_instance->cleanup();
1150
- if (is_array($return)) {
1151
- mmb_response($return, true);
1152
- } else {
1153
- mmb_response($return, false);
1154
- }
1155
- }
1156
- }
1157
-
1158
- function mmb_run_forked_action()
1159
- {
1160
-
1161
- $usernameUsed = array_key_exists('username', $_POST) ? $_POST : null;
1162
- if ($usernameUsed && !is_user_logged_in()) {
1163
- $user = function_exists('get_user_by') ? get_user_by('login', $_POST['username']) : get_user_by('login', $_POST['username']);
1164
- }
1165
-
1166
- if (isset($user)) {
1167
- wp_set_current_user($user->ID);
1168
- if (@getenv('IS_WPE')) {
1169
- wp_set_auth_cookie($user->ID);
1170
- }
1171
- }
1172
- if (!isset($_POST['mmb_fork_nonce']) || (isset($_POST['mmb_fork_nonce']) && !wp_verify_nonce($_POST['mmb_fork_nonce'], 'mmb-fork-nonce'))) {
1173
- return false;
1174
- }
1175
-
1176
- $public_key = get_option('_worker_public_key');
1177
- if (!isset($_POST['public_key']) || $public_key !== $_POST['public_key']) {
1178
- return false;
1179
- }
1180
- $args = @json_decode(stripslashes($_POST['args']), true);
1181
- $args['forked'] = true;
1182
-
1183
- if (!isset($args)) {
1184
- return false;
1185
- }
1186
- $cron_action = isset($_POST['mwp_forked_action']) ? $_POST['mwp_forked_action'] : false;
1187
- if ($cron_action) {
1188
- do_action($cron_action, $args);
1189
- }
1190
- //unset($_POST['public_key']);
1191
- unset($_POST['mmb_fork_nonce']);
1192
- unset($_POST['args']);
1193
- unset($_POST['mwp_forked_action']);
1194
-
1195
- return true;
1196
- }
1197
-
1198
- add_filter('mwp_website_add', 'mmb_readd_backup_task');
1199
-
1200
- if (!function_exists('mmb_readd_backup_task')) {
1201
- function mmb_readd_backup_task($params = array())
1202
- {
1203
- global $mmb_core;
1204
- $backup_instance = $mmb_core->get_backup_instance();
1205
- $settings = $backup_instance->readd_tasks($params);
1206
-
1207
- return $settings;
1208
- }
1209
- }
1210
-
1211
- if (!function_exists('mmb_update_worker_plugin')) {
1212
- function mmb_update_worker_plugin($params)
1213
- {
1214
- global $mmb_core;
1215
- mmb_response($mmb_core->update_worker_plugin($params), true);
1216
- }
1217
- }
1218
-
1219
- if (!function_exists('mmb_wp_checkversion')) {
1220
- function mmb_wp_checkversion($params)
1221
- {
1222
- include_once(ABSPATH.'wp-includes/version.php');
1223
- global $mmb_wp_version, $mmb_core;
1224
- mmb_response($mmb_wp_version, true);
1225
- }
1226
- }
1227
- if (!function_exists('mmb_search_posts_by_term')) {
1228
- function mmb_search_posts_by_term($params)
1229
- {
1230
- global $mmb_core;
1231
- $mmb_core->get_search_instance();
1232
-
1233
- $search_type = trim($params['search_type']);
1234
- $search_term = strtolower(trim($params['search_term']));
1235
-
1236
- switch ($search_type) {
1237
- case 'page_post':
1238
- $return = $mmb_core->search_instance->search_posts_by_term($params);
1239
- if ($return) {
1240
- $return = serialize($return);
1241
- mmb_response($return, true);
1242
- } else {
1243
- mmb_response('No posts found', false);
1244
- }
1245
- break;
1246
-
1247
- case 'plugin':
1248
- $plugins = get_option('active_plugins');
1249
-
1250
- $have_plugin = false;
1251
- foreach ($plugins as $plugin) {
1252
- if (strpos($plugin, $search_term) > -1) {
1253
- $have_plugin = true;
1254
- }
1255
- }
1256
- if ($have_plugin) {
1257
- mmb_response(serialize($plugin), true);
1258
- } else {
1259
- mmb_response(false, false);
1260
- }
1261
- break;
1262
- case 'theme':
1263
- $theme = strtolower(get_option('template'));
1264
- if (strpos($theme, $search_term) > -1) {
1265
- mmb_response($theme, true);
1266
- } else {
1267
- mmb_response(false, false);
1268
- }
1269
- break;
1270
- default:
1271
- mmb_response(false, false);
1272
- }
1273
- $return = $mmb_core->search_instance->search_posts_by_term($params);
1274
-
1275
-
1276
- if ($return_if_true) {
1277
- mmb_response($return_value, true);
1278
- } else {
1279
- mmb_response($return_if_false, false);
1280
- }
1281
- }
1282
- }
1283
-
1284
- if (!function_exists('mmb_install_addon')) {
1285
- function mmb_install_addon($params)
1286
- {
1287
- global $mmb_core;
1288
- $mmb_core->get_installer_instance();
1289
- $return = $mmb_core->installer_instance->install_remote_file($params);
1290
- mmb_response($return, true);
1291
-
1292
- }
1293
- }
1294
-
1295
- if (!function_exists('mmb_install_addons')) {
1296
- function mmb_install_addons($params)
1297
- {
1298
- global $mmb_core;
1299
- $mmb_core->get_installer_instance();
1300
- $return = $mmb_core->installer_instance->install_remote_files($params);
1301
- mmb_response($return, true);
1302
-
1303
- }
1304
- }
1305
-
1306
- if (!function_exists('mmb_do_upgrade')) {
1307
- function mmb_do_upgrade($params)
1308
- {
1309
- global $mmb_core, $mmb_upgrading;
1310
- $mmb_core->get_installer_instance();
1311
- $return = $mmb_core->installer_instance->do_upgrade($params);
1312
- mmb_response($return, true);
1313
-
1314
- }
1315
- }
1316
-
1317
- if (!function_exists('mmb_get_links')) {
1318
- function mmb_get_links($params)
1319
- {
1320
- global $mmb_core;
1321
- $mmb_core->get_link_instance();
1322
- $return = $mmb_core->link_instance->get_links($params);
1323
- if (is_array($return) && array_key_exists('error', $return)) {
1324
- mmb_response($return['error'], false);
1325
- } else {
1326
- mmb_response($return, true);
1327
- }
1328
- }
1329
- }
1330
-
1331
- if (!function_exists('mmb_add_link')) {
1332
- function mmb_add_link($params)
1333
- {
1334
- global $mmb_core;
1335
- $mmb_core->get_link_instance();
1336
- $return = $mmb_core->link_instance->add_link($params);
1337
- if (is_array($return) && array_key_exists('error', $return)) {
1338
- mmb_response($return['error'], false);
1339
- } else {
1340
- mmb_response($return, true);
1341
- }
1342
-
1343
- }
1344
- }
1345
-
1346
- if (!function_exists('mmb_delete_link')) {
1347
- function mmb_delete_link($params)
1348
- {
1349
- global $mmb_core;
1350
- $mmb_core->get_link_instance();
1351
-
1352
- $return = $mmb_core->link_instance->delete_link($params);
1353
- if (is_array($return) && array_key_exists('error', $return)) {
1354
- mmb_response($return['error'], false);
1355
- } else {
1356
- mmb_response($return, true);
1357
- }
1358
- }
1359
- }
1360
-
1361
- if (!function_exists('mmb_delete_links')) {
1362
- function mmb_delete_links($params)
1363
- {
1364
- global $mmb_core;
1365
- $mmb_core->get_link_instance();
1366
-
1367
- $return = $mmb_core->link_instance->delete_links($params);
1368
- if (is_array($return) && array_key_exists('error', $return)) {
1369
- mmb_response($return['error'], false);
1370
- } else {
1371
- mmb_response($return, true);
1372
- }
1373
- }
1374
- }
1375
-
1376
- if (!function_exists('mmb_get_comments')) {
1377
- function mmb_get_comments($params)
1378
- {
1379
- global $mmb_core;
1380
- $mmb_core->get_comment_instance();
1381
- $return = $mmb_core->comment_instance->get_comments($params);
1382
- if (is_array($return) && array_key_exists('error', $return)) {
1383
- mmb_response($return['error'], false);
1384
- } else {
1385
- mmb_response($return, true);
1386
- }
1387
- }
1388
- }
1389
-
1390
- if (!function_exists('mmb_action_comment')) {
1391
- function mmb_action_comment($params)
1392
- {
1393
- global $mmb_core;
1394
- $mmb_core->get_comment_instance();
1395
-
1396
- $return = $mmb_core->comment_instance->action_comment($params);
1397
- if (is_array($return) && array_key_exists('error', $return)) {
1398
- mmb_response($return['error'], false);
1399
- } else {
1400
- mmb_response($return, true);
1401
- }
1402
- }
1403
- }
1404
-
1405
- if (!function_exists('mmb_bulk_action_comments')) {
1406
- function mmb_bulk_action_comments($params)
1407
- {
1408
- global $mmb_core;
1409
- $mmb_core->get_comment_instance();
1410
-
1411
- $return = $mmb_core->comment_instance->bulk_action_comments($params);
1412
- if (is_array($return) && array_key_exists('error', $return)) {
1413
- mmb_response($return['error'], false);
1414
- } else {
1415
- mmb_response($return, true);
1416
- }
1417
- }
1418
- }
1419
-
1420
- if (!function_exists('mmb_reply_comment')) {
1421
- function mmb_reply_comment($params)
1422
- {
1423
- global $mmb_core;
1424
- $mmb_core->get_comment_instance();
1425
-
1426
- $return = $mmb_core->comment_instance->reply_comment($params);
1427
- if (is_array($return) && array_key_exists('error', $return)) {
1428
- mmb_response($return['error'], false);
1429
- } else {
1430
- mmb_response($return, true);
1431
- }
1432
- }
1433
- }
1434
-
1435
- if (!function_exists('mmb_add_user')) {
1436
- function mmb_add_user($params)
1437
- {
1438
- global $mmb_core;
1439
- $mmb_core->get_user_instance();
1440
- $return = $mmb_core->user_instance->add_user($params);
1441
- if (is_array($return) && array_key_exists('error', $return)) {
1442
- mmb_response($return['error'], false);
1443
- } else {
1444
- mmb_response($return, true);
1445
- }
1446
-
1447
- }
1448
- }
1449
-
1450
- if (!function_exists('mbb_security_check')) {
1451
- function mbb_security_check($params)
1452
- {
1453
- global $mmb_core;
1454
- $mmb_core->get_security_instance();
1455
- $return = $mmb_core->security_instance->security_check($params);
1456
- if (is_array($return) && array_key_exists('error', $return)) {
1457
- mmb_response($return['error'], false);
1458
- } else {
1459
- mmb_response($return, true);
1460
- }
1461
-
1462
- }
1463
- }
1464
-
1465
- if (!function_exists('mbb_security_fix_folder_listing')) {
1466
- function mbb_security_fix_folder_listing($params)
1467
- {
1468
- global $mmb_core;
1469
- $mmb_core->get_security_instance();
1470
- $return = $mmb_core->security_instance->security_fix_dir_listing($params);
1471
- if (is_array($return) && array_key_exists('error', $return)) {
1472
- mmb_response($return['error'], false);
1473
- } else {
1474
- mmb_response($return, true);
1475
- }
1476
-
1477
- }
1478
- }
1479
-
1480
- if (!function_exists('mbb_security_fix_php_reporting')) {
1481
- function mbb_security_fix_php_reporting($params)
1482
- {
1483
- global $mmb_core;
1484
- $mmb_core->get_security_instance();
1485
- $return = $mmb_core->security_instance->security_fix_php_reporting($params);
1486
- if (is_array($return) && array_key_exists('error', $return)) {
1487
- mmb_response($return['error'], false);
1488
- } else {
1489
- mmb_response($return, true);
1490
- }
1491
-
1492
- }
1493
- }
1494
-
1495
- if (!function_exists('mbb_security_fix_database_reporting')) {
1496
- function mbb_security_fix_database_reporting($params)
1497
- {
1498
- global $mmb_core;
1499
- $mmb_core->get_security_instance();
1500
- $return = $mmb_core->security_instance->security_fix_database_reporting($params);
1501
- if (is_array($return) && array_key_exists('error', $return)) {
1502
- mmb_response($return['error'], false);
1503
- } else {
1504
- mmb_response($return, true);
1505
- }
1506
-
1507
- }
1508
- }
1509
-
1510
- //security_fix_wp_version
1511
-
1512
- if (!function_exists('mbb_security_fix_wp_version')) {
1513
- function mbb_security_fix_wp_version($params)
1514
- {
1515
- global $mmb_core;
1516
- $mmb_core->get_security_instance();
1517
- $return = $mmb_core->security_instance->security_fix_wp_version($params);
1518
- if (is_array($return) && array_key_exists('error', $return)) {
1519
- mmb_response($return['error'], false);
1520
- } else {
1521
- mmb_response($return, true);
1522
- }
1523
-
1524
- }
1525
- }
1526
-
1527
- //mbb_security_fix_admin_username
1528
-
1529
- if (!function_exists('mbb_security_fix_admin_username')) {
1530
- function mbb_security_fix_admin_username($params)
1531
- {
1532
- global $mmb_core;
1533
- $mmb_core->get_security_instance();
1534
- $return = $mmb_core->security_instance->security_fix_admin_username($params);
1535
- if (is_array($return) && array_key_exists('error', $return)) {
1536
- mmb_response($return['error'], false);
1537
- } else {
1538
- mmb_response($return, true);
1539
- }
1540
-
1541
- }
1542
- }
1543
-
1544
- if (!function_exists('mbb_security_fix_scripts_styles')) {
1545
- function mbb_security_fix_scripts_styles($params)
1546
- {
1547
- global $mmb_core;
1548
- $mmb_core->get_security_instance();
1549
- $return = $mmb_core->security_instance->security_fix_scripts_styles($params);
1550
- if (is_array($return) && array_key_exists('error', $return)) {
1551
- mmb_response($return['error'], false);
1552
- } else {
1553
- mmb_response($return, true);
1554
- }
1555
-
1556
- }
1557
- }
1558
-
1559
- //mbb_security_fix_file_permission
1560
- if (!function_exists('mbb_security_fix_file_permission')) {
1561
- function mbb_security_fix_file_permission($params)
1562
- {
1563
- global $mmb_core;
1564
- $mmb_core->get_security_instance();
1565
- $return = $mmb_core->security_instance->security_fix_permissions($params);
1566
- if (is_array($return) && array_key_exists('error', $return)) {
1567
- mmb_response($return['error'], false);
1568
- } else {
1569
- mmb_response($return, true);
1570
- }
1571
-
1572
- }
1573
- }
1574
-
1575
- //mbb_security_fix_all
1576
- if (!function_exists('mbb_security_fix_all')) {
1577
- function mbb_security_fix_all($params)
1578
- {
1579
- global $mmb_core;
1580
- $mmb_core->get_security_instance();
1581
- $return = $mmb_core->security_instance->security_fix_all($params);
1582
- if (is_array($return) && array_key_exists('error', $return)) {
1583
- mmb_response($return['error'], false);
1584
- } else {
1585
- mmb_response($return, true);
1586
- }
1587
- }
1588
- }
1589
-
1590
- //mbb_security_fix_htaccess_permission
1591
-
1592
- if (!function_exists('mbb_security_fix_htaccess_permission')) {
1593
- function mbb_security_fix_htaccess_permission($params)
1594
- {
1595
- global $mmb_core;
1596
- $mmb_core->get_security_instance();
1597
- $return = $mmb_core->security_instance->security_fix_htaccess_permission($params);
1598
- if (is_array($return) && array_key_exists('error', $return)) {
1599
- mmb_response($return['error'], false);
1600
- } else {
1601
- mmb_response($return, true);
1602
- }
1603
-
1604
- }
1605
- }
1606
-
1607
- if (!function_exists('mmb_get_users')) {
1608
- function mmb_get_users($params)
1609
- {
1610
- global $mmb_core;
1611
- $mmb_core->get_user_instance();
1612
- $return = $mmb_core->user_instance->get_users($params);
1613
- if (is_array($return) && array_key_exists('error', $return)) {
1614
- mmb_response($return['error'], false);
1615
- } else {
1616
- mmb_response($return, true);
1617
- }
1618
- }
1619
- }
1620
-
1621
- if (!function_exists('mmb_edit_users')) {
1622
- function mmb_edit_users($params)
1623
- {
1624
- global $mmb_core;
1625
- $mmb_core->get_user_instance();
1626
- $users = $mmb_core->user_instance->edit_users($params);
1627
- $response = 'User updated.';
1628
- $check_error = false;
1629
- foreach ($users as $username => $user) {
1630
- $check_error = array_key_exists('error', $user);
1631
- if ($check_error) {
1632
- $response = $username.': '.$user['error'];
1633
- }
1634
- }
1635
- mmb_response($response, !$check_error);
1636
- }
1637
- }
1638
-
1639
- if (!function_exists('mmb_get_posts')) {
1640
- function mmb_get_posts($params)
1641
- {
1642
- global $mmb_core;
1643
- $mmb_core->get_post_instance();
1644
-
1645
- $return = $mmb_core->post_instance->get_posts($params);
1646
- if (is_array($return) && array_key_exists('error', $return)) {
1647
- mmb_response($return['error'], false);
1648
- } else {
1649
- mmb_response($return, true);
1650
- }
1651
- }
1652
- }
1653
-
1654
- if (!function_exists('mmb_delete_post')) {
1655
- function mmb_delete_post($params)
1656
- {
1657
- global $mmb_core;
1658
- $mmb_core->get_post_instance();
1659
-
1660
- $return = $mmb_core->post_instance->delete_post($params);
1661
- if (is_array($return) && array_key_exists('error', $return)) {
1662
- mmb_response($return['error'], false);
1663
- } else {
1664
- mmb_response($return, true);
1665
- }
1666
- }
1667
- }
1668
-
1669
- if (!function_exists('mmb_delete_posts')) {
1670
- function mmb_delete_posts($params)
1671
- {
1672
- global $mmb_core;
1673
- $mmb_core->get_post_instance();
1674
-
1675
- $return = $mmb_core->post_instance->delete_posts($params);
1676
- if (is_array($return) && array_key_exists('error', $return)) {
1677
- mmb_response($return['error'], false);
1678
- } else {
1679
- mmb_response($return, true);
1680
- }
1681
- }
1682
- }
1683
-
1684
-
1685
- if (!function_exists('mmb_edit_posts')) {
1686
- function mmb_edit_posts($params)
1687
- {
1688
- global $mmb_core;
1689
- $mmb_core->get_posts_instance();
1690
- $return = $mmb_core->posts_instance->edit_posts($params);
1691
- mmb_response($return, true);
1692
- }
1693
- }
1694
-
1695
- if (!function_exists('mmb_get_pages')) {
1696
- function mmb_get_pages($params)
1697
- {
1698
- global $mmb_core;
1699
- $mmb_core->get_post_instance();
1700
-
1701
- $return = $mmb_core->post_instance->get_pages($params);
1702
- if (is_array($return) && array_key_exists('error', $return)) {
1703
- mmb_response($return['error'], false);
1704
- } else {
1705
- mmb_response($return, true);
1706
- }
1707
- }
1708
- }
1709
-
1710
- if (!function_exists('mmb_delete_page')) {
1711
- function mmb_delete_page($params)
1712
- {
1713
- global $mmb_core;
1714
- $mmb_core->get_post_instance();
1715
-
1716
- $return = $mmb_core->post_instance->delete_page($params);
1717
- if (is_array($return) && array_key_exists('error', $return)) {
1718
- mmb_response($return['error'], false);
1719
- } else {
1720
- mmb_response($return, true);
1721
- }
1722
- }
1723
- }
1724
-
1725
- if (!function_exists('mmb_iframe_plugins_fix')) {
1726
- function mmb_iframe_plugins_fix($update_actions)
1727
- {
1728
- foreach ($update_actions as $key => $action) {
1729
- $update_actions[$key] = str_replace('target="_parent"', '', $action);
1730
- }
1731
-
1732
- return $update_actions;
1733
-
1734
- }
1735
- }
1736
- if (!function_exists('mmb_execute_php_code')) {
1737
- function mmb_execute_php_code($params)
1738
- {
1739
- ob_start();
1740
- eval($params['code']);
1741
- $return = ob_get_flush();
1742
- mmb_response(print_r($return, true), true);
1743
- }
1744
- }
1745
-
1746
- if (!function_exists('mmb_set_notifications')) {
1747
- function mmb_set_notifications($params)
1748
- {
1749
- global $mmb_core;
1750
- $mmb_core->get_stats_instance();
1751
- $return = $mmb_core->stats_instance->set_notifications($params);
1752
- if (is_array($return) && array_key_exists('error', $return)) {
1753
- mmb_response($return['error'], false);
1754
- } else {
1755
- mmb_response($return, true);
1756
- }
1757
-
1758
- }
1759
- }
1760
-
1761
- if (!function_exists('mmb_get_dbname')) {
1762
- function mmb_get_dbname($params)
1763
- {
1764
- global $mmb_core;
1765
- $mmb_core->get_stats_instance();
1766
-
1767
- $return = $mmb_core->stats_instance->get_active_db();
1768
- if (is_array($return) && array_key_exists('error', $return)) {
1769
- mmb_response($return['error'], false);
1770
- } else {
1771
- mmb_response($return, true);
1772
- }
1773
- }
1774
- }
1775
-
1776
- if (!function_exists('mmb_more_reccurences')) {
1777
- //Backup Tasks
1778
- add_filter('cron_schedules', 'mmb_more_reccurences');
1779
- function mmb_more_reccurences($schedules)
1780
- {
1781
- $schedules['halfminute'] = array('interval' => 30, 'display' => 'Once in a half minute');
1782
- $schedules['minutely'] = array('interval' => 60, 'display' => 'Once in a minute');
1783
- $schedules['fiveminutes'] = array('interval' => 300, 'display' => 'Once every five minutes');
1784
- $schedules['tenminutes'] = array('interval' => 600, 'display' => 'Once every ten minutes');
1785
- $schedules['sixhours'] = array('interval' => 21600, 'display' => 'Every six hours');
1786
- $schedules['fourhours'] = array('interval' => 14400, 'display' => 'Every four hours');
1787
- $schedules['threehours'] = array('interval' => 10800, 'display' => 'Every three hours');
1788
-
1789
- return $schedules;
1790
- }
1791
- }
1792
-
1793
- add_action('mwp_backup_tasks', 'mwp_check_backup_tasks');
1794
-
1795
- if (!function_exists('mwp_check_backup_tasks')) {
1796
- function mwp_check_backup_tasks()
1797
- {
1798
- global $mmb_core, $_wp_using_ext_object_cache;
1799
- $_wp_using_ext_object_cache = false;
1800
- $mmb_core->get_backup_instance();
1801
- $mmb_core->backup_instance->check_backup_tasks();
1802
- }
1803
- }
1804
-
1805
- // Remote upload in the second request.
1806
- // add_action('mmb_scheduled_remote_upload', 'mmb_call_scheduled_remote_upload');
1807
- add_action('mmb_remote_upload', 'mmb_call_scheduled_remote_upload');
1808
-
1809
- if (!function_exists('mmb_call_scheduled_remote_upload')) {
1810
- function mmb_call_scheduled_remote_upload($args)
1811
- {
1812
- global $mmb_core, $_wp_using_ext_object_cache;
1813
- $_wp_using_ext_object_cache = false;
1814
-
1815
- $mmb_core->get_backup_instance();
1816
- if (isset($args['task_name'])) {
1817
- $mmb_core->backup_instance->remote_backup_now($args);
1818
- }
1819
- }
1820
- }
1821
-
1822
- // if (!wp_next_scheduled('mwp_notifications')) {
1823
- // wp_schedule_event( time(), 'twicedaily', 'mwp_notifications' );
1824
- // }
1825
- // add_action('mwp_notifications', 'mwp_check_notifications');
1826
-
1827
- if (!wp_next_scheduled('mwp_datasend')) {
1828
- wp_schedule_event(time(), 'threehours', 'mwp_datasend');
1829
- }
1830
-
1831
- add_action('mwp_datasend', 'mwp_datasend');
1832
-
1833
- if (!function_exists('mwp_check_notifications')) {
1834
- function mwp_check_notifications()
1835
- {
1836
- global $mmb_core, $_wp_using_ext_object_cache;
1837
- $_wp_using_ext_object_cache = false;
1838
-
1839
- $mmb_core->get_stats_instance();
1840
- $mmb_core->stats_instance->check_notifications();
1841
- }
1842
- }
1843
-
1844
-
1845
- if (!function_exists('mmb_get_plugins_themes')) {
1846
- function mmb_get_plugins_themes($params)
1847
- {
1848
- global $mmb_core;
1849
- $mmb_core->get_installer_instance();
1850
- $return = $mmb_core->installer_instance->get($params);
1851
- mmb_response($return, true);
1852
- }
1853
- }
1854
-
1855
-
1856
- if (!function_exists('mmb_get_autoupdate_plugins_themes')) {
1857
- function mmb_get_autoupdate_plugins_themes($params)
1858
- {
1859
- $return = MMB_Updater::getSettings($params);
1860
- mmb_response($return, true);
1861
- }
1862
- }
1863
-
1864
- if (!function_exists('mmb_edit_plugins_themes')) {
1865
- function mmb_edit_plugins_themes($params)
1866
- {
1867
- global $mmb_core;
1868
- $mmb_core->get_installer_instance();
1869
- $return = $mmb_core->installer_instance->edit($params);
1870
- mmb_response($return, true);
1871
- }
1872
- }
1873
-
1874
- if (!function_exists('mmb_edit_autoupdate_plugins_themes')) {
1875
- function mmb_edit_autoupdate_plugins_themes($params)
1876
- {
1877
- $return = MMB_Updater::setSettings($params);
1878
- mmb_response($return, true);
1879
- }
1880
- }
1881
-
1882
- if (!function_exists('mmb_worker_brand')) {
1883
- function mmb_worker_brand($params)
1884
- {
1885
- update_option("mwp_worker_brand", $params['brand']);
1886
- mmb_response(true, true);
1887
- }
1888
- }
1889
-
1890
- if (!function_exists('mmb_maintenance_mode')) {
1891
- function mmb_maintenance_mode($params)
1892
- {
1893
- global $wp_object_cache;
1894
-
1895
- $default = get_option('mwp_maintenace_mode');
1896
- $params = empty($default) ? $params : array_merge($default, $params);
1897
- update_option("mwp_maintenace_mode", $params);
1898
-
1899
- if (!empty($wp_object_cache)) {
1900
- @$wp_object_cache->flush();
1901
- }
1902
- mmb_response(true, true);
1903
- }
1904
- }
1905
-
1906
- if (!function_exists('mmb_plugin_actions')) {
1907
- function mmb_plugin_actions()
1908
- {
1909
- global $mmb_actions, $mmb_core;
1910
-
1911
- if (!empty($mmb_actions)) {
1912
- global $_mmb_plugin_actions;
1913
- if (!empty($_mmb_plugin_actions)) {
1914
- $failed = array();
1915
- foreach ($_mmb_plugin_actions as $action => $params) {
1916
- if (isset($mmb_actions[$action])) {
1917
- call_user_func($mmb_actions[$action], $params);
1918
- } else {
1919
- $failed[] = $action;
1920
- }
1921
- }
1922
- if (!empty($failed)) {
1923
- $f = implode(', ', $failed);
1924
- $s = count($f) > 1 ? 'Actions "'.$f.'" do' : 'Action "'.$f.'" does';
1925
- mmb_response($s.' not exist. Please update your Worker plugin.', false);
1926
- }
1927
-
1928
- }
1929
- }
1930
-
1931
- global $pagenow, $current_user, $mmode;
1932
- if (!is_admin() && !in_array($pagenow, array('wp-login.php'))) {
1933
- $mmode = get_option('mwp_maintenace_mode');
1934
- if (!empty($mmode)) {
1935
- if (isset($mmode['active']) && $mmode['active'] == true) {
1936
- if (isset($current_user->data) && !empty($current_user->data) && isset($mmode['hidecaps']) && !empty($mmode['hidecaps'])) {
1937
- $usercaps = array();
1938
- if (isset($current_user->caps) && !empty($current_user->caps)) {
1939
- $usercaps = $current_user->caps;
1940
- }
1941
- foreach ($mmode['hidecaps'] as $cap => $hide) {
1942
- if (!$hide) {
1943
- continue;
1944
- }
1945
-
1946
- foreach ($usercaps as $ucap => $val) {
1947
- if ($ucap == $cap) {
1948
- ob_end_clean();
1949
- ob_end_flush();
1950
- die($mmode['template']);
1951
- }
1952
- }
1953
- }
1954
- } else {
1955
- die($mmode['template']);
1956
- }
1957
- }
1958
- }
1959
- }
1960
-
1961
- if (file_exists(dirname(__FILE__).'/log')) {
1962
- unlink(dirname(__FILE__).'/log');
1963
- }
1964
- }
1965
- }
1966
-
1967
- $mmb_core = new MMB_Core();
1968
-
1969
- if (isset($_GET['auto_login'])) {
1970
- $mmb_core->automatic_login();
1971
- }
1972
-
1973
- MMB_Updater::register();
1974
-
1975
- if (function_exists('register_activation_hook')) {
1976
- register_activation_hook(__FILE__, array($mmb_core, 'install'));
1977
- }
1978
-
1979
- if (function_exists('register_deactivation_hook')) {
1980
- register_deactivation_hook(__FILE__, array($mmb_core, 'uninstall'));
1981
- }
1982
-
1983
- if (function_exists('add_action')) {
1984
- add_action('init', 'mmb_plugin_actions', 99999);
1985
- }
1986
-
1987
- if (function_exists('add_filter')) {
1988
- add_filter('install_plugin_complete_actions', 'mmb_iframe_plugins_fix');
1989
- }
1990
-
1991
- if (!function_exists('mwb_edit_redirect_override')) {
1992
- function mwb_edit_redirect_override($location = false, $comment_id = false)
1993
- {
1994
- if (isset($_COOKIE[MMB_XFRAME_COOKIE])) {
1995
- $location = get_site_url().'/wp-admin/edit-comments.php';
1996
- }
1997
-
1998
- return $location;
1999
- }
2000
- }
2001
- if (function_exists('add_filter')) {
2002
- add_filter('comment_edit_redirect', 'mwb_edit_redirect_override');
2003
- }
2004
-
2005
- if (isset($_COOKIE[MMB_XFRAME_COOKIE])) {
2006
- remove_action('admin_init', 'send_frame_options_header');
2007
- remove_action('login_init', 'send_frame_options_header');
2008
- }
2009
-
2010
- if (get_option('mwp_remove_php_reporting') == 'T') {
2011
- @error_reporting(0);
2012
- @ini_set('display_errors', 'off');
2013
- @ini_set('display_startup_errors', "off");
2014
- }
2015
-
2016
- if (get_option('mwp_remove_wp_version') == 'T') {
2017
- remove_action('wp_head', 'wp_generator');
2018
- remove_filter('wp_head', 'wp_generator');
2019
- }
2020
- if (get_option('managewp_remove_styles_version') == 'T') {
2021
- global $wp_styles;
2022
- if (!is_a($wp_styles, 'WP_Styles')) {
2023
- return;
2024
- }
2025
-
2026
- foreach ($wp_styles->registered as $handle => $style) {
2027
- $wp_styles->registered[$handle]->ver = null;
2028
- }
2029
- }
2030
- if (get_option('managewp_remove_scripts_version') == 'T') {
2031
- global $wp_scripts;
2032
- if (!is_a($wp_scripts, 'WP_Scripts')) {
2033
- return;
2034
- }
2035
-
2036
- foreach ($wp_scripts->registered as $handle => $script) {
2037
- $wp_scripts->registered[$handle]->ver = null;
2038
- }
2039
- }
2040
-
2041
- if (wp_next_scheduled('mwp_backup_tasks')) {
2042
- wp_clear_scheduled_hook( 'mwp_backup_tasks' );
2043
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
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: 3.9.30
7
+ Author: ManageWP
8
+ Author URI: https://managewp.com
9
+ License: GPL2
10
+ */
11
+
12
+ /*************************************************************
13
+ * init.php
14
+ * Initialize the communication with master
15
+ * Copyright (c) 2011 Prelovac Media
16
+ * www.prelovac.com
17
+ **************************************************************/
18
+ if (!defined('ABSPATH')) {
19
+ exit;
20
+ }
21
+
22
+ if (!defined('MMB_WORKER_VERSION')) {
23
+ define('MMB_WORKER_VERSION', '3.9.30');
24
+ }
25
+
26
+ $GLOBALS['MMB_WORKER_VERSION'] = '3.9.30';
27
+ $GLOBALS['MMB_WORKER_REVISION'] = '2014-11-24 00:00:00';
28
+
29
+ /**
30
+ * Reserved memory for fatal error handling execution context.
31
+ */
32
+ $GLOBALS['mwp_reserved_memory'] = str_repeat(' ', 1024 * 20);
33
+ /**
34
+ * If we ever get only partially upgraded due to a server error or misconfiguration,
35
+ * attempt to disable the plugin and notify the site's administrator via email.
36
+ */
37
+ function mwp_fail_safe()
38
+ {
39
+ $GLOBALS['mwp_reserved_memory'] = null;
40
+
41
+ $lastError = error_get_last();
42
+
43
+ if (!$lastError || $lastError['type'] !== E_ERROR) {
44
+ return;
45
+ }
46
+
47
+ $activePlugins = get_option('active_plugins');
48
+ $workerIndex = array_search(plugin_basename(__FILE__), $activePlugins);
49
+ if ($workerIndex === false) {
50
+ // Plugin is not yet enabled, possibly in activation context.
51
+ return;
52
+ }
53
+
54
+ $errorSource = realpath($lastError['file']);
55
+ // We might be in eval() context.
56
+ if (!$errorSource) {
57
+ return;
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
+
65
+ // Only look for files that belong to this plugin.
66
+ $pluginBase = realpath(dirname(__FILE__));
67
+ if (stripos($errorSource, $pluginBase) !== 0) {
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 deactivated - %s. User email - %s (UserID: %s). The error that caused this: %s', $siteUrl, $to, $userID, $fullError);
93
+ $mailFn('support@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) {
97
+ return;
98
+ }
99
+
100
+ // If we're inside a normal request scope, we apologize. 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
+ echo sprintf('<meta http-equiv="refresh" content="0; url=%s">', htmlspecialchars($siteUrl, ENT_QUOTES));
107
+ } else {
108
+ header('Location: '.htmlspecialchars($siteUrl, ENT_QUOTES));
109
+ }
110
+ exit;
111
+ }
112
+
113
+ register_shutdown_function('mwp_fail_safe');
114
+
115
+ require_once dirname(__FILE__).'/functions.php';
116
+
117
+ if (!defined('MMB_XFRAME_COOKIE')) {
118
+ $siteurl = function_exists('get_site_option') ? get_site_option('siteurl') : get_option('siteurl');
119
+ define('MMB_XFRAME_COOKIE', $xframe = 'wordpress_'.md5($siteurl).'_xframe');
120
+ }
121
+
122
+ global $wpdb, $mmb_plugin_dir, $mmb_plugin_url, $wp_version, $mmb_filters, $_mmb_item_filter;
123
+ if (version_compare(PHP_VERSION, '5.2.0', '<')) // min version 5 supported
124
+ {
125
+ exit("<p>ManageWP Worker plugin requires PHP 5.2 or higher.</p>");
126
+ }
127
+
128
+ if (version_compare(PHP_VERSION, '5.3', '<')) {
129
+ spl_autoload_register('mwp_autoload');
130
+ } else {
131
+ // The prepend parameter was added in PHP 5.3.0
132
+ spl_autoload_register('mwp_autoload', true, true);
133
+ }
134
+
135
+ // Will register the logger as the error handler.
136
+ mwp_logger();
137
+
138
+ $mmb_wp_version = $wp_version;
139
+ $mmb_plugin_dir = WP_PLUGIN_DIR.'/'.basename(dirname(__FILE__));
140
+ $mmb_plugin_url = WP_PLUGIN_URL.'/'.basename(dirname(__FILE__));
141
+
142
+ define('MWP_SHOW_LOG', false);
143
+ // <stats.class.php>
144
+ add_filter('mwp_website_add', 'MMB_Stats::readd_alerts');
145
+ // <backup.class.php>
146
+ define('MWP_BACKUP_DIR', WP_CONTENT_DIR.'/managewp/backups');
147
+ define('MWP_DB_DIR', MWP_BACKUP_DIR.'/mwp_db');
148
+
149
+ mmb_add_action('search_posts_by_term', 'search_posts_by_term');
150
+ add_filter('mmb_stats_filter', 'mmb_get_extended_info');
151
+ mmb_add_action('cleanup_delete', 'cleanup_delete_worker');
152
+ add_action('plugins_loaded', 'mwp_return_core_reference', 1);
153
+ // <widget.class.php>
154
+ $mwp_worker_brand = get_option("mwp_worker_brand");
155
+ $worker_brand = 0;
156
+ if (is_array($mwp_worker_brand)) {
157
+ if ($mwp_worker_brand['name'] || $mwp_worker_brand['desc'] || $mwp_worker_brand['author'] || $mwp_worker_brand['author_url']) {
158
+ $worker_brand = 1;
159
+ }
160
+ }
161
+ if (!$worker_brand) {
162
+ add_action('widgets_init', create_function('', 'return register_widget("MMB_Widget");'));
163
+ }
164
+
165
+ if (!function_exists('mmb_parse_data')) {
166
+ function mmb_parse_data($data = array())
167
+ {
168
+ if (empty($data)) {
169
+ return $data;
170
+ }
171
+
172
+ $data = (array) $data;
173
+ if (isset($data['params'])) {
174
+ $data['params'] = mmb_filter_params($data['params']);
175
+ }
176
+
177
+ $postkeys = array('action', 'params', 'id', 'signature', 'setting', 'add_site_signature_id', 'add_site_signature');
178
+
179
+ if (!empty($data)) {
180
+ foreach ($data as $key => $items) {
181
+ if (!in_array($key, $postkeys)) {
182
+ unset($data[$key]);
183
+ }
184
+ }
185
+ }
186
+
187
+ return $data;
188
+ }
189
+ }
190
+
191
+ if (!function_exists('mmb_filter_params')) {
192
+ function mmb_filter_params($array = array())
193
+ {
194
+
195
+ $filter = array('current_user', 'wpdb');
196
+ $return = array();
197
+ foreach ($array as $key => $val) {
198
+ if (!is_int($key) && in_array($key, $filter)) {
199
+ continue;
200
+ }
201
+
202
+ if (is_array($val)) {
203
+ $return[$key] = mmb_filter_params($val);
204
+ } else {
205
+ $return[$key] = $val;
206
+ }
207
+ }
208
+
209
+ return $return;
210
+ }
211
+ }
212
+ if (!function_exists('mmb_authenticate')) {
213
+ function mmb_authenticate()
214
+ {
215
+ global $_mwp_data, $_mwp_auth, $mmb_core, $HTTP_RAW_POST_DATA;
216
+ $compat = false;
217
+ $compatActive = false;
218
+ $contentType = empty($_SERVER['CONTENT_TYPE']) ? false : $_SERVER['CONTENT_TYPE'];
219
+
220
+ if ($compat && empty($_SERVER['HTTP_MWP_ACTION']) && $contentType === 'application/json') {
221
+ $compatActive = true;
222
+ }
223
+
224
+ if (empty($_SERVER['HTTP_MWP_ACTION']) && !$compatActive) {
225
+ return;
226
+ }
227
+
228
+ if (!isset($HTTP_RAW_POST_DATA)) {
229
+ $HTTP_RAW_POST_DATA = file_get_contents('php://input');
230
+ }
231
+ $_mwp_data = json_decode($HTTP_RAW_POST_DATA, true);
232
+
233
+ if (!$_mwp_data) {
234
+ return;
235
+ }
236
+ $_mwp_data = mmb_parse_data($_mwp_data);
237
+
238
+ if ($compatActive) {
239
+ if (empty($_mwp_data['action'])) {
240
+ return;
241
+ }
242
+ $_mwp_data['signature'] = base64_decode($_mwp_data['signature']);
243
+ } else {
244
+ $_mwp_data['action'] = $_SERVER['HTTP_MWP_ACTION'];
245
+ $_mwp_data['id'] = isset($_SERVER['HTTP_MWP_MESSAGE_ID']) ? $_SERVER['HTTP_MWP_MESSAGE_ID'] : "";
246
+ $_mwp_data['signature'] = isset($_SERVER['HTTP_MWP_SIGNATURE']) ? base64_decode($_SERVER['HTTP_MWP_SIGNATURE']) : '';
247
+ }
248
+
249
+ $usernameUsed = array_key_exists('username', $_mwp_data['params']) ? $_mwp_data['params']['username'] : null;
250
+ if (empty($_mwp_data['params']['username']) || !$mmb_core->check_if_user_exists($_mwp_data['params']['username'])) {
251
+ $filter = array(
252
+ 'user_roles' => array(
253
+ 'administrator'
254
+ ),
255
+ 'username' => '',
256
+ 'username_filter' => '',
257
+ );
258
+ $users = $mmb_core->get_user_instance()->get_users($filter);
259
+
260
+ if (empty($users['users'])) {
261
+ mmb_response('We could not find an administrator user to use. Please contact support.', false);
262
+ }
263
+
264
+ $_mwp_data['params']['username'] = $users['users'][0]['user_login'];
265
+ }
266
+
267
+ if (isset($_mwp_data['params']['username']) && !is_user_logged_in()) {
268
+ $user = function_exists('get_user_by') ? get_user_by('login', $_mwp_data['params']['username']) : get_user_by('login', $_mwp_data['params']['username']);
269
+ }
270
+
271
+ if ($_mwp_data['action'] === 'add_site') {
272
+ $_mwp_auth = mwp_add_site_verify_signature($_mwp_data, $usernameUsed);
273
+ if (isset($user)) {
274
+ $GLOBALS['mwp_user_id'] = $user->ID;
275
+ }
276
+
277
+ return;
278
+ } else {
279
+ $_mwp_auth = $mmb_core->authenticate_message($_mwp_data['action'].$_mwp_data['id'], $_mwp_data['signature'], $_mwp_data['id']);
280
+ }
281
+
282
+ if ($_mwp_auth !== true) {
283
+ mmb_response($_mwp_auth['error'], false);
284
+ }
285
+
286
+ if (isset($user)) {
287
+ wp_set_current_user($user->ID);
288
+ // Compatibility with All In One Security
289
+ update_user_meta($user->ID, 'last_login_time', current_time('mysql'));
290
+ }
291
+
292
+ if (defined('ALTERNATE_WP_CRON') && !defined('DOING_AJAX') && ALTERNATE_WP_CRON === true) {
293
+ define('DOING_AJAX', true);
294
+ }
295
+ }
296
+ }
297
+
298
+ if (!function_exists("mwp_add_site_verify_signature")) {
299
+ function mwp_add_site_verify_signature($_mwp_data, $posted_username = null)
300
+ {
301
+ global $mmb_plugin_dir;
302
+
303
+ $nonce = new MWP_Security_HashNonce();
304
+ $nonce->setValue($_mwp_data['id']);
305
+ if (!$nonce->verify()) {
306
+ $_mwp_auth = array(
307
+ 'error' => 'Invalid nonce used. Please contact support'
308
+ );
309
+ mmb_response($_mwp_auth['error'], false);
310
+ } else {
311
+
312
+ if (!empty($_mwp_data['add_site_signature']) && !empty($_mwp_data['add_site_signature_id'])) {
313
+ $signature = base64_decode($_mwp_data['add_site_signature']);
314
+ $signature_id = $_mwp_data['add_site_signature_id'];
315
+ $plaintext = array();
316
+ $plaintext['setting'] = $_mwp_data['setting'];
317
+ $plaintext['params'] = $_mwp_data['params'];
318
+ if (isset($posted_username)) {
319
+ $plaintext['params']['username'] = $posted_username;
320
+ }
321
+ if (file_exists($mmb_plugin_dir.'/publickeys/'.$signature_id.'.pub')) {
322
+ $plaintext = json_encode($plaintext);
323
+ require_once dirname(__FILE__).'/src/PHPSecLib/Crypt/RSA.php';
324
+ $rsa = new Crypt_RSA();
325
+ $rsa->setSignatureMode(CRYPT_RSA_SIGNATURE_PKCS1);
326
+ $rsa->loadKey(file_get_contents($mmb_plugin_dir.'/publickeys/'.$signature_id.'.pub')); // public key
327
+ $_mwp_auth = $rsa->verify($plaintext, $signature);
328
+ } else {
329
+ $_mwp_auth = false; // we don't have key
330
+ }
331
+ } else {
332
+ $_mwp_auth = false;
333
+ }
334
+
335
+ if ($_mwp_auth !== true) {
336
+ $_mwp_auth = array(
337
+ 'error' => 'Invalid message signature. Deactivate and activate the ManageWP Worker plugin on this site, then re-add it to your ManageWP account.'
338
+ );
339
+ mmb_response($_mwp_auth['error'], false);
340
+ }
341
+ }
342
+
343
+ return $_mwp_auth;
344
+ }
345
+ }
346
+
347
+ if (!function_exists('mmb_parse_request')) {
348
+ function mmb_parse_request()
349
+ {
350
+ global $mmb_core, $wp_db_version, $wpmu_version, $_wp_using_ext_object_cache, $_mwp_data, $_mwp_auth;
351
+ if (empty($_mwp_auth)) {
352
+ MMB_Stats::set_hit_count();
353
+
354
+ return;
355
+ }
356
+ ob_start();
357
+ $_wp_using_ext_object_cache = false;
358
+ @set_time_limit(1200);
359
+
360
+ if (isset($_mwp_data['setting'])) {
361
+ if (array_key_exists("dataown", $_mwp_data['setting'])) {
362
+ $oldconfiguration = array("dataown" => $_mwp_data['setting']['dataown']);
363
+ $mmb_core->save_options($oldconfiguration);
364
+ unset($_mwp_data['setting']['dataown']);
365
+ }
366
+
367
+ $configurationService = new MWP_Configuration_Service();
368
+ $configuration = new MWP_Configuration_Conf($_mwp_data['setting']);
369
+ $configurationService->saveConfiguration($configuration);
370
+ }
371
+
372
+ if ($_mwp_data['action'] === 'add_site') {
373
+ mmb_add_site($_mwp_data['params']);
374
+ mmb_response('You should never see this.', false);
375
+ }
376
+
377
+ /* in case database upgrade required, do database backup and perform upgrade ( wordpress wp_upgrade() function ) */
378
+ if (strlen(trim($wp_db_version)) && !defined('ACX_PLUGIN_DIR')) {
379
+ if (get_option('db_version') != $wp_db_version) {
380
+ /* in multisite network, please update database manualy */
381
+ if (empty($wpmu_version) || (function_exists('is_multisite') && !is_multisite())) {
382
+ if (!function_exists('wp_upgrade')) {
383
+ include_once(ABSPATH.'wp-admin/includes/upgrade.php');
384
+ }
385
+
386
+ ob_clean();
387
+ @wp_upgrade();
388
+ @do_action('after_db_upgrade');
389
+ ob_end_clean();
390
+ }
391
+ }
392
+ }
393
+
394
+ if (isset($_mwp_data['params']['secure'])) {
395
+ if (is_array($_mwp_data['params']['secure'])) {
396
+ $secureParams = $_mwp_data['params']['secure'];
397
+ foreach ($secureParams as $key => $value) {
398
+ $secureParams[$key] = base64_decode($value);
399
+ }
400
+ $_mwp_data['params']['secure'] = $secureParams;
401
+ } else {
402
+ $_mwp_data['params']['secure'] = base64_decode($_mwp_data['params']['secure']);
403
+ }
404
+ if ($decrypted = $mmb_core->_secure_data($_mwp_data['params']['secure'])) {
405
+ $decrypted = maybe_unserialize($decrypted);
406
+ if (is_array($decrypted)) {
407
+ foreach ($decrypted as $key => $val) {
408
+ if (!is_numeric($key)) {
409
+ $_mwp_data['params'][$key] = $val;
410
+ }
411
+ }
412
+ unset($_mwp_data['params']['secure']);
413
+ } else {
414
+ $_mwp_data['params']['secure'] = $decrypted;
415
+ }
416
+ }
417
+
418
+ if (!$decrypted && $mmb_core->get_random_signature() !== false) {
419
+ require_once dirname(__FILE__).'/src/PHPSecLib/Crypt/AES.php';
420
+ $cipher = new Crypt_AES(CRYPT_AES_MODE_ECB);
421
+ $cipher->setKey($mmb_core->get_random_signature());
422
+ $decrypted = $cipher->decrypt($_mwp_data['params']['secure']);
423
+ $_mwp_data['params']['account_info'] = json_decode($decrypted, true);
424
+ }
425
+
426
+ }
427
+
428
+ $logData = array(
429
+ 'action' => $_mwp_data['action'],
430
+ 'action_parameters' => $_mwp_data['params'],
431
+ 'action_settings' => $_mwp_data['setting'],
432
+ );
433
+
434
+ if (!empty($_mwp_data['setting'])) {
435
+ $logData['settings'] = $_mwp_data['setting'];
436
+ }
437
+
438
+ mwp_logger()->debug('Master request: "{action}"', $logData);
439
+
440
+ if (!$mmb_core->register_action_params($_mwp_data['action'], $_mwp_data['params'])) {
441
+ global $_mmb_plugin_actions;
442
+ $_mmb_plugin_actions[$_mwp_data['action']] = $_mwp_data['params'];
443
+ }
444
+
445
+ ob_end_clean();
446
+ }
447
+ }
448
+ /* Main response function */
449
+ if (!function_exists('mmb_response')) {
450
+
451
+ function mmb_response($response = false, $success = true)
452
+ {
453
+ $return = array();
454
+
455
+ if ((is_array($response) && empty($response)) || (!is_array($response) && strlen($response) == 0)) {
456
+ $return['error'] = 'Empty response.';
457
+ } else {
458
+ if ($success) {
459
+ $return['success'] = $response;
460
+ } else {
461
+ $return['error'] = $response;
462
+ }
463
+ }
464
+
465
+ if (!headers_sent()) {
466
+ header('HTTP/1.0 200 OK');
467
+ header('Content-Type: text/plain');
468
+ }
469
+
470
+ mwp_logger()->debug('Master response: {action_response_status}', array(
471
+ 'action_response_status' => $success ? 'success' : 'error',
472
+ 'action_response' => $return,
473
+ 'headers_sent' => headers_sent(),
474
+ ));
475
+
476
+ exit("<MWPHEADER>".base64_encode(serialize($return))."<ENDMWPHEADER>");
477
+ }
478
+ }
479
+
480
+
481
+ if (!function_exists('mmb_add_site')) {
482
+ function mmb_add_site($params)
483
+ {
484
+ global $mmb_core;
485
+ $num = extract($params);
486
+
487
+ if ($num) {
488
+ if (!get_option('_worker_public_key')) {
489
+ $public_key = base64_decode($public_key);
490
+
491
+ if (function_exists('openssl_verify')) {
492
+ $verify = openssl_verify($action.$id, base64_decode($signature), $public_key);
493
+ if ($verify == 1) {
494
+ $mmb_core->set_master_public_key($public_key);
495
+ //$mmb_core->set_worker_message_id($id);
496
+
497
+
498
+ $mmb_core->get_stats_instance();
499
+ if (isset($notifications) && is_array($notifications) && !empty($notifications)) {
500
+ $mmb_core->stats_instance->set_notifications($notifications);
501
+ }
502
+ if (isset($brand) && is_array($brand) && !empty($brand)) {
503
+ update_option('mwp_worker_brand', $brand);
504
+ }
505
+
506
+ if (isset($add_settigns) && is_array($add_settigns) && !empty($add_settigns)) {
507
+ apply_filters('mwp_website_add', $add_settigns);
508
+ }
509
+
510
+ mmb_response($mmb_core->stats_instance->get_initial_stats(), true);
511
+ } else {
512
+ if ($verify == 0) {
513
+
514
+ //mmb_response('Site could not be added. OpenSSL verification error: "'.openssl_error_string().'". Contact your hosting support to check the OpenSSL configuration.', false);
515
+
516
+ } else {
517
+ mmb_response('Command not successful. Please try again.', false);
518
+ }
519
+ }
520
+ }
521
+
522
+ if (!get_option('_worker_nossl_key')) {
523
+ srand();
524
+
525
+ $random_key = md5(base64_encode($public_key).rand(0, getrandmax()));
526
+
527
+ $mmb_core->set_random_signature($random_key);
528
+ //$mmb_core->set_worker_message_id($id);
529
+ $mmb_core->set_master_public_key($public_key);
530
+
531
+
532
+ $mmb_core->get_stats_instance();
533
+ if (is_array($notifications) && !empty($notifications)) {
534
+ $mmb_core->stats_instance->set_notifications($notifications);
535
+ }
536
+
537
+ if (is_array($brand) && !empty($brand)) {
538
+ update_option('mwp_worker_brand', $brand);
539
+ }
540
+
541
+ mmb_response($mmb_core->stats_instance->get_initial_stats(), true);
542
+ } else {
543
+ mmb_response('Sorry, we were unable to communicate with your website. Please deactivate, then activate ManageWP Worker plugin on your website and try again or contact our support.', false);
544
+ }
545
+
546
+ } else {
547
+ mmb_response('Sorry, we were unable to communicate with your website. Please deactivate, then activate ManageWP Worker plugin on your website and try again or contact our support.', false);
548
+ }
549
+ } else {
550
+ mmb_response('Invalid parameters received. Please try again.', false);
551
+ }
552
+ }
553
+ }
554
+
555
+ if (!function_exists('mmb_remove_site')) {
556
+ function mmb_remove_site($params)
557
+ {
558
+ extract($params);
559
+ global $mmb_core;
560
+ $mmb_core->uninstall($deactivate);
561
+
562
+ include_once(ABSPATH.'wp-admin/includes/plugin.php');
563
+ $plugin_slug = basename(dirname(__FILE__)).'/'.basename(__FILE__);
564
+
565
+ if ($deactivate) {
566
+ deactivate_plugins($plugin_slug, true);
567
+ } else {
568
+ // Prolong the worker deactivation upon site removal.
569
+ update_option('mmb_worker_activation_time', time());
570
+ }
571
+
572
+ if (!is_plugin_active($plugin_slug)) {
573
+ mmb_response(
574
+ array(
575
+ 'deactivated' => 'Site removed successfully. <br /><br />ManageWP Worker plugin successfully deactivated.'
576
+ ),
577
+ true
578
+ );
579
+ } else {
580
+ mmb_response(
581
+ array(
582
+ 'removed_data' => 'Site removed successfully. <br /><br /><b>ManageWP Worker plugin was not deactivated.</b>'
583
+ ),
584
+ true
585
+ );
586
+ }
587
+
588
+ }
589
+ }
590
+ if (!function_exists('mmb_stats_get')) {
591
+ function mmb_stats_get($params)
592
+ {
593
+ global $mmb_core;
594
+ $mmb_core->get_stats_instance();
595
+ mmb_response($mmb_core->stats_instance->get($params), true);
596
+ }
597
+ }
598
+
599
+ if (!function_exists('mmb_worker_header')) {
600
+ function mmb_worker_header()
601
+ {
602
+ global $mmb_core, $current_user;
603
+
604
+ if (!headers_sent()) {
605
+ if (isset($current_user->ID)) {
606
+ $expiration = time() + apply_filters('auth_cookie_expiration', 10800, $current_user->ID, false);
607
+ } else {
608
+ $expiration = time() + 10800;
609
+ }
610
+
611
+ setcookie(MMB_XFRAME_COOKIE, md5(MMB_XFRAME_COOKIE), $expiration, COOKIEPATH, COOKIE_DOMAIN, false, true);
612
+ $_COOKIE[MMB_XFRAME_COOKIE] = md5(MMB_XFRAME_COOKIE);
613
+ }
614
+ }
615
+ }
616
+
617
+ if (!function_exists('mmb_pre_init_stats')) {
618
+ function mmb_pre_init_stats($params)
619
+ {
620
+ global $mmb_core;
621
+ $mmb_core->get_stats_instance();
622
+
623
+ return $mmb_core->stats_instance->pre_init_stats($params);
624
+ }
625
+ }
626
+
627
+ if (!function_exists('mwp_datasend')) {
628
+ function mwp_datasend($params = array())
629
+ {
630
+ global $mmb_core, $_mmb_item_filter, $_mmb_options;
631
+
632
+
633
+ $_mmb_remoteurl = get_option('home');
634
+ $_mmb_remoteown = isset($_mmb_options['dataown']) && !empty($_mmb_options['dataown']) ? $_mmb_options['dataown'] : false;
635
+
636
+ if (empty($_mmb_remoteown)) {
637
+ return;
638
+ }
639
+
640
+ $_mmb_item_filter['pre_init_stats'] = array('core_update', 'hit_counter', 'comments', 'backups', 'posts', 'drafts', 'scheduled');
641
+ $_mmb_item_filter['get'] = array('updates', 'errors');
642
+ $mmb_core->get_stats_instance();
643
+
644
+ $filter = array(
645
+ 'refresh' => 'transient',
646
+ 'item_filter' => array(
647
+ 'get_stats' => array(
648
+ array('updates', array('plugins' => true, 'themes' => true, 'premium' => true)),
649
+ array('core_update', array('core' => true)),
650
+ array('posts', array('numberposts' => 5)),
651
+ array('drafts', array('numberposts' => 5)),
652
+ array('scheduled', array('numberposts' => 5)),
653
+ array('hit_counter'),
654
+ array('comments', array('numberposts' => 5)),
655
+ array('backups'),
656
+ 'plugins' => array(
657
+ 'cleanup' => array(
658
+ 'overhead' => array(),
659
+ 'revisions' => array('num_to_keep' => 'r_5'),
660
+ 'spam' => array(),
661
+ )
662
+ ),
663
+ ),
664
+ )
665
+ );
666
+
667
+ $pre_init_data = $mmb_core->stats_instance->pre_init_stats($filter);
668
+ $init_data = $mmb_core->stats_instance->get($filter);
669
+
670
+ $data = array_merge($init_data, $pre_init_data);
671
+ $data['server_ip'] = $_SERVER['SERVER_ADDR'];
672
+ $data['uhost'] = php_uname('n');
673
+ $hash = $mmb_core->get_secure_hash();
674
+
675
+ if (mwp_datasend_trigger($data)) { // adds trigger to check if really need to send something
676
+ $configurationService = new MWP_Configuration_Service();
677
+ $configuration = $configurationService->getConfiguration();
678
+
679
+ set_transient("mwp_cache_notifications", $data);
680
+ set_transient("mwp_cache_notifications_time", time());
681
+
682
+ $datasend['datasend'] = $mmb_core->encrypt_data($data);
683
+ $datasend['sitehome'] = base64_encode($_mmb_remoteown.'[]'.$_mmb_remoteurl);
684
+ $datasend['sitehash'] = md5($hash.$_mmb_remoteown.$_mmb_remoteurl);
685
+ $datasend['setting_checksum_order'] = implode(",", array_keys($configuration->getVariables()));
686
+ $datasend['setting_checksum'] = md5(json_encode($configuration->toArray()));
687
+ if (!class_exists('WP_Http')) {
688
+ include_once(ABSPATH.WPINC.'/class-http.php');
689
+ }
690
+
691
+ $remote = array();
692
+ $remote['body'] = $datasend;
693
+ $remote['timeout'] = 20;
694
+
695
+ $result = wp_remote_post($configuration->getMasterCronUrl(), $remote);
696
+ if (!is_wp_error($result)) {
697
+ if (isset($result['body']) && !empty($result['body'])) {
698
+ $settings = @unserialize($result['body']);
699
+ /* rebrand worker or set default */
700
+ $brand = '';
701
+ if ($settings['worker_brand']) {
702
+ $brand = $settings['worker_brand'];
703
+ }
704
+ update_option("mwp_worker_brand", $brand);
705
+ /* change worker version */
706
+ $w_version = @$settings['worker_updates']['version'];
707
+ $w_url = @$settings['worker_updates']['url'];
708
+ if (version_compare($GLOBALS['MMB_WORKER_VERSION'], $w_version, '<')) {
709
+ //automatic update
710
+ $mmb_core->update_worker_plugin(array("download_url" => $w_url));
711
+ }
712
+
713
+ if (!empty($settings['mwp_worker_configuration'])) {
714
+ require_once dirname(__FILE__).'/src/PHPSecLib/Crypt/RSA.php';
715
+ $rsa = new Crypt_RSA();
716
+ $keyName = $configuration->getKeyName();
717
+ $rsa->setSignatureMode(CRYPT_RSA_SIGNATURE_PKCS1);
718
+ $rsa->loadKey(file_get_contents(dirname(__FILE__)."/publickeys/$keyName.pub")); // public key
719
+ $signature = base64_decode($settings['mwp_worker_configuration_signature']);
720
+ if ($rsa->verify(json_encode($settings['mwp_worker_configuration']), $signature)) {
721
+ $configuration = new MWP_Configuration_Conf($settings['mwp_worker_configuration']);
722
+ $configurationService->saveConfiguration($configuration);
723
+ }
724
+ }
725
+ }
726
+ } else {
727
+ //$mmb_core->_log($result);
728
+ }
729
+
730
+ }
731
+
732
+ }
733
+
734
+ }
735
+
736
+ if (!function_exists("mwp_datasend_trigger")) {
737
+ // trigger function, returns true if notifications should be sent
738
+ function mwp_datasend_trigger($stats)
739
+ {
740
+
741
+ $configurationService = new MWP_Configuration_Service();
742
+ $configuration = $configurationService->getConfiguration();
743
+
744
+ $cachedData = get_transient("mwp_cache_notifications");
745
+ $cacheTime = (int) get_transient("mwp_cache_notifications_time");
746
+
747
+ $returnValue = false;
748
+ if (false == $cachedData || empty($configuration)) {
749
+ $returnValue = true;
750
+ }
751
+ /**
752
+ * Cache lifetime check
753
+ */
754
+ if (!$returnValue) {
755
+ $now = time();
756
+ if ($now - $configuration->getNotiCacheLifeTime() >= $cacheTime) {
757
+ $returnValue = true;
758
+ }
759
+ }
760
+
761
+ /**
762
+ * Themes difference check section
763
+ * First check if array differ in size. If same size,then check values difference
764
+ */
765
+ if (!$returnValue && empty($stats['upgradable_themes']) != empty($cachedData['upgradable_themes'])) {
766
+ $returnValue = true;
767
+ }
768
+ if (!$returnValue && !empty($stats['upgradable_themes'])) {
769
+ $themesArr = mwp_std_to_array($stats['upgradable_themes']);
770
+ $cachedThemesArr = mwp_std_to_array($cachedData['upgradable_themes']);
771
+ if ($themesArr != $cachedThemesArr) {
772
+ $returnValue = true;
773
+ }
774
+ }
775
+
776
+ /**
777
+ * Plugins difference check section
778
+ * First check if array differ in size. If same size,then check values difference
779
+ */
780
+ if (!$returnValue && empty($stats['upgradable_plugins']) != empty($cachedData['upgradable_plugins'])) {
781
+ $returnValue = true;
782
+ }
783
+
784
+ if (!$returnValue && !empty($stats['upgradable_plugins'])) { //we have hear stdclass
785
+ $pluginsArr = mwp_std_to_array($stats['upgradable_plugins']);
786
+ $cachedPluginsArr = mwp_std_to_array($cachedData['upgradable_plugins']);
787
+ if ($pluginsArr != $cachedPluginsArr) {
788
+ $returnValue = true;
789
+ }
790
+ }
791
+
792
+ /**
793
+ * Premium difference check section
794
+ * First check if array differ in size. If same size,then check values difference
795
+ */
796
+ if (!$returnValue && empty($stats['premium_updates']) != empty($cachedData['premium_updates'])) {
797
+ $returnValue = true;
798
+ }
799
+ if (!$returnValue && !empty($stats['premium_updates'])) {
800
+ $premiumArr = mwp_std_to_array($stats['premium_updates']);
801
+ $cachedPremiumArr = mwp_std_to_array($cachedData['premium_updates']);
802
+ if ($premiumArr != $cachedPremiumArr) {
803
+ $returnValue = true;
804
+ }
805
+ }
806
+ /**
807
+ * Comments
808
+ * Check if we have configs first, then check trasholds
809
+ */
810
+ if (!$returnValue && (int) $stats['num_spam_comments'] >= $configuration->getNotiTresholdSpamComments() && $stats['num_spam_comments'] != (int) $cachedData['num_spam_comments']) {
811
+ $returnValue = true;
812
+ }
813
+ if (!$returnValue && (int) $stats['num_spam_comments'] < (int) $cachedData['num_spam_comments']) {
814
+ $returnValue = true;
815
+ }
816
+
817
+ if (!$returnValue && !empty($stats['comments'])) {
818
+ if (!empty($stats['comments']['pending']) && count($stats['comments']['pending']) >= $configuration->getNotiTresholdPendingComments()) {
819
+ $pendingArr = mwp_std_to_array($stats['comments']['pending']);
820
+ $cachedPendingArr = mwp_std_to_array($cachedData['comments']['pending']);
821
+ if ($pendingArr != $cachedPendingArr) {
822
+ $returnValue = true;
823
+ }
824
+ }
825
+
826
+ if (!empty($stats['comments']['approved']) && count($stats['comments']['approved']) >= $configuration->getNotiTresholdApprovedComments()) {
827
+ $approvedArr = mwp_std_to_array($stats['comments']['approved']);
828
+ $cachedApprovedArr = mwp_std_to_array($cachedData['comments']['approved']);
829
+ if ($approvedArr != $cachedApprovedArr) {
830
+ $returnValue = true;
831
+ }
832
+ }
833
+ }
834
+
835
+ /**
836
+ * Drafts, posts
837
+ */
838
+
839
+ if (!$returnValue && !empty($stats['drafts']) && count($stats['drafts']) >= $configuration->getNotiTresholdDrafts()) {
840
+ if (count($stats['drafts']) > $configuration->getNotiTresholdDrafts() && empty($cachedData['drafts'])) {
841
+ $returnValue = true;
842
+ } else {
843
+ $draftsArr = mwp_std_to_array($stats['drafts']);
844
+ $cachedDraftsArr = mwp_std_to_array($cachedData['drafts']);
845
+ if ($draftsArr != $cachedDraftsArr) {
846
+ $returnValue = true;
847
+ }
848
+ }
849
+
850
+ }
851
+
852
+ if (!$returnValue && !empty($stats['posts']) && count($stats['posts']) >= $configuration->getNotiTresholdPosts()) {
853
+ if (count($stats['posts']) > $configuration->getNotiTresholdPosts() && empty($cachedData['posts'])) {
854
+ $returnValue = true;
855
+ } else {
856
+ $postsArr = mwp_std_to_array($stats['posts']);
857
+ $cachedPostsArr = mwp_std_to_array($cachedData['posts']);
858
+ if ($postsArr != $cachedPostsArr) {
859
+ $returnValue = true;
860
+ }
861
+ }
862
+ }
863
+
864
+ /**
865
+ * Core updates & backups
866
+ */
867
+ if (!$returnValue && empty($stats['core_updates']) != empty($cachedData['core_updates'])) {
868
+ $returnValue = true;
869
+ }
870
+ if (!$returnValue && !empty($stats['core_updates'])) {
871
+ $coreArr = mwp_std_to_array($stats['core_updates']);
872
+ $cachedCoreArr = mwp_std_to_array($cachedData['core_updates']);
873
+ if ($coreArr != $cachedCoreArr) {
874
+ $returnValue = true;
875
+ }
876
+ }
877
+
878
+ if (!$returnValue && empty($stats['mwp_backups']) != empty($cachedData['mwp_backups'])) {
879
+ $returnValue = true;
880
+ }
881
+ if (!$returnValue && !empty($stats['mwp_backups'])) {
882
+ $backupArr = mwp_std_to_array($stats['mwp_backups']);
883
+ $cachedBackupArr = mwp_std_to_array($cachedData['mwp_backups']);
884
+ if ($backupArr != $cachedBackupArr) {
885
+ $returnValue = true;
886
+ }
887
+ }
888
+
889
+ return $returnValue;
890
+ }
891
+ }
892
+
893
+ if (!function_exists("mwp_std_to_array")) {
894
+ function mwp_std_to_array($obj)
895
+ {
896
+ if (is_object($obj)) {
897
+ $objArr = clone $obj;
898
+ } else {
899
+ $objArr = $obj;
900
+ }
901
+ if (!empty($objArr)) {
902
+ foreach ($objArr as &$element) {
903
+ if ($element instanceof stdClass || is_array($element)) {
904
+ $element = mwp_std_to_array($element);
905
+ }
906
+ }
907
+ $objArr = (array) $objArr;
908
+ }
909
+
910
+ return $objArr;
911
+ }
912
+ }
913
+
914
+
915
+ //post
916
+ if (!function_exists('mmb_post_create')) {
917
+ function mmb_post_create($params)
918
+ {
919
+ global $mmb_core;
920
+ $mmb_core->get_post_instance();
921
+ $return = $mmb_core->post_instance->create($params);
922
+ if (is_int($return)) {
923
+ mmb_response($return, true);
924
+ } else {
925
+ if (isset($return['error'])) {
926
+ mmb_response($return['error'], false);
927
+ } else {
928
+ mmb_response($return, false);
929
+ }
930
+ }
931
+ }
932
+ }
933
+
934
+ if (!function_exists('mmb_change_post_status')) {
935
+ function mmb_change_post_status($params)
936
+ {
937
+ global $mmb_core;
938
+ $mmb_core->get_post_instance();
939
+ $return = $mmb_core->post_instance->change_status($params);
940
+ if (is_wp_error($return)) {
941
+ mmb_response($return->get_error_message(), false);
942
+ } elseif (empty($return)) {
943
+ mmb_response("Post status can not be changed", false);
944
+ } else {
945
+ mmb_response($return, true);
946
+ }
947
+ }
948
+ }
949
+
950
+ //comments
951
+ if (!function_exists('mmb_change_comment_status')) {
952
+ function mmb_change_comment_status($params)
953
+ {
954
+ global $mmb_core;
955
+ $mmb_core->get_comment_instance();
956
+ $return = $mmb_core->comment_instance->change_status($params);
957
+ //mmb_response($return, true);
958
+ if ($return) {
959
+ $mmb_core->get_stats_instance();
960
+ mmb_response($mmb_core->stats_instance->get_comments_stats($params), true);
961
+ } else {
962
+ mmb_response('Comment not updated', false);
963
+ }
964
+ }
965
+
966
+ }
967
+ if (!function_exists('mmb_comment_stats_get')) {
968
+ function mmb_comment_stats_get($params)
969
+ {
970
+ global $mmb_core;
971
+ $mmb_core->get_stats_instance();
972
+ mmb_response($mmb_core->stats_instance->get_comments_stats($params), true);
973
+ }
974
+ }
975
+
976
+ if (!function_exists('mmb_backup_now')) {
977
+ //backup
978
+ function mmb_backup_now($params)
979
+ {
980
+ global $mmb_core;
981
+
982
+ $mmb_core->get_backup_instance();
983
+ $return = $mmb_core->backup_instance->backup($params);
984
+
985
+ if (is_array($return) && array_key_exists('error', $return)) {
986
+ mmb_response($return['error'], false);
987
+ } else {
988
+ mmb_response($return, true);
989
+ }
990
+ }
991
+ }
992
+
993
+ if (!function_exists('mwp_ping_backup')) {
994
+ //ping backup
995
+ function mwp_ping_backup($params)
996
+ {
997
+ global $mmb_core;
998
+
999
+ $mmb_core->get_backup_instance();
1000
+ $return = $mmb_core->backup_instance->ping_backup($params);
1001
+
1002
+ if (is_array($return) && array_key_exists('error', $return)) {
1003
+ mmb_response($return['error'], false);
1004
+ } else {
1005
+ mmb_response($return, true);
1006
+ }
1007
+ }
1008
+ }
1009
+
1010
+ if (!function_exists('mmb_run_task_now')) {
1011
+ function mmb_run_task_now($params)
1012
+ {
1013
+ global $mmb_core;
1014
+ $mmb_core->get_backup_instance();
1015
+
1016
+ $task_name = isset($params['task_name']) ? $params['task_name'] : false;
1017
+ $google_drive_token = isset($params['google_drive_token']) ? $params['google_drive_token'] : false;
1018
+
1019
+ if ($task_name) {
1020
+ $return = $mmb_core->backup_instance->task_now($task_name, $google_drive_token);
1021
+ if (is_array($return) && array_key_exists('error', $return)) {
1022
+ mmb_response($return['error'], false);
1023
+ } else {
1024
+ mmb_response($return, true);
1025
+ }
1026
+ } else {
1027
+ mmb_response("Task name is not provided.", false);
1028
+ }
1029
+
1030
+ }
1031
+ }
1032
+
1033
+ if (!function_exists('mmb_email_backup')) {
1034
+ function mmb_email_backup($params)
1035
+ {
1036
+ global $mmb_core;
1037
+ $mmb_core->get_backup_instance();
1038
+ $return = $mmb_core->backup_instance->email_backup($params);
1039
+
1040
+ if (is_array($return) && array_key_exists('error', $return)) {
1041
+ mmb_response($return['error'], false);
1042
+ } else {
1043
+ mmb_response($return, true);
1044
+ }
1045
+ }
1046
+ }
1047
+
1048
+ if (!function_exists('mmb_check_backup_compat')) {
1049
+ function mmb_check_backup_compat($params)
1050
+ {
1051
+ global $mmb_core;
1052
+ $mmb_core->get_backup_instance();
1053
+ $return = $mmb_core->backup_instance->check_backup_compat($params);
1054
+
1055
+ if (is_array($return) && array_key_exists('error', $return)) {
1056
+ mmb_response($return['error'], false);
1057
+ } else {
1058
+ mmb_response($return, true);
1059
+ }
1060
+ }
1061
+ }
1062
+
1063
+ if (!function_exists('mmb_get_backup_req')) {
1064
+ function mmb_get_backup_req($params)
1065
+ {
1066
+ global $mmb_core;
1067
+ $mmb_core->get_stats_instance();
1068
+ $return = $mmb_core->stats_instance->get_backup_req($params);
1069
+
1070
+ mmb_response($return, true);
1071
+ }
1072
+ }
1073
+
1074
+ // Fires when Backup Now, or some backup task is saved.
1075
+ if (!function_exists('mmb_scheduled_backup')) {
1076
+ function mmb_scheduled_backup($params)
1077
+ {
1078
+ global $mmb_core;
1079
+ $mmb_core->get_backup_instance();
1080
+ $return = $mmb_core->backup_instance->set_backup_task($params);
1081
+ mmb_response($return, $return);
1082
+ }
1083
+ }
1084
+
1085
+ if (!function_exists('mmm_delete_backup')) {
1086
+ function mmm_delete_backup($params)
1087
+ {
1088
+ global $mmb_core;
1089
+ $mmb_core->get_backup_instance();
1090
+ $return = $mmb_core->backup_instance->delete_backup($params);
1091
+ mmb_response($return, $return);
1092
+ }
1093
+ }
1094
+
1095
+ if (!function_exists('mmb_optimize_tables')) {
1096
+ function mmb_optimize_tables($params)
1097
+ {
1098
+ global $mmb_core;
1099
+ $mmb_core->get_backup_instance();
1100
+ $return = $mmb_core->backup_instance->optimize_tables();
1101
+ if ($return) {
1102
+ mmb_response($return, true);
1103
+ } else {
1104
+ mmb_response(false, false);
1105
+ }
1106
+ }
1107
+ }
1108
+ if (!function_exists('mmb_restore_now')) {
1109
+ function mmb_restore_now($params)
1110
+ {
1111
+ global $mmb_core;
1112
+ $mmb_core->get_backup_instance();
1113
+ $return = $mmb_core->backup_instance->restore($params);
1114
+ if (is_array($return) && array_key_exists('error', $return)) {
1115
+ mmb_response($return['error'], false);
1116
+ } else {
1117
+ mmb_response($return, true);
1118
+ }
1119
+
1120
+ }
1121
+ }
1122
+
1123
+ if (!function_exists('mmb_remote_backup_now')) {
1124
+ function mmb_remote_backup_now($params)
1125
+ {
1126
+ global $mmb_core;
1127
+ $backup_instance = $mmb_core->get_backup_instance();
1128
+ $return = $mmb_core->backup_instance->remote_backup_now($params);
1129
+ if (is_array($return) && array_key_exists('error', $return)) {
1130
+ mmb_response($return['error'], false);
1131
+ } else {
1132
+ mmb_response($return, true);
1133
+ }
1134
+ }
1135
+ }
1136
+
1137
+
1138
+ if (!function_exists('mmb_clean_orphan_backups')) {
1139
+ function mmb_clean_orphan_backups()
1140
+ {
1141
+ global $mmb_core;
1142
+ $backup_instance = $mmb_core->get_backup_instance();
1143
+ $return = $mmb_core->backup_instance->cleanup();
1144
+ if (is_array($return)) {
1145
+ mmb_response($return, true);
1146
+ } else {
1147
+ mmb_response($return, false);
1148
+ }
1149
+ }
1150
+ }
1151
+
1152
+ function mmb_run_forked_action()
1153
+ {
1154
+ if (!isset($_POST['mmb_fork_nonce'])) {
1155
+ return false;
1156
+ }
1157
+
1158
+ $originalUser = wp_get_current_user();
1159
+ $usernameUsed = array_key_exists('username', $_POST) ? $_POST : null;
1160
+
1161
+ if ($usernameUsed && !is_user_logged_in()) {
1162
+ $user = function_exists('get_user_by') ? get_user_by('login', $_POST['username']) : get_user_by('login', $_POST['username']);
1163
+ }
1164
+
1165
+ if (isset($user) && isset($user->ID)) {
1166
+ wp_set_current_user($user->ID);
1167
+ // Compatibility with All In One Security
1168
+ update_user_meta($user->ID, 'last_login_time', current_time('mysql'));
1169
+ }
1170
+
1171
+ if (!wp_verify_nonce($_POST['mmb_fork_nonce'], 'mmb-fork-nonce')) {
1172
+ wp_set_current_user($originalUser->ID);
1173
+
1174
+ return false;
1175
+ }
1176
+
1177
+ $public_key = get_option('_worker_public_key');
1178
+ if (!isset($_POST['public_key']) || $public_key !== $_POST['public_key']) {
1179
+ wp_set_current_user($originalUser->ID);
1180
+
1181
+ return false;
1182
+ }
1183
+ $args = @json_decode(stripslashes($_POST['args']), true);
1184
+ $args['forked'] = true;
1185
+
1186
+ if (!isset($args)) {
1187
+ wp_set_current_user($originalUser->ID);
1188
+
1189
+ return false;
1190
+ }
1191
+ $cron_action = isset($_POST['mwp_forked_action']) ? $_POST['mwp_forked_action'] : false;
1192
+ if ($cron_action) {
1193
+ do_action($cron_action, $args);
1194
+ }
1195
+ //unset($_POST['public_key']);
1196
+ unset($_POST['mmb_fork_nonce']);
1197
+ unset($_POST['args']);
1198
+ unset($_POST['mwp_forked_action']);
1199
+
1200
+ wp_set_current_user($originalUser->ID);
1201
+
1202
+ return true;
1203
+ }
1204
+
1205
+ add_filter('mwp_website_add', 'mmb_readd_backup_task');
1206
+
1207
+ if (!function_exists('mmb_readd_backup_task')) {
1208
+ function mmb_readd_backup_task($params = array())
1209
+ {
1210
+ global $mmb_core;
1211
+ $backup_instance = $mmb_core->get_backup_instance();
1212
+ $settings = $backup_instance->readd_tasks($params);
1213
+
1214
+ return $settings;
1215
+ }
1216
+ }
1217
+
1218
+ if (!function_exists('mmb_update_worker_plugin')) {
1219
+ function mmb_update_worker_plugin($params)
1220
+ {
1221
+ global $mmb_core;
1222
+ mmb_response($mmb_core->update_worker_plugin($params), true);
1223
+ }
1224
+ }
1225
+
1226
+ if (!function_exists('mmb_wp_checkversion')) {
1227
+ function mmb_wp_checkversion($params)
1228
+ {
1229
+ include_once(ABSPATH.'wp-includes/version.php');
1230
+ global $mmb_wp_version, $mmb_core;
1231
+ mmb_response($mmb_wp_version, true);
1232
+ }
1233
+ }
1234
+ if (!function_exists('mmb_search_posts_by_term')) {
1235
+ function mmb_search_posts_by_term($params)
1236
+ {
1237
+ global $mmb_core;
1238
+ $mmb_core->get_search_instance();
1239
+
1240
+ $search_type = trim($params['search_type']);
1241
+ $search_term = strtolower(trim($params['search_term']));
1242
+
1243
+ switch ($search_type) {
1244
+ case 'page_post':
1245
+ $return = $mmb_core->search_instance->search_posts_by_term($params);
1246
+ if ($return) {
1247
+ $return = serialize($return);
1248
+ mmb_response($return, true);
1249
+ } else {
1250
+ mmb_response('No posts found', false);
1251
+ }
1252
+ break;
1253
+
1254
+ case 'plugin':
1255
+ $plugins = get_option('active_plugins');
1256
+
1257
+ $have_plugin = false;
1258
+ foreach ($plugins as $plugin) {
1259
+ if (strpos($plugin, $search_term) > -1) {
1260
+ $have_plugin = true;
1261
+ }
1262
+ }
1263
+ if ($have_plugin) {
1264
+ mmb_response(serialize($plugin), true);
1265
+ } else {
1266
+ mmb_response(false, false);
1267
+ }
1268
+ break;
1269
+ case 'theme':
1270
+ $theme = strtolower(get_option('template'));
1271
+ if (strpos($theme, $search_term) > -1) {
1272
+ mmb_response($theme, true);
1273
+ } else {
1274
+ mmb_response(false, false);
1275
+ }
1276
+ break;
1277
+ default:
1278
+ mmb_response(false, false);
1279
+ }
1280
+ $return = $mmb_core->search_instance->search_posts_by_term($params);
1281
+
1282
+
1283
+ if ($return_if_true) {
1284
+ mmb_response($return_value, true);
1285
+ } else {
1286
+ mmb_response($return_if_false, false);
1287
+ }
1288
+ }
1289
+ }
1290
+
1291
+ if (!function_exists('mmb_install_addon')) {
1292
+ function mmb_install_addon($params)
1293
+ {
1294
+ global $mmb_core;
1295
+ $mmb_core->get_installer_instance();
1296
+ $return = $mmb_core->installer_instance->install_remote_file($params);
1297
+ mmb_response($return, true);
1298
+
1299
+ }
1300
+ }
1301
+
1302
+ if (!function_exists('mmb_install_addons')) {
1303
+ function mmb_install_addons($params)
1304
+ {
1305
+ global $mmb_core;
1306
+ $mmb_core->get_installer_instance();
1307
+ $return = $mmb_core->installer_instance->install_remote_files($params);
1308
+ mmb_response($return, true);
1309
+
1310
+ }
1311
+ }
1312
+
1313
+ if (!function_exists('mmb_do_upgrade')) {
1314
+ function mmb_do_upgrade($params)
1315
+ {
1316
+ global $mmb_core, $mmb_upgrading;
1317
+ $mmb_core->get_installer_instance();
1318
+ $return = $mmb_core->installer_instance->do_upgrade($params);
1319
+ mmb_response($return, true);
1320
+
1321
+ }
1322
+ }
1323
+
1324
+ if (!function_exists('mmb_get_links')) {
1325
+ function mmb_get_links($params)
1326
+ {
1327
+ global $mmb_core;
1328
+ $mmb_core->get_link_instance();
1329
+ $return = $mmb_core->link_instance->get_links($params);
1330
+ if (is_array($return) && array_key_exists('error', $return)) {
1331
+ mmb_response($return['error'], false);
1332
+ } else {
1333
+ mmb_response($return, true);
1334
+ }
1335
+ }
1336
+ }
1337
+
1338
+ if (!function_exists('mmb_add_link')) {
1339
+ function mmb_add_link($params)
1340
+ {
1341
+ global $mmb_core;
1342
+ $mmb_core->get_link_instance();
1343
+ $return = $mmb_core->link_instance->add_link($params);
1344
+ if (is_array($return) && array_key_exists('error', $return)) {
1345
+ mmb_response($return['error'], false);
1346
+ } else {
1347
+ mmb_response($return, true);
1348
+ }
1349
+
1350
+ }
1351
+ }
1352
+
1353
+ if (!function_exists('mmb_delete_link')) {
1354
+ function mmb_delete_link($params)
1355
+ {
1356
+ global $mmb_core;
1357
+ $mmb_core->get_link_instance();
1358
+
1359
+ $return = $mmb_core->link_instance->delete_link($params);
1360
+ if (is_array($return) && array_key_exists('error', $return)) {
1361
+ mmb_response($return['error'], false);
1362
+ } else {
1363
+ mmb_response($return, true);
1364
+ }
1365
+ }
1366
+ }
1367
+
1368
+ if (!function_exists('mmb_delete_links')) {
1369
+ function mmb_delete_links($params)
1370
+ {
1371
+ global $mmb_core;
1372
+ $mmb_core->get_link_instance();
1373
+
1374
+ $return = $mmb_core->link_instance->delete_links($params);
1375
+ if (is_array($return) && array_key_exists('error', $return)) {
1376
+ mmb_response($return['error'], false);
1377
+ } else {
1378
+ mmb_response($return, true);
1379
+ }
1380
+ }
1381
+ }
1382
+
1383
+ if (!function_exists('mmb_get_comments')) {
1384
+ function mmb_get_comments($params)
1385
+ {
1386
+ global $mmb_core;
1387
+ $mmb_core->get_comment_instance();
1388
+ $return = $mmb_core->comment_instance->get_comments($params);
1389
+ if (is_array($return) && array_key_exists('error', $return)) {
1390
+ mmb_response($return['error'], false);
1391
+ } else {
1392
+ mmb_response($return, true);
1393
+ }
1394
+ }
1395
+ }
1396
+
1397
+ if (!function_exists('mmb_action_comment')) {
1398
+ function mmb_action_comment($params)
1399
+ {
1400
+ global $mmb_core;
1401
+ $mmb_core->get_comment_instance();
1402
+
1403
+ $return = $mmb_core->comment_instance->action_comment($params);
1404
+ if (is_array($return) && array_key_exists('error', $return)) {
1405
+ mmb_response($return['error'], false);
1406
+ } else {
1407
+ mmb_response($return, true);
1408
+ }
1409
+ }
1410
+ }
1411
+
1412
+ if (!function_exists('mmb_bulk_action_comments')) {
1413
+ function mmb_bulk_action_comments($params)
1414
+ {
1415
+ global $mmb_core;
1416
+ $mmb_core->get_comment_instance();
1417
+
1418
+ $return = $mmb_core->comment_instance->bulk_action_comments($params);
1419
+ if (is_array($return) && array_key_exists('error', $return)) {
1420
+ mmb_response($return['error'], false);
1421
+ } else {
1422
+ mmb_response($return, true);
1423
+ }
1424
+ }
1425
+ }
1426
+
1427
+ if (!function_exists('mmb_reply_comment')) {
1428
+ function mmb_reply_comment($params)
1429
+ {
1430
+ global $mmb_core;
1431
+ $mmb_core->get_comment_instance();
1432
+
1433
+ $return = $mmb_core->comment_instance->reply_comment($params);
1434
+ if (is_array($return) && array_key_exists('error', $return)) {
1435
+ mmb_response($return['error'], false);
1436
+ } else {
1437
+ mmb_response($return, true);
1438
+ }
1439
+ }
1440
+ }
1441
+
1442
+ if (!function_exists('mmb_add_user')) {
1443
+ function mmb_add_user($params)
1444
+ {
1445
+ global $mmb_core;
1446
+ $mmb_core->get_user_instance();
1447
+ $return = $mmb_core->user_instance->add_user($params);
1448
+ if (is_array($return) && array_key_exists('error', $return)) {
1449
+ mmb_response($return['error'], false);
1450
+ } else {
1451
+ mmb_response($return, true);
1452
+ }
1453
+
1454
+ }
1455
+ }
1456
+
1457
+ if (!function_exists('mbb_security_check')) {
1458
+ function mbb_security_check($params)
1459
+ {
1460
+ global $mmb_core;
1461
+ $mmb_core->get_security_instance();
1462
+ $return = $mmb_core->security_instance->security_check($params);
1463
+ if (is_array($return) && array_key_exists('error', $return)) {
1464
+ mmb_response($return['error'], false);
1465
+ } else {
1466
+ mmb_response($return, true);
1467
+ }
1468
+
1469
+ }
1470
+ }
1471
+
1472
+ if (!function_exists('mbb_security_fix_folder_listing')) {
1473
+ function mbb_security_fix_folder_listing($params)
1474
+ {
1475
+ global $mmb_core;
1476
+ $mmb_core->get_security_instance();
1477
+ $return = $mmb_core->security_instance->security_fix_dir_listing($params);
1478
+ if (is_array($return) && array_key_exists('error', $return)) {
1479
+ mmb_response($return['error'], false);
1480
+ } else {
1481
+ mmb_response($return, true);
1482
+ }
1483
+
1484
+ }
1485
+ }
1486
+
1487
+ if (!function_exists('mbb_security_fix_php_reporting')) {
1488
+ function mbb_security_fix_php_reporting($params)
1489
+ {
1490
+ global $mmb_core;
1491
+ $mmb_core->get_security_instance();
1492
+ $return = $mmb_core->security_instance->security_fix_php_reporting($params);
1493
+ if (is_array($return) && array_key_exists('error', $return)) {
1494
+ mmb_response($return['error'], false);
1495
+ } else {
1496
+ mmb_response($return, true);
1497
+ }
1498
+
1499
+ }
1500
+ }
1501
+
1502
+ if (!function_exists('mbb_security_fix_database_reporting')) {
1503
+ function mbb_security_fix_database_reporting($params)
1504
+ {
1505
+ global $mmb_core;
1506
+ $mmb_core->get_security_instance();
1507
+ $return = $mmb_core->security_instance->security_fix_database_reporting($params);
1508
+ if (is_array($return) && array_key_exists('error', $return)) {
1509
+ mmb_response($return['error'], false);
1510
+ } else {
1511
+ mmb_response($return, true);
1512
+ }
1513
+
1514
+ }
1515
+ }
1516
+
1517
+ //security_fix_wp_version
1518
+
1519
+ if (!function_exists('mbb_security_fix_wp_version')) {
1520
+ function mbb_security_fix_wp_version($params)
1521
+ {
1522
+ global $mmb_core;
1523
+ $mmb_core->get_security_instance();
1524
+ $return = $mmb_core->security_instance->security_fix_wp_version($params);
1525
+ if (is_array($return) && array_key_exists('error', $return)) {
1526
+ mmb_response($return['error'], false);
1527
+ } else {
1528
+ mmb_response($return, true);
1529
+ }
1530
+
1531
+ }
1532
+ }
1533
+
1534
+ //mbb_security_fix_admin_username
1535
+
1536
+ if (!function_exists('mbb_security_fix_admin_username')) {
1537
+ function mbb_security_fix_admin_username($params)
1538
+ {
1539
+ global $mmb_core;
1540
+ $mmb_core->get_security_instance();
1541
+ $return = $mmb_core->security_instance->security_fix_admin_username($params);
1542
+ if (is_array($return) && array_key_exists('error', $return)) {
1543
+ mmb_response($return['error'], false);
1544
+ } else {
1545
+ mmb_response($return, true);
1546
+ }
1547
+
1548
+ }
1549
+ }
1550
+
1551
+ if (!function_exists('mbb_security_fix_scripts_styles')) {
1552
+ function mbb_security_fix_scripts_styles($params)
1553
+ {
1554
+ global $mmb_core;
1555
+ $mmb_core->get_security_instance();
1556
+ $return = $mmb_core->security_instance->security_fix_scripts_styles($params);
1557
+ if (is_array($return) && array_key_exists('error', $return)) {
1558
+ mmb_response($return['error'], false);
1559
+ } else {
1560
+ mmb_response($return, true);
1561
+ }
1562
+
1563
+ }
1564
+ }
1565
+
1566
+ //mbb_security_fix_file_permission
1567
+ if (!function_exists('mbb_security_fix_file_permission')) {
1568
+ function mbb_security_fix_file_permission($params)
1569
+ {
1570
+ global $mmb_core;
1571
+ $mmb_core->get_security_instance();
1572
+ $return = $mmb_core->security_instance->security_fix_permissions($params);
1573
+ if (is_array($return) && array_key_exists('error', $return)) {
1574
+ mmb_response($return['error'], false);
1575
+ } else {
1576
+ mmb_response($return, true);
1577
+ }
1578
+
1579
+ }
1580
+ }
1581
+
1582
+ //mbb_security_fix_all
1583
+ if (!function_exists('mbb_security_fix_all')) {
1584
+ function mbb_security_fix_all($params)
1585
+ {
1586
+ global $mmb_core;
1587
+ $mmb_core->get_security_instance();
1588
+ $return = $mmb_core->security_instance->security_fix_all($params);
1589
+ if (is_array($return) && array_key_exists('error', $return)) {
1590
+ mmb_response($return['error'], false);
1591
+ } else {
1592
+ mmb_response($return, true);
1593
+ }
1594
+ }
1595
+ }
1596
+
1597
+ //mbb_security_fix_htaccess_permission
1598
+
1599
+ if (!function_exists('mbb_security_fix_htaccess_permission')) {
1600
+ function mbb_security_fix_htaccess_permission($params)
1601
+ {
1602
+ global $mmb_core;
1603
+ $mmb_core->get_security_instance();
1604
+ $return = $mmb_core->security_instance->security_fix_htaccess_permission($params);
1605
+ if (is_array($return) && array_key_exists('error', $return)) {
1606
+ mmb_response($return['error'], false);
1607
+ } else {
1608
+ mmb_response($return, true);
1609
+ }
1610
+
1611
+ }
1612
+ }
1613
+
1614
+ if (!function_exists('mmb_get_users')) {
1615
+ function mmb_get_users($params)
1616
+ {
1617
+ global $mmb_core;
1618
+ $mmb_core->get_user_instance();
1619
+ $return = $mmb_core->user_instance->get_users($params);
1620
+ if (is_array($return) && array_key_exists('error', $return)) {
1621
+ mmb_response($return['error'], false);
1622
+ } else {
1623
+ mmb_response($return, true);
1624
+ }
1625
+ }
1626
+ }
1627
+
1628
+ if (!function_exists('mmb_edit_users')) {
1629
+ function mmb_edit_users($params)
1630
+ {
1631
+ global $mmb_core;
1632
+ $mmb_core->get_user_instance();
1633
+ $users = $mmb_core->user_instance->edit_users($params);
1634
+ $response = 'User updated.';
1635
+ $check_error = false;
1636
+ foreach ($users as $username => $user) {
1637
+ $check_error = array_key_exists('error', $user);
1638
+ if ($check_error) {
1639
+ $response = $username.': '.$user['error'];
1640
+ }
1641
+ }
1642
+ mmb_response($response, !$check_error);
1643
+ }
1644
+ }
1645
+
1646
+ if (!function_exists('mmb_get_posts')) {
1647
+ function mmb_get_posts($params)
1648
+ {
1649
+ global $mmb_core;
1650
+ $mmb_core->get_post_instance();
1651
+
1652
+ $return = $mmb_core->post_instance->get_posts($params);
1653
+ if (is_array($return) && array_key_exists('error', $return)) {
1654
+ mmb_response($return['error'], false);
1655
+ } else {
1656
+ mmb_response($return, true);
1657
+ }
1658
+ }
1659
+ }
1660
+
1661
+ if (!function_exists('mmb_delete_post')) {
1662
+ function mmb_delete_post($params)
1663
+ {
1664
+ global $mmb_core;
1665
+ $mmb_core->get_post_instance();
1666
+
1667
+ $return = $mmb_core->post_instance->delete_post($params);
1668
+ if (is_array($return) && array_key_exists('error', $return)) {
1669
+ mmb_response($return['error'], false);
1670
+ } else {
1671
+ mmb_response($return, true);
1672
+ }
1673
+ }
1674
+ }
1675
+
1676
+ if (!function_exists('mmb_delete_posts')) {
1677
+ function mmb_delete_posts($params)
1678
+ {
1679
+ global $mmb_core;
1680
+ $mmb_core->get_post_instance();
1681
+
1682
+ $return = $mmb_core->post_instance->delete_posts($params);
1683
+ if (is_array($return) && array_key_exists('error', $return)) {
1684
+ mmb_response($return['error'], false);
1685
+ } else {
1686
+ mmb_response($return, true);
1687
+ }
1688
+ }
1689
+ }
1690
+
1691
+
1692
+ if (!function_exists('mmb_edit_posts')) {
1693
+ function mmb_edit_posts($params)
1694
+ {
1695
+ global $mmb_core;
1696
+ $mmb_core->get_posts_instance();
1697
+ $return = $mmb_core->posts_instance->edit_posts($params);
1698
+ mmb_response($return, true);
1699
+ }
1700
+ }
1701
+
1702
+ if (!function_exists('mmb_get_pages')) {
1703
+ function mmb_get_pages($params)
1704
+ {
1705
+ global $mmb_core;
1706
+ $mmb_core->get_post_instance();
1707
+
1708
+ $return = $mmb_core->post_instance->get_pages($params);
1709
+ if (is_array($return) && array_key_exists('error', $return)) {
1710
+ mmb_response($return['error'], false);
1711
+ } else {
1712
+ mmb_response($return, true);
1713
+ }
1714
+ }
1715
+ }
1716
+
1717
+ if (!function_exists('mmb_delete_page')) {
1718
+ function mmb_delete_page($params)
1719
+ {
1720
+ global $mmb_core;
1721
+ $mmb_core->get_post_instance();
1722
+
1723
+ $return = $mmb_core->post_instance->delete_page($params);
1724
+ if (is_array($return) && array_key_exists('error', $return)) {
1725
+ mmb_response($return['error'], false);
1726
+ } else {
1727
+ mmb_response($return, true);
1728
+ }
1729
+ }
1730
+ }
1731
+
1732
+ if (!function_exists('mmb_iframe_plugins_fix')) {
1733
+ function mmb_iframe_plugins_fix($update_actions)
1734
+ {
1735
+ foreach ($update_actions as $key => $action) {
1736
+ $update_actions[$key] = str_replace('target="_parent"', '', $action);
1737
+ }
1738
+
1739
+ return $update_actions;
1740
+
1741
+ }
1742
+ }
1743
+ if (!function_exists('mmb_execute_php_code')) {
1744
+ function mmb_execute_php_code($params)
1745
+ {
1746
+ ob_start();
1747
+ eval($params['code']);
1748
+ $return = ob_get_flush();
1749
+ mmb_response(print_r($return, true), true);
1750
+ }
1751
+ }
1752
+
1753
+ if (!function_exists('mmb_set_notifications')) {
1754
+ function mmb_set_notifications($params)
1755
+ {
1756
+ global $mmb_core;
1757
+ $mmb_core->get_stats_instance();
1758
+ $return = $mmb_core->stats_instance->set_notifications($params);
1759
+ if (is_array($return) && array_key_exists('error', $return)) {
1760
+ mmb_response($return['error'], false);
1761
+ } else {
1762
+ mmb_response($return, true);
1763
+ }
1764
+
1765
+ }
1766
+ }
1767
+
1768
+ if (!function_exists('mmb_get_dbname')) {
1769
+ function mmb_get_dbname($params)
1770
+ {
1771
+ global $mmb_core;
1772
+ $mmb_core->get_stats_instance();
1773
+
1774
+ $return = $mmb_core->stats_instance->get_active_db();
1775
+ if (is_array($return) && array_key_exists('error', $return)) {
1776
+ mmb_response($return['error'], false);
1777
+ } else {
1778
+ mmb_response($return, true);
1779
+ }
1780
+ }
1781
+ }
1782
+
1783
+ if (!function_exists('mmb_more_reccurences')) {
1784
+ //Backup Tasks
1785
+ add_filter('cron_schedules', 'mmb_more_reccurences');
1786
+ function mmb_more_reccurences($schedules)
1787
+ {
1788
+ $schedules['halfminute'] = array('interval' => 30, 'display' => 'Once in a half minute');
1789
+ $schedules['minutely'] = array('interval' => 60, 'display' => 'Once in a minute');
1790
+ $schedules['fiveminutes'] = array('interval' => 300, 'display' => 'Once every five minutes');
1791
+ $schedules['tenminutes'] = array('interval' => 600, 'display' => 'Once every ten minutes');
1792
+ $schedules['sixhours'] = array('interval' => 21600, 'display' => 'Every six hours');
1793
+ $schedules['fourhours'] = array('interval' => 14400, 'display' => 'Every four hours');
1794
+ $schedules['threehours'] = array('interval' => 10800, 'display' => 'Every three hours');
1795
+
1796
+ return $schedules;
1797
+ }
1798
+ }
1799
+
1800
+ add_action('mwp_backup_tasks', 'mwp_check_backup_tasks');
1801
+
1802
+ if (!function_exists('mwp_check_backup_tasks')) {
1803
+ function mwp_check_backup_tasks()
1804
+ {
1805
+ global $mmb_core, $_wp_using_ext_object_cache;
1806
+ $_wp_using_ext_object_cache = false;
1807
+ $mmb_core->get_backup_instance();
1808
+ $mmb_core->backup_instance->check_backup_tasks();
1809
+ }
1810
+ }
1811
+
1812
+ // Remote upload in the second request.
1813
+ // add_action('mmb_scheduled_remote_upload', 'mmb_call_scheduled_remote_upload');
1814
+ add_action('mmb_remote_upload', 'mmb_call_scheduled_remote_upload');
1815
+
1816
+ if (!function_exists('mmb_call_scheduled_remote_upload')) {
1817
+ function mmb_call_scheduled_remote_upload($args)
1818
+ {
1819
+ global $mmb_core, $_wp_using_ext_object_cache;
1820
+ $_wp_using_ext_object_cache = false;
1821
+
1822
+ $mmb_core->get_backup_instance();
1823
+ if (isset($args['task_name'])) {
1824
+ $mmb_core->backup_instance->remote_backup_now($args);
1825
+ }
1826
+ }
1827
+ }
1828
+
1829
+ // if (!wp_next_scheduled('mwp_notifications')) {
1830
+ // wp_schedule_event( time(), 'twicedaily', 'mwp_notifications' );
1831
+ // }
1832
+ // add_action('mwp_notifications', 'mwp_check_notifications');
1833
+
1834
+ if (!wp_next_scheduled('mwp_datasend')) {
1835
+ wp_schedule_event(time(), 'threehours', 'mwp_datasend');
1836
+ }
1837
+
1838
+ add_action('mwp_datasend', 'mwp_datasend');
1839
+
1840
+ if (!function_exists('mwp_check_notifications')) {
1841
+ function mwp_check_notifications()
1842
+ {
1843
+ global $mmb_core, $_wp_using_ext_object_cache;
1844
+ $_wp_using_ext_object_cache = false;
1845
+
1846
+ $mmb_core->get_stats_instance();
1847
+ $mmb_core->stats_instance->check_notifications();
1848
+ }
1849
+ }
1850
+
1851
+
1852
+ if (!function_exists('mmb_get_plugins_themes')) {
1853
+ function mmb_get_plugins_themes($params)
1854
+ {
1855
+ global $mmb_core;
1856
+ $mmb_core->get_installer_instance();
1857
+ $return = $mmb_core->installer_instance->get($params);
1858
+ mmb_response($return, true);
1859
+ }
1860
+ }
1861
+
1862
+
1863
+ if (!function_exists('mmb_get_autoupdate_plugins_themes')) {
1864
+ function mmb_get_autoupdate_plugins_themes($params)
1865
+ {
1866
+ $return = MMB_Updater::getSettings($params);
1867
+ mmb_response($return, true);
1868
+ }
1869
+ }
1870
+
1871
+ if (!function_exists('mmb_edit_plugins_themes')) {
1872
+ function mmb_edit_plugins_themes($params)
1873
+ {
1874
+ global $mmb_core;
1875
+ $mmb_core->get_installer_instance();
1876
+ $return = $mmb_core->installer_instance->edit($params);
1877
+ mmb_response($return, true);
1878
+ }
1879
+ }
1880
+
1881
+ if (!function_exists('mmb_edit_autoupdate_plugins_themes')) {
1882
+ function mmb_edit_autoupdate_plugins_themes($params)
1883
+ {
1884
+ $return = MMB_Updater::setSettings($params);
1885
+ mmb_response($return, true);
1886
+ }
1887
+ }
1888
+
1889
+ if (!function_exists('mmb_worker_brand')) {
1890
+ function mmb_worker_brand($params)
1891
+ {
1892
+ update_option("mwp_worker_brand", $params['brand']);
1893
+ mmb_response(true, true);
1894
+ }
1895
+ }
1896
+
1897
+ if (!function_exists('mmb_maintenance_mode')) {
1898
+ function mmb_maintenance_mode($params)
1899
+ {
1900
+ global $wp_object_cache;
1901
+
1902
+ $default = get_option('mwp_maintenace_mode');
1903
+ $params = empty($default) ? $params : array_merge($default, $params);
1904
+ update_option("mwp_maintenace_mode", $params);
1905
+
1906
+ if (!empty($wp_object_cache)) {
1907
+ @$wp_object_cache->flush();
1908
+ }
1909
+ mmb_response(true, true);
1910
+ }
1911
+ }
1912
+
1913
+ if (!function_exists('mmb_plugin_actions')) {
1914
+ function mmb_plugin_actions()
1915
+ {
1916
+ global $mmb_actions, $mmb_core;
1917
+
1918
+ if (!empty($mmb_actions)) {
1919
+ global $_mmb_plugin_actions;
1920
+ if (!empty($_mmb_plugin_actions)) {
1921
+ $failed = array();
1922
+ foreach ($_mmb_plugin_actions as $action => $params) {
1923
+ if (isset($mmb_actions[$action])) {
1924
+ call_user_func($mmb_actions[$action], $params);
1925
+ } else {
1926
+ $failed[] = $action;
1927
+ }
1928
+ }
1929
+ if (!empty($failed)) {
1930
+ $f = implode(', ', $failed);
1931
+ $s = count($f) > 1 ? 'Actions "'.$f.'" do' : 'Action "'.$f.'" does';
1932
+ mmb_response($s.' not exist. Please update your Worker plugin.', false);
1933
+ }
1934
+
1935
+ }
1936
+ }
1937
+
1938
+ global $pagenow, $current_user, $mmode;
1939
+ if (!is_admin() && !in_array($pagenow, array('wp-login.php'))) {
1940
+ $mmode = get_option('mwp_maintenace_mode');
1941
+ if (!empty($mmode)) {
1942
+ if (isset($mmode['active']) && $mmode['active'] == true) {
1943
+ if (isset($current_user->data) && !empty($current_user->data) && isset($mmode['hidecaps']) && !empty($mmode['hidecaps'])) {
1944
+ $usercaps = array();
1945
+ if (isset($current_user->caps) && !empty($current_user->caps)) {
1946
+ $usercaps = $current_user->caps;
1947
+ }
1948
+ foreach ($mmode['hidecaps'] as $cap => $hide) {
1949
+ if (!$hide) {
1950
+ continue;
1951
+ }
1952
+
1953
+ foreach ($usercaps as $ucap => $val) {
1954
+ if ($ucap == $cap) {
1955
+ ob_end_clean();
1956
+ ob_end_flush();
1957
+ die($mmode['template']);
1958
+ }
1959
+ }
1960
+ }
1961
+ } else {
1962
+ die($mmode['template']);
1963
+ }
1964
+ }
1965
+ }
1966
+ }
1967
+
1968
+ if (file_exists(dirname(__FILE__).'/log')) {
1969
+ unlink(dirname(__FILE__).'/log');
1970
+ }
1971
+ }
1972
+ }
1973
+
1974
+ $mmb_core = $mmb_core_backup = new MMB_Core();
1975
+
1976
+ if (isset($_GET['auto_login'])) {
1977
+ $mmb_core->automatic_login();
1978
+ }
1979
+
1980
+ MMB_Updater::register();
1981
+
1982
+
1983
+ if (!function_exists('mwp_return_core_reference')) {
1984
+ function mwp_return_core_reference()
1985
+ {
1986
+ global $mmb_core, $mmb_core_backup;
1987
+ if (!$mmb_core instanceof MMB_Core) {
1988
+ $mmb_core = $mmb_core_backup;
1989
+ }
1990
+ }
1991
+ }
1992
+
1993
+ if (function_exists('register_activation_hook')) {
1994
+ register_activation_hook(__FILE__, array($mmb_core, 'install'));
1995
+ }
1996
+
1997
+ if (function_exists('register_deactivation_hook')) {
1998
+ register_deactivation_hook(__FILE__, array($mmb_core, 'uninstall'));
1999
+ }
2000
+
2001
+ if (function_exists('add_action')) {
2002
+ add_action('init', 'mmb_plugin_actions', 99999);
2003
+ }
2004
+
2005
+ if (function_exists('add_filter')) {
2006
+ add_filter('install_plugin_complete_actions', 'mmb_iframe_plugins_fix');
2007
+ }
2008
+
2009
+ if (!function_exists('mwb_edit_redirect_override')) {
2010
+ function mwb_edit_redirect_override($location = false, $comment_id = false)
2011
+ {
2012
+ if (isset($_COOKIE[MMB_XFRAME_COOKIE])) {
2013
+ $location = get_site_url().'/wp-admin/edit-comments.php';
2014
+ }
2015
+
2016
+ return $location;
2017
+ }
2018
+ }
2019
+ if (function_exists('add_filter')) {
2020
+ add_filter('comment_edit_redirect', 'mwb_edit_redirect_override');
2021
+ }
2022
+
2023
+ if (isset($_COOKIE[MMB_XFRAME_COOKIE])) {
2024
+ remove_action('admin_init', 'send_frame_options_header');
2025
+ remove_action('login_init', 'send_frame_options_header');
2026
+ }
2027
+
2028
+ if (get_option('mwp_remove_php_reporting') == 'T') {
2029
+ @error_reporting(0);
2030
+ @ini_set('display_errors', 'off');
2031
+ @ini_set('display_startup_errors', "off");
2032
+ }
2033
+
2034
+ if (get_option('mwp_remove_wp_version') == 'T') {
2035
+ remove_action('wp_head', 'wp_generator');
2036
+ remove_filter('wp_head', 'wp_generator');
2037
+ }
2038
+ if (get_option('managewp_remove_styles_version') == 'T') {
2039
+ global $wp_styles;
2040
+ if (!is_a($wp_styles, 'WP_Styles')) {
2041
+ return;
2042
+ }
2043
+
2044
+ foreach ($wp_styles->registered as $handle => $style) {
2045
+ $wp_styles->registered[$handle]->ver = null;
2046
+ }
2047
+ }
2048
+ if (get_option('managewp_remove_scripts_version') == 'T') {
2049
+ global $wp_scripts;
2050
+ if (!is_a($wp_scripts, 'WP_Scripts')) {
2051
+ return;
2052
+ }
2053
+
2054
+ foreach ($wp_scripts->registered as $handle => $script) {
2055
+ $wp_scripts->registered[$handle]->ver = null;
2056
+ }
2057
+ }
2058
+
2059
+ if (wp_next_scheduled('mwp_backup_tasks')) {
2060
+ wp_clear_scheduled_hook('mwp_backup_tasks');
2061
+ }
2062
+
2063
+ $activePlugins = get_option('active_plugins');
2064
+ if (reset($activePlugins) !== 'worker/init.php') {
2065
+ $workerKey = array_search('worker/init.php', $activePlugins);
2066
+ if ($workerKey !== false) {
2067
+ unset($activePlugins[$workerKey]);
2068
+ array_unshift($activePlugins, 'worker/init.php');
2069
+ update_option('active_plugins', $activePlugins);
2070
+ }
2071
+ }
publickeys/ManageWP_mt.pub CHANGED
@@ -1,9 +1,9 @@
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-----
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/managewp_d.pub CHANGED
@@ -1,9 +1,9 @@
1
- -----BEGIN PUBLIC KEY-----
2
- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtEvKFDXjXcqDwGZbrCCx
3
- o8kDmx4ft5SfJs8qaVxlprPQ1k9SR3Y3npGToUjlgmpeXy1zFazdcdFQsI4MdpbL
4
- 37ZckHujDIRjsG8PNRTIr0cF+gH+adrBMMLNL9x5ePom10ZRmVFwyP6RnqezX6io
5
- UVoi+B6qRecaTw432TT66zIcpgyZKeihwBPL2+ubpAVUzSBBD0Jx7VC8MzFZK/Oj
6
- DMkkWedQPn58FciQCDxnzjXI7Yi5EtXdQUL2C5FPQTgjxJcPi8x4iXl/Z6XC/sG1
7
- dExFmb1Km/+EaeaV7bYpeUnBhNkUp47TY2qQdXrtoe6YhOBFfqggRrEXDVu1nM2X
8
- iQIDAQAB
9
- -----END PUBLIC KEY-----
1
+ -----BEGIN PUBLIC KEY-----
2
+ MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtEvKFDXjXcqDwGZbrCCx
3
+ o8kDmx4ft5SfJs8qaVxlprPQ1k9SR3Y3npGToUjlgmpeXy1zFazdcdFQsI4MdpbL
4
+ 37ZckHujDIRjsG8PNRTIr0cF+gH+adrBMMLNL9x5ePom10ZRmVFwyP6RnqezX6io
5
+ UVoi+B6qRecaTw432TT66zIcpgyZKeihwBPL2+ubpAVUzSBBD0Jx7VC8MzFZK/Oj
6
+ DMkkWedQPn58FciQCDxnzjXI7Yi5EtXdQUL2C5FPQTgjxJcPi8x4iXl/Z6XC/sG1
7
+ dExFmb1Km/+EaeaV7bYpeUnBhNkUp47TY2qQdXrtoe6YhOBFfqggRrEXDVu1nM2X
8
+ iQIDAQAB
9
+ -----END PUBLIC KEY-----
publickeys/managewp_t.pub CHANGED
@@ -1,9 +1,9 @@
1
- -----BEGIN PUBLIC KEY-----
2
- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyKuVlOg8/WJ/cfk5POp3
3
- Vg+tBqdOViijE/zBNisp4VrT2n4QfCMB0TD2etYPuhmY8MO7b617SVMtkgmOg9kx
4
- ZY3eWDO6ChAoMBkmLCZksrkaHksaZeFNzjbo2GaIfP7Wz4xvShI5IAhU4w2hG6WY
5
- HJ0oD2WTF/qFYnA2/T2q8Cby6pKEy3PzMCRjGdgKB5Y3kbCyApl66So+5IqiyEcX
6
- pYSYtM90cqBWGq8bv1mK6DL62NRd+MtrBnXxO/0PF3lclnSpi8QEToMQSuNK6Yuz
7
- EEqAWlvtuUl+IKccOUBeNGOqt2QFj1nkbQawVzIiPzDpzZrqCVdHoQgAFzXbav6U
8
- NwIDAQAB
9
- -----END PUBLIC KEY-----
1
+ -----BEGIN PUBLIC KEY-----
2
+ MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyKuVlOg8/WJ/cfk5POp3
3
+ Vg+tBqdOViijE/zBNisp4VrT2n4QfCMB0TD2etYPuhmY8MO7b617SVMtkgmOg9kx
4
+ ZY3eWDO6ChAoMBkmLCZksrkaHksaZeFNzjbo2GaIfP7Wz4xvShI5IAhU4w2hG6WY
5
+ HJ0oD2WTF/qFYnA2/T2q8Cby6pKEy3PzMCRjGdgKB5Y3kbCyApl66So+5IqiyEcX
6
+ pYSYtM90cqBWGq8bv1mK6DL62NRd+MtrBnXxO/0PF3lclnSpi8QEToMQSuNK6Yuz
7
+ EEqAWlvtuUl+IKccOUBeNGOqt2QFj1nkbQawVzIiPzDpzZrqCVdHoQgAFzXbav6U
8
+ NwIDAQAB
9
+ -----END PUBLIC KEY-----
publickeys/partner1.pub CHANGED
@@ -1,9 +1,9 @@
1
- -----BEGIN PUBLIC KEY-----
2
- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA57wtC1CiWjqRtEjd2ryQ
3
- wskHNNkr6+FArJUrPcxq7xxcW/KjUSTTFbDM84vEVTzn6wsgxXOjgGSDMptk+f7L
4
- 8Ja/32XX+7jWZdTC8fyKNh4K6CD/A040WxbtMXsqOSGUiC0dzU27j0BhTwQxnhQW
5
- j6ViaPgfEzb3q34w8jNBHwraWc1bW8/KizzGXUYSBuJBWJ6rD+aEJ3fr/tlwnGDs
6
- JJc2NQnkV8RP78uFy6c1cLzSQClX9WB1E4yxFDDXS1jBTAT4v9PJoMZaROU/MYbZ
7
- nEOx4FQt8ckJyE5syyWE7jWJolXjF0lSjbf4r0i2RZ7bDh5i2czgat8OoXwvWM+4
8
- XQIDAQAB
9
- -----END PUBLIC KEY-----
1
+ -----BEGIN PUBLIC KEY-----
2
+ MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA57wtC1CiWjqRtEjd2ryQ
3
+ wskHNNkr6+FArJUrPcxq7xxcW/KjUSTTFbDM84vEVTzn6wsgxXOjgGSDMptk+f7L
4
+ 8Ja/32XX+7jWZdTC8fyKNh4K6CD/A040WxbtMXsqOSGUiC0dzU27j0BhTwQxnhQW
5
+ j6ViaPgfEzb3q34w8jNBHwraWc1bW8/KizzGXUYSBuJBWJ6rD+aEJ3fr/tlwnGDs
6
+ JJc2NQnkV8RP78uFy6c1cLzSQClX9WB1E4yxFDDXS1jBTAT4v9PJoMZaROU/MYbZ
7
+ nEOx4FQt8ckJyE5syyWE7jWJolXjF0lSjbf4r0i2RZ7bDh5i2czgat8OoXwvWM+4
8
+ XQIDAQAB
9
+ -----END PUBLIC KEY-----
publickeys/partner10.pub CHANGED
@@ -1,9 +1,9 @@
1
- -----BEGIN PUBLIC KEY-----
2
- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApTPS/ietBUIm+g6byuFV
3
- /fbW2HmGomL8PQ1JJ3ZEjbsMQhEJ066xrdOlpI/Up09Y6+aO4LUydUg4j1nQzaZF
4
- K3Nk2kUqgNYcws2Qrrs3mnkuJ4w0heAaACtaCjYpM3/Rlk2z7HKqJbCCvJVVVW7J
5
- yohUHunGZZPP5qIutEaGssETbmnmqxUqgY6TfgzhU4rCRBDabHxop/jRZ3qdWSXp
6
- 5rQUag+v6KhhbhGNrFLa3NRdHCRU/6US8njnzbDoSJ626tNJHploeSq81/Efjw0k
7
- 5eEx4EsB1Tp0JIIuKtzxfde1EkFJnU7cJa2EBWdjxfz77QGwkDRmzHUnyyNlP6BE
8
- NQIDAQAB
9
- -----END PUBLIC KEY-----
1
+ -----BEGIN PUBLIC KEY-----
2
+ MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApTPS/ietBUIm+g6byuFV
3
+ /fbW2HmGomL8PQ1JJ3ZEjbsMQhEJ066xrdOlpI/Up09Y6+aO4LUydUg4j1nQzaZF
4
+ K3Nk2kUqgNYcws2Qrrs3mnkuJ4w0heAaACtaCjYpM3/Rlk2z7HKqJbCCvJVVVW7J
5
+ yohUHunGZZPP5qIutEaGssETbmnmqxUqgY6TfgzhU4rCRBDabHxop/jRZ3qdWSXp
6
+ 5rQUag+v6KhhbhGNrFLa3NRdHCRU/6US8njnzbDoSJ626tNJHploeSq81/Efjw0k
7
+ 5eEx4EsB1Tp0JIIuKtzxfde1EkFJnU7cJa2EBWdjxfz77QGwkDRmzHUnyyNlP6BE
8
+ NQIDAQAB
9
+ -----END PUBLIC KEY-----
publickeys/partner11.pub CHANGED
@@ -1,9 +1,9 @@
1
- -----BEGIN PUBLIC KEY-----
2
- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAkyoHKQOqOF01tdC2JLSe
3
- jnhnNdljEBjKcAz6hfYwR8xsWXg17cFxY56/I788XLKME4WkKVmvsYGY4mfUOxcI
4
- gGJFxySelpK9jqMZgglCQU9mFzStuanrcxfpeuzEO4XTQk5fqwLc5bvmxEsjPcUV
5
- pkHR6TkgHP1yoyMMLb+OKrgsy2iATvONlh8iI+luynx72ZkyypVdhSoRwy9viRXW
6
- LxL2kpLgWrAQG+SJX0/T8Djtm2lqpw3V/vzFBZ6Npfv3TwPm3jjDcW2XiYG/LBvF
7
- o6VWnVdsTvAkh1+Zhqq7WQLThWtE2xW4kJqXqDzLHq9l+fEzDdqjQr9WEtKy2RKb
8
- 5QIDAQAB
9
- -----END PUBLIC KEY-----
1
+ -----BEGIN PUBLIC KEY-----
2
+ MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAkyoHKQOqOF01tdC2JLSe
3
+ jnhnNdljEBjKcAz6hfYwR8xsWXg17cFxY56/I788XLKME4WkKVmvsYGY4mfUOxcI
4
+ gGJFxySelpK9jqMZgglCQU9mFzStuanrcxfpeuzEO4XTQk5fqwLc5bvmxEsjPcUV
5
+ pkHR6TkgHP1yoyMMLb+OKrgsy2iATvONlh8iI+luynx72ZkyypVdhSoRwy9viRXW
6
+ LxL2kpLgWrAQG+SJX0/T8Djtm2lqpw3V/vzFBZ6Npfv3TwPm3jjDcW2XiYG/LBvF
7
+ o6VWnVdsTvAkh1+Zhqq7WQLThWtE2xW4kJqXqDzLHq9l+fEzDdqjQr9WEtKy2RKb
8
+ 5QIDAQAB
9
+ -----END PUBLIC KEY-----
publickeys/partner12.pub CHANGED
@@ -1,9 +1,9 @@
1
- -----BEGIN PUBLIC KEY-----
2
- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxzbLmjytu3VTo8vHvgUJ
3
- zPqDSkHcSwYPzJVPcnjThgRADG8xK9pw8NHiw3OYm+2pYosYDiGHQAisDczxcuUW
4
- ELKBb9YtSlgdQUcUrvmuf8Hsb8ryvy2b62T+qA2bHxL6Nfku9T58TD5YuFvjSMa/
5
- Zue6zd9lhkHb7oEyd0oT+Izdw2+2Cc4lPBANeAP5JlcLzGNXc1Z6fKcMYqUe/gJa
6
- MdfkZEEmsbPjW97bsPhXZ2wElImgnILyMx7zozA0vkkmwPdBZbZeIZkfrOAFgMMN
7
- PdhHPRNUJPaFN3W4VsMWsRtblj1YOwvlNiNdtDmCBZGNnCMKq0zXHCLJjpaQGQP7
8
- qwIDAQAB
9
- -----END PUBLIC KEY-----
1
+ -----BEGIN PUBLIC KEY-----
2
+ MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxzbLmjytu3VTo8vHvgUJ
3
+ zPqDSkHcSwYPzJVPcnjThgRADG8xK9pw8NHiw3OYm+2pYosYDiGHQAisDczxcuUW
4
+ ELKBb9YtSlgdQUcUrvmuf8Hsb8ryvy2b62T+qA2bHxL6Nfku9T58TD5YuFvjSMa/
5
+ Zue6zd9lhkHb7oEyd0oT+Izdw2+2Cc4lPBANeAP5JlcLzGNXc1Z6fKcMYqUe/gJa
6
+ MdfkZEEmsbPjW97bsPhXZ2wElImgnILyMx7zozA0vkkmwPdBZbZeIZkfrOAFgMMN
7
+ PdhHPRNUJPaFN3W4VsMWsRtblj1YOwvlNiNdtDmCBZGNnCMKq0zXHCLJjpaQGQP7
8
+ qwIDAQAB
9
+ -----END PUBLIC KEY-----
publickeys/partner13.pub CHANGED
@@ -1,9 +1,9 @@
1
- -----BEGIN PUBLIC KEY-----
2
- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0B9sRvkgoao+YaSTk5Wy
3
- hQFLjw/PaEfGgqpk2/MqaVZSBFHsJxUYjwoTUOWeJEhXE18jQKHKJYjcs/77y1Mc
4
- dB9UWOoRk7XDZNVMVhW9lO4Vi3Gr43WnIPiePkvJILN3kN8S+UjM9loKcKIwtr3k
5
- /5Kcu7HZu+vqh5dZQwhTspDN4nW9JMqKEWDL4gj4ggFu6PaTGqo5JyRoLzay1In5
6
- oxUs7QALi8W9CzICiuhtdvjvHXcnmg7YeW+kWYuahkn1E7C4P/rWGN6M7NGyuWtj
7
- Q5w7eTpwAg6uxlXMtmVwX5cXLszuFZOaf/OJDBuLIxVBtklwn0BBAAVLpaYFUGnQ
8
- DQIDAQAB
9
- -----END PUBLIC KEY-----
1
+ -----BEGIN PUBLIC KEY-----
2
+ MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0B9sRvkgoao+YaSTk5Wy
3
+ hQFLjw/PaEfGgqpk2/MqaVZSBFHsJxUYjwoTUOWeJEhXE18jQKHKJYjcs/77y1Mc
4
+ dB9UWOoRk7XDZNVMVhW9lO4Vi3Gr43WnIPiePkvJILN3kN8S+UjM9loKcKIwtr3k
5
+ /5Kcu7HZu+vqh5dZQwhTspDN4nW9JMqKEWDL4gj4ggFu6PaTGqo5JyRoLzay1In5
6
+ oxUs7QALi8W9CzICiuhtdvjvHXcnmg7YeW+kWYuahkn1E7C4P/rWGN6M7NGyuWtj
7
+ Q5w7eTpwAg6uxlXMtmVwX5cXLszuFZOaf/OJDBuLIxVBtklwn0BBAAVLpaYFUGnQ
8
+ DQIDAQAB
9
+ -----END PUBLIC KEY-----
publickeys/partner14.pub CHANGED
@@ -1,9 +1,9 @@
1
- -----BEGIN PUBLIC KEY-----
2
- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxWvTKrJSWeIGGiDlWyRl
3
- 6pIpXLurQtsB2FltPhapMrGE5oBbWb//xw1GNqKh/hu6J2RVZNGZXovQ5s3u+TSq
4
- VwypAEpz45khycD5cgQFxaHKVOWTcl2+7bjQ2BeG9EON4luiNU5PbqasIyXP0fNj
5
- 5v1KHhST4GXxMeLeWYpMbMqn0i0CFn4dsvWW7yLqcBcxxeTMma0tF6qpXHfIEC3m
6
- 1IpYKkQmGNJUz0Kaql9Dm5R2QjG/ZNDQeJXe0bKnX4NoC8zmGZ7Edw9b4KLDrTAX
7
- G49jUuGzWnro5gwLfWrqnugfso/unoD26Br7FD1ItD/MnzsTGnEu5yFOrEw3EzJv
8
- aQIDAQAB
9
- -----END PUBLIC KEY-----
1
+ -----BEGIN PUBLIC KEY-----
2
+ MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxWvTKrJSWeIGGiDlWyRl
3
+ 6pIpXLurQtsB2FltPhapMrGE5oBbWb//xw1GNqKh/hu6J2RVZNGZXovQ5s3u+TSq
4
+ VwypAEpz45khycD5cgQFxaHKVOWTcl2+7bjQ2BeG9EON4luiNU5PbqasIyXP0fNj
5
+ 5v1KHhST4GXxMeLeWYpMbMqn0i0CFn4dsvWW7yLqcBcxxeTMma0tF6qpXHfIEC3m
6
+ 1IpYKkQmGNJUz0Kaql9Dm5R2QjG/ZNDQeJXe0bKnX4NoC8zmGZ7Edw9b4KLDrTAX
7
+ G49jUuGzWnro5gwLfWrqnugfso/unoD26Br7FD1ItD/MnzsTGnEu5yFOrEw3EzJv
8
+ aQIDAQAB
9
+ -----END PUBLIC KEY-----
publickeys/partner15.pub CHANGED
@@ -1,9 +1,9 @@
1
- -----BEGIN PUBLIC KEY-----
2
- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3btn2odEVqxsqvd0lgD0
3
- PbqxVrPnvM1/gV14vgujb69XPdIc3nfdUtQJdYhLpTi5lEnutelFu293v6FW1L9p
4
- ZdMnzgGZonUdn6ZEwOqcSiVIuBUDKgSvjskU/RU6jnb4/2Mu5gY384y2VzD/wXCu
5
- yme+pKi+ta4CnqDn3udW3giL8fQT7oq2WhQEWmZOGTJtbaFeMgbtDLHzgdZaMkpR
6
- ecbjuvdvN5TMG7PuzcunyD0BOeEX1l6sf1/OyUFKHqubxzwoVext70HBRSJLy/TS
7
- lcNiCtBnsKb0AxVI0ZSAFmVO4H14fsVhk6whGiyqDr2sHxjZXlwOE1t3+HRK74Sn
8
- OQIDAQAB
9
- -----END PUBLIC KEY-----
1
+ -----BEGIN PUBLIC KEY-----
2
+ MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3btn2odEVqxsqvd0lgD0
3
+ PbqxVrPnvM1/gV14vgujb69XPdIc3nfdUtQJdYhLpTi5lEnutelFu293v6FW1L9p
4
+ ZdMnzgGZonUdn6ZEwOqcSiVIuBUDKgSvjskU/RU6jnb4/2Mu5gY384y2VzD/wXCu
5
+ yme+pKi+ta4CnqDn3udW3giL8fQT7oq2WhQEWmZOGTJtbaFeMgbtDLHzgdZaMkpR
6
+ ecbjuvdvN5TMG7PuzcunyD0BOeEX1l6sf1/OyUFKHqubxzwoVext70HBRSJLy/TS
7
+ lcNiCtBnsKb0AxVI0ZSAFmVO4H14fsVhk6whGiyqDr2sHxjZXlwOE1t3+HRK74Sn
8
+ OQIDAQAB
9
+ -----END PUBLIC KEY-----
publickeys/partner16.pub CHANGED
@@ -1,9 +1,9 @@
1
- -----BEGIN PUBLIC KEY-----
2
- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAo5RculesjuT4aZH8jp/r
3
- 9LAcH40H1zu5hul1WADZQEymlHB2kqP25GQPAeSfb8omO9LubyM9pgddsLflV15G
4
- jZ3KWPwa34VUtLQtk9ibU0LTnepqn3bWCVRe9AoEAYdPTVCgdvPYY9J0JD8NvB5G
5
- ndTRPNOiBuq8Fj5+oY3dvWWH2efW1OtcUq30l3i82PtpxxI6AzOCTRBEGAegx6FF
6
- +tuQR+33Apjyj4FuSDHwuRweyu+exBnMBNo5FtoYeTfIy6xHujGZ3av2YTijjAQ/
7
- 4c6+7FXXXdPGK7KhG5WaLL4Wi1eXsEL7J8EtxQLYaCXWQkYbs7ZZOCDiEMbJKbMz
8
- 2wIDAQAB
9
- -----END PUBLIC KEY-----
1
+ -----BEGIN PUBLIC KEY-----
2
+ MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAo5RculesjuT4aZH8jp/r
3
+ 9LAcH40H1zu5hul1WADZQEymlHB2kqP25GQPAeSfb8omO9LubyM9pgddsLflV15G
4
+ jZ3KWPwa34VUtLQtk9ibU0LTnepqn3bWCVRe9AoEAYdPTVCgdvPYY9J0JD8NvB5G
5
+ ndTRPNOiBuq8Fj5+oY3dvWWH2efW1OtcUq30l3i82PtpxxI6AzOCTRBEGAegx6FF
6
+ +tuQR+33Apjyj4FuSDHwuRweyu+exBnMBNo5FtoYeTfIy6xHujGZ3av2YTijjAQ/
7
+ 4c6+7FXXXdPGK7KhG5WaLL4Wi1eXsEL7J8EtxQLYaCXWQkYbs7ZZOCDiEMbJKbMz
8
+ 2wIDAQAB
9
+ -----END PUBLIC KEY-----
publickeys/partner17.pub CHANGED
@@ -1,9 +1,9 @@
1
- -----BEGIN PUBLIC KEY-----
2
- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmumb22xILsQPdKj0CFDw
3
- V4z1F2ZRsm91gItyeoUxaqZJAxPXdPk+rkLN2nuuRGNvWr0Xjz0gNvObehFqzdmz
4
- KVK/uXaD2SEpaka9Z68KiucUVdUJrHgrhJ19PBsXoFY8ZG1Nq82WTDVbguCvm626
5
- tAo6jKJ4/oimWioSaRxKoIFVIYGZPRNP53Ggawwlnruf+SG2f5AiZhVAS6wagM/F
6
- LLwNatUuw7dXdkrzY/+w2bKtLP7DsZy6fMkiZPvKgHvnYoMQfMtuNw0V3bTEZHQv
7
- C9ZAvRngePj66iHfjOWXBbHBMb16TK+2zHSwvE7i/jOQQUM3mmREAiHeholVtqaC
8
- nwIDAQAB
9
- -----END PUBLIC KEY-----
1
+ -----BEGIN PUBLIC KEY-----
2
+ MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmumb22xILsQPdKj0CFDw
3
+ V4z1F2ZRsm91gItyeoUxaqZJAxPXdPk+rkLN2nuuRGNvWr0Xjz0gNvObehFqzdmz
4
+ KVK/uXaD2SEpaka9Z68KiucUVdUJrHgrhJ19PBsXoFY8ZG1Nq82WTDVbguCvm626
5
+ tAo6jKJ4/oimWioSaRxKoIFVIYGZPRNP53Ggawwlnruf+SG2f5AiZhVAS6wagM/F
6
+ LLwNatUuw7dXdkrzY/+w2bKtLP7DsZy6fMkiZPvKgHvnYoMQfMtuNw0V3bTEZHQv
7
+ C9ZAvRngePj66iHfjOWXBbHBMb16TK+2zHSwvE7i/jOQQUM3mmREAiHeholVtqaC
8
+ nwIDAQAB
9
+ -----END PUBLIC KEY-----
publickeys/partner2.pub CHANGED
@@ -1,9 +1,9 @@
1
- -----BEGIN PUBLIC KEY-----
2
- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2doy5JneOGkPchV/zd8s
3
- K3xm6jr1T6YX1ORGZA4+0QEmLbr70VAcrO/ptdEzze9afJUAT0Mey3sa/9oOXeqO
4
- 3NI8xdFs9nXOIUKBUDBQsxWVdrOohZnQa/r8V+zeqmMl/FeZob+K1wIyFbKKVKBn
5
- NoSEQDzYUa5PbTNSJpaOhe1EalxHyucZALdeXcM00tMYOuXvOOLxM+QOG2OBXIIV
6
- FiGkLFiCi3bvJlhw/68gY2zH0xZfcyOsGj6260Y9fQ+D2yA15jlsksFT2hcj2T5D
7
- RuF0UCZqPKtQgOjpd3b4N4ZVZ7KlxAknZIHC9bf0sA7nKVr2oQY9BJrCUNOKhYjC
8
- WQIDAQAB
9
- -----END PUBLIC KEY-----
1
+ -----BEGIN PUBLIC KEY-----
2
+ MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2doy5JneOGkPchV/zd8s
3
+ K3xm6jr1T6YX1ORGZA4+0QEmLbr70VAcrO/ptdEzze9afJUAT0Mey3sa/9oOXeqO
4
+ 3NI8xdFs9nXOIUKBUDBQsxWVdrOohZnQa/r8V+zeqmMl/FeZob+K1wIyFbKKVKBn
5
+ NoSEQDzYUa5PbTNSJpaOhe1EalxHyucZALdeXcM00tMYOuXvOOLxM+QOG2OBXIIV
6
+ FiGkLFiCi3bvJlhw/68gY2zH0xZfcyOsGj6260Y9fQ+D2yA15jlsksFT2hcj2T5D
7
+ RuF0UCZqPKtQgOjpd3b4N4ZVZ7KlxAknZIHC9bf0sA7nKVr2oQY9BJrCUNOKhYjC
8
+ WQIDAQAB
9
+ -----END PUBLIC KEY-----
publickeys/partner3.pub CHANGED
@@ -1,9 +1,9 @@
1
- -----BEGIN PUBLIC KEY-----
2
- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3Rrmegqtq6ULsQe2duIf
3
- 5L/mBZ4aGOSxWjTh+nX7198E26Tt3BpmeNM0f6nZoaHORaWQBcbtwGTiwLh+ceZS
4
- 9OGe3mh0BcMqCoaqJLEJXTPccAFcSRkti6ib2/IGRFmR4U76oy9IS0ncp79WVde1
5
- X2RP8w2PC/IHjztzL40vT+8G+CbxtugdSe+d0Qg13beZngJ64SzCl3OEoe0L/3Da
6
- KZoHfUJAhGAZH210XWq8qD1FQTab7OIbgIV4zwTB++5oYfhZ2TTE+FfBKmzBrrE9
7
- w+EtutF2oFapbvJB6I3HQNprogdiedBBiQDddVPyWX3KqlFUOi13SjyRivJfbyYi
8
- owIDAQAB
9
- -----END PUBLIC KEY-----
1
+ -----BEGIN PUBLIC KEY-----
2
+ MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3Rrmegqtq6ULsQe2duIf
3
+ 5L/mBZ4aGOSxWjTh+nX7198E26Tt3BpmeNM0f6nZoaHORaWQBcbtwGTiwLh+ceZS
4
+ 9OGe3mh0BcMqCoaqJLEJXTPccAFcSRkti6ib2/IGRFmR4U76oy9IS0ncp79WVde1
5
+ X2RP8w2PC/IHjztzL40vT+8G+CbxtugdSe+d0Qg13beZngJ64SzCl3OEoe0L/3Da
6
+ KZoHfUJAhGAZH210XWq8qD1FQTab7OIbgIV4zwTB++5oYfhZ2TTE+FfBKmzBrrE9
7
+ w+EtutF2oFapbvJB6I3HQNprogdiedBBiQDddVPyWX3KqlFUOi13SjyRivJfbyYi
8
+ owIDAQAB
9
+ -----END PUBLIC KEY-----
publickeys/partner4.pub CHANGED
@@ -1,9 +1,9 @@
1
- -----BEGIN PUBLIC KEY-----
2
- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAutt+iSy6VG70mFzbkUTj
3
- 4CUZoL2wgXRfJ3sNPMg92bvQarIZRdbaydRttUHPYovFrFPBFUzHfxuISyxZbDYb
4
- wKbviq+T4YCcYo+oy79CMsUfB22Lzm8hlt0c1i3DWrQ1T0NDV2bhT+tTJs6cS1Jv
5
- Vu1Ze5ZUWiv+e61kNDvSctInX7nYPxBGuzpCci2tiWAAvvlmKVuRJDMhiSrEAFe2
6
- +5EU5kaUZiQrdXdOViBWhdm1V/QidPD7MubATwVgucsZG0S0DDw7nHyh1t6CcAhd
7
- IgIs13hZJy8FpDt6CLnHU/aM0Oufua42h4uBzkqADQ0Zw6jmTtZI7Dnmj9cnAdic
8
- dwIDAQAB
9
  -----END PUBLIC KEY-----
1
+ -----BEGIN PUBLIC KEY-----
2
+ MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAutt+iSy6VG70mFzbkUTj
3
+ 4CUZoL2wgXRfJ3sNPMg92bvQarIZRdbaydRttUHPYovFrFPBFUzHfxuISyxZbDYb
4
+ wKbviq+T4YCcYo+oy79CMsUfB22Lzm8hlt0c1i3DWrQ1T0NDV2bhT+tTJs6cS1Jv
5
+ Vu1Ze5ZUWiv+e61kNDvSctInX7nYPxBGuzpCci2tiWAAvvlmKVuRJDMhiSrEAFe2
6
+ +5EU5kaUZiQrdXdOViBWhdm1V/QidPD7MubATwVgucsZG0S0DDw7nHyh1t6CcAhd
7
+ IgIs13hZJy8FpDt6CLnHU/aM0Oufua42h4uBzkqADQ0Zw6jmTtZI7Dnmj9cnAdic
8
+ dwIDAQAB
9
  -----END PUBLIC KEY-----
publickeys/partner5.pub CHANGED
@@ -1,9 +1,9 @@
1
- -----BEGIN PUBLIC KEY-----
2
- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArcJ794ai0mbaaY17yhlb
3
- umJ1OiBEHOthp0M7DT3o+42gLB19jZtaWZPtPZFRudgN5Z6N+X0ufd7yD92uL1vg
4
- /WMuvB4LM1FKiVTrpa8/runZGek4hVNktE67gR6ut5Zwbuc5O8zTwyNj/KuEiI6t
5
- NSMMceiWElGTb0xOFdkeGq7tGJlwFXJ41zFpp5Ej61vAv4vW1WJL5ztx1l2ALOKX
6
- swbdvT3+Ht8it/wXMykPCYhDnr4oHnl9tz6dGe61xPDvSs9zb6IX5N+J0sPVN3Th
7
- VIVUS2GD1eyzPkAgo0TyScefYr1sVFHn1YxFzFZpeYsAKnhsthkNBxIQaYEc+A9w
8
- 9QIDAQAB
9
- -----END PUBLIC KEY-----
1
+ -----BEGIN PUBLIC KEY-----
2
+ MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArcJ794ai0mbaaY17yhlb
3
+ umJ1OiBEHOthp0M7DT3o+42gLB19jZtaWZPtPZFRudgN5Z6N+X0ufd7yD92uL1vg
4
+ /WMuvB4LM1FKiVTrpa8/runZGek4hVNktE67gR6ut5Zwbuc5O8zTwyNj/KuEiI6t
5
+ NSMMceiWElGTb0xOFdkeGq7tGJlwFXJ41zFpp5Ej61vAv4vW1WJL5ztx1l2ALOKX
6
+ swbdvT3+Ht8it/wXMykPCYhDnr4oHnl9tz6dGe61xPDvSs9zb6IX5N+J0sPVN3Th
7
+ VIVUS2GD1eyzPkAgo0TyScefYr1sVFHn1YxFzFZpeYsAKnhsthkNBxIQaYEc+A9w
8
+ 9QIDAQAB
9
+ -----END PUBLIC KEY-----
publickeys/partner6.pub CHANGED
@@ -1,9 +1,9 @@
1
- -----BEGIN PUBLIC KEY-----
2
- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0eZeh+/7qFWecpGLTpwJ
3
- ShKZ6ZtfS8IeRwAsKmEZavcZH/uCTioq9L+rDhXrVE07jv5QQZfzQzosycU3Nnfa
4
- yBpuPynECzBfHbKKnoVb5PMllH2/Dj7skC5kTfOpugiymLpNhIcWfJS6empwfG0i
5
- 67xYJYS7Eik+5+ALhF54KaKZ5C5HAYhcPi3NDFrHecg/t+fio8Tvd4U5ZrxloTDR
6
- 8t4p3cfPEVMJ6udCMfP6xQbVNvTV3VHUemmRaxVSTUjAJfeIRqtnLDVusrIYyxdR
7
- xjct4hDbajE0f82BefDq6g79qyc47LrxYxUypdryT+06WHsJ5wz/0BbrTGxK22mt
8
- eQIDAQAB
9
- -----END PUBLIC KEY-----
1
+ -----BEGIN PUBLIC KEY-----
2
+ MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0eZeh+/7qFWecpGLTpwJ
3
+ ShKZ6ZtfS8IeRwAsKmEZavcZH/uCTioq9L+rDhXrVE07jv5QQZfzQzosycU3Nnfa
4
+ yBpuPynECzBfHbKKnoVb5PMllH2/Dj7skC5kTfOpugiymLpNhIcWfJS6empwfG0i
5
+ 67xYJYS7Eik+5+ALhF54KaKZ5C5HAYhcPi3NDFrHecg/t+fio8Tvd4U5ZrxloTDR
6
+ 8t4p3cfPEVMJ6udCMfP6xQbVNvTV3VHUemmRaxVSTUjAJfeIRqtnLDVusrIYyxdR
7
+ xjct4hDbajE0f82BefDq6g79qyc47LrxYxUypdryT+06WHsJ5wz/0BbrTGxK22mt
8
+ eQIDAQAB
9
+ -----END PUBLIC KEY-----
publickeys/partner7.pub CHANGED
@@ -1,9 +1,9 @@
1
- -----BEGIN PUBLIC KEY-----
2
- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu6Em6gaB1pI0CJ1wUGkR
3
- vKBBTm75WAgfpZCbSBoSrruxCsOl4ofADJU8kLPOSmoXtuQikfDIYkZiKW9R4+5J
4
- Xq81hEzkhEWP67ggbAXlVsTxhuNLPFb7C0QLLaHAAcQwY7amaOKj584DiePvhZNe
5
- aIllbON8jbajEIacXBRvgCpkJISciEpwHfwSYdYkBMHbTzaYumUPUQ1K47zw6b9s
6
- Rs60Hoz9ojRvEhxNUXSWa2ztnb0Us6xeIR/waUHMVdTOinpPDUPMSLSjBrSYRs8D
7
- GL3wfIJu+DKpV+LBjDv+kgf5hs05gstrZ96N6pZW4L85gWQvS4tPXC3rr70OKdy5
8
- mQIDAQAB
9
- -----END PUBLIC KEY-----
1
+ -----BEGIN PUBLIC KEY-----
2
+ MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu6Em6gaB1pI0CJ1wUGkR
3
+ vKBBTm75WAgfpZCbSBoSrruxCsOl4ofADJU8kLPOSmoXtuQikfDIYkZiKW9R4+5J
4
+ Xq81hEzkhEWP67ggbAXlVsTxhuNLPFb7C0QLLaHAAcQwY7amaOKj584DiePvhZNe
5
+ aIllbON8jbajEIacXBRvgCpkJISciEpwHfwSYdYkBMHbTzaYumUPUQ1K47zw6b9s
6
+ Rs60Hoz9ojRvEhxNUXSWa2ztnb0Us6xeIR/waUHMVdTOinpPDUPMSLSjBrSYRs8D
7
+ GL3wfIJu+DKpV+LBjDv+kgf5hs05gstrZ96N6pZW4L85gWQvS4tPXC3rr70OKdy5
8
+ mQIDAQAB
9
+ -----END PUBLIC KEY-----
publickeys/partner8.pub CHANGED
@@ -1,9 +1,9 @@
1
- -----BEGIN PUBLIC KEY-----
2
- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0XrrzSYYtUJ8oKQcR6D0
3
- 4M/8sX6yJDpqNElrOj0YMwXuDyDiE4r9BqO+G5P2paZWIZFrC1reyaIiNIdNgcyr
4
- 7RcK1eVJZ+VW1mw7srCGgJiVyNXMawu02YlJenzgDUb4dqDqzPaa2XlEzP5YNZOY
5
- /DALizkX6uPvHlsH4UQxEZ7UK2a7hYWEwLYklj24WFGLaqXfm3scIckgdg3S5s+v
6
- KX/jqNZpCFzwdqPx09CYTlDL2Dl/kBuw5DwUrNJl+rWFtQsP2JjxSbyuxe+9XeCl
7
- Gb88lUxNPbO7C6OogTqFt+K3BnCficN0KQ6HNpmpwB4Cp5ckd85zmQemFnCXhMPu
8
- ZwIDAQAB
9
- -----END PUBLIC KEY-----
1
+ -----BEGIN PUBLIC KEY-----
2
+ MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0XrrzSYYtUJ8oKQcR6D0
3
+ 4M/8sX6yJDpqNElrOj0YMwXuDyDiE4r9BqO+G5P2paZWIZFrC1reyaIiNIdNgcyr
4
+ 7RcK1eVJZ+VW1mw7srCGgJiVyNXMawu02YlJenzgDUb4dqDqzPaa2XlEzP5YNZOY
5
+ /DALizkX6uPvHlsH4UQxEZ7UK2a7hYWEwLYklj24WFGLaqXfm3scIckgdg3S5s+v
6
+ KX/jqNZpCFzwdqPx09CYTlDL2Dl/kBuw5DwUrNJl+rWFtQsP2JjxSbyuxe+9XeCl
7
+ Gb88lUxNPbO7C6OogTqFt+K3BnCficN0KQ6HNpmpwB4Cp5ckd85zmQemFnCXhMPu
8
+ ZwIDAQAB
9
+ -----END PUBLIC KEY-----
publickeys/partner9.pub CHANGED
@@ -1,9 +1,9 @@
1
- -----BEGIN PUBLIC KEY-----
2
- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyGLveJUzI1fC7rufjTSU
3
- 1Es6Xly3Jdf5/qs+RwXp8qmKpaoZTVJO9Uk1ixi8alvC2Hq6v0qMHU/xgFAMU9y1
4
- TsVDgSJc4djLl8VrX7glyB8O12UqByk+ND+c4p6v4oUfothxr9wEr+jdlBH68eDJ
5
- XZ5jO7bU9Sh398KRj8jTzkgrSLTe0GkSrErzIq46B+wGx2RZlyKpMW7F7nLRcCpt
6
- ZH5vPatWt8gnw+8M0D66WETdUZrQaG0GYcMmE+LuVOTgx+mHMLH+ntd/B7K7NGHh
7
- fPnUm2nIG+oOgAj1RZzRi5qUF4+XFBmBWJV2vEM7HinYJlAsgCFMF6IaVAf3/ula
8
- HQIDAQAB
9
- -----END PUBLIC KEY-----
1
+ -----BEGIN PUBLIC KEY-----
2
+ MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyGLveJUzI1fC7rufjTSU
3
+ 1Es6Xly3Jdf5/qs+RwXp8qmKpaoZTVJO9Uk1ixi8alvC2Hq6v0qMHU/xgFAMU9y1
4
+ TsVDgSJc4djLl8VrX7glyB8O12UqByk+ND+c4p6v4oUfothxr9wEr+jdlBH68eDJ
5
+ XZ5jO7bU9Sh398KRj8jTzkgrSLTe0GkSrErzIq46B+wGx2RZlyKpMW7F7nLRcCpt
6
+ ZH5vPatWt8gnw+8M0D66WETdUZrQaG0GYcMmE+LuVOTgx+mHMLH+ntd/B7K7NGHh
7
+ fPnUm2nIG+oOgAj1RZzRi5qUF4+XFBmBWJV2vEM7HinYJlAsgCFMF6IaVAf3/ula
8
+ HQIDAQAB
9
+ -----END PUBLIC KEY-----
readme.txt CHANGED
@@ -1,315 +1,380 @@
1
- === ManageWP Worker ===
2
- Contributors: freediver
3
- Donate link: https://www.networkforgood.org/donation/MakeDonation.aspx?ORGID2=520781390
4
- Tags: admin, analytics, administration, amazon, api, google drive, authentication, automatic, dashboard, dropbox, events, integration, manage, multsite, notification, performance, s3, security, seo, stats, tracking, managewp
5
- Requires at least: 3.0
6
- Tested up to: 3.9
7
- Stable tag: trunk
8
-
9
- ManageWP Worker plugin allows you to remotely manage your WordPress sites from one dashboard.
10
-
11
- == Description ==
12
-
13
- [ManageWP](https://managewp.com/ "Manage Multiple Blogs") is a revolutionary service that automates the management of multiple WordPress websites. ManageWP Worker Plugin allows your site to communicate with the service, and is needed in order to enjoy all these features:
14
-
15
- Main features:
16
-
17
- * Secure and fast solution for managing multiple WordPress sites
18
- * One click upgrades for WordPress, plugin and themes across all your sites
19
- * Schedule automatic backups of your websites (Amazon S3, Google Drive and Dropbox supported)
20
- * One click to access WP admin of any site
21
- * Install WordPress, clone or migrate a website to another domain
22
- * Bulk install themes and plugins to multiple sites at once
23
- * Add sub-users (writers, staff..) to your account
24
- * SEO Statistics, track your keyword rankings
25
- * Uptime monitoring - receive an SMS notification ifyour site goes down
26
- * Bulk publish posts to multiple sites at once
27
-
28
- Check out the [ManageWP Tour video](http://vimeo.com/61268162).
29
-
30
- http://vimeo.com/61268162
31
-
32
- Check out [ManageWP.com](https://managewp.com/ "Manage Multiple Blogs").
33
-
34
- == Changelog ==
35
-
36
- = 3.9.29 =
37
-
38
- - New: Worker plugin is now 36% faster and uses 83% less memory
39
- - New: Backup no longer relies on WordPress cron
40
- - New: New Server-Client communication fixing some of the previous issues
41
- - New: Notes and Recent backups widgets
42
- - New: Refreshed app interface :)
43
-
44
- = 3.9.28 =
45
- - New: Control Wordpress Automatic Background Updates for plugins and themes!
46
- - Fix: Tweaks to SFTP support for backups and clone
47
- - Fix: Enhancements to Backup and Branding features
48
-
49
-
50
- = 3.9.27 =
51
- - New: SFTP support for backups and clone!
52
- - Fix: Database dump for backup tasks with defined socket path or port number in wp-config.php
53
- - Fix: Optimize Wordpress tables before backup
54
- - Fix: Compatibility with Better WP Security
55
- - Fix: Not adding jQuery on front page while using branding option
56
-
57
- = 3.9.26 =
58
- - New: Improved branding feature
59
- - New: Disable Plugin and Theme changes for your clients
60
- - New: Support Page for non-Admin Users
61
- - New: Manage biographical info of user
62
- - Fix: Restore backup action keeps all backup tasks and backups
63
- - Fix: Add/delete post action uses WordPress hook
64
- - Fix: Delete user action was not functioning properly
65
-
66
- = 3.9.25 =
67
- - New: Improved Worker branding feature
68
- - Fix: Traffic alerts feature was not functioning properly
69
- - Fix: Backup information was sometimes incorrectly displayed
70
- - Fix: DB Table overhead was not shown on the dashboard
71
-
72
- = 3.9.24 =
73
- - New: Better support for large database dumps
74
- - Fix: PHP notice for WordPress 3.5
75
- - Fix: Support for automatic backup reports
76
- - Fix: Incorrect backup result message for S3 large files
77
-
78
- = 3.9.23 =
79
- - New: SEO reports can be branded and viewed by sharing an URL
80
- - New: Set custom database prefix for new clone destination
81
- - New: Automatic change all URL paths for new clone destination
82
- - New: Success and fail email notifications for scheduled backup tasks
83
- - Fix: Improved scheduled backups for limited server resources
84
- - Fix: Improved backup to Dropbox (now supporting larger backup files)
85
- - Fix: Handling of external images with bulk posting
86
- - Fix: Display plugin versions on manage plugins
87
- - Fix: Deprecated get_themes function
88
- - Fix: Special characters support for notes
89
-
90
- = 3.9.22 =
91
- - New: Backup support for Google Drive
92
- - 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!)
93
- - New: Support for Google Analytics API 3.0
94
- - New: Website preview screenshot
95
- - New: Ability to assign a newly added website to existing Backup tasks (under "advanced" in add website dialogue)
96
- - Fix: Clone tool now supports special characters and localized WP installs
97
- - Fix: Backup history preserved on website re-add
98
-
99
- = 3.9.21 =
100
- * New: Continuous updates! Read more at http://managewp.com/continuous-updates
101
-
102
- = 3.9.20 =
103
- * New: ManageWP iOS app compatibility
104
- * New: Perform security and performance test as you add websites
105
- * New: New comment handling screen
106
-
107
- = 3.9.19 =
108
- * New: Improved mechanism for refreshing website stats. You should have fresh information every 4 hours without refreshing now
109
- * Fix: Categories now showing properly in Manage posts
110
- * Fix: Website stats now ignore uptime monitoring pings
111
-
112
- = 3.9.18 =
113
- * New: Pagelines themes added to the list of partners
114
- * New: Comprehensive website performance scan tool
115
- * New: You can now bulk edit posts/pages (updating that contact info will become piece of cake)
116
- * New: Upload and save your premium plugins/themes in your personal repository for quick installation
117
- * New: Run code snippets now get a repository. Save your snippets and share them with other users
118
- * New: SEO reports can now be sorted. Export as CSV and PDF reports.
119
- * New: Manage Blogroll links
120
- * New: Clean post revisions now has an option to save last x revisions when cleaning
121
- * New: Bulk delete na posts/pages/links
122
- * Fix: Amazon S3 backups failing
123
-
124
- = 3.9.17 =
125
- * New: Add your favorite sites to the Favorites bar (just drag&drop them to the small heart on the top)
126
- * New: Entirely new website menu loaded with features and tools
127
- * New: Manage Posts and Pages across all sites in a more efficient way
128
- * New: Support for all WPMU.org premium plugin updates
129
- * New: Complete Dropbox integration through Oauth which allows us to restore/delete Dropbox backups directly
130
- * New: We have the user guide as PDF now. [Download] (http://managewp.com/files/ManageWP_User_Guide.zip)
131
-
132
-
133
- = 3.9.16 =
134
- * New: Option to "Run now" backup tasks
135
- * New: Traffic alerts functionality
136
- * New: Support for Genesis premium theme updates
137
- * Fix: In some circutmsances .htaccess was not correctly zipped in the backup archive
138
-
139
- = 3.9.15 =
140
- * New: Full range of SEO Statistics now trackable for your websites (Google Page Rank and Page Speed, Backlinks and 20+ more)
141
- * New: Google keyword rank tracking with history
142
- * New: Uptime monitoring (5 min interval with email/SMS notification)
143
- * New: Insights into server PHP error logs right in your dashboard
144
- * New: Remote maintenance mode for your websites
145
- * Fix: A bug when a completed backup was reported as failed
146
-
147
- = 3.9.14 =
148
- * Two factor authentication
149
- * Run code tool
150
- * Quick access to security check and broken link tools
151
- * More accurate pageview statistics
152
- * You can now opt to completely hide the Worker plugin from the list of plugins (part of Worker branding features)
153
- * We improved the backups for folks running Windows servers
154
- * Amazon S3 directory name now "ManageWP" by default
155
- * Read more on ManageWP.com http://managewp.com/update-two-factor-authentication-run-code-tool-sucuri-security-check-more-accurate-pageview-statistics
156
-
157
- = 3.9.13 =
158
- * Added bucket location for Amazon S3 backups
159
- * Better backup feature for larger sites
160
- * Added Disable compression to further help with larger sites
161
- * Backing up wp-admin, wp-includes and wp-content by default now, other folders can be included manually
162
-
163
- = 3.9.12 =
164
- * Minor bug fixes
165
- * Backup, clone, favorites functionality improved
166
-
167
- = 3.9.10 =
168
- * Supporting updates for more premium plugins/themes
169
- * Backup notifications (users can now get notices when the backup succeeds or fails)
170
- * Support for WordPress 3.3
171
- * Worker Branding (useful for web agencies, add your own Name/Description)
172
- * Manage Groups screen
173
- * Specify wp-admin path if your site uses a custom one
174
- * Amazon S3 backups support for mixed case bucket names
175
- * Bulk Add Links has additional options
176
- * Better Multisite support
177
- * Option to set the number of items for Google Analytics
178
- * ManageWP backup folder changed to wp-content/managewp/backups
179
-
180
- = 3.9.9 =
181
- * New widget on the dashboard - Backup status
182
- * New screen for managing plugins and themes (activate, deactivate, delete, add to favorites, install) across all sites
183
- * New screen for managing users (change role or password, delete user) across all sites
184
- * Option to overwrite old plugins and themes during bulk installation
185
- * Your website admin now loads faster in ManageWP
186
- * Added API for premium theme and plugin updates
187
-
188
- = 3.9.8 =
189
- * Conversion goals integration
190
- * Update notifications
191
- * Enhanced security for your account
192
- * Better backups
193
- * Better update interface
194
- * [Full changelog](http://managewp.com/update-goals-and-adsense-analytics-integration-update-notifications-login-by-ip-better-backups "Full changelog")
195
-
196
- = 3.9.7 =
197
- * Fixed problem with cron schedules
198
-
199
- = 3.9.6 =
200
- * Improved dashboard performance
201
- * Fixed bug with W3TC, we hope it is fully comptabile now
202
- * Improved backup feature
203
- * Various other fixes and improvements
204
-
205
- = 3.9.5 =
206
- * Now supporting scheduled backups to Amazon S3 and Dropbox
207
- * Revamped cloning procedure
208
- * You can now have sites in different colors
209
- * W3 Total Cache comptability improved
210
-
211
- = 3.9.3 =
212
- * Included support for WordPress 3.2 partial updates
213
-
214
- = 3.9.2 =
215
- * Fixed problem with full backups
216
- * Fixed problem with wordpress dev version upgrades
217
-
218
- = 3.9.1 =
219
- * Support for sub-users (limited access users)
220
- * Bulk add user
221
- * 'Select all' feature for bulk posting
222
- * Featured image support for bulk posting
223
- * Reload button on the dashboard (on the top of the Right now widget) will now refresh information about available updates
224
- * Fixed a problem with the import tool
225
- * Fixed a problem when remote dashboard would not work for some servers
226
-
227
- = 3.9.0 =
228
- * New feature: Up to 50% faster dashboard loading
229
- * New feature: You can now ignore WordPress/plugin/theme updates
230
- * New feature: Setting 'Show favicon' for websites in the dashboad
231
- * New feature: Full backups now include WordPress and other folders in the root of the site
232
- * Fixed: Bug with W3 TotalCache object cache causing weird behaviour in the dashboard
233
- * Fixed: All groups now show when adding a site
234
-
235
- = 3.8.8 =
236
- * New feature: Bulk add links to blogroll
237
- * New feature: Manual backups to email address
238
- * New feature: Backup requirements check (under �Manage Backups�)
239
- * New feature: Popup menu for groups allowing to show dashboard for that group only
240
- * New feature: Favorite list for plugins and themes for later quick installation to multiple blogs
241
- * New feature: Invite friends
242
- * Fixed: problem with backups and write permissions when upload dir was wrongly set
243
- * Fixed: problem adding sites where WordPress is installed in a folder
244
- * Fixed: 408 error message problem when adding site
245
- * Fixed: site time out problems when adding site
246
- * Fixed: problems with some WP plugins (WP Sentinel)
247
- * Fixed: problems with upgrade notifications
248
-
249
- = 3.8.7 =
250
- * Fixed 408 error when adding sites
251
- * Added support for IDN domains
252
- * Fixed bug with WordPress updates
253
- * Added comment moderation to the dashboard
254
- * Added quick links for sites (menu appears on hover)
255
-
256
-
257
- = 3.8.6 =
258
- * Added seach websites feature
259
- * Enhanced dashboard actions (spam comments, post revisions, table overhead)
260
- * Added developer [API] (http://managewp.com/api "ManageWP API")
261
- * Improved Migrate/Clone site feature
262
-
263
- = 3.8.4 =
264
- * Fixed remote dashboard problems for sites with redirects
265
- * Fixed IE7 issues in the dashboard
266
-
267
- = 3.8.3 =
268
- * Fixed problem with capabilities
269
-
270
- = 3.8.2 =
271
- * New interface
272
- * SSL security protocol
273
- * No passwords required
274
- * Improved clone/backup
275
-
276
- = 3.6.3 =
277
- * Initial public release
278
-
279
- == Installation ==
280
-
281
- 1. Upload the plugin folder to your /wp-content/plugins/ folder
282
- 2. Go to the Plugins page and activate ManageWP Worker
283
- 3. Visit [ManageWP.com](https://managewp.com/ "ManageWP"), sign up and add your site
284
-
285
- Alternately
286
-
287
- 1. Visit [ManageWP.com](https://managewp.com/ "Manage Multiple WordPress Sites"), sign up and add your site
288
- 2. ManageWP will warn you the worker plugin is not installed and offer a link for quick installation
289
-
290
- == Screenshots ==
291
-
292
- 1. ManageWP dashboard with available upgrades, site statistics and management functions
293
-
294
-
295
-
296
- == License ==
297
-
298
- This file is part of ManageWP Worker.
299
-
300
- ManageWP Worker is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
301
-
302
- 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.
303
-
304
- You should have received a copy of the GNU General Public License along with ManageWP Worker. If not, see <http://www.gnu.org/licenses/>.
305
-
306
-
307
- == Frequently Asked Questions ==
308
-
309
- = I have problems adding my site =
310
-
311
- Make sure you use the latest version of the worker plugin on the site you are trying to add. If you do, sometimes deactivating and activating it again will help. If you still have problems, [contact us](http://managewp.com/contact "ManageWP Contact").
312
-
313
- = I have problems installing new plugins or upgrading WordPress through ManageWP =
314
-
315
- ManageWP Worker relies on properly set file permissions on your server. See the [user guide](https://managewp.com/user-guide#ftp "ManageWP user guide") for more tips.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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 WordPress Websites") is a revolutionary service that automates the management of multiple WordPress websites. ManageWP Worker Plugin allows your site to communicate with the service, and is needed in order to enjoy all these features:
16
+
17
+ Main features:
18
+
19
+ * Manage multiple WordPress sites securely and fast
20
+ * Manage WordPress themes, plugins, users, pages and posts for all your websites from one dashboard
21
+ * One click upgrades for WordPress, plugin and themes across all your sites
22
+ * Schedule automatic backups of your websites (Amazon S3, Google Drive, FTP/SFTP and Dropbox supported)
23
+ * Install WordPress, clone or migrate WordPress website to another domain
24
+ * One click to access WP admin of any site
25
+ * Bulk install themes and plugins to multiple sites at once
26
+ * Bulk publish posts and pages to multiple sites at once
27
+ * Add sub-users (writers, staff..) to your account
28
+ * SEO Statistics, track your keyword rankings
29
+ * Uptime monitoring - receive an SMS notification if your site goes down
30
+
31
+
32
+ Check out the [ManageWP Tour video](http://www.youtube.com/watch?v=Cg_W9MQBWt4).
33
+
34
+ http://www.youtube.com/watch?v=Cg_W9MQBWt4
35
+
36
+ ManageWP is also the creator of [ManageWP.org](https://managewp.org/ "WordPress news site"), community project capturing the pulse of the WordPress community.
37
+
38
+ == Changelog ==
39
+
40
+ = 3.9.30 =
41
+
42
+ - New: Fully compatible with WordPress 4.0
43
+ - New: Adding websites to your ManageWP Dashboard is now easier than ever
44
+ - Fix: Backup tool improvements (especially for websites located on Rackspace)
45
+ - Fix: Various Clone/Migration tool improvements and fixes
46
+ - Fix: SEO PDF report visual enhancement
47
+ - Fix: Various interface improvements and fixes
48
+
49
+ = 3.9.29 =
50
+
51
+ - New: Worker plugin is now 36% faster and uses 83% less memory
52
+ - New: Backup no longer relies on WordPress cron
53
+ - New: New Server-Client communication fixing some of the previous issues
54
+ - New: Notes and Recent backups widgets
55
+ - New: Refreshed app interface :)
56
+
57
+ = 3.9.28 =
58
+ - New: Control WordPress Automatic Background Updates for plugins and themes!
59
+ - Fix: Tweaks to SFTP support for backups and clone
60
+ - Fix: Enhancements to Backup and Branding features
61
+
62
+
63
+ = 3.9.27 =
64
+ - New: SFTP support for backups and clone!
65
+ - Fix: Database dump for backup tasks with defined socket path or port number in wp-config.php
66
+ - Fix: Optimize WordPress tables before backup
67
+ - Fix: Compatibility with Better WP Security
68
+ - Fix: Not adding jQuery on front page while using branding option
69
+
70
+ = 3.9.26 =
71
+ - New: Improved branding feature
72
+ - New: Disable Plugin and Theme changes for your clients
73
+ - New: Support Page for non-Admin Users
74
+ - New: Manage biographical info of user
75
+ - Fix: Restore backup action keeps all backup tasks and backups
76
+ - Fix: Add/delete post action uses WordPress hook
77
+ - Fix: Delete user action was not functioning properly
78
+
79
+ = 3.9.25 =
80
+ - New: Improved Worker branding feature
81
+ - Fix: Traffic alerts feature was not functioning properly
82
+ - Fix: Backup information was sometimes incorrectly displayed
83
+ - Fix: DB Table overhead was not shown on the dashboard
84
+
85
+ = 3.9.24 =
86
+ - New: Better support for large database dumps
87
+ - Fix: PHP notice for WordPress 3.5
88
+ - Fix: Support for automatic backup reports
89
+ - Fix: Incorrect backup result message for S3 large files
90
+
91
+ = 3.9.23 =
92
+ - New: SEO reports can be branded and viewed by sharing an URL
93
+ - New: Set custom database prefix for new clone destination
94
+ - New: Automatic change all URL paths for new clone destination
95
+ - New: Success and fail email notifications for scheduled backup tasks
96
+ - Fix: Improved scheduled backups for limited server resources
97
+ - Fix: Improved backup to Dropbox (now supporting larger backup files)
98
+ - Fix: Handling of external images with bulk posting
99
+ - Fix: Display plugin versions on manage plugins
100
+ - Fix: Deprecated get_themes function
101
+ - Fix: Special characters support for notes
102
+
103
+ = 3.9.22 =
104
+ - New: Backup support for Google Drive
105
+ - 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!)
106
+ - New: Support for Google Analytics API 3.0
107
+ - New: Website preview screenshot
108
+ - New: Ability to assign a newly added website to existing Backup tasks (under "advanced" in add website dialogue)
109
+ - Fix: Clone tool now supports special characters and localized WP installs
110
+ - Fix: Backup history preserved on website re-add
111
+
112
+ = 3.9.21 =
113
+ * New: Continuous updates! Read more at http://managewp.com/continuous-updates
114
+
115
+ = 3.9.20 =
116
+ * New: ManageWP iOS app compatibility
117
+ * New: Perform security and performance test as you add websites
118
+ * New: New comment handling screen
119
+
120
+ = 3.9.19 =
121
+ * New: Improved mechanism for refreshing website stats. You should have fresh information every 4 hours without refreshing now
122
+ * Fix: Categories now showing properly in Manage posts
123
+ * Fix: Website stats now ignore uptime monitoring pings
124
+
125
+ = 3.9.18 =
126
+ * New: Pagelines themes added to the list of partners
127
+ * New: Comprehensive website performance scan tool
128
+ * New: You can now bulk edit posts/pages (updating that contact info will become piece of cake)
129
+ * New: Upload and save your premium plugins/themes in your personal repository for quick installation
130
+ * New: Run code snippets now get a repository. Save your snippets and share them with other users
131
+ * New: SEO reports can now be sorted. Export as CSV and PDF reports.
132
+ * New: Manage Blogroll links
133
+ * New: Clean post revisions now has an option to save last x revisions when cleaning
134
+ * New: Bulk delete na posts/pages/links
135
+ * Fix: Amazon S3 backups failing
136
+
137
+ = 3.9.17 =
138
+ * New: Add your favorite sites to the Favorites bar (just drag&drop them to the small heart on the top)
139
+ * New: Entirely new website menu loaded with features and tools
140
+ * New: Manage Posts and Pages across all sites in a more efficient way
141
+ * New: Support for all WPMU.org premium plugin updates
142
+ * New: Complete Dropbox integration through Oauth which allows us to restore/delete Dropbox backups directly
143
+ * New: We have the user guide as PDF now. [Download] (http://managewp.com/files/ManageWP_User_Guide.zip)
144
+
145
+
146
+ = 3.9.16 =
147
+ * New: Option to "Run now" backup tasks
148
+ * New: Traffic alerts functionality
149
+ * New: Support for Genesis premium theme updates
150
+ * Fix: In some circutmsances .htaccess was not correctly zipped in the backup archive
151
+
152
+ = 3.9.15 =
153
+ * New: Full range of SEO Statistics now trackable for your websites (Google Page Rank and Page Speed, Backlinks and 20+ more)
154
+ * New: Google keyword rank tracking with history
155
+ * New: Uptime monitoring (5 min interval with email/SMS notification)
156
+ * New: Insights into server PHP error logs right in your dashboard
157
+ * New: Remote maintenance mode for your websites
158
+ * Fix: A bug when a completed backup was reported as failed
159
+
160
+ = 3.9.14 =
161
+ * Two factor authentication
162
+ * Run code tool
163
+ * Quick access to security check and broken link tools
164
+ * More accurate pageview statistics
165
+ * You can now opt to completely hide the Worker plugin from the list of plugins (part of Worker branding features)
166
+ * We improved the backups for folks running Windows servers
167
+ * Amazon S3 directory name now "ManageWP" by default
168
+ * Read more on ManageWP.com http://managewp.com/update-two-factor-authentication-run-code-tool-sucuri-security-check-more-accurate-pageview-statistics
169
+
170
+ = 3.9.13 =
171
+ * Added bucket location for Amazon S3 backups
172
+ * Better backup feature for larger sites
173
+ * Added Disable compression to further help with larger sites
174
+ * Backing up wp-admin, wp-includes and wp-content by default now, other folders can be included manually
175
+
176
+ = 3.9.12 =
177
+ * Minor bug fixes
178
+ * Backup, clone, favorites functionality improved
179
+
180
+ = 3.9.10 =
181
+ * Supporting updates for more premium plugins/themes
182
+ * Backup notifications (users can now get notices when the backup succeeds or fails)
183
+ * Support for WordPress 3.3
184
+ * Worker Branding (useful for web agencies, add your own Name/Description)
185
+ * Manage Groups screen
186
+ * Specify wp-admin path if your site uses a custom one
187
+ * Amazon S3 backups support for mixed case bucket names
188
+ * Bulk Add Links has additional options
189
+ * Better Multisite support
190
+ * Option to set the number of items for Google Analytics
191
+ * ManageWP backup folder changed to wp-content/managewp/backups
192
+
193
+ = 3.9.9 =
194
+ * New widget on the dashboard - Backup status
195
+ * New screen for managing plugins and themes (activate, deactivate, delete, add to favorites, install) across all sites
196
+ * New screen for managing users (change role or password, delete user) across all sites
197
+ * Option to overwrite old plugins and themes during bulk installation
198
+ * Your website admin now loads faster in ManageWP
199
+ * Added API for premium theme and plugin updates
200
+
201
+ = 3.9.8 =
202
+ * Conversion goals integration
203
+ * Update notifications
204
+ * Enhanced security for your account
205
+ * Better backups
206
+ * Better update interface
207
+ * [Full changelog](http://managewp.com/update-goals-and-adsense-analytics-integration-update-notifications-login-by-ip-better-backups "Full changelog")
208
+
209
+ = 3.9.7 =
210
+ * Fixed problem with cron schedules
211
+
212
+ = 3.9.6 =
213
+ * Improved dashboard performance
214
+ * Fixed bug with W3TC, we hope it is fully comptabile now
215
+ * Improved backup feature
216
+ * Various other fixes and improvements
217
+
218
+ = 3.9.5 =
219
+ * Now supporting scheduled backups to Amazon S3 and Dropbox
220
+ * Revamped cloning procedure
221
+ * You can now have sites in different colors
222
+ * W3 Total Cache comptability improved
223
+
224
+ = 3.9.3 =
225
+ * Included support for WordPress 3.2 partial updates
226
+
227
+ = 3.9.2 =
228
+ * Fixed problem with full backups
229
+ * Fixed problem with wordpress dev version upgrades
230
+
231
+ = 3.9.1 =
232
+ * Support for sub-users (limited access users)
233
+ * Bulk add user
234
+ * 'Select all' feature for bulk posting
235
+ * Featured image support for bulk posting
236
+ * Reload button on the dashboard (on the top of the Right now widget) will now refresh information about available updates
237
+ * Fixed a problem with the import tool
238
+ * Fixed a problem when remote dashboard would not work for some servers
239
+
240
+ = 3.9.0 =
241
+ * New feature: Up to 50% faster dashboard loading
242
+ * New feature: You can now ignore WordPress/plugin/theme updates
243
+ * New feature: Setting 'Show favicon' for websites in the dashboad
244
+ * New feature: Full backups now include WordPress and other folders in the root of the site
245
+ * Fixed: Bug with W3 TotalCache object cache causing weird behaviour in the dashboard
246
+ * Fixed: All groups now show when adding a site
247
+
248
+ = 3.8.8 =
249
+ * New feature: Bulk add links to blogroll
250
+ * New feature: Manual backups to email address
251
+ * New feature: Backup requirements check (under Manage Backups)
252
+ * New feature: Popup menu for groups allowing to show dashboard for that group only
253
+ * New feature: Favorite list for plugins and themes for later quick installation to multiple blogs
254
+ * New feature: Invite friends
255
+ * Fixed: problem with backups and write permissions when upload dir was wrongly set
256
+ * Fixed: problem adding sites where WordPress is installed in a folder
257
+ * Fixed: 408 error message problem when adding site
258
+ * Fixed: site time out problems when adding site
259
+ * Fixed: problems with some WP plugins (WP Sentinel)
260
+ * Fixed: problems with upgrade notifications
261
+
262
+ = 3.8.7 =
263
+ * Fixed 408 error when adding sites
264
+ * Added support for IDN domains
265
+ * Fixed bug with WordPress updates
266
+ * Added comment moderation to the dashboard
267
+ * Added quick links for sites (menu appears on hover)
268
+
269
+
270
+ = 3.8.6 =
271
+ * Added seach websites feature
272
+ * Enhanced dashboard actions (spam comments, post revisions, table overhead)
273
+ * Added developer [API] (http://managewp.com/api "ManageWP API")
274
+ * Improved Migrate/Clone site feature
275
+
276
+ = 3.8.4 =
277
+ * Fixed remote dashboard problems for sites with redirects
278
+ * Fixed IE7 issues in the dashboard
279
+
280
+ = 3.8.3 =
281
+ * Fixed problem with capabilities
282
+
283
+ = 3.8.2 =
284
+ * New interface
285
+ * SSL security protocol
286
+ * No passwords required
287
+ * Improved clone/backup
288
+
289
+ = 3.6.3 =
290
+ * Initial public release
291
+
292
+ == Installation ==
293
+
294
+ 1. Upload the plugin folder to your `/wp-content/plugins/` folder
295
+ 2. Go to the Plugins page in your website's WP-admin area and activate ManageWP Worker
296
+ 3. Visit [ManageWP.com](https://managewp.com/ "ManageWP")
297
+ 4. Sign up and add your website
298
+
299
+ Alternatively
300
+
301
+ 1. Visit [ManageWP.com](https://managewp.com/ "Manage Multiple WordPress Sites") and sign up
302
+ 2. ManageWP will notify you the Worker plugin is not installed and offer a link for quick installation
303
+
304
+ 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")
305
+
306
+ == Screenshots ==
307
+
308
+ 1. ManageWP dashboard with available upgrades, site statistics and management functions
309
+
310
+
311
+ == Upgrade Notice ==
312
+
313
+ = 3.9.30 =
314
+ 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
315
+
316
+
317
+ = 3.9.29 =
318
+ Worker plugin is 36% faster and uses 83% less memory. Backup tool no longer relies on WordPress cron
319
+
320
+
321
+ = 3.9.28 =
322
+ It is now possible to control WordPress automatic background updates for plugins and themes!
323
+
324
+
325
+ = 3.9.27 =
326
+ We have added compatibility with Better WP Security. Also, it is now possible to backup and clone to SFTP
327
+
328
+
329
+ == License ==
330
+
331
+ This file is part of ManageWP Worker.
332
+
333
+ ManageWP Worker is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
334
+
335
+ 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.
336
+
337
+ You should have received a copy of the GNU General Public License along with ManageWP Worker. If not, see <http://www.gnu.org/licenses/>.
338
+
339
+
340
+ == Frequently Asked Questions ==
341
+
342
+ = Is ManageWP secure? =
343
+
344
+ 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.
345
+
346
+ = Will ManageWP work with sites spread on different hosting accounts? =
347
+
348
+ Yes.
349
+
350
+ = Does ManageWP work with WordPress.com sites? =
351
+
352
+ No. ManageWP works only with self-hosted WordPress sites.
353
+
354
+ = Can I try all features for free? =
355
+
356
+ Absolutely. The first month is on us.
357
+
358
+ = I have problems adding my site =
359
+
360
+ 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").
361
+
362
+ = How does ManageWP compare to backup plugins like BackupBuddy, Backwpup, UpdraftPlus, WP-DB-Backup ? =
363
+
364
+ 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.
365
+
366
+ = How does ManageWP compare with clone plugins like Duplicator, WP Migrate DB, All-in-One WP Migration, XCloner ? =
367
+
368
+ 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.
369
+
370
+ = Does ManageWP work with caching plugins like W3 Total Cache or WP Super Cache =
371
+
372
+ Yes.
373
+
374
+ = 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? =
375
+
376
+ Yes. In most cases where there are conflicts we document them on our [known issues](https://managewp.com/user-guide/known-issues) page.
377
+
378
+ = How does ManageWP compare to services like InfiniteWP, MainWP, CMS Commander, IControlWP ? =
379
+
380
+ 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)
screenshot-1.png DELETED
Binary file
src/Dropbox/AppInfo.php CHANGED
@@ -1,237 +1,262 @@
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
- function getKey() { return $this->key; }
15
-
16
- /** @var string */
17
- private $key;
18
-
19
- /**
20
- * Your Dropbox <em>app secret</em> (OAuth calls this the <em>consumer secret</em>). You can
21
- * create an app key and secret on the <a href="http://dropbox.com/developers/apps">Dropbox developer website</a>.
22
- *
23
- * Make sure that this is kept a secret. Someone with your app secret can impesonate your
24
- * application. People sometimes ask for help on the Dropbox API forums and
25
- * copy/paste code that includes their app secret. Do not do that.
26
- *
27
- * @return string
28
- */
29
- function getSecret() { return $this->secret; }
30
-
31
- /** @var string */
32
- private $secret;
33
-
34
- /**
35
- * The set of servers your app will use. This defaults to the standard Dropbox servers
36
- * {@link Host::getDefault}.
37
- *
38
- * @return Dropbox_Host
39
- *
40
- * @internal
41
- */
42
- function getHost() { return $this->host; }
43
-
44
- /** @var Dropbox_Host */
45
- private $host;
46
-
47
- /**
48
- * Constructor.
49
- *
50
- * @param string $key
51
- * See {@link getKey()}
52
- * @param string $secret
53
- * See {@link getSecret()}
54
- */
55
- function __construct($key, $secret)
56
- {
57
- self::checkKeyArg($key);
58
- self::checkSecretArg($secret);
59
-
60
- $this->key = $key;
61
- $this->secret = $secret;
62
-
63
- // The $host parameter is sort of internal. We don't include it in the param list because
64
- // we don't want it to be included in the documentation. Use PHP arg list hacks to get at
65
- // it.
66
- $host = null;
67
- if (func_num_args() == 3) {
68
- $host = func_get_arg(2);
69
- Dropbox_Host::checkArgOrNull("host", $host);
70
- }
71
- if ($host === null) {
72
- $host = Dropbox_Host::getDefault();
73
- }
74
- $this->host = $host;
75
- }
76
-
77
- /**
78
- * Loads a JSON file containing information about your app. At a minimum, the file must include
79
- * the "key" and "secret" fields. Run 'php authorize.php' in the examples directory
80
- * for details about what this file should look like.
81
- *
82
- * @param string $path
83
- * Path to a JSON file
84
- *
85
- * @return Dropbox_AppInfo
86
- *
87
- * @throws Dropbox_AppInfoLoadException
88
- */
89
- static function loadFromJsonFile($path)
90
- {
91
- list($rawJson, $appInfo) = self::loadFromJsonFileWithRaw($path);
92
- return $appInfo;
93
- }
94
-
95
- /**
96
- * Loads a JSON file containing information about your app. At a minimum, the file must include
97
- * the "key" and "secret" fields. Run 'php authorize.php' in the examples directory
98
- * for details about what this file should look like.
99
- *
100
- * @param string $path
101
- * Path to a JSON file
102
- *
103
- * @return array
104
- * A list of two items. The first is a PHP array representation of the raw JSON, the second
105
- * is an AppInfo object that is the parsed version of the JSON.
106
- *
107
- * @throws Dropbox_AppInfoLoadException
108
- *
109
- * @internal
110
- */
111
- static function loadFromJsonFileWithRaw($path)
112
- {
113
- if (!file_exists($path)) {
114
- throw new Dropbox_AppInfoLoadException("File doesn't exist: \"$path\"");
115
- }
116
-
117
- $str = file_get_contents($path);
118
- $jsonArr = json_decode($str, TRUE);
119
-
120
- if (is_null($jsonArr)) {
121
- throw new Dropbox_AppInfoLoadException("JSON parse error: \"$path\"");
122
- }
123
-
124
- $appInfo = self::loadFromJson($jsonArr);
125
-
126
- return array($jsonArr, $appInfo);
127
- }
128
-
129
- /**
130
- * Parses a JSON object to build an AppInfo object. If you would like to load this from a file,
131
- * use the loadFromJsonFile() method.
132
- *
133
- * @param array $jsonArr Output from json_decode($str, TRUE)
134
- *
135
- * @return Dropbox_AppInfo
136
- *
137
- * @throws Dropbox_AppInfoLoadException
138
- */
139
- static function loadFromJson($jsonArr)
140
- {
141
- if (!is_array($jsonArr)) {
142
- throw new Dropbox_AppInfoLoadException("Expecting JSON object, got something else");
143
- }
144
-
145
- $requiredKeys = array("key", "secret");
146
- foreach ($requiredKeys as $key) {
147
- if (!array_key_exists($key, $jsonArr)) {
148
- throw new Dropbox_AppInfoLoadException("Missing field \"$key\"");
149
- }
150
-
151
- if (!is_string($jsonArr[$key])) {
152
- throw new Dropbox_AppInfoLoadException("Expecting field \"$key\" to be a string");
153
- }
154
- }
155
-
156
- // Check app_key and app_secret
157
- $appKey = $jsonArr["key"];
158
- $appSecret = $jsonArr["secret"];
159
-
160
- $tokenErr = self::getTokenPartError($appKey);
161
- if (!is_null($tokenErr)) {
162
- throw new Dropbox_AppInfoLoadException("Field \"key\" doesn't look like a valid app key: $tokenErr");
163
- }
164
-
165
- $tokenErr = self::getTokenPartError($appSecret);
166
- if (!is_null($tokenErr)) {
167
- throw new Dropbox_AppInfoLoadException("Field \"secret\" doesn't look like a valid app secret: $tokenErr");
168
- }
169
-
170
- // Check for the optional 'host' field
171
- if (!array_key_exists('host', $jsonArr)) {
172
- $host = null;
173
- }
174
- else {
175
- $baseHost = $jsonArr["host"];
176
- if (!is_string($baseHost)) {
177
- throw new Dropbox_AppInfoLoadException("Optional field \"host\" must be a string");
178
- }
179
-
180
- $api = "api-$baseHost";
181
- $content = "api-content-$baseHost";
182
- $web = "meta-$baseHost";
183
-
184
- $host = new Dropbox_Host($api, $content, $web);
185
- }
186
-
187
- return new Dropbox_AppInfo($appKey, $appSecret, $host);
188
- }
189
-
190
- /**
191
- * Use this to check that a function argument is of type <code>AppInfo</code>
192
- *
193
- * @internal
194
- */
195
- static function checkArg($argName, $argValue)
196
- {
197
- if (!($argValue instanceof self)) Dropbox_Checker::throwError($argName, $argValue, __CLASS__);
198
- }
199
-
200
- /**
201
- * Use this to check that a function argument is either <code>null</code> or of type
202
- * <code>AppInfo</code>.
203
- *
204
- * @internal
205
- */
206
- static function checkArgOrNull($argName, $argValue)
207
- {
208
- if ($argValue === null) return;
209
- if (!($argValue instanceof self)) Dropbox_Checker::throwError($argName, $argValue, __CLASS__);
210
- }
211
-
212
- /** @internal */
213
- static function getTokenPartError($s)
214
- {
215
- if ($s === null) return "can't be null";
216
- if (strlen($s) === 0) return "can't be empty";
217
- if (strstr($s, ' ')) return "can't contain a space";
218
- return null; // 'null' means "no error"
219
- }
220
-
221
- /** @internal */
222
- static function checkKeyArg($key)
223
- {
224
- $error = self::getTokenPartError($key);
225
- if ($error === null) return;
226
- throw new InvalidArgumentException("Bad 'key': \"$key\": $error.");
227
- }
228
-
229
- /** @internal */
230
- static function checkSecretArg($secret)
231
- {
232
- $error = self::getTokenPartError($secret);
233
- if ($error === null) return;
234
- throw new InvalidArgumentException("Bad 'secret': \"$secret\": $error.");
235
- }
236
-
237
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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 CHANGED
@@ -1,17 +1,17 @@
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
- function __construct($message)
14
- {
15
- parent::__construct($message);
16
- }
17
- }
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 CHANGED
@@ -1,60 +1,60 @@
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
- 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
- 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
- function set($value)
49
- {
50
- $this->array[$this->key] = $value;
51
- }
52
-
53
- /**
54
- * Clear the entry.
55
- */
56
- function clear()
57
- {
58
- unset($this->array[$this->key]);
59
- }
60
- }
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 CHANGED
@@ -1,74 +1,83 @@
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
- function getAppInfo() { return $this->appInfo; }
14
-
15
- /** @var Dropbox_AppInfo */
16
- protected $appInfo;
17
-
18
- /**
19
- * An identifier for the API client, typically of the form "Name/Version".
20
- * This is used to set the HTTP <code>User-Agent</code> header when making API requests.
21
- * Example: <code>"PhotoEditServer/1.3"</code>
22
- *
23
- * If you're the author a higher-level library on top of the basic SDK, and the
24
- * "Photo Edit" app's server code is using your library to access Dropbox, you should append
25
- * your library's name and version to form the full identifier. For example,
26
- * if your library is called "File Picker", you might set this field to:
27
- * <code>"PhotoEditServer/1.3 FilePicker/0.1-beta"</code>
28
- *
29
- * The exact format of the <code>User-Agent</code> header is described in
30
- * <a href="http://tools.ietf.org/html/rfc2616#section-3.8">section 3.8 of the HTTP specification</a>.
31
- *
32
- * Note that underlying HTTP client may append other things to the <code>User-Agent</code>, such as
33
- * the name of the library being used to actually make the HTTP request (such as cURL).
34
- *
35
- * @return string
36
- */
37
- function getClientIdentifier() { return $this->clientIdentifier; }
38
-
39
- /** @var string */
40
- protected $clientIdentifier;
41
-
42
- /**
43
- * The locale of the user of your application. Some API calls return localized
44
- * data and error messages; this "user locale" setting determines which locale
45
- * the server should use to localize those strings.
46
- *
47
- * @return null|string
48
- */
49
- function getUserLocale() { return $this->userLocale; }
50
-
51
- /** @var string */
52
- protected $userLocale;
53
-
54
- /**
55
- * Constructor.
56
- *
57
- * @param Dropbox_AppInfo $appInfo
58
- * See {@link getAppInfo()}
59
- * @param string $clientIdentifier
60
- * See {@link getClientIdentifier()}
61
- * @param null|string $userLocale
62
- * See {@link getUserLocale()}
63
- */
64
- function __construct($appInfo, $clientIdentifier, $userLocale = null)
65
- {
66
- Dropbox_AppInfo::checkArg("appInfo", $appInfo);
67
- Dropbox_Client::checkClientIdentifierArg("clientIdentifier", $clientIdentifier);
68
- Dropbox_Checker::argStringNonEmptyOrNull("userLocale", $userLocale);
69
-
70
- $this->appInfo = $appInfo;
71
- $this->clientIdentifier = $clientIdentifier;
72
- $this->userLocale = $userLocale;
73
- }
74
- }
 
 
 
 
 
 
 
 
 
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 CHANGED
@@ -1,84 +1,85 @@
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
- * @return array
18
- * A <code>list(string $accessToken, Host $host)</code>.
19
- *
20
- * @throws Dropbox_AuthInfoLoadException
21
- */
22
- static function loadFromJsonFile($path)
23
- {
24
- if (!file_exists($path)) {
25
- throw new Dropbox_AuthInfoLoadException("File doesn't exist: \"$path\"");
26
- }
27
-
28
- $str = file_get_contents($path);
29
- $jsonArr = json_decode($str, TRUE);
30
-
31
- if (is_null($jsonArr)) {
32
- throw new Dropbox_AuthInfoLoadException("JSON parse error: \"$path\"");
33
- }
34
-
35
- return self::loadFromJson($jsonArr);
36
- }
37
-
38
- /**
39
- * Parses a JSON object to build an AuthInfo object. If you would like to load this from a file,
40
- * please use the @see loadFromJsonFile method.
41
- *
42
- * @param array $jsonArr
43
- * A parsed JSON object, typcally the result of json_decode(..., TRUE).
44
- * @return array
45
- * A <code>list(string $accessToken, Host $host)</code>.
46
- *
47
- * @throws Dropbox_AuthInfoLoadException
48
- */
49
- private static function loadFromJson($jsonArr)
50
- {
51
- if (!is_array($jsonArr)) {
52
- throw new Dropbox_AuthInfoLoadException("Expecting JSON object, found something else");
53
- }
54
-
55
- // Check access_token
56
- if (!array_key_exists('access_token', $jsonArr)) {
57
- throw new Dropbox_AuthInfoLoadException("Missing field \"access_token\"");
58
- }
59
-
60
- $accessToken = $jsonArr['access_token'];
61
- if (!is_string($accessToken)) {
62
- throw new Dropbox_AuthInfoLoadException("Expecting field \"access_token\" to be a string");
63
- }
64
-
65
- // Check for the optional 'host' field
66
- if (!array_key_exists('host', $jsonArr)) {
67
- $host = null;
68
- }
69
- else {
70
- $baseHost = $jsonArr["host"];
71
- if (!is_string($baseHost)) {
72
- throw new Dropbox_AuthInfoLoadException("Optional field \"host\" must be a string");
73
- }
74
-
75
- $api = "api-$baseHost";
76
- $content = "api-content-$baseHost";
77
- $web = "meta-$baseHost";
78
-
79
- $host = new Dropbox_Host($api, $content, $web);
80
- }
81
-
82
- return array($accessToken, $host);
83
- }
84
- }
 
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 CHANGED
@@ -1,17 +1,17 @@
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
- function __construct($message)
14
- {
15
- parent::__construct($message);
16
- }
17
- }
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 CHANGED
@@ -1,93 +1,139 @@
1
- <?php
2
-
3
- /**
4
- * Helper functions to validate arguments.
5
- *
6
- * @internal
7
- */
8
- class Dropbox_Checker
9
- {
10
- static function throwError($argName, $argValue, $expectedTypeName)
11
- {
12
- if ($argValue === null) throw new InvalidArgumentException("'$argName' must not be null");
13
-
14
- if (is_object($argValue)) {
15
- // Class type.
16
- $argTypeName = get_class($argValue);
17
- } else {
18
- // Built-in type.
19
- $argTypeName = gettype($argValue);
20
- }
21
- throw new InvalidArgumentException("'$argName' has bad type; expecting $expectedTypeName, got $argTypeName");
22
- }
23
-
24
- static function argResource($argName, $argValue)
25
- {
26
- if (!is_resource($argValue)) self::throwError($argName, $argValue, "resource");
27
- }
28
-
29
- static function argCallable($argName, $argValue)
30
- {
31
- if (!is_callable($argValue)) self::throwError($argName, $argValue, "callable");
32
- }
33
-
34
- static function argBool($argName, $argValue)
35
- {
36
- if (!is_bool($argValue)) self::throwError($argName, $argValue, "boolean");
37
- }
38
-
39
- static function argArray($argName, $argValue)
40
- {
41
- if (!is_array($argValue)) self::throwError($argName, $argValue, "array");
42
- }
43
-
44
- static function argString($argName, $argValue)
45
- {
46
- if (!is_string($argValue)) self::throwError($argName, $argValue, "string");
47
- }
48
-
49
- static function argStringOrNull($argName, $argValue)
50
- {
51
- if ($argValue === null) return;
52
- if (!is_string($argValue)) self::throwError($argName, $argValue, "string");
53
- }
54
-
55
- static function argStringNonEmpty($argName, $argValue)
56
- {
57
- if (!is_string($argValue)) self::throwError($argName, $argValue, "string");
58
- if (strlen($argValue) === 0) throw new InvalidArgumentException("'$argName' must be non-empty");
59
- }
60
-
61
- static function argStringNonEmptyOrNull($argName, $argValue)
62
- {
63
- if ($argValue === null) return;
64
- if (!is_string($argValue)) self::throwError($argName, $argValue, "string");
65
- if (strlen($argValue) === 0) throw new InvalidArgumentException("'$argName' must be non-empty");
66
- }
67
-
68
- static function argNat($argName, $argValue)
69
- {
70
- if (!is_int($argValue)) self::throwError($argName, $argValue, "int");
71
- if ($argValue < 0) throw new InvalidArgumentException("'$argName' must be non-negative (you passed in $argValue)");
72
- }
73
-
74
- static function argNatOrNull($argName, $argValue)
75
- {
76
- if ($argValue === null) return;
77
- if (!is_int($argValue)) self::throwError($argName, $argValue, "int");
78
- if ($argValue < 0) throw new InvalidArgumentException("'$argName' must be non-negative (you passed in $argValue)");
79
- }
80
-
81
- static function argIntPositive($argName, $argValue)
82
- {
83
- if (!is_int($argValue)) self::throwError($argName, $argValue, "int");
84
- if ($argValue < 1) throw new InvalidArgumentException("'$argName' must be positive (you passed in $argValue)");
85
- }
86
-
87
- static function argIntPositiveOrNull($argName, $argValue)
88
- {
89
- if ($argValue === null) return;
90
- if (!is_int($argValue)) self::throwError($argName, $argValue, "int");
91
- if ($argValue < 1) throw new InvalidArgumentException("'$argName' must be positive (you passed in $argValue)");
92
- }
93
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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 CHANGED
@@ -1,1525 +1,1681 @@
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
- function getAccessToken() { return $this->accessToken; }
18
-
19
- /** @var string AccessToken */
20
- private $accessToken;
21
-
22
- /**
23
- * An identifier for the API client, typically of the form "Name/Version".
24
- * This is used to set the HTTP <code>User-Agent</code> header when making API requests.
25
- * Example: <code>"PhotoEditServer/1.3"</code>
26
- *
27
- * If you're the author a higher-level library on top of the basic SDK, and the
28
- * "Photo Edit" app's server code is using your library to access Dropbox, you should append
29
- * your library's name and version to form the full identifier. For example,
30
- * if your library is called "File Picker", you might set this field to:
31
- * <code>"PhotoEditServer/1.3 FilePicker/0.1-beta"</code>
32
- *
33
- * The exact format of the <code>User-Agent</code> header is described in
34
- * <a href="http://tools.ietf.org/html/rfc2616#section-3.8">section 3.8 of the HTTP specification</a>.
35
- *
36
- * Note that underlying HTTP client may append other things to the <code>User-Agent</code>, such as
37
- * the name of the library being used to actually make the HTTP request (such as cURL).
38
- *
39
- * @return string
40
- */
41
- function getClientIdentifier() { return $this->clientIdentifier; }
42
-
43
- /** @var string */
44
- private $clientIdentifier;
45
-
46
- /**
47
- * The locale of the user of your application. Some API calls return localized
48
- * data and error messages; this "user locale" setting determines which locale
49
- * the server should use to localize those strings.
50
- *
51
- * @return null|string
52
- */
53
- function getUserLocale() { return $this->userLocale; }
54
-
55
- /** @var null|string */
56
- private $userLocale;
57
-
58
- /**
59
- * The {@link Host} object that determines the hostnames we make requests to.
60
- *
61
- * @return Dropbox_Host
62
- */
63
- function getHost() { return $this->host; }
64
-
65
- /**
66
- * Constructor.
67
- *
68
- * @param string $accessToken
69
- * See {@link getAccessToken()}
70
- * @param string $clientIdentifier
71
- * See {@link getClientIdentifier()}
72
- * @param null|string $userLocale
73
- * See {@link getUserLocale()}
74
- */
75
- function __construct($accessToken, $clientIdentifier, $userLocale = null)
76
- {
77
- self::checkAccessTokenArg("accessToken", $accessToken);
78
- self::checkClientIdentifierArg("clientIdentifier", $clientIdentifier);
79
- Dropbox_Checker::argStringNonEmptyOrNull("userLocale", $userLocale);
80
-
81
- $this->accessToken = $accessToken;
82
- $this->clientIdentifier = $clientIdentifier;
83
- $this->userLocale = $userLocale;
84
-
85
- // The $host parameter is sort of internal. We don't include it in the param list because
86
- // we don't want it to be included in the documentation. Use PHP arg list hacks to get at
87
- // it.
88
- $host = null;
89
- if (func_num_args() == 4) {
90
- $host = func_get_arg(3);
91
- Dropbox_Host::checkArgOrNull("host", $host);
92
- }
93
- if ($host === null) {
94
- $host = Dropbox_Host::getDefault();
95
- }
96
- $this->host = $host;
97
-
98
- // These fields are redundant, but it makes these values a little more convenient
99
- // to access.
100
- $this->apiHost = $host->getApi();
101
- $this->contentHost = $host->getContent();
102
- }
103
-
104
- /** @var string */
105
- private $apiHost;
106
- /** @var string */
107
- private $contentHost;
108
-
109
- /**
110
- * Given a <code>$base</code> path for an API endpoint (for example, "/files"), append
111
- * a Dropbox API file path to the end of that URL. Special characters in the file will
112
- * be encoded properly.
113
- *
114
- * This is for endpoints like "/files" takes the path on the URL and not as a separate
115
- * query or POST parameter.
116
- *
117
- * @param string $base
118
- * @param string $path
119
- * @return string
120
- */
121
- function appendFilePath($base, $path)
122
- {
123
- return $base . "/auto/" . rawurlencode(substr($path, 1));
124
- }
125
-
126
- /**
127
- * Make an API call to disable the access token that you constructed this <code>Client</code>
128
- * with. After calling this, API calls made with this <code>Client</code> will fail.
129
- *
130
- * See <a href="https://www.dropbox.com/developers/core/docs#disable-token">/disable_access_token</a>.
131
- *
132
- * @throws Dropbox_Exception
133
- */
134
- function disableAccessToken()
135
- {
136
- $response = $this->doPost($this->apiHost, "1/disable_access_token");
137
- if ($response->statusCode !== 200) throw Dropbox_RequestUtil::unexpectedStatus($response);
138
- }
139
-
140
- /**
141
- * Make an API call to get basic account and quota information.
142
- *
143
- * <code>
144
- * $client = ...
145
- * $accountInfo = $client->getAccountInfo();
146
- * print_r($accountInfo);
147
- * </code>
148
- *
149
- * @return array
150
- * See <a href="https://www.dropbox.com/developers/core/docs#account-info">/account/info</a>.
151
- *
152
- * @throws Dropbox_Exception
153
- */
154
- function getAccountInfo()
155
- {
156
- $response = $this->doGet($this->apiHost, "1/account/info");
157
- if ($response->statusCode !== 200) throw Dropbox_RequestUtil::unexpectedStatus($response);
158
- return Dropbox_RequestUtil::parseResponseJson($response->body);
159
- }
160
-
161
- /**
162
- * Downloads a file from Dropbox. The file's contents are written to the
163
- * given <code>$outStream</code> and the file's metadata is returned.
164
- *
165
- * <code>
166
- * $client = ...;
167
- * $fd = fopen("./Frog.jpeg", "wb");
168
- * $metadata = $client->getFile("/Photos/Frog.jpeg", $fd);
169
- * fclose($fd);
170
- * print_r($metadata);
171
- * </code>
172
- *
173
- * @param string $path
174
- * The path to the file on Dropbox (UTF-8).
175
- *
176
- * @param resource $outStream
177
- * If the file exists, the file contents will be written to this stream.
178
- *
179
- * @param string|null $rev
180
- * If you want the latest revision of the file at the given path, pass in <code>null</code>.
181
- * If you want a specific version of a file, pass in value of the file metadata's "rev" field.
182
- *
183
- * @return null|array
184
- * The <a href="https://www.dropbox.com/developers/core/docs#metadata-details">metadata
185
- * object</a> for the file at the given $path and $rev, or <code>null</code> if the file
186
- * doesn't exist,
187
- *
188
- * @throws Dropbox_Exception
189
- */
190
- function getFile($path, $outStream, $rev = null)
191
- {
192
- Dropbox_Path::checkArgNonRoot("path", $path);
193
- Dropbox_Checker::argResource("outStream", $outStream);
194
- Dropbox_Checker::argStringNonEmptyOrNull("rev", $rev);
195
-
196
- $url = $this->buildUrlForGetOrPut(
197
- $this->contentHost,
198
- $this->appendFilePath("1/files", $path),
199
- array("rev" => $rev));
200
-
201
- $curl = $this->mkCurl($url);
202
- $metadataCatcher = new Dropbox_DropboxMetadataHeaderCatcher($curl->handle);
203
- $streamRelay = new Dropbox_CurlStreamRelay($curl->handle, $outStream);
204
-
205
- $response = $curl->exec();
206
-
207
- if ($response->statusCode === 404) return null;
208
-
209
- if ($response->statusCode !== 200) {
210
- $response->body = $streamRelay->getErrorBody();
211
- throw Dropbox_RequestUtil::unexpectedStatus($response);
212
- }
213
-
214
- return $metadataCatcher->getMetadata();
215
- }
216
-
217
- /**
218
- * Calling 'uploadFile' with <code>$numBytes</code> less than this value, will cause this SDK
219
- * to use the standard /files_put endpoint. When <code>$numBytes</code> is greater than this
220
- * value, we'll use the /chunked_upload endpoint.
221
- *
222
- * @var int
223
- */
224
- public static $AUTO_CHUNKED_UPLOAD_THRESHOLD = 9863168; // 8 MB
225
-
226
- /**
227
- * @var int
228
- */
229
- public static $DEFAULT_CHUNK_SIZE = 4194304; // 4 MB
230
-
231
- /**
232
- * Creates a file on Dropbox, using the data from <code>$inStream</code> for the file contents.
233
- *
234
- * <code>
235
- * use \Dropbox as dbx;
236
- * $client = ...;
237
- * $fd = fopen("./frog.jpeg", "rb");
238
- * $md1 = $client->uploadFile("/Photos/Frog.jpeg",
239
- * dbx\WriteMode::add(), $fd);
240
- * fclose($fd);
241
- * print_r($md1);
242
- * $rev = $md1["rev"];
243
- *
244
- * // Re-upload with WriteMode::update(...), which will overwrite the
245
- * // file if it hasn't been modified from our original upload.
246
- * $fd = fopen("./frog-new.jpeg", "rb");
247
- * $md2 = $client->uploadFile("/Photos/Frog.jpeg",
248
- * dbx\WriteMode::update($rev), $fd);
249
- * fclose($fd);
250
- * print_r($md2);
251
- * </code>
252
- *
253
- * @param string $path
254
- * The Dropbox path to save the file to (UTF-8).
255
- *
256
- * @param Dropbox_WriteMode $writeMode
257
- * What to do if there's already a file at the given path.
258
- *
259
- * @param resource $inStream
260
- * The data to use for the file contents.
261
- *
262
- * @param int|null $numBytes
263
- * You can pass in <code>null</code> if you don't know. If you do provide the size, we can
264
- * perform a slightly more efficient upload (fewer network round-trips) for files smaller
265
- * than 8 MB.
266
- *
267
- * @param Callable|null $callback
268
- * Curl progress callback.
269
- *
270
- * @return mixed
271
- * The <a href="https://www.dropbox.com/developers/core/docs#metadata-details>metadata
272
- * object</a> for the newly-added file.
273
- *
274
- * @throws Dropbox_Exception
275
- */
276
- function uploadFile($path, $writeMode, $inStream, $numBytes = null, $callback = null)
277
- {
278
- Dropbox_Path::checkArgNonRoot("path", $path);
279
- Dropbox_WriteMode::checkArg("writeMode", $writeMode);
280
- Dropbox_Checker::argResource("inStream", $inStream);
281
- Dropbox_Checker::argNatOrNull("numBytes", $numBytes);
282
-
283
- if ($callback !== null) {
284
- Dropbox_Checker::argCallable("callback", $callback);
285
- }
286
-
287
- // If we don't know how many bytes are coming, we have to use chunked upload.
288
- // If $numBytes is large, we elect to use chunked upload.
289
- // In all other cases, use regular upload.
290
- if ($numBytes === null || $numBytes > self::$AUTO_CHUNKED_UPLOAD_THRESHOLD) {
291
- $metadata = $this->_uploadFileChunked($path, $writeMode, $inStream, $numBytes,
292
- self::$DEFAULT_CHUNK_SIZE, $callback);
293
- } else {
294
- $config = new Dropbox_Closure_CurlConfigInStream($inStream, $numBytes);
295
- $metadata = $this->_uploadFile($path, $writeMode, $config, $callback);
296
- }
297
-
298
- return $metadata;
299
- }
300
-
301
- /**
302
- * Creates a file on Dropbox, using the given $data string as the file contents.
303
- *
304
- * <code>
305
- * use \Dropbox as dbx;
306
- * $client = ...;
307
- * $md = $client->uploadFileFromString("/Grocery List.txt",
308
- * dbx\WriteMode::add(),
309
- * "1. Coke\n2. Popcorn\n3. Toothpaste\n");
310
- * print_r($md);
311
- * </code>
312
- *
313
- * @param string $path
314
- * The Dropbox path to save the file to (UTF-8).
315
- *
316
- * @param Dropbox_WriteMode $writeMode
317
- * What to do if there's already a file at the given path.
318
- *
319
- * @param string $data
320
- * The data to use for the contents of the file.
321
- *
322
- * @return mixed
323
- * The <a href="https://www.dropbox.com/developers/core/docs#metadata-details>metadata
324
- * object</a> for the newly-added file.
325
- *
326
- * @throws Dropbox_Exception
327
- */
328
- function uploadFileFromString($path, $writeMode, $data)
329
- {
330
- Dropbox_Path::checkArgNonRoot("path", $path);
331
- Dropbox_WriteMode::checkArg("writeMode", $writeMode);
332
- Dropbox_Checker::argString("data", $data);
333
-
334
- $config = new Dropbox_Closure_CurlConfigOctetStream($data);
335
- return $this->_uploadFile($path, $writeMode, $config);
336
- }
337
-
338
- /**
339
- * Creates a file on Dropbox, using the data from $inStream as the file contents.
340
- *
341
- * This version of <code>uploadFile</code> splits uploads the file ~4MB chunks at a time and
342
- * will retry a few times if one chunk fails to upload. Uses {@link chunkedUploadStart()},
343
- * {@link chunkedUploadContinue()}, and {@link chunkedUploadFinish()}.
344
- *
345
- * @param string $path
346
- * The Dropbox path to save the file to (UTF-8).
347
- *
348
- * @param Dropbox_WriteMode $writeMode
349
- * What to do if there's already a file at the given path.
350
- *
351
- * @param resource $inStream
352
- * The data to use for the file contents.
353
- *
354
- * @param int|null $numBytes
355
- * The number of bytes available from $inStream.
356
- * You can pass in <code>null</code> if you don't know.
357
- *
358
- * @param int|null $chunkSize
359
- * The number of bytes to upload in each chunk. You can omit this (or pass in
360
- * <code>null</code> and the library will use a reasonable default.
361
- *
362
- * @return mixed
363
- * The <a href="https://www.dropbox.com/developers/core/docs#metadata-details>metadata
364
- * object</a> for the newly-added file.
365
- *
366
- * @throws Dropbox_Exception
367
- */
368
- function uploadFileChunked($path, $writeMode, $inStream, $numBytes = null, $chunkSize = null)
369
- {
370
- if ($chunkSize === null) {
371
- $chunkSize = self::$DEFAULT_CHUNK_SIZE;
372
- }
373
-
374
- Dropbox_Path::checkArgNonRoot("path", $path);
375
- Dropbox_WriteMode::checkArg("writeMode", $writeMode);
376
- Dropbox_Checker::argResource("inStream", $inStream);
377
- Dropbox_Checker::argNatOrNull("numBytes", $numBytes);
378
- Dropbox_Checker::argIntPositive("chunkSize", $chunkSize);
379
-
380
- return $this->_uploadFileChunked($path, $writeMode, $inStream, $numBytes, $chunkSize);
381
- }
382
-
383
- /**
384
- * @param string $path
385
- *
386
- * @param Dropbox_WriteMode $writeMode
387
- * What to do if there's already a file at the given path (UTF-8).
388
- *
389
- * @param resource $inStream
390
- * The source of data to upload.
391
- *
392
- * @param int|null $numBytes
393
- * You can pass in <code>null</code>. But if you know how many bytes you expect, pass in
394
- * that value and this function will do a sanity check at the end to make sure the number of
395
- * bytes read from $inStream matches up.
396
- *
397
- * @param int $chunkSize
398
- *
399
- * @return array
400
- * The <a href="https://www.dropbox.com/developers/core/docs#metadata-details>metadata
401
- * object</a> for the newly-added file.
402
- *
403
- * @throws InvalidArgumentException
404
- * @throws Dropbox_Exception_BadResponse
405
- */
406
- private function _uploadFileChunked($path, $writeMode, $inStream, $numBytes, $chunkSize, $callback = null)
407
- {
408
- Dropbox_Path::checkArg("path", $path);
409
- Dropbox_WriteMode::checkArg("writeMode", $writeMode);
410
- Dropbox_Checker::argResource("inStream", $inStream);
411
- Dropbox_Checker::argNatOrNull("numBytes", $numBytes);
412
- Dropbox_Checker::argNat("chunkSize", $chunkSize);
413
-
414
- if ($callback !== null) {
415
- Dropbox_Checker::argCallable("callback", $callback);
416
- }
417
-
418
- // NOTE: This function performs 3 retries on every call. This is maybe not the right
419
- // layer to make retry decisions. It's also awkward because none of the other calls
420
- // perform retries.
421
-
422
- assert($chunkSize > 0);
423
-
424
- $data = self::readFully($inStream, $chunkSize);
425
- $len = strlen($data);
426
-
427
- $client = $this;
428
- $uploadStart = new Dropbox_Closure_ChunkedUploadStartAction($client, $data, $callback);
429
- $uploadId = Dropbox_RequestUtil::runWithRetry(3, $uploadStart);
430
- unset($uploadStart);
431
-
432
- $byteOffset = $len;
433
-
434
- while (!feof($inStream)) {
435
- unset($data);
436
- $data = self::readFully($inStream, $chunkSize);
437
- $len = strlen($data);
438
-
439
- while (true) {
440
- $uploadContinue = new Dropbox_Closure_ChunkedUploadContinueAction($client, $uploadId, $byteOffset, $data, $callback);
441
- $r = Dropbox_RequestUtil::runWithRetry(3, $uploadContinue);
442
- unset($uploadContinue);
443
-
444
- if ($r === true) { // Chunk got uploaded!
445
- $byteOffset += $len;
446
- break;
447
- }
448
- if ($r === false) { // Server didn't recognize our upload ID
449
- // This is very unlikely since we're uploading all the chunks in sequence.
450
- throw new Dropbox_Exception_BadResponse("Server forgot our uploadId");
451
- }
452
-
453
- // Otherwise, the server is at a different byte offset from us.
454
- $serverByteOffset = $r;
455
- assert($serverByteOffset !== $byteOffset); // chunkedUploadContinue ensures this.
456
- // An earlier byte offset means the server has lost data we sent earlier.
457
- if ($serverByteOffset < $byteOffset) throw new Dropbox_Exception_BadResponse(
458
- "Server is at an ealier byte offset: us=$byteOffset, server=$serverByteOffset");
459
- $diff = $serverByteOffset - $byteOffset;
460
- // If the server is past where we think it could possibly be, something went wrong.
461
- if ($diff > $len) throw new Dropbox_Exception_BadResponse(
462
- "Server is more than a chunk ahead: us=$byteOffset, server=$serverByteOffset");
463
- // The normal case is that the server is a bit further along than us because of a
464
- // partially-uploaded chunk. Finish it off.
465
- $byteOffset += $diff;
466
- if ($diff === $len) break; // If the server is at the end, we're done.
467
- $data = substr($data, $diff);
468
- }
469
- }
470
-
471
- if ($numBytes !== null && $byteOffset !== $numBytes) throw new InvalidArgumentException(
472
- "You passed numBytes=$numBytes but the stream had $byteOffset bytes.");
473
-
474
- $uploadFinish = new Dropbox_Closure_ChunkedUploadFinishAction($client, $uploadId, $path, $writeMode);
475
- $metadata = Dropbox_RequestUtil::runWithRetry(3, $uploadFinish);
476
-
477
- return $metadata;
478
- }
479
-
480
- /**
481
- * Sometimes fread() returns less than the request number of bytes (for example, when reading
482
- * from network streams). This function repeatedly calls fread until the requested number of
483
- * bytes have been read or we've reached EOF.
484
- *
485
- * @param resource $inStream
486
- * @param int $numBytes
487
- * @throws Dropbox_StreamReadException
488
- * @return string
489
- */
490
- private static function readFully($inStream, $numBytes)
491
- {
492
- Dropbox_Checker::argNat("numBytes", $numBytes);
493
-
494
- $full = '';
495
- $bytesRemaining = $numBytes;
496
- while (!feof($inStream) && $bytesRemaining > 0) {
497
- $part = fread($inStream, $bytesRemaining);
498
- if ($part === false) throw new Dropbox_StreamReadException("Error reading from \$inStream.");
499
- if ($full === '') {
500
- $full = $part;
501
- } else {
502
- $full .= $part;
503
- }
504
- $bytesRemaining -= strlen($part);
505
- }
506
- return $full;
507
- }
508
-
509
- /**
510
- * @param string $path
511
- * @param Dropbox_WriteMode $writeMode
512
- * @param Dropbox_Closure_CurlConfigInterface $curlConfigClosure
513
- * @return array
514
- *
515
- * @throws Dropbox_Exception
516
- */
517
- private function _uploadFile($path, $writeMode, Dropbox_Closure_CurlConfigInterface $curlConfigClosure, $callback = null)
518
- {
519
- Dropbox_Path::checkArg("path", $path);
520
- Dropbox_WriteMode::checkArg("writeMode", $writeMode);
521
-
522
- $url = $this->buildUrlForGetOrPut(
523
- $this->contentHost,
524
- $this->appendFilePath("1/files_put", $path),
525
- $writeMode->getExtraParams());
526
-
527
- $curl = $this->mkCurl($url);
528
-
529
- $curlConfigClosure->configure($curl);
530
-
531
- if ($callback) {
532
- $curl->set(CURLOPT_NOPROGRESS, false);
533
- $curl->set(CURLOPT_PROGRESSFUNCTION, $callback);
534
- }
535
-
536
- $curl->set(CURLOPT_RETURNTRANSFER, true);
537
- $response = $curl->exec();
538
-
539
- if ($response->statusCode !== 200) throw Dropbox_RequestUtil::unexpectedStatus($response);
540
-
541
- return Dropbox_RequestUtil::parseResponseJson($response->body);
542
- }
543
-
544
- /**
545
- * Start a new chunked upload session and upload the first chunk of data.
546
- *
547
- * @param string $data
548
- * The data to start off the chunked upload session.
549
- *
550
- * @return array
551
- * A pair of <code>(string $uploadId, int $byteOffset)</code>. <code>$uploadId</code>
552
- * is a unique identifier for this chunked upload session. You pass this in to
553
- * {@link chunkedUploadContinue} and {@link chuunkedUploadFinish}. <code>$byteOffset</code>
554
- * is the number of bytes that were successfully uploaded.
555
- *
556
- * @throws Dropbox_Exception
557
- */
558
- function chunkedUploadStart($data, $callback = null)
559
- {
560
- Dropbox_Checker::argString("data", $data);
561
-
562
- $response = $this->_chunkedUpload(array(), $data, $callback);
563
-
564
- if ($response->statusCode === 404) {
565
- throw new Dropbox_Exception_BadResponse("Got a 404, but we didn't send up an 'upload_id'");
566
- }
567
-
568
- $correction = self::_chunkedUploadCheckForOffsetCorrection($response);
569
- if ($correction !== null) throw new Dropbox_Exception_BadResponse(
570
- "Got an offset-correcting 400 response, but we didn't send an offset");
571
-
572
- if ($response->statusCode !== 200) throw Dropbox_RequestUtil::unexpectedStatus($response);
573
-
574
- list($uploadId, $byteOffset) = self::_chunkedUploadParse200Response($response->body);
575
- $len = strlen($data);
576
- if ($byteOffset !== $len) throw new Dropbox_Exception_BadResponse(
577
- "We sent $len bytes, but server returned an offset of $byteOffset");
578
-
579
- return $uploadId;
580
- }
581
-
582
- /**
583
- * Append another chunk data to a previously-started chunked upload session.
584
- *
585
- * @param string $uploadId
586
- * The unique identifier for the chunked upload session. This is obtained via
587
- * {@link chunkedUploadStart}.
588
- *
589
- * @param int $byteOffset
590
- * The number of bytes you think you've already uploaded to the given chunked upload
591
- * session. The server will append the new chunk of data after that point.
592
- *
593
- * @param string $data
594
- * The data to append to the existing chunked upload session.
595
- *
596
- * @param Callable $callback
597
- *
598
- * @return int|bool
599
- * If <code>false</code>, it means the server didn't know about the given
600
- * <code>$uploadId</code>. This may be because the chunked upload session has expired
601
- * (they last around 24 hours).
602
- * If <code>true</code>, the chunk was successfully uploaded. If an integer, it means
603
- * you and the server don't agree on the current <code>$byteOffset</code>. The returned
604
- * integer is the server's internal byte offset for the chunked upload session. You need
605
- * to adjust your input to match.
606
- *
607
- * @throws Dropbox_Exception
608
- */
609
- function chunkedUploadContinue($uploadId, $byteOffset, $data, $callback = null)
610
- {
611
- Dropbox_Checker::argStringNonEmpty("uploadId", $uploadId);
612
- Dropbox_Checker::argNat("byteOffset", $byteOffset);
613
- Dropbox_Checker::argString("data", $data);
614
-
615
- $response = $this->_chunkedUpload(
616
- array("upload_id" => $uploadId, "offset" => $byteOffset), $data, $callback);
617
-
618
- if ($response->statusCode === 404) {
619
- // The server doesn't know our upload ID. Maybe it expired?
620
- return false;
621
- }
622
-
623
- $correction = self::_chunkedUploadCheckForOffsetCorrection($response);
624
- if ($correction !== null) {
625
- list($correctedUploadId, $correctedByteOffset) = $correction;
626
- if ($correctedUploadId !== $uploadId) throw new Dropbox_Exception_BadResponse(
627
- "Corrective 400 upload_id mismatch: us=".
628
- self::q($uploadId)." server=".self::q($correctedUploadId));
629
- if ($correctedByteOffset === $byteOffset) throw new Dropbox_Exception_BadResponse(
630
- "Corrective 400 offset is the same as ours: $byteOffset");
631
- return $correctedByteOffset;
632
- }
633
-
634
- if ($response->statusCode !== 200) throw Dropbox_RequestUtil::unexpectedStatus($response);
635
- list($retUploadId, $retByteOffset) = self::_chunkedUploadParse200Response($response->body);
636
-
637
- $nextByteOffset = $byteOffset + strlen($data);
638
- if ($uploadId !== $retUploadId) throw new Dropbox_Exception_BadResponse(
639
- "upload_id mismatch: us=".self::q($uploadId).", server=".self::q($uploadId));
640
- if ($nextByteOffset !== $retByteOffset) throw new Dropbox_Exception_BadResponse(
641
- "next-offset mismatch: us=$nextByteOffset, server=$retByteOffset");
642
-
643
- return true;
644
- }
645
-
646
- /**
647
- * @param string $body
648
- * @return array
649
- */
650
- private static function _chunkedUploadParse200Response($body)
651
- {
652
- $j = Dropbox_RequestUtil::parseResponseJson($body);
653
- $uploadId = self::getField($j, "upload_id");
654
- $byteOffset = self::getField($j, "offset");
655
- return array($uploadId, $byteOffset);
656
- }
657
-
658
- /**
659
- * @param Dropbox_HttpResponse $response
660
- * @return array|null
661
- */
662
- private static function _chunkedUploadCheckForOffsetCorrection($response)
663
- {
664
- if ($response->statusCode !== 400) return null;
665
- $j = json_decode($response->body, true);
666
- if ($j === null) return null;
667
- if (!array_key_exists("upload_id", $j) || !array_key_exists("offset", $j)) return null;
668
- $uploadId = $j["upload_id"];
669
- $byteOffset = $j["offset"];
670
- return array($uploadId, $byteOffset);
671
- }
672
-
673
- /**
674
- * Creates a file on Dropbox using the accumulated contents of the given chunked upload session.
675
- *
676
- * See <a href="https://www.dropbox.com/developers/core/docs#commit-chunked-upload">/commit_chunked_upload</a>.
677
- *
678
- * @param string $uploadId
679
- * The unique identifier for the chunked upload session. This is obtained via
680
- * {@link chunkedUploadStart}.
681
- *
682
- * @param string $path
683
- * The Dropbox path to save the file to ($path).
684
- *
685
- * @param Dropbox_WriteMode $writeMode
686
- * What to do if there's already a file at the given path.
687
- *
688
- * @return array|null
689
- * If <code>null</code>, it means the Dropbox server wasn't aware of the
690
- * <code>$uploadId</code> you gave it.
691
- * Otherwise, you get back the
692
- * <a href="https://www.dropbox.com/developers/core/docs#metadata-details">metadata object</a>
693
- * for the newly-created file.
694
- *
695
- * @throws Dropbox_Exception
696
- */
697
- function chunkedUploadFinish($uploadId, $path, $writeMode)
698
- {
699
- Dropbox_Checker::argStringNonEmpty("uploadId", $uploadId);
700
- Dropbox_Path::checkArgNonRoot("path", $path);
701
- Dropbox_WriteMode::checkArg("writeMode", $writeMode);
702
-
703
- $params = array_merge(array("upload_id" => $uploadId), $writeMode->getExtraParams());
704
-
705
- $response = $this->doPost(
706
- $this->contentHost,
707
- $this->appendFilePath("1/commit_chunked_upload", $path),
708
- $params);
709
-
710
- if ($response->statusCode === 404) return null;
711
- if ($response->statusCode !== 200) throw Dropbox_RequestUtil::unexpectedStatus($response);
712
-
713
- return Dropbox_RequestUtil::parseResponseJson($response->body);
714
- }
715
-
716
- /**
717
- * @param array $params
718
- * @param string $data
719
- * @param callable $callback
720
- *
721
- * @return Dropbox_HttpResponse
722
- */
723
- protected function _chunkedUpload($params, $data, $callback = null)
724
- {
725
- $url = $this->buildUrlForGetOrPut(
726
- $this->contentHost, "1/chunked_upload", $params);
727
-
728
- $curl = $this->mkCurl($url);
729
-
730
- // We can't use CURLOPT_PUT because it wants a stream, but we already have $data in memory.
731
- $curl->set(CURLOPT_CUSTOMREQUEST, "PUT");
732
- $curl->set(CURLOPT_POSTFIELDS, $data);
733
- $curl->addHeader("Content-Type: application/octet-stream");
734
-
735
- if ($callback) {
736
- $curl->set(CURLOPT_NOPROGRESS, false);
737
- $curl->set(CURLOPT_PROGRESSFUNCTION, $callback);
738
- }
739
-
740
- $curl->set(CURLOPT_RETURNTRANSFER, true);
741
- return $curl->exec();
742
- }
743
-
744
- /**
745
- * Returns the metadata for whatever file or folder is at the given path.
746
- *
747
- * <code>
748
- * $client = ...;
749
- * $md = $client->getMetadata("/Photos/Frog.jpeg");
750
- * print_r($md);
751
- * </code>
752
- *
753
- * @param string $path
754
- * The Dropbox path to a file or folder (UTF-8).
755
- *
756
- * @return array|null
757
- * If there is a file or folder at the given path, you'll get back the
758
- * <a href="https://www.dropbox.com/developers/core/docs#metadata-details">metadata object</a>
759
- * for that file or folder. If not, you'll get back <code>null</code>.
760
- *
761
- * @throws Dropbox_Exception
762
- */
763
- function getMetadata($path)
764
- {
765
- Dropbox_Path::checkArg("path", $path);
766
-
767
- return $this->_getMetadata($path, array("list" => "false"));
768
- }
769
-
770
- /**
771
- * Returns the metadata for whatever file or folder is at the given path and, if it's a folder,
772
- * also include the metadata for all the immediate children of that folder.
773
- *
774
- * <code>
775
- * $client = ...;
776
- * $md = $client->getMetadataWithChildren("/Photos");
777
- * print_r($md);
778
- * </code>
779
- *
780
- * @param string $path
781
- * The Dropbox path to a file or folder (UTF-8).
782
- *
783
- * @return array|null
784
- * If there is a file or folder at the given path, you'll get back the
785
- * <a href="https://www.dropbox.com/developers/core/docs#metadata-details">metadata object</a>
786
- * for that file or folder, along with all immediate children if it's a folder. If not,
787
- * you'll get back <code>null</code>.
788
- *
789
- * @throws Dropbox_Exception
790
- */
791
- function getMetadataWithChildren($path)
792
- {
793
- Dropbox_Path::checkArg("path", $path);
794
-
795
- return $this->_getMetadata($path, array("list" => "true", "file_limit" => "25000"));
796
- }
797
-
798
- /**
799
- * @param string $path
800
- * @param array $params
801
- * @return array
802
- *
803
- * @throws Dropbox_Exception
804
- */
805
- private function _getMetadata($path, $params)
806
- {
807
- $response = $this->doGet(
808
- $this->apiHost,
809
- $this->appendFilePath("1/metadata", $path),
810
- $params);
811
-
812
- if ($response->statusCode === 404) return null;
813
- if ($response->statusCode !== 200) throw Dropbox_RequestUtil::unexpectedStatus($response);
814
-
815
- $metadata = Dropbox_RequestUtil::parseResponseJson($response->body);
816
- if (array_key_exists("is_deleted", $metadata) && $metadata["is_deleted"]) return null;
817
- return $metadata;
818
- }
819
-
820
- /**
821
- * If you've previously retrieved the metadata for a folder and its children, this method will
822
- * retrieve updated metadata only if something has changed. This is more efficient than
823
- * calling {@link getMetadataWithChildren} if you have a cache of previous results.
824
- *
825
- * <code>
826
- * $client = ...;
827
- * $md = $client->getMetadataWithChildren("/Photos");
828
- * print_r($md);
829
- * assert($md["is_dir"], "expecting \"/Photos\" to be a folder");
830
- *
831
- * sleep(10);
832
- *
833
- * // Now see if anything changed...
834
- * list($changed, $new_md) = $client->getMetadataWithChildrenIfChanged(
835
- * "/Photos", $md["hash"]);
836
- * if ($changed) {
837
- * echo "Folder changed.\n";
838
- * print_r($new_md);
839
- * } else {
840
- * echo "Folder didn't change.\n";
841
- * }
842
- * </code>
843
- *
844
- * @param string $path
845
- * The Dropbox path to a folder (UTF-8).
846
- *
847
- * @param string $previousFolderHash
848
- * The "hash" field from the previously retrieved folder metadata.
849
- *
850
- * @return array
851
- * A <code>list(boolean $changed, array $metadata)</code>. If the metadata hasn't changed,
852
- * you'll get <code>list(false, null)</code>. If the metadata of the folder or any of its
853
- * children has changed, you'll get <code>list(true, $newMetadata)</code>. $metadata is a
854
- * <a href="https://www.dropbox.com/developers/core/docs#metadata-details">metadata object</a>.
855
- *
856
- * @throws Dropbox_Exception
857
- */
858
- function getMetadataWithChildrenIfChanged($path, $previousFolderHash)
859
- {
860
- Dropbox_Path::checkArg("path", $path);
861
- Dropbox_Checker::argStringNonEmpty("previousFolderHash", $previousFolderHash);
862
-
863
- $params = array("list" => "true", "file_limit" => "25000", "hash" => $previousFolderHash);
864
-
865
- $response = $this->doGet(
866
- $this->apiHost,
867
- $this->appendFilePath("1/metadata", $path),
868
- $params);
869
-
870
- if ($response->statusCode === 304) return array(false, null);
871
- if ($response->statusCode === 404) return array(true, null);
872
- if ($response->statusCode !== 200) throw Dropbox_RequestUtil::unexpectedStatus($response);
873
-
874
- $metadata = Dropbox_RequestUtil::parseResponseJson($response->body);
875
- if (array_key_exists("is_deleted", $metadata) && $metadata["is_deleted"]) {
876
- return array(true, null);
877
- }
878
- return array(true, $metadata);
879
- }
880
-
881
- /**
882
- * A way of letting you keep up with changes to files and folders in a user's Dropbox.
883
- *
884
- * @param string|null $cursor
885
- * If this is the first time you're calling this, pass in <code>null</code>. Otherwise,
886
- * pass in whatever cursor was returned by the previous call.
887
- *
888
- * @param string|null $pathPrefix
889
- * If <code>null</code>, you'll get results for the entire folder (either the user's
890
- * entire Dropbox or your App Folder). If you set <code>$path_prefix</code> to
891
- * "/Photos/Vacation", you'll only get results for that path and any files and folders
892
- * under it.
893
- *
894
- * @return array
895
- * A <a href="https://www.dropbox.com/developers/core/docs#delta">delta page</a>, which
896
- * contains a list of changes to apply along with a new "cursor" that should be passed into
897
- * future <code>getDelta</code> calls. If the "reset" field is <code>true</code>, you
898
- * should clear your local state before applying the changes. If the "has_more" field is
899
- * <code>true</code>, call <code>getDelta</code> immediately to get more results, otherwise
900
- * wait a while (at least 5 minutes) before calling <code>getDelta</code> again.
901
- *
902
- * @throws Dropbox_Exception
903
- */
904
- function getDelta($cursor = null, $pathPrefix = null)
905
- {
906
- Dropbox_Checker::argStringNonEmptyOrNull("cursor", $cursor);
907
- Dropbox_Path::checkArgOrNull("pathPrefix", $pathPrefix);
908
-
909
- $response = $this->doPost($this->apiHost, "1/delta", array(
910
- "cursor" => $cursor,
911
- "path_prefix" => $pathPrefix));
912
-
913
- if ($response->statusCode !== 200) throw Dropbox_RequestUtil::unexpectedStatus($response);
914
-
915
- return Dropbox_RequestUtil::parseResponseJson($response->body);
916
- }
917
-
918
- /**
919
- * Gets the metadata for all the file revisions (up to a limit) for a given path.
920
- *
921
- * See <a href="https://www.dropbox.com/developers/core/docs#revisions">/revisions</a>.
922
- *
923
- * @param string $path
924
- * The Dropbox path that you want file revision metadata for (UTF-8).
925
- *
926
- * @param int|null limit
927
- * The maximum number of revisions to return.
928
- *
929
- * @return array|null
930
- * A list of <a href="https://www.dropbox.com/developers/core/docs#metadata-details>metadata
931
- * objects</a>, one for each file revision. The later revisions appear first in the list.
932
- * If <code>null</code>, then there were too many revisions at that path.
933
- *
934
- * @throws Dropbox_Exception
935
- */
936
- function getRevisions($path, $limit = null)
937
- {
938
- Dropbox_Path::checkArgNonRoot("path", $path);
939
- Dropbox_Checker::argIntPositiveOrNull("limit", $limit);
940
-
941
- $response = $this->doGet(
942
- $this->apiHost,
943
- $this->appendFilePath("1/revisions", $path),
944
- array("rev_limit" => $limit));
945
-
946
- if ($response->statusCode === 406) return null;
947
- if ($response->statusCode !== 200) throw Dropbox_RequestUtil::unexpectedStatus($response);
948
-
949
- return Dropbox_RequestUtil::parseResponseJson($response->body);
950
- }
951
-
952
- /**
953
- * Takes a copy of the file at the given revision and saves it over the current copy. This
954
- * will create a new revision, but the file contents will match the revision you specified.
955
- *
956
- * See <a href="https://www.dropbox.com/developers/core/docs#restore">/restore</a>.
957
- *
958
- * @param string $path
959
- * The Dropbox path of the file to restore (UTF-8).
960
- *
961
- * @param string $rev
962
- * The revision to restore the contents to.
963
- *
964
- * @return mixed
965
- * The <a href="https://www.dropbox.com/developers/core/docs#metadata-details">metadata
966
- * object</a>
967
- *
968
- * @throws Dropbox_Exception
969
- */
970
- function restoreFile($path, $rev)
971
- {
972
- Dropbox_Path::checkArgNonRoot("path", $path);
973
- Dropbox_Checker::argStringNonEmpty("rev", $rev);
974
-
975
- $response = $this->doPost(
976
- $this->apiHost,
977
- $this->appendFilePath("1/restore", $path),
978
- array("rev" => $rev));
979
-
980
- if ($response->statusCode === 404) return null;
981
- if ($response->statusCode !== 200) throw Dropbox_RequestUtil::unexpectedStatus($response);
982
-
983
- return Dropbox_RequestUtil::parseResponseJson($response->body);
984
- }
985
-
986
- /**
987
- * Returns metadata for all files and folders whose filename matches the query string.
988
- *
989
- * See <a href="https://www.dropbox.com/developers/core/docs#search">/search</a>.
990
- *
991
- * @param string $basePath
992
- * The path to limit the search to (UTF-8). Pass in "/" to search everything.
993
- *
994
- * @param string $query
995
- * A space-separated list of substrings to search for. A file matches only if it contains
996
- * all the substrings.
997
- *
998
- * @param int|null $limit
999
- * The maximum number of results to return.
1000
- *
1001
- * @param bool $includeDeleted
1002
- * Whether to include deleted files in the results.
1003
- *
1004
- * @return mixed
1005
- * A list of <a href="https://www.dropbox.com/developers/core/docs#metadata-details>metadata
1006
- * objects</a> of files that match the search query.
1007
- *
1008
- * @throws Dropbox_Exception
1009
- */
1010
- function searchFileNames($basePath, $query, $limit = null, $includeDeleted = false)
1011
- {
1012
- Dropbox_Path::checkArg("basePath", $basePath);
1013
- Dropbox_Checker::argStringNonEmpty("query", $query);
1014
- Dropbox_Checker::argNatOrNull("limit", $limit);
1015
- Dropbox_Checker::argBool("includeDeleted", $includeDeleted);
1016
-
1017
- $response = $this->doPost(
1018
- $this->apiHost,
1019
- $this->appendFilePath("1/search", $basePath),
1020
- array(
1021
- "query" => $query,
1022
- "file_limit" => $limit,
1023
- "include_deleted" => $includeDeleted,
1024
- ));
1025
-
1026
- if ($response->statusCode !== 200) throw Dropbox_RequestUtil::unexpectedStatus($response);
1027
-
1028
- return Dropbox_RequestUtil::parseResponseJson($response->body);
1029
- }
1030
-
1031
- /**
1032
- * Creates and returns a public link to a file or folder's "preview page". This link can be
1033
- * used without authentication. The preview page may contain a thumbnail or some other
1034
- * preview of the file, along with a download link to download the actual file.
1035
- *
1036
- * See <a href="https://www.dropbox.com/developers/core/docs#shares">/shares</a>.
1037
- *
1038
- * @param string $path
1039
- * The Dropbox path to the file or folder you want to create a shareable link to (UTF-8).
1040
- *
1041
- * @return string
1042
- * The URL of the preview page.
1043
- *
1044
- * @throws Dropbox_Exception
1045
- */
1046
- function createShareableLink($path)
1047
- {
1048
- Dropbox_Path::checkArg("path", $path);
1049
-
1050
- $response = $this->doPost(
1051
- $this->apiHost,
1052
- $this->appendFilePath("1/shares", $path),
1053
- array(
1054
- "short_url" => "false",
1055
- ));
1056
-
1057
- if ($response->statusCode === 404) return null;
1058
- if ($response->statusCode !== 200) throw Dropbox_RequestUtil::unexpectedStatus($response);
1059
-
1060
- $j = Dropbox_RequestUtil::parseResponseJson($response->body);
1061
- return self::getField($j, "url");
1062
- }
1063
-
1064
- /**
1065
- * Creates and returns a direct link to a file. This link can be used without authentication.
1066
- * This link will expire in a few hours.
1067
- *
1068
- * See <a href="https://www.dropbox.com/developers/core/docs#media">/media</a>.
1069
- *
1070
- * @param string $path
1071
- * The Dropbox path to a file or folder (UTF-8).
1072
- *
1073
- * @return array
1074
- * A <code>list(string $url, \DateTime $expires)</code> where <code>$url</code> is a direct
1075
- * link to the requested file and <code>$expires</code> is a standard PHP
1076
- * <code>\DateTime</code> representing when <code>$url</code> will stop working.
1077
- *
1078
- * @throws Dropbox_Exception
1079
- */
1080
- function createTemporaryDirectLink($path)
1081
- {
1082
- Dropbox_Path::checkArgNonRoot("path", $path);
1083
-
1084
- $response = $this->doPost(
1085
- $this->apiHost,
1086
- $this->appendFilePath("1/media", $path));
1087
-
1088
- if ($response->statusCode === 404) return null;
1089
- if ($response->statusCode !== 200) throw Dropbox_RequestUtil::unexpectedStatus($response);
1090
-
1091
- $j = Dropbox_RequestUtil::parseResponseJson($response->body);
1092
- $url = self::getField($j, "url");
1093
- $expires = self::parseDateTime(self::getField($j, "expires"));
1094
- return array($url, $expires);
1095
- }
1096
-
1097
- /**
1098
- * Creates and returns a "copy ref" to a file. A copy ref can be used to copy a file across
1099
- * different Dropbox accounts without downloading and re-uploading.
1100
- *
1101
- * For example: Create a <code>Client</code> using the access token from one account and call
1102
- * <code>createCopyRef</code>. Then, create a <code>Client</code> using the access token for
1103
- * another account and call <code>copyFromCopyRef</code> using the copy ref. (You need to use
1104
- * the same app key both times.)
1105
- *
1106
- * See <a href="https://www.dropbox.com/developers/core/docs#copy_ref">/copy_ref</a>.
1107
- *
1108
- * @param string $path
1109
- * The Dropbox path of the file or folder you want to create a copy ref for (UTF-8).
1110
- *
1111
- * @return string
1112
- * The copy ref (just a string that you keep track of).
1113
- *
1114
- * @throws Dropbox_Exception
1115
- */
1116
- function createCopyRef($path)
1117
- {
1118
- Dropbox_Path::checkArg("path", $path);
1119
-
1120
- $response = $this->doGet(
1121
- $this->apiHost,
1122
- $this->appendFilePath("1/copy_ref", $path));
1123
-
1124
- if ($response->statusCode === 404) return null;
1125
- if ($response->statusCode !== 200) throw Dropbox_RequestUtil::unexpectedStatus($response);
1126
-
1127
- $j = Dropbox_RequestUtil::parseResponseJson($response->body);
1128
- return self::getField($j, "copy_ref");
1129
- }
1130
-
1131
- /**
1132
- * Gets a thumbnail image representation of the file at the given path.
1133
- *
1134
- * See <a href="https://www.dropbox.com/developers/core/docs#thumbnails">/thumbnails</a>.
1135
- *
1136
- * @param string $path
1137
- * The path to the file you want a thumbnail for (UTF-8).
1138
- *
1139
- * @param string $format
1140
- * One of the two image formats: "jpeg" or "png".
1141
- *
1142
- * @param string $size
1143
- * One of the predefined image size names, as a string:
1144
- * <ul>
1145
- * <li>"xs" - 32x32</li>
1146
- * <li>"s" - 64x64</li>
1147
- * <li>"m" - 128x128</li>
1148
- * <li>"l" - 640x480</li>
1149
- * <li>"xl" - 1024x768</li>
1150
- * </ul>
1151
- *
1152
- * @return array|null
1153
- * If the file exists, you'll get <code>list(array $metadata, string $data)</code> where
1154
- * <code>$metadata</code> is the file's
1155
- * <a href="https://www.dropbox.com/developers/core/docs#metadata-details">metadata object</a>
1156
- * and $data is the raw data for the thumbnail image. If the file doesn't exist, you'll
1157
- * get <code>null</code>.
1158
- *
1159
- * @throws Dropbox_Exception
1160
- * @throws InvalidArgumentException
1161
- */
1162
- function getThumbnail($path, $format, $size)
1163
- {
1164
- Dropbox_Path::checkArgNonRoot("path", $path);
1165
- Dropbox_Checker::argString("format", $format);
1166
- Dropbox_Checker::argString("size", $size);
1167
- if (!in_array($format, array("jpeg", "png"))) {
1168
- throw new InvalidArgumentException("Invalid 'format': ".self::q($format));
1169
- }
1170
- if (!in_array($size, array("xs", "s", "m", "l", "xl"))) {
1171
- throw new InvalidArgumentException("Invalid 'size': ".self::q($format));
1172
- }
1173
-
1174
- $url = $this->buildUrlForGetOrPut(
1175
- $this->contentHost,
1176
- $this->appendFilePath("1/thumbnails", $path),
1177
- array("size" => $size, "format" => $format));
1178
-
1179
- $curl = $this->mkCurl($url);
1180
- $metadataCatcher = new Dropbox_DropboxMetadataHeaderCatcher($curl->handle);
1181
-
1182
- $curl->set(CURLOPT_RETURNTRANSFER, true);
1183
- $response = $curl->exec();
1184
-
1185
- if ($response->statusCode === 404) return null;
1186
- if ($response->statusCode !== 200) throw Dropbox_RequestUtil::unexpectedStatus($response);
1187
-
1188
- $metadata = $metadataCatcher->getMetadata();
1189
- return array($metadata, $response->body);
1190
- }
1191
-
1192
- /**
1193
- * Copies a file or folder to a new location
1194
- *
1195
- * See <a href="https://www.dropbox.com/developers/core/docs#fileops-copy">/fileops/copy</a>.
1196
- *
1197
- * @param string $fromPath
1198
- * The Dropbox path of the file or folder you want to copy (UTF-8).
1199
- *
1200
- * @param string $toPath
1201
- * The destination Dropbox path (UTF-8).
1202
- *
1203
- * @return mixed
1204
- * The <a href="https://www.dropbox.com/developers/core/docs#metadata-details">metadata
1205
- * object</a> for the new file or folder.
1206
- *
1207
- * @throws Dropbox_Exception
1208
- */
1209
- function copy($fromPath, $toPath)
1210
- {
1211
- Dropbox_Path::checkArg("fromPath", $fromPath);
1212
- Dropbox_Path::checkArgNonRoot("toPath", $toPath);
1213
-
1214
- $response = $this->doPost(
1215
- $this->apiHost,
1216
- "1/fileops/copy",
1217
- array(
1218
- "root" => "auto",
1219
- "from_path" => $fromPath,
1220
- "to_path" => $toPath,
1221
- ));
1222
-
1223
- if ($response->statusCode !== 200) throw Dropbox_RequestUtil::unexpectedStatus($response);
1224
-
1225
- return Dropbox_RequestUtil::parseResponseJson($response->body);
1226
- }
1227
-
1228
- /**
1229
- * Creates a file or folder based on an existing copy ref (possibly from a different Dropbox
1230
- * account).
1231
- *
1232
- * See <a href="https://www.dropbox.com/developers/core/docs#fileops-copy">/fileops/copy</a>.
1233
- *
1234
- * @param string $copyRef
1235
- * A copy ref obtained via the {@link createCopyRef()} call.
1236
- *
1237
- * @param string $toPath
1238
- * The Dropbox path you want to copy the file or folder to (UTF-8).
1239
- *
1240
- * @return mixed
1241
- * The <a href="https://www.dropbox.com/developers/core/docs#metadata-details">metadata
1242
- * object</a> for the new file or folder.
1243
- *
1244
- * @throws Dropbox_Exception
1245
- */
1246
- function copyFromCopyRef($copyRef, $toPath)
1247
- {
1248
- Dropbox_Checker::argStringNonEmpty("copyRef", $copyRef);
1249
- Dropbox_Path::checkArgNonRoot("toPath", $toPath);
1250
-
1251
- $response = $this->doPost(
1252
- $this->apiHost,
1253
- "1/fileops/copy",
1254
- array(
1255
- "root" => "auto",
1256
- "from_copy_ref" => $copyRef,
1257
- "to_path" => $toPath,
1258
- )
1259
- );
1260
-
1261
- if ($response->statusCode !== 200) throw Dropbox_RequestUtil::unexpectedStatus($response);
1262
-
1263
- return Dropbox_RequestUtil::parseResponseJson($response->body);
1264
- }
1265
-
1266
- /**
1267
- * Creates a folder.
1268
- *
1269
- * See <a href="https://www.dropbox.com/developers/core/docs#fileops-create-folder">/fileops/create_folder</a>.
1270
- *
1271
- * @param string $path
1272
- * The Dropbox path at which to create the folder (UTF-8).
1273
- *
1274
- * @return array|null
1275
- * If successful, you'll get back the
1276
- * <a href="https://www.dropbox.com/developers/core/docs#metadata-details">metadata object</a>
1277
- * for the newly-created folder. If not successful, you'll get <code>null</code>.
1278
- *
1279
- * @throws Dropbox_Exception
1280
- */
1281
- function createFolder($path)
1282
- {
1283
- Dropbox_Path::checkArgNonRoot("path", $path);
1284
-
1285
- $response = $this->doPost(
1286
- $this->apiHost,
1287
- "1/fileops/create_folder",
1288
- array(
1289
- "root" => "auto",
1290
- "path" => $path,
1291
- ));
1292
-
1293
- if ($response->statusCode === 403) return null;
1294
- if ($response->statusCode !== 200) throw Dropbox_RequestUtil::unexpectedStatus($response);
1295
-
1296
- return Dropbox_RequestUtil::parseResponseJson($response->body);
1297
- }
1298
-
1299
- /**
1300
- * Deletes a file or folder
1301
- *
1302
- * See <a href="https://www.dropbox.com/developers/core/docs#fileops-delete">/fileops/delete</a>.
1303
- *
1304
- * @param string $path
1305
- * The Dropbox path of the file or folder to delete (UTF-8).
1306
- *
1307
- * @return mixed
1308
- * The <a href="https://www.dropbox.com/developers/core/docs#metadata-details">metadata
1309
- * object</a> for the deleted file or folder.
1310
- *
1311
- * @throws Dropbox_Exception
1312
- */
1313
- function delete($path)
1314
- {
1315
- Dropbox_Path::checkArgNonRoot("path", $path);
1316
-
1317
- $response = $this->doPost(
1318
- $this->apiHost,
1319
- "1/fileops/delete",
1320
- array(
1321
- "root" => "auto",
1322
- "path" => $path,
1323
- ));
1324
-
1325
- if ($response->statusCode !== 200) throw Dropbox_RequestUtil::unexpectedStatus($response);
1326
-
1327
- return Dropbox_RequestUtil::parseResponseJson($response->body);
1328
- }
1329
-
1330
- /**
1331
- * Moves a file or folder to a new location.
1332
- *
1333
- * See <a href="https://www.dropbox.com/developers/core/docs#fileops-move">/fileops/move</a>.
1334
- *
1335
- * @param string $fromPath
1336
- * The source Dropbox path (UTF-8).
1337
- *
1338
- * @param string $toPath
1339
- * The destination Dropbox path (UTF-8).
1340
- *
1341
- * @return mixed
1342
- * The <a href="https://www.dropbox.com/developers/core/docs#metadata-details">metadata
1343
- * object</a> for the destination file or folder.
1344
- *
1345
- * @throws Dropbox_Exception
1346
- */
1347
- function move($fromPath, $toPath)
1348
- {
1349
- Dropbox_Path::checkArgNonRoot("fromPath", $fromPath);
1350
- Dropbox_Path::checkArgNonRoot("toPath", $toPath);
1351
-
1352
- $response = $this->doPost(
1353
- $this->apiHost,
1354
- "1/fileops/move",
1355
- array(
1356
- "root" => "auto",
1357
- "from_path" => $fromPath,
1358
- "to_path" => $toPath,
1359
- ));
1360
-
1361
- if ($response->statusCode !== 200) throw Dropbox_RequestUtil::unexpectedStatus($response);
1362
-
1363
- return Dropbox_RequestUtil::parseResponseJson($response->body);
1364
- }
1365
-
1366
- /**
1367
- * Build a URL for making a GET or PUT request. Will add the "locale"
1368
- * parameter.
1369
- *
1370
- * @param $host
1371
- * Either the "API" or "API content" hostname from {@link getHost()}.
1372
- * @param $path
1373
- * The "path" part of the URL. For example, "/account/info".
1374
- * @param null $params
1375
- * URL parameters. For POST requests, do not put the parameters here.
1376
- * Include them in the request body instead.
1377
- *
1378
- * @return string
1379
- */
1380
- function buildUrlForGetOrPut($host, $path, $params = null)
1381
- {
1382
- return Dropbox_RequestUtil::buildUrlForGetOrPut($this->userLocale, $host, $path, $params);
1383
- }
1384
-
1385
- /**
1386
- * Perform an OAuth-2-authorized GET request to the Dropbox API. Will automatically
1387
- * fill in "User-Agent" and "locale" as well.
1388
- *
1389
- * @param string $host
1390
- * Either the "API" or "API content" hostname from {@link getHost()}.
1391
- * @param string $path
1392
- * The "path" part of the URL. For example, "/account/info".
1393
- * @param array|null $params
1394
- * GET parameters.
1395
- * @return Dropbox_HttpResponse
1396
- *
1397
- * @throws Dropbox_Exception
1398
- */
1399
- function doGet($host, $path, $params = null)
1400
- {
1401
- Dropbox_Checker::argString("host", $host);
1402
- Dropbox_Checker::argString("path", $path);
1403
- return Dropbox_RequestUtil::doGet($this->clientIdentifier, $this->accessToken, $this->userLocale,
1404
- $host, $path, $params);
1405
- }
1406
-
1407
- /**
1408
- * Perform an OAuth-2-authorized POST request to the Dropbox API. Will automatically
1409
- * fill in "User-Agent" and "locale" as well.
1410
- *
1411
- * @param string $host
1412
- * Either the "API" or "API content" hostname from {@link getHost()}.
1413
- * @param string $path
1414
- * The "path" part of the URL. For example, "/commit_chunked_upload".
1415
- * @param array|null $params
1416
- * POST parameters.
1417
- * @return Dropbox_HttpResponse
1418
- *
1419
- * @throws Dropbox_Exception
1420
- */
1421
- function doPost($host, $path, $params = null)
1422
- {
1423
- Dropbox_Checker::argString("host", $host);
1424
- Dropbox_Checker::argString("path", $path);
1425
- return Dropbox_RequestUtil::doPost($this->clientIdentifier, $this->accessToken, $this->userLocale,
1426
- $host, $path, $params);
1427
- }
1428
-
1429
- /**
1430
- * Create a {@link Curl} object that is pre-configured with {@link getClientIdentifier()},
1431
- * and the proper OAuth 2 "Authorization" header.
1432
- *
1433
- * @param string $url
1434
- * Generate this URL using {@link buildUrl()}.
1435
- *
1436
- * @return Dropbox_Curl
1437
- */
1438
- function mkCurl($url)
1439
- {
1440
- return Dropbox_RequestUtil::mkCurlWithOAuth($this->clientIdentifier, $url, $this->accessToken);
1441
- }
1442
-
1443
- /**
1444
- * Parses date/time strings returned by the Dropbox API. The Dropbox API returns date/times
1445
- * formatted like: <code>"Sat, 21 Aug 2010 22:31:20 +0000"</code>.
1446
- *
1447
- * @param string $apiDateTimeString
1448
- * A date/time string returned by the API.
1449
- *
1450
- * @return \DateTime
1451
- * A standard PHP <code>\DateTime</code> instance.
1452
- *
1453
- * @throws Dropbox_Exception_BadResponse
1454
- * Thrown if <code>$apiDateTimeString</code> isn't correctly formatted.
1455
- */
1456
- static function parseDateTime($apiDateTimeString)
1457
- {
1458
- $dt = DateTime::createFromFormat(self::$dateTimeFormat, $apiDateTimeString);
1459
- if ($dt === false) throw new Dropbox_Exception_BadResponse(
1460
- "Bad date/time from server: ".self::q($apiDateTimeString));
1461
- return $dt;
1462
- }
1463
-
1464
- private static $dateTimeFormat = "D, d M Y H:i:s T";
1465
-
1466
- /**
1467
- * @internal
1468
- */
1469
- static function q($object) { return var_export($object, true); }
1470
-
1471
- /**
1472
- * @internal
1473
- */
1474
- static function getField($j, $fieldName)
1475
- {
1476
- if (!array_key_exists($fieldName, $j)) throw new Dropbox_Exception_BadResponse(
1477
- "missing field \"$fieldName\" in ".self::q($j));
1478
- return $j[$fieldName];
1479
- }
1480
-
1481
- /**
1482
- * Given an OAuth 2 access token, returns <code>null</code> if it is well-formed (though
1483
- * not necessarily valid). Otherwise, returns a string describing what's wrong with it.
1484
- *
1485
- * @param string $s
1486
- *
1487
- * @return string
1488
- */
1489
- static function getAccessTokenError($s)
1490
- {
1491
- if ($s === null) return "can't be null";
1492
- if (strlen($s) === 0) return "can't be empty";
1493
- // if (preg_match('@[^-=_~/A-Za-z0-9\.\+]@', $s) === 1) return "contains invalid character";
1494
- return null;
1495
- }
1496
-
1497
- /**
1498
- * @internal
1499
- */
1500
- static function checkAccessTokenArg($argName, $accessToken)
1501
- {
1502
- $error = self::getAccessTokenError($accessToken);
1503
- if ($error !== null) throw new InvalidArgumentException("'$argName' invalid: $error");
1504
- }
1505
-
1506
- /**
1507
- * @internal
1508
- */
1509
- static function getClientIdentifierError($s)
1510
- {
1511
- if ($s === null) return "can't be null";
1512
- if (strlen($s) === 0) return "can't be empty";
1513
- if (preg_match('@[\x00-\x1f\x7f]@', $s) === 1) return "contains control character";
1514
- return null;
1515
- }
1516
-
1517
- /**
1518
- * @internal
1519
- */
1520
- static function checkClientIdentifierArg($argName, $accessToken)
1521
- {
1522
- $error = self::getClientIdentifierError($accessToken);
1523
- if ($error !== null) throw new InvalidArgumentException("'$argName' invalid: $error");
1524
- }
1525
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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 CHANGED
@@ -1,29 +1,28 @@
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
-
29
- }
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 CHANGED
@@ -1,25 +1,25 @@
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
- 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
- }
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 CHANGED
@@ -1,22 +1,22 @@
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
- }
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 CHANGED
@@ -1,24 +1,24 @@
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
- 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
- }
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 CHANGED
@@ -1,6 +1,6 @@
1
- <?php
2
-
3
- interface Dropbox_Closure_CurlConfigInterface
4
- {
5
- public function configure(Dropbox_Curl $curl);
6
- }
1
+ <?php
2
+
3
+ interface Dropbox_Closure_CurlConfigInterface
4
+ {
5
+ public function configure(Dropbox_Curl $curl);
6
+ }
src/Dropbox/Closure/CurlConfigOctetStream.php CHANGED
@@ -1,18 +1,18 @@
1
- <?php
2
-
3
- class Dropbox_Closure_CurlConfigOctetStream implements Dropbox_Closure_CurlConfigInterface
4
- {
5
- private $data;
6
-
7
- 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
- }
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 CHANGED
@@ -1,6 +1,6 @@
1
- <?php
2
-
3
- interface Dropbox_Closure_ReRunnableActionInterface
4
- {
5
- public function run();
6
- }
1
+ <?php
2
+
3
+ interface Dropbox_Closure_ReRunnableActionInterface
4
+ {
5
+ public function run();
6
+ }
src/Dropbox/Curl.php CHANGED
@@ -1,112 +1,116 @@
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
- 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, 3); // Enforce SSL v3.
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')) $this->set(CURLOPT_PROTOCOLS, CURLPROTO_HTTPS);
74
- if (defined('CURLOPT_REDIR_PROTOCOLS')) $this->set(CURLOPT_REDIR_PROTOCOLS, CURLPROTO_HTTPS);
75
- }
76
-
77
- /**
78
- * @param string $header
79
- */
80
- function addHeader($header)
81
- {
82
- $this->headers[] = $header;
83
- }
84
-
85
- function exec()
86
- {
87
- $this->set(CURLOPT_HTTPHEADER, $this->headers);
88
-
89
- $body = curl_exec($this->handle);
90
- if ($body === false) {
91
- throw new Dropbox_Exception_NetworkIO("Error executing HTTP request: " . curl_error($this->handle));
92
- }
93
-
94
- $statusCode = curl_getinfo($this->handle, CURLINFO_HTTP_CODE);
95
-
96
- return new Dropbox_HttpResponse($statusCode, $body);
97
- }
98
-
99
- /**
100
- * @param int $option
101
- * @param mixed $value
102
- */
103
- function set($option, $value)
104
- {
105
- curl_setopt($this->handle, $option, $value);
106
- }
107
-
108
- function __destruct()
109
- {
110
- curl_close($this->handle);
111
- }
112
- }
 
 
 
 
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 CHANGED
@@ -1,45 +1,44 @@
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
- var $outStream;
13
- var $errorData;
14
- var $isError;
15
-
16
- 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
- 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
- function getErrorBody()
41
- {
42
- return implode($this->errorData);
43
- }
44
- }
45
-
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 CHANGED
@@ -1,18 +1,18 @@
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
- function __construct($message)
15
- {
16
- parent::__construct($message);
17
- }
18
- }
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 CHANGED
@@ -1,82 +1,88 @@
1
- <?php
2
-
3
- /**
4
- * @internal
5
- */
6
- final class Dropbox_DropboxMetadataHeaderCatcher
7
- {
8
- /**
9
- * @var mixed
10
- */
11
- var $metadata = null;
12
-
13
- /**
14
- * @var string
15
- */
16
- var $error = null;
17
-
18
- /**
19
- * @var bool
20
- */
21
- var $skippedFirstLine = false;
22
-
23
- /**
24
- * @param resource $ch
25
- */
26
- 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
- * @return int
35
- * @throws Dropbox_Exception_BadResponse
36
- */
37
- function headerFunction($ch, $header)
38
- {
39
- // The first line is the HTTP status line (Ex: "HTTP/1.1 200 OK").
40
- if (!$this->skippedFirstLine) {
41
- $this->skippedFirstLine = true;
42
- return strlen($header);
43
- }
44
-
45
- // If we've encountered an error on a previous callback, then there's nothing left to do.
46
- if ($this->error !== null) {
47
- return strlen($header);
48
- }
49
-
50
- // case-insensitive starts-with check.
51
- if (strlen($header) < 19 || substr_compare($header, "x-dropbox-metadata:", 0, 19, true) !== 0) {
52
- return strlen($header);
53
- }
54
-
55
- if ($this->metadata !== null) {
56
- $this->error = "Duplicate X-Dropbox-Metadata header";
57
- return strlen($header);
58
- }
59
-
60
- $headerValue = substr($header, 19);
61
- $parsed = json_decode($headerValue, true);
62
-
63
- if ($parsed === null) {
64
- $this->error = "Bad JSON in X-Dropbox-Metadata header";
65
- return strlen($header);
66
- }
67
-
68
- $this->metadata = $parsed;
69
- return strlen($header);
70
- }
71
-
72
- function getMetadata()
73
- {
74
- if ($this->error !== null) {
75
- throw new Dropbox_Exception_BadResponse($this->error);
76
- }
77
- if ($this->metadata === null) {
78
- throw new Dropbox_Exception_BadResponse("Missing X-Dropbox-Metadata header");
79
- }
80
- return $this->metadata;
81
- }
82
- }
 
 
 
 
 
 
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 CHANGED
@@ -1,31 +1,31 @@
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
- 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
- }
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 CHANGED
@@ -1,16 +1,16 @@
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
- function __construct($message = "")
13
- {
14
- parent::__construct($message);
15
- }
16
- }
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 CHANGED
@@ -1,16 +1,16 @@
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
- function __construct($message)
13
- {
14
- parent::__construct($message);
15
- }
16
- }
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 CHANGED
@@ -1,32 +1,32 @@
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
- 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
- }
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 CHANGED
@@ -1,17 +1,17 @@
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
- function __construct($message = "")
14
- {
15
- parent::__construct($message);
16
- }
17
- }
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 CHANGED
@@ -1,15 +1,15 @@
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
- function __construct($message, $cause = null)
12
- {
13
- parent::__construct($message, $cause);
14
- }
15
- }
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 CHANGED
@@ -1,16 +1,16 @@
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
- function __construct($message)
13
- {
14
- parent::__construct($message);
15
- }
16
- }
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 CHANGED
@@ -1,16 +1,16 @@
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
- function __construct($message)
13
- {
14
- parent::__construct($message);
15
- }
16
- }
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 CHANGED
@@ -1,14 +1,14 @@
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
- function __construct($message = "")
11
- {
12
- parent::__construct($message);
13
- }
14
- }
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 CHANGED
@@ -1,98 +1,115 @@
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
- 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
- return self::$defaultValue;
26
- }
27
- private static $defaultValue;
28
-
29
- /** @var string */
30
- private $api;
31
- /** @var string */
32
- private $content;
33
- /** @var string */
34
- private $web;
35
-
36
- /**
37
- * Constructor.
38
- *
39
- * @param string $api
40
- * See {@link getApi()}
41
- * @param string $content
42
- * See {@link getContent()}
43
- * @param string $web
44
- * See {@link getWeb()}
45
- */
46
- function __construct($api, $content, $web)
47
- {
48
- $this->api = $api;
49
- $this->content = $content;
50
- $this->web = $web;
51
- }
52
-
53
- /**
54
- * Returns the host name of the main Dropbox API server.
55
- * The default is "api.dropbox.com".
56
- *
57
- * @return string
58
- */
59
- function getApi() { return $this->api; }
60
-
61
- /**
62
- * Returns the host name of the Dropbox API content server.
63
- * The default is "api-content.dropbox.com".
64
- *
65
- * @return string
66
- */
67
- function getContent() { return $this->content; }
68
-
69
- /**
70
- * Returns the host name of the Dropbox web server. Used during user authorization.
71
- * The default is "www.dropbox.com".
72
- *
73
- * @return string
74
- */
75
- function getWeb() { return $this->web; }
76
-
77
- /**
78
- * Check that a function argument is of type <code>Host</code>.
79
- *
80
- * @internal
81
- */
82
- static function checkArg($argName, $argValue)
83
- {
84
- if (!($argValue instanceof self)) Dropbox_Checker::throwError($argName, $argValue, __CLASS__);
85
- }
86
-
87
- /**
88
- * Check that a function argument is either <code>null</code> or of type
89
- * <code>Host</code>.
90
- *
91
- * @internal
92
- */
93
- static function checkArgOrNull($argName, $argValue)
94
- {
95
- if ($argValue === null) return;
96
- if (!($argValue instanceof self)) Dropbox_Checker::throwError($argName, $argValue, __CLASS__);
97
- }
98
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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 CHANGED
@@ -1,16 +1,16 @@
1
- <?php
2
-
3
- /**
4
- * @internal
5
- */
6
- final class Dropbox_HttpResponse
7
- {
8
- public $statusCode;
9
- public $body;
10
-
11
- function __construct($statusCode, $body)
12
- {
13
- $this->statusCode = $statusCode;
14
- $this->body = $body;
15
- }
16
- }
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 CHANGED
@@ -1,60 +1,68 @@
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
- function getKey() { return $this->key; }
16
-
17
- /** @var string */
18
- private $key;
19
-
20
- /**
21
- * The OAuth 1 access token secret.
22
- *
23
- * Make sure that this is kept a secret. Someone with your app secret can impesonate your
24
- * application. People sometimes ask for help on the Dropbox API forums and
25
- * copy/paste code that includes their app secret. Do not do that.
26
- *
27
- * @return string
28
- */
29
- function getSecret() { return $this->secret; }
30
-
31
- /** @var string */
32
- private $secret;
33
-
34
- /**
35
- * Constructor.
36
- *
37
- * @param string $key
38
- * {@link getKey()}
39
- * @param string $secret
40
- * {@link getSecret()}
41
- */
42
- function __construct($key, $secret)
43
- {
44
- Dropbox_AppInfo::checkKeyArg($key);
45
- Dropbox_AppInfo::checkSecretArg($secret);
46
-
47
- $this->key = $key;
48
- $this->secret = $secret;
49
- }
50
-
51
- /**
52
- * Use this to check that a function argument is of type <code>AppInfo</code>
53
- *
54
- * @internal
55
- */
56
- static function checkArg($argName, $argValue)
57
- {
58
- if (!($argValue instanceof self)) Dropbox_Checker::throwError($argName, $argValue, __CLASS__);
59
- }
60
- }
 
 
 
 
 
 
 
 
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 CHANGED
@@ -1,102 +1,106 @@
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
- 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) throw Dropbox_RequestUtil::unexpectedStatus($response);
42
-
43
- $parts = Dropbox_RequestUtil::parseResponseJson($response->body);
44
-
45
- if (!array_key_exists('token_type', $parts) or !is_string($parts['token_type'])) {
46
- throw new Dropbox_Exception_BadResponse("Missing \"token_type\" field.");
47
- }
48
- $tokenType = $parts['token_type'];
49
- if (!array_key_exists('access_token', $parts) or !is_string($parts['access_token'])) {
50
- throw new Dropbox_Exception_BadResponse("Missing \"access_token\" field.");
51
- }
52
- $accessToken = $parts['access_token'];
53
-
54
- if ($tokenType !== "Bearer" && $tokenType !== "bearer") {
55
- throw new Dropbox_Exception_BadResponse("Unknown \"token_type\"; expecting \"Bearer\", got "
56
- .Dropbox_Client::q($tokenType));
57
- }
58
-
59
- return $accessToken;
60
- }
61
-
62
- /**
63
- * Make a Dropbox API call to disable the given OAuth 1 access token.
64
- *
65
- * See <a href="https://www.dropbox.com/developers/core/docs#disable-token">/disable_access_token</a>.
66
- *
67
- * @param Dropbox_OAuth1AccessToken $oauth1AccessToken
68
- *
69
- * @throws Dropbox_Exception
70
- */
71
- function disableOAuth1AccessToken($oauth1AccessToken)
72
- {
73
- Dropbox_OAuth1AccessToken::checkArg("oauth1AccessToken", $oauth1AccessToken);
74
-
75
- $response = self::doPost($oauth1AccessToken, "1/disable_access_token");
76
-
77
- if ($response->statusCode !== 200) throw Dropbox_RequestUtil::unexpectedStatus($response);
78
- }
79
-
80
- /**
81
- * @param Dropbox_OAuth1AccessToken $oauth1AccessToken
82
- * @param string $path
83
- *
84
- * @return Dropbox_HttpResponse
85
- *
86
- * @throws Dropbox_Exception
87
- */
88
- private function doPost($oauth1AccessToken, $path)
89
- {
90
- // Construct the OAuth 1 header.
91
- $authHeaderValue = "OAuth oauth_signature_method=\"PLAINTEXT\""
92
- . ", oauth_consumer_key=\"" . rawurlencode($this->appInfo->getKey()) . "\""
93
- . ", oauth_token=\"" . rawurlencode($oauth1AccessToken->getKey()) . "\""
94
- . ", oauth_signature=\"" . rawurlencode($this->appInfo->getSecret()) . "&" . rawurlencode($oauth1AccessToken->getSecret()) . "\"";
95
-
96
- return Dropbox_RequestUtil::doPostWithSpecificAuth(
97
- $this->clientIdentifier, $authHeaderValue, $this->userLocale,
98
- $this->appInfo->getHost()->getApi(),
99
- $path,
100
- null);
101
- }
102
- }
 
 
 
 
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 CHANGED
@@ -1,170 +1,201 @@
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
- static function isValid($path)
18
- {
19
- $error = self::findError($path);
20
- return ($error === null);
21
- }
22
-
23
- /**
24
- * Return whether the given path is a valid non-root Dropbox path.
25
- * This is the same as {@link isValid} except <code>"/"</code> is not allowed.
26
- *
27
- * @param string $path
28
- * The path you want to check for validity.
29
- *
30
- * @return bool
31
- * Whether the path was valid or not.
32
- */
33
- static function isValidNonRoot($path)
34
- {
35
- $error = self::findErrorNonRoot($path);
36
- return ($error === null);
37
- }
38
-
39
- /**
40
- * If the given path is a valid Dropbox path, return <code>null</code>,
41
- * otherwise return an English string error message describing what is wrong with the path.
42
- *
43
- * @param string $path
44
- * The path you want to check for validity.
45
- *
46
- * @return string|null
47
- * If the path was valid, return <code>null</code>. Otherwise, returns
48
- * an English string describing the problem.
49
- */
50
- static function findError($path)
51
- {
52
- Dropbox_Checker::argString("path", $path);
53
-
54
- $matchResult = preg_match('%^(?:
55
- [\x09\x0A\x0D\x20-\x7E] # ASCII
56
- | [\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte
57
- | \xE0[\xA0-\xBF][\x80-\xBD] # excluding overlongs, FFFE, and FFFF
58
- | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte
59
- | \xED[\x80-\x9F][\x80-\xBF] # excluding surrogates
60
- )*$%xs', $path);
61
-
62
- if ($matchResult !== 1) {
63
- return "must be valid UTF-8; BMP only, no surrogates, no U+FFFE or U+FFFF";
64
- }
65
-
66
- if (substr_compare($path, "/", 0, 1) !== 0) return "must start with \"/\"";
67
- $l = strlen($path);
68
- if ($l === 1) return null; // Special case for "/"
69
-
70
- if ($path[$l-1] === "/") return "must not end with \"/\"";
71
-
72
- // TODO: More checks.
73
-
74
- return null;
75
- }
76
-
77
- /**
78
- * If the given path is a valid non-root Dropbox path, return <code>null</code>,
79
- * otherwise return an English string error message describing what is wrong with the path.
80
- * This is the same as {@link findError} except <code>"/"</code> will yield an error message.
81
- *
82
- * @param string $path
83
- * The path you want to check for validity.
84
- *
85
- * @return string|null
86
- * If the path was valid, return <code>null</code>. Otherwise, returns
87
- * an English string describing the problem.
88
- */
89
- static function findErrorNonRoot($path)
90
- {
91
- if ($path == "/") return "root path not allowed";
92
- return self::findError($path);
93
- }
94
-
95
- /**
96
- * Return the last component of a path (the file or folder name).
97
- *
98
- * <code>
99
- * Path::getName("/Misc/Notes.txt") // "Notes.txt"
100
- * Path::getName("/Misc") // "Misc"
101
- * Path::getName("/") // null
102
- * </code>
103
- *
104
- * @param string $path
105
- * The full path you want to get the last component of.
106
- *
107
- * @return null|string
108
- * The last component of <code>$path</code> or <code>null</code> if the given
109
- * <code>$path</code> was <code>"/"<code>.
110
- */
111
- static function getName($path)
112
- {
113
- Dropbox_Checker::argString("path", $path);
114
-
115
- if (substr_compare($path, "/", 0, 1) !== 0) {
116
- throw new InvalidArgumentException("'path' must start with \"/\"");
117
- }
118
- $l = strlen($path);
119
- if ($l === 1) return null;
120
- if ($path[$l-1] === "/") {
121
- throw new InvalidArgumentException("'path' must not end with \"/\"");
122
- }
123
-
124
- $lastSlash = strrpos($path, "/");
125
- return substr($path, $lastSlash+1);
126
- }
127
-
128
- /**
129
- * @internal
130
- *
131
- * @param string $argName
132
- * @param mixed $value
133
- * @throws InvalidArgumentException
134
- */
135
- static function checkArg($argName, $value)
136
- {
137
- if ($value === null) throw new InvalidArgumentException("'$argName' must not be null");
138
- if (!is_string($value)) throw new InvalidArgumentException("'$argName' must be a string");
139
- $error = self::findError($value);
140
- if ($error !== null) throw new InvalidArgumentException("'$argName'': bad path: $error: ".var_export($value, true));
141
- }
142
-
143
- /**
144
- * @internal
145
- *
146
- * @param string $argName
147
- * @param mixed $value
148
- * @throws InvalidArgumentException
149
- */
150
- static function checkArgOrNull($argName, $value)
151
- {
152
- if ($value === null) return;
153
- self::checkArg($argName, $value);
154
- }
155
-
156
- /**
157
- * @internal
158
- *
159
- * @param string $argName
160
- * @param mixed $value
161
- * @throws InvalidArgumentException
162
- */
163
- static function checkArgNonRoot($argName, $value)
164
- {
165
- if ($value === null) throw new InvalidArgumentException("'$argName' must not be null");
166
- if (!is_string($value)) throw new InvalidArgumentException("'$argName' must be a string");
167
- $error = self::findErrorNonRoot($value);
168
- if ($error !== null) throw new InvalidArgumentException("'$argName'': bad path: $error: ".var_export($value, true));
169
- }
170
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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 CHANGED
@@ -1,287 +1,308 @@
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
- * @return string
14
- */
15
- static function buildUrlForGetOrPut($userLocale, $host, $path, $params = null)
16
- {
17
- $url = self::buildUri($host, $path);
18
- $url .= "?locale=" . rawurlencode($userLocale);
19
-
20
- if ($params !== null) {
21
- foreach ($params as $key => $value) {
22
- Dropbox_Checker::argStringNonEmpty("key in 'params'", $key);
23
- if ($value !== null) {
24
- if (is_bool($value)) {
25
- $value = $value ? "true" : "false";
26
- }
27
- else if (is_int($value)) {
28
- $value = (string) $value;
29
- }
30
- else if (!is_string($value)) {
31
- throw new InvalidArgumentException("params['$key'] is not a string, int, or bool");
32
- }
33
- $url .= "&" . rawurlencode($key) . "=" . rawurlencode($value);
34
- }
35
- }
36
- }
37
- return $url;
38
- }
39
-
40
- /**
41
- * @param string $host
42
- * @param string $path
43
- * @return string
44
- */
45
- static function buildUri($host, $path)
46
- {
47
- Dropbox_Checker::argStringNonEmpty("host", $host);
48
- Dropbox_Checker::argStringNonEmpty("path", $path);
49
- return "https://" . $host . "/" . $path;
50
- }
51
-
52
- /**
53
- * @param string $clientIdentifier
54
- * @param string $url
55
- * @return Dropbox_Curl
56
- */
57
- static function mkCurl($clientIdentifier, $url)
58
- {
59
- $curl = new Dropbox_Curl($url);
60
-
61
- $curl->set(CURLOPT_CONNECTTIMEOUT, 10);
62
-
63
- // If the transfer speed is below 1kB/sec for 10 sec, abort.
64
- $curl->set(CURLOPT_LOW_SPEED_LIMIT, 1024);
65
- $curl->set(CURLOPT_LOW_SPEED_TIME, 10);
66
-
67
- //$curl->set(CURLOPT_VERBOSE, true); // For debugging.
68
- // TODO: Figure out how to encode clientIdentifier (urlencode?)
69
- $curl->addHeader("User-Agent: ".$clientIdentifier." Dropbox-PHP-SDK");
70
-
71
- return $curl;
72
- }
73
-
74
- /**
75
- * @param string $clientIdentifier
76
- * @param string $url
77
- * @param string $authHeaderValue
78
- * @return Dropbox_Curl
79
- */
80
- static function mkCurlWithAuth($clientIdentifier, $url, $authHeaderValue)
81
- {
82
- $curl = self::mkCurl($clientIdentifier, $url);
83
- $curl->addHeader("Authorization: $authHeaderValue");
84
- return $curl;
85
- }
86
-
87
- /**
88
- * @param string $clientIdentifier
89
- * @param string $url
90
- * @param string $accessToken
91
- * @return Dropbox_Curl
92
- */
93
- static function mkCurlWithOAuth($clientIdentifier, $url, $accessToken)
94
- {
95
- return self::mkCurlWithAuth($clientIdentifier, $url, $accessToken);
96
- }
97
-
98
- static function buildPostBody($params)
99
- {
100
- if ($params === null) return "";
101
-
102
- $pairs = array();
103
- foreach ($params as $key => $value) {
104
- Dropbox_Checker::argStringNonEmpty("key in 'params'", $key);
105
- if ($value !== null) {
106
- if (is_bool($value)) {
107
- $value = $value ? "true" : "false";
108
- }
109
- else if (is_int($value)) {
110
- $value = (string) $value;
111
- }
112
- else if (!is_string($value)) {
113
- throw new InvalidArgumentException("params['$key'] is not a string, int, or bool");
114
- }
115
- $pairs[] = rawurlencode($key) . "=" . rawurlencode((string) $value);
116
- }
117
- }
118
- return implode("&", $pairs);
119
- }
120
-
121
- /**
122
- * @param string $clientIdentifier
123
- * @param string $accessToken
124
- * @param string $userLocale
125
- * @param string $host
126
- * @param string $path
127
- * @param array|null $params
128
- *
129
- * @return Dropbox_HttpResponse
130
- *
131
- * @throws Dropbox_Exception
132
- */
133
- static function doPost($clientIdentifier, $accessToken, $userLocale, $host, $path, $params = null)
134
- {
135
- Dropbox_Checker::argStringNonEmpty("accessToken", $accessToken);
136
-
137
- $url = self::buildUri($host, $path);
138
-
139
- if ($params === null) $params = array();
140
- $params['locale'] = $userLocale;
141
-
142
- $curl = self::mkCurlWithOAuth($clientIdentifier, $url, $accessToken);
143
- $curl->set(CURLOPT_POST, true);
144
- $curl->set(CURLOPT_POSTFIELDS, self::buildPostBody($params));
145
-
146
- $curl->set(CURLOPT_RETURNTRANSFER, true);
147
- return $curl->exec();
148
- }
149
-
150
- /**
151
- * @param string $clientIdentifier
152
- * @param string $authHeaderValue
153
- * @param string $userLocale
154
- * @param string $host
155
- * @param string $path
156
- * @param array|null $params
157
- *
158
- * @return Dropbox_HttpResponse
159
- *
160
- * @throws Dropbox_Exception
161
- */
162
- static function doPostWithSpecificAuth($clientIdentifier, $authHeaderValue, $userLocale, $host, $path, $params = null)
163
- {
164
- Dropbox_Checker::argStringNonEmpty("authHeaderValue", $authHeaderValue);
165
-
166
- $url = self::buildUri($host, $path);
167
-
168
- if ($params === null) $params = array();
169
- $params['locale'] = $userLocale;
170
-
171
- $curl = self::mkCurlWithAuth($clientIdentifier, $url, $authHeaderValue);
172
- $curl->set(CURLOPT_POST, true);
173
- $curl->set(CURLOPT_POSTFIELDS, self::buildPostBody($params));
174
-
175
- $curl->set(CURLOPT_RETURNTRANSFER, true);
176
- return $curl->exec();
177
- }
178
-
179
- /**
180
- * @param string $clientIdentifier
181
- * @param string $accessToken
182
- * @param string $userLocale
183
- * @param string $host
184
- * @param string $path
185
- * @param array|null $params
186
- *
187
- * @return Dropbox_HttpResponse
188
- *
189
- * @throws Dropbox_Exception
190
- */
191
- static function doGet($clientIdentifier, $accessToken, $userLocale, $host, $path, $params = null)
192
- {
193
- Dropbox_Checker::argStringNonEmpty("accessToken", $accessToken);
194
-
195
- $url = self::buildUrlForGetOrPut($userLocale, $host, $path, $params);
196
-
197
- $curl = self::mkCurlWithOAuth($clientIdentifier, $url, $accessToken);
198
- $curl->set(CURLOPT_HTTPGET, true);
199
- $curl->set(CURLOPT_RETURNTRANSFER, true);
200
-
201
- return $curl->exec();
202
- }
203
-
204
- /**
205
- * @param string $responseBody
206
- * @return mixed
207
- * @throws Dropbox_Exception_BadResponse
208
- */
209
- static function parseResponseJson($responseBody)
210
- {
211
- $obj = json_decode($responseBody, TRUE);
212
- if ($obj === null) {
213
- throw new Dropbox_Exception_BadResponse("Got bad JSON from server: $responseBody");
214
- }
215
- return $obj;
216
- }
217
-
218
- /**
219
- * @param Dropbox_HttpResponse $httpResponse
220
- *
221
- * @return Dropbox_Exception
222
- */
223
- static function unexpectedStatus($httpResponse)
224
- {
225
- $sc = $httpResponse->statusCode;
226
-
227
- $message = "HTTP status $sc";
228
- if (is_string($httpResponse->body)) {
229
- if (($info = json_decode($httpResponse->body, true)) && isset($info['error'])) {
230
- $message .= ' '.$info['error'];
231
- } else {
232
- $message .= "\n".$httpResponse->body;
233
- }
234
- }
235
-
236
- if ($sc === 400) return new Dropbox_Exception_BadRequest($message);
237
- if ($sc === 401) return new Dropbox_Exception_InvalidAccessToken($message);
238
- if ($sc === 500 || $sc === 502) return new Dropbox_Exception_ServerError($message);
239
- if ($sc === 503) return new Dropbox_Exception_RetryLater($message);
240
-
241
- return new Dropbox_Exception_BadResponseCode("Unexpected $message", $sc);
242
- }
243
-
244
- /**
245
- * @param int $maxRetries
246
- * The number of times to retry it the action if it fails with one of the transient
247
- * API errors. A value of 1 means we'll try the action once and if it fails, we
248
- * will retry once.
249
- *
250
- * @param callable $action
251
- * The the action you want to retry.
252
- *
253
- * @return mixed
254
- * Whatever is returned by the $action callable.
255
- */
256
- static function runWithRetry($maxRetries, Dropbox_Closure_ReRunnableActionInterface $action)
257
- {
258
- Dropbox_Checker::argNat("maxRetries", $maxRetries);
259
-
260
- $retryDelay = 1;
261
- $numRetries = 0;
262
- while (true) {
263
- try {
264
- return $action->run();
265
- }
266
- // These exception types are the ones we think are possibly transient errors.
267
- catch (Dropbox_Exception_NetworkIO $ex) {
268
- $savedEx = $ex;
269
- }
270
- catch (Dropbox_Exception_ServerError $ex) {
271
- $savedEx = $ex;
272
- }
273
- catch (Dropbox_Exception_RetryLater $ex) {
274
- $savedEx = $ex;
275
- }
276
-
277
- // We maxed out our retries. Propagate the last exception we got.
278
- if ($numRetries >= $maxRetries) throw $savedEx;
279
-
280
- $numRetries++;
281
- sleep($retryDelay);
282
- $retryDelay *= 2; // Exponential back-off.
283
- }
284
- throw new RuntimeException("unreachable");
285
- }
286
-
287
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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 CHANGED
@@ -1,110 +1,112 @@
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
- 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
- return false;
35
- }
36
- else if ($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
- return false;
47
- }
48
- else {
49
- return true;
50
- }
51
- }
52
-
53
- 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
- return $anyFailed;
70
- }
71
-
72
- static function testPinnedCert()
73
- {
74
- }
75
-
76
- static function testAllowed($url)
77
- {
78
- $curl = Dropbox_RequestUtil::mkCurl("test-ssl", $url);
79
- $curl->set(CURLOPT_RETURNTRANSFER, true);
80
- $curl->exec();
81
- return true;
82
- }
83
-
84
- static function testUntrustedCert($url)
85
- {
86
- return self::testDisallowed($url, 'Error executing HTTP request: SSL certificate problem, verify that the CA cert is OK');
87
- }
88
-
89
- static function testHostnameMismatch($url)
90
- {
91
- return self::testDisallowed($url, 'Error executing HTTP request: SSL certificate problem: Invalid certificate chain');
92
- }
93
-
94
- static function testDisallowed($url, $expectedExceptionMessage)
95
- {
96
- $curl = Dropbox_RequestUtil::mkCurl("test-ssl", $url);
97
- $curl->set(CURLOPT_RETURNTRANSFER, true);
98
- try {
99
- $curl->exec();
100
- }
101
- catch (Dropbox_Exception_NetworkIO $ex) {
102
- if (strpos($ex->getMessage(), $expectedExceptionMessage) == 0) {
103
- return true;
104
- } else {
105
- throw $ex;
106
- }
107
- }
108
- return false;
109
- }
110
- }
 
 
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 CHANGED
@@ -1,64 +1,71 @@
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
- * @return bool
19
- */
20
- static function stringEquals($a, $b)
21
- {
22
- // Be strict with arguments. PHP's liberal types could get us pwned.
23
- if (func_num_args() !== 2) {
24
- throw new InvalidArgumentException("Expecting 2 args, got ".func_num_args().".");
25
- }
26
- Dropbox_Checker::argString("a", $a);
27
- Dropbox_Checker::argString("b", $b);
28
-
29
- if (strlen($a) !== strlen($b)) return false;
30
- $result = 0;
31
- for ($i = 0; $i < strlen($a); $i++) {
32
- $result |= ord($a[$i]) ^ ord($b[$i]);
33
- }
34
- return $result === 0;
35
- }
36
-
37
- /**
38
- * Returns cryptographically strong secure random bytes (as a PHP string).
39
- *
40
- * @param int $numBytes
41
- * The number of bytes of random data to return.
42
- *
43
- * @return string
44
- */
45
- static function getRandomBytes($numBytes)
46
- {
47
- Dropbox_Checker::argIntPositive("numBytes", $numBytes);
48
-
49
- // openssl_random_pseudo_bytes had some issues prior to PHP 5.3.4
50
- if (function_exists('openssl_random_pseudo_bytes')
51
- && version_compare(PHP_VERSION, '5.3.4') >= 0) {
52
- $s = openssl_random_pseudo_bytes($numBytes, $isCryptoStrong);
53
- if ($isCryptoStrong) return $s;
54
- }
55
-
56
- if (function_exists('mcrypt_create_iv')) {
57
- return mcrypt_create_iv($numBytes);
58
- }
59
-
60
- // Hopefully the above two options cover all our users. But if not, there are
61
- // other platform-specific options we could add.
62
- throw new Exception("no suitable random number source available");
63
- }
64
- }
 
 
 
 
 
 
 
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 CHANGED
@@ -1,15 +1,15 @@
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
- function __construct($message, $cause = null)
12
- {
13
- parent::__construct($message, 0, $cause);
14
- }
15
- }
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 CHANGED
@@ -1,60 +1,60 @@
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
- function get();
48
-
49
- /**
50
- * Set the entry to the given value.
51
- *
52
- * @param string $value
53
- */
54
- function set($value);
55
-
56
- /**
57
- * Remove the value.
58
- */
59
- function clear();
60
- }
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 CHANGED
@@ -1,274 +1,281 @@
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
- function getRedirectUri() { return $this->redirectUri; }
77
-
78
- /** @var string */
79
- private $redirectUri;
80
-
81
- /**
82
- * A object that lets us save CSRF token string to the user's session. If you're using the
83
- * standard PHP <code>$_SESSION</code>, you can pass in something like
84
- * <code>new ArrayEntryStore($_SESSION, 'dropbox-auth-csrf-token')</code>.
85
- *
86
- * If you're not using $_SESSION, you might have to create your own class that provides
87
- * the same <code>get()</code>/<code>set()</code>/<code>clear()</code> methods as
88
- * {@link ArrayEntryStore}.
89
- *
90
- * @return Dropbox_ValueStore
91
- */
92
- function getCsrfTokenStore() { return $this->csrfTokenStore; }
93
-
94
- /** @var object */
95
- private $csrfTokenStore;
96
-
97
- /**
98
- * Constructor.
99
- *
100
- * @param Dropbox_AppInfo $appInfo
101
- * See {@link getAppInfo()}
102
- * @param string $clientIdentifier
103
- * See {@link getClientIdentifier()}
104
- * @param null|string $redirectUri
105
- * See {@link getRedirectUri()}
106
- * @param null|Dropbox_ValueStore $csrfTokenStore
107
- * See {@link getCsrfTokenStore()}
108
- * @param null|string $userLocale
109
- * See {@link getUserLocale()}
110
- */
111
- function __construct($appInfo, $clientIdentifier, $redirectUri, $csrfTokenStore, $userLocale = null)
112
- {
113
- parent::__construct($appInfo, $clientIdentifier, $userLocale);
114
-
115
- Dropbox_Checker::argStringNonEmpty("redirectUri", $redirectUri);
116
-
117
- $this->csrfTokenStore = $csrfTokenStore;
118
- $this->redirectUri = $redirectUri;
119
- }
120
-
121
- /**
122
- * Starts the OAuth 2 authorization process, which involves redirecting the user to the
123
- * returned authorization URL (a URL on the Dropbox website). When the user then
124
- * either approves or denies your app access, Dropbox will redirect them to the
125
- * <code>$redirectUri</code> given to constructor, at which point you should
126
- * call {@link finish()} to complete the authorization process.
127
- *
128
- * This function will also save a CSRF token using the <code>$csrfTokenStore</code> given to
129
- * the constructor. This CSRF token will be checked on {@link finish()} to prevent
130
- * request forgery.
131
- *
132
- * See <a href="https://www.dropbox.com/developers/core/docs#oa2-authorize">/oauth2/authorize</a>.
133
- *
134
- * @param string|null $urlState
135
- * Any data you would like to keep in the URL through the authorization process.
136
- * This exact state will be returned to you by {@link finish()}.
137
- *
138
- * @return array
139
- * The URL to redirect the user to.
140
- *
141
- * @throws Dropbox_Exception
142
- */
143
- function start($urlState = null)
144
- {
145
- Dropbox_Checker::argStringOrNull("urlState", $urlState);
146
-
147
- $csrfToken = self::encodeCsrfToken(Dropbox_Security::getRandomBytes(16));
148
- $state = $csrfToken;
149
- if ($urlState !== null) {
150
- $state .= "|";
151
- $state .= $urlState;
152
- }
153
- $this->csrfTokenStore->set($csrfToken);
154
-
155
- return $this->_getAuthorizeUrl($this->redirectUri, $state);
156
- }
157
-
158
- private static function encodeCsrfToken($string)
159
- {
160
- return strtr(base64_encode($string), '+/', '-_');
161
- }
162
-
163
- /**
164
- * Call this after the user has visited the authorize URL ({@link start()}), approved your app,
165
- * and was redirected to your redirect URI.
166
- *
167
- * See <a href="https://www.dropbox.com/developers/core/docs#oa2-token">/oauth2/token</a>.
168
- *
169
- * @param array $queryParams
170
- * The query parameters on the GET request to your redirect URI.
171
- *
172
- * @return array
173
- * A <code>list(string $accessToken, string $userId, string $urlState)</code>, where
174
- * <code>$accessToken</code> can be used to construct a {@link Client}, <code>$userId</code>
175
- * is the user ID of the user's Dropbox account, and <code>$urlState</code> is the
176
- * value you originally passed in to {@link start()}.
177
- *
178
- * @throws Dropbox_Exception
179
- * Thrown if there's an error getting the access token from Dropbox.
180
- * @throws Dropbox_WebAuthException_BadRequest
181
- * @throws Dropbox_WebAuthException_BadState
182
- * @throws Dropbox_WebAuthException_Csrf
183
- * @throws Dropbox_WebAuthException_NotApproved
184
- * @throws Dropbox_WebAuthException_Provider
185
- *
186
- *
187
- */
188
- function finish($queryParams)
189
- {
190
- Dropbox_Checker::argArray("queryParams", $queryParams);
191
-
192
- $csrfTokenFromSession = $this->csrfTokenStore->get();
193
- Dropbox_Checker::argStringOrNull("this->csrfTokenStore->get()", $csrfTokenFromSession);
194
-
195
- // Check well-formedness of request.
196
-
197
- if (!isset($queryParams['state'])) {
198
- throw new Dropbox_WebAuthException_BadRequest("Missing query parameter 'state'.");
199
- }
200
- $state = $queryParams['state'];
201
- Dropbox_Checker::argString("queryParams['state']", $state);
202
-
203
- $error = null;
204
- $errorDescription = null;
205
- if (isset($queryParams['error'])) {
206
- $error = $queryParams['error'];
207
- Dropbox_Checker::argString("queryParams['error']", $error);
208
- if (isset($queryParams['error_description'])) {
209
- $errorDescription = $queryParams['error_description'];
210
- Dropbox_Checker::argString("queryParams['error_description']", $errorDescription);
211
- }
212
- }
213
-
214
- $code = null;
215
- if (isset($queryParams['code'])) {
216
- $code = $queryParams['code'];
217
- Dropbox_Checker::argString("queryParams['code']", $code);
218
- }
219
-
220
- if ($code !== null && $error !== null) {
221
- throw new Dropbox_WebAuthException_BadRequest("Query parameters 'code' and 'error' are both set;".
222
- " only one must be set.");
223
- }
224
- if ($code === null && $error === null) {
225
- throw new Dropbox_WebAuthException_BadRequest("Neither query parameter 'code' or 'error' is set.");
226
- }
227
-
228
- // Check CSRF token
229
-
230
- if ($csrfTokenFromSession === null) {
231
- throw new Dropbox_WebAuthException_BadState();
232
- }
233
-
234
- $splitPos = strpos($state, "|");
235
- if ($splitPos === false) {
236
- $givenCsrfToken = $state;
237
- $urlState = null;
238
- } else {
239
- $givenCsrfToken = substr($state, 0, $splitPos);
240
- $urlState = substr($state, $splitPos + 1);
241
- }
242
- if (!Dropbox_Security::stringEquals($csrfTokenFromSession, $givenCsrfToken)) {
243
- throw new Dropbox_WebAuthException_Csrf("Expected ".Dropbox_Client::q($csrfTokenFromSession).
244
- ", got ".Dropbox_Client::q($givenCsrfToken).".");
245
- }
246
- $this->csrfTokenStore->clear();
247
-
248
- // Check for error identifier
249
-
250
- if ($error !== null) {
251
- if ($error === 'access_denied') {
252
- // When the user clicks "Deny".
253
- if ($errorDescription === null) {
254
- throw new Dropbox_WebAuthException_NotApproved("No additional description from Dropbox.");
255
- } else {
256
- throw new Dropbox_WebAuthException_NotApproved("Additional description from Dropbox: $errorDescription");
257
- }
258
- } else {
259
- // All other errors.
260
- $fullMessage = $error;
261
- if ($errorDescription !== null) {
262
- $fullMessage .= ": ";
263
- $fullMessage .= $errorDescription;
264
- }
265
- throw new Dropbox_WebAuthException_Provider($fullMessage);
266
- }
267
- }
268
-
269
- // If everything went ok, make the network call to get an access token.
270
-
271
- list($accessToken, $userId) = $this->_finish($code, $this->redirectUri);
272
- return array($accessToken, $userId, $urlState);
273
- }
274
- }
 
 
 
 
 
 
 
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 CHANGED
@@ -1,62 +1,64 @@
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) throw Dropbox_RequestUtil::unexpectedStatus($response);
39
-
40
- $parts = Dropbox_RequestUtil::parseResponseJson($response->body);
41
-
42
- if (!array_key_exists('token_type', $parts) or !is_string($parts['token_type'])) {
43
- throw new Dropbox_Exception_BadResponse("Missing \"token_type\" field.");
44
- }
45
- $tokenType = $parts['token_type'];
46
- if (!array_key_exists('access_token', $parts) or !is_string($parts['access_token'])) {
47
- throw new Dropbox_Exception_BadResponse("Missing \"access_token\" field.");
48
- }
49
- $accessToken = $parts['access_token'];
50
- if (!array_key_exists('uid', $parts) or !is_string($parts['uid'])) {
51
- throw new Dropbox_Exception_BadResponse("Missing \"uid\" string field.");
52
- }
53
- $userId = $parts['uid'];
54
-
55
- if ($tokenType !== "Bearer" && $tokenType !== "bearer") {
56
- throw new Dropbox_Exception_BadResponse("Unknown \"token_type\"; expecting \"Bearer\", got "
57
- .Dropbox_Client::q($tokenType));
58
- }
59
-
60
- return array($accessToken, $userId);
61
- }
62
- }
 
 
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 CHANGED
@@ -1,19 +1,19 @@
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
- function __construct($message)
16
- {
17
- parent::__construct($message);
18
- }
19
- }
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 CHANGED
@@ -1,18 +1,18 @@
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
- function __construct()
15
- {
16
- parent::__construct("Missing CSRF token in session.");
17
- }
18
- }
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 CHANGED
@@ -1,20 +1,20 @@
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
- function __construct($message)
17
- {
18
- parent::__construct($message);
19
- }
20
- }
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 CHANGED
@@ -1,17 +1,17 @@
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
- function __construct($message)
14
- {
15
- parent::__construct($message);
16
- }
17
- }
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 CHANGED
@@ -1,17 +1,17 @@
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
- function __construct($message)
14
- {
15
- parent::__construct($message);
16
- }
17
- }
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 CHANGED
@@ -1,82 +1,82 @@
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
- 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
- function finish($code)
77
- {
78
- Dropbox_Checker::argStringNonEmpty("code", $code);
79
- return $this->_finish($code, null);
80
- }
81
- }
82
-
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 CHANGED
@@ -1,115 +1,126 @@
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
- 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
- static function add()
45
- {
46
- if (self::$addInstance === null) {
47
- self::$addInstance = new Dropbox_WriteMode(array("overwrite" => "false"));
48
- }
49
- return self::$addInstance;
50
- }
51
- private static $addInstance = null;
52
-
53
- /**
54
- * Returns a {@link WriteMode} for forcing a file to be at a certain path. If there's already
55
- * a file at that path, the existing file will be overwritten. If there's a folder at that
56
- * path, however, it will not be overwritten and the API call will fail.
57
- *
58
- * @return Dropbox_WriteMode
59
- */
60
- static function force()
61
- {
62
- if (self::$forceInstance === null) {
63
- self::$forceInstance = new Dropbox_WriteMode(array("overwrite" => "true"));
64
- }
65
- return self::$forceInstance;
66
- }
67
- private static $forceInstance = null;
68
-
69
- /**
70
- * Returns a {@link WriteMode} for updating an existing file. This is useful for when you
71
- * have downloaded a file, made modifications, and want to save your modifications back to
72
- * Dropbox. You need to specify the revision of the copy of the file you downloaded (it's
73
- * the "rev" parameter of the file's metadata object).
74
- *
75
- * If, when you attempt to save, the revision of the file currently on Dropbox matches
76
- * $revToReplace, the file on Dropbox will be overwritten with the new contents you provide.
77
- *
78
- * If the revision of the file currently on Dropbox doesn't match $revToReplace, Dropbox will
79
- * create a new file and save your contents to that file. For example, if the original file
80
- * path is "/Notes/Groceries.txt", the new file's path might be
81
- * "/Notes/Groceries (conflicted copy).txt".
82
- *
83
- * You can determine whether your file was renamed by checking the "path" field of the
84
- * metadata object returned by the API call.
85
- *
86
- * @param string $revToReplace
87
- * @return Dropbox_WriteMode
88
- */
89
- static function update($revToReplace)
90
- {
91
- return new Dropbox_WriteMode(array("parent_rev" => $revToReplace));
92
- }
93
-
94
- /**
95
- * Check that a function argument is of type <code>WriteMode</code>.
96
- *
97
- * @internal
98
- */
99
- static function checkArg($argName, $argValue)
100
- {
101
- if (!($argValue instanceof self)) Dropbox_Checker::throwError($argName, $argValue, __CLASS__);
102
- }
103
-
104
- /**
105
- * Check that a function argument is either <code>null</code> or of type
106
- * <code>WriteMode</code>.
107
- *
108
- * @internal
109
- */
110
- static function checkArgOrNull($argName, $argValue)
111
- {
112
- if ($argValue === null) return;
113
- if (!($argValue instanceof self)) Dropbox_Checker::throwError($argName, $argValue, __CLASS__);
114
- }
115
- }
 
 
 
 
 
 
 
 
 
 
 
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/Gelf/Message.php CHANGED
@@ -1,294 +1,294 @@
1
- <?php
2
-
3
- class Gelf_Message
4
- {
5
- /**#@+
6
- * Log levels according to syslog priority
7
- */
8
- const EMERGENCY = 0;
9
- const ALERT = 1;
10
- const CRITICAL = 2;
11
- const ERROR = 3;
12
- const WARNING = 4;
13
- const NOTICE = 5;
14
- const INFO = 6;
15
- const DEBUG = 7;
16
- /**#@-*/
17
-
18
- /**
19
- * @var string
20
- */
21
- private $version = null;
22
-
23
- /**
24
- * @var integer
25
- */
26
- private $timestamp = null;
27
-
28
- /**
29
- * @var string
30
- */
31
- private $shortMessage = null;
32
-
33
- /**
34
- * @var string
35
- */
36
- private $fullMessage = null;
37
-
38
- /**
39
- * @var string
40
- */
41
- private $facility = null;
42
-
43
- /**
44
- * @var string
45
- */
46
- private $host = null;
47
-
48
- /**
49
- * @var integer
50
- */
51
- private $level = null;
52
-
53
- /**
54
- * @var string
55
- */
56
- private $file = null;
57
-
58
- /**
59
- * @var integer
60
- */
61
- private $line = null;
62
-
63
- /**
64
- * @var array
65
- */
66
- private $data = array();
67
-
68
- /**
69
- * @param string $version
70
- *
71
- * @return Gelf_Message
72
- */
73
- public function setVersion($version)
74
- {
75
- $this->version = $version;
76
-
77
- return $this;
78
- }
79
-
80
- /**
81
- * @return string
82
- */
83
- public function getVersion()
84
- {
85
- return $this->version;
86
- }
87
-
88
- /**
89
- * @param integer $timestamp
90
- *
91
- * @return Gelf_Message
92
- */
93
- public function setTimestamp($timestamp)
94
- {
95
- $this->timestamp = $timestamp;
96
-
97
- return $this;
98
- }
99
-
100
- /**
101
- * @return integer
102
- */
103
- public function getTimestamp()
104
- {
105
- return $this->timestamp;
106
- }
107
-
108
- /**
109
- * @param string $shortMessage
110
- *
111
- * @return Gelf_Message
112
- */
113
- public function setShortMessage($shortMessage)
114
- {
115
- $this->shortMessage = $shortMessage;
116
-
117
- return $this;
118
- }
119
-
120
- /**
121
- * @return string
122
- */
123
- public function getShortMessage()
124
- {
125
- return $this->shortMessage;
126
- }
127
-
128
- /**
129
- * @param string $fullMessage
130
- *
131
- * @return Gelf_Message
132
- */
133
- public function setFullMessage($fullMessage)
134
- {
135
- $this->fullMessage = $fullMessage;
136
-
137
- return $this;
138
- }
139
-
140
- /**
141
- * @return string
142
- */
143
- public function getFullMessage()
144
- {
145
- return $this->fullMessage;
146
- }
147
-
148
- /**
149
- * @param string $facility
150
- *
151
- * @return Gelf_Message
152
- */
153
- public function setFacility($facility)
154
- {
155
- $this->facility = $facility;
156
-
157
- return $this;
158
- }
159
-
160
- /**
161
- * @return string
162
- */
163
- public function getFacility()
164
- {
165
- return $this->facility;
166
- }
167
-
168
- /**
169
- * @param string $host
170
- *
171
- * @return Gelf_Message
172
- */
173
- public function setHost($host)
174
- {
175
- $this->host = $host;
176
-
177
- return $this;
178
- }
179
-
180
- /**
181
- * @return string
182
- */
183
- public function getHost()
184
- {
185
- return $this->host;
186
- }
187
-
188
- /**
189
- * @param integer $level
190
- *
191
- * @return Gelf_Message
192
- */
193
- public function setLevel($level)
194
- {
195
- $this->level = $level;
196
-
197
- return $this;
198
- }
199
-
200
- /**
201
- * @return integer
202
- */
203
- public function getLevel()
204
- {
205
- return $this->level;
206
- }
207
-
208
- /**
209
- * @param string $file
210
- *
211
- * @return Gelf_Message
212
- */
213
- public function setFile($file)
214
- {
215
- $this->file = $file;
216
-
217
- return $this;
218
- }
219
-
220
- /**
221
- * @return string
222
- */
223
- public function getFile()
224
- {
225
- return $this->file;
226
- }
227
-
228
- /**
229
- * @param integer $line
230
- *
231
- * @return Gelf_Message
232
- */
233
- public function setLine($line)
234
- {
235
- $this->line = $line;
236
-
237
- return $this;
238
- }
239
-
240
- /**
241
- * @return integer
242
- */
243
- public function getLine()
244
- {
245
- return $this->line;
246
- }
247
-
248
- /**
249
- * @param string $key
250
- * @param mixed $value
251
- *
252
- * @return Gelf_Message
253
- */
254
- public function setAdditional($key, $value)
255
- {
256
- $this->data["_".trim($key)] = $value;
257
-
258
- return $this;
259
- }
260
-
261
- /**
262
- * @return mixed
263
- */
264
- public function getAdditional($key)
265
- {
266
- $additional_key = "_".trim($key);
267
-
268
- return isset($this->data[$additional_key]) ? $this->data[$additional_key] : null;
269
- }
270
-
271
- /**
272
- * @return array
273
- */
274
- public function toArray()
275
- {
276
- $messageAsArray = array(
277
- 'version' => $this->getVersion(),
278
- 'timestamp' => $this->getTimestamp(),
279
- 'short_message' => $this->getShortMessage(),
280
- 'full_message' => $this->getFullMessage(),
281
- 'facility' => $this->getFacility(),
282
- 'host' => $this->getHost(),
283
- 'level' => $this->getLevel(),
284
- 'file' => $this->getFile(),
285
- 'line' => $this->getLine(),
286
- );
287
-
288
- foreach ($this->data as $key => $value) {
289
- $messageAsArray[$key] = $value;
290
- }
291
-
292
- return $messageAsArray;
293
- }
294
- }
1
+ <?php
2
+
3
+ class Gelf_Message
4
+ {
5
+ /**#@+
6
+ * Log levels according to syslog priority
7
+ */
8
+ const EMERGENCY = 0;
9
+ const ALERT = 1;
10
+ const CRITICAL = 2;
11
+ const ERROR = 3;
12
+ const WARNING = 4;
13
+ const NOTICE = 5;
14
+ const INFO = 6;
15
+ const DEBUG = 7;
16
+ /**#@-*/
17
+
18
+ /**
19
+ * @var string
20
+ */
21
+ private $version = null;
22
+
23
+ /**
24
+ * @var integer
25
+ */
26
+ private $timestamp = null;
27
+
28
+ /**
29
+ * @var string
30
+ */
31
+ private $shortMessage = null;
32
+
33
+ /**
34
+ * @var string
35
+ */
36
+ private $fullMessage = null;
37
+
38
+ /**
39
+ * @var string
40
+ */
41
+ private $facility = null;
42
+
43
+ /**
44
+ * @var string
45
+ */
46
+ private $host = null;
47
+
48
+ /**
49
+ * @var integer
50
+ */
51
+ private $level = null;
52
+
53
+ /**
54
+ * @var string
55
+ */
56
+ private $file = null;
57
+
58
+ /**
59
+ * @var integer
60
+ */
61
+ private $line = null;
62
+
63
+ /**
64
+ * @var array
65
+ */
66
+ private $data = array();
67
+
68
+ /**
69
+ * @param string $version
70
+ *
71
+ * @return Gelf_Message
72
+ */
73
+ public function setVersion($version)
74
+ {
75
+ $this->version = $version;
76
+
77
+ return $this;
78
+ }
79
+
80
+ /**
81
+ * @return string
82
+ */
83
+ public function getVersion()
84
+ {
85
+ return $this->version;
86
+ }
87
+
88
+ /**
89
+ * @param integer $timestamp
90
+ *
91
+ * @return Gelf_Message
92
+ */
93
+ public function setTimestamp($timestamp)
94
+ {
95
+ $this->timestamp = $timestamp;
96
+
97
+ return $this;
98
+ }
99
+
100
+ /**
101
+ * @return integer
102
+ */
103
+ public function getTimestamp()
104
+ {
105
+ return $this->timestamp;
106
+ }
107
+
108
+ /**
109
+ * @param string $shortMessage
110
+ *
111
+ * @return Gelf_Message
112
+ */
113
+ public function setShortMessage($shortMessage)
114
+ {
115
+ $this->shortMessage = $shortMessage;
116
+
117
+ return $this;
118
+ }
119
+
120
+ /**
121
+ * @return string
122
+ */
123
+ public function getShortMessage()
124
+ {
125
+ return $this->shortMessage;
126
+ }
127
+
128
+ /**
129
+ * @param string $fullMessage
130
+ *
131
+ * @return Gelf_Message
132
+ */
133
+ public function setFullMessage($fullMessage)
134
+ {
135
+ $this->fullMessage = $fullMessage;
136
+
137
+ return $this;
138
+ }
139
+
140
+ /**
141
+ * @return string
142
+ */
143
+ public function getFullMessage()
144
+ {
145
+ return $this->fullMessage;
146
+ }
147
+
148
+ /**
149
+ * @param string $facility
150
+ *
151
+ * @return Gelf_Message
152
+ */
153
+ public function setFacility($facility)
154
+ {
155
+ $this->facility = $facility;
156
+
157
+ return $this;
158
+ }
159
+
160
+ /**
161
+ * @return string
162
+ */
163
+ public function getFacility()
164
+ {
165
+ return $this->facility;
166
+ }
167
+
168
+ /**
169
+ * @param string $host
170
+ *
171
+ * @return Gelf_Message
172
+ */
173
+ public function setHost($host)
174
+ {
175
+ $this->host = $host;
176
+
177
+ return $this;
178
+ }
179
+
180
+ /**
181
+ * @return string
182
+ */
183
+ public function getHost()
184
+ {
185
+ return $this->host;
186
+ }
187
+
188
+ /**
189
+ * @param integer $level
190
+ *
191
+ * @return Gelf_Message
192
+ */
193
+ public function setLevel($level)
194
+ {
195
+ $this->level = $level;
196
+
197
+ return $this;
198
+ }
199
+
200
+ /**
201
+ * @return integer
202
+ */
203
+ public function getLevel()
204
+ {
205
+ return $this->level;
206
+ }
207
+
208
+ /**
209
+ * @param string $file
210
+ *
211
+ * @return Gelf_Message
212
+ */
213
+ public function setFile($file)
214
+ {
215
+ $this->file = $file;
216
+
217
+ return $this;
218
+ }
219
+
220
+ /**
221
+ * @return string
222
+ */
223
+ public function getFile()
224
+ {
225
+ return $this->file;
226
+ }
227
+
228
+ /**
229
+ * @param integer $line
230
+ *
231
+ * @return Gelf_Message
232
+ */
233
+ public function setLine($line)
234
+ {
235
+ $this->line = $line;
236
+
237
+ return $this;
238
+ }
239
+
240
+ /**
241
+ * @return integer
242
+ */
243
+ public function getLine()
244
+ {
245
+ return $this->line;
246
+ }
247
+
248
+ /**
249
+ * @param string $key
250
+ * @param mixed $value
251
+ *
252
+ * @return Gelf_Message
253
+ */
254
+ public function setAdditional($key, $value)
255
+ {
256
+ $this->data["_".trim($key)] = $value;
257
+
258
+ return $this;
259
+ }
260
+
261
+ /**
262
+ * @return mixed
263
+ */
264
+ public function getAdditional($key)
265
+ {
266
+ $additional_key = "_".trim($key);
267
+
268
+ return isset($this->data[$additional_key]) ? $this->data[$additional_key] : null;
269
+ }
270
+
271
+ /**
272
+ * @return array
273
+ */
274
+ public function toArray()
275
+ {
276
+ $messageAsArray = array(
277
+ 'version' => $this->getVersion(),
278
+ 'timestamp' => $this->getTimestamp(),
279
+ 'short_message' => $this->getShortMessage(),
280
+ 'full_message' => $this->getFullMessage(),
281
+ 'facility' => $this->getFacility(),
282
+ 'host' => $this->getHost(),
283
+ 'level' => $this->getLevel(),
284
+ 'file' => $this->getFile(),
285
+ 'line' => $this->getLine(),
286
+ );
287
+
288
+ foreach ($this->data as $key => $value) {
289
+ $messageAsArray[$key] = $value;
290
+ }
291
+
292
+ return $messageAsArray;
293
+ }
294
+ }
src/Gelf/Publisher.php CHANGED
@@ -1,250 +1,250 @@
1
- <?php
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
- *
79
- * @param Gelf_Message $message
80
- *
81
- * @return boolean
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(
88
- 'Missing required data parameter: "version", "short_message" and "host" are required.'
89
- );
90
- }
91
-
92
- // Set Graylog protocol version
93
- $message->setVersion(self::GRAYLOG2_PROTOCOL_VERSION);
94
-
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,
114
- $messageId,
115
- $messageChunk,
116
- $messageChunkIndex,
117
- $messageChunksCount
118
- );
119
-
120
- if (false === $bytesWritten) {
121
- // Abort due to write error
122
- return false;
123
- }
124
- }
125
- } else {
126
- // A single write is enough to get the message published
127
- if (false === $this->writeMessageToSocket($socket, $preparedMessage)) {
128
- // Abort due to write error
129
- return false;
130
- }
131
- }
132
-
133
- // This increases stability a lot if messages are sent in a loop
134
- // A value of 20 means 0.02 ms
135
- usleep(20);
136
-
137
- // Message successful sent
138
- return true;
139
- }
140
-
141
- /**
142
- * @param Gelf_Message $message
143
- *
144
- * @return string
145
- */
146
- protected function getPreparedMessage(Gelf_Message $message)
147
- {
148
- return gzcompress(json_encode($message->toArray()));
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;
163
- }
164
-
165
- /**
166
- * @param string $preparedMessage
167
- *
168
- * @return boolean
169
- */
170
- protected function isMessageSizeGreaterChunkSize($preparedMessage)
171
- {
172
- return (strlen($preparedMessage) > $this->chunkSize);
173
- }
174
-
175
- /**
176
- * @return float
177
- */
178
- protected function getMessageId()
179
- {
180
- return (float) (microtime(true).mt_rand(0, 10000));
181
- }
182
-
183
- /**
184
- * @param string $preparedMessage
185
- *
186
- * @return array
187
- */
188
- protected function getMessageChunks($preparedMessage)
189
- {
190
- return str_split($preparedMessage, $this->chunkSize);
191
- }
192
-
193
- /**
194
- * @param float $messageId
195
- * @param string $data
196
- * @param integer $sequence
197
- * @param integer $sequenceSize
198
- *
199
- * @throws InvalidArgumentException
200
- * @return string
201
- */
202
- protected function prependChunkInformation($messageId, $data, $sequence, $sequenceSize)
203
- {
204
- if (!is_string($data) || $data === '') {
205
- throw new InvalidArgumentException('Data must be a string and not be empty.');
206
- }
207
-
208
- if (!is_integer($sequence) || !is_integer($sequenceSize)) {
209
- throw new InvalidArgumentException('Sequence number and size must be integer.');
210
- }
211
-
212
- if ($sequenceSize <= 0) {
213
- throw new InvalidArgumentException('Sequence size must be greater than 0.');
214
- }
215
-
216
- if ($sequence > $sequenceSize) {
217
- throw new InvalidArgumentException('Sequence size must be greater than sequence number.');
218
- }
219
-
220
- return pack('CC', 30, 15).substr(md5($messageId, true), 0, 8).pack('CC', $sequence, $sequenceSize).$data;
221
- }
222
-
223
- /**
224
- * @param resource $socket
225
- * @param float $messageId
226
- * @param string $messageChunk
227
- * @param integer $messageChunkIndex
228
- * @param integer $messageChunksCount
229
- *
230
- * @return integer|boolean
231
- */
232
- protected function writeMessageChunkToSocket($socket, $messageId, $messageChunk, $messageChunkIndex, $messageChunksCount)
233
- {
234
- return fwrite(
235
- $socket,
236
- $this->prependChunkInformation($messageId, $messageChunk, $messageChunkIndex, $messageChunksCount)
237
- );
238
- }
239
-
240
- /**
241
- * @param resource $socket
242
- * @param string $preparedMessage
243
- *
244
- * @return integer|boolean
245
- */
246
- protected function writeMessageToSocket($socket, $preparedMessage)
247
- {
248
- return fwrite($socket, $preparedMessage);
249
- }
250
- }
1
+ <?php
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
+ *
79
+ * @param Gelf_Message $message
80
+ *
81
+ * @return boolean
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(
88
+ 'Missing required data parameter: "version", "short_message" and "host" are required.'
89
+ );
90
+ }
91
+
92
+ // Set Graylog protocol version
93
+ $message->setVersion(self::GRAYLOG2_PROTOCOL_VERSION);
94
+
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,
114
+ $messageId,
115
+ $messageChunk,
116
+ $messageChunkIndex,
117
+ $messageChunksCount
118
+ );
119
+
120
+ if (false === $bytesWritten) {
121
+ // Abort due to write error
122
+ return false;
123
+ }
124
+ }
125
+ } else {
126
+ // A single write is enough to get the message published
127
+ if (false === $this->writeMessageToSocket($socket, $preparedMessage)) {
128
+ // Abort due to write error
129
+ return false;
130
+ }
131
+ }
132
+
133
+ // This increases stability a lot if messages are sent in a loop
134
+ // A value of 20 means 0.02 ms
135
+ usleep(20);
136
+
137
+ // Message successful sent
138
+ return true;
139
+ }
140
+
141
+ /**
142
+ * @param Gelf_Message $message
143
+ *
144
+ * @return string
145
+ */
146
+ protected function getPreparedMessage(Gelf_Message $message)
147
+ {
148
+ return gzcompress(json_encode($message->toArray()));
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;
163
+ }
164
+
165
+ /**
166
+ * @param string $preparedMessage
167
+ *
168
+ * @return boolean
169
+ */
170
+ protected function isMessageSizeGreaterChunkSize($preparedMessage)
171
+ {
172
+ return (strlen($preparedMessage) > $this->chunkSize);
173
+ }
174
+
175
+ /**
176
+ * @return float
177
+ */
178
+ protected function getMessageId()
179
+ {
180
+ return (float) (microtime(true).mt_rand(0, 10000));
181
+ }
182
+
183
+ /**
184
+ * @param string $preparedMessage
185
+ *
186
+ * @return array
187
+ */
188
+ protected function getMessageChunks($preparedMessage)
189
+ {
190
+ return str_split($preparedMessage, $this->chunkSize);
191
+ }
192
+
193
+ /**
194
+ * @param float $messageId
195
+ * @param string $data
196
+ * @param integer $sequence
197
+ * @param integer $sequenceSize
198
+ *
199
+ * @throws InvalidArgumentException
200
+ * @return string
201
+ */
202
+ protected function prependChunkInformation($messageId, $data, $sequence, $sequenceSize)
203
+ {
204
+ if (!is_string($data) || $data === '') {
205
+ throw new InvalidArgumentException('Data must be a string and not be empty.');
206
+ }
207
+
208
+ if (!is_integer($sequence) || !is_integer($sequenceSize)) {
209
+ throw new InvalidArgumentException('Sequence number and size must be integer.');
210
+ }
211
+
212
+ if ($sequenceSize <= 0) {
213
+ throw new InvalidArgumentException('Sequence size must be greater than 0.');
214
+ }
215
+
216
+ if ($sequence > $sequenceSize) {
217
+ throw new InvalidArgumentException('Sequence size must be greater than sequence number.');
218
+ }
219
+
220
+ return pack('CC', 30, 15).substr(md5($messageId, true), 0, 8).pack('CC', $sequence, $sequenceSize).$data;
221
+ }
222
+
223
+ /**
224
+ * @param resource $socket
225
+ * @param float $messageId
226
+ * @param string $messageChunk
227
+ * @param integer $messageChunkIndex
228
+ * @param integer $messageChunksCount
229
+ *
230
+ * @return integer|boolean
231
+ */
232
+ protected function writeMessageChunkToSocket($socket, $messageId, $messageChunk, $messageChunkIndex, $messageChunksCount)
233
+ {
234
+ return fwrite(
235
+ $socket,
236
+ $this->prependChunkInformation($messageId, $messageChunk, $messageChunkIndex, $messageChunksCount)
237
+ );
238
+ }
239
+
240
+ /**
241
+ * @param resource $socket
242
+ * @param string $preparedMessage
243
+ *
244
+ * @return integer|boolean
245
+ */
246
+ protected function writeMessageToSocket($socket, $preparedMessage)
247
+ {
248
+ return fwrite($socket, $preparedMessage);
249
+ }
250
+ }
src/Google/ApiClient.php CHANGED
@@ -15,7 +15,6 @@
15
  * limitations under the License.
16
  */
17
 
18
-
19
  /**
20
  * The Google API Client
21
  * http://code.google.com/p/google-api-php-client/
@@ -25,7 +24,7 @@
25
  */
26
  class Google_ApiClient
27
  {
28
- const LIBVER = "1.0.3-beta";
29
  const USER_AGENT_SUFFIX = "google-api-php-client/";
30
  /**
31
  * @var Google_Auth_Abstract $auth
@@ -69,14 +68,15 @@ class Google_ApiClient
69
  */
70
  public function __construct($config = null)
71
  {
72
- if (! ini_get('date.timezone') &&
73
- function_exists('date_default_timezone_set')) {
 
74
  date_default_timezone_set('UTC');
75
  }
76
 
77
  if (is_string($config) && strlen($config)) {
78
  $config = new Google_Config($config);
79
- } else if ( !($config instanceof Google_Config)) {
80
  $config = new Google_Config();
81
 
82
  if ($this->isAppEngine()) {
@@ -116,11 +116,13 @@ class Google_ApiClient
116
  * Helper wrapped around the OAuth 2.0 implementation.
117
  *
118
  * @param $code string code from accounts.google.com
 
119
  * @return string token
120
  */
121
  public function authenticate($code)
122
  {
123
  $this->authenticated = true;
 
124
  return $this->getAuth()->authenticate($code);
125
  }
126
 
@@ -129,12 +131,13 @@ class Google_ApiClient
129
  * This structure should match the file downloaded from
130
  * the "Download JSON" button on in the Google Developer
131
  * Console.
 
132
  * @param string $json the configuration json
133
  */
134
  public function setAuthConfig($json)
135
  {
136
  $data = json_decode($json);
137
- $key = isset($data->installed) ? 'installed' : 'web';
138
  if (!isset($data->$key)) {
139
  throw new Google_ApiException("Invalid client secret JSON file.");
140
  }
@@ -150,6 +153,7 @@ class Google_ApiClient
150
  * provided. This should match the file downloaded from
151
  * the "Download JSON" button on in the Google Developer
152
  * Console.
 
153
  * @param string $file the file location of the client json
154
  */
155
  public function setAuthConfigFile($file)
@@ -167,15 +171,17 @@ class Google_ApiClient
167
  throw new Google_Auth_Exception("No scopes specified");
168
  }
169
  $scopes = implode(' ', $this->requestedScopes);
 
170
  return $scopes;
171
  }
172
 
173
  /**
174
  * Set the OAuth 2.0 access token using the string that resulted from calling createAuthUrl()
175
  * or Google_ApiClient#getAccessToken().
 
176
  * @param string $accessToken JSON encoded string containing in the following format:
177
- * {"access_token":"TOKEN", "refresh_token":"TOKEN", "token_type":"Bearer",
178
- * "expires_in":3600, "id_token":"TOKEN", "created":1320790426}
179
  */
180
  public function setAccessToken($accessToken)
181
  {
@@ -185,10 +191,9 @@ class Google_ApiClient
185
  $this->getAuth()->setAccessToken($accessToken);
186
  }
187
 
188
-
189
-
190
  /**
191
  * Set the authenticator object
 
192
  * @param Google_Auth_Abstract $auth
193
  */
194
  public function setAuth(Google_Auth_Abstract $auth)
@@ -199,6 +204,7 @@ class Google_ApiClient
199
 
200
  /**
201
  * Set the IO object
 
202
  * @param Google_Io_Abstract $auth
203
  */
204
  public function setIo(Google_Io_Abstract $io)
@@ -209,6 +215,7 @@ class Google_ApiClient
209
 
210
  /**
211
  * Set the Cache object
 
212
  * @param Google_Cache_Abstract $auth
213
  */
214
  public function setCache(Google_Cache_Abstract $cache)
@@ -224,14 +231,15 @@ class Google_ApiClient
224
  public function createAuthUrl()
225
  {
226
  $scopes = $this->prepareScopes();
 
227
  return $this->getAuth()->createAuthUrl($scopes);
228
  }
229
 
230
  /**
231
  * Get the OAuth 2.0 access token.
232
  * @return string $accessToken JSON encoded string in the following format:
233
- * {"access_token":"TOKEN", "refresh_token":"TOKEN", "token_type":"Bearer",
234
- * "expires_in":3600,"id_token":"TOKEN", "created":1320790426}
235
  */
236
  public function getAccessToken()
237
  {
@@ -254,6 +262,7 @@ class Google_ApiClient
254
  /**
255
  * Set OAuth 2.0 "state" parameter to achieve per-request customization.
256
  * @see http://tools.ietf.org/html/draft-ietf-oauth-v2-22#section-3.1.2.2
 
257
  * @param string $state
258
  */
259
  public function setState($state)
@@ -263,8 +272,8 @@ class Google_ApiClient
263
 
264
  /**
265
  * @param string $accessType Possible values for access_type include:
266
- * {@code "offline"} to request offline access from the user.
267
- * {@code "online"} to request online access from the user.
268
  */
269
  public function setAccessType($accessType)
270
  {
@@ -273,8 +282,8 @@ class Google_ApiClient
273
 
274
  /**
275
  * @param string $approvalPrompt Possible values for approval_prompt include:
276
- * {@code "force"} to force the approval UI to appear. (This is the default value)
277
- * {@code "auto"} to request auto-approval when possible.
278
  */
279
  public function setApprovalPrompt($approvalPrompt)
280
  {
@@ -283,6 +292,7 @@ class Google_ApiClient
283
 
284
  /**
285
  * Set the application name, this is included in the User-Agent HTTP header.
 
286
  * @param string $applicationName
287
  */
288
  public function setApplicationName($applicationName)
@@ -292,6 +302,7 @@ class Google_ApiClient
292
 
293
  /**
294
  * Set the OAuth 2.0 Client ID.
 
295
  * @param string $clientId
296
  */
297
  public function setClientId($clientId)
@@ -301,6 +312,7 @@ class Google_ApiClient
301
 
302
  /**
303
  * Set the OAuth 2.0 Client Secret.
 
304
  * @param string $clientSecret
305
  */
306
  public function setClientSecret($clientSecret)
@@ -310,6 +322,7 @@ class Google_ApiClient
310
 
311
  /**
312
  * Set the OAuth 2.0 Redirect URI.
 
313
  * @param string $redirectUri
314
  */
315
  public function setRedirectUri($redirectUri)
@@ -336,6 +349,7 @@ class Google_ApiClient
336
  /**
337
  * Set the developer key to use, these are obtained through the API Console.
338
  * @see http://code.google.com/apis/console-help/#generatingdevkeys
 
339
  * @param string $developerKey
340
  */
341
  public function setDeveloperKey($developerKey)
@@ -345,7 +359,9 @@ class Google_ApiClient
345
 
346
  /**
347
  * Fetches a fresh OAuth 2.0 access token with the given refresh token.
 
348
  * @param string $refreshToken
 
349
  * @return void
350
  */
351
  public function refreshToken($refreshToken)
@@ -357,7 +373,9 @@ class Google_ApiClient
357
  * Revoke an OAuth2 access token or refresh token. This method will revoke the current access
358
  * token, if a token isn't provided.
359
  * @throws Google_Auth_Exception
 
360
  * @param string|null $token The token (access token or a refresh token) that should be revoked.
 
361
  * @return boolean Returns True if the revocation was successful, otherwise False.
362
  */
363
  public function revokeToken($token = null)
@@ -369,9 +387,11 @@ class Google_ApiClient
369
  * Verify an id_token. This method will verify the current id_token, if one
370
  * isn't provided.
371
  * @throws Google_Auth_Exception
 
372
  * @param string|null $token The token (id_token) that should be verified.
 
373
  * @return Google_Auth_LoginTicket Returns an apiLoginTicket if the verification was
374
- * successful.
375
  */
376
  public function verifyIdToken($token = null)
377
  {
@@ -381,22 +401,25 @@ class Google_ApiClient
381
  /**
382
  * Verify a JWT that was signed with your own certificates.
383
  *
384
- * @param $jwt the token
385
- * @param $certs array of certificates
386
  * @param $required_audience the expected consumer of the token
387
  * @param [$issuer] the expected issues, defaults to Google
388
  * @param [$max_expiry] the max lifetime of a token, defaults to MAX_TOKEN_LIFETIME_SECS
 
389
  * @return token information if valid, false if not
390
  */
391
  public function verifySignedJwt($id_token, $cert_location, $audience, $issuer, $max_expiry = null)
392
  {
393
- $auth = new Google_Auth_OAuth2($this);
394
  $certs = $auth->retrieveCertsFromLocation($cert_location);
 
395
  return $auth->verifySignedJwtWithCerts($id_token, $certs, $audience, $issuer, $max_expiry);
396
  }
397
 
398
  /**
399
  * @param Google_Auth_AssertionCredentials $creds
 
400
  * @return void
401
  */
402
  public function setAssertionCredentials(Google_Auth_AssertionCredentials $creds)
@@ -407,8 +430,9 @@ class Google_ApiClient
407
  /**
408
  * Set the scopes to be requested. Must be called before createAuthUrl().
409
  * Will remove any previously configured scopes.
410
- * @param array $scopes, ie: array('https://www.googleapis.com/auth/plus.login',
411
- * 'https://www.googleapis.com/auth/moderator')
 
412
  */
413
  public function setScopes($scopes)
414
  {
@@ -421,13 +445,14 @@ class Google_ApiClient
421
  * Will append any scopes not previously requested to the scope parameter.
422
  * A single string will be treated as a scope to request. An array of strings
423
  * will each be appended.
 
424
  * @param $scope_or_scopes string|array e.g. "profile"
425
  */
426
  public function addScope($scope_or_scopes)
427
  {
428
  if (is_string($scope_or_scopes) && !in_array($scope_or_scopes, $this->requestedScopes)) {
429
  $this->requestedScopes[] = $scope_or_scopes;
430
- } else if (is_array($scope_or_scopes)) {
431
  foreach ($scope_or_scopes as $scope) {
432
  $this->addScope($scope);
433
  }
@@ -449,7 +474,7 @@ class Google_ApiClient
449
  * by making multiple requests in one connection.
450
  *
451
  * @param boolean $useBatch True if the batch support should
452
- * be enabled. Defaults to False.
453
  */
454
  public function setUseBatch($useBatch)
455
  {
@@ -477,16 +502,17 @@ class Google_ApiClient
477
  {
478
  if ($request instanceof Google_Http_Request) {
479
  $request->setUserAgent(
480
- $this->getApplicationName()
481
- . " " . self::USER_AGENT_SUFFIX
482
- . $this->getLibraryVersion()
483
  );
484
  if (!$this->getClassConfig("Google_Http_Request", "disable_gzip")) {
485
  $request->enableGzip();
486
  }
487
  $request->maybeMoveParametersToBody();
 
488
  return Google_Http_REST::execute($this, $request);
489
- } else if ($request instanceof Google_Http_Batch) {
490
  return $request->execute();
491
  } else {
492
  throw new Google_ApiException("Do not know how to execute this type of object.");
@@ -508,9 +534,10 @@ class Google_ApiClient
508
  public function getAuth()
509
  {
510
  if (!isset($this->auth)) {
511
- $class = $this->config->getAuthClass();
512
  $this->auth = new $class($this);
513
  }
 
514
  return $this->auth;
515
  }
516
 
@@ -520,9 +547,10 @@ class Google_ApiClient
520
  public function getIo()
521
  {
522
  if (!isset($this->io)) {
523
- $class = $this->config->getIoClass();
524
  $this->io = new $class($this);
525
  }
 
526
  return $this->io;
527
  }
528
 
@@ -532,22 +560,25 @@ class Google_ApiClient
532
  public function getCache()
533
  {
534
  if (!isset($this->cache)) {
535
- $class = $this->config->getCacheClass();
536
  $this->cache = new $class($this);
537
  }
 
538
  return $this->cache;
539
  }
540
 
541
  /**
542
  * Retrieve custom configuration for a specific class.
 
543
  * @param $class string|object - class or instance of class to retrieve
544
- * @param $key string optional - key to retrieve
545
  */
546
  public function getClassConfig($class, $key = null)
547
  {
548
  if (!is_string($class)) {
549
  $class = get_class($class);
550
  }
 
551
  return $this->config->getClassConfig($class, $key);
552
  }
553
 
@@ -555,9 +586,10 @@ class Google_ApiClient
555
  * Set configuration specific to a given class.
556
  * $config->setClassConfig('Google_Cache_File',
557
  * array('directory' => '/tmp/cache'));
558
- * @param $class The class name for the configuration
 
559
  * @param $config string key or an array of configuration values
560
- * @param $value optional - if $config is a key, the value
561
  *
562
  */
563
  public function setClassConfig($class, $config, $value = null)
@@ -565,8 +597,8 @@ class Google_ApiClient
565
  if (!is_string($class)) {
566
  $class = get_class($class);
567
  }
568
- return $this->config->setClassConfig($class, $config, $value);
569
 
 
570
  }
571
 
572
  /**
@@ -592,6 +624,6 @@ class Google_ApiClient
592
  public function isAppEngine()
593
  {
594
  return (isset($_SERVER['SERVER_SOFTWARE']) &&
595
- strpos($_SERVER['SERVER_SOFTWARE'], 'Google App Engine') !== false);
596
  }
597
  }
15
  * limitations under the License.
16
  */
17
 
 
18
  /**
19
  * The Google API Client
20
  * http://code.google.com/p/google-api-php-client/
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
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()) {
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
 
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
  }
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)
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
  {
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)
204
 
205
  /**
206
  * Set the IO object
207
+ *
208
  * @param Google_Io_Abstract $auth
209
  */
210
  public function setIo(Google_Io_Abstract $io)
215
 
216
  /**
217
  * Set the Cache object
218
+ *
219
  * @param Google_Cache_Abstract $auth
220
  */
221
  public function setCache(Google_Cache_Abstract $cache)
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
  {
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)
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
  {
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
  {
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)
302
 
303
  /**
304
  * Set the OAuth 2.0 Client ID.
305
+ *
306
  * @param string $clientId
307
  */
308
  public function setClientId($clientId)
312
 
313
  /**
314
  * Set the OAuth 2.0 Client Secret.
315
+ *
316
  * @param string $clientSecret
317
  */
318
  public function setClientSecret($clientSecret)
322
 
323
  /**
324
  * Set the OAuth 2.0 Redirect URI.
325
+ *
326
  * @param string $redirectUri
327
  */
328
  public function setRedirectUri($redirectUri)
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)
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)
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)
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
  {
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)
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
  {
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
  }
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
  {
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.");
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
 
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
 
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
 
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)
597
  if (!is_string($class)) {
598
  $class = get_class($class);
599
  }
 
600
 
601
+ return $this->config->setClassConfig($class, $config, $value);
602
  }
603
 
604
  /**
624
  public function isAppEngine()
625
  {
626
  return (isset($_SERVER['SERVER_SOFTWARE']) &&
627
+ strpos($_SERVER['SERVER_SOFTWARE'], 'Google App Engine') !== false);
628
  }
629
  }
src/Google/ApiModel.php CHANGED
@@ -25,7 +25,7 @@
25
  */
26
  class Google_ApiModel implements ArrayAccess
27
  {
28
- protected $data = array();
29
  protected $processed = array();
30
 
31
  /**
@@ -56,16 +56,16 @@ class Google_ApiModel implements ArrayAccess
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
- } else if (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
  }
@@ -79,14 +79,16 @@ class Google_ApiModel implements ArrayAccess
79
  * Initialize this object's properties from an array.
80
  *
81
  * @param array $array Used to seed this object's properties.
 
82
  * @return void
83
  */
84
  protected function mapTypes($array)
85
  {
86
  // Hard initilise simple types, lazy load more complex ones.
87
  foreach ($array as $key => $val) {
88
- if ( !property_exists($this, $this->keyType($key)) &&
89
- property_exists($this, $key)) {
 
90
  $this->$key = $val;
91
  unset($array[$key]);
92
  } elseif (property_exists($this, $camelKey = Google_ApiUtils::camelCase($key))) {
@@ -118,9 +120,9 @@ class Google_ApiModel implements ArrayAccess
118
 
119
  // Process all public properties.
120
  $reflect = new ReflectionObject($this);
121
- $props = $reflect->getProperties(ReflectionProperty::IS_PUBLIC);
122
  foreach ($props as $member) {
123
- $name = $member->getName();
124
  $result = $this->getSimpleValue($this->$name);
125
  if ($result != null) {
126
  $object->$name = $result;
@@ -138,7 +140,7 @@ class Google_ApiModel implements ArrayAccess
138
  {
139
  if ($value instanceof Google_ApiModel) {
140
  return $value->toSimpleObject();
141
- } else if (is_array($value)) {
142
  $return = array();
143
  foreach ($value as $key => $a_value) {
144
  $a_value = $this->getSimpleValue($a_value);
@@ -146,14 +148,18 @@ class Google_ApiModel implements ArrayAccess
146
  $return[$key] = $a_value;
147
  }
148
  }
 
149
  return $return;
150
  }
 
151
  return $value;
152
  }
153
 
154
  /**
155
  * Returns true only if the array is associative.
 
156
  * @param array $array
 
157
  * @return bool True if the array is associative.
158
  */
159
  protected function isAssociativeArray($array)
@@ -167,6 +173,7 @@ class Google_ApiModel implements ArrayAccess
167
  return true;
168
  }
169
  }
 
170
  return false;
171
  }
172
 
@@ -175,25 +182,28 @@ class Google_ApiModel implements ArrayAccess
175
  *
176
  * @param $name
177
  * @param $item
 
178
  * @return object The object from the item.
179
  */
180
  private function createObjectFromName($name, $item)
181
  {
182
  $type = $this->$name;
 
183
  return new $type($item);
184
  }
185
 
186
  /**
187
  * Verify if $obj is an array.
188
  * @throws Google_ApiException Thrown if $obj isn't an array.
189
- * @param array $obj Items that should be validated.
 
190
  * @param string $method Method expecting an array as an argument.
191
  */
192
  public function assertIsArray($obj, $method)
193
  {
194
  if ($obj && !is_array($obj)) {
195
  throw new Google_ApiException(
196
- "Incorrect parameter type passed to $method(). Expected an array."
197
  );
198
  }
199
  }
@@ -206,8 +216,8 @@ class Google_ApiModel implements ArrayAccess
206
  public function offsetGet($offset)
207
  {
208
  return isset($this->$offset) ?
209
- $this->$offset :
210
- $this->__get($offset);
211
  }
212
 
213
  public function offsetSet($offset, $value)
@@ -215,7 +225,7 @@ class Google_ApiModel implements ArrayAccess
215
  if (property_exists($this, $offset)) {
216
  $this->$offset = $value;
217
  } else {
218
- $this->data[$offset] = $value;
219
  $this->processed[$offset] = true;
220
  }
221
  }
@@ -227,12 +237,12 @@ class Google_ApiModel implements ArrayAccess
227
 
228
  protected function keyType($key)
229
  {
230
- return $key . "Type";
231
  }
232
 
233
  protected function dataType($key)
234
  {
235
- return $key . "DataType";
236
  }
237
 
238
  public function __isset($key)
25
  */
26
  class Google_ApiModel implements ArrayAccess
27
  {
28
+ protected $data = array();
29
  protected $processed = array();
30
 
31
  /**
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
  }
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))) {
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;
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);
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)
173
  return true;
174
  }
175
  }
176
+
177
  return false;
178
  }
179
 
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
  }
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)
225
  if (property_exists($this, $offset)) {
226
  $this->$offset = $value;
227
  } else {
228
+ $this->data[$offset] = $value;
229
  $this->processed[$offset] = true;
230
  }
231
  }
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)
src/Google/ApiUtils.php CHANGED
@@ -27,20 +27,22 @@ class Google_ApiUtils
27
  {
28
  $b64 = base64_encode($data);
29
  $b64 = str_replace(
30
- array('+', '/', '\r', '\n', '='),
31
- array('-', '_'),
32
- $b64
33
  );
 
34
  return $b64;
35
  }
36
 
37
  public static function urlSafeB64Decode($b64)
38
  {
39
  $b64 = str_replace(
40
- array('-', '_'),
41
- array('+', '/'),
42
- $b64
43
  );
 
44
  return base64_decode($b64);
45
  }
46
 
@@ -56,19 +58,21 @@ class Google_ApiUtils
56
  * @link http://solarphp.com/
57
  * @link http://svn.solarphp.com/core/trunk/Solar/Json.php
58
  * @link http://framework.zend.com/svn/framework/standard/trunk/library/Zend/Json/Decoder.php
59
- * @param string $str
 
 
60
  * @return int The number of bytes in a string.
61
  */
62
  public static function getStrLen($str)
63
  {
64
  $strlenVar = strlen($str);
65
- $d = $ret = 0;
66
- for ($count = 0; $count < $strlenVar; ++ $count) {
67
  $ordinalValue = ord($str{$ret});
68
  switch (true) {
69
  case (($ordinalValue >= 0x20) && ($ordinalValue <= 0x7F)):
70
  // characters U-00000000 - U-0000007F (same as ASCII)
71
- $ret ++;
72
  break;
73
  case (($ordinalValue & 0xE0) == 0xC0):
74
  // characters U-00000080 - U-000007FF, mask 110XXXXX
@@ -96,15 +100,18 @@ class Google_ApiUtils
96
  $ret += 6;
97
  break;
98
  default:
99
- $ret ++;
100
  }
101
  }
 
102
  return $ret;
103
  }
104
 
105
  /**
106
  * Normalize all keys in an array to lower-case.
 
107
  * @param array $arr
 
108
  * @return array Normalized array.
109
  */
110
  public static function normalize($arr)
@@ -117,19 +124,23 @@ class Google_ApiUtils
117
  foreach ($arr as $key => $val) {
118
  $normalized[strtolower($key)] = $val;
119
  }
 
120
  return $normalized;
121
  }
122
 
123
  /**
124
  * Convert a string to camelCase
125
- * @param string $value
 
 
126
  * @return string
127
  */
128
  public static function camelCase($value)
129
  {
130
- $value = ucwords(str_replace(array('-', '_'), ' ', $value));
131
- $value = str_replace(' ', '', $value);
132
  $value[0] = strtolower($value[0]);
 
133
  return $value;
134
  }
135
  }
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
 
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
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)
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 CHANGED
@@ -15,7 +15,6 @@
15
  * limitations under the License.
16
  */
17
 
18
-
19
  /**
20
  * Abstract class for the Authentication in the API client
21
  *
15
  * limitations under the License.
16
  */
17
 
 
18
  /**
19
  * Abstract class for the Authentication in the API client
20
  *
src/Google/Auth/AssertionCredentials.php CHANGED
@@ -15,7 +15,6 @@
15
  * limitations under the License.
16
  */
17
 
18
-
19
  /**
20
  * Credentials object used for OAuth 2.0 Signed JWT assertion grants.
21
  *
@@ -40,23 +39,23 @@ class Google_Auth_AssertionCredentials
40
 
41
  /**
42
  * @param $serviceAccountName
43
- * @param $scopes array List of scopes
44
  * @param $privateKey
45
  * @param string $privateKeyPassword
46
  * @param string $assertionType
47
- * @param bool|string $sub The email address of the user for which the
48
- * application is requesting delegated access.
49
  * @param bool useCache Whether to generate a cache key and allow
50
- * automatic caching of the generated token.
51
  */
52
  public function __construct(
53
- $serviceAccountName,
54
- $scopes,
55
- $privateKey,
56
- $privateKeyPassword = 'notasecret',
57
- $assertionType = 'http://oauth.net/grant_type/jwt/1.0/bearer',
58
- $sub = false,
59
- $useCache = true
60
  ) {
61
  $this->serviceAccountName = $serviceAccountName;
62
  $this->scopes = is_string($scopes) ? $scopes : implode(' ', $scopes);
@@ -92,11 +91,11 @@ class Google_Auth_AssertionCredentials
92
  $now = time();
93
 
94
  $jwtParams = array(
95
- 'aud' => Google_Auth_OAuth2::OAUTH2_TOKEN_URI,
96
- 'scope' => $this->scopes,
97
- 'iat' => $now,
98
- 'exp' => $now + self::MAX_TOKEN_LIFETIME_SECS,
99
- 'iss' => $this->serviceAccountName,
100
  );
101
 
102
  if ($this->sub !== false) {
@@ -122,8 +121,8 @@ class Google_Auth_AssertionCredentials
122
  $header = array('typ' => 'JWT', 'alg' => 'RS256');
123
 
124
  $segments = array(
125
- Google_ApiUtils::urlSafeB64Encode(json_encode($header)),
126
- Google_ApiUtils::urlSafeB64Encode(json_encode($payload))
127
  );
128
 
129
  $signingInput = implode('.', $segments);
15
  * limitations under the License.
16
  */
17
 
 
18
  /**
19
  * Credentials object used for OAuth 2.0 Signed JWT assertion grants.
20
  *
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);
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) {
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);
src/Google/Auth/Exception.php CHANGED
@@ -16,7 +16,6 @@
16
  * limitations under the License.
17
  */
18
 
19
-
20
  class Google_Auth_Exception extends Google_ApiException
21
  {
22
  }
16
  * limitations under the License.
17
  */
18
 
 
19
  class Google_Auth_Exception extends Google_ApiException
20
  {
21
  }
src/Google/Auth/LoginTicket.php CHANGED
@@ -15,7 +15,6 @@
15
  * limitations under the License.
16
  */
17
 
18
-
19
  /**
20
  * Class to hold information about an authenticated login.
21
  *
15
  * limitations under the License.
16
  */
17
 
 
18
  /**
19
  * Class to hold information about an authenticated login.
20
  *
src/Google/Auth/OAuth2.php CHANGED
@@ -15,7 +15,6 @@
15
  * limitations under the License.
16
  */
17
 
18
-
19
  /**
20
  * Authentication class that deals with the OAuth 2 web-server authentication flow
21
  *
@@ -25,13 +24,13 @@
25
  */
26
  class Google_Auth_OAuth2 extends Google_Auth_Abstract
27
  {
28
- const OAUTH2_REVOKE_URI = 'https://accounts.google.com/o/oauth2/revoke';
29
- const OAUTH2_TOKEN_URI = 'https://accounts.google.com/o/oauth2/token';
30
- const OAUTH2_AUTH_URL = 'https://accounts.google.com/o/oauth2/auth';
31
- const CLOCK_SKEW_SECS = 300; // five minutes in seconds
32
  const AUTH_TOKEN_LIFETIME_SECS = 300; // five minutes in seconds
33
- const MAX_TOKEN_LIFETIME_SECS = 86400; // one day in seconds
34
- const OAUTH2_ISSUER = 'accounts.google.com';
35
 
36
  /** @var Google_Auth_AssertionCredentials $assertionCredentials */
37
  private $assertionCredentials;
@@ -67,17 +66,20 @@ class Google_Auth_OAuth2 extends Google_Auth_Abstract
67
  * and then calls apiCurlIO::makeRequest on the signed request
68
  *
69
  * @param Google_Http_Request $request
 
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
  return $this->client->getIo()->makeRequest($request);
77
  }
78
 
79
  /**
80
  * @param string $code
 
81
  * @throws Google_Auth_Exception
82
  * @return string
83
  */
@@ -90,16 +92,16 @@ class Google_Auth_OAuth2 extends Google_Auth_Abstract
90
  // We got here from the redirect from a successful authorization grant,
91
  // fetch the access token
92
  $request = new Google_Http_Request(
93
- self::OAUTH2_TOKEN_URI,
94
- 'POST',
95
- array(),
96
- array(
97
- 'code' => $code,
98
- 'grant_type' => 'authorization_code',
99
- 'redirect_uri' => $this->client->getClassConfig($this, 'redirect_uri'),
100
- 'client_id' => $this->client->getClassConfig($this, 'client_id'),
101
- 'client_secret' => $this->client->getClassConfig($this, 'client_secret')
102
- )
103
  );
104
  $request->disableGzip();
105
  $response = $this->client->getIo()->makeRequest($request);
@@ -107,6 +109,7 @@ class Google_Auth_OAuth2 extends Google_Auth_Abstract
107
  if ($response->getResponseHttpCode() == 200) {
108
  $this->setAccessToken($response->getResponseBody());
109
  $this->token['created'] = time();
 
110
  return $this->getAccessToken();
111
  } else {
112
  $decodedResponse = json_decode($response->getResponseBody(), true);
@@ -114,11 +117,11 @@ class Google_Auth_OAuth2 extends Google_Auth_Abstract
114
  $decodedResponse = $decodedResponse['error'];
115
  }
116
  throw new Google_Auth_Exception(
117
- sprintf(
118
- "Error fetching OAuth2 access token, message: '%s'",
119
- $decodedResponse
120
- ),
121
- $response->getResponseHttpCode()
122
  );
123
  }
124
  }
@@ -127,18 +130,20 @@ class Google_Auth_OAuth2 extends Google_Auth_Abstract
127
  * Create a URL to obtain user authorization.
128
  * The authorization endpoint allows the user to first
129
  * authenticate, and then grant/deny the access request.
 
130
  * @param string $scope The scope is expressed as a list of space-delimited strings.
 
131
  * @return string
132
  */
133
  public function createAuthUrl($scope)
134
  {
135
  $params = array(
136
- 'response_type' => 'code',
137
- 'redirect_uri' => $this->client->getClassConfig($this, 'redirect_uri'),
138
- 'client_id' => $this->client->getClassConfig($this, 'client_id'),
139
- 'scope' => $scope,
140
- 'access_type' => $this->client->getClassConfig($this, 'access_type'),
141
- 'approval_prompt' => $this->client->getClassConfig($this, 'approval_prompt'),
142
  );
143
 
144
  // If the list of scopes contains plus.login, add request_visible_actions
@@ -152,11 +157,12 @@ class Google_Auth_OAuth2 extends Google_Auth_Abstract
152
  $params['state'] = $this->state;
153
  }
154
 
155
- return self::OAUTH2_AUTH_URL . "?" . http_build_query($params, '', '&');
156
  }
157
 
158
  /**
159
  * @param string $token
 
160
  * @throws Google_Auth_Exception
161
  */
162
  public function setAccessToken($token)
@@ -165,7 +171,7 @@ class Google_Auth_OAuth2 extends Google_Auth_Abstract
165
  if ($token == null) {
166
  throw new Google_Auth_Exception('Could not json decode the token');
167
  }
168
- if (! isset($token['access_token'])) {
169
  throw new Google_Auth_Exception("Invalid token format");
170
  }
171
  $this->token = $token;
@@ -188,7 +194,9 @@ class Google_Auth_OAuth2 extends Google_Auth_Abstract
188
 
189
  /**
190
  * Include an accessToken in a given apiHttpRequest.
 
191
  * @param Google_Http_Request $request
 
192
  * @return Google_Http_Request
193
  * @throws Google_Auth_Exception
194
  */
@@ -210,11 +218,11 @@ class Google_Auth_OAuth2 extends Google_Auth_Abstract
210
  if ($this->assertionCredentials) {
211
  $this->refreshTokenWithAssertion();
212
  } else {
213
- if (! array_key_exists('refresh_token', $this->token)) {
214
  throw new Google_Auth_Exception(
215
- "The OAuth 2.0 access token has expired,"
216
- ." and a refresh token is not available. Refresh tokens"
217
- ." are not returned for responses that were auto-approved."
218
  );
219
  }
220
  $this->refreshToken($this->token['refresh_token']);
@@ -223,7 +231,7 @@ class Google_Auth_OAuth2 extends Google_Auth_Abstract
223
 
224
  // Add the OAuth2 header to the request
225
  $request->setRequestHeaders(
226
- array('Authorization' => 'Bearer ' . $this->token['access_token'])
227
  );
228
 
229
  return $request;
@@ -231,24 +239,28 @@ class Google_Auth_OAuth2 extends Google_Auth_Abstract
231
 
232
  /**
233
  * Fetches a fresh access token with the given refresh token.
 
234
  * @param string $refreshToken
 
235
  * @return void
236
  */
237
  public function refreshToken($refreshToken)
238
  {
239
  $this->refreshTokenRequest(
240
- array(
241
- 'client_id' => $this->client->getClassConfig($this, 'client_id'),
242
- 'client_secret' => $this->client->getClassConfig($this, 'client_secret'),
243
- 'refresh_token' => $refreshToken,
244
- 'grant_type' => 'refresh_token'
245
- )
246
  );
247
  }
248
 
249
  /**
250
  * Fetches a fresh access token with a given assertion token.
 
251
  * @param Google_Auth_AssertionCredentials $assertionCredentials optional.
 
252
  * @return void
253
  */
254
  public function refreshTokenWithAssertion($assertionCredentials = null)
@@ -273,18 +285,18 @@ class Google_Auth_OAuth2 extends Google_Auth_Abstract
273
  }
274
 
275
  $this->refreshTokenRequest(
276
- array(
277
- 'grant_type' => 'assertion',
278
- 'assertion_type' => $assertionCredentials->assertionType,
279
- 'assertion' => $assertionCredentials->generateAssertion(),
280
- )
281
  );
282
 
283
  if ($cacheKey) {
284
  // Attempt to cache the token.
285
  $this->client->getCache()->set(
286
- $cacheKey,
287
- $this->getAccessToken()
288
  );
289
  }
290
  }
@@ -292,10 +304,10 @@ class Google_Auth_OAuth2 extends Google_Auth_Abstract
292
  private function refreshTokenRequest($params)
293
  {
294
  $http = new Google_Http_Request(
295
- self::OAUTH2_TOKEN_URI,
296
- 'POST',
297
- array(),
298
- $params
299
  );
300
  $http->disableGzip();
301
  $request = $this->client->getIo()->makeRequest($http);
@@ -308,13 +320,13 @@ class Google_Auth_OAuth2 extends Google_Auth_Abstract
308
  throw new Google_Auth_Exception("Could not json decode the access token");
309
  }
310
 
311
- if (! isset($token['access_token']) || ! isset($token['expires_in'])) {
312
  throw new Google_Auth_Exception("Invalid token format");
313
  }
314
 
315
  $this->token['access_token'] = $token['access_token'];
316
- $this->token['expires_in'] = $token['expires_in'];
317
- $this->token['created'] = time();
318
  } else {
319
  throw new Google_Auth_Exception("Error refreshing the OAuth2 token, message: '$body'", $code);
320
  }
@@ -324,7 +336,9 @@ class Google_Auth_OAuth2 extends Google_Auth_Abstract
324
  * Revoke an OAuth2 access token or refresh token. This method will revoke the current access
325
  * token, if a token isn't provided.
326
  * @throws Google_Auth_Exception
 
327
  * @param string|null $token The token (access token or a refresh token) that should be revoked.
 
328
  * @return boolean Returns True if the revocation was successful, otherwise False.
329
  */
330
  public function revokeToken($token = null)
@@ -333,16 +347,17 @@ class Google_Auth_OAuth2 extends Google_Auth_Abstract
333
  $token = $this->token['access_token'];
334
  }
335
  $request = new Google_Http_Request(
336
- self::OAUTH2_REVOKE_URI,
337
- 'POST',
338
- array(),
339
- "token=$token"
340
  );
341
  $request->disableGzip();
342
  $response = $this->client->getIo()->makeRequest($request);
343
- $code = $response->getResponseHttpCode();
344
  if ($code == 200) {
345
  $this->token = null;
 
346
  return true;
347
  }
348
 
@@ -361,7 +376,7 @@ class Google_Auth_OAuth2 extends Google_Auth_Abstract
361
 
362
  // If the token is set to expire in the next 30 seconds.
363
  $expired = ($this->token['created']
364
- + ($this->token['expires_in'] - 30)) < time();
365
 
366
  return $expired;
367
  }
@@ -372,13 +387,15 @@ class Google_Auth_OAuth2 extends Google_Auth_Abstract
372
  private function getFederatedSignOnCerts()
373
  {
374
  return $this->retrieveCertsFromLocation(
375
- $this->client->getClassConfig($this, 'federated_signon_certs_url')
376
  );
377
  }
378
 
379
  /**
380
  * Retrieve and cache a certificates file.
 
381
  * @param $url location
 
382
  * @return array certificates
383
  */
384
  public function retrieveCertsFromLocation($url)
@@ -390,17 +407,17 @@ class Google_Auth_OAuth2 extends Google_Auth_Abstract
390
  return json_decode($file, true);
391
  } else {
392
  throw new Google_Auth_Exception(
393
- "Failed to retrieve verification certificates: '" .
394
- $url . "'."
395
  );
396
  }
397
  }
398
 
399
  // This relies on makeRequest caching certificate responses.
400
  $request = $this->client->getIo()->makeRequest(
401
- new Google_Http_Request(
402
- $url
403
- )
404
  );
405
  if ($request->getResponseHttpCode() == 200) {
406
  $certs = json_decode($request->getResponseBody(), true);
@@ -409,9 +426,9 @@ class Google_Auth_OAuth2 extends Google_Auth_Abstract
409
  }
410
  }
411
  throw new Google_Auth_Exception(
412
- "Failed to retrieve verification certificates: '" .
413
- $request->getResponseBody() . "'.",
414
- $request->getResponseHttpCode()
415
  );
416
  }
417
 
@@ -423,6 +440,7 @@ class Google_Auth_OAuth2 extends Google_Auth_Abstract
423
  *
424
  * @param $id_token
425
  * @param $audience
 
426
  * @return Google_Auth_LoginTicket
427
  */
428
  public function verifyIdToken($id_token = null, $audience = null)
@@ -441,19 +459,20 @@ class Google_Auth_OAuth2 extends Google_Auth_Abstract
441
  /**
442
  * Verifies the id token, returns the verified token contents.
443
  *
444
- * @param $jwt the token
445
- * @param $certs array of certificates
446
  * @param $required_audience the expected consumer of the token
447
  * @param [$issuer] the expected issues, defaults to Google
448
  * @param [$max_expiry] the max lifetime of a token, defaults to MAX_TOKEN_LIFETIME_SECS
 
449
  * @return token information if valid, false if not
450
  */
451
  public function verifySignedJwtWithCerts(
452
- $jwt,
453
- $certs,
454
- $required_audience,
455
- $issuer = null,
456
- $max_expiry = null
457
  ) {
458
  if (!$max_expiry) {
459
  // Set the maximum time we will accept a token for.
@@ -464,20 +483,20 @@ class Google_Auth_OAuth2 extends Google_Auth_Abstract
464
  if (count($segments) != 3) {
465
  throw new Google_Auth_Exception("Wrong number of segments in token: $jwt");
466
  }
467
- $signed = $segments[0] . "." . $segments[1];
468
  $signature = Google_ApiUtils::urlSafeB64Decode($segments[2]);
469
 
470
  // Parse envelope.
471
  $envelope = json_decode(Google_ApiUtils::urlSafeB64Decode($segments[0]), true);
472
  if (!$envelope) {
473
- throw new Google_Auth_Exception("Can't parse token envelope: " . $segments[0]);
474
  }
475
 
476
  // Parse token
477
  $json_body = Google_ApiUtils::urlSafeB64Decode($segments[1]);
478
- $payload = json_decode($json_body, true);
479
  if (!$payload) {
480
- throw new Google_Auth_Exception("Can't parse token payload: " . $segments[1]);
481
  }
482
 
483
  // Check signature
@@ -515,41 +534,41 @@ class Google_Auth_OAuth2 extends Google_Auth_Abstract
515
  }
516
  if ($exp >= $now + $max_expiry) {
517
  throw new Google_Auth_Exception(
518
- sprintf("Expiration time too far in future: %s", $json_body)
519
  );
520
  }
521
 
522
  $latest = $exp + self::CLOCK_SKEW_SECS;
523
  if ($now < $earliest) {
524
  throw new Google_Auth_Exception(
525
- sprintf(
526
- "Token used too early, %s < %s: %s",
527
- $now,
528
- $earliest,
529
- $json_body
530
- )
531
  );
532
  }
533
  if ($now > $latest) {
534
  throw new Google_Auth_Exception(
535
- sprintf(
536
- "Token used too late, %s > %s: %s",
537
- $now,
538
- $latest,
539
- $json_body
540
- )
541
  );
542
  }
543
 
544
  $iss = $payload['iss'];
545
  if ($issuer && $iss != $issuer) {
546
  throw new Google_Auth_Exception(
547
- sprintf(
548
- "Invalid issuer, %s != %s: %s",
549
- $iss,
550
- $issuer,
551
- $json_body
552
- )
553
  );
554
  }
555
 
@@ -557,12 +576,12 @@ class Google_Auth_OAuth2 extends Google_Auth_Abstract
557
  $aud = $payload["aud"];
558
  if ($aud != $required_audience) {
559
  throw new Google_Auth_Exception(
560
- sprintf(
561
- "Wrong recipient, %s != %s:",
562
- $aud,
563
- $required_audience,
564
- $json_body
565
- )
566
  );
567
  }
568
 
15
  * limitations under the License.
16
  */
17
 
 
18
  /**
19
  * Authentication class that deals with the OAuth 2 web-server authentication flow
20
  *
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;
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
  */
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);
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);
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
  }
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
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)
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;
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
  */
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']);
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;
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)
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
  }
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);
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
  }
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)
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
 
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
  }
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)
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);
426
  }
427
  }
428
  throw new Google_Auth_Exception(
429
+ "Failed to retrieve verification certificates: '".
430
+ $request->getResponseBody()."'.",
431
+ $request->getResponseHttpCode()
432
  );
433
  }
434
 
440
  *
441
  * @param $id_token
442
  * @param $audience
443
+ *
444
  * @return Google_Auth_LoginTicket
445
  */
446
  public function verifyIdToken($id_token = null, $audience = null)
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.
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
534
  }
535
  if ($exp >= $now + $max_expiry) {
536
  throw new Google_Auth_Exception(
537
+ sprintf("Expiration time too far in future: %s", $json_body)
538
  );
539
  }
540
 
541
  $latest = $exp + self::CLOCK_SKEW_SECS;
542
  if ($now < $earliest) {
543
  throw new Google_Auth_Exception(
544
+ sprintf(
545
+ "Token used too early, %s < %s: %s",
546
+ $now,
547
+ $earliest,
548
+ $json_body
549
+ )
550
  );
551
  }
552
  if ($now > $latest) {
553
  throw new Google_Auth_Exception(
554
+ sprintf(
555
+ "Token used too late, %s > %s: %s",
556
+ $now,
557
+ $latest,
558
+ $json_body
559
+ )
560
  );
561
  }
562
 
563
  $iss = $payload['iss'];
564
  if ($issuer && $iss != $issuer) {
565
  throw new Google_Auth_Exception(
566
+ sprintf(
567
+ "Invalid issuer, %s != %s: %s",
568
+ $iss,
569
+ $issuer,
570
+ $json_body
571
+ )
572
  );
573
  }
574
 
576
  $aud = $payload["aud"];
577
  if ($aud != $required_audience) {
578
  throw new Google_Auth_Exception(
579
+ sprintf(
580
+ "Wrong recipient, %s != %s:",
581
+ $aud,
582
+ $required_audience,
583
+ $json_body
584
+ )
585
  );
586
  }
587
 
src/Google/Auth/Simple.php CHANGED
@@ -15,7 +15,6 @@
15
  * limitations under the License.
16
  */
17
 
18
-
19
  /**
20
  * Simple API access implementation. Can either be used to make requests
21
  * completely unauthenticated, or by using a Simple API Access developer
@@ -43,7 +42,7 @@ class Google_Auth_Simple extends Google_Auth_Abstract
43
  * @param Google_Http_Request $request
44
  *
45
  * @return Google_Http_Request The resulting HTTP response including the
46
- * responseHttpCode, responseHeaders and responseBody.
47
  */
48
  public function authenticatedRequest(Google_Http_Request $request)
49
  {
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
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
  {
src/Google/Cache/Abstract.php CHANGED
@@ -22,7 +22,6 @@
22
  */
23
  abstract class Google_Cache_Abstract
24
  {
25
-
26
  abstract public function __construct(Google_ApiClient $client);
27
 
28
  /**
22
  */
23
  abstract class Google_Cache_Abstract
24
  {
 
25
  abstract public function __construct(Google_ApiClient $client);
26
 
27
  /**
src/Google/Cache/Apc.php CHANGED
@@ -15,7 +15,6 @@
15
  * limitations under the License.
16
  */
17
 
18
-
19
  /**
20
  * A persistent storage class based on the APC cache, which is not
21
  * really very persistent, as soon as you restart your web server
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
src/Google/Cache/Exception.php CHANGED
@@ -16,7 +16,6 @@
16
  * limitations under the License.
17
  */
18
 
19
-
20
  class Google_Cache_Exception extends Google_ApiException
21
  {
22
  }
16
  * limitations under the License.
17
  */
18
 
 
19
  class Google_Cache_Exception extends Google_ApiException
20
  {
21
  }
src/Google/Cache/File.php CHANGED
@@ -15,7 +15,6 @@
15
  * limitations under the License.
16
  */
17
 
18
-
19
  /*
20
  * This class implements a basic on disk storage. While that does
21
  * work quite well it's not the most elegant and scalable solution.
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.
src/Google/Cache/Memcache.php CHANGED
@@ -15,7 +15,6 @@
15
  * limitations under the License.
16
  */
17
 
18
-
19
  /**
20
  * A persistent storage class based on the memcache, which is not
21
  * really very persistent, as soon as you restart your memcache daemon
@@ -29,7 +28,7 @@
29
  class Google_Cache_Memcache extends Google_Cache_Abstract
30
  {
31
  private $connection = false;
32
- private $mc = false;
33
  private $host;
34
  private $port;
35
 
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
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
 
src/Google/Cache/Null.php CHANGED
@@ -15,7 +15,6 @@
15
  * limitations under the License.
16
  */
17
 
18
-
19
  /**
20
  * A blank storage class, for cases where caching is not
21
  * required.
@@ -24,7 +23,6 @@ class Google_Cache_Null extends Google_Cache_Abstract
24
  {
25
  public function __construct(Google_ApiClient $client)
26
  {
27
-
28
  }
29
 
30
  /**
@@ -45,6 +43,7 @@ class Google_Cache_Null extends Google_Cache_Abstract
45
 
46
  /**
47
  * @inheritDoc
 
48
  * @param String $key
49
  */
50
  public function delete($key)
15
  * limitations under the License.
16
  */
17
 
 
18
  /**
19
  * A blank storage class, for cases where caching is not
20
  * required.
23
  {
24
  public function __construct(Google_ApiClient $client)
25
  {
 
26
  }
27
 
28
  /**
43
 
44
  /**
45
  * @inheritDoc
46
+ *
47
  * @param String $key
48
  */
49
  public function delete($key)
src/Google/Collection.php CHANGED
@@ -90,7 +90,7 @@ class Google_Collection extends Google_ApiModel implements Iterator, Countable
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
  }
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 CHANGED
@@ -38,54 +38,53 @@ class Google_Config
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' =>
79
- 'https://www.googleapis.com/oauth2/v1/certs',
80
- ),
81
- // Set a default directory for the file cache.
82
- 'Google_Cache_File' => array(
83
- 'directory' => sys_get_temp_dir().'/Google_ApiClient'
84
- )
85
- ),
86
  // Definition of service specific values like scopes, oauth token URLs,
87
  // etc. Example:
88
- 'services' => array(),
89
  );
90
  if ($ini_file_location) {
91
  $ini = parse_ini_file($ini_file_location, true);
@@ -157,10 +156,10 @@ class Google_Config
157
  {
158
  $prev = $this->configuration['auth_class'];
159
  if (!isset($this->configuration['classes'][$class]) &&
160
- isset($this->configuration['classes'][$prev])
161
  ) {
162
  $this->configuration['classes'][$class] =
163
- $this->configuration['classes'][$prev];
164
  }
165
  $this->configuration['auth_class'] = $class;
166
  }
@@ -174,10 +173,10 @@ class Google_Config
174
  {
175
  $prev = $this->configuration['io_class'];
176
  if (!isset($this->configuration['classes'][$class]) &&
177
- isset($this->configuration['classes'][$prev])
178
  ) {
179
  $this->configuration['classes'][$class] =
180
- $this->configuration['classes'][$prev];
181
  }
182
  $this->configuration['io_class'] = $class;
183
  }
@@ -191,10 +190,10 @@ class Google_Config
191
  {
192
  $prev = $this->configuration['cache_class'];
193
  if (!isset($this->configuration['classes'][$class]) &&
194
- isset($this->configuration['classes'][$prev])
195
  ) {
196
  $this->configuration['classes'][$class] =
197
- $this->configuration['classes'][$prev];
198
  }
199
  $this->configuration['cache_class'] = $class;
200
  }
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);
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
  }
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
  }
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
  }
src/Google/Http/Batch.php CHANGED
@@ -20,7 +20,6 @@
20
  */
21
  class Google_Http_Batch
22
  {
23
-
24
  /** @var string Multipart Boundary. */
25
  private $boundary;
26
 
@@ -100,14 +99,14 @@ class Google_Http_Batch
100
  $part = trim($part);
101
  if (!empty($part)) {
102
  list($metaHeaders, $part) = explode("\r\n\r\n", $part, 2);
103
- $metaHeaders = $this->client->getIo()->getHttpResponseHeaders($metaHeaders);
104
 
105
  $status = substr($part, 0, strpos($part, "\n"));
106
  $status = explode(" ", $status);
107
  $status = $status[1];
108
 
109
  list($partHeaders, $partBody) = $this->client->getIo()->ParseHttpResponse($part, false);
110
- $response = new Google_Http_Request("");
111
  $response->setResponseHttpCode($status);
112
  $response->setResponseHeaders($partHeaders);
113
  $response->setResponseBody($partBody);
20
  */
21
  class Google_Http_Batch
22
  {
 
23
  /** @var string Multipart Boundary. */
24
  private $boundary;
25
 
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);
src/Google/Http/CacheParser.php CHANGED
@@ -15,7 +15,6 @@
15
  * limitations under the License.
16
  */
17
 
18
-
19
  /**
20
  * Implement the caching directives specified in rfc2616. This
21
  * implementation is guided by the guidance offered in rfc2616-sec13.
@@ -35,7 +34,7 @@ class Google_Http_CacheParser
35
  * @param Google_Http_Request $resp
36
  *
37
  * @return bool True if the request is cacheable.
38
- * False if the request is uncacheable.
39
  */
40
  public static function isRequestCacheable(Google_Http_Request $resp)
41
  {
@@ -63,7 +62,7 @@ class Google_Http_CacheParser
63
  * @param Google_Http_Request $resp
64
  *
65
  * @return bool True if the response is cacheable.
66
- * False if the response is un-cacheable.
67
  */
68
  public static function isResponseCacheable(Google_Http_Request $resp)
69
  {
@@ -117,7 +116,7 @@ class Google_Http_CacheParser
117
  * @param Google_Http_Request $resp
118
  *
119
  * @return bool True if the HTTP response is considered to be expired.
120
- * False if it is considered to be fresh.
121
  */
122
  public static function isExpired(Google_Http_Request $resp)
123
  {
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.
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
  {
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
  {
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
  {
src/Google/Http/MediaFileUpload.php CHANGED
@@ -15,7 +15,6 @@
15
  * limitations under the License.
16
  */
17
 
18
-
19
  /**
20
  * @author Chirag Shah <chirags@google.com>
21
  *
@@ -64,13 +63,13 @@ class Google_Http_MediaFileUpload
64
  * only used if resumable=True
65
  */
66
  public function __construct(
67
- Google_ApiClient $client,
68
- Google_Http_Request $request,
69
- $mimeType,
70
- $data,
71
- $resumable = false,
72
- $chunkSize = false,
73
- $boundary = false
74
  ) {
75
  $this->client = $client;
76
  $this->request = $request;
@@ -127,17 +126,17 @@ class Google_Http_MediaFileUpload
127
 
128
  $lastBytePos = $this->progress + strlen($chunk) - 1;
129
  $headers = array(
130
- 'content-range' => "bytes $this->progress-$lastBytePos/$this->size",
131
- 'content-type' => $this->request->getRequestHeader('content-type'),
132
- 'content-length' => $this->chunkSize,
133
- 'expect' => '',
134
  );
135
 
136
  $httpRequest = new Google_Http_Request(
137
- $this->resumeUri,
138
- 'PUT',
139
- $headers,
140
- $chunk
141
  );
142
 
143
  if ($this->client->getClassConfig("Google_Http_Request", "enable_gzip_for_uploads")) {
@@ -187,8 +186,8 @@ class Google_Http_MediaFileUpload
187
  $this->request->setQueryParam('uploadType', $uploadType);
188
  $this->transformToUploadUrl();
189
  $mimeType = $this->mimeType ?
190
- $this->mimeType :
191
- $this->request->getRequestHeader('content-type');
192
 
193
  if (self::UPLOAD_RESUMABLE_TYPE == $uploadType) {
194
  $contentType = $mimeType;
@@ -260,11 +259,11 @@ class Google_Http_MediaFileUpload
260
  $body = $this->request->getPostBody();
261
  if ($body) {
262
  $headers = array(
263
- 'content-type' => 'application/json; charset=UTF-8',
264
- 'content-length' => Google_ApiUtils::getStrLen($body),
265
- 'x-upload-content-type' => $this->mimeType,
266
- 'x-upload-content-length' => $this->size,
267
- 'expect' => '',
268
  );
269
  $this->request->setRequestHeaders($headers);
270
  }
15
  * limitations under the License.
16
  */
17
 
 
18
  /**
19
  * @author Chirag Shah <chirags@google.com>
20
  *
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;
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")) {
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;
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
  }
src/Google/Http/REST.php CHANGED
@@ -15,7 +15,6 @@
15
  * limitations under the License.
16
  */
17
 
18
-
19
  /**
20
  * This class implements the RESTful transport of apiServiceRequest()'s
21
  *
@@ -30,9 +29,9 @@ class Google_Http_REST
30
  * @param Google_ApiClient $client
31
  * @param Google_Http_Request $req
32
  *
33
- * @return array decoded result
34
  * @throws Google_Service_Exception on server side error (ie: not authenticated,
35
- * invalid or malformed post body, invalid url)
36
  */
37
  public static function execute(Google_ApiClient $client, Google_Http_Request $req)
38
  {
@@ -42,7 +41,6 @@ class Google_Http_REST
42
  return self::decodeHttpResponse($httpRequest);
43
  }
44
 
45
-
46
  /**
47
  * Decode an HTTP Response.
48
  *
@@ -63,8 +61,8 @@ class Google_Http_REST
63
  $decoded = json_decode($body, true);
64
  $err = 'Error calling '.$response->getRequestMethod().' '.$response->getUrl();
65
  if (isset($decoded['error']) &&
66
- isset($decoded['error']['message']) &&
67
- isset($decoded['error']['code'])
68
  ) {
69
  // if we're getting a json encoded error definition, use that instead of the raw response
70
  // body for improved readability
15
  * limitations under the License.
16
  */
17
 
 
18
  /**
19
  * This class implements the RESTful transport of apiServiceRequest()'s
20
  *
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
  {
41
  return self::decodeHttpResponse($httpRequest);
42
  }
43
 
 
44
  /**
45
  * Decode an HTTP Response.
46
  *
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
src/Google/Http/Request.php CHANGED
@@ -15,7 +15,6 @@
15
  * limitations under the License.
16
  */
17
 
18
-
19
  /**
20
  * HTTP Request to be executed by IO classes. Upon execution, the
21
  * responseHttpCode, responseHeaders and responseBody will be filled in.
@@ -29,9 +28,9 @@ class Google_Http_Request
29
  const GZIP_UA = " (gzip)";
30
 
31
  private $batchHeaders = array(
32
- 'Content-Type' => 'application/http',
33
- 'Content-Transfer-Encoding' => 'binary',
34
- 'MIME-Version' => '1.0',
35
  );
36
 
37
  protected $queryParams;
@@ -52,10 +51,10 @@ class Google_Http_Request
52
  public $accessKey;
53
 
54
  public function __construct(
55
- $url,
56
- $method = 'GET',
57
- $headers = array(),
58
- $postBody = null
59
  ) {
60
  $this->setUrl($url);
61
  $this->setRequestMethod($method);
@@ -100,8 +99,8 @@ class Google_Http_Request
100
  public function disableGzip()
101
  {
102
  if (
103
- isset($this->requestHeaders['accept-encoding']) &&
104
- $this->requestHeaders['accept-encoding'] == "gzip"
105
  ) {
106
  unset($this->requestHeaders['accept-encoding']);
107
  }
@@ -211,13 +210,13 @@ class Google_Http_Request
211
  * @param string $key
212
  *
213
  * @return array|boolean Returns the requested HTTP header or
214
- * false if unavailable.
215
  */
216
  public function getResponseHeader($key)
217
  {
218
  return isset($this->responseHeaders[$key])
219
- ? $this->responseHeaders[$key]
220
- : false;
221
  }
222
 
223
  /**
@@ -235,8 +234,8 @@ class Google_Http_Request
235
  {
236
  return $this->baseComponent.$this->path.
237
  (count($this->queryParams) ?
238
- "?".$this->buildQuery($this->queryParams) :
239
- '');
240
  }
241
 
242
  /**
@@ -259,13 +258,13 @@ class Google_Http_Request
259
  * @param string $key
260
  *
261
  * @return array|boolean Returns the requested HTTP header or
262
- * false if unavailable.
263
  */
264
  public function getRequestHeader($key)
265
  {
266
  return isset($this->requestHeaders[$key])
267
- ? $this->requestHeaders[$key]
268
- : false;
269
  }
270
 
271
  /**
@@ -290,10 +289,10 @@ class Google_Http_Request
290
  $parts = parse_url($url);
291
  if (isset($parts['host'])) {
292
  $this->baseComponent = sprintf(
293
- "%s%s%s",
294
- isset($parts['scheme']) ? $parts['scheme']."://" : '',
295
- isset($parts['host']) ? $parts['host'] : '',
296
- isset($parts['port']) ? ":".$parts['port'] : ''
297
  );
298
  }
299
  $this->path = isset($parts['path']) ? $parts['path'] : '';
@@ -398,7 +397,7 @@ class Google_Http_Request
398
  {
399
  $str = '';
400
  $path = parse_url($this->getUrl(), PHP_URL_PATH)."?".
401
- http_build_query($this->queryParams);
402
  $str .= $this->getRequestMethod().' '.$path." HTTP/1.1\n";
403
 
404
  foreach ($this->getRequestHeaders() as $key => $val) {
@@ -433,7 +432,7 @@ class Google_Http_Request
433
  $parts = explode("&", $string);
434
  foreach ($parts as $part) {
435
  list($key, $value) = explode('=', $part, 2);
436
- $value = urldecode($value);
437
  if (isset($return[$key])) {
438
  if (!is_array($return[$key])) {
439
  $return[$key] = array($return[$key]);
@@ -478,10 +477,9 @@ class Google_Http_Request
478
  {
479
  if ($this->getRequestMethod() == "POST" && empty($this->postBody)) {
480
  $this->setRequestHeaders(
481
- array(
482
- "content-type" =>
483
- "application/x-www-form-urlencoded; charset=UTF-8"
484
- )
485
  );
486
  $this->setPostBody($this->buildQuery($this->queryParams));
487
  $this->queryParams = array();
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.
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;
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);
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
  }
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
  /**
234
  {
235
  return $this->baseComponent.$this->path.
236
  (count($this->queryParams) ?
237
+ "?".$this->buildQuery($this->queryParams) :
238
+ '');
239
  }
240
 
241
  /**
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
  /**
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'] : '';
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) {
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]);
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();
src/Google/IO/Abstract.php CHANGED
@@ -20,8 +20,8 @@
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);
@@ -86,7 +86,7 @@ abstract class Google_IO_Abstract
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
  {
@@ -105,8 +105,8 @@ abstract class Google_IO_Abstract
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)
@@ -152,7 +152,7 @@ abstract class Google_IO_Abstract
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
  {
@@ -310,7 +310,7 @@ abstract class Google_IO_Abstract
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 {
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);
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
  {
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)
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
  {
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 {
src/Google/IO/Curl.php CHANGED
@@ -32,8 +32,8 @@ class Google_IO_Curl extends Google_IO_Abstract
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)
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)
src/Google/IO/Exception.php CHANGED
@@ -16,7 +16,6 @@
16
  * limitations under the License.
17
  */
18
 
19
-
20
  class Google_IO_Exception extends Google_ApiException
21
  {
22
  }
16
  * limitations under the License.
17
  */
18
 
 
19
  class Google_IO_Exception extends Google_ApiException
20
  {
21
  }
src/Google/IO/Stream.php CHANGED
@@ -20,29 +20,28 @@
20
  *
21
  * @author Stuart Langley <slangley@google.com>
22
  */
23
-
24
-
25
  class Google_IO_Stream extends Google_IO_Abstract
26
  {
27
- const TIMEOUT = "timeout";
28
- const ZLIB = "compress.zlib://";
29
  private $options = array();
30
 
31
  private static $DEFAULT_HTTP_CONTEXT = array(
32
- "follow_location" => 0,
33
- "ignore_errors" => 1,
34
  );
35
 
36
  private static $DEFAULT_SSL_CONTEXT = array(
37
- "verify_peer" => true,
38
  );
39
 
40
  /**
41
  * Execute an HTTP Request
42
  *
43
  * @param Google_HttpRequest $request the http request to be executed
44
- * @return Google_HttpRequest http request with the response http code,
45
- * response headers and response body filled in
 
46
  * @throws Google_IO_Exception on curl or IO error
47
  */
48
  public function executeRequest(Google_Http_Request $request)
@@ -50,7 +49,7 @@ class Google_IO_Stream extends Google_IO_Abstract
50
  $default_options = stream_context_get_options(stream_context_get_default());
51
 
52
  $requestHttpContext = array_key_exists('http', $default_options) ?
53
- $default_options['http'] : array();
54
 
55
  if ($request->getPostBody()) {
56
  $requestHttpContext["content"] = $request->getPostBody();
@@ -65,25 +64,25 @@ class Google_IO_Stream extends Google_IO_Abstract
65
  $requestHttpContext["header"] = $headers;
66
  }
67
 
68
- $requestHttpContext["method"] = $request->getRequestMethod();
69
  $requestHttpContext["user_agent"] = $request->getUserAgent();
70
 
71
  $requestSslContext = array_key_exists('ssl', $default_options) ?
72
- $default_options['ssl'] : array();
73
 
74
  if (!array_key_exists("cafile", $requestSslContext)) {
75
- $requestSslContext["cafile"] = dirname(__FILE__) . '/cacerts.pem';
76
  }
77
 
78
  $options = array(
79
- "http" => array_merge(
80
- self::$DEFAULT_HTTP_CONTEXT,
81
- $requestHttpContext
82
- ),
83
- "ssl" => array_merge(
84
- self::$DEFAULT_SSL_CONTEXT,
85
- $requestSslContext
86
- )
87
  );
88
 
89
  $context = stream_context_create($options);
@@ -91,7 +90,7 @@ class Google_IO_Stream extends Google_IO_Abstract
91
  $url = $request->getUrl();
92
 
93
  if ($request->canGzip()) {
94
- $url = self::ZLIB . $url;
95
  }
96
 
97
  // Not entirely happy about this, but supressing the warning from the
@@ -101,7 +100,7 @@ class Google_IO_Stream extends Google_IO_Abstract
101
  @$fh = fopen($url, 'r', false, $context);
102
 
103
  $response_data = false;
104
- $respHttpCode = self::UNKNOWN_CODE;
105
  if ($fh) {
106
  if (isset($this->options[self::TIMEOUT])) {
107
  stream_set_timeout($fh, $this->options[self::TIMEOUT]);
@@ -115,11 +114,11 @@ class Google_IO_Stream extends Google_IO_Abstract
115
 
116
  if (false === $response_data) {
117
  throw new Google_IO_Exception(
118
- sprintf(
119
- "HTTP Error: Unable to connect: '%s'",
 
 
120
  $respHttpCode
121
- ),
122
- $respHttpCode
123
  );
124
  }
125
 
@@ -130,6 +129,7 @@ class Google_IO_Stream extends Google_IO_Abstract
130
 
131
  /**
132
  * Set options that update the transport implementation's behavior.
 
133
  * @param $options
134
  */
135
  public function setOptions($options)
@@ -139,6 +139,7 @@ class Google_IO_Stream extends Google_IO_Abstract
139
 
140
  /**
141
  * Set the maximum request time in seconds.
 
142
  * @param $timeout in seconds
143
  */
144
  public function setTimeout($timeout)
@@ -163,9 +164,11 @@ class Google_IO_Stream extends Google_IO_Abstract
163
  $header = $response_headers[$i];
164
  if (strncasecmp("HTTP", $header, strlen("HTTP")) == 0) {
165
  $response = explode(' ', $header);
 
166
  return $response[1];
167
  }
168
  }
 
169
  return self::UNKNOWN_CODE;
170
  }
171
  }
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)
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();
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);
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
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]);
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
 
129
 
130
  /**
131
  * Set options that update the transport implementation's behavior.
132
+ *
133
  * @param $options
134
  */
135
  public function setOptions($options)
139
 
140
  /**
141
  * Set the maximum request time in seconds.
142
+ *
143
  * @param $timeout in seconds
144
  */
145
  public function setTimeout($timeout)
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
  }
src/Google/IO/cacerts.pem CHANGED
@@ -1,738 +1,738 @@
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-----
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 CHANGED
@@ -60,7 +60,6 @@ class Google_Service_Drive extends Google_ApiService
60
  public $replies;
61
  public $revisions;
62
 
63
-
64
  /**
65
  * Constructs the internal representation of the Drive service.
66
  *
@@ -73,1186 +72,1185 @@ class Google_Service_Drive extends Google_ApiService
73
  $this->version = 'v2';
74
  $this->serviceName = 'drive';
75
 
76
- $this->about = new Google_Service_Drive_About_Resource(
77
- $this,
78
- $this->serviceName,
79
- 'about',
80
- array(
81
- 'methods' => array(
82
- 'get' => array(
83
- 'path' => 'about',
84
- 'httpMethod' => 'GET',
85
- 'parameters' => array(
86
- 'includeSubscribed' => array(
87
- 'location' => 'query',
88
- 'type' => 'boolean',
89
- ),
90
- 'maxChangeIdCount' => array(
91
- 'location' => 'query',
92
- 'type' => 'string',
93
- ),
94
- 'startChangeId' => array(
95
- 'location' => 'query',
96
- 'type' => 'string',
97
- ),
 
 
98
  ),
99
- ),
100
  )
101
- )
102
  );
103
- $this->apps = new Google_Service_Drive_Apps_Resource(
104
- $this,
105
- $this->serviceName,
106
- 'apps',
107
- array(
108
- 'methods' => array(
109
- 'get' => array(
110
- 'path' => 'apps/{appId}',
111
- 'httpMethod' => 'GET',
112
- 'parameters' => array(
113
- 'appId' => array(
114
- 'location' => 'path',
115
- 'type' => 'string',
116
- 'required' => true,
117
- ),
 
 
 
 
 
 
 
118
  ),
119
- ),
120
- 'list' => array(
121
- 'path' => 'apps',
122
- 'httpMethod' => 'GET',
123
- 'parameters' => array(),
124
- ),
125
  )
126
- )
127
  );
128
- $this->changes = new Google_Service_Drive_Changes_Resource(
129
- $this,
130
- $this->serviceName,
131
- 'changes',
132
- array(
133
- 'methods' => array(
134
- 'get' => array(
135
- 'path' => 'changes/{changeId}',
136
- 'httpMethod' => 'GET',
137
- 'parameters' => array(
138
- 'changeId' => array(
139
- 'location' => 'path',
140
- 'type' => 'string',
141
- 'required' => true,
142
- ),
143
- ),
144
- ),
145
- 'list' => array(
146
- 'path' => 'changes',
147
- 'httpMethod' => 'GET',
148
- 'parameters' => array(
149
- 'includeSubscribed' => array(
150
- 'location' => 'query',
151
- 'type' => 'boolean',
152
- ),
153
- 'startChangeId' => array(
154
- 'location' => 'query',
155
- 'type' => 'string',
156
- ),
157
- 'includeDeleted' => array(
158
- 'location' => 'query',
159
- 'type' => 'boolean',
160
- ),
161
- 'maxResults' => array(
162
- 'location' => 'query',
163
- 'type' => 'integer',
164
- ),
165
- 'pageToken' => array(
166
- 'location' => 'query',
167
- 'type' => 'string',
168
- ),
169
- ),
170
- ),
171
- 'watch' => array(
172
- 'path' => 'changes/watch',
173
- 'httpMethod' => 'POST',
174
- 'parameters' => array(
175
- 'includeSubscribed' => array(
176
- 'location' => 'query',
177
- 'type' => 'boolean',
178
- ),
179
- 'startChangeId' => array(
180
- 'location' => 'query',
181
- 'type' => 'string',
182
- ),
183
- 'includeDeleted' => array(
184
- 'location' => 'query',
185
- 'type' => 'boolean',
186
- ),
187
- 'maxResults' => array(
188
- 'location' => 'query',
189
- 'type' => 'integer',
190
- ),
191
- 'pageToken' => array(
192
- 'location' => 'query',
193
- 'type' => 'string',
194
- ),
 
 
195
  ),
196
- ),
197
  )
198
- )
199
  );
200
- $this->channels = new Google_Service_Drive_Channels_Resource(
201
- $this,
202
- $this->serviceName,
203
- 'channels',
204
- array(
205
- 'methods' => array(
206
- 'stop' => array(
207
- 'path' => 'channels/stop',
208
- 'httpMethod' => 'POST',
209
- 'parameters' => array(),
210
- ),
 
211
  )
212
- )
213
  );
214
- $this->children = new Google_Service_Drive_Children_Resource(
215
- $this,
216
- $this->serviceName,
217
- 'children',
218
- array(
219
- 'methods' => array(
220
- 'delete' => array(
221
- 'path' => 'files/{folderId}/children/{childId}',
222
- 'httpMethod' => 'DELETE',
223
- 'parameters' => array(
224
- 'folderId' => array(
225
- 'location' => 'path',
226
- 'type' => 'string',
227
- 'required' => true,
228
- ),
229
- 'childId' => array(
230
- 'location' => 'path',
231
- 'type' => 'string',
232
- 'required' => true,
233
- ),
234
- ),
235
- ),
236
- 'get' => array(
237
- 'path' => 'files/{folderId}/children/{childId}',
238
- 'httpMethod' => 'GET',
239
- 'parameters' => array(
240
- 'folderId' => array(
241
- 'location' => 'path',
242
- 'type' => 'string',
243
- 'required' => true,
244
- ),
245
- 'childId' => array(
246
- 'location' => 'path',
247
- 'type' => 'string',
248
- 'required' => true,
249
- ),
250
- ),
251
- ),
252
- 'insert' => array(
253
- 'path' => 'files/{folderId}/children',
254
- 'httpMethod' => 'POST',
255
- 'parameters' => array(
256
- 'folderId' => array(
257
- 'location' => 'path',
258
- 'type' => 'string',
259
- 'required' => true,
260
- ),
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
261
  ),
262
- ),
263
- 'list' => array(
264
- 'path' => 'files/{folderId}/children',
265
- 'httpMethod' => 'GET',
266
- 'parameters' => array(
267
- 'folderId' => array(
268
- 'location' => 'path',
269
- 'type' => 'string',
270
- 'required' => true,
271
- ),
272
- 'q' => array(
273
- 'location' => 'query',
274
- 'type' => 'string',
275
- ),
276
- 'pageToken' => array(
277
- 'location' => 'query',
278
- 'type' => 'string',
279
- ),
280
- 'maxResults' => array(
281
- 'location' => 'query',
282
- 'type' => 'integer',
283
- ),
284
- ),
285
- ),
286
  )
287
- )
288
  );
289
- $this->comments = new Google_Service_Drive_Comments_Resource(
290
- $this,
291
- $this->serviceName,
292
- 'comments',
293
- array(
294
- 'methods' => array(
295
- 'delete' => array(
296
- 'path' => 'files/{fileId}/comments/{commentId}',
297
- 'httpMethod' => 'DELETE',
298
- 'parameters' => array(
299
- 'fileId' => array(
300
- 'location' => 'path',
301
- 'type' => 'string',
302
- 'required' => true,
303
- ),
304
- 'commentId' => array(
305
- 'location' => 'path',
306
- 'type' => 'string',
307
- 'required' => true,
308
- ),
309
- ),
310
- ),
311
- 'get' => array(
312
- 'path' => 'files/{fileId}/comments/{commentId}',
313
- 'httpMethod' => 'GET',
314
- 'parameters' => array(
315
- 'fileId' => array(
316
- 'location' => 'path',
317
- 'type' => 'string',
318
- 'required' => true,
319
- ),
320
- 'commentId' => array(
321
- 'location' => 'path',
322
- 'type' => 'string',
323
- 'required' => true,
324
- ),
325
- 'includeDeleted' => array(
326
- 'location' => 'query',
327
- 'type' => 'boolean',
328
- ),
329
- ),
330
- ),
331
- 'insert' => array(
332
- 'path' => 'files/{fileId}/comments',
333
- 'httpMethod' => 'POST',
334
- 'parameters' => array(
335
- 'fileId' => array(
336
- 'location' => 'path',
337
- 'type' => 'string',
338
- 'required' => true,
339
- ),
340
- ),
341
- ),
342
- 'list' => array(
343
- 'path' => 'files/{fileId}/comments',
344
- 'httpMethod' => 'GET',
345
- 'parameters' => array(
346
- 'fileId' => array(
347
- 'location' => 'path',
348
- 'type' => 'string',
349
- 'required' => true,
350
- ),
351
- 'pageToken' => array(
352
- 'location' => 'query',
353
- 'type' => 'string',
354
- ),
355
- 'updatedMin' => array(
356
- 'location' => 'query',
357
- 'type' => 'string',
358
- ),
359
- 'includeDeleted' => array(
360
- 'location' => 'query',
361
- 'type' => 'boolean',
362
- ),
363
- 'maxResults' => array(
364
- 'location' => 'query',
365
- 'type' => 'integer',
366
- ),
367
- ),
368
- ),
369
- 'patch' => array(
370
- 'path' => 'files/{fileId}/comments/{commentId}',
371
- 'httpMethod' => 'PATCH',
372
- 'parameters' => array(
373
- 'fileId' => array(
374
- 'location' => 'path',
375
- 'type' => 'string',
376
- 'required' => true,
377
- ),
378
- 'commentId' => array(
379
- 'location' => 'path',
380
- 'type' => 'string',
381
- 'required' => true,
382
- ),
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
383
  ),
384
- ),
385
- 'update' => array(
386
- 'path' => 'files/{fileId}/comments/{commentId}',
387
- 'httpMethod' => 'PUT',
388
- 'parameters' => array(
389
- 'fileId' => array(
390
- 'location' => 'path',
391
- 'type' => 'string',
392
- 'required' => true,
393
- ),
394
- 'commentId' => array(
395
- 'location' => 'path',
396
- 'type' => 'string',
397
- 'required' => true,
398
- ),
399
- ),
400
- ),
401
  )
402
- )
403
  );
404
- $this->files = new Google_Service_Drive_Files_Resource(
405
- $this,
406
- $this->serviceName,
407
- 'files',
408
- array(
409
- 'methods' => array(
410
- 'copy' => array(
411
- 'path' => 'files/{fileId}/copy',
412
- 'httpMethod' => 'POST',
413
- 'parameters' => array(
414
- 'fileId' => array(
415
- 'location' => 'path',
416
- 'type' => 'string',
417
- 'required' => true,
418
- ),
419
- 'convert' => array(
420
- 'location' => 'query',
421
- 'type' => 'boolean',
422
- ),
423
- 'ocrLanguage' => array(
424
- 'location' => 'query',
425
- 'type' => 'string',
426
- ),
427
- 'visibility' => array(
428
- 'location' => 'query',
429
- 'type' => 'string',
430
- ),
431
- 'pinned' => array(
432
- 'location' => 'query',
433
- 'type' => 'boolean',
434
- ),
435
- 'ocr' => array(
436
- 'location' => 'query',
437
- 'type' => 'boolean',
438
- ),
439
- 'timedTextTrackName' => array(
440
- 'location' => 'query',
441
- 'type' => 'string',
442
- ),
443
- 'timedTextLanguage' => array(
444
- 'location' => 'query',
445
- 'type' => 'string',
446
- ),
447
- ),
448
- ),
449
- 'delete' => array(
450
- 'path' => 'files/{fileId}',
451
- 'httpMethod' => 'DELETE',
452
- 'parameters' => array(
453
- 'fileId' => array(
454
- 'location' => 'path',
455
- 'type' => 'string',
456
- 'required' => true,
457
- ),
458
- ),
459
- ),
460
- 'get' => array(
461
- 'path' => 'files/{fileId}',
462
- 'httpMethod' => 'GET',
463
- 'parameters' => array(
464
- 'fileId' => array(
465
- 'location' => 'path',
466
- 'type' => 'string',
467
- 'required' => true,
468
- ),
469
- 'updateViewedDate' => array(
470
- 'location' => 'query',
471
- 'type' => 'boolean',
472
- ),
473
- 'projection' => array(
474
- 'location' => 'query',
475
- 'type' => 'string',
476
- ),
477
- ),
478
- ),
479
- 'insert' => array(
480
- 'path' => 'files',
481
- 'httpMethod' => 'POST',
482
- 'parameters' => array(
483
- 'convert' => array(
484
- 'location' => 'query',
485
- 'type' => 'boolean',
486
- ),
487
- 'useContentAsIndexableText' => array(
488
- 'location' => 'query',
489
- 'type' => 'boolean',
490
- ),
491
- 'ocrLanguage' => array(
492
- 'location' => 'query',
493
- 'type' => 'string',
494
- ),
495
- 'visibility' => array(
496
- 'location' => 'query',
497
- 'type' => 'string',
498
- ),
499
- 'pinned' => array(
500
- 'location' => 'query',
501
- 'type' => 'boolean',
502
- ),
503
- 'ocr' => array(
504
- 'location' => 'query',
505
- 'type' => 'boolean',
506
- ),
507
- 'timedTextTrackName' => array(
508
- 'location' => 'query',
509
- 'type' => 'string',
510
- ),
511
- 'timedTextLanguage' => array(
512
- 'location' => 'query',
513
- 'type' => 'string',
514
- ),
515
- ),
516
- ),
517
- 'list' => array(
518
- 'path' => 'files',
519
- 'httpMethod' => 'GET',
520
- 'parameters' => array(
521
- 'q' => array(
522
- 'location' => 'query',
523
- 'type' => 'string',
524
- ),
525
- 'pageToken' => array(
526
- 'location' => 'query',
527
- 'type' => 'string',
528
- ),
529
- 'projection' => array(
530
- 'location' => 'query',
531
- 'type' => 'string',
532
- ),
533
- 'maxResults' => array(
534
- 'location' => 'query',
535
- 'type' => 'integer',
536
- ),
537
- ),
538
- ),
539
- 'patch' => array(
540
- 'path' => 'files/{fileId}',
541
- 'httpMethod' => 'PATCH',
542
- 'parameters' => array(
543
- 'fileId' => array(
544
- 'location' => 'path',
545
- 'type' => 'string',
546
- 'required' => true,
547
- ),
548
- 'convert' => array(
549
- 'location' => 'query',
550
- 'type' => 'boolean',
551
- ),
552
- 'updateViewedDate' => array(
553
- 'location' => 'query',
554
- 'type' => 'boolean',
555
- ),
556
- 'setModifiedDate' => array(
557
- 'location' => 'query',
558
- 'type' => 'boolean',
559
- ),
560
- 'useContentAsIndexableText' => array(
561
- 'location' => 'query',
562
- 'type' => 'boolean',
563
- ),
564
- 'ocrLanguage' => array(
565
- 'location' => 'query',
566
- 'type' => 'string',
567
- ),
568
- 'pinned' => array(
569
- 'location' => 'query',
570
- 'type' => 'boolean',
571
- ),
572
- 'newRevision' => array(
573
- 'location' => 'query',
574
- 'type' => 'boolean',
575
- ),
576
- 'ocr' => array(
577
- 'location' => 'query',
578
- 'type' => 'boolean',
579
- ),
580
- 'timedTextLanguage' => array(
581
- 'location' => 'query',
582
- 'type' => 'string',
583
- ),
584
- 'timedTextTrackName' => array(
585
- 'location' => 'query',
586
- 'type' => 'string',
587
- ),
588
- ),
589
- ),
590
- 'touch' => array(
591
- 'path' => 'files/{fileId}/touch',
592
- 'httpMethod' => 'POST',
593
- 'parameters' => array(
594
- 'fileId' => array(
595
- 'location' => 'path',
596
- 'type' => 'string',
597
- 'required' => true,
598
- ),
599
- ),
600
- ),
601
- 'trash' => array(
602
- 'path' => 'files/{fileId}/trash',
603
- 'httpMethod' => 'POST',
604
- 'parameters' => array(
605
- 'fileId' => array(
606
- 'location' => 'path',
607
- 'type' => 'string',
608
- 'required' => true,
609
- ),
610
- ),
611
- ),
612
- 'untrash' => array(
613
- 'path' => 'files/{fileId}/untrash',
614
- 'httpMethod' => 'POST',
615
- 'parameters' => array(
616
- 'fileId' => array(
617
- 'location' => 'path',
618
- 'type' => 'string',
619
- 'required' => true,
620
- ),
621
- ),
622
- ),
623
- 'update' => array(
624
- 'path' => 'files/{fileId}',
625
- 'httpMethod' => 'PUT',
626
- 'parameters' => array(
627
- 'fileId' => array(
628
- 'location' => 'path',
629
- 'type' => 'string',
630
- 'required' => true,
631
- ),
632
- 'convert' => array(
633
- 'location' => 'query',
634
- 'type' => 'boolean',
635
- ),
636
- 'updateViewedDate' => array(
637
- 'location' => 'query',
638
- 'type' => 'boolean',
639
- ),
640
- 'setModifiedDate' => array(
641
- 'location' => 'query',
642
- 'type' => 'boolean',
643
- ),
644
- 'useContentAsIndexableText' => array(
645
- 'location' => 'query',
646
- 'type' => 'boolean',
647
- ),
648
- 'ocrLanguage' => array(
649
- 'location' => 'query',
650
- 'type' => 'string',
651
- ),
652
- 'pinned' => array(
653
- 'location' => 'query',
654
- 'type' => 'boolean',
655
- ),
656
- 'newRevision' => array(
657
- 'location' => 'query',
658
- 'type' => 'boolean',
659
- ),
660
- 'ocr' => array(
661
- 'location' => 'query',
662
- 'type' => 'boolean',
663
- ),
664
- 'timedTextLanguage' => array(
665
- 'location' => 'query',
666
- 'type' => 'string',
667
- ),
668
- 'timedTextTrackName' => array(
669
- 'location' => 'query',
670
- 'type' => 'string',
671
- ),
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
672
  ),
673
- ),
674
- 'watch' => array(
675
- 'path' => 'files/{fileId}/watch',
676
- 'httpMethod' => 'POST',
677
- 'parameters' => array(
678
- 'fileId' => array(
679
- 'location' => 'path',
680
- 'type' => 'string',
681
- 'required' => true,
682
- ),
683
- 'updateViewedDate' => array(
684
- 'location' => 'query',
685
- 'type' => 'boolean',
686
- ),
687
- 'projection' => array(
688
- 'location' => 'query',
689
- 'type' => 'string',
690
- ),
691
- ),
692
- ),
693
  )
694
- )
695
  );
696
- $this->parents = new Google_Service_Drive_Parents_Resource(
697
- $this,
698
- $this->serviceName,
699
- 'parents',
700
- array(
701
- 'methods' => array(
702
- 'delete' => array(
703
- 'path' => 'files/{fileId}/parents/{parentId}',
704
- 'httpMethod' => 'DELETE',
705
- 'parameters' => array(
706
- 'fileId' => array(
707
- 'location' => 'path',
708
- 'type' => 'string',
709
- 'required' => true,
710
- ),
711
- 'parentId' => array(
712
- 'location' => 'path',
713
- 'type' => 'string',
714
- 'required' => true,
715
- ),
716
- ),
717
- ),
718
- 'get' => array(
719
- 'path' => 'files/{fileId}/parents/{parentId}',
720
- 'httpMethod' => 'GET',
721
- 'parameters' => array(
722
- 'fileId' => array(
723
- 'location' => 'path',
724
- 'type' => 'string',
725
- 'required' => true,
726
- ),
727
- 'parentId' => array(
728
- 'location' => 'path',
729
- 'type' => 'string',
730
- 'required' => true,
731
- ),
732
- ),
733
- ),
734
- 'insert' => array(
735
- 'path' => 'files/{fileId}/parents',
736
- 'httpMethod' => 'POST',
737
- 'parameters' => array(
738
- 'fileId' => array(
739
- 'location' => 'path',
740
- 'type' => 'string',
741
- 'required' => true,
742
- ),
 
 
 
 
 
 
 
 
 
 
 
 
 
743
  ),
744
- ),
745
- 'list' => array(
746
- 'path' => 'files/{fileId}/parents',
747
- 'httpMethod' => 'GET',
748
- 'parameters' => array(
749
- 'fileId' => array(
750
- 'location' => 'path',
751
- 'type' => 'string',
752
- 'required' => true,
753
- ),
754
- ),
755
- ),
756
  )
757
- )
758
  );
759
  $this->permissions = new Google_Service_Drive_Permissions_Resource(
760
- $this,
761
- $this->serviceName,
762
- 'permissions',
763
- array(
764
- 'methods' => array(
765
- 'delete' => array(
766
- 'path' => 'files/{fileId}/permissions/{permissionId}',
767
- 'httpMethod' => 'DELETE',
768
- 'parameters' => array(
769
- 'fileId' => array(
770
- 'location' => 'path',
771
- 'type' => 'string',
772
- 'required' => true,
773
- ),
774
- 'permissionId' => array(
775
- 'location' => 'path',
776
- 'type' => 'string',
777
- 'required' => true,
778
- ),
779
- ),
780
- ),
781
- 'get' => array(
782
- 'path' => 'files/{fileId}/permissions/{permissionId}',
783
- 'httpMethod' => 'GET',
784
- 'parameters' => array(
785
- 'fileId' => array(
786
- 'location' => 'path',
787
- 'type' => 'string',
788
- 'required' => true,
789
- ),
790
- 'permissionId' => array(
791
- 'location' => 'path',
792
- 'type' => 'string',
793
- 'required' => true,
794
- ),
795
- ),
796
- ),
797
- 'getIdForEmail' => array(
798
- 'path' => 'permissionIds/{email}',
799
- 'httpMethod' => 'GET',
800
- 'parameters' => array(
801
- 'email' => array(
802
- 'location' => 'path',
803
- 'type' => 'string',
804
- 'required' => true,
805
- ),
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
806
  ),
807
- ),
808
- 'insert' => array(
809
- 'path' => 'files/{fileId}/permissions',
810
- 'httpMethod' => 'POST',
811
- 'parameters' => array(
812
- 'fileId' => array(
813
- 'location' => 'path',
814
- 'type' => 'string',
815
- 'required' => true,
816
- ),
817
- 'emailMessage' => array(
818
- 'location' => 'query',
819
- 'type' => 'string',
820
- ),
821
- 'sendNotificationEmails' => array(
822
- 'location' => 'query',
823
- 'type' => 'boolean',
824
- ),
825
- ),
826
- ),
827
- 'list' => array(
828
- 'path' => 'files/{fileId}/permissions',
829
- 'httpMethod' => 'GET',
830
- 'parameters' => array(
831
- 'fileId' => array(
832
- 'location' => 'path',
833
- 'type' => 'string',
834
- 'required' => true,
835
- ),
836
- ),
837
- ),
838
- 'patch' => array(
839
- 'path' => 'files/{fileId}/permissions/{permissionId}',
840
- 'httpMethod' => 'PATCH',
841
- 'parameters' => array(
842
- 'fileId' => array(
843
- 'location' => 'path',
844
- 'type' => 'string',
845
- 'required' => true,
846
- ),
847
- 'permissionId' => array(
848
- 'location' => 'path',
849
- 'type' => 'string',
850
- 'required' => true,
851
- ),
852
- 'transferOwnership' => array(
853
- 'location' => 'query',
854
- 'type' => 'boolean',
855
- ),
856
- ),
857
- ),
858
- 'update' => array(
859
- 'path' => 'files/{fileId}/permissions/{permissionId}',
860
- 'httpMethod' => 'PUT',
861
- 'parameters' => array(
862
- 'fileId' => array(
863
- 'location' => 'path',
864
- 'type' => 'string',
865
- 'required' => true,
866
- ),
867
- 'permissionId' => array(
868
- 'location' => 'path',
869
- 'type' => 'string',
870
- 'required' => true,
871
- ),
872
- 'transferOwnership' => array(
873
- 'location' => 'query',
874
- 'type' => 'boolean',
875
- ),
876
- ),
877
- ),
878
  )
879
- )
880
  );
881
- $this->properties = new Google_Service_Drive_Properties_Resource(
882
- $this,
883
- $this->serviceName,
884
- 'properties',
885
- array(
886
- 'methods' => array(
887
- 'delete' => array(
888
- 'path' => 'files/{fileId}/properties/{propertyKey}',
889
- 'httpMethod' => 'DELETE',
890
- 'parameters' => array(
891
- 'fileId' => array(
892
- 'location' => 'path',
893
- 'type' => 'string',
894
- 'required' => true,
895
- ),
896
- 'propertyKey' => array(
897
- 'location' => 'path',
898
- 'type' => 'string',
899
- 'required' => true,
900
- ),
901
- 'visibility' => array(
902
- 'location' => 'query',
903
- 'type' => 'string',
904
- ),
905
- ),
906
- ),
907
- 'get' => array(
908
- 'path' => 'files/{fileId}/properties/{propertyKey}',
909
- 'httpMethod' => 'GET',
910
- 'parameters' => array(
911
- 'fileId' => array(
912
- 'location' => 'path',
913
- 'type' => 'string',
914
- 'required' => true,
915
- ),
916
- 'propertyKey' => array(
917
- 'location' => 'path',
918
- 'type' => 'string',
919
- 'required' => true,
920
- ),
921
- 'visibility' => array(
922
- 'location' => 'query',
923
- 'type' => 'string',
924
- ),
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
925
  ),
926
- ),
927
- 'insert' => array(
928
- 'path' => 'files/{fileId}/properties',
929
- 'httpMethod' => 'POST',
930
- 'parameters' => array(
931
- 'fileId' => array(
932
- 'location' => 'path',
933
- 'type' => 'string',
934
- 'required' => true,
935
- ),
936
- ),
937
- ),
938
- 'list' => array(
939
- 'path' => 'files/{fileId}/properties',
940
- 'httpMethod' => 'GET',
941
- 'parameters' => array(
942
- 'fileId' => array(
943
- 'location' => 'path',
944
- 'type' => 'string',
945
- 'required' => true,
946
- ),
947
- ),
948
- ),
949
- 'patch' => array(
950
- 'path' => 'files/{fileId}/properties/{propertyKey}',
951
- 'httpMethod' => 'PATCH',
952
- 'parameters' => array(
953
- 'fileId' => array(
954
- 'location' => 'path',
955
- 'type' => 'string',
956
- 'required' => true,
957
- ),
958
- 'propertyKey' => array(
959
- 'location' => 'path',
960
- 'type' => 'string',
961
- 'required' => true,
962
- ),
963
- 'visibility' => array(
964
- 'location' => 'query',
965
- 'type' => 'string',
966
- ),
967
- ),
968
- ),
969
- 'update' => array(
970
- 'path' => 'files/{fileId}/properties/{propertyKey}',
971
- 'httpMethod' => 'PUT',
972
- 'parameters' => array(
973
- 'fileId' => array(
974
- 'location' => 'path',
975
- 'type' => 'string',
976
- 'required' => true,
977
- ),
978
- 'propertyKey' => array(
979
- 'location' => 'path',
980
- 'type' => 'string',
981
- 'required' => true,
982
- ),
983
- 'visibility' => array(
984
- 'location' => 'query',
985
- 'type' => 'string',
986
- ),
987
- ),
988
- ),
989
  )
990
- )
991
  );
992
- $this->realtime = new Google_Service_Drive_Realtime_Resource(
993
- $this,
994
- $this->serviceName,
995
- 'realtime',
996
- array(
997
- 'methods' => array(
998
- 'get' => array(
999
- 'path' => 'files/{fileId}/realtime',
1000
- 'httpMethod' => 'GET',
1001
- 'parameters' => array(
1002
- 'fileId' => array(
1003
- 'location' => 'path',
1004
- 'type' => 'string',
1005
- 'required' => true,
1006
- ),
1007
- ),
1008
- ),
1009
- 'update' => array(
1010
- 'path' => 'files/{fileId}/realtime',
1011
- 'httpMethod' => 'PUT',
1012
- 'parameters' => array(
1013
- 'fileId' => array(
1014
- 'location' => 'path',
1015
- 'type' => 'string',
1016
- 'required' => true,
1017
- ),
1018
- 'baseRevision' => array(
1019
- 'location' => 'query',
1020
- 'type' => 'string',
1021
- ),
 
 
1022
  ),
1023
- ),
1024
  )
1025
- )
1026
  );
1027
- $this->replies = new Google_Service_Drive_Replies_Resource(
1028
- $this,
1029
- $this->serviceName,
1030
- 'replies',
1031
- array(
1032
- 'methods' => array(
1033
- 'delete' => array(
1034
- 'path' => 'files/{fileId}/comments/{commentId}/replies/{replyId}',
1035
- 'httpMethod' => 'DELETE',
1036
- 'parameters' => array(
1037
- 'fileId' => array(
1038
- 'location' => 'path',
1039
- 'type' => 'string',
1040
- 'required' => true,
1041
- ),
1042
- 'commentId' => array(
1043
- 'location' => 'path',
1044
- 'type' => 'string',
1045
- 'required' => true,
1046
- ),
1047
- 'replyId' => array(
1048
- 'location' => 'path',
1049
- 'type' => 'string',
1050
- 'required' => true,
1051
- ),
1052
- ),
1053
- ),
1054
- 'get' => array(
1055
- 'path' => 'files/{fileId}/comments/{commentId}/replies/{replyId}',
1056
- 'httpMethod' => 'GET',
1057
- 'parameters' => array(
1058
- 'fileId' => array(
1059
- 'location' => 'path',
1060
- 'type' => 'string',
1061
- 'required' => true,
1062
- ),
1063
- 'commentId' => array(
1064
- 'location' => 'path',
1065
- 'type' => 'string',
1066
- 'required' => true,
1067
- ),
1068
- 'replyId' => array(
1069
- 'location' => 'path',
1070
- 'type' => 'string',
1071
- 'required' => true,
1072
- ),
1073
- 'includeDeleted' => array(
1074
- 'location' => 'query',
1075
- 'type' => 'boolean',
1076
- ),
1077
- ),
1078
- ),
1079
- 'insert' => array(
1080
- 'path' => 'files/{fileId}/comments/{commentId}/replies',
1081
- 'httpMethod' => 'POST',
1082
- 'parameters' => array(
1083
- 'fileId' => array(
1084
- 'location' => 'path',
1085
- 'type' => 'string',
1086
- 'required' => true,
1087
- ),
1088
- 'commentId' => array(
1089
- 'location' => 'path',
1090
- 'type' => 'string',
1091
- 'required' => true,
1092
- ),
1093
- ),
1094
- ),
1095
- 'list' => array(
1096
- 'path' => 'files/{fileId}/comments/{commentId}/replies',
1097
- 'httpMethod' => 'GET',
1098
- 'parameters' => array(
1099
- 'fileId' => array(
1100
- 'location' => 'path',
1101
- 'type' => 'string',
1102
- 'required' => true,
1103
- ),
1104
- 'commentId' => array(
1105
- 'location' => 'path',
1106
- 'type' => 'string',
1107
- 'required' => true,
1108
- ),
1109
- 'pageToken' => array(
1110
- 'location' => 'query',
1111
- 'type' => 'string',
1112
- ),
1113
- 'includeDeleted' => array(
1114
- 'location' => 'query',
1115
- 'type' => 'boolean',
1116
- ),
1117
- 'maxResults' => array(
1118
- 'location' => 'query',
1119
- 'type' => 'integer',
1120
- ),
1121
- ),
1122
- ),
1123
- 'patch' => array(
1124
- 'path' => 'files/{fileId}/comments/{commentId}/replies/{replyId}',
1125
- 'httpMethod' => 'PATCH',
1126
- 'parameters' => array(
1127
- 'fileId' => array(
1128
- 'location' => 'path',
1129
- 'type' => 'string',
1130
- 'required' => true,
1131
- ),
1132
- 'commentId' => array(
1133
- 'location' => 'path',
1134
- 'type' => 'string',
1135
- 'required' => true,
1136
- ),
1137
- 'replyId' => array(
1138
- 'location' => 'path',
1139
- 'type' => 'string',
1140
- 'required' => true,
1141
- ),
1142
- ),
1143
- ),
1144
- 'update' => array(
1145
- 'path' => 'files/{fileId}/comments/{commentId}/replies/{replyId}',
1146
- 'httpMethod' => 'PUT',
1147
- 'parameters' => array(
1148
- 'fileId' => array(
1149
- 'location' => 'path',
1150
- 'type' => 'string',
1151
- 'required' => true,
1152
- ),
1153
- 'commentId' => array(
1154
- 'location' => 'path',
1155
- 'type' => 'string',
1156
- 'required' => true,
1157
- ),
1158
- 'replyId' => array(
1159
- 'location' => 'path',
1160
- 'type' => 'string',
1161
- 'required' => true,
1162
- ),
 
 
1163
  ),
1164
- ),
1165
  )
1166
- )
1167
  );
1168
- $this->revisions = new Google_Service_Drive_Revisions_Resource(
1169
- $this,
1170
- $this->serviceName,
1171
- 'revisions',
1172
- array(
1173
- 'methods' => array(
1174
- 'delete' => array(
1175
- 'path' => 'files/{fileId}/revisions/{revisionId}',
1176
- 'httpMethod' => 'DELETE',
1177
- 'parameters' => array(
1178
- 'fileId' => array(
1179
- 'location' => 'path',
1180
- 'type' => 'string',
1181
- 'required' => true,
1182
- ),
1183
- 'revisionId' => array(
1184
- 'location' => 'path',
1185
- 'type' => 'string',
1186
- 'required' => true,
1187
- ),
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1188
  ),
1189
- ),
1190
- 'get' => array(
1191
- 'path' => 'files/{fileId}/revisions/{revisionId}',
1192
- 'httpMethod' => 'GET',
1193
- 'parameters' => array(
1194
- 'fileId' => array(
1195
- 'location' => 'path',
1196
- 'type' => 'string',
1197
- 'required' => true,
1198
- ),
1199
- 'revisionId' => array(
1200
- 'location' => 'path',
1201
- 'type' => 'string',
1202
- 'required' => true,
1203
- ),
1204
- ),
1205
- ),
1206
- 'list' => array(
1207
- 'path' => 'files/{fileId}/revisions',
1208
- 'httpMethod' => 'GET',
1209
- 'parameters' => array(
1210
- 'fileId' => array(
1211
- 'location' => 'path',
1212
- 'type' => 'string',
1213
- 'required' => true,
1214
- ),
1215
- ),
1216
- ),
1217
- 'patch' => array(
1218
- 'path' => 'files/{fileId}/revisions/{revisionId}',
1219
- 'httpMethod' => 'PATCH',
1220
- 'parameters' => array(
1221
- 'fileId' => array(
1222
- 'location' => 'path',
1223
- 'type' => 'string',
1224
- 'required' => true,
1225
- ),
1226
- 'revisionId' => array(
1227
- 'location' => 'path',
1228
- 'type' => 'string',
1229
- 'required' => true,
1230
- ),
1231
- ),
1232
- ),
1233
- 'update' => array(
1234
- 'path' => 'files/{fileId}/revisions/{revisionId}',
1235
- 'httpMethod' => 'PUT',
1236
- 'parameters' => array(
1237
- 'fileId' => array(
1238
- 'location' => 'path',
1239
- 'type' => 'string',
1240
- 'required' => true,
1241
- ),
1242
- 'revisionId' => array(
1243
- 'location' => 'path',
1244
- 'type' => 'string',
1245
- 'required' => true,
1246
- ),
1247
- ),
1248
- ),
1249
  )
1250
- )
1251
  );
1252
  }
1253
  }
1254
 
1255
-
1256
  /**
1257
  * The "about" collection of methods.
1258
  * Typical usage is:
@@ -1263,7 +1261,6 @@ class Google_Service_Drive extends Google_ApiService
1263
  */
1264
  class Google_Service_Drive_About_Resource extends Google_Service_Resource
1265
  {
1266
-
1267
  /**
1268
  * Gets the information about the current user along with Drive API settings
1269
  * (about.get)
@@ -1299,7 +1296,6 @@ class Google_Service_Drive_About_Resource extends Google_Service_Resource
1299
  */
1300
  class Google_Service_Drive_Apps_Resource extends Google_Service_Resource
1301
  {
1302
-
1303
  /**
1304
  * Gets a specific app. (apps.get)
1305
  *
@@ -1343,7 +1339,6 @@ class Google_Service_Drive_Apps_Resource extends Google_Service_Resource
1343
  */
1344
  class Google_Service_Drive_Changes_Resource extends Google_Service_Resource
1345
  {
1346
-
1347
  /**
1348
  * Gets a specific change. (changes.get)
1349
  *
@@ -1427,7 +1422,6 @@ class Google_Service_Drive_Changes_Resource extends Google_Service_Resource
1427
  */
1428
  class Google_Service_Drive_Channels_Resource extends Google_Service_Resource
1429
  {
1430
-
1431
  /**
1432
  * Stop watching resources through this channel (channels.stop)
1433
  *
@@ -1453,7 +1447,6 @@ class Google_Service_Drive_Channels_Resource extends Google_Service_Resource
1453
  */
1454
  class Google_Service_Drive_Children_Resource extends Google_Service_Resource
1455
  {
1456
-
1457
  /**
1458
  * Removes a child from a folder. (children.delete)
1459
  *
@@ -1542,7 +1535,6 @@ class Google_Service_Drive_Children_Resource extends Google_Service_Resource
1542
  */
1543
  class Google_Service_Drive_Comments_Resource extends Google_Service_Resource
1544
  {
1545
-
1546
  /**
1547
  * Deletes a comment. (comments.delete)
1548
  *
@@ -1680,7 +1672,6 @@ class Google_Service_Drive_Comments_Resource extends Google_Service_Resource
1680
  */
1681
  class Google_Service_Drive_Files_Resource extends Google_Service_Resource
1682
  {
1683
-
1684
  /**
1685
  * Creates a copy of the specified file. (files.copy)
1686
  *
@@ -1970,7 +1961,6 @@ class Google_Service_Drive_Files_Resource extends Google_Service_Resource
1970
  */
1971
  class Google_Service_Drive_Parents_Resource extends Google_Service_Resource
1972
  {
1973
-
1974
  /**
1975
  * Removes a parent from a file. (parents.delete)
1976
  *
@@ -2053,15 +2043,14 @@ class Google_Service_Drive_Parents_Resource extends Google_Service_Resource
2053
  */
2054
  class Google_Service_Drive_Permissions_Resource extends Google_Service_Resource
2055
  {
2056
-
2057
  /**
2058
  * Deletes a permission from a file. (permissions.delete)
2059
  *
2060
  * @param string $fileId
2061
- * The ID for the file.
2062
  * @param string $permissionId
2063
- * The ID for the permission.
2064
- * @param array $optParams Optional parameters.
2065
  */
2066
  public function delete($fileId, $permissionId, $optParams = array())
2067
  {
@@ -2075,10 +2064,10 @@ class Google_Service_Drive_Permissions_Resource extends Google_Service_Resource
2075
  * Gets a permission by ID. (permissions.get)
2076
  *
2077
  * @param string $fileId
2078
- * The ID for the file.
2079
  * @param string $permissionId
2080
- * The ID for the permission.
2081
- * @param array $optParams Optional parameters.
2082
  *
2083
  * @return Google_Service_Drive_Permission
2084
  */
@@ -2151,11 +2140,11 @@ class Google_Service_Drive_Permissions_Resource extends Google_Service_Resource
2151
  * (permissions.patch)
2152
  *
2153
  * @param string $fileId
2154
- * The ID for the file.
2155
  * @param string $permissionId
2156
- * The ID for the permission.
2157
  * @param Google_Permission $postBody
2158
- * @param array $optParams Optional parameters.
2159
  *
2160
  * @opt_param bool transferOwnership
2161
  * Whether changing a role to 'owner' should also downgrade the current owners to writers.
@@ -2173,11 +2162,11 @@ class Google_Service_Drive_Permissions_Resource extends Google_Service_Resource
2173
  * Updates a permission. (permissions.update)
2174
  *
2175
  * @param string $fileId
2176
- * The ID for the file.
2177
  * @param string $permissionId
2178
- * The ID for the permission.
2179
  * @param Google_Permission $postBody
2180
- * @param array $optParams Optional parameters.
2181
  *
2182
  * @opt_param bool transferOwnership
2183
  * Whether changing a role to 'owner' should also downgrade the current owners to writers.
@@ -2202,15 +2191,14 @@ class Google_Service_Drive_Permissions_Resource extends Google_Service_Resource
2202
  */
2203
  class Google_Service_Drive_Properties_Resource extends Google_Service_Resource
2204
  {
2205
-
2206
  /**
2207
  * Deletes a property. (properties.delete)
2208
  *
2209
  * @param string $fileId
2210
- * The ID of the file.
2211
  * @param string $propertyKey
2212
- * The key of the property.
2213
- * @param array $optParams Optional parameters.
2214
  *
2215
  * @opt_param string visibility
2216
  * The visibility of the property.
@@ -2227,10 +2215,10 @@ class Google_Service_Drive_Properties_Resource extends Google_Service_Resource
2227
  * Gets a property by its key. (properties.get)
2228
  *
2229
  * @param string $fileId
2230
- * The ID of the file.
2231
  * @param string $propertyKey
2232
- * The key of the property.
2233
- * @param array $optParams Optional parameters.
2234
  *
2235
  * @opt_param string visibility
2236
  * The visibility of the property.
@@ -2283,11 +2271,11 @@ class Google_Service_Drive_Properties_Resource extends Google_Service_Resource
2283
  * Updates a property. This method supports patch semantics. (properties.patch)
2284
  *
2285
  * @param string $fileId
2286
- * The ID of the file.
2287
  * @param string $propertyKey
2288
- * The key of the property.
2289
  * @param Google_Property $postBody
2290
- * @param array $optParams Optional parameters.
2291
  *
2292
  * @opt_param string visibility
2293
  * The visibility of the property.
@@ -2305,11 +2293,11 @@ class Google_Service_Drive_Properties_Resource extends Google_Service_Resource
2305
  * Updates a property. (properties.update)
2306
  *
2307
  * @param string $fileId
2308
- * The ID of the file.
2309
  * @param string $propertyKey
2310
- * The key of the property.
2311
  * @param Google_Property $postBody
2312
- * @param array $optParams Optional parameters.
2313
  *
2314
  * @opt_param string visibility
2315
  * The visibility of the property.
@@ -2334,7 +2322,6 @@ class Google_Service_Drive_Properties_Resource extends Google_Service_Resource
2334
  */
2335
  class Google_Service_Drive_Realtime_Resource extends Google_Service_Resource
2336
  {
2337
-
2338
  /**
2339
  * Exports the contents of the Realtime API data model associated with this file
2340
  * as JSON. (realtime.get)
@@ -2384,7 +2371,6 @@ class Google_Service_Drive_Realtime_Resource extends Google_Service_Resource
2384
  */
2385
  class Google_Service_Drive_Replies_Resource extends Google_Service_Resource
2386
  {
2387
-
2388
  /**
2389
  * Deletes a reply. (replies.delete)
2390
  *
@@ -2529,15 +2515,14 @@ class Google_Service_Drive_Replies_Resource extends Google_Service_Resource
2529
  */
2530
  class Google_Service_Drive_Revisions_Resource extends Google_Service_Resource
2531
  {
2532
-
2533
  /**
2534
  * Removes a revision. (revisions.delete)
2535
  *
2536
  * @param string $fileId
2537
- * The ID of the file.
2538
  * @param string $revisionId
2539
- * The ID of the revision.
2540
- * @param array $optParams Optional parameters.
2541
  */
2542
  public function delete($fileId, $revisionId, $optParams = array())
2543
  {
@@ -2551,10 +2536,10 @@ class Google_Service_Drive_Revisions_Resource extends Google_Service_Resource
2551
  * Gets a specific revision. (revisions.get)
2552
  *
2553
  * @param string $fileId
2554
- * The ID of the file.
2555
  * @param string $revisionId
2556
- * The ID of the revision.
2557
- * @param array $optParams Optional parameters.
2558
  *
2559
  * @return Google_Service_Drive_Revision
2560
  */
@@ -2587,11 +2572,11 @@ class Google_Service_Drive_Revisions_Resource extends Google_Service_Resource
2587
  * Updates a revision. This method supports patch semantics. (revisions.patch)
2588
  *
2589
  * @param string $fileId
2590
- * The ID for the file.
2591
  * @param string $revisionId
2592
- * The ID for the revision.
2593
  * @param Google_Revision $postBody
2594
- * @param array $optParams Optional parameters.
2595
  *
2596
  * @return Google_Service_Drive_Revision
2597
  */
@@ -2607,11 +2592,11 @@ class Google_Service_Drive_Revisions_Resource extends Google_Service_Resource
2607
  * Updates a revision. (revisions.update)
2608
  *
2609
  * @param string $fileId
2610
- * The ID for the file.
2611
  * @param string $revisionId
2612
- * The ID for the revision.
2613
  * @param Google_Revision $postBody
2614
- * @param array $optParams Optional parameters.
2615
  *
2616
  * @return Google_Service_Drive_Revision
2617
  */
@@ -2624,23 +2609,22 @@ class Google_Service_Drive_Revisions_Resource extends Google_Service_Resource
2624
  }
2625
  }
2626
 
2627
-
2628
  class Google_Service_Drive_About extends Google_Collection
2629
  {
2630
- protected $additionalRoleInfoType = 'Google_Service_Drive_AboutAdditionalRoleInfo';
2631
  protected $additionalRoleInfoDataType = 'array';
2632
  public $domainSharingPolicy;
2633
  public $etag;
2634
- protected $exportFormatsType = 'Google_Service_Drive_AboutExportFormats';
2635
  protected $exportFormatsDataType = 'array';
2636
- protected $featuresType = 'Google_Service_Drive_AboutFeatures';
2637
- protected $featuresDataType = 'array';
2638
- protected $importFormatsType = 'Google_Service_Drive_AboutImportFormats';
2639
  protected $importFormatsDataType = 'array';
2640
  public $isCurrentAppInstalled;
2641
  public $kind;
2642
  public $largestChangeId;
2643
- protected $maxUploadSizesType = 'Google_Service_Drive_AboutMaxUploadSizes';
2644
  protected $maxUploadSizesDataType = 'array';
2645
  public $name;
2646
  public $permissionId;
@@ -2651,7 +2635,7 @@ class Google_Service_Drive_About extends Google_Collection
2651
  public $remainingChangeIds;
2652
  public $rootFolderId;
2653
  public $selfLink;
2654
- protected $userType = 'Google_Service_Drive_User';
2655
  protected $userDataType = '';
2656
 
2657
  public function setAdditionalRoleInfo($additionalRoleInfo)
@@ -2857,7 +2841,7 @@ class Google_Service_Drive_About extends Google_Collection
2857
 
2858
  class Google_Service_Drive_AboutAdditionalRoleInfo extends Google_Collection
2859
  {
2860
- protected $roleSetsType = 'Google_Service_Drive_AboutAdditionalRoleInfoRoleSets';
2861
  protected $roleSetsDataType = 'array';
2862
  public $type;
2863
 
@@ -3017,7 +3001,7 @@ class Google_Service_Drive_App extends Google_Collection
3017
  public $authorized;
3018
  public $createInFolderTemplate;
3019
  public $createUrl;
3020
- protected $iconsType = 'Google_Service_Drive_AppIcons';
3021
  protected $iconsDataType = 'array';
3022
  public $id;
3023
  public $installed;
@@ -3299,7 +3283,7 @@ class Google_Service_Drive_AppIcons extends Google_ApiModel
3299
  class Google_Service_Drive_AppList extends Google_Collection
3300
  {
3301
  public $etag;
3302
- protected $itemsType = 'Google_Service_Drive_App';
3303
  protected $itemsDataType = 'array';
3304
  public $kind;
3305
  public $selfLink;
@@ -3348,7 +3332,7 @@ class Google_Service_Drive_AppList extends Google_Collection
3348
  class Google_Service_Drive_Change extends Google_ApiModel
3349
  {
3350
  public $deleted;
3351
- protected $fileType = 'Google_Service_Drive_DriveFile';
3352
  protected $fileDataType = '';
3353
  public $fileId;
3354
  public $id;
@@ -3430,7 +3414,7 @@ class Google_Service_Drive_Change extends Google_ApiModel
3430
  class Google_Service_Drive_ChangeList extends Google_Collection
3431
  {
3432
  public $etag;
3433
- protected $itemsType = 'Google_Service_Drive_Change';
3434
  protected $itemsDataType = 'array';
3435
  public $kind;
3436
  public $largestChangeId;
@@ -3626,7 +3610,7 @@ class Google_Service_Drive_Channel extends Google_ApiModel
3626
  class Google_Service_Drive_ChildList extends Google_Collection
3627
  {
3628
  public $etag;
3629
- protected $itemsType = 'Google_Service_Drive_ChildReference';
3630
  protected $itemsDataType = 'array';
3631
  public $kind;
3632
  public $nextLink;
@@ -3745,11 +3729,11 @@ class Google_Service_Drive_ChildReference extends Google_ApiModel
3745
  class Google_Service_Drive_Comment extends Google_Collection
3746
  {
3747
  public $anchor;
3748
- protected $authorType = 'Google_Service_Drive_User';
3749
  protected $authorDataType = '';
3750
  public $commentId;
3751
  public $content;
3752
- protected $contextType = 'Google_Service_Drive_CommentContext';
3753
  protected $contextDataType = '';
3754
  public $createdDate;
3755
  public $deleted;
@@ -3758,7 +3742,7 @@ class Google_Service_Drive_Comment extends Google_Collection
3758
  public $htmlContent;
3759
  public $kind;
3760
  public $modifiedDate;
3761
- protected $repliesType = 'Google_Service_Drive_CommentReply';
3762
  protected $repliesDataType = 'array';
3763
  public $selfLink;
3764
  public $status;
@@ -3942,7 +3926,7 @@ class Google_Service_Drive_CommentContext extends Google_ApiModel
3942
 
3943
  class Google_Service_Drive_CommentList extends Google_Collection
3944
  {
3945
- protected $itemsType = 'Google_Service_Drive_Comment';
3946
  protected $itemsDataType = 'array';
3947
  public $kind;
3948
  public $nextLink;
@@ -4002,7 +3986,7 @@ class Google_Service_Drive_CommentList extends Google_Collection
4002
 
4003
  class Google_Service_Drive_CommentReply extends Google_ApiModel
4004
  {
4005
- protected $authorType = 'Google_Service_Drive_User';
4006
  protected $authorDataType = '';
4007
  public $content;
4008
  public $createdDate;
@@ -4106,7 +4090,7 @@ class Google_Service_Drive_CommentReply extends Google_ApiModel
4106
 
4107
  class Google_Service_Drive_CommentReplyList extends Google_Collection
4108
  {
4109
- protected $itemsType = 'Google_Service_Drive_CommentReply';
4110
  protected $itemsDataType = 'array';
4111
  public $kind;
4112
  public $nextLink;
@@ -4183,14 +4167,14 @@ class Google_Service_Drive_DriveFile extends Google_Collection
4183
  public $headRevisionId;
4184
  public $iconLink;
4185
  public $id;
4186
- protected $imageMediaMetadataType = 'Google_Service_Drive_DriveFileImageMediaMetadata';
4187
  protected $imageMediaMetadataDataType = '';
4188
- protected $indexableTextType = 'Google_Service_Drive_DriveFileIndexableText';
4189
- protected $indexableTextDataType = '';
4190
  public $kind;
4191
- protected $labelsType = 'Google_Service_Drive_DriveFileLabels';
4192
- protected $labelsDataType = '';
4193
- protected $lastModifyingUserType = 'Google_Service_Drive_User';
4194
  protected $lastModifyingUserDataType = '';
4195
  public $lastModifyingUserName;
4196
  public $lastViewedByMeDate;
@@ -4201,21 +4185,21 @@ class Google_Service_Drive_DriveFile extends Google_Collection
4201
  public $openWithLinks;
4202
  public $originalFilename;
4203
  public $ownerNames;
4204
- protected $ownersType = 'Google_Service_Drive_User';
4205
- protected $ownersDataType = 'array';
4206
- protected $parentsType = 'Google_Service_Drive_ParentReference';
4207
- protected $parentsDataType = 'array';
4208
- protected $propertiesType = 'Google_Service_Drive_Property';
4209
  protected $propertiesDataType = 'array';
4210
  public $quotaBytesUsed;
4211
  public $selfLink;
4212
  public $shared;
4213
  public $sharedWithMeDate;
4214
- protected $thumbnailType = 'Google_Service_Drive_DriveFileThumbnail';
4215
  protected $thumbnailDataType = '';
4216
  public $thumbnailLink;
4217
  public $title;
4218
- protected $userPermissionType = 'Google_Service_Drive_Permission';
4219
  protected $userPermissionDataType = '';
4220
  public $webContentLink;
4221
  public $webViewLink;
@@ -4687,7 +4671,7 @@ class Google_Service_Drive_DriveFileImageMediaMetadata extends Google_ApiModel
4687
  public $height;
4688
  public $isoSpeed;
4689
  public $lens;
4690
- protected $locationType = 'Google_Service_Drive_DriveFileImageMediaMetadataLocation';
4691
  protected $locationDataType = '';
4692
  public $maxApertureValue;
4693
  public $meteringMode;
@@ -5048,7 +5032,7 @@ class Google_Service_Drive_DriveFileThumbnail extends Google_ApiModel
5048
  class Google_Service_Drive_FileList extends Google_Collection
5049
  {
5050
  public $etag;
5051
- protected $itemsType = 'Google_Service_Drive_DriveFile';
5052
  protected $itemsDataType = 'array';
5053
  public $kind;
5054
  public $nextLink;
@@ -5119,7 +5103,7 @@ class Google_Service_Drive_FileList extends Google_Collection
5119
  class Google_Service_Drive_ParentList extends Google_Collection
5120
  {
5121
  public $etag;
5122
- protected $itemsType = 'Google_Service_Drive_ParentReference';
5123
  protected $itemsDataType = 'array';
5124
  public $kind;
5125
  public $selfLink;
@@ -5411,7 +5395,7 @@ class Google_Service_Drive_PermissionId extends Google_ApiModel
5411
  class Google_Service_Drive_PermissionList extends Google_Collection
5412
  {
5413
  public $etag;
5414
- protected $itemsType = 'Google_Service_Drive_Permission';
5415
  protected $itemsDataType = 'array';
5416
  public $kind;
5417
  public $selfLink;
@@ -5530,7 +5514,7 @@ class Google_Service_Drive_Property extends Google_ApiModel
5530
  class Google_Service_Drive_PropertyList extends Google_Collection
5531
  {
5532
  public $etag;
5533
- protected $itemsType = 'Google_Service_Drive_Property';
5534
  protected $itemsDataType = 'array';
5535
  public $kind;
5536
  public $selfLink;
@@ -5584,7 +5568,7 @@ class Google_Service_Drive_Revision extends Google_ApiModel
5584
  public $fileSize;
5585
  public $id;
5586
  public $kind;
5587
- protected $lastModifyingUserType = 'Google_Service_Drive_User';
5588
  protected $lastModifyingUserDataType = '';
5589
  public $lastModifyingUserName;
5590
  public $md5Checksum;
@@ -5782,7 +5766,7 @@ class Google_Service_Drive_Revision extends Google_ApiModel
5782
  class Google_Service_Drive_RevisionList extends Google_Collection
5783
  {
5784
  public $etag;
5785
- protected $itemsType = 'Google_Service_Drive_Revision';
5786
  protected $itemsDataType = 'array';
5787
  public $kind;
5788
  public $selfLink;
@@ -5834,7 +5818,7 @@ class Google_Service_Drive_User extends Google_ApiModel
5834
  public $isAuthenticatedUser;
5835
  public $kind;
5836
  public $permissionId;
5837
- protected $pictureType = 'Google_Service_Drive_UserPicture';
5838
  protected $pictureDataType = '';
5839
 
5840
  public function setDisplayName($displayName)
60
  public $replies;
61
  public $revisions;
62
 
 
63
  /**
64
  * Constructs the internal representation of the Drive service.
65
  *
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:
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)
1296
  */
1297
  class Google_Service_Drive_Apps_Resource extends Google_Service_Resource
1298
  {
 
1299
  /**
1300
  * Gets a specific app. (apps.get)
1301
  *
1339
  */
1340
  class Google_Service_Drive_Changes_Resource extends Google_Service_Resource
1341
  {
 
1342
  /**
1343
  * Gets a specific change. (changes.get)
1344
  *
1422
  */
1423
  class Google_Service_Drive_Channels_Resource extends Google_Service_Resource
1424
  {
 
1425
  /**
1426
  * Stop watching resources through this channel (channels.stop)
1427
  *
1447
  */
1448
  class Google_Service_Drive_Children_Resource extends Google_Service_Resource
1449
  {
 
1450
  /**
1451
  * Removes a child from a folder. (children.delete)
1452
  *
1535
  */
1536
  class Google_Service_Drive_Comments_Resource extends Google_Service_Resource
1537
  {
 
1538
  /**
1539
  * Deletes a comment. (comments.delete)
1540
  *
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
  *
1961
  */
1962
  class Google_Service_Drive_Parents_Resource extends Google_Service_Resource
1963
  {
 
1964
  /**
1965
  * Removes a parent from a file. (parents.delete)
1966
  *
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
  {
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
  */
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.
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.
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.
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.
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.
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.
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)
2371
  */
2372
  class Google_Service_Drive_Replies_Resource extends Google_Service_Resource
2373
  {
 
2374
  /**
2375
  * Deletes a reply. (replies.delete)
2376
  *
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
  {
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
  */
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
  */
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
  */
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;
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)
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
 
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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)
src/Google/Service/Exception.php CHANGED
@@ -15,13 +15,13 @@ class Google_Service_Exception extends Google_ApiException
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);
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);
src/Google/Service/Oauth2.php CHANGED
@@ -56,56 +56,56 @@ class Google_Service_Oauth2 extends Google_ApiService
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
 
@@ -129,7 +129,6 @@ class Google_Service_Oauth2 extends Google_ApiService
129
  }
130
  }
131
 
132
-
133
  /**
134
  * The "userinfo" collection of methods.
135
  * Typical usage is:
@@ -140,7 +139,6 @@ class Google_Service_Oauth2 extends Google_ApiService
140
  */
141
  class Google_Service_Oauth2_Userinfo_Resource extends Google_Service_Resource
142
  {
143
-
144
  /**
145
  * (userinfo.get)
146
  *
@@ -167,7 +165,6 @@ class Google_Service_Oauth2_Userinfo_Resource extends Google_Service_Resource
167
  */
168
  class Google_Service_Oauth2_UserinfoV2_Resource extends Google_Service_Resource
169
  {
170
-
171
  }
172
 
173
  /**
@@ -180,7 +177,6 @@ class Google_Service_Oauth2_UserinfoV2_Resource extends Google_Service_Resource
180
  */
181
  class Google_Service_Oauth2_UserinfoV2Me_Resource extends Google_Service_Resource
182
  {
183
-
184
  /**
185
  * (me.get)
186
  *
@@ -197,7 +193,6 @@ class Google_Service_Oauth2_UserinfoV2Me_Resource extends Google_Service_Resourc
197
  }
198
  }
199
 
200
-
201
  class Google_Service_Oauth2_Tokeninfo extends Google_ApiModel
202
  {
203
  public $accessType;
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
 
129
  }
130
  }
131
 
 
132
  /**
133
  * The "userinfo" collection of methods.
134
  * Typical usage is:
139
  */
140
  class Google_Service_Oauth2_Userinfo_Resource extends Google_Service_Resource
141
  {
 
142
  /**
143
  * (userinfo.get)
144
  *
165
  */
166
  class Google_Service_Oauth2_UserinfoV2_Resource extends Google_Service_Resource
167
  {
 
168
  }
169
 
170
  /**
177
  */
178
  class Google_Service_Oauth2_UserinfoV2Me_Resource extends Google_Service_Resource
179
  {
 
180
  /**
181
  * (me.get)
182
  *
193
  }
194
  }
195
 
 
196
  class Google_Service_Oauth2_Tokeninfo extends Google_ApiModel
197
  {
198
  public $accessType;
src/Google/Service/Resource.php CHANGED
@@ -15,7 +15,6 @@
15
  * limitations under the License.
16
  */
17
 
18
-
19
  /**
20
  * Implements the actual methods/resources of the discovered Google API using magic function
21
  * calling overloading (__call()), which on call will see if the method name (plus.activities.list)
@@ -29,16 +28,16 @@ class Google_Service_Resource
29
  {
30
  // Valid query parameters that work, but don't appear in discovery.
31
  private $stackParameters = array(
32
- 'alt' => array('type' => 'string', 'location' => 'query'),
33
- 'fields' => array('type' => 'string', 'location' => 'query'),
34
- 'trace' => array('type' => 'string', 'location' => 'query'),
35
- 'userIp' => array('type' => 'string', 'location' => 'query'),
36
- 'userip' => array('type' => 'string', 'location' => 'query'),
37
- 'quotaUser' => array('type' => 'string', 'location' => 'query'),
38
- 'data' => array('type' => 'string', 'location' => 'body'),
39
- 'mimeType' => array('type' => 'string', 'location' => 'header'),
40
- 'uploadType' => array('type' => 'string', 'location' => 'query'),
41
- 'mediaUpload' => array('type' => 'complex', 'location' => 'query'),
42
  );
43
 
44
  /** @var Google_ApiService $service */
@@ -63,8 +62,8 @@ class Google_Service_Resource
63
  $this->serviceName = $serviceName;
64
  $this->resourceName = $resourceName;
65
  $this->methods = isset($resource['methods']) ?
66
- $resource['methods'] :
67
- array($resourceName => $resource);
68
  }
69
 
70
  /**
@@ -81,8 +80,8 @@ class Google_Service_Resource
81
  {
82
  if (!isset($this->methods[$name])) {
83
  throw new Google_ApiException(
84
- "Unknown function: ".
85
- "{$this->serviceName}->{$this->resourceName}->{$name}()"
86
  );
87
  }
88
  $method = $this->methods[$name];
@@ -102,7 +101,7 @@ class Google_Service_Resource
102
  // If the post body is another kind of object, we will try and
103
  // wrangle it into a sensible format.
104
  $parameters['postBody'] =
105
- $this->convertToArrayAndStripNulls($parameters['postBody']);
106
  }
107
  }
108
  $postBody = json_encode($parameters['postBody']);
@@ -122,8 +121,8 @@ class Google_Service_Resource
122
  }
123
 
124
  $method['parameters'] = array_merge(
125
- $method['parameters'],
126
- $this->stackParameters
127
  );
128
  foreach ($parameters as $key => $val) {
129
  if ($key != 'postBody' && !isset($method['parameters'][$key])) {
@@ -133,8 +132,8 @@ class Google_Service_Resource
133
 
134
  foreach ($method['parameters'] as $paramName => $paramSpec) {
135
  if (isset($paramSpec['required']) &&
136
- $paramSpec['required'] &&
137
- !isset($parameters[$paramName])
138
  ) {
139
  throw new Google_ApiException("($name) missing required param: '$paramName'");
140
  }
@@ -151,16 +150,16 @@ class Google_Service_Resource
151
 
152
  $servicePath = $this->service->servicePath;
153
 
154
- $url = Google_Http_REST::createRequestUri(
155
- $servicePath,
156
- $method['path'],
157
- $parameters
158
  );
159
  $httpRequest = new Google_Http_Request(
160
- $url,
161
- $method['httpMethod'],
162
- null,
163
- $postBody
164
  );
165
  $httpRequest->setBaseComponent($this->client->getBasePath());
166
 
@@ -175,14 +174,14 @@ class Google_Service_Resource
175
  $httpRequest->setExpectedClass($expected_class);
176
 
177
  if (isset($parameters['data']) &&
178
- ($parameters['uploadType']['value'] == 'media' || $parameters['uploadType']['value'] == 'multipart')
179
  ) {
180
  // If we are doing a simple media upload, trigger that as a convenience.
181
  $mfu = new Google_Http_MediaFileUpload(
182
- $this->client,
183
- $httpRequest,
184
- isset($parameters['mimeType']) ? $parameters['mimeType']['value'] : 'application/octet-stream',
185
- $parameters['data']['value']
186
  );
187
  }
188
 
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)
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 */
62
  $this->serviceName = $serviceName;
63
  $this->resourceName = $resourceName;
64
  $this->methods = isset($resource['methods']) ?
65
+ $resource['methods'] :
66
+ array($resourceName => $resource);
67
  }
68
 
69
  /**
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];
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']);
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])) {
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
  }
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
 
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
 
src/Google/Signer/P12.php CHANGED
@@ -15,7 +15,6 @@
15
  * limitations under the License.
16
  */
17
 
18
-
19
  /**
20
  * Signs data.
21
  *
@@ -33,7 +32,7 @@ class Google_Signer_P12 extends Google_Signer_Abstract
33
  {
34
  if (!function_exists('openssl_x509_read')) {
35
  throw new Google_ApiException(
36
- 'The Google PHP API library needs the openssl PHP extension'
37
  );
38
  }
39
 
@@ -48,9 +47,9 @@ class Google_Signer_P12 extends Google_Signer_Abstract
48
  $certs = array();
49
  if (!openssl_pkcs12_read($p12, $certs, $password)) {
50
  throw new Google_Auth_Exception(
51
- "Unable to parse the p12 file. " .
52
- "Is this a .p12 file? Is the password correct? OpenSSL error: " .
53
- openssl_error_string()
54
  );
55
  }
56
  // TODO(beaton): is this part of the contract for the openssl_pkcs12_read
@@ -77,12 +76,13 @@ class Google_Signer_P12 extends Google_Signer_Abstract
77
  {
78
  if (version_compare(PHP_VERSION, '5.3.0') < 0) {
79
  throw new Google_Auth_Exception(
80
- "PHP 5.3.0 or higher is required to use service accounts."
81
  );
82
  }
83
  if (!openssl_sign($data, $signature, $this->privateKey, "sha256")) {
84
  throw new Google_Auth_Exception("Unable to sign data");
85
  }
 
86
  return $signature;
87
  }
88
  }
15
  * limitations under the License.
16
  */
17
 
 
18
  /**
19
  * Signs data.
20
  *
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
 
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
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 CHANGED
@@ -33,13 +33,13 @@ class Google_Utils_URITemplate
33
  * processed.
34
  */
35
  private $operators = array(
36
- "+" => "reserved",
37
- "/" => "segments",
38
- "." => "dotprefix",
39
- "#" => "fragment",
40
- ";" => "semicolon",
41
- "?" => "form",
42
- "&" => "continuation"
43
  );
44
 
45
  /**
@@ -48,46 +48,46 @@ class Google_Utils_URITemplate
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)
@@ -171,7 +171,6 @@ class Google_Utils_URITemplate
171
  if ($data || ($data !== false && $prefix_on_missing)) {
172
  $data = $prefix.$data;
173
  }
174
-
175
  } else {
176
  // If no operator we replace with the defaults.
177
  $data = $this->replaceVars($data, $parameters);
@@ -182,24 +181,24 @@ class Google_Utils_URITemplate
182
  }
183
 
184
  private function replaceVars(
185
- $section,
186
- $parameters,
187
- $sep = ",",
188
- $combine = null,
189
- $reserved = false,
190
- $tag_empty = false,
191
- $combine_on_empty = true
192
  ) {
193
  if (strpos($section, ",") === false) {
194
  // If we only have a single value, we can immediately process.
195
  return $this->combine(
196
- $section,
197
- $parameters,
198
- $sep,
199
- $combine,
200
- $reserved,
201
- $tag_empty,
202
- $combine_on_empty
203
  );
204
  } else {
205
  // If we have multiple values, we need to split and loop over them.
@@ -208,25 +207,25 @@ class Google_Utils_URITemplate
208
  $vars = explode(",", $section);
209
 
210
  return $this->combineList(
211
- $vars,
212
- $sep,
213
- $parameters,
214
- $combine,
215
- $reserved,
216
- false, // Never emit empty strings in multi-param replacements
217
- $combine_on_empty
218
  );
219
  }
220
  }
221
 
222
  public function combine(
223
- $key,
224
- $parameters,
225
- $sep,
226
- $combine,
227
- $reserved,
228
- $tag_empty,
229
- $combine_on_empty
230
  ) {
231
  $length = false;
232
  $explode = false;
@@ -333,24 +332,24 @@ class Google_Utils_URITemplate
333
  * for multi-key templates.
334
  */
335
  private function combineList(
336
- $vars,
337
- $sep,
338
- $parameters,
339
- $combine,
340
- $reserved,
341
- $tag_empty,
342
- $combine_on_empty
343
  ) {
344
  $ret = array();
345
  foreach ($vars as $var) {
346
  $response = $this->combine(
347
- $var,
348
- $parameters,
349
- $sep,
350
- $combine,
351
- $reserved,
352
- $tag_empty,
353
- $combine_on_empty
354
  );
355
  if ($response === false) {
356
  continue;
33
  * processed.
34
  */
35
  private $operators = array(
36
+ "+" => "reserved",
37
+ "/" => "segments",
38
+ "." => "dotprefix",
39
+ "#" => "fragment",
40
+ ";" => "semicolon",
41
+ "?" => "form",
42
+ "&" => "continuation",
43
  );
44
 
45
  /**
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)
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);
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.
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;
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;
src/Google/Verifier/Pem.php CHANGED
@@ -15,7 +15,6 @@
15
  * limitations under the License.
16
  */
17
 
18
-
19
  /**
20
  * Verifies signatures using PEM encoded certificates.
21
  *
15
  * limitations under the License.
16
  */
17
 
 
18
  /**
19
  * Verifies signatures using PEM encoded certificates.
20
  *
src/MMB/Backup.php CHANGED
@@ -64,16 +64,16 @@ class MMB_Backup extends MMB_Core
64
  51 => 'The end of the ZIP archive was encountered prematurely.',
65
  80 => 'The user aborted unzip prematurely.',
66
  81 => 'Testing or extraction of one or more files failed due to unsupported compression methods or unsupported decryption.',
67
- 82 => 'No files were found due to bad decryption password(s)'
68
  );
69
 
70
  /**
71
  * Initializes site_name, statuses, and tasks attributes.
72
  */
73
- function __construct()
74
  {
75
  parent::__construct();
76
- $this->site_name = str_replace(array("_", "/", "~", ":",), array("", "-", "-", "-",), rtrim($this->remove_http(get_bloginfo('url')), "/"));
77
  $this->statuses = array(
78
  'db_dump' => 1,
79
  'db_zip' => 2,
@@ -84,7 +84,7 @@ class MMB_Backup extends MMB_Core
84
  'email' => 7,
85
  'google_drive' => 8,
86
  'sftp' => 9,
87
- 'finished' => 100
88
  );
89
 
90
  $this->w3tc_flush();
@@ -95,9 +95,9 @@ class MMB_Backup extends MMB_Core
95
  /**
96
  * Tries to increase memory limit to 384M and execution time to 600s.
97
  *
98
- * @return array an array with two keys for execution time and memory limit (0 - if not changed, 1 - if succesfully)
99
  */
100
- function set_memory()
101
  {
102
  $changed = array('execution_time' => 0, 'memory_limit' => 0);
103
  ignore_user_abort(true);
@@ -130,9 +130,9 @@ class MMB_Backup extends MMB_Core
130
  /**
131
  * Returns backup settings from local database for all tasks
132
  *
133
- * @return mixed|boolean
134
  */
135
- function get_backup_settings()
136
  {
137
  $backup_settings = get_option('mwp_backup_tasks');
138
 
@@ -146,15 +146,14 @@ class MMB_Backup extends MMB_Core
146
  /**
147
  * Sets backup task defined from master, if task name is "Backup Now" this function fires processing backup.
148
  *
149
- * @param mixed $params parameters sent from master
150
  *
151
- * @return mixed|boolean $this->tasks variable if success, array with error message if error has ocurred, false if $params are empty
152
  */
153
- function set_backup_task($params)
154
  {
155
  //$params => [$task_name, $args, $error]
156
  if (!empty($params)) {
157
-
158
  //Make sure backup cron job is set
159
  /*if (!wp_next_scheduled('mwp_backup_tasks')) {
160
  wp_schedule_event(time(), 'tenminutes', 'mwp_backup_tasks');
@@ -171,7 +170,7 @@ class MMB_Backup extends MMB_Core
171
  if (isset($args['remove'])) {
172
  unset($before[$task_name]);
173
  $return = array(
174
- 'removed' => true
175
  );
176
  } else {
177
  if (isset($params['account_info']) && is_array($params['account_info'])) { //only if sends from master first time(secure data)
@@ -228,7 +227,7 @@ class MMB_Backup extends MMB_Core
228
  * @deprecated deprecated since version 3.9.29
229
  * @return void
230
  */
231
- function check_backup_tasks()
232
  {
233
  $this->check_cron_remove();
234
 
@@ -244,7 +243,7 @@ class MMB_Backup extends MMB_Core
244
  'task_name' => $task_name,
245
  'task_id' => $setting['task_args']['task_id'],
246
  'site_key' => $setting['task_args']['site_key'],
247
- 'worker_version' => $GLOBALS['MMB_WORKER_VERSION']
248
  );
249
 
250
  if (isset($setting['task_args']['account_info']['mwp_google_drive']['google_drive_token'])) {
@@ -275,12 +274,11 @@ class MMB_Backup extends MMB_Core
275
  $setting['task_args']['account_info']['mwp_google_drive']['google_drive_token'] = $potential_token;
276
  }
277
  }
278
-
279
  }
280
 
281
  $update = array(
282
  'task_name' => $task_name,
283
- 'args' => $settings[$task_name]['task_args']
284
  );
285
 
286
  if ($check != 'paused') {
@@ -294,7 +292,6 @@ class MMB_Backup extends MMB_Core
294
  continue;
295
  }
296
 
297
-
298
  $result = $this->backup($setting['task_args'], $task_name);
299
  $error = '';
300
 
@@ -304,7 +301,7 @@ class MMB_Backup extends MMB_Core
304
  array(
305
  'task_name' => $task_name,
306
  'args' => $settings[$task_name]['task_args'],
307
- 'error' => $error
308
  ));
309
  } else {
310
  if (@count($setting['task_args']['account_info'])) {
@@ -316,18 +313,17 @@ class MMB_Backup extends MMB_Core
316
  }
317
  }
318
  }
319
-
320
  }
321
 
322
  /**
323
  * Runs backup task invoked from ManageWP master.
324
  *
325
- * @param string $task_name name of backup task
326
- * @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)
327
  *
328
- * @return mixed array with backup statistics if successful, array with error message if not
329
  */
330
- function task_now($task_name, $google_drive_token = false)
331
  {
332
  if ($google_drive_token) {
333
  $this->tasks[$task_name]['task_args']['account_info']['mwp_google_drive']['google_drive_token'] = $google_drive_token;
@@ -343,7 +339,7 @@ class MMB_Backup extends MMB_Core
343
  $this->set_backup_task(array(
344
  'task_name' => $task_name,
345
  'args' => $settings[$task_name]['task_args'],
346
- 'time' => time()
347
  ));
348
 
349
  //Run backup
@@ -354,7 +350,7 @@ class MMB_Backup extends MMB_Core
354
  $this->set_backup_task(array(
355
  'task_name' => $task_name,
356
  'args' => $settings[$task_name]['task_args'],
357
- 'error' => $result['error']
358
  ));
359
 
360
  return $result;
@@ -367,17 +363,17 @@ class MMB_Backup extends MMB_Core
367
  * Backup a full wordpress instance, including a database dump, which is placed in mwp_db dir in root folder.
368
  * All backups are compressed by zip and placed in wp-content/managewp/backups folder.
369
  *
370
- * @param string $args arguments passed from master
371
- * [type] -> db, full
372
- * [what] -> daily, weekly, monthly
373
- * [account_info] -> remote destinations ftp, amazons3, dropbox, google_drive, email with their parameters
374
- * [include] -> array of folders from site root which are included to backup (wp-admin, wp-content, wp-includes are default)
375
- * [exclude] -> array of files of folders to exclude, relative to site's root
376
- * @param bool|string[optional] $task_name the name of backup task, which backup is done (default: false)
377
  *
378
- * @return bool|array false if $args are missing, array with error if error has occured, ture if is successful
379
  */
380
- function backup($args, $task_name = false)
381
  {
382
  if (!$args || empty($args)) {
383
  return false;
@@ -395,7 +391,7 @@ class MMB_Backup extends MMB_Core
395
  $error_message = 'Remote destination is not supported, please update your client plugin.';
396
 
397
  return array(
398
- 'error' => $error_message
399
  );
400
  }
401
  }
@@ -416,7 +412,7 @@ class MMB_Backup extends MMB_Core
416
  if (!file_exists($new_file_path)) {
417
  if (!mkdir($new_file_path, 0755, true)) {
418
  return array(
419
- 'error' => 'Permission denied, make sure you have write permissions to the wp-content folder.'
420
  );
421
  }
422
  }
@@ -443,7 +439,7 @@ class MMB_Backup extends MMB_Core
443
  $error_message = $db_backup['error'];
444
 
445
  return array(
446
- 'error' => $error_message
447
  );
448
  }
449
  } elseif (trim($what) == 'full') {
@@ -458,7 +454,7 @@ class MMB_Backup extends MMB_Core
458
  $error_message = $content_backup['error'];
459
 
460
  return array(
461
- 'error' => $error_message
462
  );
463
  }
464
  }
@@ -484,12 +480,12 @@ class MMB_Backup extends MMB_Core
484
  if ($task_name != 'Backup Now') {
485
  $paths['server'] = array(
486
  'file_path' => $backup_file,
487
- 'file_url' => $backup_url
488
  );
489
  } else {
490
  $paths['server'] = array(
491
  'file_path' => $backup_file,
492
- 'file_url' => $backup_url
493
  );
494
  }
495
 
@@ -523,7 +519,6 @@ class MMB_Backup extends MMB_Core
523
  if ($task_name != 'Backup Now') {
524
  $paths['status'] = $temp[count($temp) - 1]['status'];
525
  $temp[count($temp) - 1] = $paths;
526
-
527
  } else {
528
  $temp[count($temp)] = $paths;
529
  }
@@ -545,26 +540,26 @@ class MMB_Backup extends MMB_Core
545
  * Backup a full wordpress instance, including a database dump, which is placed in mwp_db dir in root folder.
546
  * All backups are compressed by zip and placed in wp-content/managewp/backups folder.
547
  *
548
- * @param string $task_name the name of backup task, which backup is done
549
- * @param string $backup_file relative path to file which backup is stored
550
- * @param array [optional] $exclude the list of files and folders, which are excluded from backup (default: array())
551
- * @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())
552
  *
553
- * @return bool|array true if backup is successful, or an array with error message if is failed
554
  */
555
- function backup_full($task_name, $backup_file, $exclude = array(), $include = array())
556
  {
557
  $this->update_status($task_name, $this->statuses['db_dump']);
558
  $db_result = $this->backup_db();
559
 
560
  if ($db_result == false) {
561
  return array(
562
- 'error' => 'Failed to backup database.'
563
  );
564
  } else {
565
  if (is_array($db_result) && isset($db_result['error'])) {
566
  return array(
567
- 'error' => $db_result['error']
568
  );
569
  }
570
  }
@@ -596,7 +591,7 @@ class MMB_Backup extends MMB_Core
596
  }
597
 
598
  return array(
599
- 'error' => 'Failed to zip database. '.$archive->error_code.$archive->error_string
600
  );
601
  }
602
  }
@@ -607,11 +602,20 @@ class MMB_Backup extends MMB_Core
607
  @unlink($db_result);
608
  @rmdir(MWP_DB_DIR);
609
 
610
- $remove = array(
611
  trim(basename(WP_CONTENT_DIR))."/managewp/backups",
 
612
  trim(basename(WP_CONTENT_DIR))."/".md5('mmb-worker')."/mwp_backups",
 
 
 
613
  trim(basename(WP_CONTENT_DIR))."/cache",
 
 
614
  trim(basename(WP_CONTENT_DIR))."/w3tc",
 
 
 
615
  );
616
  $exclude = array_merge($exclude, $remove);
617
 
@@ -647,7 +651,7 @@ class MMB_Backup extends MMB_Core
647
  @unlink($backup_file);
648
 
649
  return array(
650
- 'error' => 'Failed to zip files. pclZip error ('.$archive->error_code.'): .'.$archive->error_string
651
  );
652
  }
653
  }
@@ -672,7 +676,7 @@ class MMB_Backup extends MMB_Core
672
  * @todo report errors back to the user
673
  * @todo report error if DB dump is not found
674
  */
675
- function zip_backup_db($taskName, $backupFile)
676
  {
677
  $disableCompression = $this->tasks[$taskName]['task_args']['disable_comp'];
678
 
@@ -684,10 +688,10 @@ class MMB_Backup extends MMB_Core
684
  ->setWorkingDirectory(untrailingslashit(MWP_BACKUP_DIR))
685
  ->setTimeout(3600)
686
  ->setPrefix($zip)
687
- ->add('-q') // quiet operation
688
- ->add('-r') // recurse paths, include files in subdirs: zip -r a path path ...
689
  ->add($compressionLevel)
690
- ->add($backupFile) // zipfile to write to
691
  ->add('mwp_db') // file/directory list
692
  ;
693
 
@@ -730,13 +734,13 @@ class MMB_Backup extends MMB_Core
730
  /**
731
  * Zipping database dump and index.php in folder mwp_db by ZipArchive class, requires php zip extension.
732
  *
733
- * @param string $task_name the name of backup task
734
- * @param string $db_result relative path to database dump file
735
- * @param string $backup_file absolute path to zip file
736
  *
737
- * @return bool is compress successful or not
738
  */
739
- function zip_archive_backup_db($task_name, $db_result, $backup_file)
740
  {
741
  $disable_comp = $this->tasks[$task_name]['task_args']['disable_comp'];
742
  $zip = new ZipArchive();
@@ -760,12 +764,12 @@ class MMB_Backup extends MMB_Core
760
  /**
761
  * Zipping database dump and index.php in folder mwp_db by PclZip library.
762
  *
763
- * @param string $task_name the name of backup task
764
- * @param string $backup_file absolute path to zip file
765
  *
766
- * @return bool is compress successful or not
767
  */
768
- function pclzip_backup_db($task_name, $backup_file)
769
  {
770
  $disable_comp = $this->tasks[$task_name]['task_args']['disable_comp'];
771
  define('PCLZIP_TEMPORARY_DIR', MWP_BACKUP_DIR.'/');
@@ -785,14 +789,14 @@ class MMB_Backup extends MMB_Core
785
  * Zipping whole site root folder and append to backup file with database dump
786
  * by system zip command, requires zip installed on OS.
787
  *
788
- * @param string $task_name the name of backup task
789
- * @param string $backupFile absolute path to zip file
790
- * @param array $exclude array of files of folders to exclude, relative to site's root
791
- * @param array $include array of folders from site root which are included to backup (wp-admin, wp-content, wp-includes are default)
792
  *
793
- * @return array|bool true if successful or an array with error message if not
794
  */
795
- function zip_backup($task_name, $backupFile, $exclude, $include)
796
  {
797
  $compressionLevel = $this->tasks[$task_name]['task_args']['disable_comp'] ? 0 : 1;
798
 
@@ -981,14 +985,14 @@ class MMB_Backup extends MMB_Core
981
  * Zipping whole site root folder and append to backup file with database dump
982
  * by ZipArchive class, requires php zip extension.
983
  *
984
- * @param string $task_name the name of backup task
985
- * @param string $backup_file absolute path to zip file
986
- * @param array $exclude array of files of folders to exclude, relative to site's root
987
- * @param array $include array of folders from site root which are included to backup (wp-admin, wp-content, wp-includes are default)
988
  *
989
- * @return array|bool true if successful or an array with error message if not
990
  */
991
- function zip_archive_backup($task_name, $backup_file, $exclude, $include, $overwrite = false)
992
  {
993
  $filelist = $this->get_backup_files($exclude, $include);
994
  $disable_comp = $this->tasks[$task_name]['task_args']['disable_comp'];
@@ -1024,14 +1028,14 @@ class MMB_Backup extends MMB_Core
1024
  * Zipping whole site root folder and append to backup file with database dump
1025
  * by PclZip library.
1026
  *
1027
- * @param string $task_name the name of backup task
1028
- * @param string $backup_file absolute path to zip file
1029
- * @param array $exclude array of files of folders to exclude, relative to site's root
1030
- * @param array $include array of folders from site root which are included to backup (wp-admin, wp-content, wp-includes are default)
1031
  *
1032
- * @return array|bool true if successful or an array with error message if not
1033
  */
1034
- function pclzip_backup($task_name, $backup_file, $exclude, $include)
1035
  {
1036
  define('PCLZIP_TEMPORARY_DIR', MWP_BACKUP_DIR.'/');
1037
  require_once ABSPATH.'/wp-admin/includes/class-pclzip.php';
@@ -1039,7 +1043,7 @@ class MMB_Backup extends MMB_Core
1039
  $add = array(
1040
  trim(WPINC),
1041
  trim(basename(WP_CONTENT_DIR)),
1042
- 'wp-admin'
1043
  );
1044
 
1045
  if (!file_exists(ABSPATH.'wp-config.php')
@@ -1104,17 +1108,17 @@ class MMB_Backup extends MMB_Core
1104
  * By default, there are all files from root folder, all files from folders wp-admin, wp-content, wp-includes recursively.
1105
  * Parameter $include adds other folders from site root, and excludes any file or folder by relative path to site's root.
1106
  *
1107
- * @param array $exclude array of files of folders to exclude, relative to site's root
1108
- * @param array $include array of folders from site root which are included to backup (wp-admin, wp-content, wp-includes are default)
1109
  *
1110
- * @return array array with all files in site root dir
1111
  */
1112
- function get_backup_files($exclude, $include)
1113
  {
1114
  $add = array(
1115
  trim(WPINC),
1116
  trim(basename(WP_CONTENT_DIR)),
1117
- "wp-admin"
1118
  );
1119
 
1120
  $include = array_merge($add, $include);
@@ -1159,24 +1163,24 @@ class MMB_Backup extends MMB_Core
1159
  * Backup a database dump of WordPress site.
1160
  * All backups are compressed by zip and placed in wp-content/managewp/backups folder.
1161
  *
1162
- * @param string $task_name the name of backup task, which backup is done
1163
- * @param string $backup_file relative path to file which backup is stored
1164
  *
1165
- * @return bool|array true if backup is successful, or an array with error message if is failed
1166
  */
1167
- function backup_db_compress($task_name, $backup_file)
1168
  {
1169
  $this->update_status($task_name, $this->statuses['db_dump']);
1170
  $db_result = $this->backup_db();
1171
 
1172
  if ($db_result == false) {
1173
  return array(
1174
- 'error' => 'Failed to backup database.'
1175
  );
1176
  } else {
1177
  if (is_array($db_result) && isset($db_result['error'])) {
1178
  return array(
1179
- 'error' => $db_result['error']
1180
  );
1181
  }
1182
  }
@@ -1202,7 +1206,7 @@ class MMB_Backup extends MMB_Core
1202
  @rmdir(MWP_DB_DIR);
1203
 
1204
  return array(
1205
- 'error' => 'Failed to zip database. pclZip error ('.$archive->error_code.'): .'.$archive->error_string
1206
  );
1207
  }
1208
  }
@@ -1221,15 +1225,15 @@ class MMB_Backup extends MMB_Core
1221
  * Creates database dump and places it in mwp_db folder in site's root.
1222
  * This function dispatches if OS mysql command does not work calls a php alternative.
1223
  *
1224
- * @return string|array path to dump file if successful, or an array with error message if is failed
1225
  */
1226
- function backup_db()
1227
  {
1228
  $db_folder = MWP_DB_DIR.'/';
1229
  if (!file_exists($db_folder)) {
1230
  if (!mkdir($db_folder, 0755, true)) {
1231
  return array(
1232
- 'error' => 'Error creating database backup folder ('.$db_folder.'). Make sure you have correct write permissions.'
1233
  );
1234
  }
1235
  }
@@ -1239,7 +1243,7 @@ class MMB_Backup extends MMB_Core
1239
  return $result;
1240
  }
1241
 
1242
- function file_get_size($file)
1243
  {
1244
  if (!extension_loaded('bcmath')) {
1245
  return filesize($file);
@@ -1289,7 +1293,7 @@ class MMB_Backup extends MMB_Core
1289
  *
1290
  * @return string|array path to dump file if successful, or an array with error message if is failed
1291
  */
1292
- function backup_db_dump($file)
1293
  {
1294
  $mysqldump = mwp_container()->getExecutableFinder()->find('mysqldump', 'mysqldump');
1295
 
@@ -1297,11 +1301,11 @@ class MMB_Backup extends MMB_Core
1297
  ->setWorkingDirectory(untrailingslashit(ABSPATH))
1298
  ->setTimeout(3600)
1299
  ->setPrefix($mysqldump)
1300
- ->add('--force') // Continue even if we get an SQL error.
1301
- ->add('--user='.DB_USER) // User for login if not current user.
1302
- ->add('--password='.DB_PASSWORD) // Password to use when connecting to server. If password is not given it's solicited on the tty.
1303
- ->add('--add-drop-table') // Add a DROP TABLE before each create.
1304
- ->add('--lock-tables=false') // Don't lock all tables for read.
1305
  ->add(DB_NAME)
1306
  ->add('--result-file='.$file);
1307
 
@@ -1322,7 +1326,7 @@ class MMB_Backup extends MMB_Core
1322
  $processBuilder->add('--socket='.$host);
1323
  } else {
1324
  $processBuilder->add('--host='.$host);
1325
- if(!empty($port)){
1326
  $processBuilder->add('--port='.$port);
1327
  }
1328
  }
@@ -1352,7 +1356,7 @@ class MMB_Backup extends MMB_Core
1352
  ));
1353
  }
1354
 
1355
- if (class_exists('PDO')) {
1356
  mwp_logger()->info('Using PHP dumper v2');
1357
  try {
1358
  $config = array(
@@ -1393,7 +1397,6 @@ class MMB_Backup extends MMB_Core
1393
  }
1394
  }
1395
 
1396
-
1397
  if (filesize($file) === 0) {
1398
  unlink($file);
1399
  mwp_logger()->error('Database dumping process failed with unknown reason', array(
@@ -1415,11 +1418,11 @@ class MMB_Backup extends MMB_Core
1415
  /**
1416
  * Creates database dump by php functions.
1417
  *
1418
- * @param string $file absolute path to file in which dump should be placed
1419
  *
1420
- * @return string|array path to dump file if successful, or an array with error message if is failed
1421
  */
1422
- function backup_db_php($file)
1423
  {
1424
  global $wpdb;
1425
  $tables = $wpdb->get_results('SHOW TABLES', ARRAY_N);
@@ -1474,14 +1477,14 @@ class MMB_Backup extends MMB_Core
1474
  @unlink($file);
1475
 
1476
  return array(
1477
- 'error' => 'Database backup failed. Try to enable MySQL dump on your server.'
1478
  );
1479
  }
1480
 
1481
  return $file;
1482
  }
1483
 
1484
- function restore($params)
1485
  {
1486
  global $wpdb;
1487
  if (empty($params)) {
@@ -1524,7 +1527,7 @@ class MMB_Backup extends MMB_Core
1524
  $unzipFailed = true;
1525
  }
1526
 
1527
- if($unzipFailed && class_exists("ZipArchive")){
1528
  $unzipFailed = false;
1529
  try {
1530
  $this->unzipWithZipArchive($backupFile);
@@ -1585,20 +1588,20 @@ class MMB_Backup extends MMB_Core
1585
 
1586
  // Try to fetch old home and site url, as well as new ones for usage later in database updates
1587
  // Take fresh options
1588
- $homeOpt = $wpdb->get_row($wpdb->prepare("SELECT option_value FROM $wpdb->options WHERE option_name = %s LIMIT 1", 'home'));
1589
  $siteUrlOpt = $wpdb->get_row($wpdb->prepare("SELECT option_value FROM $wpdb->options WHERE option_name = %s LIMIT 1", 'siteurl'));
1590
  global $restoreParams;
1591
- $restoreParams = array (
1592
- 'oldUrl' => is_object($homeOpt) ? $homeOpt->option_value : null,
1593
  'oldSiteUrl' => is_object($siteUrlOpt) ? $siteUrlOpt->option_value : null,
1594
  'tablePrefix' => $this->get_table_prefix(),
1595
- 'newUrl' => ''
1596
  );
1597
 
1598
  /* Replace options and content urls */
1599
  $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, $params['current_tasks_tmp']);
1600
 
1601
- $newUrl = $wpdb->get_row($wpdb->prepare("SELECT option_value FROM $wpdb->options WHERE option_name = %s LIMIT 1", 'home'));
1602
  $restoreParams['newUrl'] = is_object($newUrl) ? $newUrl->option_value : null;
1603
  restore_migrate_urls();
1604
  restore_htaccess();
@@ -1606,7 +1609,7 @@ class MMB_Backup extends MMB_Core
1606
  global $configDiff;
1607
  $result = array(
1608
  'status' => true,
1609
- 'admins' => $this->getAdminUsers()
1610
  );
1611
  if (isset($configDiff)
1612
  && is_array($configDiff)
@@ -1617,14 +1620,15 @@ class MMB_Backup extends MMB_Core
1617
  return $result;
1618
  }
1619
 
1620
- private function getAdminUsers(){
 
1621
  global $wpdb;
1622
  $users = get_users(array(
1623
- 'role' => array('administrator'),
1624
- 'fields' => array('user_login')
1625
- ));
1626
- return $users;
1627
 
 
1628
  }
1629
 
1630
  private function getBackup($taskName, $resultId, $backupUrl = null)
@@ -1727,7 +1731,6 @@ class MMB_Backup extends MMB_Core
1727
  $oldOptions['clone_options']['upload_path'] = get_option('upload_path');
1728
  $oldOptions['clone_options']['upload_url_path'] = get_option('upload_url_path');
1729
 
1730
-
1731
  $oldOptions['clone_options']['mwp_backup_tasks'] = maybe_serialize(get_option('mwp_backup_tasks'));
1732
  $oldOptions['clone_options']['mwp_notifications'] = maybe_serialize(get_option('mwp_notifications'));
1733
  $oldOptions['clone_options']['mwp_pageview_alerts'] = maybe_serialize(get_option('mwp_pageview_alerts'));
@@ -1780,15 +1783,15 @@ class MMB_Backup extends MMB_Core
1780
  private function unzipWithZipArchive($backupFile)
1781
  {
1782
  mwp_logger()->info('Falling back to ZipArchive Module');
1783
- $result = false;
1784
  $zipArchive = new ZipArchive();
1785
- $zipOpened = $zipArchive->open($backupFile);
1786
- if($zipOpened === true){
1787
  $result = $zipArchive->extractTo(ABSPATH);
1788
  $zipArchive->close();
1789
  }
1790
- if($result === false){
1791
- throw new Exception('Failed to unzip files with ZipArchive. Message: '. $zipArchive->getStatusString());
1792
  }
1793
  }
1794
 
@@ -1821,9 +1824,9 @@ class MMB_Backup extends MMB_Core
1821
  /* Get New Table prefix */
1822
  $new_table_prefix = trim($this->get_table_prefix());
1823
 
1824
- $configPath = ABSPATH . 'wp-config.php';
1825
- $sourceConfigCopyPath = ABSPATH . 'wp-config.source.php';
1826
- $destinationConfigPath = ABSPATH . 'mwp-temp-wp-config.php';
1827
 
1828
  @rename($configPath, $sourceConfigCopyPath);
1829
 
@@ -1841,7 +1844,7 @@ class MMB_Backup extends MMB_Core
1841
  global $configDiff;
1842
  $configDiff = array(
1843
  'additions' => array_values(array_diff($sourceTokens, $destinationTokens)),
1844
- 'subtractions' => array_values(array_diff($destinationTokens, $sourceTokens))
1845
  );
1846
  }
1847
  }
@@ -1902,7 +1905,6 @@ class MMB_Backup extends MMB_Core
1902
  $query = "UPDATE ".$new_table_prefix."users SET user_email=%s, user_login = %s, user_pass = %s WHERE user_login = %s";
1903
  $wpdb->query($wpdb->prepare($query, $adminEmail, $newUser, $newPassword, $temp_user->user_login));
1904
  }
1905
-
1906
  }
1907
  }
1908
  }
@@ -1912,7 +1914,7 @@ class MMB_Backup extends MMB_Core
1912
  if (!empty($key)) {
1913
  $query = "SELECT option_value FROM ".$new_table_prefix."options WHERE option_name = %s";
1914
  $res = $wpdb->get_var($wpdb->prepare($query, $key));
1915
- if ($res == false) {
1916
  $query = "INSERT INTO ".$new_table_prefix."options (option_value,option_name) VALUES(%s,%s)";
1917
  $wpdb->query($wpdb->prepare($query, $option, $key));
1918
  } else {
@@ -1928,7 +1930,7 @@ class MMB_Backup extends MMB_Core
1928
  $wpdb->query($query);
1929
 
1930
  /* Restore previous backups */
1931
- $wpdb->query("UPDATE ".$new_table_prefix."options SET option_value = ".serialize($currentTasksTmp)." WHERE option_name = 'mwp_backup_tasks'");
1932
 
1933
  /* Check for .htaccess permalinks update */
1934
  $this->replace_htaccess($home);
@@ -1942,7 +1944,7 @@ class MMB_Backup extends MMB_Core
1942
  }
1943
  }
1944
 
1945
- function restore_db($fileName)
1946
  {
1947
  if (!$fileName) {
1948
  throw new Exception('Cannot access database file.');
@@ -2005,15 +2007,14 @@ class MMB_Backup extends MMB_Core
2005
  // unlink($fileName);
2006
  }
2007
 
2008
-
2009
  /**
2010
  * Restores database dump by php functions.
2011
  *
2012
- * @param string $file_name relative path to database dump, which should be restored
2013
  *
2014
- * @return bool is successful or not
2015
  */
2016
- function restore_db_php($file_name)
2017
  {
2018
  global $wpdb;
2019
 
@@ -2059,9 +2060,9 @@ class MMB_Backup extends MMB_Core
2059
  * Retruns table_prefix for this WordPress installation.
2060
  * It is used by restore.
2061
  *
2062
- * @return string table prefix from wp-config.php file, (default: wp_)
2063
  */
2064
- function get_table_prefix()
2065
  {
2066
  $lines = file(ABSPATH.'wp-config.php');
2067
  foreach ($lines as $line) {
@@ -2081,9 +2082,9 @@ class MMB_Backup extends MMB_Core
2081
  /**
2082
  * Change all tables to InnoDB engine, and executes mysql OPTIMIZE TABLE for each table.
2083
  *
2084
- * @return bool optimized successfully or not
2085
  */
2086
- function optimize_tables()
2087
  {
2088
  global $wpdb;
2089
  $query = 'SHOW TABLE STATUS';
@@ -2096,7 +2097,6 @@ class MMB_Backup extends MMB_Core
2096
  $optimize = $wpdb->query("OPTIMIZE TABLE $table_string");
2097
 
2098
  return (bool) $optimize;
2099
-
2100
  }
2101
 
2102
  public function getServerInformationForStats()
@@ -2120,7 +2120,7 @@ class MMB_Backup extends MMB_Core
2120
  /**
2121
  * Check if proc_open exists
2122
  *
2123
- * @return string|bool exec if exists, then system, then passthru, then false if no one exist
2124
  */
2125
  private function procOpenExists()
2126
  {
@@ -2218,9 +2218,9 @@ class MMB_Backup extends MMB_Core
2218
  /**
2219
  * Returns all important information of worker's system status to master.
2220
  *
2221
- * @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
2222
  */
2223
- function check_backup_compat()
2224
  {
2225
  $reqs = array();
2226
  if (strpos($_SERVER['DOCUMENT_ROOT'], '/') === 0) {
@@ -2361,42 +2361,42 @@ class MMB_Backup extends MMB_Core
2361
  * Uploads backup file from server to email.
2362
  * A lot of email service have limitation to 10mb.
2363
  *
2364
- * @param array $args arguments passed to the function
2365
- * [email] -> email address which backup should send to
2366
- * [task_name] -> name of backup task
2367
- * [file_path] -> absolute path of backup file on local server
2368
  *
2369
- * @return bool|array true is successful, array with error message if not
2370
  */
2371
- function email_backup($args)
2372
  {
2373
  $email = $args['email'];
2374
 
2375
  if (!is_email($email)) {
2376
  return array(
2377
- 'error' => 'Your email ('.$email.') is not correct'
2378
  );
2379
  }
2380
  $backup_file = $args['file_path'];
2381
  $task_name = isset($args['task_name']) ? $args['task_name'] : '';
2382
  if (file_exists($backup_file)) {
2383
  $attachments = array(
2384
- $backup_file
2385
  );
2386
- $headers = 'From: ManageWP <no-reply@managewp.com>'."\r\n";
2387
- $subject = "ManageWP - ".$task_name." - ".$this->site_name;
2388
  ob_start();
2389
  $result = wp_mail($email, $subject, $subject, $headers, $attachments);
2390
  ob_end_clean();
2391
  } else {
2392
  return array(
2393
- 'error' => 'The backup file ('.$backup_file.') does not exist.'
2394
  );
2395
  }
2396
 
2397
  if (!$result) {
2398
  return array(
2399
- 'error' => 'Email not sent. Maybe your backup is too big for email or email server is not available on your website.'
2400
  );
2401
  }
2402
 
@@ -2406,20 +2406,20 @@ class MMB_Backup extends MMB_Core
2406
  /**
2407
  * Uploads backup file from server to remote sftp server.
2408
  *
2409
- * @param array $args arguments passed to the function
2410
- * [sftp_username] -> sftp username on remote server
2411
- * [sftp_password] -> sftp password on remote server
2412
- * [sftp_hostname] -> sftp hostname of remote host
2413
- * [sftp_remote_folder] -> folder on remote site which backup file should be upload to
2414
- * [sftp_site_folder] -> subfolder with site name in ftp_remote_folder which backup file should be upload to
2415
- * [sftp_passive] -> passive mode or not
2416
- * [sftp_ssl] -> ssl or not
2417
- * [sftp_port] -> number of port for ssl protocol
2418
- * [backup_file] -> absolute path of backup file on local server
2419
  *
2420
- * @return bool|array true is successful, array with error message if not
2421
  */
2422
- function sftp_backup($args)
2423
  {
2424
  $port = $args['sftp_port'] ? (int) $args['sftp_port'] : 22; //default port is 22
2425
  $sftp_hostname = $args['sftp_hostname'];
@@ -2547,20 +2547,20 @@ class MMB_Backup extends MMB_Core
2547
  /**
2548
  * Uploads backup file from server to remote ftp server.
2549
  *
2550
- * @param array $args arguments passed to the function
2551
- * [ftp_username] -> ftp username on remote server
2552
- * [ftp_password] -> ftp password on remote server
2553
- * [ftp_hostname] -> ftp hostname of remote host
2554
- * [ftp_remote_folder] -> folder on remote site which backup file should be upload to
2555
- * [ftp_site_folder] -> subfolder with site name in ftp_remote_folder which backup file should be upload to
2556
- * [ftp_passive] -> passive mode or not
2557
- * [ftp_ssl] -> ssl or not
2558
- * [ftp_port] -> number of port for ssl protocol
2559
- * [backup_file] -> absolute path of backup file on local server
2560
  *
2561
- * @return bool|array true is successful, array with error message if not
2562
  */
2563
- function ftp_backup($args)
2564
  {
2565
  $port = $args['ftp_port'] ? $args['ftp_port'] : 21;
2566
  $ftp_hostname = $args['ftp_hostname'];
@@ -2662,17 +2662,17 @@ class MMB_Backup extends MMB_Core
2662
  /**
2663
  * Deletes backup file from remote ftp server.
2664
  *
2665
- * @param array $args arguments passed to the function
2666
- * [ftp_username] -> ftp username on remote server
2667
- * [ftp_password] -> ftp password on remote server
2668
- * [ftp_hostname] -> ftp hostname of remote host
2669
- * [ftp_remote_folder] -> folder on remote site which backup file should be deleted from
2670
- * [ftp_site_folder] -> subfolder with site name in ftp_remote_folder which backup file should be deleted from
2671
- * [backup_file] -> absolute path of backup file on local server
2672
  *
2673
- * @return void
2674
  */
2675
- function remove_ftp_backup($args)
2676
  {
2677
  $port = $args['ftp_port'] ? (int) $args['ftp_port'] : 21;
2678
  $ftp_remote_folder = untrailingslashit($args['ftp_remote_folder']);
@@ -2695,7 +2695,6 @@ class MMB_Backup extends MMB_Core
2695
  return;
2696
  }
2697
 
2698
-
2699
  $errorCatcher->register('ftp_delete');
2700
  $delete = ftp_delete($ftp, $ftp_remote_folder.'/'.$args['backup_file']);
2701
  $errorCatcher->unRegister();
@@ -2713,17 +2712,17 @@ class MMB_Backup extends MMB_Core
2713
  /**
2714
  * Deletes backup file from remote sftp server.
2715
  *
2716
- * @param array $args arguments passed to the function
2717
- * [sftp_username] -> sftp username on remote server
2718
- * [sftp_password] -> sftp password on remote server
2719
- * [sftp_hostname] -> sftp hostname of remote host
2720
- * [sftp_remote_folder] -> folder on remote site which backup file should be deleted from
2721
- * [sftp_site_folder] -> subfolder with site name in ftp_remote_folder which backup file should be deleted from
2722
- * [backup_file] -> absolute path of backup file on local server
2723
  *
2724
- * @return void
2725
  */
2726
- function remove_sftp_backup($args)
2727
  {
2728
  $port = $args['sftp_port'] ? (int) $args['sftp_port'] : 22; //default port is 22
2729
  $sftp_hostname = $args['sftp_hostname'];
@@ -2748,21 +2747,20 @@ class MMB_Backup extends MMB_Core
2748
  $sftp->disconnect();
2749
  }
2750
 
2751
-
2752
  /**
2753
  * Downloads backup file from server from remote ftp server to root folder on local server.
2754
  *
2755
- * @param array $args arguments passed to the function
2756
- * [ftp_username] -> ftp username on remote server
2757
- * [ftp_password] -> ftp password on remote server
2758
- * [ftp_hostname] -> ftp hostname of remote host
2759
- * [ftp_remote_folder] -> folder on remote site which backup file should be downloaded from
2760
- * [ftp_site_folder] -> subfolder with site name in ftp_remote_folder which backup file should be downloaded from
2761
- * [backup_file] -> absolute path of backup file on local server
2762
  *
2763
- * @return string|array absolute path to downloaded file is successful, array with error message if not
2764
  */
2765
- function get_ftp_backup($args)
2766
  {
2767
  $port = $args['ftp_port'] ? (int) $args['ftp_port'] : 21;
2768
  $ftp_remote_folder = untrailingslashit($args['ftp_remote_folder']);
@@ -2811,21 +2809,20 @@ class MMB_Backup extends MMB_Core
2811
  return $temp;
2812
  }
2813
 
2814
-
2815
  /**
2816
  * Downloads backup file from server from remote ftp server to root folder on local server.
2817
  *
2818
- * @param array $args arguments passed to the function
2819
- * [sftp_username] -> ftp username on remote server
2820
- * [sftp_password] -> ftp password on remote server
2821
- * [sftp_hostname] -> ftp hostname of remote host
2822
- * [sftp_remote_folder] -> folder on remote site which backup file should be downloaded from
2823
- * [sftp_site_folder] -> subfolder with site name in ftp_remote_folder which backup file should be downloaded from
2824
- * [backup_file] -> absolute path of backup file on local server
2825
  *
2826
- * @return string|array absolute path to downloaded file is successful, array with error message if not
2827
  */
2828
- function get_sftp_backup($args)
2829
  {
2830
  $port = $args['sftp_port'] ? (int) $args['sftp_port'] : 22;
2831
  $sftp_hostname = $args['sftp_hostname'];
@@ -2936,22 +2933,22 @@ class MMB_Backup extends MMB_Core
2936
  /**
2937
  * Uploads backup file from server to Dropbox.
2938
  *
2939
- * @param array $args arguments passed to the function
2940
- * [consumer_key] -> consumer key of ManageWP Dropbox application
2941
- * [consumer_secret] -> consumer secret of ManageWP Dropbox application
2942
- * [oauth_token] -> oauth token of user on ManageWP Dropbox application
2943
- * [oauth_token_secret] -> oauth token secret of user on ManageWP Dropbox application
2944
- * [dropbox_destination] -> folder on user's Dropbox account which backup file should be upload to
2945
- * [dropbox_site_folder] -> subfolder with site name in dropbox_destination which backup file should be upload to
2946
- * [backup_file] -> absolute path of backup file on local server
2947
  *
2948
- * @return bool|array true is successful, array with error message if not
2949
  */
2950
- function dropbox_backup($args)
2951
  {
2952
  mwp_logger()->info('Acquiring Dropbox token to start uploading the backup file');
2953
  try {
2954
- $dropbox = mwp_dropbox_oauth1_factory($args['consumer_key'], $args['consumer_secret'], $args['oauth_token'], $args['oauth_token_secret']);
2955
  } catch (Exception $e) {
2956
  mwp_logger()->error('Error while acquiring Dropbox token', array(
2957
  'exception' => $e,
@@ -2959,7 +2956,7 @@ class MMB_Backup extends MMB_Core
2959
 
2960
  return array(
2961
  'error' => $e->getMessage(),
2962
- 'partial' => 1
2963
  );
2964
  }
2965
 
@@ -2995,7 +2992,7 @@ class MMB_Backup extends MMB_Core
2995
 
2996
  return array(
2997
  'error' => $e->getMessage(),
2998
- 'partial' => 1
2999
  );
3000
  }
3001
 
@@ -3009,22 +3006,22 @@ class MMB_Backup extends MMB_Core
3009
  /**
3010
  * Deletes backup file from Dropbox to root folder on local server.
3011
  *
3012
- * @param array $args arguments passed to the function
3013
- * [consumer_key] -> consumer key of ManageWP Dropbox application
3014
- * [consumer_secret] -> consumer secret of ManageWP Dropbox application
3015
- * [oauth_token] -> oauth token of user on ManageWP Dropbox application
3016
- * [oauth_token_secret] -> oauth token secret of user on ManageWP Dropbox application
3017
- * [dropbox_destination] -> folder on user's Dropbox account which backup file should be downloaded from
3018
- * [dropbox_site_folder] -> subfolder with site name in dropbox_destination which backup file should be downloaded from
3019
- * [backup_file] -> absolute path of backup file on local server
3020
  *
3021
- * @return void
3022
  */
3023
- function remove_dropbox_backup($args)
3024
  {
3025
  mwp_logger()->info('Acquiring Dropbox token to remove a backup file');
3026
  try {
3027
- $dropbox = mwp_dropbox_oauth1_factory($args['consumer_key'], $args['consumer_secret'], $args['oauth_token'], $args['oauth_token_secret']);
3028
  } catch (Exception $e) {
3029
  mwp_logger()->error('Error while acquiring Dropbox token', array(
3030
  'exception' => $e,
@@ -3054,22 +3051,22 @@ class MMB_Backup extends MMB_Core
3054
  /**
3055
  * Downloads backup file from Dropbox to root folder on local server.
3056
  *
3057
- * @param array $args arguments passed to the function
3058
- * [consumer_key] -> consumer key of ManageWP Dropbox application
3059
- * [consumer_secret] -> consumer secret of ManageWP Dropbox application
3060
- * [oauth_token] -> oauth token of user on ManageWP Dropbox application
3061
- * [oauth_token_secret] -> oauth token secret of user on ManageWP Dropbox application
3062
- * [dropbox_destination] -> folder on user's Dropbox account which backup file should be deleted from
3063
- * [dropbox_site_folder] -> subfolder with site name in dropbox_destination which backup file should be deleted from
3064
- * [backup_file] -> absolute path of backup file on local server
3065
  *
3066
- * @return bool|array absolute path to downloaded file is successful, array with error message if not
3067
  */
3068
- function get_dropbox_backup($args)
3069
  {
3070
  mwp_logger()->info('Acquiring Dropbox token to download the backup file');
3071
  try {
3072
- $dropbox = mwp_dropbox_oauth1_factory($args['consumer_key'], $args['consumer_secret'], $args['oauth_token'], $args['oauth_token_secret']);
3073
  } catch (Exception $e) {
3074
  mwp_logger()->error('Error while acquiring Dropbox token', array(
3075
  'exception' => $e,
@@ -3077,7 +3074,7 @@ class MMB_Backup extends MMB_Core
3077
 
3078
  return array(
3079
  'error' => $e->getMessage(),
3080
- 'partial' => 1
3081
  );
3082
  }
3083
 
@@ -3116,14 +3113,14 @@ class MMB_Backup extends MMB_Core
3116
 
3117
  return array(
3118
  'error' => $e->getMessage(),
3119
- 'partial' => 1
3120
  );
3121
  }
3122
 
3123
  $fileSize = filesize($temp);
3124
  mwp_logger()->info('Downloading backup file from Dropbox completed; file size is {backup_size}; average speed is {speed}', array(
3125
  'backup_size' => mwp_format_bytes($fileSize),
3126
- 'speed' => mwp_format_bytes($fileSize / (microtime(true) - $start))
3127
  ));
3128
 
3129
  return $temp;
@@ -3132,18 +3129,18 @@ class MMB_Backup extends MMB_Core
3132
  /**
3133
  * Uploads backup file from server to Amazon S3.
3134
  *
3135
- * @param array $args arguments passed to the function
3136
- * [as3_bucket_region] -> Amazon S3 bucket region
3137
- * [as3_bucket] -> Amazon S3 bucket
3138
- * [as3_access_key] -> Amazon S3 access key
3139
- * [as3_secure_key] -> Amazon S3 secure key
3140
- * [as3_directory] -> folder on user's Amazon S3 account which backup file should be upload to
3141
- * [as3_site_folder] -> subfolder with site name in as3_directory which backup file should be upload to
3142
- * [backup_file] -> absolute path of backup file on local server
3143
  *
3144
- * @return bool|array true is successful, array with error message if not
3145
  */
3146
- function amazons3_backup($args)
3147
  {
3148
  if ($args['as3_site_folder'] == true) {
3149
  $args['as3_directory'] .= '/'.$this->site_name;
@@ -3189,22 +3186,21 @@ class MMB_Backup extends MMB_Core
3189
  return true;
3190
  }
3191
 
3192
-
3193
  /**
3194
  * Deletes backup file from Amazon S3.
3195
  *
3196
- * @param array $args arguments passed to the function
3197
- * [as3_bucket_region] -> Amazon S3 bucket region
3198
- * [as3_bucket] -> Amazon S3 bucket
3199
- * [as3_access_key] -> Amazon S3 access key
3200
- * [as3_secure_key] -> Amazon S3 secure key
3201
- * [as3_directory] -> folder on user's Amazon S3 account which backup file should be deleted from
3202
- * [as3_site_folder] -> subfolder with site name in as3_directory which backup file should be deleted from
3203
- * [backup_file] -> absolute path of backup file on local server
3204
  *
3205
- * @return void
3206
  */
3207
- function remove_amazons3_backup($args)
3208
  {
3209
  if ($args['as3_site_folder'] == true) {
3210
  $args['as3_directory'] .= '/'.$this->site_name;
@@ -3230,18 +3226,18 @@ class MMB_Backup extends MMB_Core
3230
  /**
3231
  * Downloads backup file from Amazon S3 to root folder on local server.
3232
  *
3233
- * @param array $args arguments passed to the function
3234
- * [as3_bucket_region] -> Amazon S3 bucket region
3235
- * [as3_bucket] -> Amazon S3 bucket
3236
- * [as3_access_key] -> Amazon S3 access key
3237
- * [as3_secure_key] -> Amazon S3 secure key
3238
- * [as3_directory] -> folder on user's Amazon S3 account which backup file should be downloaded from
3239
- * [as3_site_folder] -> subfolder with site name in as3_directory which backup file should be downloaded from
3240
- * [backup_file] -> absolute path of backup file on local server
3241
  *
3242
- * @return bool|array absolute path to downloaded file is successful, array with error message if not
3243
  */
3244
- function get_amazons3_backup($args)
3245
  {
3246
  $endpoint = isset($args['as3_bucket_region']) ? $args['as3_bucket_region'] : 's3.amazonaws.com';
3247
 
@@ -3279,7 +3275,7 @@ class MMB_Backup extends MMB_Core
3279
  $fileSize = filesize($temp);
3280
  mwp_logger()->info('Downloading backup file from Amazon S3 completed; file size is {backup_size}; average speed is {speed}', array(
3281
  'backup_size' => mwp_format_bytes($fileSize),
3282
- 'speed' => mwp_format_bytes($fileSize / (microtime(true) - $start))
3283
  ));
3284
 
3285
  return $temp;
@@ -3288,15 +3284,15 @@ class MMB_Backup extends MMB_Core
3288
  /**
3289
  * Uploads backup file from server to Google Drive.
3290
  *
3291
- * @param array $args arguments passed to the function
3292
- * [google_drive_token] -> user's Google drive token in json form
3293
- * [google_drive_directory] -> folder on user's Google Drive account which backup file should be upload to
3294
- * [google_drive_site_folder] -> subfolder with site name in google_drive_directory which backup file should be upload to
3295
- * [backup_file] -> absolute path of backup file on local server
3296
  *
3297
- * @return bool|array true is successful, array with error message if not
3298
  */
3299
- function google_drive_backup($args)
3300
  {
3301
  mwp_register_autoload_google();
3302
  $googleClient = new Google_ApiClient();
@@ -3472,15 +3468,15 @@ class MMB_Backup extends MMB_Core
3472
  /**
3473
  * Deletes backup file from Google Drive.
3474
  *
3475
- * @param array $args arguments passed to the function
3476
- * [google_drive_token] -> user's Google drive token in json form
3477
- * [google_drive_directory] -> folder on user's Google Drive account which backup file should be deleted from
3478
- * [google_drive_site_folder] -> subfolder with site name in google_drive_directory which backup file should be deleted from
3479
- * [backup_file] -> absolute path of backup file on local server
3480
  *
3481
- * @return void
3482
  */
3483
- function remove_google_drive_backup($args)
3484
  {
3485
  mwp_register_autoload_google();
3486
  mwp_logger()->info('Removing Google Drive backup file', array(
@@ -3555,7 +3551,7 @@ class MMB_Backup extends MMB_Core
3555
  try {
3556
  $backup_folder_id = $backup_folder->getId();
3557
  $listFiles = $driveService->files->listFiles(array("q" => "title='".addslashes($args['backup_file'])."' and '$backup_folder_id' in parents and trashed = false"));
3558
- $files = $listFiles->getItems();;
3559
  } catch (Exception $e) {
3560
  $this->_log($e->getMessage());
3561
  /*return array(
@@ -3576,15 +3572,15 @@ class MMB_Backup extends MMB_Core
3576
  /**
3577
  * Downloads backup file from Google Drive to root folder on local server.
3578
  *
3579
- * @param array $args arguments passed to the function
3580
- * [google_drive_token] -> user's Google drive token in json form
3581
- * [google_drive_directory] -> folder on user's Google Drive account which backup file should be downloaded from
3582
- * [google_drive_site_folder] -> subfolder with site name in google_drive_directory which backup file should be downloaded from
3583
- * [backup_file] -> absolute path of backup file on local server
3584
  *
3585
- * @return bool|array absolute path to downloaded file is successful, array with error message if not
3586
  */
3587
- function get_google_drive_backup($args)
3588
  {
3589
  mwp_register_autoload_google();
3590
  $googleClient = new Google_ApiClient();
@@ -3733,12 +3729,12 @@ class MMB_Backup extends MMB_Core
3733
  /**
3734
  * Schedules the next execution of some backup task.
3735
  *
3736
- * @param string $type daily, weekly or monthly
3737
- * @param string $schedule format: task_time (if daily), task_time|task_day (if weekly), task_time|task_date (if monthly)
3738
  *
3739
- * @return bool|int timestamp if sucessful, false if not
3740
  */
3741
- function schedule_next($type, $schedule)
3742
  {
3743
  $schedule = explode("|", $schedule);
3744
 
@@ -3828,15 +3824,15 @@ class MMB_Backup extends MMB_Core
3828
  /**
3829
  * Parse task arguments for info on master.
3830
  *
3831
- * @return mixed associative array with stats for every backup task or error if backup is manually deleted on server
3832
  */
3833
- function get_backup_stats()
3834
  {
3835
  $stats = array();
3836
  $tasks = $this->tasks;
3837
  if (is_array($tasks) && !empty($tasks)) {
3838
  foreach ($tasks as $task_name => $info) {
3839
- if (is_array($info['task_results']) && !empty($info['task_results'])) {
3840
  foreach ($info['task_results'] as $key => $result) {
3841
  if (isset($result['server']) && !isset($result['error'])) {
3842
  if (isset($result['server']['file_path']) && !$info['task_args']['del_host_file']) {
@@ -3846,8 +3842,6 @@ class MMB_Backup extends MMB_Core
3846
  }
3847
  }
3848
  }
3849
- }
3850
- if (is_array($info['task_results'])) {
3851
  $stats[$task_name] = $info['task_results'];
3852
  }
3853
  }
@@ -3859,9 +3853,9 @@ class MMB_Backup extends MMB_Core
3859
  /**
3860
  * Returns all backup tasks with information when the next schedule will be.
3861
  *
3862
- * @return mixed associative array with timestamp with next schedule for every backup task
3863
  */
3864
- function get_next_schedules()
3865
  {
3866
  $stats = array();
3867
  $tasks = $this->tasks;
@@ -3878,11 +3872,11 @@ class MMB_Backup extends MMB_Core
3878
  * Deletes all old backups from local server.
3879
  * It depends on configuration on master (Number of backups to keep).
3880
  *
3881
- * @param string $task_name name of backup task
3882
  *
3883
- * @return bool|void true if there are backups for deletion, void if not
3884
  */
3885
- function remove_old_backups($task_name)
3886
  {
3887
  //Check for previous failed backups first
3888
  $this->cleanup();
@@ -3959,14 +3953,14 @@ class MMB_Backup extends MMB_Core
3959
  /**
3960
  * Deletes specified backup.
3961
  *
3962
- * @param array $args arguments passed to function
3963
- * [task_name] -> name of backup task
3964
- * [result_id] -> id of baskup task result, which should be restored
3965
- * [google_drive_token] -> json of Google Drive token, if it is remote destination
3966
  *
3967
- * @return bool true if successful, false if not
3968
  */
3969
- function delete_backup($args)
3970
  {
3971
  if (empty($args)) {
3972
  return false;
@@ -4039,9 +4033,9 @@ class MMB_Backup extends MMB_Core
4039
  /**
4040
  * Deletes all unneeded files produced by backup process.
4041
  *
4042
- * @return array array of deleted files
4043
  */
4044
- function cleanup()
4045
  {
4046
  $tasks = $this->tasks;
4047
  $backup_folder = WP_CONTENT_DIR.'/'.md5('mmb-worker').'/mwp_backups/';
@@ -4109,12 +4103,12 @@ class MMB_Backup extends MMB_Core
4109
  /**
4110
  * Uploads to remote destination in the second step, invoked from master.
4111
  *
4112
- * @param array $args arguments passed to function
4113
- * [task_name] -> name of backup task
4114
  *
4115
- * @return array|void void if success, array with error message if not
4116
  */
4117
- function remote_backup_now($args)
4118
  {
4119
  /**
4120
  * Remember if this is called as a forked http request, or a connection to the dasboard is persistent
@@ -4127,7 +4121,6 @@ class MMB_Backup extends MMB_Core
4127
  extract($args);
4128
  }
4129
 
4130
-
4131
  $tasks = $this->tasks;
4132
  $task_name = stripslashes($task_name);
4133
  $task = $tasks[$task_name];
@@ -4226,7 +4219,7 @@ class MMB_Backup extends MMB_Core
4226
  $this->update_tasks($tasks);
4227
  } else {
4228
  $return = array(
4229
- 'error' => 'Backup file not found on your server. Please try again.'
4230
  );
4231
  }
4232
  $this->sendDataToMaster();
@@ -4237,20 +4230,20 @@ class MMB_Backup extends MMB_Core
4237
  /**
4238
  * Checks if scheduled backup tasks should be executed.
4239
  *
4240
- * @param array $args arguments passed to function
4241
- * [task_name] -> name of backup task
4242
- * [task_id] -> id of backup task
4243
- * [$site_key] -> hash key of backup task
4244
- * [worker_version] -> version of worker
4245
- * [mwp_google_drive_refresh_token] -> should be Google Drive token be refreshed, true if it is remote destination of task
4246
- * @param string $url url on master where worker validate task
4247
  *
4248
- * @return string|array|boolean
4249
  */
4250
- function validate_task($args, $url)
4251
  {
4252
  if (!class_exists('WP_Http')) {
4253
- include_once(ABSPATH.WPINC.'/class-http.php');
4254
  }
4255
 
4256
  $worker_upto_3_9_22 = ($GLOBALS['MMB_WORKER_VERSION'] <= '3.9.22'); // worker version is less or equals to 3.9.22
@@ -4297,25 +4290,25 @@ class MMB_Backup extends MMB_Core
4297
  * Updates status of backup task.
4298
  * Positive number if completed, negative if not.
4299
  *
4300
- * @param string $task_name name of backup task
4301
- * @param int $status status which tasks should be updated to
4302
- * (
4303
- * 0 - Backup started,
4304
- * 1 - DB dump,
4305
- * 2 - DB ZIP,
4306
- * 3 - Files ZIP,
4307
- * 4 - Amazon S3,
4308
- * 5 - Dropbox,
4309
- * 6 - FTP,
4310
- * 7 - Email,
4311
- * 8 - Google Drive,
4312
- * 100 - Finished
4313
- * )
4314
- * @param bool $completed completed or not
4315
  *
4316
- * @return void
4317
  */
4318
- function update_status($task_name, $status, $completed = false)
4319
  {
4320
  if ($task_name != 'Backup Now') {
4321
  $tasks = $this->tasks;
@@ -4338,11 +4331,11 @@ class MMB_Backup extends MMB_Core
4338
  /**
4339
  * Update $this->tasks attribute and save it to wp_options with key mwp_backup_tasks.
4340
  *
4341
- * @param mixed $tasks associative array with all tasks data
4342
  *
4343
- * @return void
4344
  */
4345
- function update_tasks($tasks)
4346
  {
4347
  $this->tasks = $tasks;
4348
  update_option('mwp_backup_tasks', $tasks);
@@ -4353,7 +4346,7 @@ class MMB_Backup extends MMB_Core
4353
  *
4354
  * @return void
4355
  */
4356
- function wpdb_reconnect()
4357
  {
4358
  global $wpdb;
4359
 
@@ -4372,11 +4365,11 @@ class MMB_Backup extends MMB_Core
4372
  /**
4373
  * Replaces .htaccess file in process of restoring WordPress site.
4374
  *
4375
- * @param string $url url of current site
4376
  *
4377
- * @return void
4378
  */
4379
- function replace_htaccess($url)
4380
  {
4381
  $file = @file_get_contents(ABSPATH.'.htaccess');
4382
  if ($file && strlen($file)) {
@@ -4392,9 +4385,9 @@ class MMB_Backup extends MMB_Core
4392
  /**
4393
  * Removes cron for checking scheduled tasks, if there are not any scheduled task.
4394
  *
4395
- * @return void
4396
  */
4397
- function check_cron_remove()
4398
  {
4399
  if (empty($this->tasks) || (count($this->tasks) == 1 && isset($this->tasks['Backup Now']))) {
4400
  wp_clear_scheduled_hook('mwp_backup_tasks');
@@ -4405,9 +4398,9 @@ class MMB_Backup extends MMB_Core
4405
  /**
4406
  * Re-add tasks on website re-add.
4407
  *
4408
- * @param array $params arguments passed to function
4409
  *
4410
- * @return array $params without backups
4411
  */
4412
  public function readd_tasks($params = array())
4413
  {
@@ -4460,7 +4453,6 @@ class MMB_Backup extends MMB_Core
4460
  $decrypted = $cipher->decrypt($task['secure']);
4461
  $task['account_info'] = json_decode($decrypted, true);
4462
  }
4463
-
4464
  }
4465
  if (isset($task['account_info']) && is_array($task['account_info'])) { //only if sends from master first time(secure data)
4466
  $task['args']['account_info'] = $task['account_info'];
@@ -4480,19 +4472,19 @@ class MMB_Backup extends MMB_Core
4480
  /**
4481
  * Start backup process. Invoked from remote ping
4482
  *
4483
- * @param array $args arguments passed to function
4484
- * [task_name] -> name of backup task
4485
  *
4486
- * @return array array with error message or if success task results
4487
  */
4488
  public function ping_backup($args)
4489
  {
4490
  // Belows code follows logic from check_backup
4491
- $return = "PONG";
4492
- $task_name = $args['task_name'];
4493
  $sendDataToMaster = false;
4494
  if (is_array($this->tasks) && !empty($this->tasks) && !empty($this->tasks[$task_name])) {
4495
- $task = $this->tasks[$task_name];
4496
  $sendDataToMaster = isset($task['task_args']['account_info']) ? false : true;
4497
  if ($task['task_args']['task_id'] && $task['task_args']['site_key']) {
4498
  $potential_token = !empty($args['google_drive_token']) ? $args['google_drive_token'] : false;
@@ -4504,9 +4496,9 @@ class MMB_Backup extends MMB_Core
4504
  * From this point I am simulating previous way of working. In order to fix this,
4505
  * I need to refactor greater part, and release is tomorrow morning
4506
  */
4507
- $update = array(
4508
  'task_name' => $task_name,
4509
- 'args' => $task['task_args']
4510
  );
4511
  $update['time'] = time();
4512
  $this->set_backup_task($update);
@@ -4521,7 +4513,7 @@ class MMB_Backup extends MMB_Core
4521
  array(
4522
  'task_name' => $task_name,
4523
  'args' => $task['task_args'],
4524
- 'error' => $return
4525
  )
4526
  );
4527
  } else {
@@ -4530,8 +4522,6 @@ class MMB_Backup extends MMB_Core
4530
  }
4531
  $return = $this->tasks[$task_name]['task_results'];
4532
  }
4533
-
4534
-
4535
  }
4536
  } else {
4537
  $return = array("error" => "Unknown task name");
@@ -4539,6 +4529,7 @@ class MMB_Backup extends MMB_Core
4539
  if ($sendDataToMaster) {
4540
  $this->sendDataToMaster();
4541
  }
 
4542
  return $return;
4543
  }
4544
 
@@ -4551,25 +4542,24 @@ class MMB_Backup extends MMB_Core
4551
  {
4552
  $backup_file = $this->tasks[$task_name]['task_results'][count($this->tasks[$task_name]['task_results']) - 1]['server']['file_url'];
4553
  $del_host_file = $this->tasks[$task_name]['task_args']['del_host_file'];
4554
- $args = array('task_name' => $task_name, 'backup_file' => $backup_file, 'del_host_file' => $del_host_file);
4555
 
4556
  $this->notifyMyself('mmb_remote_upload', $args);
4557
  }
4558
-
4559
  }
4560
 
4561
  /*if( function_exists('add_filter') ) {
4562
- add_filter( 'mwp_website_add', 'MMB_Backup::readd_tasks' );
4563
  }*/
4564
 
4565
  if (!function_exists('get_all_files_from_dir')) {
4566
  /**
4567
  * Get all files in directory
4568
  *
4569
- * @param string $path Relative or absolute path to folder
4570
- * @param array $exclude List of excluded files or folders, relative to $path
4571
  *
4572
- * @return array List of all files in folder $path, exclude all files in $exclude array
4573
  */
4574
  function get_all_files_from_dir($path, $exclude = array())
4575
  {
@@ -4598,9 +4588,9 @@ if (!function_exists('get_all_files_from_dir_recursive')) {
4598
  * wrapped function which writes in global variable
4599
  * and exclued files or folders are read from global variable
4600
  *
4601
- * @param string $path Relative or absolute path to folder
4602
  *
4603
- * @return void
4604
  */
4605
  function get_all_files_from_dir_recursive($path)
4606
  {
@@ -4645,7 +4635,7 @@ function recursiveUrlReplacement(&$value, $index, $data)
4645
  if (is_string($value)) {
4646
  if (is_string($data['regex'])) {
4647
  $expressions = array($data['regex']);
4648
- } else if (is_array($data['regex'])) {
4649
  $expressions = $data['regex'];
4650
  } else {
4651
  return;
@@ -4677,7 +4667,7 @@ function restore_migrate_urls()
4677
  $tablePrefix = $restoreParams['tablePrefix'];
4678
  $newUrl = $restoreParams['newUrl'];
4679
 
4680
- if(!isset($oldSiteUrl) || !isset($oldUrl)){
4681
  return false;
4682
  }
4683
 
@@ -4685,7 +4675,7 @@ function restore_migrate_urls()
4685
  $parsedOldUrl = parse_url(strpos($oldUrl, '://') === false ? "http://$oldUrl" : $oldUrl);
4686
  $host = getKey('host', $parsedOldSiteUrl, '');
4687
  $path = getKey('path', $parsedOldSiteUrl, '');
4688
- $oldSiteUrlNoWww = preg_replace('#^www\.(.+\.)#i', '$1', $host) . $path;
4689
  $parsedOldSiteUrlNoWww = parse_url(strpos($oldSiteUrlNoWww, '://') === false
4690
  ? "http://$oldSiteUrlNoWww"
4691
  : $oldSiteUrlNoWww
@@ -4696,8 +4686,8 @@ function restore_migrate_urls()
4696
 
4697
  // Modify the database for two variants of url, one with and one without WWW
4698
  $oldUrls = array('oldSiteUrl' => $oldSiteUrl);
4699
- $tmp1 = @"{$parsedOldUrl['host']}/{$parsedOldUrl['path']}";
4700
- $tmp2 = @"{$parsedOldSiteUrlNoWww['host']}/{$parsedOldSiteUrlNoWww['path']}";
4701
  if ($oldSiteUrlNoWww != $oldSiteUrl && $tmp1 != $tmp2) {
4702
  $oldUrls['oldSiteUrlNoWww'] = $oldSiteUrlNoWww;
4703
  }
@@ -4728,7 +4718,7 @@ function restore_migrate_urls()
4728
  if (is_array($unserialized)) {
4729
  array_walk_recursive($unserialized, 'recursiveUrlReplacement', array(
4730
  'newUrl' => $newUrl,
4731
- 'regex' => $amazingRegex
4732
  )
4733
  );
4734
  $replaced = serialize($unserialized);
@@ -4756,7 +4746,7 @@ function restore_migrate_urls()
4756
  if (is_array($unserialized)) {
4757
  array_walk_recursive($unserialized, 'recursiveUrlReplacement', array(
4758
  'newUrl' => $newUrl,
4759
- 'regex' => $amazingRegex
4760
  )
4761
  );
4762
  }
@@ -4771,7 +4761,6 @@ function restore_migrate_urls()
4771
  $query = "UPDATE {$tablePrefix}postmeta SET meta_value = '{$escapedReplacement}' WHERE meta_id = '$id'";
4772
  $wpdb->query($query);
4773
  }
4774
-
4775
  }
4776
 
4777
  // Do the same with posts
@@ -4781,7 +4770,6 @@ function restore_migrate_urls()
4781
  $postContent = preg_replace($amazingRegex, $newUrl, $row['post_content']);
4782
  $guid = preg_replace($amazingRegex, $newUrl, $row['guid']);
4783
 
4784
-
4785
  if ($postContent != $row['post_content'] || $guid != $row['guid']) {
4786
  $postContent = $wpdb->_escape($postContent);
4787
  $guid = $wpdb->_escape($guid);
@@ -4795,11 +4783,11 @@ function restore_migrate_urls()
4795
 
4796
  function restore_htaccess()
4797
  {
4798
- $htaccessRealpath = realpath(ABSPATH . '.htaccess');
4799
 
4800
  if ($htaccessRealpath) {
4801
  @rename($htaccessRealpath, "$htaccessRealpath.old");
4802
  }
4803
- @include(ABSPATH . 'wp-admin/includes/admin.php');
4804
  @flush_rewrite_rules(true);
4805
  }
64
  51 => 'The end of the ZIP archive was encountered prematurely.',
65
  80 => 'The user aborted unzip prematurely.',
66
  81 => 'Testing or extraction of one or more files failed due to unsupported compression methods or unsupported decryption.',
67
+ 82 => 'No files were found due to bad decryption password(s)',
68
  );
69
 
70
  /**
71
  * Initializes site_name, statuses, and tasks attributes.
72
  */
73
+ public function __construct()
74
  {
75
  parent::__construct();
76
+ $this->site_name = str_replace(array("_", "/", "~", ":"), array("", "-", "-", "-"), rtrim($this->remove_http(get_bloginfo('url')), "/"));
77
  $this->statuses = array(
78
  'db_dump' => 1,
79
  'db_zip' => 2,
84
  'email' => 7,
85
  'google_drive' => 8,
86
  'sftp' => 9,
87
+ 'finished' => 100,
88
  );
89
 
90
  $this->w3tc_flush();
95
  /**
96
  * Tries to increase memory limit to 384M and execution time to 600s.
97
  *
98
+ * @return array an array with two keys for execution time and memory limit (0 - if not changed, 1 - if succesfully)
99
  */
100
+ public function set_memory()
101
  {
102
  $changed = array('execution_time' => 0, 'memory_limit' => 0);
103
  ignore_user_abort(true);
130
  /**
131
  * Returns backup settings from local database for all tasks
132
  *
133
+ * @return mixed|boolean
134
  */
135
+ public function get_backup_settings()
136
  {
137
  $backup_settings = get_option('mwp_backup_tasks');
138
 
146
  /**
147
  * Sets backup task defined from master, if task name is "Backup Now" this function fires processing backup.
148
  *
149
+ * @param mixed $params parameters sent from master
150
  *
151
+ * @return mixed|boolean $this->tasks variable if success, array with error message if error has ocurred, false if $params are empty
152
  */
153
+ public function set_backup_task($params)
154
  {
155
  //$params => [$task_name, $args, $error]
156
  if (!empty($params)) {
 
157
  //Make sure backup cron job is set
158
  /*if (!wp_next_scheduled('mwp_backup_tasks')) {
159
  wp_schedule_event(time(), 'tenminutes', 'mwp_backup_tasks');
170
  if (isset($args['remove'])) {
171
  unset($before[$task_name]);
172
  $return = array(
173
+ 'removed' => true,
174
  );
175
  } else {
176
  if (isset($params['account_info']) && is_array($params['account_info'])) { //only if sends from master first time(secure data)
227
  * @deprecated deprecated since version 3.9.29
228
  * @return void
229
  */
230
+ public function check_backup_tasks()
231
  {
232
  $this->check_cron_remove();
233
 
243
  'task_name' => $task_name,
244
  'task_id' => $setting['task_args']['task_id'],
245
  'site_key' => $setting['task_args']['site_key'],
246
+ 'worker_version' => $GLOBALS['MMB_WORKER_VERSION'],
247
  );
248
 
249
  if (isset($setting['task_args']['account_info']['mwp_google_drive']['google_drive_token'])) {
274
  $setting['task_args']['account_info']['mwp_google_drive']['google_drive_token'] = $potential_token;
275
  }
276
  }
 
277
  }
278
 
279
  $update = array(
280
  'task_name' => $task_name,
281
+ 'args' => $settings[$task_name]['task_args'],
282
  );
283
 
284
  if ($check != 'paused') {
292
  continue;
293
  }
294
 
 
295
  $result = $this->backup($setting['task_args'], $task_name);
296
  $error = '';
297
 
301
  array(
302
  'task_name' => $task_name,
303
  'args' => $settings[$task_name]['task_args'],
304
+ 'error' => $error,
305
  ));
306
  } else {
307
  if (@count($setting['task_args']['account_info'])) {
313
  }
314
  }
315
  }
 
316
  }
317
 
318
  /**
319
  * Runs backup task invoked from ManageWP master.
320
  *
321
+ * @param string $task_name name of backup task
322
+ * @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)
323
  *
324
+ * @return mixed array with backup statistics if successful, array with error message if not
325
  */
326
+ public function task_now($task_name, $google_drive_token = false)
327
  {
328
  if ($google_drive_token) {
329
  $this->tasks[$task_name]['task_args']['account_info']['mwp_google_drive']['google_drive_token'] = $google_drive_token;
339
  $this->set_backup_task(array(
340
  'task_name' => $task_name,
341
  'args' => $settings[$task_name]['task_args'],
342
+ 'time' => time(),
343
  ));
344
 
345
  //Run backup
350
  $this->set_backup_task(array(
351
  'task_name' => $task_name,
352
  'args' => $settings[$task_name]['task_args'],
353
+ 'error' => $result['error'],
354
  ));
355
 
356
  return $result;
363
  * Backup a full wordpress instance, including a database dump, which is placed in mwp_db dir in root folder.
364
  * All backups are compressed by zip and placed in wp-content/managewp/backups folder.
365
  *
366
+ * @param string $args arguments passed from master
367
+ * [type] -> db, full
368
+ * [what] -> daily, weekly, monthly
369
+ * [account_info] -> remote destinations ftp, amazons3, dropbox, google_drive, email with their parameters
370
+ * [include] -> array of folders from site root which are included to backup (wp-admin, wp-content, wp-includes are default)
371
+ * [exclude] -> array of files of folders to exclude, relative to site's root
372
+ * @param bool|string[optional] $task_name the name of backup task, which backup is done (default: false)
373
  *
374
+ * @return bool|array false if $args are missing, array with error if error has occured, ture if is successful
375
  */
376
+ public function backup($args, $task_name = false)
377
  {
378
  if (!$args || empty($args)) {
379
  return false;
391
  $error_message = 'Remote destination is not supported, please update your client plugin.';
392
 
393
  return array(
394
+ 'error' => $error_message,
395
  );
396
  }
397
  }
412
  if (!file_exists($new_file_path)) {
413
  if (!mkdir($new_file_path, 0755, true)) {
414
  return array(
415
+ 'error' => 'Permission denied, make sure you have write permissions to the wp-content folder.',
416
  );
417
  }
418
  }
439
  $error_message = $db_backup['error'];
440
 
441
  return array(
442
+ 'error' => $error_message,
443
  );
444
  }
445
  } elseif (trim($what) == 'full') {
454
  $error_message = $content_backup['error'];
455
 
456
  return array(
457
+ 'error' => $error_message,
458
  );
459
  }
460
  }
480
  if ($task_name != 'Backup Now') {
481
  $paths['server'] = array(
482
  'file_path' => $backup_file,
483
+ 'file_url' => $backup_url,
484
  );
485
  } else {
486
  $paths['server'] = array(
487
  'file_path' => $backup_file,
488
+ 'file_url' => $backup_url,
489
  );
490
  }
491
 
519
  if ($task_name != 'Backup Now') {
520
  $paths['status'] = $temp[count($temp) - 1]['status'];
521
  $temp[count($temp) - 1] = $paths;
 
522
  } else {
523
  $temp[count($temp)] = $paths;
524
  }
540
  * Backup a full wordpress instance, including a database dump, which is placed in mwp_db dir in root folder.
541
  * All backups are compressed by zip and placed in wp-content/managewp/backups folder.
542
  *
543
+ * @param string $task_name the name of backup task, which backup is done
544
+ * @param string $backup_file relative path to file which backup is stored
545
+ * @param array [optional] $exclude the list of files and folders, which are excluded from backup (default: array())
546
+ * @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())
547
  *
548
+ * @return bool|array true if backup is successful, or an array with error message if is failed
549
  */
550
+ public function backup_full($task_name, $backup_file, $exclude = array(), $include = array())
551
  {
552
  $this->update_status($task_name, $this->statuses['db_dump']);
553
  $db_result = $this->backup_db();
554
 
555
  if ($db_result == false) {
556
  return array(
557
+ 'error' => 'Failed to backup database.',
558
  );
559
  } else {
560
  if (is_array($db_result) && isset($db_result['error'])) {
561
  return array(
562
+ 'error' => $db_result['error'],
563
  );
564
  }
565
  }
591
  }
592
 
593
  return array(
594
+ 'error' => 'Failed to zip database. '.$archive->error_code.$archive->error_string,
595
  );
596
  }
597
  }
602
  @unlink($db_result);
603
  @rmdir(MWP_DB_DIR);
604
 
605
+ $remove = array(
606
  trim(basename(WP_CONTENT_DIR))."/managewp/backups",
607
+ trim(basename(WP_CONTENT_DIR))."/infinitewp/backups",
608
  trim(basename(WP_CONTENT_DIR))."/".md5('mmb-worker')."/mwp_backups",
609
+ trim(basename(WP_CONTENT_DIR))."/backupwordpress",
610
+ trim(basename(WP_CONTENT_DIR))."/contents/cache",
611
+ trim(basename(WP_CONTENT_DIR))."/content/cache",
612
  trim(basename(WP_CONTENT_DIR))."/cache",
613
+ trim(basename(WP_CONTENT_DIR))."/old-cache",
614
+ trim(basename(WP_CONTENT_DIR))."/uploads/backupbuddy_backups",
615
  trim(basename(WP_CONTENT_DIR))."/w3tc",
616
+ "dbcache",
617
+ "pgcache",
618
+ "objectcache",
619
  );
620
  $exclude = array_merge($exclude, $remove);
621
 
651
  @unlink($backup_file);
652
 
653
  return array(
654
+ 'error' => 'Failed to zip files. pclZip error ('.$archive->error_code.'): .'.$archive->error_string,
655
  );
656
  }
657
  }
676
  * @todo report errors back to the user
677
  * @todo report error if DB dump is not found
678
  */
679
+ public function zip_backup_db($taskName, $backupFile)
680
  {
681
  $disableCompression = $this->tasks[$taskName]['task_args']['disable_comp'];
682
 
688
  ->setWorkingDirectory(untrailingslashit(MWP_BACKUP_DIR))
689
  ->setTimeout(3600)
690
  ->setPrefix($zip)
691
+ ->add('-q')// quiet operation
692
+ ->add('-r')// recurse paths, include files in subdirs: zip -r a path path ...
693
  ->add($compressionLevel)
694
+ ->add($backupFile)// zipfile to write to
695
  ->add('mwp_db') // file/directory list
696
  ;
697
 
734
  /**
735
  * Zipping database dump and index.php in folder mwp_db by ZipArchive class, requires php zip extension.
736
  *
737
+ * @param string $task_name the name of backup task
738
+ * @param string $db_result relative path to database dump file
739
+ * @param string $backup_file absolute path to zip file
740
  *
741
+ * @return bool is compress successful or not
742
  */
743
+ public function zip_archive_backup_db($task_name, $db_result, $backup_file)
744
  {
745
  $disable_comp = $this->tasks[$task_name]['task_args']['disable_comp'];
746
  $zip = new ZipArchive();
764
  /**
765
  * Zipping database dump and index.php in folder mwp_db by PclZip library.
766
  *
767
+ * @param string $task_name the name of backup task
768
+ * @param string $backup_file absolute path to zip file
769
  *
770
+ * @return bool is compress successful or not
771
  */
772
+ public function pclzip_backup_db($task_name, $backup_file)
773
  {
774
  $disable_comp = $this->tasks[$task_name]['task_args']['disable_comp'];
775
  define('PCLZIP_TEMPORARY_DIR', MWP_BACKUP_DIR.'/');
789
  * Zipping whole site root folder and append to backup file with database dump
790
  * by system zip command, requires zip installed on OS.
791
  *
792
+ * @param string $task_name the name of backup task
793
+ * @param string $backupFile absolute path to zip file
794
+ * @param array $exclude array of files of folders to exclude, relative to site's root
795
+ * @param array $include array of folders from site root which are included to backup (wp-admin, wp-content, wp-includes are default)
796
  *
797
+ * @return array|bool true if successful or an array with error message if not
798
  */
799
+ public function zip_backup($task_name, $backupFile, $exclude, $include)
800
  {
801
  $compressionLevel = $this->tasks[$task_name]['task_args']['disable_comp'] ? 0 : 1;
802
 
985
  * Zipping whole site root folder and append to backup file with database dump
986
  * by ZipArchive class, requires php zip extension.
987
  *
988
+ * @param string $task_name the name of backup task
989
+ * @param string $backup_file absolute path to zip file
990
+ * @param array $exclude array of files of folders to exclude, relative to site's root
991
+ * @param array $include array of folders from site root which are included to backup (wp-admin, wp-content, wp-includes are default)
992
  *
993
+ * @return array|bool true if successful or an array with error message if not
994
  */
995
+ public function zip_archive_backup($task_name, $backup_file, $exclude, $include, $overwrite = false)
996
  {
997
  $filelist = $this->get_backup_files($exclude, $include);
998
  $disable_comp = $this->tasks[$task_name]['task_args']['disable_comp'];
1028
  * Zipping whole site root folder and append to backup file with database dump
1029
  * by PclZip library.
1030
  *
1031
+ * @param string $task_name the name of backup task
1032
+ * @param string $backup_file absolute path to zip file
1033
+ * @param array $exclude array of files of folders to exclude, relative to site's root
1034
+ * @param array $include array of folders from site root which are included to backup (wp-admin, wp-content, wp-includes are default)
1035
  *
1036
+ * @return array|bool true if successful or an array with error message if not
1037
  */
1038
+ public function pclzip_backup($task_name, $backup_file, $exclude, $include)
1039
  {
1040
  define('PCLZIP_TEMPORARY_DIR', MWP_BACKUP_DIR.'/');
1041
  require_once ABSPATH.'/wp-admin/includes/class-pclzip.php';
1043
  $add = array(
1044
  trim(WPINC),
1045
  trim(basename(WP_CONTENT_DIR)),
1046
+ 'wp-admin',
1047
  );
1048
 
1049
  if (!file_exists(ABSPATH.'wp-config.php')
1108
  * By default, there are all files from root folder, all files from folders wp-admin, wp-content, wp-includes recursively.
1109
  * Parameter $include adds other folders from site root, and excludes any file or folder by relative path to site's root.
1110
  *
1111
+ * @param array $exclude array of files of folders to exclude, relative to site's root
1112
+ * @param array $include array of folders from site root which are included to backup (wp-admin, wp-content, wp-includes are default)
1113
  *
1114
+ * @return array array with all files in site root dir
1115
  */
1116
+ public function get_backup_files($exclude, $include)
1117
  {
1118
  $add = array(
1119
  trim(WPINC),
1120
  trim(basename(WP_CONTENT_DIR)),
1121
+ "wp-admin",
1122
  );
1123
 
1124
  $include = array_merge($add, $include);
1163
  * Backup a database dump of WordPress site.
1164
  * All backups are compressed by zip and placed in wp-content/managewp/backups folder.
1165
  *
1166
+ * @param string $task_name the name of backup task, which backup is done
1167
+ * @param string $backup_file relative path to file which backup is stored
1168
  *
1169
+ * @return bool|array true if backup is successful, or an array with error message if is failed
1170
  */
1171
+ public function backup_db_compress($task_name, $backup_file)
1172
  {
1173
  $this->update_status($task_name, $this->statuses['db_dump']);
1174
  $db_result = $this->backup_db();
1175
 
1176
  if ($db_result == false) {
1177
  return array(
1178
+ 'error' => 'Failed to backup database.',
1179
  );
1180
  } else {
1181
  if (is_array($db_result) && isset($db_result['error'])) {
1182
  return array(
1183
+ 'error' => $db_result['error'],
1184
  );
1185
  }
1186
  }
1206
  @rmdir(MWP_DB_DIR);
1207
 
1208
  return array(
1209
+ 'error' => 'Failed to zip database. pclZip error ('.$archive->error_code.'): .'.$archive->error_string,
1210
  );
1211
  }
1212
  }
1225
  * Creates database dump and places it in mwp_db folder in site's root.
1226
  * This function dispatches if OS mysql command does not work calls a php alternative.
1227
  *
1228
+ * @return string|array path to dump file if successful, or an array with error message if is failed
1229
  */
1230
+ public function backup_db()
1231
  {
1232
  $db_folder = MWP_DB_DIR.'/';
1233
  if (!file_exists($db_folder)) {
1234
  if (!mkdir($db_folder, 0755, true)) {
1235
  return array(
1236
+ 'error' => 'Error creating database backup folder ('.$db_folder.'). Make sure you have correct write permissions.',
1237
  );
1238
  }
1239
  }
1243
  return $result;
1244
  }
1245
 
1246
+ public function file_get_size($file)
1247
  {
1248
  if (!extension_loaded('bcmath')) {
1249
  return filesize($file);
1293
  *
1294
  * @return string|array path to dump file if successful, or an array with error message if is failed
1295
  */
1296
+ public function backup_db_dump($file)
1297
  {
1298
  $mysqldump = mwp_container()->getExecutableFinder()->find('mysqldump', 'mysqldump');
1299
 
1301
  ->setWorkingDirectory(untrailingslashit(ABSPATH))
1302
  ->setTimeout(3600)
1303
  ->setPrefix($mysqldump)
1304
+ ->add('--force')// Continue even if we get an SQL error.
1305
+ ->add('--user='.DB_USER)// User for login if not current user.
1306
+ ->add('--password='.DB_PASSWORD)// Password to use when connecting to server. If password is not given it's solicited on the tty.
1307
+ ->add('--add-drop-table')// Add a DROP TABLE before each create.
1308
+ ->add('--lock-tables=false')// Don't lock all tables for read.
1309
  ->add(DB_NAME)
1310
  ->add('--result-file='.$file);
1311
 
1326
  $processBuilder->add('--socket='.$host);
1327
  } else {
1328
  $processBuilder->add('--host='.$host);
1329
+ if (!empty($port)) {
1330
  $processBuilder->add('--port='.$port);
1331
  }
1332
  }
1356
  ));
1357
  }
1358
 
1359
+ if (class_exists('PDO') && extension_loaded('pdo_mysql')) {
1360
  mwp_logger()->info('Using PHP dumper v2');
1361
  try {
1362
  $config = array(
1397
  }
1398
  }
1399
 
 
1400
  if (filesize($file) === 0) {
1401
  unlink($file);
1402
  mwp_logger()->error('Database dumping process failed with unknown reason', array(
1418
  /**
1419
  * Creates database dump by php functions.
1420
  *
1421
+ * @param string $file absolute path to file in which dump should be placed
1422
  *
1423
+ * @return string|array path to dump file if successful, or an array with error message if is failed
1424
  */
1425
+ public function backup_db_php($file)
1426
  {
1427
  global $wpdb;
1428
  $tables = $wpdb->get_results('SHOW TABLES', ARRAY_N);
1477
  @unlink($file);
1478
 
1479
  return array(
1480
+ 'error' => 'Database backup failed. Try to enable MySQL dump on your server.',
1481
  );
1482
  }
1483
 
1484
  return $file;
1485
  }
1486
 
1487
+ public function restore($params)
1488
  {
1489
  global $wpdb;
1490
  if (empty($params)) {
1527
  $unzipFailed = true;
1528
  }
1529
 
1530
+ if ($unzipFailed && class_exists("ZipArchive")) {
1531
  $unzipFailed = false;
1532
  try {
1533
  $this->unzipWithZipArchive($backupFile);
1588
 
1589
  // Try to fetch old home and site url, as well as new ones for usage later in database updates
1590
  // Take fresh options
1591
+ $homeOpt = $wpdb->get_row($wpdb->prepare("SELECT option_value FROM $wpdb->options WHERE option_name = %s LIMIT 1", 'home'));
1592
  $siteUrlOpt = $wpdb->get_row($wpdb->prepare("SELECT option_value FROM $wpdb->options WHERE option_name = %s LIMIT 1", 'siteurl'));
1593
  global $restoreParams;
1594
+ $restoreParams = array(
1595
+ 'oldUrl' => is_object($homeOpt) ? $homeOpt->option_value : null,
1596
  'oldSiteUrl' => is_object($siteUrlOpt) ? $siteUrlOpt->option_value : null,
1597
  'tablePrefix' => $this->get_table_prefix(),
1598
+ 'newUrl' => '',
1599
  );
1600
 
1601
  /* Replace options and content urls */
1602
  $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, $params['current_tasks_tmp']);
1603
 
1604
+ $newUrl = $wpdb->get_row($wpdb->prepare("SELECT option_value FROM $wpdb->options WHERE option_name = %s LIMIT 1", 'home'));
1605
  $restoreParams['newUrl'] = is_object($newUrl) ? $newUrl->option_value : null;
1606
  restore_migrate_urls();
1607
  restore_htaccess();
1609
  global $configDiff;
1610
  $result = array(
1611
  'status' => true,
1612
+ 'admins' => $this->getAdminUsers(),
1613
  );
1614
  if (isset($configDiff)
1615
  && is_array($configDiff)
1620
  return $result;
1621
  }
1622
 
1623
+ private function getAdminUsers()
1624
+ {
1625
  global $wpdb;
1626
  $users = get_users(array(
1627
+ 'role' => array('administrator'),
1628
+ 'fields' => array('user_login'),
1629
+ ));
 
1630
 
1631
+ return $users;
1632
  }
1633
 
1634
  private function getBackup($taskName, $resultId, $backupUrl = null)
1731
  $oldOptions['clone_options']['upload_path'] = get_option('upload_path');
1732
  $oldOptions['clone_options']['upload_url_path'] = get_option('upload_url_path');
1733
 
 
1734
  $oldOptions['clone_options']['mwp_backup_tasks'] = maybe_serialize(get_option('mwp_backup_tasks'));
1735
  $oldOptions['clone_options']['mwp_notifications'] = maybe_serialize(get_option('mwp_notifications'));
1736
  $oldOptions['clone_options']['mwp_pageview_alerts'] = maybe_serialize(get_option('mwp_pageview_alerts'));
1783
  private function unzipWithZipArchive($backupFile)
1784
  {
1785
  mwp_logger()->info('Falling back to ZipArchive Module');
1786
+ $result = false;
1787
  $zipArchive = new ZipArchive();
1788
+ $zipOpened = $zipArchive->open($backupFile);
1789
+ if ($zipOpened === true) {
1790
  $result = $zipArchive->extractTo(ABSPATH);
1791
  $zipArchive->close();
1792
  }
1793
+ if ($result === false) {
1794
+ throw new Exception('Failed to unzip files with ZipArchive. Message: '.$zipArchive->getStatusString());
1795
  }
1796
  }
1797
 
1824
  /* Get New Table prefix */
1825
  $new_table_prefix = trim($this->get_table_prefix());
1826
 
1827
+ $configPath = ABSPATH.'wp-config.php';
1828
+ $sourceConfigCopyPath = ABSPATH.'wp-config.source.php';
1829
+ $destinationConfigPath = ABSPATH.'mwp-temp-wp-config.php';
1830
 
1831
  @rename($configPath, $sourceConfigCopyPath);
1832
 
1844
  global $configDiff;
1845
  $configDiff = array(
1846
  'additions' => array_values(array_diff($sourceTokens, $destinationTokens)),
1847
+ 'subtractions' => array_values(array_diff($destinationTokens, $sourceTokens)),
1848
  );
1849
  }
1850
  }
1905
  $query = "UPDATE ".$new_table_prefix."users SET user_email=%s, user_login = %s, user_pass = %s WHERE user_login = %s";
1906
  $wpdb->query($wpdb->prepare($query, $adminEmail, $newUser, $newPassword, $temp_user->user_login));
1907
  }
 
1908
  }
1909
  }
1910
  }
1914
  if (!empty($key)) {
1915
  $query = "SELECT option_value FROM ".$new_table_prefix."options WHERE option_name = %s";
1916
  $res = $wpdb->get_var($wpdb->prepare($query, $key));
1917
+ if ($res === false) {
1918
  $query = "INSERT INTO ".$new_table_prefix."options (option_value,option_name) VALUES(%s,%s)";
1919
  $wpdb->query($wpdb->prepare($query, $option, $key));
1920
  } else {
1930
  $wpdb->query($query);
1931
 
1932
  /* Restore previous backups */
1933
+ $wpdb->query("UPDATE ".$new_table_prefix."options SET option_value = '".serialize($currentTasksTmp)."' WHERE option_name = 'mwp_backup_tasks'");
1934
 
1935
  /* Check for .htaccess permalinks update */
1936
  $this->replace_htaccess($home);
1944
  }
1945
  }
1946
 
1947
+ public function restore_db($fileName)
1948
  {
1949
  if (!$fileName) {
1950
  throw new Exception('Cannot access database file.');
2007
  // unlink($fileName);
2008
  }
2009
 
 
2010
  /**
2011
  * Restores database dump by php functions.
2012
  *
2013
+ * @param string $file_name relative path to database dump, which should be restored
2014
  *
2015
+ * @return bool is successful or not
2016
  */
2017
+ public function restore_db_php($file_name)
2018
  {
2019
  global $wpdb;
2020
 
2060
  * Retruns table_prefix for this WordPress installation.
2061
  * It is used by restore.
2062
  *
2063
+ * @return string table prefix from wp-config.php file, (default: wp_)
2064
  */
2065
+ public function get_table_prefix()
2066
  {
2067
  $lines = file(ABSPATH.'wp-config.php');
2068
  foreach ($lines as $line) {
2082
  /**
2083
  * Change all tables to InnoDB engine, and executes mysql OPTIMIZE TABLE for each table.
2084
  *
2085
+ * @return bool optimized successfully or not
2086
  */
2087
+ public function optimize_tables()
2088
  {
2089
  global $wpdb;
2090
  $query = 'SHOW TABLE STATUS';
2097
  $optimize = $wpdb->query("OPTIMIZE TABLE $table_string");
2098
 
2099
  return (bool) $optimize;
 
2100
  }
2101
 
2102
  public function getServerInformationForStats()
2120
  /**
2121
  * Check if proc_open exists
2122
  *
2123
+ * @return string|bool exec if exists, then system, then passthru, then false if no one exist
2124
  */
2125
  private function procOpenExists()
2126
  {
2218
  /**
2219
  * Returns all important information of worker's system status to master.
2220
  *
2221
+ * @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
2222
  */
2223
+ public function check_backup_compat()
2224
  {
2225
  $reqs = array();
2226
  if (strpos($_SERVER['DOCUMENT_ROOT'], '/') === 0) {
2361
  * Uploads backup file from server to email.
2362
  * A lot of email service have limitation to 10mb.
2363
  *
2364
+ * @param array $args arguments passed to the function
2365
+ * [email] -> email address which backup should send to
2366
+ * [task_name] -> name of backup task
2367
+ * [file_path] -> absolute path of backup file on local server
2368
  *
2369
+ * @return bool|array true is successful, array with error message if not
2370
  */
2371
+ public function email_backup($args)
2372
  {
2373
  $email = $args['email'];
2374
 
2375
  if (!is_email($email)) {
2376
  return array(
2377
+ 'error' => 'Your email ('.$email.') is not correct',
2378
  );
2379
  }
2380
  $backup_file = $args['file_path'];
2381
  $task_name = isset($args['task_name']) ? $args['task_name'] : '';
2382
  if (file_exists($backup_file)) {
2383
  $attachments = array(
2384
+ $backup_file,
2385
  );
2386
+ $headers = 'From: ManageWP <no-reply@managewp.com>'."\r\n";
2387
+ $subject = "ManageWP - ".$task_name." - ".$this->site_name;
2388
  ob_start();
2389
  $result = wp_mail($email, $subject, $subject, $headers, $attachments);
2390
  ob_end_clean();
2391
  } else {
2392
  return array(
2393
+ 'error' => 'The backup file ('.$backup_file.') does not exist.',
2394
  );
2395
  }
2396
 
2397
  if (!$result) {
2398
  return array(
2399
+ 'error' => 'Email not sent. Maybe your backup is too big for email or email server is not available on your website.',
2400
  );
2401
  }
2402
 
2406
  /**
2407
  * Uploads backup file from server to remote sftp server.
2408
  *
2409
+ * @param array $args arguments passed to the function
2410
+ * [sftp_username] -> sftp username on remote server
2411
+ * [sftp_password] -> sftp password on remote server
2412
+ * [sftp_hostname] -> sftp hostname of remote host
2413
+ * [sftp_remote_folder] -> folder on remote site which backup file should be upload to
2414
+ * [sftp_site_folder] -> subfolder with site name in ftp_remote_folder which backup file should be upload to
2415
+ * [sftp_passive] -> passive mode or not
2416
+ * [sftp_ssl] -> ssl or not
2417
+ * [sftp_port] -> number of port for ssl protocol
2418
+ * [backup_file] -> absolute path of backup file on local server
2419
  *
2420
+ * @return bool|array true is successful, array with error message if not
2421
  */
2422
+ public function sftp_backup($args)
2423
  {
2424
  $port = $args['sftp_port'] ? (int) $args['sftp_port'] : 22; //default port is 22
2425
  $sftp_hostname = $args['sftp_hostname'];
2547
  /**
2548
  * Uploads backup file from server to remote ftp server.
2549
  *
2550
+ * @param array $args arguments passed to the function
2551
+ * [ftp_username] -> ftp username on remote server
2552
+ * [ftp_password] -> ftp password on remote server
2553
+ * [ftp_hostname] -> ftp hostname of remote host
2554
+ * [ftp_remote_folder] -> folder on remote site which backup file should be upload to
2555
+ * [ftp_site_folder] -> subfolder with site name in ftp_remote_folder which backup file should be upload to
2556
+ * [ftp_passive] -> passive mode or not
2557
+ * [ftp_ssl] -> ssl or not
2558
+ * [ftp_port] -> number of port for ssl protocol
2559
+ * [backup_file] -> absolute path of backup file on local server
2560
  *
2561
+ * @return bool|array true is successful, array with error message if not
2562
  */
2563
+ public function ftp_backup($args)
2564
  {
2565
  $port = $args['ftp_port'] ? $args['ftp_port'] : 21;
2566
  $ftp_hostname = $args['ftp_hostname'];
2662
  /**
2663
  * Deletes backup file from remote ftp server.
2664
  *
2665
+ * @param array $args arguments passed to the function
2666
+ * [ftp_username] -> ftp username on remote server
2667
+ * [ftp_password] -> ftp password on remote server
2668
+ * [ftp_hostname] -> ftp hostname of remote host
2669
+ * [ftp_remote_folder] -> folder on remote site which backup file should be deleted from
2670
+ * [ftp_site_folder] -> subfolder with site name in ftp_remote_folder which backup file should be deleted from
2671
+ * [backup_file] -> absolute path of backup file on local server
2672
  *
2673
+ * @return void
2674
  */
2675
+ public function remove_ftp_backup($args)
2676
  {
2677
  $port = $args['ftp_port'] ? (int) $args['ftp_port'] : 21;
2678
  $ftp_remote_folder = untrailingslashit($args['ftp_remote_folder']);
2695
  return;
2696
  }
2697
 
 
2698
  $errorCatcher->register('ftp_delete');
2699
  $delete = ftp_delete($ftp, $ftp_remote_folder.'/'.$args['backup_file']);
2700
  $errorCatcher->unRegister();
2712
  /**
2713
  * Deletes backup file from remote sftp server.
2714
  *
2715
+ * @param array $args arguments passed to the function
2716
+ * [sftp_username] -> sftp username on remote server
2717
+ * [sftp_password] -> sftp password on remote server
2718
+ * [sftp_hostname] -> sftp hostname of remote host
2719
+ * [sftp_remote_folder] -> folder on remote site which backup file should be deleted from
2720
+ * [sftp_site_folder] -> subfolder with site name in ftp_remote_folder which backup file should be deleted from
2721
+ * [backup_file] -> absolute path of backup file on local server
2722
  *
2723
+ * @return void
2724
  */
2725
+ public function remove_sftp_backup($args)
2726
  {
2727
  $port = $args['sftp_port'] ? (int) $args['sftp_port'] : 22; //default port is 22
2728
  $sftp_hostname = $args['sftp_hostname'];
2747
  $sftp->disconnect();
2748
  }
2749
 
 
2750
  /**
2751
  * Downloads backup file from server from remote ftp server to root folder on local server.
2752
  *
2753
+ * @param array $args arguments passed to the function
2754
+ * [ftp_username] -> ftp username on remote server
2755
+ * [ftp_password] -> ftp password on remote server
2756
+ * [ftp_hostname] -> ftp hostname of remote host
2757
+ * [ftp_remote_folder] -> folder on remote site which backup file should be downloaded from
2758
+ * [ftp_site_folder] -> subfolder with site name in ftp_remote_folder which backup file should be downloaded from
2759
+ * [backup_file] -> absolute path of backup file on local server
2760
  *
2761
+ * @return string|array absolute path to downloaded file is successful, array with error message if not
2762
  */
2763
+ public function get_ftp_backup($args)
2764
  {
2765
  $port = $args['ftp_port'] ? (int) $args['ftp_port'] : 21;
2766
  $ftp_remote_folder = untrailingslashit($args['ftp_remote_folder']);
2809
  return $temp;
2810
  }
2811
 
 
2812
  /**
2813
  * Downloads backup file from server from remote ftp server to root folder on local server.
2814
  *
2815
+ * @param array $args arguments passed to the function
2816
+ * [sftp_username] -> ftp username on remote server
2817
+ * [sftp_password] -> ftp password on remote server
2818
+ * [sftp_hostname] -> ftp hostname of remote host
2819
+ * [sftp_remote_folder] -> folder on remote site which backup file should be downloaded from
2820
+ * [sftp_site_folder] -> subfolder with site name in ftp_remote_folder which backup file should be downloaded from
2821
+ * [backup_file] -> absolute path of backup file on local server
2822
  *
2823
+ * @return string|array absolute path to downloaded file is successful, array with error message if not
2824
  */
2825
+ public function get_sftp_backup($args)
2826
  {
2827
  $port = $args['sftp_port'] ? (int) $args['sftp_port'] : 22;
2828
  $sftp_hostname = $args['sftp_hostname'];
2933
  /**
2934
  * Uploads backup file from server to Dropbox.
2935
  *
2936
+ * @param array $args arguments passed to the function
2937
+ * [consumer_key] -> consumer key of ManageWP Dropbox application
2938
+ * [consumer_secret] -> consumer secret of ManageWP Dropbox application
2939
+ * [oauth_token] -> oauth token of user on ManageWP Dropbox application
2940
+ * [oauth_token_secret] -> oauth token secret of user on ManageWP Dropbox application
2941
+ * [dropbox_destination] -> folder on user's Dropbox account which backup file should be upload to
2942
+ * [dropbox_site_folder] -> subfolder with site name in dropbox_destination which backup file should be upload to
2943
+ * [backup_file] -> absolute path of backup file on local server
2944
  *
2945
+ * @return bool|array true is successful, array with error message if not
2946
  */
2947
+ public function dropbox_backup($args)
2948
  {
2949
  mwp_logger()->info('Acquiring Dropbox token to start uploading the backup file');
2950
  try {
2951
+ $dropbox = mwp_dropbox_oauth_factory($args['consumer_key'], $args['consumer_secret'], $args['oauth_token'], $args['oauth_token_secret']);
2952
  } catch (Exception $e) {
2953
  mwp_logger()->error('Error while acquiring Dropbox token', array(
2954
  'exception' => $e,
2956
 
2957
  return array(
2958
  'error' => $e->getMessage(),
2959
+ 'partial' => 1,
2960
  );
2961
  }
2962
 
2992
 
2993
  return array(
2994
  'error' => $e->getMessage(),
2995
+ 'partial' => 1,
2996
  );
2997
  }
2998
 
3006
  /**
3007
  * Deletes backup file from Dropbox to root folder on local server.
3008
  *
3009
+ * @param array $args arguments passed to the function
3010
+ * [consumer_key] -> consumer key of ManageWP Dropbox application
3011
+ * [consumer_secret] -> consumer secret of ManageWP Dropbox application
3012
+ * [oauth_token] -> oauth token of user on ManageWP Dropbox application
3013
+ * [oauth_token_secret] -> oauth token secret of user on ManageWP Dropbox application
3014
+ * [dropbox_destination] -> folder on user's Dropbox account which backup file should be downloaded from
3015
+ * [dropbox_site_folder] -> subfolder with site name in dropbox_destination which backup file should be downloaded from
3016
+ * [backup_file] -> absolute path of backup file on local server
3017
  *
3018
+ * @return void
3019
  */
3020
+ public function remove_dropbox_backup($args)
3021
  {
3022
  mwp_logger()->info('Acquiring Dropbox token to remove a backup file');
3023
  try {
3024
+ $dropbox = mwp_dropbox_oauth_factory($args['consumer_key'], $args['consumer_secret'], $args['oauth_token'], $args['oauth_token_secret']);
3025
  } catch (Exception $e) {
3026
  mwp_logger()->error('Error while acquiring Dropbox token', array(
3027
  'exception' => $e,
3051
  /**
3052
  * Downloads backup file from Dropbox to root folder on local server.
3053
  *
3054
+ * @param array $args arguments passed to the function
3055
+ * [consumer_key] -> consumer key of ManageWP Dropbox application
3056
+ * [consumer_secret] -> consumer secret of ManageWP Dropbox application
3057
+ * [oauth_token] -> oauth token of user on ManageWP Dropbox application
3058
+ * [oauth_token_secret] -> oauth token secret of user on ManageWP Dropbox application
3059
+ * [dropbox_destination] -> folder on user's Dropbox account which backup file should be deleted from
3060
+ * [dropbox_site_folder] -> subfolder with site name in dropbox_destination which backup file should be deleted from
3061
+ * [backup_file] -> absolute path of backup file on local server
3062
  *
3063
+ * @return bool|array absolute path to downloaded file is successful, array with error message if not
3064
  */
3065
+ public function get_dropbox_backup($args)
3066
  {
3067
  mwp_logger()->info('Acquiring Dropbox token to download the backup file');
3068
  try {
3069
+ $dropbox = mwp_dropbox_oauth_factory($args['consumer_key'], $args['consumer_secret'], $args['oauth_token'], $args['oauth_token_secret']);
3070
  } catch (Exception $e) {
3071
  mwp_logger()->error('Error while acquiring Dropbox token', array(
3072
  'exception' => $e,
3074
 
3075
  return array(
3076
  'error' => $e->getMessage(),
3077
+ 'partial' => 1,
3078
  );
3079
  }
3080
 
3113
 
3114
  return array(
3115
  'error' => $e->getMessage(),
3116
+ 'partial' => 1,
3117
  );
3118
  }
3119
 
3120
  $fileSize = filesize($temp);
3121
  mwp_logger()->info('Downloading backup file from Dropbox completed; file size is {backup_size}; average speed is {speed}', array(
3122
  'backup_size' => mwp_format_bytes($fileSize),
3123
+ 'speed' => mwp_format_bytes($fileSize / (microtime(true) - $start)),
3124
  ));
3125
 
3126
  return $temp;
3129
  /**
3130
  * Uploads backup file from server to Amazon S3.
3131
  *
3132
+ * @param array $args arguments passed to the function
3133
+ * [as3_bucket_region] -> Amazon S3 bucket region
3134
+ * [as3_bucket] -> Amazon S3 bucket
3135
+ * [as3_access_key] -> Amazon S3 access key
3136
+ * [as3_secure_key] -> Amazon S3 secure key
3137
+ * [as3_directory] -> folder on user's Amazon S3 account which backup file should be upload to
3138
+ * [as3_site_folder] -> subfolder with site name in as3_directory which backup file should be upload to
3139
+ * [backup_file] -> absolute path of backup file on local server
3140
  *
3141
+ * @return bool|array true is successful, array with error message if not
3142
  */
3143
+ public function amazons3_backup($args)
3144
  {
3145
  if ($args['as3_site_folder'] == true) {
3146
  $args['as3_directory'] .= '/'.$this->site_name;
3186
  return true;
3187
  }
3188
 
 
3189
  /**
3190
  * Deletes backup file from Amazon S3.
3191
  *
3192
+ * @param array $args arguments passed to the function
3193
+ * [as3_bucket_region] -> Amazon S3 bucket region
3194
+ * [as3_bucket] -> Amazon S3 bucket
3195
+ * [as3_access_key] -> Amazon S3 access key
3196
+ * [as3_secure_key] -> Amazon S3 secure key
3197
+ * [as3_directory] -> folder on user's Amazon S3 account which backup file should be deleted from
3198
+ * [as3_site_folder] -> subfolder with site name in as3_directory which backup file should be deleted from
3199
+ * [backup_file] -> absolute path of backup file on local server
3200
  *
3201
+ * @return void
3202
  */
3203
+ public function remove_amazons3_backup($args)
3204
  {
3205
  if ($args['as3_site_folder'] == true) {
3206
  $args['as3_directory'] .= '/'.$this->site_name;
3226
  /**
3227
  * Downloads backup file from Amazon S3 to root folder on local server.
3228
  *
3229
+ * @param array $args arguments passed to the function
3230
+ * [as3_bucket_region] -> Amazon S3 bucket region
3231
+ * [as3_bucket] -> Amazon S3 bucket
3232
+ * [as3_access_key] -> Amazon S3 access key
3233
+ * [as3_secure_key] -> Amazon S3 secure key
3234
+ * [as3_directory] -> folder on user's Amazon S3 account which backup file should be downloaded from
3235
+ * [as3_site_folder] -> subfolder with site name in as3_directory which backup file should be downloaded from
3236
+ * [backup_file] -> absolute path of backup file on local server
3237
  *
3238
+ * @return bool|array absolute path to downloaded file is successful, array with error message if not
3239
  */
3240
+ public function get_amazons3_backup($args)
3241
  {
3242
  $endpoint = isset($args['as3_bucket_region']) ? $args['as3_bucket_region'] : 's3.amazonaws.com';
3243
 
3275
  $fileSize = filesize($temp);
3276
  mwp_logger()->info('Downloading backup file from Amazon S3 completed; file size is {backup_size}; average speed is {speed}', array(
3277
  'backup_size' => mwp_format_bytes($fileSize),
3278
+ 'speed' => mwp_format_bytes($fileSize / (microtime(true) - $start)),
3279
  ));
3280
 
3281
  return $temp;
3284
  /**
3285
  * Uploads backup file from server to Google Drive.
3286
  *
3287
+ * @param array $args arguments passed to the function
3288
+ * [google_drive_token] -> user's Google drive token in json form
3289
+ * [google_drive_directory] -> folder on user's Google Drive account which backup file should be upload to
3290
+ * [google_drive_site_folder] -> subfolder with site name in google_drive_directory which backup file should be upload to
3291
+ * [backup_file] -> absolute path of backup file on local server
3292
  *
3293
+ * @return bool|array true is successful, array with error message if not
3294
  */
3295
+ public function google_drive_backup($args)
3296
  {
3297
  mwp_register_autoload_google();
3298
  $googleClient = new Google_ApiClient();
3468
  /**
3469
  * Deletes backup file from Google Drive.
3470
  *
3471
+ * @param array $args arguments passed to the function
3472
+ * [google_drive_token] -> user's Google drive token in json form
3473
+ * [google_drive_directory] -> folder on user's Google Drive account which backup file should be deleted from
3474
+ * [google_drive_site_folder] -> subfolder with site name in google_drive_directory which backup file should be deleted from
3475
+ * [backup_file] -> absolute path of backup file on local server
3476
  *
3477
+ * @return void
3478
  */
3479
+ public function remove_google_drive_backup($args)
3480
  {
3481
  mwp_register_autoload_google();
3482
  mwp_logger()->info('Removing Google Drive backup file', array(
3551
  try {
3552
  $backup_folder_id = $backup_folder->getId();
3553
  $listFiles = $driveService->files->listFiles(array("q" => "title='".addslashes($args['backup_file'])."' and '$backup_folder_id' in parents and trashed = false"));
3554
+ $files = $listFiles->getItems();
3555
  } catch (Exception $e) {
3556
  $this->_log($e->getMessage());
3557
  /*return array(
3572
  /**
3573
  * Downloads backup file from Google Drive to root folder on local server.
3574
  *
3575
+ * @param array $args arguments passed to the function
3576
+ * [google_drive_token] -> user's Google drive token in json form
3577
+ * [google_drive_directory] -> folder on user's Google Drive account which backup file should be downloaded from
3578
+ * [google_drive_site_folder] -> subfolder with site name in google_drive_directory which backup file should be downloaded from
3579
+ * [backup_file] -> absolute path of backup file on local server
3580
  *
3581
+ * @return bool|array absolute path to downloaded file is successful, array with error message if not
3582
  */
3583
+ public function get_google_drive_backup($args)
3584
  {
3585
  mwp_register_autoload_google();
3586
  $googleClient = new Google_ApiClient();
3729
  /**
3730
  * Schedules the next execution of some backup task.
3731
  *
3732
+ * @param string $type daily, weekly or monthly
3733
+ * @param string $schedule format: task_time (if daily), task_time|task_day (if weekly), task_time|task_date (if monthly)
3734
  *
3735
+ * @return bool|int timestamp if sucessful, false if not
3736
  */
3737
+ public function schedule_next($type, $schedule)
3738
  {
3739
  $schedule = explode("|", $schedule);
3740
 
3824
  /**
3825
  * Parse task arguments for info on master.
3826
  *
3827
+ * @return mixed associative array with stats for every backup task or error if backup is manually deleted on server
3828
  */
3829
+ public function get_backup_stats()
3830
  {
3831
  $stats = array();
3832
  $tasks = $this->tasks;
3833
  if (is_array($tasks) && !empty($tasks)) {
3834
  foreach ($tasks as $task_name => $info) {
3835
+ if (!empty($info['task_results']) && is_array($info['task_results'])) {
3836
  foreach ($info['task_results'] as $key => $result) {
3837
  if (isset($result['server']) && !isset($result['error'])) {
3838
  if (isset($result['server']['file_path']) && !$info['task_args']['del_host_file']) {
3842
  }
3843
  }
3844
  }
 
 
3845
  $stats[$task_name] = $info['task_results'];
3846
  }
3847
  }
3853
  /**
3854
  * Returns all backup tasks with information when the next schedule will be.
3855
  *
3856
+ * @return mixed associative array with timestamp with next schedule for every backup task
3857
  */
3858
+ public function get_next_schedules()
3859
  {
3860
  $stats = array();
3861
  $tasks = $this->tasks;
3872
  * Deletes all old backups from local server.
3873
  * It depends on configuration on master (Number of backups to keep).
3874
  *
3875
+ * @param string $task_name name of backup task
3876
  *
3877
+ * @return bool|void true if there are backups for deletion, void if not
3878
  */
3879
+ public function remove_old_backups($task_name)
3880
  {
3881
  //Check for previous failed backups first
3882
  $this->cleanup();
3953
  /**
3954
  * Deletes specified backup.
3955
  *
3956
+ * @param array $args arguments passed to function
3957
+ * [task_name] -> name of backup task
3958
+ * [result_id] -> id of baskup task result, which should be restored
3959
+ * [google_drive_token] -> json of Google Drive token, if it is remote destination
3960
  *
3961
+ * @return bool true if successful, false if not
3962
  */
3963
+ public function delete_backup($args)
3964
  {
3965
  if (empty($args)) {
3966
  return false;
4033
  /**
4034
  * Deletes all unneeded files produced by backup process.
4035
  *
4036
+ * @return array array of deleted files
4037
  */
4038
+ public function cleanup()
4039
  {
4040
  $tasks = $this->tasks;
4041
  $backup_folder = WP_CONTENT_DIR.'/'.md5('mmb-worker').'/mwp_backups/';
4103
  /**
4104
  * Uploads to remote destination in the second step, invoked from master.
4105
  *
4106
+ * @param array $args arguments passed to function
4107
+ * [task_name] -> name of backup task
4108
  *
4109
+ * @return array|void void if success, array with error message if not
4110
  */
4111
+ public function remote_backup_now($args)
4112
  {
4113
  /**
4114
  * Remember if this is called as a forked http request, or a connection to the dasboard is persistent
4121
  extract($args);
4122
  }
4123
 
 
4124
  $tasks = $this->tasks;
4125
  $task_name = stripslashes($task_name);
4126
  $task = $tasks[$task_name];
4219
  $this->update_tasks($tasks);
4220
  } else {
4221
  $return = array(
4222
+ 'error' => 'Backup file not found on your server. Please try again.',
4223
  );
4224
  }
4225
  $this->sendDataToMaster();
4230
  /**
4231
  * Checks if scheduled backup tasks should be executed.
4232
  *
4233
+ * @param array $args arguments passed to function
4234
+ * [task_name] -> name of backup task
4235
+ * [task_id] -> id of backup task
4236
+ * [$site_key] -> hash key of backup task
4237
+ * [worker_version] -> version of worker
4238
+ * [mwp_google_drive_refresh_token] -> should be Google Drive token be refreshed, true if it is remote destination of task
4239
+ * @param string $url url on master where worker validate task
4240
  *
4241
+ * @return string|array|boolean
4242
  */
4243
+ public function validate_task($args, $url)
4244
  {
4245
  if (!class_exists('WP_Http')) {
4246
+ include_once ABSPATH.WPINC.'/class-http.php';
4247
  }
4248
 
4249
  $worker_upto_3_9_22 = ($GLOBALS['MMB_WORKER_VERSION'] <= '3.9.22'); // worker version is less or equals to 3.9.22
4290
  * Updates status of backup task.
4291
  * Positive number if completed, negative if not.
4292
  *
4293
+ * @param string $task_name name of backup task
4294
+ * @param int $status status which tasks should be updated to
4295
+ * (
4296
+ * 0 - Backup started,
4297
+ * 1 - DB dump,
4298
+ * 2 - DB ZIP,
4299
+ * 3 - Files ZIP,
4300
+ * 4 - Amazon S3,
4301
+ * 5 - Dropbox,
4302
+ * 6 - FTP,
4303
+ * 7 - Email,
4304
+ * 8 - Google Drive,
4305
+ * 100 - Finished
4306
+ * )
4307
+ * @param bool $completed completed or not
4308
  *
4309
+ * @return void
4310
  */
4311
+ public function update_status($task_name, $status, $completed = false)
4312
  {
4313
  if ($task_name != 'Backup Now') {
4314
  $tasks = $this->tasks;
4331
  /**
4332
  * Update $this->tasks attribute and save it to wp_options with key mwp_backup_tasks.
4333
  *
4334
+ * @param mixed $tasks associative array with all tasks data
4335
  *
4336
+ * @return void
4337
  */
4338
+ public function update_tasks($tasks)
4339
  {
4340
  $this->tasks = $tasks;
4341
  update_option('mwp_backup_tasks', $tasks);
4346
  *
4347
  * @return void
4348
  */
4349
+ public function wpdb_reconnect()
4350
  {
4351
  global $wpdb;
4352
 
4365
  /**
4366
  * Replaces .htaccess file in process of restoring WordPress site.
4367
  *
4368
+ * @param string $url url of current site
4369
  *
4370
+ * @return void
4371
  */
4372
+ public function replace_htaccess($url)
4373
  {
4374
  $file = @file_get_contents(ABSPATH.'.htaccess');
4375
  if ($file && strlen($file)) {
4385
  /**
4386
  * Removes cron for checking scheduled tasks, if there are not any scheduled task.
4387
  *
4388
+ * @return void
4389
  */
4390
+ public function check_cron_remove()
4391
  {
4392
  if (empty($this->tasks) || (count($this->tasks) == 1 && isset($this->tasks['Backup Now']))) {
4393
  wp_clear_scheduled_hook('mwp_backup_tasks');
4398
  /**
4399
  * Re-add tasks on website re-add.
4400
  *
4401
+ * @param array $params arguments passed to function
4402
  *
4403
+ * @return array $params without backups
4404
  */
4405
  public function readd_tasks($params = array())
4406
  {
4453
  $decrypted = $cipher->decrypt($task['secure']);
4454
  $task['account_info'] = json_decode($decrypted, true);
4455
  }
 
4456
  }
4457
  if (isset($task['account_info']) && is_array($task['account_info'])) { //only if sends from master first time(secure data)
4458
  $task['args']['account_info'] = $task['account_info'];
4472
  /**
4473
  * Start backup process. Invoked from remote ping
4474
  *
4475
+ * @param array $args arguments passed to function
4476
+ * [task_name] -> name of backup task
4477
  *
4478
+ * @return array array with error message or if success task results
4479
  */
4480
  public function ping_backup($args)
4481
  {
4482
  // Belows code follows logic from check_backup
4483
+ $return = "PONG";
4484
+ $task_name = $args['task_name'];
4485
  $sendDataToMaster = false;
4486
  if (is_array($this->tasks) && !empty($this->tasks) && !empty($this->tasks[$task_name])) {
4487
+ $task = $this->tasks[$task_name];
4488
  $sendDataToMaster = isset($task['task_args']['account_info']) ? false : true;
4489
  if ($task['task_args']['task_id'] && $task['task_args']['site_key']) {
4490
  $potential_token = !empty($args['google_drive_token']) ? $args['google_drive_token'] : false;
4496
  * From this point I am simulating previous way of working. In order to fix this,
4497
  * I need to refactor greater part, and release is tomorrow morning
4498
  */
4499
+ $update = array(
4500
  'task_name' => $task_name,
4501
+ 'args' => $task['task_args'],
4502
  );
4503
  $update['time'] = time();
4504
  $this->set_backup_task($update);
4513
  array(
4514
  'task_name' => $task_name,
4515
  'args' => $task['task_args'],
4516
+ 'error' => $return,
4517
  )
4518
  );
4519
  } else {
4522
  }
4523
  $return = $this->tasks[$task_name]['task_results'];
4524
  }
 
 
4525
  }
4526
  } else {
4527
  $return = array("error" => "Unknown task name");
4529
  if ($sendDataToMaster) {
4530
  $this->sendDataToMaster();
4531
  }
4532
+
4533
  return $return;
4534
  }
4535
 
4542
  {
4543
  $backup_file = $this->tasks[$task_name]['task_results'][count($this->tasks[$task_name]['task_results']) - 1]['server']['file_url'];
4544
  $del_host_file = $this->tasks[$task_name]['task_args']['del_host_file'];
4545
+ $args = array('task_name' => $task_name, 'backup_file' => $backup_file, 'del_host_file' => $del_host_file);
4546
 
4547
  $this->notifyMyself('mmb_remote_upload', $args);
4548
  }
 
4549
  }
4550
 
4551
  /*if( function_exists('add_filter') ) {
4552
+ add_filter( 'mwp_website_add', 'MMB_Backup::readd_tasks' );
4553
  }*/
4554
 
4555
  if (!function_exists('get_all_files_from_dir')) {
4556
  /**
4557
  * Get all files in directory
4558
  *
4559
+ * @param string $path Relative or absolute path to folder
4560
+ * @param array $exclude List of excluded files or folders, relative to $path
4561
  *
4562
+ * @return array List of all files in folder $path, exclude all files in $exclude array
4563
  */
4564
  function get_all_files_from_dir($path, $exclude = array())
4565
  {
4588
  * wrapped function which writes in global variable
4589
  * and exclued files or folders are read from global variable
4590
  *
4591
+ * @param string $path Relative or absolute path to folder
4592
  *
4593
+ * @return void
4594
  */
4595
  function get_all_files_from_dir_recursive($path)
4596
  {
4635
  if (is_string($value)) {
4636
  if (is_string($data['regex'])) {
4637
  $expressions = array($data['regex']);
4638
+ } elseif (is_array($data['regex'])) {
4639
  $expressions = $data['regex'];
4640
  } else {
4641
  return;
4667
  $tablePrefix = $restoreParams['tablePrefix'];
4668
  $newUrl = $restoreParams['newUrl'];
4669
 
4670
+ if (!isset($oldSiteUrl) || !isset($oldUrl)) {
4671
  return false;
4672
  }
4673
 
4675
  $parsedOldUrl = parse_url(strpos($oldUrl, '://') === false ? "http://$oldUrl" : $oldUrl);
4676
  $host = getKey('host', $parsedOldSiteUrl, '');
4677
  $path = getKey('path', $parsedOldSiteUrl, '');
4678
+ $oldSiteUrlNoWww = preg_replace('#^www\.(.+\.)#i', '$1', $host).$path;
4679
  $parsedOldSiteUrlNoWww = parse_url(strpos($oldSiteUrlNoWww, '://') === false
4680
  ? "http://$oldSiteUrlNoWww"
4681
  : $oldSiteUrlNoWww
4686
 
4687
  // Modify the database for two variants of url, one with and one without WWW
4688
  $oldUrls = array('oldSiteUrl' => $oldSiteUrl);
4689
+ $tmp1 = @"{$parsedOldUrl['host']}/{$parsedOldUrl['path']}";
4690
+ $tmp2 = @"{$parsedOldSiteUrlNoWww['host']}/{$parsedOldSiteUrlNoWww['path']}";
4691
  if ($oldSiteUrlNoWww != $oldSiteUrl && $tmp1 != $tmp2) {
4692
  $oldUrls['oldSiteUrlNoWww'] = $oldSiteUrlNoWww;
4693
  }
4718
  if (is_array($unserialized)) {
4719
  array_walk_recursive($unserialized, 'recursiveUrlReplacement', array(
4720
  'newUrl' => $newUrl,
4721
+ 'regex' => $amazingRegex,
4722
  )
4723
  );
4724
  $replaced = serialize($unserialized);
4746
  if (is_array($unserialized)) {
4747
  array_walk_recursive($unserialized, 'recursiveUrlReplacement', array(
4748
  'newUrl' => $newUrl,
4749
+ 'regex' => $amazingRegex,
4750
  )
4751
  );
4752
  }
4761
  $query = "UPDATE {$tablePrefix}postmeta SET meta_value = '{$escapedReplacement}' WHERE meta_id = '$id'";
4762
  $wpdb->query($query);
4763
  }
 
4764
  }
4765
 
4766
  // Do the same with posts
4770
  $postContent = preg_replace($amazingRegex, $newUrl, $row['post_content']);
4771
  $guid = preg_replace($amazingRegex, $newUrl, $row['guid']);
4772
 
 
4773
  if ($postContent != $row['post_content'] || $guid != $row['guid']) {
4774
  $postContent = $wpdb->_escape($postContent);
4775
  $guid = $wpdb->_escape($guid);
4783
 
4784
  function restore_htaccess()
4785
  {
4786
+ $htaccessRealpath = realpath(ABSPATH.'.htaccess');
4787
 
4788
  if ($htaccessRealpath) {
4789
  @rename($htaccessRealpath, "$htaccessRealpath.old");
4790
  }
4791
+ @include ABSPATH.'wp-admin/includes/admin.php';
4792
  @flush_rewrite_rules(true);
4793
  }
src/MMB/Comment.php CHANGED
@@ -8,7 +8,7 @@
8
  **************************************************************/
9
  class MMB_Comment extends MMB_Core
10
  {
11
- function change_status($args)
12
  {
13
  $comment_id = $args['comment_id'];
14
  $status = $args['status'];
@@ -26,7 +26,7 @@ class MMB_Comment extends MMB_Core
26
  return true;
27
  }
28
 
29
- function get_comments($args)
30
  {
31
  /** @var wpdb $wpdb */
32
  global $wpdb;
@@ -101,7 +101,7 @@ class MMB_Comment extends MMB_Core
101
  return array('comments' => $comments, 'total' => $total);
102
  }
103
 
104
- function comment_total()
105
  {
106
  /** @var wpdb $wpdb */
107
  global $wpdb;
@@ -125,14 +125,12 @@ class MMB_Comment extends MMB_Core
125
  return $totals;
126
  }
127
 
128
- function action_comment($args)
129
  {
130
-
131
  $docomaction = $args['docomaction'];
132
- $comment_id = $args['comment_id'];
133
 
134
  if (!empty($comment_id) && is_numeric($comment_id)) {
135
-
136
  if ($docomaction == 'delete') {
137
  wp_delete_comment($comment_id, true);
138
  delete_comment_meta($comment_id);
@@ -152,17 +150,15 @@ class MMB_Comment extends MMB_Core
152
  }
153
  }
154
 
155
- function bulk_action_comments($args)
156
  {
157
-
158
  $docomaction = $args['docomaction'];
159
 
160
  foreach ($args as $val) {
161
  if (!empty($val) && is_numeric($val)) {
162
-
163
- if($docomaction == 'delete') {
164
  wp_delete_comment($val, true);
165
- } elseif ($docomaction == 'unapprove'|| $docomaction == 'untrash' || $docomaction == 'unspam') {
166
  wp_set_comment_status($val, 'hold');
167
  } elseif ($docomaction == 'approve') {
168
  wp_set_comment_status($val, 'approve');
@@ -177,7 +173,7 @@ class MMB_Comment extends MMB_Core
177
  return "comments updated";
178
  }
179
 
180
- function reply_comment($args)
181
  {
182
  /** @var wpdb $wpdb */
183
  global $wpdb, $current_user;
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'];
26
  return true;
27
  }
28
 
29
+ public function get_comments($args)
30
  {
31
  /** @var wpdb $wpdb */
32
  global $wpdb;
101
  return array('comments' => $comments, 'total' => $total);
102
  }
103
 
104
+ public function comment_total()
105
  {
106
  /** @var wpdb $wpdb */
107
  global $wpdb;
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);
150
  }
151
  }
152
 
153
+ public function bulk_action_comments($args)
154
  {
 
155
  $docomaction = $args['docomaction'];
156
 
157
  foreach ($args as $val) {
158
  if (!empty($val) && is_numeric($val)) {
159
+ if ($docomaction == 'delete') {
 
160
  wp_delete_comment($val, true);
161
+ } elseif ($docomaction == 'unapprove' || $docomaction == 'untrash' || $docomaction == 'unspam') {
162
  wp_set_comment_status($val, 'hold');
163
  } elseif ($docomaction == 'approve') {
164
  wp_set_comment_status($val, 'approve');
173
  return "comments updated";
174
  }
175
 
176
+ public function reply_comment($args)
177
  {
178
  /** @var wpdb $wpdb */
179
  global $wpdb, $current_user;
src/MMB/Container.php CHANGED
@@ -51,7 +51,7 @@ class MMB_Container
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'));
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'));
src/MMB/Core.php CHANGED
@@ -32,7 +32,7 @@ class MMB_Core extends MMB_Helper
32
  private $mmb_pre_init_filters;
33
  private $mmb_init_actions;
34
 
35
- function __construct()
36
  {
37
  global $wpmu_version, $blog_id, $_mmb_plugin_actions, $_mmb_item_filter, $_mmb_options;
38
 
@@ -172,12 +172,12 @@ class MMB_Core extends MMB_Helper
172
  add_action('set_auth_cookie', array(&$this, 'mmb_set_auth_cookie'));
173
  add_action('set_logged_in_cookie', array(&$this, 'mmb_set_logged_in_cookie'));
174
 
175
- if(!get_option('_worker_nossl_key') && !get_option('_worker_public_key')){
176
  add_action('init', array(&$this, 'deactivateWorkerIfNotAddedAfterTenMinutes'));
177
  }
178
  }
179
 
180
- function mmb_remote_action()
181
  {
182
  if ($this->action_call != null) {
183
  $params = isset($this->action_params) && $this->action_params != null ? $this->action_params : array();
@@ -185,9 +185,8 @@ class MMB_Core extends MMB_Helper
185
  }
186
  }
187
 
188
- function register_action_params($action = false, $params = array())
189
  {
190
-
191
  if (isset($this->mmb_pre_init_actions[$action]) && function_exists($this->mmb_pre_init_actions[$action])) {
192
  call_user_func($this->mmb_pre_init_actions[$action], $params);
193
  }
@@ -213,7 +212,6 @@ class MMB_Core extends MMB_Helper
213
  add_filter($_name, create_function('$a', 'global $mmb_filters; return array_merge($a, $mmb_filters["'.$_name.'"]);'));
214
  }
215
  }
216
-
217
  }
218
  }
219
 
@@ -226,38 +224,37 @@ class MMB_Core extends MMB_Helper
226
  /**
227
  * Add notice to network admin dashboard for security reasons
228
  */
229
- function network_admin_notice()
230
  {
231
  global $status, $page, $s;
232
- $context = $status;
233
- $plugin = 'worker/init.php';
234
- $nonce = wp_create_nonce('deactivate-plugin_'.$plugin);
235
- $actions = 'plugins.php?action=deactivate&amp;plugin='.urlencode($plugin).'&amp;plugin_status='.$context.'&amp;paged='.$page.'&amp;s='.$s.'&amp;_wpnonce='.$nonce;
236
  $configurationService = new MWP_Configuration_Service();
237
- $configuration = $configurationService->getConfiguration();
238
- $notice = $configuration->getNetworkNotice();
239
- $notice = str_replace("{deactivate_url}", $actions, $notice);
240
  echo $notice;
241
  }
242
 
243
-
244
  /**
245
  * Add notice to admin dashboard for security reasons
246
  */
247
- function admin_notice()
248
  {
249
  global $status, $page, $s;
250
- $context = $status;
251
- $plugin = 'worker/init.php';
252
- $nonce = wp_create_nonce('deactivate-plugin_'.$plugin);
253
- $actions = 'plugins.php?action=deactivate&amp;plugin='.urlencode($plugin).'&amp;plugin_status='.$context.'&amp;paged='.$page.'&amp;s='.$s.'&amp;_wpnonce='.$nonce;
254
  $configurationService = new MWP_Configuration_Service();
255
  $configuration = $configurationService->getConfiguration();
256
  $notice = $configuration->getNotice();
257
  $deactivateText = $configuration->getDeactivateText();
258
  if ($this->mmb_multisite && $this->network_admin_install != '1') {
259
  $deactivateTextLink = ''.$deactivateText;
260
- }else{
261
  $deactivateTextLink = '<a href="'.$actions.'" class="mwp_text_notice">'.$deactivateText.'</a>';
262
  }
263
  $notice = str_replace("{deactivate_text}", $deactivateTextLink, $notice);
@@ -271,7 +268,7 @@ class MMB_Core extends MMB_Helper
271
  * Add an item into the Right Now Dashboard widget
272
  * to inform that the blog can be managed remotely
273
  */
274
- function add_right_now_info()
275
  {
276
  $mwp_worker_brand = get_option('mwp_worker_brand');
277
  echo '<div class="mmb-slave-info">';
@@ -298,20 +295,20 @@ class MMB_Core extends MMB_Helper
298
  echo '</div>';
299
  }
300
 
301
- function enqueue_scripts()
302
  {
303
  wp_enqueue_script('jquery');
304
  wp_enqueue_script('jquery-ui-core');
305
  wp_enqueue_script('jquery-ui-dialog');
306
  }
307
 
308
- function enqueue_styles()
309
  {
310
  wp_enqueue_style('wp-jquery-ui');
311
  wp_enqueue_style('jquery-style', 'http://ajax.googleapis.com/ajax/libs/jqueryui/1.10.3/themes/smoothness/jquery-ui.css');
312
  }
313
 
314
- function send_email_to_admin()
315
  {
316
  if (!isset($_POST['support_mwp_message'])) {
317
  return;
@@ -324,8 +321,8 @@ class MMB_Core extends MMB_Helper
324
  if (empty($mwp_worker_brand['admin_email'])) {
325
  $this->mwp_send_ajax_response(false, "Unable to send email to admin.");
326
  }
327
- $subject = 'New ticket for site '.get_bloginfo('url');
328
- $message = <<<EOF
329
  Hi,
330
  User with a username {$current_user->user_login} has a new question:
331
  {$_POST['support_mwp_message']}
@@ -337,7 +334,7 @@ EOF;
337
  $this->mwp_send_ajax_response(true, "Message successfully sent.");
338
  }
339
 
340
- function mwp_send_ajax_response($success = true, $message = '')
341
  {
342
  $response = json_encode(
343
  array(
@@ -349,7 +346,7 @@ EOF;
349
  exit;
350
  }
351
 
352
- function support_page_dialog()
353
  {
354
  $mwp_worker_brand = get_option('mwp_worker_brand');
355
 
@@ -360,7 +357,8 @@ EOF;
360
  <div id="support_dialog" style="display: none;">
361
  <?php if (!empty($notification_text)): ?>
362
  <div>
363
- <p><?php echo $notification_text; ?></p>
 
364
  </div>
365
  <?php endif ?>
366
  <?php if ($mwp_worker_brand['email_or_link'] == 1): ?>
@@ -379,9 +377,10 @@ EOF;
379
  <?php endif ?>
380
  </div>
381
  <?php
 
382
  }
383
 
384
- function support_page_script()
385
  {
386
  ?>
387
  <script type="text/javascript">
@@ -429,12 +428,13 @@ EOF;
429
  });
430
  </script>
431
  <?php
 
432
  }
433
 
434
  /**
435
  * Add Support page on Top Menu
436
  */
437
- function add_support_page()
438
  {
439
  $mwp_worker_brand = get_option('mwp_worker_brand');
440
  if ($mwp_worker_brand && isset($mwp_worker_brand['text_for_client']) && ($mwp_worker_brand['text_for_client'] != '')) {
@@ -445,15 +445,14 @@ EOF;
445
  /**
446
  * Support page handler
447
  */
448
- function support_function()
449
  {
450
  }
451
 
452
-
453
  /**
454
  * Remove editor from plugins&themes submenu page
455
  */
456
- function dissalow_text_editor()
457
  {
458
  $mwp_worker_brand = get_option('mwp_worker_brand');
459
  if ($mwp_worker_brand && isset($mwp_worker_brand['dissalow_edit']) && ($mwp_worker_brand['dissalow_edit'] == 'checked')) {
@@ -477,7 +476,7 @@ EOF;
477
  /**
478
  * Gets an instance of the Comment class
479
  */
480
- function get_comment_instance()
481
  {
482
  if (!isset($this->comment_instance)) {
483
  $this->comment_instance = new MMB_Comment();
@@ -489,7 +488,7 @@ EOF;
489
  /**
490
  * Gets an instance of MMB_Post class
491
  */
492
- function get_post_instance()
493
  {
494
  if (!isset($this->post_instance)) {
495
  $this->post_instance = new MMB_Post();
@@ -501,7 +500,7 @@ EOF;
501
  /**
502
  * Gets an instance of User
503
  */
504
- function get_user_instance()
505
  {
506
  if (!isset($this->user_instance)) {
507
  $this->user_instance = new MMB_User();
@@ -513,7 +512,7 @@ EOF;
513
  /**
514
  * Gets an instance of Security
515
  */
516
- function get_security_instance()
517
  {
518
  if (!isset($this->security_instance)) {
519
  $this->security_instance = new MMB_Security();
@@ -522,11 +521,10 @@ EOF;
522
  return $this->security_instance;
523
  }
524
 
525
-
526
  /**
527
  * Gets an instance of stats class
528
  */
529
- function get_stats_instance()
530
  {
531
  if (!isset($this->stats_instance)) {
532
  $this->stats_instance = new MMB_Stats();
@@ -538,7 +536,7 @@ EOF;
538
  /**
539
  * Gets an instance of stats class
540
  */
541
- function get_backup_instance()
542
  {
543
  if (!isset($this->backup_instance)) {
544
  $this->backup_instance = new MMB_Backup();
@@ -551,7 +549,7 @@ EOF;
551
  * Gets an instance of links class
552
 
553
  */
554
- function get_link_instance()
555
  {
556
  if (!isset($this->link_instance)) {
557
  $this->link_instance = new MMB_Link();
@@ -560,7 +558,7 @@ EOF;
560
  return $this->link_instance;
561
  }
562
 
563
- function get_installer_instance()
564
  {
565
  if (!isset($this->installer_instance)) {
566
  $this->installer_instance = new MMB_Installer();
@@ -573,7 +571,7 @@ EOF;
573
  * Plugin install callback function
574
  * Check PHP version
575
  */
576
- function install()
577
  {
578
  /** @var wpdb $wpdb */
579
  global $wpdb, $_wp_using_ext_object_cache;
@@ -618,17 +616,18 @@ EOF;
618
  if (file_exists($path)) {
619
  $configuration = file_get_contents($path);
620
  $jsonConfiguration = json_decode($configuration, true);
621
- if($jsonConfiguration !== NULL){
622
  update_option("mwp_worker_configuration", $jsonConfiguration);
623
  }
624
  }
625
  update_option('mmb_worker_activation_time', time());
626
  }
 
627
  /**
628
  * Saves the (modified) options into the database
629
  * Deprecated
630
  */
631
- function save_options($options = array())
632
  {
633
  global $_mmb_options;
634
 
@@ -639,7 +638,7 @@ EOF;
639
  /**
640
  * Deletes options for communication with master
641
  */
642
- function uninstall($deactivate = false)
643
  {
644
  /** @var wpdb $wpdb */
645
  global $current_user, $wpdb, $_wp_using_ext_object_cache;
@@ -693,14 +692,12 @@ EOF;
693
  delete_option('mmb_worker_activation_time');
694
  }
695
 
696
-
697
-
698
  /**
699
  * Constructs a url (for ajax purpose)
700
  *
701
  * @param mixed $base_page
702
  */
703
- function construct_url($params = array(), $base_page = 'index.php')
704
  {
705
  $url = "$base_page?_wpnonce=".wp_create_nonce($this->slug);
706
  foreach ($params as $key => $value) {
@@ -713,7 +710,7 @@ EOF;
713
  /**
714
  * Worker update
715
  */
716
- function update_worker_plugin($params)
717
  {
718
  if ($params['download_url']) {
719
  @include_once ABSPATH.'wp-admin/includes/file.php';
@@ -725,7 +722,7 @@ EOF;
725
 
726
  if (!$this->is_server_writable()) {
727
  return array(
728
- 'error' => 'Failed, please <a target="_blank" href="http://managewp.com/user-guide/faq/my-pluginsthemes-fail-to-update-or-i-receive-a-yellow-ftp-warning">add FTP details for automatic upgrades.</a>'
729
  );
730
  }
731
 
@@ -739,38 +736,38 @@ EOF;
739
  'clear_destination' => true,
740
  'clear_working' => true,
741
  'hook_extra' => array(
742
- 'plugin' => 'worker/init.php'
743
- )
744
  )
745
  );
746
  ob_end_clean();
747
  if (is_wp_error($result) || !$result) {
748
  return array(
749
- 'error' => 'ManageWP Worker plugin could not be updated.'
750
  );
751
  } else {
752
  return array(
753
- 'success' => 'ManageWP Worker plugin successfully updated.'
754
  );
755
  }
756
  }
757
 
758
  return array(
759
- 'error' => 'Bad download path for worker installation file.'
760
  );
761
  }
762
 
763
  /**
764
  * Automatically logs in when called from Master
765
  */
766
- function automatic_login()
767
  {
768
  $where = isset($_GET['mwp_goto']) ? $_GET['mwp_goto'] : false;
769
  $username = isset($_GET['username']) ? $_GET['username'] : '';
770
  $auto_login = isset($_GET['auto_login']) ? $_GET['auto_login'] : 0;
771
 
772
  if (!function_exists('is_user_logged_in')) {
773
- include_once(ABSPATH.'wp-includes/pluggable.php');
774
  }
775
 
776
  if (($auto_login && strlen(trim($username)) && !is_user_logged_in()) || (isset($this->mmb_multisite) && $this->mmb_multisite)) {
@@ -779,7 +776,6 @@ EOF;
779
 
780
  $auth = $this->authenticate_message($where.$message_id, $signature, $message_id);
781
  if ($auth === true) {
782
-
783
  if (!headers_sent()) {
784
  header('P3P: CP="CAO PSA OUR"');
785
  }
@@ -791,6 +787,8 @@ EOF;
791
  $siteurl = function_exists('get_site_option') ? get_site_option('siteurl') : get_option('siteurl');
792
  $user = $this->mmb_get_user_info($username);
793
  wp_set_current_user($user->ID);
 
 
794
 
795
  if (!defined('COOKIEHASH') || (isset($this->mmb_multisite) && $this->mmb_multisite)) {
796
  wp_cookie_constants();
@@ -819,7 +817,7 @@ EOF;
819
  }
820
  }
821
 
822
- function mmb_set_auth_cookie($auth_cookie)
823
  {
824
  if (!defined('MMB_USER_LOGIN')) {
825
  return;
@@ -832,7 +830,7 @@ EOF;
832
  $_COOKIE['wordpress_'.COOKIEHASH] = $auth_cookie;
833
  }
834
 
835
- function mmb_set_logged_in_cookie($logged_in_cookie)
836
  {
837
  if (!defined('MMB_USER_LOGIN')) {
838
  return;
@@ -845,12 +843,12 @@ EOF;
845
  $_COOKIE['wordpress_logged_in_'.COOKIEHASH] = $logged_in_cookie;
846
  }
847
 
848
- function admin_actions()
849
  {
850
  add_filter('all_plugins', array($this, 'worker_replace'));
851
  }
852
 
853
- function worker_replace($all_plugins)
854
  {
855
  $replace = get_option("mwp_worker_brand");
856
  if (is_array($replace)) {
@@ -866,7 +864,7 @@ EOF;
866
 
867
  if ($replace['hide']) {
868
  if (!function_exists('get_plugins')) {
869
- include_once(ABSPATH.'wp-admin/includes/plugin.php');
870
  }
871
  $activated_plugins = get_option('active_plugins');
872
  if (!$activated_plugins) {
@@ -881,18 +879,18 @@ EOF;
881
  return $all_plugins;
882
  }
883
 
884
- function deactivateWorkerIfNotAddedAfterTenMinutes()
885
  {
886
  $workerActivationTime = get_option("mmb_worker_activation_time");
887
- if((int)$workerActivationTime + 600 > time()){
888
  return;
889
  }
890
  $activated_plugins = get_option('active_plugins');
891
- $keyWorker = array_search("worker/init.php", $activated_plugins, true);
892
- if($keyWorker === false){
893
  return;
894
  }
895
  unset($activated_plugins[$keyWorker]);
896
- update_option('active_plugins',$activated_plugins);
897
  }
898
  }
32
  private $mmb_pre_init_filters;
33
  private $mmb_init_actions;
34
 
35
+ public function __construct()
36
  {
37
  global $wpmu_version, $blog_id, $_mmb_plugin_actions, $_mmb_item_filter, $_mmb_options;
38
 
172
  add_action('set_auth_cookie', array(&$this, 'mmb_set_auth_cookie'));
173
  add_action('set_logged_in_cookie', array(&$this, 'mmb_set_logged_in_cookie'));
174
 
175
+ if (!get_option('_worker_nossl_key') && !get_option('_worker_public_key')) {
176
  add_action('init', array(&$this, 'deactivateWorkerIfNotAddedAfterTenMinutes'));
177
  }
178
  }
179
 
180
+ public function mmb_remote_action()
181
  {
182
  if ($this->action_call != null) {
183
  $params = isset($this->action_params) && $this->action_params != null ? $this->action_params : array();
185
  }
186
  }
187
 
188
+ public function register_action_params($action = false, $params = array())
189
  {
 
190
  if (isset($this->mmb_pre_init_actions[$action]) && function_exists($this->mmb_pre_init_actions[$action])) {
191
  call_user_func($this->mmb_pre_init_actions[$action], $params);
192
  }
212
  add_filter($_name, create_function('$a', 'global $mmb_filters; return array_merge($a, $mmb_filters["'.$_name.'"]);'));
213
  }
214
  }
 
215
  }
216
  }
217
 
224
  /**
225
  * Add notice to network admin dashboard for security reasons
226
  */
227
+ public function network_admin_notice()
228
  {
229
  global $status, $page, $s;
230
+ $context = $status;
231
+ $plugin = 'worker/init.php';
232
+ $nonce = wp_create_nonce('deactivate-plugin_'.$plugin);
233
+ $actions = 'plugins.php?action=deactivate&amp;plugin='.urlencode($plugin).'&amp;plugin_status='.$context.'&amp;paged='.$page.'&amp;s='.$s.'&amp;_wpnonce='.$nonce;
234
  $configurationService = new MWP_Configuration_Service();
235
+ $configuration = $configurationService->getConfiguration();
236
+ $notice = $configuration->getNetworkNotice();
237
+ $notice = str_replace("{deactivate_url}", $actions, $notice);
238
  echo $notice;
239
  }
240
 
 
241
  /**
242
  * Add notice to admin dashboard for security reasons
243
  */
244
+ public function admin_notice()
245
  {
246
  global $status, $page, $s;
247
+ $context = $status;
248
+ $plugin = 'worker/init.php';
249
+ $nonce = wp_create_nonce('deactivate-plugin_'.$plugin);
250
+ $actions = 'plugins.php?action=deactivate&amp;plugin='.urlencode($plugin).'&amp;plugin_status='.$context.'&amp;paged='.$page.'&amp;s='.$s.'&amp;_wpnonce='.$nonce;
251
  $configurationService = new MWP_Configuration_Service();
252
  $configuration = $configurationService->getConfiguration();
253
  $notice = $configuration->getNotice();
254
  $deactivateText = $configuration->getDeactivateText();
255
  if ($this->mmb_multisite && $this->network_admin_install != '1') {
256
  $deactivateTextLink = ''.$deactivateText;
257
+ } else {
258
  $deactivateTextLink = '<a href="'.$actions.'" class="mwp_text_notice">'.$deactivateText.'</a>';
259
  }
260
  $notice = str_replace("{deactivate_text}", $deactivateTextLink, $notice);
268
  * Add an item into the Right Now Dashboard widget
269
  * to inform that the blog can be managed remotely
270
  */
271
+ public function add_right_now_info()
272
  {
273
  $mwp_worker_brand = get_option('mwp_worker_brand');
274
  echo '<div class="mmb-slave-info">';
295
  echo '</div>';
296
  }
297
 
298
+ public function enqueue_scripts()
299
  {
300
  wp_enqueue_script('jquery');
301
  wp_enqueue_script('jquery-ui-core');
302
  wp_enqueue_script('jquery-ui-dialog');
303
  }
304
 
305
+ public function enqueue_styles()
306
  {
307
  wp_enqueue_style('wp-jquery-ui');
308
  wp_enqueue_style('jquery-style', 'http://ajax.googleapis.com/ajax/libs/jqueryui/1.10.3/themes/smoothness/jquery-ui.css');
309
  }
310
 
311
+ public function send_email_to_admin()
312
  {
313
  if (!isset($_POST['support_mwp_message'])) {
314
  return;
321
  if (empty($mwp_worker_brand['admin_email'])) {
322
  $this->mwp_send_ajax_response(false, "Unable to send email to admin.");
323
  }
324
+ $subject = 'New ticket for site '.get_bloginfo('url');
325
+ $message = <<<EOF
326
  Hi,
327
  User with a username {$current_user->user_login} has a new question:
328
  {$_POST['support_mwp_message']}
334
  $this->mwp_send_ajax_response(true, "Message successfully sent.");
335
  }
336
 
337
+ public function mwp_send_ajax_response($success = true, $message = '')
338
  {
339
  $response = json_encode(
340
  array(
346
  exit;
347
  }
348
 
349
+ public function support_page_dialog()
350
  {
351
  $mwp_worker_brand = get_option('mwp_worker_brand');
352
 
357
  <div id="support_dialog" style="display: none;">
358
  <?php if (!empty($notification_text)): ?>
359
  <div>
360
+ <p><?php echo $notification_text;
361
+ ?></p>
362
  </div>
363
  <?php endif ?>
364
  <?php if ($mwp_worker_brand['email_or_link'] == 1): ?>
377
  <?php endif ?>
378
  </div>
379
  <?php
380
+
381
  }
382
 
383
+ public function support_page_script()
384
  {
385
  ?>
386
  <script type="text/javascript">
428
  });
429
  </script>
430
  <?php
431
+
432
  }
433
 
434
  /**
435
  * Add Support page on Top Menu
436
  */
437
+ public function add_support_page()
438
  {
439
  $mwp_worker_brand = get_option('mwp_worker_brand');
440
  if ($mwp_worker_brand && isset($mwp_worker_brand['text_for_client']) && ($mwp_worker_brand['text_for_client'] != '')) {
445
  /**
446
  * Support page handler
447
  */
448
+ public function support_function()
449
  {
450
  }
451
 
 
452
  /**
453
  * Remove editor from plugins&themes submenu page
454
  */
455
+ public function dissalow_text_editor()
456
  {
457
  $mwp_worker_brand = get_option('mwp_worker_brand');
458
  if ($mwp_worker_brand && isset($mwp_worker_brand['dissalow_edit']) && ($mwp_worker_brand['dissalow_edit'] == 'checked')) {
476
  /**
477
  * Gets an instance of the Comment class
478
  */
479
+ public function get_comment_instance()
480
  {
481
  if (!isset($this->comment_instance)) {
482
  $this->comment_instance = new MMB_Comment();
488
  /**
489
  * Gets an instance of MMB_Post class
490
  */
491
+ public function get_post_instance()
492
  {
493
  if (!isset($this->post_instance)) {
494
  $this->post_instance = new MMB_Post();
500
  /**
501
  * Gets an instance of User
502
  */
503
+ public function get_user_instance()
504
  {
505
  if (!isset($this->user_instance)) {
506
  $this->user_instance = new MMB_User();
512
  /**
513
  * Gets an instance of Security
514
  */
515
+ public function get_security_instance()
516
  {
517
  if (!isset($this->security_instance)) {
518
  $this->security_instance = new MMB_Security();
521
  return $this->security_instance;
522
  }
523
 
 
524
  /**
525
  * Gets an instance of stats class
526
  */
527
+ public function get_stats_instance()
528
  {
529
  if (!isset($this->stats_instance)) {
530
  $this->stats_instance = new MMB_Stats();
536
  /**
537
  * Gets an instance of stats class
538
  */
539
+ public function get_backup_instance()
540
  {
541
  if (!isset($this->backup_instance)) {
542
  $this->backup_instance = new MMB_Backup();
549
  * Gets an instance of links class
550
 
551
  */
552
+ public function get_link_instance()
553
  {
554
  if (!isset($this->link_instance)) {
555
  $this->link_instance = new MMB_Link();
558
  return $this->link_instance;
559
  }
560
 
561
+ public function get_installer_instance()
562
  {
563
  if (!isset($this->installer_instance)) {
564
  $this->installer_instance = new MMB_Installer();
571
  * Plugin install callback function
572
  * Check PHP version
573
  */
574
+ public function install()
575
  {
576
  /** @var wpdb $wpdb */
577
  global $wpdb, $_wp_using_ext_object_cache;
616
  if (file_exists($path)) {
617
  $configuration = file_get_contents($path);
618
  $jsonConfiguration = json_decode($configuration, true);
619
+ if ($jsonConfiguration !== null) {
620
  update_option("mwp_worker_configuration", $jsonConfiguration);
621
  }
622
  }
623
  update_option('mmb_worker_activation_time', time());
624
  }
625
+
626
  /**
627
  * Saves the (modified) options into the database
628
  * Deprecated
629
  */
630
+ public function save_options($options = array())
631
  {
632
  global $_mmb_options;
633
 
638
  /**
639
  * Deletes options for communication with master
640
  */
641
+ public function uninstall($deactivate = false)
642
  {
643
  /** @var wpdb $wpdb */
644
  global $current_user, $wpdb, $_wp_using_ext_object_cache;
692
  delete_option('mmb_worker_activation_time');
693
  }
694
 
 
 
695
  /**
696
  * Constructs a url (for ajax purpose)
697
  *
698
  * @param mixed $base_page
699
  */
700
+ public function construct_url($params = array(), $base_page = 'index.php')
701
  {
702
  $url = "$base_page?_wpnonce=".wp_create_nonce($this->slug);
703
  foreach ($params as $key => $value) {
710
  /**
711
  * Worker update
712
  */
713
+ public function update_worker_plugin($params)
714
  {
715
  if ($params['download_url']) {
716
  @include_once ABSPATH.'wp-admin/includes/file.php';
722
 
723
  if (!$this->is_server_writable()) {
724
  return array(
725
+ 'error' => 'Failed, please <a target="_blank" href="http://managewp.com/user-guide/faq/my-pluginsthemes-fail-to-update-or-i-receive-a-yellow-ftp-warning">add FTP details for automatic upgrades.</a>',
726
  );
727
  }
728
 
736
  'clear_destination' => true,
737
  'clear_working' => true,
738
  'hook_extra' => array(
739
+ 'plugin' => 'worker/init.php',
740
+ ),
741
  )
742
  );
743
  ob_end_clean();
744
  if (is_wp_error($result) || !$result) {
745
  return array(
746
+ 'error' => 'ManageWP Worker plugin could not be updated.',
747
  );
748
  } else {
749
  return array(
750
+ 'success' => 'ManageWP Worker plugin successfully updated.',
751
  );
752
  }
753
  }
754
 
755
  return array(
756
+ 'error' => 'Bad download path for worker installation file.',
757
  );
758
  }
759
 
760
  /**
761
  * Automatically logs in when called from Master
762
  */
763
+ public function automatic_login()
764
  {
765
  $where = isset($_GET['mwp_goto']) ? $_GET['mwp_goto'] : false;
766
  $username = isset($_GET['username']) ? $_GET['username'] : '';
767
  $auto_login = isset($_GET['auto_login']) ? $_GET['auto_login'] : 0;
768
 
769
  if (!function_exists('is_user_logged_in')) {
770
+ include_once ABSPATH.'wp-includes/pluggable.php';
771
  }
772
 
773
  if (($auto_login && strlen(trim($username)) && !is_user_logged_in()) || (isset($this->mmb_multisite) && $this->mmb_multisite)) {
776
 
777
  $auth = $this->authenticate_message($where.$message_id, $signature, $message_id);
778
  if ($auth === true) {
 
779
  if (!headers_sent()) {
780
  header('P3P: CP="CAO PSA OUR"');
781
  }
787
  $siteurl = function_exists('get_site_option') ? get_site_option('siteurl') : get_option('siteurl');
788
  $user = $this->mmb_get_user_info($username);
789
  wp_set_current_user($user->ID);
790
+ // Compatibility with All In One Security
791
+ update_user_meta($user->ID, 'last_login_time', current_time('mysql'));
792
 
793
  if (!defined('COOKIEHASH') || (isset($this->mmb_multisite) && $this->mmb_multisite)) {
794
  wp_cookie_constants();
817
  }
818
  }
819
 
820
+ public function mmb_set_auth_cookie($auth_cookie)
821
  {
822
  if (!defined('MMB_USER_LOGIN')) {
823
  return;
830
  $_COOKIE['wordpress_'.COOKIEHASH] = $auth_cookie;
831
  }
832
 
833
+ public function mmb_set_logged_in_cookie($logged_in_cookie)
834
  {
835
  if (!defined('MMB_USER_LOGIN')) {
836
  return;
843
  $_COOKIE['wordpress_logged_in_'.COOKIEHASH] = $logged_in_cookie;
844
  }
845
 
846
+ public function admin_actions()
847
  {
848
  add_filter('all_plugins', array($this, 'worker_replace'));
849
  }
850
 
851
+ public function worker_replace($all_plugins)
852
  {
853
  $replace = get_option("mwp_worker_brand");
854
  if (is_array($replace)) {
864
 
865
  if ($replace['hide']) {
866
  if (!function_exists('get_plugins')) {
867
+ include_once ABSPATH.'wp-admin/includes/plugin.php';
868
  }
869
  $activated_plugins = get_option('active_plugins');
870
  if (!$activated_plugins) {
879
  return $all_plugins;
880
  }
881
 
882
+ public function deactivateWorkerIfNotAddedAfterTenMinutes()
883
  {
884
  $workerActivationTime = get_option("mmb_worker_activation_time");
885
+ if ((int) $workerActivationTime + 600 > time()) {
886
  return;
887
  }
888
  $activated_plugins = get_option('active_plugins');
889
+ $keyWorker = array_search("worker/init.php", $activated_plugins, true);
890
+ if ($keyWorker === false) {
891
  return;
892
  }
893
  unset($activated_plugins[$keyWorker]);
894
+ update_option('active_plugins', $activated_plugins);
895
  }
896
  }
src/MMB/Exception.php CHANGED
@@ -1,9 +1,9 @@
1
  <?php
 
2
  /**
3
  * Created by miljenko.rebernisak@prelovac.com
4
  * Date: 3/7/14
5
- */
6
-
7
- class MMB_Exception extends Exception{
8
-
9
- }
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 CHANGED
@@ -17,7 +17,7 @@ class MMB_Helper
17
  *
18
  * @param mixed $mixed
19
  */
20
- function _log($mixed)
21
  {
22
  if ((defined('MWP_SHOW_LOG') && MWP_SHOW_LOG == true) || get_option('mwp_debug_enable')) {
23
  if (is_array($mixed)) {
@@ -44,7 +44,7 @@ class MMB_Helper
44
  /**
45
  * Initializes the file system
46
  */
47
- function init_filesystem()
48
  {
49
  global $wp_filesystem;
50
 
@@ -59,9 +59,8 @@ class MMB_Helper
59
  return true;
60
  }
61
 
62
- function mmb_get_user_info($user_info = false, $info = 'login')
63
  {
64
-
65
  if ($user_info === false) {
66
  return false;
67
  }
@@ -76,9 +75,8 @@ class MMB_Helper
76
  /**
77
  * Call action item filters
78
  */
79
- function mmb_parse_action_params($key = '', $params = null, $call_object = null)
80
  {
81
-
82
  global $_mmb_item_filter;
83
  $call_object = $call_object !== null ? $call_object : $this;
84
  $return = array();
@@ -104,9 +102,8 @@ class MMB_Helper
104
  /**
105
  * Check if function exists or not on `suhosin` black list
106
  */
107
- function mmb_function_exists($function_callback)
108
  {
109
-
110
  if (!function_exists($function_callback)) {
111
  return false;
112
  }
@@ -131,7 +128,7 @@ class MMB_Helper
131
  return true;
132
  }
133
 
134
- function mmb_get_transient($option_name)
135
  {
136
  if (trim($option_name) == '') {
137
  return false;
@@ -157,7 +154,7 @@ class MMB_Helper
157
  }
158
  }
159
 
160
- function mmb_delete_transient($option_name)
161
  {
162
  if (trim($option_name) == '') {
163
  return;
@@ -176,7 +173,7 @@ class MMB_Helper
176
  }
177
  }
178
 
179
- function mmb_get_sitemeta_transient($option_name)
180
  {
181
  /** @var wpdb $wpdb */
182
  global $wpdb;
@@ -188,7 +185,7 @@ class MMB_Helper
188
  return $result;
189
  }
190
 
191
- function mmb_set_sitemeta_transient($option_name, $option_value)
192
  {
193
  /** @var wpdb $wpdb */
194
  global $wpdb;
@@ -198,11 +195,11 @@ class MMB_Helper
198
  $result = $wpdb->update(
199
  $wpdb->sitemeta,
200
  array(
201
- 'meta_value' => maybe_serialize($option_value)
202
  ),
203
  array(
204
  'meta_key' => $option_name,
205
- 'site_id' => $this->mmb_multisite
206
  )
207
  );
208
  } else {
@@ -211,7 +208,7 @@ class MMB_Helper
211
  array(
212
  'meta_key' => $option_name,
213
  'meta_value' => maybe_serialize($option_value),
214
- 'site_id' => $this->mmb_multisite
215
  )
216
  );
217
  }
@@ -219,7 +216,7 @@ class MMB_Helper
219
  return $result;
220
  }
221
 
222
- function delete_temp_dir($directory)
223
  {
224
  if (substr($directory, -1) == "/") {
225
  $directory = substr($directory, 0, -1);
@@ -249,7 +246,7 @@ class MMB_Helper
249
  }
250
  }
251
 
252
- function set_worker_message_id($message_id = false)
253
  {
254
  if ($message_id) {
255
  add_option('_action_message_id', $message_id) or update_option('_action_message_id', $message_id);
@@ -260,12 +257,12 @@ class MMB_Helper
260
  return false;
261
  }
262
 
263
- function get_worker_message_id()
264
  {
265
  return (int) get_option('_action_message_id');
266
  }
267
 
268
- function set_master_public_key($public_key = false)
269
  {
270
  if ($public_key && !get_option('_worker_public_key')) {
271
  add_option('_worker_public_key', base64_encode($public_key));
@@ -276,7 +273,7 @@ class MMB_Helper
276
  return false;
277
  }
278
 
279
- function get_master_public_key()
280
  {
281
  if (!get_option('_worker_public_key')) {
282
  return false;
@@ -285,8 +282,7 @@ class MMB_Helper
285
  return base64_decode(get_option('_worker_public_key'));
286
  }
287
 
288
-
289
- function get_random_signature()
290
  {
291
  if (!get_option('_worker_nossl_key')) {
292
  return false;
@@ -295,7 +291,7 @@ class MMB_Helper
295
  return base64_decode(get_option('_worker_nossl_key'));
296
  }
297
 
298
- function set_random_signature($random_key = false)
299
  {
300
  if ($random_key && !get_option('_worker_nossl_key')) {
301
  add_option('_worker_nossl_key', base64_encode($random_key));
@@ -306,26 +302,25 @@ class MMB_Helper
306
  return false;
307
  }
308
 
309
-
310
- function authenticate_message($data = false, $signature = false, $message_id = false)
311
  {
312
  if (!$data && !$signature) {
313
  return array(
314
- 'error' => 'Authentication failed.'
315
  );
316
  }
317
  $nonce = new MWP_Security_HashNonce();
318
  $nonce->setValue($message_id);
319
  if (!$nonce->verify()) {
320
  return array(
321
- 'error' => 'Invalid nonce used. Please contact support'
322
  );
323
  }
324
 
325
  $pl_key = $this->get_master_public_key();
326
  if (!$pl_key) {
327
  return array(
328
- 'error' => 'Authentication failed. Deactivate and activate the ManageWP Worker plugin on this site, then re-add it to your ManageWP account.'
329
  );
330
  }
331
 
@@ -338,11 +333,11 @@ class MMB_Helper
338
  } else {
339
  if ($verify == 0) {
340
  return array(
341
- 'error' => 'Invalid message signature. Deactivate and activate the ManageWP Worker plugin on this site, then re-add it to your ManageWP account.'
342
  );
343
  } else {
344
  return array(
345
- 'error' => 'Command not successful! Please try again.'
346
  );
347
  }
348
  }
@@ -355,20 +350,19 @@ class MMB_Helper
355
  }
356
 
357
  return array(
358
- 'error' => 'Invalid message signature. Deactivate and activate the ManageWP Worker plugin on this site, then re-add it to your ManageWP account.'
359
  );
360
  } // no rand key - deleted in get_stat maybe
361
  else {
362
  return array(
363
- 'error' => 'Invalid message signature. Deactivate and activate the ManageWP Worker plugin on this site, then re-add it to your ManageWP account.'
364
  );
365
  }
366
  }
367
  }
368
 
369
- function get_secure_hash()
370
  {
371
-
372
  $pl_key = $this->get_master_public_key();
373
  if (empty($pl_key) || $this->get_random_signature() !== false) {
374
  $pl_key = $this->get_random_signature();
@@ -381,7 +375,7 @@ class MMB_Helper
381
  return false;
382
  }
383
 
384
- function _secure_data($data = false)
385
  {
386
  if ($data == false) {
387
  return false;
@@ -412,10 +406,9 @@ class MMB_Helper
412
  }
413
 
414
  return false;
415
-
416
  }
417
 
418
- function encrypt_data($data = false)
419
  {
420
  if (empty($data)) {
421
  return $data;
@@ -444,10 +437,9 @@ class MMB_Helper
444
  }
445
 
446
  return $crypted;
447
-
448
  }
449
 
450
- function check_if_user_exists($username = false)
451
  {
452
  global $wpdb;
453
 
@@ -477,27 +469,26 @@ class MMB_Helper
477
  return false;
478
  }
479
 
480
- function refresh_updates()
481
  {
482
  if (rand(1, 3) == '2') {
483
- require_once(ABSPATH.WPINC.'/update.php');
484
  wp_update_plugins();
485
  wp_update_themes();
486
  wp_version_check();
487
  }
488
  }
489
 
490
- function remove_http($url = '')
491
  {
492
- if ($url == 'http://' OR $url == 'https://') {
493
  return $url;
494
  }
495
 
496
  return preg_replace('/^(http|https)\:\/\/(www.)?/i', '', $url);
497
-
498
  }
499
 
500
- function mmb_get_error($error_object)
501
  {
502
  if (!is_wp_error($error_object)) {
503
  return $error_object != '' ? $error_object : '';
@@ -517,9 +508,8 @@ class MMB_Helper
517
  }
518
  }
519
 
520
- function is_server_writable()
521
  {
522
-
523
  if ((!defined('FTP_HOST') || !defined('FTP_USER')) && (get_filesystem_method(array(), false) != 'direct')) {
524
  return false;
525
  } else {
@@ -527,7 +517,7 @@ class MMB_Helper
527
  }
528
  }
529
 
530
- function return_bytes($val)
531
  {
532
  $val = trim($val);
533
  $last = strtolower($val[strlen($val) - 1]);
@@ -543,18 +533,16 @@ class MMB_Helper
543
 
544
  return $val;
545
  }
546
-
547
- function w3tc_flush($flushAll = false)
548
  {
549
  if ($flushAll) {
550
  if (function_exists('w3tc_pgcache_flush')) {
551
  w3tc_pgcache_flush();
552
-
553
  }
554
 
555
  if (function_exists('w3tc_dbcache_flush')) {
556
  w3tc_dbcache_flush();
557
-
558
  }
559
  }
560
 
@@ -566,10 +554,10 @@ class MMB_Helper
566
  protected function notifyMyself($functionName, $args = array())
567
  {
568
  global $current_user;
569
- $nonce = wp_create_nonce("mmb-fork-nonce");
570
- $cron_url = site_url('index.php');
571
- $public_key = get_option('_worker_public_key');
572
- $args = array(
573
  'body' => array(
574
  'mwp_forked_action' => $functionName,
575
  'args' => json_encode($args),
@@ -579,7 +567,7 @@ class MMB_Helper
579
  ),
580
  'timeout' => 0.01,
581
  'blocking' => false,
582
- 'sslverify' => apply_filters('https_local_ssl_verify', true)
583
  );
584
  wp_remote_post($cron_url, $args);
585
  }
17
  *
18
  * @param mixed $mixed
19
  */
20
+ public function _log($mixed)
21
  {
22
  if ((defined('MWP_SHOW_LOG') && MWP_SHOW_LOG == true) || get_option('mwp_debug_enable')) {
23
  if (is_array($mixed)) {
44
  /**
45
  * Initializes the file system
46
  */
47
+ public function init_filesystem()
48
  {
49
  global $wp_filesystem;
50
 
59
  return true;
60
  }
61
 
62
+ public function mmb_get_user_info($user_info = false, $info = 'login')
63
  {
 
64
  if ($user_info === false) {
65
  return false;
66
  }
75
  /**
76
  * Call action item filters
77
  */
78
+ public function mmb_parse_action_params($key = '', $params = null, $call_object = null)
79
  {
 
80
  global $_mmb_item_filter;
81
  $call_object = $call_object !== null ? $call_object : $this;
82
  $return = array();
102
  /**
103
  * Check if function exists or not on `suhosin` black list
104
  */
105
+ public function mmb_function_exists($function_callback)
106
  {
 
107
  if (!function_exists($function_callback)) {
108
  return false;
109
  }
128
  return true;
129
  }
130
 
131
+ public function mmb_get_transient($option_name)
132
  {
133
  if (trim($option_name) == '') {
134
  return false;
154
  }
155
  }
156
 
157
+ public function mmb_delete_transient($option_name)
158
  {
159
  if (trim($option_name) == '') {
160
  return;
173
  }
174
  }
175
 
176
+ public function mmb_get_sitemeta_transient($option_name)
177
  {
178
  /** @var wpdb $wpdb */
179
  global $wpdb;
185
  return $result;
186
  }
187
 
188
+ public function mmb_set_sitemeta_transient($option_name, $option_value)
189
  {
190
  /** @var wpdb $wpdb */
191
  global $wpdb;
195
  $result = $wpdb->update(
196
  $wpdb->sitemeta,
197
  array(
198
+ 'meta_value' => maybe_serialize($option_value),
199
  ),
200
  array(
201
  'meta_key' => $option_name,
202
+ 'site_id' => $this->mmb_multisite,
203
  )
204
  );
205
  } else {
208
  array(
209
  'meta_key' => $option_name,
210
  'meta_value' => maybe_serialize($option_value),
211
+ 'site_id' => $this->mmb_multisite,
212
  )
213
  );
214
  }
216
  return $result;
217
  }
218
 
219
+ public function delete_temp_dir($directory)
220
  {
221
  if (substr($directory, -1) == "/") {
222
  $directory = substr($directory, 0, -1);
246
  }
247
  }
248
 
249
+ public function set_worker_message_id($message_id = false)
250
  {
251
  if ($message_id) {
252
  add_option('_action_message_id', $message_id) or update_option('_action_message_id', $message_id);
257
  return false;
258
  }
259
 
260
+ public function get_worker_message_id()
261
  {
262
  return (int) get_option('_action_message_id');
263
  }
264
 
265
+ public function set_master_public_key($public_key = false)
266
  {
267
  if ($public_key && !get_option('_worker_public_key')) {
268
  add_option('_worker_public_key', base64_encode($public_key));
273
  return false;
274
  }
275
 
276
+ public function get_master_public_key()
277
  {
278
  if (!get_option('_worker_public_key')) {
279
  return false;
282
  return base64_decode(get_option('_worker_public_key'));
283
  }
284
 
285
+ public function get_random_signature()
 
286
  {
287
  if (!get_option('_worker_nossl_key')) {
288
  return false;
291
  return base64_decode(get_option('_worker_nossl_key'));
292
  }
293
 
294
+ public function set_random_signature($random_key = false)
295
  {
296
  if ($random_key && !get_option('_worker_nossl_key')) {
297
  add_option('_worker_nossl_key', base64_encode($random_key));
302
  return false;
303
  }
304
 
305
+ public function authenticate_message($data = false, $signature = false, $message_id = false)
 
306
  {
307
  if (!$data && !$signature) {
308
  return array(
309
+ 'error' => 'Authentication failed.',
310
  );
311
  }
312
  $nonce = new MWP_Security_HashNonce();
313
  $nonce->setValue($message_id);
314
  if (!$nonce->verify()) {
315
  return array(
316
+ 'error' => 'Invalid nonce used. Please contact support',
317
  );
318
  }
319
 
320
  $pl_key = $this->get_master_public_key();
321
  if (!$pl_key) {
322
  return array(
323
+ 'error' => 'Authentication failed. Deactivate and activate the ManageWP Worker plugin on this site, then re-add it to your ManageWP account.',
324
  );
325
  }
326
 
333
  } else {
334
  if ($verify == 0) {
335
  return array(
336
+ 'error' => 'Invalid message signature. Deactivate and activate the ManageWP Worker plugin on this site, then re-add it to your ManageWP account.',
337
  );
338
  } else {
339
  return array(
340
+ 'error' => 'Command not successful! Please try again.',
341
  );
342
  }
343
  }
350
  }
351
 
352
  return array(
353
+ 'error' => 'Invalid message signature. Deactivate and activate the ManageWP Worker plugin on this site, then re-add it to your ManageWP account.',
354
  );
355
  } // no rand key - deleted in get_stat maybe
356
  else {
357
  return array(
358
+ 'error' => 'Invalid message signature. Deactivate and activate the ManageWP Worker plugin on this site, then re-add it to your ManageWP account.',
359
  );
360
  }
361
  }
362
  }
363
 
364
+ public function get_secure_hash()
365
  {
 
366
  $pl_key = $this->get_master_public_key();
367
  if (empty($pl_key) || $this->get_random_signature() !== false) {
368
  $pl_key = $this->get_random_signature();
375
  return false;
376
  }
377
 
378
+ public function _secure_data($data = false)
379
  {
380
  if ($data == false) {
381
  return false;
406
  }
407
 
408
  return false;
 
409
  }
410
 
411
+ public function encrypt_data($data = false)
412
  {
413
  if (empty($data)) {
414
  return $data;
437
  }
438
 
439
  return $crypted;
 
440
  }
441
 
442
+ public function check_if_user_exists($username = false)
443
  {
444
  global $wpdb;
445
 
469
  return false;
470
  }
471
 
472
+ public function refresh_updates()
473
  {
474
  if (rand(1, 3) == '2') {
475
+ require_once ABSPATH.WPINC.'/update.php';
476
  wp_update_plugins();
477
  wp_update_themes();
478
  wp_version_check();
479
  }
480
  }
481
 
482
+ public function remove_http($url = '')
483
  {
484
+ if ($url == 'http://' or $url == 'https://') {
485
  return $url;
486
  }
487
 
488
  return preg_replace('/^(http|https)\:\/\/(www.)?/i', '', $url);
 
489
  }
490
 
491
+ public function mmb_get_error($error_object)
492
  {
493
  if (!is_wp_error($error_object)) {
494
  return $error_object != '' ? $error_object : '';
508
  }
509
  }
510
 
511
+ public function is_server_writable()
512
  {
 
513
  if ((!defined('FTP_HOST') || !defined('FTP_USER')) && (get_filesystem_method(array(), false) != 'direct')) {
514
  return false;
515
  } else {
517
  }
518
  }
519
 
520
+ public function return_bytes($val)
521
  {
522
  $val = trim($val);
523
  $last = strtolower($val[strlen($val) - 1]);
533
 
534
  return $val;
535
  }
536
+
537
+ public function w3tc_flush($flushAll = false)
538
  {
539
  if ($flushAll) {
540
  if (function_exists('w3tc_pgcache_flush')) {
541
  w3tc_pgcache_flush();
 
542
  }
543
 
544
  if (function_exists('w3tc_dbcache_flush')) {
545
  w3tc_dbcache_flush();
 
546
  }
547
  }
548
 
554
  protected function notifyMyself($functionName, $args = array())
555
  {
556
  global $current_user;
557
+ $nonce = wp_create_nonce("mmb-fork-nonce");
558
+ $cron_url = site_url('index.php');
559
+ $public_key = get_option('_worker_public_key');
560
+ $args = array(
561
  'body' => array(
562
  'mwp_forked_action' => $functionName,
563
  'args' => json_encode($args),
567
  ),
568
  'timeout' => 0.01,
569
  'blocking' => false,
570
+ 'sslverify' => apply_filters('https_local_ssl_verify', true),
571
  );
572
  wp_remote_post($cron_url, $args);
573
  }
src/MMB/Installer.php CHANGED
@@ -8,16 +8,16 @@
8
  **************************************************************/
9
  class MMB_Installer extends MMB_Core
10
  {
11
- function __construct()
12
  {
13
  @set_time_limit(600);
14
  parent::__construct();
15
- @include_once(ABSPATH.'wp-admin/includes/file.php');
16
- @include_once(ABSPATH.'wp-admin/includes/plugin.php');
17
- @include_once(ABSPATH.'wp-admin/includes/theme.php');
18
- @include_once(ABSPATH.'wp-admin/includes/misc.php');
19
- @include_once(ABSPATH.'wp-admin/includes/template.php');
20
- @include_once(ABSPATH.'wp-admin/includes/class-wp-upgrader.php');
21
 
22
  global $wp_filesystem;
23
  if (!$wp_filesystem) {
@@ -25,7 +25,7 @@ class MMB_Installer extends MMB_Core
25
  }
26
  }
27
 
28
- function mmb_maintenance_mode($enable = false, $maintenance_message = '')
29
  {
30
  global $wp_filesystem;
31
 
@@ -40,48 +40,48 @@ class MMB_Installer extends MMB_Core
40
  }
41
  }
42
 
43
- function install_remote_files($params)
44
  {
45
  $data = array();
46
  foreach ($params['plugins'] as $theme) {
47
- $dataTmp = $this->install_remote_file($theme);
48
- $pluginName = key($dataTmp);
49
  $data[$pluginName] = $dataTmp;
50
  }
51
  foreach ($params['themes'] as $theme) {
52
- $dataTmp = $this->install_remote_file($theme);
53
- $themeName = key($dataTmp);
54
  $data[$themeName] = $dataTmp;
55
  }
56
 
57
  return $data;
58
  }
59
 
60
- function install_remote_file($params)
61
  {
62
  global $wp_filesystem;
63
  extract($params);
64
 
65
  if (!isset($package) || empty($package)) {
66
  return array(
67
- 'error' => '<p>No files received. Internal error.</p>'
68
  );
69
  }
70
 
71
  if (!$this->is_server_writable()) {
72
  return array(
73
- 'error' => 'Failed, please <a target="_blank" href="http://managewp.com/user-guide/faq/my-pluginsthemes-fail-to-update-or-i-receive-a-yellow-ftp-warning">add FTP details</a>'
74
  );
75
  }
76
 
77
  if (defined('WP_INSTALLING') && file_exists(ABSPATH.'.maintenance')) {
78
  return array(
79
- 'error' => '<p>Site under maintanace.</p>'
80
  );
81
  }
82
 
83
  if (!class_exists('WP_Upgrader')) {
84
- include_once(ABSPATH.'wp-admin/includes/class-wp-upgrader.php');
85
  }
86
 
87
  $upgrader_skin = new WP_Upgrader_Skin();
@@ -99,14 +99,14 @@ class MMB_Installer extends MMB_Core
99
  'destination' => $destination,
100
  'clear_destination' => $clear_destination, //Do not overwrite files.
101
  'clear_working' => true,
102
- 'hook_extra' => array()
103
  )
104
  );
105
  }
106
 
107
  if ($activate) {
108
  if ($type == 'plugins') {
109
- include_once(ABSPATH.'wp-admin/includes/plugin.php');
110
  $all_plugins = get_plugins();
111
  foreach ($all_plugins as $plugin_slug => $plugin) {
112
  $plugin_dir = preg_split('/\//', $plugin_slug);
@@ -122,7 +122,7 @@ class MMB_Installer extends MMB_Core
122
  } else {
123
  if (count($install_info) == 1) {
124
  global $wp_themes;
125
- include_once(ABSPATH.'wp-includes/theme.php');
126
 
127
  $wp_themes = null;
128
  unset($wp_themes); //prevent theme data caching
@@ -162,23 +162,41 @@ class MMB_Installer extends MMB_Core
162
  return $install_info;
163
  }
164
 
165
- function do_upgrade($params = null)
166
  {
 
 
 
 
 
 
 
 
 
167
 
 
 
 
 
 
 
 
 
168
 
 
 
169
  if ($params == null || empty($params)) {
170
  return array(
171
- 'error' => 'No upgrades passed.'
172
  );
173
  }
174
 
175
  if (!$this->is_server_writable()) {
176
  return array(
177
- 'error' => 'Failed, please <a target="_blank" href="http://managewp.com/user-guide/faq/my-pluginsthemes-fail-to-update-or-i-receive-a-yellow-ftp-warning">add FTP details</a>'
178
  );
179
  }
180
 
181
-
182
  $params = isset($params['upgrades_all']) ? $params['upgrades_all'] : $params;
183
 
184
  $core_upgrade = isset($params['wp_upgrade']) ? $params['wp_upgrade'] : array();
@@ -193,6 +211,7 @@ class MMB_Installer extends MMB_Core
193
 
194
  if (!empty($upgrade_plugins)) {
195
  $plugin_files = array();
 
196
  foreach ($upgrade_plugins as $plugin) {
197
  if (isset($plugin['file'])) {
198
  $plugin_files[$plugin['file']] = $plugin['old_version'];
@@ -203,7 +222,7 @@ class MMB_Installer extends MMB_Core
203
  if (!empty($plugin_files)) {
204
  $upgrades['plugins'] = $this->upgrade_plugins($plugin_files);
205
  }
206
-
207
  }
208
 
209
  if (!empty($upgrade_themes)) {
@@ -219,7 +238,6 @@ class MMB_Installer extends MMB_Core
219
  if (!empty($theme_temps)) {
220
  $upgrades['themes'] = $this->upgrade_themes($theme_temps);
221
  }
222
-
223
  }
224
 
225
  if (!empty($premium_upgrades)) {
@@ -246,12 +264,12 @@ class MMB_Installer extends MMB_Core
246
  * Upgrades WordPress locally
247
 
248
  */
249
- function upgrade_core($current)
250
  {
251
  ob_start();
252
 
253
  if (file_exists(ABSPATH.'/wp-admin/includes/update.php')) {
254
- include_once(ABSPATH.'/wp-admin/includes/update.php');
255
  }
256
 
257
  @wp_version_check();
@@ -266,13 +284,13 @@ class MMB_Installer extends MMB_Core
266
  $updated = $core->updates[0];
267
  if (!isset($updated->response) || $updated->response == 'latest') {
268
  return array(
269
- 'upgraded' => ' updated'
270
  );
271
  }
272
 
273
  if ($updated->response == "development" && $current['response'] == "upgrade") {
274
  return array(
275
- 'error' => '<font color="#900">Unexpected error. Please upgrade manually.</font>'
276
  );
277
  } else {
278
  if ($updated->response == $current['response'] || ($updated->response == "upgrade" && $current['response'] == "development")) {
@@ -285,7 +303,7 @@ class MMB_Installer extends MMB_Core
285
  }
286
  if ($current_update == false) {
287
  return array(
288
- 'error' => ' Localization mismatch. Try again.'
289
  );
290
  }
291
  } else {
@@ -293,13 +311,13 @@ class MMB_Installer extends MMB_Core
293
  }
294
  } else {
295
  return array(
296
- 'error' => ' Transient mismatch. Try again.'
297
  );
298
  }
299
  }
300
  } else {
301
  return array(
302
- 'error' => ' Refresh transient failed. Try again.'
303
  );
304
  }
305
  if ($current_update != false) {
@@ -307,7 +325,7 @@ class MMB_Installer extends MMB_Core
307
 
308
  if (version_compare($wp_version, '3.1.9', '>')) {
309
  if (!class_exists('Core_Upgrader')) {
310
- include_once(ABSPATH.'wp-admin/includes/class-wp-upgrader.php');
311
  }
312
 
313
  $core = new Core_Upgrader();
@@ -315,26 +333,25 @@ class MMB_Installer extends MMB_Core
315
  $this->mmb_maintenance_mode(false);
316
  if (is_wp_error($result)) {
317
  return array(
318
- 'error' => $this->mmb_get_error($result)
319
  );
320
  } else {
321
  return array(
322
- 'upgraded' => ' updated'
323
  );
324
  }
325
-
326
  } else {
327
  if (!class_exists('WP_Upgrader')) {
328
- include_once(ABSPATH.'wp-admin/includes/update.php');
329
  if (function_exists('wp_update_core')) {
330
  $result = wp_update_core($current_update);
331
  if (is_wp_error($result)) {
332
  return array(
333
- 'error' => $this->mmb_get_error($result)
334
  );
335
  } else {
336
  return array(
337
- 'upgraded' => ' updated'
338
  );
339
  }
340
  }
@@ -349,19 +366,19 @@ class MMB_Installer extends MMB_Core
349
  // Is an update available?
350
  if (!isset($current_update->response) || $current_update->response == 'latest') {
351
  return array(
352
- 'upgraded' => ' updated'
353
  );
354
  }
355
 
356
  $res = $upgrader->fs_connect(
357
  array(
358
  ABSPATH,
359
- WP_CONTENT_DIR
360
  )
361
  );
362
  if (is_wp_error($res)) {
363
  return array(
364
- 'error' => $this->mmb_get_error($res)
365
  );
366
  }
367
 
@@ -377,14 +394,14 @@ class MMB_Installer extends MMB_Core
377
  $download = $upgrader->download_package($core_package);
378
  if (is_wp_error($download)) {
379
  return array(
380
- 'error' => $this->mmb_get_error($download)
381
  );
382
  }
383
 
384
  $working_dir = $upgrader->unpack_package($download);
385
  if (is_wp_error($working_dir)) {
386
  return array(
387
- 'error' => $this->mmb_get_error($working_dir)
388
  );
389
  }
390
 
@@ -392,14 +409,13 @@ class MMB_Installer extends MMB_Core
392
  $wp_filesystem->delete($working_dir, true);
393
 
394
  return array(
395
- 'error' => 'Unable to move update files.'
396
  );
397
  }
398
 
399
  $wp_filesystem->chmod($wp_dir.'wp-admin/includes/update-core.php', FS_CHMOD_FILE);
400
 
401
- require(ABSPATH.'wp-admin/includes/update-core.php');
402
-
403
 
404
  $update_core = update_core($working_dir, $wp_dir);
405
  ob_end_clean();
@@ -407,32 +423,32 @@ class MMB_Installer extends MMB_Core
407
  $this->mmb_maintenance_mode(false);
408
  if (is_wp_error($update_core)) {
409
  return array(
410
- 'error' => $this->mmb_get_error($update_core)
411
  );
412
  }
413
  ob_end_flush();
414
 
415
  return array(
416
- 'upgraded' => 'updated'
417
  );
418
  } else {
419
  return array(
420
- 'error' => 'failed'
421
  );
422
  }
423
  }
424
  } else {
425
  return array(
426
- 'error' => 'failed'
427
  );
428
  }
429
  }
430
 
431
- function upgrade_plugins($plugins = false)
432
  {
433
  if (!$plugins || empty($plugins)) {
434
  return array(
435
- 'error' => 'No plugin files for upgrade.'
436
  );
437
  }
438
 
@@ -453,7 +469,7 @@ class MMB_Installer extends MMB_Core
453
  $upgrader = new Plugin_Upgrader(new Bulk_Plugin_Upgrader_Skin(compact('nonce', 'url')));
454
  $result = $upgrader->bulk_upgrade(array_keys($plugins));
455
  if (!function_exists('wp_update_plugins')) {
456
- include_once(ABSPATH.'wp-includes/update.php');
457
  }
458
 
459
  @wp_update_plugins();
@@ -474,27 +490,27 @@ class MMB_Installer extends MMB_Core
474
  ob_end_clean();
475
 
476
  return array(
477
- 'upgraded' => $return
478
  );
479
  } else {
480
  return array(
481
- 'error' => 'Upgrade failed.'
482
  );
483
  }
484
  } else {
485
  ob_end_clean();
486
 
487
  return array(
488
- 'error' => 'WordPress update required first.'
489
  );
490
  }
491
  }
492
 
493
- function upgrade_themes($themes = false)
494
  {
495
  if (!$themes || empty($themes)) {
496
  return array(
497
- 'error' => 'No theme files for upgrade.'
498
  );
499
  }
500
 
@@ -512,7 +528,7 @@ class MMB_Installer extends MMB_Core
512
  $result = $upgrader->bulk_upgrade($themes);
513
 
514
  if (!function_exists('wp_update_themes')) {
515
- include_once(ABSPATH.'wp-includes/update.php');
516
  }
517
 
518
  @wp_update_themes();
@@ -533,33 +549,33 @@ class MMB_Installer extends MMB_Core
533
  }
534
 
535
  return array(
536
- 'upgraded' => $return
537
  );
538
  } else {
539
  return array(
540
- 'error' => 'Upgrade failed.'
541
  );
542
  }
543
  } else {
544
  ob_end_clean();
545
 
546
  return array(
547
- 'error' => 'WordPress update required first'
548
  );
549
  }
550
  }
551
 
552
- function upgrade_premium($premium = false)
553
  {
554
  global $mmb_plugin_url;
555
 
556
  if (!class_exists('WP_Upgrader')) {
557
- include_once(ABSPATH.'wp-admin/includes/class-wp-upgrader.php');
558
  }
559
 
560
  if (!$premium || empty($premium)) {
561
  return array(
562
- 'error' => 'No premium files for upgrade.'
563
  );
564
  }
565
 
@@ -571,12 +587,10 @@ class MMB_Installer extends MMB_Core
571
  $premium_update = array();
572
  $premium_update = apply_filters('mwp_premium_perform_update', $premium_update);
573
  if (!empty($premium_update)) {
574
-
575
  foreach ($premium as $pr) {
576
  foreach ($premium_update as $key => $update) {
577
  $update = array_change_key_case($update, CASE_LOWER);
578
  if ($update['name'] == $pr['name']) {
579
-
580
  // prepare bulk updates for premiums that use WordPress upgrader
581
  if (isset($update['type'])) {
582
  if ($update['type'] == 'plugin') {
@@ -646,18 +660,17 @@ class MMB_Installer extends MMB_Core
646
  $upgrader_skin = new WP_Upgrader_Skin();
647
  $upgrader_skin->done_header = true;
648
  $upgrader = new WP_Upgrader();
649
- @$update_result = $upgrader->run(
650
  array(
651
  'package' => $update['url'],
652
  'destination' => isset($update['type']) && $update['type'] == 'theme' ? WP_CONTENT_DIR.'/themes' : WP_PLUGIN_DIR,
653
  'clear_destination' => true,
654
  'clear_working' => true,
655
  'is_multi' => true,
656
- 'hook_extra' => array()
657
  )
658
  );
659
  $update_result = !$update_result || is_wp_error($update_result) ? $this->mmb_get_error($update_result) : 1;
660
-
661
  } else {
662
  if (isset($update['callback'])) {
663
  if (is_array($update['callback'])) {
@@ -690,7 +703,7 @@ class MMB_Installer extends MMB_Core
690
  }
691
  }
692
 
693
- function get_upgradable_plugins($filter = array())
694
  {
695
  $current = $this->mmb_get_transient('update_plugins');
696
 
@@ -724,7 +737,7 @@ class MMB_Installer extends MMB_Core
724
  }
725
  }
726
 
727
- function get_upgradable_themes($filter = array())
728
  {
729
  if (function_exists('wp_get_themes')) {
730
  $all_themes = wp_get_themes();
@@ -783,11 +796,10 @@ class MMB_Installer extends MMB_Core
783
  }
784
  }
785
 
786
-
787
  return $upgrade_themes;
788
  }
789
 
790
- function get($args)
791
  {
792
  if (empty($args)) {
793
  return false;
@@ -806,22 +818,22 @@ class MMB_Installer extends MMB_Core
806
  return $return;
807
  }
808
 
809
- function get_plugins($args)
810
  {
811
  if (empty($args)) {
812
  return false;
813
  }
814
 
815
  $search = $args['search'];
816
- $type = trim((string) $args['type']);
817
 
818
  if (!function_exists('get_plugins')) {
819
- include_once(ABSPATH.'wp-admin/includes/plugin.php');
820
  }
821
  $all_plugins = get_plugins();
822
  $plugins = array(
823
  'active' => array(),
824
- 'inactive' => array()
825
  );
826
  if (is_array($all_plugins) && !empty($all_plugins)) {
827
  $activated_plugins = get_option('active_plugins');
@@ -836,7 +848,7 @@ class MMB_Installer extends MMB_Core
836
  $plugin = array(
837
  'path' => $path,
838
  'name' => strip_tags($plugin['Name']),
839
- 'version' => $plugin['Version']
840
  );
841
 
842
  // If type is set, it must be equal to the current plugin status
@@ -849,7 +861,6 @@ class MMB_Installer extends MMB_Core
849
 
850
  if ($typeMatches && $searchTermFound) {
851
  $plugins[$status][] = $plugin;
852
-
853
  }
854
  }
855
  }
@@ -858,7 +869,7 @@ class MMB_Installer extends MMB_Core
858
  return $plugins;
859
  }
860
 
861
- function get_themes($args)
862
  {
863
  if (empty($args)) {
864
  return false;
@@ -867,13 +878,13 @@ class MMB_Installer extends MMB_Core
867
  extract($args);
868
 
869
  if (!function_exists('wp_get_themes')) {
870
- include_once(ABSPATH.WPINC.'/theme.php');
871
  }
872
  if (function_exists('wp_get_themes')) {
873
  $all_themes = wp_get_themes();
874
  $themes = array(
875
  'active' => array(),
876
- 'inactive' => array()
877
  );
878
 
879
  if (is_array($all_themes) && !empty($all_themes)) {
@@ -897,7 +908,6 @@ class MMB_Installer extends MMB_Core
897
  $themes['inactive'][$br_i]['stylesheet'] = $theme->Stylesheet;
898
  $br_i++;
899
  }
900
-
901
  }
902
 
903
  if ($search) {
@@ -918,7 +928,7 @@ class MMB_Installer extends MMB_Core
918
  $all_themes = get_themes();
919
  $themes = array(
920
  'active' => array(),
921
- 'inactive' => array()
922
  );
923
 
924
  if (is_array($all_themes) && !empty($all_themes)) {
@@ -942,7 +952,6 @@ class MMB_Installer extends MMB_Core
942
  $themes['inactive'][$br_i]['stylesheet'] = $theme['Stylesheet'];
943
  $br_i++;
944
  }
945
-
946
  }
947
 
948
  if ($search) {
@@ -959,13 +968,12 @@ class MMB_Installer extends MMB_Core
959
  }
960
  }
961
  }
962
-
963
  }
964
 
965
  return $themes;
966
  }
967
 
968
- function edit($args)
969
  {
970
  extract($args);
971
  $return = array();
@@ -978,7 +986,7 @@ class MMB_Installer extends MMB_Core
978
  return $return;
979
  }
980
 
981
- function edit_plugins($args)
982
  {
983
  extract($args);
984
  $return = array();
@@ -990,14 +998,14 @@ class MMB_Installer extends MMB_Core
990
  case 'deactivate':
991
  $result = deactivate_plugins(
992
  array(
993
- $item['path']
994
  )
995
  );
996
  break;
997
  case 'delete':
998
  $result = delete_plugins(
999
  array(
1000
- $item['path']
1001
  )
1002
  );
1003
  break;
@@ -1007,11 +1015,11 @@ class MMB_Installer extends MMB_Core
1007
 
1008
  if (is_wp_error($result)) {
1009
  $result = array(
1010
- 'error' => $result->get_error_message()
1011
  );
1012
  } elseif ($result === false) {
1013
  $result = array(
1014
- 'error' => "Failed to perform action."
1015
  );
1016
  } else {
1017
  $result = "OK";
@@ -1022,7 +1030,7 @@ class MMB_Installer extends MMB_Core
1022
  return $return;
1023
  }
1024
 
1025
- function edit_themes($args)
1026
  {
1027
  extract($args);
1028
  $return = array();
@@ -1040,11 +1048,11 @@ class MMB_Installer extends MMB_Core
1040
 
1041
  if (is_wp_error($result)) {
1042
  $result = array(
1043
- 'error' => $result->get_error_message()
1044
  );
1045
  } elseif ($result === false) {
1046
  $result = array(
1047
- 'error' => "Failed to perform action."
1048
  );
1049
  } else {
1050
  $result = "OK";
@@ -1053,6 +1061,5 @@ class MMB_Installer extends MMB_Core
1053
  }
1054
 
1055
  return $return;
1056
-
1057
  }
1058
  }
8
  **************************************************************/
9
  class MMB_Installer extends MMB_Core
10
  {
11
+ public function __construct()
12
  {
13
  @set_time_limit(600);
14
  parent::__construct();
15
+ @include_once ABSPATH.'wp-admin/includes/file.php';
16
+ @include_once ABSPATH.'wp-admin/includes/plugin.php';
17
+ @include_once ABSPATH.'wp-admin/includes/theme.php';
18
+ @include_once ABSPATH.'wp-admin/includes/misc.php';
19
+ @include_once ABSPATH.'wp-admin/includes/template.php';
20
+ @include_once ABSPATH.'wp-admin/includes/class-wp-upgrader.php';
21
 
22
  global $wp_filesystem;
23
  if (!$wp_filesystem) {
25
  }
26
  }
27
 
28
+ public function mmb_maintenance_mode($enable = false, $maintenance_message = '')
29
  {
30
  global $wp_filesystem;
31
 
40
  }
41
  }
42
 
43
+ public function install_remote_files($params)
44
  {
45
  $data = array();
46
  foreach ($params['plugins'] as $theme) {
47
+ $dataTmp = $this->install_remote_file($theme);
48
+ $pluginName = key($dataTmp);
49
  $data[$pluginName] = $dataTmp;
50
  }
51
  foreach ($params['themes'] as $theme) {
52
+ $dataTmp = $this->install_remote_file($theme);
53
+ $themeName = key($dataTmp);
54
  $data[$themeName] = $dataTmp;
55
  }
56
 
57
  return $data;
58
  }
59
 
60
+ public function install_remote_file($params)
61
  {
62
  global $wp_filesystem;
63
  extract($params);
64
 
65
  if (!isset($package) || empty($package)) {
66
  return array(
67
+ 'error' => '<p>No files received. Internal error.</p>',
68
  );
69
  }
70
 
71
  if (!$this->is_server_writable()) {
72
  return array(
73
+ 'error' => 'Failed, please <a target="_blank" href="http://managewp.com/user-guide/faq/my-pluginsthemes-fail-to-update-or-i-receive-a-yellow-ftp-warning">add FTP details</a>',
74
  );
75
  }
76
 
77
  if (defined('WP_INSTALLING') && file_exists(ABSPATH.'.maintenance')) {
78
  return array(
79
+ 'error' => '<p>Site under maintanace.</p>',
80
  );
81
  }
82
 
83
  if (!class_exists('WP_Upgrader')) {
84
+ include_once ABSPATH.'wp-admin/includes/class-wp-upgrader.php';
85
  }
86
 
87
  $upgrader_skin = new WP_Upgrader_Skin();
99
  'destination' => $destination,
100
  'clear_destination' => $clear_destination, //Do not overwrite files.
101
  'clear_working' => true,
102
+ 'hook_extra' => array(),
103
  )
104
  );
105
  }
106
 
107
  if ($activate) {
108
  if ($type == 'plugins') {
109
+ include_once ABSPATH.'wp-admin/includes/plugin.php';
110
  $all_plugins = get_plugins();
111
  foreach ($all_plugins as $plugin_slug => $plugin) {
112
  $plugin_dir = preg_split('/\//', $plugin_slug);
122
  } else {
123
  if (count($install_info) == 1) {
124
  global $wp_themes;
125
+ include_once ABSPATH.'wp-includes/theme.php';
126
 
127
  $wp_themes = null;
128
  unset($wp_themes); //prevent theme data caching
162
  return $install_info;
163
  }
164
 
165
+ private function ithemes_updater_compatiblity()
166
  {
167
+ // Check for the iThemes updater class
168
+ if (empty($GLOBALS['ithemes_updater_path']) ||
169
+ !file_exists($GLOBALS['ithemes_updater_path'].'/settings.php')
170
+ ) {
171
+ return;
172
+ }
173
+
174
+ // Include iThemes updater
175
+ require_once $GLOBALS['ithemes_updater_path'].'/settings.php';
176
 
177
+ // Check if the updater is instantiated
178
+ if (empty($GLOBALS['ithemes-updater-settings'])) {
179
+ return;
180
+ }
181
+
182
+ // Update the download link
183
+ $GLOBALS['ithemes-updater-settings']->flush('forced');
184
+ }
185
 
186
+ public function do_upgrade($params = null)
187
+ {
188
  if ($params == null || empty($params)) {
189
  return array(
190
+ 'error' => 'No upgrades passed.',
191
  );
192
  }
193
 
194
  if (!$this->is_server_writable()) {
195
  return array(
196
+ 'error' => 'Failed, please <a target="_blank" href="http://managewp.com/user-guide/faq/my-pluginsthemes-fail-to-update-or-i-receive-a-yellow-ftp-warning">add FTP details</a>',
197
  );
198
  }
199
 
 
200
  $params = isset($params['upgrades_all']) ? $params['upgrades_all'] : $params;
201
 
202
  $core_upgrade = isset($params['wp_upgrade']) ? $params['wp_upgrade'] : array();
211
 
212
  if (!empty($upgrade_plugins)) {
213
  $plugin_files = array();
214
+ $this->ithemes_updater_compatiblity();
215
  foreach ($upgrade_plugins as $plugin) {
216
  if (isset($plugin['file'])) {
217
  $plugin_files[$plugin['file']] = $plugin['old_version'];
222
  if (!empty($plugin_files)) {
223
  $upgrades['plugins'] = $this->upgrade_plugins($plugin_files);
224
  }
225
+ $this->ithemes_updater_compatiblity();
226
  }
227
 
228
  if (!empty($upgrade_themes)) {
238
  if (!empty($theme_temps)) {
239
  $upgrades['themes'] = $this->upgrade_themes($theme_temps);
240
  }
 
241
  }
242
 
243
  if (!empty($premium_upgrades)) {
264
  * Upgrades WordPress locally
265
 
266
  */
267
+ public function upgrade_core($current)
268
  {
269
  ob_start();
270
 
271
  if (file_exists(ABSPATH.'/wp-admin/includes/update.php')) {
272
+ include_once ABSPATH.'/wp-admin/includes/update.php';
273
  }
274
 
275
  @wp_version_check();
284
  $updated = $core->updates[0];
285
  if (!isset($updated->response) || $updated->response == 'latest') {
286
  return array(
287
+ 'upgraded' => ' updated',
288
  );
289
  }
290
 
291
  if ($updated->response == "development" && $current['response'] == "upgrade") {
292
  return array(
293
+ 'error' => '<font color="#900">Unexpected error. Please upgrade manually.</font>',
294
  );
295
  } else {
296
  if ($updated->response == $current['response'] || ($updated->response == "upgrade" && $current['response'] == "development")) {
303
  }
304
  if ($current_update == false) {
305
  return array(
306
+ 'error' => ' Localization mismatch. Try again.',
307
  );
308
  }
309
  } else {
311
  }
312
  } else {
313
  return array(
314
+ 'error' => ' Transient mismatch. Try again.',
315
  );
316
  }
317
  }
318
  } else {
319
  return array(
320
+ 'error' => ' Refresh transient failed. Try again.',
321
  );
322
  }
323
  if ($current_update != false) {
325
 
326
  if (version_compare($wp_version, '3.1.9', '>')) {
327
  if (!class_exists('Core_Upgrader')) {
328
+ include_once ABSPATH.'wp-admin/includes/class-wp-upgrader.php';
329
  }
330
 
331
  $core = new Core_Upgrader();
333
  $this->mmb_maintenance_mode(false);
334
  if (is_wp_error($result)) {
335
  return array(
336
+ 'error' => $this->mmb_get_error($result),
337
  );
338
  } else {
339
  return array(
340
+ 'upgraded' => ' updated',
341
  );
342
  }
 
343
  } else {
344
  if (!class_exists('WP_Upgrader')) {
345
+ include_once ABSPATH.'wp-admin/includes/update.php';
346
  if (function_exists('wp_update_core')) {
347
  $result = wp_update_core($current_update);
348
  if (is_wp_error($result)) {
349
  return array(
350
+ 'error' => $this->mmb_get_error($result),
351
  );
352
  } else {
353
  return array(
354
+ 'upgraded' => ' updated',
355
  );
356
  }
357
  }
366
  // Is an update available?
367
  if (!isset($current_update->response) || $current_update->response == 'latest') {
368
  return array(
369
+ 'upgraded' => ' updated',
370
  );
371
  }
372
 
373
  $res = $upgrader->fs_connect(
374
  array(
375
  ABSPATH,
376
+ WP_CONTENT_DIR,
377
  )
378
  );
379
  if (is_wp_error($res)) {
380
  return array(
381
+ 'error' => $this->mmb_get_error($res),
382
  );
383
  }
384
 
394
  $download = $upgrader->download_package($core_package);
395
  if (is_wp_error($download)) {
396
  return array(
397
+ 'error' => $this->mmb_get_error($download),
398
  );
399
  }
400
 
401
  $working_dir = $upgrader->unpack_package($download);
402
  if (is_wp_error($working_dir)) {
403
  return array(
404
+ 'error' => $this->mmb_get_error($working_dir),
405
  );
406
  }
407
 
409
  $wp_filesystem->delete($working_dir, true);
410
 
411
  return array(
412
+ 'error' => 'Unable to move update files.',
413
  );
414
  }
415
 
416
  $wp_filesystem->chmod($wp_dir.'wp-admin/includes/update-core.php', FS_CHMOD_FILE);
417
 
418
+ require ABSPATH.'wp-admin/includes/update-core.php';
 
419
 
420
  $update_core = update_core($working_dir, $wp_dir);
421
  ob_end_clean();
423
  $this->mmb_maintenance_mode(false);
424
  if (is_wp_error($update_core)) {
425
  return array(
426
+ 'error' => $this->mmb_get_error($update_core),
427
  );
428
  }
429
  ob_end_flush();
430
 
431
  return array(
432
+ 'upgraded' => 'updated',
433
  );
434
  } else {
435
  return array(
436
+ 'error' => 'failed',
437
  );
438
  }
439
  }
440
  } else {
441
  return array(
442
+ 'error' => 'failed',
443
  );
444
  }
445
  }
446
 
447
+ public function upgrade_plugins($plugins = false)
448
  {
449
  if (!$plugins || empty($plugins)) {
450
  return array(
451
+ 'error' => 'No plugin files for upgrade.',
452
  );
453
  }
454
 
469
  $upgrader = new Plugin_Upgrader(new Bulk_Plugin_Upgrader_Skin(compact('nonce', 'url')));
470
  $result = $upgrader->bulk_upgrade(array_keys($plugins));
471
  if (!function_exists('wp_update_plugins')) {
472
+ include_once ABSPATH.'wp-includes/update.php';
473
  }
474
 
475
  @wp_update_plugins();
490
  ob_end_clean();
491
 
492
  return array(
493
+ 'upgraded' => $return,
494
  );
495
  } else {
496
  return array(
497
+ 'error' => 'Upgrade failed.',
498
  );
499
  }
500
  } else {
501
  ob_end_clean();
502
 
503
  return array(
504
+ 'error' => 'WordPress update required first.',
505
  );
506
  }
507
  }
508
 
509
+ public function upgrade_themes($themes = false)
510
  {
511
  if (!$themes || empty($themes)) {
512
  return array(
513
+ 'error' => 'No theme files for upgrade.',
514
  );
515
  }
516
 
528
  $result = $upgrader->bulk_upgrade($themes);
529
 
530
  if (!function_exists('wp_update_themes')) {
531
+ include_once ABSPATH.'wp-includes/update.php';
532
  }
533
 
534
  @wp_update_themes();
549
  }
550
 
551
  return array(
552
+ 'upgraded' => $return,
553
  );
554
  } else {
555
  return array(
556
+ 'error' => 'Upgrade failed.',
557
  );
558
  }
559
  } else {
560
  ob_end_clean();
561
 
562
  return array(
563
+ 'error' => 'WordPress update required first',
564
  );
565
  }
566
  }
567
 
568
+ public function upgrade_premium($premium = false)
569
  {
570
  global $mmb_plugin_url;
571
 
572
  if (!class_exists('WP_Upgrader')) {
573
+ include_once ABSPATH.'wp-admin/includes/class-wp-upgrader.php';
574
  }
575
 
576
  if (!$premium || empty($premium)) {
577
  return array(
578
+ 'error' => 'No premium files for upgrade.',
579
  );
580
  }
581
 
587
  $premium_update = array();
588
  $premium_update = apply_filters('mwp_premium_perform_update', $premium_update);
589
  if (!empty($premium_update)) {
 
590
  foreach ($premium as $pr) {
591
  foreach ($premium_update as $key => $update) {
592
  $update = array_change_key_case($update, CASE_LOWER);
593
  if ($update['name'] == $pr['name']) {
 
594
  // prepare bulk updates for premiums that use WordPress upgrader
595
  if (isset($update['type'])) {
596
  if ($update['type'] == 'plugin') {
660
  $upgrader_skin = new WP_Upgrader_Skin();
661
  $upgrader_skin->done_header = true;
662
  $upgrader = new WP_Upgrader();
663
+ @$update_result = $upgrader->run(
664
  array(
665
  'package' => $update['url'],
666
  'destination' => isset($update['type']) && $update['type'] == 'theme' ? WP_CONTENT_DIR.'/themes' : WP_PLUGIN_DIR,
667
  'clear_destination' => true,
668
  'clear_working' => true,
669
  'is_multi' => true,
670
+ 'hook_extra' => array(),
671
  )
672
  );
673
  $update_result = !$update_result || is_wp_error($update_result) ? $this->mmb_get_error($update_result) : 1;
 
674
  } else {
675
  if (isset($update['callback'])) {
676
  if (is_array($update['callback'])) {
703
  }
704
  }
705
 
706
+ public function get_upgradable_plugins($filter = array())
707
  {
708
  $current = $this->mmb_get_transient('update_plugins');
709
 
737
  }
738
  }
739
 
740
+ public function get_upgradable_themes($filter = array())
741
  {
742
  if (function_exists('wp_get_themes')) {
743
  $all_themes = wp_get_themes();
796
  }
797
  }
798
 
 
799
  return $upgrade_themes;
800
  }
801
 
802
+ public function get($args)
803
  {
804
  if (empty($args)) {
805
  return false;
818
  return $return;
819
  }
820
 
821
+ public function get_plugins($args)
822
  {
823
  if (empty($args)) {
824
  return false;
825
  }
826
 
827
  $search = $args['search'];
828
+ $type = trim((string) $args['type']);
829
 
830
  if (!function_exists('get_plugins')) {
831
+ include_once ABSPATH.'wp-admin/includes/plugin.php';
832
  }
833
  $all_plugins = get_plugins();
834
  $plugins = array(
835
  'active' => array(),
836
+ 'inactive' => array(),
837
  );
838
  if (is_array($all_plugins) && !empty($all_plugins)) {
839
  $activated_plugins = get_option('active_plugins');
848
  $plugin = array(
849
  'path' => $path,
850
  'name' => strip_tags($plugin['Name']),
851
+ 'version' => $plugin['Version'],
852
  );
853
 
854
  // If type is set, it must be equal to the current plugin status
861
 
862
  if ($typeMatches && $searchTermFound) {
863
  $plugins[$status][] = $plugin;
 
864
  }
865
  }
866
  }
869
  return $plugins;
870
  }
871
 
872
+ public function get_themes($args)
873
  {
874
  if (empty($args)) {
875
  return false;
878
  extract($args);
879
 
880
  if (!function_exists('wp_get_themes')) {
881
+ include_once ABSPATH.WPINC.'/theme.php';
882
  }
883
  if (function_exists('wp_get_themes')) {
884
  $all_themes = wp_get_themes();
885
  $themes = array(
886
  'active' => array(),
887
+ 'inactive' => array(),
888
  );
889
 
890
  if (is_array($all_themes) && !empty($all_themes)) {
908
  $themes['inactive'][$br_i]['stylesheet'] = $theme->Stylesheet;
909
  $br_i++;
910
  }
 
911
  }
912
 
913
  if ($search) {
928
  $all_themes = get_themes();
929
  $themes = array(
930
  'active' => array(),
931
+ 'inactive' => array(),
932
  );
933
 
934
  if (is_array($all_themes) && !empty($all_themes)) {
952
  $themes['inactive'][$br_i]['stylesheet'] = $theme['Stylesheet'];
953
  $br_i++;
954
  }
 
955
  }
956
 
957
  if ($search) {
968
  }
969
  }
970
  }
 
971
  }
972
 
973
  return $themes;
974
  }
975
 
976
+ public function edit($args)
977
  {
978
  extract($args);
979
  $return = array();
986
  return $return;
987
  }
988
 
989
+ public function edit_plugins($args)
990
  {
991
  extract($args);
992
  $return = array();
998
  case 'deactivate':
999
  $result = deactivate_plugins(
1000
  array(
1001
+ $item['path'],
1002
  )
1003
  );
1004
  break;
1005
  case 'delete':
1006
  $result = delete_plugins(
1007
  array(
1008
+ $item['path'],
1009
  )
1010
  );
1011
  break;
1015
 
1016
  if (is_wp_error($result)) {
1017
  $result = array(
1018
+ 'error' => $result->get_error_message(),
1019
  );
1020
  } elseif ($result === false) {
1021
  $result = array(
1022
+ 'error' => "Failed to perform action.",
1023
  );
1024
  } else {
1025
  $result = "OK";
1030
  return $return;
1031
  }
1032
 
1033
+ public function edit_themes($args)
1034
  {
1035
  extract($args);
1036
  $return = array();
1048
 
1049
  if (is_wp_error($result)) {
1050
  $result = array(
1051
+ 'error' => $result->get_error_message(),
1052
  );
1053
  } elseif ($result === false) {
1054
  $result = array(
1055
+ 'error' => "Failed to perform action.",
1056
  );
1057
  } else {
1058
  $result = "OK";
1061
  }
1062
 
1063
  return $return;
 
1064
  }
1065
  }
src/MMB/Link.php CHANGED
@@ -8,12 +8,12 @@
8
  **************************************************************/
9
  class MMB_Link extends MMB_Core
10
  {
11
- function __construct()
12
  {
13
  parent::__construct();
14
  }
15
 
16
- function add_link($args)
17
  {
18
  extract($args);
19
 
@@ -56,9 +56,8 @@ class MMB_Link extends MMB_Core
56
  $params['link_owner'] = $user_obj->ID;
57
  }
58
 
59
-
60
  if (!function_exists('wp_insert_link')) {
61
- include_once(ABSPATH.'wp-admin/includes/bookmark.php');
62
  }
63
 
64
  $is_success = wp_insert_link($params);
@@ -66,7 +65,7 @@ class MMB_Link extends MMB_Core
66
  return $is_success ? true : array('error' => 'Failed to add link.');
67
  }
68
 
69
- function remove_element($arr, $val)
70
  {
71
  foreach ($arr as $key => $value) {
72
  if ($value == $val) {
@@ -77,7 +76,7 @@ class MMB_Link extends MMB_Core
77
  return $arr = array_values($arr);
78
  }
79
 
80
- function get_links($args)
81
  {
82
  global $wpdb;
83
 
@@ -111,14 +110,14 @@ class MMB_Link extends MMB_Core
111
  "link_visible" => $link_info->link_visible,
112
  "link_rating" => $link_info->link_rating,
113
  "link_rel" => $link_info->link_rel,
114
- "link_cats" => $cats
115
  );
116
  }
117
 
118
  return array('links' => $links, 'total' => $total);
119
  }
120
 
121
- function getLinkCats($taxonomy = 'link_category')
122
  {
123
  global $wpdb;
124
 
@@ -132,14 +131,13 @@ INNER JOIN $wpdb->terms ON ( $wpdb->term_taxonomy.term_id = $wpdb->terms.term_id
132
  );
133
 
134
  foreach ($cats as $post_val) {
135
-
136
  $post_cats[$post_val->link_id][] = $post_val->name;
137
  }
138
 
139
  return $post_cats;
140
  }
141
 
142
- function delete_link($args)
143
  {
144
  global $wpdb;
145
 
@@ -153,7 +151,7 @@ INNER JOIN $wpdb->terms ON ( $wpdb->term_taxonomy.term_id = $wpdb->terms.term_id
153
  }
154
  }
155
 
156
- function delete_links($args)
157
  {
158
  global $wpdb;
159
  extract($args);
@@ -162,7 +160,6 @@ INNER JOIN $wpdb->terms ON ( $wpdb->term_taxonomy.term_id = $wpdb->terms.term_id
162
  $delete_query_intro = "DELETE FROM $wpdb->links WHERE link_id = ";
163
  }
164
  foreach ($args as $key => $val) {
165
-
166
  if (!empty($val) && is_numeric($val)) {
167
  $delete_query = $delete_query_intro.$val;
168
 
@@ -172,5 +169,4 @@ INNER JOIN $wpdb->terms ON ( $wpdb->term_taxonomy.term_id = $wpdb->terms.term_id
172
 
173
  return "Link deleted";
174
  }
175
-
176
  }
8
  **************************************************************/
9
  class MMB_Link extends MMB_Core
10
  {
11
+ public function __construct()
12
  {
13
  parent::__construct();
14
  }
15
 
16
+ public function add_link($args)
17
  {
18
  extract($args);
19
 
56
  $params['link_owner'] = $user_obj->ID;
57
  }
58
 
 
59
  if (!function_exists('wp_insert_link')) {
60
+ include_once ABSPATH.'wp-admin/includes/bookmark.php';
61
  }
62
 
63
  $is_success = wp_insert_link($params);
65
  return $is_success ? true : array('error' => 'Failed to add link.');
66
  }
67
 
68
+ public function remove_element($arr, $val)
69
  {
70
  foreach ($arr as $key => $value) {
71
  if ($value == $val) {
76
  return $arr = array_values($arr);
77
  }
78
 
79
+ public function get_links($args)
80
  {
81
  global $wpdb;
82
 
110
  "link_visible" => $link_info->link_visible,
111
  "link_rating" => $link_info->link_rating,
112
  "link_rel" => $link_info->link_rel,
113
+ "link_cats" => $cats,
114
  );
115
  }
116
 
117
  return array('links' => $links, 'total' => $total);
118
  }
119
 
120
+ public function getLinkCats($taxonomy = 'link_category')
121
  {
122
  global $wpdb;
123
 
131
  );
132
 
133
  foreach ($cats as $post_val) {
 
134
  $post_cats[$post_val->link_id][] = $post_val->name;
135
  }
136
 
137
  return $post_cats;
138
  }
139
 
140
+ public function delete_link($args)
141
  {
142
  global $wpdb;
143
 
151
  }
152
  }
153
 
154
+ public function delete_links($args)
155
  {
156
  global $wpdb;
157
  extract($args);
160
  $delete_query_intro = "DELETE FROM $wpdb->links WHERE link_id = ";
161
  }
162
  foreach ($args as $key => $val) {
 
163
  if (!empty($val) && is_numeric($val)) {
164
  $delete_query = $delete_query_intro.$val;
165
 
169
 
170
  return "Link deleted";
171
  }
 
172
  }
src/MMB/Post.php CHANGED
@@ -8,9 +8,8 @@
8
  **************************************************************/
9
  class MMB_Post extends MMB_Core
10
  {
11
- function create($args)
12
  {
13
-
14
  //$this->_log($args);
15
  global $wpdb;
16
 
@@ -45,14 +44,14 @@ class MMB_Post extends MMB_Core
45
  '+',
46
  '.',
47
  ':',
48
- '?'
49
  );
50
- $with = array(
51
  '\/',
52
  '\+',
53
  '\.',
54
  '\:',
55
- '\?'
56
  );
57
  $mwp_regexp_url = str_replace($rep, $with, $mwp_regexp_url);
58
 
@@ -74,7 +73,6 @@ class MMB_Post extends MMB_Core
74
  }
75
  }
76
 
77
-
78
  //to find all the images
79
  $match_count = preg_match_all('/(<a[^>]+href=\"([^"]+)\"[^>]*>)?(<\s*img.[^\/>]*src="([^"]+'.$mmb_regexp_url.'[^\s]+\.(jpg|jpeg|png|gif|bmp))"[^>]*>)/ixu', $post_data['post_content'], $get_urls, PREG_SET_ORDER);
80
  if ($match_count > 0) {
@@ -147,7 +145,7 @@ class MMB_Post extends MMB_Core
147
  'post_type' => 'attachment',
148
  //'post_parent' => $post_id,
149
  'post_mime_type' => 'image/'.$get_url[5],
150
- 'guid' => $attach_upload['url']
151
  );
152
 
153
  // Save the data
@@ -187,11 +185,9 @@ class MMB_Post extends MMB_Core
187
  }
188
  }
189
 
190
-
191
  $some_data = wp_generate_attachment_metadata($attach_id, $attach_upload['path']);
192
  wp_update_attachment_metadata($attach_id, $some_data);
193
 
194
-
195
  // changing href of a tag
196
  if ($get_url[1] != '') {
197
  $mmb_mp = '/'.str_replace($rep, $with, $get_url[2]).'/';
@@ -204,14 +200,11 @@ class MMB_Post extends MMB_Core
204
  @unlink($tmp_file);
205
 
206
  return array('error' => "Cannot create attachment file in ".$attach_upload['path']." Please set correct permissions.");
207
-
208
  }
209
  @unlink($tmp_file);
210
  }
211
 
212
-
213
  $post_data['post_content'] = $post_content;
214
-
215
  }
216
  if (count($post_atta_img)) {
217
  foreach ($post_atta_img as $img) {
@@ -238,7 +231,7 @@ class MMB_Post extends MMB_Core
238
  'post_type' => 'attachment',
239
  //'post_parent' => $post_id,
240
  'post_mime_type' => 'image/'.$atta_ext,
241
- 'guid' => $attach_upload['url']
242
  );
243
 
244
  // Save the data
@@ -260,7 +253,6 @@ class MMB_Post extends MMB_Core
260
  $attachments[$attach_id] = $attach_id;
261
  }
262
  }
263
-
264
  } else {
265
  @unlink($tmp_file);
266
 
@@ -281,8 +273,6 @@ class MMB_Post extends MMB_Core
281
  //check for edit post
282
  $post_result = 0;
283
  if (isset($post_data['mwp_post_edit']) && $post_data['mwp_post_edit']) {
284
-
285
-
286
  if ($post_data['mwp_match_by'] == 'title') {
287
  $match_by = "post_title = '".$post_data['post_title']."'";
288
  } else {
@@ -292,23 +282,20 @@ class MMB_Post extends MMB_Core
292
  $query = "SELECT ID FROM $wpdb->posts WHERE $match_by AND post_status NOT IN('inherit','auto-draft','draft') LIMIT 1";
293
 
294
  $post_result = $wpdb->get_var($query);
295
-
296
  }
297
 
298
-
299
  if ($post_result) {
300
  //update existing post
301
  $post_data['ID'] = $post_result;
302
  $post_id = wp_update_post($post_data);
303
 
304
  //check for previous attachments
305
- $atta_allimages =& get_children('post_type=attachment&post_parent='.$post_id);
306
  if (!empty($atta_allimages)) {
307
  foreach ($atta_allimages as $image) {
308
  wp_delete_attachment($image->ID);
309
  }
310
  }
311
-
312
  } else {
313
  if ($post_data['mwp_post_edit'] && $post_data['mwp_force_publish']) {
314
  $post_id = wp_insert_post($post_data);
@@ -317,7 +304,6 @@ class MMB_Post extends MMB_Core
317
  } else {
318
  $post_id = wp_insert_post($post_data);
319
  }
320
-
321
  }
322
 
323
  if (count($attachments)) {
@@ -325,12 +311,12 @@ class MMB_Post extends MMB_Core
325
  $result = wp_update_post(
326
  array(
327
  'ID' => $atta_id,
328
- 'post_parent' => $post_id
329
  )
330
  );
331
  if ($featured_id > 0) {
332
  $new_custom['_thumbnail_id'] = array(
333
- $featured_id
334
  );
335
  }
336
  }
@@ -358,14 +344,14 @@ class MMB_Post extends MMB_Core
358
  'post_type' => 'attachment',
359
  'post_parent' => $post_id,
360
  'post_mime_type' => 'image/'.$atta_ext,
361
- 'guid' => $attach_upload['url']
362
  );
363
 
364
  // Save the data
365
  $attach_id = wp_insert_attachment($attachment, $attach_upload['path']);
366
  wp_update_attachment_metadata($attach_id, wp_generate_attachment_metadata($attach_id, $attach_upload['path']));
367
  $new_custom['_thumbnail_id'] = array(
368
- $attach_id
369
  );
370
  } else {
371
  @unlink($tmp_file);
@@ -381,7 +367,6 @@ class MMB_Post extends MMB_Core
381
  $cat_ids = wp_create_categories($post_categories, $post_id);
382
  }
383
 
384
-
385
  //get current custom fields
386
  $cur_custom = get_post_custom($post_id);
387
  //check which values doesnot exists in new custom fields
@@ -404,10 +389,8 @@ class MMB_Post extends MMB_Core
404
  return $post_id;
405
  }
406
 
407
-
408
- function change_status($args)
409
  {
410
-
411
  global $wpdb;
412
  $post_id = $args['post_id'];
413
  $status = $args['status'];
@@ -416,9 +399,9 @@ class MMB_Post extends MMB_Core
416
  if (in_array($status, array('draft', 'publish', 'trash'))) {
417
  $edited_status = array(
418
  'ID' => $post_id,
419
- 'post_status' => $status
420
  );
421
- $success = wp_update_post($edited_status);
422
  }
423
 
424
  return $success;
@@ -444,7 +427,7 @@ class MMB_Post extends MMB_Core
444
  * @arg string mwp_get_posts_trash on or off
445
  * @return array posts related to args
446
  */
447
- function get_posts($args)
448
  {
449
  global $wpdb;
450
 
@@ -491,7 +474,6 @@ class MMB_Post extends MMB_Core
491
  $total['total_num'] = count($posts_info);
492
 
493
  foreach ($posts_info as $post_info) {
494
-
495
  $cats = array();
496
  foreach ($post_cats[$post_info->ID] as $cat_array => $cat_array_val) {
497
  $cats[] = array('name' => $cat_array_val);
@@ -509,17 +491,17 @@ class MMB_Post extends MMB_Core
509
  'post_title' => htmlspecialchars($post_info->post_title),
510
  'post_name' => $post_info->post_name,
511
  'post_author' => array('author_id' => $post_info->post_author, 'author_name' => $user_info[$post_info->post_author]),
512
- 'post_date' => $post_info->post_date,
513
- 'post_modified' => $post_info->post_modified,
514
- 'post_status' => $post_info->post_status,
515
- 'post_type' => $post_info->post_type,
516
- 'guid' => $post_info->guid,
517
- 'post_password' => $post_info->post_password,
518
- 'ping_status' => $post_info->ping_status,
519
- 'comment_status' => $post_info->comment_status,
520
- 'comment_count' => $post_info->comment_count,
521
- 'cats' => $cats,
522
- 'tags' => $tags,
523
 
524
  );
525
  }
@@ -527,16 +509,16 @@ class MMB_Post extends MMB_Core
527
  return array('posts' => $posts, 'total' => $total);
528
  }
529
 
530
- function delete_post($args)
531
  {
532
  if (!empty($args['post_id']) && !empty($args['action'])) {
533
  if ($args['action'] == 'delete' || $args['action'] == 'delete_restore') {
534
  $action = ($args['action'] == 'delete') ? 'trash' : 'publish';
535
  $edited_status = array(
536
  'ID' => $args['post_id'],
537
- 'post_status' => $action
538
  );
539
- $success = wp_update_post($edited_status);
540
  } else {
541
  if ($args['action'] == 'delete_perm') {
542
  $success = wp_delete_post($args['post_id'], true);
@@ -549,7 +531,7 @@ class MMB_Post extends MMB_Core
549
  }
550
  }
551
 
552
- function delete_posts($args)
553
  {
554
  extract($args);
555
  if ($deleteaction == 'trash' || $deleteaction == 'draft' || $deleteaction == 'publish') {
@@ -557,9 +539,9 @@ class MMB_Post extends MMB_Core
557
  if (!empty($val) && is_numeric($val)) {
558
  $edited_status = array(
559
  'ID' => $val,
560
- 'post_status' => $deleteaction
561
  );
562
- $success = wp_update_post($edited_status);
563
  }
564
  }
565
  } elseif ($deleteaction == 'delete') {
@@ -571,7 +553,6 @@ class MMB_Post extends MMB_Core
571
  }
572
 
573
  return "Post deleted";
574
-
575
  }
576
 
577
  /**
@@ -594,7 +575,7 @@ class MMB_Post extends MMB_Core
594
  * @arg string mwp_get_pages_trash on or off
595
  * @return array pages related to args
596
  */
597
- function get_pages($args)
598
  {
599
  global $wpdb;
600
 
@@ -638,21 +619,20 @@ class MMB_Post extends MMB_Core
638
  $total['total_num'] = count($posts_info);
639
 
640
  foreach ($posts_info as $post_info) {
641
-
642
  $posts[] = array(
643
  'post_id' => $post_info->ID,
644
  'post_title' => htmlspecialchars($post_info->post_title),
645
  'post_name' => $post_info->post_name,
646
  'post_author' => array('author_id' => $post_info->post_author, 'author_name' => $user_info[$post_info->post_author]),
647
- 'post_date' => $post_info->post_date,
648
- 'post_modified' => $post_info->post_modified,
649
- 'post_status' => $post_info->post_status,
650
- 'post_type' => $post_info->post_type,
651
- 'guid' => $post_info->guid,
652
- 'post_password' => $post_info-
8
  **************************************************************/
9
  class MMB_Post extends MMB_Core
10
  {
11
+ public function create($args)
12
  {
 
13
  //$this->_log($args);
14
  global $wpdb;
15
 
44
  '+',
45
  '.',
46
  ':',
47
+ '?',
48
  );
49
+ $with = array(
50
  '\/',
51
  '\+',
52
  '\.',
53
  '\:',
54
+ '\?',
55
  );
56
  $mwp_regexp_url = str_replace($rep, $with, $mwp_regexp_url);
57
 
73
  }
74
  }
75
 
 
76
  //to find all the images
77
  $match_count = preg_match_all('/(<a[^>]+href=\"([^"]+)\"[^>]*>)?(<\s*img.[^\/>]*src="([^"]+'.$mmb_regexp_url.'[^\s]+\.(jpg|jpeg|png|gif|bmp))"[^>]*>)/ixu', $post_data['post_content'], $get_urls, PREG_SET_ORDER);
78
  if ($match_count > 0) {
145
  'post_type' => 'attachment',
146
  //'post_parent' => $post_id,
147
  'post_mime_type' => 'image/'.$get_url[5],
148
+ 'guid' => $attach_upload['url'],
149
  );
150
 
151
  // Save the data
185
  }
186
  }
187
 
 
188
  $some_data = wp_generate_attachment_metadata($attach_id, $attach_upload['path']);
189
  wp_update_attachment_metadata($attach_id, $some_data);
190
 
 
191
  // changing href of a tag
192
  if ($get_url[1] != '') {
193
  $mmb_mp = '/'.str_replace($rep, $with, $get_url[2]).'/';
200
  @unlink($tmp_file);
201
 
202
  return array('error' => "Cannot create attachment file in ".$attach_upload['path']." Please set correct permissions.");
 
203
  }
204
  @unlink($tmp_file);
205
  }
206
 
 
207
  $post_data['post_content'] = $post_content;
 
208
  }
209
  if (count($post_atta_img)) {
210
  foreach ($post_atta_img as $img) {
231
  'post_type' => 'attachment',
232
  //'post_parent' => $post_id,
233
  'post_mime_type' => 'image/'.$atta_ext,
234
+ 'guid' => $attach_upload['url'],
235
  );
236
 
237
  // Save the data
253
  $attachments[$attach_id] = $attach_id;
254
  }
255
  }
 
256
  } else {
257
  @unlink($tmp_file);
258
 
273
  //check for edit post
274
  $post_result = 0;
275
  if (isset($post_data['mwp_post_edit']) && $post_data['mwp_post_edit']) {
 
 
276
  if ($post_data['mwp_match_by'] == 'title') {
277
  $match_by = "post_title = '".$post_data['post_title']."'";
278
  } else {
282
  $query = "SELECT ID FROM $wpdb->posts WHERE $match_by AND post_status NOT IN('inherit','auto-draft','draft') LIMIT 1";
283
 
284
  $post_result = $wpdb->get_var($query);
 
285
  }
286
 
 
287
  if ($post_result) {
288
  //update existing post
289
  $post_data['ID'] = $post_result;
290
  $post_id = wp_update_post($post_data);
291
 
292
  //check for previous attachments
293
+ $atta_allimages = & get_children('post_type=attachment&post_parent='.$post_id);
294
  if (!empty($atta_allimages)) {
295
  foreach ($atta_allimages as $image) {
296
  wp_delete_attachment($image->ID);
297
  }
298
  }
 
299
  } else {
300
  if ($post_data['mwp_post_edit'] && $post_data['mwp_force_publish']) {
301
  $post_id = wp_insert_post($post_data);
304
  } else {
305
  $post_id = wp_insert_post($post_data);
306
  }
 
307
  }
308
 
309
  if (count($attachments)) {
311
  $result = wp_update_post(
312
  array(
313
  'ID' => $atta_id,
314
+ 'post_parent' => $post_id,
315
  )
316
  );
317
  if ($featured_id > 0) {
318
  $new_custom['_thumbnail_id'] = array(
319
+ $featured_id,
320
  );
321
  }
322
  }
344
  'post_type' => 'attachment',
345
  'post_parent' => $post_id,
346
  'post_mime_type' => 'image/'.$atta_ext,
347
+ 'guid' => $attach_upload['url'],
348
  );
349
 
350
  // Save the data
351
  $attach_id = wp_insert_attachment($attachment, $attach_upload['path']);
352
  wp_update_attachment_metadata($attach_id, wp_generate_attachment_metadata($attach_id, $attach_upload['path']));
353
  $new_custom['_thumbnail_id'] = array(
354
+ $attach_id,
355
  );
356
  } else {
357
  @unlink($tmp_file);
367
  $cat_ids = wp_create_categories($post_categories, $post_id);
368
  }
369
 
 
370
  //get current custom fields
371
  $cur_custom = get_post_custom($post_id);
372
  //check which values doesnot exists in new custom fields
389
  return $post_id;
390
  }
391
 
392
+ public function change_status($args)
 
393
  {
 
394
  global $wpdb;
395
  $post_id = $args['post_id'];
396
  $status = $args['status'];
399
  if (in_array($status, array('draft', 'publish', 'trash'))) {
400
  $edited_status = array(
401
  'ID' => $post_id,
402
+ 'post_status' => $status,
403
  );
404
+ $success = wp_update_post($edited_status);
405
  }
406
 
407
  return $success;
427
  * @arg string mwp_get_posts_trash on or off
428
  * @return array posts related to args
429
  */
430
+ public function get_posts($args)
431
  {
432
  global $wpdb;
433
 
474
  $total['total_num'] = count($posts_info);
475
 
476
  foreach ($posts_info as $post_info) {
 
477
  $cats = array();
478
  foreach ($post_cats[$post_info->ID] as $cat_array => $cat_array_val) {
479
  $cats[] = array('name' => $cat_array_val);
491
  'post_title' => htmlspecialchars($post_info->post_title),
492
  'post_name' => $post_info->post_name,
493
  'post_author' => array('author_id' => $post_info->post_author, 'author_name' => $user_info[$post_info->post_author]),
494
+ 'post_date' => $post_info->post_date,
495
+ 'post_modified' => $post_info->post_modified,
496
+ 'post_status' => $post_info->post_status,
497
+ 'post_type' => $post_info->post_type,
498
+ 'guid' => $post_info->guid,
499
+ 'post_password' => $post_info->post_password,
500
+ 'ping_status' => $post_info->ping_status,
501
+ 'comment_status' => $post_info->comment_status,
502
+ 'comment_count' => $post_info->comment_count,
503
+ 'cats' => $cats,
504
+ 'tags' => $tags,
505
 
506
  );
507
  }
509
  return array('posts' => $posts, 'total' => $total);
510
  }
511
 
512
+ public function delete_post($args)
513
  {
514
  if (!empty($args['post_id']) && !empty($args['action'])) {
515
  if ($args['action'] == 'delete' || $args['action'] == 'delete_restore') {
516
  $action = ($args['action'] == 'delete') ? 'trash' : 'publish';
517
  $edited_status = array(
518
  'ID' => $args['post_id'],
519
+ 'post_status' => $action,
520
  );
521
+ $success = wp_update_post($edited_status);
522
  } else {
523
  if ($args['action'] == 'delete_perm') {
524
  $success = wp_delete_post($args['post_id'], true);
531
  }
532
  }
533
 
534
+ public function delete_posts($args)
535
  {
536
  extract($args);
537
  if ($deleteaction == 'trash' || $deleteaction == 'draft' || $deleteaction == 'publish') {
539
  if (!empty($val) && is_numeric($val)) {
540
  $edited_status = array(
541
  'ID' => $val,
542
+ 'post_status' => $deleteaction,
543
  );
544
+ $success = wp_update_post($edited_status);
545
  }
546
  }
547
  } elseif ($deleteaction == 'delete') {
553
  }
554
 
555
  return "Post deleted";
 
556
  }
557
 
558
  /**
575
  * @arg string mwp_get_pages_trash on or off
576
  * @return array pages related to args
577
  */
578
+ public function get_pages($args)
579
  {
580
  global $wpdb;
581
 
619
  $total['total_num'] = count($posts_info);
620
 
621
  foreach ($posts_info as $post_info) {
 
622
  $posts[] = array(
623
  'post_id' => $post_info->ID,
624
  'post_title' => htmlspecialchars($post_info->post_title),
625
  'post_name' => $post_info->post_name,
626
  'post_author' => array('author_id' => $post_info->post_author, 'author_name' => $user_info[$post_info->post_author]),