ManageWP Worker - Version 3.9.17

Version Description

  • New: Add your favorite sites to the Favorites bar (just drag&drop them to the small heart on the top)
  • New: Entirely new website menu loaded with features and tools
  • New: Manage Posts and Pages across all sites in a more efficient way
  • New: Support for all WPMU.org premium plugin updates
  • New: Complete Dropbox integration through Oauth which allows us to restore/delete Dropbox backups directly
  • New: We have the user guide as PDF now. Download
Download this release

Release Info

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

Code changes from version 3.9.16 to 3.9.17

Files changed (20) hide show
  1. api.php +40 -40
  2. backup.class.php +2185 -2131
  3. comment.class.php +42 -42
  4. core.class.php +664 -659
  5. helper.class.php +498 -498
  6. init.php +899 -829
  7. installer.class.php +867 -867
  8. lib/dropbox.oauth.php +1133 -1133
  9. lib/dropbox.php +144 -144
  10. lib/s3.php +1966 -1965
  11. link.class.php +60 -60
  12. plugins/cleanup/cleanup.php +188 -188
  13. plugins/extra_html_example/extra_html_example.php +17 -17
  14. plugins/search/search.php +129 -129
  15. post.class.php +616 -377
  16. readme.txt +228 -218
  17. stats.class.php +763 -763
  18. user.class.php +212 -212
  19. version +1 -1
  20. widget.class.php +51 -51
api.php CHANGED
@@ -1,41 +1,41 @@
1
- <?php
2
- /*************************************************************
3
- *
4
- * api.php
5
- *
6
- * ManageWP addons api
7
- *
8
- * Copyright (c) 2011 Prelovac Media
9
- * www.prelovac.com
10
- **************************************************************/
11
- if( !function_exists('mmb_add_action')) :
12
- function mmb_add_action($action = false, $callback = false)
13
- {
14
- if (!$action || !$callback)
15
- return false;
16
-
17
- global $mmb_actions;
18
- mmb_function_exists($callback);
19
-
20
- if (isset($mmb_actions[$action]))
21
- wp_die('Cannot redeclare ManageWP action "' . $action . '".');
22
-
23
- $mmb_actions[$action] = $callback;
24
- }
25
- endif;
26
-
27
- if( !function_exists('mmb_function_exists') ) :
28
- function mmb_function_exists($callback)
29
- {
30
- global $mwp_core;
31
- if (count($callback) === 2) {
32
- if (!method_exists($callback[0], $callback[1]))
33
- wp_die($mwp_core->mwp_dashboard_widget('Information', '', '<p>Class ' . get_class($callback[0]) . ' does not contain <b>"' . $callback[1] . '"</b> function</p>', '', '50%'));
34
- } else {
35
- if (!function_exists($callback))
36
- wp_die($mwp_core->mwp_dashboard_widget('Information', '', '<p>Function <b>"' . $callback . '"</b> does not exists.</p>', '', '50%'));
37
- }
38
- }
39
- endif;
40
-
41
  ?>
1
+ <?php
2
+ /*************************************************************
3
+ *
4
+ * api.php
5
+ *
6
+ * ManageWP addons api
7
+ *
8
+ * Copyright (c) 2011 Prelovac Media
9
+ * www.prelovac.com
10
+ **************************************************************/
11
+ if( !function_exists('mmb_add_action')) :
12
+ function mmb_add_action($action = false, $callback = false)
13
+ {
14
+ if (!$action || !$callback)
15
+ return false;
16
+
17
+ global $mmb_actions;
18
+ mmb_function_exists($callback);
19
+
20
+ if (isset($mmb_actions[$action]))
21
+ wp_die('Cannot redeclare ManageWP action "' . $action . '".');
22
+
23
+ $mmb_actions[$action] = $callback;
24
+ }
25
+ endif;
26
+
27
+ if( !function_exists('mmb_function_exists') ) :
28
+ function mmb_function_exists($callback)
29
+ {
30
+ global $mwp_core;
31
+ if (count($callback) === 2) {
32
+ if (!method_exists($callback[0], $callback[1]))
33
+ wp_die($mwp_core->mwp_dashboard_widget('Information', '', '<p>Class ' . get_class($callback[0]) . ' does not contain <b>"' . $callback[1] . '"</b> function</p>', '', '50%'));
34
+ } else {
35
+ if (!function_exists($callback))
36
+ wp_die($mwp_core->mwp_dashboard_widget('Information', '', '<p>Function <b>"' . $callback . '"</b> does not exists.</p>', '', '50%'));
37
+ }
38
+ }
39
+ endif;
40
+
41
  ?>
backup.class.php CHANGED
@@ -1,2132 +1,2186 @@
1
- <?php
2
- /*************************************************************
3
- *
4
- * backup.class.php
5
- *
6
- * Manage Backups
7
- *
8
- *
9
- * Copyright (c) 2011 Prelovac Media
10
- * www.prelovac.com
11
- **************************************************************/
12
- define('MWP_BACKUP_DIR', WP_CONTENT_DIR . '/managewp/backups');
13
- define('MWP_DB_DIR', MWP_BACKUP_DIR . '/mwp_db');
14
-
15
- $zip_errors = array(
16
- 'No error',
17
- 'No error',
18
- 'Unexpected end of zip file',
19
- 'A generic error in the zipfile format was detected.',
20
- 'zip was unable to allocate itself memory',
21
- 'A severe error in the zipfile format was detected',
22
- 'Entry too large to be split with zipsplit',
23
- 'Invalid comment format',
24
- 'zip -T failed or out of memory',
25
- 'The user aborted zip prematurely',
26
- 'zip encountered an error while using a temp file',
27
- 'Read or seek error',
28
- 'zip has nothing to do',
29
- 'Missing or empty zip file',
30
- 'Error writing to a file',
31
- 'zip was unable to create a file to write to',
32
- 'bad command line parameters',
33
- 'no error',
34
- 'zip could not open a specified file to read'
35
- );
36
- $unzip_errors = array(
37
- 'No error',
38
- 'One or more warning errors were encountered, but processing completed successfully anyway',
39
- 'A generic error in the zipfile format was detected',
40
- 'A severe error in the zipfile format was detected.',
41
- 'unzip was unable to allocate itself memory.',
42
- 'unzip was unable to allocate memory, or encountered an encryption error',
43
- 'unzip was unable to allocate memory during decompression to disk',
44
- 'unzip was unable allocate memory during in-memory decompression',
45
- 'unused',
46
- 'The specified zipfiles were not found',
47
- 'Bad command line parameters',
48
- 'No matching files were found',
49
- 50 => 'The disk is (or was) full during extraction',
50
- 51 => 'The end of the ZIP archive was encountered prematurely.',
51
- 80 => 'The user aborted unzip prematurely.',
52
- 81 => 'Testing or extraction of one or more files failed due to unsupported compression methods or unsupported decryption.',
53
- 82 => 'No files were found due to bad decryption password(s)'
54
- );
55
-
56
-
57
- class MMB_Backup extends MMB_Core
58
- {
59
- var $site_name;
60
- var $statuses;
61
- var $tasks;
62
- var $s3;
63
- var $ftp;
64
- var $dropbox;
65
- function __construct()
66
- {
67
- parent::__construct();
68
- $this->site_name = str_replace(array(
69
- "_",
70
- "/"
71
- ), array(
72
- "",
73
- "-"
74
- ), rtrim($this->remove_http(get_bloginfo('url')), "/"));
75
- $this->statuses = array(
76
- 'db_dump' => 1,
77
- 'db_zip' => 2,
78
- 'files_zip' => 3,
79
- 's3' => 4,
80
- 'dropbox' => 5,
81
- 'ftp' => 6,
82
- 'email' => 7,
83
- 'finished' => 100
84
- );
85
- $this->tasks = get_option('mwp_backup_tasks');
86
- }
87
-
88
- function get_backup_settings()
89
- {
90
- $backup_settings = get_option('mwp_backup_tasks');
91
- if (!empty($backup_settings))
92
- return $backup_settings;
93
- else
94
- return false;
95
- }
96
-
97
- function set_backup_task($params)
98
- {
99
- //$params => [$task_name, $args, $error]
100
- if (!empty($params)) {
101
-
102
- //Make sure backup cron job is set
103
- if (!wp_next_scheduled('mwp_backup_tasks')) {
104
- wp_schedule_event( time(), 'tenminutes', 'mwp_backup_tasks' );
105
- }
106
-
107
- extract($params);
108
-
109
- //$before = $this->get_backup_settings();
110
- $before = $this->tasks;
111
- if (!$before || empty($before))
112
- $before = array();
113
-
114
- if (isset($args['remove'])) {
115
- unset($before[$task_name]);
116
- $return = array(
117
- 'removed' => true
118
- );
119
- } else {
120
- if (is_array($params['account_info'])) { //only if sends from master first time(secure data)
121
- $args['account_info'] = $account_info;
122
- }
123
-
124
- $before[$task_name]['task_args'] = $args;
125
- if (strlen($args['schedule']))
126
- $before[$task_name]['task_args']['next'] = $this->schedule_next($args['type'], $args['schedule']);
127
-
128
- $return = $before[$task_name];
129
- }
130
-
131
- //Update with error
132
- if ($error) {
133
- if (is_array($error)) {
134
- $before[$task_name]['task_results'][count($before[$task_name]['task_results']) - 1]['error'] = $error['error'];
135
- } else {
136
- $before[$task_name]['task_results'][count($before[$task_name]['task_results'])]['error'] = $error;
137
- }
138
- }
139
-
140
- if ($time) { //set next result time before backup
141
- if (is_array($before[$task_name]['task_results'])) {
142
- $before[$task_name]['task_results'] = array_values($before[$task_name]['task_results']);
143
- }
144
- $before[$task_name]['task_results'][count($before[$task_name]['task_results'])]['time'] = $time;
145
- }
146
-
147
- $this->update_tasks($before);
148
- //update_option('mwp_backup_tasks', $before);
149
-
150
- if ($task_name == 'Backup Now') {
151
- $result = $this->backup($args, $task_name);
152
- $backup_settings = $this->tasks;
153
-
154
- if (is_array($result) && array_key_exists('error', $result)) {
155
- $return = $result;
156
- } else {
157
- $return = $backup_settings[$task_name];
158
- }
159
- }
160
- return $return;
161
- }
162
-
163
-
164
-
165
- return false;
166
- }
167
-
168
- //Cron check
169
- function check_backup_tasks()
170
- {
171
-
172
- $this->check_cron_remove();
173
-
174
- $settings = $this->tasks;
175
- if (is_array($settings) && !empty($settings)) {
176
- foreach ($settings as $task_name => $setting) {
177
- if ($setting['task_args']['next'] && $setting['task_args']['next'] < time()) {
178
- //if ($setting['task_args']['next'] && $_GET['force_backup']) {
179
- if ($setting['task_args']['url'] && $setting['task_args']['task_id'] && $setting['task_args']['site_key']) {
180
- //Check orphan task
181
- $check_data = array(
182
- 'task_name' => $task_name,
183
- 'task_id' => $setting['task_args']['task_id'],
184
- 'site_key' => $setting['task_args']['site_key']
185
- );
186
-
187
- $check = $this->validate_task($check_data, $setting['task_args']['url']);
188
-
189
- }
190
-
191
- $update = array(
192
- 'task_name' => $task_name,
193
- 'args' => $settings[$task_name]['task_args']
194
- );
195
-
196
-
197
- if($check != 'paused'){
198
- $update['time'] = time();
199
- }
200
-
201
- //Update task with next schedule
202
- $this->set_backup_task($update);
203
-
204
- if($check == 'paused'){
205
- continue;
206
- }
207
-
208
-
209
- $result = $this->backup($setting['task_args'], $task_name);
210
- $error = '';
211
- if (is_array($result) && array_key_exists('error', $result)) {
212
- $error = $result;
213
- $this->set_backup_task(array(
214
- 'task_name' => $task_name,
215
- 'args' => $settings[$task_name]['task_args'],
216
- 'error' => $error
217
- ));
218
- } else {
219
- $error = '';
220
- }
221
- break; //Only one backup per cron
222
- }
223
- }
224
- }
225
-
226
- }
227
-
228
- function task_now($task_name){
229
-
230
- $settings = $this->tasks;
231
- if(!array_key_exists($task_name,$settings)){
232
- return array('error' => $task_name." does not exist.");
233
- } else {
234
- $setting = $settings[$task_name];
235
- }
236
-
237
- $this->set_backup_task(array(
238
- 'task_name' => $task_name,
239
- 'args' => $settings[$task_name]['task_args'],
240
- 'time' => time()
241
- ));
242
-
243
- //Run backup
244
- $result = $this->backup($setting['task_args'], $task_name);
245
-
246
- //Check for error
247
- if (is_array($result) && array_key_exists('error', $result)) {
248
- $this->set_backup_task(array(
249
- 'task_name' => $task_name,
250
- 'args' => $settings[$task_name]['task_args'],
251
- 'error' => $result
252
- ));
253
- return $result;
254
- } else {
255
- return $this->get_backup_stats();
256
- }
257
-
258
- }
259
-
260
-
261
-
262
- /*
263
- * If Task Name not set then it's manual backup
264
- * Backup args:
265
- * type -> db, full
266
- * what -> daily, weekly, monthly
267
- * account_info -> ftp, amazons3, dropbox
268
- * exclude-> array of paths to exclude from backup
269
- */
270
-
271
- function backup($args, $task_name = false)
272
- {
273
- if (!$args || empty($args))
274
- return false;
275
-
276
- extract($args); //extract settings
277
-
278
- //Try increase memory limit and execution time
279
- @ini_set('memory_limit', '256M');
280
- @set_time_limit(600); //ten minutes
281
-
282
- //Remove old backup(s)
283
- $this->remove_old_backups($task_name);
284
-
285
- $new_file_path = MWP_BACKUP_DIR;
286
-
287
- if (!file_exists($new_file_path)) {
288
- if (!mkdir($new_file_path, 0755, true))
289
- return array(
290
- 'error' => 'Permission denied, make sure you have write permission to wp-content folder.'
291
- );
292
- }
293
-
294
- @file_put_contents($new_file_path . '/index.php', ''); //safe
295
-
296
- //Prepare .zip file name
297
- $hash = md5(time());
298
- $label = $type ? $type : 'manual';
299
- $backup_file = $new_file_path . '/' . $this->site_name . '_' . $label . '_' . $what . '_' . date('Y-m-d') . '_' . $hash . '.zip';
300
- $backup_url = WP_CONTENT_URL . '/managewp/backups/' . $this->site_name . '_' . $label . '_' . $what . '_' . date('Y-m-d') . '_' . $hash . '.zip';
301
-
302
- //Optimize tables?
303
- if (isset($optimize_tables) && !empty($optimize_tables)) {
304
- $this->optimize_tables();
305
- }
306
-
307
- //What to backup - db or full?
308
- if (trim($what) == 'db') {
309
- //Take database backup
310
- $this->update_status($task_name, $this->statuses['db_dump']);
311
- $db_result = $this->backup_db();
312
- if ($db_result == false) {
313
- return array(
314
- 'error' => 'Failed to backup database.'
315
- );
316
- } else if (is_array($db_result) && isset($db_result['error'])) {
317
- return array(
318
- 'error' => $db_result['error']
319
- );
320
- } else {
321
- $this->update_status($task_name, $this->statuses['db_dump'], true);
322
- $this->update_status($task_name, $this->statuses['db_zip']);
323
-
324
- $disable_comp = $this->tasks[$task_name]['task_args']['disable_comp'];
325
- $comp_level = $disable_comp ? '-0' : '-1';
326
-
327
- chdir(MWP_BACKUP_DIR);
328
- $zip = $this->get_zip();
329
- $command = "$zip -q -r $comp_level $backup_file 'mwp_db'";
330
- ob_start();
331
- $result = $this->mmb_exec($command);
332
- ob_get_clean();
333
- if (!$result) { // fallback to pclzip
334
- define('PCLZIP_TEMPORARY_DIR', MWP_BACKUP_DIR . '/');
335
- require_once ABSPATH . '/wp-admin/includes/class-pclzip.php';
336
- $archive = new PclZip($backup_file);
337
- if ($disable_comp) {
338
- $result = $archive->add($db_result, PCLZIP_OPT_REMOVE_PATH, MWP_BACKUP_DIR, PCLZIP_OPT_NO_COMPRESSION);
339
- } else {
340
- $result = $archive->add($db_result, PCLZIP_OPT_REMOVE_PATH, MWP_BACKUP_DIR);
341
- }
342
- @unlink($db_result);
343
- @rmdir(MWP_DB_DIR);
344
- if (!$result) {
345
- return array(
346
- 'error' => 'Failed to zip database (pclZip - ' . $archive->error_code . '): .' . $archive->error_string
347
- );
348
- }
349
- }
350
-
351
- @unlink($db_result);
352
- @rmdir(MWP_DB_DIR);
353
- if (!$result) {
354
- return array(
355
- 'error' => 'Failed to zip database.'
356
- );
357
- }
358
- $this->update_status($task_name, $this->statuses['db_zip'], true);
359
- }
360
- } elseif (trim($what) == 'full') {
361
- $content_backup = $this->backup_full($task_name, $backup_file, $exclude, $include);
362
- if (is_array($content_backup) && array_key_exists('error', $content_backup)) {
363
- return array(
364
- 'error' => $content_backup['error']
365
- );
366
- }
367
- }
368
-
369
- //Update backup info
370
- if ($task_name) {
371
- //backup task (scheduled)
372
- $backup_settings = $this->tasks;
373
- $paths = array();
374
- $size = ceil(filesize($backup_file) / 1024);
375
-
376
- if ($size > 1000) {
377
- $paths['size'] = ceil($size / 1024) . "Mb";
378
- } else {
379
- $paths['size'] = $size . 'kb';
380
- }
381
-
382
- if ($task_name != 'Backup Now') {
383
- if (!$backup_settings[$task_name]['task_args']['del_host_file']) {
384
- $paths['server'] = array(
385
- 'file_path' => $backup_file,
386
- 'file_url' => $backup_url
387
- );
388
- }
389
- } else {
390
- $paths['server'] = array(
391
- 'file_path' => $backup_file,
392
- 'file_url' => $backup_url
393
- );
394
- }
395
-
396
- if (isset($backup_settings[$task_name]['task_args']['account_info']['mwp_ftp'])) {
397
- $paths['ftp'] = basename($backup_url);
398
- }
399
-
400
- if (isset($backup_settings[$task_name]['task_args']['account_info']['mwp_amazon_s3'])) {
401
- $paths['amazons3'] = basename($backup_url);
402
- }
403
-
404
- if (isset($backup_settings[$task_name]['task_args']['account_info']['mwp_dropbox'])) {
405
- $paths['dropbox'] = basename($backup_url);
406
- }
407
-
408
- if (isset($backup_settings[$task_name]['task_args']['account_info']['mwp_email'])) {
409
- $paths['email'] = basename($backup_url);
410
- }
411
-
412
- $temp = $backup_settings[$task_name]['task_results'];
413
- $temp = array_values($temp);
414
- $paths['time'] = time();
415
-
416
- if ($task_name != 'Backup Now') {
417
- $paths['status'] = $temp[count($temp) - 1]['status'];
418
- $temp[count($temp) - 1] = $paths;
419
-
420
- } else {
421
- $temp[count($temp)] = $paths;
422
- }
423
-
424
- $backup_settings[$task_name]['task_results'] = $temp;
425
- $this->update_tasks($backup_settings);
426
- //update_option('mwp_backup_tasks', $backup_settings);
427
- }
428
-
429
-
430
- //Additional: Email, ftp, amazon_s3, dropbox...
431
-
432
- if ($task_name != 'Backup Now') {
433
- if (isset($account_info['mwp_ftp']) && !empty($account_info['mwp_ftp'])) {
434
- $this->update_status($task_name, $this->statuses['ftp']);
435
- $account_info['mwp_ftp']['backup_file'] = $backup_file;
436
- $ftp_result = $this->ftp_backup($account_info['mwp_ftp']);
437
-
438
- if ($ftp_result !== true && $del_host_file) {
439
- @unlink($backup_file);
440
- }
441
-
442
- if (is_array($ftp_result) && isset($ftp_result['error'])) {
443
- return $ftp_result;
444
- }
445
- $this->wpdb_reconnect();
446
- $this->update_status($task_name, $this->statuses['ftp'], true);
447
- }
448
-
449
- if (isset($account_info['mwp_amazon_s3']) && !empty($account_info['mwp_amazon_s3'])) {
450
- $this->update_status($task_name, $this->statuses['s3']);
451
- $account_info['mwp_amazon_s3']['backup_file'] = $backup_file;
452
- $amazons3_result = $this->amazons3_backup($account_info['mwp_amazon_s3']);
453
- if ($amazons3_result !== true && $del_host_file) {
454
- @unlink($backup_file);
455
- }
456
- if (is_array($amazons3_result) && isset($amazons3_result['error'])) {
457
- return $amazons3_result;
458
- }
459
- $this->wpdb_reconnect();
460
- $this->update_status($task_name, $this->statuses['s3'], true);
461
- }
462
-
463
- if (isset($account_info['mwp_dropbox']) && !empty($account_info['mwp_dropbox'])) {
464
- $this->update_status($task_name, $this->statuses['dropbox']);
465
- $account_info['mwp_dropbox']['backup_file'] = $backup_file;
466
- $dropbox_result = $this->dropbox_backup($account_info['mwp_dropbox']);
467
- if ($dropbox_result !== true && $del_host_file) {
468
- @unlink($backup_file);
469
- }
470
-
471
- if (is_array($dropbox_result) && isset($dropbox_result['error'])) {
472
- return $dropbox_result;
473
- }
474
- $this->wpdb_reconnect();
475
- $this->update_status($task_name, $this->statuses['dropbox'], true);
476
- }
477
-
478
- if (isset($account_info['mwp_email']) && !empty($account_info['mwp_email'])) {
479
- $this->update_status($task_name, $this->statuses['email']);
480
- $account_info['mwp_email']['task_name'] = $task_name;
481
- $account_info['mwp_email']['file_path'] = $backup_file;
482
-
483
- $email_result = $this->email_backup($account_info['mwp_email']);
484
- if (is_array($email_result) && isset($email_result['error'])) {
485
- return $email_result;
486
- }
487
- $this->update_status($task_name, $this->statuses['email'], true);
488
- }
489
-
490
- if ($del_host_file) {
491
- @unlink($backup_file);
492
- }
493
-
494
- } //end additional
495
-
496
- //$this->update_status($task_name,$this->statuses['finished'],true);
497
- return $backup_url; //Return url to backup file
498
- }
499
-
500
- function backup_full($task_name, $backup_file, $exclude = array(), $include = array())
501
- {
502
- global $zip_errors;
503
- $sys = substr(PHP_OS, 0, 3);
504
-
505
- $this->update_status($task_name, $this->statuses['db_dump']);
506
- $db_result = $this->backup_db();
507
-
508
- if ($db_result == false) {
509
- return array(
510
- 'error' => 'Failed to backup database.'
511
- );
512
- } else if (is_array($db_result) && isset($db_result['error'])) {
513
- return array(
514
- 'error' => $db_result['error']
515
- );
516
- }
517
-
518
- $this->update_status($task_name, $this->statuses['db_dump'], true);
519
- $this->update_status($task_name, $this->statuses['db_zip']);
520
- $disable_comp = $this->tasks[$task_name]['task_args']['disable_comp'];
521
- $comp_level = $disable_comp ? '-0' : '-1';
522
-
523
- $zip = $this->get_zip();
524
- //Add database file
525
- chdir(MWP_BACKUP_DIR);
526
- $command = "$zip -q -r $comp_level $backup_file 'mwp_db'";
527
- ob_start();
528
- $result = $this->mmb_exec($command);
529
- ob_get_clean();
530
-
531
-
532
- if (!$result) {
533
- define('PCLZIP_TEMPORARY_DIR', MWP_BACKUP_DIR . '/');
534
- require_once ABSPATH . '/wp-admin/includes/class-pclzip.php';
535
- $archive = new PclZip($backup_file);
536
-
537
- if ($disable_comp) {
538
- $result_db = $archive->add($db_result, PCLZIP_OPT_REMOVE_PATH, MWP_BACKUP_DIR, PCLZIP_OPT_NO_COMPRESSION);
539
- } else {
540
- $result_db = $archive->add($db_result, PCLZIP_OPT_REMOVE_PATH, MWP_BACKUP_DIR);
541
- }
542
-
543
- @unlink($db_result);
544
- @rmdir(MWP_DB_DIR);
545
-
546
- if (!$result_db) {
547
- return array(
548
- 'error' => 'Failed to zip database. pclZip error (' . $archive->error_code . '): .' . $archive->error_string
549
- );
550
- }
551
- }
552
-
553
- @unlink($db_result);
554
- @rmdir(MWP_DB_DIR);
555
-
556
- $this->update_status($task_name, $this->statuses['db_zip'], true);
557
-
558
-
559
- //Always remove backup folders
560
- $remove = array(
561
- trim(basename(WP_CONTENT_DIR)) . "/managewp/backups",
562
- trim(basename(WP_CONTENT_DIR)) . "/" . md5('mmb-worker') . "/mwp_backups"
563
- );
564
-
565
- //Exclude paths
566
- $exclude_data = "-x";
567
-
568
- if (!empty($exclude)) {
569
- foreach ($exclude as $data) {
570
- if (is_dir(ABSPATH . $data)) {
571
- if ($sys == 'WIN')
572
- $exclude_data .= " $data/*.*";
573
- else
574
- $exclude_data .= " '$data/*'";
575
- } else {
576
- if ($sys == 'WIN')
577
- $exclude_data .= " $data";
578
- else
579
- $exclude_data .= " '$data'";
580
- }
581
- }
582
- }
583
-
584
- foreach ($remove as $data) {
585
- if ($sys == 'WIN')
586
- $exclude_data .= " $data/*.*";
587
- else
588
- $exclude_data .= " '$data/*'";
589
- }
590
-
591
- //Include paths by default
592
- $add = array(
593
- trim(WPINC),
594
- trim(basename(WP_CONTENT_DIR)),
595
- "wp-admin"
596
- );
597
-
598
- $include_data = ". -i";
599
- foreach ($add as $data) {
600
- if ($sys == 'WIN')
601
- $include_data .= " $data/*.*";
602
- else
603
- $include_data .= " '$data/*'";
604
- }
605
-
606
- //Additional includes?
607
- if (!empty($include)) {
608
- foreach ($include as $data) {
609
- if ($data) {
610
- if ($sys == 'WIN')
611
- $include_data .= " $data/*.*";
612
- else
613
- $include_data .= " '$data/*'";
614
- }
615
- }
616
- }
617
-
618
- $this->update_status($task_name, $this->statuses['files_zip']);
619
- chdir(ABSPATH);
620
- ob_start();
621
- $command = "$zip -q -j $comp_level $backup_file .* * $exclude_data";
622
- $result_f = $this->mmb_exec($command, false, true);
623
- if (!$result_f || $result_f == 18) { // disregard permissions error, file can't be accessed
624
- $command = "$zip -q -r $comp_level $backup_file $include_data $exclude_data";
625
- $result_d = $this->mmb_exec($command, false, true);
626
- if ($result_d && $result_d != 18) {
627
- @unlink($backup_file);
628
- if ($result_d > 0 && $result_d < 18)
629
- return array(
630
- 'error' => 'Failed to archive files (' . $zip_errors[$result_d] . ') .'
631
- );
632
- else
633
- return array(
634
- 'error' => 'Failed to archive files.'
635
- );
636
- }
637
- }
638
- ob_get_clean();
639
-
640
- if ($result_f && $result_f != 18) { //Try pclZip
641
-
642
- if (!isset($archive)) {
643
- define('PCLZIP_TEMPORARY_DIR', MWP_BACKUP_DIR . '/');
644
- require_once ABSPATH . '/wp-admin/includes/class-pclzip.php';
645
- $archive = new PclZip($backup_file);
646
- }
647
-
648
- //Include paths
649
- $include_data = array();
650
- if (!empty($include)) {
651
- foreach ($include as $data) {
652
- if ($data && file_exists(ABSPATH . $data))
653
- $include_data[] = ABSPATH . $data . '/';
654
- }
655
- }
656
-
657
- foreach ($add as $data) {
658
- if (file_exists(ABSPATH . $data))
659
- $include_data[] = ABSPATH . $data . '/';
660
- }
661
-
662
- //Include root files
663
- if ($handle = opendir(ABSPATH)) {
664
- while (false !== ($file = readdir($handle))) {
665
- if ($file != "." && $file != ".." && !is_dir($file) && file_exists(ABSPATH . $file)) {
666
- $include_data[] = ABSPATH . $file;
667
- }
668
- }
669
- closedir($handle);
670
- }
671
-
672
- if ($disable_comp) {
673
- $result = $archive->add($include_data, PCLZIP_OPT_REMOVE_PATH, ABSPATH, PCLZIP_OPT_NO_COMPRESSION);
674
- } else {
675
- $result = $archive->add($include_data, PCLZIP_OPT_REMOVE_PATH, ABSPATH);
676
- }
677
- if (!$result) {
678
- @unlink($backup_file);
679
- return array(
680
- 'error' => 'Failed to zip files. pclZip error (' . $archive->error_code . '): .' . $archive->error_string
681
- );
682
- }
683
-
684
- //Now exclude paths
685
- $exclude_data = array();
686
- if (!empty($exclude)) {
687
- foreach ($exclude as $data) {
688
- if (is_dir(ABSPATH . $data))
689
- $exclude_data[] = $data . '/';
690
- else
691
- $exclude_data[] = $data;
692
- }
693
- }
694
-
695
- foreach ($remove as $rem) {
696
- $exclude_data[] = $rem . '/';
697
- }
698
-
699
- $result_excl = $archive->delete(PCLZIP_OPT_BY_NAME, $exclude_data);
700
- if (!$result_excl) {
701
- @unlink($backup_file);
702
- return array(
703
- 'error' => 'Failed to zip files. pclZip error (' . $archive->error_code . '): .' . $archive->error_string
704
- );
705
- }
706
-
707
- }
708
-
709
- //Reconnect
710
- $this->wpdb_reconnect();
711
-
712
- $this->update_status($task_name, $this->statuses['files_zip'], true);
713
- return true;
714
- }
715
-
716
-
717
- function backup_db()
718
- {
719
- $db_folder = MWP_DB_DIR . '/';
720
- if (!file_exists($db_folder)) {
721
- if (!mkdir($db_folder, 0755, true))
722
- return array(
723
- 'error' => 'Error creating database backup folder (' . $db_folder . '). Make sure you have corrrect write permissions.'
724
- );
725
- }
726
-
727
- $file = $db_folder . DB_NAME . '.sql';
728
- $result = $this->backup_db_dump($file); // try mysqldump always then fallback to php dump
729
- return $result;
730
- }
731
-
732
- function backup_db_dump($file)
733
- {
734
- global $wpdb;
735
- $paths = $this->check_mysql_paths();
736
- $brace = (substr(PHP_OS, 0, 3) == 'WIN') ? '"' : '';
737
- $command = $brace . $paths['mysqldump'] . $brace . ' --force --host="' . DB_HOST . '" --user="' . DB_USER . '" --password="' . DB_PASSWORD . '" --add-drop-table --skip-lock-tables "' . DB_NAME . '" > ' . $brace . $file . $brace;
738
- ob_start();
739
- $result = $this->mmb_exec($command);
740
- ob_get_clean();
741
-
742
- if (!$result) { // Fallback to php
743
- $result = $this->backup_db_php($file);
744
- return $result;
745
- }
746
-
747
- if (filesize($file) == 0 || !is_file($file) || !$result) {
748
- @unlink($file);
749
- return false;
750
- } else {
751
- return $file;
752
- }
753
- }
754
-
755
- function backup_db_php($file)
756
- {
757
- global $wpdb;
758
- $tables = $wpdb->get_results('SHOW TABLES', ARRAY_N);
759
- foreach ($tables as $table) {
760
- //drop existing table
761
- $dump_data = "DROP TABLE IF EXISTS $table[0];";
762
- //create table
763
- $create_table = $wpdb->get_row("SHOW CREATE TABLE $table[0]", ARRAY_N);
764
- $dump_data .= "\n\n" . $create_table[1] . ";\n\n";
765
-
766
- $count = $wpdb->get_var("SELECT count(*) FROM $table[0]");
767
- if ($count > 100)
768
- $count = ceil($count / 100);
769
- else if ($count > 0)
770
- $count = 1;
771
-
772
- for ($i = 0; $i < $count; $i++) {
773
- $low_limit = $i * 100;
774
- $qry = "SELECT * FROM $table[0] LIMIT $low_limit, 100";
775
- $rows = $wpdb->get_results($qry, ARRAY_A);
776
- if (is_array($rows)) {
777
- foreach ($rows as $row) {
778
- //insert single row
779
- $dump_data .= "INSERT INTO $table[0] VALUES(";
780
- $num_values = count($row);
781
- $j = 1;
782
- foreach ($row as $value) {
783
- $value = addslashes($value);
784
- $value = preg_replace("/\n/Ui", "\\n", $value);
785
- $num_values == $j ? $dump_data .= "'" . $value . "'" : $dump_data .= "'" . $value . "', ";
786
- $j++;
787
- unset($value);
788
- }
789
- $dump_data .= ");\n";
790
- }
791
- }
792
- }
793
- $dump_data .= "\n\n\n";
794
-
795
- unset($rows);
796
- file_put_contents($file, $dump_data, FILE_APPEND);
797
- unset($dump_data);
798
- }
799
-
800
- if (filesize($file) == 0 || !is_file($file)) {
801
- @unlink($file);
802
- return array(
803
- 'error' => 'Database backup failed. Try to enable MySQL dump on your server.'
804
- );
805
- }
806
-
807
- return $file;
808
-
809
- }
810
-
811
- function restore($args)
812
- {
813
- global $wpdb;
814
- if (empty($args)) {
815
- return false;
816
- }
817
-
818
- extract($args);
819
- @ini_set('memory_limit', '256M');
820
- @set_time_limit(600);
821
-
822
- $unlink_file = true; //Delete file after restore
823
-
824
- //Detect source
825
- if ($backup_url) {
826
- //This is for clone (overwrite)
827
- include_once ABSPATH . 'wp-admin/includes/file.php';
828
- $backup_file = download_url($backup_url);
829
- if (is_wp_error($backup_file)) {
830
- return array(
831
- 'error' => 'Unable to download backup file ('.$backup_file->get_error_message().')'
832
- );
833
- }
834
- $what = 'full';
835
- } else {
836
- $tasks = $this->tasks;
837
- $task = $tasks[$task_name];
838
- if (isset($task['task_results'][$result_id]['server'])) {
839
- $backup_file = $task['task_results'][$result_id]['server']['file_path'];
840
- $unlink_file = false; //Don't delete file if stored on server
841
- } elseif (isset($task['task_results'][$result_id]['ftp'])) {
842
- $ftp_file = $task['task_results'][$result_id]['ftp'];
843
- $args = $task['task_args']['account_info']['mwp_ftp'];
844
- $args['backup_file'] = $ftp_file;
845
- $backup_file = $this->get_ftp_backup($args);
846
- if ($backup_file == false) {
847
- return array(
848
- 'error' => 'Failed to download file from FTP.'
849
- );
850
- }
851
- } elseif (isset($task['task_results'][$result_id]['amazons3'])) {
852
- $amazons3_file = $task['task_results'][$result_id]['amazons3'];
853
- $args = $task['task_args']['account_info']['mwp_amazon_s3'];
854
- $args['backup_file'] = $amazons3_file;
855
- $backup_file = $this->get_amazons3_backup($args);
856
- if ($backup_file == false) {
857
- return array(
858
- 'error' => 'Failed to download file from Amazon S3.'
859
- );
860
- }
861
- } elseif(isset($task['task_results'][$result_id]['dropbox'])){
862
- $dropbox_file = $task['task_results'][$result_id]['dropbox'];
863
- $args = $task['task_args']['account_info']['mwp_dropbox'];
864
- $args['backup_file'] = $dropbox_file;
865
- $backup_file = $this->get_dropbox_backup($args);
866
-
867
- if ($backup_file == false) {
868
- return array(
869
- 'error' => 'Failed to download file from Dropbox.'
870
- );
871
- }
872
- }
873
-
874
- $what = $tasks[$task_name]['task_args']['what'];
875
- }
876
-
877
- if ($backup_file && file_exists($backup_file)) {
878
- if ($overwrite) {
879
- //Keep old db credentials before overwrite
880
- if (!copy(ABSPATH . 'wp-config.php', ABSPATH . 'mwp-temp-wp-config.php')) {
881
- @unlink($backup_file);
882
- return array(
883
- 'error' => 'Error creating wp-config. Please check your write permissions.'
884
- );
885
- }
886
-
887
- $db_host = DB_HOST;
888
- $db_user = DB_USER;
889
- $db_password = DB_PASSWORD;
890
- $home = rtrim(get_option('home'), "/");
891
- $site_url = get_option('site_url');
892
-
893
- $clone_options = array();
894
- if (trim($clone_from_url) || trim($mwp_clone)) {
895
-
896
- $clone_options['_worker_nossl_key'] = get_option('_worker_nossl_key');
897
- $clone_options['_worker_public_key'] = get_option('_worker_public_key');
898
- $clone_options['_action_message_id'] = get_option('_action_message_id');
899
-
900
- }
901
-
902
- $clone_options['mwp_backup_tasks'] = serialize(get_option('mwp_backup_tasks'));
903
- $clone_options['mwp_notifications'] = serialize(get_option('mwp_notifications'));
904
- $clone_options['mwp_pageview_alerts'] = serialize(get_option('mwp_pageview_alerts'));
905
-
906
-
907
- } else {
908
- $restore_options = array();
909
- $restore_options['mwp_notifications'] = get_option('mwp_notifications');
910
- $restore_options['mwp_pageview_alerts'] = get_option('mwp_pageview_alerts');
911
- $restore_options['user_hit_count'] = get_option('user_hit_count');
912
- }
913
-
914
-
915
- chdir(ABSPATH);
916
- $unzip = $this->get_unzip();
917
- $command = "$unzip -o $backup_file";
918
- ob_start();
919
- $result = $this->mmb_exec($command);
920
- ob_get_clean();
921
-
922
- if (!$result) { //fallback to pclzip
923
- define('PCLZIP_TEMPORARY_DIR', MWP_BACKUP_DIR . '/');
924
- require_once ABSPATH . '/wp-admin/includes/class-pclzip.php';
925
- $archive = new PclZip($backup_file);
926
- $result = $archive->extract(PCLZIP_OPT_PATH, ABSPATH, PCLZIP_OPT_REPLACE_NEWER);
927
- }
928
-
929
- if ($unlink_file) {
930
- @unlink($backup_file);
931
- }
932
-
933
- if (!$result) {
934
- return array(
935
- 'error' => 'Failed to unzip files. pclZip error (' . $archive->error_code . '): .' . $archive->error_string
936
- );
937
- }
938
-
939
- $db_result = $this->restore_db();
940
-
941
- if (!$db_result) {
942
- return array(
943
- 'error' => 'Error restoring database.'
944
- );
945
- } else if(is_array($db_result) && isset($db_result['error'])){
946
- return array(
947
- 'error' => $db_result['error']
948
- );
949
- }
950
-
951
- } else {
952
- return array(
953
- 'error' => 'Error restoring. Cannot find backup file.'
954
- );
955
- }
956
-
957
- //Replace options and content urls
958
- if ($overwrite) {
959
- //Get New Table prefix
960
- $new_table_prefix = trim($this->get_table_prefix());
961
- //Retrieve old wp_config
962
- @unlink(ABSPATH . 'wp-config.php');
963
- //Replace table prefix
964
- $lines = file(ABSPATH . 'mwp-temp-wp-config.php');
965
-
966
- foreach ($lines as $line) {
967
- if (strstr($line, '$table_prefix')) {
968
- $line = '$table_prefix = "' . $new_table_prefix . '";' . PHP_EOL;
969
- }
970
- file_put_contents(ABSPATH . 'wp-config.php', $line, FILE_APPEND);
971
- }
972
-
973
- @unlink(ABSPATH . 'mwp-temp-wp-config.php');
974
-
975
- //Replace options
976
- $query = "SELECT option_value FROM " . $new_table_prefix . "options WHERE option_name = 'home'";
977
- $old = $wpdb->get_var($wpdb->prepare($query));
978
- $old = rtrim($old, "/");
979
- $query = "UPDATE " . $new_table_prefix . "options SET option_value = '$home' WHERE option_name = 'home'";
980
- $wpdb->query($wpdb->prepare($query));
981
- $query = "UPDATE " . $new_table_prefix . "options SET option_value = '$home' WHERE option_name = 'siteurl'";
982
- $wpdb->query($wpdb->prepare($query));
983
- //Replace content urls
984
- $query = "UPDATE " . $new_table_prefix . "posts SET post_content = REPLACE (post_content, '$old','$home') WHERE post_content REGEXP 'src=\"(.*)$old(.*)\"' OR post_content REGEXP 'href=\"(.*)$old(.*)\"'";
985
- $wpdb->query($wpdb->prepare($query));
986
-
987
- if (trim($new_password)) {
988
- $new_password = wp_hash_password($new_password);
989
- }
990
- if (!trim($clone_from_url) && !trim($mwp_clone)) {
991
- if ($new_user && $new_password) {
992
- $query = "UPDATE " . $new_table_prefix . "users SET user_login = '$new_user', user_pass = '$new_password' WHERE user_login = '$old_user'";
993
- $wpdb->query($wpdb->prepare($query));
994
- }
995
- } else {
996
- if ($clone_from_url) {
997
- if ($new_user && $new_password) {
998
- $query = "UPDATE " . $new_table_prefix . "users SET user_pass = '$new_password' WHERE user_login = '$new_user'";
999
- $wpdb->query($wpdb->prepare($query));
1000
- }
1001
- }
1002
-
1003
- if ($mwp_clone) {
1004
- if ($admin_email) {
1005
- //Clean Install
1006
- $query = "UPDATE " . $new_table_prefix . "options SET option_value = '$admin_email' WHERE option_name = 'admin_email'";
1007
- $wpdb->query($wpdb->prepare($query));
1008
- $query = "SELECT * FROM " . $new_table_prefix . "users LIMIT 1";
1009
- $temp_user = $wpdb->get_row($query);
1010
- if (!empty($temp_user)) {
1011
- $query = "UPDATE " . $new_table_prefix . "users SET user_email='$admin_email', user_login = '$new_user', user_pass = '$new_password' WHERE user_login = '$temp_user->user_login'";
1012
- $wpdb->query($wpdb->prepare($query));
1013
- }
1014
-
1015
- }
1016
- }
1017
- }
1018
-
1019
- if (is_array($clone_options) && !empty($clone_options)) {
1020
- foreach ($clone_options as $key => $option) {
1021
- if (!empty($key)) {
1022
- $query = "SELECT option_value FROM " . $new_table_prefix . "options WHERE option_name = '$key'";
1023
- $res = $wpdb->get_var($query);
1024
- if ($res == false) {
1025
- $query = "INSERT INTO " . $new_table_prefix . "options (option_value,option_name) VALUES('$option','$key')";
1026
- $wpdb->query($wpdb->prepare($query));
1027
- } else {
1028
- $query = "UPDATE " . $new_table_prefix . "options SET option_value = '$option' WHERE option_name = '$key'";
1029
- $wpdb->query($wpdb->prepare($query));
1030
- }
1031
- }
1032
- }
1033
- }
1034
-
1035
- //Remove hit count
1036
- $query = "DELETE FROM " . $new_table_prefix . "options WHERE option_name = 'user_hit_count'";
1037
- $wpdb->query($wpdb->prepare($query));
1038
-
1039
- //Check for .htaccess permalinks update
1040
- $this->replace_htaccess($home);
1041
- } else {
1042
-
1043
- //restore worker options
1044
- if (is_array($restore_options) && !empty($restore_options)) {
1045
- foreach ($restore_options as $key => $option) {
1046
- update_option($key,$option);
1047
- }
1048
- }
1049
-
1050
- }
1051
-
1052
-
1053
-
1054
-
1055
- return true;
1056
- }
1057
-
1058
- function restore_db()
1059
- {
1060
- global $wpdb;
1061
- $paths = $this->check_mysql_paths();
1062
- $file_path = ABSPATH . 'mwp_db';
1063
- @chmod($file_path,0755);
1064
- $file_name = glob($file_path . '/*.sql');
1065
- $file_name = $file_name[0];
1066
-
1067
- if(!$file_name){
1068
- return array('error' => 'Cannot access database file.');
1069
- }
1070
-
1071
- $brace = (substr(PHP_OS, 0, 3) == 'WIN') ? '"' : '';
1072
- $command = $brace . $paths['mysql'] . $brace . ' --host="' . DB_HOST . '" --user="' . DB_USER . '" --password="' . DB_PASSWORD . '" ' . DB_NAME . ' < ' . $brace . $file_name . $brace;
1073
-
1074
- ob_start();
1075
- $result = $this->mmb_exec($command);
1076
- ob_get_clean();
1077
- if (!$result) {
1078
- //try php
1079
- $this->restore_db_php($file_name);
1080
- }
1081
-
1082
-
1083
- @unlink($file_name);
1084
- return true;
1085
- }
1086
-
1087
- function restore_db_php($file_name)
1088
- {
1089
- global $wpdb;
1090
- $current_query = '';
1091
- // Read in entire file
1092
- $lines = file($file_name);
1093
- // Loop through each line
1094
- foreach ($lines as $line) {
1095
- // Skip it if it's a comment
1096
- if (substr($line, 0, 2) == '--' || $line == '')
1097
- continue;
1098
-
1099
- // Add this line to the current query
1100
- $current_query .= $line;
1101
- // If it has a semicolon at the end, it's the end of the query
1102
- if (substr(trim($line), -1, 1) == ';') {
1103
- // Perform the query
1104
- $result = $wpdb->query($current_query);
1105
- if ($result === false)
1106
- return false;
1107
- // Reset temp variable to empty
1108
- $current_query = '';
1109
- }
1110
- }
1111
-
1112
- @unlink($file_name);
1113
- return true;
1114
- }
1115
-
1116
- function get_table_prefix()
1117
- {
1118
- $lines = file(ABSPATH . 'wp-config.php');
1119
- foreach ($lines as $line) {
1120
- if (strstr($line, '$table_prefix')) {
1121
- $pattern = "/(\'|\")[^(\'|\")]*/";
1122
- preg_match($pattern, $line, $matches);
1123
- $prefix = substr($matches[0], 1);
1124
- return $prefix;
1125
- break;
1126
- }
1127
- }
1128
- return 'wp_'; //default
1129
- }
1130
-
1131
- function optimize_tables()
1132
- {
1133
- global $wpdb;
1134
- $query = 'SHOW TABLE STATUS FROM ' . DB_NAME;
1135
- $tables = $wpdb->get_results($wpdb->prepare($query), ARRAY_A);
1136
- foreach ($tables as $table) {
1137
- if (in_array($table['Engine'], array(
1138
- 'MyISAM',
1139
- 'ISAM',
1140
- 'HEAP',
1141
- 'MEMORY',
1142
- 'ARCHIVE'
1143
- )))
1144
- $table_string .= $table['Name'] . ",";
1145
- elseif ($table['Engine'] == 'InnoDB') {
1146
- $optimize = $wpdb->query("ALTER TABLE {$table['Name']} ENGINE=InnoDB");
1147
- }
1148
- }
1149
-
1150
- $table_string = rtrim($table_string);
1151
- $optimize = $wpdb->query("OPTIMIZE TABLE $table_string");
1152
-
1153
- return $optimize ? true : false;
1154
- }
1155
-
1156
- ### Function: Auto Detect MYSQL and MYSQL Dump Paths
1157
- function check_mysql_paths()
1158
- {
1159
- global $wpdb;
1160
- $paths = array(
1161
- 'mysql' => '',
1162
- 'mysqldump' => ''
1163
- );
1164
- if (substr(PHP_OS, 0, 3) == 'WIN') {
1165
- $mysql_install = $wpdb->get_row("SHOW VARIABLES LIKE 'basedir'");
1166
- if ($mysql_install) {
1167
- $install_path = str_replace('\\', '/', $mysql_install->Value);
1168
- $paths['mysql'] = $install_path . 'bin/mysql.exe';
1169
- $paths['mysqldump'] = $install_path . 'bin/mysqldump.exe';
1170
- } else {
1171
- $paths['mysql'] = 'mysql.exe';
1172
- $paths['mysqldump'] = 'mysqldump.exe';
1173
- }
1174
- } else {
1175
- $paths['mysql'] = $this->mmb_exec('which mysql', true);
1176
- if (empty($paths['mysql']))
1177
- $paths['mysql'] = 'mysql'; // try anyway
1178
-
1179
- $paths['mysqldump'] = $this->mmb_exec('which mysqldump', true);
1180
- if (empty($paths['mysqldump']))
1181
- $paths['mysqldump'] = 'mysqldump'; // try anyway
1182
-
1183
- }
1184
-
1185
-
1186
- return $paths;
1187
- }
1188
-
1189
- //Check if exec, system, passthru functions exist
1190
- function check_sys()
1191
- {
1192
- if ($this->mmb_function_exists('exec'))
1193
- return 'exec';
1194
-
1195
- if ($this->mmb_function_exists('system'))
1196
- return 'system';
1197
-
1198
- if ($this->mmb_function_exists('passhtru'))
1199
- return 'passthru';
1200
-
1201
- return false;
1202
-
1203
- }
1204
-
1205
- function mmb_exec($command, $string = false, $rawreturn = false)
1206
- {
1207
- if ($command == '')
1208
- return false;
1209
-
1210
- if ($this->mmb_function_exists('exec')) {
1211
- $log = @exec($command, $output, $return);
1212
-
1213
- if ($string)
1214
- return $log;
1215
- if ($rawreturn)
1216
- return $return;
1217
-
1218
- return $return ? false : true;
1219
- } elseif ($this->mmb_function_exists('system')) {
1220
- $log = @system($command, $return);
1221
-
1222
- if ($string)
1223
- return $log;
1224
-
1225
- if ($rawreturn)
1226
- return $return;
1227
-
1228
- return $return ? false : true;
1229
- } elseif ($this->mmb_function_exists('passthru') && !$string) {
1230
- $log = passthru($command, $return);
1231
-
1232
- if ($rawreturn)
1233
- return $return;
1234
-
1235
- return $return ? false : true;
1236
- }
1237
-
1238
- if ($rawreturn)
1239
- return -1;
1240
-
1241
- return false;
1242
- }
1243
-
1244
- function get_zip()
1245
- {
1246
- $zip = $this->mmb_exec('which zip', true);
1247
- if (!$zip)
1248
- $zip = "zip";
1249
- return $zip;
1250
- }
1251
-
1252
- function get_unzip()
1253
- {
1254
- $unzip = $this->mmb_exec('which unzip', true);
1255
- if (!$unzip)
1256
- $unzip = "unzip";
1257
- return $unzip;
1258
- }
1259
-
1260
- function check_backup_compat()
1261
- {
1262
- $reqs = array();
1263
- if (strpos($_SERVER['DOCUMENT_ROOT'], '/') === 0) {
1264
- $reqs['Server OS']['status'] = 'Linux (or compatible)';
1265
- $reqs['Server OS']['pass'] = true;
1266
- } else {
1267
- $reqs['Server OS']['status'] = 'Windows';
1268
- $reqs['Server OS']['pass'] = true;
1269
- $pass = false;
1270
- }
1271
- $reqs['PHP Version']['status'] = phpversion();
1272
- if ((float) phpversion() >= 5.1) {
1273
- $reqs['PHP Version']['pass'] = true;
1274
- } else {
1275
- $reqs['PHP Version']['pass'] = false;
1276
- $pass = false;
1277
- }
1278
-
1279
-
1280
- if (is_writable(WP_CONTENT_DIR)) {
1281
- $reqs['Backup Folder']['status'] = "writable";
1282
- $reqs['Backup Folder']['pass'] = true;
1283
- } else {
1284
- $reqs['Backup Folder']['status'] = "not writable";
1285
- $reqs['Backup Folder']['pass'] = false;
1286
- }
1287
-
1288
-
1289
- $file_path = MWP_BACKUP_DIR;
1290
- $reqs['Backup Folder']['status'] .= ' (' . $file_path . ')';
1291
-
1292
- if ($func = $this->check_sys()) {
1293
- $reqs['Execute Function']['status'] = $func;
1294
- $reqs['Execute Function']['pass'] = true;
1295
- } else {
1296
- $reqs['Execute Function']['status'] = "not found";
1297
- $reqs['Execute Function']['info'] = "(will try PHP replacement)";
1298
- $reqs['Execute Function']['pass'] = false;
1299
- }
1300
- $reqs['Zip']['status'] = $this->get_zip();
1301
-
1302
- $reqs['Zip']['pass'] = true;
1303
-
1304
-
1305
-
1306
- $reqs['Unzip']['status'] = $this->get_unzip();
1307
-
1308
- $reqs['Unzip']['pass'] = true;
1309
-
1310
- $paths = $this->check_mysql_paths();
1311
-
1312
- if (!empty($paths['mysqldump'])) {
1313
- $reqs['MySQL Dump']['status'] = $paths['mysqldump'];
1314
- $reqs['MySQL Dump']['pass'] = true;
1315
- } else {
1316
- $reqs['MySQL Dump']['status'] = "not found";
1317
- $reqs['MySQL Dump']['info'] = "(will try PHP replacement)";
1318
- $reqs['MySQL Dump']['pass'] = false;
1319
- }
1320
-
1321
- $exec_time = ini_get('max_execution_time');
1322
- $reqs['Execution time']['status'] = $exec_time ? $exec_time . "s" : 'unknown';
1323
- $reqs['Execution time']['pass'] = true;
1324
-
1325
- $mem_limit = ini_get('memory_limit');
1326
- $reqs['Memory limit']['status'] = $mem_limit ? $mem_limit : 'unknown';
1327
- $reqs['Memory limit']['pass'] = true;
1328
-
1329
-
1330
- return $reqs;
1331
- }
1332
-
1333
- function email_backup($args)
1334
- {
1335
- $email = $args['email'];
1336
-
1337
- if (!is_email($email)) {
1338
- return array(
1339
- 'error' => 'Your email (' . $email . ') is not correct'
1340
- );
1341
- }
1342
- $backup_file = $args['file_path'];
1343
- $task_name = isset($args['task_name']) ? $args['task_name'] : '';
1344
- if (file_exists($backup_file) && $email) {
1345
- $attachments = array(
1346
- $backup_file
1347
- );
1348
- $headers = 'From: ManageWP <no-reply@managewp.com>' . "\r\n";
1349
- $subject = "ManageWP - " . $task_name . " - " . $this->site_name;
1350
- ob_start();
1351
- $result = wp_mail($email, $subject, $subject, $headers, $attachments);
1352
- ob_end_clean();
1353
-
1354
- }
1355
-
1356
- if (!$result) {
1357
- return array(
1358
- 'error' => 'Email not sent. Maybe your backup is too big for email or email server is not available on your website.'
1359
- );
1360
- }
1361
- return true;
1362
-
1363
- }
1364
-
1365
- function ftp_backup($args)
1366
- {
1367
- extract($args);
1368
- //Args: $ftp_username, $ftp_password, $ftp_hostname, $backup_file, $ftp_remote_folder, $ftp_site_folder
1369
- $port = $ftp_port ? $ftp_port : 21; //default port is 21
1370
- if ($ftp_ssl) {
1371
- if (function_exists('ftp_ssl_connect')) {
1372
- $conn_id = ftp_ssl_connect($ftp_hostname,$port);
1373
- } else {
1374
- return array(
1375
- 'error' => 'Your server doesn\'t support SFTP',
1376
- 'partial' => 1
1377
- );
1378
- }
1379
- } else {
1380
- if (function_exists('ftp_connect')) {
1381
- $conn_id = ftp_connect($ftp_hostname,$port);
1382
- if ($conn_id === false) {
1383
- return array(
1384
- 'error' => 'Failed to connect to ' . $ftp_hostname,
1385
- 'partial' => 1
1386
- );
1387
- }
1388
- } else {
1389
- return array(
1390
- 'error' => 'Your server doesn\'t support FTP',
1391
- 'partial' => 1
1392
- );
1393
- }
1394
- }
1395
- $login = @ftp_login($conn_id, $ftp_username, $ftp_password);
1396
- if ($login === false) {
1397
- return array(
1398
- 'error' => 'FTP login failed for ' . $ftp_username . ', ' . $ftp_password,
1399
- 'partial' => 1
1400
- );
1401
- }
1402
-
1403
- if($ftp_passive){
1404
- @ftp_pasv($conn_id,true);
1405
- }
1406
-
1407
- @ftp_mkdir($conn_id, $ftp_remote_folder);
1408
- if ($ftp_site_folder) {
1409
- $ftp_remote_folder .= '/' . $this->site_name;
1410
- }
1411
- @ftp_mkdir($conn_id, $ftp_remote_folder);
1412
-
1413
- $upload = @ftp_put($conn_id, $ftp_remote_folder . '/' . basename($backup_file), $backup_file, FTP_BINARY);
1414
-
1415
- if ($upload === false) { //Try ascii
1416
- $upload = @ftp_put($conn_id, $ftp_remote_folder . '/' . basename($backup_file), $backup_file, FTP_ASCII);
1417
- }
1418
- ftp_close($conn_id);
1419
-
1420
- if ($upload === false) {
1421
- return array(
1422
- 'error' => 'Failed to upload file to FTP. Please check your specified path.',
1423
- 'partial' => 1
1424
- );
1425
- }
1426
-
1427
- return true;
1428
- }
1429
-
1430
- function remove_ftp_backup($args)
1431
- {
1432
- extract($args);
1433
- //Args: $ftp_username, $ftp_password, $ftp_hostname, $backup_file, $ftp_remote_folder
1434
- $port = $ftp_port ? $ftp_port : 21; //default port is 21
1435
- if ($ftp_ssl && function_exists('ftp_ssl_connect')) {
1436
- $conn_id = ftp_ssl_connect($ftp_hostname,$port);
1437
- } else if (function_exists('ftp_connect')) {
1438
- $conn_id = ftp_connect($ftp_hostname,$port);
1439
- }
1440
-
1441
- if ($conn_id) {
1442
- $login = @ftp_login($conn_id, $ftp_username, $ftp_password);
1443
- if ($ftp_site_folder)
1444
- $ftp_remote_folder .= '/' . $this->site_name;
1445
-
1446
- if($ftp_passive){
1447
- @ftp_pasv($conn_id,true);
1448
- }
1449
-
1450
- $delete = ftp_delete($conn_id, $ftp_remote_folder . '/' . $backup_file);
1451
-
1452
- ftp_close($conn_id);
1453
- }
1454
-
1455
- }
1456
-
1457
- function get_ftp_backup($args)
1458
- {
1459
- extract($args);
1460
- //Args: $ftp_username, $ftp_password, $ftp_hostname, $backup_file, $ftp_remote_folder
1461
- $port = $ftp_port ? $ftp_port : 21; //default port is 21
1462
- if ($ftp_ssl && function_exists('ftp_ssl_connect')) {
1463
- $conn_id = ftp_ssl_connect($ftp_hostname,$port);
1464
-
1465
- } else if (function_exists('ftp_connect')) {
1466
- $conn_id = ftp_connect($ftp_hostname,$port);
1467
- if ($conn_id === false) {
1468
- return false;
1469
- }
1470
- }
1471
- $login = @ftp_login($conn_id, $ftp_username, $ftp_password);
1472
- if ($login === false) {
1473
- return false;
1474
- } else {
1475
- }
1476
-
1477
- if ($ftp_site_folder)
1478
- $ftp_remote_folder .= '/' . $this->site_name;
1479
-
1480
- if($ftp_passive){
1481
- @ftp_pasv($conn_id,true);
1482
- }
1483
-
1484
- $temp = ABSPATH . 'mwp_temp_backup.zip';
1485
- $get = ftp_get($conn_id, $temp, $ftp_remote_folder . '/' . $backup_file, FTP_BINARY);
1486
- if ($get === false) {
1487
- return false;
1488
- } else {
1489
- }
1490
- ftp_close($conn_id);
1491
-
1492
- return $temp;
1493
- }
1494
-
1495
- function dropbox_backup($args)
1496
- {
1497
-
1498
- extract($args);
1499
-
1500
- if(isset($consumer_secret) && !empty($consumer_secret)){
1501
- //New way
1502
- require_once('lib/dropbox.oauth.php');
1503
-
1504
- $dropbox = new Dropbox($consumer_key, $consumer_secret);
1505
- $dropbox->setOAuthToken($oauth_token);
1506
- $dropbox->setOAuthTokenSecret($oauth_token_secret);
1507
-
1508
- if ($dropbox_site_folder == true)
1509
- $dropbox_destination .= '/' . $this->site_name;
1510
-
1511
- try{
1512
-
1513
- $dropbox->filesPost($dropbox_destination, $backup_file,true);
1514
-
1515
- } catch(Exception $e){
1516
- return array(
1517
- 'error' => 'Dropbox upload error. '.$e->getMessage()
1518
- );
1519
- }
1520
-
1521
- return true;
1522
-
1523
- } else {
1524
- //old way
1525
- require_once('lib/dropbox.php');
1526
-
1527
- //$email, $password, $backup_file, $destination, $dropbox_site_folder
1528
-
1529
- $size = ceil(filesize($backup_file) / 1024);
1530
- if ($size > 300000) {
1531
- return array(
1532
- 'error' => 'Cannot upload file to Dropbox. Dropbox has upload limit of 300Mb per file.',
1533
- 'partial' => 1
1534
- );
1535
- }
1536
-
1537
- if ($dropbox_site_folder == true)
1538
- $dropbox_destination .= '/' . $this->site_name;
1539
-
1540
- try {
1541
- $uploader = new DropboxUploader($dropbox_username, $dropbox_password);
1542
- $uploader->upload($backup_file, $dropbox_destination);
1543
- }
1544
- catch (Exception $e) {
1545
- return array(
1546
- 'error' => $e->getMessage(),
1547
- 'partial' => 1
1548
- );
1549
- }
1550
-
1551
- return true;
1552
- }
1553
-
1554
- }
1555
-
1556
- function remove_dropbox_backup($args){
1557
- extract($args);
1558
- if(isset($consumer_secret) && !empty($consumer_secret)){
1559
- //New way
1560
- require_once('lib/dropbox.oauth.php');
1561
-
1562
- $dropbox = new Dropbox($consumer_key, $consumer_secret);
1563
- $dropbox->setOAuthToken($oauth_token);
1564
- $dropbox->setOAuthTokenSecret($oauth_token_secret);
1565
-
1566
- if ($dropbox_site_folder == true)
1567
- $dropbox_destination .= '/' . $this->site_name;
1568
-
1569
- try{
1570
- $dropbox->fileopsDelete($dropbox_destination.'/'.$backup_file, true);
1571
- } catch(Exception $e){
1572
-
1573
- }
1574
- }
1575
- }
1576
-
1577
- function get_dropbox_backup($args){
1578
- extract($args);
1579
-
1580
- if(isset($consumer_secret) && !empty($consumer_secret)){
1581
- //New way
1582
- require_once('lib/dropbox.oauth.php');
1583
-
1584
- $dropbox = new Dropbox($consumer_key, $consumer_secret);
1585
- $dropbox->setOAuthToken($oauth_token);
1586
- $dropbox->setOAuthTokenSecret($oauth_token_secret);
1587
-
1588
- if ($dropbox_site_folder == true)
1589
- $dropbox_destination .= '/' . $this->site_name;
1590
-
1591
- $temp = ABSPATH . 'mwp_temp_backup.zip';
1592
-
1593
- try{
1594
- $file = $dropbox->filesGet($dropbox_destination.'/'.$backup_file, true);
1595
-
1596
- if(isset($file['data']) && !empty($file['data']) )
1597
- $stream = base64_decode($file['data']);
1598
- else
1599
- return false;
1600
-
1601
- $handle = @fopen($temp, 'w+');
1602
- $result = fwrite($handle,$stream);
1603
- fclose($handle);
1604
-
1605
- if($result)
1606
- return $temp;
1607
- else
1608
- return false;
1609
-
1610
- } catch(Exception $e){
1611
- $this->_log("exception");
1612
-
1613
- return false;
1614
- }
1615
-
1616
- } else {
1617
- return false;
1618
- }
1619
-
1620
-
1621
- }
1622
-
1623
- function amazons3_backup($args)
1624
- {
1625
- if ($this->mmb_function_exists('curl_init')) {
1626
- require_once('lib/s3.php');
1627
- extract($args);
1628
-
1629
- if ($as3_site_folder == true)
1630
- $as3_directory .= '/' . $this->site_name;
1631
-
1632
- $endpoint = isset($as3_bucket_region) ? $as3_bucket_region : 's3.amazonaws.com';
1633
-
1634
- $s3 = new S3(trim($as3_access_key), trim(str_replace(' ', '+', $as3_secure_key)), false, $endpoint);
1635
-
1636
- $s3->putBucket($as3_bucket, S3::ACL_PUBLIC_READ);
1637
-
1638
- if ($s3->putObjectFile($backup_file, $as3_bucket, $as3_directory . '/' . basename($backup_file), S3::ACL_PRIVATE)) {
1639
- return true;
1640
- } else {
1641
- return array(
1642
- 'error' => 'Failed to upload to Amazon S3. Please check your details and set upload/delete permissions on your bucket.',
1643
- 'partial' => 1
1644
- );
1645
- }
1646
- } else {
1647
- return array(
1648
- 'error' => 'You cannot use Amazon S3 on your server. Please enable curl first.',
1649
- 'partial' => 1
1650
- );
1651
- }
1652
- }
1653
-
1654
- function remove_amazons3_backup($args)
1655
- {
1656
- require_once('lib/s3.php');
1657
- extract($args);
1658
- if ($as3_site_folder == true)
1659
- $as3_directory .= '/' . $this->site_name;
1660
- $endpoint = isset($as3_bucket_region) ? $as3_bucket_region : 's3.amazonaws.com';
1661
- $s3 = new S3($as3_access_key, str_replace(' ', '+', $as3_secure_key), false, $endpoint);
1662
- $s3->deleteObject($as3_bucket, $as3_directory . '/' . $backup_file);
1663
- }
1664
-
1665
- function get_amazons3_backup($args)
1666
- {
1667
- require_once('lib/s3.php');
1668
- extract($args);
1669
- $endpoint = isset($as3_bucket_region) ? $as3_bucket_region : 's3.amazonaws.com';
1670
- $s3 = new S3($as3_access_key, str_replace(' ', '+', $as3_secure_key), false, $endpoint);
1671
- if ($as3_site_folder == true)
1672
- $as3_directory .= '/' . $this->site_name;
1673
-
1674
- $temp = ABSPATH . 'mwp_temp_backup.zip';
1675
- $s3->getObject($as3_bucket, $as3_directory . '/' . $backup_file, $temp);
1676
-
1677
- return $temp;
1678
- }
1679
-
1680
- function schedule_next($type, $schedule)
1681
- {
1682
- $schedule = explode("|", $schedule);
1683
- if (empty($schedule))
1684
- return false;
1685
- switch ($type) {
1686
-
1687
- case 'daily':
1688
-
1689
- if ($schedule[1]) {
1690
- $delay_time = $schedule[1] * 60;
1691
- }
1692
-
1693
- $current_hour = date("H");
1694
- $schedule_hour = $schedule[0];
1695
- if ($current_hour >= $schedule_hour)
1696
- $time = mktime($schedule_hour, 0, 0, date("m"), date("d") + 1, date("Y"));
1697
- else
1698
- $time = mktime($schedule_hour, 0, 0, date("m"), date("d"), date("Y"));
1699
- break;
1700
-
1701
-
1702
- case 'weekly':
1703
- if ($schedule[2]) {
1704
- $delay_time = $schedule[2] * 60;
1705
- }
1706
- $current_weekday = date('w');
1707
- $schedule_weekday = $schedule[1];
1708
- $current_hour = date("H");
1709
- $schedule_hour = $schedule[0];
1710
-
1711
- if ($current_weekday > $schedule_weekday)
1712
- $weekday_offset = 7 - ($week_day - $task_schedule[1]);
1713
- else
1714
- $weekday_offset = $schedule_weekday - $current_weekday;
1715
-
1716
-
1717
- if (!$weekday_offset) { //today is scheduled weekday
1718
- if ($current_hour >= $schedule_hour)
1719
- $time = mktime($schedule_hour, 0, 0, date("m"), date("d") + 7, date("Y"));
1720
- else
1721
- $time = mktime($schedule_hour, 0, 0, date("m"), date("d"), date("Y"));
1722
- } else {
1723
- $time = mktime($schedule_hour, 0, 0, date("m"), date("d") + $weekday_offset, date("Y"));
1724
- }
1725
-
1726
- break;
1727
-
1728
- case 'monthly':
1729
- if ($schedule[2]) {
1730
- $delay_time = $schedule[2] * 60;
1731
- }
1732
- $current_monthday = date('j');
1733
- $schedule_monthday = $schedule[1];
1734
- $current_hour = date("H");
1735
- $schedule_hour = $schedule[0];
1736
-
1737
- if ($current_monthday > $schedule_monthday) {
1738
- $time = mktime($schedule_hour, 0, 0, date("m") + 1, $schedule_monthday, date("Y"));
1739
- } else if ($current_monthday < $schedule_monthday) {
1740
- $time = mktime($schedule_hour, 0, 0, date("m"), $schedule_monthday, date("Y"));
1741
- } else if ($current_monthday == $schedule_monthday) {
1742
- if ($current_hour >= $schedule_hour)
1743
- $time = mktime($schedule_hour, 0, 0, date("m") + 1, $schedule_monthday, date("Y"));
1744
- else
1745
- $time = mktime($schedule_hour, 0, 0, date("m"), $schedule_monthday, date("Y"));
1746
- break;
1747
- }
1748
-
1749
- break;
1750
- default:
1751
- break;
1752
- }
1753
-
1754
- if ($delay_time) {
1755
- $time += $delay_time;
1756
- }
1757
-
1758
-
1759
- return $time;
1760
-
1761
- }
1762
-
1763
- //Parse task arguments for info on master
1764
- function get_backup_stats()
1765
- {
1766
- $stats = array();
1767
- $tasks = $this->tasks;
1768
- if (is_array($tasks) && !empty($tasks)) {
1769
- foreach ($tasks as $task_name => $info) {
1770
- if (is_array($info['task_results']) && !empty($info['task_results'])) {
1771
- foreach ($info['task_results'] as $key => $result) {
1772
- if (isset($result['server']) && !isset($result['error'])) {
1773
- if (!file_exists($result['server']['file_path'])) {
1774
- $info['task_results'][$key]['error'] = 'Backup created but manually removed from server.';
1775
- }
1776
- }
1777
- }
1778
- }
1779
- if (is_array($info['task_results']))
1780
- $stats[$task_name] = array_values($info['task_results']);
1781
-
1782
- }
1783
- }
1784
- return $stats;
1785
- }
1786
-
1787
- function get_next_schedules()
1788
- {
1789
- $stats = array();
1790
- $tasks = $this->tasks;
1791
- if (is_array($tasks) && !empty($tasks)) {
1792
- foreach ($tasks as $task_name => $info) {
1793
- $stats[$task_name] = isset($info['task_args']['next']) ? $info['task_args']['next'] : array();
1794
- }
1795
- }
1796
- return $stats;
1797
- }
1798
-
1799
- function remove_old_backups($task_name)
1800
- {
1801
- //Check for previous failed backups first
1802
- $this->cleanup();
1803
-
1804
- //Remove by limit
1805
- $backups = $this->tasks;
1806
- if ($task_name == 'Backup Now') {
1807
- $num = 0;
1808
- } else {
1809
- $num = 1;
1810
- }
1811
-
1812
-
1813
- if ((count($backups[$task_name]['task_results']) - $num) >= $backups[$task_name]['task_args']['limit']) {
1814
- //how many to remove ?
1815
- $remove_num = (count($backups[$task_name]['task_results']) - $num - $backups[$task_name]['task_args']['limit']) + 1;
1816
- for ($i = 0; $i < $remove_num; $i++) {
1817
- //Remove from the server
1818
- if (isset($backups[$task_name]['task_results'][$i]['server'])) {
1819
- @unlink($backups[$task_name]['task_results'][$i]['server']['file_path']);
1820
- }
1821
-
1822
- //Remove from ftp
1823
- if (isset($backups[$task_name]['task_results'][$i]['ftp'])) {
1824
- $ftp_file = $backups[$task_name]['task_results'][$i]['ftp'];
1825
- $args = $backups[$task_name]['task_args']['account_info']['mwp_ftp'];
1826
- $args['backup_file'] = $ftp_file;
1827
- $this->remove_ftp_backup($args);
1828
- }
1829
-
1830
- if (isset($backups[$task_name]['task_results'][$i]['amazons3'])) {
1831
- $amazons3_file = $backups[$task_name]['task_results'][$i]['amazons3'];
1832
- $args = $backups[$task_name]['task_args']['account_info']['mwp_amazon_s3'];
1833
- $args['backup_file'] = $amazons3_file;
1834
- $this->remove_amazons3_backup($args);
1835
- }
1836
-
1837
- if (isset($backups[$task_name]['task_results'][$i]['dropbox'])) {
1838
- //To do: dropbox remove
1839
- $dropbox_file = $backups[$task_name]['task_results'][$i]['dropbox'];
1840
- $args = $backups[$task_name]['task_args']['account_info']['mwp_dropbox'];
1841
- $args['backup_file'] = $dropbox_file;
1842
- $this->remove_dropbox_backup($args);
1843
- }
1844
-
1845
- //Remove database backup info
1846
- unset($backups[$task_name]['task_results'][$i]);
1847
-
1848
- } //end foreach
1849
-
1850
- if (is_array($backups[$task_name]['task_results']))
1851
- $backups[$task_name]['task_results'] = array_values($backups[$task_name]['task_results']);
1852
- else
1853
- $backups[$task_name]['task_results']=array();
1854
-
1855
- $this->update_tasks($backups);
1856
- //update_option('mwp_backup_tasks', $backups);
1857
- }
1858
- }
1859
-
1860
- /**
1861
- * Delete specified backup
1862
- * Args: $task_name, $result_id
1863
- */
1864
-
1865
- function delete_backup($args)
1866
- {
1867
- if (empty($args))
1868
- return false;
1869
- extract($args);
1870
-
1871
- $tasks = $this->tasks;
1872
- $task = $tasks[$task_name];
1873
- $backups = $task['task_results'];
1874
- $backup = $backups[$result_id];
1875
-
1876
- if (isset($backup['server'])) {
1877
- @unlink($backup['server']['file_path']);
1878
- }
1879
-
1880
- //Remove from ftp
1881
- if (isset($backup['ftp'])) {
1882
- $ftp_file = $backup['ftp'];
1883
- $args = $tasks[$task_name]['task_args']['account_info']['mwp_ftp'];
1884
- $args['backup_file'] = $ftp_file;
1885
- $this->remove_ftp_backup($args);
1886
- }
1887
-
1888
- if (isset($backup['amazons3'])) {
1889
- $amazons3_file = $backup['amazons3'];
1890
- $args = $tasks[$task_name]['task_args']['account_info']['mwp_amazon_s3'];
1891
- $args['backup_file'] = $amazons3_file;
1892
- $this->remove_amazons3_backup($args);
1893
- }
1894
-
1895
- if (isset($backup['dropbox'])) {
1896
- $dropbox_file = $backup['dropbox'];
1897
- $args = $tasks[$task_name]['task_args']['account_info']['mwp_dropbox'];
1898
- $args['backup_file'] = $dropbox_file;
1899
- $this->remove_dropbox_backup($args);
1900
- }
1901
-
1902
- unset($backups[$result_id]);
1903
-
1904
- if (count($backups)) {
1905
- $tasks[$task_name]['task_results'] = $backups;
1906
- } else {
1907
- unset($tasks[$task_name]['task_results']);
1908
- }
1909
-
1910
- $this->update_tasks($tasks);
1911
- //update_option('mwp_backup_tasks', $tasks);
1912
- return true;
1913
-
1914
- }
1915
-
1916
- function cleanup()
1917
- {
1918
- $tasks = $this->tasks;
1919
- $backup_folder = WP_CONTENT_DIR . '/' . md5('mmb-worker') . '/mwp_backups/';
1920
- $backup_folder_new = MWP_BACKUP_DIR . '/';
1921
- $files = glob($backup_folder . "*");
1922
- $new = glob($backup_folder_new . "*");
1923
-
1924
- //Failed db files first
1925
- $db_folder = MWP_DB_DIR . '/';
1926
- $db_files = glob($db_folder . "*");
1927
- if (is_array($db_files) && !empty($db_files)) {
1928
- foreach ($db_files as $file) {
1929
- @unlink($file);
1930
- }
1931
- @rmdir(MWP_DB_DIR);
1932
- }
1933
-
1934
-
1935
- //clean_old folder?
1936
- if ((basename($files[0]) == 'index.php' && count($files) == 1) || (empty($files))) {
1937
- foreach ($files as $file) {
1938
- @unlink($file);
1939
- }
1940
- @rmdir(WP_CONTENT_DIR . '/' . md5('mmb-worker') . '/mwp_backups');
1941
- @rmdir(WP_CONTENT_DIR . '/' . md5('mmb-worker'));
1942
- }
1943
-
1944
-
1945
- foreach ($new as $b) {
1946
- $files[] = $b;
1947
- }
1948
- $deleted = array();
1949
-
1950
- if (is_array($files) && count($files)) {
1951
- $results = array();
1952
- if (!empty($tasks)) {
1953
- foreach ((array) $tasks as $task) {
1954
- if (isset($task['task_results']) && count($task['task_results'])) {
1955
- foreach ($task['task_results'] as $backup) {
1956
- if (isset($backup['server'])) {
1957
- $results[] = $backup['server']['file_path'];
1958
- }
1959
- }
1960
- }
1961
- }
1962
- }
1963
-
1964
- $num_deleted = 0;
1965
- foreach ($files as $file) {
1966
- if (!in_array($file, $results) && basename($file) != 'index.php') {
1967
- @unlink($file);
1968
- $deleted[] = basename($file);
1969
- $num_deleted++;
1970
- }
1971
- }
1972
- }
1973
-
1974
-
1975
-
1976
- return $deleted;
1977
- }
1978
-
1979
-
1980
- function remote_backup_now($args)
1981
- {
1982
- if (!empty($args))
1983
- extract($args);
1984
-
1985
- $tasks = $this->tasks;
1986
- $task = $tasks['Backup Now'];
1987
-
1988
- if (!empty($task)) {
1989
- extract($task['task_args']);
1990
- }
1991
-
1992
- $results = $task['task_results'];
1993
-
1994
- if (is_array($results) && count($results)) {
1995
- $backup_file = $results[count($results) - 1]['server']['file_path'];
1996
- }
1997
-
1998
- if ($backup_file && file_exists($backup_file)) {
1999
- //FTP, Amazon S3 or Dropbox
2000
- if (isset($account_info['mwp_ftp']) && !empty($account_info['mwp_ftp'])) {
2001
- $account_info['mwp_ftp']['backup_file'] = $backup_file;
2002
- $return = $this->ftp_backup($account_info['mwp_ftp']);
2003
- }
2004
-
2005
- if (isset($account_info['mwp_amazon_s3']) && !empty($account_info['mwp_amazon_s3'])) {
2006
- $account_info['mwp_amazon_s3']['backup_file'] = $backup_file;
2007
- $return = $this->amazons3_backup($account_info['mwp_amazon_s3']);
2008
- }
2009
-
2010
- if (isset($account_info['mwp_dropbox']) && !empty($account_info['mwp_dropbox'])) {
2011
- $account_info['mwp_dropbox']['backup_file'] = $backup_file;
2012
- $return = $this->dropbox_backup($account_info['mwp_dropbox']);
2013
- }
2014
-
2015
- if (isset($account_info['mwp_email']) && !empty($account_info['mwp_email'])) {
2016
- $account_info['mwp_email']['file_path'] = $backup_file;
2017
- $account_info['mwp_email']['task_name'] = 'Backup Now';
2018
- $return = $this->email_backup($account_info['mwp_email']);
2019
- }
2020
-
2021
-
2022
- if ($return == true && $del_host_file) {
2023
- @unlink($backup_file);
2024
- unset($tasks['Backup Now']['task_results'][count($results) - 1]['server']);
2025
- $this->update_tasks($tasks);
2026
- //update_option('mwp_backup_tasks', $tasks);
2027
- }
2028
-
2029
-
2030
-
2031
- } else {
2032
- $return = array(
2033
- 'error' => 'Backup file not found on your server. Please try again.'
2034
- );
2035
- }
2036
-
2037
- return $return;
2038
-
2039
- }
2040
-
2041
- function validate_task($args, $url)
2042
- {
2043
- if (!class_exists('WP_Http')) {
2044
- include_once(ABSPATH . WPINC . '/class-http.php');
2045
- }
2046
- $params = array();
2047
- $params['body'] = $args;
2048
- $result = wp_remote_post($url, $params);
2049
- if (is_array($result) && $result['body'] == 'mwp_delete_task') {
2050
- //$tasks = $this->get_backup_settings();
2051
- $tasks = $this->tasks;
2052
- unset($tasks[$args['task_name']]);
2053
- $this->update_tasks($tasks);
2054
- $this->cleanup();
2055
- exit;
2056
- } elseif(is_array($result) && $result['body'] == 'mwp_pause_task'){
2057
- return 'paused';
2058
- }
2059
-
2060
- return 'ok';
2061
- }
2062
-
2063
- function update_status($task_name, $status, $completed = false)
2064
- {
2065
- /* Statuses:
2066
- 0 - Backup started
2067
- 1 - DB dump
2068
- 2 - DB ZIP
2069
- 3 - Files ZIP
2070
- 4 - Amazon S3
2071
- 5 - Dropbox
2072
- 6 - FTP
2073
- 7 - Email
2074
- 100 - Finished
2075
- */
2076
- if ($task_name != 'Backup Now') {
2077
- $tasks = $this->tasks;
2078
- $index = count($tasks[$task_name]['task_results']) - 1;
2079
- if (!is_array($tasks[$task_name]['task_results'][$index]['status'])) {
2080
- $tasks[$task_name]['task_results'][$index]['status'] = array();
2081
- }
2082
- if (!$completed) {
2083
- $tasks[$task_name]['task_results'][$index]['status'][] = (int) $status * (-1);
2084
- } else {
2085
- $status_index = count($tasks[$task_name]['task_results'][$index]['status']) - 1;
2086
- $tasks[$task_name]['task_results'][$index]['status'][$status_index] = abs($tasks[$task_name]['task_results'][$index]['status'][$status_index]);
2087
- }
2088
-
2089
- $this->update_tasks($tasks);
2090
- //update_option('mwp_backup_tasks',$tasks);
2091
- }
2092
- }
2093
-
2094
- function update_tasks($tasks)
2095
- {
2096
- $this->tasks = $tasks;
2097
- update_option('mwp_backup_tasks', $tasks);
2098
- }
2099
-
2100
- function wpdb_reconnect(){
2101
- global $wpdb;
2102
- //Reconnect to avoid timeout problem after ZIP files
2103
- if(class_exists('wpdb') && function_exists('wp_set_wpdb_vars')){
2104
- @mysql_close($wpdb->dbh);
2105
- $wpdb = new wpdb( DB_USER, DB_PASSWORD, DB_NAME, DB_HOST );
2106
- wp_set_wpdb_vars();
2107
- }
2108
- }
2109
-
2110
- function replace_htaccess($url)
2111
- {
2112
- $file = @file_get_contents(ABSPATH.'.htaccess');
2113
- if ($file && strlen($file)) {
2114
- $args = parse_url($url);
2115
- $string = rtrim($args['path'], "/");
2116
- $regex = "/BEGIN WordPress(.*?)RewriteBase(.*?)\n(.*?)RewriteRule \.(.*?)index\.php(.*?)END WordPress/sm";
2117
- $replace = "BEGIN WordPress$1RewriteBase " . $string . "/ \n$3RewriteRule . " . $string . "/index.php$5END WordPress";
2118
- $file = preg_replace($regex, $replace, $file);
2119
- @file_put_contents(ABSPATH.'.htaccess', $file);
2120
- }
2121
- }
2122
-
2123
- function check_cron_remove(){
2124
- if(empty($this->tasks) || (count($this->tasks) == 1 && isset($this->tasks['Backup Now'])) ){
2125
- wp_clear_scheduled_hook('mwp_backup_tasks');
2126
- exit;
2127
- }
2128
- }
2129
-
2130
- }
2131
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2132
  ?>
1
+ <?php
2
+ /*************************************************************
3
+ *
4
+ * backup.class.php
5
+ *
6
+ * Manage Backups
7
+ *
8
+ *
9
+ * Copyright (c) 2011 Prelovac Media
10
+ * www.prelovac.com
11
+ **************************************************************/
12
+ define('MWP_BACKUP_DIR', WP_CONTENT_DIR . '/managewp/backups');
13
+ define('MWP_DB_DIR', MWP_BACKUP_DIR . '/mwp_db');
14
+
15
+ $zip_errors = array(
16
+ 'No error',
17
+ 'No error',
18
+ 'Unexpected end of zip file',
19
+ 'A generic error in the zipfile format was detected.',
20
+ 'zip was unable to allocate itself memory',
21
+ 'A severe error in the zipfile format was detected',
22
+ 'Entry too large to be split with zipsplit',
23
+ 'Invalid comment format',
24
+ 'zip -T failed or out of memory',
25
+ 'The user aborted zip prematurely',
26
+ 'zip encountered an error while using a temp file',
27
+ 'Read or seek error',
28
+ 'zip has nothing to do',
29
+ 'Missing or empty zip file',
30
+ 'Error writing to a file',
31
+ 'zip was unable to create a file to write to',
32
+ 'bad command line parameters',
33
+ 'no error',
34
+ 'zip could not open a specified file to read'
35
+ );
36
+ $unzip_errors = array(
37
+ 'No error',
38
+ 'One or more warning errors were encountered, but processing completed successfully anyway',
39
+ 'A generic error in the zipfile format was detected',
40
+ 'A severe error in the zipfile format was detected.',
41
+ 'unzip was unable to allocate itself memory.',
42
+ 'unzip was unable to allocate memory, or encountered an encryption error',
43
+ 'unzip was unable to allocate memory during decompression to disk',
44
+ 'unzip was unable allocate memory during in-memory decompression',
45
+ 'unused',
46
+ 'The specified zipfiles were not found',
47
+ 'Bad command line parameters',
48
+ 'No matching files were found',
49
+ 50 => 'The disk is (or was) full during extraction',
50
+ 51 => 'The end of the ZIP archive was encountered prematurely.',
51
+ 80 => 'The user aborted unzip prematurely.',
52
+ 81 => 'Testing or extraction of one or more files failed due to unsupported compression methods or unsupported decryption.',
53
+ 82 => 'No files were found due to bad decryption password(s)'
54
+ );
55
+
56
+
57
+ class MMB_Backup extends MMB_Core
58
+ {
59
+ var $site_name;
60
+ var $statuses;
61
+ var $tasks;
62
+ var $s3;
63
+ var $ftp;
64
+ var $dropbox;
65
+ function __construct()
66
+ {
67
+ parent::__construct();
68
+ $this->site_name = str_replace(array(
69
+ "_",
70
+ "/"
71
+ ), array(
72
+ "",
73
+ "-"
74
+ ), rtrim($this->remove_http(get_bloginfo('url')), "/"));
75
+ $this->statuses = array(
76
+ 'db_dump' => 1,
77
+ 'db_zip' => 2,
78
+ 'files_zip' => 3,
79
+ 's3' => 4,
80
+ 'dropbox' => 5,
81
+ 'ftp' => 6,
82
+ 'email' => 7,
83
+ 'finished' => 100
84
+ );
85
+ $this->tasks = get_option('mwp_backup_tasks');
86
+ }
87
+
88
+ function get_backup_settings()
89
+ {
90
+ $backup_settings = get_option('mwp_backup_tasks');
91
+ if (!empty($backup_settings))
92
+ return $backup_settings;
93
+ else
94
+ return false;
95
+ }
96
+
97
+ function set_backup_task($params)
98
+ {
99
+ //$params => [$task_name, $args, $error]
100
+ if (!empty($params)) {
101
+
102
+ //Make sure backup cron job is set
103
+ if (!wp_next_scheduled('mwp_backup_tasks')) {
104
+ wp_schedule_event( time(), 'tenminutes', 'mwp_backup_tasks' );
105
+ }
106
+
107
+ extract($params);
108
+
109
+ //$before = $this->get_backup_settings();
110
+ $before = $this->tasks;
111
+ if (!$before || empty($before))
112
+ $before = array();
113
+
114
+ if (isset($args['remove'])) {
115
+ unset($before[$task_name]);
116
+ $return = array(
117
+ 'removed' => true
118
+ );
119
+ } else {
120
+ if (isset($params['account_info']) && is_array($params['account_info'])) { //only if sends from master first time(secure data)
121
+ $args['account_info'] = $account_info;
122
+ }
123
+
124
+ $before[$task_name]['task_args'] = $args;
125
+ if (strlen($args['schedule']))
126
+ $before[$task_name]['task_args']['next'] = $this->schedule_next($args['type'], $args['schedule']);
127
+
128
+ $return = $before[$task_name];
129
+ }
130
+
131
+ //Update with error
132
+ if (isset($error)) {
133
+ if (is_array($error)) {
134
+ $before[$task_name]['task_results'][count($before[$task_name]['task_results']) - 1]['error'] = $error['error'];
135
+ } else {
136
+ $before[$task_name]['task_results'][count($before[$task_name]['task_results'])]['error'] = $error;
137
+ }
138
+ }
139
+
140
+ if ($time) { //set next result time before backup
141
+ if (is_array($before[$task_name]['task_results'])) {
142
+ $before[$task_name]['task_results'] = array_values($before[$task_name]['task_results']);
143
+ }
144
+ $before[$task_name]['task_results'][count($before[$task_name]['task_results'])]['time'] = $time;
145
+ }
146
+
147
+ $this->update_tasks($before);
148
+ //update_option('mwp_backup_tasks', $before);
149
+
150
+ if ($task_name == 'Backup Now') {
151
+ $result = $this->backup($args, $task_name);
152
+ $backup_settings = $this->tasks;
153
+
154
+ if (is_array($result) && array_key_exists('error', $result)) {
155
+ $return = $result;
156
+ } else {
157
+ $return = $backup_settings[$task_name];
158
+ }
159
+ }
160
+ return $return;
161
+ }
162
+
163
+
164
+
165
+ return false;
166
+ }
167
+
168
+ //Cron check
169
+ function check_backup_tasks()
170
+ {
171
+
172
+ $this->check_cron_remove();
173
+
174
+ $settings = $this->tasks;
175
+ if (is_array($settings) && !empty($settings)) {
176
+ foreach ($settings as $task_name => $setting) {
177
+ if ($setting['task_args']['next'] && $setting['task_args']['next'] < time()) {
178
+ //if ($setting['task_args']['next'] && $_GET['force_backup']) {
179
+ if ($setting['task_args']['url'] && $setting['task_args']['task_id'] && $setting['task_args']['site_key']) {
180
+ //Check orphan task
181
+ $check_data = array(
182
+ 'task_name' => $task_name,
183
+ 'task_id' => $setting['task_args']['task_id'],
184
+ 'site_key' => $setting['task_args']['site_key']
185
+ );
186
+
187
+ $check = $this->validate_task($check_data, $setting['task_args']['url']);
188
+
189
+ }
190
+
191
+ $update = array(
192
+ 'task_name' => $task_name,
193
+ 'args' => $settings[$task_name]['task_args']
194
+ );
195
+
196
+
197
+ if($check != 'paused'){
198
+ $update['time'] = time();
199
+ }
200
+
201
+ //Update task with next schedule
202
+ $this->set_backup_task($update);
203
+
204
+ if($check == 'paused'){
205
+ continue;
206
+ }
207
+
208
+
209
+ $result = $this->backup($setting['task_args'], $task_name);
210
+ $error = '';
211
+ if (is_array($result) && array_key_exists('error', $result)) {
212
+ $error = $result;
213
+ $this->set_backup_task(array(
214
+ 'task_name' => $task_name,
215
+ 'args' => $settings[$task_name]['task_args'],
216
+ 'error' => $error
217
+ ));
218
+ } else {
219
+ $error = '';
220
+ }
221
+ break; //Only one backup per cron
222
+ }
223
+ }
224
+ }
225
+
226
+ }
227
+
228
+ function task_now($task_name){
229
+
230
+ $settings = $this->tasks;
231
+ if(!array_key_exists($task_name,$settings)){
232
+ return array('error' => $task_name." does not exist.");
233
+ } else {
234
+ $setting = $settings[$task_name];
235
+ }
236
+
237
+ $this->set_backup_task(array(
238
+ 'task_name' => $task_name,
239
+ 'args' => $settings[$task_name]['task_args'],
240
+ 'time' => time()
241
+ ));
242
+
243
+ //Run backup
244
+ $result = $this->backup($setting['task_args'], $task_name);
245
+
246
+ //Check for error
247
+ if (is_array($result) && array_key_exists('error', $result)) {
248
+ $this->set_backup_task(array(
249
+ 'task_name' => $task_name,
250
+ 'args' => $settings[$task_name]['task_args'],
251
+ 'error' => $result
252
+ ));
253
+ return $result;
254
+ } else {
255
+ return $this->get_backup_stats();
256
+ }
257
+
258
+ }
259
+
260
+
261
+
262
+ /*
263
+ * If Task Name not set then it's manual backup
264
+ * Backup args:
265
+ * type -> db, full
266
+ * what -> daily, weekly, monthly
267
+ * account_info -> ftp, amazons3, dropbox
268
+ * exclude-> array of paths to exclude from backup
269
+ */
270
+
271
+ function backup($args, $task_name = false)
272
+ {
273
+
274
+ if (!$args || empty($args))
275
+ return false;
276
+
277
+ extract($args); //extract settings
278
+
279
+ //Try increase memory limit and execution time
280
+ @ini_set('memory_limit', '256M');
281
+ @set_time_limit(600); //ten minutes
282
+
283
+
284
+
285
+ //Remove old backup(s)
286
+ $this->remove_old_backups($task_name);
287
+
288
+
289
+
290
+ $new_file_path = MWP_BACKUP_DIR;
291
+
292
+ if (!file_exists($new_file_path)) {
293
+ if (!mkdir($new_file_path, 0755, true))
294
+ return array(
295
+ 'error' => 'Permission denied, make sure you have write permission to wp-content folder.'
296
+ );
297
+ }
298
+
299
+ @file_put_contents($new_file_path . '/index.php', ''); //safe
300
+
301
+ //Prepare .zip file name
302
+ $hash = md5(time());
303
+ $label = $type ? $type : 'manual';
304
+ $backup_file = $new_file_path . '/' . $this->site_name . '_' . $label . '_' . $what . '_' . date('Y-m-d') . '_' . $hash . '.zip';
305
+ $backup_url = WP_CONTENT_URL . '/managewp/backups/' . $this->site_name . '_' . $label . '_' . $what . '_' . date('Y-m-d') . '_' . $hash . '.zip';
306
+
307
+ //Optimize tables?
308
+ if (isset($optimize_tables) && !empty($optimize_tables)) {
309
+ $this->optimize_tables();
310
+ }
311
+
312
+ //What to backup - db or full?
313
+ if (trim($what) == 'db') {
314
+ //Take database backup
315
+ $this->update_status($task_name, $this->statuses['db_dump']);
316
+ $db_result = $this->backup_db();
317
+ if ($db_result == false) {
318
+ return array(
319
+ 'error' => 'Failed to backup database.'
320
+ );
321
+ } else if (is_array($db_result) && isset($db_result['error'])) {
322
+ return array(
323
+ 'error' => $db_result['error']
324
+ );
325
+ } else {
326
+ $this->update_status($task_name, $this->statuses['db_dump'], true);
327
+ $this->update_status($task_name, $this->statuses['db_zip']);
328
+
329
+ $disable_comp = $this->tasks[$task_name]['task_args']['disable_comp'];
330
+ $comp_level = $disable_comp ? '-0' : '-1';
331
+
332
+ chdir(MWP_BACKUP_DIR);
333
+ $zip = $this->get_zip();
334
+ $command = "$zip -q -r $comp_level $backup_file 'mwp_db'";
335
+ ob_start();
336
+ $result = $this->mmb_exec($command);
337
+ ob_get_clean();
338
+ if (!$result) { // fallback to pclzip
339
+ define('PCLZIP_TEMPORARY_DIR', MWP_BACKUP_DIR . '/');
340
+ require_once ABSPATH . '/wp-admin/includes/class-pclzip.php';
341
+ $archive = new PclZip($backup_file);
342
+ if ($disable_comp) {
343
+ $result = $archive->add($db_result, PCLZIP_OPT_REMOVE_PATH, MWP_BACKUP_DIR, PCLZIP_OPT_NO_COMPRESSION);
344
+ } else {
345
+ $result = $archive->add($db_result, PCLZIP_OPT_REMOVE_PATH, MWP_BACKUP_DIR);
346
+ }
347
+ @unlink($db_result);
348
+ @rmdir(MWP_DB_DIR);
349
+ if (!$result) {
350
+ return array(
351
+ 'error' => 'Failed to zip database (pclZip - ' . $archive->error_code . '): .' . $archive->error_string
352
+ );
353
+ }
354
+ }
355
+
356
+ @unlink($db_result);
357
+ @rmdir(MWP_DB_DIR);
358
+ if (!$result) {
359
+ return array(
360
+ 'error' => 'Failed to zip database.'
361
+ );
362
+ }
363
+ $this->update_status($task_name, $this->statuses['db_zip'], true);
364
+ }
365
+ } elseif (trim($what) == 'full') {
366
+ $content_backup = $this->backup_full($task_name, $backup_file, $exclude, $include);
367
+ if (is_array($content_backup) && array_key_exists('error', $content_backup)) {
368
+ return array(
369
+ 'error' => $content_backup['error']
370
+ );
371
+ }
372
+ }
373
+
374
+ //Update backup info
375
+ if ($task_name) {
376
+ //backup task (scheduled)
377
+ $backup_settings = $this->tasks;
378
+ $paths = array();
379
+ $size = ceil(filesize($backup_file) / 1024);
380
+
381
+ if ($size > 1000) {
382
+ $paths['size'] = ceil($size / 1024) . "Mb";
383
+ } else {
384
+ $paths['size'] = $size . 'kb';
385
+ }
386
+
387
+ if ($task_name != 'Backup Now') {
388
+ if (!$backup_settings[$task_name]['task_args']['del_host_file']) {
389
+ $paths['server'] = array(
390
+ 'file_path' => $backup_file,
391
+ 'file_url' => $backup_url
392
+ );
393
+ }
394
+ } else {
395
+ $paths['server'] = array(
396
+ 'file_path' => $backup_file,
397
+ 'file_url' => $backup_url
398
+ );
399
+ }
400
+
401
+ if (isset($backup_settings[$task_name]['task_args']['account_info']['mwp_ftp'])) {
402
+ $paths['ftp'] = basename($backup_url);
403
+ }
404
+
405
+ if (isset($backup_settings[$task_name]['task_args']['account_info']['mwp_amazon_s3'])) {
406
+ $paths['amazons3'] = basename($backup_url);
407
+ }
408
+
409
+ if (isset($backup_settings[$task_name]['task_args']['account_info']['mwp_dropbox'])) {
410
+ $paths['dropbox'] = basename($backup_url);
411
+ }
412
+
413
+ if (isset($backup_settings[$task_name]['task_args']['account_info']['mwp_email'])) {
414
+ $paths['email'] = basename($backup_url);
415
+ }
416
+
417
+ $temp = $backup_settings[$task_name]['task_results'];
418
+ $temp = array_values($temp);
419
+ $paths['time'] = time();
420
+
421
+ if ($task_name != 'Backup Now') {
422
+ $paths['status'] = $temp[count($temp) - 1]['status'];
423
+ $temp[count($temp) - 1] = $paths;
424
+
425
+ } else {
426
+ $temp[count($temp)] = $paths;
427
+ }
428
+
429
+ $backup_settings[$task_name]['task_results'] = $temp;
430
+ $this->update_tasks($backup_settings);
431
+ //update_option('mwp_backup_tasks', $backup_settings);
432
+ }
433
+
434
+
435
+ //Additional: Email, ftp, amazon_s3, dropbox...
436
+
437
+ if ($task_name != 'Backup Now') {
438
+ if (isset($account_info['mwp_ftp']) && !empty($account_info['mwp_ftp'])) {
439
+ $this->update_status($task_name, $this->statuses['ftp']);
440
+ $account_info['mwp_ftp']['backup_file'] = $backup_file;
441
+ $ftp_result = $this->ftp_backup($account_info['mwp_ftp']);
442
+
443
+ if ($ftp_result !== true && $del_host_file) {
444
+ @unlink($backup_file);
445
+ }
446
+
447
+ if (is_array($ftp_result) && isset($ftp_result['error'])) {
448
+ return $ftp_result;
449
+ }
450
+ $this->wpdb_reconnect();
451
+ $this->update_status($task_name, $this->statuses['ftp'], true);
452
+ }
453
+
454
+ if (isset($account_info['mwp_amazon_s3']) && !empty($account_info['mwp_amazon_s3'])) {
455
+ $this->update_status($task_name, $this->statuses['s3']);
456
+ $account_info['mwp_amazon_s3']['backup_file'] = $backup_file;
457
+ $amazons3_result = $this->amazons3_backup($account_info['mwp_amazon_s3']);
458
+ if ($amazons3_result !== true && $del_host_file) {
459
+ @unlink($backup_file);
460
+ }
461
+ if (is_array($amazons3_result) && isset($amazons3_result['error'])) {
462
+ return $amazons3_result;
463
+ }
464
+ $this->wpdb_reconnect();
465
+ $this->update_status($task_name, $this->statuses['s3'], true);
466
+ }
467
+
468
+ if (isset($account_info['mwp_dropbox']) && !empty($account_info['mwp_dropbox'])) {
469
+ $this->update_status($task_name, $this->statuses['dropbox']);
470
+ $account_info['mwp_dropbox']['backup_file'] = $backup_file;
471
+ $dropbox_result = $this->dropbox_backup($account_info['mwp_dropbox']);
472
+ if ($dropbox_result !== true && $del_host_file) {
473
+ @unlink($backup_file);
474
+ }
475
+
476
+ if (is_array($dropbox_result) && isset($dropbox_result['error'])) {
477
+ return $dropbox_result;
478
+ }
479
+ $this->wpdb_reconnect();
480
+ $this->update_status($task_name, $this->statuses['dropbox'], true);
481
+ }
482
+
483
+ if (isset($account_info['mwp_email']) && !empty($account_info['mwp_email'])) {
484
+ $this->update_status($task_name, $this->statuses['email']);
485
+ $account_info['mwp_email']['task_name'] = $task_name;
486
+ $account_info['mwp_email']['file_path'] = $backup_file;
487
+
488
+ $email_result = $this->email_backup($account_info['mwp_email']);
489
+ if (is_array($email_result) && isset($email_result['error'])) {
490
+ return $email_result;
491
+ }
492
+ $this->update_status($task_name, $this->statuses['email'], true);
493
+ }
494
+
495
+ if ($del_host_file) {
496
+ @unlink($backup_file);
497
+ }
498
+
499
+ } //end additional
500
+
501
+ //$this->update_status($task_name,$this->statuses['finished'],true);
502
+ return $backup_url; //Return url to backup file
503
+ }
504
+
505
+ function backup_full($task_name, $backup_file, $exclude = array(), $include = array())
506
+ {
507
+ global $zip_errors;
508
+ $sys = substr(PHP_OS, 0, 3);
509
+
510
+ $this->update_status($task_name, $this->statuses['db_dump']);
511
+ $db_result = $this->backup_db();
512
+
513
+ if ($db_result == false) {
514
+ return array(
515
+ 'error' => 'Failed to backup database.'
516
+ );
517
+ } else if (is_array($db_result) && isset($db_result['error'])) {
518
+ return array(
519
+ 'error' => $db_result['error']
520
+ );
521
+ }
522
+
523
+ $this->update_status($task_name, $this->statuses['db_dump'], true);
524
+ $this->update_status($task_name, $this->statuses['db_zip']);
525
+ $disable_comp = $this->tasks[$task_name]['task_args']['disable_comp'];
526
+ $comp_level = $disable_comp ? '-0' : '-1';
527
+
528
+ $zip = $this->get_zip();
529
+ //Add database file
530
+ chdir(MWP_BACKUP_DIR);
531
+ $command = "$zip -q -r $comp_level $backup_file 'mwp_db'";
532
+ ob_start();
533
+ $result = $this->mmb_exec($command);
534
+ ob_get_clean();
535
+
536
+
537
+ if (!$result) {
538
+ define('PCLZIP_TEMPORARY_DIR', MWP_BACKUP_DIR . '/');
539
+ require_once ABSPATH . '/wp-admin/includes/class-pclzip.php';
540
+ $archive = new PclZip($backup_file);
541
+
542
+ if ($disable_comp) {
543
+ $result_db = $archive->add($db_result, PCLZIP_OPT_REMOVE_PATH, MWP_BACKUP_DIR, PCLZIP_OPT_NO_COMPRESSION);
544
+ } else {
545
+ $result_db = $archive->add($db_result, PCLZIP_OPT_REMOVE_PATH, MWP_BACKUP_DIR);
546
+ }
547
+
548
+ @unlink($db_result);
549
+ @rmdir(MWP_DB_DIR);
550
+
551
+ if (!$result_db) {
552
+ return array(
553
+ 'error' => 'Failed to zip database. pclZip error (' . $archive->error_code . '): .' . $archive->error_string
554
+ );
555
+ }
556
+ }
557
+
558
+ @unlink($db_result);
559
+ @rmdir(MWP_DB_DIR);
560
+
561
+ $this->update_status($task_name, $this->statuses['db_zip'], true);
562
+
563
+
564
+ //Always remove backup folders
565
+ $remove = array(
566
+ trim(basename(WP_CONTENT_DIR)) . "/managewp/backups",
567
+ trim(basename(WP_CONTENT_DIR)) . "/" . md5('mmb-worker') . "/mwp_backups"
568
+ );
569
+
570
+ //Exclude paths
571
+ $exclude_data = "-x";
572
+
573
+ $exclude_file_data = '';
574
+
575
+ if (!empty($exclude)) {
576
+ foreach ($exclude as $data) {
577
+ if (is_dir(ABSPATH . $data)) {
578
+ if ($sys == 'WIN')
579
+ $exclude_data .= " $data/*.*";
580
+ else
581
+ $exclude_data .= " $data/*";
582
+
583
+
584
+ } else {
585
+ if ($sys == 'WIN'){
586
+ if(file_exists(ABSPATH . $data)){
587
+ $exclude_data .= " $data";
588
+ $exclude_file_data .= " $data";
589
+ }
590
+ } else {
591
+ if(file_exists(ABSPATH . $data)){
592
+ $exclude_data .= " '$data'";
593
+ $exclude_file_data .= " '$data'";
594
+ }
595
+ }
596
+ }
597
+ }
598
+ }
599
+
600
+ if($exclude_file_data){
601
+ $exclude_file_data = "-x".$exclude_file_data;
602
+ }
603
+
604
+ foreach ($remove as $data) {
605
+ if ($sys == 'WIN')
606
+ $exclude_data .= " $data/*.*";
607
+ else
608
+ $exclude_data .= " '$data/*'";
609
+ }
610
+
611
+ //Include paths by default
612
+ $add = array(
613
+ trim(WPINC),
614
+ trim(basename(WP_CONTENT_DIR)),
615
+ "wp-admin"
616
+ );
617
+
618
+ $include_data = ". -i";
619
+ foreach ($add as $data) {
620
+ if ($sys == 'WIN')
621
+ $include_data .= " $data/*.*";
622
+ else
623
+ $include_data .= " '$data/*'";
624
+ }
625
+
626
+ //Additional includes?
627
+ if (!empty($include)) {
628
+ foreach ($include as $data) {
629
+ if ($data) {
630
+ if ($sys == 'WIN')
631
+ $include_data .= " $data/*.*";
632
+ else
633
+ $include_data .= " '$data/*'";
634
+ }
635
+ }
636
+ }
637
+
638
+ $this->update_status($task_name, $this->statuses['files_zip']);
639
+ chdir(ABSPATH);
640
+ ob_start();
641
+ $command = "$zip -q -j $comp_level $backup_file .* * $exclude_file_data";
642
+ $result_f = $this->mmb_exec($command, false, true);
643
+ if (!$result_f || $result_f == 18) { // disregard permissions error, file can't be accessed
644
+ $command = "$zip -q -r $comp_level $backup_file $include_data $exclude_data";
645
+ $result_d = $this->mmb_exec($command, false, true);
646
+ if ($result_d && $result_d != 18) {
647
+ @unlink($backup_file);
648
+ if ($result_d > 0 && $result_d < 18)
649
+ return array(
650
+ 'error' => 'Failed to archive files (' . $zip_errors[$result_d] . ') .'
651
+ );
652
+ else
653
+ return array(
654
+ 'error' => 'Failed to archive files.'
655
+ );
656
+ }
657
+ }
658
+ ob_get_clean();
659
+
660
+ if ($result_f && $result_f != 18) { //Try pclZip
661
+
662
+ if (!isset($archive)) {
663
+ define('PCLZIP_TEMPORARY_DIR', MWP_BACKUP_DIR . '/');
664
+ require_once ABSPATH . '/wp-admin/includes/class-pclzip.php';
665
+ $archive = new PclZip($backup_file);
666
+ }
667
+
668
+ //Include paths
669
+ $include_data = array();
670
+ if (!empty($include)) {
671
+ foreach ($include as $data) {
672
+ if ($data && file_exists(ABSPATH . $data))
673
+ $include_data[] = ABSPATH . $data . '/';
674
+ }
675
+ }
676
+
677
+ foreach ($add as $data) {
678
+ if (file_exists(ABSPATH . $data))
679
+ $include_data[] = ABSPATH . $data . '/';
680
+ }
681
+
682
+ //Include root files
683
+ if ($handle = opendir(ABSPATH)) {
684
+ while (false !== ($file = readdir($handle))) {
685
+ if ($file != "." && $file != ".." && !is_dir($file) && file_exists(ABSPATH . $file)) {
686
+ $include_data[] = ABSPATH . $file;
687
+ }
688
+ }
689
+ closedir($handle);
690
+ }
691
+
692
+ if ($disable_comp) {
693
+ $result = $archive->add($include_data, PCLZIP_OPT_REMOVE_PATH, ABSPATH, PCLZIP_OPT_NO_COMPRESSION);
694
+ } else {
695
+ $result = $archive->add($include_data, PCLZIP_OPT_REMOVE_PATH, ABSPATH);
696
+ }
697
+ if (!$result) {
698
+ @unlink($backup_file);
699
+ return array(
700
+ 'error' => 'Failed to zip files. pclZip error (' . $archive->error_code . '): .' . $archive->error_string
701
+ );
702
+ }
703
+
704
+ //Now exclude paths
705
+ $exclude_data = array();
706
+ if (!empty($exclude)) {
707
+ foreach ($exclude as $data) {
708
+ if (is_dir(ABSPATH . $data))
709
+ $exclude_data[] = $data . '/';
710
+ else
711
+ $exclude_data[] = $data;
712
+ }
713
+ }
714
+
715
+ foreach ($remove as $rem) {
716
+ $exclude_data[] = $rem . '/';
717
+ }
718
+
719
+ $result_excl = $archive->delete(PCLZIP_OPT_BY_NAME, $exclude_data);
720
+ if (!$result_excl) {
721
+ @unlink($backup_file);
722
+ return array(
723
+ 'error' => 'Failed to zip files. pclZip error (' . $archive->error_code . '): .' . $archive->error_string
724
+ );
725
+ }
726
+
727
+ }
728
+
729
+ //Reconnect
730
+ $this->wpdb_reconnect();
731
+
732
+ $this->update_status($task_name, $this->statuses['files_zip'], true);
733
+ return true;
734
+ }
735
+
736
+
737
+ function backup_db()
738
+ {
739
+ $db_folder = MWP_DB_DIR . '/';
740
+ if (!file_exists($db_folder)) {
741
+ if (!mkdir($db_folder, 0755, true))
742
+ return array(
743
+ 'error' => 'Error creating database backup folder (' . $db_folder . '). Make sure you have corrrect write permissions.'
744
+ );
745
+ }
746
+
747
+ $file = $db_folder . DB_NAME . '.sql';
748
+ $result = $this->backup_db_dump($file); // try mysqldump always then fallback to php dump
749
+ return $result;
750
+ }
751
+
752
+ function backup_db_dump($file)
753
+ {
754
+ global $wpdb;
755
+ $paths = $this->check_mysql_paths();
756
+ $brace = (substr(PHP_OS, 0, 3) == 'WIN') ? '"' : '';
757
+ $command = $brace . $paths['mysqldump'] . $brace . ' --force --host="' . DB_HOST . '" --user="' . DB_USER . '" --password="' . DB_PASSWORD . '" --add-drop-table --skip-lock-tables "' . DB_NAME . '" > ' . $brace . $file . $brace;
758
+ ob_start();
759
+ $result = $this->mmb_exec($command);
760
+ ob_get_clean();
761
+
762
+ if (!$result) { // Fallback to php
763
+ $result = $this->backup_db_php($file);
764
+ return $result;
765
+ }
766
+
767
+ if (filesize($file) == 0 || !is_file($file) || !$result) {
768
+ @unlink($file);
769
+ return false;
770
+ } else {
771
+ return $file;
772
+ }
773
+ }
774
+
775
+ function backup_db_php($file)
776
+ {
777
+ global $wpdb;
778
+ $tables = $wpdb->get_results('SHOW TABLES', ARRAY_N);
779
+ foreach ($tables as $table) {
780
+ //drop existing table
781
+ $dump_data = "DROP TABLE IF EXISTS $table[0];";
782
+ //create table
783
+ $create_table = $wpdb->get_row("SHOW CREATE TABLE $table[0]", ARRAY_N);
784
+ $dump_data .= "\n\n" . $create_table[1] . ";\n\n";
785
+
786
+ $count = $wpdb->get_var("SELECT count(*) FROM $table[0]");
787
+ if ($count > 100)
788
+ $count = ceil($count / 100);
789
+ else if ($count > 0)
790
+ $count = 1;
791
+
792
+ for ($i = 0; $i < $count; $i++) {
793
+ $low_limit = $i * 100;
794
+ $qry = "SELECT * FROM $table[0] LIMIT $low_limit, 100";
795
+ $rows = $wpdb->get_results($qry, ARRAY_A);
796
+ if (is_array($rows)) {
797
+ foreach ($rows as $row) {
798
+ //insert single row
799
+ $dump_data .= "INSERT INTO $table[0] VALUES(";
800
+ $num_values = count($row);
801
+ $j = 1;
802
+ foreach ($row as $value) {
803
+ $value = addslashes($value);
804
+ $value = preg_replace("/\n/Ui", "\\n", $value);
805
+ $num_values == $j ? $dump_data .= "'" . $value . "'" : $dump_data .= "'" . $value . "', ";
806
+ $j++;
807
+ unset($value);
808
+ }
809
+ $dump_data .= ");\n";
810
+ }
811
+ }
812
+ }
813
+ $dump_data .= "\n\n\n";
814
+
815
+ unset($rows);
816
+ file_put_contents($file, $dump_data, FILE_APPEND);
817
+ unset($dump_data);
818
+ }
819
+
820
+ if (filesize($file) == 0 || !is_file($file)) {
821
+ @unlink($file);
822
+ return array(
823
+ 'error' => 'Database backup failed. Try to enable MySQL dump on your server.'
824
+ );
825
+ }
826
+
827
+ return $file;
828
+
829
+ }
830
+
831
+ function restore($args)
832
+ {
833
+ global $wpdb;
834
+ if (empty($args)) {
835
+ return false;
836
+ }
837
+
838
+ extract($args);
839
+ @ini_set('memory_limit', '256M');
840
+ @set_time_limit(600);
841
+
842
+ $unlink_file = true; //Delete file after restore
843
+
844
+ //Detect source
845
+ if ($backup_url) {
846
+ //This is for clone (overwrite)
847
+ include_once ABSPATH . 'wp-admin/includes/file.php';
848
+ $backup_file = download_url($backup_url);
849
+ if (is_wp_error($backup_file)) {
850
+ return array(
851
+ 'error' => 'Unable to download backup file ('.$backup_file->get_error_message().')'
852
+ );
853
+ }
854
+ $what = 'full';
855
+ } else {
856
+ $tasks = $this->tasks;
857
+ $task = $tasks[$task_name];
858
+ if (isset($task['task_results'][$result_id]['server'])) {
859
+ $backup_file = $task['task_results'][$result_id]['server']['file_path'];
860
+ $unlink_file = false; //Don't delete file if stored on server
861
+ } elseif (isset($task['task_results'][$result_id]['ftp'])) {
862
+ $ftp_file = $task['task_results'][$result_id]['ftp'];
863
+ $args = $task['task_args']['account_info']['mwp_ftp'];
864
+ $args['backup_file'] = $ftp_file;
865
+ $backup_file = $this->get_ftp_backup($args);
866
+ if ($backup_file == false) {
867
+ return array(
868
+ 'error' => 'Failed to download file from FTP.'
869
+ );
870
+ }
871
+ } elseif (isset($task['task_results'][$result_id]['amazons3'])) {
872
+ $amazons3_file = $task['task_results'][$result_id]['amazons3'];
873
+ $args = $task['task_args']['account_info']['mwp_amazon_s3'];
874
+ $args['backup_file'] = $amazons3_file;
875
+ $backup_file = $this->get_amazons3_backup($args);
876
+ if ($backup_file == false) {
877
+ return array(
878
+ 'error' => 'Failed to download file from Amazon S3.'
879
+ );
880
+ }
881
+ } elseif(isset($task['task_results'][$result_id]['dropbox'])){
882
+ $dropbox_file = $task['task_results'][$result_id]['dropbox'];
883
+ $args = $task['task_args']['account_info']['mwp_dropbox'];
884
+ $args['backup_file'] = $dropbox_file;
885
+ $backup_file = $this->get_dropbox_backup($args);
886
+
887
+ if ($backup_file == false) {
888
+ return array(
889
+ 'error' => 'Failed to download file from Dropbox.'
890
+ );
891
+ }
892
+ }
893
+
894
+ $what = $tasks[$task_name]['task_args']['what'];
895
+ }
896
+
897
+ $this->wpdb_reconnect();
898
+
899
+ if ($backup_file && file_exists($backup_file)) {
900
+ if ($overwrite) {
901
+ //Keep old db credentials before overwrite
902
+ if (!copy(ABSPATH . 'wp-config.php', ABSPATH . 'mwp-temp-wp-config.php')) {
903
+ @unlink($backup_file);
904
+ return array(
905
+ 'error' => 'Error creating wp-config. Please check your write permissions.'
906
+ );
907
+ }
908
+
909
+ $db_host = DB_HOST;
910
+ $db_user = DB_USER;
911
+ $db_password = DB_PASSWORD;
912
+ $home = rtrim(get_option('home'), "/");
913
+ $site_url = get_option('site_url');
914
+
915
+ $clone_options = array();
916
+ if (trim($clone_from_url) || trim($mwp_clone)) {
917
+
918
+ $clone_options['_worker_nossl_key'] = get_option('_worker_nossl_key');
919
+ $clone_options['_worker_public_key'] = get_option('_worker_public_key');
920
+ $clone_options['_action_message_id'] = get_option('_action_message_id');
921
+
922
+ }
923
+ $clone_options['upload_path'] = get_option('upload_path');
924
+ $clone_options['upload_url_path'] = get_option('upload_url_path');
925
+
926
+ $clone_options['mwp_backup_tasks'] = serialize(get_option('mwp_backup_tasks'));
927
+ $clone_options['mwp_notifications'] = serialize(get_option('mwp_notifications'));
928
+ $clone_options['mwp_pageview_alerts'] = serialize(get_option('mwp_pageview_alerts'));
929
+
930
+
931
+ } else {
932
+ $restore_options = array();
933
+ $restore_options['mwp_notifications'] = get_option('mwp_notifications');
934
+ $restore_options['mwp_pageview_alerts'] = get_option('mwp_pageview_alerts');
935
+ $restore_options['user_hit_count'] = get_option('user_hit_count');
936
+ }
937
+
938
+
939
+ chdir(ABSPATH);
940
+ $unzip = $this->get_unzip();
941
+ $command = "$unzip -o $backup_file";
942
+ ob_start();
943
+ $result = $this->mmb_exec($command);
944
+ ob_get_clean();
945
+
946
+ if (!$result) { //fallback to pclzip
947
+ define('PCLZIP_TEMPORARY_DIR', MWP_BACKUP_DIR . '/');
948
+ require_once ABSPATH . '/wp-admin/includes/class-pclzip.php';
949
+ $archive = new PclZip($backup_file);
950
+ $result = $archive->extract(PCLZIP_OPT_PATH, ABSPATH, PCLZIP_OPT_REPLACE_NEWER);
951
+ }
952
+
953
+ if ($unlink_file) {
954
+ @unlink($backup_file);
955
+ }
956
+
957
+ if (!$result) {
958
+ return array(
959
+ 'error' => 'Failed to unzip files. pclZip error (' . $archive->error_code . '): .' . $archive->error_string
960
+ );
961
+ }
962
+
963
+ $db_result = $this->restore_db();
964
+
965
+ if (!$db_result) {
966
+ return array(
967
+ 'error' => 'Error restoring database.'
968
+ );
969
+ } else if(is_array($db_result) && isset($db_result['error'])){
970
+ return array(
971
+ 'error' => $db_result['error']
972
+ );
973
+ }
974
+
975
+ } else {
976
+ return array(
977
+ 'error' => 'Error restoring. Cannot find backup file.'
978
+ );
979
+ }
980
+
981
+ $this->wpdb_reconnect();
982
+
983
+ //Replace options and content urls
984
+ if ($overwrite) {
985
+ //Get New Table prefix
986
+ $new_table_prefix = trim($this->get_table_prefix());
987
+ //Retrieve old wp_config
988
+ @unlink(ABSPATH . 'wp-config.php');
989
+ //Replace table prefix
990
+ $lines = file(ABSPATH . 'mwp-temp-wp-config.php');
991
+
992
+ foreach ($lines as $line) {
993
+ if (strstr($line, '$table_prefix')) {
994
+ $line = '$table_prefix = "' . $new_table_prefix . '";' . PHP_EOL;
995
+ }
996
+ file_put_contents(ABSPATH . 'wp-config.php', $line, FILE_APPEND);
997
+ }
998
+
999
+ @unlink(ABSPATH . 'mwp-temp-wp-config.php');
1000
+
1001
+ //Replace options
1002
+ $query = "SELECT option_value FROM " . $new_table_prefix . "options WHERE option_name = 'home'";
1003
+ $old = $wpdb->get_var($wpdb->prepare($query));
1004
+ $old = rtrim($old, "/");
1005
+ $query = "UPDATE " . $new_table_prefix . "options SET option_value = '$home' WHERE option_name = 'home'";
1006
+ $wpdb->query($wpdb->prepare($query));
1007
+ $query = "UPDATE " . $new_table_prefix . "options SET option_value = '$home' WHERE option_name = 'siteurl'";
1008
+ $wpdb->query($wpdb->prepare($query));
1009
+ //Replace content urls
1010
+ $query = "UPDATE " . $new_table_prefix . "posts SET post_content = REPLACE (post_content, '$old','$home') WHERE post_content REGEXP 'src=\"(.*)$old(.*)\"' OR post_content REGEXP 'href=\"(.*)$old(.*)\"'";
1011
+ $wpdb->query($wpdb->prepare($query));
1012
+
1013
+ if (trim($new_password)) {
1014
+ $new_password = wp_hash_password($new_password);
1015
+ }
1016
+ if (!trim($clone_from_url) && !trim($mwp_clone)) {
1017
+ if ($new_user && $new_password) {
1018
+ $query = "UPDATE " . $new_table_prefix . "users SET user_login = '$new_user', user_pass = '$new_password' WHERE user_login = '$old_user'";
1019
+ $wpdb->query($wpdb->prepare($query));
1020
+ }
1021
+ } else {
1022
+ if ($clone_from_url) {
1023
+ if ($new_user && $new_password) {
1024
+ $query = "UPDATE " . $new_table_prefix . "users SET user_pass = '$new_password' WHERE user_login = '$new_user'";
1025
+ $wpdb->query($wpdb->prepare($query));
1026
+ }
1027
+ }
1028
+
1029
+ if ($mwp_clone) {
1030
+ if ($admin_email) {
1031
+ //Clean Install
1032
+ $query = "UPDATE " . $new_table_prefix . "options SET option_value = '$admin_email' WHERE option_name = 'admin_email'";
1033
+ $wpdb->query($wpdb->prepare($query));
1034
+ $query = "SELECT * FROM " . $new_table_prefix . "users LIMIT 1";
1035
+ $temp_user = $wpdb->get_row($query);
1036
+ if (!empty($temp_user)) {
1037
+ $query = "UPDATE " . $new_table_prefix . "users SET user_email='$admin_email', user_login = '$new_user', user_pass = '$new_password' WHERE user_login = '$temp_user->user_login'";
1038
+ $wpdb->query($wpdb->prepare($query));
1039
+ }
1040
+
1041
+ }
1042
+ }
1043
+ }
1044
+
1045
+ if (is_array($clone_options) && !empty($clone_options)) {
1046
+ foreach ($clone_options as $key => $option) {
1047
+ if (!empty($key)) {
1048
+ $query = "SELECT option_value FROM " . $new_table_prefix . "options WHERE option_name = '$key'";
1049
+ $res = $wpdb->get_var($query);
1050
+ if ($res == false) {
1051
+ $query = "INSERT INTO " . $new_table_prefix . "options (option_value,option_name) VALUES('$option','$key')";
1052
+ $wpdb->query($wpdb->prepare($query));
1053
+ } else {
1054
+ $query = "UPDATE " . $new_table_prefix . "options SET option_value = '$option' WHERE option_name = '$key'";
1055
+ $wpdb->query($wpdb->prepare($query));
1056
+ }
1057
+ }
1058
+ }
1059
+ }
1060
+
1061
+ //Remove hit count
1062
+ $query = "DELETE FROM " . $new_table_prefix . "options WHERE option_name = 'user_hit_count'";
1063
+ $wpdb->query($wpdb->prepare($query));
1064
+
1065
+ //Check for .htaccess permalinks update
1066
+ $this->replace_htaccess($home);
1067
+ } else {
1068
+
1069
+ //restore worker options
1070
+ if (is_array($restore_options) && !empty($restore_options)) {
1071
+ foreach ($restore_options as $key => $option) {
1072
+ update_option($key,$option);
1073
+ }
1074
+ }
1075
+
1076
+ }
1077
+
1078
+
1079
+
1080
+
1081
+ return true;
1082
+ }
1083
+
1084
+ function restore_db()
1085
+ {
1086
+ global $wpdb;
1087
+ $paths = $this->check_mysql_paths();
1088
+ $file_path = ABSPATH . 'mwp_db';
1089
+ @chmod($file_path,0755);
1090
+ $file_name = glob($file_path . '/*.sql');
1091
+ $file_name = $file_name[0];
1092
+
1093
+ if(!$file_name){
1094
+ return array('error' => 'Cannot access database file.');
1095
+ }
1096
+
1097
+ $brace = (substr(PHP_OS, 0, 3) == 'WIN') ? '"' : '';
1098
+ $command = $brace . $paths['mysql'] . $brace . ' --host="' . DB_HOST . '" --user="' . DB_USER . '" --password="' . DB_PASSWORD . '" ' . DB_NAME . ' < ' . $brace . $file_name . $brace;
1099
+
1100
+ ob_start();
1101
+ $result = $this->mmb_exec($command);
1102
+ ob_get_clean();
1103
+ if (!$result) {
1104
+ //try php
1105
+ $this->restore_db_php($file_name);
1106
+ }
1107
+
1108
+
1109
+ @unlink($file_name);
1110
+ return true;
1111
+ }
1112
+
1113
+ function restore_db_php($file_name)
1114
+ {
1115
+ global $wpdb;
1116
+ $current_query = '';
1117
+ // Read in entire file
1118
+ $lines = file($file_name);
1119
+ // Loop through each line
1120
+ foreach ($lines as $line) {
1121
+ // Skip it if it's a comment
1122
+ if (substr($line, 0, 2) == '--' || $line == '')
1123
+ continue;
1124
+
1125
+ // Add this line to the current query
1126
+ $current_query .= $line;
1127
+ // If it has a semicolon at the end, it's the end of the query
1128
+ if (substr(trim($line), -1, 1) == ';') {
1129
+ // Perform the query
1130
+ $result = $wpdb->query($current_query);
1131
+ if ($result === false)
1132
+ return false;
1133
+ // Reset temp variable to empty
1134
+ $current_query = '';
1135
+ }
1136
+ }
1137
+
1138
+ @unlink($file_name);
1139
+ return true;
1140
+ }
1141
+
1142
+ function get_table_prefix()
1143
+ {
1144
+ $lines = file(ABSPATH . 'wp-config.php');
1145
+ foreach ($lines as $line) {
1146
+ if (strstr($line, '$table_prefix')) {
1147
+ $pattern = "/(\'|\")[^(\'|\")]*/";
1148
+ preg_match($pattern, $line, $matches);
1149
+ $prefix = substr($matches[0], 1);
1150
+ return $prefix;
1151
+ break;
1152
+ }
1153
+ }
1154
+ return 'wp_'; //default
1155
+ }
1156
+
1157
+ function optimize_tables()
1158
+ {
1159
+ global $wpdb;
1160
+ $query = 'SHOW TABLE STATUS FROM ' . DB_NAME;
1161
+ $tables = $wpdb->get_results($wpdb->prepare($query), ARRAY_A);
1162
+ foreach ($tables as $table) {
1163
+ if (in_array($table['Engine'], array(
1164
+ 'MyISAM',
1165
+ 'ISAM',
1166
+ 'HEAP',
1167
+ 'MEMORY',
1168
+ 'ARCHIVE'
1169
+ )))
1170
+ $table_string .= $table['Name'] . ",";
1171
+ elseif ($table['Engine'] == 'InnoDB') {
1172
+ $optimize = $wpdb->query("ALTER TABLE {$table['Name']} ENGINE=InnoDB");
1173
+ }
1174
+ }
1175
+
1176
+ $table_string = rtrim($table_string);
1177
+ $optimize = $wpdb->query("OPTIMIZE TABLE $table_string");
1178
+
1179
+ return $optimize ? true : false;
1180
+ }
1181
+
1182
+ ### Function: Auto Detect MYSQL and MYSQL Dump Paths
1183
+ function check_mysql_paths()
1184
+ {
1185
+ global $wpdb;
1186
+ $paths = array(
1187
+ 'mysql' => '',
1188
+ 'mysqldump' => ''
1189
+ );
1190
+ if (substr(PHP_OS, 0, 3) == 'WIN') {
1191
+ $mysql_install = $wpdb->get_row("SHOW VARIABLES LIKE 'basedir'");
1192
+ if ($mysql_install) {
1193
+ $install_path = str_replace('\\', '/', $mysql_install->Value);
1194
+ $paths['mysql'] = $install_path . 'bin/mysql.exe';
1195
+ $paths['mysqldump'] = $install_path . 'bin/mysqldump.exe';
1196
+ } else {
1197
+ $paths['mysql'] = 'mysql.exe';
1198
+ $paths['mysqldump'] = 'mysqldump.exe';
1199
+ }
1200
+ } else {
1201
+ $paths['mysql'] = $this->mmb_exec('which mysql', true);
1202
+ if (empty($paths['mysql']))
1203
+ $paths['mysql'] = 'mysql'; // try anyway
1204
+
1205
+ $paths['mysqldump'] = $this->mmb_exec('which mysqldump', true);
1206
+ if (empty($paths['mysqldump']))
1207
+ $paths['mysqldump'] = 'mysqldump'; // try anyway
1208
+
1209
+ }
1210
+
1211
+
1212
+ return $paths;
1213
+ }
1214
+
1215
+ //Check if exec, system, passthru functions exist
1216
+ function check_sys()
1217
+ {
1218
+ if ($this->mmb_function_exists('exec'))
1219
+ return 'exec';
1220
+
1221
+ if ($this->mmb_function_exists('system'))
1222
+ return 'system';
1223
+
1224
+ if ($this->mmb_function_exists('passhtru'))
1225
+ return 'passthru';
1226
+
1227
+ return false;
1228
+
1229
+ }
1230
+
1231
+ function mmb_exec($command, $string = false, $rawreturn = false)
1232
+ {
1233
+ if ($command == '')
1234
+ return false;
1235
+
1236
+ if ($this->mmb_function_exists('exec')) {
1237
+ $log = @exec($command, $output, $return);
1238
+
1239
+ if ($string)
1240
+ return $log;
1241
+ if ($rawreturn)
1242
+ return $return;
1243
+
1244
+ return $return ? false : true;
1245
+ } elseif ($this->mmb_function_exists('system')) {
1246
+ $log = @system($command, $return);
1247
+
1248
+ if ($string)
1249
+ return $log;
1250
+
1251
+ if ($rawreturn)
1252
+ return $return;
1253
+
1254
+ return $return ? false : true;
1255
+ } elseif ($this->mmb_function_exists('passthru') && !$string) {
1256
+ $log = passthru($command, $return);
1257
+
1258
+ if ($rawreturn)
1259
+ return $return;
1260
+
1261
+ return $return ? false : true;
1262
+ }
1263
+
1264
+ if ($rawreturn)
1265
+ return -1;
1266
+
1267
+ return false;
1268
+ }
1269
+
1270
+ function get_zip()
1271
+ {
1272
+ $zip = $this->mmb_exec('which zip', true);
1273
+ if (!$zip)
1274
+ $zip = "zip";
1275
+ return $zip;
1276
+ }
1277
+
1278
+ function get_unzip()
1279
+ {
1280
+ $unzip = $this->mmb_exec('which unzip', true);
1281
+ if (!$unzip)
1282
+ $unzip = "unzip";
1283
+ return $unzip;
1284
+ }
1285
+
1286
+ function check_backup_compat()
1287
+ {
1288
+ $reqs = array();
1289
+ if (strpos($_SERVER['DOCUMENT_ROOT'], '/') === 0) {
1290
+ $reqs['Server OS']['status'] = 'Linux (or compatible)';
1291
+ $reqs['Server OS']['pass'] = true;
1292
+ } else {
1293
+ $reqs['Server OS']['status'] = 'Windows';
1294
+ $reqs['Server OS']['pass'] = true;
1295
+ $pass = false;
1296
+ }
1297
+ $reqs['PHP Version']['status'] = phpversion();
1298
+ if ((float) phpversion() >= 5.1) {
1299
+ $reqs['PHP Version']['pass'] = true;
1300
+ } else {
1301
+ $reqs['PHP Version']['pass'] = false;
1302
+ $pass = false;
1303
+ }
1304
+
1305
+
1306
+ if (is_writable(WP_CONTENT_DIR)) {
1307
+ $reqs['Backup Folder']['status'] = "writable";
1308
+ $reqs['Backup Folder']['pass'] = true;
1309
+ } else {
1310
+ $reqs['Backup Folder']['status'] = "not writable";
1311
+ $reqs['Backup Folder']['pass'] = false;
1312
+ }
1313
+
1314
+
1315
+ $file_path = MWP_BACKUP_DIR;
1316
+ $reqs['Backup Folder']['status'] .= ' (' . $file_path . ')';
1317
+
1318
+ if ($func = $this->check_sys()) {
1319
+ $reqs['Execute Function']['status'] = $func;
1320
+ $reqs['Execute Function']['pass'] = true;
1321
+ } else {
1322
+ $reqs['Execute Function']['status'] = "not found";
1323
+ $reqs['Execute Function']['info'] = "(will try PHP replacement)";
1324
+ $reqs['Execute Function']['pass'] = false;
1325
+ }
1326
+ $reqs['Zip']['status'] = $this->get_zip();
1327
+
1328
+ $reqs['Zip']['pass'] = true;
1329
+
1330
+
1331
+
1332
+ $reqs['Unzip']['status'] = $this->get_unzip();
1333
+
1334
+ $reqs['Unzip']['pass'] = true;
1335
+
1336
+ $paths = $this->check_mysql_paths();
1337
+
1338
+ if (!empty($paths['mysqldump'])) {
1339
+ $reqs['MySQL Dump']['status'] = $paths['mysqldump'];
1340
+ $reqs['MySQL Dump']['pass'] = true;
1341
+ } else {
1342
+ $reqs['MySQL Dump']['status'] = "not found";
1343
+ $reqs['MySQL Dump']['info'] = "(will try PHP replacement)";
1344
+ $reqs['MySQL Dump']['pass'] = false;
1345
+ }
1346
+
1347
+ $exec_time = ini_get('max_execution_time');
1348
+ $reqs['Execution time']['status'] = $exec_time ? $exec_time . "s" : 'unknown';
1349
+ $reqs['Execution time']['pass'] = true;
1350
+
1351
+ $mem_limit = ini_get('memory_limit');
1352
+ $reqs['Memory limit']['status'] = $mem_limit ? $mem_limit : 'unknown';
1353
+ $reqs['Memory limit']['pass'] = true;
1354
+
1355
+
1356
+ return $reqs;
1357
+ }
1358
+
1359
+ function email_backup($args)
1360
+ {
1361
+ $email = $args['email'];
1362
+
1363
+ if (!is_email($email)) {
1364
+ return array(
1365
+ 'error' => 'Your email (' . $email . ') is not correct'
1366
+ );
1367
+ }
1368
+ $backup_file = $args['file_path'];
1369
+ $task_name = isset($args['task_name']) ? $args['task_name'] : '';
1370
+ if (file_exists($backup_file) && $email) {
1371
+ $attachments = array(
1372
+ $backup_file
1373
+ );
1374
+ $headers = 'From: ManageWP <no-reply@managewp.com>' . "\r\n";
1375
+ $subject = "ManageWP - " . $task_name . " - " . $this->site_name;
1376
+ ob_start();
1377
+ $result = wp_mail($email, $subject, $subject, $headers, $attachments);
1378
+ ob_end_clean();
1379
+
1380
+ }
1381
+
1382
+ if (!$result) {
1383
+ return array(
1384
+ 'error' => 'Email not sent. Maybe your backup is too big for email or email server is not available on your website.'
1385
+ );
1386
+ }
1387
+ return true;
1388
+
1389
+ }
1390
+
1391
+ function ftp_backup($args)
1392
+ {
1393
+ extract($args);
1394
+ //Args: $ftp_username, $ftp_password, $ftp_hostname, $backup_file, $ftp_remote_folder, $ftp_site_folder
1395
+ $port = $ftp_port ? $ftp_port : 21; //default port is 21
1396
+ if ($ftp_ssl) {
1397
+ if (function_exists('ftp_ssl_connect')) {
1398
+ $conn_id = ftp_ssl_connect($ftp_hostname,$port);
1399
+ } else {
1400
+ return array(
1401
+ 'error' => 'Your server doesn\'t support SFTP',
1402
+ 'partial' => 1
1403
+ );
1404
+ }
1405
+ } else {
1406
+ if (function_exists('ftp_connect')) {
1407
+ $conn_id = ftp_connect($ftp_hostname,$port);
1408
+ if ($conn_id === false) {
1409
+ return array(
1410
+ 'error' => 'Failed to connect to ' . $ftp_hostname,
1411
+ 'partial' => 1
1412
+ );
1413
+ }
1414
+ } else {
1415
+ return array(
1416
+ 'error' => 'Your server doesn\'t support FTP',
1417
+ 'partial' => 1
1418
+ );
1419
+ }
1420
+ }
1421
+ $login = @ftp_login($conn_id, $ftp_username, $ftp_password);
1422
+ if ($login === false) {
1423
+ return array(
1424
+ 'error' => 'FTP login failed for ' . $ftp_username . ', ' . $ftp_password,
1425
+ 'partial' => 1
1426
+ );
1427
+ }
1428
+
1429
+ if($ftp_passive){
1430
+ @ftp_pasv($conn_id,true);
1431
+ }
1432
+
1433
+ @ftp_mkdir($conn_id, $ftp_remote_folder);
1434
+ if ($ftp_site_folder) {
1435
+ $ftp_remote_folder .= '/' . $this->site_name;
1436
+ }
1437
+ @ftp_mkdir($conn_id, $ftp_remote_folder);
1438
+
1439
+ $upload = @ftp_put($conn_id, $ftp_remote_folder . '/' . basename($backup_file), $backup_file, FTP_BINARY);
1440
+
1441
+ if ($upload === false) { //Try ascii
1442
+ $upload = @ftp_put($conn_id, $ftp_remote_folder . '/' . basename($backup_file), $backup_file, FTP_ASCII);
1443
+ }
1444
+ ftp_close($conn_id);
1445
+
1446
+ if ($upload === false) {
1447
+ return array(
1448
+ 'error' => 'Failed to upload file to FTP. Please check your specified path.',
1449
+ 'partial' => 1
1450
+ );
1451
+ }
1452
+
1453
+ return true;
1454
+ }
1455
+
1456
+ function remove_ftp_backup($args)
1457
+ {
1458
+ extract($args);
1459
+ //Args: $ftp_username, $ftp_password, $ftp_hostname, $backup_file, $ftp_remote_folder
1460
+ $port = $ftp_port ? $ftp_port : 21; //default port is 21
1461
+ if ($ftp_ssl && function_exists('ftp_ssl_connect')) {
1462
+ $conn_id = ftp_ssl_connect($ftp_hostname,$port);
1463
+ } else if (function_exists('ftp_connect')) {
1464
+ $conn_id = ftp_connect($ftp_hostname,$port);
1465
+ }
1466
+
1467
+ if ($conn_id) {
1468
+ $login = @ftp_login($conn_id, $ftp_username, $ftp_password);
1469
+ if ($ftp_site_folder)
1470
+ $ftp_remote_folder .= '/' . $this->site_name;
1471
+
1472
+ if($ftp_passive){
1473
+ @ftp_pasv($conn_id,true);
1474
+ }
1475
+
1476
+ $delete = ftp_delete($conn_id, $ftp_remote_folder . '/' . $backup_file);
1477
+
1478
+ ftp_close($conn_id);
1479
+ }
1480
+
1481
+ }
1482
+
1483
+ function get_ftp_backup($args)
1484
+ {
1485
+ extract($args);
1486
+ //Args: $ftp_username, $ftp_password, $ftp_hostname, $backup_file, $ftp_remote_folder
1487
+ $port = $ftp_port ? $ftp_port : 21; //default port is 21
1488
+ if ($ftp_ssl && function_exists('ftp_ssl_connect')) {
1489
+ $conn_id = ftp_ssl_connect($ftp_hostname,$port);
1490
+
1491
+ } else if (function_exists('ftp_connect')) {
1492
+ $conn_id = ftp_connect($ftp_hostname,$port);
1493
+ if ($conn_id === false) {
1494
+ return false;
1495
+ }
1496
+ }
1497
+ $login = @ftp_login($conn_id, $ftp_username, $ftp_password);
1498
+ if ($login === false) {
1499
+ return false;
1500
+ } else {
1501
+ }
1502
+
1503
+ if ($ftp_site_folder)
1504
+ $ftp_remote_folder .= '/' . $this->site_name;
1505
+
1506
+ if($ftp_passive){
1507
+ @ftp_pasv($conn_id,true);
1508
+ }
1509
+
1510
+ $temp = ABSPATH . 'mwp_temp_backup.zip';
1511
+ $get = ftp_get($conn_id, $temp, $ftp_remote_folder . '/' . $backup_file, FTP_BINARY);
1512
+ if ($get === false) {
1513
+ return false;
1514
+ } else {
1515
+ }
1516
+ ftp_close($conn_id);
1517
+
1518
+ return $temp;
1519
+ }
1520
+
1521
+ function dropbox_backup($args)
1522
+ {
1523
+
1524
+ extract($args);
1525
+
1526
+ if(isset($consumer_secret) && !empty($consumer_secret)){
1527
+ //New way
1528
+ require_once('lib/dropbox.oauth.php');
1529
+
1530
+ $dropbox = new Dropbox($consumer_key, $consumer_secret);
1531
+ $dropbox->setOAuthToken($oauth_token);
1532
+ $dropbox->setOAuthTokenSecret($oauth_token_secret);
1533
+
1534
+ if ($dropbox_site_folder == true)
1535
+ $dropbox_destination .= '/' . $this->site_name;
1536
+
1537
+ try{
1538
+
1539
+ $dropbox->filesPost($dropbox_destination, $backup_file,true);
1540
+
1541
+ } catch(Exception $e){
1542
+ return array(
1543
+ 'error' => 'Dropbox upload error. '.$e->getMessage()
1544
+ );
1545
+ }
1546
+
1547
+ return true;
1548
+
1549
+ } else {
1550
+ //old way
1551
+ require_once('lib/dropbox.php');
1552
+
1553
+ //$email, $password, $backup_file, $destination, $dropbox_site_folder
1554
+
1555
+ $size = ceil(filesize($backup_file) / 1024);
1556
+ if ($size > 300000) {
1557
+ return array(
1558
+ 'error' => 'Cannot upload file to Dropbox. Dropbox has upload limit of 300Mb per file.',
1559
+ 'partial' => 1
1560
+ );
1561
+ }
1562
+
1563
+ if ($dropbox_site_folder == true)
1564
+ $dropbox_destination .= '/' . $this->site_name;
1565
+
1566
+ try {
1567
+ $uploader = new DropboxUploader($dropbox_username, $dropbox_password);
1568
+ $uploader->upload($backup_file, $dropbox_destination);
1569
+ }
1570
+ catch (Exception $e) {
1571
+ return array(
1572
+ 'error' => $e->getMessage(),
1573
+ 'partial' => 1
1574
+ );
1575
+ }
1576
+
1577
+ return true;
1578
+ }
1579
+
1580
+ }
1581
+
1582
+ function remove_dropbox_backup($args){
1583
+ extract($args);
1584
+ if(isset($consumer_secret) && !empty($consumer_secret)){
1585
+ //New way
1586
+ require_once('lib/dropbox.oauth.php');
1587
+
1588
+ $dropbox = new Dropbox($consumer_key, $consumer_secret);
1589
+ $dropbox->setOAuthToken($oauth_token);
1590
+ $dropbox->setOAuthTokenSecret($oauth_token_secret);
1591
+
1592
+ if ($dropbox_site_folder == true)
1593
+ $dropbox_destination .= '/' . $this->site_name;
1594
+
1595
+ try{
1596
+ $dropbox->fileopsDelete($dropbox_destination.'/'.$backup_file, true);
1597
+ } catch(Exception $e){
1598
+
1599
+ }
1600
+ }
1601
+ }
1602
+
1603
+ function get_dropbox_backup($args){
1604
+ extract($args);
1605
+
1606
+ if(isset($consumer_secret) && !empty($consumer_secret)){
1607
+ //New way
1608
+ require_once('lib/dropbox.oauth.php');
1609
+
1610
+ $dropbox = new Dropbox($consumer_key, $consumer_secret);
1611
+ $dropbox->setOAuthToken($oauth_token);
1612
+ $dropbox->setOAuthTokenSecret($oauth_token_secret);
1613
+
1614
+ if ($dropbox_site_folder == true)
1615
+ $dropbox_destination .= '/' . $this->site_name;
1616
+
1617
+ $temp = ABSPATH . 'mwp_temp_backup.zip';
1618
+
1619
+ try{
1620
+ $file = $dropbox->filesGet($dropbox_destination.'/'.$backup_file, true);
1621
+
1622
+ if(isset($file['data']) && !empty($file['data']) )
1623
+ $stream = base64_decode($file['data']);
1624
+ else
1625
+ return false;
1626
+
1627
+ $handle = @fopen($temp, 'w+');
1628
+ $result = fwrite($handle,$stream);
1629
+ fclose($handle);
1630
+
1631
+ if($result)
1632
+ return $temp;
1633
+ else
1634
+ return false;
1635
+
1636
+ } catch(Exception $e){
1637
+
1638
+
1639
+ return false;
1640
+ }
1641
+
1642
+ } else {
1643
+ return false;
1644
+ }
1645
+
1646
+
1647
+ }
1648
+
1649
+ function amazons3_backup($args)
1650
+ {
1651
+ if ($this->mmb_function_exists('curl_init')) {
1652
+ require_once('lib/s3.php');
1653
+ extract($args);
1654
+
1655
+ if ($as3_site_folder == true)
1656
+ $as3_directory .= '/' . $this->site_name;
1657
+
1658
+ $endpoint = isset($as3_bucket_region) ? $as3_bucket_region : 's3.amazonaws.com';
1659
+ try{
1660
+ $s3 = new mwpS3(trim($as3_access_key), trim(str_replace(' ', '+', $as3_secure_key)), false, $endpoint);
1661
+ if ($s3->putObjectFile($backup_file, $as3_bucket, $as3_directory . '/' . basename($backup_file), mwpS3::ACL_PRIVATE)) {
1662
+ return true;
1663
+ } else {
1664
+
1665
+ return array(
1666
+ 'error' => 'Failed to upload to Amazon S3. Please check your details and set upload/delete permissions on your bucket.',
1667
+ 'partial' => 1
1668
+ );
1669
+ }
1670
+
1671
+ }catch (Exception $e){
1672
+ $err = $e->getMessage();
1673
+ if($err){
1674
+ return array(
1675
+ 'error' => 'Failed to upload to AmazonS3 ('.$err.').'
1676
+ );
1677
+ } else {
1678
+ return array(
1679
+ 'error' => 'Failed to upload to Amazon S3.'
1680
+ );
1681
+ }
1682
+ }
1683
+
1684
+ } else {
1685
+ return array(
1686
+ 'error' => 'You cannot use Amazon S3 on your server. Please enable curl extension first.',
1687
+ 'partial' => 1
1688
+ );
1689
+ }
1690
+ }
1691
+
1692
+ function remove_amazons3_backup($args)
1693
+ {
1694
+ if ($this->mmb_function_exists('curl_init')) {
1695
+ require_once('lib/s3.php');
1696
+ extract($args);
1697
+ if ($as3_site_folder == true)
1698
+ $as3_directory .= '/' . $this->site_name;
1699
+ $endpoint = isset($as3_bucket_region) ? $as3_bucket_region : 's3.amazonaws.com';
1700
+ try{
1701
+ $s3 = new mwpS3(trim($as3_access_key), trim(str_replace(' ', '+', $as3_secure_key)), false, $endpoint);
1702
+ $s3->deleteObject($as3_bucket, $as3_directory . '/' . $backup_file);
1703
+ } catch (Exception $e){
1704
+
1705
+ }
1706
+ }
1707
+ }
1708
+
1709
+ function get_amazons3_backup($args)
1710
+ {
1711
+ require_once('lib/s3.php');
1712
+ extract($args);
1713
+ $endpoint = isset($as3_bucket_region) ? $as3_bucket_region : 's3.amazonaws.com';
1714
+ $temp = '';
1715
+ try{
1716
+ $s3 = new mwpS3($as3_access_key, str_replace(' ', '+', $as3_secure_key), false, $endpoint);
1717
+ if ($as3_site_folder == true)
1718
+ $as3_directory .= '/' . $this->site_name;
1719
+
1720
+ $temp = ABSPATH . 'mwp_temp_backup.zip';
1721
+ $s3->getObject($as3_bucket, $as3_directory . '/' . $backup_file, $temp);
1722
+ } catch (Exception $e){
1723
+ return $temp;
1724
+ }
1725
+ return $temp;
1726
+ }
1727
+
1728
+ function schedule_next($type, $schedule)
1729
+ {
1730
+ $schedule = explode("|", $schedule);
1731
+ if (empty($schedule))
1732
+ return false;
1733
+ switch ($type) {
1734
+
1735
+ case 'daily':
1736
+
1737
+ if (isset($schedule[1]) && $schedule[1]) {
1738
+ $delay_time = $schedule[1] * 60;
1739
+ }
1740
+
1741
+ $current_hour = date("H");
1742
+ $schedule_hour = $schedule[0];
1743
+ if ($current_hour >= $schedule_hour)
1744
+ $time = mktime($schedule_hour, 0, 0, date("m"), date("d") + 1, date("Y"));
1745
+ else
1746
+ $time = mktime($schedule_hour, 0, 0, date("m"), date("d"), date("Y"));
1747
+ break;
1748
+
1749
+
1750
+ case 'weekly':
1751
+ if (isset($schedule[2]) && $schedule[2]) {
1752
+ $delay_time = $schedule[2] * 60;
1753
+ }
1754
+ $current_weekday = date('w');
1755
+ $schedule_weekday = $schedule[1];
1756
+ $current_hour = date("H");
1757
+ $schedule_hour = $schedule[0];
1758
+
1759
+ if ($current_weekday > $schedule_weekday)
1760
+ $weekday_offset = 7 - ($week_day - $task_schedule[1]);
1761
+ else
1762
+ $weekday_offset = $schedule_weekday - $current_weekday;
1763
+
1764
+
1765
+ if (!$weekday_offset) { //today is scheduled weekday
1766
+ if ($current_hour >= $schedule_hour)
1767
+ $time = mktime($schedule_hour, 0, 0, date("m"), date("d") + 7, date("Y"));
1768
+ else
1769
+ $time = mktime($schedule_hour, 0, 0, date("m"), date("d"), date("Y"));
1770
+ } else {
1771
+ $time = mktime($schedule_hour, 0, 0, date("m"), date("d") + $weekday_offset, date("Y"));
1772
+ }
1773
+
1774
+ break;
1775
+
1776
+ case 'monthly':
1777
+ if (isset($schedule[2]) && $schedule[2]) {
1778
+ $delay_time = $schedule[2] * 60;
1779
+ }
1780
+ $current_monthday = date('j');
1781
+ $schedule_monthday = $schedule[1];
1782
+ $current_hour = date("H");
1783
+ $schedule_hour = $schedule[0];
1784
+
1785
+ if ($current_monthday > $schedule_monthday) {
1786
+ $time = mktime($schedule_hour, 0, 0, date("m") + 1, $schedule_monthday, date("Y"));
1787
+ } else if ($current_monthday < $schedule_monthday) {
1788
+ $time = mktime($schedule_hour, 0, 0, date("m"), $schedule_monthday, date("Y"));
1789
+ } else if ($current_monthday == $schedule_monthday) {
1790
+ if ($current_hour >= $schedule_hour)
1791
+ $time = mktime($schedule_hour, 0, 0, date("m") + 1, $schedule_monthday, date("Y"));
1792
+ else
1793
+ $time = mktime($schedule_hour, 0, 0, date("m"), $schedule_monthday, date("Y"));
1794
+ break;
1795
+ }
1796
+
1797
+ break;
1798
+ default:
1799
+ break;
1800
+ }
1801
+
1802
+ if (isset($delay_time) && $delay_time) {
1803
+ $time += $delay_time;
1804
+ }
1805
+
1806
+
1807
+ return $time;
1808
+
1809
+ }
1810
+
1811
+ //Parse task arguments for info on master
1812
+ function get_backup_stats()
1813
+ {
1814
+ $stats = array();
1815
+ $tasks = $this->tasks;
1816
+ if (is_array($tasks) && !empty($tasks)) {
1817
+ foreach ($tasks as $task_name => $info) {
1818
+ if (is_array($info['task_results']) && !empty($info['task_results'])) {
1819
+ foreach ($info['task_results'] as $key => $result) {
1820
+ if (isset($result['server']) && !isset($result['error'])) {
1821
+ if (!file_exists($result['server']['file_path'])) {
1822
+ $info['task_results'][$key]['error'] = 'Backup created but manually removed from server.';
1823
+ }
1824
+ }
1825
+ }
1826
+ }
1827
+ if (is_array($info['task_results']))
1828
+ $stats[$task_name] = array_values($info['task_results']);
1829
+
1830
+ }
1831
+ }
1832
+ return $stats;
1833
+ }
1834
+
1835
+ function get_next_schedules()
1836
+ {
1837
+ $stats = array();
1838
+ $tasks = $this->tasks;
1839
+ if (is_array($tasks) && !empty($tasks)) {
1840
+ foreach ($tasks as $task_name => $info) {
1841
+ $stats[$task_name] = isset($info['task_args']['next']) ? $info['task_args']['next'] : array();
1842
+ }
1843
+ }
1844
+ return $stats;
1845
+ }
1846
+
1847
+ function remove_old_backups($task_name)
1848
+ {
1849
+
1850
+ //Check for previous failed backups first
1851
+ $this->cleanup();
1852
+
1853
+ //Remove by limit
1854
+ $backups = $this->tasks;
1855
+ if ($task_name == 'Backup Now') {
1856
+ $num = 0;
1857
+ } else {
1858
+ $num = 1;
1859
+ }
1860
+
1861
+
1862
+ if ((count($backups[$task_name]['task_results']) - $num) >= $backups[$task_name]['task_args']['limit']) {
1863
+ //how many to remove ?
1864
+ $remove_num = (count($backups[$task_name]['task_results']) - $num - $backups[$task_name]['task_args']['limit']) + 1;
1865
+ for ($i = 0; $i < $remove_num; $i++) {
1866
+ //Remove from the server
1867
+ if (isset($backups[$task_name]['task_results'][$i]['server'])) {
1868
+ @unlink($backups[$task_name]['task_results'][$i]['server']['file_path']);
1869
+ }
1870
+
1871
+ //Remove from ftp
1872
+ if (isset($backups[$task_name]['task_results'][$i]['ftp']) && isset($backups[$task_name]['task_args']['account_info']['mwp_ftp'])) {
1873
+ $ftp_file = $backups[$task_name]['task_results'][$i]['ftp'];
1874
+ $args = $backups[$task_name]['task_args']['account_info']['mwp_ftp'];
1875
+ $args['backup_file'] = $ftp_file;
1876
+ $this->remove_ftp_backup($args);
1877
+ }
1878
+
1879
+ if (isset($backups[$task_name]['task_results'][$i]['amazons3']) && isset($backups[$task_name]['task_args']['account_info']['mwp_amazon_s3'])) {
1880
+ $amazons3_file = $backups[$task_name]['task_results'][$i]['amazons3'];
1881
+ $args = $backups[$task_name]['task_args']['account_info']['mwp_amazon_s3'];
1882
+ $args['backup_file'] = $amazons3_file;
1883
+ $this->remove_amazons3_backup($args);
1884
+ }
1885
+
1886
+ if (isset($backups[$task_name]['task_results'][$i]['dropbox']) && isset($backups[$task_name]['task_args']['account_info']['mwp_dropbox'])) {
1887
+ //To do: dropbox remove
1888
+ $dropbox_file = $backups[$task_name]['task_results'][$i]['dropbox'];
1889
+ $args = $backups[$task_name]['task_args']['account_info']['mwp_dropbox'];
1890
+ $args['backup_file'] = $dropbox_file;
1891
+ $this->remove_dropbox_backup($args);
1892
+ }
1893
+
1894
+ //Remove database backup info
1895
+ unset($backups[$task_name]['task_results'][$i]);
1896
+
1897
+ } //end foreach
1898
+
1899
+ if (is_array($backups[$task_name]['task_results']))
1900
+ $backups[$task_name]['task_results'] = array_values($backups[$task_name]['task_results']);
1901
+ else
1902
+ $backups[$task_name]['task_results']=array();
1903
+
1904
+ $this->update_tasks($backups);
1905
+ //update_option('mwp_backup_tasks', $backups);
1906
+ }
1907
+ }
1908
+
1909
+ /**
1910
+ * Delete specified backup
1911
+ * Args: $task_name, $result_id
1912
+ */
1913
+
1914
+ function delete_backup($args)
1915
+ {
1916
+ if (empty($args))
1917
+ return false;
1918
+ extract($args);
1919
+
1920
+ $tasks = $this->tasks;
1921
+ $task = $tasks[$task_name];
1922
+ $backups = $task['task_results'];
1923
+ $backup = $backups[$result_id];
1924
+
1925
+ if (isset($backup['server'])) {
1926
+ @unlink($backup['server']['file_path']);
1927
+ }
1928
+
1929
+ //Remove from ftp
1930
+ if (isset($backup['ftp'])) {
1931
+ $ftp_file = $backup['ftp'];
1932
+ $args = $tasks[$task_name]['task_args']['account_info']['mwp_ftp'];
1933
+ $args['backup_file'] = $ftp_file;
1934
+ $this->remove_ftp_backup($args);
1935
+ }
1936
+
1937
+ if (isset($backup['amazons3'])) {
1938
+ $amazons3_file = $backup['amazons3'];
1939
+ $args = $tasks[$task_name]['task_args']['account_info']['mwp_amazon_s3'];
1940
+ $args['backup_file'] = $amazons3_file;
1941
+ $this->remove_amazons3_backup($args);
1942
+ }
1943
+
1944
+ if (isset($backup['dropbox'])) {
1945
+ $dropbox_file = $backup['dropbox'];
1946
+ $args = $tasks[$task_name]['task_args']['account_info']['mwp_dropbox'];
1947
+ $args['backup_file'] = $dropbox_file;
1948
+ $this->remove_dropbox_backup($args);
1949
+ }
1950
+
1951
+ unset($backups[$result_id]);
1952
+
1953
+ if (count($backups)) {
1954
+ $tasks[$task_name]['task_results'] = $backups;
1955
+ } else {
1956
+ unset($tasks[$task_name]['task_results']);
1957
+ }
1958
+
1959
+ $this->update_tasks($tasks);
1960
+ //update_option('mwp_backup_tasks', $tasks);
1961
+ return true;
1962
+
1963
+ }
1964
+
1965
+ function cleanup()
1966
+ {
1967
+ $tasks = $this->tasks;
1968
+ $backup_folder = WP_CONTENT_DIR . '/' . md5('mmb-worker') . '/mwp_backups/';
1969
+ $backup_folder_new = MWP_BACKUP_DIR . '/';
1970
+ $files = glob($backup_folder . "*");
1971
+ $new = glob($backup_folder_new . "*");
1972
+
1973
+ //Failed db files first
1974
+ $db_folder = MWP_DB_DIR . '/';
1975
+ $db_files = glob($db_folder . "*");
1976
+ if (is_array($db_files) && !empty($db_files)) {
1977
+ foreach ($db_files as $file) {
1978
+ @unlink($file);
1979
+ }
1980
+ @rmdir(MWP_DB_DIR);
1981
+ }
1982
+
1983
+
1984
+ //clean_old folder?
1985
+ if ((isset($files[0]) && basename($files[0]) == 'index.php' && count($files) == 1) || (empty($files))) {
1986
+ foreach ($files as $file) {
1987
+ @unlink($file);
1988
+ }
1989
+ @rmdir(WP_CONTENT_DIR . '/' . md5('mmb-worker') . '/mwp_backups');
1990
+ @rmdir(WP_CONTENT_DIR . '/' . md5('mmb-worker'));
1991
+ }
1992
+
1993
+
1994
+ foreach ($new as $b) {
1995
+ $files[] = $b;
1996
+ }
1997
+ $deleted = array();
1998
+
1999
+ if (is_array($files) && count($files)) {
2000
+ $results = array();
2001
+ if (!empty($tasks)) {
2002
+ foreach ((array) $tasks as $task) {
2003
+ if (isset($task['task_results']) && count($task['task_results'])) {
2004
+ foreach ($task['task_results'] as $backup) {
2005
+ if (isset($backup['server'])) {
2006
+ $results[] = $backup['server']['file_path'];
2007
+ }
2008
+ }
2009
+ }
2010
+ }
2011
+ }
2012
+
2013
+ $num_deleted = 0;
2014
+ foreach ($files as $file) {
2015
+ if (!in_array($file, $results) && basename($file) != 'index.php') {
2016
+ @unlink($file);
2017
+ $deleted[] = basename($file);
2018
+ $num_deleted++;
2019
+ }
2020
+ }
2021
+ }
2022
+
2023
+
2024
+
2025
+ return $deleted;
2026
+ }
2027
+
2028
+
2029
+ function remote_backup_now($args)
2030
+ {
2031
+ @ini_set('memory_limit', '256M');
2032
+ @set_time_limit(600); //ten minutes
2033
+
2034
+
2035
+
2036
+ if (!empty($args))
2037
+ extract($args);
2038
+
2039
+ $tasks = $this->tasks;
2040
+ $task = $tasks['Backup Now'];
2041
+
2042
+ if (!empty($task)) {
2043
+ extract($task['task_args']);
2044
+ }
2045
+
2046
+ $results = $task['task_results'];
2047
+
2048
+ if (is_array($results) && count($results)) {
2049
+ $backup_file = $results[count($results) - 1]['server']['file_path'];
2050
+ }
2051
+
2052
+ if ($backup_file && file_exists($backup_file)) {
2053
+ //FTP, Amazon S3 or Dropbox
2054
+ if (isset($account_info['mwp_ftp']) && !empty($account_info['mwp_ftp'])) {
2055
+ $account_info['mwp_ftp']['backup_file'] = $backup_file;
2056
+ $return = $this->ftp_backup($account_info['mwp_ftp']);
2057
+ }
2058
+
2059
+ if (isset($account_info['mwp_amazon_s3']) && !empty($account_info['mwp_amazon_s3'])) {
2060
+ $account_info['mwp_amazon_s3']['backup_file'] = $backup_file;
2061
+ $return = $this->amazons3_backup($account_info['mwp_amazon_s3']);
2062
+ }
2063
+
2064
+ if (isset($account_info['mwp_dropbox']) && !empty($account_info['mwp_dropbox'])) {
2065
+ $account_info['mwp_dropbox']['backup_file'] = $backup_file;
2066
+ $return = $this->dropbox_backup($account_info['mwp_dropbox']);
2067
+ }
2068
+
2069
+ if (isset($account_info['mwp_email']) && !empty($account_info['mwp_email'])) {
2070
+ $account_info['mwp_email']['file_path'] = $backup_file;
2071
+ $account_info['mwp_email']['task_name'] = 'Backup Now';
2072
+ $return = $this->email_backup($account_info['mwp_email']);
2073
+ }
2074
+
2075
+
2076
+ if ($return == true && $del_host_file) {
2077
+ @unlink($backup_file);
2078
+ unset($tasks['Backup Now']['task_results'][count($results) - 1]['server']);
2079
+ $this->update_tasks($tasks);
2080
+ //update_option('mwp_backup_tasks', $tasks);
2081
+ }
2082
+
2083
+
2084
+
2085
+ } else {
2086
+ $return = array(
2087
+ 'error' => 'Backup file not found on your server. Please try again.'
2088
+ );
2089
+ }
2090
+
2091
+ return $return;
2092
+
2093
+ }
2094
+
2095
+ function validate_task($args, $url)
2096
+ {
2097
+ if (!class_exists('WP_Http')) {
2098
+ include_once(ABSPATH . WPINC . '/class-http.php');
2099
+ }
2100
+ $params = array();
2101
+ $params['body'] = $args;
2102
+ $result = wp_remote_post($url, $params);
2103
+ if (is_array($result) && $result['body'] == 'mwp_delete_task') {
2104
+ //$tasks = $this->get_backup_settings();
2105
+ $tasks = $this->tasks;
2106
+ unset($tasks[$args['task_name']]);
2107
+ $this->update_tasks($tasks);
2108
+ $this->cleanup();
2109
+ exit;
2110
+ } elseif(is_array($result) && $result['body'] == 'mwp_pause_task'){
2111
+ return 'paused';
2112
+ }
2113
+
2114
+ return 'ok';
2115
+ }
2116
+
2117
+ function update_status($task_name, $status, $completed = false)
2118
+ {
2119
+ /* Statuses:
2120
+ 0 - Backup started
2121
+ 1 - DB dump
2122
+ 2 - DB ZIP
2123
+ 3 - Files ZIP
2124
+ 4 - Amazon S3
2125
+ 5 - Dropbox
2126
+ 6 - FTP
2127
+ 7 - Email
2128
+ 100 - Finished
2129
+ */
2130
+ if ($task_name != 'Backup Now') {
2131
+ $tasks = $this->tasks;
2132
+ $index = count($tasks[$task_name]['task_results']) - 1;
2133
+ if (!is_array($tasks[$task_name]['task_results'][$index]['status'])) {
2134
+ $tasks[$task_name]['task_results'][$index]['status'] = array();
2135
+ }
2136
+ if (!$completed) {
2137
+ $tasks[$task_name]['task_results'][$index]['status'][] = (int) $status * (-1);
2138
+ } else {
2139
+ $status_index = count($tasks[$task_name]['task_results'][$index]['status']) - 1;
2140
+ $tasks[$task_name]['task_results'][$index]['status'][$status_index] = abs($tasks[$task_name]['task_results'][$index]['status'][$status_index]);
2141
+ }
2142
+
2143
+ $this->update_tasks($tasks);
2144
+ //update_option('mwp_backup_tasks',$tasks);
2145
+ }
2146
+ }
2147
+
2148
+ function update_tasks($tasks)
2149
+ {
2150
+ $this->tasks = $tasks;
2151
+ update_option('mwp_backup_tasks', $tasks);
2152
+ }
2153
+
2154
+ function wpdb_reconnect(){
2155
+ global $wpdb;
2156
+ //Reconnect to avoid timeout problem after ZIP files
2157
+ if(class_exists('wpdb') && function_exists('wp_set_wpdb_vars')){
2158
+ @mysql_close($wpdb->dbh);
2159
+ $wpdb = new wpdb( DB_USER, DB_PASSWORD, DB_NAME, DB_HOST );
2160
+ wp_set_wpdb_vars();
2161
+ }
2162
+ }
2163
+
2164
+ function replace_htaccess($url)
2165
+ {
2166
+ $file = @file_get_contents(ABSPATH.'.htaccess');
2167
+ if ($file && strlen($file)) {
2168
+ $args = parse_url($url);
2169
+ $string = rtrim($args['path'], "/");
2170
+ $regex = "/BEGIN WordPress(.*?)RewriteBase(.*?)\n(.*?)RewriteRule \.(.*?)index\.php(.*?)END WordPress/sm";
2171
+ $replace = "BEGIN WordPress$1RewriteBase " . $string . "/ \n$3RewriteRule . " . $string . "/index.php$5END WordPress";
2172
+ $file = preg_replace($regex, $replace, $file);
2173
+ @file_put_contents(ABSPATH.'.htaccess', $file);
2174
+ }
2175
+ }
2176
+
2177
+ function check_cron_remove(){
2178
+ if(empty($this->tasks) || (count($this->tasks) == 1 && isset($this->tasks['Backup Now'])) ){
2179
+ wp_clear_scheduled_hook('mwp_backup_tasks');
2180
+ exit;
2181
+ }
2182
+ }
2183
+
2184
+ }
2185
+
2186
  ?>
comment.class.php CHANGED
@@ -1,43 +1,43 @@
1
- <?php
2
- /*************************************************************
3
- *
4
- * post.class.php
5
- *
6
- * Create remote post
7
- *
8
- *
9
- * Copyright (c) 2011 Prelovac Media
10
- * www.prelovac.com
11
- **************************************************************/
12
-
13
- class MMB_Comment extends MMB_Core
14
- {
15
- function __construct()
16
- {
17
- parent::__construct();
18
- }
19
-
20
- function change_status($args)
21
- {
22
-
23
- global $wpdb;
24
- $comment_id = $args['comment_id'];
25
- $status = $args['status'];
26
-
27
- if ( 'approve' == $status )
28
- $status_sql = '1';
29
- elseif ( 'unapprove' == $status )
30
- $status_sql = '0';
31
- elseif ( 'spam' == $status )
32
- $status_sql = 'spam';
33
- elseif ( 'trash' == $status )
34
- $status_sql = 'trash';
35
- $sql = "update ".$wpdb->prefix."comments set comment_approved = '$status_sql' where comment_ID = '$comment_id'";
36
- $success = $wpdb->query($sql);
37
-
38
-
39
- return $success;
40
- }
41
-
42
- }
43
  ?>
1
+ <?php
2
+ /*************************************************************
3
+ *
4
+ * post.class.php
5
+ *
6
+ * Create remote post
7
+ *
8
+ *
9
+ * Copyright (c) 2011 Prelovac Media
10
+ * www.prelovac.com
11
+ **************************************************************/
12
+
13
+ class MMB_Comment extends MMB_Core
14
+ {
15
+ function __construct()
16
+ {
17
+ parent::__construct();
18
+ }
19
+
20
+ function change_status($args)
21
+ {
22
+
23
+ global $wpdb;
24
+ $comment_id = $args['comment_id'];
25
+ $status = $args['status'];
26
+
27
+ if ( 'approve' == $status )
28
+ $status_sql = '1';
29
+ elseif ( 'unapprove' == $status )
30
+ $status_sql = '0';
31
+ elseif ( 'spam' == $status )
32
+ $status_sql = 'spam';
33
+ elseif ( 'trash' == $status )
34
+ $status_sql = 'trash';
35
+ $sql = "update ".$wpdb->prefix."comments set comment_approved = '$status_sql' where comment_ID = '$comment_id'";
36
+ $success = $wpdb->query($sql);
37
+
38
+
39
+ return $success;
40
+ }
41
+
42
+ }
43
  ?>
core.class.php CHANGED
@@ -1,660 +1,665 @@
1
- <?php
2
- /*************************************************************
3
- *
4
- * core.class.php
5
- *
6
- * Upgrade Plugins
7
- *
8
- *
9
- * Copyright (c) 2011 Prelovac Media
10
- * www.prelovac.com
11
- **************************************************************/
12
- class MMB_Core extends MMB_Helper
13
- {
14
- var $name;
15
- var $slug;
16
- var $settings;
17
- var $remote_client;
18
- var $comment_instance;
19
- var $plugin_instance;
20
- var $theme_instance;
21
- var $wp_instance;
22
- var $post_instance;
23
- var $stats_instance;
24
- var $search_instance;
25
- var $links_instance;
26
- var $user_instance;
27
- var $backup_instance;
28
- var $installer_instance;
29
- var $mmb_multisite;
30
- var $network_admin_install;
31
- private $action_call;
32
- private $action_params;
33
- private $mmb_pre_init_actions;
34
- private $mmb_pre_init_filters;
35
- private $mmb_init_actions;
36
-
37
-
38
- function __construct()
39
- {
40
- global $mmb_plugin_dir, $wpmu_version, $blog_id, $_mmb_plugin_actions, $_mmb_item_filter;
41
-
42
- $_mmb_plugin_actions = array();
43
- $this->name = 'Manage Multiple Blogs';
44
- $this->slug = 'manage-multiple-blogs';
45
- $this->action_call = null;
46
- $this->action_params = null;
47
-
48
-
49
- $this->settings = get_option($this->slug);
50
- if (!$this->settings) {
51
- $this->settings = array(
52
- 'blogs' => array(),
53
- 'current_blog' => array(
54
- 'type' => null
55
- )
56
- );
57
- $this->save_options();
58
- }
59
- if ( function_exists('is_multisite') ) {
60
- if ( is_multisite() ) {
61
- $this->mmb_multisite = $blog_id;
62
- $this->network_admin_install = get_option('mmb_network_admin_install');
63
- }
64
- } else if (!empty($wpmu_version)) {
65
- $this->mmb_multisite = $blog_id;
66
- $this->network_admin_install = get_option('mmb_network_admin_install');
67
- } else {
68
- $this->mmb_multisite = false;
69
- $this->network_admin_install = null;
70
- }
71
-
72
- // admin notices
73
- if ( !get_option('_worker_public_key') ){
74
- if( $this->mmb_multisite ){
75
- if( is_network_admin() && $this->network_admin_install == '1'){
76
- add_action('network_admin_notices', array( &$this, 'network_admin_notice' ));
77
- } else if( $this->network_admin_install != '1' ){
78
- $parent_key = $this->get_parent_blog_option('_worker_public_key');
79
- if(empty($parent_key))
80
- add_action('admin_notices', array( &$this, 'admin_notice' ));
81
- }
82
- } else {
83
- add_action('admin_notices', array( &$this, 'admin_notice' ));
84
- }
85
- }
86
-
87
- // default filters
88
- //$this->mmb_pre_init_filters['get_stats']['mmb_stats_filter'][] = array('MMB_Stats', 'pre_init_stats'); // called with class name, use global $mmb_core inside the function instead of $this
89
- $this->mmb_pre_init_filters['get_stats']['mmb_stats_filter'][] = 'mmb_pre_init_stats';
90
-
91
- $_mmb_item_filter['pre_init_stats'] = array( 'core_update', 'hit_counter', 'comments', 'backups', 'posts', 'drafts', 'scheduled' );
92
- $_mmb_item_filter['get'] = array( 'updates', 'errors' );
93
-
94
- $this->mmb_pre_init_actions = array(
95
- 'backup_req' => 'mmb_get_backup_req',
96
- );
97
-
98
- $this->mmb_init_actions = array(
99
- 'do_upgrade' => 'mmb_do_upgrade',
100
- 'get_stats' => 'mmb_stats_get',
101
- 'remove_site' => 'mmb_remove_site',
102
- 'backup_clone' => 'mmb_backup_now',
103
- 'restore' => 'mmb_restore_now',
104
- 'optimize_tables' => 'mmb_optimize_tables',
105
- 'check_wp_version' => 'mmb_wp_checkversion',
106
- 'create_post' => 'mmb_post_create',
107
- 'update_worker' => 'mmb_update_worker_plugin',
108
- 'change_comment_status' => 'mmb_change_comment_status',
109
- 'change_post_status' => 'mmb_change_post_status',
110
- 'get_comment_stats' => 'mmb_comment_stats_get',
111
- 'install_addon' => 'mmb_install_addon',
112
- 'add_link' => 'mmb_add_link',
113
- 'add_user' => 'mmb_add_user',
114
- 'email_backup' => 'mmb_email_backup',
115
- 'check_backup_compat' => 'mmb_check_backup_compat',
116
- 'scheduled_backup' => 'mmb_scheduled_backup',
117
- 'run_task' => 'mmb_run_task_now',
118
- 'execute_php_code' => 'mmb_execute_php_code',
119
- 'delete_backup' => 'mmm_delete_backup',
120
- 'remote_backup_now' => 'mmb_remote_backup_now',
121
- 'set_notifications' => 'mmb_set_notifications',
122
- 'clean_orphan_backups' => 'mmb_clean_orphan_backups',
123
- 'get_users' => 'mmb_get_users',
124
- 'edit_users' => 'mmb_edit_users',
125
- 'get_plugins_themes' => 'mmb_get_plugins_themes',
126
- 'edit_plugins_themes' => 'mmb_edit_plugins_themes',
127
- 'worker_brand' => 'mmb_worker_brand',
128
- 'set_alerts' => 'mmb_set_alerts',
129
- 'maintenance' => 'mmb_maintenance_mode'
130
- );
131
-
132
- add_action('rightnow_end', array( &$this, 'add_right_now_info' ));
133
- add_action('admin_init', array(&$this,'admin_actions'));
134
- add_action('init', array( &$this, 'mmb_remote_action'), 9999);
135
- add_action('setup_theme', 'mmb_parse_request');
136
- add_action('set_auth_cookie', array( &$this, 'mmb_set_auth_cookie'));
137
- add_action('set_logged_in_cookie', array( &$this, 'mmb_set_logged_in_cookie'));
138
-
139
- }
140
-
141
- function mmb_remote_action(){
142
- if($this->action_call != null){
143
- $params = isset($this->action_params) && $this->action_params != null ? $this->action_params : array();
144
- call_user_func($this->action_call, $params);
145
- }
146
- }
147
-
148
- function register_action_params( $action = false, $params = array() ){
149
-
150
- if(isset($this->mmb_pre_init_actions[$action]) && function_exists($this->mmb_pre_init_actions[$action])){
151
- call_user_func($this->mmb_pre_init_actions[$action], $params);
152
- }
153
-
154
- if(isset($this->mmb_init_actions[$action]) && function_exists($this->mmb_init_actions[$action])){
155
- $this->action_call = $this->mmb_init_actions[$action];
156
- $this->action_params = $params;
157
-
158
- if( isset($this->mmb_pre_init_filters[$action]) && !empty($this->mmb_pre_init_filters[$action])){
159
- global $mmb_filters;
160
-
161
- foreach($this->mmb_pre_init_filters[$action] as $_name => $_functions){
162
- if(!empty($_functions)){
163
- $data = array();
164
-
165
- foreach($_functions as $_k => $_callback){
166
- if(is_array($_callback) && method_exists($_callback[0], $_callback[1]) ){
167
- $data = call_user_func( $_callback, $params );
168
- } elseif (is_string($_callback) && function_exists( $_callback )){
169
- $data = call_user_func( $_callback, $params );
170
- }
171
- $mmb_filters[$_name] = isset($mmb_filters[$_name]) && !empty($mmb_filters[$_name]) ? array_merge($mmb_filters[$_name], $data) : $data;
172
- add_filter( $_name, create_function( '$a' , 'global $mmb_filters; return array_merge($a, $mmb_filters["'.$_name.'"]);') );
173
- }
174
- }
175
-
176
- }
177
- }
178
- return true;
179
- }
180
- return false;
181
- }
182
-
183
- /**
184
- * Add notice to network admin dashboard for security reasons
185
- *
186
- */
187
- function network_admin_notice()
188
- {
189
- echo '<div class="error" style="text-align: center;"><p style="color: red; font-size: 14px; font-weight: bold;">Attention !</p><p>
190
- Please add this site and your network blogs, with your network adminstrator username, to your <a target="_blank" href="http://managewp.com/wp-admin">ManageWP.com</a> account now to remove this notice or "Network Deactivate" the Worker plugin to avoid <a target="_blank" href="http://managewp.com/user-guide/security">security issues</a>.
191
- </p></div>';
192
- }
193
-
194
-
195
- /**
196
- * Add notice to admin dashboard for security reasons
197
- *
198
- */
199
- function admin_notice()
200
- {
201
- echo '<div class="error" style="text-align: center;"><p style="color: red; font-size: 14px; font-weight: bold;">Attention !</p><p>
202
- Please add this site now to your <a target="_blank" href="http://managewp.com/wp-admin">ManageWP.com</a> account. Or deactivate the Worker plugin to avoid <a target="_blank" href="http://managewp.com/user-guide/security">security issues</a>.
203
- </p></div>';
204
- }
205
-
206
- /**
207
- * Add an item into the Right Now Dashboard widget
208
- * to inform that the blog can be managed remotely
209
- *
210
- */
211
- function add_right_now_info()
212
- {
213
- echo '<div class="mmb-slave-info">
214
- <p>This site can be managed remotely.</p>
215
- </div>';
216
- }
217
-
218
- /**
219
- * Get parent blog options
220
- *
221
- */
222
- private function get_parent_blog_option( $option_name = '' )
223
- {
224
- global $wpdb;
225
- $option = $wpdb->get_var( $wpdb->prepare( "SELECT `option_value` FROM {$wpdb->base_prefix}options WHERE option_name = '{$option_name}' LIMIT 1" ) );
226
- return $option;
227
- }
228
-
229
- /**
230
- * Gets an instance of the Comment class
231
- *
232
- */
233
- function get_comment_instance()
234
- {
235
- if (!isset($this->comment_instance)) {
236
- $this->comment_instance = new MMB_Comment();
237
- }
238
-
239
- return $this->comment_instance;
240
- }
241
-
242
- /**
243
- * Gets an instance of the Plugin class
244
- *
245
- */
246
- function get_plugin_instance()
247
- {
248
- if (!isset($this->plugin_instance)) {
249
- $this->plugin_instance = new MMB_Plugin();
250
- }
251
-
252
- return $this->plugin_instance;
253
- }
254
-
255
- /**
256
- * Gets an instance of the Theme class
257
- *
258
- */
259
- function get_theme_instance()
260
- {
261
- if (!isset($this->theme_instance)) {
262
- $this->theme_instance = new MMB_Theme();
263
- }
264
-
265
- return $this->theme_instance;
266
- }
267
-
268
-
269
- /**
270
- * Gets an instance of MMB_Post class
271
- *
272
- */
273
- function get_post_instance()
274
- {
275
- if (!isset($this->post_instance)) {
276
- $this->post_instance = new MMB_Post();
277
- }
278
-
279
- return $this->post_instance;
280
- }
281
-
282
- /**
283
- * Gets an instance of Blogroll class
284
- *
285
- */
286
- function get_blogroll_instance()
287
- {
288
- if (!isset($this->blogroll_instance)) {
289
- $this->blogroll_instance = new MMB_Blogroll();
290
- }
291
-
292
- return $this->blogroll_instance;
293
- }
294
-
295
-
296
-
297
- /**
298
- * Gets an instance of the WP class
299
- *
300
- */
301
- function get_wp_instance()
302
- {
303
- if (!isset($this->wp_instance)) {
304
- $this->wp_instance = new MMB_WP();
305
- }
306
-
307
- return $this->wp_instance;
308
- }
309
-
310
- /**
311
- * Gets an instance of User
312
- *
313
- */
314
- function get_user_instance()
315
- {
316
- if (!isset($this->user_instance)) {
317
- $this->user_instance = new MMB_User();
318
- }
319
-
320
- return $this->user_instance;
321
- }
322
-
323
- /**
324
- * Gets an instance of stats class
325
- *
326
- */
327
- function get_stats_instance()
328
- {
329
- if (!isset($this->stats_instance)) {
330
- $this->stats_instance = new MMB_Stats();
331
- }
332
- return $this->stats_instance;
333
- }
334
- /**
335
- * Gets an instance of search class
336
- *
337
- */
338
- function get_search_instance()
339
- {
340
- if (!isset($this->search_instance)) {
341
- $this->search_instance = new MMB_Search();
342
- }
343
- //return $this->search_instance;
344
- return $this->search_instance;
345
- }
346
- /**
347
- * Gets an instance of stats class
348
- *
349
- */
350
- function get_backup_instance()
351
- {
352
- if (!isset($this->backup_instance)) {
353
- $this->backup_instance = new MMB_Backup();
354
- }
355
-
356
- return $this->backup_instance;
357
- }
358
-
359
- /**
360
- * Gets an instance of links class
361
- *
362
- */
363
- function get_link_instance()
364
- {
365
- if (!isset($this->link_instance)) {
366
- $this->link_instance = new MMB_Link();
367
- }
368
-
369
- return $this->link_instance;
370
- }
371
-
372
- function get_installer_instance()
373
- {
374
- if (!isset($this->installer_instance)) {
375
- $this->installer_instance = new MMB_Installer();
376
- }
377
- return $this->installer_instance;
378
- }
379
-
380
- /**
381
- * Plugin install callback function
382
- * Check PHP version
383
- */
384
- function install() {
385
-
386
- global $wpdb, $_wp_using_ext_object_cache, $current_user;
387
- $_wp_using_ext_object_cache = false;
388
-
389
- //delete plugin options, just in case
390
- if ($this->mmb_multisite != false) {
391
- $network_blogs = $wpdb->get_results($wpdb->prepare("select `blog_id`, `site_id` from `{$wpdb->blogs}`"));
392
- if(!empty($network_blogs)){
393
- if( is_network_admin() ){
394
- update_option('mmb_network_admin_install', 1);
395
- foreach($network_blogs as $details){
396
- if($details->site_id == $details->blog_id)
397
- update_blog_option($details->blog_id, 'mmb_network_admin_install', 1);
398
- else
399
- update_blog_option($details->blog_id, 'mmb_network_admin_install', -1);
400
-
401
- delete_blog_option($blog_id, '_worker_nossl_key');
402
- delete_blog_option($blog_id, '_worker_public_key');
403
- delete_blog_option($blog_id, '_action_message_id');
404
- }
405
- } else {
406
- update_option('mmb_network_admin_install', -1);
407
- delete_option('_worker_nossl_key');
408
- delete_option('_worker_public_key');
409
- delete_option('_action_message_id');
410
- }
411
- }
412
- } else {
413
- delete_option('_worker_nossl_key');
414
- delete_option('_worker_public_key');
415
- delete_option('_action_message_id');
416
- }
417
-
418
- delete_option('mwp_backup_tasks');
419
- delete_option('mwp_notifications');
420
- delete_option('mwp_worker_brand');
421
- delete_option('mwp_pageview_alerts');
422
-
423
- }
424
-
425
- /**
426
- * Saves the (modified) options into the database
427
- *
428
- */
429
- function save_options()
430
- {
431
- if (get_option($this->slug)) {
432
- update_option($this->slug, $this->settings);
433
- } else {
434
- add_option($this->slug, $this->settings);
435
- }
436
- }
437
-
438
- /**
439
- * Deletes options for communication with master
440
- *
441
- */
442
- function uninstall( $deactivate = false )
443
- {
444
- global $current_user, $wpdb, $_wp_using_ext_object_cache;
445
- $_wp_using_ext_object_cache = false;
446
-
447
- if ($this->mmb_multisite != false) {
448
- $network_blogs = $wpdb->get_col($wpdb->prepare("select `blog_id` from `{$wpdb->blogs}`"));
449
- if(!empty($network_blogs)){
450
- if( is_network_admin() ){
451
- if( $deactivate ) {
452
- delete_option('mmb_network_admin_install');
453
- foreach($network_blogs as $blog_id){
454
- delete_blog_option($blog_id, 'mmb_network_admin_install');
455
- delete_blog_option($blog_id, '_worker_nossl_key');
456
- delete_blog_option($blog_id, '_worker_public_key');
457
- delete_blog_option($blog_id, '_action_message_id');
458
- delete_blog_option($blog_id, 'mwp_maintenace_mode');
459
- }
460
- }
461
- } else {
462
- if( $deactivate )
463
- delete_option('mmb_network_admin_install');
464
-
465
- delete_option('_worker_nossl_key');
466
- delete_option('_worker_public_key');
467
- delete_option('_action_message_id');
468
- }
469
- }
470
- } else {
471
- delete_option('_worker_nossl_key');
472
- delete_option('_worker_public_key');
473
- delete_option('_action_message_id');
474
- }
475
-
476
- //Delete options
477
- delete_option('mwp_maintenace_mode');
478
- delete_option('mwp_backup_tasks');
479
- wp_clear_scheduled_hook('mwp_backup_tasks');
480
- delete_option('mwp_notifications');
481
- wp_clear_scheduled_hook('mwp_notifications');
482
- delete_option('mwp_worker_brand');
483
- delete_option('mwp_pageview_alerts');
484
- }
485
-
486
-
487
- /**
488
- * Constructs a url (for ajax purpose)
489
- *
490
- * @param mixed $base_page
491
- */
492
- function construct_url($params = array(), $base_page = 'index.php')
493
- {
494
- $url = "$base_page?_wpnonce=" . wp_create_nonce($this->slug);
495
- foreach ($params as $key => $value) {
496
- $url .= "&$key=$value";
497
- }
498
-
499
- return $url;
500
- }
501
-
502
- /**
503
- * Worker update
504
- *
505
- */
506
- function update_worker_plugin($params)
507
- {
508
- extract($params);
509
- if ($download_url) {
510
- @include_once ABSPATH . 'wp-admin/includes/file.php';
511
- @include_once ABSPATH . 'wp-admin/includes/misc.php';
512
- @include_once ABSPATH . 'wp-admin/includes/template.php';
513
- @include_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
514
- @include_once ABSPATH . 'wp-admin/includes/screen.php';
515
-
516
- if (!$this->is_server_writable()) {
517
- return array(
518
- 'error' => 'Failed, please <a target="_blank" href="http://managewp.com/user-guide#ftp">add FTP details for automatic upgrades.</a></a>'
519
- );
520
- }
521
-
522
- ob_start();
523
- @unlink(dirname(__FILE__));
524
- $upgrader = new Plugin_Upgrader();
525
- $result = $upgrader->run(array(
526
- 'package' => $download_url,
527
- 'destination' => WP_PLUGIN_DIR,
528
- 'clear_destination' => true,
529
- 'clear_working' => true,
530
- 'hook_extra' => array(
531
- 'plugin' => 'worker/init.php'
532
- )
533
- ));
534
- ob_end_clean();
535
- if (is_wp_error($result) || !$result) {
536
- return array(
537
- 'error' => 'ManageWP Worker plugin could not be updated.'
538
- );
539
- } else {
540
- return array(
541
- 'success' => 'ManageWP Worker plugin successfully updated.'
542
- );
543
- }
544
- }
545
- return array(
546
- 'error' => 'Bad download path for worker installation file.'
547
- );
548
- }
549
-
550
- /**
551
- * Automatically logs in when called from Master
552
- *
553
- */
554
- function automatic_login()
555
- {
556
- $where = isset($_GET['mwp_goto']) ? $_GET['mwp_goto'] : false;
557
- $username = isset($_GET['username']) ? $_GET['username'] : '';
558
- $auto_login = isset($_GET['auto_login']) ? $_GET['auto_login'] : 0;
559
-
560
- if( !function_exists('is_user_logged_in') )
561
- include_once( ABSPATH.'wp-includes/pluggable.php' );
562
-
563
- if (( $auto_login && strlen(trim($username)) && !is_user_logged_in() ) || (isset($this->mmb_multisite) && $this->mmb_multisite )) {
564
- $signature = base64_decode($_GET['signature']);
565
- $message_id = trim($_GET['message_id']);
566
-
567
- $auth = $this->authenticate_message($where . $message_id, $signature, $message_id);
568
- if ($auth === true) {
569
-
570
- if (!headers_sent())
571
- header('P3P: CP="CAO PSA OUR"');
572
-
573
- if(!defined('MMB_USER_LOGIN'))
574
- define('MMB_USER_LOGIN', true);
575
-
576
- $siteurl = function_exists('get_site_option') ? get_site_option( 'siteurl' ) : get_option('siteurl');
577
- $user = $this->mmb_get_user_info($username);
578
- wp_set_current_user($user->ID);
579
-
580
- if(!defined('COOKIEHASH') || (isset($this->mmb_multisite) && $this->mmb_multisite) )
581
- wp_cookie_constants();
582
-
583
- wp_set_auth_cookie($user->ID);
584
- @mmb_worker_header();
585
-
586
- if((isset($this->mmb_multisite) && $this->mmb_multisite ) || isset($_REQUEST['mwpredirect'])){
587
- if(function_exists('wp_safe_redirect') && function_exists('admin_url')){
588
- wp_safe_redirect(admin_url($where));
589
- exit();
590
- }
591
- }
592
- } else {
593
- wp_die($auth['error']);
594
- }
595
- } elseif( is_user_logged_in() ) {
596
- @mmb_worker_header();
597
- if(isset($_REQUEST['mwpredirect'])){
598
- if(function_exists('wp_safe_redirect') && function_exists('admin_url')){
599
- wp_safe_redirect(admin_url($where));
600
- exit();
601
- }
602
- }
603
- }
604
- }
605
-
606
- function mmb_set_auth_cookie( $auth_cookie ){
607
- if(!defined('MMB_USER_LOGIN'))
608
- return false;
609
-
610
- if( !defined('COOKIEHASH') )
611
- wp_cookie_constants();
612
-
613
- $_COOKIE['wordpress_'.COOKIEHASH] = $auth_cookie;
614
-
615
- }
616
- function mmb_set_logged_in_cookie( $logged_in_cookie ){
617
- if(!defined('MMB_USER_LOGIN'))
618
- return false;
619
-
620
- if( !defined('COOKIEHASH') )
621
- wp_cookie_constants();
622
-
623
- $_COOKIE['wordpress_logged_in_'.COOKIEHASH] = $logged_in_cookie;
624
- }
625
-
626
- function admin_actions(){
627
- add_filter('all_plugins', array($this, 'worker_replace'));
628
- }
629
-
630
- function worker_replace($all_plugins){
631
- $replace = get_option("mwp_worker_brand");
632
- if(is_array($replace)){
633
- if($replace['name'] || $replace['desc'] || $replace['author'] || $replace['author_url']){
634
- $all_plugins['worker/init.php']['Name'] = $replace['name'];
635
- $all_plugins['worker/init.php']['Title'] = $replace['name'];
636
- $all_plugins['worker/init.php']['Description'] = $replace['desc'];
637
- $all_plugins['worker/init.php']['AuthorURI'] = $replace['author_url'];
638
- $all_plugins['worker/init.php']['Author'] = $replace['author'];
639
- $all_plugins['worker/init.php']['AuthorName'] = $replace['author'];
640
- $all_plugins['worker/init.php']['PluginURI'] = '';
641
- }
642
-
643
- if($replace['hide']){
644
- if (!function_exists('get_plugins')) {
645
- include_once(ABSPATH . 'wp-admin/includes/plugin.php');
646
- }
647
- $activated_plugins = get_option('active_plugins');
648
- if (!$activated_plugins)
649
- $activated_plugins = array();
650
- if(in_array('worker/init.php',$activated_plugins))
651
- unset($all_plugins['worker/init.php']);
652
- }
653
- }
654
-
655
-
656
- return $all_plugins;
657
- }
658
-
659
- }
 
 
 
 
 
660
  ?>
1
+ <?php
2
+ /*************************************************************
3
+ *
4
+ * core.class.php
5
+ *
6
+ * Upgrade Plugins
7
+ *
8
+ *
9
+ * Copyright (c) 2011 Prelovac Media
10
+ * www.prelovac.com
11
+ **************************************************************/
12
+ class MMB_Core extends MMB_Helper
13
+ {
14
+ var $name;
15
+ var $slug;
16
+ var $settings;
17
+ var $remote_client;
18
+ var $comment_instance;
19
+ var $plugin_instance;
20
+ var $theme_instance;
21
+ var $wp_instance;
22
+ var $post_instance;
23
+ var $stats_instance;
24
+ var $search_instance;
25
+ var $links_instance;
26
+ var $user_instance;
27
+ var $backup_instance;
28
+ var $installer_instance;
29
+ var $mmb_multisite;
30
+ var $network_admin_install;
31
+ private $action_call;
32
+ private $action_params;
33
+ private $mmb_pre_init_actions;
34
+ private $mmb_pre_init_filters;
35
+ private $mmb_init_actions;
36
+
37
+
38
+ function __construct()
39
+ {
40
+ global $mmb_plugin_dir, $wpmu_version, $blog_id, $_mmb_plugin_actions, $_mmb_item_filter;
41
+
42
+ $_mmb_plugin_actions = array();
43
+ $this->name = 'Manage Multiple Blogs';
44
+ $this->slug = 'manage-multiple-blogs';
45
+ $this->action_call = null;
46
+ $this->action_params = null;
47
+
48
+
49
+ $this->settings = get_option($this->slug);
50
+ if (!$this->settings) {
51
+ $this->settings = array(
52
+ 'blogs' => array(),
53
+ 'current_blog' => array(
54
+ 'type' => null
55
+ )
56
+ );
57
+ $this->save_options();
58
+ }
59
+ if ( function_exists('is_multisite') ) {
60
+ if ( is_multisite() ) {
61
+ $this->mmb_multisite = $blog_id;
62
+ $this->network_admin_install = get_option('mmb_network_admin_install');
63
+ }
64
+ } else if (!empty($wpmu_version)) {
65
+ $this->mmb_multisite = $blog_id;
66
+ $this->network_admin_install = get_option('mmb_network_admin_install');
67
+ } else {
68
+ $this->mmb_multisite = false;
69
+ $this->network_admin_install = null;
70
+ }
71
+
72
+ // admin notices
73
+ if ( !get_option('_worker_public_key') ){
74
+ if( $this->mmb_multisite ){
75
+ if( is_network_admin() && $this->network_admin_install == '1'){
76
+ add_action('network_admin_notices', array( &$this, 'network_admin_notice' ));
77
+ } else if( $this->network_admin_install != '1' ){
78
+ $parent_key = $this->get_parent_blog_option('_worker_public_key');
79
+ if(empty($parent_key))
80
+ add_action('admin_notices', array( &$this, 'admin_notice' ));
81
+ }
82
+ } else {
83
+ add_action('admin_notices', array( &$this, 'admin_notice' ));
84
+ }
85
+ }
86
+
87
+ // default filters
88
+ //$this->mmb_pre_init_filters['get_stats']['mmb_stats_filter'][] = array('MMB_Stats', 'pre_init_stats'); // called with class name, use global $mmb_core inside the function instead of $this
89
+ $this->mmb_pre_init_filters['get_stats']['mmb_stats_filter'][] = 'mmb_pre_init_stats';
90
+
91
+ $_mmb_item_filter['pre_init_stats'] = array( 'core_update', 'hit_counter', 'comments', 'backups', 'posts', 'drafts', 'scheduled' );
92
+ $_mmb_item_filter['get'] = array( 'updates', 'errors' );
93
+
94
+ $this->mmb_pre_init_actions = array(
95
+ 'backup_req' => 'mmb_get_backup_req',
96
+ );
97
+
98
+ $this->mmb_init_actions = array(
99
+ 'do_upgrade' => 'mmb_do_upgrade',
100
+ 'get_stats' => 'mmb_stats_get',
101
+ 'remove_site' => 'mmb_remove_site',
102
+ 'backup_clone' => 'mmb_backup_now',
103
+ 'restore' => 'mmb_restore_now',
104
+ 'optimize_tables' => 'mmb_optimize_tables',
105
+ 'check_wp_version' => 'mmb_wp_checkversion',
106
+ 'create_post' => 'mmb_post_create',
107
+ 'update_worker' => 'mmb_update_worker_plugin',
108
+ 'change_comment_status' => 'mmb_change_comment_status',
109
+ 'change_post_status' => 'mmb_change_post_status',
110
+ 'get_comment_stats' => 'mmb_comment_stats_get',
111
+ 'install_addon' => 'mmb_install_addon',
112
+ 'add_link' => 'mmb_add_link',
113
+ 'add_user' => 'mmb_add_user',
114
+ 'email_backup' => 'mmb_email_backup',
115
+ 'check_backup_compat' => 'mmb_check_backup_compat',
116
+ 'scheduled_backup' => 'mmb_scheduled_backup',
117
+ 'run_task' => 'mmb_run_task_now',
118
+ 'execute_php_code' => 'mmb_execute_php_code',
119
+ 'delete_backup' => 'mmm_delete_backup',
120
+ 'remote_backup_now' => 'mmb_remote_backup_now',
121
+ 'set_notifications' => 'mmb_set_notifications',
122
+ 'clean_orphan_backups' => 'mmb_clean_orphan_backups',
123
+ 'get_users' => 'mmb_get_users',
124
+ 'edit_users' => 'mmb_edit_users',
125
+ 'get_posts' => 'mmb_get_posts',
126
+ 'delete_post' => 'mmb_delete_post',
127
+ 'edit_posts' => 'mmb_edit_posts',
128
+ 'get_pages' => 'mmb_get_pages',
129
+ 'delete_page' => 'mmb_delete_page',
130
+ 'get_plugins_themes' => 'mmb_get_plugins_themes',
131
+ 'edit_plugins_themes' => 'mmb_edit_plugins_themes',
132
+ 'worker_brand' => 'mmb_worker_brand',
133
+ 'set_alerts' => 'mmb_set_alerts',
134
+ 'maintenance' => 'mmb_maintenance_mode'
135
+ );
136
+
137
+ add_action('rightnow_end', array( &$this, 'add_right_now_info' ));
138
+ add_action('admin_init', array(&$this,'admin_actions'));
139
+ add_action('init', array( &$this, 'mmb_remote_action'), 9999);
140
+ add_action('setup_theme', 'mmb_parse_request');
141
+ add_action('set_auth_cookie', array( &$this, 'mmb_set_auth_cookie'));
142
+ add_action('set_logged_in_cookie', array( &$this, 'mmb_set_logged_in_cookie'));
143
+
144
+ }
145
+
146
+ function mmb_remote_action(){
147
+ if($this->action_call != null){
148
+ $params = isset($this->action_params) && $this->action_params != null ? $this->action_params : array();
149
+ call_user_func($this->action_call, $params);
150
+ }
151
+ }
152
+
153
+ function register_action_params( $action = false, $params = array() ){
154
+
155
+ if(isset($this->mmb_pre_init_actions[$action]) && function_exists($this->mmb_pre_init_actions[$action])){
156
+ call_user_func($this->mmb_pre_init_actions[$action], $params);
157
+ }
158
+
159
+ if(isset($this->mmb_init_actions[$action]) && function_exists($this->mmb_init_actions[$action])){
160
+ $this->action_call = $this->mmb_init_actions[$action];
161
+ $this->action_params = $params;
162
+
163
+ if( isset($this->mmb_pre_init_filters[$action]) && !empty($this->mmb_pre_init_filters[$action])){
164
+ global $mmb_filters;
165
+
166
+ foreach($this->mmb_pre_init_filters[$action] as $_name => $_functions){
167
+ if(!empty($_functions)){
168
+ $data = array();
169
+
170
+ foreach($_functions as $_k => $_callback){
171
+ if(is_array($_callback) && method_exists($_callback[0], $_callback[1]) ){
172
+ $data = call_user_func( $_callback, $params );
173
+ } elseif (is_string($_callback) && function_exists( $_callback )){
174
+ $data = call_user_func( $_callback, $params );
175
+ }
176
+ $mmb_filters[$_name] = isset($mmb_filters[$_name]) && !empty($mmb_filters[$_name]) ? array_merge($mmb_filters[$_name], $data) : $data;
177
+ add_filter( $_name, create_function( '$a' , 'global $mmb_filters; return array_merge($a, $mmb_filters["'.$_name.'"]);') );
178
+ }
179
+ }
180
+
181
+ }
182
+ }
183
+ return true;
184
+ }
185
+ return false;
186
+ }
187
+
188
+ /**
189
+ * Add notice to network admin dashboard for security reasons
190
+ *
191
+ */
192
+ function network_admin_notice()
193
+ {
194
+ echo '<div class="error" style="text-align: center;"><p style="color: red; font-size: 14px; font-weight: bold;">Attention !</p><p>
195
+ Please add this site and your network blogs, with your network adminstrator username, to your <a target="_blank" href="http://managewp.com/wp-admin">ManageWP.com</a> account now to remove this notice or "Network Deactivate" the Worker plugin to avoid <a target="_blank" href="http://managewp.com/user-guide/security">security issues</a>.
196
+ </p></div>';
197
+ }
198
+
199
+
200
+ /**
201
+ * Add notice to admin dashboard for security reasons
202
+ *
203
+ */
204
+ function admin_notice()
205
+ {
206
+ echo '<div class="error" style="text-align: center;"><p style="color: red; font-size: 14px; font-weight: bold;">Attention !</p><p>
207
+ Please add this site now to your <a target="_blank" href="http://managewp.com/wp-admin">ManageWP.com</a> account. Or deactivate the Worker plugin to avoid <a target="_blank" href="http://managewp.com/user-guide/security">security issues</a>.
208
+ </p></div>';
209
+ }
210
+
211
+ /**
212
+ * Add an item into the Right Now Dashboard widget
213
+ * to inform that the blog can be managed remotely
214
+ *
215
+ */
216
+ function add_right_now_info()
217
+ {
218
+ echo '<div class="mmb-slave-info">
219
+ <p>This site can be managed remotely.</p>
220
+ </div>';
221
+ }
222
+
223
+ /**
224
+ * Get parent blog options
225
+ *
226
+ */
227
+ private function get_parent_blog_option( $option_name = '' )
228
+ {
229
+ global $wpdb;
230
+ $option = $wpdb->get_var( $wpdb->prepare( "SELECT `option_value` FROM {$wpdb->base_prefix}options WHERE option_name = '{$option_name}' LIMIT 1" ) );
231
+ return $option;
232
+ }
233
+
234
+ /**
235
+ * Gets an instance of the Comment class
236
+ *
237
+ */
238
+ function get_comment_instance()
239
+ {
240
+ if (!isset($this->comment_instance)) {
241
+ $this->comment_instance = new MMB_Comment();
242
+ }
243
+
244
+ return $this->comment_instance;
245
+ }
246
+
247
+ /**
248
+ * Gets an instance of the Plugin class
249
+ *
250
+ */
251
+ function get_plugin_instance()
252
+ {
253
+ if (!isset($this->plugin_instance)) {
254
+ $this->plugin_instance = new MMB_Plugin();
255
+ }
256
+
257
+ return $this->plugin_instance;
258
+ }
259
+
260
+ /**
261
+ * Gets an instance of the Theme class
262
+ *
263
+ */
264
+ function get_theme_instance()
265
+ {
266
+ if (!isset($this->theme_instance)) {
267
+ $this->theme_instance = new MMB_Theme();
268
+ }
269
+
270
+ return $this->theme_instance;
271
+ }
272
+
273
+
274
+ /**
275
+ * Gets an instance of MMB_Post class
276
+ *
277
+ */
278
+ function get_post_instance()
279
+ {
280
+ if (!isset($this->post_instance)) {
281
+ $this->post_instance = new MMB_Post();
282
+ }
283
+
284
+ return $this->post_instance;
285
+ }
286
+
287
+ /**
288
+ * Gets an instance of Blogroll class
289
+ *
290
+ */
291
+ function get_blogroll_instance()
292
+ {
293
+ if (!isset($this->blogroll_instance)) {
294
+ $this->blogroll_instance = new MMB_Blogroll();
295
+ }
296
+
297
+ return $this->blogroll_instance;
298
+ }
299
+
300
+
301
+
302
+ /**
303
+ * Gets an instance of the WP class
304
+ *
305
+ */
306
+ function get_wp_instance()
307
+ {
308
+ if (!isset($this->wp_instance)) {
309
+ $this->wp_instance = new MMB_WP();
310
+ }
311
+
312
+ return $this->wp_instance;
313
+ }
314
+
315
+ /**
316
+ * Gets an instance of User
317
+ *
318
+ */
319
+ function get_user_instance()
320
+ {
321
+ if (!isset($this->user_instance)) {
322
+ $this->user_instance = new MMB_User();
323
+ }
324
+
325
+ return $this->user_instance;
326
+ }
327
+
328
+ /**
329
+ * Gets an instance of stats class
330
+ *
331
+ */
332
+ function get_stats_instance()
333
+ {
334
+ if (!isset($this->stats_instance)) {
335
+ $this->stats_instance = new MMB_Stats();
336
+ }
337
+ return $this->stats_instance;
338
+ }
339
+ /**
340
+ * Gets an instance of search class
341
+ *
342
+ */
343
+ function get_search_instance()
344
+ {
345
+ if (!isset($this->search_instance)) {
346
+ $this->search_instance = new MMB_Search();
347
+ }
348
+ //return $this->search_instance;
349
+ return $this->search_instance;
350
+ }
351
+ /**
352
+ * Gets an instance of stats class
353
+ *
354
+ */
355
+ function get_backup_instance()
356
+ {
357
+ if (!isset($this->backup_instance)) {
358
+ $this->backup_instance = new MMB_Backup();
359
+ }
360
+
361
+ return $this->backup_instance;
362
+ }
363
+
364
+ /**
365
+ * Gets an instance of links class
366
+ *
367
+ */
368
+ function get_link_instance()
369
+ {
370
+ if (!isset($this->link_instance)) {
371
+ $this->link_instance = new MMB_Link();
372
+ }
373
+
374
+ return $this->link_instance;
375
+ }
376
+
377
+ function get_installer_instance()
378
+ {
379
+ if (!isset($this->installer_instance)) {
380
+ $this->installer_instance = new MMB_Installer();
381
+ }
382
+ return $this->installer_instance;
383
+ }
384
+
385
+ /**
386
+ * Plugin install callback function
387
+ * Check PHP version
388
+ */
389
+ function install() {
390
+
391
+ global $wpdb, $_wp_using_ext_object_cache, $current_user;
392
+ $_wp_using_ext_object_cache = false;
393
+
394
+ //delete plugin options, just in case
395
+ if ($this->mmb_multisite != false) {
396
+ $network_blogs = $wpdb->get_results($wpdb->prepare("select `blog_id`, `site_id` from `{$wpdb->blogs}`"));
397
+ if(!empty($network_blogs)){
398
+ if( is_network_admin() ){
399
+ update_option('mmb_network_admin_install', 1);
400
+ foreach($network_blogs as $details){
401
+ if($details->site_id == $details->blog_id)
402
+ update_blog_option($details->blog_id, 'mmb_network_admin_install', 1);
403
+ else
404
+ update_blog_option($details->blog_id, 'mmb_network_admin_install', -1);
405
+
406
+ delete_blog_option($blog_id, '_worker_nossl_key');
407
+ delete_blog_option($blog_id, '_worker_public_key');
408
+ delete_blog_option($blog_id, '_action_message_id');
409
+ }
410
+ } else {
411
+ update_option('mmb_network_admin_install', -1);
412
+ delete_option('_worker_nossl_key');
413
+ delete_option('_worker_public_key');
414
+ delete_option('_action_message_id');
415
+ }
416
+ }
417
+ } else {
418
+ delete_option('_worker_nossl_key');
419
+ delete_option('_worker_public_key');
420
+ delete_option('_action_message_id');
421
+ }
422
+
423
+ delete_option('mwp_backup_tasks');
424
+ delete_option('mwp_notifications');
425
+ delete_option('mwp_worker_brand');
426
+ delete_option('mwp_pageview_alerts');
427
+
428
+ }
429
+
430
+ /**
431
+ * Saves the (modified) options into the database
432
+ *
433
+ */
434
+ function save_options()
435
+ {
436
+ if (get_option($this->slug)) {
437
+ update_option($this->slug, $this->settings);
438
+ } else {
439
+ add_option($this->slug, $this->settings);
440
+ }
441
+ }
442
+
443
+ /**
444
+ * Deletes options for communication with master
445
+ *
446
+ */
447
+ function uninstall( $deactivate = false )
448
+ {
449
+ global $current_user, $wpdb, $_wp_using_ext_object_cache;
450
+ $_wp_using_ext_object_cache = false;
451
+
452
+ if ($this->mmb_multisite != false) {
453
+ $network_blogs = $wpdb->get_col($wpdb->prepare("select `blog_id` from `{$wpdb->blogs}`"));
454
+ if(!empty($network_blogs)){
455
+ if( is_network_admin() ){
456
+ if( $deactivate ) {
457
+ delete_option('mmb_network_admin_install');
458
+ foreach($network_blogs as $blog_id){
459
+ delete_blog_option($blog_id, 'mmb_network_admin_install');
460
+ delete_blog_option($blog_id, '_worker_nossl_key');
461
+ delete_blog_option($blog_id, '_worker_public_key');
462
+ delete_blog_option($blog_id, '_action_message_id');
463
+ delete_blog_option($blog_id, 'mwp_maintenace_mode');
464
+ }
465
+ }
466
+ } else {
467
+ if( $deactivate )
468
+ delete_option('mmb_network_admin_install');
469
+
470
+ delete_option('_worker_nossl_key');
471
+ delete_option('_worker_public_key');
472
+ delete_option('_action_message_id');
473
+ }
474
+ }
475
+ } else {
476
+ delete_option('_worker_nossl_key');
477
+ delete_option('_worker_public_key');
478
+ delete_option('_action_message_id');
479
+ }
480
+
481
+ //Delete options
482
+ delete_option('mwp_maintenace_mode');
483
+ delete_option('mwp_backup_tasks');
484
+ wp_clear_scheduled_hook('mwp_backup_tasks');
485
+ delete_option('mwp_notifications');
486
+ wp_clear_scheduled_hook('mwp_notifications');
487
+ delete_option('mwp_worker_brand');
488
+ delete_option('mwp_pageview_alerts');
489
+ }
490
+
491
+
492
+ /**
493
+ * Constructs a url (for ajax purpose)
494
+ *
495
+ * @param mixed $base_page
496
+ */
497
+ function construct_url($params = array(), $base_page = 'index.php')
498
+ {
499
+ $url = "$base_page?_wpnonce=" . wp_create_nonce($this->slug);
500
+ foreach ($params as $key => $value) {
501
+ $url .= "&$key=$value";
502
+ }
503
+
504
+ return $url;
505
+ }
506
+
507
+ /**
508
+ * Worker update
509
+ *
510
+ */
511
+ function update_worker_plugin($params)
512
+ {
513
+ extract($params);
514
+ if ($download_url) {
515
+ @include_once ABSPATH . 'wp-admin/includes/file.php';
516
+ @include_once ABSPATH . 'wp-admin/includes/misc.php';
517
+ @include_once ABSPATH . 'wp-admin/includes/template.php';
518
+ @include_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
519
+ @include_once ABSPATH . 'wp-admin/includes/screen.php';
520
+
521
+ if (!$this->is_server_writable()) {
522
+ return array(
523
+ 'error' => 'Failed, please <a target="_blank" href="http://managewp.com/user-guide#ftp">add FTP details for automatic upgrades.</a></a>'
524
+ );
525
+ }
526
+
527
+ ob_start();
528
+ @unlink(dirname(__FILE__));
529
+ $upgrader = new Plugin_Upgrader();
530
+ $result = $upgrader->run(array(
531
+ 'package' => $download_url,
532
+ 'destination' => WP_PLUGIN_DIR,
533
+ 'clear_destination' => true,
534
+ 'clear_working' => true,
535
+ 'hook_extra' => array(
536
+ 'plugin' => 'worker/init.php'
537
+ )
538
+ ));
539
+ ob_end_clean();
540
+ if (is_wp_error($result) || !$result) {
541
+ return array(
542
+ 'error' => 'ManageWP Worker plugin could not be updated.'
543
+ );
544
+ } else {
545
+ return array(
546
+ 'success' => 'ManageWP Worker plugin successfully updated.'
547
+ );
548
+ }
549
+ }
550
+ return array(
551
+ 'error' => 'Bad download path for worker installation file.'
552
+ );
553
+ }
554
+
555
+ /**
556
+ * Automatically logs in when called from Master
557
+ *
558
+ */
559
+ function automatic_login()
560
+ {
561
+ $where = isset($_GET['mwp_goto']) ? $_GET['mwp_goto'] : false;
562
+ $username = isset($_GET['username']) ? $_GET['username'] : '';
563
+ $auto_login = isset($_GET['auto_login']) ? $_GET['auto_login'] : 0;
564
+
565
+ if( !function_exists('is_user_logged_in') )
566
+ include_once( ABSPATH.'wp-includes/pluggable.php' );
567
+
568
+ if (( $auto_login && strlen(trim($username)) && !is_user_logged_in() ) || (isset($this->mmb_multisite) && $this->mmb_multisite )) {
569
+ $signature = base64_decode($_GET['signature']);
570
+ $message_id = trim($_GET['message_id']);
571
+
572
+ $auth = $this->authenticate_message($where . $message_id, $signature, $message_id);
573
+ if ($auth === true) {
574
+
575
+ if (!headers_sent())
576
+ header('P3P: CP="CAO PSA OUR"');
577
+
578
+ if(!defined('MMB_USER_LOGIN'))
579
+ define('MMB_USER_LOGIN', true);
580
+
581
+ $siteurl = function_exists('get_site_option') ? get_site_option( 'siteurl' ) : get_option('siteurl');
582
+ $user = $this->mmb_get_user_info($username);
583
+ wp_set_current_user($user->ID);
584
+
585
+ if(!defined('COOKIEHASH') || (isset($this->mmb_multisite) && $this->mmb_multisite) )
586
+ wp_cookie_constants();
587
+
588
+ wp_set_auth_cookie($user->ID);
589
+ @mmb_worker_header();
590
+
591
+ if((isset($this->mmb_multisite) && $this->mmb_multisite ) || isset($_REQUEST['mwpredirect'])){
592
+ if(function_exists('wp_safe_redirect') && function_exists('admin_url')){
593
+ wp_safe_redirect(admin_url($where));
594
+ exit();
595
+ }
596
+ }
597
+ } else {
598
+ wp_die($auth['error']);
599
+ }
600
+ } elseif( is_user_logged_in() ) {
601
+ @mmb_worker_header();
602
+ if(isset($_REQUEST['mwpredirect'])){
603
+ if(function_exists('wp_safe_redirect') && function_exists('admin_url')){
604
+ wp_safe_redirect(admin_url($where));
605
+ exit();
606
+ }
607
+ }
608
+ }
609
+ }
610
+
611
+ function mmb_set_auth_cookie( $auth_cookie ){
612
+ if(!defined('MMB_USER_LOGIN'))
613
+ return false;
614
+
615
+ if( !defined('COOKIEHASH') )
616
+ wp_cookie_constants();
617
+
618
+ $_COOKIE['wordpress_'.COOKIEHASH] = $auth_cookie;
619
+
620
+ }
621
+ function mmb_set_logged_in_cookie( $logged_in_cookie ){
622
+ if(!defined('MMB_USER_LOGIN'))
623
+ return false;
624
+
625
+ if( !defined('COOKIEHASH') )
626
+ wp_cookie_constants();
627
+
628
+ $_COOKIE['wordpress_logged_in_'.COOKIEHASH] = $logged_in_cookie;
629
+ }
630
+
631
+ function admin_actions(){
632
+ add_filter('all_plugins', array($this, 'worker_replace'));
633
+ }
634
+
635
+ function worker_replace($all_plugins){
636
+ $replace = get_option("mwp_worker_brand");
637
+ if(is_array($replace)){
638
+ if($replace['name'] || $replace['desc'] || $replace['author'] || $replace['author_url']){
639
+ $all_plugins['worker/init.php']['Name'] = $replace['name'];
640
+ $all_plugins['worker/init.php']['Title'] = $replace['name'];
641
+ $all_plugins['worker/init.php']['Description'] = $replace['desc'];
642
+ $all_plugins['worker/init.php']['AuthorURI'] = $replace['author_url'];
643
+ $all_plugins['worker/init.php']['Author'] = $replace['author'];
644
+ $all_plugins['worker/init.php']['AuthorName'] = $replace['author'];
645
+ $all_plugins['worker/init.php']['PluginURI'] = '';
646
+ }
647
+
648
+ if($replace['hide']){
649
+ if (!function_exists('get_plugins')) {
650
+ include_once(ABSPATH . 'wp-admin/includes/plugin.php');
651
+ }
652
+ $activated_plugins = get_option('active_plugins');
653
+ if (!$activated_plugins)
654
+ $activated_plugins = array();
655
+ if(in_array('worker/init.php',$activated_plugins))
656
+ unset($all_plugins['worker/init.php']);
657
+ }
658
+ }
659
+
660
+
661
+ return $all_plugins;
662
+ }
663
+
664
+ }
665
  ?>
helper.class.php CHANGED
@@ -1,499 +1,499 @@
1
- <?php
2
- /*************************************************************
3
- *
4
- * helper.class.php
5
- *
6
- * Utility functions
7
- *
8
- *
9
- * Copyright (c) 2011 Prelovac Media
10
- * www.prelovac.com
11
- **************************************************************/
12
-
13
- class MMB_Helper
14
- {
15
- /**
16
- * A helper function to log data
17
- *
18
- * @param mixed $mixed
19
- */
20
- function _log($mixed)
21
- {
22
- if (is_array($mixed)) {
23
- $mixed = print_r($mixed, 1);
24
- } else if (is_object($mixed)) {
25
- ob_start();
26
- var_dump($mixed);
27
- $mixed = ob_get_clean();
28
- }
29
-
30
- $handle = fopen(dirname(__FILE__) . '/log', 'a');
31
- fwrite($handle, $mixed . PHP_EOL);
32
- fclose($handle);
33
- }
34
-
35
- function _escape(&$array)
36
- {
37
- global $wpdb;
38
-
39
- if (!is_array($array)) {
40
- return ($wpdb->escape($array));
41
- } else {
42
- foreach ((array) $array as $k => $v) {
43
- if (is_array($v)) {
44
- $this->_escape($array[$k]);
45
- } else if (is_object($v)) {
46
- //skip
47
- } else {
48
- $array[$k] = $wpdb->escape($v);
49
- }
50
- }
51
- }
52
- }
53
-
54
- /**
55
- * Initializes the file system
56
- *
57
- */
58
- function init_filesystem()
59
- {
60
- global $wp_filesystem;
61
-
62
- if (!$wp_filesystem || !is_object($wp_filesystem)) {
63
- WP_Filesystem();
64
- }
65
-
66
- if (!is_object($wp_filesystem))
67
- return FALSE;
68
-
69
- return TRUE;
70
- }
71
-
72
- /**
73
- *
74
- * Check if function exists or not on `suhosin` black list
75
- *
76
- */
77
-
78
- function mmb_get_user_info( $user_info = false, $info = 'login' ){
79
-
80
- if($user_info === false)
81
- return false;
82
-
83
- if( strlen( trim( $user_info ) ) == 0)
84
- return false;
85
-
86
-
87
- global $wp_version;
88
- if (version_compare($wp_version, '3.2.2', '<=')){
89
- return get_userdatabylogin( $user_info );
90
- } else {
91
- return get_user_by( $info, $user_info );
92
- }
93
- }
94
-
95
- /**
96
- *
97
- * Call action item filters
98
- *
99
- */
100
-
101
- function mmb_parse_action_params( $key = '', $params = null, $call_object = null ){
102
-
103
- global $_mmb_item_filter;
104
- $call_object = $call_object !== null ? $call_object : $this;
105
- $return = array();
106
-
107
- if(isset($_mmb_item_filter[$key]) && !empty($_mmb_item_filter[$key])){
108
- if( isset($params['item_filter']) && !empty($params['item_filter'])){
109
- foreach($params['item_filter'] as $_items){
110
- if(!empty($_items)){
111
- foreach($_items as $_item){
112
- if(in_array($_item[0], $_mmb_item_filter[$key])){
113
- $_item[1] = isset($_item[1]) ? $_item[1] : array();
114
- $return = call_user_func(array( &$call_object, 'get_'.$_item[0]), $return, $_item[1]);
115
- }
116
- }
117
- }
118
- }
119
- }
120
- }
121
-
122
- return $return;
123
- }
124
-
125
- /**
126
- *
127
- * Check if function exists or not on `suhosin` black list
128
- *
129
- */
130
-
131
- function mmb_function_exists($function_callback){
132
-
133
- if(!function_exists($function_callback))
134
- return false;
135
-
136
- $disabled = explode(', ', @ini_get('disable_functions'));
137
- if (in_array($function_callback, $disabled))
138
- return false;
139
-
140
- if (extension_loaded('suhosin')) {
141
- $suhosin = @ini_get("suhosin.executor.func.blacklist");
142
- if (empty($suhosin) == false) {
143
- $suhosin = explode(',', $suhosin);
144
- $blacklist = array_map('trim', $suhosin);
145
- $blacklist = array_map('strtolower', $blacklist);
146
- if(in_array($function_callback, $blacklist))
147
- return false;
148
- }
149
- }
150
- return true;
151
- }
152
-
153
- /**
154
- * Gets transient based on WP version
155
- *
156
- * @global string $wp_version
157
- * @param string $option_name
158
- * @return mixed
159
- */
160
-
161
- function mmb_set_transient($option_name = false, $data = false){
162
-
163
- if (!$option_name || !$data) {
164
- return false;
165
- }
166
- if($this->mmb_multisite)
167
- return $this->mmb_set_sitemeta_transient($option_name, $data);
168
-
169
- global $wp_version;
170
-
171
- if (version_compare($wp_version, '2.7.9', '<=')) {
172
- update_option($option_name, $data);
173
- } else if (version_compare($wp_version, '2.9.9', '<=')) {
174
- update_option('_transient_' . $option_name, $data);
175
- } else {
176
- update_option('_site_transient_' . $option_name, $data);
177
- }
178
-
179
- }
180
- function mmb_get_transient($option_name)
181
- {
182
- if (trim($option_name) == '') {
183
- return FALSE;
184
- }
185
- if($this->mmb_multisite)
186
- return $this->mmb_get_sitemeta_transient($option_name);
187
-
188
- global $wp_version;
189
-
190
- $transient = array();
191
-
192
- if (version_compare($wp_version, '2.7.9', '<=')) {
193
- return get_option($option_name);
194
- } else if (version_compare($wp_version, '2.9.9', '<=')) {
195
- $transient = get_option('_transient_' . $option_name);
196
- return apply_filters("transient_".$option_name, $transient);
197
- } else {
198
- $transient = get_option('_site_transient_' . $option_name);
199
- return apply_filters("site_transient_".$option_name, $transient);
200
- }
201
- }
202
-
203
- function mmb_delete_transient($option_name)
204
- {
205
- if (trim($option_name) == '') {
206
- return FALSE;
207
- }
208
-
209
- global $wp_version;
210
-
211
- if (version_compare($wp_version, '2.7.9', '<=')) {
212
- delete_option($option_name);
213
- } else if (version_compare($wp_version, '2.9.9', '<=')) {
214
- delete_option('_transient_' . $option_name);
215
- } else {
216
- delete_option('_site_transient_' . $option_name);
217
- }
218
- }
219
-
220
- function mmb_get_sitemeta_transient($option_name){
221
- global $wpdb;
222
- $option_name = '_site_transient_'. $option_name;
223
-
224
- $result = $wpdb->get_var( $wpdb->prepare("SELECT `meta_value` FROM `{$wpdb->sitemeta}` WHERE meta_key = '{$option_name}' AND `site_id` = '{$this->mmb_multisite}' "));
225
- $result = maybe_unserialize($result);
226
- return $result;
227
- }
228
-
229
- function mmb_set_sitemeta_transient($option_name, $option_value){
230
- global $wpdb;
231
- $option_name = '_site_transient_'. $option_name;
232
-
233
- if($this->mmb_get_sitemeta_transient($option_name)){
234
- $result = $wpdb->update( $wpdb->sitemeta,
235
- array(
236
- 'meta_value' => maybe_serialize($option_value)
237
- ),
238
- array(
239
- 'meta_key' => $option_name,
240
- 'site_id' => $this->mmb_multisite
241
- )
242
- );
243
- }else {
244
- $result = $wpdb->insert( $wpdb->sitemeta,
245
- array(
246
- 'meta_key' => $option_name,
247
- 'meta_value' => maybe_serialize($option_value),
248
- 'site_id' => $this->mmb_multisite
249
- )
250
- );
251
- }
252
- return $result;
253
- }
254
-
255
- function delete_temp_dir($directory)
256
- {
257
- if (substr($directory, -1) == "/") {
258
- $directory = substr($directory, 0, -1);
259
- }
260
- if (!file_exists($directory) || !is_dir($directory)) {
261
- return false;
262
- } elseif (!is_readable($directory)) {
263
- return false;
264
- } else {
265
- $directoryHandle = opendir($directory);
266
-
267
- while ($contents = readdir($directoryHandle)) {
268
- if ($contents != '.' && $contents != '..') {
269
- $path = $directory . "/" . $contents;
270
-
271
- if (is_dir($path)) {
272
- $this->delete_temp_dir($path);
273
- } else {
274
- unlink($path);
275
- }
276
- }
277
- }
278
- closedir($directoryHandle);
279
- rmdir($directory);
280
- return true;
281
- }
282
- }
283
-
284
- function set_worker_message_id($message_id = false)
285
- {
286
- if ($message_id) {
287
- add_option('_action_message_id', $message_id) or update_option('_action_message_id', $message_id);
288
- return $message_id;
289
- }
290
- return false;
291
- }
292
-
293
- function get_worker_message_id()
294
- {
295
- return (int) get_option('_action_message_id');
296
- }
297
-
298
- function set_master_public_key($public_key = false)
299
- {
300
- if ($public_key && !get_option('_worker_public_key')) {
301
- add_option('_worker_public_key', base64_encode($public_key));
302
- return true;
303
- }
304
- return false;
305
- }
306
-
307
- function get_master_public_key()
308
- {
309
- if (!get_option('_worker_public_key'))
310
- return false;
311
- return base64_decode(get_option('_worker_public_key'));
312
- }
313
-
314
-
315
- function get_random_signature()
316
- {
317
- if (!get_option('_worker_nossl_key'))
318
- return false;
319
- return base64_decode(get_option('_worker_nossl_key'));
320
- }
321
-
322
- function set_random_signature($random_key = false)
323
- {
324
- if ($random_key && !get_option('_worker_nossl_key')) {
325
- add_option('_worker_nossl_key', base64_encode($random_key));
326
- return true;
327
- }
328
- return false;
329
- }
330
-
331
-
332
- function authenticate_message($data = false, $signature = false, $message_id = false)
333
- {
334
- if (!$data && !$signature) {
335
- return array(
336
- 'error' => 'Authentication failed.'
337
- );
338
- }
339
-
340
- $current_message = $this->get_worker_message_id();
341
-
342
- if ((int) $current_message > (int) $message_id)
343
- return array(
344
- 'error' => 'Invalid message recieved. Deactivate and activate the ManageWP Worker plugin on this site, then remove the website from your ManageWP account and add it again.'
345
- );
346
-
347
- $pl_key = $this->get_master_public_key();
348
- if (!$pl_key) {
349
- return array(
350
- 'error' => 'Authentication failed. Deactivate and activate the ManageWP Worker plugin on this site, then remove the website from your ManageWP account and add it again.'
351
- );
352
- }
353
-
354
- if (function_exists('openssl_verify') && !$this->get_random_signature()) {
355
- $verify = openssl_verify($data, $signature, $pl_key);
356
- if ($verify == 1) {
357
- $message_id = $this->set_worker_message_id($message_id);
358
- return true;
359
- } else if ($verify == 0) {
360
- return array(
361
- 'error' => 'Invalid message signature. Deactivate and activate the ManageWP Worker plugin on this site, then remove the website from your ManageWP account and add it again.'
362
- );
363
- } else {
364
- return array(
365
- 'error' => 'Command not successful! Please try again.'
366
- );
367
- }
368
- } else if ($this->get_random_signature()) {
369
- if (md5($data . $this->get_random_signature()) == $signature) {
370
- $message_id = $this->set_worker_message_id($message_id);
371
- return true;
372
- }
373
- return array(
374
- 'error' => 'Invalid message signature. Deactivate and activate the ManageWP Worker plugin on this site, then remove the website from your ManageWP account and add it again.'
375
- );
376
- }
377
- // no rand key - deleted in get_stat maybe
378
- else
379
- return array(
380
- 'error' => 'Invalid message signature. Deactivate and activate the ManageWP Worker plugin on this site, then remove the website from your ManageWP account and add it again.'
381
- );
382
- }
383
-
384
- function _secure_data($data = false){
385
- if($data == false)
386
- return false;
387
-
388
- $pl_key = $this->get_master_public_key();
389
- if (!$pl_key)
390
- return false;
391
-
392
- $secure = '';
393
- if( function_exists('openssl_public_decrypt') && !$this->get_random_signature()){
394
- if(is_array($data) && !empty($data)){
395
- foreach($data as $input){
396
- openssl_public_decrypt($input, $decrypted, $pl_key);
397
- $secure .= $decrypted;
398
- }
399
- } else {
400
- openssl_public_decrypt($input, $decrypted, $pl_key);
401
- $secure = $decrypted;
402
- }
403
- return $secure;
404
- }
405
- return false;
406
-
407
- }
408
-
409
- function check_if_user_exists($username = false)
410
- {
411
- global $wpdb;
412
- if ($username) {
413
- if( !function_exists('username_exists') )
414
- include_once(ABSPATH . WPINC . '/registration.php');
415
-
416
- include_once(ABSPATH . 'wp-includes/pluggable.php');
417
-
418
- if (username_exists($username) == null) {
419
- return false;
420
- }
421
-
422
- $user = (array) $this->mmb_get_user_info( $username );
423
- if ((isset($user[$wpdb->prefix . 'user_level']) && $user[$wpdb->prefix . 'user_level'] == 10) || isset($user[$wpdb->prefix . 'capabilities']['administrator']) ||
424
- (isset($user['caps']['administrator']) && $user['caps']['administrator'] == 1)){
425
- return true;
426
- }
427
- return false;
428
- }
429
- return false;
430
- }
431
-
432
- function refresh_updates()
433
- {
434
- if (rand(1, 3) == '2') {
435
- require_once(ABSPATH . WPINC . '/update.php');
436
- wp_update_plugins();
437
- wp_update_themes();
438
- wp_version_check();
439
- }
440
- }
441
-
442
- function remove_http($url = '')
443
- {
444
- if ($url == 'http://' OR $url == 'https://') {
445
- return $url;
446
- }
447
- return preg_replace('/^(http|https)\:\/\/(www.)?/i', '', $url);
448
-
449
- }
450
-
451
- function mmb_get_error($error_object)
452
- {
453
- if (!is_wp_error($error_object)) {
454
- return $error_object != '' ? $error_object : '';
455
- } else {
456
- $errors = array();
457
- if(!empty($error_object->error_data)) {
458
- foreach ($error_object->error_data as $error_key => $error_string) {
459
- $errors[] = str_replace('_', ' ', ucfirst($error_key)) . ': ' . $error_string;
460
- }
461
- } elseif (!empty($error_object->errors)){
462
- foreach ($error_object->errors as $error_key => $err) {
463
- $errors[] = 'Error: '.str_replace('_', ' ', strtolower($error_key));
464
- }
465
- }
466
- return implode('<br />', $errors);
467
- }
468
- }
469
-
470
- function is_server_writable(){
471
- if((!defined('FTP_HOST') || !defined('FTP_USER') || !defined('FTP_PASS')) && (get_filesystem_method(array(), false) != 'direct'))
472
- return false;
473
- else
474
- return true;
475
- }
476
-
477
- function mmb_download_url($url, $file_name)
478
- {
479
- if (function_exists('fopen') && function_exists('ini_get') && ini_get('allow_url_fopen') == true && ($destination = @fopen($file_name, 'wb')) && ($source = @fopen($url, "r")) ) {
480
-
481
-
482
- while ($a = @fread($source, 1024* 1024)) {
483
- @fwrite($destination, $a);
484
- }
485
-
486
- fclose($source);
487
- fclose($destination);
488
- } else
489
- if (!fsockopen_download($url, $file_name))
490
- die('Error downloading file ' . $url);
491
- return $file_name;
492
- }
493
-
494
-
495
-
496
-
497
-
498
- }
499
  ?>
1
+ <?php
2
+ /*************************************************************
3
+ *
4
+ * helper.class.php
5
+ *
6
+ * Utility functions
7
+ *
8
+ *
9
+ * Copyright (c) 2011 Prelovac Media
10
+ * www.prelovac.com
11
+ **************************************************************/
12
+
13
+ class MMB_Helper
14
+ {
15
+ /**
16
+ * A helper function to log data
17
+ *
18
+ * @param mixed $mixed
19
+ */
20
+ function _log($mixed)
21
+ {
22
+ if (is_array($mixed)) {
23
+ $mixed = print_r($mixed, 1);
24
+ } else if (is_object($mixed)) {
25
+ ob_start();
26
+ var_dump($mixed);
27
+ $mixed = ob_get_clean();
28
+ }
29
+
30
+ $handle = fopen(dirname(__FILE__) . '/log', 'a');
31
+ fwrite($handle, $mixed . PHP_EOL);
32
+ fclose($handle);
33
+ }
34
+
35
+ function _escape(&$array)
36
+ {
37
+ global $wpdb;
38
+
39
+ if (!is_array($array)) {
40
+ return ($wpdb->escape($array));
41
+ } else {
42
+ foreach ((array) $array as $k => $v) {
43
+ if (is_array($v)) {
44
+ $this->_escape($array[$k]);
45
+ } else if (is_object($v)) {
46
+ //skip
47
+ } else {
48
+ $array[$k] = $wpdb->escape($v);
49
+ }
50
+ }
51
+ }
52
+ }
53
+
54
+ /**
55
+ * Initializes the file system
56
+ *
57
+ */
58
+ function init_filesystem()
59
+ {
60
+ global $wp_filesystem;
61
+
62
+ if (!$wp_filesystem || !is_object($wp_filesystem)) {
63
+ WP_Filesystem();
64
+ }
65
+
66
+ if (!is_object($wp_filesystem))
67
+ return FALSE;
68
+
69
+ return TRUE;
70
+ }
71
+
72
+ /**
73
+ *
74
+ * Check if function exists or not on `suhosin` black list
75
+ *
76
+ */
77
+
78
+ function mmb_get_user_info( $user_info = false, $info = 'login' ){
79
+
80
+ if($user_info === false)
81
+ return false;
82
+
83
+ if( strlen( trim( $user_info ) ) == 0)
84
+ return false;
85
+
86
+
87
+ global $wp_version;
88
+ if (version_compare($wp_version, '3.2.2', '<=')){
89
+ return get_userdatabylogin( $user_info );
90
+ } else {
91
+ return get_user_by( $info, $user_info );
92
+ }
93
+ }
94
+
95
+ /**
96
+ *
97
+ * Call action item filters
98
+ *
99
+ */
100
+
101
+ function mmb_parse_action_params( $key = '', $params = null, $call_object = null ){
102
+
103
+ global $_mmb_item_filter;
104
+ $call_object = $call_object !== null ? $call_object : $this;
105
+ $return = array();
106
+
107
+ if(isset($_mmb_item_filter[$key]) && !empty($_mmb_item_filter[$key])){
108
+ if( isset($params['item_filter']) && !empty($params['item_filter'])){
109
+ foreach($params['item_filter'] as $_items){
110
+ if(!empty($_items)){
111
+ foreach($_items as $_item){
112
+ if(in_array($_item[0], $_mmb_item_filter[$key])){
113
+ $_item[1] = isset($_item[1]) ? $_item[1] : array();
114
+ $return = call_user_func(array( &$call_object, 'get_'.$_item[0]), $return, $_item[1]);
115
+ }
116
+ }
117
+ }
118
+ }
119
+ }
120
+ }
121
+
122
+ return $return;
123
+ }
124
+
125
+ /**
126
+ *
127
+ * Check if function exists or not on `suhosin` black list
128
+ *
129
+ */
130
+
131
+ function mmb_function_exists($function_callback){
132
+
133
+ if(!function_exists($function_callback))
134
+ return false;
135
+
136
+ $disabled = explode(', ', @ini_get('disable_functions'));
137
+ if (in_array($function_callback, $disabled))
138
+ return false;
139
+
140
+ if (extension_loaded('suhosin')) {
141
+ $suhosin = @ini_get("suhosin.executor.func.blacklist");
142
+ if (empty($suhosin) == false) {
143
+ $suhosin = explode(',', $suhosin);
144
+ $blacklist = array_map('trim', $suhosin);
145
+ $blacklist = array_map('strtolower', $blacklist);
146
+ if(in_array($function_callback, $blacklist))
147
+ return false;
148
+ }
149
+ }
150
+ return true;
151
+ }
152
+
153
+ /**
154
+ * Gets transient based on WP version
155
+ *
156
+ * @global string $wp_version
157
+ * @param string $option_name
158
+ * @return mixed
159
+ */
160
+
161
+ function mmb_set_transient($option_name = false, $data = false){
162
+
163
+ if (!$option_name || !$data) {
164
+ return false;
165
+ }
166
+ if($this->mmb_multisite)
167
+ return $this->mmb_set_sitemeta_transient($option_name, $data);
168
+
169
+ global $wp_version;
170
+
171
+ if (version_compare($wp_version, '2.7.9', '<=')) {
172
+ update_option($option_name, $data);
173
+ } else if (version_compare($wp_version, '2.9.9', '<=')) {
174
+ update_option('_transient_' . $option_name, $data);
175
+ } else {
176
+ update_option('_site_transient_' . $option_name, $data);
177
+ }
178
+
179
+ }
180
+ function mmb_get_transient($option_name)
181
+ {
182
+ if (trim($option_name) == '') {
183
+ return FALSE;
184
+ }
185
+ if($this->mmb_multisite)
186
+ return $this->mmb_get_sitemeta_transient($option_name);
187
+
188
+ global $wp_version;
189
+
190
+ $transient = array();
191
+
192
+ if (version_compare($wp_version, '2.7.9', '<=')) {
193
+ return get_option($option_name);
194
+ } else if (version_compare($wp_version, '2.9.9', '<=')) {
195
+ $transient = get_option('_transient_' . $option_name);
196
+ return apply_filters("transient_".$option_name, $transient);
197
+ } else {
198
+ $transient = get_option('_site_transient_' . $option_name);
199
+ return apply_filters("site_transient_".$option_name, $transient);
200
+ }
201
+ }
202
+
203
+ function mmb_delete_transient($option_name)
204
+ {
205
+ if (trim($option_name) == '') {
206
+ return FALSE;
207
+ }
208
+
209
+ global $wp_version;
210
+
211
+ if (version_compare($wp_version, '2.7.9', '<=')) {
212
+ delete_option($option_name);
213
+ } else if (version_compare($wp_version, '2.9.9', '<=')) {
214
+ delete_option('_transient_' . $option_name);
215
+ } else {
216
+ delete_option('_site_transient_' . $option_name);
217
+ }
218
+ }
219
+
220
+ function mmb_get_sitemeta_transient($option_name){
221
+ global $wpdb;
222
+ $option_name = '_site_transient_'. $option_name;
223
+
224
+ $result = $wpdb->get_var( $wpdb->prepare("SELECT `meta_value` FROM `{$wpdb->sitemeta}` WHERE meta_key = '{$option_name}' AND `site_id` = '{$this->mmb_multisite}' "));
225
+ $result = maybe_unserialize($result);
226
+ return $result;
227
+ }
228
+
229
+ function mmb_set_sitemeta_transient($option_name, $option_value){
230
+ global $wpdb;
231
+ $option_name = '_site_transient_'. $option_name;
232
+
233
+ if($this->mmb_get_sitemeta_transient($option_name)){
234
+ $result = $wpdb->update( $wpdb->sitemeta,
235
+ array(
236
+ 'meta_value' => maybe_serialize($option_value)
237
+ ),
238
+ array(
239
+ 'meta_key' => $option_name,
240
+ 'site_id' => $this->mmb_multisite
241
+ )
242
+ );
243
+ }else {
244
+ $result = $wpdb->insert( $wpdb->sitemeta,
245
+ array(
246
+ 'meta_key' => $option_name,
247
+ 'meta_value' => maybe_serialize($option_value),
248
+ 'site_id' => $this->mmb_multisite
249
+ )
250
+ );
251
+ }
252
+ return $result;
253
+ }
254
+
255
+ function delete_temp_dir($directory)
256
+ {
257
+ if (substr($directory, -1) == "/") {
258
+ $directory = substr($directory, 0, -1);
259
+ }
260
+ if (!file_exists($directory) || !is_dir($directory)) {
261
+ return false;
262
+ } elseif (!is_readable($directory)) {
263
+ return false;
264
+ } else {
265
+ $directoryHandle = opendir($directory);
266
+
267
+ while ($contents = readdir($directoryHandle)) {
268
+ if ($contents != '.' && $contents != '..') {
269
+ $path = $directory . "/" . $contents;
270
+
271
+ if (is_dir($path)) {
272
+ $this->delete_temp_dir($path);
273
+ } else {
274
+ unlink($path);
275
+ }
276
+ }
277
+ }
278
+ closedir($directoryHandle);
279
+ rmdir($directory);
280
+ return true;
281
+ }
282
+ }
283
+
284
+ function set_worker_message_id($message_id = false)
285
+ {
286
+ if ($message_id) {
287
+ add_option('_action_message_id', $message_id) or update_option('_action_message_id', $message_id);
288
+ return $message_id;
289
+ }
290
+ return false;
291
+ }
292
+
293
+ function get_worker_message_id()
294
+ {
295
+ return (int) get_option('_action_message_id');
296
+ }
297
+
298
+ function set_master_public_key($public_key = false)
299
+ {
300
+ if ($public_key && !get_option('_worker_public_key')) {
301
+ add_option('_worker_public_key', base64_encode($public_key));
302
+ return true;
303
+ }
304
+ return false;
305
+ }
306
+
307
+ function get_master_public_key()
308
+ {
309
+ if (!get_option('_worker_public_key'))
310
+ return false;
311
+ return base64_decode(get_option('_worker_public_key'));
312
+ }
313
+
314
+
315
+ function get_random_signature()
316
+ {
317
+ if (!get_option('_worker_nossl_key'))
318
+ return false;
319
+ return base64_decode(get_option('_worker_nossl_key'));
320
+ }
321
+
322
+ function set_random_signature($random_key = false)
323
+ {
324
+ if ($random_key && !get_option('_worker_nossl_key')) {
325
+ add_option('_worker_nossl_key', base64_encode($random_key));
326
+ return true;
327
+ }
328
+ return false;
329
+ }
330
+
331
+
332
+ function authenticate_message($data = false, $signature = false, $message_id = false)
333
+ {
334
+ if (!$data && !$signature) {
335
+ return array(
336
+ 'error' => 'Authentication failed.'
337
+ );
338
+ }
339
+
340
+ $current_message = $this->get_worker_message_id();
341
+
342
+ if ((int) $current_message > (int) $message_id)
343
+ return array(
344
+ 'error' => 'Invalid message recieved. Deactivate and activate the ManageWP Worker plugin on this site, then remove the website from your ManageWP account and add it again.'
345
+ );
346
+
347
+ $pl_key = $this->get_master_public_key();
348
+ if (!$pl_key) {
349
+ return array(
350
+ 'error' => 'Authentication failed. Deactivate and activate the ManageWP Worker plugin on this site, then remove the website from your ManageWP account and add it again.'
351
+ );
352
+ }
353
+
354
+ if (function_exists('openssl_verify') && !$this->get_random_signature()) {
355
+ $verify = openssl_verify($data, $signature, $pl_key);
356
+ if ($verify == 1) {
357
+ $message_id = $this->set_worker_message_id($message_id);
358
+ return true;
359
+ } else if ($verify == 0) {
360
+ return array(
361
+ 'error' => 'Invalid message signature. Deactivate and activate the ManageWP Worker plugin on this site, then remove the website from your ManageWP account and add it again.'
362
+ );
363
+ } else {
364
+ return array(
365
+ 'error' => 'Command not successful! Please try again.'
366
+ );
367
+ }
368
+ } else if ($this->get_random_signature()) {
369
+ if (md5($data . $this->get_random_signature()) == $signature) {
370
+ $message_id = $this->set_worker_message_id($message_id);
371
+ return true;
372
+ }
373
+ return array(
374
+ 'error' => 'Invalid message signature. Deactivate and activate the ManageWP Worker plugin on this site, then remove the website from your ManageWP account and add it again.'
375
+ );
376
+ }
377
+ // no rand key - deleted in get_stat maybe
378
+ else
379
+ return array(
380
+ 'error' => 'Invalid message signature. Deactivate and activate the ManageWP Worker plugin on this site, then remove the website from your ManageWP account and add it again.'
381
+ );
382
+ }
383
+
384
+ function _secure_data($data = false){
385
+ if($data == false)
386
+ return false;
387
+
388
+ $pl_key = $this->get_master_public_key();
389
+ if (!$pl_key)
390
+ return false;
391
+
392
+ $secure = '';
393
+ if( function_exists('openssl_public_decrypt') && !$this->get_random_signature()){
394
+ if(is_array($data) && !empty($data)){
395
+ foreach($data as $input){
396
+ openssl_public_decrypt($input, $decrypted, $pl_key);
397
+ $secure .= $decrypted;
398
+ }
399
+ } else {
400
+ openssl_public_decrypt($input, $decrypted, $pl_key);
401
+ $secure = $decrypted;
402
+ }
403
+ return $secure;
404
+ }
405
+ return false;
406
+
407
+ }
408
+
409
+ function check_if_user_exists($username = false)
410
+ {
411
+ global $wpdb;
412
+ if ($username) {
413
+ if( !function_exists('username_exists') )
414
+ include_once(ABSPATH . WPINC . '/registration.php');
415
+
416
+ include_once(ABSPATH . 'wp-includes/pluggable.php');
417
+
418
+ if (username_exists($username) == null) {
419
+ return false;
420
+ }
421
+
422
+ $user = (array) $this->mmb_get_user_info( $username );
423
+ if ((isset($user[$wpdb->prefix . 'user_level']) && $user[$wpdb->prefix . 'user_level'] == 10) || isset($user[$wpdb->prefix . 'capabilities']['administrator']) ||
424
+ (isset($user['caps']['administrator']) && $user['caps']['administrator'] == 1)){
425
+ return true;
426
+ }
427
+ return false;
428
+ }
429
+ return false;
430
+ }
431
+
432
+ function refresh_updates()
433
+ {
434
+ if (rand(1, 3) == '2') {
435
+ require_once(ABSPATH . WPINC . '/update.php');
436
+ wp_update_plugins();
437
+ wp_update_themes();
438
+ wp_version_check();
439
+ }
440
+ }
441
+
442
+ function remove_http($url = '')
443
+ {
444
+ if ($url == 'http://' OR $url == 'https://') {
445
+ return $url;
446
+ }
447
+ return preg_replace('/^(http|https)\:\/\/(www.)?/i', '', $url);
448
+
449
+ }
450
+
451
+ function mmb_get_error($error_object)
452
+ {
453
+ if (!is_wp_error($error_object)) {
454
+ return $error_object != '' ? $error_object : '';
455
+ } else {
456
+ $errors = array();
457
+ if(!empty($error_object->error_data)) {
458
+ foreach ($error_object->error_data as $error_key => $error_string) {
459
+ $errors[] = str_replace('_', ' ', ucfirst($error_key)) . ': ' . $error_string;
460
+ }
461
+ } elseif (!empty($error_object->errors)){
462
+ foreach ($error_object->errors as $error_key => $err) {
463
+ $errors[] = 'Error: '.str_replace('_', ' ', strtolower($error_key));
464
+ }
465
+ }
466
+ return implode('<br />', $errors);
467
+ }
468
+ }
469
+
470
+ function is_server_writable(){
471
+ if((!defined('FTP_HOST') || !defined('FTP_USER') || !defined('FTP_PASS')) && (get_filesystem_method(array(), false) != 'direct'))
472
+ return false;
473
+ else
474
+ return true;
475
+ }
476
+
477
+ function mmb_download_url($url, $file_name)
478
+ {
479
+ if (function_exists('fopen') && function_exists('ini_get') && ini_get('allow_url_fopen') == true && ($destination = @fopen($file_name, 'wb')) && ($source = @fopen($url, "r")) ) {
480
+
481
+
482
+ while ($a = @fread($source, 1024* 1024)) {
483
+ @fwrite($destination, $a);
484
+ }
485
+
486
+ fclose($source);
487
+ fclose($destination);
488
+ } else
489
+ if (!fsockopen_download($url, $file_name))
490
+ die('Error downloading file ' . $url);
491
+ return $file_name;
492
+ }
493
+
494
+
495
+
496
+
497
+
498
+ }
499
  ?>
init.php CHANGED
@@ -1,830 +1,900 @@
1
- <?php
2
- /*
3
- Plugin Name: ManageWP - Worker
4
- Plugin URI: http://managewp.com/
5
- Description: Manage all your blogs from one dashboard. Visit <a href="http://managewp.com">ManageWP.com</a> to sign up.
6
- Author: Prelovac Media
7
- Version: 3.9.16
8
- Author URI: http://www.prelovac.com
9
- */
10
-
11
- /*************************************************************
12
- *
13
- * init.php
14
- *
15
- * Initialize the communication with master
16
- *
17
- *
18
- * Copyright (c) 2011 Prelovac Media
19
- * www.prelovac.com
20
- **************************************************************/
21
-
22
- if(!defined('MMB_WORKER_VERSION'))
23
- define('MMB_WORKER_VERSION', '3.9.16');
24
-
25
- if ( !defined('MMB_XFRAME_COOKIE')){
26
- $siteurl = function_exists('get_site_option') ? get_site_option( 'siteurl' ) : get_option('siteurl');
27
- define('MMB_XFRAME_COOKIE', $xframe = 'wordpress_'.md5($siteurl).'_xframe');
28
- }
29
- global $wpdb, $mmb_plugin_dir, $mmb_plugin_url, $wp_version, $mmb_filters, $_mmb_item_filter;
30
- if (version_compare(PHP_VERSION, '5.0.0', '<')) // min version 5 supported
31
- exit("<p>ManageWP Worker plugin requires PHP 5 or higher.</p>");
32
-
33
-
34
- $mmb_wp_version = $wp_version;
35
- $mmb_plugin_dir = WP_PLUGIN_DIR . '/' . basename(dirname(__FILE__));
36
- $mmb_plugin_url = WP_PLUGIN_URL . '/' . basename(dirname(__FILE__));
37
-
38
- require_once("$mmb_plugin_dir/helper.class.php");
39
- require_once("$mmb_plugin_dir/core.class.php");
40
- require_once("$mmb_plugin_dir/post.class.php");
41
- require_once("$mmb_plugin_dir/comment.class.php");
42
- require_once("$mmb_plugin_dir/stats.class.php");
43
- require_once("$mmb_plugin_dir/backup.class.php");
44
- require_once("$mmb_plugin_dir/installer.class.php");
45
- require_once("$mmb_plugin_dir/link.class.php");
46
- require_once("$mmb_plugin_dir/user.class.php");
47
- require_once("$mmb_plugin_dir/api.php");
48
-
49
- require_once("$mmb_plugin_dir/plugins/search/search.php");
50
- require_once("$mmb_plugin_dir/plugins/cleanup/cleanup.php");
51
-
52
- require_once("$mmb_plugin_dir/widget.class.php");
53
-
54
- if( !function_exists ( 'mmb_parse_request' )) {
55
- function mmb_parse_request()
56
- {
57
-
58
- if (!isset($HTTP_RAW_POST_DATA)) {
59
- $HTTP_RAW_POST_DATA = file_get_contents('php://input');
60
- }
61
- ob_start();
62
-
63
- global $current_user, $mmb_core, $new_actions, $wp_db_version, $wpmu_version, $_wp_using_ext_object_cache;
64
- $data = base64_decode($HTTP_RAW_POST_DATA);
65
- if ($data)
66
- $num = @extract(unserialize($data));
67
-
68
- if (isset($action)) {
69
- $_wp_using_ext_object_cache = false;
70
- @set_time_limit(600);
71
-
72
- if (!$mmb_core->check_if_user_exists($params['username']))
73
- mmb_response('Username <b>' . $params['username'] . '</b> does not have administrator capabilities. Enter the correct username in the site options.', false);
74
-
75
- if ($action == 'add_site') {
76
- mmb_add_site($params);
77
- mmb_response('You should never see this.', false);
78
- }
79
-
80
- $auth = $mmb_core->authenticate_message($action . $id, $signature, $id);
81
- if ($auth === true) {
82
-
83
- if(isset($params['username']) && !is_user_logged_in()){
84
- $user = function_exists('get_user_by') ? get_user_by('login', $params['username']) : get_userdatabylogin( $params['username'] );
85
- wp_set_current_user($user->ID);
86
- }
87
-
88
- /* in case database upgrade required, do database backup and perform upgrade ( wordpress wp_upgrade() function ) */
89
- if( strlen(trim($wp_db_version)) && !defined('ACX_PLUGIN_DIR') ){
90
- if ( get_option('db_version') != $wp_db_version ) {
91
- /* in multisite network, please update database manualy */
92
- if (empty($wpmu_version) || (function_exists('is_multisite') && !is_multisite())){
93
- if( ! function_exists('wp_upgrade'))
94
- include_once(ABSPATH.'wp-admin/includes/upgrade.php');
95
-
96
- ob_clean();
97
- @wp_upgrade();
98
- @do_action('after_db_upgrade');
99
- ob_end_clean();
100
- }
101
- }
102
- }
103
-
104
- if(isset($params['secure'])){
105
- if($decrypted = $mmb_core->_secure_data($params['secure'])){
106
- $decrypted = maybe_unserialize($decrypted);
107
- if(is_array($decrypted)){
108
- foreach($decrypted as $key => $val){
109
- if(!is_numeric($key))
110
- $params[$key] = $val;
111
- }
112
- unset($params['secure']);
113
- } else $params['secure'] = $decrypted;
114
- }
115
- }
116
-
117
- if( !$mmb_core->register_action_params( $action, $params ) ){
118
- global $_mmb_plugin_actions;
119
- $_mmb_plugin_actions[$action] = $params;
120
- }
121
-
122
-
123
- } else {
124
- mmb_response($auth['error'], false);
125
- }
126
- } else {
127
- MMB_Stats::set_hit_count();
128
- }
129
- ob_end_clean();
130
- }
131
- }
132
- /* Main response function */
133
- if( !function_exists ( 'mmb_response' )) {
134
-
135
- function mmb_response($response = false, $success = true)
136
- {
137
- $return = array();
138
-
139
- if ((is_array($response) && empty($response)) || (!is_array($response) && strlen($response) == 0))
140
- $return['error'] = 'Empty response.';
141
- else if ($success)
142
- $return['success'] = $response;
143
- else
144
- $return['error'] = $response;
145
-
146
- if( !headers_sent() ){
147
- header('HTTP/1.0 200 OK');
148
- header('Content-Type: text/plain');
149
- }
150
- exit("<MWPHEADER>" . base64_encode(serialize($return))."<ENDMWPHEADER>");
151
- }
152
- }
153
-
154
-
155
-
156
- if( !function_exists ( 'mmb_add_site' )) {
157
- function mmb_add_site($params)
158
- {
159
- global $mmb_core;
160
- $num = extract($params);
161
-
162
- if ($num) {
163
- if (!get_option('_action_message_id') && !get_option('_worker_public_key')) {
164
- $public_key = base64_decode($public_key);
165
-
166
- if (function_exists('openssl_verify')) {
167
- $verify = openssl_verify($action . $id, base64_decode($signature), $public_key);
168
- if ($verify == 1) {
169
- $mmb_core->set_master_public_key($public_key);
170
- $mmb_core->set_worker_message_id($id);
171
- $mmb_core->get_stats_instance();
172
- if(is_array($notifications) && !empty($notifications)){
173
- $mmb_core->stats_instance->set_notifications($notifications);
174
- }
175
- if(is_array($brand) && !empty($brand)){
176
- update_option('mwp_worker_brand',$brand);
177
- }
178
-
179
- mmb_response($mmb_core->stats_instance->get_initial_stats(), true);
180
- } else if ($verify == 0) {
181
- mmb_response('Invalid message signature. Please contact us if you see this message often.', false);
182
- } else {
183
- mmb_response('Command not successful. Please try again.', false);
184
- }
185
- } else {
186
- if (!get_option('_worker_nossl_key')) {
187
- srand();
188
-
189
- $random_key = md5(base64_encode($public_key) . rand(0, getrandmax()));
190
-
191
- $mmb_core->set_random_signature($random_key);
192
- $mmb_core->set_worker_message_id($id);
193
- $mmb_core->set_master_public_key($public_key);
194
- $mmb_core->get_stats_instance();
195
- if(is_array($notifications) && !empty($notifications)){
196
- $mmb_core->stats_instance->set_notifications($notifications);
197
- }
198
-
199
- if(is_array($brand) && !empty($brand)){
200
- update_option('mwp_worker_brand',$brand);
201
- }
202
-
203
- mmb_response($mmb_core->stats_instance->get_initial_stats(), true);
204
- } else
205
- mmb_response('Please deactivate & activate ManageWP Worker plugin on your site, then re-add the site to your dashboard.', false);
206
- }
207
- } else {
208
- mmb_response('Please deactivate & activate ManageWP Worker plugin on your site and re-add the site to your dashboard.', false);
209
- }
210
- } else {
211
- mmb_response('Invalid parameters received. Please try again.', false);
212
- }
213
- }
214
- }
215
-
216
- if( !function_exists ( 'mmb_remove_site' )) {
217
- function mmb_remove_site($params)
218
- {
219
- extract($params);
220
- global $mmb_core;
221
- $mmb_core->uninstall( $deactivate );
222
-
223
- include_once(ABSPATH . 'wp-admin/includes/plugin.php');
224
- $plugin_slug = basename(dirname(__FILE__)) . '/' . basename(__FILE__);
225
-
226
- if ($deactivate) {
227
- deactivate_plugins($plugin_slug, true);
228
- }
229
-
230
- if (!is_plugin_active($plugin_slug))
231
- mmb_response(array(
232
- 'deactivated' => 'Site removed successfully. <br /><br />ManageWP Worker plugin successfully deactivated.'
233
- ), true);
234
- else
235
- mmb_response(array(
236
- 'removed_data' => 'Site removed successfully. <br /><br /><b>ManageWP Worker plugin was not deactivated.</b>'
237
- ), true);
238
-
239
- }
240
- }
241
- if( !function_exists ( 'mmb_stats_get' )) {
242
- function mmb_stats_get($params)
243
- {
244
- global $mmb_core;
245
- $mmb_core->get_stats_instance();
246
- mmb_response($mmb_core->stats_instance->get($params), true);
247
- }
248
- }
249
-
250
- if( !function_exists ( 'mmb_worker_header' )) {
251
- function mmb_worker_header()
252
- { global $mmb_core, $current_user;
253
-
254
- if(!headers_sent()){
255
- if(isset($current_user->ID))
256
- $expiration = time() + apply_filters('auth_cookie_expiration', 10800, $current_user->ID, false);
257
- else
258
- $expiration = time() + 10800;
259
-
260
- setcookie(MMB_XFRAME_COOKIE, md5(MMB_XFRAME_COOKIE), $expiration, COOKIEPATH, COOKIE_DOMAIN, false, true);
261
- $_COOKIE[MMB_XFRAME_COOKIE] = md5(MMB_XFRAME_COOKIE);
262
- }
263
- }
264
- }
265
-
266
- if( !function_exists ( 'mmb_pre_init_stats' )) {
267
- function mmb_pre_init_stats( $params )
268
- {
269
- global $mmb_core;
270
- $mmb_core->get_stats_instance();
271
- return $mmb_core->stats_instance->pre_init_stats($params);
272
- }
273
- }
274
-
275
- //post
276
- if( !function_exists ( 'mmb_post_create' )) {
277
- function mmb_post_create($params)
278
- {
279
- global $mmb_core;
280
- $mmb_core->get_post_instance();
281
- $return = $mmb_core->post_instance->create($params);
282
- if (is_int($return))
283
- mmb_response($return, true);
284
- else{
285
- if(isset($return['error'])){
286
- mmb_response($return['error'], false);
287
- } else {
288
- mmb_response($return, false);
289
- }
290
- }
291
- }
292
- }
293
-
294
- if( !function_exists ( 'mmb_change_post_status' )) {
295
- function mmb_change_post_status($params)
296
- {
297
- global $mmb_core;
298
- $mmb_core->get_post_instance();
299
- $return = $mmb_core->post_instance->change_status($params);
300
- //mmb_response($return, true);
301
-
302
- }
303
- }
304
-
305
- //comments
306
- if( !function_exists ( 'mmb_change_comment_status' )) {
307
- function mmb_change_comment_status($params)
308
- {
309
- global $mmb_core;
310
- $mmb_core->get_comment_instance();
311
- $return = $mmb_core->comment_instance->change_status($params);
312
- //mmb_response($return, true);
313
- if ($return){
314
- $mmb_core->get_stats_instance();
315
- mmb_response($mmb_core->stats_instance->get_comments_stats($params), true);
316
- }else
317
- mmb_response('Comment not updated', false);
318
- }
319
-
320
- }
321
- if( !function_exists ( 'mmb_comment_stats_get' )) {
322
- function mmb_comment_stats_get($params)
323
- {
324
- global $mmb_core;
325
- $mmb_core->get_stats_instance();
326
- mmb_response($mmb_core->stats_instance->get_comments_stats($params), true);
327
- }
328
- }
329
-
330
- if( !function_exists ( 'mmb_backup_now' )) {
331
- //backup
332
- function mmb_backup_now($params)
333
- {
334
- global $mmb_core;
335
-
336
- $mmb_core->get_backup_instance();
337
- $return = $mmb_core->backup_instance->backup($params);
338
-
339
- if (is_array($return) && array_key_exists('error', $return))
340
- mmb_response($return['error'], false);
341
- else {
342
- mmb_response($return, true);
343
- }
344
- }
345
- }
346
-
347
- if( !function_exists ( 'mmb_run_task_now' )) {
348
- function mmb_run_task_now($params)
349
- {
350
- global $mmb_core;
351
- $mmb_core->get_backup_instance();
352
- $return = $mmb_core->backup_instance->task_now($params['task_name']);
353
- if (is_array($return) && array_key_exists('error', $return))
354
- mmb_response($return['error'], false);
355
- else {
356
- mmb_response($return, true);
357
- }
358
- }
359
- }
360
-
361
- if( !function_exists ( 'mmb_email_backup' )) {
362
- function mmb_email_backup($params)
363
- {
364
- global $mmb_core;
365
- $mmb_core->get_backup_instance();
366
- $return = $mmb_core->backup_instance->email_backup($params);
367
-
368
- if (is_array($return) && array_key_exists('error', $return))
369
- mmb_response($return['error'], false);
370
- else {
371
- mmb_response($return, true);
372
- }
373
- }
374
- }
375
-
376
- if( !function_exists ( 'mmb_check_backup_compat' )) {
377
- function mmb_check_backup_compat($params)
378
- {
379
- global $mmb_core;
380
- $mmb_core->get_backup_instance();
381
- $return = $mmb_core->backup_instance->check_backup_compat($params);
382
-
383
- if (is_array($return) && array_key_exists('error', $return))
384
- mmb_response($return['error'], false);
385
- else {
386
- mmb_response($return, true);
387
- }
388
- }
389
- }
390
-
391
- if( !function_exists ( 'mmb_get_backup_req' )) {
392
- function mmb_get_backup_req( $params )
393
- {
394
- global $mmb_core;
395
- $mmb_core->get_stats_instance();
396
- $return = $mmb_core->stats_instance->get_backup_req($params);
397
-
398
- mmb_response($return, true);
399
- }
400
- }
401
-
402
- if( !function_exists ( 'mmb_scheduled_backup' )) {
403
- function mmb_scheduled_backup($params)
404
- {
405
- global $mmb_core;
406
- $mmb_core->get_backup_instance();
407
- $return = $mmb_core->backup_instance->set_backup_task($params);
408
- mmb_response($return, $return);
409
- }
410
- }
411
-
412
- if( !function_exists ( 'mmm_delete_backup' )) {
413
- function mmm_delete_backup($params)
414
- {
415
- global $mmb_core;
416
- $mmb_core->get_backup_instance();
417
- $return = $mmb_core->backup_instance->delete_backup($params);
418
- mmb_response($return, $return);
419
- }
420
- }
421
-
422
- if( !function_exists ( 'mmb_optimize_tables' )) {
423
- function mmb_optimize_tables($params)
424
- {
425
- global $mmb_core;
426
- $mmb_core->get_backup_instance();
427
- $return = $mmb_core->backup_instance->optimize_tables();
428
- if ($return)
429
- mmb_response($return, true);
430
- else
431
- mmb_response(false, false);
432
- }
433
- }
434
- if( !function_exists ( 'mmb_restore_now' )) {
435
- function mmb_restore_now($params)
436
- {
437
- global $mmb_core;
438
- $mmb_core->get_backup_instance();
439
- $return = $mmb_core->backup_instance->restore($params);
440
- if (is_array($return) && array_key_exists('error', $return))
441
- mmb_response($return['error'], false);
442
- else
443
- mmb_response($return, true);
444
-
445
- }
446
- }
447
-
448
- if( !function_exists ( 'mmb_remote_backup_now' )) {
449
- function mmb_remote_backup_now($params)
450
- {
451
- global $mmb_core;
452
- $backup_instance = $mmb_core->get_backup_instance();
453
- $return = $mmb_core->backup_instance->remote_backup_now($params);
454
- if (is_array($return) && array_key_exists('error', $return))
455
- mmb_response($return['error'], false);
456
- else
457
- mmb_response($return, true);
458
- }
459
- }
460
-
461
-
462
- if( !function_exists ( 'mmb_clean_orphan_backups' )) {
463
- function mmb_clean_orphan_backups()
464
- {
465
- global $mmb_core;
466
- $backup_instance = $mmb_core->get_backup_instance();
467
- $return = $mmb_core->backup_instance->cleanup();
468
- if(is_array($return))
469
- mmb_response($return, true);
470
- else
471
- mmb_response($return, false);
472
- }
473
- }
474
-
475
- if( !function_exists ( 'mmb_update_worker_plugin' )) {
476
- function mmb_update_worker_plugin($params)
477
- {
478
- global $mmb_core;
479
- mmb_response($mmb_core->update_worker_plugin($params), true);
480
- }
481
- }
482
-
483
- if( !function_exists ( 'mmb_wp_checkversion' )) {
484
- function mmb_wp_checkversion($params)
485
- {
486
- include_once(ABSPATH . 'wp-includes/version.php');
487
- global $mmb_wp_version, $mmb_core;
488
- mmb_response($mmb_wp_version, true);
489
- }
490
- }
491
- if( !function_exists ( 'mmb_search_posts_by_term' )) {
492
- function mmb_search_posts_by_term($params)
493
- {
494
- global $mmb_core;
495
- $mmb_core->get_search_instance();
496
-
497
- $search_type = trim($params['search_type']);
498
- $search_term = strtolower(trim($params['search_term']));
499
-
500
- switch ($search_type){
501
- case 'page_post':
502
- $return = $mmb_core->search_instance->search_posts_by_term($params);
503
- if($return){
504
- $return = serialize($return);
505
- mmb_response($return, true);
506
- }else{
507
- mmb_response('No posts found', false);
508
- }
509
- break;
510
-
511
- case 'plugin':
512
- $plugins = get_option('active_plugins');
513
-
514
- $have_plugin = false;
515
- foreach ($plugins as $plugin) {
516
- if(strpos($plugin, $search_term)>-1){
517
- $have_plugin = true;
518
- }
519
- }
520
- if($have_plugin){
521
- mmb_response(serialize($plugin), true);
522
- }else{
523
- mmb_response(false, false);
524
- }
525
- break;
526
- case 'theme':
527
- $theme = strtolower(get_option('template'));
528
- if(strpos($theme, $search_term)>-1){
529
- mmb_response($theme, true);
530
- }else{
531
- mmb_response(false, false);
532
- }
533
- break;
534
- default: mmb_response(false, false);
535
- }
536
- $return = $mmb_core->search_instance->search_posts_by_term($params);
537
-
538
-
539
-
540
- if ($return_if_true) {
541
- mmb_response($return_value, true);
542
- } else {
543
- mmb_response($return_if_false, false);
544
- }
545
- }
546
- }
547
-
548
- if( !function_exists ( 'mmb_install_addon' )) {
549
- function mmb_install_addon($params)
550
- {
551
- global $mmb_core;
552
- $mmb_core->get_installer_instance();
553
- $return = $mmb_core->installer_instance->install_remote_file($params);
554
- mmb_response($return, true);
555
-
556
- }
557
- }
558
-
559
- if( !function_exists ( 'mmb_do_upgrade' )) {
560
- function mmb_do_upgrade($params)
561
- {
562
- global $mmb_core, $mmb_upgrading;
563
- $mmb_core->get_installer_instance();
564
- $return = $mmb_core->installer_instance->do_upgrade($params);
565
- mmb_response($return, true);
566
-
567
- }
568
- }
569
- if( !function_exists ( 'mmb_add_link' )) {
570
- function mmb_add_link($params)
571
- {
572
- global $mmb_core;
573
- $mmb_core->get_link_instance();
574
- $return = $mmb_core->link_instance->add_link($params);
575
- if (is_array($return) && array_key_exists('error', $return))
576
-
577
- mmb_response($return['error'], false);
578
- else {
579
- mmb_response($return, true);
580
- }
581
-
582
- }
583
- }
584
-
585
- if( !function_exists ( 'mmb_add_user' )) {
586
- function mmb_add_user($params)
587
- {
588
- global $mmb_core;
589
- $mmb_core->get_user_instance();
590
- $return = $mmb_core->user_instance->add_user($params);
591
- if (is_array($return) && array_key_exists('error', $return))
592
-
593
- mmb_response($return['error'], false);
594
- else {
595
- mmb_response($return, true);
596
- }
597
-
598
- }
599
- }
600
-
601
- if( !function_exists ('mmb_get_users')) {
602
- function mmb_get_users($params)
603
- {
604
- global $mmb_core;
605
- $mmb_core->get_user_instance();
606
- $return = $mmb_core->user_instance->get_users($params);
607
- if (is_array($return) && array_key_exists('error', $return))
608
- mmb_response($return['error'], false);
609
- else {
610
- mmb_response($return, true);
611
- }
612
- }
613
- }
614
-
615
- if( !function_exists ('mmb_edit_users')) {
616
- function mmb_edit_users($params)
617
- {
618
- global $mmb_core;
619
- $mmb_core->get_user_instance();
620
- $return = $mmb_core->user_instance->edit_users($params);
621
- mmb_response($return, true);
622
- }
623
- }
624
-
625
- if( !function_exists ( 'mmb_iframe_plugins_fix' )) {
626
- function mmb_iframe_plugins_fix($update_actions)
627
- {
628
- foreach($update_actions as $key => $action)
629
- {
630
- $update_actions[$key] = str_replace('target="_parent"','',$action);
631
- }
632
-
633
- return $update_actions;
634
-
635
- }
636
- }
637
- if( !function_exists ( 'mmb_execute_php_code' )) {
638
- function mmb_execute_php_code($params)
639
- {
640
- ob_start();
641
- eval($params['code']);
642
- $return = ob_get_flush();
643
- mmb_response(print_r($return, true), true);
644
- }
645
- }
646
-
647
- if( !function_exists ( 'mmb_set_notifications' )) {
648
- function mmb_set_notifications($params)
649
- {
650
- global $mmb_core;
651
- $mmb_core->get_stats_instance();
652
- $return = $mmb_core->stats_instance->set_notifications($params);
653
- if (is_array($return) && array_key_exists('error', $return))
654
- mmb_response($return['error'], false);
655
- else {
656
- mmb_response($return, true);
657
- }
658
-
659
- }
660
- }
661
-
662
- if( !function_exists ( 'mmb_set_alerts' )) {
663
- function mmb_set_alerts($params)
664
- {
665
- global $mmb_core;
666
- $mmb_core->get_stats_instance();
667
- $return = $mmb_core->stats_instance->set_alerts($params);
668
- mmb_response(true, true);
669
- }
670
-
671
- }
672
-
673
- if(!function_exists('mmb_more_reccurences')){
674
- //Backup Tasks
675
- add_filter('cron_schedules', 'mmb_more_reccurences');
676
- function mmb_more_reccurences($schedules) {
677
- $schedules['halfminute'] = array('interval' => 30, 'display' => 'Once in a half minute');
678
- $schedules['minutely'] = array('interval' => 60, 'display' => 'Once in a minute');
679
- $schedules['fiveminutes'] = array('interval' => 300, 'display' => 'Once every five minutes');
680
- $schedules['tenminutes'] = array('interval' => 600, 'display' => 'Once every ten minutes');
681
-
682
- return $schedules;
683
- }
684
- }
685
-
686
- add_action('mwp_backup_tasks', 'mwp_check_backup_tasks');
687
-
688
- if( !function_exists('mwp_check_backup_tasks') ){
689
- function mwp_check_backup_tasks() {
690
- global $mmb_core, $_wp_using_ext_object_cache;
691
- $_wp_using_ext_object_cache = false;
692
-
693
- $mmb_core->get_backup_instance();
694
- $mmb_core->backup_instance->check_backup_tasks();
695
- }
696
- }
697
-
698
- if (!wp_next_scheduled('mwp_notifications')) {
699
- wp_schedule_event( time(), 'twicedaily', 'mwp_notifications' );
700
- }
701
- add_action('mwp_notifications', 'mwp_check_notifications');
702
-
703
-
704
-
705
- if( !function_exists('mwp_check_notifications') ){
706
- function mwp_check_notifications() {
707
- global $mmb_core, $_wp_using_ext_object_cache;
708
- $_wp_using_ext_object_cache = false;
709
-
710
- $mmb_core->get_stats_instance();
711
- $mmb_core->stats_instance->check_notifications();
712
- }
713
- }
714
-
715
-
716
- if( !function_exists('mmb_get_plugins_themes') ){
717
- function mmb_get_plugins_themes($params) {
718
- global $mmb_core;
719
- $mmb_core->get_installer_instance();
720
- $return = $mmb_core->installer_instance->get($params);
721
- mmb_response($return, true);
722
- }
723
- }
724
-
725
- if( !function_exists('mmb_edit_plugins_themes') ){
726
- function mmb_edit_plugins_themes($params) {
727
- global $mmb_core;
728
- $mmb_core->get_installer_instance();
729
- $return = $mmb_core->installer_instance->edit($params);
730
- mmb_response($return, true);
731
- }
732
- }
733
-
734
- if( !function_exists('mmb_worker_brand')){
735
- function mmb_worker_brand($params) {
736
- update_option("mwp_worker_brand",$params['brand']);
737
- mmb_response(true, true);
738
- }
739
- }
740
-
741
- if( !function_exists('mmb_maintenance_mode')){
742
- function mmb_maintenance_mode( $params ) {
743
- global $wp_object_cache;
744
-
745
- $default = get_option('mwp_maintenace_mode');
746
- $params = empty($default) ? $params : array_merge($default, $params);
747
- update_option("mwp_maintenace_mode", $params);
748
-
749
- if(!empty($wp_object_cache))
750
- @$wp_object_cache->flush();
751
- mmb_response(true, true);
752
- }
753
- }
754
-
755
- if( !function_exists('mmb_plugin_actions') ){
756
- function mmb_plugin_actions() {
757
- global $mmb_actions, $mmb_core;
758
-
759
- if(!empty($mmb_actions)){
760
- global $_mmb_plugin_actions;
761
- if(!empty($_mmb_plugin_actions)){
762
- $failed = array();
763
- foreach($_mmb_plugin_actions as $action => $params){
764
- if(isset($mmb_actions[$action]))
765
- call_user_func($mmb_actions[$action], $params);
766
- else
767
- $failed[] = $action;
768
- }
769
- if(!empty($failed)){
770
- $f = implode(', ', $failed);
771
- $s = count($f) > 1 ? 'Actions "' . $f . '" do' : 'Action "' . $f . '" does';
772
- mmb_response($s.' not exist. Please update your Worker plugin.', false);
773
- }
774
-
775
- }
776
- }
777
-
778
- global $pagenow, $current_user, $mmode;
779
- if( !is_admin() && !in_array($pagenow, array( 'wp-login.php' ))){
780
- $mmode = get_option('mwp_maintenace_mode');
781
- if( !empty($mmode) ){
782
- if(isset($mmode['active']) && $mmode['active'] == true){
783
- if(isset($current_user->data) && !empty($current_user->data) && isset($mmode['hidecaps']) && !empty($mmode['hidecaps'])){
784
- $usercaps = array();
785
- if(isset($current_user->caps) && !empty($current_user->caps)){
786
- $usercaps = $current_user->caps;
787
- }
788
- foreach($mmode['hidecaps'] as $cap => $hide){
789
- if(!$hide)
790
- continue;
791
-
792
- foreach($usercaps as $ucap => $val){
793
- if($ucap == $cap){
794
- ob_end_clean();
795
- ob_end_flush();
796
- die($mmode['template']);
797
- }
798
- }
799
- }
800
- } else
801
- die($mmode['template']);
802
- }
803
- }
804
- }
805
- }
806
- }
807
-
808
- $mmb_core = new MMB_Core();
809
-
810
- if(isset($_GET['auto_login']))
811
- $mmb_core->automatic_login();
812
-
813
- if (function_exists('register_activation_hook'))
814
- register_activation_hook( __FILE__ , array( $mmb_core, 'install' ));
815
-
816
- if (function_exists('register_deactivation_hook'))
817
- register_deactivation_hook(__FILE__, array( $mmb_core, 'uninstall' ));
818
-
819
- if (function_exists('add_action'))
820
- add_action('init', 'mmb_plugin_actions', 99999);
821
-
822
- if (function_exists('add_filter'))
823
- add_filter('install_plugin_complete_actions','mmb_iframe_plugins_fix');
824
-
825
- if( isset($_COOKIE[MMB_XFRAME_COOKIE]) ){
826
- remove_action( 'admin_init', 'send_frame_options_header');
827
- remove_action( 'login_init', 'send_frame_options_header');
828
- }
829
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
830
  ?>
1
+ <?php
2
+ /*
3
+ Plugin Name: ManageWP - Worker
4
+ Plugin URI: http://managewp.com/
5
+ Description: Manage all your blogs from one dashboard. Visit <a href="http://managewp.com">ManageWP.com</a> to sign up.
6
+ Author: Prelovac Media
7
+ Version: 3.9.17
8
+ Author URI: http://www.prelovac.com
9
+ */
10
+
11
+ /*************************************************************
12
+ *
13
+ * init.php
14
+ *
15
+ * Initialize the communication with master
16
+ *
17
+ *
18
+ * Copyright (c) 2011 Prelovac Media
19
+ * www.prelovac.com
20
+ **************************************************************/
21
+
22
+ if(!defined('MMB_WORKER_VERSION'))
23
+ define('MMB_WORKER_VERSION', '3.9.17');
24
+
25
+ if ( !defined('MMB_XFRAME_COOKIE')){
26
+ $siteurl = function_exists('get_site_option') ? get_site_option( 'siteurl' ) : get_option('siteurl');
27
+ define('MMB_XFRAME_COOKIE', $xframe = 'wordpress_'.md5($siteurl).'_xframe');
28
+ }
29
+ global $wpdb, $mmb_plugin_dir, $mmb_plugin_url, $wp_version, $mmb_filters, $_mmb_item_filter;
30
+ if (version_compare(PHP_VERSION, '5.0.0', '<')) // min version 5 supported
31
+ exit("<p>ManageWP Worker plugin requires PHP 5 or higher.</p>");
32
+
33
+
34
+ $mmb_wp_version = $wp_version;
35
+ $mmb_plugin_dir = WP_PLUGIN_DIR . '/' . basename(dirname(__FILE__));
36
+ $mmb_plugin_url = WP_PLUGIN_URL . '/' . basename(dirname(__FILE__));
37
+
38
+ require_once("$mmb_plugin_dir/helper.class.php");
39
+ require_once("$mmb_plugin_dir/core.class.php");
40
+ require_once("$mmb_plugin_dir/post.class.php");
41
+ require_once("$mmb_plugin_dir/comment.class.php");
42
+ require_once("$mmb_plugin_dir/stats.class.php");
43
+ require_once("$mmb_plugin_dir/backup.class.php");
44
+ require_once("$mmb_plugin_dir/installer.class.php");
45
+ require_once("$mmb_plugin_dir/link.class.php");
46
+ require_once("$mmb_plugin_dir/user.class.php");
47
+ require_once("$mmb_plugin_dir/api.php");
48
+
49
+ require_once("$mmb_plugin_dir/plugins/search/search.php");
50
+ require_once("$mmb_plugin_dir/plugins/cleanup/cleanup.php");
51
+
52
+ require_once("$mmb_plugin_dir/widget.class.php");
53
+
54
+ if( !function_exists ( 'mmb_parse_request' )) {
55
+ function mmb_parse_request()
56
+ {
57
+
58
+ if (!isset($HTTP_RAW_POST_DATA)) {
59
+ $HTTP_RAW_POST_DATA = file_get_contents('php://input');
60
+ }
61
+ ob_start();
62
+
63
+ global $current_user, $mmb_core, $new_actions, $wp_db_version, $wpmu_version, $_wp_using_ext_object_cache;
64
+ $data = base64_decode($HTTP_RAW_POST_DATA);
65
+ if ($data)
66
+ $num = @extract(unserialize($data));
67
+
68
+ if (isset($action)) {
69
+ $_wp_using_ext_object_cache = false;
70
+ @set_time_limit(600);
71
+
72
+ if (!$mmb_core->check_if_user_exists($params['username']))
73
+ mmb_response('Username <b>' . $params['username'] . '</b> does not have administrator capabilities. Enter the correct username in the site options.', false);
74
+
75
+ if ($action == 'add_site') {
76
+ mmb_add_site($params);
77
+ mmb_response('You should never see this.', false);
78
+ }
79
+
80
+ $auth = $mmb_core->authenticate_message($action . $id, $signature, $id);
81
+ if ($auth === true) {
82
+
83
+ if(isset($params['username']) && !is_user_logged_in()){
84
+ $user = function_exists('get_user_by') ? get_user_by('login', $params['username']) : get_userdatabylogin( $params['username'] );
85
+ wp_set_current_user($user->ID);
86
+ }
87
+
88
+ /* in case database upgrade required, do database backup and perform upgrade ( wordpress wp_upgrade() function ) */
89
+ if( strlen(trim($wp_db_version)) && !defined('ACX_PLUGIN_DIR') ){
90
+ if ( get_option('db_version') != $wp_db_version ) {
91
+ /* in multisite network, please update database manualy */
92
+ if (empty($wpmu_version) || (function_exists('is_multisite') && !is_multisite())){
93
+ if( ! function_exists('wp_upgrade'))
94
+ include_once(ABSPATH.'wp-admin/includes/upgrade.php');
95
+
96
+ ob_clean();
97
+ @wp_upgrade();
98
+ @do_action('after_db_upgrade');
99
+ ob_end_clean();
100
+ }
101
+ }
102
+ }
103
+
104
+ if(isset($params['secure'])){
105
+ if($decrypted = $mmb_core->_secure_data($params['secure'])){
106
+ $decrypted = maybe_unserialize($decrypted);
107
+ if(is_array($decrypted)){
108
+ foreach($decrypted as $key => $val){
109
+ if(!is_numeric($key))
110
+ $params[$key] = $val;
111
+ }
112
+ unset($params['secure']);
113
+ } else $params['secure'] = $decrypted;
114
+ }
115
+ }
116
+
117
+ if( !$mmb_core->register_action_params( $action, $params ) ){
118
+ global $_mmb_plugin_actions;
119
+ $_mmb_plugin_actions[$action] = $params;
120
+ }
121
+
122
+
123
+ } else {
124
+ mmb_response($auth['error'], false);
125
+ }
126
+ } else {
127
+ MMB_Stats::set_hit_count();
128
+ }
129
+ ob_end_clean();
130
+ }
131
+ }
132
+ /* Main response function */
133
+ if( !function_exists ( 'mmb_response' )) {
134
+
135
+ function mmb_response($response = false, $success = true)
136
+ {
137
+ $return = array();
138
+
139
+ if ((is_array($response) && empty($response)) || (!is_array($response) && strlen($response) == 0))
140
+ $return['error'] = 'Empty response.';
141
+ else if ($success)
142
+ $return['success'] = $response;
143
+ else
144
+ $return['error'] = $response;
145
+
146
+ if( !headers_sent() ){
147
+ header('HTTP/1.0 200 OK');
148
+ header('Content-Type: text/plain');
149
+ }
150
+ exit("<MWPHEADER>" . base64_encode(serialize($return))."<ENDMWPHEADER>");
151
+ }
152
+ }
153
+
154
+
155
+
156
+ if( !function_exists ( 'mmb_add_site' )) {
157
+ function mmb_add_site($params)
158
+ {
159
+ global $mmb_core;
160
+ $num = extract($params);
161
+
162
+ if ($num) {
163
+ if (!get_option('_action_message_id') && !get_option('_worker_public_key')) {
164
+ $public_key = base64_decode($public_key);
165
+
166
+ if (function_exists('openssl_verify')) {
167
+ $verify = openssl_verify($action . $id, base64_decode($signature), $public_key);
168
+ if ($verify == 1) {
169
+ $mmb_core->set_master_public_key($public_key);
170
+ $mmb_core->set_worker_message_id($id);
171
+ $mmb_core->get_stats_instance();
172
+ if(is_array($notifications) && !empty($notifications)){
173
+ $mmb_core->stats_instance->set_notifications($notifications);
174
+ }
175
+ if(is_array($brand) && !empty($brand)){
176
+ update_option('mwp_worker_brand',$brand);
177
+ }
178
+
179
+ mmb_response($mmb_core->stats_instance->get_initial_stats(), true);
180
+ } else if ($verify == 0) {
181
+ mmb_response('Invalid message signature. Please contact us if you see this message often.', false);
182
+ } else {
183
+ mmb_response('Command not successful. Please try again.', false);
184
+ }
185
+ } else {
186
+ if (!get_option('_worker_nossl_key')) {
187
+ srand();
188
+
189
+ $random_key = md5(base64_encode($public_key) . rand(0, getrandmax()));
190
+
191
+ $mmb_core->set_random_signature($random_key);
192
+ $mmb_core->set_worker_message_id($id);
193
+ $mmb_core->set_master_public_key($public_key);
194
+ $mmb_core->get_stats_instance();
195
+ if(is_array($notifications) && !empty($notifications)){
196
+ $mmb_core->stats_instance->set_notifications($notifications);
197
+ }
198
+
199
+ if(is_array($brand) && !empty($brand)){
200
+ update_option('mwp_worker_brand',$brand);
201
+ }
202
+
203
+ mmb_response($mmb_core->stats_instance->get_initial_stats(), true);
204
+ } else
205
+ mmb_response('Please deactivate & activate ManageWP Worker plugin on your site, then re-add the site to your dashboard.', false);
206
+ }
207
+ } else {
208
+ mmb_response('Please deactivate & activate ManageWP Worker plugin on your site and re-add the site to your dashboard.', false);
209
+ }
210
+ } else {
211
+ mmb_response('Invalid parameters received. Please try again.', false);
212
+ }
213
+ }
214
+ }
215
+
216
+ if( !function_exists ( 'mmb_remove_site' )) {
217
+ function mmb_remove_site($params)
218
+ {
219
+ extract($params);
220
+ global $mmb_core;
221
+ $mmb_core->uninstall( $deactivate );
222
+
223
+ include_once(ABSPATH . 'wp-admin/includes/plugin.php');
224
+ $plugin_slug = basename(dirname(__FILE__)) . '/' . basename(__FILE__);
225
+
226
+ if ($deactivate) {
227
+ deactivate_plugins($plugin_slug, true);
228
+ }
229
+
230
+ if (!is_plugin_active($plugin_slug))
231
+ mmb_response(array(
232
+ 'deactivated' => 'Site removed successfully. <br /><br />ManageWP Worker plugin successfully deactivated.'
233
+ ), true);
234
+ else
235
+ mmb_response(array(
236
+ 'removed_data' => 'Site removed successfully. <br /><br /><b>ManageWP Worker plugin was not deactivated.</b>'
237
+ ), true);
238
+
239
+ }
240
+ }
241
+ if( !function_exists ( 'mmb_stats_get' )) {
242
+ function mmb_stats_get($params)
243
+ {
244
+ global $mmb_core;
245
+ $mmb_core->get_stats_instance();
246
+ mmb_response($mmb_core->stats_instance->get($params), true);
247
+ }
248
+ }
249
+
250
+ if( !function_exists ( 'mmb_worker_header' )) {
251
+ function mmb_worker_header()
252
+ { global $mmb_core, $current_user;
253
+
254
+ if(!headers_sent()){
255
+ if(isset($current_user->ID))
256
+ $expiration = time() + apply_filters('auth_cookie_expiration', 10800, $current_user->ID, false);
257
+ else
258
+ $expiration = time() + 10800;
259
+
260
+ setcookie(MMB_XFRAME_COOKIE, md5(MMB_XFRAME_COOKIE), $expiration, COOKIEPATH, COOKIE_DOMAIN, false, true);
261
+ $_COOKIE[MMB_XFRAME_COOKIE] = md5(MMB_XFRAME_COOKIE);
262
+ }
263
+ }
264
+ }
265
+
266
+ if( !function_exists ( 'mmb_pre_init_stats' )) {
267
+ function mmb_pre_init_stats( $params )
268
+ {
269
+ global $mmb_core;
270
+ $mmb_core->get_stats_instance();
271
+ return $mmb_core->stats_instance->pre_init_stats($params);
272
+ }
273
+ }
274
+
275
+ //post
276
+ if( !function_exists ( 'mmb_post_create' )) {
277
+ function mmb_post_create($params)
278
+ {
279
+ global $mmb_core;
280
+ $mmb_core->get_post_instance();
281
+ $return = $mmb_core->post_instance->create($params);
282
+ if (is_int($return))
283
+ mmb_response($return, true);
284
+ else{
285
+ if(isset($return['error'])){
286
+ mmb_response($return['error'], false);
287
+ } else {
288
+ mmb_response($return, false);
289
+ }
290
+ }
291
+ }
292
+ }
293
+
294
+ if( !function_exists ( 'mmb_change_post_status' )) {
295
+ function mmb_change_post_status($params)
296
+ {
297
+ global $mmb_core;
298
+ $mmb_core->get_post_instance();
299
+ $return = $mmb_core->post_instance->change_status($params);
300
+ //mmb_response($return, true);
301
+
302
+ }
303
+ }
304
+
305
+ //comments
306
+ if( !function_exists ( 'mmb_change_comment_status' )) {
307
+ function mmb_change_comment_status($params)
308
+ {
309
+ global $mmb_core;
310
+ $mmb_core->get_comment_instance();
311
+ $return = $mmb_core->comment_instance->change_status($params);
312
+ //mmb_response($return, true);
313
+ if ($return){
314
+ $mmb_core->get_stats_instance();
315
+ mmb_response($mmb_core->stats_instance->get_comments_stats($params), true);
316
+ }else
317
+ mmb_response('Comment not updated', false);
318
+ }
319
+
320
+ }
321
+ if( !function_exists ( 'mmb_comment_stats_get' )) {
322
+ function mmb_comment_stats_get($params)
323
+ {
324
+ global $mmb_core;
325
+ $mmb_core->get_stats_instance();
326
+ mmb_response($mmb_core->stats_instance->get_comments_stats($params), true);
327
+ }
328
+ }
329
+
330
+ if( !function_exists ( 'mmb_backup_now' )) {
331
+ //backup
332
+ function mmb_backup_now($params)
333
+ {
334
+ global $mmb_core;
335
+
336
+ $mmb_core->get_backup_instance();
337
+ $return = $mmb_core->backup_instance->backup($params);
338
+
339
+ if (is_array($return) && array_key_exists('error', $return))
340
+ mmb_response($return['error'], false);
341
+ else {
342
+ mmb_response($return, true);
343
+ }
344
+ }
345
+ }
346
+
347
+ if( !function_exists ( 'mmb_run_task_now' )) {
348
+ function mmb_run_task_now($params)
349
+ {
350
+ global $mmb_core;
351
+ $mmb_core->get_backup_instance();
352
+ $return = $mmb_core->backup_instance->task_now($params['task_name']);
353
+ if (is_array($return) && array_key_exists('error', $return))
354
+ mmb_response($return['error'], false);
355
+ else {
356
+ mmb_response($return, true);
357
+ }
358
+ }
359
+ }
360
+
361
+ if( !function_exists ( 'mmb_email_backup' )) {
362
+ function mmb_email_backup($params)
363
+ {
364
+ global $mmb_core;
365
+ $mmb_core->get_backup_instance();
366
+ $return = $mmb_core->backup_instance->email_backup($params);
367
+
368
+ if (is_array($return) && array_key_exists('error', $return))
369
+ mmb_response($return['error'], false);
370
+ else {
371
+ mmb_response($return, true);
372
+ }
373
+ }
374
+ }
375
+
376
+ if( !function_exists ( 'mmb_check_backup_compat' )) {
377
+ function mmb_check_backup_compat($params)
378
+ {
379
+ global $mmb_core;
380
+ $mmb_core->get_backup_instance();
381
+ $return = $mmb_core->backup_instance->check_backup_compat($params);
382
+
383
+ if (is_array($return) && array_key_exists('error', $return))
384
+ mmb_response($return['error'], false);
385
+ else {
386
+ mmb_response($return, true);
387
+ }
388
+ }
389
+ }
390
+
391
+ if( !function_exists ( 'mmb_get_backup_req' )) {
392
+ function mmb_get_backup_req( $params )
393
+ {
394
+ global $mmb_core;
395
+ $mmb_core->get_stats_instance();
396
+ $return = $mmb_core->stats_instance->get_backup_req($params);
397
+
398
+ mmb_response($return, true);
399
+ }
400
+ }
401
+
402
+ if( !function_exists ( 'mmb_scheduled_backup' )) {
403
+ function mmb_scheduled_backup($params)
404
+ {
405
+ global $mmb_core;
406
+ $mmb_core->get_backup_instance();
407
+ $return = $mmb_core->backup_instance->set_backup_task($params);
408
+ mmb_response($return, $return);
409
+ }
410
+ }
411
+
412
+ if( !function_exists ( 'mmm_delete_backup' )) {
413
+ function mmm_delete_backup($params)
414
+ {
415
+ global $mmb_core;
416
+ $mmb_core->get_backup_instance();
417
+ $return = $mmb_core->backup_instance->delete_backup($params);
418
+ mmb_response($return, $return);
419
+ }
420
+ }
421
+
422
+ if( !function_exists ( 'mmb_optimize_tables' )) {
423
+ function mmb_optimize_tables($params)
424
+ {
425
+ global $mmb_core;
426
+ $mmb_core->get_backup_instance();
427
+ $return = $mmb_core->backup_instance->optimize_tables();
428
+ if ($return)
429
+ mmb_response($return, true);
430
+ else
431
+ mmb_response(false, false);
432
+ }
433
+ }
434
+ if( !function_exists ( 'mmb_restore_now' )) {
435
+ function mmb_restore_now($params)
436
+ {
437
+ global $mmb_core;
438
+ $mmb_core->get_backup_instance();
439
+ $return = $mmb_core->backup_instance->restore($params);
440
+ if (is_array($return) && array_key_exists('error', $return))
441
+ mmb_response($return['error'], false);
442
+ else
443
+ mmb_response($return, true);
444
+
445
+ }
446
+ }
447
+
448
+ if( !function_exists ( 'mmb_remote_backup_now' )) {
449
+ function mmb_remote_backup_now($params)
450
+ {
451
+ global $mmb_core;
452
+ $backup_instance = $mmb_core->get_backup_instance();
453
+ $return = $mmb_core->backup_instance->remote_backup_now($params);
454
+ if (is_array($return) && array_key_exists('error', $return))
455
+ mmb_response($return['error'], false);
456
+ else
457
+ mmb_response($return, true);
458
+ }
459
+ }
460
+
461
+
462
+ if( !function_exists ( 'mmb_clean_orphan_backups' )) {
463
+ function mmb_clean_orphan_backups()
464
+ {
465
+ global $mmb_core;
466
+ $backup_instance = $mmb_core->get_backup_instance();
467
+ $return = $mmb_core->backup_instance->cleanup();
468
+ if(is_array($return))
469
+ mmb_response($return, true);
470
+ else
471
+ mmb_response($return, false);
472
+ }
473
+ }
474
+
475
+ if( !function_exists ( 'mmb_update_worker_plugin' )) {
476
+ function mmb_update_worker_plugin($params)
477
+ {
478
+ global $mmb_core;
479
+ mmb_response($mmb_core->update_worker_plugin($params), true);
480
+ }
481
+ }
482
+
483
+ if( !function_exists ( 'mmb_wp_checkversion' )) {
484
+ function mmb_wp_checkversion($params)
485
+ {
486
+ include_once(ABSPATH . 'wp-includes/version.php');
487
+ global $mmb_wp_version, $mmb_core;
488
+ mmb_response($mmb_wp_version, true);
489
+ }
490
+ }
491
+ if( !function_exists ( 'mmb_search_posts_by_term' )) {
492
+ function mmb_search_posts_by_term($params)
493
+ {
494
+ global $mmb_core;
495
+ $mmb_core->get_search_instance();
496
+
497
+ $search_type = trim($params['search_type']);
498
+ $search_term = strtolower(trim($params['search_term']));
499
+
500
+ switch ($search_type){
501
+ case 'page_post':
502
+ $return = $mmb_core->search_instance->search_posts_by_term($params);
503
+ if($return){
504
+ $return = serialize($return);
505
+ mmb_response($return, true);
506
+ }else{
507
+ mmb_response('No posts found', false);
508
+ }
509
+ break;
510
+
511
+ case 'plugin':
512
+ $plugins = get_option('active_plugins');
513
+
514
+ $have_plugin = false;
515
+ foreach ($plugins as $plugin) {
516
+ if(strpos($plugin, $search_term)>-1){
517
+ $have_plugin = true;
518
+ }
519
+ }
520
+ if($have_plugin){
521
+ mmb_response(serialize($plugin), true);
522
+ }else{
523
+ mmb_response(false, false);
524
+ }
525
+ break;
526
+ case 'theme':
527
+ $theme = strtolower(get_option('template'));
528
+ if(strpos($theme, $search_term)>-1){
529
+ mmb_response($theme, true);
530
+ }else{
531
+ mmb_response(false, false);
532
+ }
533
+ break;
534
+ default: mmb_response(false, false);
535
+ }
536
+ $return = $mmb_core->search_instance->search_posts_by_term($params);
537
+
538
+
539
+
540
+ if ($return_if_true) {
541
+ mmb_response($return_value, true);
542
+ } else {
543
+ mmb_response($return_if_false, false);
544
+ }
545
+ }
546
+ }
547
+
548
+ if( !function_exists ( 'mmb_install_addon' )) {
549
+ function mmb_install_addon($params)
550
+ {
551
+ global $mmb_core;
552
+ $mmb_core->get_installer_instance();
553
+ $return = $mmb_core->installer_instance->install_remote_file($params);
554
+ mmb_response($return, true);
555
+
556
+ }
557
+ }
558
+
559
+ if( !function_exists ( 'mmb_do_upgrade' )) {
560
+ function mmb_do_upgrade($params)
561
+ {
562
+ global $mmb_core, $mmb_upgrading;
563
+ $mmb_core->get_installer_instance();
564
+ $return = $mmb_core->installer_instance->do_upgrade($params);
565
+ mmb_response($return, true);
566
+
567
+ }
568
+ }
569
+ if( !function_exists ( 'mmb_add_link' )) {
570
+ function mmb_add_link($params)
571
+ {
572
+ global $mmb_core;
573
+ $mmb_core->get_link_instance();
574
+ $return = $mmb_core->link_instance->add_link($params);
575
+ if (is_array($return) && array_key_exists('error', $return))
576
+
577
+ mmb_response($return['error'], false);
578
+ else {
579
+ mmb_response($return, true);
580
+ }
581
+
582
+ }
583
+ }
584
+
585
+ if( !function_exists ( 'mmb_add_user' )) {
586
+ function mmb_add_user($params)
587
+ {
588
+ global $mmb_core;
589
+ $mmb_core->get_user_instance();
590
+ $return = $mmb_core->user_instance->add_user($params);
591
+ if (is_array($return) && array_key_exists('error', $return))
592
+
593
+ mmb_response($return['error'], false);
594
+ else {
595
+ mmb_response($return, true);
596
+ }
597
+
598
+ }
599
+ }
600
+
601
+ if( !function_exists ('mmb_get_users')) {
602
+ function mmb_get_users($params)
603
+ {
604
+ global $mmb_core;
605
+ $mmb_core->get_user_instance();
606
+ $return = $mmb_core->user_instance->get_users($params);
607
+ if (is_array($return) && array_key_exists('error', $return))
608
+ mmb_response($return['error'], false);
609
+ else {
610
+ mmb_response($return, true);
611
+ }
612
+ }
613
+ }
614
+
615
+ if( !function_exists ('mmb_edit_users')) {
616
+ function mmb_edit_users($params)
617
+ {
618
+ global $mmb_core;
619
+ $mmb_core->get_user_instance();
620
+ $return = $mmb_core->user_instance->edit_users($params);
621
+ mmb_response($return, true);
622
+ }
623
+ }
624
+
625
+ if( !function_exists ('mmb_get_posts')) {
626
+ function mmb_get_posts($params)
627
+ {
628
+ global $mmb_core;
629
+ $mmb_core->get_post_instance();
630
+
631
+ $return = $mmb_core->post_instance->get_posts($params);
632
+ if (is_array($return) && array_key_exists('error', $return))
633
+ mmb_response($return['error'], false);
634
+ else {
635
+ mmb_response($return, true);
636
+ }
637
+ }
638
+ }
639
+
640
+ if( !function_exists ('mmb_delete_post')) {
641
+ function mmb_delete_post($params)
642
+ {
643
+ global $mmb_core;
644
+ $mmb_core->get_post_instance();
645
+
646
+ $return = $mmb_core->post_instance->delete_post($params);
647
+ if (is_array($return) && array_key_exists('error', $return))
648
+ mmb_response($return['error'], false);
649
+ else {
650
+ mmb_response($return, true);
651
+ }
652
+ }
653
+ }
654
+
655
+ if( !function_exists ('mmb_edit_posts')) {
656
+ function mmb_edit_posts($params)
657
+ {
658
+ global $mmb_core;
659
+ $mmb_core->get_posts_instance();
660
+ $return = $mmb_core->posts_instance->edit_posts($params);
661
+ mmb_response($return, true);
662
+ }
663
+ }
664
+
665
+ if( !function_exists ('mmb_get_pages')) {
666
+ function mmb_get_pages($params)
667
+ {
668
+ global $mmb_core;
669
+ $mmb_core->get_post_instance();
670
+
671
+ $return = $mmb_core->post_instance->get_pages($params);
672
+ if (is_array($return) && array_key_exists('error', $return))
673
+ mmb_response($return['error'], false);
674
+ else {
675
+ mmb_response($return, true);
676
+ }
677
+ }
678
+ }
679
+
680
+ if( !function_exists ('mmb_delete_page')) {
681
+ function mmb_delete_page($params)
682
+ {
683
+ global $mmb_core;
684
+ $mmb_core->get_post_instance();
685
+
686
+ $return = $mmb_core->post_instance->delete_page($params);
687
+ if (is_array($return) && array_key_exists('error', $return))
688
+ mmb_response($return['error'], false);
689
+ else {
690
+ mmb_response($return, true);
691
+ }
692
+ }
693
+ }
694
+
695
+ if( !function_exists ( 'mmb_iframe_plugins_fix' )) {
696
+ function mmb_iframe_plugins_fix($update_actions)
697
+ {
698
+ foreach($update_actions as $key => $action)
699
+ {
700
+ $update_actions[$key] = str_replace('target="_parent"','',$action);
701
+ }
702
+
703
+ return $update_actions;
704
+
705
+ }
706
+ }
707
+ if( !function_exists ( 'mmb_execute_php_code' )) {
708
+ function mmb_execute_php_code($params)
709
+ {
710
+ ob_start();
711
+ eval($params['code']);
712
+ $return = ob_get_flush();
713
+ mmb_response(print_r($return, true), true);
714
+ }
715
+ }
716
+
717
+ if( !function_exists ( 'mmb_set_notifications' )) {
718
+ function mmb_set_notifications($params)
719
+ {
720
+ global $mmb_core;
721
+ $mmb_core->get_stats_instance();
722
+ $return = $mmb_core->stats_instance->set_notifications($params);
723
+ if (is_array($return) && array_key_exists('error', $return))
724
+ mmb_response($return['error'], false);
725
+ else {
726
+ mmb_response($return, true);
727
+ }
728
+
729
+ }
730
+ }
731
+
732
+ if( !function_exists ( 'mmb_set_alerts' )) {
733
+ function mmb_set_alerts($params)
734
+ {
735
+ global $mmb_core;
736
+ $mmb_core->get_stats_instance();
737
+ $return = $mmb_core->stats_instance->set_alerts($params);
738
+ mmb_response(true, true);
739
+ }
740
+
741
+ }
742
+
743
+ if(!function_exists('mmb_more_reccurences')){
744
+ //Backup Tasks
745
+ add_filter('cron_schedules', 'mmb_more_reccurences');
746
+ function mmb_more_reccurences($schedules) {
747
+ $schedules['halfminute'] = array('interval' => 30, 'display' => 'Once in a half minute');
748
+ $schedules['minutely'] = array('interval' => 60, 'display' => 'Once in a minute');
749
+ $schedules['fiveminutes'] = array('interval' => 300, 'display' => 'Once every five minutes');
750
+ $schedules['tenminutes'] = array('interval' => 600, 'display' => 'Once every ten minutes');
751
+
752
+ return $schedules;
753
+ }
754
+ }
755
+
756
+ add_action('mwp_backup_tasks', 'mwp_check_backup_tasks');
757
+
758
+ if( !function_exists('mwp_check_backup_tasks') ){
759
+ function mwp_check_backup_tasks() {
760
+ global $mmb_core, $_wp_using_ext_object_cache;
761
+ $_wp_using_ext_object_cache = false;
762
+
763
+ $mmb_core->get_backup_instance();
764
+ $mmb_core->backup_instance->check_backup_tasks();
765
+ }
766
+ }
767
+
768
+ if (!wp_next_scheduled('mwp_notifications')) {
769
+ wp_schedule_event( time(), 'twicedaily', 'mwp_notifications' );
770
+ }
771
+ add_action('mwp_notifications', 'mwp_check_notifications');
772
+
773
+
774
+
775
+ if( !function_exists('mwp_check_notifications') ){
776
+ function mwp_check_notifications() {
777
+ global $mmb_core, $_wp_using_ext_object_cache;
778
+ $_wp_using_ext_object_cache = false;
779
+
780
+ $mmb_core->get_stats_instance();
781
+ $mmb_core->stats_instance->check_notifications();
782
+ }
783
+ }
784
+
785
+
786
+ if( !function_exists('mmb_get_plugins_themes') ){
787
+ function mmb_get_plugins_themes($params) {
788
+ global $mmb_core;
789
+ $mmb_core->get_installer_instance();
790
+ $return = $mmb_core->installer_instance->get($params);
791
+ mmb_response($return, true);
792
+ }
793
+ }
794
+
795
+ if( !function_exists('mmb_edit_plugins_themes') ){
796
+ function mmb_edit_plugins_themes($params) {
797
+ global $mmb_core;
798
+ $mmb_core->get_installer_instance();
799
+ $return = $mmb_core->installer_instance->edit($params);
800
+ mmb_response($return, true);
801
+ }
802
+ }
803
+
804
+ if( !function_exists('mmb_worker_brand')){
805
+ function mmb_worker_brand($params) {
806
+ update_option("mwp_worker_brand",$params['brand']);
807
+ mmb_response(true, true);
808
+ }
809
+ }
810
+
811
+ if( !function_exists('mmb_maintenance_mode')){
812
+ function mmb_maintenance_mode( $params ) {
813
+ global $wp_object_cache;
814
+
815
+ $default = get_option('mwp_maintenace_mode');
816
+ $params = empty($default) ? $params : array_merge($default, $params);
817
+ update_option("mwp_maintenace_mode", $params);
818
+
819
+ if(!empty($wp_object_cache))
820
+ @$wp_object_cache->flush();
821
+ mmb_response(true, true);
822
+ }
823
+ }
824
+
825
+ if( !function_exists('mmb_plugin_actions') ){
826
+ function mmb_plugin_actions() {
827
+ global $mmb_actions, $mmb_core;
828
+
829
+ if(!empty($mmb_actions)){
830
+ global $_mmb_plugin_actions;
831
+ if(!empty($_mmb_plugin_actions)){
832
+ $failed = array();
833
+ foreach($_mmb_plugin_actions as $action => $params){
834
+ if(isset($mmb_actions[$action]))
835
+ call_user_func($mmb_actions[$action], $params);
836
+ else
837
+ $failed[] = $action;
838
+ }
839
+ if(!empty($failed)){
840
+ $f = implode(', ', $failed);
841
+ $s = count($f) > 1 ? 'Actions "' . $f . '" do' : 'Action "' . $f . '" does';
842
+ mmb_response($s.' not exist. Please update your Worker plugin.', false);
843
+ }
844
+
845
+ }
846
+ }
847
+
848
+ global $pagenow, $current_user, $mmode;
849
+ if( !is_admin() && !in_array($pagenow, array( 'wp-login.php' ))){
850
+ $mmode = get_option('mwp_maintenace_mode');
851
+ if( !empty($mmode) ){
852
+ if(isset($mmode['active']) && $mmode['active'] == true){
853
+ if(isset($current_user->data) && !empty($current_user->data) && isset($mmode['hidecaps']) && !empty($mmode['hidecaps'])){
854
+ $usercaps = array();
855
+ if(isset($current_user->caps) && !empty($current_user->caps)){
856
+ $usercaps = $current_user->caps;
857
+ }
858
+ foreach($mmode['hidecaps'] as $cap => $hide){
859
+ if(!$hide)
860
+ continue;
861
+
862
+ foreach($usercaps as $ucap => $val){
863
+ if($ucap == $cap){
864
+ ob_end_clean();
865
+ ob_end_flush();
866
+ die($mmode['template']);
867
+ }
868
+ }
869
+ }
870
+ } else
871
+ die($mmode['template']);
872
+ }
873
+ }
874
+ }
875
+ }
876
+ }
877
+
878
+ $mmb_core = new MMB_Core();
879
+
880
+ if(isset($_GET['auto_login']))
881
+ $mmb_core->automatic_login();
882
+
883
+ if (function_exists('register_activation_hook'))
884
+ register_activation_hook( __FILE__ , array( $mmb_core, 'install' ));
885
+
886
+ if (function_exists('register_deactivation_hook'))
887
+ register_deactivation_hook(__FILE__, array( $mmb_core, 'uninstall' ));
888
+
889
+ if (function_exists('add_action'))
890
+ add_action('init', 'mmb_plugin_actions', 99999);
891
+
892
+ if (function_exists('add_filter'))
893
+ add_filter('install_plugin_complete_actions','mmb_iframe_plugins_fix');
894
+
895
+ if( isset($_COOKIE[MMB_XFRAME_COOKIE]) ){
896
+ remove_action( 'admin_init', 'send_frame_options_header');
897
+ remove_action( 'login_init', 'send_frame_options_header');
898
+ }
899
+
900
  ?>
installer.class.php CHANGED
@@ -1,868 +1,868 @@
1
- <?php
2
- /*************************************************************
3
- *
4
- * installer.class.php
5
- *
6
- * Upgrade WordPress
7
- *
8
- *
9
- * Copyright (c) 2011 Prelovac Media
10
- * www.prelovac.com
11
- **************************************************************/
12
-
13
- class MMB_Installer extends MMB_Core
14
- {
15
- function __construct()
16
- {
17
- @set_time_limit(600);
18
- parent::__construct();
19
- @include_once(ABSPATH . 'wp-admin/includes/file.php');
20
- @include_once(ABSPATH . 'wp-admin/includes/plugin.php');
21
- @include_once(ABSPATH . 'wp-admin/includes/theme.php');
22
- @include_once(ABSPATH . 'wp-admin/includes/misc.php');
23
- @include_once(ABSPATH . 'wp-admin/includes/template.php');
24
- @include_once(ABSPATH . 'wp-admin/includes/class-wp-upgrader.php');
25
-
26
- global $wp_filesystem;
27
- if (!$wp_filesystem)
28
- WP_Filesystem();
29
- }
30
-
31
- function mmb_maintenance_mode($enable = false, $maintenance_message = '')
32
- {
33
- global $wp_filesystem;
34
-
35
- $maintenance_message .= '<?php $upgrading = ' . time() . '; ?>';
36
-
37
- $file = $wp_filesystem->abspath() . '.maintenance';
38
- if ($enable) {
39
- $wp_filesystem->delete($file);
40
- $wp_filesystem->put_contents($file, $maintenance_message, FS_CHMOD_FILE);
41
- } else {
42
- $wp_filesystem->delete($file);
43
- }
44
- }
45
-
46
- function install_remote_file($params)
47
- {
48
- global $wp_filesystem;
49
- extract($params);
50
-
51
- if (!isset($package) || empty($package))
52
- return array(
53
- 'error' => '<p>No files received. Internal error.</p>'
54
- );
55
-
56
- if (defined('WP_INSTALLING') && file_exists(ABSPATH . '.maintenance'))
57
- return array(
58
- 'error' => '<p>Site under maintanace.</p>'
59
- );
60
-
61
- if (!class_exists('WP_Upgrader'))
62
- include_once(ABSPATH . 'wp-admin/includes/class-wp-upgrader.php');
63
-
64
- $upgrader_skin = new WP_Upgrader_Skin();
65
- $upgrader_skin->done_header = true;
66
-
67
- $upgrader = new WP_Upgrader($upgrader_skin);
68
- $destination = $type == 'themes' ? WP_CONTENT_DIR . '/themes' : WP_PLUGIN_DIR;
69
- $clear_destination = isset($clear_destination) ? $clear_destination : false;
70
-
71
- foreach ($package as $package_url) {
72
- $key = basename($package_url);
73
- $install_info[$key] = @$upgrader->run(array(
74
- 'package' => $package_url,
75
- 'destination' => $destination,
76
- 'clear_destination' => $clear_destination, //Do not overwrite files.
77
- 'clear_working' => true,
78
- 'hook_extra' => array()
79
- ));
80
- }
81
-
82
- if ($activate) {
83
- if ($type == 'plugins') {
84
- include_once(ABSPATH . 'wp-admin/includes/plugin.php');
85
- $all_plugins = get_plugins();
86
- foreach ($all_plugins as $plugin_slug => $plugin) {
87
- $plugin_dir = preg_split('/\//', $plugin_slug);
88
- foreach ($install_info as $key => $install) {
89
- if (!$install || is_wp_error($install))
90
- continue;
91
- if ($install['destination_name'] == $plugin_dir[0]) {
92
- $install_info[$key]['activated'] = activate_plugin($plugin_slug, '', false);
93
- }
94
- }
95
- }
96
- } else if (count($install_info) == 1) {
97
- global $wp_themes;
98
- include_once(ABSPATH . 'wp-includes/theme.php');
99
-
100
- $wp_themes = null;
101
- unset($wp_themes); //prevent theme data caching
102
-
103
- $all_themes = get_themes();
104
- foreach ($all_themes as $theme_name => $theme_data) {
105
- foreach ($install_info as $key => $install) {
106
- if (!$install || is_wp_error($install))
107
- continue;
108
-
109
- if ($theme_data['Template'] == $install['destination_name']) {
110
- $install_info[$key]['activated'] = switch_theme($theme_data['Template'], $theme_data['Stylesheet']);
111
- }
112
- }
113
- }
114
- }
115
- }
116
- ob_clean();
117
- $this->mmb_maintenance_mode(false);
118
- return $install_info;
119
- }
120
-
121
- function do_upgrade($params = null)
122
- {
123
- if ($params == null || empty($params))
124
- return array(
125
- 'failed' => 'No upgrades passed.'
126
- );
127
-
128
- if (!$this->is_server_writable()) {
129
- return array(
130
- 'error' => 'Failed, please <a target="_blank" href="http://managewp.com/user-guide#ftp">add FTP details</a></a>'
131
- );
132
- }
133
-
134
-
135
- $params = isset($params['upgrades_all']) ? $params['upgrades_all'] : $params;
136
-
137
- $core_upgrade = isset($params['wp_upgrade']) ? $params['wp_upgrade'] : array();
138
- $upgrade_plugins = isset($params['upgrade_plugins']) ? $params['upgrade_plugins'] : array();
139
- $upgrade_themes = isset($params['upgrade_themes']) ? $params['upgrade_themes'] : array();
140
-
141
- $upgrades = array();
142
- $premium_upgrades = array();
143
- if (!empty($core_upgrade)) {
144
- $upgrades['core'] = $this->upgrade_core($core_upgrade);
145
- }
146
-
147
- if (!empty($upgrade_plugins)) {
148
- $plugin_files = array();
149
- foreach ($upgrade_plugins as $plugin) {
150
- if (isset($plugin->file))
151
- $plugin_files[$plugin->file] = $plugin->old_version;
152
- else
153
- $premium_upgrades[md5($plugin->name)] = $plugin;
154
- }
155
- if (!empty($plugin_files))
156
- $upgrades['plugins'] = $this->upgrade_plugins($plugin_files);
157
-
158
- }
159
-
160
- if (!empty($upgrade_themes)) {
161
- $theme_temps = array();
162
- foreach ($upgrade_themes as $theme) {
163
- if (isset($theme['theme_tmp']))
164
- $theme_temps[] = $theme['theme_tmp'];
165
- else
166
- $premium_upgrades[md5($theme['name'])] = $theme;
167
- }
168
-
169
- if (!empty($theme_temps))
170
- $upgrades['themes'] = $this->upgrade_themes($theme_temps);
171
-
172
- }
173
-
174
- if (!empty($premium_upgrades)) {
175
- $premium_upgrades = $this->upgrade_premium($premium_upgrades);
176
- if (!empty($premium_upgrades)) {
177
- if (!empty($upgrades)) {
178
- foreach ($upgrades as $key => $val) {
179
- if (isset($premium_upgrades[$key])) {
180
- $upgrades[$key] = array_merge_recursive($upgrades[$key], $premium_upgrades[$key]);
181
- }
182
- }
183
- } else {
184
- $upgrades = $premium_upgrades;
185
- }
186
- }
187
- }
188
- ob_clean();
189
- $this->mmb_maintenance_mode(false);
190
- return $upgrades;
191
- }
192
-
193
- /**
194
- * Upgrades WordPress locally
195
- *
196
- */
197
- function upgrade_core($current)
198
- {
199
- ob_start();
200
- if (!function_exists('wp_version_check'))
201
- include_once(ABSPATH . '/wp-admin/includes/update.php');
202
-
203
- @wp_version_check();
204
-
205
- $current_update = false;
206
- ob_end_flush();
207
- ob_end_clean();
208
- $core = $this->mmb_get_transient('update_core');
209
-
210
- if (isset($core->updates) && !empty($core->updates)) {
211
- $updates = $core->updates[0];
212
- $updated = $core->updates[0];
213
- if (!isset($updated->response) || $updated->response == 'latest')
214
- return array(
215
- 'upgraded' => ' updated'
216
- );
217
-
218
- if ($updated->response == "development" && $current->response == "upgrade") {
219
- return array(
220
- 'upgraded' => '<font color="#900">Unexpected error. Please upgrade manually.</font>'
221
- );
222
- } else if ($updated->response == $current->response || ($updated->response == "upgrade" && $current->response == "development")) {
223
- if ($updated->locale != $current->locale) {
224
- foreach ($updates as $update) {
225
- if ($update->locale == $current->locale) {
226
- $current_update = $update;
227
- break;
228
- }
229
- }
230
- if ($current_update == false)
231
- return array(
232
- 'error' => ' Localization mismatch. Try again.'
233
- );
234
- } else {
235
- $current_update = $updated;
236
- }
237
- } else
238
- return array(
239
- 'error' => ' Transient mismatch. Try again.'
240
- );
241
- } else
242
- return array(
243
- 'error' => ' Refresh transient failed. Try again.'
244
- );
245
- if ($current_update != false) {
246
- global $mmb_wp_version, $wp_filesystem, $wp_version;
247
-
248
- if (version_compare($wp_version, '3.1.9', '>')) {
249
- if (!class_exists('Core_Upgrader'))
250
- include_once(ABSPATH . 'wp-admin/includes/class-wp-upgrader.php');
251
-
252
- $core = new Core_Upgrader();
253
- $result = $core->upgrade($current_update);
254
- $this->mmb_maintenance_mode(false);
255
- if (is_wp_error($result)) {
256
- return array(
257
- 'error' => $this->mmb_get_error($result)
258
- );
259
- } else
260
- return array(
261
- 'upgraded' => ' updated'
262
- );
263
-
264
- } else {
265
- if (!class_exists('WP_Upgrader')) {
266
- include_once(ABSPATH . 'wp-admin/includes/update.php');
267
- if (function_exists('wp_update_core')) {
268
- $result = wp_update_core($current_update);
269
- if (is_wp_error($result)) {
270
- return array(
271
- 'error' => $this->mmb_get_error($result)
272
- );
273
- } else
274
- return array(
275
- 'upgraded' => ' updated'
276
- );
277
- }
278
- }
279
-
280
- if (class_exists('WP_Upgrader')) {
281
- $upgrader_skin = new WP_Upgrader_Skin();
282
- $upgrader_skin->done_header = true;
283
-
284
- $upgrader = new WP_Upgrader($upgrader_skin);
285
-
286
- // Is an update available?
287
- if (!isset($current_update->response) || $current_update->response == 'latest')
288
- return array(
289
- 'upgraded' => ' updated'
290
- );
291
-
292
- $res = $upgrader->fs_connect(array(
293
- ABSPATH,
294
- WP_CONTENT_DIR
295
- ));
296
- if (is_wp_error($res))
297
- return array(
298
- 'error' => $this->mmb_get_error($res)
299
- );
300
-
301
- $wp_dir = trailingslashit($wp_filesystem->abspath());
302
-
303
- $core_package = false;
304
- if (isset($current_update->package) && !empty($current_update->package))
305
- $core_package = $current_update->package;
306
- elseif (isset($current_update->packages->full) && !empty($current_update->packages->full))
307
- $core_package = $current_update->packages->full;
308
-
309
- $download = $upgrader->download_package($core_package);
310
- if (is_wp_error($download))
311
- return array(
312
- 'error' => $this->mmb_get_error($download)
313
- );
314
-
315
- $working_dir = $upgrader->unpack_package($download);
316
- if (is_wp_error($working_dir))
317
- return array(
318
- 'error' => $this->mmb_get_error($working_dir)
319
- );
320
-
321
- if (!$wp_filesystem->copy($working_dir . '/wordpress/wp-admin/includes/update-core.php', $wp_dir . 'wp-admin/includes/update-core.php', true)) {
322
- $wp_filesystem->delete($working_dir, true);
323
- return array(
324
- 'error' => 'Unable to move update files.'
325
- );
326
- }
327
-
328
- $wp_filesystem->chmod($wp_dir . 'wp-admin/includes/update-core.php', FS_CHMOD_FILE);
329
-
330
- require(ABSPATH . 'wp-admin/includes/update-core.php');
331
-
332
-
333
- $update_core = update_core($working_dir, $wp_dir);
334
- ob_end_clean();
335
-
336
- $this->mmb_maintenance_mode(false);
337
- if (is_wp_error($update_core))
338
- return array(
339
- 'error' => $this->mmb_get_error($update_core)
340
- );
341
- ob_end_flush();
342
- return array(
343
- 'upgraded' => 'updated'
344
- );
345
- } else {
346
- return array(
347
- 'error' => 'failed'
348
- );
349
- }
350
- }
351
- } else {
352
- return array(
353
- 'error' => 'failed'
354
- );
355
- }
356
- }
357
-
358
- function upgrade_plugins($plugins = false)
359
- {
360
- if (!$plugins || empty($plugins))
361
- return array(
362
- 'error' => 'No plugin files for upgrade.'
363
- );
364
-
365
- $current = $this->mmb_get_transient('update_plugins');
366
- $versions = array();
367
- if(!empty($current)){
368
- foreach($plugins as $plugin => $data){
369
- if(isset($current->checked[$plugin])){
370
- $versions[$current->checked[$plugin]] = $plugin;
371
- }
372
- }
373
- }
374
- $return = array();
375
- if (class_exists('Plugin_Upgrader') && class_exists('Bulk_Plugin_Upgrader_Skin')) {
376
- $upgrader = new Plugin_Upgrader(new Bulk_Plugin_Upgrader_Skin(compact('nonce', 'url')));
377
- $result = $upgrader->bulk_upgrade(array_keys($plugins));
378
- if (!function_exists('wp_update_plugins'))
379
- include_once(ABSPATH . 'wp-includes/update.php');
380
-
381
- @wp_update_plugins();
382
- $current = $this->mmb_get_transient('update_plugins');
383
- if (!empty($result)) {
384
- foreach ($result as $plugin_slug => $plugin_info) {
385
- if (!$plugin_info || is_wp_error($plugin_info)) {
386
- $return[$plugin_slug] = $this->mmb_get_error($plugin_info);
387
- } else {
388
- if(!empty($result[$plugin_slug]) || (isset($current->checked[$plugin_slug]) && version_compare(array_search($plugin_slug, $versions), $current->checked[$plugin_slug], '<') == true)){
389
- $return[$plugin_slug] = 1;
390
- } else {
391
- update_option('mmb_forcerefresh', true);
392
- $return[$plugin_slug] = 'Could not refresh upgrade transients, please reload website data';
393
- }
394
- }
395
- }
396
- ob_end_clean();
397
- return array(
398
- 'upgraded' => $return
399
- );
400
- } else
401
- return array(
402
- 'error' => 'Upgrade failed.'
403
- );
404
- } else {
405
- ob_end_clean();
406
- return array(
407
- 'error' => 'WordPress update required first.'
408
- );
409
- }
410
- }
411
-
412
- function upgrade_themes($themes = false)
413
- {
414
- if (!$themes || empty($themes))
415
- return array(
416
- 'error' => 'No theme files for upgrade.'
417
- );
418
-
419
- $current = $this->mmb_get_transient('update_themes');
420
- $versions = array();
421
- if(!empty($current)){
422
- foreach($themes as $theme){
423
- if(isset($current->checked[$theme])){
424
- $versions[$current->checked[$theme]] = $theme;
425
- }
426
- }
427
- }
428
- if (class_exists('Theme_Upgrader') && class_exists('Bulk_Theme_Upgrader_Skin')) {
429
- $upgrader = new Theme_Upgrader(new Bulk_Theme_Upgrader_Skin(compact('title', 'nonce', 'url', 'theme')));
430
- $result = $upgrader->bulk_upgrade($themes);
431
-
432
- if (!function_exists('wp_update_themes'))
433
- include_once(ABSPATH . 'wp-includes/update.php');
434
-
435
- @wp_update_themes();
436
- $current = $this->mmb_get_transient('update_themes');
437
- $return = array();
438
- if (!empty($result)) {
439
- foreach ($result as $theme_tmp => $theme_info) {
440
- if (is_wp_error($theme_info) || empty($theme_info)) {
441
- $return[$theme_tmp] = $this->mmb_get_error($theme_info);
442
- } else {
443
- if(!empty($result[$theme_tmp]) || (isset($current->checked[$theme_tmp]) && version_compare(array_search($theme_tmp, $versions), $current->checked[$theme_tmp], '<') == true)){
444
- $return[$theme_tmp] = 1;
445
- } else {
446
- update_option('mmb_forcerefresh', true);
447
- $return[$theme_tmp] = 'Could not refresh upgrade transients, please reload website data';
448
- }
449
- }
450
- }
451
- return array(
452
- 'upgraded' => $return
453
- );
454
- } else
455
- return array(
456
- 'error' => 'Upgrade failed.'
457
- );
458
- } else {
459
- ob_end_clean();
460
- return array(
461
- 'error' => 'WordPress update required first'
462
- );
463
- }
464
- }
465
-
466
- function upgrade_premium($premium = false)
467
- {
468
- global $mmb_plugin_url;
469
-
470
- if (!class_exists('WP_Upgrader'))
471
- include_once(ABSPATH . 'wp-admin/includes/class-wp-upgrader.php');
472
-
473
- if (!$premium || empty($premium))
474
- return array(
475
- 'error' => 'No premium files for upgrade.'
476
- );
477
-
478
- $upgrader = false;
479
- $pr_update = array();
480
- $themes = array();
481
- $plugins = array();
482
- $result = array();
483
- $premium_update = array();
484
- $premium_update = apply_filters('mwp_premium_perform_update', $premium_update);
485
- if (!empty($premium_update)) {
486
-
487
- foreach ($premium as $pr) {
488
- foreach ($premium_update as $key => $update) {
489
- $update = array_change_key_case($update, CASE_LOWER);
490
- if ($update['name'] == $pr['name']) {
491
-
492
- // prepare bulk updates for premiums that use WordPress upgrader
493
- if(isset($update['type'])){
494
- if($update['type'] == 'plugin'){
495
- if(isset($update['slug']) && !empty($update['slug']))
496
- $plugins[$update['slug']] = $update;
497
- }
498
-
499
- if($update['type'] == 'theme'){
500
- if(isset($update['template']) && !empty($update['template']))
501
- $themes[$update['template']] = $update;
502
- }
503
- }
504
- } else {
505
- unset($premium_update[$key]);
506
- }
507
- }
508
- }
509
-
510
- // try default wordpress upgrader
511
- if(!empty($plugins)){
512
- $updateplugins = $this->upgrade_plugins(array_keys($plugins));
513
- if(!empty($updateplugins) && isset($updateplugins['upgraded'])){
514
- foreach ($premium_update as $key => $update) {
515
- $update = array_change_key_case($update, CASE_LOWER);
516
- foreach($updateplugins['upgraded'] as $slug => $upgrade){
517
- if( isset($update['slug']) && $update['slug'] == $slug){
518
- if( $upgrade == 1 )
519
- unset($premium_update[$key]);
520
-
521
- $pr_update['plugins']['upgraded'][md5($update['name'])] = $upgrade;
522
- }
523
- }
524
- }
525
- }
526
- }
527
-
528
- if(!empty($themes)){
529
- $updatethemes = $this->upgrade_themes(array_keys($themes));
530
- if(!empty($updatethemes) && isset($updatethemes['upgraded'])){
531
- foreach ($premium_update as $key => $update) {
532
- $update = array_change_key_case($update, CASE_LOWER);
533
- foreach($updatethemes['upgraded'] as $template => $upgrade){
534
- if( isset($update['template']) && $update['template'] == $template) {
535
- if( $upgrade == 1 )
536
- unset($premium_update[$key]);
537
-
538
- $pr_update['themes']['upgraded'][md5($update['name'])] = $upgrade;
539
- }
540
- }
541
- }
542
- }
543
- }
544
-
545
- //try direct install with overwrite
546
- if(!empty($premium_update)){
547
- foreach ($premium_update as $update) {
548
- $update = array_change_key_case($update, CASE_LOWER);
549
- $update_result = false;
550
- if (isset($update['url'])) {
551
- if (defined('WP_INSTALLING') && file_exists(ABSPATH . '.maintenance'))
552
- $pr_update[$update['type'] . 's']['upgraded'][md5($update['name'])] = 'Site under maintanace.';
553
-
554
- $upgrader_skin = new WP_Upgrader_Skin();
555
- $upgrader_skin->done_header = true;
556
- $upgrader = new WP_Upgrader();
557
- @$update_result = $upgrader->run(array(
558
- 'package' => $update['url'],
559
- 'destination' => isset($update['type']) && $update['type'] == 'theme' ? WP_CONTENT_DIR . '/themes' : WP_PLUGIN_DIR,
560
- 'clear_destination' => true,
561
- 'clear_working' => true,
562
- 'is_multi' => true,
563
- 'hook_extra' => array()
564
- ));
565
- $update_result = !$update_result || is_wp_error($update_result) ? $this->mmb_get_error($update_result) : 1;
566
-
567
- } else if (isset($update['callback'])) {
568
- if (is_array($update['callback'])) {
569
- $update_result = call_user_func(array( $update['callback'][0], $update['callback'][1] ));
570
- } else if (is_string($update['callback'])) {
571
- $update_result = call_user_func($update['callback']);
572
- } else {
573
- $update_result = 'Upgrade function "' . $update['callback'] . '" does not exists.';
574
- }
575
-
576
- $update_result = $update_result !== true ? $this->mmb_get_error($update_result) : 1;
577
- } else
578
- $update_result = 'Bad update params.';
579
-
580
- $pr_update[$update['type'] . 's']['upgraded'][md5($update['name'])] = $update_result;
581
- }
582
- }
583
- return $pr_update;
584
- } else {
585
- foreach ($premium as $pr) {
586
- $result[$pr['type'] . 's']['upgraded'][md5($pr['name'])] = 'This premium update is not registered.';
587
- }
588
- return $result;
589
- }
590
- }
591
-
592
- function get_upgradable_plugins( $filter = array() )
593
- {
594
- $current = $this->mmb_get_transient('update_plugins');
595
-
596
- $upgradable_plugins = array();
597
- if (!empty($current->response)) {
598
- if (!function_exists('get_plugin_data'))
599
- include_once ABSPATH . 'wp-admin/includes/plugin.php';
600
- foreach ($current->response as $plugin_path => $plugin_data) {
601
- if ($plugin_path == 'worker/init.php')
602
- continue;
603
-
604
- $data = get_plugin_data(WP_PLUGIN_DIR . '/' . $plugin_path);
605
- if(isset($data['Name']) && in_array($data['Name'], $filter))
606
- continue;
607
-
608
- if (strlen($data['Name']) > 0 && strlen($data['Version']) > 0) {
609
- $current->response[$plugin_path]->name = $data['Name'];
610
- $current->response[$plugin_path]->old_version = $data['Version'];
611
- $current->response[$plugin_path]->file = $plugin_path;
612
- unset($current->response[$plugin_path]->upgrade_notice);
613
- $upgradable_plugins[] = $current->response[$plugin_path];
614
- }
615
- }
616
- return $upgradable_plugins;
617
- } else
618
- return array();
619
- }
620
-
621
- function get_upgradable_themes( $filter = array() )
622
- {
623
- $all_themes = get_themes();
624
- $upgrade_themes = array();
625
-
626
- $current = $this->mmb_get_transient('update_themes');
627
- if (!empty($current->response)) {
628
- foreach ((array) $all_themes as $theme_template => $theme_data) {
629
- if(isset($theme_data['Parent Theme']) && !empty($theme_data['Parent Theme']))
630
- continue;
631
-
632
- if(isset($theme_data['Name']) && in_array($theme_data['Name'], $filter))
633
- continue;
634
-
635
- foreach ($current->response as $current_themes => $theme) {
636
- if ($theme_data['Template'] == $current_themes) {
637
- if (strlen($theme_data['Name']) > 0 && strlen($theme_data['Version']) > 0) {
638
- $current->response[$current_themes]['name'] = $theme_data['Name'];
639
- $current->response[$current_themes]['old_version'] = $theme_data['Version'];
640
- $current->response[$current_themes]['theme_tmp'] = $theme_data['Template'];
641
- $upgrade_themes[] = $current->response[$current_themes];
642
- }
643
- }
644
- }
645
- }
646
- }
647
-
648
- return $upgrade_themes;
649
- }
650
-
651
- function get($args)
652
- {
653
- if (empty($args))
654
- return false;
655
-
656
- //Args: $items('plugins,'themes'), $type (active || inactive), $search(name string)
657
-
658
- $return = array();
659
- if (is_array($args['items']) && in_array('plugins', $args['items'])) {
660
- $return['plugins'] = $this->get_plugins($args);
661
- }
662
- if (is_array($args['items']) && in_array('themes', $args['items'])) {
663
- $return['themes'] = $this->get_themes($args);
664
- }
665
-
666
- return $return;
667
- }
668
-
669
- function get_plugins($args)
670
- {
671
- if (empty($args))
672
- return false;
673
-
674
- extract($args);
675
-
676
- if (!function_exists('get_plugins')) {
677
- include_once(ABSPATH . 'wp-admin/includes/plugin.php');
678
- }
679
- $all_plugins = get_plugins();
680
- $plugins = array(
681
- 'active' => array(),
682
- 'inactive' => array()
683
- );
684
- if (is_array($all_plugins) && !empty($all_plugins)) {
685
- $activated_plugins = get_option('active_plugins');
686
- if (!$activated_plugins)
687
- $activated_plugins = array();
688
-
689
- $br_a = 0;
690
- $br_i = 0;
691
- foreach ($all_plugins as $path => $plugin) {
692
- if ($plugin['Name'] != 'ManageWP - Worker') {
693
- if (in_array($path, $activated_plugins)) {
694
- $plugins['active'][$br_a]['path'] = $path;
695
- $plugins['active'][$br_a]['name'] = $plugin['Name'];
696
- $br_a++;
697
- }
698
-
699
- if (!in_array($path, $activated_plugins)) {
700
- $plugins['inactive'][$br_i]['path'] = $path;
701
- $plugins['inactive'][$br_i]['name'] = $plugin['Name'];
702
- $br_i++;
703
- }
704
-
705
- }
706
-
707
- if ($search) {
708
- foreach ($plugins['active'] as $k => $plugin) {
709
- if (!stristr($plugin['name'], $search)) {
710
- unset($plugins['active'][$k]);
711
- }
712
- }
713
-
714
- foreach ($plugins['inactive'] as $k => $plugin) {
715
- if (!stristr($plugin['name'], $search)) {
716
- unset($plugins['inactive'][$k]);
717
- }
718
- }
719
- }
720
- }
721
- }
722
-
723
- return $plugins;
724
- }
725
-
726
- function get_themes($args)
727
- {
728
- if (empty($args))
729
- return false;
730
-
731
- extract($args);
732
-
733
- if (!function_exists('get_themes')) {
734
- include_once(ABSPATH . WPINC . '/theme.php');
735
- }
736
- $all_themes = get_themes();
737
- $themes = array(
738
- 'active' => array(),
739
- 'inactive' => array()
740
- );
741
-
742
- if (is_array($all_themes) && !empty($all_themes)) {
743
- $current_theme = get_current_theme();
744
-
745
- $br_a = 0;
746
- $br_i = 0;
747
- foreach ($all_themes as $theme_name => $theme) {
748
- if ($current_theme == $theme_name) {
749
- $themes['active'][$br_a]['path'] = $theme['Template'];
750
- $themes['active'][$br_a]['name'] = $theme['Name'];
751
- $themes['active'][$br_a]['stylesheet'] = $theme['Stylesheet'];
752
- $br_a++;
753
- }
754
-
755
- if ($current_theme != $theme_name) {
756
- $themes['inactive'][$br_i]['path'] = $theme['Template'];
757
- $themes['inactive'][$br_i]['name'] = $theme['Name'];
758
- $themes['inactive'][$br_i]['stylesheet'] = $theme['Stylesheet'];
759
- $br_i++;
760
- }
761
-
762
- }
763
-
764
- if ($search) {
765
- foreach ($themes['active'] as $k => $theme) {
766
- if (!stristr($theme['name'], $search)) {
767
- unset($themes['active'][$k]);
768
- }
769
- }
770
-
771
- foreach ($themes['inactive'] as $k => $theme) {
772
- if (!stristr($theme['name'], $search)) {
773
- unset($themes['inactive'][$k]);
774
- }
775
- }
776
- }
777
- }
778
-
779
- return $themes;
780
- }
781
-
782
- function edit($args)
783
- {
784
- extract($args);
785
- $return = array();
786
- if ($type == 'plugins') {
787
- $return['plugins'] = $this->edit_plugins($args);
788
- } elseif ($type == 'themes') {
789
- $return['themes'] = $this->edit_themes($args);
790
- }
791
- return $return;
792
- }
793
-
794
- function edit_plugins($args)
795
- {
796
- extract($args);
797
- $return = array();
798
- foreach ($items as $item) {
799
- switch ($items_edit_action) {
800
- case 'activate':
801
- $result = activate_plugin($item['path']);
802
- break;
803
- case 'deactivate':
804
- $result = deactivate_plugins(array(
805
- $item['path']
806
- ));
807
- break;
808
- case 'delete':
809
- $result = delete_plugins(array(
810
- $item['path']
811
- ));
812
- break;
813
- default:
814
- break;
815
- }
816
-
817
- if (is_wp_error($result)) {
818
- $result = array(
819
- 'error' => $result->get_error_message()
820
- );
821
- } elseif ($result === false) {
822
- $result = array(
823
- 'error' => "Failed to perform action."
824
- );
825
- } else {
826
- $result = "OK";
827
- }
828
- $return[$item['name']] = $result;
829
- }
830
-
831
- return $return;
832
- }
833
-
834
- function edit_themes($args)
835
- {
836
- extract($args);
837
- $return = array();
838
- foreach ($items as $item) {
839
- switch ($items_edit_action) {
840
- case 'activate':
841
- switch_theme($item['path'], $item['stylesheet']);
842
- break;
843
- case 'delete':
844
- $result = delete_theme($item['path']);
845
- break;
846
- default:
847
- break;
848
- }
849
-
850
- if (is_wp_error($result)) {
851
- $result = array(
852
- 'error' => $result->get_error_message()
853
- );
854
- } elseif ($result === false) {
855
- $result = array(
856
- 'error' => "Failed to perform action."
857
- );
858
- } else {
859
- $result = "OK";
860
- }
861
- $return[$item['name']] = $result;
862
- }
863
-
864
- return $return;
865
-
866
- }
867
- }
868
  ?>
1
+ <?php
2
+ /*************************************************************
3
+ *
4
+ * installer.class.php
5
+ *
6
+ * Upgrade WordPress
7
+ *
8
+ *
9
+ * Copyright (c) 2011 Prelovac Media
10
+ * www.prelovac.com
11
+ **************************************************************/
12
+
13
+ class MMB_Installer extends MMB_Core
14
+ {
15
+ function __construct()
16
+ {
17
+ @set_time_limit(600);
18
+ parent::__construct();
19
+ @include_once(ABSPATH . 'wp-admin/includes/file.php');
20
+ @include_once(ABSPATH . 'wp-admin/includes/plugin.php');
21
+ @include_once(ABSPATH . 'wp-admin/includes/theme.php');
22
+ @include_once(ABSPATH . 'wp-admin/includes/misc.php');
23
+ @include_once(ABSPATH . 'wp-admin/includes/template.php');
24
+ @include_once(ABSPATH . 'wp-admin/includes/class-wp-upgrader.php');
25
+
26
+ global $wp_filesystem;
27
+ if (!$wp_filesystem)
28
+ WP_Filesystem();
29
+ }
30
+
31
+ function mmb_maintenance_mode($enable = false, $maintenance_message = '')
32
+ {
33
+ global $wp_filesystem;
34
+
35
+ $maintenance_message .= '<?php $upgrading = ' . time() . '; ?>';
36
+
37
+ $file = $wp_filesystem->abspath() . '.maintenance';
38
+ if ($enable) {
39
+ $wp_filesystem->delete($file);
40
+ $wp_filesystem->put_contents($file, $maintenance_message, FS_CHMOD_FILE);
41
+ } else {
42
+ $wp_filesystem->delete($file);
43
+ }
44
+ }
45
+
46
+ function install_remote_file($params)
47
+ {
48
+ global $wp_filesystem;
49
+ extract($params);
50
+
51
+ if (!isset($package) || empty($package))
52
+ return array(
53
+ 'error' => '<p>No files received. Internal error.</p>'
54
+ );
55
+
56
+ if (defined('WP_INSTALLING') && file_exists(ABSPATH . '.maintenance'))
57
+ return array(
58
+ 'error' => '<p>Site under maintanace.</p>'
59
+ );
60
+
61
+ if (!class_exists('WP_Upgrader'))
62
+ include_once(ABSPATH . 'wp-admin/includes/class-wp-upgrader.php');
63
+
64
+ $upgrader_skin = new WP_Upgrader_Skin();
65
+ $upgrader_skin->done_header = true;
66
+
67
+ $upgrader = new WP_Upgrader($upgrader_skin);
68
+ $destination = $type == 'themes' ? WP_CONTENT_DIR . '/themes' : WP_PLUGIN_DIR;
69
+ $clear_destination = isset($clear_destination) ? $clear_destination : false;
70
+
71
+ foreach ($package as $package_url) {
72
+ $key = basename($package_url);
73
+ $install_info[$key] = @$upgrader->run(array(
74
+ 'package' => $package_url,
75
+ 'destination' => $destination,
76
+ 'clear_destination' => $clear_destination, //Do not overwrite files.
77
+ 'clear_working' => true,
78
+ 'hook_extra' => array()
79
+ ));
80
+ }
81
+
82
+ if ($activate) {
83
+ if ($type == 'plugins') {
84
+ include_once(ABSPATH . 'wp-admin/includes/plugin.php');
85
+ $all_plugins = get_plugins();
86
+ foreach ($all_plugins as $plugin_slug => $plugin) {
87
+ $plugin_dir = preg_split('/\//', $plugin_slug);
88
+ foreach ($install_info as $key => $install) {
89
+ if (!$install || is_wp_error($install))
90
+ continue;
91
+ if ($install['destination_name'] == $plugin_dir[0]) {
92
+ $install_info[$key]['activated'] = activate_plugin($plugin_slug, '', false);
93
+ }
94
+ }
95
+ }
96
+ } else if (count($install_info) == 1) {
97
+ global $wp_themes;
98
+ include_once(ABSPATH . 'wp-includes/theme.php');
99
+
100
+ $wp_themes = null;
101
+ unset($wp_themes); //prevent theme data caching
102
+
103
+ $all_themes = get_themes();
104
+ foreach ($all_themes as $theme_name => $theme_data) {
105
+ foreach ($install_info as $key => $install) {
106
+ if (!$install || is_wp_error($install))
107
+ continue;
108
+
109
+ if ($theme_data['Template'] == $install['destination_name']) {
110
+ $install_info[$key]['activated'] = switch_theme($theme_data['Template'], $theme_data['Stylesheet']);
111
+ }
112
+ }
113
+ }
114
+ }
115
+ }
116
+ ob_clean();
117
+ $this->mmb_maintenance_mode(false);
118
+ return $install_info;
119
+ }
120
+
121
+ function do_upgrade($params = null)
122
+ {
123
+ if ($params == null || empty($params))
124
+ return array(
125
+ 'failed' => 'No upgrades passed.'
126
+ );
127
+
128
+ if (!$this->is_server_writable()) {
129
+ return array(
130
+ 'error' => 'Failed, please <a target="_blank" href="http://managewp.com/user-guide#ftp">add FTP details</a></a>'
131
+ );
132
+ }
133
+
134
+
135
+ $params = isset($params['upgrades_all']) ? $params['upgrades_all'] : $params;
136
+
137
+ $core_upgrade = isset($params['wp_upgrade']) ? $params['wp_upgrade'] : array();
138
+ $upgrade_plugins = isset($params['upgrade_plugins']) ? $params['upgrade_plugins'] : array();
139
+ $upgrade_themes = isset($params['upgrade_themes']) ? $params['upgrade_themes'] : array();
140
+
141
+ $upgrades = array();
142
+ $premium_upgrades = array();
143
+ if (!empty($core_upgrade)) {
144
+ $upgrades['core'] = $this->upgrade_core($core_upgrade);
145
+ }
146
+
147
+ if (!empty($upgrade_plugins)) {
148
+ $plugin_files = array();
149
+ foreach ($upgrade_plugins as $plugin) {
150
+ if (isset($plugin->file))
151
+ $plugin_files[$plugin->file] = $plugin->old_version;
152
+ else
153
+ $premium_upgrades[md5($plugin->name)] = $plugin;
154
+ }
155
+ if (!empty($plugin_files))
156
+ $upgrades['plugins'] = $this->upgrade_plugins($plugin_files);
157
+
158
+ }
159
+
160
+ if (!empty($upgrade_themes)) {
161
+ $theme_temps = array();
162
+ foreach ($upgrade_themes as $theme) {
163
+ if (isset($theme['theme_tmp']))
164
+ $theme_temps[] = $theme['theme_tmp'];
165
+ else
166
+ $premium_upgrades[md5($theme['name'])] = $theme;
167
+ }
168
+
169
+ if (!empty($theme_temps))
170
+ $upgrades['themes'] = $this->upgrade_themes($theme_temps);
171
+
172
+ }
173
+
174
+ if (!empty($premium_upgrades)) {
175
+ $premium_upgrades = $this->upgrade_premium($premium_upgrades);
176
+ if (!empty($premium_upgrades)) {
177
+ if (!empty($upgrades)) {
178
+ foreach ($upgrades as $key => $val) {
179
+ if (isset($premium_upgrades[$key])) {
180
+ $upgrades[$key] = array_merge_recursive($upgrades[$key], $premium_upgrades[$key]);
181
+ }
182
+ }
183
+ } else {
184
+ $upgrades = $premium_upgrades;
185
+ }
186
+ }
187
+ }
188
+ ob_clean();
189
+ $this->mmb_maintenance_mode(false);
190
+ return $upgrades;
191
+ }
192
+
193
+ /**
194
+ * Upgrades WordPress locally
195
+ *
196
+ */
197
+ function upgrade_core($current)
198
+ {
199
+ ob_start();
200
+ if (!function_exists('wp_version_check'))
201
+ include_once(ABSPATH . '/wp-admin/includes/update.php');
202
+
203
+ @wp_version_check();
204
+
205
+ $current_update = false;
206
+ ob_end_flush();
207
+ ob_end_clean();
208
+ $core = $this->mmb_get_transient('update_core');
209
+
210
+ if (isset($core->updates) && !empty($core->updates)) {
211
+ $updates = $core->updates[0];
212
+ $updated = $core->updates[0];
213
+ if (!isset($updated->response) || $updated->response == 'latest')
214
+ return array(
215
+ 'upgraded' => ' updated'
216
+ );
217
+
218
+ if ($updated->response == "development" && $current->response == "upgrade") {
219
+ return array(
220
+ 'upgraded' => '<font color="#900">Unexpected error. Please upgrade manually.</font>'
221
+ );
222
+ } else if ($updated->response == $current->response || ($updated->response == "upgrade" && $current->response == "development")) {
223
+ if ($updated->locale != $current->locale) {
224
+ foreach ($updates as $update) {
225
+ if ($update->locale == $current->locale) {
226
+ $current_update = $update;
227
+ break;
228
+ }
229
+ }
230
+ if ($current_update == false)
231
+ return array(
232
+ 'error' => ' Localization mismatch. Try again.'
233
+ );
234
+ } else {
235
+ $current_update = $updated;
236
+ }
237
+ } else
238
+ return array(
239
+ 'error' => ' Transient mismatch. Try again.'
240
+ );
241
+ } else
242
+ return array(
243
+ 'error' => ' Refresh transient failed. Try again.'
244
+ );
245
+ if ($current_update != false) {
246
+ global $mmb_wp_version, $wp_filesystem, $wp_version;
247
+
248
+ if (version_compare($wp_version, '3.1.9', '>')) {
249
+ if (!class_exists('Core_Upgrader'))
250
+ include_once(ABSPATH . 'wp-admin/includes/class-wp-upgrader.php');
251
+
252
+ $core = new Core_Upgrader();
253
+ $result = $core->upgrade($current_update);
254
+ $this->mmb_maintenance_mode(false);
255
+ if (is_wp_error($result)) {
256
+ return array(
257
+ 'error' => $this->mmb_get_error($result)
258
+ );
259
+ } else
260
+ return array(
261
+ 'upgraded' => ' updated'
262
+ );
263
+
264
+ } else {
265
+ if (!class_exists('WP_Upgrader')) {
266
+ include_once(ABSPATH . 'wp-admin/includes/update.php');
267
+ if (function_exists('wp_update_core')) {
268
+ $result = wp_update_core($current_update);
269
+ if (is_wp_error($result)) {
270
+ return array(
271
+ 'error' => $this->mmb_get_error($result)
272
+ );
273
+ } else
274
+ return array(
275
+ 'upgraded' => ' updated'
276
+ );
277
+ }
278
+ }
279
+
280
+ if (class_exists('WP_Upgrader')) {
281
+ $upgrader_skin = new WP_Upgrader_Skin();
282
+ $upgrader_skin->done_header = true;
283
+
284
+ $upgrader = new WP_Upgrader($upgrader_skin);
285
+
286
+ // Is an update available?
287
+ if (!isset($current_update->response) || $current_update->response == 'latest')
288
+ return array(
289
+ 'upgraded' => ' updated'
290
+ );
291
+
292
+ $res = $upgrader->fs_connect(array(
293
+ ABSPATH,
294
+ WP_CONTENT_DIR
295
+ ));
296
+ if (is_wp_error($res))
297
+ return array(
298
+ 'error' => $this->mmb_get_error($res)
299
+ );
300
+
301
+ $wp_dir = trailingslashit($wp_filesystem->abspath());
302
+
303
+ $core_package = false;
304
+ if (isset($current_update->package) && !empty($current_update->package))
305
+ $core_package = $current_update->package;
306
+ elseif (isset($current_update->packages->full) && !empty($current_update->packages->full))
307
+ $core_package = $current_update->packages->full;
308
+
309
+ $download = $upgrader->download_package($core_package);
310
+ if (is_wp_error($download))
311
+ return array(
312
+ 'error' => $this->mmb_get_error($download)
313
+ );
314
+
315
+ $working_dir = $upgrader->unpack_package($download);
316
+ if (is_wp_error($working_dir))
317
+ return array(
318
+ 'error' => $this->mmb_get_error($working_dir)
319
+ );
320
+
321
+ if (!$wp_filesystem->copy($working_dir . '/wordpress/wp-admin/includes/update-core.php', $wp_dir . 'wp-admin/includes/update-core.php', true)) {
322
+ $wp_filesystem->delete($working_dir, true);
323
+ return array(
324
+ 'error' => 'Unable to move update files.'
325
+ );
326
+ }
327
+
328
+ $wp_filesystem->chmod($wp_dir . 'wp-admin/includes/update-core.php', FS_CHMOD_FILE);
329
+
330
+ require(ABSPATH . 'wp-admin/includes/update-core.php');
331
+
332
+
333
+ $update_core = update_core($working_dir, $wp_dir);
334
+ ob_end_clean();
335
+
336
+ $this->mmb_maintenance_mode(false);
337
+ if (is_wp_error($update_core))
338
+ return array(
339
+ 'error' => $this->mmb_get_error($update_core)
340
+ );
341
+ ob_end_flush();
342
+ return array(
343
+ 'upgraded' => 'updated'
344
+ );
345
+ } else {
346
+ return array(
347
+ 'error' => 'failed'
348
+ );
349
+ }
350
+ }
351
+ } else {
352
+ return array(
353
+ 'error' => 'failed'
354
+ );
355
+ }
356
+ }
357
+
358
+ function upgrade_plugins($plugins = false)
359
+ {
360
+ if (!$plugins || empty($plugins))
361
+ return array(
362
+ 'error' => 'No plugin files for upgrade.'
363
+ );
364
+
365
+ $current = $this->mmb_get_transient('update_plugins');
366
+ $versions = array();
367
+ if(!empty($current)){
368
+ foreach($plugins as $plugin => $data){
369
+ if(isset($current->checked[$plugin])){
370
+ $versions[$current->checked[$plugin]] = $plugin;
371
+ }
372
+ }
373
+ }
374
+ $return = array();
375
+ if (class_exists('Plugin_Upgrader') && class_exists('Bulk_Plugin_Upgrader_Skin')) {
376
+ $upgrader = new Plugin_Upgrader(new Bulk_Plugin_Upgrader_Skin(compact('nonce', 'url')));
377
+ $result = $upgrader->bulk_upgrade(array_keys($plugins));
378
+ if (!function_exists('wp_update_plugins'))
379
+ include_once(ABSPATH . 'wp-includes/update.php');
380
+
381
+ @wp_update_plugins();
382
+ $current = $this->mmb_get_transient('update_plugins');
383
+ if (!empty($result)) {
384
+ foreach ($result as $plugin_slug => $plugin_info) {
385
+ if (!$plugin_info || is_wp_error($plugin_info)) {
386
+ $return[$plugin_slug] = $this->mmb_get_error($plugin_info);
387
+ } else {
388
+ if(!empty($result[$plugin_slug]) || (isset($current->checked[$plugin_slug]) && version_compare(array_search($plugin_slug, $versions), $current->checked[$plugin_slug], '<') == true)){
389
+ $return[$plugin_slug] = 1;
390
+ } else {
391
+ update_option('mmb_forcerefresh', true);
392
+ $return[$plugin_slug] = 'Could not refresh upgrade transients, please reload website data';
393
+ }
394
+ }
395
+ }
396
+ ob_end_clean();
397
+ return array(
398
+ 'upgraded' => $return
399
+ );
400
+ } else
401
+ return array(
402
+ 'error' => 'Upgrade failed.'
403
+ );
404
+ } else {
405
+ ob_end_clean();
406
+ return array(
407
+ 'error' => 'WordPress update required first.'
408
+ );
409
+ }
410
+ }
411
+
412
+ function upgrade_themes($themes = false)
413
+ {
414
+ if (!$themes || empty($themes))
415
+ return array(
416
+ 'error' => 'No theme files for upgrade.'
417
+ );
418
+
419
+ $current = $this->mmb_get_transient('update_themes');
420
+ $versions = array();
421
+ if(!empty($current)){
422
+ foreach($themes as $theme){
423
+ if(isset($current->checked[$theme])){
424
+ $versions[$current->checked[$theme]] = $theme;
425
+ }
426
+ }
427
+ }
428
+ if (class_exists('Theme_Upgrader') && class_exists('Bulk_Theme_Upgrader_Skin')) {
429
+ $upgrader = new Theme_Upgrader(new Bulk_Theme_Upgrader_Skin(compact('title', 'nonce', 'url', 'theme')));
430
+ $result = $upgrader->bulk_upgrade($themes);
431
+
432
+ if (!function_exists('wp_update_themes'))
433
+ include_once(ABSPATH . 'wp-includes/update.php');
434
+
435
+ @wp_update_themes();
436
+ $current = $this->mmb_get_transient('update_themes');
437
+ $return = array();
438
+ if (!empty($result)) {
439
+ foreach ($result as $theme_tmp => $theme_info) {
440
+ if (is_wp_error($theme_info) || empty($theme_info)) {
441
+ $return[$theme_tmp] = $this->mmb_get_error($theme_info);
442
+ } else {
443
+ if(!empty($result[$theme_tmp]) || (isset($current->checked[$theme_tmp]) && version_compare(array_search($theme_tmp, $versions), $current->checked[$theme_tmp], '<') == true)){
444
+ $return[$theme_tmp] = 1;
445
+ } else {
446
+ update_option('mmb_forcerefresh', true);
447
+ $return[$theme_tmp] = 'Could not refresh upgrade transients, please reload website data';
448
+ }
449
+ }
450
+ }
451
+ return array(
452
+ 'upgraded' => $return
453
+ );
454
+ } else
455
+ return array(
456
+ 'error' => 'Upgrade failed.'
457
+ );
458
+ } else {
459
+ ob_end_clean();
460
+ return array(
461
+ 'error' => 'WordPress update required first'
462
+ );
463
+ }
464
+ }
465
+
466
+ function upgrade_premium($premium = false)
467
+ {
468
+ global $mmb_plugin_url;
469
+
470
+ if (!class_exists('WP_Upgrader'))
471
+ include_once(ABSPATH . 'wp-admin/includes/class-wp-upgrader.php');
472
+
473
+ if (!$premium || empty($premium))
474
+ return array(
475
+ 'error' => 'No premium files for upgrade.'
476
+ );
477
+
478
+ $upgrader = false;
479
+ $pr_update = array();
480
+ $themes = array();
481
+ $plugins = array();
482
+ $result = array();
483
+ $premium_update = array();
484
+ $premium_update = apply_filters('mwp_premium_perform_update', $premium_update);
485
+ if (!empty($premium_update)) {
486
+
487
+ foreach ($premium as $pr) {
488
+ foreach ($premium_update as $key => $update) {
489
+ $update = array_change_key_case($update, CASE_LOWER);
490
+ if ($update['name'] == $pr['name']) {
491
+
492
+ // prepare bulk updates for premiums that use WordPress upgrader
493
+ if(isset($update['type'])){
494
+ if($update['type'] == 'plugin'){
495
+ if(isset($update['slug']) && !empty($update['slug']))
496
+ $plugins[$update['slug']] = $update;
497
+ }
498
+
499
+ if($update['type'] == 'theme'){
500
+ if(isset($update['template']) && !empty($update['template']))
501
+ $themes[$update['template']] = $update;
502
+ }
503
+ }
504
+ } else {
505
+ unset($premium_update[$key]);
506
+ }
507
+ }
508
+ }
509
+
510
+ // try default wordpress upgrader
511
+ if(!empty($plugins)){
512
+ $updateplugins = $this->upgrade_plugins(array_keys($plugins));
513
+ if(!empty($updateplugins) && isset($updateplugins['upgraded'])){
514
+ foreach ($premium_update as $key => $update) {
515
+ $update = array_change_key_case($update, CASE_LOWER);
516
+ foreach($updateplugins['upgraded'] as $slug => $upgrade){
517
+ if( isset($update['slug']) && $update['slug'] == $slug){
518
+ if( $upgrade == 1 )
519
+ unset($premium_update[$key]);
520
+
521
+ $pr_update['plugins']['upgraded'][md5($update['name'])] = $upgrade;
522
+ }
523
+ }
524
+ }
525
+ }
526
+ }
527
+
528
+ if(!empty($themes)){
529
+ $updatethemes = $this->upgrade_themes(array_keys($themes));
530
+ if(!empty($updatethemes) && isset($updatethemes['upgraded'])){
531
+ foreach ($premium_update as $key => $update) {
532
+ $update = array_change_key_case($update, CASE_LOWER);
533
+ foreach($updatethemes['upgraded'] as $template => $upgrade){
534
+ if( isset($update['template']) && $update['template'] == $template) {
535
+ if( $upgrade == 1 )
536
+ unset($premium_update[$key]);
537
+
538
+ $pr_update['themes']['upgraded'][md5($update['name'])] = $upgrade;
539
+ }
540
+ }
541
+ }
542
+ }
543
+ }
544
+
545
+ //try direct install with overwrite
546
+ if(!empty($premium_update)){
547
+ foreach ($premium_update as $update) {
548
+ $update = array_change_key_case($update, CASE_LOWER);
549
+ $update_result = false;
550
+ if (isset($update['url'])) {
551
+ if (defined('WP_INSTALLING') && file_exists(ABSPATH . '.maintenance'))
552
+ $pr_update[$update['type'] . 's']['upgraded'][md5($update['name'])] = 'Site under maintanace.';
553
+
554
+ $upgrader_skin = new WP_Upgrader_Skin();
555
+ $upgrader_skin->done_header = true;
556
+ $upgrader = new WP_Upgrader();
557
+ @$update_result = $upgrader->run(array(
558
+ 'package' => $update['url'],
559
+ 'destination' => isset($update['type']) && $update['type'] == 'theme' ? WP_CONTENT_DIR . '/themes' : WP_PLUGIN_DIR,
560
+ 'clear_destination' => true,
561
+ 'clear_working' => true,
562
+ 'is_multi' => true,
563
+ 'hook_extra' => array()
564
+ ));
565
+ $update_result = !$update_result || is_wp_error($update_result) ? $this->mmb_get_error($update_result) : 1;
566
+
567
+ } else if (isset($update['callback'])) {
568
+ if (is_array($update['callback'])) {
569
+ $update_result = call_user_func(array( $update['callback'][0], $update['callback'][1] ));
570
+ } else if (is_string($update['callback'])) {
571
+ $update_result = call_user_func($update['callback']);
572
+ } else {
573
+ $update_result = 'Upgrade function "' . $update['callback'] . '" does not exists.';
574
+ }
575
+
576
+ $update_result = $update_result !== true ? $this->mmb_get_error($update_result) : 1;
577
+ } else
578
+ $update_result = 'Bad update params.';
579
+
580
+ $pr_update[$update['type'] . 's']['upgraded'][md5($update['name'])] = $update_result;
581
+ }
582
+ }
583
+ return $pr_update;
584
+ } else {
585
+ foreach ($premium as $pr) {
586
+ $result[$pr['type'] . 's']['upgraded'][md5($pr['name'])] = 'This premium update is not registered.';
587
+ }
588
+ return $result;
589
+ }
590
+ }
591
+
592
+ function get_upgradable_plugins( $filter = array() )
593
+ {
594
+ $current = $this->mmb_get_transient('update_plugins');
595
+
596
+ $upgradable_plugins = array();
597
+ if (!empty($current->response)) {
598
+ if (!function_exists('get_plugin_data'))
599
+ include_once ABSPATH . 'wp-admin/includes/plugin.php';
600
+ foreach ($current->response as $plugin_path => $plugin_data) {
601
+ if ($plugin_path == 'worker/init.php')
602
+ continue;
603
+
604
+ $data = get_plugin_data(WP_PLUGIN_DIR . '/' . $plugin_path);
605
+ if(isset($data['Name']) && in_array($data['Name'], $filter))
606
+ continue;
607
+
608
+ if (strlen($data['Name']) > 0 && strlen($data['Version']) > 0) {
609
+ $current->response[$plugin_path]->name = $data['Name'];
610
+ $current->response[$plugin_path]->old_version = $data['Version'];
611
+ $current->response[$plugin_path]->file = $plugin_path;
612
+ unset($current->response[$plugin_path]->upgrade_notice);
613
+ $upgradable_plugins[] = $current->response[$plugin_path];
614
+ }
615
+ }
616
+ return $upgradable_plugins;
617
+ } else
618
+ return array();
619
+ }
620
+
621
+ function get_upgradable_themes( $filter = array() )
622
+ {
623
+ $all_themes = get_themes();
624
+ $upgrade_themes = array();
625
+
626
+ $current = $this->mmb_get_transient('update_themes');
627
+ if (!empty($current->response)) {
628
+ foreach ((array) $all_themes as $theme_template => $theme_data) {
629
+ if(isset($theme_data['Parent Theme']) && !empty($theme_data['Parent Theme']))
630
+ continue;
631
+
632
+ if(isset($theme_data['Name']) && in_array($theme_data['Name'], $filter))
633
+ continue;
634
+
635
+ foreach ($current->response as $current_themes => $theme) {
636
+ if ($theme_data['Template'] == $current_themes) {
637
+ if (strlen($theme_data['Name']) > 0 && strlen($theme_data['Version']) > 0) {
638
+ $current->response[$current_themes]['name'] = $theme_data['Name'];
639
+ $current->response[$current_themes]['old_version'] = $theme_data['Version'];
640
+ $current->response[$current_themes]['theme_tmp'] = $theme_data['Template'];
641
+ $upgrade_themes[] = $current->response[$current_themes];
642
+ }
643
+ }
644
+ }
645
+ }
646
+ }
647
+
648
+ return $upgrade_themes;
649
+ }
650
+
651
+ function get($args)
652
+ {
653
+ if (empty($args))
654
+ return false;
655
+
656
+ //Args: $items('plugins,'themes'), $type (active || inactive), $search(name string)
657
+
658
+ $return = array();
659
+ if (is_array($args['items']) && in_array('plugins', $args['items'])) {
660
+ $return['plugins'] = $this->get_plugins($args);
661
+ }
662
+ if (is_array($args['items']) && in_array('themes', $args['items'])) {
663
+ $return['themes'] = $this->get_themes($args);
664
+ }
665
+
666
+ return $return;
667
+ }
668
+
669
+ function get_plugins($args)
670
+ {
671
+ if (empty($args))
672
+ return false;
673
+
674
+ extract($args);
675
+
676
+ if (!function_exists('get_plugins')) {
677
+ include_once(ABSPATH . 'wp-admin/includes/plugin.php');
678
+ }
679
+ $all_plugins = get_plugins();
680
+ $plugins = array(
681
+ 'active' => array(),
682
+ 'inactive' => array()
683
+ );
684
+ if (is_array($all_plugins) && !empty($all_plugins)) {
685
+ $activated_plugins = get_option('active_plugins');
686
+ if (!$activated_plugins)
687
+ $activated_plugins = array();
688
+
689
+ $br_a = 0;
690
+ $br_i = 0;
691
+ foreach ($all_plugins as $path => $plugin) {
692
+ if ($plugin['Name'] != 'ManageWP - Worker') {
693
+ if (in_array($path, $activated_plugins)) {
694
+ $plugins['active'][$br_a]['path'] = $path;
695
+ $plugins['active'][$br_a]['name'] = strip_tags($plugin['Name']);
696
+ $br_a++;
697
+ }
698
+
699
+ if (!in_array($path, $activated_plugins)) {
700
+ $plugins['inactive'][$br_i]['path'] = $path;
701
+ $plugins['inactive'][$br_i]['name'] = strip_tags($plugin['Name']);
702
+ $br_i++;
703
+ }
704
+
705
+ }
706
+
707
+ if ($search) {
708
+ foreach ($plugins['active'] as $k => $plugin) {
709
+ if (!stristr($plugin['name'], $search)) {
710
+ unset($plugins['active'][$k]);
711
+ }
712
+ }
713
+
714
+ foreach ($plugins['inactive'] as $k => $plugin) {
715
+ if (!stristr($plugin['name'], $search)) {
716
+ unset($plugins['inactive'][$k]);
717
+ }
718
+ }
719
+ }
720
+ }
721
+ }
722
+
723
+ return $plugins;
724
+ }
725
+
726
+ function get_themes($args)
727
+ {
728
+ if (empty($args))
729
+ return false;
730
+
731
+ extract($args);
732
+
733
+ if (!function_exists('get_themes')) {
734
+ include_once(ABSPATH . WPINC . '/theme.php');
735
+ }
736
+ $all_themes = get_themes();
737
+ $themes = array(
738
+ 'active' => array(),
739
+ 'inactive' => array()
740
+ );
741
+
742
+ if (is_array($all_themes) && !empty($all_themes)) {
743
+ $current_theme = get_current_theme();
744
+
745
+ $br_a = 0;
746
+ $br_i = 0;
747
+ foreach ($all_themes as $theme_name => $theme) {
748
+ if ($current_theme == $theme_name) {
749
+ $themes['active'][$br_a]['path'] = $theme['Template'];
750
+ $themes['active'][$br_a]['name'] = strip_tags($theme['Name']);
751
+ $themes['active'][$br_a]['stylesheet'] = $theme['Stylesheet'];
752
+ $br_a++;
753
+ }
754
+
755
+ if ($current_theme != $theme_name) {
756
+ $themes['inactive'][$br_i]['path'] = $theme['Template'];
757
+ $themes['inactive'][$br_i]['name'] = strip_tags($theme['Name']);
758
+ $themes['inactive'][$br_i]['stylesheet'] = $theme['Stylesheet'];
759
+ $br_i++;
760
+ }
761
+
762
+ }
763
+
764
+ if ($search) {
765
+ foreach ($themes['active'] as $k => $theme) {
766
+ if (!stristr($theme['name'], $search)) {
767
+ unset($themes['active'][$k]);
768
+ }
769
+ }
770
+
771
+ foreach ($themes['inactive'] as $k => $theme) {
772
+ if (!stristr($theme['name'], $search)) {
773
+ unset($themes['inactive'][$k]);
774
+ }
775
+ }
776
+ }
777
+ }
778
+
779
+ return $themes;
780
+ }
781
+
782
+ function edit($args)
783
+ {
784
+ extract($args);
785
+ $return = array();
786
+ if ($type == 'plugins') {
787
+ $return['plugins'] = $this->edit_plugins($args);
788
+ } elseif ($type == 'themes') {
789
+ $return['themes'] = $this->edit_themes($args);
790
+ }
791
+ return $return;
792
+ }
793
+
794
+ function edit_plugins($args)
795
+ {
796
+ extract($args);
797
+ $return = array();
798
+ foreach ($items as $item) {
799
+ switch ($items_edit_action) {
800
+ case 'activate':
801
+ $result = activate_plugin($item['path']);
802
+ break;
803
+ case 'deactivate':
804
+ $result = deactivate_plugins(array(
805
+ $item['path']
806
+ ));
807
+ break;
808
+ case 'delete':
809
+ $result = delete_plugins(array(
810
+ $item['path']
811
+ ));
812
+ break;
813
+ default:
814
+ break;
815
+ }
816
+
817
+ if (is_wp_error($result)) {
818
+ $result = array(
819
+ 'error' => $result->get_error_message()
820
+ );
821
+ } elseif ($result === false) {
822
+ $result = array(
823
+ 'error' => "Failed to perform action."
824
+ );
825
+ } else {
826
+ $result = "OK";
827
+ }
828
+ $return[$item['name']] = $result;
829
+ }
830
+
831
+ return $return;
832
+ }
833
+
834
+ function edit_themes($args)
835
+ {
836
+ extract($args);
837
+ $return = array();
838
+ foreach ($items as $item) {
839
+ switch ($items_edit_action) {
840
+ case 'activate':
841
+ switch_theme($item['path'], $item['stylesheet']);
842
+ break;
843
+ case 'delete':
844
+ $result = delete_theme($item['path']);
845
+ break;
846
+ default:
847
+ break;
848
+ }
849
+
850
+ if (is_wp_error($result)) {
851
+ $result = array(
852
+ 'error' => $result->get_error_message()
853
+ );
854
+ } elseif ($result === false) {
855
+ $result = array(
856
+ 'error' => "Failed to perform action."
857
+ );
858
+ } else {
859
+ $result = "OK";
860
+ }
861
+ $return[$item['name']] = $result;
862
+ }
863
+
864
+ return $return;
865
+
866
+ }
867
+ }
868
  ?>
lib/dropbox.oauth.php CHANGED
@@ -1,1133 +1,1133 @@
1
- <?php
2
-
3
- /**
4
- * Dropbox class
5
- *
6
- * This source file can be used to communicate with Dropbox (http://dropbox.com)
7
- *
8
- * The class is documented in the file itself. If you find any bugs help me out and report them. Reporting can be done by sending an email to php-dropbox-bugs[at]verkoyen[dot]eu.
9
- * If you report a bug, make sure you give me enough information (include your code).
10
- *
11
- * Changelog since 1.0.4
12
- * - Fixed filesPost so it returns a boolean.
13
- * - Some code styling
14
- *
15
- * Changelog since 1.0.3
16
- * - Corrected the authorize-URL (thx to Jacob Budin).
17
- *
18
- * Changelog since 1.0.2
19
- * - Added methods to enable oauth-usage.
20
- *
21
- * Changelog since 1.0.1
22
- * - Bugfix: when doing multiple calles where GET and POST is mixed, the postfields should be reset (thx to Daniel Hトてスsken)
23
- *
24
- * Changelog since 1.0.0
25
- * - fixed some issues with generation off the basestring
26
- *
27
- * License
28
- * Copyright (c), Tijs Verkoyen. All rights reserved.
29
- *
30
- * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
31
- *
32
- * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
33
- * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
34
- * 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission.
35
- *
36
- * This software is provided by the author "as is" and any express or implied warranties, including, but not limited to, the implied warranties of merchantability and fitness for a particular purpose are disclaimed. In no event shall the author be liable for any direct, indirect, incidental, special, exemplary, or consequential damages (including, but not limited to, procurement of substitute goods or services; loss of use, data, or profits; or business interruption) however caused and on any theory of liability, whether in contract, strict liability, or tort (including negligence or otherwise) arising in any way out of the use of this software, even if advised of the possibility of such damage.
37
- *
38
- * @author Tijs Verkoyen <php-dropbox@verkoyen.eu>
39
- * @version 1.0.5
40
- *
41
- * @copyright Copyright (c), Tijs Verkoyen. All rights reserved.
42
- * @license BSD License
43
- */
44
- class Dropbox
45
- {
46
- // internal constant to enable/disable debugging
47
- const DEBUG = false;
48
-
49
- // url for the dropbox-api
50
- const API_URL = 'https://api.dropbox.com';
51
- const API_AUTH_URL = 'https://www.dropbox.com';
52
- const API_CONTENT_URL = 'https://api-content.dropbox.com';
53
-
54
- // port for the dropbox-api
55
- const API_PORT = 443;
56
-
57
- // current version
58
- const VERSION = '1.0.5';
59
-
60
-
61
- /**
62
- * A cURL instance
63
- *
64
- * @var resource
65
- */
66
- private $curl;
67
-
68
-
69
- /**
70
- * The application key
71
- *
72
- * @var string
73
- */
74
- private $applicationKey;
75
-
76
-
77
- /**
78
- * The application secret
79
- *
80
- * @var string
81
- */
82
- private $applicationSecret;
83
-
84
-
85
- /**
86
- * The oAuth-token
87
- *
88
- * @var string
89
- */
90
- private $oAuthToken = '';
91
-
92
-
93
- /**
94
- * The oAuth-token-secret
95
- *
96
- * @var string
97
- */
98
- private $oAuthTokenSecret = '';
99
-
100
-
101
- /**
102
- * The timeout
103
- *
104
- * @var int
105
- */
106
- private $timeOut = 60;
107
-
108
-
109
- /**
110
- * The user agent
111
- *
112
- * @var string
113
- */
114
- private $userAgent;
115
-
116
-
117
- // class methods
118
- /**
119
- * Default constructor
120
- *
121
- * @return void
122
- * @param string $applicationKey The application key to use.
123
- * @param string $applicationSecret The application secret to use.
124
- */
125
- public function __construct($applicationKey, $applicationSecret)
126
- {
127
- $this->setApplicationKey($applicationKey);
128
- $this->setApplicationSecret($applicationSecret);
129
- }
130
-
131
-
132
- /**
133
- * Default destructor
134
- *
135
- * @return void
136
- */
137
- public function __destruct()
138
- {
139
- if($this->curl != null) curl_close($this->curl);
140
- }
141
-
142
-
143
- /**
144
- * Format the parameters as a querystring
145
- *
146
- * @return string
147
- * @param array $parameters The parameters to pass.
148
- */
149
- private function buildQuery(array $parameters)
150
- {
151
- // no parameters?
152
- if(empty($parameters)) return '';
153
-
154
- // encode the keys
155
- $keys = self::urlencode_rfc3986(array_keys($parameters));
156
-
157
- // encode the values
158
- $values = self::urlencode_rfc3986(array_values($parameters));
159
-
160
- // reset the parameters
161
- $parameters = array_combine($keys, $values);
162
-
163
- // sort parameters by key
164
- uksort($parameters, 'strcmp');
165
-
166
- // loop parameters
167
- foreach($parameters as $key => $value)
168
- {
169
- // sort by value
170
- if(is_array($value)) $parameters[$key] = natsort($value);
171
- }
172
-
173
- // process parameters
174
- foreach($parameters as $key => $value) $chunks[] = $key . '=' . str_replace('%25', '%', $value);
175
-
176
- // return
177
- return implode('&', $chunks);
178
- }
179
-
180
-
181
- /**
182
- * All OAuth 1.0 requests use the same basic algorithm for creating a signature base string and a signature.
183
- * The signature base string is composed of the HTTP method being used, followed by an ampersand ("&") and then the URL-encoded base URL being accessed,
184
- * complete with path (but not query parameters), followed by an ampersand ("&").
185
- * Then, you take all query parameters and POST body parameters (when the POST body is of the URL-encoded type, otherwise the POST body is ignored),
186
- * including the OAuth parameters necessary for negotiation with the request at hand, and sort them in lexicographical order by first parameter name and
187
- * then parameter value (for duplicate parameters), all the while ensuring that both the key and the value for each parameter are URL encoded in isolation.
188
- * Instead of using the equals ("=") sign to mark the key/value relationship, you use the URL-encoded form of "%3D". Each parameter is then joined by the
189
- * URL-escaped ampersand sign, "%26".
190
- *
191
- * @return string
192
- * @param string $url The url to use.
193
- * @param string $method The method that will be called.
194
- * @param array $parameters The parameters to pass.
195
- */
196
- private function calculateBaseString($url, $method, array $parameters)
197
- {
198
- // redefine
199
- $url = (string) $url;
200
- $parameters = (array) $parameters;
201
-
202
- // init var
203
- $pairs = array();
204
- $chunks = array();
205
-
206
- // sort parameters by key
207
- uksort($parameters, 'strcmp');
208
-
209
- // loop parameters
210
- foreach($parameters as $key => $value)
211
- {
212
- // sort by value
213
- if(is_array($value)) $parameters[$key] = natsort($value);
214
- }
215
-
216
- // process queries
217
- foreach($parameters as $key => $value)
218
- {
219
- // only add if not already in the url
220
- if(substr_count($url, $key . '=' . $value) == 0) $chunks[] = self::urlencode_rfc3986($key) . '%3D' . self::urlencode_rfc3986($value);
221
- }
222
-
223
- $urlChunks = explode('/', $url);
224
- $i = 0;
225
-
226
- foreach($urlChunks as &$chunk)
227
- {
228
- if($i > 4) $chunk = self::urlencode_rfc3986($chunk);
229
- else $chunk = urlencode($chunk);
230
-
231
- $i++;
232
-
233
- }
234
-
235
- // build base
236
- $base = $method . '&';
237
- $base .= implode('%2F', $urlChunks);
238
- $base .= (substr_count($url, '?')) ? '%26' : '&';
239
- $base .= implode('%26', $chunks);
240
- $base = str_replace(array('%3F', '%20'), array('&', '%2520'), $base);
241
-
242
- // return
243
- return $base;
244
- }
245
-
246
-
247
- /**
248
- * Build the Authorization header
249
- * @later: fix me
250
- *
251
- * @return string
252
- * @param array $parameters The parameters to pass.
253
- * @param string $url The url to use.
254
- */
255
- private function calculateHeader(array $parameters, $url)
256
- {
257
- // redefine
258
- $url = (string) $url;
259
-
260
- // divide into parts
261
- $parts = parse_url($url);
262
-
263
- // init var
264
- $chunks = array();
265
-
266
- // process queries
267
- foreach($parameters as $key => $value) $chunks[] = str_replace('%25', '%', self::urlencode_rfc3986($key) . '="' . self::urlencode_rfc3986($value) . '"');
268
- $parts['path']=str_replace("%2F", "/", rawurlencode($parts['path']));
269
- // build return
270
- $return = 'Authorization: OAuth realm="' . $parts['scheme'] . '://' . $parts['host'] . $parts['path'] . '", ';
271
- $return .= implode(',', $chunks);
272
- // prepend name and OAuth part
273
- return $return;
274
- }
275
-
276
-
277
- /**
278
- * Make an call to the oAuth
279
- * @todo refactor me
280
- *
281
- * @return array
282
- * @param string $url The url that has to be called.
283
- * @param array[optional] $parameters The parameters to pass.
284
- * @param string[optional] $method Which HTTP-method should we use? Possible values are POST, GET.
285
- * @param bool[optional] $expectJSON Do we expect JSON?
286
- */
287
- private function doOAuthCall($url, array $parameters = null, $method = 'POST', $expectJSON = true)
288
- {
289
- // redefine
290
- $url = (string) $url;
291
-
292
- // append default parameters
293
- $parameters['oauth_consumer_key'] = $this->getApplicationKey();
294
- $parameters['oauth_nonce'] = md5(microtime() . rand());
295
- $parameters['oauth_timestamp'] = time();
296
- $parameters['oauth_signature_method'] = 'HMAC-SHA1';
297
- $parameters['oauth_version'] = '1.0';
298
-
299
- // calculate the base string
300
- $base = $this->calculateBaseString(self::API_URL . '/' . $url, 'POST', $parameters);
301
-
302
- // add sign into the parameters
303
- $parameters['oauth_signature'] = $this->hmacsha1($this->getApplicationSecret() . '&' . $this->getOAuthTokenSecret(), $base);
304
-
305
- // calculate header
306
- $header = $this->calculateHeader($parameters, self::API_URL . '/' . $url);
307
-
308
- if($method == 'POST')
309
- {
310
- $options[CURLOPT_POST] = true;
311
- $options[CURLOPT_POSTFIELDS] = $this->buildQuery($parameters);
312
- }
313
-
314
- else
315
- {
316
- // reset post
317
- $options[CURLOPT_POST] = 0;
318
- unset($options[CURLOPT_POSTFIELDS]);
319
-
320
- // add the parameters into the querystring
321
- if(!empty($parameters)) $url .= '?' . $this->buildQuery($parameters);
322
- }
323
-
324
- // set options
325
- $options[CURLOPT_URL] = self::API_URL . '/' . $url;
326
- $options[CURLOPT_PORT] = self::API_PORT;
327
- $options[CURLOPT_USERAGENT] = $this->getUserAgent();
328
- if(ini_get('open_basedir') == '' && ini_get('safe_mode' == 'Off')) $options[CURLOPT_FOLLOWLOCATION] = true;
329
- $options[CURLOPT_RETURNTRANSFER] = true;
330
- $options[CURLOPT_TIMEOUT] = (int) $this->getTimeOut();
331
- $options[CURLOPT_SSL_VERIFYPEER] = false;
332
- $options[CURLOPT_SSL_VERIFYHOST] = false;
333
- $options[CURLOPT_HTTPHEADER] = array('Expect:');
334
-
335
- // init
336
- $this->curl = curl_init();
337
-
338
- // set options
339
- curl_setopt_array($this->curl, $options);
340
-
341
- // execute
342
- $response = curl_exec($this->curl);
343
- $headers = curl_getinfo($this->curl);
344
-
345
- // fetch errors
346
- $errorNumber = curl_errno($this->curl);
347
- $errorMessage = curl_error($this->curl);
348
-
349
- // error?
350
- if($errorNumber != '') throw new DropboxException($errorMessage, $errorNumber);
351
-
352
- // return
353
- if($expectJSON) return json_decode($response, true);
354
-
355
- // fallback
356
- return $response;
357
- }
358
-
359
-
360
- /**
361
- * Make the call
362
- *
363
- * @return string
364
- * @param string $url The url to call.
365
- * @param array[optional] $parameters Optional parameters.
366
- * @param bool[optional] $method The method to use. Possible values are GET, POST.
367
- * @param string[optional] $filePath The path to the file to upload.
368
- * @param bool[optional] $expectJSON Do we expect JSON?
369
- * @param bool[optional] $isContent Is this content?
370
- */
371
- private function doCall($url, array $parameters = null, $method = 'GET', $filePath = null, $expectJSON = true, $isContent = false)
372
- {
373
- // allowed methods
374
- $allowedMethods = array('GET', 'POST');
375
-
376
- // redefine
377
- $url = (string) $url;
378
- $parameters = (array) $parameters;
379
- $method = (string) $method;
380
- $expectJSON = (bool) $expectJSON;
381
-
382
- // validate method
383
- if(!in_array($method, $allowedMethods)) throw new DropboxException('Unknown method (' . $method . '). Allowed methods are: ' . implode(', ', $allowedMethods));
384
-
385
- // append default parameters
386
- $oauth['oauth_consumer_key'] = $this->getApplicationKey();
387
- $oauth['oauth_nonce'] = md5(microtime() . rand());
388
- $oauth['oauth_timestamp'] = time();
389
- $oauth['oauth_token'] = $this->getOAuthToken();
390
- $oauth['oauth_signature_method'] = 'HMAC-SHA1';
391
- $oauth['oauth_version'] = '1.0';
392
-
393
- // set data
394
- $data = $oauth;
395
- if(!empty($parameters))
396
- {
397
- // convert to UTF-8
398
- foreach($parameters as &$value) $value = utf8_encode($value);
399
-
400
- // merge
401
- $data = array_merge($data, $parameters);
402
- }
403
-
404
- if($filePath != null)
405
- {
406
- // process file
407
- $fileInfo = pathinfo($filePath);
408
-
409
- // add to the data
410
- $data['file'] = $fileInfo['basename'];
411
-
412
- }
413
-
414
- // calculate the base string
415
- if($isContent) $base = $this->calculateBaseString(self::API_CONTENT_URL . '/' . $url, $method, $data);
416
- else $base = $this->calculateBaseString(self::API_URL . '/' . $url, $method, $data);
417
-
418
- // based on the method, we should handle the parameters in a different way
419
- if($method == 'POST')
420
- {
421
- // file provided?
422
- if($filePath != null)
423
- {
424
- // build a boundary
425
- $boundary = md5(time());
426
-
427
- // init var
428
- $content = '--' . $boundary . "\r\n";
429
-
430
- // set file
431
- $content .= 'Content-Disposition: form-data; name=file; filename="' . $fileInfo['basename'] . '"' . "\r\n";
432
- $content .= 'Content-Type: application/octet-stream' . "\r\n";
433
- $content .= "\r\n";
434
- $content .= file_get_contents($filePath);
435
- $content .= "\r\n";
436
- $content .= "--" . $boundary . '--';
437
-
438
- // build headers
439
- $headers[] = 'Content-Type: multipart/form-data; boundary=' . $boundary;
440
- $headers[] = 'Content-Length: ' . strlen($content);
441
-
442
- // set content
443
- $options[CURLOPT_POSTFIELDS] = $content;
444
- }
445
-
446
- // no file
447
- else $options[CURLOPT_POSTFIELDS] = $this->buildQuery($parameters);
448
-
449
- // enable post
450
- $options[CURLOPT_POST] = 1;
451
- }
452
-
453
- else
454
- {
455
- // reset post
456
- $options[CURLOPT_POST] = 0;
457
- unset($options[CURLOPT_POSTFIELDS]);
458
- $url=str_replace("%2F", "/", rawurlencode($url));
459
-
460
- // add the parameters into the querystring
461
- if(!empty($parameters)) $url .= '?' . $this->buildQuery($parameters);
462
- }
463
-
464
- // add sign into the parameters
465
- $oauth['oauth_signature'] = $this->hmacsha1($this->getApplicationSecret() . '&' . $this->getOAuthTokenSecret(), $base);
466
-
467
- if($isContent) $headers[] = $this->calculateHeader($oauth, self::API_CONTENT_URL . '/' . $url);
468
- else $headers[] = $this->calculateHeader($oauth, self::API_URL . '/' . $url);
469
- $headers[] = 'Expect:';
470
-
471
- // set options
472
- if($isContent) $options[CURLOPT_URL] = self::API_CONTENT_URL . '/' . $url;
473
- else $options[CURLOPT_URL] = self::API_URL . '/' . $url;
474
- $options[CURLOPT_PORT] = self::API_PORT;
475
- $options[CURLOPT_USERAGENT] = $this->getUserAgent();
476
- if(ini_get('open_basedir') == '' && ini_get('safe_mode' == 'Off')) $options[CURLOPT_FOLLOWLOCATION] = true;
477
- $options[CURLOPT_RETURNTRANSFER] = true;
478
- $options[CURLOPT_TIMEOUT] = (int) $this->getTimeOut();
479
- $options[CURLOPT_SSL_VERIFYPEER] = false;
480
- $options[CURLOPT_SSL_VERIFYHOST] = false;
481
- $options[CURLOPT_HTTP_VERSION] = CURL_HTTP_VERSION_1_1;
482
- $options[CURLOPT_HTTPHEADER] = $headers;
483
- // init
484
- if($this->curl == null) $this->curl = curl_init();
485
-
486
- // set options
487
- curl_setopt_array($this->curl, $options);
488
-
489
- // execute
490
- $response = curl_exec($this->curl);
491
- $headers = curl_getinfo($this->curl);
492
-
493
- // fetch errors
494
- $errorNumber = curl_errno($this->curl);
495
- $errorMessage = curl_error($this->curl);
496
-
497
- if(!$expectJSON && $isContent)
498
- {
499
- // is it JSON?
500
- $json = @json_decode($response, true);
501
- if($json !== false && isset($json['error'])) throw new DropboxException($json['error']);
502
-
503
- // set return
504
- $return['content_type'] = $headers['content_type'];
505
- $return['data'] = base64_encode($response);
506
-
507
- // return
508
- return $return;
509
- }
510
-
511
- // we don't expect JSON, return the response
512
- if(!$expectJSON) return $response;
513
-
514
- // replace ids with their string values, added because of some PHP-version can't handle these large values
515
- $response = preg_replace('/id":(\d+)/', 'id":"\1"', $response);
516
-
517
- // we expect JSON, so decode it
518
- $json = @json_decode($response, true);
519
-
520
- // validate JSON
521
- if($json === null)
522
- {
523
- // should we provide debug information
524
- if(self::DEBUG)
525
- {
526
- // make it output proper
527
- echo '<pre>';
528
-
529
- // dump the header-information
530
- var_dump($headers);
531
-
532
- // dump the error
533
- var_dump($errorMessage);
534
-
535
- // dump the raw response
536
- var_dump($response);
537
-
538
- // end proper format
539
- echo '</pre>';
540
- }
541
-
542
- // throw exception
543
- throw new DropboxException('Invalid response.');
544
- }
545
-
546
- // any error
547
- if(isset($json['error']))
548
- {
549
- // should we provide debug information
550
- if(self::DEBUG)
551
- {
552
- // make it output proper
553
- echo '<pre>';
554
-
555
- // dump the header-information
556
- var_dump($headers);
557
-
558
- // dump the raw response
559
- var_dump($response);
560
-
561
- // end proper format
562
- echo '</pre>';
563
- }
564
-
565
- if(isset($json['error']) && is_string($json['error'])) $message = $json['error'];
566
- elseif(isset($json['error']['hash']) && $json['error']['hash'] != '') $message = (string) $json['error']['hash'];
567
- else $message = 'Invalid response.';
568
-
569
- // throw exception
570
- throw new DropboxException($message);
571
- }
572
-
573
- // return
574
- return $json;
575
- }
576
-
577
-
578
- /**
579
- * Get the application key
580
- *
581
- * @return string
582
- */
583
- private function getApplicationKey()
584
- {
585
- return $this->applicationKey;
586
- }
587
-
588
-
589
- /**
590
- * Get the application secret
591
- *
592
- * @return string
593
- */
594
- private function getApplicationSecret()
595
- {
596
- return $this->applicationSecret;
597
- }
598
-
599
-
600
- /**
601
- * Get the oAuth-token
602
- *
603
- * @return string
604
- */
605
- private function getOAuthToken()
606
- {
607
- return $this->oAuthToken;
608
- }
609
-
610
-
611
- /**
612
- * Get the oAuth-token-secret
613
- *
614
- * @return string
615
- */
616
- private function getOAuthTokenSecret()
617
- {
618
- return $this->oAuthTokenSecret;
619
- }
620
-
621
-
622
- /**
623
- * Get the timeout
624
- *
625
- * @return int
626
- */
627
- public function getTimeOut()
628
- {
629
- return (int) $this->timeOut;
630
- }
631
-
632
-
633
- /**
634
- * Get the useragent that will be used. Our version will be prepended to yours.
635
- * It will look like: "PHP Dropbox/<version> <your-user-agent>"
636
- *
637
- * @return string
638
- */
639
- public function getUserAgent()
640
- {
641
- return (string) 'PHP Dropbox/' . self::VERSION . ' ' . $this->userAgent;
642
- }
643
-
644
-
645
- /**
646
- * Set the application key
647
- *
648
- * @return void
649
- * @param string $key The application key to use.
650
- */
651
- private function setApplicationKey($key)
652
- {
653
- $this->applicationKey = (string) $key;
654
- }
655
-
656
-
657
- /**
658
- * Set the application secret
659
- *
660
- * @return void
661
- * @param string $secret The application secret to use.
662
- */
663
- private function setApplicationSecret($secret)
664
- {
665
- $this->applicationSecret = (string) $secret;
666
- }
667
-
668
-
669
- /**
670
- * Set the oAuth-token
671
- *
672
- * @return void
673
- * @param string $token The token to use.
674
- */
675
- public function setOAuthToken($token)
676
- {
677
- $this->oAuthToken = (string) $token;
678
- }
679
-
680
-
681
- /**
682
- * Set the oAuth-secret
683
- *
684
- * @return void
685
- * @param string $secret The secret to use.
686
- */
687
- public function setOAuthTokenSecret($secret)
688
- {
689
- $this->oAuthTokenSecret = (string) $secret;
690
- }
691
-
692
-
693
- /**
694
- * Set the timeout
695
- *
696
- * @return void
697
- * @param int $seconds The timeout in seconds.
698
- */
699
- public function setTimeOut($seconds)
700
- {
701
- $this->timeOut = (int) $seconds;
702
- }
703
-
704
-
705
- /**
706
- * Get the useragent that will be used. Our version will be prepended to yours.
707
- * It will look like: "PHP Dropbox/<version> <your-user-agent>"
708
- *
709
- * @return void
710
- * @param string $userAgent Your user-agent, it should look like <app-name>/<app-version>.
711
- */
712
- public function setUserAgent($userAgent)
713
- {
714
- $this->userAgent = (string) $userAgent;
715
- }
716
-
717
-
718
- /**
719
- * Build the signature for the data
720
- *
721
- * @return string
722
- * @param string $key The key to use for signing.
723
- * @param string $data The data that has to be signed.
724
- */
725
- private function hmacsha1($key, $data)
726
- {
727
- return base64_encode(hash_hmac('SHA1', $data, $key, true));
728
- }
729
-
730
-
731
- /**
732
- * URL-encode method for internatl use
733
- *
734
- * @return string
735
- * @param mixed $value The value to encode.
736
- */
737
- private static function urlencode_rfc3986($value)
738
- {
739
- if(is_array($value)) return array_map(array('Dropbox', 'urlencode_rfc3986'), $value);
740
- else
741
- {
742
- $search = array('+', ' ', '%7E', '%');
743
- $replace = array('%20', '%20', '~', '%25');
744
-
745
- return str_replace($search, $replace, rawurlencode($value));
746
- }
747
- }
748
-
749
-
750
- // oauth resources
751
- /**
752
- * Call for obtaining an OAuth request token.
753
- * Returns a request token and the corresponding request token secret. This token and secret cannot be used to sign requests for the /metadata and /file content API calls.
754
- * Their only purpose is for signing a request to oauth/access_token once the user has gone through the application authorization steps provided by oauth/authorize.
755
- *
756
- * @return array
757
- */
758
- public function oAuthRequestToken()
759
- {
760
- // make the call
761
- $response = $this->doOAuthCall('1/oauth/request_token', null, 'POST', false);
762
-
763
- // process response
764
- $response = (array) explode('&', $response);
765
- $return = array();
766
-
767
- // loop chunks
768
- foreach($response as $chunk)
769
- {
770
- // split again
771
- $chunks = explode('=', $chunk, 2);
772
-
773
- // store return
774
- if(count($chunks) == 2) $return[$chunks[0]] = $chunks[1];
775
- }
776
-
777
- // return
778
- return $return;
779
- }
780
-
781
-
782
- /**
783
- * Redirect the user to the oauth/authorize location so that Dropbox can authenticate the user and ask whether or not the user wants to authorize the application to access
784
- * file metadata and content on its behalf. oauth/authorize is not an API call per se, because it does not have a return value, but rather directs the user to a page on
785
- * api.dropbox.com where they are provided means to log in to Dropbox and grant authority to the application requesting it.
786
- * The page served by oauth/authorize should be presented to the user through their web browser.
787
- * Please note, without directing the user to a Dropbox-provided page via oauth/authorize, it is impossible for your application to use the request token it received
788
- * via oauth/request_token to obtain an access token from oauth/access_token.
789
- *
790
- * @return void
791
- * @param string $oauthToken The request token of the application requesting authority from a user.
792
- * @param string[optional] $oauthCallback After the user authorizes an application, the user is redirected to the application-served URL provided by this parameter.
793
- */
794
- public function oAuthAuthorize($oauthToken, $oauthCallback = null)
795
- {
796
- // build parameters
797
- $parameters = array();
798
- $parameters['oauth_token'] = (string) $oauthToken;
799
- if($oauthCallback !== null) $parameters['oauth_callback'] = (string) $oauthCallback;
800
-
801
- // build url
802
- $url = self::API_AUTH_URL . '/1/oauth/authorize?' . http_build_query($parameters);
803
-
804
- // redirect
805
- header('Location: ' . $url);
806
- exit;
807
- }
808
-
809
- public function mwp_oAuthAuthorize($oauthToken, $oauthCallback = null)
810
- {
811
- // build parameters
812
- $parameters = array();
813
- $parameters['oauth_token'] = (string) $oauthToken;
814
- if($oauthCallback !== null) $parameters['oauth_callback'] = (string) $oauthCallback;
815
-
816
- // build url
817
- $url = self::API_AUTH_URL . '/1/oauth/authorize?' . http_build_query($parameters);
818
-
819
- return $url;
820
- }
821
-
822
- /**
823
- * This call returns a access token and the corresponding access token secret.
824
- * Upon return, the authorization process is now complete and the access token and corresponding secret are used to sign requests for the metadata and file content API calls.
825
- *
826
- * @return array
827
- * @param string $oauthToken The token returned after authorizing.
828
- */
829
- public function oAuthAccessToken($oauthToken)
830
- {
831
- // build parameters
832
- $parameters = array();
833
- $parameters['oauth_token'] = (string) $oauthToken;
834
-
835
- // make the call
836
- $response = $this->doOAuthCall('1/oauth/access_token', $parameters, 'POST', false);
837
-
838
- // process response
839
- $response = (array) explode('&', $response);
840
- $return = array();
841
-
842
- // loop chunks
843
- foreach($response as $chunk)
844
- {
845
- // split again
846
- $chunks = explode('=', $chunk, 2);
847
-
848
- // store return
849
- if(count($chunks) == 2) $return[$chunks[0]] = $chunks[1];
850
- }
851
-
852
- // return
853
- return $return;
854
- }
855
-
856
-
857
- // token resources
858
- /**
859
- * The token call provides a consumer/secret key pair you can use to consistently access the user's account.
860
- * This is the preferred method of authentication over storing the username and password.
861
- * Use the key pair as a signature with every subsequent call.
862
- * The request must be signed using the application's developer and secret key token. Request or access tokens are necessary.
863
- *
864
- * Warning: DO NOT STORE THE USER'S PASSWORD! The way this call works is you call it once with the user's email and password and then
865
- * keep the token around for later. You do NOT (I repeat NOT) call this before everything you do or on each program startup.
866
- * We watch for this and will shut down your application with little notice if we catch you.
867
- * In fact, the Objective-C code does this for you so you can't get it wrong.
868
- *
869
- * @return array Upon successful verification of the user's credentials, returns an array representation of the access token and secret.
870
- * @param string $email The email account of the user.
871
- * @param string $password The password of the user.
872
- */
873
- public function token($email, $password)
874
- {
875
- // build parameters
876
- $parameters = array();
877
- $parameters['email'] = (string) $email;
878
- $parameters['password'] = (string) $password;
879
-
880
- // make the call
881
- $response = (array) $this->doOAuthCall('1/token', $parameters);
882
-
883
- // validate and set
884
- if(isset($response['token'])) $this->setOAuthToken($response['token']);
885
- if(isset($response['secret'])) $this->setOAuthTokenSecret($response['secret']);
886
-
887
- // return
888
- return $response;
889
- }
890
-
891
-
892
- // account resources
893
- /**
894
- * Given a set of account information, the account call allows an application to create a new Dropbox user account.
895
- * This is useful for situations where the trusted third party application is possibly the user's first interaction with Dropbox.
896
- *
897
- * @return bool
898
- * @param string $email The email account of the user.
899
- * @param string $password The password for the user.
900
- * @param string $firstName The user's first name.
901
- * @param string $lastName The user's last name.
902
- */
903
- public function account($email, $password, $firstName, $lastName)
904
- {
905
- // build parameters
906
- $parameters['email'] = (string) $email;
907
- $parameters['first_name'] = (string) $firstName;
908
- $parameters['last_name'] = (string) $lastName;
909
- $parameters['password'] = (string) $password;
910
-
911
- return (bool) ($this->doCall('1/account', $parameters, 'POST', null, false) == 'OK');
912
- }
913
-
914
-
915
- /**
916
- * Get the user account information.
917
- *
918
- * @return array
919
- */
920
- public function accountInfo()
921
- {
922
- // make the call
923
- return (array) $this->doCall('1/account/info');
924
- }
925
-
926
-
927
- // files & metadata
928
- /**
929
- * Retrieves file contents relative to the user's Dropbox root or the application's directory within the user's Dropbox.
930
- *
931
- * @return string
932
- * @param string $path Path of the directory wherin the file is located.
933
- * @param bool[optional] $sandbox Sandbox mode?
934
- */
935
- public function filesGet($path, $sandbox = false)
936
- {
937
- // build url
938
- $url = '1/files/';
939
- $url .= ($sandbox) ? 'sandbox/' : 'dropbox/';
940
- $url .= trim((string) $path, '/');
941
-
942
- // make the call
943
- return $this->doCall($url, null, 'GET', null, false, true);
944
- }
945
-
946
-
947
- /**
948
- * Uploads file contents relative to the user's Dropbox root or the application's directory within the user's Dropbox.
949
- *
950
- * @return bool
951
- * @param string $path Path of the directory wherin the file should be uploaded.
952
- * @param string $localFile Path to the local file.
953
- * @param bool[optional] $sandbox Sandbox mode?
954
- */
955
- public function filesPost($path, $localFile, $sandbox = false)
956
- {
957
- // build url
958
- $url = '1/files/';
959
- $url .= ($sandbox) ? 'sandbox/' : 'dropbox/';
960
- $url .= trim((string) $path, '/');
961
-
962
- // make the call
963
- $return = $this->doCall($url, null, 'POST', $localFile, true, true);
964
- // return the result
965
- return (bool) (isset($return['size']) && $return['size'] == 'winner!');
966
- }
967
-
968
-
969
- /**
970
- * Returns metadata for the file or directory at the given <path> location relative to the user's Dropbox or
971
- * the user's application sandbox. If <path> represents a directory and the list parameter is true, the metadata will
972
- * also include a listing of metadata for the directory's contents.
973
- *
974
- * @return array
975
- * @param string[optional] $path The path to the file/director to get the metadata for.
976
- * @param int[optional] $fileLimit When listing a directory, the service will not report listings containing more than $fileLimit files.
977
- * @param bool[optional] $hash Listing return values include a hash representing the state of the directory's contents.
978
- * @param bool[optional] $list If true, this call returns a list of metadata representations for the contents of the directory. If false, this call returns the metadata for the directory itself.
979
- * @param bool[optional] $sandbox Sandbox mode?
980
- */
981
- public function metadata($path = '', $fileLimit = 10000, $hash = false, $list = true, $sandbox = false)
982
- {
983
- // build url
984
- $url = '1/metadata/';
985
- $url .= ($sandbox) ? 'sandbox/' : 'dropbox/';
986
- $url .= trim((string) $path, '/');
987
-
988
- // build parameters
989
- $parameters = null;
990
- $parameters['file_limit'] = (int) $fileLimit;
991
- if((bool) $hash) $parameters['hash'] = '';
992
- $parameters['list'] = ($list) ? 'true': 'false';
993
-
994
- // make the call
995
- return (array) $this->doCall($url, $parameters);
996
- }
997
-
998
-
999
- /**
1000
- * Get a minimized thumbnail for a photo.
1001
- *
1002
- * @return string Will return a base64_encode string with the JPEG-data
1003
- * @param string $path The path to the photo.
1004
- * @param string[optional] $size The size, possible values are: 'small' (32x32), 'medium' (64x64), 'large' (128x128).
1005
- */
1006
- public function thumbnails($path, $size = 'small')
1007
- {
1008
- // build url
1009
- $url = '1/thumbnails/dropbox/';
1010
- $url .= trim((string) $path, '/');
1011
-
1012
- // build parameters
1013
- $parameters['size'] = (string) $size;
1014
-
1015
- // make the call
1016
- return $this->doCall($url, $parameters, 'GET', null, false, true);
1017
- }
1018
-
1019
-
1020
- // file operations
1021
- /**
1022
- * Copy a file or folder to a new location.
1023
- *
1024
- * @return array
1025
- * @param string $fromPath fromPath specifies either a file or folder to be copied to the location specified by toPath. This path is interpreted relative to the location specified by root.
1026
- * @param string $toPath toPath specifies the destination path including the new name for file or folder. This path is interpreted relative to the location specified by root.
1027
- * @param bool[optional] $sandbox Sandbox mode?
1028
- */
1029
- public function fileopsCopy($fromPath, $toPath, $sandbox = false)
1030
- {
1031
- // build url
1032
- $url = '1/fileops/copy';
1033
-
1034
- // build parameters
1035
- $parameters['from_path'] = (string) $fromPath;
1036
- $parameters['to_path'] = (string) $toPath;
1037
- $parameters['root'] = ($sandbox) ? 'sandbox' : 'dropbox';
1038
-
1039
- // make the call
1040
- return $this->doCall($url, $parameters, 'POST');
1041
- }
1042
-
1043
-
1044
- /**
1045
- * Create a folder relative to the user's Dropbox root or the user's application sandbox folder.
1046
- *
1047
- * @return array
1048
- * @param string $path The path to the new folder to create, relative to root.
1049
- * @param bool[optional] $sandbox Sandbox mode?
1050
- */
1051
- public function fileopsCreateFolder($path, $sandbox = false)
1052
- {
1053
- // build url
1054
- $url = '1/fileops/create_folder';
1055
-
1056
- // build parameters
1057
- $parameters['path'] = trim((string) $path, '/');
1058
- $parameters['root'] = ($sandbox) ? 'sandbox' : 'dropbox';
1059
-
1060
- // make the call
1061
- return $this->doCall($url, $parameters, 'POST');
1062
- }
1063
-
1064
-
1065
- /**
1066
- * Deletes a file or folder.
1067
- *
1068
- * @return array
1069
- * @param string $path path specifies either a file or folder to be deleted. This path is interpreted relative to the location specified by root.
1070
- * @param bool[optional] $sandbox Sandbox mode?
1071
- */
1072
- public function fileopsDelete($path, $sandbox = false)
1073
- {
1074
- // build url
1075
- $url = '1/fileops/delete';
1076
-
1077
- // build parameters
1078
- $parameters['path'] = trim((string) $path, '/');
1079
- $parameters['root'] = ($sandbox) ? 'sandbox' : 'dropbox';
1080
- // make the call
1081
- return $this->doCall($url, $parameters, 'POST');
1082
- }
1083
-
1084
-
1085
- /**
1086
- * Move a file or folder to a new location.
1087
- *
1088
- * @return array
1089
- * @param string $fromPath fromPath specifies either a file or folder to be copied to the location specified by toPath. This path is interpreted relative to the location specified by root.
1090
- * @param string $toPath toPath specifies the destination path including the new name for file or folder. This path is interpreted relative to the location specified by root.
1091
- * @param bool[optional] $sandbox Sandbox mode?
1092
- */
1093
- public function fileopsMove($fromPath, $toPath, $sandbox = false)
1094
- {
1095
- // build url
1096
- $url = '1/fileops/move';
1097
-
1098
- // build parameters
1099
- $parameters['from_path'] = (string) $fromPath;
1100
- $parameters['to_path'] = (string) $toPath;
1101
- $parameters['root'] = ($sandbox) ? 'sandbox' : 'dropbox';
1102
-
1103
- // make the call
1104
- return $this->doCall($url, $parameters, 'POST');
1105
- }
1106
-
1107
- function _log($mixed)
1108
- {
1109
- if (is_array($mixed)) {
1110
- $mixed = print_r($mixed, 1);
1111
- } else if (is_object($mixed)) {
1112
- ob_start();
1113
- var_dump($mixed);
1114
- $mixed = ob_get_clean();
1115
- }
1116
-
1117
- $handle = fopen(dirname(__FILE__) . '/log', 'a');
1118
- fwrite($handle, $mixed . PHP_EOL);
1119
- fclose($handle);
1120
- }
1121
- }
1122
-
1123
-
1124
- /**
1125
- * Dropbox Exception class
1126
- *
1127
- * @author Tijs Verkoyen <php-dropbox@verkoyen.eu>
1128
- */
1129
- class DropboxException extends Exception
1130
- {
1131
- }
1132
-
1133
- ?>
1
+ <?php
2
+
3
+ /**
4
+ * Dropbox class
5
+ *
6
+ * This source file can be used to communicate with Dropbox (http://dropbox.com)
7
+ *
8
+ * The class is documented in the file itself. If you find any bugs help me out and report them. Reporting can be done by sending an email to php-dropbox-bugs[at]verkoyen[dot]eu.
9
+ * If you report a bug, make sure you give me enough information (include your code).
10
+ *
11
+ * Changelog since 1.0.4
12
+ * - Fixed filesPost so it returns a boolean.
13
+ * - Some code styling
14
+ *
15
+ * Changelog since 1.0.3
16
+ * - Corrected the authorize-URL (thx to Jacob Budin).
17
+ *
18
+ * Changelog since 1.0.2
19
+ * - Added methods to enable oauth-usage.
20
+ *
21
+ * Changelog since 1.0.1
22
+ * - Bugfix: when doing multiple calles where GET and POST is mixed, the postfields should be reset (thx to Daniel Hトてスsken)
23
+ *
24
+ * Changelog since 1.0.0
25
+ * - fixed some issues with generation off the basestring
26
+ *
27
+ * License
28
+ * Copyright (c), Tijs Verkoyen. All rights reserved.
29
+ *
30
+ * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
31
+ *
32
+ * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
33
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
34
+ * 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission.
35
+ *
36
+ * This software is provided by the author "as is" and any express or implied warranties, including, but not limited to, the implied warranties of merchantability and fitness for a particular purpose are disclaimed. In no event shall the author be liable for any direct, indirect, incidental, special, exemplary, or consequential damages (including, but not limited to, procurement of substitute goods or services; loss of use, data, or profits; or business interruption) however caused and on any theory of liability, whether in contract, strict liability, or tort (including negligence or otherwise) arising in any way out of the use of this software, even if advised of the possibility of such damage.
37
+ *
38
+ * @author Tijs Verkoyen <php-dropbox@verkoyen.eu>
39
+ * @version 1.0.5
40
+ *
41
+ * @copyright Copyright (c), Tijs Verkoyen. All rights reserved.
42
+ * @license BSD License
43
+ */
44
+ class Dropbox
45
+ {
46
+ // internal constant to enable/disable debugging
47
+ const DEBUG = false;
48
+
49
+ // url for the dropbox-api
50
+ const API_URL = 'https://api.dropbox.com';
51
+ const API_AUTH_URL = 'https://www.dropbox.com';
52
+ const API_CONTENT_URL = 'https://api-content.dropbox.com';
53
+
54
+ // port for the dropbox-api
55
+ const API_PORT = 443;
56
+
57
+ // current version
58
+ const VERSION = '1.0.5';
59
+
60
+
61
+ /**
62
+ * A cURL instance
63
+ *
64
+ * @var resource
65
+ */
66
+ private $curl;
67
+
68
+
69
+ /**
70
+ * The application key
71
+ *
72
+ * @var string
73
+ */
74
+ private $applicationKey;
75
+
76
+
77
+ /**
78
+ * The application secret
79
+ *
80
+ * @var string
81
+ */
82
+ private $applicationSecret;
83
+
84
+
85
+ /**
86
+ * The oAuth-token
87
+ *
88
+ * @var string
89
+ */
90
+ private $oAuthToken = '';
91
+
92
+
93
+ /**
94
+ * The oAuth-token-secret
95
+ *
96
+ * @var string
97
+ */
98
+ private $oAuthTokenSecret = '';
99
+
100
+
101
+ /**
102
+ * The timeout
103
+ *
104
+ * @var int
105
+ */
106
+ private $timeOut = 60;
107
+
108
+
109
+ /**
110
+ * The user agent
111
+ *
112
+ * @var string
113
+ */
114
+ private $userAgent;
115
+
116
+
117
+ // class methods
118
+ /**
119
+ * Default constructor
120
+ *
121
+ * @return void
122
+ * @param string $applicationKey The application key to use.
123
+ * @param string $applicationSecret The application secret to use.
124
+ */
125
+ public function __construct($applicationKey, $applicationSecret)
126
+ {
127
+ $this->setApplicationKey($applicationKey);
128
+ $this->setApplicationSecret($applicationSecret);
129
+ }
130
+
131
+
132
+ /**
133
+ * Default destructor
134
+ *
135
+ * @return void
136
+ */
137
+ public function __destruct()
138
+ {
139
+ if($this->curl != null) curl_close($this->curl);
140
+ }
141
+
142
+
143
+ /**
144
+ * Format the parameters as a querystring
145
+ *
146
+ * @return string
147
+ * @param array $parameters The parameters to pass.
148
+ */
149
+ private function buildQuery(array $parameters)
150
+ {
151
+ // no parameters?
152
+ if(empty($parameters)) return '';
153
+
154
+ // encode the keys
155
+ $keys = self::urlencode_rfc3986(array_keys($parameters));
156
+
157
+ // encode the values
158
+ $values = self::urlencode_rfc3986(array_values($parameters));
159
+
160
+ // reset the parameters
161
+ $parameters = array_combine($keys, $values);
162
+
163
+ // sort parameters by key
164
+ uksort($parameters, 'strcmp');
165
+
166
+ // loop parameters
167
+ foreach($parameters as $key => $value)
168
+ {
169
+ // sort by value
170
+ if(is_array($value)) $parameters[$key] = natsort($value);
171
+ }
172
+
173
+ // process parameters
174
+ foreach($parameters as $key => $value) $chunks[] = $key . '=' . str_replace('%25', '%', $value);
175
+
176
+ // return
177
+ return implode('&', $chunks);
178
+ }
179
+
180
+
181
+ /**
182
+ * All OAuth 1.0 requests use the same basic algorithm for creating a signature base string and a signature.
183
+ * The signature base string is composed of the HTTP method being used, followed by an ampersand ("&") and then the URL-encoded base URL being accessed,
184
+ * complete with path (but not query parameters), followed by an ampersand ("&").
185
+ * Then, you take all query parameters and POST body parameters (when the POST body is of the URL-encoded type, otherwise the POST body is ignored),
186
+ * including the OAuth parameters necessary for negotiation with the request at hand, and sort them in lexicographical order by first parameter name and
187
+ * then parameter value (for duplicate parameters), all the while ensuring that both the key and the value for each parameter are URL encoded in isolation.
188
+ * Instead of using the equals ("=") sign to mark the key/value relationship, you use the URL-encoded form of "%3D". Each parameter is then joined by the
189
+ * URL-escaped ampersand sign, "%26".
190
+ *
191
+ * @return string
192
+ * @param string $url The url to use.
193
+ * @param string $method The method that will be called.
194
+ * @param array $parameters The parameters to pass.
195
+ */
196
+ private function calculateBaseString($url, $method, array $parameters)
197
+ {
198
+ // redefine
199
+ $url = (string) $url;
200
+ $parameters = (array) $parameters;
201
+
202
+ // init var
203
+ $pairs = array();
204
+ $chunks = array();
205
+
206
+ // sort parameters by key
207
+ uksort($parameters, 'strcmp');
208
+
209
+ // loop parameters
210
+ foreach($parameters as $key => $value)
211
+ {
212
+ // sort by value
213
+ if(is_array($value)) $parameters[$key] = natsort($value);
214
+ }
215
+
216
+ // process queries
217
+ foreach($parameters as $key => $value)
218
+ {
219
+ // only add if not already in the url
220
+ if(substr_count($url, $key . '=' . $value) == 0) $chunks[] = self::urlencode_rfc3986($key) . '%3D' . self::urlencode_rfc3986($value);
221
+ }
222
+
223
+ $urlChunks = explode('/', $url);
224
+ $i = 0;
225
+
226
+ foreach($urlChunks as &$chunk)
227
+ {
228
+ if($i > 4) $chunk = self::urlencode_rfc3986($chunk);
229
+ else $chunk = urlencode($chunk);
230
+
231
+ $i++;
232
+
233
+ }
234
+
235
+ // build base
236
+ $base = $method . '&';
237
+ $base .= implode('%2F', $urlChunks);
238
+ $base .= (substr_count($url, '?')) ? '%26' : '&';
239
+ $base .= implode('%26', $chunks);
240
+ $base = str_replace(array('%3F', '%20'), array('&', '%2520'), $base);
241
+
242
+ // return
243
+ return $base;
244
+ }
245
+
246
+
247
+ /**
248
+ * Build the Authorization header
249
+ * @later: fix me
250
+ *
251
+ * @return string
252
+ * @param array $parameters The parameters to pass.
253
+ * @param string $url The url to use.
254
+ */
255
+ private function calculateHeader(array $parameters, $url)
256
+ {
257
+ // redefine
258
+ $url = (string) $url;
259
+
260
+ // divide into parts
261
+ $parts = parse_url($url);
262
+
263
+ // init var
264
+ $chunks = array();
265
+
266
+ // process queries
267
+ foreach($parameters as $key => $value) $chunks[] = str_replace('%25', '%', self::urlencode_rfc3986($key) . '="' . self::urlencode_rfc3986($value) . '"');
268
+ $parts['path']=str_replace("%2F", "/", rawurlencode($parts['path']));
269
+ // build return
270
+ $return = 'Authorization: OAuth realm="' . $parts['scheme'] . '://' . $parts['host'] . $parts['path'] . '", ';
271
+ $return .= implode(',', $chunks);
272
+ // prepend name and OAuth part
273
+ return $return;
274
+ }
275
+
276
+
277
+ /**
278
+ * Make an call to the oAuth
279
+ * @todo refactor me
280
+ *
281
+ * @return array
282
+ * @param string $url The url that has to be called.
283
+ * @param array[optional] $parameters The parameters to pass.
284
+ * @param string[optional] $method Which HTTP-method should we use? Possible values are POST, GET.
285
+ * @param bool[optional] $expectJSON Do we expect JSON?
286
+ */
287
+ private function doOAuthCall($url, array $parameters = null, $method = 'POST', $expectJSON = true)
288
+ {
289
+ // redefine
290
+ $url = (string) $url;
291
+
292
+ // append default parameters
293
+ $parameters['oauth_consumer_key'] = $this->getApplicationKey();
294
+ $parameters['oauth_nonce'] = md5(microtime() . rand());
295
+ $parameters['oauth_timestamp'] = time();
296
+ $parameters['oauth_signature_method'] = 'HMAC-SHA1';
297
+ $parameters['oauth_version'] = '1.0';
298
+
299
+ // calculate the base string
300
+ $base = $this->calculateBaseString(self::API_URL . '/' . $url, 'POST', $parameters);
301
+
302
+ // add sign into the parameters
303
+ $parameters['oauth_signature'] = $this->hmacsha1($this->getApplicationSecret() . '&' . $this->getOAuthTokenSecret(), $base);
304
+
305
+ // calculate header
306
+ $header = $this->calculateHeader($parameters, self::API_URL . '/' . $url);
307
+
308
+ if($method == 'POST')
309
+ {
310
+ $options[CURLOPT_POST] = true;
311
+ $options[CURLOPT_POSTFIELDS] = $this->buildQuery($parameters);
312
+ }
313
+
314
+ else
315
+ {
316
+ // reset post
317
+ $options[CURLOPT_POST] = 0;
318
+ unset($options[CURLOPT_POSTFIELDS]);
319
+
320
+ // add the parameters into the querystring
321
+ if(!empty($parameters)) $url .= '?' . $this->buildQuery($parameters);
322
+ }
323
+
324
+ // set options
325
+ $options[CURLOPT_URL] = self::API_URL . '/' . $url;
326
+ $options[CURLOPT_PORT] = self::API_PORT;
327
+ $options[CURLOPT_USERAGENT] = $this->getUserAgent();
328
+ if(ini_get('open_basedir') == '' && ini_get('safe_mode' == 'Off')) $options[CURLOPT_FOLLOWLOCATION] = true;
329
+ $options[CURLOPT_RETURNTRANSFER] = true;
330
+ $options[CURLOPT_TIMEOUT] = (int) $this->getTimeOut();
331
+ $options[CURLOPT_SSL_VERIFYPEER] = false;
332
+ $options[CURLOPT_SSL_VERIFYHOST] = false;
333
+ $options[CURLOPT_HTTPHEADER] = array('Expect:');
334
+
335
+ // init
336
+ $this->curl = curl_init();
337
+
338
+ // set options
339
+ curl_setopt_array($this->curl, $options);
340
+
341
+ // execute
342
+ $response = curl_exec($this->curl);
343
+ $headers = curl_getinfo($this->curl);
344
+
345
+ // fetch errors
346
+ $errorNumber = curl_errno($this->curl);
347
+ $errorMessage = curl_error($this->curl);
348
+
349
+ // error?
350
+ if($errorNumber != '') throw new DropboxException($errorMessage, $errorNumber);
351
+
352
+ // return
353
+ if($expectJSON) return json_decode($response, true);
354
+
355
+ // fallback
356
+ return $response;
357
+ }
358
+
359
+
360
+ /**
361
+ * Make the call
362
+ *
363
+ * @return string
364
+ * @param string $url The url to call.
365
+ * @param array[optional] $parameters Optional parameters.
366
+ * @param bool[optional] $method The method to use. Possible values are GET, POST.
367
+ * @param string[optional] $filePath The path to the file to upload.
368
+ * @param bool[optional] $expectJSON Do we expect JSON?
369
+ * @param bool[optional] $isContent Is this content?
370
+ */
371
+ private function doCall($url, array $parameters = null, $method = 'GET', $filePath = null, $expectJSON = true, $isContent = false)
372
+ {
373
+ // allowed methods
374
+ $allowedMethods = array('GET', 'POST');
375
+
376
+ // redefine
377
+ $url = (string) $url;
378
+ $parameters = (array) $parameters;
379
+ $method = (string) $method;
380
+ $expectJSON = (bool) $expectJSON;
381
+
382
+ // validate method
383
+ if(!in_array($method, $allowedMethods)) throw new DropboxException('Unknown method (' . $method . '). Allowed methods are: ' . implode(', ', $allowedMethods));
384
+
385
+ // append default parameters
386
+ $oauth['oauth_consumer_key'] = $this->getApplicationKey();
387
+ $oauth['oauth_nonce'] = md5(microtime() . rand());
388
+ $oauth['oauth_timestamp'] = time();
389
+ $oauth['oauth_token'] = $this->getOAuthToken();
390
+ $oauth['oauth_signature_method'] = 'HMAC-SHA1';
391
+ $oauth['oauth_version'] = '1.0';
392
+
393
+ // set data
394
+ $data = $oauth;
395
+ if(!empty($parameters))
396
+ {
397
+ // convert to UTF-8
398
+ foreach($parameters as &$value) $value = utf8_encode($value);
399
+
400
+ // merge
401
+ $data = array_merge($data, $parameters);
402
+ }
403
+
404
+ if($filePath != null)
405
+ {
406
+ // process file
407
+ $fileInfo = pathinfo($filePath);
408
+
409
+ // add to the data
410
+ $data['file'] = $fileInfo['basename'];
411
+
412
+ }
413
+
414
+ // calculate the base string
415
+ if($isContent) $base = $this->calculateBaseString(self::API_CONTENT_URL . '/' . $url, $method, $data);
416
+ else $base = $this->calculateBaseString(self::API_URL . '/' . $url, $method, $data);
417
+
418
+ // based on the method, we should handle the parameters in a different way
419
+ if($method == 'POST')
420
+ {
421
+ // file provided?
422
+ if($filePath != null)
423
+ {
424
+ // build a boundary
425
+ $boundary = md5(time());
426
+
427
+ // init var
428
+ $content = '--' . $boundary . "\r\n";
429
+
430
+ // set file
431
+ $content .= 'Content-Disposition: form-data; name=file; filename="' . $fileInfo['basename'] . '"' . "\r\n";
432
+ $content .= 'Content-Type: application/octet-stream' . "\r\n";
433
+ $content .= "\r\n";
434
+ $content .= file_get_contents($filePath);
435
+ $content .= "\r\n";
436
+ $content .= "--" . $boundary . '--';
437
+
438
+ // build headers
439
+ $headers[] = 'Content-Type: multipart/form-data; boundary=' . $boundary;
440
+ $headers[] = 'Content-Length: ' . strlen($content);
441
+
442
+ // set content
443
+ $options[CURLOPT_POSTFIELDS] = $content;
444
+ }
445
+
446
+ // no file
447
+ else $options[CURLOPT_POSTFIELDS] = $this->buildQuery($parameters);
448
+
449
+ // enable post
450
+ $options[CURLOPT_POST] = 1;
451
+ }
452
+
453
+ else
454
+ {
455
+ // reset post
456
+ $options[CURLOPT_POST] = 0;
457
+ unset($options[CURLOPT_POSTFIELDS]);
458
+ $url=str_replace("%2F", "/", rawurlencode($url));
459
+
460
+ // add the parameters into the querystring
461
+ if(!empty($parameters)) $url .= '?' . $this->buildQuery($parameters);
462
+ }
463
+
464
+ // add sign into the parameters
465
+ $oauth['oauth_signature'] = $this->hmacsha1($this->getApplicationSecret() . '&' . $this->getOAuthTokenSecret(), $base);
466
+
467
+ if($isContent) $headers[] = $this->calculateHeader($oauth, self::API_CONTENT_URL . '/' . $url);
468
+ else $headers[] = $this->calculateHeader($oauth, self::API_URL . '/' . $url);
469
+ $headers[] = 'Expect:';
470
+
471
+ // set options
472
+ if($isContent) $options[CURLOPT_URL] = self::API_CONTENT_URL . '/' . $url;
473
+ else $options[CURLOPT_URL] = self::API_URL . '/' . $url;
474
+ $options[CURLOPT_PORT] = self::API_PORT;
475
+ $options[CURLOPT_USERAGENT] = $this->getUserAgent();
476
+ if(ini_get('open_basedir') == '' && ini_get('safe_mode' == 'Off')) $options[CURLOPT_FOLLOWLOCATION] = true;
477
+ $options[CURLOPT_RETURNTRANSFER] = true;
478
+ $options[CURLOPT_TIMEOUT] = (int) $this->getTimeOut();
479
+ $options[CURLOPT_SSL_VERIFYPEER] = false;
480
+ $options[CURLOPT_SSL_VERIFYHOST] = false;
481
+ $options[CURLOPT_HTTP_VERSION] = CURL_HTTP_VERSION_1_1;
482
+ $options[CURLOPT_HTTPHEADER] = $headers;
483
+ // init
484
+ if($this->curl == null) $this->curl = curl_init();
485
+
486
+ // set options
487
+ curl_setopt_array($this->curl, $options);
488
+
489
+ // execute
490
+ $response = curl_exec($this->curl);
491
+ $headers = curl_getinfo($this->curl);
492
+
493
+ // fetch errors
494
+ $errorNumber = curl_errno($this->curl);
495
+ $errorMessage = curl_error($this->curl);
496
+
497
+ if(!$expectJSON && $isContent)
498
+ {
499
+ // is it JSON?
500
+ $json = @json_decode($response, true);
501
+ if($json !== false && isset($json['error'])) throw new DropboxException($json['error']);
502
+
503
+ // set return
504
+ $return['content_type'] = $headers['content_type'];
505
+ $return['data'] = base64_encode($response);
506
+
507
+ // return
508
+ return $return;
509
+ }
510
+
511
+ // we don't expect JSON, return the response
512
+ if(!$expectJSON) return $response;
513
+
514
+ // replace ids with their string values, added because of some PHP-version can't handle these large values
515
+ $response = preg_replace('/id":(\d+)/', 'id":"\1"', $response);
516
+
517
+ // we expect JSON, so decode it
518
+ $json = @json_decode($response, true);
519
+
520
+ // validate JSON
521
+ if($json === null)
522
+ {
523
+ // should we provide debug information
524
+ if(self::DEBUG)
525
+ {
526
+ // make it output proper
527
+ echo '<pre>';
528
+
529
+ // dump the header-information
530
+ var_dump($headers);
531
+
532
+ // dump the error
533
+ var_dump($errorMessage);
534
+
535
+ // dump the raw response
536
+ var_dump($response);
537
+
538
+ // end proper format
539
+ echo '</pre>';
540
+ }
541
+
542
+ // throw exception
543
+ throw new DropboxException('Invalid response.');
544
+ }
545
+
546
+ // any error
547
+ if(isset($json['error']))
548
+ {
549
+ // should we provide debug information
550
+ if(self::DEBUG)
551
+ {
552
+ // make it output proper
553
+ echo '<pre>';
554
+
555
+ // dump the header-information
556
+ var_dump($headers);
557
+
558
+ // dump the raw response
559
+ var_dump($response);
560
+
561
+ // end proper format
562
+ echo '</pre>';
563
+ }
564
+
565
+ if(isset($json['error']) && is_string($json['error'])) $message = $json['error'];
566
+ elseif(isset($json['error']['hash']) && $json['error']['hash'] != '') $message = (string) $json['error']['hash'];
567
+ else $message = 'Invalid response.';
568
+
569
+ // throw exception
570
+ throw new DropboxException($message);
571
+ }
572
+
573
+ // return
574
+ return $json;
575
+ }
576
+
577
+
578
+ /**
579
+ * Get the application key
580
+ *
581
+ * @return string
582
+ */
583
+ private function getApplicationKey()
584
+ {
585
+ return $this->applicationKey;
586
+ }
587
+
588
+
589
+ /**
590
+ * Get the application secret
591
+ *
592
+ * @return string
593
+ */
594
+ private function getApplicationSecret()
595
+ {
596
+ return $this->applicationSecret;
597
+ }
598
+
599
+
600
+ /**
601
+ * Get the oAuth-token
602
+ *
603
+ * @return string
604
+ */
605
+ private function getOAuthToken()
606
+ {
607
+ return $this->oAuthToken;
608
+ }
609
+
610
+
611
+ /**
612
+ * Get the oAuth-token-secret
613
+ *
614
+ * @return string
615
+ */
616
+ private function getOAuthTokenSecret()
617
+ {
618
+ return $this->oAuthTokenSecret;
619
+ }
620
+
621
+
622
+ /**
623
+ * Get the timeout
624
+ *
625
+ * @return int
626
+ */
627
+ public function getTimeOut()
628
+ {
629
+ return (int) $this->timeOut;
630
+ }
631
+
632
+
633
+ /**
634
+ * Get the useragent that will be used. Our version will be prepended to yours.
635
+ * It will look like: "PHP Dropbox/<version> <your-user-agent>"
636
+ *
637
+ * @return string
638
+ */
639
+ public function getUserAgent()
640
+ {
641
+ return (string) 'PHP Dropbox/' . self::VERSION . ' ' . $this->userAgent;
642
+ }
643
+
644
+
645
+ /**
646
+ * Set the application key
647
+ *
648
+ * @return void
649
+ * @param string $key The application key to use.
650
+ */
651
+ private function setApplicationKey($key)
652
+ {
653
+ $this->applicationKey = (string) $key;
654
+ }
655
+
656
+
657
+ /**
658
+ * Set the application secret
659
+ *
660
+ * @return void
661
+ * @param string $secret The application secret to use.
662
+ */
663
+ private function setApplicationSecret($secret)
664
+ {
665
+ $this->applicationSecret = (string) $secret;
666
+ }
667
+
668
+
669
+ /**
670
+ * Set the oAuth-token
671
+ *
672
+ * @return void
673
+ * @param string $token The token to use.
674
+ */
675
+ public function setOAuthToken($token)
676
+ {
677
+ $this->oAuthToken = (string) $token;
678
+ }
679
+
680
+
681
+ /**
682
+ * Set the oAuth-secret
683
+ *
684
+ * @return void
685
+ * @param string $secret The secret to use.
686
+ */
687
+ public function setOAuthTokenSecret($secret)
688
+ {
689
+ $this->oAuthTokenSecret = (string) $secret;
690
+ }
691
+
692
+
693
+ /**
694
+ * Set the timeout
695
+ *
696
+ * @return void
697
+ * @param int $seconds The timeout in seconds.
698
+ */
699
+ public function setTimeOut($seconds)
700
+ {
701
+ $this->timeOut = (int) $seconds;
702
+ }
703
+
704
+
705
+ /**
706
+ * Get the useragent that will be used. Our version will be prepended to yours.
707
+ * It will look like: "PHP Dropbox/<version> <your-user-agent>"
708
+ *
709
+ * @return void
710
+ * @param string $userAgent Your user-agent, it should look like <app-name>/<app-version>.
711
+ */
712
+ public function setUserAgent($userAgent)
713
+ {
714
+ $this->userAgent = (string) $userAgent;
715
+ }
716
+
717
+
718
+ /**
719
+ * Build the signature for the data
720
+ *
721
+ * @return string
722
+ * @param string $key The key to use for signing.
723
+ * @param string $data The data that has to be signed.
724
+ */
725
+ private function hmacsha1($key, $data)
726
+ {
727
+ return base64_encode(hash_hmac('SHA1', $data, $key, true));
728
+ }
729
+
730
+
731
+ /**
732
+ * URL-encode method for internatl use
733
+ *
734
+ * @return string
735
+ * @param mixed $value The value to encode.
736
+ */
737
+ private static function urlencode_rfc3986($value)
738
+ {
739
+ if(is_array($value)) return array_map(array('Dropbox', 'urlencode_rfc3986'), $value);
740
+ else
741
+ {
742
+ $search = array('+', ' ', '%7E', '%');
743
+ $replace = array('%20', '%20', '~', '%25');
744
+
745
+ return str_replace($search, $replace, rawurlencode($value));
746
+ }
747
+ }
748
+
749
+
750
+ // oauth resources
751
+ /**
752
+ * Call for obtaining an OAuth request token.
753
+ * Returns a request token and the corresponding request token secret. This token and secret cannot be used to sign requests for the /metadata and /file content API calls.
754
+ * Their only purpose is for signing a request to oauth/access_token once the user has gone through the application authorization steps provided by oauth/authorize.
755
+ *
756
+ * @return array
757
+ */
758
+ public function oAuthRequestToken()
759
+ {
760
+ // make the call
761
+ $response = $this->doOAuthCall('1/oauth/request_token', null, 'POST', false);
762
+
763
+ // process response
764
+ $response = (array) explode('&', $response);
765
+ $return = array();
766
+
767
+ // loop chunks
768
+ foreach($response as $chunk)
769
+ {
770
+ // split again
771
+ $chunks = explode('=', $chunk, 2);
772
+
773
+ // store return
774
+ if(count($chunks) == 2) $return[$chunks[0]] = $chunks[1];
775
+ }
776
+
777
+ // return
778
+ return $return;
779
+ }
780
+
781
+
782
+ /**
783
+ * Redirect the user to the oauth/authorize location so that Dropbox can authenticate the user and ask whether or not the user wants to authorize the application to access
784
+ * file metadata and content on its behalf. oauth/authorize is not an API call per se, because it does not have a return value, but rather directs the user to a page on
785
+ * api.dropbox.com where they are provided means to log in to Dropbox and grant authority to the application requesting it.
786
+ * The page served by oauth/authorize should be presented to the user through their web browser.
787
+ * Please note, without directing the user to a Dropbox-provided page via oauth/authorize, it is impossible for your application to use the request token it received
788
+ * via oauth/request_token to obtain an access token from oauth/access_token.
789
+ *
790
+ * @return void
791
+ * @param string $oauthToken The request token of the application requesting authority from a user.
792
+ * @param string[optional] $oauthCallback After the user authorizes an application, the user is redirected to the application-served URL provided by this parameter.
793
+ */
794
+ public function oAuthAuthorize($oauthToken, $oauthCallback = null)
795
+ {
796
+ // build parameters
797
+ $parameters = array();
798
+ $parameters['oauth_token'] = (string) $oauthToken;
799
+ if($oauthCallback !== null) $parameters['oauth_callback'] = (string) $oauthCallback;
800
+
801
+ // build url
802
+ $url = self::API_AUTH_URL . '/1/oauth/authorize?' . http_build_query($parameters);
803
+
804
+ // redirect
805
+ header('Location: ' . $url);
806
+ exit;
807
+ }
808
+
809
+ public function mwp_oAuthAuthorize($oauthToken, $oauthCallback = null)
810
+ {
811
+ // build parameters
812
+ $parameters = array();
813
+ $parameters['oauth_token'] = (string) $oauthToken;
814
+ if($oauthCallback !== null) $parameters['oauth_callback'] = (string) $oauthCallback;
815
+
816
+ // build url
817
+ $url = self::API_AUTH_URL . '/1/oauth/authorize?' . http_build_query($parameters);
818
+
819
+ return $url;
820
+ }
821
+
822
+ /**
823
+ * This call returns a access token and the corresponding access token secret.
824
+ * Upon return, the authorization process is now complete and the access token and corresponding secret are used to sign requests for the metadata and file content API calls.
825
+ *
826
+ * @return array
827
+ * @param string $oauthToken The token returned after authorizing.
828
+ */
829
+ public function oAuthAccessToken($oauthToken)
830
+ {
831
+ // build parameters
832
+ $parameters = array();
833
+ $parameters['oauth_token'] = (string) $oauthToken;
834
+
835
+ // make the call
836
+ $response = $this->doOAuthCall('1/oauth/access_token', $parameters, 'POST', false);
837
+
838
+ // process response
839
+ $response = (array) explode('&', $response);
840
+ $return = array();
841
+
842
+ // loop chunks
843
+ foreach($response as $chunk)
844
+ {
845
+ // split again
846
+ $chunks = explode('=', $chunk, 2);
847
+
848
+ // store return
849
+ if(count($chunks) == 2) $return[$chunks[0]] = $chunks[1];
850
+ }
851
+
852
+ // return
853
+ return $return;
854
+ }
855
+
856
+
857
+ // token resources
858
+ /**
859
+ * The token call provides a consumer/secret key pair you can use to consistently access the user's account.
860
+ * This is the preferred method of authentication over storing the username and password.
861
+ * Use the key pair as a signature with every subsequent call.
862
+ * The request must be signed using the application's developer and secret key token. Request or access tokens are necessary.
863
+ *
864
+ * Warning: DO NOT STORE THE USER'S PASSWORD! The way this call works is you call it once with the user's email and password and then
865
+ * keep the token around for later. You do NOT (I repeat NOT) call this before everything you do or on each program startup.
866
+ * We watch for this and will shut down your application with little notice if we catch you.
867
+ * In fact, the Objective-C code does this for you so you can't get it wrong.
868
+ *
869
+ * @return array Upon successful verification of the user's credentials, returns an array representation of the access token and secret.
870
+ * @param string $email The email account of the user.
871
+ * @param string $password The password of the user.
872
+ */
873
+ public function token($email, $password)
874
+ {
875
+ // build parameters
876
+ $parameters = array();
877
+ $parameters['email'] = (string) $email;
878
+ $parameters['password'] = (string) $password;
879
+
880
+ // make the call
881
+ $response = (array) $this->doOAuthCall('1/token', $parameters);
882
+
883
+ // validate and set
884
+ if(isset($response['token'])) $this->setOAuthToken($response['token']);
885
+ if(isset($response['secret'])) $this->setOAuthTokenSecret($response['secret']);
886
+
887
+ // return
888
+ return $response;
889
+ }
890
+
891
+
892
+ // account resources
893
+ /**
894
+ * Given a set of account information, the account call allows an application to create a new Dropbox user account.
895
+ * This is useful for situations where the trusted third party application is possibly the user's first interaction with Dropbox.
896
+ *
897
+ * @return bool
898
+ * @param string $email The email account of the user.
899
+ * @param string $password The password for the user.
900
+ * @param string $firstName The user's first name.
901
+ * @param string $lastName The user's last name.
902
+ */
903
+ public function account($email, $password, $firstName, $lastName)
904
+ {
905
+ // build parameters
906
+ $parameters['email'] = (string) $email;
907
+ $parameters['first_name'] = (string) $firstName;
908
+ $parameters['last_name'] = (string) $lastName;
909
+ $parameters['password'] = (string) $password;
910
+
911
+ return (bool) ($this->doCall('1/account', $parameters, 'POST', null, false) == 'OK');
912
+ }
913
+
914
+
915
+ /**
916
+ * Get the user account information.
917
+ *
918
+ * @return array
919
+ */
920
+ public function accountInfo()
921
+ {
922
+ // make the call
923
+ return (array) $this->doCall('1/account/info');
924
+ }
925
+
926
+
927
+ // files & metadata
928
+ /**
929
+ * Retrieves file contents relative to the user's Dropbox root or the application's directory within the user's Dropbox.
930
+ *
931
+ * @return string
932
+ * @param string $path Path of the directory wherin the file is located.
933
+ * @param bool[optional] $sandbox Sandbox mode?
934
+ */
935
+ public function filesGet($path, $sandbox = false)
936
+ {
937
+ // build url
938
+ $url = '1/files/';
939
+ $url .= ($sandbox) ? 'sandbox/' : 'dropbox/';
940
+ $url .= trim((string) $path, '/');
941
+
942
+ // make the call
943
+ return $this->doCall($url, null, 'GET', null, false, true);
944
+ }
945
+
946
+
947
+ /**
948
+ * Uploads file contents relative to the user's Dropbox root or the application's directory within the user's Dropbox.
949
+ *
950
+ * @return bool
951
+ * @param string $path Path of the directory wherin the file should be uploaded.
952
+ * @param string $localFile Path to the local file.
953
+ * @param bool[optional] $sandbox Sandbox mode?
954
+ */
955
+ public function filesPost($path, $localFile, $sandbox = false)
956
+ {
957
+ // build url
958
+ $url = '1/files/';
959
+ $url .= ($sandbox) ? 'sandbox/' : 'dropbox/';
960
+ $url .= trim((string) $path, '/');
961
+
962
+ // make the call
963
+ $return = $this->doCall($url, null, 'POST', $localFile, true, true);
964
+ // return the result
965
+ return (bool) (isset($return['size']) && $return['size'] == 'winner!');
966
+ }
967
+
968
+
969
+ /**
970
+ * Returns metadata for the file or directory at the given <path> location relative to the user's Dropbox or
971
+ * the user's application sandbox. If <path> represents a directory and the list parameter is true, the metadata will
972
+ * also include a listing of metadata for the directory's contents.
973
+ *
974
+ * @return array
975
+ * @param string[optional] $path The path to the file/director to get the metadata for.
976
+ * @param int[optional] $fileLimit When listing a directory, the service will not report listings containing more than $fileLimit files.
977
+ * @param bool[optional] $hash Listing return values include a hash representing the state of the directory's contents.
978
+ * @param bool[optional] $list If true, this call returns a list of metadata representations for the contents of the directory. If false, this call returns the metadata for the directory itself.
979
+ * @param bool[optional] $sandbox Sandbox mode?
980
+ */
981
+ public function metadata($path = '', $fileLimit = 10000, $hash = false, $list = true, $sandbox = false)
982
+ {
983
+ // build url
984
+ $url = '1/metadata/';
985
+ $url .= ($sandbox) ? 'sandbox/' : 'dropbox/';
986
+ $url .= trim((string) $path, '/');
987
+
988
+ // build parameters
989
+ $parameters = null;
990
+ $parameters['file_limit'] = (int) $fileLimit;
991
+ if((bool) $hash) $parameters['hash'] = '';
992
+ $parameters['list'] = ($list) ? 'true': 'false';
993
+
994
+ // make the call
995
+ return (array) $this->doCall($url, $parameters);
996
+ }
997
+
998
+
999
+ /**
1000
+ * Get a minimized thumbnail for a photo.
1001
+ *
1002
+ * @return string Will return a base64_encode string with the JPEG-data
1003
+ * @param string $path The path to the photo.
1004
+ * @param string[optional] $size The size, possible values are: 'small' (32x32), 'medium' (64x64), 'large' (128x128).
1005
+ */
1006
+ public function thumbnails($path, $size = 'small')
1007
+ {
1008
+ // build url
1009
+ $url = '1/thumbnails/dropbox/';
1010
+ $url .= trim((string) $path, '/');
1011
+
1012
+ // build parameters
1013
+ $parameters['size'] = (string) $size;
1014
+
1015
+ // make the call
1016
+ return $this->doCall($url, $parameters, 'GET', null, false, true);
1017
+ }
1018
+
1019
+
1020
+ // file operations
1021
+ /**
1022
+ * Copy a file or folder to a new location.
1023
+ *
1024
+ * @return array
1025
+ * @param string $fromPath fromPath specifies either a file or folder to be copied to the location specified by toPath. This path is interpreted relative to the location specified by root.
1026
+ * @param string $toPath toPath specifies the destination path including the new name for file or folder. This path is interpreted relative to the location specified by root.
1027
+ * @param bool[optional] $sandbox Sandbox mode?
1028
+ */
1029
+ public function fileopsCopy($fromPath, $toPath, $sandbox = false)
1030
+ {
1031
+ // build url
1032
+ $url = '1/fileops/copy';
1033
+
1034
+ // build parameters
1035
+ $parameters['from_path'] = (string) $fromPath;
1036
+ $parameters['to_path'] = (string) $toPath;
1037
+ $parameters['root'] = ($sandbox) ? 'sandbox' : 'dropbox';
1038
+
1039
+ // make the call
1040
+ return $this->doCall($url, $parameters, 'POST');
1041
+ }
1042
+
1043
+
1044
+ /**
1045
+ * Create a folder relative to the user's Dropbox root or the user's application sandbox folder.
1046
+ *
1047
+ * @return array
1048
+ * @param string $path The path to the new folder to create, relative to root.
1049
+ * @param bool[optional] $sandbox Sandbox mode?
1050
+ */
1051
+ public function fileopsCreateFolder($path, $sandbox = false)
1052
+ {
1053
+ // build url
1054
+ $url = '1/fileops/create_folder';
1055
+
1056
+ // build parameters
1057
+ $parameters['path'] = trim((string) $path, '/');
1058
+ $parameters['root'] = ($sandbox) ? 'sandbox' : 'dropbox';
1059
+
1060
+ // make the call
1061
+ return $this->doCall($url, $parameters, 'POST');
1062
+ }
1063
+
1064
+
1065
+ /**
1066
+ * Deletes a file or folder.
1067
+ *
1068
+ * @return array
1069
+ * @param string $path path specifies either a file or folder to be deleted. This path is interpreted relative to the location specified by root.
1070
+ * @param bool[optional] $sandbox Sandbox mode?
1071
+ */
1072
+ public function fileopsDelete($path, $sandbox = false)
1073
+ {
1074
+ // build url
1075
+ $url = '1/fileops/delete';
1076
+
1077
+ // build parameters
1078
+ $parameters['path'] = trim((string) $path, '/');
1079
+ $parameters['root'] = ($sandbox) ? 'sandbox' : 'dropbox';
1080
+ // make the call
1081
+ return $this->doCall($url, $parameters, 'POST');
1082
+ }
1083
+
1084
+
1085
+ /**
1086
+ * Move a file or folder to a new location.
1087
+ *
1088
+ * @return array
1089
+ * @param string $fromPath fromPath specifies either a file or folder to be copied to the location specified by toPath. This path is interpreted relative to the location specified by root.
1090
+ * @param string $toPath toPath specifies the destination path including the new name for file or folder. This path is interpreted relative to the location specified by root.
1091
+ * @param bool[optional] $sandbox Sandbox mode?
1092
+ */
1093
+ public function fileopsMove($fromPath, $toPath, $sandbox = false)
1094
+ {
1095
+ // build url
1096
+ $url = '1/fileops/move';
1097
+
1098
+ // build parameters
1099
+ $parameters['from_path'] = (string) $fromPath;
1100
+ $parameters['to_path'] = (string) $toPath;
1101
+ $parameters['root'] = ($sandbox) ? 'sandbox' : 'dropbox';
1102
+
1103
+ // make the call
1104
+ return $this->doCall($url, $parameters, 'POST');
1105
+ }
1106
+
1107
+ function _log($mixed)
1108
+ {
1109
+ if (is_array($mixed)) {
1110
+ $mixed = print_r($mixed, 1);
1111
+ } else if (is_object($mixed)) {
1112
+ ob_start();
1113
+ var_dump($mixed);
1114
+ $mixed = ob_get_clean();
1115
+ }
1116
+
1117
+ $handle = fopen(dirname(__FILE__) . '/log', 'a');
1118
+ fwrite($handle, $mixed . PHP_EOL);
1119
+ fclose($handle);
1120
+ }
1121
+ }
1122
+
1123
+
1124
+ /**
1125
+ * Dropbox Exception class
1126
+ *
1127
+ * @author Tijs Verkoyen <php-dropbox@verkoyen.eu>
1128
+ */
1129
+ class DropboxException extends Exception
1130
+ {
1131
+ }
1132
+
1133
+ ?>
lib/dropbox.php CHANGED
@@ -1,144 +1,144 @@
1
- <?php
2
- /**
3
- * Dropbox Uploader
4
- *
5
- * Copyright (c) 2009 Jaka Jancar
6
- *
7
- * Permission is hereby granted, free of charge, to any person obtaining a copy
8
- * of this software and associated documentation files (the "Software"), to deal
9
- * in the Software without restriction, including without limitation the rights
10
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
- * copies of the Software, and to permit persons to whom the Software is
12
- * furnished to do so, subject to the following conditions:
13
- *
14
- * The above copyright notice and this permission notice shall be included in
15
- * all copies or substantial portions of the Software.
16
- *
17
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23
- * THE SOFTWARE.
24
- *
25
- * @author Jaka Jancar [jaka@kubje.org] [http://jaka.kubje.org/]
26
- * @version 1.1.5
27
- */
28
- class DropboxUploader {
29
- protected $email;
30
- protected $password;
31
- protected $caCertSourceType = self::CACERT_SOURCE_SYSTEM;
32
- const CACERT_SOURCE_SYSTEM = 0;
33
- const CACERT_SOURCE_FILE = 1;
34
- const CACERT_SOURCE_DIR = 2;
35
- protected $caCertSource;
36
- protected $loggedIn = false;
37
- protected $cookies = array();
38
-
39
- /**
40
- * Constructor
41
- *
42
- * @param string $email
43
- * @param string|null $password
44
- */
45
- public function __construct($email, $password) {
46
- // Check requirements
47
- if (!extension_loaded('curl'))
48
- throw new Exception('DropboxUploader requires the cURL extension.');
49
-
50
- $this->email = $email;
51
- $this->password = $password;
52
- }
53
-
54
- public function setCaCertificateFile($file)
55
- {
56
- $this->caCertSourceType = self::CACERT_SOURCE_FILE;
57
- $this->caCertSource = $file;
58
- }
59
-
60
- public function setCaCertificateDir($dir)
61
- {
62
- $this->caCertSourceType = self::CACERT_SOURCE_DIR;
63
- $this->caCertSource = $dir;
64
- }
65
-
66
- public function upload($filename, $remoteDir='/') {
67
- if (!file_exists($filename) or !is_file($filename) or !is_readable($filename))
68
- throw new Exception("File '$filename' does not exist or is not readable.");
69
-
70
- if (!is_string($remoteDir))
71
- throw new Exception("Remote directory must be a string, is ".gettype($remoteDir)." instead.");
72
-
73
- if (!$this->loggedIn)
74
- $this->login();
75
-
76
- $data = $this->request('https://www.dropbox.com/home');
77
- $token = $this->extractToken($data, 'https://dl-web.dropbox.com/upload');
78
-
79
- $data = $this->request('https://dl-web.dropbox.com/upload', true, array('plain'=>'yes', 'file'=>'@'.$filename, 'dest'=>$remoteDir, 't'=>$token));
80
- if (strpos($data, 'HTTP/1.1 302 FOUND') === false)
81
- throw new Exception('Upload failed!');
82
- }
83
-
84
- protected function login() {
85
- $data = $this->request('https://www.dropbox.com/login');
86
- $token = $this->extractToken($data, '/login');
87
-
88
- $data = $this->request('https://www.dropbox.com/login', true, array('login_email'=>$this->email, 'login_password'=>$this->password, 't'=>$token));
89
-
90
- if (stripos($data, 'location: /home') === false)
91
- throw new Exception('Login unsuccessful.');
92
-
93
- $this->loggedIn = true;
94
- }
95
-
96
- protected function request($url, $post=false, $postData=array()) {
97
- $ch = curl_init();
98
- curl_setopt($ch, CURLOPT_URL, $url);
99
- curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
100
- curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
101
- switch ($this->caCertSourceType) {
102
- case self::CACERT_SOURCE_FILE:
103
- curl_setopt($ch, CURLOPT_CAINFO, $this->caCertSource);
104
- break;
105
- case self::CACERT_SOURCE_DIR:
106
- curl_setopt($ch, CURLOPT_CAPATH, $this->caCertSource);
107
- break;
108
- }
109
- curl_setopt($ch, CURLOPT_HEADER, 1);
110
- curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
111
- if ($post) {
112
- curl_setopt($ch, CURLOPT_POST, $post);
113
- curl_setopt($ch, CURLOPT_POSTFIELDS, array_map('stripcslashes', $postData));
114
- }
115
-
116
- // Send cookies
117
- $rawCookies = array();
118
- foreach ($this->cookies as $k=>$v)
119
- $rawCookies[] = "$k=$v";
120
- $rawCookies = implode(';', $rawCookies);
121
- curl_setopt($ch, CURLOPT_COOKIE, $rawCookies);
122
-
123
- $data = curl_exec($ch);
124
-
125
- if ($data === false)
126
- throw new Exception('Cannot execute request: '.curl_error($ch));
127
-
128
- // Store received cookies
129
- preg_match_all('/Set-Cookie: ([^=]+)=(.*?);/i', $data, $matches, PREG_SET_ORDER);
130
- foreach ($matches as $match)
131
- $this->cookies[$match[1]] = $match[2];
132
-
133
- curl_close($ch);
134
-
135
- return $data;
136
- }
137
-
138
- protected function extractToken($html, $formAction) {
139
- if (!preg_match('/<form [^>]*'.preg_quote($formAction, '/').'[^>]*>.*?(<input [^>]*name="t" [^>]*value="(.*?)"[^>]*>).*?<\/form>/is', $html, $matches) || !isset($matches[2]))
140
- throw new Exception("Cannot extract token! (form action=$formAction)");
141
- return $matches[2];
142
- }
143
-
144
- }
1
+ <?php
2
+ /**
3
+ * Dropbox Uploader
4
+ *
5
+ * Copyright (c) 2009 Jaka Jancar
6
+ *
7
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ * of this software and associated documentation files (the "Software"), to deal
9
+ * in the Software without restriction, including without limitation the rights
10
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ * copies of the Software, and to permit persons to whom the Software is
12
+ * furnished to do so, subject to the following conditions:
13
+ *
14
+ * The above copyright notice and this permission notice shall be included in
15
+ * all copies or substantial portions of the Software.
16
+ *
17
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23
+ * THE SOFTWARE.
24
+ *
25
+ * @author Jaka Jancar [jaka@kubje.org] [http://jaka.kubje.org/]
26
+ * @version 1.1.5
27
+ */
28
+ class DropboxUploader {
29
+ protected $email;
30
+ protected $password;
31
+ protected $caCertSourceType = self::CACERT_SOURCE_SYSTEM;
32
+ const CACERT_SOURCE_SYSTEM = 0;
33
+ const CACERT_SOURCE_FILE = 1;
34
+ const CACERT_SOURCE_DIR = 2;
35
+ protected $caCertSource;
36
+ protected $loggedIn = false;
37
+ protected $cookies = array();
38
+
39
+ /**
40
+ * Constructor
41
+ *
42
+ * @param string $email
43
+ * @param string|null $password
44
+ */
45
+ public function __construct($email, $password) {
46
+ // Check requirements
47
+ if (!extension_loaded('curl'))
48
+ throw new Exception('DropboxUploader requires the cURL extension.');
49
+
50
+ $this->email = $email;
51
+ $this->password = $password;
52
+ }
53
+
54
+ public function setCaCertificateFile($file)
55
+ {
56
+ $this->caCertSourceType = self::CACERT_SOURCE_FILE;
57
+ $this->caCertSource = $file;
58
+ }
59
+
60
+ public function setCaCertificateDir($dir)
61
+ {
62
+ $this->caCertSourceType = self::CACERT_SOURCE_DIR;
63
+ $this->caCertSource = $dir;
64
+ }
65
+
66
+ public function upload($filename, $remoteDir='/') {
67
+ if (!file_exists($filename) or !is_file($filename) or !is_readable($filename))
68
+ throw new Exception("File '$filename' does not exist or is not readable.");
69
+
70
+ if (!is_string($remoteDir))
71
+ throw new Exception("Remote directory must be a string, is ".gettype($remoteDir)." instead.");
72
+
73
+ if (!$this->loggedIn)
74
+ $this->login();
75
+
76
+ $data = $this->request('https://www.dropbox.com/home');
77
+ $token = $this->extractToken($data, 'https://dl-web.dropbox.com/upload');
78
+
79
+ $data = $this->request('https://dl-web.dropbox.com/upload', true, array('plain'=>'yes', 'file'=>'@'.$filename, 'dest'=>$remoteDir, 't'=>$token));
80
+ if (strpos($data, 'HTTP/1.1 302 FOUND') === false)
81
+ throw new Exception('Upload failed!');
82
+ }
83
+
84
+ protected function login() {
85
+ $data = $this->request('https://www.dropbox.com/login');
86
+ $token = $this->extractToken($data, '/login');
87
+
88
+ $data = $this->request('https://www.dropbox.com/login', true, array('login_email'=>$this->email, 'login_password'=>$this->password, 't'=>$token));
89
+
90
+ if (stripos($data, 'location: /home') === false)
91
+ throw new Exception('Login unsuccessful.');
92
+
93
+ $this->loggedIn = true;
94
+ }
95
+
96
+ protected function request($url, $post=false, $postData=array()) {
97
+ $ch = curl_init();
98
+ curl_setopt($ch, CURLOPT_URL, $url);
99
+ curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
100
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
101
+ switch ($this->caCertSourceType) {
102
+ case self::CACERT_SOURCE_FILE:
103
+ curl_setopt($ch, CURLOPT_CAINFO, $this->caCertSource);
104
+ break;
105
+ case self::CACERT_SOURCE_DIR:
106
+ curl_setopt($ch, CURLOPT_CAPATH, $this->caCertSource);
107
+ break;
108
+ }
109
+ curl_setopt($ch, CURLOPT_HEADER, 1);
110
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
111
+ if ($post) {
112
+ curl_setopt($ch, CURLOPT_POST, $post);
113
+ curl_setopt($ch, CURLOPT_POSTFIELDS, array_map('stripcslashes', $postData));
114
+ }
115
+
116
+ // Send cookies
117
+ $rawCookies = array();
118
+ foreach ($this->cookies as $k=>$v)
119
+ $rawCookies[] = "$k=$v";
120
+ $rawCookies = implode(';', $rawCookies);
121
+ curl_setopt($ch, CURLOPT_COOKIE, $rawCookies);
122
+
123
+ $data = curl_exec($ch);
124
+
125
+ if ($data === false)
126
+ throw new Exception('Cannot execute request: '.curl_error($ch));
127
+
128
+ // Store received cookies
129
+ preg_match_all('/Set-Cookie: ([^=]+)=(.*?);/i', $data, $matches, PREG_SET_ORDER);
130
+ foreach ($matches as $match)
131
+ $this->cookies[$match[1]] = $match[2];
132
+
133
+ curl_close($ch);
134
+
135
+ return $data;
136
+ }
137
+
138
+ protected function extractToken($html, $formAction) {
139
+ if (!preg_match('/<form [^>]*'.preg_quote($formAction, '/').'[^>]*>.*?(<input [^>]*name="t" [^>]*value="(.*?)"[^>]*>).*?<\/form>/is', $html, $matches) || !isset($matches[2]))
140
+ throw new Exception("Cannot extract token! (form action=$formAction)");
141
+ return $matches[2];
142
+ }
143
+
144
+ }
lib/s3.php CHANGED
@@ -1,1965 +1,1966 @@
1
- <?php
2
- /**
3
- * $Id$
4
- *
5
- * Copyright (c) 2011, Donovan Schönknecht. All rights reserved.
6
- *
7
- * Redistribution and use in source and binary forms, with or without
8
- * modification, are permitted provided that the following conditions are met:
9
- *
10
- * - Redistributions of source code must retain the above copyright notice,
11
- * this list of conditions and the following disclaimer.
12
- * - Redistributions in binary form must reproduce the above copyright
13
- * notice, this list of conditions and the following disclaimer in the
14
- * documentation and/or other materials provided with the distribution.
15
- *
16
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
20
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26
- * POSSIBILITY OF SUCH DAMAGE.
27
- *
28
- * Amazon S3 is a trademark of Amazon.com, Inc. or its affiliates.
29
- */
30
-
31
- /**
32
- * Amazon S3 PHP class
33
- *
34
- * @link http://undesigned.org.za/2007/10/22/amazon-s3-php-class
35
- * @version 0.5.0-dev
36
- */
37
- class S3
38
- {
39
- // ACL flags
40
- const ACL_PRIVATE = 'private';
41
- const ACL_PUBLIC_READ = 'public-read';
42
- const ACL_PUBLIC_READ_WRITE = 'public-read-write';
43
- const ACL_AUTHENTICATED_READ = 'authenticated-read';
44
-
45
- const STORAGE_CLASS_STANDARD = 'STANDARD';
46
- const STORAGE_CLASS_RRS = 'REDUCED_REDUNDANCY';
47
-
48
- private static $__accessKey = null; // AWS Access key
49
- private static $__secretKey = null; // AWS Secret key
50
- private static $__sslKey = null;
51
-
52
- public static $endpoint = 's3.amazonaws.com';
53
- public static $proxy = null;
54
-
55
- public static $useSSL = false;
56
- public static $useSSLValidation = true;
57
- public static $useExceptions = false;
58
-
59
- // SSL CURL SSL options - only needed if you are experiencing problems with your OpenSSL configuration
60
- public static $sslKey = null;
61
- public static $sslCert = null;
62
- public static $sslCACert = null;
63
-
64
- private static $__signingKeyPairId = null; // AWS Key Pair ID
65
- private static $__signingKeyResource = false; // Key resource, freeSigningKey() must be called to clear it from memory
66
-
67
-
68
- /**
69
- * Constructor - if you're not using the class statically
70
- *
71
- * @param string $accessKey Access key
72
- * @param string $secretKey Secret key
73
- * @param boolean $useSSL Enable SSL
74
- * @return void
75
- */
76
- public function __construct($accessKey = null, $secretKey = null, $useSSL = false, $endpoint = 's3.amazonaws.com')
77
- {
78
- if ($accessKey !== null && $secretKey !== null)
79
- self::setAuth($accessKey, $secretKey);
80
- self::$useSSL = $useSSL;
81
- self::$endpoint = $endpoint;
82
- }
83
-
84
-
85
- /**
86
- * Set the sertvice endpoint
87
- *
88
- * @param string $host Hostname
89
- * @return void
90
- */
91
- public function setEndpoint($host)
92
- {
93
- self::$endpoint = $host;
94
- }
95
-
96
- /**
97
- * Set AWS access key and secret key
98
- *
99
- * @param string $accessKey Access key
100
- * @param string $secretKey Secret key
101
- * @return void
102
- */
103
- public static function setAuth($accessKey, $secretKey)
104
- {
105
- self::$__accessKey = $accessKey;
106
- self::$__secretKey = $secretKey;
107
- }
108
-
109
-
110
- /**
111
- * Check if AWS keys have been set
112
- *
113
- * @return boolean
114
- */
115
- public static function hasAuth() {
116
- return (self::$__accessKey !== null && self::$__secretKey !== null);
117
- }
118
-
119
-
120
- /**
121
- * Set SSL on or off
122
- *
123
- * @param boolean $enabled SSL enabled
124
- * @param boolean $validate SSL certificate validation
125
- * @return void
126
- */
127
- public static function setSSL($enabled, $validate = true)
128
- {
129
- self::$useSSL = $enabled;
130
- self::$useSSLValidation = $validate;
131
- }
132
-
133
-
134
- /**
135
- * Set SSL client certificates (experimental)
136
- *
137
- * @param string $sslCert SSL client certificate
138
- * @param string $sslKey SSL client key
139
- * @param string $sslCACert SSL CA cert (only required if you are having problems with your system CA cert)
140
- * @return void
141
- */
142
- public static function setSSLAuth($sslCert = null, $sslKey = null, $sslCACert = null)
143
- {
144
- self::$sslCert = $sslCert;
145
- self::$sslKey = $sslKey;
146
- self::$sslCACert = $sslCACert;
147
- }
148
-
149
-
150
- /**
151
- * Set proxy information
152
- *
153
- * @param string $host Proxy hostname and port (localhost:1234)
154
- * @param string $user Proxy username
155
- * @param string $pass Proxy password
156
- * @param constant $type CURL proxy type
157
- * @return void
158
- */
159
- public static function setProxy($host, $user = null, $pass = null, $type = CURLPROXY_SOCKS5)
160
- {
161
- self::$proxy = array('host' => $host, 'type' => $type, 'user' => null, 'pass' => 'null');
162
- }
163
-
164
-
165
- /**
166
- * Set the error mode to exceptions
167
- *
168
- * @param boolean $enabled Enable exceptions
169
- * @return void
170
- */
171
- public static function setExceptions($enabled = true)
172
- {
173
- self::$useExceptions = $enabled;
174
- }
175
-
176
-
177
- /**
178
- * Set signing key
179
- *
180
- * @param string $keyPairId AWS Key Pair ID
181
- * @param string $signingKey Private Key
182
- * @param boolean $isFile Load private key from file, set to false to load string
183
- * @return boolean
184
- */
185
- public static function setSigningKey($keyPairId, $signingKey, $isFile = true)
186
- {
187
- self::$__signingKeyPairId = $keyPairId;
188
- if ((self::$__signingKeyResource = openssl_pkey_get_private($isFile ?
189
- file_get_contents($signingKey) : $signingKey)) !== false) return true;
190
- self::__triggerError('S3::setSigningKey(): Unable to open load private key: '.$signingKey, __FILE__, __LINE__);
191
- return false;
192
- }
193
-
194
-
195
- /**
196
- * Free signing key from memory, MUST be called if you are using setSigningKey()
197
- *
198
- * @return void
199
- */
200
- public static function freeSigningKey()
201
- {
202
- if (self::$__signingKeyResource !== false)
203
- openssl_free_key(self::$__signingKeyResource);
204
- }
205
-
206
-
207
- /**
208
- * Internal error handler
209
- *
210
- * @internal Internal error handler
211
- * @param string $message Error message
212
- * @param string $file Filename
213
- * @param integer $line Line number
214
- * @param integer $code Error code
215
- * @return void
216
- */
217
- private static function __triggerError($message, $file, $line, $code = 0)
218
- {
219
- if (self::$useExceptions)
220
- throw new S3Exception($message, $file, $line, $code);
221
- else
222
- trigger_error($message, E_USER_WARNING);
223
- }
224
-
225
-
226
- /**
227
- * Get a list of buckets
228
- *
229
- * @param boolean $detailed Returns detailed bucket list when true
230
- * @return array | false
231
- */
232
- public static function listBuckets($detailed = false)
233
- {
234
- $rest = new S3Request('GET', '', '', self::$endpoint);
235
- $rest = $rest->getResponse();
236
- if ($rest->error === false && $rest->code !== 200)
237
- $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
238
- if ($rest->error !== false)
239
- {
240
- self::__triggerError(sprintf("S3::listBuckets(): [%s] %s", $rest->error['code'],
241
- $rest->error['message']), __FILE__, __LINE__);
242
- return false;
243
- }
244
- $results = array();
245
- if (!isset($rest->body->Buckets)) return $results;
246
-
247
- if ($detailed)
248
- {
249
- if (isset($rest->body->Owner, $rest->body->Owner->ID, $rest->body->Owner->DisplayName))
250
- $results['owner'] = array(
251
- 'id' => (string)$rest->body->Owner->ID, 'name' => (string)$rest->body->Owner->ID
252
- );
253
- $results['buckets'] = array();
254
- foreach ($rest->body->Buckets->Bucket as $b)
255
- $results['buckets'][] = array(
256
- 'name' => (string)$b->Name, 'time' => strtotime((string)$b->CreationDate)
257
- );
258
- } else
259
- foreach ($rest->body->Buckets->Bucket as $b) $results[] = (string)$b->Name;
260
-
261
- return $results;
262
- }
263
-
264
-
265
- /*
266
- * Get contents for a bucket
267
- *
268
- * If maxKeys is null this method will loop through truncated result sets
269
- *
270
- * @param string $bucket Bucket name
271
- * @param string $prefix Prefix
272
- * @param string $marker Marker (last file listed)
273
- * @param string $maxKeys Max keys (maximum number of keys to return)
274
- * @param string $delimiter Delimiter
275
- * @param boolean $returnCommonPrefixes Set to true to return CommonPrefixes
276
- * @return array | false
277
- */
278
- public static function getBucket($bucket, $prefix = null, $marker = null, $maxKeys = null, $delimiter = null, $returnCommonPrefixes = false)
279
- {
280
- $rest = new S3Request('GET', $bucket, '', self::$endpoint);
281
- if ($maxKeys == 0) $maxKeys = null;
282
- if ($prefix !== null && $prefix !== '') $rest->setParameter('prefix', $prefix);
283
- if ($marker !== null && $marker !== '') $rest->setParameter('marker', $marker);
284
- if ($maxKeys !== null && $maxKeys !== '') $rest->setParameter('max-keys', $maxKeys);
285
- if ($delimiter !== null && $delimiter !== '') $rest->setParameter('delimiter', $delimiter);
286
- $response = $rest->getResponse();
287
- if ($response->error === false && $response->code !== 200)
288
- $response->error = array('code' => $response->code, 'message' => 'Unexpected HTTP status');
289
- if ($response->error !== false)
290
- {
291
- self::__triggerError(sprintf("S3::getBucket(): [%s] %s",
292
- $response->error['code'], $response->error['message']), __FILE__, __LINE__);
293
- return false;
294
- }
295
-
296
- $results = array();
297
-
298
- $nextMarker = null;
299
- if (isset($response->body, $response->body->Contents))
300
- foreach ($response->body->Contents as $c)
301
- {
302
- $results[(string)$c->Key] = array(
303
- 'name' => (string)$c->Key,
304
- 'time' => strtotime((string)$c->LastModified),
305
- 'size' => (int)$c->Size,
306
- 'hash' => substr((string)$c->ETag, 1, -1)
307
- );
308
- $nextMarker = (string)$c->Key;
309
- }
310
-
311
- if ($returnCommonPrefixes && isset($response->body, $response->body->CommonPrefixes))
312
- foreach ($response->body->CommonPrefixes as $c)
313
- $results[(string)$c->Prefix] = array('prefix' => (string)$c->Prefix);
314
-
315
- if (isset($response->body, $response->body->IsTruncated) &&
316
- (string)$response->body->IsTruncated == 'false') return $results;
317
-
318
- if (isset($response->body, $response->body->NextMarker))
319
- $nextMarker = (string)$response->body->NextMarker;
320
-
321
- // Loop through truncated results if maxKeys isn't specified
322
- if ($maxKeys == null && $nextMarker !== null && (string)$response->body->IsTruncated == 'true')
323
- do
324
- {
325
- $rest = new S3Request('GET', $bucket, '', self::$endpoint);
326
- if ($prefix !== null && $prefix !== '') $rest->setParameter('prefix', $prefix);
327
- $rest->setParameter('marker', $nextMarker);
328
- if ($delimiter !== null && $delimiter !== '') $rest->setParameter('delimiter', $delimiter);
329
-
330
- if (($response = $rest->getResponse(true)) == false || $response->code !== 200) break;
331
-
332
- if (isset($response->body, $response->body->Contents))
333
- foreach ($response->body->Contents as $c)
334
- {
335
- $results[(string)$c->Key] = array(
336
- 'name' => (string)$c->Key,
337
- 'time' => strtotime((string)$c->LastModified),
338
- 'size' => (int)$c->Size,
339
- 'hash' => substr((string)$c->ETag, 1, -1)
340
- );
341
- $nextMarker = (string)$c->Key;
342
- }
343
-
344
- if ($returnCommonPrefixes && isset($response->body, $response->body->CommonPrefixes))
345
- foreach ($response->body->CommonPrefixes as $c)
346
- $results[(string)$c->Prefix] = array('prefix' => (string)$c->Prefix);
347
-
348
- if (isset($response->body, $response->body->NextMarker))
349
- $nextMarker = (string)$response->body->NextMarker;
350
-
351
- } while ($response !== false && (string)$response->body->IsTruncated == 'true');
352
-
353
- return $results;
354
- }
355
-
356
-
357
- /**
358
- * Put a bucket
359
- *
360
- * @param string $bucket Bucket name
361
- * @param constant $acl ACL flag
362
- * @param string $location Set as "EU" to create buckets hosted in Europe
363
- * @return boolean
364
- */
365
- public static function putBucket($bucket, $acl = self::ACL_PRIVATE, $location = false)
366
- {
367
- $rest = new S3Request('PUT', $bucket, '', self::$endpoint);
368
- $rest->setAmzHeader('x-amz-acl', $acl);
369
-
370
- if ($location !== false)
371
- {
372
- $dom = new DOMDocument;
373
- $createBucketConfiguration = $dom->createElement('CreateBucketConfiguration');
374
- $locationConstraint = $dom->createElement('LocationConstraint', $location);
375
- $createBucketConfiguration->appendChild($locationConstraint);
376
- $dom->appendChild($createBucketConfiguration);
377
- $rest->data = $dom->saveXML();
378
- $rest->size = strlen($rest->data);
379
- $rest->setHeader('Content-Type', 'application/xml');
380
- }
381
- $rest = $rest->getResponse();
382
-
383
- if ($rest->error === false && $rest->code !== 200)
384
- $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
385
- if ($rest->error !== false)
386
- {
387
- self::__triggerError(sprintf("S3::putBucket({$bucket}, {$acl}, {$location}): [%s] %s",
388
- $rest->error['code'], $rest->error['message']), __FILE__, __LINE__);
389
- return false;
390
- }
391
- return true;
392
- }
393
-
394
-
395
- /**
396
- * Delete an empty bucket
397
- *
398
- * @param string $bucket Bucket name
399
- * @return boolean
400
- */
401
- public static function deleteBucket($bucket)
402
- {
403
- $rest = new S3Request('DELETE', $bucket, '', self::$endpoint);
404
- $rest = $rest->getResponse();
405
- if ($rest->error === false && $rest->code !== 204)
406
- $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
407
- if ($rest->error !== false)
408
- {
409
- self::__triggerError(sprintf("S3::deleteBucket({$bucket}): [%s] %s",
410
- $rest->error['code'], $rest->error['message']), __FILE__, __LINE__);
411
- return false;
412
- }
413
- return true;
414
- }
415
-
416
-
417
- /**
418
- * Create input info array for putObject()
419
- *
420
- * @param string $file Input file
421
- * @param mixed $md5sum Use MD5 hash (supply a string if you want to use your own)
422
- * @return array | false
423
- */
424
- public static function inputFile($file, $md5sum = true)
425
- {
426
- if (!file_exists($file) || !is_file($file) || !is_readable($file))
427
- {
428
- self::__triggerError('S3::inputFile(): Unable to open input file: '.$file, __FILE__, __LINE__);
429
- return false;
430
- }
431
- return array('file' => $file, 'size' => filesize($file), 'md5sum' => $md5sum !== false ?
432
- (is_string($md5sum) ? $md5sum : base64_encode(md5_file($file, true))) : '');
433
- }
434
-
435
-
436
- /**
437
- * Create input array info for putObject() with a resource
438
- *
439
- * @param string $resource Input resource to read from
440
- * @param integer $bufferSize Input byte size
441
- * @param string $md5sum MD5 hash to send (optional)
442
- * @return array | false
443
- */
444
- public static function inputResource(&$resource, $bufferSize, $md5sum = '')
445
- {
446
- if (!is_resource($resource) || $bufferSize < 0)
447
- {
448
- self::__triggerError('S3::inputResource(): Invalid resource or buffer size', __FILE__, __LINE__);
449
- return false;
450
- }
451
- $input = array('size' => $bufferSize, 'md5sum' => $md5sum);
452
- $input['fp'] =& $resource;
453
- return $input;
454
- }
455
-
456
-
457
- /**
458
- * Put an object
459
- *
460
- * @param mixed $input Input data
461
- * @param string $bucket Bucket name
462
- * @param string $uri Object URI
463
- * @param constant $acl ACL constant
464
- * @param array $metaHeaders Array of x-amz-meta-* headers
465
- * @param array $requestHeaders Array of request headers or content type as a string
466
- * @param constant $storageClass Storage class constant
467
- * @return boolean
468
- */
469
- public static function putObject($input, $bucket, $uri, $acl = self::ACL_PRIVATE, $metaHeaders = array(), $requestHeaders = array(), $storageClass = self::STORAGE_CLASS_STANDARD)
470
- {
471
- if ($input === false) return false;
472
- $rest = new S3Request('PUT', $bucket, $uri, self::$endpoint);
473
-
474
- if (is_string($input)) $input = array(
475
- 'data' => $input, 'size' => strlen($input),
476
- 'md5sum' => base64_encode(md5($input, true))
477
- );
478
-
479
- // Data
480
- if (isset($input['fp']))
481
- $rest->fp =& $input['fp'];
482
- elseif (isset($input['file']))
483
- $rest->fp = @fopen($input['file'], 'rb');
484
- elseif (isset($input['data']))
485
- $rest->data = $input['data'];
486
-
487
- // Content-Length (required)
488
- if (isset($input['size']) && $input['size'] >= 0)
489
- $rest->size = $input['size'];
490
- else {
491
- if (isset($input['file']))
492
- $rest->size = filesize($input['file']);
493
- elseif (isset($input['data']))
494
- $rest->size = strlen($input['data']);
495
- }
496
-
497
- // Custom request headers (Content-Type, Content-Disposition, Content-Encoding)
498
- if (is_array($requestHeaders))
499
- foreach ($requestHeaders as $h => $v) $rest->setHeader($h, $v);
500
- elseif (is_string($requestHeaders)) // Support for legacy contentType parameter
501
- $input['type'] = $requestHeaders;
502
-
503
- // Content-Type
504
- if (!isset($input['type']))
505
- {
506
- if (isset($requestHeaders['Content-Type']))
507
- $input['type'] =& $requestHeaders['Content-Type'];
508
- elseif (isset($input['file']))
509
- $input['type'] = self::__getMimeType($input['file']);
510
- else
511
- $input['type'] = 'application/octet-stream';
512
- }
513
-
514
- if ($storageClass !== self::STORAGE_CLASS_STANDARD) // Storage class
515
- $rest->setAmzHeader('x-amz-storage-class', $storageClass);
516
-
517
- // We need to post with Content-Length and Content-Type, MD5 is optional
518
- if ($rest->size >= 0 && ($rest->fp !== false || $rest->data !== false))
519
- {
520
- $rest->setHeader('Content-Type', $input['type']);
521
- if (isset($input['md5sum'])) $rest->setHeader('Content-MD5', $input['md5sum']);
522
-
523
- $rest->setAmzHeader('x-amz-acl', $acl);
524
- foreach ($metaHeaders as $h => $v) $rest->setAmzHeader('x-amz-meta-'.$h, $v);
525
- $rest->getResponse();
526
- } else
527
- $rest->response->error = array('code' => 0, 'message' => 'Missing input parameters');
528
-
529
- if ($rest->response->error === false && $rest->response->code !== 200)
530
- $rest->response->error = array('code' => $rest->response->code, 'message' => 'Unexpected HTTP status');
531
- if ($rest->response->error !== false)
532
- {
533
- self::__triggerError(sprintf("S3::putObject(): [%s] %s",
534
- $rest->response->error['code'], $rest->response->error['message']), __FILE__, __LINE__);
535
- return false;
536
- }
537
- return true;
538
- }
539
-
540
-
541
- /**
542
- * Put an object from a file (legacy function)
543
- *
544
- * @param string $file Input file path
545
- * @param string $bucket Bucket name
546
- * @param string $uri Object URI
547
- * @param constant $acl ACL constant
548
- * @param array $metaHeaders Array of x-amz-meta-* headers
549
- * @param string $contentType Content type
550
- * @return boolean
551
- */
552
- public static function putObjectFile($file, $bucket, $uri, $acl = self::ACL_PRIVATE, $metaHeaders = array(), $contentType = null)
553
- {
554
- return self::putObject(self::inputFile($file), $bucket, $uri, $acl, $metaHeaders, $contentType);
555
- }
556
-
557
-
558
- /**
559
- * Put an object from a string (legacy function)
560
- *
561
- * @param string $string Input data
562
- * @param string $bucket Bucket name
563
- * @param string $uri Object URI
564
- * @param constant $acl ACL constant
565
- * @param array $metaHeaders Array of x-amz-meta-* headers
566
- * @param string $contentType Content type
567
- * @return boolean
568
- */
569
- public static function putObjectString($string, $bucket, $uri, $acl = self::ACL_PRIVATE, $metaHeaders = array(), $contentType = 'text/plain')
570
- {
571
- return self::putObject($string, $bucket, $uri, $acl, $metaHeaders, $contentType);
572
- }
573
-
574
-
575
- /**
576
- * Get an object
577
- *
578
- * @param string $bucket Bucket name
579
- * @param string $uri Object URI
580
- * @param mixed $saveTo Filename or resource to write to
581
- * @return mixed
582
- */
583
- public static function getObject($bucket, $uri, $saveTo = false)
584
- {
585
- $rest = new S3Request('GET', $bucket, $uri, self::$endpoint);
586
- if ($saveTo !== false)
587
- {
588
- if (is_resource($saveTo))
589
- $rest->fp =& $saveTo;
590
- else
591
- if (($rest->fp = @fopen($saveTo, 'wb')) !== false)
592
- $rest->file = realpath($saveTo);
593
- else
594
- $rest->response->error = array('code' => 0, 'message' => 'Unable to open save file for writing: '.$saveTo);
595
- }
596
- if ($rest->response->error === false) $rest->getResponse();
597
-
598
- if ($rest->response->error === false && $rest->response->code !== 200)
599
- $rest->response->error = array('code' => $rest->response->code, 'message' => 'Unexpected HTTP status');
600
- if ($rest->response->error !== false)
601
- {
602
- self::__triggerError(sprintf("S3::getObject({$bucket}, {$uri}): [%s] %s",
603
- $rest->response->error['code'], $rest->response->error['message']), __FILE__, __LINE__);
604
- return false;
605
- }
606
- return $rest->response;
607
- }
608
-
609
-
610
- /**
611
- * Get object information
612
- *
613
- * @param string $bucket Bucket name
614
- * @param string $uri Object URI
615
- * @param boolean $returnInfo Return response information
616
- * @return mixed | false
617
- */
618
- public static function getObjectInfo($bucket, $uri, $returnInfo = true)
619
- {
620
- $rest = new S3Request('HEAD', $bucket, $uri, self::$endpoint);
621
- $rest = $rest->getResponse();
622
- if ($rest->error === false && ($rest->code !== 200 && $rest->code !== 404))
623
- $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
624
- if ($rest->error !== false)
625
- {
626
- self::__triggerError(sprintf("S3::getObjectInfo({$bucket}, {$uri}): [%s] %s",
627
- $rest->error['code'], $rest->error['message']), __FILE__, __LINE__);
628
- return false;
629
- }
630
- return $rest->code == 200 ? $returnInfo ? $rest->headers : true : false;
631
- }
632
-
633
-
634
- /**
635
- * Copy an object
636
- *
637
- * @param string $bucket Source bucket name
638
- * @param string $uri Source object URI
639
- * @param string $bucket Destination bucket name
640
- * @param string $uri Destination object URI
641
- * @param constant $acl ACL constant
642
- * @param array $metaHeaders Optional array of x-amz-meta-* headers
643
- * @param array $requestHeaders Optional array of request headers (content type, disposition, etc.)
644
- * @param constant $storageClass Storage class constant
645
- * @return mixed | false
646
- */
647
- public static function copyObject($srcBucket, $srcUri, $bucket, $uri, $acl = self::ACL_PRIVATE, $metaHeaders = array(), $requestHeaders = array(), $storageClass = self::STORAGE_CLASS_STANDARD)
648
- {
649
- $rest = new S3Request('PUT', $bucket, $uri, self::$endpoint);
650
- $rest->setHeader('Content-Length', 0);
651
- foreach ($requestHeaders as $h => $v) $rest->setHeader($h, $v);
652
- foreach ($metaHeaders as $h => $v) $rest->setAmzHeader('x-amz-meta-'.$h, $v);
653
- if ($storageClass !== self::STORAGE_CLASS_STANDARD) // Storage class
654
- $rest->setAmzHeader('x-amz-storage-class', $storageClass);
655
- $rest->setAmzHeader('x-amz-acl', $acl); // Added rawurlencode() for $srcUri (thanks a.yamanoi)
656
- $rest->setAmzHeader('x-amz-copy-source', sprintf('/%s/%s', $srcBucket, rawurlencode($srcUri)));
657
- if (sizeof($requestHeaders) > 0 || sizeof($metaHeaders) > 0)
658
- $rest->setAmzHeader('x-amz-metadata-directive', 'REPLACE');
659
-
660
- $rest = $rest->getResponse();
661
- if ($rest->error === false && $rest->code !== 200)
662
- $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
663
- if ($rest->error !== false)
664
- {
665
- self::__triggerError(sprintf("S3::copyObject({$srcBucket}, {$srcUri}, {$bucket}, {$uri}): [%s] %s",
666
- $rest->error['code'], $rest->error['message']), __FILE__, __LINE__);
667
- return false;
668
- }
669
- return isset($rest->body->LastModified, $rest->body->ETag) ? array(
670
- 'time' => strtotime((string)$rest->body->LastModified),
671
- 'hash' => substr((string)$rest->body->ETag, 1, -1)
672
- ) : false;
673
- }
674
-
675
-
676
- /**
677
- * Set logging for a bucket
678
- *
679
- * @param string $bucket Bucket name
680
- * @param string $targetBucket Target bucket (where logs are stored)
681
- * @param string $targetPrefix Log prefix (e,g; domain.com-)
682
- * @return boolean
683
- */
684
- public static function setBucketLogging($bucket, $targetBucket, $targetPrefix = null)
685
- {
686
- // The S3 log delivery group has to be added to the target bucket's ACP
687
- if ($targetBucket !== null && ($acp = self::getAccessControlPolicy($targetBucket, '')) !== false)
688
- {
689
- // Only add permissions to the target bucket when they do not exist
690
- $aclWriteSet = false;
691
- $aclReadSet = false;
692
- foreach ($acp['acl'] as $acl)
693
- if ($acl['type'] == 'Group' && $acl['uri'] == 'http://acs.amazonaws.com/groups/s3/LogDelivery')
694
- {
695
- if ($acl['permission'] == 'WRITE') $aclWriteSet = true;
696
- elseif ($acl['permission'] == 'READ_ACP') $aclReadSet = true;
697
- }
698
- if (!$aclWriteSet) $acp['acl'][] = array(
699
- 'type' => 'Group', 'uri' => 'http://acs.amazonaws.com/groups/s3/LogDelivery', 'permission' => 'WRITE'
700
- );
701
- if (!$aclReadSet) $acp['acl'][] = array(
702
- 'type' => 'Group', 'uri' => 'http://acs.amazonaws.com/groups/s3/LogDelivery', 'permission' => 'READ_ACP'
703
- );
704
- if (!$aclReadSet || !$aclWriteSet) self::setAccessControlPolicy($targetBucket, '', $acp);
705
- }
706
-
707
- $dom = new DOMDocument;
708
- $bucketLoggingStatus = $dom->createElement('BucketLoggingStatus');
709
- $bucketLoggingStatus->setAttribute('xmlns', 'http://s3.amazonaws.com/doc/2006-03-01/');
710
- if ($targetBucket !== null)
711
- {
712
- if ($targetPrefix == null) $targetPrefix = $bucket . '-';
713
- $loggingEnabled = $dom->createElement('LoggingEnabled');
714
- $loggingEnabled->appendChild($dom->createElement('TargetBucket', $targetBucket));
715
- $loggingEnabled->appendChild($dom->createElement('TargetPrefix', $targetPrefix));
716
- // TODO: Add TargetGrants?
717
- $bucketLoggingStatus->appendChild($loggingEnabled);
718
- }
719
- $dom->appendChild($bucketLoggingStatus);
720
-
721
- $rest = new S3Request('PUT', $bucket, '', self::$endpoint);
722
- $rest->setParameter('logging', null);
723
- $rest->data = $dom->saveXML();
724
- $rest->size = strlen($rest->data);
725
- $rest->setHeader('Content-Type', 'application/xml');
726
- $rest = $rest->getResponse();
727
- if ($rest->error === false && $rest->code !== 200)
728
- $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
729
- if ($rest->error !== false)
730
- {
731
- self::__triggerError(sprintf("S3::setBucketLogging({$bucket}, {$uri}): [%s] %s",
732
- $rest->error['code'], $rest->error['message']), __FILE__, __LINE__);
733
- return false;
734
- }
735
- return true;
736
- }
737
-
738
-
739
- /**
740
- * Get logging status for a bucket
741
- *
742
- * This will return false if logging is not enabled.
743
- * Note: To enable logging, you also need to grant write access to the log group
744
- *
745
- * @param string $bucket Bucket name
746
- * @return array | false
747
- */
748
- public static function getBucketLogging($bucket)
749
- {
750
- $rest = new S3Request('GET', $bucket, '', self::$endpoint);
751
- $rest->setParameter('logging', null);
752
- $rest = $rest->getResponse();
753
- if ($rest->error === false && $rest->code !== 200)
754
- $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
755
- if ($rest->error !== false)
756
- {
757
- self::__triggerError(sprintf("S3::getBucketLogging({$bucket}): [%s] %s",
758
- $rest->error['code'], $rest->error['message']), __FILE__, __LINE__);
759
- return false;
760
- }
761
- if (!isset($rest->body->LoggingEnabled)) return false; // No logging
762
- return array(
763
- 'targetBucket' => (string)$rest->body->LoggingEnabled->TargetBucket,
764
- 'targetPrefix' => (string)$rest->body->LoggingEnabled->TargetPrefix,
765
- );
766
- }
767
-
768
-
769
- /**
770
- * Disable bucket logging
771
- *
772
- * @param string $bucket Bucket name
773
- * @return boolean
774
- */
775
- public static function disableBucketLogging($bucket)
776
- {
777
- return self::setBucketLogging($bucket, null);
778
- }
779
-
780
-
781
- /**
782
- * Get a bucket's location
783
- *
784
- * @param string $bucket Bucket name
785
- * @return string | false
786
- */
787
- public static function getBucketLocation($bucket)
788
- {
789
- $rest = new S3Request('GET', $bucket, '', self::$endpoint);
790
- $rest->setParameter('location', null);
791
- $rest = $rest->getResponse();
792
- if ($rest->error === false && $rest->code !== 200)
793
- $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
794
- if ($rest->error !== false)
795
- {
796
- self::__triggerError(sprintf("S3::getBucketLocation({$bucket}): [%s] %s",
797
- $rest->error['code'], $rest->error['message']), __FILE__, __LINE__);
798
- return false;
799
- }
800
- return (isset($rest->body[0]) && (string)$rest->body[0] !== '') ? (string)$rest->body[0] : 'US';
801
- }
802
-
803
-
804
- /**
805
- * Set object or bucket Access Control Policy
806
- *
807
- * @param string $bucket Bucket name
808
- * @param string $uri Object URI
809
- * @param array $acp Access Control Policy Data (same as the data returned from getAccessControlPolicy)
810
- * @return boolean
811
- */
812
- public static function setAccessControlPolicy($bucket, $uri = '', $acp = array())
813
- {
814
- $dom = new DOMDocument;
815
- $dom->formatOutput = true;
816
- $accessControlPolicy = $dom->createElement('AccessControlPolicy');
817
- $accessControlList = $dom->createElement('AccessControlList');
818
-
819
- // It seems the owner has to be passed along too
820
- $owner = $dom->createElement('Owner');
821
- $owner->appendChild($dom->createElement('ID', $acp['owner']['id']));
822
- $owner->appendChild($dom->createElement('DisplayName', $acp['owner']['name']));
823
- $accessControlPolicy->appendChild($owner);
824
-
825
- foreach ($acp['acl'] as $g)
826
- {
827
- $grant = $dom->createElement('Grant');
828
- $grantee = $dom->createElement('Grantee');
829
- $grantee->setAttribute('xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance');
830
- if (isset($g['id']))
831
- { // CanonicalUser (DisplayName is omitted)
832
- $grantee->setAttribute('xsi:type', 'CanonicalUser');
833
- $grantee->appendChild($dom->createElement('ID', $g['id']));
834
- }
835
- elseif (isset($g['email']))
836
- { // AmazonCustomerByEmail
837
- $grantee->setAttribute('xsi:type', 'AmazonCustomerByEmail');
838
- $grantee->appendChild($dom->createElement('EmailAddress', $g['email']));
839
- }
840
- elseif ($g['type'] == 'Group')
841
- { // Group
842
- $grantee->setAttribute('xsi:type', 'Group');
843
- $grantee->appendChild($dom->createElement('URI', $g['uri']));
844
- }
845
- $grant->appendChild($grantee);
846
- $grant->appendChild($dom->createElement('Permission', $g['permission']));
847
- $accessControlList->appendChild($grant);
848
- }
849
-
850
- $accessControlPolicy->appendChild($accessControlList);
851
- $dom->appendChild($accessControlPolicy);
852
-
853
- $rest = new S3Request('PUT', $bucket, $uri, self::$endpoint);
854
- $rest->setParameter('acl', null);
855
- $rest->data = $dom->saveXML();
856
- $rest->size = strlen($rest->data);
857
- $rest->setHeader('Content-Type', 'application/xml');
858
- $rest = $rest->getResponse();
859
- if ($rest->error === false && $rest->code !== 200)
860
- $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
861
- if ($rest->error !== false)
862
- {
863
- self::__triggerError(sprintf("S3::setAccessControlPolicy({$bucket}, {$uri}): [%s] %s",
864
- $rest->error['code'], $rest->error['message']), __FILE__, __LINE__);
865
- return false;
866
- }
867
- return true;
868
- }
869
-
870
-
871
- /**
872
- * Get object or bucket Access Control Policy
873
- *
874
- * @param string $bucket Bucket name
875
- * @param string $uri Object URI
876
- * @return mixed | false
877
- */
878
- public static function getAccessControlPolicy($bucket, $uri = '')
879
- {
880
- $rest = new S3Request('GET', $bucket, $uri, self::$endpoint);
881
- $rest->setParameter('acl', null);
882
- $rest = $rest->getResponse();
883
- if ($rest->error === false && $rest->code !== 200)
884
- $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
885
- if ($rest->error !== false)
886
- {
887
- self::__triggerError(sprintf("S3::getAccessControlPolicy({$bucket}, {$uri}): [%s] %s",
888
- $rest->error['code'], $rest->error['message']), __FILE__, __LINE__);
889
- return false;
890
- }
891
-
892
- $acp = array();
893
- if (isset($rest->body->Owner, $rest->body->Owner->ID, $rest->body->Owner->DisplayName))
894
- $acp['owner'] = array(
895
- 'id' => (string)$rest->body->Owner->ID, 'name' => (string)$rest->body->Owner->DisplayName
896
- );
897
-
898
- if (isset($rest->body->AccessControlList))
899
- {
900
- $acp['acl'] = array();
901
- foreach ($rest->body->AccessControlList->Grant as $grant)
902
- {
903
- foreach ($grant->Grantee as $grantee)
904
- {
905
- if (isset($grantee->ID, $grantee->DisplayName)) // CanonicalUser
906
- $acp['acl'][] = array(
907
- 'type' => 'CanonicalUser',
908
- 'id' => (string)$grantee->ID,
909
- 'name' => (string)$grantee->DisplayName,
910
- 'permission' => (string)$grant->Permission
911
- );
912
- elseif (isset($grantee->EmailAddress)) // AmazonCustomerByEmail
913
- $acp['acl'][] = array(
914
- 'type' => 'AmazonCustomerByEmail',
915
- 'email' => (string)$grantee->EmailAddress,
916
- 'permission' => (string)$grant->Permission
917
- );
918
- elseif (isset($grantee->URI)) // Group
919
- $acp['acl'][] = array(
920
- 'type' => 'Group',
921
- 'uri' => (string)$grantee->URI,
922
- 'permission' => (string)$grant->Permission
923
- );
924
- else continue;
925
- }
926
- }
927
- }
928
- return $acp;
929
- }
930
-
931
-
932
- /**
933
- * Delete an object
934
- *
935
- * @param string $bucket Bucket name
936
- * @param string $uri Object URI
937
- * @return boolean
938
- */
939
- public static function deleteObject($bucket, $uri)
940
- {
941
- $rest = new S3Request('DELETE', $bucket, $uri, self::$endpoint);
942
- $rest = $rest->getResponse();
943
- if ($rest->error === false && $rest->code !== 204)
944
- $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
945
- if ($rest->error !== false)
946
- {
947
- self::__triggerError(sprintf("S3::deleteObject(): [%s] %s",
948
- $rest->error['code'], $rest->error['message']), __FILE__, __LINE__);
949
- return false;
950
- }
951
- return true;
952
- }
953
-
954
-
955
- /**
956
- * Get a query string authenticated URL
957
- *
958
- * @param string $bucket Bucket name
959
- * @param string $uri Object URI
960
- * @param integer $lifetime Lifetime in seconds
961
- * @param boolean $hostBucket Use the bucket name as the hostname
962
- * @param boolean $https Use HTTPS ($hostBucket should be false for SSL verification)
963
- * @return string
964
- */
965
- public static function getAuthenticatedURL($bucket, $uri, $lifetime, $hostBucket = false, $https = false)
966
- {
967
- $expires = time() + $lifetime;
968
- $uri = str_replace('%2F', '/', rawurlencode($uri)); // URI should be encoded (thanks Sean O'Dea)
969
- return sprintf(($https ? 'https' : 'http').'://%s/%s?AWSAccessKeyId=%s&Expires=%u&Signature=%s',
970
- // $hostBucket ? $bucket : $bucket.'.s3.amazonaws.com', $uri, self::$__accessKey, $expires,
971
- $hostBucket ? $bucket : 's3.amazonaws.com/'.$bucket, $uri, self::$__accessKey, $expires,
972
- urlencode(self::__getHash("GET\n\n\n{$expires}\n/{$bucket}/{$uri}")));
973
- }
974
-
975
-
976
- /**
977
- * Get a CloudFront signed policy URL
978
- *
979
- * @param array $policy Policy
980
- * @return string
981
- */
982
- public static function getSignedPolicyURL($policy)
983
- {
984
- $data = json_encode($policy);
985
- $signature = '';
986
- if (!openssl_sign($data, $signature, self::$__signingKeyResource)) return false;
987
-
988
- $encoded = str_replace(array('+', '='), array('-', '_', '~'), base64_encode($data));
989
- $signature = str_replace(array('+', '='), array('-', '_', '~'), base64_encode($signature));
990
-
991
- $url = $policy['Statement'][0]['Resource'] . '?';
992
- foreach (array('Policy' => $encoded, 'Signature' => $signature, 'Key-Pair-Id' => self::$__signingKeyPairId) as $k => $v)
993
- $url .= $k.'='.str_replace('%2F', '/', rawurlencode($v)).'&';
994
- return substr($url, 0, -1);
995
- }
996
-
997
-
998
- /**
999
- * Get a CloudFront canned policy URL
1000
- *
1001
- * @param string $string URL to sign
1002
- * @param integer $lifetime URL lifetime
1003
- * @return string
1004
- */
1005
- public static function getSignedCannedURL($url, $lifetime)
1006
- {
1007
- return self::getSignedPolicyURL(array(
1008
- 'Statement' => array(
1009
- array('Resource' => $url, 'Condition' => array(
1010
- 'DateLessThan' => array('AWS:EpochTime' => time() + $lifetime)
1011
- ))
1012
- )
1013
- ));
1014
- }
1015
-
1016
-
1017
- /**
1018
- * Get upload POST parameters for form uploads
1019
- *
1020
- * @param string $bucket Bucket name
1021
- * @param string $uriPrefix Object URI prefix
1022
- * @param constant $acl ACL constant
1023
- * @param integer $lifetime Lifetime in seconds
1024
- * @param integer $maxFileSize Maximum filesize in bytes (default 5MB)
1025
- * @param string $successRedirect Redirect URL or 200 / 201 status code
1026
- * @param array $amzHeaders Array of x-amz-meta-* headers
1027
- * @param array $headers Array of request headers or content type as a string
1028
- * @param boolean $flashVars Includes additional "Filename" variable posted by Flash
1029
- * @return object
1030
- */
1031
- public static function getHttpUploadPostParams($bucket, $uriPrefix = '', $acl = self::ACL_PRIVATE, $lifetime = 3600,
1032
- $maxFileSize = 5242880, $successRedirect = "201", $amzHeaders = array(), $headers = array(), $flashVars = false)
1033
- {
1034
- // Create policy object
1035
- $policy = new stdClass;
1036
- $policy->expiration = gmdate('Y-m-d\TH:i:s\Z', (time() + $lifetime));
1037
- $policy->conditions = array();
1038
- $obj = new stdClass; $obj->bucket = $bucket; array_push($policy->conditions, $obj);
1039
- $obj = new stdClass; $obj->acl = $acl; array_push($policy->conditions, $obj);
1040
-
1041
- $obj = new stdClass; // 200 for non-redirect uploads
1042
- if (is_numeric($successRedirect) && in_array((int)$successRedirect, array(200, 201)))
1043
- $obj->success_action_status = (string)$successRedirect;
1044
- else // URL
1045
- $obj->success_action_redirect = $successRedirect;
1046
- array_push($policy->conditions, $obj);
1047
-
1048
- if ($acl !== self::ACL_PUBLIC_READ)
1049
- array_push($policy->conditions, array('eq', '$acl', $acl));
1050
-
1051
- array_push($policy->conditions, array('starts-with', '$key', $uriPrefix));
1052
- if ($flashVars) array_push($policy->conditions, array('starts-with', '$Filename', ''));
1053
- foreach (array_keys($headers) as $headerKey)
1054
- array_push($policy->conditions, array('starts-with', '$'.$headerKey, ''));
1055
- foreach ($amzHeaders as $headerKey => $headerVal)
1056
- {
1057
- $obj = new stdClass;
1058
- $obj->{$headerKey} = (string)$headerVal;
1059
- array_push($policy->conditions, $obj);
1060
- }
1061
- array_push($policy->conditions, array('content-length-range', 0, $maxFileSize));
1062
- $policy = base64_encode(str_replace('\/', '/', json_encode($policy)));
1063
-
1064
- // Create parameters
1065
- $params = new stdClass;
1066
- $params->AWSAccessKeyId = self::$__accessKey;
1067
- $params->key = $uriPrefix.'${filename}';
1068
- $params->acl = $acl;
1069
- $params->policy = $policy; unset($policy);
1070
- $params->signature = self::__getHash($params->policy);
1071
- if (is_numeric($successRedirect) && in_array((int)$successRedirect, array(200, 201)))
1072
- $params->success_action_status = (string)$successRedirect;
1073
- else
1074
- $params->success_action_redirect = $successRedirect;
1075
- foreach ($headers as $headerKey => $headerVal) $params->{$headerKey} = (string)$headerVal;
1076
- foreach ($amzHeaders as $headerKey => $headerVal) $params->{$headerKey} = (string)$headerVal;
1077
- return $params;
1078
- }
1079
-
1080
-
1081
- /**
1082
- * Create a CloudFront distribution
1083
- *
1084
- * @param string $bucket Bucket name
1085
- * @param boolean $enabled Enabled (true/false)
1086
- * @param array $cnames Array containing CNAME aliases
1087
- * @param string $comment Use the bucket name as the hostname
1088
- * @param string $defaultRootObject Default root object
1089
- * @param string $originAccessIdentity Origin access identity
1090
- * @param array $trustedSigners Array of trusted signers
1091
- * @return array | false
1092
- */
1093
- public static function createDistribution($bucket, $enabled = true, $cnames = array(), $comment = null, $defaultRootObject = null, $originAccessIdentity = null, $trustedSigners = array())
1094
- {
1095
- if (!extension_loaded('openssl'))
1096
- {
1097
- self::__triggerError(sprintf("S3::createDistribution({$bucket}, ".(int)$enabled.", [], '$comment'): %s",
1098
- "CloudFront functionality requires SSL"), __FILE__, __LINE__);
1099
- return false;
1100
- }
1101
- $useSSL = self::$useSSL;
1102
-
1103
- self::$useSSL = true; // CloudFront requires SSL
1104
- $rest = new S3Request('POST', '', '2010-11-01/distribution', 'cloudfront.amazonaws.com');
1105
- $rest->data = self::__getCloudFrontDistributionConfigXML(
1106
- $bucket.'.s3.amazonaws.com',
1107
- $enabled,
1108
- (string)$comment,
1109
- (string)microtime(true),
1110
- $cnames,
1111
- $defaultRootObject,
1112
- $originAccessIdentity,
1113
- $trustedSigners
1114
- );
1115
-
1116
- $rest->size = strlen($rest->data);
1117
- $rest->setHeader('Content-Type', 'application/xml');
1118
- $rest = self::__getCloudFrontResponse($rest);
1119
-
1120
- self::$useSSL = $useSSL;
1121
-
1122
- if ($rest->error === false && $rest->code !== 201)
1123
- $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
1124
- if ($rest->error !== false)
1125
- {
1126
- self::__triggerError(sprintf("S3::createDistribution({$bucket}, ".(int)$enabled.", [], '$comment'): [%s] %s",
1127
- $rest->error['code'], $rest->error['message']), __FILE__, __LINE__);
1128
- return false;
1129
- } elseif ($rest->body instanceof SimpleXMLElement)
1130
- return self::__parseCloudFrontDistributionConfig($rest->body);
1131
- return false;
1132
- }
1133
-
1134
-
1135
- /**
1136
- * Get CloudFront distribution info
1137
- *
1138
- * @param string $distributionId Distribution ID from listDistributions()
1139
- * @return array | false
1140
- */
1141
- public static function getDistribution($distributionId)
1142
- {
1143
- if (!extension_loaded('openssl'))
1144
- {
1145
- self::__triggerError(sprintf("S3::getDistribution($distributionId): %s",
1146
- "CloudFront functionality requires SSL"), __FILE__, __LINE__);
1147
- return false;
1148
- }
1149
- $useSSL = self::$useSSL;
1150
-
1151
- self::$useSSL = true; // CloudFront requires SSL
1152
- $rest = new S3Request('GET', '', '2010-11-01/distribution/'.$distributionId, 'cloudfront.amazonaws.com');
1153
- $rest = self::__getCloudFrontResponse($rest);
1154
-
1155
- self::$useSSL = $useSSL;
1156
-
1157
- if ($rest->error === false && $rest->code !== 200)
1158
- $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
1159
- if ($rest->error !== false)
1160
- {
1161
- self::__triggerError(sprintf("S3::getDistribution($distributionId): [%s] %s",
1162
- $rest->error['code'], $rest->error['message']), __FILE__, __LINE__);
1163
- return false;
1164
- }
1165
- elseif ($rest->body instanceof SimpleXMLElement)
1166
- {
1167
- $dist = self::__parseCloudFrontDistributionConfig($rest->body);
1168
- $dist['hash'] = $rest->headers['hash'];
1169
- $dist['id'] = $distributionId;
1170
- return $dist;
1171
- }
1172
- return false;
1173
- }
1174
-
1175
-
1176
- /**
1177
- * Update a CloudFront distribution
1178
- *
1179
- * @param array $dist Distribution array info identical to output of getDistribution()
1180
- * @return array | false
1181
- */
1182
- public static function updateDistribution($dist)
1183
- {
1184
- if (!extension_loaded('openssl'))
1185
- {
1186
- self::__triggerError(sprintf("S3::updateDistribution({$dist['id']}): %s",
1187
- "CloudFront functionality requires SSL"), __FILE__, __LINE__);
1188
- return false;
1189
- }
1190
-
1191
- $useSSL = self::$useSSL;
1192
-
1193
- self::$useSSL = true; // CloudFront requires SSL
1194
- $rest = new S3Request('PUT', '', '2010-11-01/distribution/'.$dist['id'].'/config', 'cloudfront.amazonaws.com');
1195
- $rest->data = self::__getCloudFrontDistributionConfigXML(
1196
- $dist['origin'],
1197
- $dist['enabled'],
1198
- $dist['comment'],
1199
- $dist['callerReference'],
1200
- $dist['cnames'],
1201
- $dist['defaultRootObject'],
1202
- $dist['originAccessIdentity'],
1203
- $dist['trustedSigners']
1204
- );
1205
-
1206
- $rest->size = strlen($rest->data);
1207
- $rest->setHeader('If-Match', $dist['hash']);
1208
- $rest = self::__getCloudFrontResponse($rest);
1209
-
1210
- self::$useSSL = $useSSL;
1211
-
1212
- if ($rest->error === false && $rest->code !== 200)
1213
- $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
1214
- if ($rest->error !== false)
1215
- {
1216
- self::__triggerError(sprintf("S3::updateDistribution({$dist['id']}): [%s] %s",
1217
- $rest->error['code'], $rest->error['message']), __FILE__, __LINE__);
1218
- return false;
1219
- } else {
1220
- $dist = self::__parseCloudFrontDistributionConfig($rest->body);
1221
- $dist['hash'] = $rest->headers['hash'];
1222
- return $dist;
1223
- }
1224
- return false;
1225
- }
1226
-
1227
-
1228
- /**
1229
- * Delete a CloudFront distribution
1230
- *
1231
- * @param array $dist Distribution array info identical to output of getDistribution()
1232
- * @return boolean
1233
- */
1234
- public static function deleteDistribution($dist)
1235
- {
1236
- if (!extension_loaded('openssl'))
1237
- {
1238
- self::__triggerError(sprintf("S3::deleteDistribution({$dist['id']}): %s",
1239
- "CloudFront functionality requires SSL"), __FILE__, __LINE__);
1240
- return false;
1241
- }
1242
-
1243
- $useSSL = self::$useSSL;
1244
-
1245
- self::$useSSL = true; // CloudFront requires SSL
1246
- $rest = new S3Request('DELETE', '', '2008-06-30/distribution/'.$dist['id'], 'cloudfront.amazonaws.com');
1247
- $rest->setHeader('If-Match', $dist['hash']);
1248
- $rest = self::__getCloudFrontResponse($rest);
1249
-
1250
- self::$useSSL = $useSSL;
1251
-
1252
- if ($rest->error === false && $rest->code !== 204)
1253
- $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
1254
- if ($rest->error !== false)
1255
- {
1256
- self::__triggerError(sprintf("S3::deleteDistribution({$dist['id']}): [%s] %s",
1257
- $rest->error['code'], $rest->error['message']), __FILE__, __LINE__);
1258
- return false;
1259
- }
1260
- return true;
1261
- }
1262
-
1263
-
1264
- /**
1265
- * Get a list of CloudFront distributions
1266
- *
1267
- * @return array
1268
- */
1269
- public static function listDistributions()
1270
- {
1271
- if (!extension_loaded('openssl'))
1272
- {
1273
- self::__triggerError(sprintf("S3::listDistributions(): [%s] %s",
1274
- "CloudFront functionality requires SSL"), __FILE__, __LINE__);
1275
- return false;
1276
- }
1277
-
1278
- $useSSL = self::$useSSL;
1279
- self::$useSSL = true; // CloudFront requires SSL
1280
- $rest = new S3Request('GET', '', '2010-11-01/distribution', 'cloudfront.amazonaws.com');
1281
- $rest = self::__getCloudFrontResponse($rest);
1282
- self::$useSSL = $useSSL;
1283
-
1284
- if ($rest->error === false && $rest->code !== 200)
1285
- $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
1286
- if ($rest->error !== false)
1287
- {
1288
- self::__triggerError(sprintf("S3::listDistributions(): [%s] %s",
1289
- $rest->error['code'], $rest->error['message']), __FILE__, __LINE__);
1290
- return false;
1291
- }
1292
- elseif ($rest->body instanceof SimpleXMLElement && isset($rest->body->DistributionSummary))
1293
- {
1294
- $list = array();
1295
- if (isset($rest->body->Marker, $rest->body->MaxItems, $rest->body->IsTruncated))
1296
- {
1297
- //$info['marker'] = (string)$rest->body->Marker;
1298
- //$info['maxItems'] = (int)$rest->body->MaxItems;
1299
- //$info['isTruncated'] = (string)$rest->body->IsTruncated == 'true' ? true : false;
1300
- }
1301
- foreach ($rest->body->DistributionSummary as $summary)
1302
- $list[(string)$summary->Id] = self::__parseCloudFrontDistributionConfig($summary);
1303
-
1304
- return $list;
1305
- }
1306
- return array();
1307
- }
1308
-
1309
- /**
1310
- * List CloudFront Origin Access Identities
1311
- *
1312
- * @return array
1313
- */
1314
- public static function listOriginAccessIdentities()
1315
- {
1316
- if (!extension_loaded('openssl'))
1317
- {
1318
- self::__triggerError(sprintf("S3::listOriginAccessIdentities(): [%s] %s",
1319
- "CloudFront functionality requires SSL"), __FILE__, __LINE__);
1320
- return false;
1321
- }
1322
-
1323
- self::$useSSL = true; // CloudFront requires SSL
1324
- $rest = new S3Request('GET', '', '2010-11-01/origin-access-identity/cloudfront', 'cloudfront.amazonaws.com');
1325
- $rest = self::__getCloudFrontResponse($rest);
1326
- $useSSL = self::$useSSL;
1327
-
1328
- if ($rest->error === false && $rest->code !== 200)
1329
- $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
1330
- if ($rest->error !== false)
1331
- {
1332
- trigger_error(sprintf("S3::listOriginAccessIdentities(): [%s] %s",
1333
- $rest->error['code'], $rest->error['message']), E_USER_WARNING);
1334
- return false;
1335
- }
1336
-
1337
- if (isset($rest->body->CloudFrontOriginAccessIdentitySummary))
1338
- {
1339
- $identities = array();
1340
- foreach ($rest->body->CloudFrontOriginAccessIdentitySummary as $identity)
1341
- if (isset($identity->S3CanonicalUserId))
1342
- $identities[(string)$identity->Id] = array('id' => (string)$identity->Id, 's3CanonicalUserId' => (string)$identity->S3CanonicalUserId);
1343
- return $identities;
1344
- }
1345
- return false;
1346
- }
1347
-
1348
-
1349
- /**
1350
- * Invalidate objects in a CloudFront distribution
1351
- *
1352
- * Thanks to Martin Lindkvist for S3::invalidateDistribution()
1353
- *
1354
- * @param string $distributionId Distribution ID from listDistributions()
1355
- * @param array $paths Array of object paths to invalidate
1356
- * @return boolean
1357
- */
1358
- public static function invalidateDistribution($distributionId, $paths)
1359
- {
1360
- if (!extension_loaded('openssl'))
1361
- {
1362
- self::__triggerError(sprintf("S3::invalidateDistribution(): [%s] %s",
1363
- "CloudFront functionality requires SSL"), __FILE__, __LINE__);
1364
- return false;
1365
- }
1366
-
1367
- $useSSL = self::$useSSL;
1368
- self::$useSSL = true; // CloudFront requires SSL
1369
- $rest = new S3Request('POST', '', '2010-08-01/distribution/'.$distributionId.'/invalidation', 'cloudfront.amazonaws.com');
1370
- $rest->data = self::__getCloudFrontInvalidationBatchXML($paths, (string)microtime(true));
1371
- $rest->size = strlen($rest->data);
1372
- $rest = self::__getCloudFrontResponse($rest);
1373
- self::$useSSL = $useSSL;
1374
-
1375
- if ($rest->error === false && $rest->code !== 201)
1376
- $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
1377
- if ($rest->error !== false)
1378
- {
1379
- trigger_error(sprintf("S3::invalidate('{$distributionId}',{$paths}): [%s] %s",
1380
- $rest->error['code'], $rest->error['message']), E_USER_WARNING);
1381
- return false;
1382
- }
1383
- return true;
1384
- }
1385
-
1386
-
1387
- /**
1388
- * Get a InvalidationBatch DOMDocument
1389
- *
1390
- * @internal Used to create XML in invalidateDistribution()
1391
- * @param array $paths Paths to objects to invalidateDistribution
1392
- * @return string
1393
- */
1394
- private static function __getCloudFrontInvalidationBatchXML($paths, $callerReference = '0') {
1395
- $dom = new DOMDocument('1.0', 'UTF-8');
1396
- $dom->formatOutput = true;
1397
- $invalidationBatch = $dom->createElement('InvalidationBatch');
1398
- foreach ($paths as $path)
1399
- $invalidationBatch->appendChild($dom->createElement('Path', $path));
1400
-
1401
- $invalidationBatch->appendChild($dom->createElement('CallerReference', $callerReference));
1402
- $dom->appendChild($invalidationBatch);
1403
- return $dom->saveXML();
1404
- }
1405
-
1406
-
1407
- /**
1408
- * Get a DistributionConfig DOMDocument
1409
- *
1410
- * http://docs.amazonwebservices.com/AmazonCloudFront/latest/APIReference/index.html?PutConfig.html
1411
- *
1412
- * @internal Used to create XML in createDistribution() and updateDistribution()
1413
- * @param string $bucket S3 Origin bucket
1414
- * @param boolean $enabled Enabled (true/false)
1415
- * @param string $comment Comment to append
1416
- * @param string $callerReference Caller reference
1417
- * @param array $cnames Array of CNAME aliases
1418
- * @param string $defaultRootObject Default root object
1419
- * @param string $originAccessIdentity Origin access identity
1420
- * @param array $trustedSigners Array of trusted signers
1421
- * @return string
1422
- */
1423
- private static function __getCloudFrontDistributionConfigXML($bucket, $enabled, $comment, $callerReference = '0', $cnames = array(), $defaultRootObject = null, $originAccessIdentity = null, $trustedSigners = array())
1424
- {
1425
- $dom = new DOMDocument('1.0', 'UTF-8');
1426
- $dom->formatOutput = true;
1427
- $distributionConfig = $dom->createElement('DistributionConfig');
1428
- $distributionConfig->setAttribute('xmlns', 'http://cloudfront.amazonaws.com/doc/2010-11-01/');
1429
-
1430
- $origin = $dom->createElement('S3Origin');
1431
- $origin->appendChild($dom->createElement('DNSName', $bucket));
1432
- if ($originAccessIdentity !== null) $origin->appendChild($dom->createElement('OriginAccessIdentity', $originAccessIdentity));
1433
- $distributionConfig->appendChild($origin);
1434
-
1435
- if ($defaultRootObject !== null) $distributionConfig->appendChild($dom->createElement('DefaultRootObject', $defaultRootObject));
1436
-
1437
- $distributionConfig->appendChild($dom->createElement('CallerReference', $callerReference));
1438
- foreach ($cnames as $cname)
1439
- $distributionConfig->appendChild($dom->createElement('CNAME', $cname));
1440
- if ($comment !== '') $distributionConfig->appendChild($dom->createElement('Comment', $comment));
1441
- $distributionConfig->appendChild($dom->createElement('Enabled', $enabled ? 'true' : 'false'));
1442
-
1443
- $trusted = $dom->createElement('TrustedSigners');
1444
- foreach ($trustedSigners as $id => $type)
1445
- $trusted->appendChild($id !== '' ? $dom->createElement($type, $id) : $dom->createElement($type));
1446
- $distributionConfig->appendChild($trusted);
1447
-
1448
- $dom->appendChild($distributionConfig);
1449
- //var_dump($dom->saveXML());
1450
- return $dom->saveXML();
1451
- }
1452
-
1453
-
1454
- /**
1455
- * Parse a CloudFront distribution config
1456
- *
1457
- * See http://docs.amazonwebservices.com/AmazonCloudFront/latest/APIReference/index.html?GetDistribution.html
1458
- *
1459
- * @internal Used to parse the CloudFront DistributionConfig node to an array
1460
- * @param object &$node DOMNode
1461
- * @return array
1462
- */
1463
- private static function __parseCloudFrontDistributionConfig(&$node)
1464
- {
1465
- if (isset($node->DistributionConfig))
1466
- return self::__parseCloudFrontDistributionConfig($node->DistributionConfig);
1467
-
1468
- $dist = array();
1469
- if (isset($node->Id, $node->Status, $node->LastModifiedTime, $node->DomainName))
1470
- {
1471
- $dist['id'] = (string)$node->Id;
1472
- $dist['status'] = (string)$node->Status;
1473
- $dist['time'] = strtotime((string)$node->LastModifiedTime);
1474
- $dist['domain'] = (string)$node->DomainName;
1475
- }
1476
-
1477
- if (isset($node->CallerReference))
1478
- $dist['callerReference'] = (string)$node->CallerReference;
1479
-
1480
- if (isset($node->Enabled))
1481
- $dist['enabled'] = (string)$node->Enabled == 'true' ? true : false;
1482
-
1483
- if (isset($node->S3Origin))
1484
- {
1485
- if (isset($node->S3Origin->DNSName))
1486
- $dist['origin'] = (string)$node->S3Origin->DNSName;
1487
-
1488
- $dist['originAccessIdentity'] = isset($node->S3Origin->OriginAccessIdentity) ?
1489
- (string)$node->S3Origin->OriginAccessIdentity : null;
1490
- }
1491
-
1492
- $dist['defaultRootObject'] = isset($node->DefaultRootObject) ? (string)$node->DefaultRootObject : null;
1493
-
1494
- $dist['cnames'] = array();
1495
- if (isset($node->CNAME))
1496
- foreach ($node->CNAME as $cname)
1497
- $dist['cnames'][(string)$cname] = (string)$cname;
1498
-
1499
- $dist['trustedSigners'] = array();
1500
- if (isset($node->TrustedSigners))
1501
- foreach ($node->TrustedSigners as $signer)
1502
- {
1503
- if (isset($signer->Self))
1504
- $dist['trustedSigners'][''] = 'Self';
1505
- elseif (isset($signer->KeyPairId))
1506
- $dist['trustedSigners'][(string)$signer->KeyPairId] = 'KeyPairId';
1507
- elseif (isset($signer->AwsAccountNumber))
1508
- $dist['trustedSigners'][(string)$signer->AwsAccountNumber] = 'AwsAccountNumber';
1509
- }
1510
-
1511
- $dist['comment'] = isset($node->Comment) ? (string)$node->Comment : null;
1512
- return $dist;
1513
- }
1514
-
1515
-
1516
- /**
1517
- * Grab CloudFront response
1518
- *
1519
- * @internal Used to parse the CloudFront S3Request::getResponse() output
1520
- * @param object &$rest S3Request instance
1521
- * @return object
1522
- */
1523
- private static function __getCloudFrontResponse(&$rest)
1524
- {
1525
- $rest->getResponse();
1526
- if ($rest->response->error === false && isset($rest->response->body) &&
1527
- is_string($rest->response->body) && substr($rest->response->body, 0, 5) == '<?xml')
1528
- {
1529
- $rest->response->body = simplexml_load_string($rest->response->body);
1530
- // Grab CloudFront errors
1531
- if (isset($rest->response->body->Error, $rest->response->body->Error->Code,
1532
- $rest->response->body->Error->Message))
1533
- {
1534
- $rest->response->error = array(
1535
- 'code' => (string)$rest->response->body->Error->Code,
1536
- 'message' => (string)$rest->response->body->Error->Message
1537
- );
1538
- unset($rest->response->body);
1539
- }
1540
- }
1541
- return $rest->response;
1542
- }
1543
-
1544
-
1545
- /**
1546
- * Get MIME type for file
1547
- *
1548
- * @internal Used to get mime types
1549
- * @param string &$file File path
1550
- * @return string
1551
- */
1552
- public static function __getMimeType(&$file)
1553
- {
1554
- $type = false;
1555
- // Fileinfo documentation says fileinfo_open() will use the
1556
- // MAGIC env var for the magic file
1557
- if (extension_loaded('fileinfo') && isset($_ENV['MAGIC']) &&
1558
- ($finfo = finfo_open(FILEINFO_MIME, $_ENV['MAGIC'])) !== false)
1559
- {
1560
- if (($type = finfo_file($finfo, $file)) !== false)
1561
- {
1562
- // Remove the charset and grab the last content-type
1563
- $type = explode(' ', str_replace('; charset=', ';charset=', $type));
1564
- $type = array_pop($type);
1565
- $type = explode(';', $type);
1566
- $type = trim(array_shift($type));
1567
- }
1568
- finfo_close($finfo);
1569
-
1570
- // If anyone is still using mime_content_type()
1571
- } elseif (function_exists('mime_content_type'))
1572
- $type = trim(mime_content_type($file));
1573
-
1574
- if ($type !== false && strlen($type) > 0) return $type;
1575
-
1576
- // Otherwise do it the old fashioned way
1577
- static $exts = array(
1578
- 'jpg' => 'image/jpeg', 'gif' => 'image/gif', 'png' => 'image/png',
1579
- 'tif' => 'image/tiff', 'tiff' => 'image/tiff', 'ico' => 'image/x-icon',
1580
- 'swf' => 'application/x-shockwave-flash', 'pdf' => 'application/pdf',
1581
- 'zip' => 'application/zip', 'gz' => 'application/x-gzip',
1582
- 'tar' => 'application/x-tar', 'bz' => 'application/x-bzip',
1583
- 'bz2' => 'application/x-bzip2', 'txt' => 'text/plain',
1584
- 'asc' => 'text/plain', 'htm' => 'text/html', 'html' => 'text/html',
1585
- 'css' => 'text/css', 'js' => 'text/javascript',
1586
- 'xml' => 'text/xml', 'xsl' => 'application/xsl+xml',
1587
- 'ogg' => 'application/ogg', 'mp3' => 'audio/mpeg', 'wav' => 'audio/x-wav',
1588
- 'avi' => 'video/x-msvideo', 'mpg' => 'video/mpeg', 'mpeg' => 'video/mpeg',
1589
- 'mov' => 'video/quicktime', 'flv' => 'video/x-flv', 'php' => 'text/x-php'
1590
- );
1591
- $ext = strtolower(pathInfo($file, PATHINFO_EXTENSION));
1592
- return isset($exts[$ext]) ? $exts[$ext] : 'application/octet-stream';
1593
- }
1594
-
1595
-
1596
- /**
1597
- * Generate the auth string: "AWS AccessKey:Signature"
1598
- *
1599
- * @internal Used by S3Request::getResponse()
1600
- * @param string $string String to sign
1601
- * @return string
1602
- */
1603
- public static function __getSignature($string)
1604
- {
1605
- return 'AWS '.self::$__accessKey.':'.self::__getHash($string);
1606
- }
1607
-
1608
-
1609
- /**
1610
- * Creates a HMAC-SHA1 hash
1611
- *
1612
- * This uses the hash extension if loaded
1613
- *
1614
- * @internal Used by __getSignature()
1615
- * @param string $string String to sign
1616
- * @return string
1617
- */
1618
- private static function __getHash($string)
1619
- {
1620
- return base64_encode(extension_loaded('hash') ?
1621
- hash_hmac('sha1', $string, self::$__secretKey, true) : pack('H*', sha1(
1622
- (str_pad(self::$__secretKey, 64, chr(0x00)) ^ (str_repeat(chr(0x5c), 64))) .
1623
- pack('H*', sha1((str_pad(self::$__secretKey, 64, chr(0x00)) ^
1624
- (str_repeat(chr(0x36), 64))) . $string)))));
1625
- }
1626
-
1627
- }
1628
-
1629
- final class S3Request
1630
- {
1631
- private $endpoint, $verb, $bucket, $uri, $resource = '', $parameters = array(),
1632
- $amzHeaders = array(), $headers = array(
1633
- 'Host' => '', 'Date' => '', 'Content-MD5' => '', 'Content-Type' => ''
1634
- );
1635
- public $fp = false, $size = 0, $data = false, $response;
1636
-
1637
-
1638
- /**
1639
- * Constructor
1640
- *
1641
- * @param string $verb Verb
1642
- * @param string $bucket Bucket name
1643
- * @param string $uri Object URI
1644
- * @return mixed
1645
- */
1646
- function __construct($verb, $bucket = '', $uri = '', $endpoint = 's3.amazonaws.com')
1647
- {
1648
- $this->endpoint = $endpoint;
1649
- $this->verb = $verb;
1650
- $this->bucket = $bucket;
1651
- $this->uri = $uri !== '' ? '/'.str_replace('%2F', '/', rawurlencode($uri)) : '/';
1652
-
1653
- //if ($this->bucket !== '')
1654
- // $this->resource = '/'.$this->bucket.$this->uri;
1655
- //else
1656
- // $this->resource = $this->uri;
1657
-
1658
- if ($this->bucket !== '')
1659
- {
1660
- if ($this->__dnsBucketName($this->bucket))
1661
- {
1662
- $this->headers['Host'] = $this->bucket.'.'.$this->endpoint;
1663
- $this->resource = '/'.$this->bucket.$this->uri;
1664
- }
1665
- else
1666
- {
1667
- $this->headers['Host'] = $this->endpoint;
1668
- $this->uri = $this->uri;
1669
- if ($this->bucket !== '') $this->uri = '/'.$this->bucket.$this->uri;
1670
- $this->bucket = '';
1671
- $this->resource = $this->uri;
1672
- }
1673
- }
1674
- else
1675
- {
1676
- $this->headers['Host'] = $this->endpoint;
1677
- $this->resource = $this->uri;
1678
- }
1679
-
1680
-
1681
- $this->headers['Date'] = gmdate('D, d M Y H:i:s T');
1682
- $this->response = new STDClass;
1683
- $this->response->error = false;
1684
- }
1685
-
1686
-
1687
- /**
1688
- * Set request parameter
1689
- *
1690
- * @param string $key Key
1691
- * @param string $value Value
1692
- * @return void
1693
- */
1694
- public function setParameter($key, $value)
1695
- {
1696
- $this->parameters[$key] = $value;
1697
- }
1698
-
1699
-
1700
- /**
1701
- * Set request header
1702
- *
1703
- * @param string $key Key
1704
- * @param string $value Value
1705
- * @return void
1706
- */
1707
- public function setHeader($key, $value)
1708
- {
1709
- $this->headers[$key] = $value;
1710
- }
1711
-
1712
-
1713
- /**
1714
- * Set x-amz-meta-* header
1715
- *
1716
- * @param string $key Key
1717
- * @param string $value Value
1718
- * @return void
1719
- */
1720
- public function setAmzHeader($key, $value)
1721
- {
1722
- $this->amzHeaders[$key] = $value;
1723
- }
1724
-
1725
-
1726
- /**
1727
- * Get the S3 response
1728
- *
1729
- * @return object | false
1730
- */
1731
- public function getResponse()
1732
- {
1733
- $query = '';
1734
- if (sizeof($this->parameters) > 0)
1735
- {
1736
- $query = substr($this->uri, -1) !== '?' ? '?' : '&';
1737
- foreach ($this->parameters as $var => $value)
1738
- if ($value == null || $value == '') $query .= $var.'&';
1739
- // Parameters should be encoded (thanks Sean O'Dea)
1740
- else $query .= $var.'='.rawurlencode($value).'&';
1741
- $query = substr($query, 0, -1);
1742
- $this->uri .= $query;
1743
-
1744
- if (array_key_exists('acl', $this->parameters) ||
1745
- array_key_exists('location', $this->parameters) ||
1746
- array_key_exists('torrent', $this->parameters) ||
1747
- array_key_exists('website', $this->parameters) ||
1748
- array_key_exists('logging', $this->parameters))
1749
- $this->resource .= $query;
1750
- }
1751
- $url = (S3::$useSSL ? 'https://' : 'http://') . ($this->headers['Host'] !== '' ? $this->headers['Host'] : $this->endpoint) . $this->uri;
1752
-
1753
- //var_dump('bucket: ' . $this->bucket, 'uri: ' . $this->uri, 'resource: ' . $this->resource, 'url: ' . $url);
1754
-
1755
- // Basic setup
1756
- $curl = curl_init();
1757
- curl_setopt($curl, CURLOPT_USERAGENT, 'S3/php');
1758
-
1759
- if (S3::$useSSL)
1760
- {
1761
- // SSL Validation can now be optional for those with broken OpenSSL installations
1762
- curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, S3::$useSSLValidation ? 1 : 0);
1763
- curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, S3::$useSSLValidation ? 1 : 0);
1764
-
1765
- if (S3::$sslKey !== null) curl_setopt($curl, CURLOPT_SSLKEY, S3::$sslKey);
1766
- if (S3::$sslCert !== null) curl_setopt($curl, CURLOPT_SSLCERT, S3::$sslCert);
1767
- if (S3::$sslCACert !== null) curl_setopt($curl, CURLOPT_CAINFO, S3::$sslCACert);
1768
- }
1769
-
1770
- curl_setopt($curl, CURLOPT_URL, $url);
1771
-
1772
- if (S3::$proxy != null && isset(S3::$proxy['host']))
1773
- {
1774
- curl_setopt($curl, CURLOPT_PROXY, S3::$proxy['host']);
1775
- curl_setopt($curl, CURLOPT_PROXYTYPE, S3::$proxy['type']);
1776
- if (isset(S3::$proxy['user'], S3::$proxy['pass']) && $proxy['user'] != null && $proxy['pass'] != null)
1777
- curl_setopt($curl, CURLOPT_PROXYUSERPWD, sprintf('%s:%s', S3::$proxy['user'], S3::$proxy['pass']));
1778
- }
1779
-
1780
- // Headers
1781
- $headers = array(); $amz = array();
1782
- foreach ($this->amzHeaders as $header => $value)
1783
- if (strlen($value) > 0) $headers[] = $header.': '.$value;
1784
- foreach ($this->headers as $header => $value)
1785
- if (strlen($value) > 0) $headers[] = $header.': '.$value;
1786
-
1787
- // Collect AMZ headers for signature
1788
- foreach ($this->amzHeaders as $header => $value)
1789
- if (strlen($value) > 0) $amz[] = strtolower($header).':'.$value;
1790
-
1791
- // AMZ headers must be sorted
1792
- if (sizeof($amz) > 0)
1793
- {
1794
- sort($amz);
1795
- $amz = "\n".implode("\n", $amz);
1796
- } else $amz = '';
1797
-
1798
- if (S3::hasAuth())
1799
- {
1800
- // Authorization string (CloudFront stringToSign should only contain a date)
1801
- if ($this->headers['Host'] == 'cloudfront.amazonaws.com')
1802
- $headers[] = 'Authorization: ' . S3::__getSignature($this->headers['Date']);
1803
- else
1804
- {
1805
- $headers[] = 'Authorization: ' . S3::__getSignature(
1806
- $this->verb."\n".
1807
- $this->headers['Content-MD5']."\n".
1808
- $this->headers['Content-Type']."\n".
1809
- $this->headers['Date'].$amz."\n".
1810
- $this->resource
1811
- );
1812
- }
1813
- }
1814
-
1815
- curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
1816
- curl_setopt($curl, CURLOPT_HEADER, false);
1817
- curl_setopt($curl, CURLOPT_RETURNTRANSFER, false);
1818
- curl_setopt($curl, CURLOPT_WRITEFUNCTION, array(&$this, '__responseWriteCallback'));
1819
- curl_setopt($curl, CURLOPT_HEADERFUNCTION, array(&$this, '__responseHeaderCallback'));
1820
- curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
1821
-
1822
- // Request types
1823
- switch ($this->verb)
1824
- {
1825
- case 'GET': break;
1826
- case 'PUT': case 'POST': // POST only used for CloudFront
1827
- if ($this->fp !== false)
1828
- {
1829
- curl_setopt($curl, CURLOPT_PUT, true);
1830
- curl_setopt($curl, CURLOPT_INFILE, $this->fp);
1831
- if ($this->size >= 0)
1832
- curl_setopt($curl, CURLOPT_INFILESIZE, $this->size);
1833
- }
1834
- elseif ($this->data !== false)
1835
- {
1836
- curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $this->verb);
1837
- curl_setopt($curl, CURLOPT_POSTFIELDS, $this->data);
1838
- }
1839
- else
1840
- curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $this->verb);
1841
- break;
1842
- case 'HEAD':
1843
- curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'HEAD');
1844
- curl_setopt($curl, CURLOPT_NOBODY, true);
1845
- break;
1846
- case 'DELETE':
1847
- curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'DELETE');
1848
- break;
1849
- default: break;
1850
- }
1851
-
1852
- // Execute, grab errors
1853
- if (curl_exec($curl))
1854
- $this->response->code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
1855
- else
1856
- $this->response->error = array(
1857
- 'code' => curl_errno($curl),
1858
- 'message' => curl_error($curl),
1859
- 'resource' => $this->resource
1860
- );
1861
-
1862
- @curl_close($curl);
1863
-
1864
- // Parse body into XML
1865
- if ($this->response->error === false && isset($this->response->headers['type']) &&
1866
- $this->response->headers['type'] == 'application/xml' && isset($this->response->body))
1867
- {
1868
- $this->response->body = simplexml_load_string($this->response->body);
1869
-
1870
- // Grab S3 errors
1871
- if (!in_array($this->response->code, array(200, 204, 206)) &&
1872
- isset($this->response->body->Code, $this->response->body->Message))
1873
- {
1874
- $this->response->error = array(
1875
- 'code' => (string)$this->response->body->Code,
1876
- 'message' => (string)$this->response->body->Message
1877
- );
1878
- if (isset($this->response->body->Resource))
1879
- $this->response->error['resource'] = (string)$this->response->body->Resource;
1880
- unset($this->response->body);
1881
- }
1882
- }
1883
-
1884
- // Clean up file resources
1885
- if ($this->fp !== false && is_resource($this->fp)) fclose($this->fp);
1886
-
1887
- return $this->response;
1888
- }
1889
-
1890
-
1891
- /**
1892
- * CURL write callback
1893
- *
1894
- * @param resource &$curl CURL resource
1895
- * @param string &$data Data
1896
- * @return integer
1897
- */
1898
- private function __responseWriteCallback(&$curl, &$data)
1899
- {
1900
- if (in_array($this->response->code, array(200, 206)) && $this->fp !== false)
1901
- return fwrite($this->fp, $data);
1902
- else
1903
- $this->response->body .= $data;
1904
- return strlen($data);
1905
- }
1906
-
1907
-
1908
- /**
1909
- * Check DNS conformity
1910
- *
1911
- * @param string $bucket Bucket name
1912
- * @return boolean
1913
- */
1914
- private function __dnsBucketName($bucket)
1915
- {
1916
- if (strlen($bucket) > 63 || !preg_match("/[^a-z0-9\.-]/", $bucket)) return false;
1917
- if (strstr($bucket, '-.') !== false) return false;
1918
- if (strstr($bucket, '..') !== false) return false;
1919
- if (!preg_match("/^[0-9a-z]/", $bucket)) return false;
1920
- if (!preg_match("/[0-9a-z]$/", $bucket)) return false;
1921
- return true;
1922
- }
1923
-
1924
-
1925
- /**
1926
- * CURL header callback
1927
- *
1928
- * @param resource &$curl CURL resource
1929
- * @param string &$data Data
1930
- * @return integer
1931
- */
1932
- private function __responseHeaderCallback(&$curl, &$data)
1933
- {
1934
- if (($strlen = strlen($data)) <= 2) return $strlen;
1935
- if (substr($data, 0, 4) == 'HTTP')
1936
- $this->response->code = (int)substr($data, 9, 3);
1937
- else
1938
- {
1939
- $data = trim($data);
1940
- if (strpos($data, ': ') === false) return $strlen;
1941
- list($header, $value) = explode(': ', $data, 2);
1942
- if ($header == 'Last-Modified')
1943
- $this->response->headers['time'] = strtotime($value);
1944
- elseif ($header == 'Content-Length')
1945
- $this->response->headers['size'] = (int)$value;
1946
- elseif ($header == 'Content-Type')
1947
- $this->response->headers['type'] = $value;
1948
- elseif ($header == 'ETag')
1949
- $this->response->headers['hash'] = $value{0} == '"' ? substr($value, 1, -1) : $value;
1950
- elseif (preg_match('/^x-amz-meta-.*$/', $header))
1951
- $this->response->headers[$header] = is_numeric($value) ? (int)$value : $value;
1952
- }
1953
- return $strlen;
1954
- }
1955
-
1956
- }
1957
-
1958
- class S3Exception extends Exception {
1959
- function __construct($message, $file, $line, $code = 0)
1960
- {
1961
- parent::__construct($message, $code);
1962
- $this->file = $file;
1963
- $this->line = $line;
1964
- }
1965
- }
 
1
+ <?php
2
+ /**
3
+ * $Id$
4
+ *
5
+ * Copyright (c) 2011, Donovan Schönknecht. All rights reserved.
6
+ *
7
+ * Redistribution and use in source and binary forms, with or without
8
+ * modification, are permitted provided that the following conditions are met:
9
+ *
10
+ * - Redistributions of source code must retain the above copyright notice,
11
+ * this list of conditions and the following disclaimer.
12
+ * - Redistributions in binary form must reproduce the above copyright
13
+ * notice, this list of conditions and the following disclaimer in the
14
+ * documentation and/or other materials provided with the distribution.
15
+ *
16
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
20
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26
+ * POSSIBILITY OF SUCH DAMAGE.
27
+ *
28
+ * Amazon S3 is a trademark of Amazon.com, Inc. or its affiliates.
29
+ */
30
+
31
+ /**
32
+ * Amazon S3 PHP class
33
+ *
34
+ * @link http://undesigned.org.za/2007/10/22/amazon-s3-php-class
35
+ * @version 0.5.0-dev
36
+ */
37
+ class mwpS3
38
+ {
39
+ // ACL flags
40
+ const ACL_PRIVATE = 'private';
41
+ const ACL_PUBLIC_READ = 'public-read';
42
+ const ACL_PUBLIC_READ_WRITE = 'public-read-write';
43
+ const ACL_AUTHENTICATED_READ = 'authenticated-read';
44
+
45
+ const STORAGE_CLASS_STANDARD = 'STANDARD';
46
+ const STORAGE_CLASS_RRS = 'REDUCED_REDUNDANCY';
47
+
48
+ private static $__accessKey = null; // AWS Access key
49
+ private static $__secretKey = null; // AWS Secret key
50
+ private static $__sslKey = null;
51
+
52
+ public static $endpoint = 's3.amazonaws.com';
53
+ public static $proxy = null;
54
+
55
+ public static $useSSL = false;
56
+ public static $useSSLValidation = true;
57
+ public static $useExceptions = false;
58
+
59
+ // SSL CURL SSL options - only needed if you are experiencing problems with your OpenSSL configuration
60
+ public static $sslKey = null;
61
+ public static $sslCert = null;
62
+ public static $sslCACert = null;
63
+
64
+ private static $__signingKeyPairId = null; // AWS Key Pair ID
65
+ private static $__signingKeyResource = false; // Key resource, freeSigningKey() must be called to clear it from memory
66
+
67
+
68
+ /**
69
+ * Constructor - if you're not using the class statically
70
+ *
71
+ * @param string $accessKey Access key
72
+ * @param string $secretKey Secret key
73
+ * @param boolean $useSSL Enable SSL
74
+ * @return void
75
+ */
76
+ public function __construct($accessKey = null, $secretKey = null, $useSSL = false, $endpoint = 's3.amazonaws.com')
77
+ {
78
+ if ($accessKey !== null && $secretKey !== null)
79
+ self::setAuth($accessKey, $secretKey);
80
+ self::$useSSL = $useSSL;
81
+ self::$endpoint = $endpoint;
82
+ }
83
+
84
+
85
+ /**
86
+ * Set the sertvice endpoint
87
+ *
88
+ * @param string $host Hostname
89
+ * @return void
90
+ */
91
+ public function setEndpoint($host)
92
+ {
93
+ self::$endpoint = $host;
94
+ }
95
+
96
+ /**
97
+ * Set AWS access key and secret key
98
+ *
99
+ * @param string $accessKey Access key
100
+ * @param string $secretKey Secret key
101
+ * @return void
102
+ */
103
+ public static function setAuth($accessKey, $secretKey)
104
+ {
105
+ self::$__accessKey = $accessKey;
106
+ self::$__secretKey = $secretKey;
107
+ }
108
+
109
+
110
+ /**
111
+ * Check if AWS keys have been set
112
+ *
113
+ * @return boolean
114
+ */
115
+ public static function hasAuth() {
116
+ return (self::$__accessKey !== null && self::$__secretKey !== null);
117
+ }
118
+
119
+
120
+ /**
121
+ * Set SSL on or off
122
+ *
123
+ * @param boolean $enabled SSL enabled
124
+ * @param boolean $validate SSL certificate validation
125
+ * @return void
126
+ */
127
+ public static function setSSL($enabled, $validate = true)
128
+ {
129
+ self::$useSSL = $enabled;
130
+ self::$useSSLValidation = $validate;
131
+ }
132
+
133
+
134
+ /**
135
+ * Set SSL client certificates (experimental)
136
+ *
137
+ * @param string $sslCert SSL client certificate
138
+ * @param string $sslKey SSL client key
139
+ * @param string $sslCACert SSL CA cert (only required if you are having problems with your system CA cert)
140
+ * @return void
141
+ */
142
+ public static function setSSLAuth($sslCert = null, $sslKey = null, $sslCACert = null)
143
+ {
144
+ self::$sslCert = $sslCert;
145
+ self::$sslKey = $sslKey;
146
+ self::$sslCACert = $sslCACert;
147
+ }
148
+
149
+
150
+ /**
151
+ * Set proxy information
152
+ *
153
+ * @param string $host Proxy hostname and port (localhost:1234)
154
+ * @param string $user Proxy username
155
+ * @param string $pass Proxy password
156
+ * @param constant $type CURL proxy type
157
+ * @return void
158
+ */
159
+ public static function setProxy($host, $user = null, $pass = null, $type = CURLPROXY_SOCKS5)
160
+ {
161
+ self::$proxy = array('host' => $host, 'type' => $type, 'user' => null, 'pass' => 'null');
162
+ }
163
+
164
+
165
+ /**
166
+ * Set the error mode to exceptions
167
+ *
168
+ * @param boolean $enabled Enable exceptions
169
+ * @return void
170
+ */
171
+ public static function setExceptions($enabled = true)
172
+ {
173
+ self::$useExceptions = $enabled;
174
+ }
175
+
176
+
177
+ /**
178
+ * Set signing key
179
+ *
180
+ * @param string $keyPairId AWS Key Pair ID
181
+ * @param string $signingKey Private Key
182
+ * @param boolean $isFile Load private key from file, set to false to load string
183
+ * @return boolean
184
+ */
185
+ public static function setSigningKey($keyPairId, $signingKey, $isFile = true)
186
+ {
187
+ self::$__signingKeyPairId = $keyPairId;
188
+ if ((self::$__signingKeyResource = openssl_pkey_get_private($isFile ?
189
+ file_get_contents($signingKey) : $signingKey)) !== false) return true;
190
+ self::__triggerError('mwpS3::setSigningKey(): Unable to open load private key: '.$signingKey, __FILE__, __LINE__);
191
+ return false;
192
+ }
193
+
194
+
195
+ /**
196
+ * Free signing key from memory, MUST be called if you are using setSigningKey()
197
+ *
198
+ * @return void
199
+ */
200
+ public static function freeSigningKey()
201
+ {
202
+ if (self::$__signingKeyResource !== false)
203
+ openssl_free_key(self::$__signingKeyResource);
204
+ }
205
+
206
+
207
+ /**
208
+ * Internal error handler
209
+ *
210
+ * @internal Internal error handler
211
+ * @param string $message Error message
212
+ * @param string $file Filename
213
+ * @param integer $line Line number
214
+ * @param integer $code Error code
215
+ * @return void
216
+ */
217
+ private static function __triggerError($message, $file, $line, $code = 0)
218
+ {
219
+
220
+ //if (self::$useExceptions)
221
+ throw new mwpS3Exception($message, $file, $line, $code);
222
+ //else
223
+ //trigger_error($message, E_USER_WARNING);
224
+ }
225
+
226
+
227
+ /**
228
+ * Get a list of buckets
229
+ *
230
+ * @param boolean $detailed Returns detailed bucket list when true
231
+ * @return array | false
232
+ */
233
+ public static function listBuckets($detailed = false)
234
+ {
235
+ $rest = new mwpS3Request('GET', '', '', self::$endpoint);
236
+ $rest = $rest->getResponse();
237
+ if ($rest->error === false && $rest->code !== 200)
238
+ $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
239
+ if ($rest->error !== false)
240
+ {
241
+ self::__triggerError(sprintf("mwpS3::listBuckets(): [%s] %s", $rest->error['code'],
242
+ $rest->error['message']), __FILE__, __LINE__);
243
+ return false;
244
+ }
245
+ $results = array();
246
+ if (!isset($rest->body->Buckets)) return $results;
247
+
248
+ if ($detailed)
249
+ {
250
+ if (isset($rest->body->Owner, $rest->body->Owner->ID, $rest->body->Owner->DisplayName))
251
+ $results['owner'] = array(
252
+ 'id' => (string)$rest->body->Owner->ID, 'name' => (string)$rest->body->Owner->ID
253
+ );
254
+ $results['buckets'] = array();
255
+ foreach ($rest->body->Buckets->Bucket as $b)
256
+ $results['buckets'][] = array(
257
+ 'name' => (string)$b->Name, 'time' => strtotime((string)$b->CreationDate)
258
+ );
259
+ } else
260
+ foreach ($rest->body->Buckets->Bucket as $b) $results[] = (string)$b->Name;
261
+
262
+ return $results;
263
+ }
264
+
265
+
266
+ /*
267
+ * Get contents for a bucket
268
+ *
269
+ * If maxKeys is null this method will loop through truncated result sets
270
+ *
271
+ * @param string $bucket Bucket name
272
+ * @param string $prefix Prefix
273
+ * @param string $marker Marker (last file listed)
274
+ * @param string $maxKeys Max keys (maximum number of keys to return)
275
+ * @param string $delimiter Delimiter
276
+ * @param boolean $returnCommonPrefixes Set to true to return CommonPrefixes
277
+ * @return array | false
278
+ */
279
+ public static function getBucket($bucket, $prefix = null, $marker = null, $maxKeys = null, $delimiter = null, $returnCommonPrefixes = false)
280
+ {
281
+ $rest = new mwpS3Request('GET', $bucket, '', self::$endpoint);
282
+ if ($maxKeys == 0) $maxKeys = null;
283
+ if ($prefix !== null && $prefix !== '') $rest->setParameter('prefix', $prefix);
284
+ if ($marker !== null && $marker !== '') $rest->setParameter('marker', $marker);
285
+ if ($maxKeys !== null && $maxKeys !== '') $rest->setParameter('max-keys', $maxKeys);
286
+ if ($delimiter !== null && $delimiter !== '') $rest->setParameter('delimiter', $delimiter);
287
+ $response = $rest->getResponse();
288
+ if ($response->error === false && $response->code !== 200)
289
+ $response->error = array('code' => $response->code, 'message' => 'Unexpected HTTP status');
290
+ if ($response->error !== false)
291
+ {
292
+ self::__triggerError(sprintf("mwpS3::getBucket(): [%s] %s",
293
+ $response->error['code'], $response->error['message']), __FILE__, __LINE__);
294
+ return false;
295
+ }
296
+
297
+ $results = array();
298
+
299
+ $nextMarker = null;
300
+ if (isset($response->body, $response->body->Contents))
301
+ foreach ($response->body->Contents as $c)
302
+ {
303
+ $results[(string)$c->Key] = array(
304
+ 'name' => (string)$c->Key,
305
+ 'time' => strtotime((string)$c->LastModified),
306
+ 'size' => (int)$c->Size,
307
+ 'hash' => substr((string)$c->ETag, 1, -1)
308
+ );
309
+ $nextMarker = (string)$c->Key;
310
+ }
311
+
312
+ if ($returnCommonPrefixes && isset($response->body, $response->body->CommonPrefixes))
313
+ foreach ($response->body->CommonPrefixes as $c)
314
+ $results[(string)$c->Prefix] = array('prefix' => (string)$c->Prefix);
315
+
316
+ if (isset($response->body, $response->body->IsTruncated) &&
317
+ (string)$response->body->IsTruncated == 'false') return $results;
318
+
319
+ if (isset($response->body, $response->body->NextMarker))
320
+ $nextMarker = (string)$response->body->NextMarker;
321
+
322
+ // Loop through truncated results if maxKeys isn't specified
323
+ if ($maxKeys == null && $nextMarker !== null && (string)$response->body->IsTruncated == 'true')
324
+ do
325
+ {
326
+ $rest = new mwpS3Request('GET', $bucket, '', self::$endpoint);
327
+ if ($prefix !== null && $prefix !== '') $rest->setParameter('prefix', $prefix);
328
+ $rest->setParameter('marker', $nextMarker);
329
+ if ($delimiter !== null && $delimiter !== '') $rest->setParameter('delimiter', $delimiter);
330
+
331
+ if (($response = $rest->getResponse(true)) == false || $response->code !== 200) break;
332
+
333
+ if (isset($response->body, $response->body->Contents))
334
+ foreach ($response->body->Contents as $c)
335
+ {
336
+ $results[(string)$c->Key] = array(
337
+ 'name' => (string)$c->Key,
338
+ 'time' => strtotime((string)$c->LastModified),
339
+ 'size' => (int)$c->Size,
340
+ 'hash' => substr((string)$c->ETag, 1, -1)
341
+ );
342
+ $nextMarker = (string)$c->Key;
343
+ }
344
+
345
+ if ($returnCommonPrefixes && isset($response->body, $response->body->CommonPrefixes))
346
+ foreach ($response->body->CommonPrefixes as $c)
347
+ $results[(string)$c->Prefix] = array('prefix' => (string)$c->Prefix);
348
+
349
+ if (isset($response->body, $response->body->NextMarker))
350
+ $nextMarker = (string)$response->body->NextMarker;
351
+
352
+ } while ($response !== false && (string)$response->body->IsTruncated == 'true');
353
+
354
+ return $results;
355
+ }
356
+
357
+
358
+ /**
359
+ * Put a bucket
360
+ *
361
+ * @param string $bucket Bucket name
362
+ * @param constant $acl ACL flag
363
+ * @param string $location Set as "EU" to create buckets hosted in Europe
364
+ * @return boolean
365
+ */
366
+ public static function putBucket($bucket, $acl = self::ACL_PRIVATE, $location = false)
367
+ {
368
+ $rest = new mwpS3Request('PUT', $bucket, '', self::$endpoint);
369
+ $rest->setAmzHeader('x-amz-acl', $acl);
370
+
371
+ if ($location !== false)
372
+ {
373
+ $dom = new DOMDocument;
374
+ $createBucketConfiguration = $dom->createElement('CreateBucketConfiguration');
375
+ $locationConstraint = $dom->createElement('LocationConstraint', $location);
376
+ $createBucketConfiguration->appendChild($locationConstraint);
377
+ $dom->appendChild($createBucketConfiguration);
378
+ $rest->data = $dom->saveXML();
379
+ $rest->size = strlen($rest->data);
380
+ $rest->setHeader('Content-Type', 'application/xml');
381
+ }
382
+ $rest = $rest->getResponse();
383
+
384
+ if ($rest->error === false && $rest->code !== 200)
385
+ $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
386
+ if ($rest->error !== false)
387
+ {
388
+ self::__triggerError(sprintf("mwpS3::putBucket({$bucket}, {$acl}, {$location}): [%s] %s",
389
+ $rest->error['code'], $rest->error['message']), __FILE__, __LINE__);
390
+ return false;
391
+ }
392
+ return true;
393
+ }
394
+
395
+
396
+ /**
397
+ * Delete an empty bucket
398
+ *
399
+ * @param string $bucket Bucket name
400
+ * @return boolean
401
+ */
402
+ public static function deleteBucket($bucket)
403
+ {
404
+ $rest = new mwpS3Request('DELETE', $bucket, '', self::$endpoint);
405
+ $rest = $rest->getResponse();
406
+ if ($rest->error === false && $rest->code !== 204)
407
+ $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
408
+ if ($rest->error !== false)
409
+ {
410
+ self::__triggerError(sprintf("mwpS3::deleteBucket({$bucket}): [%s] %s",
411
+ $rest->error['code'], $rest->error['message']), __FILE__, __LINE__);
412
+ return false;
413
+ }
414
+ return true;
415
+ }
416
+
417
+
418
+ /**
419
+ * Create input info array for putObject()
420
+ *
421
+ * @param string $file Input file
422
+ * @param mixed $md5sum Use MD5 hash (supply a string if you want to use your own)
423
+ * @return array | false
424
+ */
425
+ public static function inputFile($file, $md5sum = true)
426
+ {
427
+ if (!file_exists($file) || !is_file($file) || !is_readable($file))
428
+ {
429
+ self::__triggerError('mwpS3::inputFile(): Unable to open input file: '.$file, __FILE__, __LINE__);
430
+ return false;
431
+ }
432
+ return array('file' => $file, 'size' => filesize($file), 'md5sum' => $md5sum !== false ?
433
+ (is_string($md5sum) ? $md5sum : base64_encode(md5_file($file, true))) : '');
434
+ }
435
+
436
+
437
+ /**
438
+ * Create input array info for putObject() with a resource
439
+ *
440
+ * @param string $resource Input resource to read from
441
+ * @param integer $bufferSize Input byte size
442
+ * @param string $md5sum MD5 hash to send (optional)
443
+ * @return array | false
444
+ */
445
+ public static function inputResource(&$resource, $bufferSize, $md5sum = '')
446
+ {
447
+ if (!is_resource($resource) || $bufferSize < 0)
448
+ {
449
+ self::__triggerError('mwpS3::inputResource(): Invalid resource or buffer size', __FILE__, __LINE__);
450
+ return false;
451
+ }
452
+ $input = array('size' => $bufferSize, 'md5sum' => $md5sum);
453
+ $input['fp'] =& $resource;
454
+ return $input;
455
+ }
456
+
457
+
458
+ /**
459
+ * Put an object
460
+ *
461
+ * @param mixed $input Input data
462
+ * @param string $bucket Bucket name
463
+ * @param string $uri Object URI
464
+ * @param constant $acl ACL constant
465
+ * @param array $metaHeaders Array of x-amz-meta-* headers
466
+ * @param array $requestHeaders Array of request headers or content type as a string
467
+ * @param constant $storageClass Storage class constant
468
+ * @return boolean
469
+ */
470
+ public static function putObject($input, $bucket, $uri, $acl = self::ACL_PRIVATE, $metaHeaders = array(), $requestHeaders = array(), $storageClass = self::STORAGE_CLASS_STANDARD)
471
+ {
472
+ if ($input === false) return false;
473
+ $rest = new mwpS3Request('PUT', $bucket, $uri, self::$endpoint);
474
+
475
+ if (is_string($input)) $input = array(
476
+ 'data' => $input, 'size' => strlen($input),
477
+ 'md5sum' => base64_encode(md5($input, true))
478
+ );
479
+
480
+ // Data
481
+ if (isset($input['fp']))
482
+ $rest->fp =& $input['fp'];
483
+ elseif (isset($input['file']))
484
+ $rest->fp = @fopen($input['file'], 'rb');
485
+ elseif (isset($input['data']))
486
+ $rest->data = $input['data'];
487
+
488
+ // Content-Length (required)
489
+ if (isset($input['size']) && $input['size'] >= 0)
490
+ $rest->size = $input['size'];
491
+ else {
492
+ if (isset($input['file']))
493
+ $rest->size = filesize($input['file']);
494
+ elseif (isset($input['data']))
495
+ $rest->size = strlen($input['data']);
496
+ }
497
+
498
+ // Custom request headers (Content-Type, Content-Disposition, Content-Encoding)
499
+ if (is_array($requestHeaders))
500
+ foreach ($requestHeaders as $h => $v) $rest->setHeader($h, $v);
501
+ elseif (is_string($requestHeaders)) // Support for legacy contentType parameter
502
+ $input['type'] = $requestHeaders;
503
+
504
+ // Content-Type
505
+ if (!isset($input['type']))
506
+ {
507
+ if (isset($requestHeaders['Content-Type']))
508
+ $input['type'] =& $requestHeaders['Content-Type'];
509
+ elseif (isset($input['file']))
510
+ $input['type'] = self::__getMimeType($input['file']);
511
+ else
512
+ $input['type'] = 'application/octet-stream';
513
+ }
514
+
515
+ if ($storageClass !== self::STORAGE_CLASS_STANDARD) // Storage class
516
+ $rest->setAmzHeader('x-amz-storage-class', $storageClass);
517
+
518
+ // We need to post with Content-Length and Content-Type, MD5 is optional
519
+ if ($rest->size >= 0 && ($rest->fp !== false || $rest->data !== false))
520
+ {
521
+ $rest->setHeader('Content-Type', $input['type']);
522
+ if (isset($input['md5sum'])) $rest->setHeader('Content-MD5', $input['md5sum']);
523
+
524
+ $rest->setAmzHeader('x-amz-acl', $acl);
525
+ foreach ($metaHeaders as $h => $v) $rest->setAmzHeader('x-amz-meta-'.$h, $v);
526
+ $rest->getResponse();
527
+ } else
528
+ $rest->response->error = array('code' => 0, 'message' => 'Missing input parameters');
529
+
530
+ if ($rest->response->error === false && $rest->response->code !== 200)
531
+ $rest->response->error = array('code' => $rest->response->code, 'message' => 'Unexpected HTTP status');
532
+ if ($rest->response->error !== false)
533
+ {
534
+ self::__triggerError(sprintf("mwpS3::putObject(): [%s] %s",
535
+ $rest->response->error['code'], $rest->response->error['message']), __FILE__, __LINE__);
536
+ return false;
537
+ }
538
+ return true;
539
+ }
540
+
541
+
542
+ /**
543
+ * Put an object from a file (legacy function)
544
+ *
545
+ * @param string $file Input file path
546
+ * @param string $bucket Bucket name
547
+ * @param string $uri Object URI
548
+ * @param constant $acl ACL constant
549
+ * @param array $metaHeaders Array of x-amz-meta-* headers
550
+ * @param string $contentType Content type
551
+ * @return boolean
552
+ */
553
+ public static function putObjectFile($file, $bucket, $uri, $acl = self::ACL_PRIVATE, $metaHeaders = array(), $contentType = null)
554
+ {
555
+ return self::putObject(self::inputFile($file), $bucket, $uri, $acl, $metaHeaders, $contentType);
556
+ }
557
+
558
+
559
+ /**
560
+ * Put an object from a string (legacy function)
561
+ *
562
+ * @param string $string Input data
563
+ * @param string $bucket Bucket name
564
+ * @param string $uri Object URI
565
+ * @param constant $acl ACL constant
566
+ * @param array $metaHeaders Array of x-amz-meta-* headers
567
+ * @param string $contentType Content type
568
+ * @return boolean
569
+ */
570
+ public static function putObjectString($string, $bucket, $uri, $acl = self::ACL_PRIVATE, $metaHeaders = array(), $contentType = 'text/plain')
571
+ {
572
+ return self::putObject($string, $bucket, $uri, $acl, $metaHeaders, $contentType);
573
+ }
574
+
575
+
576
+ /**
577
+ * Get an object
578
+ *
579
+ * @param string $bucket Bucket name
580
+ * @param string $uri Object URI
581
+ * @param mixed $saveTo Filename or resource to write to
582
+ * @return mixed
583
+ */
584
+ public static function getObject($bucket, $uri, $saveTo = false)
585
+ {
586
+ $rest = new mwpS3Request('GET', $bucket, $uri, self::$endpoint);
587
+ if ($saveTo !== false)
588
+ {
589
+ if (is_resource($saveTo))
590
+ $rest->fp =& $saveTo;
591
+ else
592
+ if (($rest->fp = @fopen($saveTo, 'wb')) !== false)
593
+ $rest->file = realpath($saveTo);
594
+ else
595
+ $rest->response->error = array('code' => 0, 'message' => 'Unable to open save file for writing: '.$saveTo);
596
+ }
597
+ if ($rest->response->error === false) $rest->getResponse();
598
+
599
+ if ($rest->response->error === false && $rest->response->code !== 200)
600
+ $rest->response->error = array('code' => $rest->response->code, 'message' => 'Unexpected HTTP status');
601
+ if ($rest->response->error !== false)
602
+ {
603
+ self::__triggerError(sprintf("mwpS3::getObject({$bucket}, {$uri}): [%s] %s",
604
+ $rest->response->error['code'], $rest->response->error['message']), __FILE__, __LINE__);
605
+ return false;
606
+ }
607
+ return $rest->response;
608
+ }
609
+
610
+
611
+ /**
612
+ * Get object information
613
+ *
614
+ * @param string $bucket Bucket name
615
+ * @param string $uri Object URI
616
+ * @param boolean $returnInfo Return response information
617
+ * @return mixed | false
618
+ */
619
+ public static function getObjectInfo($bucket, $uri, $returnInfo = true)
620
+ {
621
+ $rest = new mwpS3Request('HEAD', $bucket, $uri, self::$endpoint);
622
+ $rest = $rest->getResponse();
623
+ if ($rest->error === false && ($rest->code !== 200 && $rest->code !== 404))
624
+ $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
625
+ if ($rest->error !== false)
626
+ {
627
+ self::__triggerError(sprintf("mwpS3::getObjectInfo({$bucket}, {$uri}): [%s] %s",
628
+ $rest->error['code'], $rest->error['message']), __FILE__, __LINE__);
629
+ return false;
630
+ }
631
+ return $rest->code == 200 ? $returnInfo ? $rest->headers : true : false;
632
+ }
633
+
634
+
635
+ /**
636
+ * Copy an object
637
+ *
638
+ * @param string $bucket Source bucket name
639
+ * @param string $uri Source object URI
640
+ * @param string $bucket Destination bucket name
641
+ * @param string $uri Destination object URI
642
+ * @param constant $acl ACL constant
643
+ * @param array $metaHeaders Optional array of x-amz-meta-* headers
644
+ * @param array $requestHeaders Optional array of request headers (content type, disposition, etc.)
645
+ * @param constant $storageClass Storage class constant
646
+ * @return mixed | false
647
+ */
648
+ public static function copyObject($srcBucket, $srcUri, $bucket, $uri, $acl = self::ACL_PRIVATE, $metaHeaders = array(), $requestHeaders = array(), $storageClass = self::STORAGE_CLASS_STANDARD)
649
+ {
650
+ $rest = new mwpS3Request('PUT', $bucket, $uri, self::$endpoint);
651
+ $rest->setHeader('Content-Length', 0);
652
+ foreach ($requestHeaders as $h => $v) $rest->setHeader($h, $v);
653
+ foreach ($metaHeaders as $h => $v) $rest->setAmzHeader('x-amz-meta-'.$h, $v);
654
+ if ($storageClass !== self::STORAGE_CLASS_STANDARD) // Storage class
655
+ $rest->setAmzHeader('x-amz-storage-class', $storageClass);
656
+ $rest->setAmzHeader('x-amz-acl', $acl); // Added rawurlencode() for $srcUri (thanks a.yamanoi)
657
+ $rest->setAmzHeader('x-amz-copy-source', sprintf('/%s/%s', $srcBucket, rawurlencode($srcUri)));
658
+ if (sizeof($requestHeaders) > 0 || sizeof($metaHeaders) > 0)
659
+ $rest->setAmzHeader('x-amz-metadata-directive', 'REPLACE');
660
+
661
+ $rest = $rest->getResponse();
662
+ if ($rest->error === false && $rest->code !== 200)
663
+ $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
664
+ if ($rest->error !== false)
665
+ {
666
+ self::__triggerError(sprintf("mwpS3::copyObject({$srcBucket}, {$srcUri}, {$bucket}, {$uri}): [%s] %s",
667
+ $rest->error['code'], $rest->error['message']), __FILE__, __LINE__);
668
+ return false;
669
+ }
670
+ return isset($rest->body->LastModified, $rest->body->ETag) ? array(
671
+ 'time' => strtotime((string)$rest->body->LastModified),
672
+ 'hash' => substr((string)$rest->body->ETag, 1, -1)
673
+ ) : false;
674
+ }
675
+
676
+
677
+ /**
678
+ * Set logging for a bucket
679
+ *
680
+ * @param string $bucket Bucket name
681
+ * @param string $targetBucket Target bucket (where logs are stored)
682
+ * @param string $targetPrefix Log prefix (e,g; domain.com-)
683
+ * @return boolean
684
+ */
685
+ public static function setBucketLogging($bucket, $targetBucket, $targetPrefix = null)
686
+ {
687
+ // The S3 log delivery group has to be added to the target bucket's ACP
688
+ if ($targetBucket !== null && ($acp = self::getAccessControlPolicy($targetBucket, '')) !== false)
689
+ {
690
+ // Only add permissions to the target bucket when they do not exist
691
+ $aclWriteSet = false;
692
+ $aclReadSet = false;
693
+ foreach ($acp['acl'] as $acl)
694
+ if ($acl['type'] == 'Group' && $acl['uri'] == 'http://acs.amazonaws.com/groups/s3/LogDelivery')
695
+ {
696
+ if ($acl['permission'] == 'WRITE') $aclWriteSet = true;
697
+ elseif ($acl['permission'] == 'READ_ACP') $aclReadSet = true;
698
+ }
699
+ if (!$aclWriteSet) $acp['acl'][] = array(
700
+ 'type' => 'Group', 'uri' => 'http://acs.amazonaws.com/groups/s3/LogDelivery', 'permission' => 'WRITE'
701
+ );
702
+ if (!$aclReadSet) $acp['acl'][] = array(
703
+ 'type' => 'Group', 'uri' => 'http://acs.amazonaws.com/groups/s3/LogDelivery', 'permission' => 'READ_ACP'
704
+ );
705
+ if (!$aclReadSet || !$aclWriteSet) self::setAccessControlPolicy($targetBucket, '', $acp);
706
+ }
707
+
708
+ $dom = new DOMDocument;
709
+ $bucketLoggingStatus = $dom->createElement('BucketLoggingStatus');
710
+ $bucketLoggingStatus->setAttribute('xmlns', 'http://s3.amazonaws.com/doc/2006-03-01/');
711
+ if ($targetBucket !== null)
712
+ {
713
+ if ($targetPrefix == null) $targetPrefix = $bucket . '-';
714
+ $loggingEnabled = $dom->createElement('LoggingEnabled');
715
+ $loggingEnabled->appendChild($dom->createElement('TargetBucket', $targetBucket));
716
+ $loggingEnabled->appendChild($dom->createElement('TargetPrefix', $targetPrefix));
717
+ // TODO: Add TargetGrants?
718
+ $bucketLoggingStatus->appendChild($loggingEnabled);
719
+ }
720
+ $dom->appendChild($bucketLoggingStatus);
721
+
722
+ $rest = new mwpS3Request('PUT', $bucket, '', self::$endpoint);
723
+ $rest->setParameter('logging', null);
724
+ $rest->data = $dom->saveXML();
725
+ $rest->size = strlen($rest->data);
726
+ $rest->setHeader('Content-Type', 'application/xml');
727
+ $rest = $rest->getResponse();
728
+ if ($rest->error === false && $rest->code !== 200)
729
+ $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
730
+ if ($rest->error !== false)
731
+ {
732
+ self::__triggerError(sprintf("mwpS3::setBucketLogging({$bucket}, {$uri}): [%s] %s",
733
+ $rest->error['code'], $rest->error['message']), __FILE__, __LINE__);
734
+ return false;
735
+ }
736
+ return true;
737
+ }
738
+
739
+
740
+ /**
741
+ * Get logging status for a bucket
742
+ *
743
+ * This will return false if logging is not enabled.
744
+ * Note: To enable logging, you also need to grant write access to the log group
745
+ *
746
+ * @param string $bucket Bucket name
747
+ * @return array | false
748
+ */
749
+ public static function getBucketLogging($bucket)
750
+ {
751
+ $rest = new mwpS3Request('GET', $bucket, '', self::$endpoint);
752
+ $rest->setParameter('logging', null);
753
+ $rest = $rest->getResponse();
754
+ if ($rest->error === false && $rest->code !== 200)
755
+ $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
756
+ if ($rest->error !== false)
757
+ {
758
+ self::__triggerError(sprintf("mwpS3::getBucketLogging({$bucket}): [%s] %s",
759
+ $rest->error['code'], $rest->error['message']), __FILE__, __LINE__);
760
+ return false;
761
+ }
762
+ if (!isset($rest->body->LoggingEnabled)) return false; // No logging
763
+ return array(
764
+ 'targetBucket' => (string)$rest->body->LoggingEnabled->TargetBucket,
765
+ 'targetPrefix' => (string)$rest->body->LoggingEnabled->TargetPrefix,
766
+ );
767
+ }
768
+
769
+
770
+ /**
771
+ * Disable bucket logging
772
+ *
773
+ * @param string $bucket Bucket name
774
+ * @return boolean
775
+ */
776
+ public static function disableBucketLogging($bucket)
777
+ {
778
+ return self::setBucketLogging($bucket, null);
779
+ }
780
+
781
+
782
+ /**
783
+ * Get a bucket's location
784
+ *
785
+ * @param string $bucket Bucket name
786
+ * @return string | false
787
+ */
788
+ public static function getBucketLocation($bucket)
789
+ {
790
+ $rest = new mwpS3Request('GET', $bucket, '', self::$endpoint);
791
+ $rest->setParameter('location', null);
792
+ $rest = $rest->getResponse();
793
+ if ($rest->error === false && $rest->code !== 200)
794
+ $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
795
+ if ($rest->error !== false)
796
+ {
797
+ self::__triggerError(sprintf("mwpS3::getBucketLocation({$bucket}): [%s] %s",
798
+ $rest->error['code'], $rest->error['message']), __FILE__, __LINE__);
799
+ return false;
800
+ }
801
+ return (isset($rest->body[0]) && (string)$rest->body[0] !== '') ? (string)$rest->body[0] : 'US';
802
+ }
803
+
804
+
805
+ /**
806
+ * Set object or bucket Access Control Policy
807
+ *
808
+ * @param string $bucket Bucket name
809
+ * @param string $uri Object URI
810
+ * @param array $acp Access Control Policy Data (same as the data returned from getAccessControlPolicy)
811
+ * @return boolean
812
+ */
813
+ public static function setAccessControlPolicy($bucket, $uri = '', $acp = array())
814
+ {
815
+ $dom = new DOMDocument;
816
+ $dom->formatOutput = true;
817
+ $accessControlPolicy = $dom->createElement('AccessControlPolicy');
818
+ $accessControlList = $dom->createElement('AccessControlList');
819
+
820
+ // It seems the owner has to be passed along too
821
+ $owner = $dom->createElement('Owner');
822
+ $owner->appendChild($dom->createElement('ID', $acp['owner']['id']));
823
+ $owner->appendChild($dom->createElement('DisplayName', $acp['owner']['name']));
824
+ $accessControlPolicy->appendChild($owner);
825
+
826
+ foreach ($acp['acl'] as $g)
827
+ {
828
+ $grant = $dom->createElement('Grant');
829
+ $grantee = $dom->createElement('Grantee');
830
+ $grantee->setAttribute('xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance');
831
+ if (isset($g['id']))
832
+ { // CanonicalUser (DisplayName is omitted)
833
+ $grantee->setAttribute('xsi:type', 'CanonicalUser');
834
+ $grantee->appendChild($dom->createElement('ID', $g['id']));
835
+ }
836
+ elseif (isset($g['email']))
837
+ { // AmazonCustomerByEmail
838
+ $grantee->setAttribute('xsi:type', 'AmazonCustomerByEmail');
839
+ $grantee->appendChild($dom->createElement('EmailAddress', $g['email']));
840
+ }
841
+ elseif ($g['type'] == 'Group')
842
+ { // Group
843
+ $grantee->setAttribute('xsi:type', 'Group');
844
+ $grantee->appendChild($dom->createElement('URI', $g['uri']));
845
+ }
846
+ $grant->appendChild($grantee);
847
+ $grant->appendChild($dom->createElement('Permission', $g['permission']));
848
+ $accessControlList->appendChild($grant);
849
+ }
850
+
851
+ $accessControlPolicy->appendChild($accessControlList);
852
+ $dom->appendChild($accessControlPolicy);
853
+
854
+ $rest = new mwpS3Request('PUT', $bucket, $uri, self::$endpoint);
855
+ $rest->setParameter('acl', null);
856
+ $rest->data = $dom->saveXML();
857
+ $rest->size = strlen($rest->data);
858
+ $rest->setHeader('Content-Type', 'application/xml');
859
+ $rest = $rest->getResponse();
860
+ if ($rest->error === false && $rest->code !== 200)
861
+ $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
862
+ if ($rest->error !== false)
863
+ {
864
+ self::__triggerError(sprintf("mwpS3::setAccessControlPolicy({$bucket}, {$uri}): [%s] %s",
865
+ $rest->error['code'], $rest->error['message']), __FILE__, __LINE__);
866
+ return false;
867
+ }
868
+ return true;
869
+ }
870
+
871
+
872
+ /**
873
+ * Get object or bucket Access Control Policy
874
+ *
875
+ * @param string $bucket Bucket name
876
+ * @param string $uri Object URI
877
+ * @return mixed | false
878
+ */
879
+ public static function getAccessControlPolicy($bucket, $uri = '')
880
+ {
881
+ $rest = new mwpS3Request('GET', $bucket, $uri, self::$endpoint);
882
+ $rest->setParameter('acl', null);
883
+ $rest = $rest->getResponse();
884
+ if ($rest->error === false && $rest->code !== 200)
885
+ $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
886
+ if ($rest->error !== false)
887
+ {
888
+ self::__triggerError(sprintf("mwpS3::getAccessControlPolicy({$bucket}, {$uri}): [%s] %s",
889
+ $rest->error['code'], $rest->error['message']), __FILE__, __LINE__);
890
+ return false;
891
+ }
892
+
893
+ $acp = array();
894
+ if (isset($rest->body->Owner, $rest->body->Owner->ID, $rest->body->Owner->DisplayName))
895
+ $acp['owner'] = array(
896
+ 'id' => (string)$rest->body->Owner->ID, 'name' => (string)$rest->body->Owner->DisplayName
897
+ );
898
+
899
+ if (isset($rest->body->AccessControlList))
900
+ {
901
+ $acp['acl'] = array();
902
+ foreach ($rest->body->AccessControlList->Grant as $grant)
903
+ {
904
+ foreach ($grant->Grantee as $grantee)
905
+ {
906
+ if (isset($grantee->ID, $grantee->DisplayName)) // CanonicalUser
907
+ $acp['acl'][] = array(
908
+ 'type' => 'CanonicalUser',
909
+ 'id' => (string)$grantee->ID,
910
+ 'name' => (string)$grantee->DisplayName,
911
+ 'permission' => (string)$grant->Permission
912
+ );
913
+ elseif (isset($grantee->EmailAddress)) // AmazonCustomerByEmail
914
+ $acp['acl'][] = array(
915
+ 'type' => 'AmazonCustomerByEmail',
916
+ 'email' => (string)$grantee->EmailAddress,
917
+ 'permission' => (string)$grant->Permission
918
+ );
919
+ elseif (isset($grantee->URI)) // Group
920
+ $acp['acl'][] = array(
921
+ 'type' => 'Group',
922
+ 'uri' => (string)$grantee->URI,
923
+ 'permission' => (string)$grant->Permission
924
+ );
925
+ else continue;
926
+ }
927
+ }
928
+ }
929
+ return $acp;
930
+ }
931
+
932
+
933
+ /**
934
+ * Delete an object
935
+ *
936
+ * @param string $bucket Bucket name
937
+ * @param string $uri Object URI
938
+ * @return boolean
939
+ */
940
+ public static function deleteObject($bucket, $uri)
941
+ {
942
+ $rest = new mwpS3Request('DELETE', $bucket, $uri, self::$endpoint);
943
+ $rest = $rest->getResponse();
944
+ if ($rest->error === false && $rest->code !== 204)
945
+ $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
946
+ if ($rest->error !== false)
947
+ {
948
+ self::__triggerError(sprintf("mwpS3::deleteObject(): [%s] %s",
949
+ $rest->error['code'], $rest->error['message']), __FILE__, __LINE__);
950
+ return false;
951
+ }
952
+ return true;
953
+ }
954
+
955
+
956
+ /**
957
+ * Get a query string authenticated URL
958
+ *
959
+ * @param string $bucket Bucket name
960
+ * @param string $uri Object URI
961
+ * @param integer $lifetime Lifetime in seconds
962
+ * @param boolean $hostBucket Use the bucket name as the hostname
963
+ * @param boolean $https Use HTTPS ($hostBucket should be false for SSL verification)
964
+ * @return string
965
+ */
966
+ public static function getAuthenticatedURL($bucket, $uri, $lifetime, $hostBucket = false, $https = false)
967
+ {
968
+ $expires = time() + $lifetime;
969
+ $uri = str_replace('%2F', '/', rawurlencode($uri)); // URI should be encoded (thanks Sean O'Dea)
970
+ return sprintf(($https ? 'https' : 'http').'://%s/%s?AWSAccessKeyId=%s&Expires=%u&Signature=%s',
971
+ // $hostBucket ? $bucket : $bucket.'.s3.amazonaws.com', $uri, self::$__accessKey, $expires,
972
+ $hostBucket ? $bucket : 's3.amazonaws.com/'.$bucket, $uri, self::$__accessKey, $expires,
973
+ urlencode(self::__getHash("GET\n\n\n{$expires}\n/{$bucket}/{$uri}")));
974
+ }
975
+
976
+
977
+ /**
978
+ * Get a CloudFront signed policy URL
979
+ *
980
+ * @param array $policy Policy
981
+ * @return string
982
+ */
983
+ public static function getSignedPolicyURL($policy)
984
+ {
985
+ $data = json_encode($policy);
986
+ $signature = '';
987
+ if (!openssl_sign($data, $signature, self::$__signingKeyResource)) return false;
988
+
989
+ $encoded = str_replace(array('+', '='), array('-', '_', '~'), base64_encode($data));
990
+ $signature = str_replace(array('+', '='), array('-', '_', '~'), base64_encode($signature));
991
+
992
+ $url = $policy['Statement'][0]['Resource'] . '?';
993
+ foreach (array('Policy' => $encoded, 'Signature' => $signature, 'Key-Pair-Id' => self::$__signingKeyPairId) as $k => $v)
994
+ $url .= $k.'='.str_replace('%2F', '/', rawurlencode($v)).'&';
995
+ return substr($url, 0, -1);
996
+ }
997
+
998
+
999
+ /**
1000
+ * Get a CloudFront canned policy URL
1001
+ *
1002
+ * @param string $string URL to sign
1003
+ * @param integer $lifetime URL lifetime
1004
+ * @return string
1005
+ */
1006
+ public static function getSignedCannedURL($url, $lifetime)
1007
+ {
1008
+ return self::getSignedPolicyURL(array(
1009
+ 'Statement' => array(
1010
+ array('Resource' => $url, 'Condition' => array(
1011
+ 'DateLessThan' => array('AWS:EpochTime' => time() + $lifetime)
1012
+ ))
1013
+ )
1014
+ ));
1015
+ }
1016
+
1017
+
1018
+ /**
1019
+ * Get upload POST parameters for form uploads
1020
+ *
1021
+ * @param string $bucket Bucket name
1022
+ * @param string $uriPrefix Object URI prefix
1023
+ * @param constant $acl ACL constant
1024
+ * @param integer $lifetime Lifetime in seconds
1025
+ * @param integer $maxFileSize Maximum filesize in bytes (default 5MB)
1026
+ * @param string $successRedirect Redirect URL or 200 / 201 status code
1027
+ * @param array $amzHeaders Array of x-amz-meta-* headers
1028
+ * @param array $headers Array of request headers or content type as a string
1029
+ * @param boolean $flashVars Includes additional "Filename" variable posted by Flash
1030
+ * @return object
1031
+ */
1032
+ public static function getHttpUploadPostParams($bucket, $uriPrefix = '', $acl = self::ACL_PRIVATE, $lifetime = 3600,
1033
+ $maxFileSize = 5242880, $successRedirect = "201", $amzHeaders = array(), $headers = array(), $flashVars = false)
1034
+ {
1035
+ // Create policy object
1036
+ $policy = new stdClass;
1037
+ $policy->expiration = gmdate('Y-m-d\TH:i:s\Z', (time() + $lifetime));
1038
+ $policy->conditions = array();
1039
+ $obj = new stdClass; $obj->bucket = $bucket; array_push($policy->conditions, $obj);
1040
+ $obj = new stdClass; $obj->acl = $acl; array_push($policy->conditions, $obj);
1041
+
1042
+ $obj = new stdClass; // 200 for non-redirect uploads
1043
+ if (is_numeric($successRedirect) && in_array((int)$successRedirect, array(200, 201)))
1044
+ $obj->success_action_status = (string)$successRedirect;
1045
+ else // URL
1046
+ $obj->success_action_redirect = $successRedirect;
1047
+ array_push($policy->conditions, $obj);
1048
+
1049
+ if ($acl !== self::ACL_PUBLIC_READ)
1050
+ array_push($policy->conditions, array('eq', '$acl', $acl));
1051
+
1052
+ array_push($policy->conditions, array('starts-with', '$key', $uriPrefix));
1053
+ if ($flashVars) array_push($policy->conditions, array('starts-with', '$Filename', ''));
1054
+ foreach (array_keys($headers) as $headerKey)
1055
+ array_push($policy->conditions, array('starts-with', '$'.$headerKey, ''));
1056
+ foreach ($amzHeaders as $headerKey => $headerVal)
1057
+ {
1058
+ $obj = new stdClass;
1059
+ $obj->{$headerKey} = (string)$headerVal;
1060
+ array_push($policy->conditions, $obj);
1061
+ }
1062
+ array_push($policy->conditions, array('content-length-range', 0, $maxFileSize));
1063
+ $policy = base64_encode(str_replace('\/', '/', json_encode($policy)));
1064
+
1065
+ // Create parameters
1066
+ $params = new stdClass;
1067
+ $params->AWSAccessKeyId = self::$__accessKey;
1068
+ $params->key = $uriPrefix.'${filename}';
1069
+ $params->acl = $acl;
1070
+ $params->policy = $policy; unset($policy);
1071
+ $params->signature = self::__getHash($params->policy);
1072
+ if (is_numeric($successRedirect) && in_array((int)$successRedirect, array(200, 201)))
1073
+ $params->success_action_status = (string)$successRedirect;
1074
+ else
1075
+ $params->success_action_redirect = $successRedirect;
1076
+ foreach ($headers as $headerKey => $headerVal) $params->{$headerKey} = (string)$headerVal;
1077
+ foreach ($amzHeaders as $headerKey => $headerVal) $params->{$headerKey} = (string)$headerVal;
1078
+ return $params;
1079
+ }
1080
+
1081
+
1082
+ /**
1083
+ * Create a CloudFront distribution
1084
+ *
1085
+ * @param string $bucket Bucket name
1086
+ * @param boolean $enabled Enabled (true/false)
1087
+ * @param array $cnames Array containing CNAME aliases
1088
+ * @param string $comment Use the bucket name as the hostname
1089
+ * @param string $defaultRootObject Default root object
1090
+ * @param string $originAccessIdentity Origin access identity
1091
+ * @param array $trustedSigners Array of trusted signers
1092
+ * @return array | false
1093
+ */
1094
+ public static function createDistribution($bucket, $enabled = true, $cnames = array(), $comment = null, $defaultRootObject = null, $originAccessIdentity = null, $trustedSigners = array())
1095
+ {
1096
+ if (!extension_loaded('openssl'))
1097
+ {
1098
+ self::__triggerError(sprintf("mwpS3::createDistribution({$bucket}, ".(int)$enabled.", [], '$comment'): %s",
1099
+ "CloudFront functionality requires SSL"), __FILE__, __LINE__);
1100
+ return false;
1101
+ }
1102
+ $useSSL = self::$useSSL;
1103
+
1104
+ self::$useSSL = true; // CloudFront requires SSL
1105
+ $rest = new mwpS3Request('POST', '', '2010-11-01/distribution', 'cloudfront.amazonaws.com');
1106
+ $rest->data = self::__getCloudFrontDistributionConfigXML(
1107
+ $bucket.'.s3.amazonaws.com',
1108
+ $enabled,
1109
+ (string)$comment,
1110
+ (string)microtime(true),
1111
+ $cnames,
1112
+ $defaultRootObject,
1113
+ $originAccessIdentity,
1114
+ $trustedSigners
1115
+ );
1116
+
1117
+ $rest->size = strlen($rest->data);
1118
+ $rest->setHeader('Content-Type', 'application/xml');
1119
+ $rest = self::__getCloudFrontResponse($rest);
1120
+
1121
+ self::$useSSL = $useSSL;
1122
+
1123
+ if ($rest->error === false && $rest->code !== 201)
1124
+ $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
1125
+ if ($rest->error !== false)
1126
+ {
1127
+ self::__triggerError(sprintf("mwpS3::createDistribution({$bucket}, ".(int)$enabled.", [], '$comment'): [%s] %s",
1128
+ $rest->error['code'], $rest->error['message']), __FILE__, __LINE__);
1129
+ return false;
1130
+ } elseif ($rest->body instanceof SimpleXMLElement)
1131
+ return self::__parseCloudFrontDistributionConfig($rest->body);
1132
+ return false;
1133
+ }
1134
+
1135
+
1136
+ /**
1137
+ * Get CloudFront distribution info
1138
+ *
1139
+ * @param string $distributionId Distribution ID from listDistributions()
1140
+ * @return array | false
1141
+ */
1142
+ public static function getDistribution($distributionId)
1143
+ {
1144
+ if (!extension_loaded('openssl'))
1145
+ {
1146
+ self::__triggerError(sprintf("mwpS3::getDistribution($distributionId): %s",
1147
+ "CloudFront functionality requires SSL"), __FILE__, __LINE__);
1148
+ return false;
1149
+ }
1150
+ $useSSL = self::$useSSL;
1151
+
1152
+ self::$useSSL = true; // CloudFront requires SSL
1153
+ $rest = new mwpS3Request('GET', '', '2010-11-01/distribution/'.$distributionId, 'cloudfront.amazonaws.com');
1154
+ $rest = self::__getCloudFrontResponse($rest);
1155
+
1156
+ self::$useSSL = $useSSL;
1157
+
1158
+ if ($rest->error === false && $rest->code !== 200)
1159
+ $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
1160
+ if ($rest->error !== false)
1161
+ {
1162
+ self::__triggerError(sprintf("mwpS3::getDistribution($distributionId): [%s] %s",
1163
+ $rest->error['code'], $rest->error['message']), __FILE__, __LINE__);
1164
+ return false;
1165
+ }
1166
+ elseif ($rest->body instanceof SimpleXMLElement)
1167
+ {
1168
+ $dist = self::__parseCloudFrontDistributionConfig($rest->body);
1169
+ $dist['hash'] = $rest->headers['hash'];
1170
+ $dist['id'] = $distributionId;
1171
+ return $dist;
1172
+ }
1173
+ return false;
1174
+ }
1175
+
1176
+
1177
+ /**
1178
+ * Update a CloudFront distribution
1179
+ *
1180
+ * @param array $dist Distribution array info identical to output of getDistribution()
1181
+ * @return array | false
1182
+ */
1183
+ public static function updateDistribution($dist)
1184
+ {
1185
+ if (!extension_loaded('openssl'))
1186
+ {
1187
+ self::__triggerError(sprintf("mwpS3::updateDistribution({$dist['id']}): %s",
1188
+ "CloudFront functionality requires SSL"), __FILE__, __LINE__);
1189
+ return false;
1190
+ }
1191
+
1192
+ $useSSL = self::$useSSL;
1193
+
1194
+ self::$useSSL = true; // CloudFront requires SSL
1195
+ $rest = new mwpS3Request('PUT', '', '2010-11-01/distribution/'.$dist['id'].'/config', 'cloudfront.amazonaws.com');
1196
+ $rest->data = self::__getCloudFrontDistributionConfigXML(
1197
+ $dist['origin'],
1198
+ $dist['enabled'],
1199
+ $dist['comment'],
1200
+ $dist['callerReference'],
1201
+ $dist['cnames'],
1202
+ $dist['defaultRootObject'],
1203
+ $dist['originAccessIdentity'],
1204
+ $dist['trustedSigners']
1205
+ );
1206
+
1207
+ $rest->size = strlen($rest->data);
1208
+ $rest->setHeader('If-Match', $dist['hash']);
1209
+ $rest = self::__getCloudFrontResponse($rest);
1210
+
1211
+ self::$useSSL = $useSSL;
1212
+
1213
+ if ($rest->error === false && $rest->code !== 200)
1214
+ $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
1215
+ if ($rest->error !== false)
1216
+ {
1217
+ self::__triggerError(sprintf("mwpS3::updateDistribution({$dist['id']}): [%s] %s",
1218
+ $rest->error['code'], $rest->error['message']), __FILE__, __LINE__);
1219
+ return false;
1220
+ } else {
1221
+ $dist = self::__parseCloudFrontDistributionConfig($rest->body);
1222
+ $dist['hash'] = $rest->headers['hash'];
1223
+ return $dist;
1224
+ }
1225
+ return false;
1226
+ }
1227
+
1228
+
1229
+ /**
1230
+ * Delete a CloudFront distribution
1231
+ *
1232
+ * @param array $dist Distribution array info identical to output of getDistribution()
1233
+ * @return boolean
1234
+ */
1235
+ public static function deleteDistribution($dist)
1236
+ {
1237
+ if (!extension_loaded('openssl'))
1238
+ {
1239
+ self::__triggerError(sprintf("mwpS3::deleteDistribution({$dist['id']}): %s",
1240
+ "CloudFront functionality requires SSL"), __FILE__, __LINE__);
1241
+ return false;
1242
+ }
1243
+
1244
+ $useSSL = self::$useSSL;
1245
+
1246
+ self::$useSSL = true; // CloudFront requires SSL
1247
+ $rest = new mwpS3Request('DELETE', '', '2008-06-30/distribution/'.$dist['id'], 'cloudfront.amazonaws.com');
1248
+ $rest->setHeader('If-Match', $dist['hash']);
1249
+ $rest = self::__getCloudFrontResponse($rest);
1250
+
1251
+ self::$useSSL = $useSSL;
1252
+
1253
+ if ($rest->error === false && $rest->code !== 204)
1254
+ $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
1255
+ if ($rest->error !== false)
1256
+ {
1257
+ self::__triggerError(sprintf("mwpS3::deleteDistribution({$dist['id']}): [%s] %s",
1258
+ $rest->error['code'], $rest->error['message']), __FILE__, __LINE__);
1259
+ return false;
1260
+ }
1261
+ return true;
1262
+ }
1263
+
1264
+
1265
+ /**
1266
+ * Get a list of CloudFront distributions
1267
+ *
1268
+ * @return array
1269
+ */
1270
+ public static function listDistributions()
1271
+ {
1272
+ if (!extension_loaded('openssl'))
1273
+ {
1274
+ self::__triggerError(sprintf("mwpS3::listDistributions(): [%s] %s",
1275
+ "CloudFront functionality requires SSL"), __FILE__, __LINE__);
1276
+ return false;
1277
+ }
1278
+
1279
+ $useSSL = self::$useSSL;
1280
+ self::$useSSL = true; // CloudFront requires SSL
1281
+ $rest = new mwpS3Request('GET', '', '2010-11-01/distribution', 'cloudfront.amazonaws.com');
1282
+ $rest = self::__getCloudFrontResponse($rest);
1283
+ self::$useSSL = $useSSL;
1284
+
1285
+ if ($rest->error === false && $rest->code !== 200)
1286
+ $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
1287
+ if ($rest->error !== false)
1288
+ {
1289
+ self::__triggerError(sprintf("mwpS3::listDistributions(): [%s] %s",
1290
+ $rest->error['code'], $rest->error['message']), __FILE__, __LINE__);
1291
+ return false;
1292
+ }
1293
+ elseif ($rest->body instanceof SimpleXMLElement && isset($rest->body->DistributionSummary))
1294
+ {
1295
+ $list = array();
1296
+ if (isset($rest->body->Marker, $rest->body->MaxItems, $rest->body->IsTruncated))
1297
+ {
1298
+ //$info['marker'] = (string)$rest->body->Marker;
1299
+ //$info['maxItems'] = (int)$rest->body->MaxItems;
1300
+ //$info['isTruncated'] = (string)$rest->body->IsTruncated == 'true' ? true : false;
1301
+ }
1302
+ foreach ($rest->body->DistributionSummary as $summary)
1303
+ $list[(string)$summary->Id] = self::__parseCloudFrontDistributionConfig($summary);
1304
+
1305
+ return $list;
1306
+ }
1307
+ return array();
1308
+ }
1309
+
1310
+ /**
1311
+ * List CloudFront Origin Access Identities
1312
+ *
1313
+ * @return array
1314
+ */
1315
+ public static function listOriginAccessIdentities()
1316
+ {
1317
+ if (!extension_loaded('openssl'))
1318
+ {
1319
+ self::__triggerError(sprintf("mwpS3::listOriginAccessIdentities(): [%s] %s",
1320
+ "CloudFront functionality requires SSL"), __FILE__, __LINE__);
1321
+ return false;
1322
+ }
1323
+
1324
+ self::$useSSL = true; // CloudFront requires SSL
1325
+ $rest = new mwpS3Request('GET', '', '2010-11-01/origin-access-identity/cloudfront', 'cloudfront.amazonaws.com');
1326
+ $rest = self::__getCloudFrontResponse($rest);
1327
+ $useSSL = self::$useSSL;
1328
+
1329
+ if ($rest->error === false && $rest->code !== 200)
1330
+ $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
1331
+ if ($rest->error !== false)
1332
+ {
1333
+ trigger_error(sprintf("mwpS3::listOriginAccessIdentities(): [%s] %s",
1334
+ $rest->error['code'], $rest->error['message']), E_USER_WARNING);
1335
+ return false;
1336
+ }
1337
+
1338
+ if (isset($rest->body->CloudFrontOriginAccessIdentitySummary))
1339
+ {
1340
+ $identities = array();
1341
+ foreach ($rest->body->CloudFrontOriginAccessIdentitySummary as $identity)
1342
+ if (isset($identity->S3CanonicalUserId))
1343
+ $identities[(string)$identity->Id] = array('id' => (string)$identity->Id, 's3CanonicalUserId' => (string)$identity->S3CanonicalUserId);
1344
+ return $identities;
1345
+ }
1346
+ return false;
1347
+ }
1348
+
1349
+
1350
+ /**
1351
+ * Invalidate objects in a CloudFront distribution
1352
+ *
1353
+ * Thanks to Martin Lindkvist for mwpS3::invalidateDistribution()
1354
+ *
1355
+ * @param string $distributionId Distribution ID from listDistributions()
1356
+ * @param array $paths Array of object paths to invalidate
1357
+ * @return boolean
1358
+ */
1359
+ public static function invalidateDistribution($distributionId, $paths)
1360
+ {
1361
+ if (!extension_loaded('openssl'))
1362
+ {
1363
+ self::__triggerError(sprintf("mwpS3::invalidateDistribution(): [%s] %s",
1364
+ "CloudFront functionality requires SSL"), __FILE__, __LINE__);
1365
+ return false;
1366
+ }
1367
+
1368
+ $useSSL = self::$useSSL;
1369
+ self::$useSSL = true; // CloudFront requires SSL
1370
+ $rest = new mwpS3Request('POST', '', '2010-08-01/distribution/'.$distributionId.'/invalidation', 'cloudfront.amazonaws.com');
1371
+ $rest->data = self::__getCloudFrontInvalidationBatchXML($paths, (string)microtime(true));
1372
+ $rest->size = strlen($rest->data);
1373
+ $rest = self::__getCloudFrontResponse($rest);
1374
+ self::$useSSL = $useSSL;
1375
+
1376
+ if ($rest->error === false && $rest->code !== 201)
1377
+ $rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
1378
+ if ($rest->error !== false)
1379
+ {
1380
+ trigger_error(sprintf("mwpS3::invalidate('{$distributionId}',{$paths}): [%s] %s",
1381
+ $rest->error['code'], $rest->error['message']), E_USER_WARNING);
1382
+ return false;
1383
+ }
1384
+ return true;
1385
+ }
1386
+
1387
+
1388
+ /**
1389
+ * Get a InvalidationBatch DOMDocument
1390
+ *
1391
+ * @internal Used to create XML in invalidateDistribution()
1392
+ * @param array $paths Paths to objects to invalidateDistribution
1393
+ * @return string
1394
+ */
1395
+ private static function __getCloudFrontInvalidationBatchXML($paths, $callerReference = '0') {
1396
+ $dom = new DOMDocument('1.0', 'UTF-8');
1397
+ $dom->formatOutput = true;
1398
+ $invalidationBatch = $dom->createElement('InvalidationBatch');
1399
+ foreach ($paths as $path)
1400
+ $invalidationBatch->appendChild($dom->createElement('Path', $path));
1401
+
1402
+ $invalidationBatch->appendChild($dom->createElement('CallerReference', $callerReference));
1403
+ $dom->appendChild($invalidationBatch);
1404
+ return $dom->saveXML();
1405
+ }
1406
+
1407
+
1408
+ /**
1409
+ * Get a DistributionConfig DOMDocument
1410
+ *
1411
+ * http://docs.amazonwebservices.com/AmazonCloudFront/latest/APIReference/index.html?PutConfig.html
1412
+ *
1413
+ * @internal Used to create XML in createDistribution() and updateDistribution()
1414
+ * @param string $bucket S3 Origin bucket
1415
+ * @param boolean $enabled Enabled (true/false)
1416
+ * @param string $comment Comment to append
1417
+ * @param string $callerReference Caller reference
1418
+ * @param array $cnames Array of CNAME aliases
1419
+ * @param string $defaultRootObject Default root object
1420
+ * @param string $originAccessIdentity Origin access identity
1421
+ * @param array $trustedSigners Array of trusted signers
1422
+ * @return string
1423
+ */
1424
+ private static function __getCloudFrontDistributionConfigXML($bucket, $enabled, $comment, $callerReference = '0', $cnames = array(), $defaultRootObject = null, $originAccessIdentity = null, $trustedSigners = array())
1425
+ {
1426
+ $dom = new DOMDocument('1.0', 'UTF-8');
1427
+ $dom->formatOutput = true;
1428
+ $distributionConfig = $dom->createElement('DistributionConfig');
1429
+ $distributionConfig->setAttribute('xmlns', 'http://cloudfront.amazonaws.com/doc/2010-11-01/');
1430
+
1431
+ $origin = $dom->createElement('S3Origin');
1432
+ $origin->appendChild($dom->createElement('DNSName', $bucket));
1433
+ if ($originAccessIdentity !== null) $origin->appendChild($dom->createElement('OriginAccessIdentity', $originAccessIdentity));
1434
+ $distributionConfig->appendChild($origin);
1435
+
1436
+ if ($defaultRootObject !== null) $distributionConfig->appendChild($dom->createElement('DefaultRootObject', $defaultRootObject));
1437
+
1438
+ $distributionConfig->appendChild($dom->createElement('CallerReference', $callerReference));
1439
+ foreach ($cnames as $cname)
1440
+ $distributionConfig->appendChild($dom->createElement('CNAME', $cname));
1441
+ if ($comment !== '') $distributionConfig->appendChild($dom->createElement('Comment', $comment));
1442
+ $distributionConfig->appendChild($dom->createElement('Enabled', $enabled ? 'true' : 'false'));
1443
+
1444
+ $trusted = $dom->createElement('TrustedSigners');
1445
+ foreach ($trustedSigners as $id => $type)
1446
+ $trusted->appendChild($id !== '' ? $dom->createElement($type, $id) : $dom->createElement($type));
1447
+ $distributionConfig->appendChild($trusted);
1448
+
1449
+ $dom->appendChild($distributionConfig);
1450
+ //var_dump($dom->saveXML());
1451
+ return $dom->saveXML();
1452
+ }
1453
+
1454
+
1455
+ /**
1456
+ * Parse a CloudFront distribution config
1457
+ *
1458
+ * See http://docs.amazonwebservices.com/AmazonCloudFront/latest/APIReference/index.html?GetDistribution.html
1459
+ *
1460
+ * @internal Used to parse the CloudFront DistributionConfig node to an array
1461
+ * @param object &$node DOMNode
1462
+ * @return array
1463
+ */
1464
+ private static function __parseCloudFrontDistributionConfig(&$node)
1465
+ {
1466
+ if (isset($node->DistributionConfig))
1467
+ return self::__parseCloudFrontDistributionConfig($node->DistributionConfig);
1468
+
1469
+ $dist = array();
1470
+ if (isset($node->Id, $node->Status, $node->LastModifiedTime, $node->DomainName))
1471
+ {
1472
+ $dist['id'] = (string)$node->Id;
1473
+ $dist['status'] = (string)$node->Status;
1474
+ $dist['time'] = strtotime((string)$node->LastModifiedTime);
1475
+ $dist['domain'] = (string)$node->DomainName;
1476
+ }
1477
+
1478
+ if (isset($node->CallerReference))
1479
+ $dist['callerReference'] = (string)$node->CallerReference;
1480
+
1481
+ if (isset($node->Enabled))
1482
+ $dist['enabled'] = (string)$node->Enabled == 'true' ? true : false;
1483
+
1484
+ if (isset($node->S3Origin))
1485
+ {
1486
+ if (isset($node->S3Origin->DNSName))
1487
+ $dist['origin'] = (string)$node->S3Origin->DNSName;
1488
+
1489
+ $dist['originAccessIdentity'] = isset($node->S3Origin->OriginAccessIdentity) ?
1490
+ (string)$node->S3Origin->OriginAccessIdentity : null;
1491
+ }
1492
+
1493
+ $dist['defaultRootObject'] = isset($node->DefaultRootObject) ? (string)$node->DefaultRootObject : null;
1494
+
1495
+ $dist['cnames'] = array();
1496
+ if (isset($node->CNAME))
1497
+ foreach ($node->CNAME as $cname)
1498
+ $dist['cnames'][(string)$cname] = (string)$cname;
1499
+
1500
+ $dist['trustedSigners'] = array();
1501
+ if (isset($node->TrustedSigners))
1502
+ foreach ($node->TrustedSigners as $signer)
1503
+ {
1504
+ if (isset($signer->Self))
1505
+ $dist['trustedSigners'][''] = 'Self';
1506
+ elseif (isset($signer->KeyPairId))
1507
+ $dist['trustedSigners'][(string)$signer->KeyPairId] = 'KeyPairId';
1508
+ elseif (isset($signer->AwsAccountNumber))
1509
+ $dist['trustedSigners'][(string)$signer->AwsAccountNumber] = 'AwsAccountNumber';
1510
+ }
1511
+
1512
+ $dist['comment'] = isset($node->Comment) ? (string)$node->Comment : null;
1513
+ return $dist;
1514
+ }
1515
+
1516
+
1517
+ /**
1518
+ * Grab CloudFront response
1519
+ *
1520
+ * @internal Used to parse the CloudFront S3Request::getResponse() output
1521
+ * @param object &$rest S3Request instance
1522
+ * @return object
1523
+ */
1524
+ private static function __getCloudFrontResponse(&$rest)
1525
+ {
1526
+ $rest->getResponse();
1527
+ if ($rest->response->error === false && isset($rest->response->body) &&
1528
+ is_string($rest->response->body) && substr($rest->response->body, 0, 5) == '<?xml')
1529
+ {
1530
+ $rest->response->body = simplexml_load_string($rest->response->body);
1531
+ // Grab CloudFront errors
1532
+ if (isset($rest->response->body->Error, $rest->response->body->Error->Code,
1533
+ $rest->response->body->Error->Message))
1534
+ {
1535
+ $rest->response->error = array(
1536
+ 'code' => (string)$rest->response->body->Error->Code,
1537
+ 'message' => (string)$rest->response->body->Error->Message
1538
+ );
1539
+ unset($rest->response->body);
1540
+ }
1541
+ }
1542
+ return $rest->response;
1543
+ }
1544
+
1545
+
1546
+ /**
1547
+ * Get MIME type for file
1548
+ *
1549
+ * @internal Used to get mime types
1550
+ * @param string &$file File path
1551
+ * @return string
1552
+ */
1553
+ public static function __getMimeType(&$file)
1554
+ {
1555
+ $type = false;
1556
+ // Fileinfo documentation says fileinfo_open() will use the
1557
+ // MAGIC env var for the magic file
1558
+ if (extension_loaded('fileinfo') && isset($_ENV['MAGIC']) &&
1559
+ ($finfo = finfo_open(FILEINFO_MIME, $_ENV['MAGIC'])) !== false)
1560
+ {
1561
+ if (($type = finfo_file($finfo, $file)) !== false)
1562
+ {
1563
+ // Remove the charset and grab the last content-type
1564
+ $type = explode(' ', str_replace('; charset=', ';charset=', $type));
1565
+ $type = array_pop($type);
1566
+ $type = explode(';', $type);
1567
+ $type = trim(array_shift($type));
1568
+ }
1569
+ finfo_close($finfo);
1570
+
1571
+ // If anyone is still using mime_content_type()
1572
+ } elseif (function_exists('mime_content_type'))
1573
+ $type = trim(mime_content_type($file));
1574
+
1575
+ if ($type !== false && strlen($type) > 0) return $type;
1576
+
1577
+ // Otherwise do it the old fashioned way
1578
+ static $exts = array(
1579
+ 'jpg' => 'image/jpeg', 'gif' => 'image/gif', 'png' => 'image/png',
1580
+ 'tif' => 'image/tiff', 'tiff' => 'image/tiff', 'ico' => 'image/x-icon',
1581
+ 'swf' => 'application/x-shockwave-flash', 'pdf' => 'application/pdf',
1582
+ 'zip' => 'application/zip', 'gz' => 'application/x-gzip',
1583
+ 'tar' => 'application/x-tar', 'bz' => 'application/x-bzip',
1584
+ 'bz2' => 'application/x-bzip2', 'txt' => 'text/plain',
1585
+ 'asc' => 'text/plain', 'htm' => 'text/html', 'html' => 'text/html',
1586
+ 'css' => 'text/css', 'js' => 'text/javascript',
1587
+ 'xml' => 'text/xml', 'xsl' => 'application/xsl+xml',
1588
+ 'ogg' => 'application/ogg', 'mp3' => 'audio/mpeg', 'wav' => 'audio/x-wav',
1589
+ 'avi' => 'video/x-msvideo', 'mpg' => 'video/mpeg', 'mpeg' => 'video/mpeg',
1590
+ 'mov' => 'video/quicktime', 'flv' => 'video/x-flv', 'php' => 'text/x-php'
1591
+ );
1592
+ $ext = strtolower(pathInfo($file, PATHINFO_EXTENSION));
1593
+ return isset($exts[$ext]) ? $exts[$ext] : 'application/octet-stream';
1594
+ }
1595
+
1596
+
1597
+ /**
1598
+ * Generate the auth string: "AWS AccessKey:Signature"
1599
+ *
1600
+ * @internal Used by S3Request::getResponse()
1601
+ * @param string $string String to sign
1602
+ * @return string
1603
+ */
1604
+ public static function __getSignature($string)
1605
+ {
1606
+ return 'AWS '.self::$__accessKey.':'.self::__getHash($string);
1607
+ }
1608
+
1609
+
1610
+ /**
1611
+ * Creates a HMAC-SHA1 hash
1612
+ *
1613
+ * This uses the hash extension if loaded
1614
+ *
1615
+ * @internal Used by __getSignature()
1616
+ * @param string $string String to sign
1617
+ * @return string
1618
+ */
1619
+ private static function __getHash($string)
1620
+ {
1621
+ return base64_encode(extension_loaded('hash') ?
1622
+ hash_hmac('sha1', $string, self::$__secretKey, true) : pack('H*', sha1(
1623
+ (str_pad(self::$__secretKey, 64, chr(0x00)) ^ (str_repeat(chr(0x5c), 64))) .
1624
+ pack('H*', sha1((str_pad(self::$__secretKey, 64, chr(0x00)) ^
1625
+ (str_repeat(chr(0x36), 64))) . $string)))));
1626
+ }
1627
+
1628
+ }
1629
+
1630
+ final class mwpS3Request
1631
+ {
1632
+ private $endpoint, $verb, $bucket, $uri, $resource = '', $parameters = array(),
1633
+ $amzHeaders = array(), $headers = array(
1634
+ 'Host' => '', 'Date' => '', 'Content-MD5' => '', 'Content-Type' => ''
1635
+ );
1636
+ public $fp = false, $size = 0, $data = false, $response;
1637
+
1638
+
1639
+ /**
1640
+ * Constructor
1641
+ *
1642
+ * @param string $verb Verb
1643
+ * @param string $bucket Bucket name
1644
+ * @param string $uri Object URI
1645
+ * @return mixed
1646
+ */
1647
+ function __construct($verb, $bucket = '', $uri = '', $endpoint = 's3.amazonaws.com')
1648
+ {
1649
+ $this->endpoint = $endpoint;
1650
+ $this->verb = $verb;
1651
+ $this->bucket = $bucket;
1652
+ $this->uri = $uri !== '' ? '/'.str_replace('%2F', '/', rawurlencode($uri)) : '/';
1653
+
1654
+ //if ($this->bucket !== '')
1655
+ // $this->resource = '/'.$this->bucket.$this->uri;
1656
+ //else
1657
+ // $this->resource = $this->uri;
1658
+
1659
+ if ($this->bucket !== '')
1660
+ {
1661
+ if ($this->__dnsBucketName($this->bucket))
1662
+ {
1663
+ $this->headers['Host'] = $this->bucket.'.'.$this->endpoint;
1664
+ $this->resource = '/'.$this->bucket.$this->uri;
1665
+ }
1666
+ else
1667
+ {
1668
+ $this->headers['Host'] = $this->endpoint;
1669
+ $this->uri = $this->uri;
1670
+ if ($this->bucket !== '') $this->uri = '/'.$this->bucket.$this->uri;
1671
+ $this->bucket = '';
1672
+ $this->resource = $this->uri;
1673
+ }
1674
+ }
1675
+ else
1676
+ {
1677
+ $this->headers['Host'] = $this->endpoint;
1678
+ $this->resource = $this->uri;
1679
+ }
1680
+
1681
+
1682
+ $this->headers['Date'] = gmdate('D, d M Y H:i:s T');
1683
+ $this->response = new STDClass;
1684
+ $this->response->error = false;
1685
+ }
1686
+
1687
+
1688
+ /**
1689
+ * Set request parameter
1690
+ *
1691
+ * @param string $key Key
1692
+ * @param string $value Value
1693
+ * @return void
1694
+ */
1695
+ public function setParameter($key, $value)
1696
+ {
1697
+ $this->parameters[$key] = $value;
1698
+ }
1699
+
1700
+
1701
+ /**
1702
+ * Set request header
1703
+ *
1704
+ * @param string $key Key
1705
+ * @param string $value Value
1706
+ * @return void
1707
+ */
1708
+ public function setHeader($key, $value)
1709
+ {
1710
+ $this->headers[$key] = $value;
1711
+ }
1712
+
1713
+
1714
+ /**
1715
+ * Set x-amz-meta-* header
1716
+ *
1717
+ * @param string $key Key
1718
+ * @param string $value Value
1719
+ * @return void
1720
+ */
1721
+ public function setAmzHeader($key, $value)
1722
+ {
1723
+ $this->amzHeaders[$key] = $value;
1724
+ }
1725
+
1726
+
1727
+ /**
1728
+ * Get the S3 response
1729
+ *
1730
+ * @return object | false
1731
+ */
1732
+ public function getResponse()
1733
+ {
1734
+ $query = '';
1735
+ if (sizeof($this->parameters) > 0)
1736
+ {
1737
+ $query = substr($this->uri, -1) !== '?' ? '?' : '&';
1738
+ foreach ($this->parameters as $var => $value)
1739
+ if ($value == null || $value == '') $query .= $var.'&';
1740
+ // Parameters should be encoded (thanks Sean O'Dea)
1741
+ else $query .= $var.'='.rawurlencode($value).'&';
1742
+ $query = substr($query, 0, -1);
1743
+ $this->uri .= $query;
1744
+
1745
+ if (array_key_exists('acl', $this->parameters) ||
1746
+ array_key_exists('location', $this->parameters) ||
1747
+ array_key_exists('torrent', $this->parameters) ||
1748
+ array_key_exists('website', $this->parameters) ||
1749
+ array_key_exists('logging', $this->parameters))
1750
+ $this->resource .= $query;
1751
+ }
1752
+ $url = (mwpS3::$useSSL ? 'https://' : 'http://') . ($this->headers['Host'] !== '' ? $this->headers['Host'] : $this->endpoint) . $this->uri;
1753
+
1754
+ //var_dump('bucket: ' . $this->bucket, 'uri: ' . $this->uri, 'resource: ' . $this->resource, 'url: ' . $url);
1755
+
1756
+ // Basic setup
1757
+ $curl = curl_init();
1758
+ curl_setopt($curl, CURLOPT_USERAGENT, 'S3/php');
1759
+ curl_setopt($curl,CURLOPT_TIMEOUT,600);
1760
+ if (mwpS3::$useSSL)
1761
+ {
1762
+ // SSL Validation can now be optional for those with broken OpenSSL installations
1763
+ curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, mwpS3::$useSSLValidation ? 1 : 0);
1764
+ curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, mwpS3::$useSSLValidation ? 1 : 0);
1765
+
1766
+ if (mwpS3::$sslKey !== null) curl_setopt($curl, CURLOPT_SSLKEY, mwpS3::$sslKey);
1767
+ if (mwpS3::$sslCert !== null) curl_setopt($curl, CURLOPT_SSLCERT, mwpS3::$sslCert);
1768
+ if (mwpS3::$sslCACert !== null) curl_setopt($curl, CURLOPT_CAINFO, mwpS3::$sslCACert);
1769
+ }
1770
+
1771
+ curl_setopt($curl, CURLOPT_URL, $url);
1772
+
1773
+ if (mwpS3::$proxy != null && isset(mwpS3::$proxy['host']))
1774
+ {
1775
+ curl_setopt($curl, CURLOPT_PROXY, mwpS3::$proxy['host']);
1776
+ curl_setopt($curl, CURLOPT_PROXYTYPE, mwpS3::$proxy['type']);
1777
+ if (isset(mwpS3::$proxy['user'], mwpS3::$proxy['pass']) && $proxy['user'] != null && $proxy['pass'] != null)
1778
+ curl_setopt($curl, CURLOPT_PROXYUSERPWD, sprintf('%s:%s', mwpS3::$proxy['user'], mwpS3::$proxy['pass']));
1779
+ }
1780
+
1781
+ // Headers
1782
+ $headers = array(); $amz = array();
1783
+ foreach ($this->amzHeaders as $header => $value)
1784
+ if (strlen($value) > 0) $headers[] = $header.': '.$value;
1785
+ foreach ($this->headers as $header => $value)
1786
+ if (strlen($value) > 0) $headers[] = $header.': '.$value;
1787
+
1788
+ // Collect AMZ headers for signature
1789
+ foreach ($this->amzHeaders as $header => $value)
1790
+ if (strlen($value) > 0) $amz[] = strtolower($header).':'.$value;
1791
+
1792
+ // AMZ headers must be sorted
1793
+ if (sizeof($amz) > 0)
1794
+ {
1795
+ sort($amz);
1796
+ $amz = "\n".implode("\n", $amz);
1797
+ } else $amz = '';
1798
+
1799
+ if (mwpS3::hasAuth())
1800
+ {
1801
+ // Authorization string (CloudFront stringToSign should only contain a date)
1802
+ if ($this->headers['Host'] == 'cloudfront.amazonaws.com')
1803
+ $headers[] = 'Authorization: ' . mwpS3::__getSignature($this->headers['Date']);
1804
+ else
1805
+ {
1806
+ $headers[] = 'Authorization: ' . mwpS3::__getSignature(
1807
+ $this->verb."\n".
1808
+ $this->headers['Content-MD5']."\n".
1809
+ $this->headers['Content-Type']."\n".
1810
+ $this->headers['Date'].$amz."\n".
1811
+ $this->resource
1812
+ );
1813
+ }
1814
+ }
1815
+
1816
+ curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
1817
+ curl_setopt($curl, CURLOPT_HEADER, false);
1818
+ curl_setopt($curl, CURLOPT_RETURNTRANSFER, false);
1819
+ curl_setopt($curl, CURLOPT_WRITEFUNCTION, array(&$this, '__responseWriteCallback'));
1820
+ curl_setopt($curl, CURLOPT_HEADERFUNCTION, array(&$this, '__responseHeaderCallback'));
1821
+ curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
1822
+
1823
+ // Request types
1824
+ switch ($this->verb)
1825
+ {
1826
+ case 'GET': break;
1827
+ case 'PUT': case 'POST': // POST only used for CloudFront
1828
+ if ($this->fp !== false)
1829
+ {
1830
+ curl_setopt($curl, CURLOPT_PUT, true);
1831
+ curl_setopt($curl, CURLOPT_INFILE, $this->fp);
1832
+ if ($this->size >= 0)
1833
+ curl_setopt($curl, CURLOPT_INFILESIZE, $this->size);
1834
+ }
1835
+ elseif ($this->data !== false)
1836
+ {
1837
+ curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $this->verb);
1838
+ curl_setopt($curl, CURLOPT_POSTFIELDS, $this->data);
1839
+ }
1840
+ else
1841
+ curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $this->verb);
1842
+ break;
1843
+ case 'HEAD':
1844
+ curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'HEAD');
1845
+ curl_setopt($curl, CURLOPT_NOBODY, true);
1846
+ break;
1847
+ case 'DELETE':
1848
+ curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'DELETE');
1849
+ break;
1850
+ default: break;
1851
+ }
1852
+
1853
+ // Execute, grab errors
1854
+ if (curl_exec($curl))
1855
+ $this->response->code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
1856
+ else
1857
+ $this->response->error = array(
1858
+ 'code' => curl_errno($curl),
1859
+ 'message' => curl_error($curl),
1860
+ 'resource' => $this->resource
1861
+ );
1862
+
1863
+ @curl_close($curl);
1864
+
1865
+ // Parse body into XML
1866
+ if ($this->response->error === false && isset($this->response->headers['type']) &&
1867
+ $this->response->headers['type'] == 'application/xml' && isset($this->response->body))
1868
+ {
1869
+ $this->response->body = simplexml_load_string($this->response->body);
1870
+
1871
+ // Grab S3 errors
1872
+ if (!in_array($this->response->code, array(200, 204, 206)) &&
1873
+ isset($this->response->body->Code, $this->response->body->Message))
1874
+ {
1875
+ $this->response->error = array(
1876
+ 'code' => (string)$this->response->body->Code,
1877
+ 'message' => (string)$this->response->body->Message
1878
+ );
1879
+ if (isset($this->response->body->Resource))
1880
+ $this->response->error['resource'] = (string)$this->response->body->Resource;
1881
+ unset($this->response->body);
1882
+ }
1883
+ }
1884
+
1885
+ // Clean up file resources
1886
+ if ($this->fp !== false && is_resource($this->fp)) fclose($this->fp);
1887
+
1888
+ return $this->response;
1889
+ }
1890
+
1891
+
1892
+ /**
1893
+ * CURL write callback
1894
+ *
1895
+ * @param resource &$curl CURL resource
1896
+ * @param string &$data Data
1897
+ * @return integer
1898
+ */
1899
+ private function __responseWriteCallback(&$curl, &$data)
1900
+ {
1901
+ if (in_array($this->response->code, array(200, 206)) && $this->fp !== false)
1902
+ return fwrite($this->fp, $data);
1903
+ else
1904
+ $this->response->body .= $data;
1905
+ return strlen($data);
1906
+ }
1907
+
1908
+
1909
+ /**
1910
+ * Check DNS conformity
1911
+ *
1912
+ * @param string $bucket Bucket name
1913
+ * @return boolean
1914
+ */
1915
+ private function __dnsBucketName($bucket)
1916
+ {
1917
+ if (strlen($bucket) > 63 || !preg_match("/[^a-z0-9\.-]/", $bucket)) return false;
1918
+ if (strstr($bucket, '-.') !== false) return false;
1919
+ if (strstr($bucket, '..') !== false) return false;
1920
+ if (!preg_match("/^[0-9a-z]/", $bucket)) return false;
1921
+ if (!preg_match("/[0-9a-z]$/", $bucket)) return false;
1922
+ return true;
1923
+ }
1924
+
1925
+
1926
+ /**
1927
+ * CURL header callback
1928
+ *
1929
+ * @param resource &$curl CURL resource
1930
+ * @param string &$data Data
1931
+ * @return integer
1932
+ */
1933
+ private function __responseHeaderCallback(&$curl, &$data)
1934
+ {
1935
+ if (($strlen = strlen($data)) <= 2) return $strlen;
1936
+ if (substr($data, 0, 4) == 'HTTP')
1937
+ $this->response->code = (int)substr($data, 9, 3);
1938
+ else
1939
+ {
1940
+ $data = trim($data);
1941
+ if (strpos($data, ': ') === false) return $strlen;
1942
+ list($header, $value) = explode(': ', $data, 2);
1943
+ if ($header == 'Last-Modified')
1944
+ $this->response->headers['time'] = strtotime($value);
1945
+ elseif ($header == 'Content-Length')
1946
+ $this->response->headers['size'] = (int)$value;
1947
+ elseif ($header == 'Content-Type')
1948
+ $this->response->headers['type'] = $value;
1949
+ elseif ($header == 'ETag')
1950
+ $this->response->headers['hash'] = $value{0} == '"' ? substr($value, 1, -1) : $value;
1951
+ elseif (preg_match('/^x-amz-meta-.*$/', $header))
1952
+ $this->response->headers[$header] = is_numeric($value) ? (int)$value : $value;
1953
+ }
1954
+ return $strlen;
1955
+ }
1956
+
1957
+ }
1958
+
1959
+ class mwpS3Exception extends Exception {
1960
+ function __construct($message, $file, $line, $code = 0)
1961
+ {
1962
+ parent::__construct($message, $code);
1963
+ $this->file = $file;
1964
+ $this->line = $line;
1965
+ }
1966
+ }
link.class.php CHANGED
@@ -1,61 +1,61 @@
1
- <?php
2
- /*************************************************************
3
- *
4
- * user.class.php
5
- *
6
- * Add Users
7
- *
8
- *
9
- * Copyright (c) 2011 Prelovac Media
10
- * www.prelovac.com
11
- **************************************************************/
12
-
13
- class MMB_Link extends MMB_Core
14
- {
15
- function __construct()
16
- {
17
- parent::__construct();
18
- }
19
-
20
- function add_link($args)
21
- {
22
- extract($args);
23
-
24
- $params['link_url'] = esc_html($url);
25
- $params['link_url'] = esc_url($params['link_url']);
26
- $params['link_name'] = esc_html($name);
27
- $params['link_id'] = '';
28
- $params['link_description'] = $description;
29
- $params['link_target'] = $link_target;
30
- $params['link_category'] = array();
31
-
32
- //Add Link category
33
- if(is_array($link_category) && !empty($link_category)){
34
- $terms = get_terms('link_category',array('hide_empty' => 0));
35
-
36
- if($terms){
37
- foreach($terms as $term){
38
- if(in_array($term->name,$link_category)){
39
- $params['link_category'][] = $term->term_id;
40
- }
41
- }
42
- }
43
- }
44
-
45
- //Add Link Owner
46
- $user_obj = get_userdatabylogin($user);
47
- if($user_obj && $user_obj->ID){
48
- $params['link_owner'] = $user_obj->ID;
49
- }
50
-
51
-
52
- if(!function_exists('wp_insert_link'))
53
- include_once (ABSPATH . 'wp-admin/includes/bookmark.php');
54
-
55
- $is_success = wp_insert_link($params);
56
-
57
- return $is_success ? true : array('error' => 'Failed to add link.');
58
- }
59
-
60
- }
61
  ?>
1
+ <?php
2
+ /*************************************************************
3
+ *
4
+ * user.class.php
5
+ *
6
+ * Add Users
7
+ *
8
+ *
9
+ * Copyright (c) 2011 Prelovac Media
10
+ * www.prelovac.com
11
+ **************************************************************/
12
+
13
+ class MMB_Link extends MMB_Core
14
+ {
15
+ function __construct()
16
+ {
17
+ parent::__construct();
18
+ }
19
+
20
+ function add_link($args)
21
+ {
22
+ extract($args);
23
+
24
+ $params['link_url'] = esc_html($url);
25
+ $params['link_url'] = esc_url($params['link_url']);
26
+ $params['link_name'] = esc_html($name);
27
+ $params['link_id'] = '';
28
+ $params['link_description'] = $description;
29
+ $params['link_target'] = $link_target;
30
+ $params['link_category'] = array();
31
+
32
+ //Add Link category
33
+ if(is_array($link_category) && !empty($link_category)){
34
+ $terms = get_terms('link_category',array('hide_empty' => 0));
35
+
36
+ if($terms){
37
+ foreach($terms as $term){
38
+ if(in_array($term->name,$link_category)){
39
+ $params['link_category'][] = $term->term_id;
40
+ }
41
+ }
42
+ }
43
+ }
44
+
45
+ //Add Link Owner
46
+ $user_obj = get_userdatabylogin($user);
47
+ if($user_obj && $user_obj->ID){
48
+ $params['link_owner'] = $user_obj->ID;
49
+ }
50
+
51
+
52
+ if(!function_exists('wp_insert_link'))
53
+ include_once (ABSPATH . 'wp-admin/includes/bookmark.php');
54
+
55
+ $is_success = wp_insert_link($params);
56
+
57
+ return $is_success ? true : array('error' => 'Failed to add link.');
58
+ }
59
+
60
+ }
61
  ?>
plugins/cleanup/cleanup.php CHANGED
@@ -1,189 +1,189 @@
1
- <?php
2
- /*************************************************************
3
- *
4
- *
5
- *
6
- * ManageWP Worker Plugin
7
- *
8
- *
9
- * Copyright (c) 2011 Prelovac Media
10
- * www.prelovac.com
11
- **************************************************************/
12
-
13
- add_filter('mmb_stats_filter', 'mmb_get_extended_info');
14
-
15
-
16
- function mmb_get_extended_info($stats)
17
- {
18
- $stats['num_revisions'] = mmb_num_revisions();
19
- //$stats['num_revisions'] = 5;
20
- $stats['overhead'] = mmb_handle_overhead(false);
21
- $stats['num_spam_comments'] = mmb_num_spam_comments();
22
- return $stats;
23
- }
24
-
25
- /* Revisions */
26
-
27
- mmb_add_action('cleanup_delete', 'cleanup_delete_worker');
28
-
29
- function cleanup_delete_worker($params = array())
30
- {
31
- global $mmb_core;
32
-
33
- $params_array = explode('_', $params['actions']);
34
- $return_array = array();
35
- foreach ($params_array as $param) {
36
- switch ($param) {
37
- case 'revision':
38
- if (mmb_delete_all_revisions()) {
39
- $return_array['revision'] = 'OK';
40
- } else {
41
- $return_array['revision_error'] = 'Failed, please try again';
42
- }
43
- break;
44
- case 'overhead':
45
- if (mmb_handle_overhead(true)) {
46
- $return_array['overhead'] = 'OK';
47
- } else {
48
- $return_array['overhead_error'] = 'Failed, please try again';
49
- }
50
- break;
51
- case 'comment':
52
- if (mmb_delete_spam_comments()) {
53
- $return_array['comment'] = 'OK';
54
- } else {
55
- $return_array['comment_error'] = 'Failed, please try again';
56
- }
57
- break;
58
- default:
59
- break;
60
- }
61
-
62
- }
63
-
64
- unset($params);
65
-
66
- mmb_response($return_array, true);
67
- }
68
-
69
- function mmb_num_revisions()
70
- {
71
- global $wpdb;
72
- $sql = "SELECT COUNT(*) FROM $wpdb->posts WHERE post_type = 'revision'";
73
- $num_revisions = $wpdb->get_var($wpdb->prepare($sql));
74
- return $num_revisions;
75
- }
76
-
77
- function mmb_select_all_revisions()
78
- {
79
- global $wpdb;
80
- $sql = "SELECT * FROM $wpdb->posts WHERE post_type = 'revision'";
81
- $revisions = $wpdb->get_results($wpdb->prepare($sql));
82
- return $revisions;
83
- }
84
-
85
- function mmb_delete_all_revisions()
86
- {
87
- global $wpdb;
88
- $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'";
89
- $revisions = $wpdb->query($wpdb->prepare($sql));
90
-
91
- return $revisions;
92
- }
93
-
94
-
95
-
96
-
97
-
98
- /* Optimize */
99
-
100
- function mmb_handle_overhead($clear = false)
101
- {
102
- global $wpdb, $mmb_core;
103
- $tot_data = 0;
104
- $tot_idx = 0;
105
- $tot_all = 0;
106
- $query = 'SHOW TABLE STATUS FROM ' . DB_NAME;
107
- $tables = $wpdb->get_results($wpdb->prepare($query), ARRAY_A);
108
- $total_gain = 0;
109
- $table_string = '';
110
- foreach ($tables as $table) {
111
- if (in_array($table['Engine'], array(
112
- 'MyISAM',
113
- 'ISAM',
114
- 'HEAP',
115
- 'MEMORY',
116
- 'ARCHIVE'
117
- ))) {
118
- if ($wpdb->base_prefix != $wpdb->prefix) {
119
- if (preg_match('/^' . $wpdb->prefix . '*/Ui', $table['Name'])) {
120
- if ($table['Data_free'] > 0) {
121
- $total_gain += $table['Data_free'] / 1024;
122
- $table_string .= $table['Name'] . ",";
123
- }
124
- }
125
- } else if (preg_match('/^' . $wpdb->prefix . '[0-9]{1,20}_*/Ui', $table['Name'])) {
126
- continue;
127
- } else {
128
- if ($table['Data_free'] > 0) {
129
- $total_gain += $table['Data_free'] / 1024;
130
- $table_string .= $table['Name'] . ",";
131
- }
132
- }
133
- } elseif ($table['Engine'] == 'InnoDB') {
134
- //$total_gain += $table['Data_free'] > 100*1024*1024 ? $table['Data_free'] / 1024 : 0;
135
- }
136
- }
137
-
138
- if ($clear) {
139
- $table_string = substr($table_string, 0, strlen($table_string) - 1); //remove last ,
140
-
141
- $table_string = rtrim($table_string);
142
-
143
- $query = "OPTIMIZE TABLE $table_string";
144
-
145
- $optimize = $wpdb->query($query);
146
-
147
- return $optimize === FALSE ? false : true;
148
- } else
149
- return round($total_gain, 3);
150
- }
151
-
152
-
153
-
154
-
155
- /* Spam Comments */
156
-
157
- function mmb_num_spam_comments()
158
- {
159
- global $wpdb;
160
- $sql = "SELECT COUNT(*) FROM $wpdb->comments WHERE comment_approved = 'spam'";
161
- $num_spams = $wpdb->get_var($wpdb->prepare($sql));
162
- return $num_spams;
163
- }
164
-
165
- function mmb_delete_spam_comments()
166
- {
167
- global $wpdb;
168
- $spams = 1;
169
- $total = 0;
170
- while ($spams) {
171
- $sql = "DELETE FROM $wpdb->comments WHERE comment_approved = 'spam' LIMIT 200";
172
- $spams = $wpdb->query($wpdb->prepare($sql));
173
- $total += $spams;
174
- if ($spams)
175
- usleep(100000);
176
- }
177
- return $total;
178
- }
179
-
180
-
181
- function mmb_get_spam_comments()
182
- {
183
- global $wpdb;
184
- $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'";
185
- $spams = $wpdb->get_results($wpdb->prepare($sql));
186
- return $spams;
187
- }
188
-
189
  ?>
1
+ <?php
2
+ /*************************************************************
3
+ *
4
+ *
5
+ *
6
+ * ManageWP Worker Plugin
7
+ *
8
+ *
9
+ * Copyright (c) 2011 Prelovac Media
10
+ * www.prelovac.com
11
+ **************************************************************/
12
+
13
+ add_filter('mmb_stats_filter', 'mmb_get_extended_info');
14
+
15
+
16
+ function mmb_get_extended_info($stats)
17
+ {
18
+ $stats['num_revisions'] = mmb_num_revisions();
19
+ //$stats['num_revisions'] = 5;
20
+ $stats['overhead'] = mmb_handle_overhead(false);
21
+ $stats['num_spam_comments'] = mmb_num_spam_comments();
22
+ return $stats;
23
+ }
24
+
25
+ /* Revisions */
26
+
27
+ mmb_add_action('cleanup_delete', 'cleanup_delete_worker');
28
+
29
+ function cleanup_delete_worker($params = array())
30
+ {
31
+ global $mmb_core;
32
+
33
+ $params_array = explode('_', $params['actions']);
34
+ $return_array = array();
35
+ foreach ($params_array as $param) {
36
+ switch ($param) {
37
+ case 'revision':
38
+ if (mmb_delete_all_revisions()) {
39
+ $return_array['revision'] = 'OK';
40
+ } else {
41
+ $return_array['revision_error'] = 'Failed, please try again';
42
+ }
43
+ break;
44
+ case 'overhead':
45
+ if (mmb_handle_overhead(true)) {
46
+ $return_array['overhead'] = 'OK';
47
+ } else {
48
+ $return_array['overhead_error'] = 'Failed, please try again';
49
+ }
50
+ break;
51
+ case 'comment':
52
+ if (mmb_delete_spam_comments()) {
53
+ $return_array['comment'] = 'OK';
54
+ } else {
55
+ $return_array['comment_error'] = 'Failed, please try again';
56
+ }
57
+ break;
58
+ default:
59
+ break;
60
+ }
61
+
62
+ }
63
+
64
+ unset($params);
65
+
66
+ mmb_response($return_array, true);
67
+ }
68
+
69
+ function mmb_num_revisions()
70
+ {
71
+ global $wpdb;
72
+ $sql = "SELECT COUNT(*) FROM $wpdb->posts WHERE post_type = 'revision'";
73
+ $num_revisions = $wpdb->get_var($wpdb->prepare($sql));
74
+ return $num_revisions;
75
+ }
76
+
77
+ function mmb_select_all_revisions()
78
+ {
79
+ global $wpdb;
80
+ $sql = "SELECT * FROM $wpdb->posts WHERE post_type = 'revision'";
81
+ $revisions = $wpdb->get_results($wpdb->prepare($sql));
82
+ return $revisions;
83
+ }
84
+
85
+ function mmb_delete_all_revisions()
86
+ {
87
+ global $wpdb;
88
+ $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'";
89
+ $revisions = $wpdb->query($wpdb->prepare($sql));
90
+
91
+ return $revisions;
92
+ }
93
+
94
+
95
+
96
+
97
+
98
+ /* Optimize */
99
+
100
+ function mmb_handle_overhead($clear = false)
101
+ {
102
+ global $wpdb, $mmb_core;
103
+ $tot_data = 0;
104
+ $tot_idx = 0;
105
+ $tot_all = 0;
106
+ $query = 'SHOW TABLE STATUS FROM ' . DB_NAME;
107
+ $tables = $wpdb->get_results($wpdb->prepare($query), ARRAY_A);
108
+ $total_gain = 0;
109
+ $table_string = '';
110
+ foreach ($tables as $table) {
111
+ if (in_array($table['Engine'], array(
112
+ 'MyISAM',
113
+ 'ISAM',
114
+ 'HEAP',
115
+ 'MEMORY',
116
+ 'ARCHIVE'
117
+ ))) {
118
+ if ($wpdb->base_prefix != $wpdb->prefix) {
119
+ if (preg_match('/^' . $wpdb->prefix . '*/Ui', $table['Name'])) {
120
+ if ($table['Data_free'] > 0) {
121
+ $total_gain += $table['Data_free'] / 1024;
122
+ $table_string .= $table['Name'] . ",";
123
+ }
124
+ }
125
+ } else if (preg_match('/^' . $wpdb->prefix . '[0-9]{1,20}_*/Ui', $table['Name'])) {
126
+ continue;
127
+ } else {
128
+ if ($table['Data_free'] > 0) {
129
+ $total_gain += $table['Data_free'] / 1024;
130
+ $table_string .= $table['Name'] . ",";
131
+ }
132
+ }
133
+ } elseif ($table['Engine'] == 'InnoDB') {
134
+ //$total_gain += $table['Data_free'] > 100*1024*1024 ? $table['Data_free'] / 1024 : 0;
135
+ }
136
+ }
137
+
138
+ if ($clear) {
139
+ $table_string = substr($table_string, 0, strlen($table_string) - 1); //remove last ,
140
+
141
+ $table_string = rtrim($table_string);
142
+
143
+ $query = "OPTIMIZE TABLE $table_string";
144
+
145
+ $optimize = $wpdb->query($query);
146
+
147
+ return $optimize === FALSE ? false : true;
148
+ } else
149
+ return round($total_gain, 3);
150
+ }
151
+
152
+
153
+
154
+
155
+ /* Spam Comments */
156
+
157
+ function mmb_num_spam_comments()
158
+ {
159
+ global $wpdb;
160
+ $sql = "SELECT COUNT(*) FROM $wpdb->comments WHERE comment_approved = 'spam'";
161
+ $num_spams = $wpdb->get_var($wpdb->prepare($sql));
162
+ return $num_spams;
163
+ }
164
+
165
+ function mmb_delete_spam_comments()
166
+ {
167
+ global $wpdb;
168
+ $spams = 1;
169
+ $total = 0;
170
+ while ($spams) {
171
+ $sql = "DELETE FROM $wpdb->comments WHERE comment_approved = 'spam' LIMIT 200";
172
+ $spams = $wpdb->query($wpdb->prepare($sql));
173
+ $total += $spams;
174
+ if ($spams)
175
+ usleep(100000);
176
+ }
177
+ return $total;
178
+ }
179
+
180
+
181
+ function mmb_get_spam_comments()
182
+ {
183
+ global $wpdb;
184
+ $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'";
185
+ $spams = $wpdb->get_results($wpdb->prepare($sql));
186
+ return $spams;
187
+ }
188
+
189
  ?>
plugins/extra_html_example/extra_html_example.php CHANGED
@@ -1,18 +1,18 @@
1
- <?php
2
-
3
- // add filter for the stats structure
4
- add_filter('mmb_stats_filter', mmb_extra_html_example);
5
-
6
- function mmb_extra_html_example($stats)
7
- {
8
- $count_posts = wp_count_posts();
9
-
10
- $published_posts = $count_posts->publish;
11
-
12
- // add 'extra_html' element. This is what gets displayed in the dashboard
13
- $stats['extra_html'] = '<p>Hello from '.get_bloginfo('name').' with '.$published_posts.' published posts.</p>';
14
-
15
- // return the whole array back
16
- return $stats;
17
- }
18
  ?>
1
+ <?php
2
+
3
+ // add filter for the stats structure
4
+ add_filter('mmb_stats_filter', mmb_extra_html_example);
5
+
6
+ function mmb_extra_html_example($stats)
7
+ {
8
+ $count_posts = wp_count_posts();
9
+
10
+ $published_posts = $count_posts->publish;
11
+
12
+ // add 'extra_html' element. This is what gets displayed in the dashboard
13
+ $stats['extra_html'] = '<p>Hello from '.get_bloginfo('name').' with '.$published_posts.' published posts.</p>';
14
+
15
+ // return the whole array back
16
+ return $stats;
17
+ }
18
  ?>
plugins/search/search.php CHANGED
@@ -1,130 +1,130 @@
1
- <?php
2
- /*************************************************************
3
- *
4
- * stats.class.php
5
- *
6
- * Various searches on worker
7
- *
8
- *
9
- * Copyright (c) 2011 Prelovac Media
10
- * www.prelovac.com
11
- **************************************************************/
12
-
13
- mmb_add_action('search_posts_by_term', 'search_posts_by_term');
14
-
15
- function search_posts_by_term($params = false){
16
-
17
- global $wpdb, $current_user;
18
-
19
- $search_type = trim($params['search_type']);
20
- $search_term = strtolower(trim($params['search_term']));
21
- switch ($search_type){
22
- case 'page_post':
23
- $num_posts = 10;
24
- $num_content_char = 30;
25
-
26
- $term_orig = trim($params['search_term']);
27
-
28
- $term_base= addslashes(trim($params['search_term']));
29
-
30
- $query = "SELECT *
31
- FROM $wpdb->posts
32
- WHERE $wpdb->posts.post_status = 'publish'
33
- AND ($wpdb->posts.post_title LIKE '%$term_base%'
34
- OR $wpdb->posts.post_content LIKE '%$term_base%')
35
- ORDER BY $wpdb->posts.post_modified DESC
36
- LIMIT 0, $num_posts
37
- ";
38
-
39
- $posts_array = $wpdb->get_results($query);
40
-
41
- $ret_posts = array();
42
-
43
- foreach($posts_array as $post){
44
- //highlight searched term
45
-
46
- if (substr_count(strtolower($post->post_title), strtolower($term_orig))){
47
- $str_position_start = strpos(strtolower($post->post_title), strtolower($term_orig));
48
-
49
- $post->post_title = substr($post->post_title, 0, $str_position_start).'<b>'.
50
- substr($post->post_title, $str_position_start, strlen($term_orig)).'</b>'.
51
- substr($post->post_title, $str_position_start + strlen($term_orig));
52
-
53
- }
54
- $post->post_content = html_entity_decode($post->post_content);
55
-
56
- $post->post_content = strip_tags($post->post_content);
57
-
58
-
59
-
60
- if (substr_count(strtolower($post->post_content), strtolower($term_orig))){
61
- $str_position_start = strpos(strtolower($post->post_content), strtolower($term_orig));
62
-
63
- $start = $str_position_start > $num_content_char ? $str_position_start - $num_content_char: 0;
64
- $first_len = $str_position_start > $num_content_char? $num_content_char : $str_position_start;
65
-
66
- $start_substring = $start>0 ? '...' : '';
67
- $post->post_content = $start_substring . substr($post->post_content, $start, $first_len).'<b>'.
68
- substr($post->post_content, $str_position_start, strlen($term_orig)).'</b>'.
69
- substr($post->post_content, $str_position_start + strlen($term_orig), $num_content_char) . '...';
70
-
71
-
72
- }else{
73
- $post->post_content = substr($post->post_content,0, 50). '...';
74
- }
75
-
76
- $ret_posts[] = array(
77
- 'ID' => $post->ID
78
- ,'post_permalink' => get_permalink($post->ID)
79
- ,'post_date' => $post->post_date
80
- ,'post_title' => $post->post_title
81
- ,'post_content' => $post->post_content
82
- ,'post_modified' => $post->post_modified
83
- ,'comment_count' => $post->comment_count
84
-
85
-
86
- );
87
- }
88
- mmb_response($ret_posts, true);
89
- break;
90
-
91
- case 'plugin':
92
- $plugins = get_option('active_plugins');
93
-
94
- if(!function_exists('get_plugin_data'))
95
- include_once( ABSPATH.'/wp-admin/includes/plugin.php');
96
-
97
- $have_plugin = array();
98
- foreach ($plugins as $plugin) {
99
- $pl = WP_PLUGIN_DIR . '/' . $plugin ;
100
- $pl_extended = get_plugin_data($pl);
101
- $pl_name = $pl_extended['Name'];
102
- if(strpos(strtolower($pl_name), $search_term)>-1){
103
-
104
- $have_plugin[] = $pl_name;
105
- }
106
- }
107
- if($have_plugin){
108
- mmb_response($have_plugin, true);
109
- }else{
110
- mmb_response('Not found', false);
111
- }
112
- break;
113
- case 'theme':
114
- $theme = strtolower(get_option('stylesheet'));
115
- $tm = ABSPATH . 'wp-content/themes/'. $theme . '/style.css' ;
116
- $tm_extended = get_theme_data($tm);
117
- $tm_name = $tm_extended['Name'];
118
- $have_theme = array();
119
- if(strpos(strtolower($tm_name), $search_term)>-1){
120
- $have_theme[] = $tm_name;
121
- mmb_response($have_theme, true);
122
- }else{
123
- mmb_response('Not found', false);
124
- }
125
- break;
126
- default: mmb_response('Not found', false);
127
- }
128
- }
129
-
130
  ?>
1
+ <?php
2
+ /*************************************************************
3
+ *
4
+ * stats.class.php
5
+ *
6
+ * Various searches on worker
7
+ *
8
+ *
9
+ * Copyright (c) 2011 Prelovac Media
10
+ * www.prelovac.com
11
+ **************************************************************/
12
+
13
+ mmb_add_action('search_posts_by_term', 'search_posts_by_term');
14
+
15
+ function search_posts_by_term($params = false){
16
+
17
+ global $wpdb, $current_user;
18
+
19
+ $search_type = trim($params['search_type']);
20
+ $search_term = strtolower(trim($params['search_term']));
21
+ switch ($search_type){
22
+ case 'page_post':
23
+ $num_posts = 10;
24
+ $num_content_char = 30;
25
+
26
+ $term_orig = trim($params['search_term']);
27
+
28
+ $term_base= addslashes(trim($params['search_term']));
29
+
30
+ $query = "SELECT *
31
+ FROM $wpdb->posts
32
+ WHERE $wpdb->posts.post_status = 'publish'
33
+ AND ($wpdb->posts.post_title LIKE '%$term_base%'
34
+ OR $wpdb->posts.post_content LIKE '%$term_base%')
35
+ ORDER BY $wpdb->posts.post_modified DESC
36
+ LIMIT 0, $num_posts
37
+ ";
38
+
39
+ $posts_array = $wpdb->get_results($query);
40
+
41
+ $ret_posts = array();
42
+
43
+ foreach($posts_array as $post){
44
+ //highlight searched term
45
+
46
+ if (substr_count(strtolower($post->post_title), strtolower($term_orig))){
47
+ $str_position_start = strpos(strtolower($post->post_title), strtolower($term_orig));
48
+
49
+ $post->post_title = substr($post->post_title, 0, $str_position_start).'<b>'.
50
+ substr($post->post_title, $str_position_start, strlen($term_orig)).'</b>'.
51
+ substr($post->post_title, $str_position_start + strlen($term_orig));
52
+
53
+ }
54
+ $post->post_content = html_entity_decode($post->post_content);
55
+
56
+ $post->post_content = strip_tags($post->post_content);
57
+
58
+
59
+
60
+ if (substr_count(strtolower($post->post_content), strtolower($term_orig))){
61
+ $str_position_start = strpos(strtolower($post->post_content), strtolower($term_orig));
62
+
63
+ $start = $str_position_start > $num_content_char ? $str_position_start - $num_content_char: 0;
64
+ $first_len = $str_position_start > $num_content_char? $num_content_char : $str_position_start;
65
+
66
+ $start_substring = $start>0 ? '...' : '';
67
+ $post->post_content = $start_substring . substr($post->post_content, $start, $first_len).'<b>'.
68
+ substr($post->post_content, $str_position_start, strlen($term_orig)).'</b>'.
69
+ substr($post->post_content, $str_position_start + strlen($term_orig), $num_content_char) . '...';
70
+
71
+
72
+ }else{
73
+ $post->post_content = substr($post->post_content,0, 50). '...';
74
+ }
75
+
76
+ $ret_posts[] = array(
77
+ 'ID' => $post->ID
78
+ ,'post_permalink' => get_permalink($post->ID)
79
+ ,'post_date' => $post->post_date
80
+ ,'post_title' => $post->post_title
81
+ ,'post_content' => $post->post_content
82
+ ,'post_modified' => $post->post_modified
83
+ ,'comment_count' => $post->comment_count
84
+
85
+
86
+ );
87
+ }
88
+ mmb_response($ret_posts, true);
89
+ break;
90
+
91
+ case 'plugin':
92
+ $plugins = get_option('active_plugins');
93
+
94
+ if(!function_exists('get_plugin_data'))
95
+ include_once( ABSPATH.'/wp-admin/includes/plugin.php');
96
+
97
+ $have_plugin = array();
98
+ foreach ($plugins as $plugin) {
99
+ $pl = WP_PLUGIN_DIR . '/' . $plugin ;
100
+ $pl_extended = get_plugin_data($pl);
101
+ $pl_name = $pl_extended['Name'];
102
+ if(strpos(strtolower($pl_name), $search_term)>-1){
103
+
104
+ $have_plugin[] = $pl_name;
105
+ }
106
+ }
107
+ if($have_plugin){
108
+ mmb_response($have_plugin, true);
109
+ }else{
110
+ mmb_response('Not found', false);
111
+ }
112
+ break;
113
+ case 'theme':
114
+ $theme = strtolower(get_option('stylesheet'));
115
+ $tm = ABSPATH . 'wp-content/themes/'. $theme . '/style.css' ;
116
+ $tm_extended = get_theme_data($tm);
117
+ $tm_name = $tm_extended['Name'];
118
+ $have_theme = array();
119
+ if(strpos(strtolower($tm_name), $search_term)>-1){
120
+ $have_theme[] = $tm_name;
121
+ mmb_response($have_theme, true);
122
+ }else{
123
+ mmb_response('Not found', false);
124
+ }
125
+ break;
126
+ default: mmb_response('Not found', false);
127
+ }
128
+ }
129
+
130
  ?>
post.class.php CHANGED
@@ -1,378 +1,617 @@
1
- <?php
2
- /*************************************************************
3
- *
4
- * post.class.php
5
- *
6
- * Create remote post
7
- *
8
- *
9
- * Copyright (c) 2011 Prelovac Media
10
- * www.prelovac.com
11
- **************************************************************/
12
-
13
- class MMB_Post extends MMB_Core
14
- {
15
- function __construct()
16
- {
17
- parent::__construct();
18
- }
19
-
20
- function create($args)
21
- {
22
-
23
- /**
24
- * algorithm
25
- * 1. create post using wp_insert_post (insert tags also here itself)
26
- * 2. use wp_create_categories() to create(not exists) and insert in the post
27
- * 3. insert meta values
28
- */
29
-
30
- include_once ABSPATH . 'wp-admin/includes/taxonomy.php';
31
- include_once ABSPATH . 'wp-admin/includes/image.php';
32
- include_once ABSPATH . 'wp-admin/includes/file.php';
33
-
34
- $post_struct = $args['post_data'];
35
-
36
- $post_data = $post_struct['post_data'];
37
- $new_custom = $post_struct['post_extras']['post_meta'];
38
- $post_categories = explode(',', $post_struct['post_extras']['post_categories']);
39
- $post_atta_img = $post_struct['post_extras']['post_atta_images'];
40
- $post_upload_dir = $post_struct['post_extras']['post_upload_dir'];
41
- $post_checksum = $post_struct['post_extras']['post_checksum'];
42
- $post_featured_img = $post_struct['post_extras']['featured_img'];
43
-
44
- $upload = wp_upload_dir();
45
-
46
- // create dynamic url RegExp
47
- $mwp_base_url = parse_url($post_upload_dir['url']);
48
- $mwp_regexp_url = $mwp_base_url['host'] . $mwp_base_url['path'];
49
- $rep = array(
50
- '/',
51
- '+',
52
- '.',
53
- ':',
54
- '?'
55
- );
56
- $with = array(
57
- '\/',
58
- '\+',
59
- '\.',
60
- '\:',
61
- '\?'
62
- );
63
- $mwp_regexp_url = str_replace($rep, $with, $mwp_regexp_url);
64
-
65
- // rename all src ../wp-content/ with hostname/wp-content/
66
- $mmb_dot_url = '..' . $mmb_base_url['path'];
67
- $mmb_dot_url = str_replace($rep, $with, $mmb_dot_url);
68
- $dot_match_count = preg_match_all('/(<a[^>]+href=\"([^"]+)\"[^>]*>)?(<\s*img.[^\/>]*src="([^"]*' . $mmb_dot_url . '[^\s]+\.(jpg|jpeg|png|gif|bmp))"[^>]*>)/ixu', $post_data['post_content'], $dot_get_urls, PREG_SET_ORDER);
69
- if ($dot_match_count > 0) {
70
- foreach ($dot_get_urls as $dot_url) {
71
- $match_dot = '/' . str_replace($rep, $with, $dot_url[4]) . '/';
72
- $replace_dot = 'http://' . $mmb_base_url['host'] . substr($dot_url[4], 2, strlen($dot_url[4]));
73
- $post_data['post_content'] = preg_replace($match_dot, $replace_dot, $post_data['post_content']);
74
-
75
- if ($dot_url[1] != '') {
76
- $match_dot_a = '/' . str_replace($rep, $with, $dot_url[2]) . '/';
77
- $replace_dot_a = 'http://' . $mmb_base_url['host'] . substr($dot_url[2], 2, strlen($dot_url[2]));
78
- $post_data['post_content'] = preg_replace($match_dot_a, $replace_dot_a, $post_data['post_content']);
79
- }
80
- }
81
- }
82
-
83
-
84
-
85
- //to find all the images
86
- $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);
87
- if ($match_count > 0) {
88
- $attachments = array();
89
- $post_content = $post_data['post_content'];
90
-
91
- foreach ($get_urls as $get_url_k => $get_url) {
92
- // unset url in attachment array
93
- foreach ($post_atta_img as $atta_url_k => $atta_url_v) {
94
- $match_patt_url = '/' . str_replace($rep, $with, substr($atta_url_v['src'], 0, strrpos($atta_url_v['src'], '.'))) . '/';
95
- if (preg_match($match_patt_url, $get_url[4])) {
96
- unset($post_atta_img[$atta_url_k]);
97
- }
98
- }
99
-
100
- if (isset($get_urls[$get_url_k][6])) { // url have parent, don't download this url
101
- if ($get_url[1] != '') {
102
- // change src url
103
- $s_mmb_mp = '/' . str_replace($rep, $with, $get_url[4]) . '/';
104
-
105
- $s_img_atta = wp_get_attachment_image_src($get_urls[$get_url_k][6]);
106
- $s_mmb_rp = $s_img_atta[0];
107
- $post_content = preg_replace($s_mmb_mp, $s_mmb_rp, $post_content);
108
- // change attachment url
109
- if (preg_match('/attachment_id/i', $get_url[2])) {
110
- $mmb_mp = '/' . str_replace($rep, $with, $get_url[2]) . '/';
111
- $mmb_rp = get_bloginfo('wpurl') . '/?attachment_id=' . $get_urls[$get_url_k][6];
112
- $post_content = preg_replace($mmb_mp, $mmb_rp, $post_content);
113
- }
114
- }
115
- continue;
116
- }
117
-
118
- $no_thumb = '';
119
- if (preg_match('/-\d{3}x\d{3}\.[a-zA-Z0-9]{3,4}$/', $get_url[4])) {
120
- $no_thumb = preg_replace('/-\d{3}x\d{3}\.[a-zA-Z0-9]{3,4}$/', '.' . $get_url[5], $get_url[4]);
121
- } else {
122
- $no_thumb = $get_url[4];
123
- }
124
-
125
- if(isset($upload['error']) && !empty($upload['error'])){
126
- return array('error' => $upload['error']);
127
- }
128
- $file_name = basename($no_thumb);
129
- $tmp_file = download_url($no_thumb);
130
-
131
- if(is_wp_error($tmp_file)){
132
- return array('error' => $tmp_file->get_error_message());
133
- }
134
-
135
- $attach_upload['url'] = $upload['url'] . '/' . $file_name;
136
- $attach_upload['path'] = $upload['path'] . '/' . $file_name;
137
- $renamed = @rename($tmp_file, $attach_upload['path']);
138
- if ($renamed === true) {
139
- $match_pattern = '/' . str_replace($rep, $with, $get_url[4]) . '/';
140
- $replace_pattern = $attach_upload['url'];
141
- $post_content = preg_replace($match_pattern, $replace_pattern, $post_content);
142
- if (preg_match('/-\d{3}x\d{3}\.[a-zA-Z0-9]{3,4}$/', $get_url[4])) {
143
- $match_pattern = '/' . str_replace($rep, $with, preg_replace('/-\d{3}x\d{3}\.[a-zA-Z0-9]{3,4}$/', '.' . $get_url[5], $get_url[4])) . '/';
144
- $post_content = preg_replace($match_pattern, $replace_pattern, $post_content);
145
- }
146
-
147
- $attachment = array(
148
- 'post_title' => $file_name,
149
- 'post_content' => '',
150
- 'post_type' => 'attachment',
151
- //'post_parent' => $post_id,
152
- 'post_mime_type' => 'image/' . $get_url[5],
153
- 'guid' => $attach_upload['url']
154
- );
155
-
156
- // Save the data
157
-
158
- $attach_id = wp_insert_attachment($attachment, $attach_upload['path']);
159
-
160
- $attachments[$attach_id] = 0;
161
-
162
- // featured image
163
- if ($post_featured_img != '') {
164
- $feat_img_url = '';
165
- if (preg_match('/-\d{3}x\d{3}\.[a-zA-Z0-9]{3,4}$/', $post_featured_img)) {
166
- $feat_img_url = substr($post_featured_img, 0, strrpos($post_featured_img, '.') - 8);
167
- } else {
168
- $feat_img_url = substr($post_featured_img, 0, strrpos($post_featured_img, '.'));
169
- }
170
- $m_feat_url = '/' . str_replace($rep, $with, $feat_img_url) . '/';
171
- if (preg_match($m_feat_url, $get_url[4])) {
172
- $post_featured_img = '';
173
- $attachments[$attach_id] = $attach_id;
174
- }
175
- }
176
-
177
- // set $get_urls value[6] - parent atta_id
178
- foreach ($get_urls as $url_k => $url_v) {
179
- if ($get_url_k != $url_k) {
180
- $s_get_url = '';
181
- if (preg_match('/-\d{3}x\d{3}\.[a-zA-Z0-9]{3,4}$/', $url_v[4])) {
182
- $s_get_url = substr($url_v[4], 0, strrpos($url_v[4], '.') - 8);
183
- } else {
184
- $s_get_url = substr($url_v[4], 0, strrpos($url_v[4], '.'));
185
- }
186
- $m_patt_url = '/' . str_replace($rep, $with, $s_get_url) . '/';
187
- if (preg_match($m_patt_url, $get_url[4])) {
188
- array_push($get_urls[$url_k], $attach_id);
189
- }
190
- }
191
- }
192
-
193
-
194
- $some_data = wp_generate_attachment_metadata($attach_id, $attach_upload['path']);
195
- wp_update_attachment_metadata($attach_id, $some_data);
196
-
197
-
198
- // changing href of a tag
199
- if ($get_url[1] != '') {
200
- $mmb_mp = '/' . str_replace($rep, $with, $get_url[2]) . '/';
201
- if (preg_match('/attachment_id/i', $get_url[2])) {
202
- $mmb_rp = get_bloginfo('wpurl') . '/?attachment_id=' . $attach_id;
203
- $post_content = preg_replace($mmb_mp, $mmb_rp, $post_content);
204
- }
205
- }
206
- } else {
207
- @unlink($tmp_file);
208
- return array('error' => "Cannot create attachment file in ".$attach_upload['path']." Please set correct permissions.");
209
-
210
- }
211
- @unlink($tmp_file);
212
- }
213
-
214
-
215
- $post_data['post_content'] = $post_content;
216
-
217
- }
218
- if (count($post_atta_img)) {
219
- foreach ($post_atta_img as $img) {
220
- $file_name = basename($img['src']);
221
-
222
- if(isset($upload['error']) && !empty($upload['error'])){
223
- return array('error' => $upload['error']);
224
- }
225
-
226
- $tmp_file = download_url($img['src']);
227
- if(is_wp_error($tmp_file)){
228
- return array('error' => $tmp_file->get_error_message());
229
- }
230
-
231
- $attach_upload['url'] = $upload['url'] . '/' . $file_name;
232
- $attach_upload['path'] = $upload['path'] . '/' . $file_name;
233
- $renamed = @rename($tmp_file, $attach_upload['path']);
234
- if ($renamed === true) {
235
- $atta_ext = end(explode('.', $file_name));
236
-
237
- $attachment = array(
238
- 'post_title' => $file_name,
239
- 'post_content' => '',
240
- 'post_type' => 'attachment',
241
- //'post_parent' => $post_id,
242
- 'post_mime_type' => 'image/' . $atta_ext,
243
- 'guid' => $attach_upload['url']
244
- );
245
-
246
- // Save the data
247
- $attach_id = wp_insert_attachment($attachment, $attach_upload['path']);
248
- wp_update_attachment_metadata($attach_id, wp_generate_attachment_metadata($attach_id, $attach_upload['path']));
249
- $attachments[$attach_id] = 0;
250
-
251
- // featured image
252
- if ($post_featured_img != '') {
253
- $feat_img_url = '';
254
- if (preg_match('/-\d{3}x\d{3}\.[a-zA-Z0-9]{3,4}$/', $post_featured_img)) {
255
- $feat_img_url = substr($post_featured_img, 0, strrpos($post_featured_img, '.') - 8);
256
- } else {
257
- $feat_img_url = substr($post_featured_img, 0, strrpos($post_featured_img, '.'));
258
- }
259
- $m_feat_url = '/' . str_replace($rep, $with, $feat_img_url) . '/';
260
- if (preg_match($m_feat_url, $img['src'])) {
261
- $post_featured_img = '';
262
- $attachments[$attach_id] = $attach_id;
263
- }
264
- }
265
-
266
- } else {
267
- @unlink($tmp_file);
268
- return array('error' => "Cannot create attachment file in ".$attach_upload['path']." Please set correct permissions.");
269
- }
270
- @unlink($tmp_file);
271
- }
272
- }
273
-
274
- //Prepare post data and temporarily remove content filters before insert post
275
- $user = $this->mmb_get_user_info( $args['username'] );
276
- if($user && $user->ID){
277
- $post_data['post_author'] = $user->ID;
278
- }
279
- remove_filter('content_save_pre', 'wp_filter_post_kses');
280
- $post_id = wp_insert_post($post_data);
281
-
282
- if (count($attachments)) {
283
- foreach ($attachments as $atta_id => $featured_id) {
284
- $result = wp_update_post(array(
285
- 'ID' => $atta_id,
286
- 'post_parent' => $post_id
287
- ));
288
- if ($featured_id > 0) {
289
- $new_custom['_thumbnail_id'] = array(
290
- $featured_id
291
- );
292
- }
293
- }
294
- }
295
-
296
- // featured image
297
- if ($post_featured_img != '') {
298
- $file_name = basename($post_featured_img);
299
- if(isset($upload['error']) && !empty($upload['error'])){
300
- return array('error' => $upload['error']);
301
- }
302
- $tmp_file = download_url($post_featured_img);
303
- if(is_wp_error($tmp_file)){
304
- return array('error' => $tmp_file->get_error_message());
305
- }
306
- $attach_upload['url'] = $upload['url'] . '/' . $file_name;
307
- $attach_upload['path'] = $upload['path'] . '/' . $file_name;
308
- $renamed = @rename($tmp_file, $attach_upload['path']);
309
- if ($renamed === true) {
310
- $atta_ext = end(explode('.', $file_name));
311
-
312
- $attachment = array(
313
- 'post_title' => $file_name,
314
- 'post_content' => '',
315
- 'post_type' => 'attachment',
316
- 'post_parent' => $post_id,
317
- 'post_mime_type' => 'image/' . $atta_ext,
318
- 'guid' => $attach_upload['url']
319
- );
320
-
321
- // Save the data
322
- $attach_id = wp_insert_attachment($attachment, $attach_upload['path']);
323
- wp_update_attachment_metadata($attach_id, wp_generate_attachment_metadata($attach_id, $attach_upload['path']));
324
- $new_custom['_thumbnail_id'] = array(
325
- $attach_id
326
- );
327
- } else {
328
- @unlink($tmp_file);
329
- return array('error' => "Cannot create attachment file in ".$attach_upload['path']." Please set correct permissions.");
330
- }
331
- @unlink($tmp_file);
332
- }
333
-
334
- if ($post_id && is_array($post_categories)) {
335
- //insert categories
336
-
337
- $cat_ids = wp_create_categories($post_categories, $post_id);
338
- }
339
-
340
-
341
- //get current custom fields
342
- $cur_custom = get_post_custom($post_id);
343
- //check which values doesnot exists in new custom fields
344
- $diff_values = array_diff_key($cur_custom, $new_custom);
345
-
346
- if (is_array($diff_values))
347
- foreach ($diff_values as $meta_key => $value) {
348
- delete_post_meta($post_id, $meta_key);
349
- }
350
- //insert new post meta
351
- foreach ($new_custom as $meta_key => $value) {
352
- if (strpos($meta_key, '_mmb') === 0 || strpos($meta_key, '_edit') === 0) {
353
- continue;
354
- } else {
355
- update_post_meta($post_id, $meta_key, $value[0]);
356
- }
357
- }
358
- return $post_id;
359
- }
360
-
361
-
362
- function change_status($args)
363
- {
364
-
365
- global $wpdb;
366
- $post_id = $args['post_id'];
367
- $status = $args['status'];
368
- $success = false;
369
-
370
- if(in_array($status, array('draft', 'publish', 'trash'))){
371
- $sql = "update ".$wpdb->prefix."posts set post_status = '$status' where ID = '$post_id'";
372
- $success = $wpdb->query($sql);
373
- }
374
-
375
- return $success;
376
- }
377
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
378
  ?>
1
+ <?php
2
+ /*************************************************************
3
+ *
4
+ * post.class.php
5
+ *
6
+ * Create remote post
7
+ *
8
+ *
9
+ * Copyright (c) 2011 Prelovac Media
10
+ * www.prelovac.com
11
+ **************************************************************/
12
+
13
+ class MMB_Post extends MMB_Core
14
+ {
15
+ function __construct()
16
+ {
17
+ parent::__construct();
18
+ }
19
+
20
+ function create($args)
21
+ {
22
+
23
+ /**
24
+ * algorithm
25
+ * 1. create post using wp_insert_post (insert tags also here itself)
26
+ * 2. use wp_create_categories() to create(not exists) and insert in the post
27
+ * 3. insert meta values
28
+ */
29
+
30
+ include_once ABSPATH . 'wp-admin/includes/taxonomy.php';
31
+ include_once ABSPATH . 'wp-admin/includes/image.php';
32
+ include_once ABSPATH . 'wp-admin/includes/file.php';
33
+
34
+ $post_struct = $args['post_data'];
35
+
36
+ $post_data = $post_struct['post_data'];
37
+ $new_custom = $post_struct['post_extras']['post_meta'];
38
+ $post_categories = explode(',', $post_struct['post_extras']['post_categories']);
39
+ $post_atta_img = $post_struct['post_extras']['post_atta_images'];
40
+ $post_upload_dir = $post_struct['post_extras']['post_upload_dir'];
41
+ $post_checksum = $post_struct['post_extras']['post_checksum'];
42
+ $post_featured_img = $post_struct['post_extras']['featured_img'];
43
+
44
+ $upload = wp_upload_dir();
45
+
46
+ // create dynamic url RegExp
47
+ $mwp_base_url = parse_url($post_upload_dir['url']);
48
+ $mwp_regexp_url = $mwp_base_url['host'] . $mwp_base_url['path'];
49
+ $rep = array(
50
+ '/',
51
+ '+',
52
+ '.',
53
+ ':',
54
+ '?'
55
+ );
56
+ $with = array(
57
+ '\/',
58
+ '\+',
59
+ '\.',
60
+ '\:',
61
+ '\?'
62
+ );
63
+ $mwp_regexp_url = str_replace($rep, $with, $mwp_regexp_url);
64
+
65
+ // rename all src ../wp-content/ with hostname/wp-content/
66
+ $mmb_dot_url = '..' . $mmb_base_url['path'];
67
+ $mmb_dot_url = str_replace($rep, $with, $mmb_dot_url);
68
+ $dot_match_count = preg_match_all('/(<a[^>]+href=\"([^"]+)\"[^>]*>)?(<\s*img.[^\/>]*src="([^"]*' . $mmb_dot_url . '[^\s]+\.(jpg|jpeg|png|gif|bmp))"[^>]*>)/ixu', $post_data['post_content'], $dot_get_urls, PREG_SET_ORDER);
69
+ if ($dot_match_count > 0) {
70
+ foreach ($dot_get_urls as $dot_url) {
71
+ $match_dot = '/' . str_replace($rep, $with, $dot_url[4]) . '/';
72
+ $replace_dot = 'http://' . $mmb_base_url['host'] . substr($dot_url[4], 2, strlen($dot_url[4]));
73
+ $post_data['post_content'] = preg_replace($match_dot, $replace_dot, $post_data['post_content']);
74
+
75
+ if ($dot_url[1] != '') {
76
+ $match_dot_a = '/' . str_replace($rep, $with, $dot_url[2]) . '/';
77
+ $replace_dot_a = 'http://' . $mmb_base_url['host'] . substr($dot_url[2], 2, strlen($dot_url[2]));
78
+ $post_data['post_content'] = preg_replace($match_dot_a, $replace_dot_a, $post_data['post_content']);
79
+ }
80
+ }
81
+ }
82
+
83
+
84
+
85
+ //to find all the images
86
+ $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);
87
+ if ($match_count > 0) {
88
+ $attachments = array();
89
+ $post_content = $post_data['post_content'];
90
+
91
+ foreach ($get_urls as $get_url_k => $get_url) {
92
+ // unset url in attachment array
93
+ foreach ($post_atta_img as $atta_url_k => $atta_url_v) {
94
+ $match_patt_url = '/' . str_replace($rep, $with, substr($atta_url_v['src'], 0, strrpos($atta_url_v['src'], '.'))) . '/';
95
+ if (preg_match($match_patt_url, $get_url[4])) {
96
+ unset($post_atta_img[$atta_url_k]);
97
+ }
98
+ }
99
+
100
+ if (isset($get_urls[$get_url_k][6])) { // url have parent, don't download this url
101
+ if ($get_url[1] != '') {
102
+ // change src url
103
+ $s_mmb_mp = '/' . str_replace($rep, $with, $get_url[4]) . '/';
104
+
105
+ $s_img_atta = wp_get_attachment_image_src($get_urls[$get_url_k][6]);
106
+ $s_mmb_rp = $s_img_atta[0];
107
+ $post_content = preg_replace($s_mmb_mp, $s_mmb_rp, $post_content);
108
+ // change attachment url
109
+ if (preg_match('/attachment_id/i', $get_url[2])) {
110
+ $mmb_mp = '/' . str_replace($rep, $with, $get_url[2]) . '/';
111
+ $mmb_rp = get_bloginfo('wpurl') . '/?attachment_id=' . $get_urls[$get_url_k][6];
112
+ $post_content = preg_replace($mmb_mp, $mmb_rp, $post_content);
113
+ }
114
+ }
115
+ continue;
116
+ }
117
+
118
+ $no_thumb = '';
119
+ if (preg_match('/-\d{3}x\d{3}\.[a-zA-Z0-9]{3,4}$/', $get_url[4])) {
120
+ $no_thumb = preg_replace('/-\d{3}x\d{3}\.[a-zA-Z0-9]{3,4}$/', '.' . $get_url[5], $get_url[4]);
121
+ } else {
122
+ $no_thumb = $get_url[4];
123
+ }
124
+
125
+ if(isset($upload['error']) && !empty($upload['error'])){
126
+ return array('error' => $upload['error']);
127
+ }
128
+ $file_name = basename($no_thumb);
129
+ $tmp_file = download_url($no_thumb);
130
+
131
+ if(is_wp_error($tmp_file)){
132
+ return array('error' => $tmp_file->get_error_message());
133
+ }
134
+
135
+ $attach_upload['url'] = $upload['url'] . '/' . $file_name;
136
+ $attach_upload['path'] = $upload['path'] . '/' . $file_name;
137
+ $renamed = @rename($tmp_file, $attach_upload['path']);
138
+ if ($renamed === true) {
139
+ $match_pattern = '/' . str_replace($rep, $with, $get_url[4]) . '/';
140
+ $replace_pattern = $attach_upload['url'];
141
+ $post_content = preg_replace($match_pattern, $replace_pattern, $post_content);
142
+ if (preg_match('/-\d{3}x\d{3}\.[a-zA-Z0-9]{3,4}$/', $get_url[4])) {
143
+ $match_pattern = '/' . str_replace($rep, $with, preg_replace('/-\d{3}x\d{3}\.[a-zA-Z0-9]{3,4}$/', '.' . $get_url[5], $get_url[4])) . '/';
144
+ $post_content = preg_replace($match_pattern, $replace_pattern, $post_content);
145
+ }
146
+
147
+ $attachment = array(
148
+ 'post_title' => $file_name,
149
+ 'post_content' => '',
150
+ 'post_type' => 'attachment',
151
+ //'post_parent' => $post_id,
152
+ 'post_mime_type' => 'image/' . $get_url[5],
153
+ 'guid' => $attach_upload['url']
154
+ );
155
+
156
+ // Save the data
157
+
158
+ $attach_id = wp_insert_attachment($attachment, $attach_upload['path']);
159
+
160
+ $attachments[$attach_id] = 0;
161
+
162
+ // featured image
163
+ if ($post_featured_img != '') {
164
+ $feat_img_url = '';
165
+ if (preg_match('/-\d{3}x\d{3}\.[a-zA-Z0-9]{3,4}$/', $post_featured_img)) {
166
+ $feat_img_url = substr($post_featured_img, 0, strrpos($post_featured_img, '.') - 8);
167
+ } else {
168
+ $feat_img_url = substr($post_featured_img, 0, strrpos($post_featured_img, '.'));
169
+ }
170
+ $m_feat_url = '/' . str_replace($rep, $with, $feat_img_url) . '/';
171
+ if (preg_match($m_feat_url, $get_url[4])) {
172
+ $post_featured_img = '';
173
+ $attachments[$attach_id] = $attach_id;
174
+ }
175
+ }
176
+
177
+ // set $get_urls value[6] - parent atta_id
178
+ foreach ($get_urls as $url_k => $url_v) {
179
+ if ($get_url_k != $url_k) {
180
+ $s_get_url = '';
181
+ if (preg_match('/-\d{3}x\d{3}\.[a-zA-Z0-9]{3,4}$/', $url_v[4])) {
182
+ $s_get_url = substr($url_v[4], 0, strrpos($url_v[4], '.') - 8);
183
+ } else {
184
+ $s_get_url = substr($url_v[4], 0, strrpos($url_v[4], '.'));
185
+ }
186
+ $m_patt_url = '/' . str_replace($rep, $with, $s_get_url) . '/';
187
+ if (preg_match($m_patt_url, $get_url[4])) {
188
+ array_push($get_urls[$url_k], $attach_id);
189
+ }
190
+ }
191
+ }
192
+
193
+
194
+ $some_data = wp_generate_attachment_metadata($attach_id, $attach_upload['path']);
195
+ wp_update_attachment_metadata($attach_id, $some_data);
196
+
197
+
198
+ // changing href of a tag
199
+ if ($get_url[1] != '') {
200
+ $mmb_mp = '/' . str_replace($rep, $with, $get_url[2]) . '/';
201
+ if (preg_match('/attachment_id/i', $get_url[2])) {
202
+ $mmb_rp = get_bloginfo('wpurl') . '/?attachment_id=' . $attach_id;
203
+ $post_content = preg_replace($mmb_mp, $mmb_rp, $post_content);
204
+ }
205
+ }
206
+ } else {
207
+ @unlink($tmp_file);
208
+ return array('error' => "Cannot create attachment file in ".$attach_upload['path']." Please set correct permissions.");
209
+
210
+ }
211
+ @unlink($tmp_file);
212
+ }
213
+
214
+
215
+ $post_data['post_content'] = $post_content;
216
+
217
+ }
218
+ if (count($post_atta_img)) {
219
+ foreach ($post_atta_img as $img) {
220
+ $file_name = basename($img['src']);
221
+
222
+ if(isset($upload['error']) && !empty($upload['error'])){
223
+ return array('error' => $upload['error']);
224
+ }
225
+
226
+ $tmp_file = download_url($img['src']);
227
+ if(is_wp_error($tmp_file)){
228
+ return array('error' => $tmp_file->get_error_message());
229
+ }
230
+
231
+ $attach_upload['url'] = $upload['url'] . '/' . $file_name;
232
+ $attach_upload['path'] = $upload['path'] . '/' . $file_name;
233
+ $renamed = @rename($tmp_file, $attach_upload['path']);
234
+ if ($renamed === true) {
235
+ $atta_ext = end(explode('.', $file_name));
236
+
237
+ $attachment = array(
238
+ 'post_title' => $file_name,
239
+ 'post_content' => '',
240
+ 'post_type' => 'attachment',
241
+ //'post_parent' => $post_id,
242
+ 'post_mime_type' => 'image/' . $atta_ext,
243
+ 'guid' => $attach_upload['url']
244
+ );
245
+
246
+ // Save the data
247
+ $attach_id = wp_insert_attachment($attachment, $attach_upload['path']);
248
+ wp_update_attachment_metadata($attach_id, wp_generate_attachment_metadata($attach_id, $attach_upload['path']));
249
+ $attachments[$attach_id] = 0;
250
+
251
+ // featured image
252
+ if ($post_featured_img != '') {
253
+ $feat_img_url = '';
254
+ if (preg_match('/-\d{3}x\d{3}\.[a-zA-Z0-9]{3,4}$/', $post_featured_img)) {
255
+ $feat_img_url = substr($post_featured_img, 0, strrpos($post_featured_img, '.') - 8);
256
+ } else {
257
+ $feat_img_url = substr($post_featured_img, 0, strrpos($post_featured_img, '.'));
258
+ }
259
+ $m_feat_url = '/' . str_replace($rep, $with, $feat_img_url) . '/';
260
+ if (preg_match($m_feat_url, $img['src'])) {
261
+ $post_featured_img = '';
262
+ $attachments[$attach_id] = $attach_id;
263
+ }
264
+ }
265
+
266
+ } else {
267
+ @unlink($tmp_file);
268
+ return array('error' => "Cannot create attachment file in ".$attach_upload['path']." Please set correct permissions.");
269
+ }
270
+ @unlink($tmp_file);
271
+ }
272
+ }
273
+
274
+ //Prepare post data and temporarily remove content filters before insert post
275
+ $user = $this->mmb_get_user_info( $args['username'] );
276
+ if($user && $user->ID){
277
+ $post_data['post_author'] = $user->ID;
278
+ }
279
+ remove_filter('content_save_pre', 'wp_filter_post_kses');
280
+ $post_id = wp_insert_post($post_data);
281
+
282
+ if (count($attachments)) {
283
+ foreach ($attachments as $atta_id => $featured_id) {
284
+ $result = wp_update_post(array(
285
+ 'ID' => $atta_id,
286
+ 'post_parent' => $post_id
287
+ ));
288
+ if ($featured_id > 0) {
289
+ $new_custom['_thumbnail_id'] = array(
290
+ $featured_id
291
+ );
292
+ }
293
+ }
294
+ }
295
+
296
+ // featured image
297
+ if ($post_featured_img != '') {
298
+ $file_name = basename($post_featured_img);
299
+ if(isset($upload['error']) && !empty($upload['error'])){
300
+ return array('error' => $upload['error']);
301
+ }
302
+ $tmp_file = download_url($post_featured_img);
303
+ if(is_wp_error($tmp_file)){
304
+ return array('error' => $tmp_file->get_error_message());
305
+ }
306
+ $attach_upload['url'] = $upload['url'] . '/' . $file_name;
307
+ $attach_upload['path'] = $upload['path'] . '/' . $file_name;
308
+ $renamed = @rename($tmp_file, $attach_upload['path']);
309
+ if ($renamed === true) {
310
+ $atta_ext = end(explode('.', $file_name));
311
+
312
+ $attachment = array(
313
+ 'post_title' => $file_name,
314
+ 'post_content' => '',
315
+ 'post_type' => 'attachment',
316
+ 'post_parent' => $post_id,
317
+ 'post_mime_type' => 'image/' . $atta_ext,
318
+ 'guid' => $attach_upload['url']
319
+ );
320
+
321
+ // Save the data
322
+ $attach_id = wp_insert_attachment($attachment, $attach_upload['path']);
323
+ wp_update_attachment_metadata($attach_id, wp_generate_attachment_metadata($attach_id, $attach_upload['path']));
324
+ $new_custom['_thumbnail_id'] = array(
325
+ $attach_id
326
+ );
327
+ } else {
328
+ @unlink($tmp_file);
329
+ return array('error' => "Cannot create attachment file in ".$attach_upload['path']." Please set correct permissions.");
330
+ }
331
+ @unlink($tmp_file);
332
+ }
333
+
334
+ if ($post_id && is_array($post_categories)) {
335
+ //insert categories
336
+
337
+ $cat_ids = wp_create_categories($post_categories, $post_id);
338
+ }
339
+
340
+
341
+ //get current custom fields
342
+ $cur_custom = get_post_custom($post_id);
343
+ //check which values doesnot exists in new custom fields
344
+ $diff_values = array_diff_key($cur_custom, $new_custom);
345
+
346
+ if (is_array($diff_values))
347
+ foreach ($diff_values as $meta_key => $value) {
348
+ delete_post_meta($post_id, $meta_key);
349
+ }
350
+ //insert new post meta
351
+ foreach ($new_custom as $meta_key => $value) {
352
+ if (strpos($meta_key, '_mmb') === 0 || strpos($meta_key, '_edit') === 0) {
353
+ continue;
354
+ } else {
355
+ update_post_meta($post_id, $meta_key, $value[0]);
356
+ }
357
+ }
358
+ return $post_id;
359
+ }
360
+
361
+
362
+ function change_status($args)
363
+ {
364
+
365
+ global $wpdb;
366
+ $post_id = $args['post_id'];
367
+ $status = $args['status'];
368
+ $success = false;
369
+
370
+ if(in_array($status, array('draft', 'publish', 'trash'))){
371
+ $sql = "update ".$wpdb->prefix."posts set post_status = '$status' where ID = '$post_id'";
372
+ $success = $wpdb->query($sql);
373
+ }
374
+
375
+ return $success;
376
+ }
377
+
378
+ function get_posts($args){
379
+ global $wpdb;
380
+
381
+ $where='';
382
+
383
+ extract($args);
384
+
385
+ if(!empty($filter_posts))
386
+ {
387
+ $where.=" AND post_title LIKE '%".mysql_real_escape_string($filter_posts)."%'";
388
+ }
389
+
390
+ if(!empty($mwp_get_posts_date_from) && !empty($mwp_get_posts_date_to))
391
+ {
392
+ $where.=" AND post_date BETWEEN '".mysql_real_escape_string($mwp_get_posts_date_from)."' AND '".mysql_real_escape_string($mwp_get_posts_date_to)."'";
393
+ }
394
+ else if(!empty($mwp_get_posts_date_from) && empty($mwp_get_posts_date_to))
395
+ {
396
+ $where.=" AND post_date >= '".mysql_real_escape_string($mwp_get_posts_date_from)."'";
397
+ }
398
+ else if(empty($mwp_get_posts_date_from) && !empty($mwp_get_posts_date_to))
399
+ {
400
+ $where.=" AND post_date <= '".mysql_real_escape_string($mwp_get_posts_date_to)."'";
401
+ }
402
+ $post_array=array();
403
+ $post_statuses = array('publish', 'pending', 'private', 'future', 'draft', 'trash');
404
+ foreach ($args as $checkbox => $checkbox_val)
405
+ {
406
+ if($checkbox_val=="on") {
407
+ $post_array[]="'".str_replace("mwp_get_posts_","",$checkbox)."'";
408
+ }
409
+ }
410
+ if(!empty($post_array))
411
+ {
412
+ $where.=" AND post_status IN (".implode(",",$post_array).")";
413
+ }
414
+
415
+ $sql_query = "$wpdb->posts WHERE post_status!='auto-draft' AND post_status!='inherit' AND post_type='post' ".$where." ORDER BY post_date DESC";
416
+
417
+ $total = array();
418
+ $user_info = $this->getUsersIDs();
419
+ $post_cats=$this->getPostCats();
420
+ $post_tags=$this->getPostCats('post_tag');
421
+ $posts_total = $wpdb->get_results("SELECT count(*) as total_posts FROM ".$sql_query);
422
+ $total['total_num']=$posts_total[0]->total_posts;
423
+
424
+ $posts = array();
425
+ $posts_info = $wpdb->get_results("SELECT * FROM ".$sql_query." LIMIT 250");
426
+
427
+ foreach ( $posts_info as $post_info )
428
+ {
429
+
430
+ $cats=array();
431
+ foreach($post_cats[$post_info->ID] as $cat_array => $cat_array_val)
432
+ {
433
+ $cats[] = array('name' => $cat_array_val);
434
+ }
435
+
436
+ $tags=array();
437
+ foreach($post_tags[$post_info->ID] as $tag_array => $tag_array_val)
438
+ {
439
+ $tags[] = array('name' => $tag_array_val);
440
+ }
441
+
442
+ $posts[]=array(
443
+ 'post_id'=>$post_info->ID,
444
+ 'post_title'=>$post_info->post_title,
445
+ 'post_name'=>$post_info->post_name,
446
+ 'post_author'=>array('author_id'=>$post_info->post_author, 'author_name'=>$user_info[$post_info->post_author]),
447
+ 'post_date'=>$post_info->post_date,
448
+ 'post_modified'=>$post_info->post_modified,
449
+ 'post_status'=>$post_info->post_status,
450
+ 'post_type'=>$post_info->post_type,
451
+ 'guid'=>$post_info->guid,
452
+ 'post_password'=>$post_info->post_password,
453
+ 'ping_status'=>$post_info->ping_status,
454
+ 'comment_status'=>$post_info->comment_status,
455
+ 'comment_count'=>$post_info->comment_count,
456
+ 'cats'=>$cats,
457
+ 'tags'=>$tags,
458
+
459
+ );
460
+ }
461
+
462
+ return array('posts' => $posts, 'total' => $total);
463
+ }
464
+
465
+ function delete_post($args){
466
+ global $wpdb;
467
+ if(!empty($args['post_id']) && !empty($args['action']))
468
+ {
469
+ if($args['action']=='delete')
470
+ {
471
+ $delete_query = "UPDATE $wpdb->posts SET post_status = 'trash' WHERE ID = ".$args['post_id'];
472
+ }
473
+ else if($args['action']=='delete_perm'){
474
+ $delete_query = "DELETE FROM $wpdb->posts WHERE ID = ".$args['post_id'];
475
+ }
476
+ else if($args['action']=='delete_restore'){
477
+ $delete_query = "UPDATE $wpdb->posts SET post_status = 'publish' WHERE ID = ".$args['post_id'];
478
+ }
479
+ $wpdb->get_results($delete_query);
480
+
481
+ return 'Post deleted.';
482
+ }
483
+ else
484
+ {
485
+ return 'No ID...';
486
+ }
487
+ }
488
+
489
+ function get_pages($args){
490
+ global $wpdb;
491
+
492
+ $where='';
493
+ extract($args);
494
+
495
+ if(!empty($filter_pages))
496
+ {
497
+ $where.=" AND post_title LIKE '%".mysql_real_escape_string($filter_pages)."%'";
498
+ }
499
+ if(!empty($mwp_get_pages_date_from) && !empty($mwp_get_pages_date_to))
500
+ {
501
+ $where.=" AND post_date BETWEEN '".mysql_real_escape_string($mwp_get_pages_date_from)."' AND '".mysql_real_escape_string($mwp_get_pages_date_to)."'";
502
+ }
503
+ else if(!empty($mwp_get_pages_date_from) && empty($mwp_get_pages_date_to))
504
+ {
505
+ $where.=" AND post_date >= '".mysql_real_escape_string($mwp_get_pages_date_from)."'";
506
+ }
507
+ else if(empty($mwp_get_pages_date_from) && !empty($mwp_get_pages_date_to))
508
+ {
509
+ $where.=" AND post_date <= '".mysql_real_escape_string($mwp_get_pages_date_to)."'";
510
+ }
511
+
512
+ $post_array=array();
513
+ $post_statuses = array('publish', 'pending', 'private', 'future', 'draft', 'trash');
514
+ foreach ($args as $checkbox => $checkbox_val)
515
+ {
516
+ if($checkbox_val=="on") {
517
+ $post_array[]="'".str_replace("mwp_get_pages_","",$checkbox)."'";
518
+ }
519
+ }
520
+ if(!empty($post_array))
521
+ {
522
+ $where.=" AND post_status IN (".implode(",",$post_array).")";
523
+ }
524
+
525
+ $sql_query = "$wpdb->posts WHERE post_status!='auto-draft' AND post_status!='inherit' AND post_type='page' ".$where.' ORDER BY post_date DESC';
526
+
527
+ $total = array();
528
+ $user_info = $this->getUsersIDs();
529
+ $posts_total = $wpdb->get_results("SELECT count(*) as total_posts FROM ".$sql_query);
530
+ $total['total_num']=$posts_total[0]->total_posts;
531
+
532
+ $posts = array();
533
+ $posts_info = $wpdb->get_results("SELECT * FROM ".$sql_query." LIMIT 250");
534
+
535
+ foreach ( $posts_info as $post_info )
536
+ {
537
+
538
+ $posts[]=array(
539
+ 'post_id'=>$post_info->ID,
540
+ 'post_title'=>$post_info->post_title,
541
+ 'post_name'=>$post_info->post_name,
542
+ 'post_author'=>array('author_id'=>$post_info->post_author, 'author_name'=>$user_info[$post_info->post_author]),
543
+ 'post_date'=>$post_info->post_date,
544
+ 'post_modified'=>$post_info->post_modified,
545
+ 'post_status'=>$post_info->post_status,
546
+ 'post_type'=>$post_info->post_type,
547
+ 'guid'=>$post_info->guid,
548
+ 'post_password'=>$post_info->post_password,
549
+ 'ping_status'=>$post_info->ping_status,
550
+ 'comment_status'=>$post_info->comment_status,
551
+ 'comment_count'=>$post_info->comment_count
552
+
553
+ );
554
+ }
555
+
556
+ return array('posts' => $posts, 'total' => $total);
557
+ }
558
+
559
+ function delete_page($args){
560
+ global $wpdb;
561
+ if(!empty($args['post_id']) && !empty($args['action']))
562
+ {
563
+ if($args['action']=='delete')
564
+ {
565
+ $delete_query = "UPDATE $wpdb->posts SET post_status = 'trash' WHERE ID = ".$args['post_id'];
566
+ }
567
+ else if($args['action']=='delete_perm'){
568
+ $delete_query = "DELETE FROM $wpdb->posts WHERE ID = ".$args['post_id'];
569
+ }
570
+ else if($args['action']=='delete_restore'){
571
+ $delete_query = "UPDATE $wpdb->posts SET post_status = 'publish' WHERE ID = ".$args['post_id'];
572
+ }
573
+ $wpdb->get_results($delete_query);
574
+
575
+ return 'Page deleted.';
576
+ }
577
+ else
578
+ {
579
+ return 'No ID...';
580
+ }
581
+ }
582
+
583
+ function getPostCats($taxonomy = 'category')
584
+ {
585
+ global $wpdb;
586
+
587
+ $cats = $wpdb->get_results("SELECT p.ID AS post_id, $wpdb->terms.name
588
+ FROM $wpdb->posts AS p
589
+ INNER JOIN $wpdb->term_relationships ON ( p.ID = $wpdb->term_relationships.object_id )
590
+ INNER JOIN $wpdb->term_taxonomy ON ( $wpdb->term_relationships.term_taxonomy_id = $wpdb->term_taxonomy.term_taxonomy_id
591
+ AND $wpdb->term_taxonomy.taxonomy = '".$taxonomy."' )
592
+ INNER JOIN $wpdb->terms ON ( $wpdb->term_taxonomy.term_taxonomy_id = $wpdb->terms.term_id )");
593
+
594
+ foreach ( $cats as $post_val )
595
+ {
596
+
597
+ $post_cats[$post_val->post_id][] = $post_val->name;
598
+ }
599
+
600
+ return $post_cats;
601
+ }
602
+
603
+ function getUsersIDs()
604
+ {
605
+ global $wpdb;
606
+ $users_authors=array();
607
+ $users = $wpdb->get_results("SELECT ID as user_id, display_name FROM $wpdb->users WHERE user_status=0");
608
+
609
+ foreach ( $users as $user_key=>$user_val )
610
+ {
611
+ $users_authors[$user_val->user_id] = $user_val->display_name;
612
+ }
613
+
614
+ return $users_authors;
615
+ }
616
+ }
617
  ?>
readme.txt CHANGED
@@ -1,219 +1,229 @@
1
- === ManageWP Worker ===
2
- Contributors: freediver
3
- Donate link: https://www.networkforgood.org/donation/MakeDonation.aspx?ORGID2=520781390
4
- Tags: admin, administration, amazon, api, 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.3
7
- Stable tag: trunk
8
-
9
- ManageWP Worker plugin allows you to remotely manage your blogs from one dashboard.
10
-
11
- == Description ==
12
-
13
- [ManageWP](http://managewp.com/ "Manage Multiple Blogs") is a revolutionary plugin that helps users manage multiple WordPress blogs from one dashboard.
14
-
15
- Main features:
16
-
17
- * Secure and fast solution for managing your WordPress sites
18
- * One click upgrades of WordPress, plugin and themes across all your sites
19
- * Schedule automatic backups of your websites (Amazon S3 and Dropbox supported)
20
- * One click to access WP admin of any site
21
- * Bulk install themes and plugins to multiple sites at once
22
- * Add sub-users (writers, staff..) to your account
23
- * Bulk publish posts to multiple sites at once
24
- * SEO Statistics, track your keyword rankings
25
- * Install WordPress, clone or migrate a website to another domain
26
- * Much, much more...
27
-
28
- Check out the [ManageWP Tour video](http://vimeo.com/22099014).
29
-
30
- http://vimeo.com/22099014
31
-
32
- Check out [ManageWP.com](http://managewp.com/ "Manage Multiple Blogs").
33
-
34
- == Changelog ==
35
-
36
- = 3.9.16 =
37
- * New: Option to "Run now" backup tasks
38
- * New: Traffic alerts functionality
39
- * New: Support for Genesis premium theme updates
40
- * Fix: In some circutmsances .htaccess was not correctly zipped in the backup archive
41
-
42
- = 3.9.15 =
43
- * New: Full range of SEO Statistics now trackable for your websites (Google Page Rank and Page Speed, Backlinks and 20+ more)
44
- * New: Google keyword rank tracking with history
45
- * New: Uptime monitoring (5 min interval with email/SMS notification)
46
- * New: Insights into server PHP error logs right in your dashboard
47
- * New: Remote maintenance mode for your websites
48
- * Fix: A bug when a completed backup was reported as failed
49
-
50
- = 3.9.14 =
51
- * Two factor authentication
52
- * Run code tool
53
- * Quick access to security check and broken link tools
54
- * More accurate pageview statistics
55
- * You can now opt to completely hide the Worker plugin from the list of plugins (part of Worker branding features)
56
- * We improved the backups for folks running Windows servers
57
- * Amazon S3 directory name now "ManageWP" by default
58
- * Read more on ManageWP.com http://managewp.com/update-two-factor-authentication-run-code-tool-sucuri-security-check-more-accurate-pageview-statistics
59
-
60
- = 3.9.13 =
61
- * Added bucket location for Amazon S3 backups
62
- * Better backup feature for larger sites
63
- * Added Disable compression to further help with larger sites
64
- * Backing up wp-admin, wp-includes and wp-content by default now, other folders can be included manually
65
-
66
- = 3.9.12 =
67
- * Minor bug fixes
68
- * Backup, clone, favorites functionality improved
69
-
70
- = 3.9.10 =
71
- * Supporting updates for more premium plugins/themes
72
- * Backup notifications (users can now get notices when the backup succeeds or fails)
73
- * Support for WordPress 3.3
74
- * Worker Branding (useful for web agencies, add your own Name/Description)
75
- * Manage Groups screen
76
- * Specify wp-admin path if your site uses a custom one
77
- * Amazon S3 backups support for mixed case bucket names
78
- * Bulk Add Links has additional options
79
- * Better Multisite support
80
- * Option to set the number of items for Google Analytics
81
- * ManageWP backup folder changed to wp-content/managewp/backups
82
-
83
- = 3.9.9 =
84
- * New widget on the dashboard - Backup status
85
- * New screen for managing plugins and themes (activate, deactivate, delete, add to favorites, install) across all sites
86
- * New screen for managing users (change role or password, delete user) across all sites
87
- * Option to overwrite old plugins and themes during bulk installation
88
- * Your website admin now loads faster in ManageWP
89
- * Added API for premium theme and plugin updates
90
-
91
- = 3.9.8 =
92
- * Conversion goals integration
93
- * Update notifications
94
- * Enhanced security for your account
95
- * Better backups
96
- * Better update interface
97
- * [Full changelog](http://managewp.com/update-goals-and-adsense-analytics-integration-update-notifications-login-by-ip-better-backups "Full changelog")
98
-
99
- = 3.9.7 =
100
- * Fixed problem with cron schedules
101
-
102
- = 3.9.6 =
103
- * Improved dashboard performance
104
- * Fixed bug with W3TC, we hope it is fully comptabile now
105
- * Improved backup feature
106
- * Various other fixes and improvements
107
-
108
- = 3.9.5 =
109
- * Now supporting scheduled backups to Amazon S3 and Dropbox
110
- * Revamped cloning procedure
111
- * You can now have sites in different colors
112
- * W3 Total Cache comptability improved
113
-
114
- = 3.9.3 =
115
- * Included support for WordPress 3.2 partial updates
116
-
117
- = 3.9.2 =
118
- * Fixed problem with full backups
119
- * Fixed problem with wordpress dev version upgrades
120
-
121
- = 3.9.1 =
122
- * Support for sub-users (limited access users)
123
- * Bulk add user
124
- * 'Select all' feature for bulk posting
125
- * Featured image support for bulk posting
126
- * Reload button on the dashboard (on the top of the Right now widget) will now refresh information about available updates
127
- * Fixed a problem with the import tool
128
- * Fixed a problem when remote dashboard would not work for some servers
129
-
130
- = 3.9.0 =
131
- * New feature: Up to 50% faster dashboard loading
132
- * New feature: You can now ignore WordPress/plugin/theme updates
133
- * New feature: Setting 'Show favicon' for websites in the dashboad
134
- * New feature: Full backups now include WordPress and other folders in the root of the site
135
- * Fixed: Bug with W3 TotalCache object cache causing weird behaviour in the dashboard
136
- * Fixed: All groups now show when adding a site
137
-
138
- = 3.8.8 =
139
- * New feature: Bulk add links to blogroll
140
- * New feature: Manual backups to email address
141
- * New feature: Backup requirements check (under �Manage Backups�)
142
- * New feature: Popup menu for groups allowing to show dashboard for that group only
143
- * New feature: Favorite list for plugins and themes for later quick installation to multiple blogs
144
- * New feature: Invite friends
145
- * Fixed: problem with backups and write permissions when upload dir was wrongly set
146
- * Fixed: problem adding sites where WordPress is installed in a folder
147
- * Fixed: 408 error message problem when adding site
148
- * Fixed: site time out problems when adding site
149
- * Fixed: problems with some WP plugins (WP Sentinel)
150
- * Fixed: problems with upgrade notifications
151
-
152
- = 3.8.7 =
153
- * Fixed 408 error when adding sites
154
- * Added support for IDN domains
155
- * Fixed bug with WordPress updates
156
- * Added comment moderation to the dashboard
157
- * Added quick links for sites (menu appears on hover)
158
-
159
-
160
- = 3.8.6 =
161
- * Added seach websites feature
162
- * Enhanced dashboard actions (spam comments, post revisions, table overhead)
163
- * Added developer [API] (http://managewp.com/api "ManageWP API")
164
- * Improved Migrate/Clone site feature
165
-
166
- = 3.8.4 =
167
- * Fixed remote dashboard problems for sites with redirects
168
- * Fixed IE7 issues in the dashboard
169
-
170
- = 3.8.3 =
171
- * Fixed problem with capabilities
172
-
173
- = 3.8.2 =
174
- * New interface
175
- * SSL security protocol
176
- * No passwords required
177
- * Improved clone/backup
178
-
179
-
180
- = 3.6.3 =
181
- * Initial public release
182
-
183
- == Installation ==
184
-
185
- 1. Upload the plugin folder to your /wp-content/plugins/ folder
186
- 2. Go to the Plugins page and activate ManageWP Worker
187
- 3. Visit [ManageWP.com](http://managewp.com/ "Manage Multiple Blogs"), sign up and add your site
188
-
189
- Alternately
190
-
191
- 1. Visit [ManageWP.com](http://managewp.com/ "Manage Multiple Blogs"), sign up and add your site
192
- 2. ManageWP will warn you the worker plugin is not installed and offer a link for quick installation
193
-
194
- == Screenshots ==
195
-
196
- 1. ManageWP dashboard with available upgrades, site statistics and management functions
197
-
198
-
199
-
200
- == License ==
201
-
202
- This file is part of ManageWP Worker.
203
-
204
- 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.
205
-
206
- 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.
207
-
208
- You should have received a copy of the GNU General Public License along with ManageWP Worker. If not, see <http://www.gnu.org/licenses/>.
209
-
210
-
211
- == Frequently Asked Questions ==
212
-
213
- = I have problems adding my site =
214
-
215
- 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").
216
-
217
- = I have problems installing new plugins or upgrading WordPress through ManageWP =
218
-
 
 
 
 
 
 
 
 
 
 
219
  ManageWP Worker relies on properly set file permissions on your server. See the [user guide](http://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: admin, administration, amazon, api, 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.3.1
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](http://managewp.com/ "Manage Multiple Blogs") is a revolutionary plugin that helps users manage multiple WordPress blogs from one dashboard.
14
+
15
+ Main features:
16
+
17
+ * Secure and fast solution for managing your WordPress sites
18
+ * One click upgrades for WordPress, plugin and themes across all your sites
19
+ * Schedule automatic backups of your websites (Amazon S3 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
+ * Bulk publish posts to multiple sites at once
25
+ * SEO Statistics, track your keyword rankings
26
+ * Uptime monitoring
27
+ * Much, much more...
28
+
29
+ Check out the [ManageWP Tour video](http://vimeo.com/22099014).
30
+
31
+ http://vimeo.com/22099014
32
+
33
+ Check out [ManageWP.com](http://managewp.com/ "Manage Multiple Blogs").
34
+
35
+ == Changelog ==
36
+
37
+ = 3.9.17 =
38
+ * New: Add your favorite sites to the Favorites bar (just drag&drop them to the small heart on the top)
39
+ * New: Entirely new website menu loaded with features and tools
40
+ * New: Manage Posts and Pages across all sites in a more efficient way
41
+ * New: Support for all WPMU.org premium plugin updates
42
+ * New: Complete Dropbox integration through Oauth which allows us to restore/delete Dropbox backups directly
43
+ * New: We have the user guide as PDF now. [Download] (http://managewp.com/files/ManageWP_User_Guide.zip)
44
+
45
+
46
+ = 3.9.16 =
47
+ * New: Option to "Run now" backup tasks
48
+ * New: Traffic alerts functionality
49
+ * New: Support for Genesis premium theme updates
50
+ * Fix: In some circutmsances .htaccess was not correctly zipped in the backup archive
51
+
52
+ = 3.9.15 =
53
+ * New: Full range of SEO Statistics now trackable for your websites (Google Page Rank and Page Speed, Backlinks and 20+ more)
54
+ * New: Google keyword rank tracking with history
55
+ * New: Uptime monitoring (5 min interval with email/SMS notification)
56
+ * New: Insights into server PHP error logs right in your dashboard
57
+ * New: Remote maintenance mode for your websites
58
+ * Fix: A bug when a completed backup was reported as failed
59
+
60
+ = 3.9.14 =
61
+ * Two factor authentication
62
+ * Run code tool
63
+ * Quick access to security check and broken link tools
64
+ * More accurate pageview statistics
65
+ * You can now opt to completely hide the Worker plugin from the list of plugins (part of Worker branding features)
66
+ * We improved the backups for folks running Windows servers
67
+ * Amazon S3 directory name now "ManageWP" by default
68
+ * Read more on ManageWP.com http://managewp.com/update-two-factor-authentication-run-code-tool-sucuri-security-check-more-accurate-pageview-statistics
69
+
70
+ = 3.9.13 =
71
+ * Added bucket location for Amazon S3 backups
72
+ * Better backup feature for larger sites
73
+ * Added Disable compression to further help with larger sites
74
+ * Backing up wp-admin, wp-includes and wp-content by default now, other folders can be included manually
75
+
76
+ = 3.9.12 =
77
+ * Minor bug fixes
78
+ * Backup, clone, favorites functionality improved
79
+
80
+ = 3.9.10 =
81
+ * Supporting updates for more premium plugins/themes
82
+ * Backup notifications (users can now get notices when the backup succeeds or fails)
83
+ * Support for WordPress 3.3
84
+ * Worker Branding (useful for web agencies, add your own Name/Description)
85
+ * Manage Groups screen
86
+ * Specify wp-admin path if your site uses a custom one
87
+ * Amazon S3 backups support for mixed case bucket names
88
+ * Bulk Add Links has additional options
89
+ * Better Multisite support
90
+ * Option to set the number of items for Google Analytics
91
+ * ManageWP backup folder changed to wp-content/managewp/backups
92
+
93
+ = 3.9.9 =
94
+ * New widget on the dashboard - Backup status
95
+ * New screen for managing plugins and themes (activate, deactivate, delete, add to favorites, install) across all sites
96
+ * New screen for managing users (change role or password, delete user) across all sites
97
+ * Option to overwrite old plugins and themes during bulk installation
98
+ * Your website admin now loads faster in ManageWP
99
+ * Added API for premium theme and plugin updates
100
+
101
+ = 3.9.8 =
102
+ * Conversion goals integration
103
+ * Update notifications
104
+ * Enhanced security for your account
105
+ * Better backups
106
+ * Better update interface
107
+ * [Full changelog](http://managewp.com/update-goals-and-adsense-analytics-integration-update-notifications-login-by-ip-better-backups "Full changelog")
108
+
109
+ = 3.9.7 =
110
+ * Fixed problem with cron schedules
111
+
112
+ = 3.9.6 =
113
+ * Improved dashboard performance
114
+ * Fixed bug with W3TC, we hope it is fully comptabile now
115
+ * Improved backup feature
116
+ * Various other fixes and improvements
117
+
118
+ = 3.9.5 =
119
+ * Now supporting scheduled backups to Amazon S3 and Dropbox
120
+ * Revamped cloning procedure
121
+ * You can now have sites in different colors
122
+ * W3 Total Cache comptability improved
123
+
124
+ = 3.9.3 =
125
+ * Included support for WordPress 3.2 partial updates
126
+
127
+ = 3.9.2 =
128
+ * Fixed problem with full backups
129
+ * Fixed problem with wordpress dev version upgrades
130
+
131
+ = 3.9.1 =
132
+ * Support for sub-users (limited access users)
133
+ * Bulk add user
134
+ * 'Select all' feature for bulk posting
135
+ * Featured image support for bulk posting
136
+ * Reload button on the dashboard (on the top of the Right now widget) will now refresh information about available updates
137
+ * Fixed a problem with the import tool
138
+ * Fixed a problem when remote dashboard would not work for some servers
139
+
140
+ = 3.9.0 =
141
+ * New feature: Up to 50% faster dashboard loading
142
+ * New feature: You can now ignore WordPress/plugin/theme updates
143
+ * New feature: Setting 'Show favicon' for websites in the dashboad
144
+ * New feature: Full backups now include WordPress and other folders in the root of the site
145
+ * Fixed: Bug with W3 TotalCache object cache causing weird behaviour in the dashboard
146
+ * Fixed: All groups now show when adding a site
147
+
148
+ = 3.8.8 =
149
+ * New feature: Bulk add links to blogroll
150
+ * New feature: Manual backups to email address
151
+ * New feature: Backup requirements check (under �Manage Backups�)
152
+ * New feature: Popup menu for groups allowing to show dashboard for that group only
153
+ * New feature: Favorite list for plugins and themes for later quick installation to multiple blogs
154
+ * New feature: Invite friends
155
+ * Fixed: problem with backups and write permissions when upload dir was wrongly set
156
+ * Fixed: problem adding sites where WordPress is installed in a folder
157
+ * Fixed: 408 error message problem when adding site
158
+ * Fixed: site time out problems when adding site
159
+ * Fixed: problems with some WP plugins (WP Sentinel)
160
+ * Fixed: problems with upgrade notifications
161
+
162
+ = 3.8.7 =
163
+ * Fixed 408 error when adding sites
164
+ * Added support for IDN domains
165
+ * Fixed bug with WordPress updates
166
+ * Added comment moderation to the dashboard
167
+ * Added quick links for sites (menu appears on hover)
168
+
169
+
170
+ = 3.8.6 =
171
+ * Added seach websites feature
172
+ * Enhanced dashboard actions (spam comments, post revisions, table overhead)
173
+ * Added developer [API] (http://managewp.com/api "ManageWP API")
174
+ * Improved Migrate/Clone site feature
175
+
176
+ = 3.8.4 =
177
+ * Fixed remote dashboard problems for sites with redirects
178
+ * Fixed IE7 issues in the dashboard
179
+
180
+ = 3.8.3 =
181
+ * Fixed problem with capabilities
182
+
183
+ = 3.8.2 =
184
+ * New interface
185
+ * SSL security protocol
186
+ * No passwords required
187
+ * Improved clone/backup
188
+
189
+
190
+ = 3.6.3 =
191
+ * Initial public release
192
+
193
+ == Installation ==
194
+
195
+ 1. Upload the plugin folder to your /wp-content/plugins/ folder
196
+ 2. Go to the Plugins page and activate ManageWP Worker
197
+ 3. Visit [ManageWP.com](http://managewp.com/ "Manage Multiple Blogs"), sign up and add your site
198
+
199
+ Alternately
200
+
201
+ 1. Visit [ManageWP.com](http://managewp.com/ "Manage Multiple Blogs"), sign up and add your site
202
+ 2. ManageWP will warn you the worker plugin is not installed and offer a link for quick installation
203
+
204
+ == Screenshots ==
205
+
206
+ 1. ManageWP dashboard with available upgrades, site statistics and management functions
207
+
208
+
209
+
210
+ == License ==
211
+
212
+ This file is part of ManageWP Worker.
213
+
214
+ 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.
215
+
216
+ 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.
217
+
218
+ You should have received a copy of the GNU General Public License along with ManageWP Worker. If not, see <http://www.gnu.org/licenses/>.
219
+
220
+
221
+ == Frequently Asked Questions ==
222
+
223
+ = I have problems adding my site =
224
+
225
+ 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").
226
+
227
+ = I have problems installing new plugins or upgrading WordPress through ManageWP =
228
+
229
  ManageWP Worker relies on properly set file permissions on your server. See the [user guide](http://managewp.com/user-guide#ftp "ManageWP user guide") for more tips.
stats.class.php CHANGED
@@ -1,764 +1,764 @@
1
- <?php
2
- /*************************************************************
3
- *
4
- * stats.class.php
5
- *
6
- * Get Site Stats
7
- *
8
- *
9
- * Copyright (c) 2011 Prelovac Media
10
- * www.prelovac.com
11
- **************************************************************/
12
-
13
-
14
- class MMB_Stats extends MMB_Core
15
- {
16
- function __construct()
17
- {
18
- parent::__construct();
19
- }
20
-
21
- /*************************************************************
22
- * FACADE functions
23
- * (functions to be called after a remote call from Master)
24
- **************************************************************/
25
-
26
- function get_core_update($stats, $options = array())
27
- {
28
- global $wp_version;
29
-
30
- if (isset($options['core']) && $options['core']) {
31
- $core = $this->mmb_get_transient('update_core');
32
- if (isset($core->updates) && !empty($core->updates)) {
33
- $current_transient = $core->updates[0];
34
- if ($current_transient->response == "development" || version_compare($wp_version, $current_transient->current, '<')) {
35
- $current_transient->current_version = $wp_version;
36
- $stats['core_updates'] = $current_transient;
37
- } else
38
- $stats['core_updates'] = false;
39
- } else
40
- $stats['core_updates'] = false;
41
- }
42
-
43
- return $stats;
44
- }
45
-
46
- function get_hit_counter($stats, $options = array())
47
- {
48
- $mmb_user_hits = get_option('user_hit_count');
49
- if (is_array($mmb_user_hits)) {
50
- end($mmb_user_hits);
51
- $last_key_date = key($mmb_user_hits);
52
- $current_date = date('Y-m-d');
53
- if ($last_key_date != $current_date)
54
- $this->set_hit_count(true);
55
- }
56
- $stats['hit_counter'] = get_option('user_hit_count');
57
-
58
- return $stats;
59
- }
60
-
61
- function get_comments($stats, $options = array())
62
- {
63
- $nposts = isset($options['numberposts']) ? (int) $options['numberposts'] : 20;
64
- $trimlen = isset($options['trimcontent']) ? (int) $options['trimcontent'] : 200;
65
-
66
- if ($nposts) {
67
- $comments = get_comments('status=hold&number=' . $nposts);
68
- if (!empty($comments)) {
69
- foreach ($comments as &$comment) {
70
- $commented_post = get_post($comment->comment_post_ID);
71
- $comment->post_title = $commented_post->post_title;
72
- $comment->comment_content = $this->trim_content($comment->comment_content, $trimlen);
73
- unset($comment->comment_author_url);
74
- unset($comment->comment_author_email);
75
- unset($comment->comment_author_IP);
76
- unset($comment->comment_date_gmt);
77
- unset($comment->comment_karma);
78
- unset($comment->comment_agent);
79
- unset($comment->comment_type);
80
- unset($comment->comment_parent);
81
- unset($comment->user_id);
82
- }
83
- $stats['comments']['pending'] = $comments;
84
- }
85
-
86
- $comments = get_comments('status=approve&number=' . $nposts);
87
- if (!empty($comments)) {
88
- foreach ($comments as &$comment) {
89
- $commented_post = get_post($comment->comment_post_ID);
90
- $comment->post_title = $commented_post->post_title;
91
- $comment->comment_content = $this->trim_content($comment->comment_content, $trimlen);
92
- unset($comment->comment_author_url);
93
- unset($comment->comment_author_email);
94
- unset($comment->comment_author_IP);
95
- unset($comment->comment_date_gmt);
96
- unset($comment->comment_karma);
97
- unset($comment->comment_agent);
98
- unset($comment->comment_type);
99
- unset($comment->comment_parent);
100
- unset($comment->user_id);
101
- }
102
- $stats['comments']['approved'] = $comments;
103
- }
104
- }
105
- return $stats;
106
- }
107
-
108
- function get_posts($stats, $options = array())
109
- {
110
- $nposts = isset($options['numberposts']) ? (int) $options['numberposts'] : 20;
111
-
112
- if ($nposts) {
113
- $posts = get_posts('post_status=publish&numberposts=' . $nposts . '&orderby=post_date&order=desc');
114
- $recent_posts = array();
115
- if (!empty($posts)) {
116
- foreach ($posts as $id => $recent_post) {
117
- $recent = new stdClass();
118
- $recent->post_permalink = get_permalink($recent_post->ID);
119
- $recent->ID = $recent_post->ID;
120
- $recent->post_date = $recent_post->post_date;
121
- $recent->post_title = $recent_post->post_title;
122
- $recent->comment_count = (int) $recent_post->comment_count;
123
- $recent_posts[] = $recent;
124
- }
125
- }
126
-
127
- $posts = get_pages('post_status=publish&numberposts=' . $nposts . '&orderby=post_date&order=desc');
128
- $recent_pages_published = array();
129
- if (!empty($posts)) {
130
- foreach ((array) $posts as $id => $recent_page_published) {
131
- $recent = new stdClass();
132
- $recent->post_permalink = get_permalink($recent_page_published->ID);
133
-
134
- $recent->ID = $recent_page_published->ID;
135
- $recent->post_date = $recent_page_published->post_date;
136
- $recent->post_title = $recent_page_published->post_title;
137
-
138
- $recent_posts[] = $recent;
139
- }
140
- }
141
- if (!empty($recent_posts)) {
142
- usort($recent_posts, array(
143
- $this,
144
- 'cmp_posts_worker'
145
- ));
146
- $stats['posts'] = array_slice($recent_posts, 0, $nposts);
147
- }
148
- }
149
- return $stats;
150
- }
151
-
152
- function get_drafts($stats, $options = array())
153
- {
154
- $nposts = isset($options['numberposts']) ? (int) $options['numberposts'] : 20;
155
-
156
- if ($nposts) {
157
- $drafts = get_posts('post_status=draft&numberposts=' . $nposts . '&orderby=post_date&order=desc');
158
- $recent_drafts = array();
159
- if (!empty($drafts)) {
160
- foreach ($drafts as $id => $recent_draft) {
161
- $recent = new stdClass();
162
- $recent->post_permalink = get_permalink($recent_draft->ID);
163
- $recent->ID = $recent_draft->ID;
164
- $recent->post_date = $recent_draft->post_date;
165
- $recent->post_title = $recent_draft->post_title;
166
-
167
- $recent_drafts[] = $recent;
168
- }
169
- }
170
- $drafts = get_pages('post_status=draft&numberposts=' . $nposts . '&orderby=post_date&order=desc');
171
- $recent_pages_drafts = array();
172
- if (!empty($drafts)) {
173
- foreach ((array) $drafts as $id => $recent_pages_draft) {
174
- $recent = new stdClass();
175
- $recent->post_permalink = get_permalink($recent_pages_draft->ID);
176
- $recent->ID = $recent_pages_draft->ID;
177
- $recent->post_date = $recent_pages_draft->post_date;
178
- $recent->post_title = $recent_pages_draft->post_title;
179
-
180
- $recent_drafts[] = $recent;
181
- }
182
- }
183
- if (!empty($recent_drafts)) {
184
- usort($recent_drafts, array(
185
- $this,
186
- 'cmp_posts_worker'
187
- ));
188
- $stats['drafts'] = array_slice($recent_drafts, 0, $nposts);
189
- }
190
- }
191
- return $stats;
192
- }
193
-
194
- function get_scheduled($stats, $options = array())
195
- {
196
- $nposts = isset($options['numberposts']) ? (int) $options['numberposts'] : 20;
197
-
198
- if ($nposts) {
199
- $scheduled = get_posts('post_status=future&numberposts=' . $nposts . '&orderby=post_date&order=desc');
200
- $scheduled_posts = array();
201
- if (!empty($scheduled)) {
202
- foreach ($scheduled as $id => $scheduled) {
203
- $recent = new stdClass();
204
- $recent->post_permalink = get_permalink($scheduled->ID);
205
- $recent->ID = $scheduled->ID;
206
- $recent->post_date = $scheduled->post_date;
207
- $recent->post_title = $scheduled->post_title;
208
- $scheduled_posts[] = $recent;
209
- }
210
- }
211
- $scheduled = get_pages('post_status=future&numberposts=' . $nposts . '&orderby=post_date&order=desc');
212
- $recent_pages_drafts = array();
213
- if (!empty($scheduled)) {
214
- foreach ((array) $scheduled as $id => $scheduled) {
215
- $recent = new stdClass();
216
- $recent->post_permalink = get_permalink($scheduled->ID);
217
- $recent->ID = $scheduled->ID;
218
- $recent->post_date = $scheduled->post_date;
219
- $recent->post_title = $scheduled->post_title;
220
-
221
- $scheduled_posts[] = $recent;
222
- }
223
- }
224
- if (!empty($scheduled_posts)) {
225
- usort($scheduled_posts, array(
226
- $this,
227
- 'cmp_posts_worker'
228
- ));
229
- $stats['scheduled'] = array_slice($scheduled_posts, 0, $nposts);
230
- }
231
- }
232
- return $stats;
233
- }
234
-
235
- function get_backups($stats, $options = array())
236
- {
237
- $stats['mwp_backups'] = $this->get_backup_instance()->get_backup_stats();
238
- $stats['mwp_next_backups'] = $this->get_backup_instance()->get_next_schedules();
239
-
240
- return $stats;
241
- }
242
-
243
- function get_backup_req($stats = array(), $options = array())
244
- {
245
- $stats['mwp_backups'] = $this->get_backup_instance()->get_backup_stats();
246
- $stats['mwp_next_backups'] = $this->get_backup_instance()->get_next_schedules();
247
- $stats['mwp_backup_req'] = $this->get_backup_instance()->check_backup_compat();
248
-
249
- return $stats;
250
- }
251
-
252
- function get_updates($stats, $options = array())
253
- {
254
- $upgrades = false;
255
- $premium = array();
256
- if (isset($options['premium']) && $options['premium']) {
257
- $premium_updates = array();
258
- $upgrades = apply_filters('mwp_premium_update_notification', $premium_updates);
259
- if (!empty($upgrades)) {
260
- foreach( $upgrades as $data ){
261
- if( isset($data['Name']) )
262
- $premium[] = $data['Name'];
263
- }
264
- $stats['premium_updates'] = $upgrades;
265
- $upgrades = false;
266
- }
267
- }
268
- if (isset($options['themes']) && $options['themes']) {
269
- $this->get_installer_instance();
270
- $upgrades = $this->installer_instance->get_upgradable_themes( $premium );
271
- if (!empty($upgrades)) {
272
- $stats['upgradable_themes'] = $upgrades;
273
- $upgrades = false;
274
- }
275
- }
276
-
277
- if (isset($options['plugins']) && $options['plugins']) {
278
- $this->get_installer_instance();
279
- $upgrades = $this->installer_instance->get_upgradable_plugins( $premium );
280
- if (!empty($upgrades)) {
281
- $stats['upgradable_plugins'] = $upgrades;
282
- $upgrades = false;
283
- }
284
- }
285
-
286
- return $stats;
287
- }
288
-
289
- function get_errors($stats, $options = array())
290
- {
291
- $period = isset($options['days']) ? (int) $options['days'] * 86400 : 86400;
292
- $maxerrors = isset($options['max']) ? (int) $options['max'] : 20;
293
- $errors = array();
294
- if (isset($options['get']) && $options['get'] == true) {
295
- if (function_exists('ini_get')) {
296
- $logpath = ini_get('error_log');
297
- if (!empty($logpath) && file_exists($logpath)) {
298
- $logfile = @fopen($logpath, 'r');
299
- if ($logfile && filesize($logpath) > 0) {
300
- $maxlines = 1;
301
- $linesize = -4096;
302
- $lines = array();
303
- $line = true;
304
- while ($line !== false) {
305
- if( fseek($logfile, ($maxlines * $linesize), SEEK_END) !== -1){
306
- $maxlines++;
307
- if ($line) {
308
- $line = fread($logfile, ($linesize * -1)) . $line;
309
-
310
- foreach ((array) preg_split("/(\r|\n|\r\n)/U", $line) as $l) {
311
- preg_match('/\[(.*)\]/Ui', $l, $match);
312
- if (!empty($match)) {
313
- $key = str_replace($match[0], '', $l);
314
- if(!isset($errors[$key])){
315
- $errors[$key] = 1;
316
- } else {
317
- $errors[$key] = $errors[$key] + 1;
318
- }
319
-
320
- if ((strtotime($match[1]) < ((int) time() - $period)) || count($errors) >= $maxerrors) {
321
- $line = false;
322
- break;
323
- }
324
- }
325
- }
326
- }
327
- } else
328
- break;
329
- }
330
- }
331
- if (!empty($errors)){
332
- $stats['errors'] = $errors;
333
- $stats['logpath'] = $logpath;
334
- $stats['logsize'] = @filesize($logpath);
335
- }
336
- }
337
- }
338
- }
339
-
340
- return $stats;
341
- }
342
-
343
- function pre_init_stats($params)
344
- {
345
- global $_mmb_item_filter;
346
-
347
- include_once(ABSPATH . 'wp-includes/update.php');
348
- include_once(ABSPATH . '/wp-admin/includes/update.php');
349
-
350
- $stats = $this->mmb_parse_action_params('pre_init_stats', $params, $this);
351
- $num = extract($params);
352
-
353
- if ($refresh == 'transient') {
354
- $current = $this->mmb_get_transient('update_core');
355
- if (isset($current->last_checked) || get_option('mmb_forcerefresh')) {
356
- update_option('mmb_forcerefresh', false);
357
- if (time() - $current->last_checked > 14400) {
358
- @wp_version_check();
359
- @wp_update_plugins();
360
- @wp_update_themes();
361
- }
362
- }
363
- }
364
-
365
- global $wpdb, $mmb_wp_version, $mmb_plugin_dir, $wp_version, $wp_local_package;
366
-
367
- $stats['worker_version'] = MMB_WORKER_VERSION;
368
- $stats['wordpress_version'] = $wp_version;
369
- $stats['wordpress_locale_pckg'] = $wp_local_package;
370
- $stats['php_version'] = phpversion();
371
- $stats['mysql_version'] = $wpdb->db_version();
372
- $stats['wp_multisite'] = $this->mmb_multisite;
373
- $stats['network_install'] = $this->network_admin_install;
374
-
375
- if ( !function_exists('get_filesystem_method') )
376
- include_once(ABSPATH . 'wp-admin/includes/file.php');
377
- $mmode = get_option('mwp_maintenace_mode');
378
-
379
- if( !empty($mmode) && isset($mmode['active']) && $mmode['active'] == true){
380
- $stats['maintenance'] = true;
381
- }
382
- $stats['writable'] = $this->is_server_writable();
383
-
384
- return $stats;
385
- }
386
-
387
- function get($params)
388
- {
389
- global $wpdb, $mmb_wp_version, $mmb_plugin_dir, $_mmb_item_filter;
390
-
391
- include_once(ABSPATH . 'wp-includes/update.php');
392
- include_once(ABSPATH . '/wp-admin/includes/update.php');
393
-
394
- $stats = $this->mmb_parse_action_params('get', $params, $this);
395
- $update_check = array();
396
- $num = extract($params);
397
- if ($refresh == 'transient') {
398
- $update_check = apply_filters('mwp_premium_update_check', $update_check);
399
- if (!empty($update_check)) {
400
- foreach ($update_check as $update) {
401
- if (is_array($update['callback'])) {
402
- $update_result = call_user_func(array(
403
- $update['callback'][0],
404
- $update['callback'][1]
405
- ));
406
- } else if (is_string($update['callback'])) {
407
- $update_result = call_user_func($update['callback']);
408
- }
409
- }
410
- }
411
- }
412
-
413
- if ($this->mmb_multisite) {
414
- $stats = $this->get_multisite($stats);
415
- }
416
-
417
- $stats = apply_filters('mmb_stats_filter', $stats);
418
- return $stats;
419
- }
420
-
421
- function get_multisite($stats = array())
422
- {
423
- global $current_user, $wpdb;
424
- $user_blogs = get_blogs_of_user( $current_user->ID );
425
- $network_blogs = $wpdb->get_results( $wpdb->prepare("select `blog_id`, `site_id` from `{$wpdb->blogs}`") );
426
- if ($this->network_admin_install == '1' && is_super_admin()) {
427
- if (!empty($network_blogs)) {
428
- $blogs = array();
429
- foreach ( $network_blogs as $details) {
430
- if($details->site_id == $details->blog_id)
431
- continue;
432
- else {
433
- $data = get_blog_details($details->blog_id);
434
- if(in_array($details->blog_id, array_keys($user_blogs)))
435
- $stats['network_blogs'][] = $data->siteurl;
436
- else {
437
- $user = get_users( array( 'blog_id' => $details->blog_id, 'number' => 1) );
438
- if( !empty($user) )
439
- $stats['other_blogs'][$data->siteurl] = $user[0]->user_login;
440
- }
441
- }
442
- }
443
- }
444
- }
445
- return $stats;
446
- }
447
-
448
- function get_comments_stats()
449
- {
450
- $num_pending_comments = 3;
451
- $num_approved_comments = 3;
452
- $pending_comments = get_comments('status=hold&number=' . $num_pending_comments);
453
- foreach ($pending_comments as &$comment) {
454
- $commented_post = get_post($comment->comment_post_ID);
455
- $comment->post_title = $commented_post->post_title;
456
- }
457
- $stats['comments']['pending'] = $pending_comments;
458
-
459
-
460
- $approved_comments = get_comments('status=approve&number=' . $num_approved_comments);
461
- foreach ($approved_comments as &$comment) {
462
- $commented_post = get_post($comment->comment_post_ID);
463
- $comment->post_title = $commented_post->post_title;
464
- }
465
- $stats['comments']['approved'] = $approved_comments;
466
-
467
- return $stats;
468
- }
469
-
470
- function get_initial_stats()
471
- {
472
- global $mmb_plugin_dir;
473
-
474
- $stats = array();
475
-
476
- $stats['email'] = get_option('admin_email');
477
- $stats['no_openssl'] = $this->get_random_signature();
478
- $stats['content_path'] = WP_CONTENT_DIR;
479
- $stats['worker_path'] = $mmb_plugin_dir;
480
- $stats['worker_version'] = MMB_WORKER_VERSION;
481
- $stats['site_title'] = get_bloginfo('name');
482
- $stats['site_tagline'] = get_bloginfo('description');
483
- $stats['site_home'] = get_option('home');
484
- $stats['admin_url'] = admin_url();
485
- $stats['wp_multisite'] = $this->mmb_multisite;
486
- $stats['network_install'] = $this->network_admin_install;
487
-
488
- if ($this->mmb_multisite) {
489
- $details = get_blog_details($this->mmb_multisite);
490
- if (isset($details->site_id)) {
491
- $details = get_blog_details($details->site_id);
492
- if (isset($details->siteurl))
493
- $stats['network_parent'] = $details->siteurl;
494
- }
495
- }
496
- if (!function_exists('get_filesystem_method'))
497
- include_once(ABSPATH . 'wp-admin/includes/file.php');
498
-
499
- $stats['writable'] = $this->is_server_writable();
500
-
501
- return $stats;
502
- }
503
-
504
- function set_hit_count($fix_count = false)
505
- {
506
- global $mmb_core;
507
- if ($fix_count || (!is_admin() && !MMB_Stats::is_bot() && !isset($_GET['doing_wp_cron']))) {
508
-
509
- $date = date('Y-m-d');
510
- $user_hit_count = (array) get_option('user_hit_count');
511
- if (!$user_hit_count) {
512
- $user_hit_count[$date] = 1;
513
- update_option('user_hit_count', $user_hit_count);
514
- } else {
515
- $dated_keys = array_keys($user_hit_count);
516
- $last_visit_date = $dated_keys[count($dated_keys) - 1];
517
-
518
- $days = intval((strtotime($date) - strtotime($last_visit_date)) / 60 / 60 / 24);
519
-
520
- if ($days > 1) {
521
- $date_to_add = date('Y-m-d', strtotime($last_visit_date));
522
-
523
- for ($i = 1; $i < $days; $i++) {
524
- if (count($user_hit_count) > 14) {
525
- $shifted = @array_shift($user_hit_count);
526
- }
527
-
528
- $next_key = strtotime('+1 day', strtotime($date_to_add));
529
- if ($next_key == $date) {
530
- break;
531
- } else {
532
- $user_hit_count[$next_key] = 0;
533
- }
534
- }
535
-
536
- }
537
-
538
- if (!isset($user_hit_count[$date])) {
539
- $user_hit_count[$date] = 0;
540
- }
541
- if (!$fix_count)
542
- $user_hit_count[$date] = ((int) $user_hit_count[$date]) + 1;
543
-
544
- if (count($user_hit_count) > 14) {
545
- $shifted = @array_shift($user_hit_count);
546
- }
547
-
548
- update_option('user_hit_count', $user_hit_count);
549
-
550
- }
551
- }
552
- }
553
-
554
- function get_hit_count()
555
- {
556
- // Check if there are no hits on last key date
557
- $mmb_user_hits = get_option('user_hit_count');
558
- if (is_array($mmb_user_hits)) {
559
- end($mmb_user_hits);
560
- $last_key_date = key($mmb_user_hits);
561
- $current_date = date('Y-m-d');
562
- if ($last_key_date != $curent_date)
563
- $this->set_hit_count(true);
564
- }
565
-
566
- return get_option('user_hit_count');
567
- }
568
-
569
- function is_bot()
570
- {
571
- $agent = $_SERVER['HTTP_USER_AGENT'];
572
-
573
- if ($agent == '')
574
- return false;
575
-
576
- $bot_list = array(
577
- "Teoma",
578
- "alexa",
579
- "froogle",
580
- "Gigabot",
581
- "inktomi",
582
- "looksmart",
583
- "URL_Spider_SQL",
584
- "Firefly",
585
- "NationalDirectory",
586
- "Ask Jeeves",
587
- "TECNOSEEK",
588
- "InfoSeek",
589
- "WebFindBot",
590
- "girafabot",
591
- "crawler",
592
- "www.galaxy.com",
593
- "Googlebot",
594
- "Scooter",
595
- "Slurp",
596
- "msnbot",
597
- "appie",
598
- "FAST",
599
- "WebBug",
600
- "Spade",
601
- "ZyBorg",
602
- "rabaz",
603
- "Baiduspider",
604
- "Feedfetcher-Google",
605
- "TechnoratiSnoop",
606
- "Rankivabot",
607
- "Mediapartners-Google",
608
- "Sogou web spider",
609
- "WebAlta Crawler",
610
- "aolserver"
611
- );
612
-
613
- foreach ($bot_list as $bot)
614
- if (strpos($agent, $bot) !== false)
615
- return true;
616
-
617
- return false;
618
- }
619
-
620
-
621
- function set_notifications($params)
622
- {
623
- if (empty($params))
624
- return false;
625
-
626
- extract($params);
627
-
628
- if (!isset($delete)) {
629
- $mwp_notifications = array(
630
- 'plugins' => $plugins,
631
- 'themes' => $themes,
632
- 'wp' => $wp,
633
- 'backups' => $backups,
634
- 'url' => $url,
635
- 'notification_key' => $notification_key
636
- );
637
- update_option('mwp_notifications', $mwp_notifications);
638
- } else {
639
- delete_option('mwp_notifications');
640
- }
641
-
642
- return true;
643
-
644
- }
645
-
646
- //Cron update check for notifications
647
- function check_notifications()
648
- {
649
- global $wpdb, $mmb_wp_version, $mmb_plugin_dir, $wp_version, $wp_local_package;
650
-
651
- $mwp_notifications = get_option('mwp_notifications', true);
652
-
653
- $args = array();
654
- $updates = array();
655
- $send = 0;
656
- if (is_array($mwp_notifications) && $mwp_notifications != false) {
657
- include_once(ABSPATH . 'wp-includes/update.php');
658
- include_once(ABSPATH . '/wp-admin/includes/update.php');
659
- extract($mwp_notifications);
660
-
661
- //Check wordpress core updates
662
- if ($wp) {
663
- @wp_version_check();
664
- if (function_exists('get_core_updates')) {
665
- $wp_updates = get_core_updates();
666
- if (!empty($wp_updates)) {
667
- $current_transient = $wp_updates[0];
668
- if ($current_transient->response == "development" || version_compare($wp_version, $current_transient->current, '<')) {
669
- $current_transient->current_version = $wp_version;
670
- $updates['core_updates'] = $current_transient;
671
- } else
672
- $updates['core_updates'] = array();
673
- } else
674
- $updates['core_updates'] = array();
675
- }
676
- }
677
-
678
- //Check plugin updates
679
- if ($plugins) {
680
- @wp_update_plugins();
681
- $this->get_installer_instance();
682
- $updates['upgradable_plugins'] = $this->installer_instance->get_upgradable_plugins();
683
- }
684
-
685
- //Check theme updates
686
- if ($themes) {
687
- @wp_update_themes();
688
- $this->get_installer_instance();
689
-
690
- $updates['upgradable_themes'] = $this->installer_instance->get_upgradable_themes();
691
- }
692
-
693
- if ($backups) {
694
- $this->get_backup_instance();
695
- $backups = $this->backup_instance->get_backup_stats();
696
- $updates['backups'] = $backups;
697
- foreach ($backups as $task_name => $backup_results) {
698
- foreach ($backup_results as $k => $backup) {
699
- if (isset($backups[$task_name][$k]['server']['file_path'])) {
700
- unset($backups[$task_name][$k]['server']['file_path']);
701
- }
702
- }
703
- }
704
- $updates['backups'] = $backups;
705
- }
706
-
707
-
708
- if (!empty($updates)) {
709
- $args['body']['updates'] = $updates;
710
- $args['body']['notification_key'] = $notification_key;
711
- $send = 1;
712
- }
713
-
714
- }
715
-
716
-
717
- $alert_data = get_option('mwp_pageview_alerts',true);
718
- if(is_array($alert_data) && $alert_data['alert']){
719
- $pageviews = get_option('user_hit_count');
720
- $args['body']['alerts']['pageviews'] = $pageviews;
721
- $args['body']['alerts']['site_id'] = $alert_data['site_id'];
722
- if(!isset($url)){
723
- $url = $alert_data['url'];
724
- }
725
- $send = 1;
726
- }
727
-
728
- if($send){
729
- if (!class_exists('WP_Http')) {
730
- include_once(ABSPATH . WPINC . '/class-http.php');
731
- }
732
- $result = wp_remote_post($url, $args);
733
-
734
- if (is_array($result) && $result['body'] == 'mwp_delete_alert') {
735
- delete_option('mwp_pageview_alerts');
736
- }
737
- }
738
-
739
-
740
- }
741
-
742
-
743
- function cmp_posts_worker($a, $b)
744
- {
745
- return ($a->post_date < $b->post_date);
746
- }
747
-
748
- function trim_content($content = '', $length = 200)
749
- {
750
- if (function_exists('mb_strlen') && function_exists('mb_substr'))
751
- $content = (mb_strlen($content) > ($length + 3)) ? mb_substr($content, 0, $length) . '...' : $content;
752
- else
753
- $content = (strlen($content) > ($length + 3)) ? substr($content, 0, $length) . '...' : $content;
754
-
755
- return $content;
756
- }
757
-
758
- function set_alerts($args){
759
- extract($args);
760
- update_option('mwp_pageview_alerts',array('site_id' => $site_id,'alert' => $alert,'url' => $url));
761
- }
762
-
763
- }
764
  ?>
1
+ <?php
2
+ /*************************************************************
3
+ *
4
+ * stats.class.php
5
+ *
6
+ * Get Site Stats
7
+ *
8
+ *
9
+ * Copyright (c) 2011 Prelovac Media
10
+ * www.prelovac.com
11
+ **************************************************************/
12
+
13
+
14
+ class MMB_Stats extends MMB_Core
15
+ {
16
+ function __construct()
17
+ {
18
+ parent::__construct();
19
+ }
20
+
21
+ /*************************************************************
22
+ * FACADE functions
23
+ * (functions to be called after a remote call from Master)
24
+ **************************************************************/
25
+
26
+ function get_core_update($stats, $options = array())
27
+ {
28
+ global $wp_version;
29
+
30
+ if (isset($options['core']) && $options['core']) {
31
+ $core = $this->mmb_get_transient('update_core');
32
+ if (isset($core->updates) && !empty($core->updates)) {
33
+ $current_transient = $core->updates[0];
34
+ if ($current_transient->response == "development" || version_compare($wp_version, $current_transient->current, '<')) {
35
+ $current_transient->current_version = $wp_version;
36
+ $stats['core_updates'] = $current_transient;
37
+ } else
38
+ $stats['core_updates'] = false;
39
+ } else
40
+ $stats['core_updates'] = false;
41
+ }
42
+
43
+ return $stats;
44
+ }
45
+
46
+ function get_hit_counter($stats, $options = array())
47
+ {
48
+ $mmb_user_hits = get_option('user_hit_count');
49
+ if (is_array($mmb_user_hits)) {
50
+ end($mmb_user_hits);
51
+ $last_key_date = key($mmb_user_hits);
52
+ $current_date = date('Y-m-d');
53
+ if ($last_key_date != $current_date)
54
+ $this->set_hit_count(true);
55
+ }
56
+ $stats['hit_counter'] = get_option('user_hit_count');
57
+
58
+ return $stats;
59
+ }
60
+
61
+ function get_comments($stats, $options = array())
62
+ {
63
+ $nposts = isset($options['numberposts']) ? (int) $options['numberposts'] : 20;
64
+ $trimlen = isset($options['trimcontent']) ? (int) $options['trimcontent'] : 200;
65
+
66
+ if ($nposts) {
67
+ $comments = get_comments('status=hold&number=' . $nposts);
68
+ if (!empty($comments)) {
69
+ foreach ($comments as &$comment) {
70
+ $commented_post = get_post($comment->comment_post_ID);
71
+ $comment->post_title = $commented_post->post_title;
72
+ $comment->comment_content = $this->trim_content($comment->comment_content, $trimlen);
73
+ unset($comment->comment_author_url);
74
+ unset($comment->comment_author_email);
75
+ unset($comment->comment_author_IP);
76
+ unset($comment->comment_date_gmt);
77
+ unset($comment->comment_karma);
78
+ unset($comment->comment_agent);
79
+ unset($comment->comment_type);
80
+ unset($comment->comment_parent);
81
+ unset($comment->user_id);
82
+ }
83
+ $stats['comments']['pending'] = $comments;
84
+ }
85
+
86
+ $comments = get_comments('status=approve&number=' . $nposts);
87
+ if (!empty($comments)) {
88
+ foreach ($comments as &$comment) {
89
+ $commented_post = get_post($comment->comment_post_ID);
90
+ $comment->post_title = $commented_post->post_title;
91
+ $comment->comment_content = $this->trim_content($comment->comment_content, $trimlen);
92
+ unset($comment->comment_author_url);
93
+ unset($comment->comment_author_email);
94
+ unset($comment->comment_author_IP);
95
+ unset($comment->comment_date_gmt);
96
+ unset($comment->comment_karma);
97
+ unset($comment->comment_agent);
98
+ unset($comment->comment_type);
99
+ unset($comment->comment_parent);
100
+ unset($comment->user_id);
101
+ }
102
+ $stats['comments']['approved'] = $comments;
103
+ }
104
+ }
105
+ return $stats;
106
+ }
107
+
108
+ function get_posts($stats, $options = array())
109
+ {
110
+ $nposts = isset($options['numberposts']) ? (int) $options['numberposts'] : 20;
111
+
112
+ if ($nposts) {
113
+ $posts = get_posts('post_status=publish&numberposts=' . $nposts . '&orderby=post_date&order=desc');
114
+ $recent_posts = array();
115
+ if (!empty($posts)) {
116
+ foreach ($posts as $id => $recent_post) {
117
+ $recent = new stdClass();
118
+ $recent->post_permalink = get_permalink($recent_post->ID);
119
+ $recent->ID = $recent_post->ID;
120
+ $recent->post_date = $recent_post->post_date;
121
+ $recent->post_title = $recent_post->post_title;
122
+ $recent->comment_count = (int) $recent_post->comment_count;
123
+ $recent_posts[] = $recent;
124
+ }
125
+ }
126
+
127
+ $posts = get_pages('post_status=publish&numberposts=' . $nposts . '&orderby=post_date&order=desc');
128
+ $recent_pages_published = array();
129
+ if (!empty($posts)) {
130
+ foreach ((array) $posts as $id => $recent_page_published) {
131
+ $recent = new stdClass();
132
+ $recent->post_permalink = get_permalink($recent_page_published->ID);
133
+
134
+ $recent->ID = $recent_page_published->ID;
135
+ $recent->post_date = $recent_page_published->post_date;
136
+ $recent->post_title = $recent_page_published->post_title;
137
+
138
+ $recent_posts[] = $recent;
139
+ }
140
+ }
141
+ if (!empty($recent_posts)) {
142
+ usort($recent_posts, array(
143
+ $this,
144
+ 'cmp_posts_worker'
145
+ ));
146
+ $stats['posts'] = array_slice($recent_posts, 0, $nposts);
147
+ }
148
+ }
149
+ return $stats;
150
+ }
151
+
152
+ function get_drafts($stats, $options = array())
153
+ {
154
+ $nposts = isset($options['numberposts']) ? (int) $options['numberposts'] : 20;
155
+
156
+ if ($nposts) {
157
+ $drafts = get_posts('post_status=draft&numberposts=' . $nposts . '&orderby=post_date&order=desc');
158
+ $recent_drafts = array();
159
+ if (!empty($drafts)) {
160
+ foreach ($drafts as $id => $recent_draft) {
161
+ $recent = new stdClass();
162
+ $recent->post_permalink = get_permalink($recent_draft->ID);
163
+ $recent->ID = $recent_draft->ID;
164
+ $recent->post_date = $recent_draft->post_date;
165
+ $recent->post_title = $recent_draft->post_title;
166
+
167
+ $recent_drafts[] = $recent;
168
+ }
169
+ }
170
+ $drafts = get_pages('post_status=draft&numberposts=' . $nposts . '&orderby=post_date&order=desc');
171
+ $recent_pages_drafts = array();
172
+ if (!empty($drafts)) {
173
+ foreach ((array) $drafts as $id => $recent_pages_draft) {
174
+ $recent = new stdClass();
175
+ $recent->post_permalink = get_permalink($recent_pages_draft->ID);
176
+ $recent->ID = $recent_pages_draft->ID;
177
+ $recent->post_date = $recent_pages_draft->post_date;
178
+ $recent->post_title = $recent_pages_draft->post_title;
179
+
180
+ $recent_drafts[] = $recent;
181
+ }
182
+ }
183
+ if (!empty($recent_drafts)) {
184
+ usort($recent_drafts, array(
185
+ $this,
186
+ 'cmp_posts_worker'
187
+ ));
188
+ $stats['drafts'] = array_slice($recent_drafts, 0, $nposts);
189
+ }
190
+ }
191
+ return $stats;
192
+ }
193
+
194
+ function get_scheduled($stats, $options = array())
195
+ {
196
+ $nposts = isset($options['numberposts']) ? (int) $options['numberposts'] : 20;
197
+
198
+ if ($nposts) {
199
+ $scheduled = get_posts('post_status=future&numberposts=' . $nposts . '&orderby=post_date&order=desc');
200
+ $scheduled_posts = array();
201
+ if (!empty($scheduled)) {
202
+ foreach ($scheduled as $id => $scheduled) {
203
+ $recent = new stdClass();
204
+ $recent->post_permalink = get_permalink($scheduled->ID);
205
+ $recent->ID = $scheduled->ID;
206
+ $recent->post_date = $scheduled->post_date;
207
+ $recent->post_title = $scheduled->post_title;
208
+ $scheduled_posts[] = $recent;
209
+ }
210
+ }
211
+ $scheduled = get_pages('post_status=future&numberposts=' . $nposts . '&orderby=post_date&order=desc');
212
+ $recent_pages_drafts = array();
213
+ if (!empty($scheduled)) {
214
+ foreach ((array) $scheduled as $id => $scheduled) {
215
+ $recent = new stdClass();
216
+ $recent->post_permalink = get_permalink($scheduled->ID);
217
+ $recent->ID = $scheduled->ID;
218
+ $recent->post_date = $scheduled->post_date;
219
+ $recent->post_title = $scheduled->post_title;
220
+
221
+ $scheduled_posts[] = $recent;
222
+ }
223
+ }
224
+ if (!empty($scheduled_posts)) {
225
+ usort($scheduled_posts, array(
226
+ $this,
227
+ 'cmp_posts_worker'
228
+ ));
229
+ $stats['scheduled'] = array_slice($scheduled_posts, 0, $nposts);
230
+ }
231
+ }
232
+ return $stats;
233
+ }
234
+
235
+ function get_backups($stats, $options = array())
236
+ {
237
+ $stats['mwp_backups'] = $this->get_backup_instance()->get_backup_stats();
238
+ $stats['mwp_next_backups'] = $this->get_backup_instance()->get_next_schedules();
239
+
240
+ return $stats;
241
+ }
242
+
243
+ function get_backup_req($stats = array(), $options = array())
244
+ {
245
+ $stats['mwp_backups'] = $this->get_backup_instance()->get_backup_stats();
246
+ $stats['mwp_next_backups'] = $this->get_backup_instance()->get_next_schedules();
247
+ $stats['mwp_backup_req'] = $this->get_backup_instance()->check_backup_compat();
248
+
249
+ return $stats;
250
+ }
251
+
252
+ function get_updates($stats, $options = array())
253
+ {
254
+ $upgrades = false;
255
+ $premium = array();
256
+ if (isset($options['premium']) && $options['premium']) {
257
+ $premium_updates = array();
258
+ $upgrades = apply_filters('mwp_premium_update_notification', $premium_updates);
259
+ if (!empty($upgrades)) {
260
+ foreach( $upgrades as $data ){
261
+ if( isset($data['Name']) )
262
+ $premium[] = $data['Name'];
263
+ }
264
+ $stats['premium_updates'] = $upgrades;
265
+ $upgrades = false;
266
+ }
267
+ }
268
+ if (isset($options['themes']) && $options['themes']) {
269
+ $this->get_installer_instance();
270
+ $upgrades = $this->installer_instance->get_upgradable_themes( $premium );
271
+ if (!empty($upgrades)) {
272
+ $stats['upgradable_themes'] = $upgrades;
273
+ $upgrades = false;
274
+ }
275
+ }
276
+
277
+ if (isset($options['plugins']) && $options['plugins']) {
278
+ $this->get_installer_instance();
279
+ $upgrades = $this->installer_instance->get_upgradable_plugins( $premium );
280
+ if (!empty($upgrades)) {
281
+ $stats['upgradable_plugins'] = $upgrades;
282
+ $upgrades = false;
283
+ }
284
+ }
285
+
286
+ return $stats;
287
+ }
288
+
289
+ function get_errors($stats, $options = array())
290
+ {
291
+ $period = isset($options['days']) ? (int) $options['days'] * 86400 : 86400;
292
+ $maxerrors = isset($options['max']) ? (int) $options['max'] : 20;
293
+ $errors = array();
294
+ if (isset($options['get']) && $options['get'] == true) {
295
+ if (function_exists('ini_get')) {
296
+ $logpath = ini_get('error_log');
297
+ if (!empty($logpath) && file_exists($logpath)) {
298
+ $logfile = @fopen($logpath, 'r');
299
+ if ($logfile && filesize($logpath) > 0) {
300
+ $maxlines = 1;
301
+ $linesize = -4096;
302
+ $lines = array();
303
+ $line = true;
304
+ while ($line !== false) {
305
+ if( fseek($logfile, ($maxlines * $linesize), SEEK_END) !== -1){
306
+ $maxlines++;
307
+ if ($line) {
308
+ $line = fread($logfile, ($linesize * -1)) . $line;
309
+
310
+ foreach ((array) preg_split("/(\r|\n|\r\n)/U", $line) as $l) {
311
+ preg_match('/\[(.*)\]/Ui', $l, $match);
312
+ if (!empty($match)) {
313
+ $key = str_replace($match[0], '', $l);
314
+ if(!isset($errors[$key])){
315
+ $errors[$key] = 1;
316
+ } else {
317
+ $errors[$key] = $errors[$key] + 1;
318
+ }
319
+
320
+ if ((strtotime($match[1]) < ((int) time() - $period)) || count($errors) >= $maxerrors) {
321
+ $line = false;
322
+ break;
323
+ }
324
+ }
325
+ }
326
+ }
327
+ } else
328
+ break;
329
+ }
330
+ }
331
+ if (!empty($errors)){
332
+ $stats['errors'] = $errors;
333
+ $stats['logpath'] = $logpath;
334
+ $stats['logsize'] = @filesize($logpath);
335
+ }
336
+ }
337
+ }
338
+ }
339
+
340
+ return $stats;
341
+ }
342
+
343
+ function pre_init_stats($params)
344
+ {
345
+ global $_mmb_item_filter;
346
+
347
+ include_once(ABSPATH . 'wp-includes/update.php');
348
+ include_once(ABSPATH . '/wp-admin/includes/update.php');
349
+
350
+ $stats = $this->mmb_parse_action_params('pre_init_stats', $params, $this);
351
+ $num = extract($params);
352
+
353
+ if ($refresh == 'transient') {
354
+ $current = $this->mmb_get_transient('update_core');
355
+ if (isset($current->last_checked) || get_option('mmb_forcerefresh')) {
356
+ update_option('mmb_forcerefresh', false);
357
+ if (time() - $current->last_checked > 14400) {
358
+ @wp_version_check();
359
+ @wp_update_plugins();
360
+ @wp_update_themes();
361
+ }
362
+ }
363
+ }
364
+
365
+ global $wpdb, $mmb_wp_version, $mmb_plugin_dir, $wp_version, $wp_local_package;
366
+
367
+ $stats['worker_version'] = MMB_WORKER_VERSION;
368
+ $stats['wordpress_version'] = $wp_version;
369
+ $stats['wordpress_locale_pckg'] = $wp_local_package;
370
+ $stats['php_version'] = phpversion();
371
+ $stats['mysql_version'] = $wpdb->db_version();
372
+ $stats['wp_multisite'] = $this->mmb_multisite;
373
+ $stats['network_install'] = $this->network_admin_install;
374
+
375
+ if ( !function_exists('get_filesystem_method') )
376
+ include_once(ABSPATH . 'wp-admin/includes/file.php');
377
+ $mmode = get_option('mwp_maintenace_mode');
378
+
379
+ if( !empty($mmode) && isset($mmode['active']) && $mmode['active'] == true){
380
+ $stats['maintenance'] = true;
381
+ }
382
+ $stats['writable'] = $this->is_server_writable();
383
+
384
+ return $stats;
385
+ }
386
+
387
+ function get($params)
388
+ {
389
+ global $wpdb, $mmb_wp_version, $mmb_plugin_dir, $_mmb_item_filter;
390
+
391
+ include_once(ABSPATH . 'wp-includes/update.php');
392
+ include_once(ABSPATH . '/wp-admin/includes/update.php');
393
+
394
+ $stats = $this->mmb_parse_action_params('get', $params, $this);
395
+ $update_check = array();
396
+ $num = extract($params);
397
+ if ($refresh == 'transient') {
398
+ $update_check = apply_filters('mwp_premium_update_check', $update_check);
399
+ if (!empty($update_check)) {
400
+ foreach ($update_check as $update) {
401
+ if (is_array($update['callback'])) {
402
+ $update_result = call_user_func(array(
403
+ $update['callback'][0],
404
+ $update['callback'][1]
405
+ ));
406
+ } else if (is_string($update['callback'])) {
407
+ $update_result = call_user_func($update['callback']);
408
+ }
409
+ }
410
+ }
411
+ }
412
+
413
+ if ($this->mmb_multisite) {
414
+ $stats = $this->get_multisite($stats);
415
+ }
416
+
417
+ $stats = apply_filters('mmb_stats_filter', $stats);
418
+ return $stats;
419
+ }
420
+
421
+ function get_multisite($stats = array())
422
+ {
423
+ global $current_user, $wpdb;
424
+ $user_blogs = get_blogs_of_user( $current_user->ID );
425
+ $network_blogs = $wpdb->get_results( $wpdb->prepare("select `blog_id`, `site_id` from `{$wpdb->blogs}`") );
426
+ if ($this->network_admin_install == '1' && is_super_admin()) {
427
+ if (!empty($network_blogs)) {
428
+ $blogs = array();
429
+ foreach ( $network_blogs as $details) {
430
+ if($details->site_id == $details->blog_id)
431
+ continue;
432
+ else {
433
+ $data = get_blog_details($details->blog_id);
434
+ if(in_array($details->blog_id, array_keys($user_blogs)))
435
+ $stats['network_blogs'][] = $data->siteurl;
436
+ else {
437
+ $user = get_users( array( 'blog_id' => $details->blog_id, 'number' => 1) );
438
+ if( !empty($user) )
439
+ $stats['other_blogs'][$data->siteurl] = $user[0]->user_login;
440
+ }
441
+ }
442
+ }
443
+ }
444
+ }
445
+ return $stats;
446
+ }
447
+
448
+ function get_comments_stats()
449
+ {
450
+ $num_pending_comments = 3;
451
+ $num_approved_comments = 3;
452
+ $pending_comments = get_comments('status=hold&number=' . $num_pending_comments);
453
+ foreach ($pending_comments as &$comment) {
454
+ $commented_post = get_post($comment->comment_post_ID);
455
+ $comment->post_title = $commented_post->post_title;
456
+ }
457
+ $stats['comments']['pending'] = $pending_comments;
458
+
459
+
460
+ $approved_comments = get_comments('status=approve&number=' . $num_approved_comments);
461
+ foreach ($approved_comments as &$comment) {
462
+ $commented_post = get_post($comment->comment_post_ID);
463
+ $comment->post_title = $commented_post->post_title;
464
+ }
465
+ $stats['comments']['approved'] = $approved_comments;
466
+
467
+ return $stats;
468
+ }
469
+
470
+ function get_initial_stats()
471
+ {
472
+ global $mmb_plugin_dir;
473
+
474
+ $stats = array();
475
+
476
+ $stats['email'] = get_option('admin_email');
477
+ $stats['no_openssl'] = $this->get_random_signature();
478
+ $stats['content_path'] = WP_CONTENT_DIR;
479
+ $stats['worker_path'] = $mmb_plugin_dir;
480
+ $stats['worker_version'] = MMB_WORKER_VERSION;
481
+ $stats['site_title'] = get_bloginfo('name');
482
+ $stats['site_tagline'] = get_bloginfo('description');
483
+ $stats['site_home'] = get_option('home');
484
+ $stats['admin_url'] = admin_url();
485
+ $stats['wp_multisite'] = $this->mmb_multisite;
486
+ $stats['network_install'] = $this->network_admin_install;
487
+
488
+ if ($this->mmb_multisite) {
489
+ $details = get_blog_details($this->mmb_multisite);
490
+ if (isset($details->site_id)) {
491
+ $details = get_blog_details($details->site_id);
492
+ if (isset($details->siteurl))
493
+ $stats['network_parent'] = $details->siteurl;
494
+ }
495
+ }
496
+ if (!function_exists('get_filesystem_method'))
497
+ include_once(ABSPATH . 'wp-admin/includes/file.php');
498
+
499
+ $stats['writable'] = $this->is_server_writable();
500
+
501
+ return $stats;
502
+ }
503
+
504
+ function set_hit_count($fix_count = false)
505
+ {
506
+ global $mmb_core;
507
+ if ($fix_count || (!is_admin() && !MMB_Stats::is_bot() && !isset($_GET['doing_wp_cron']))) {
508
+
509
+ $date = date('Y-m-d');
510
+ $user_hit_count = (array) get_option('user_hit_count');
511
+ if (!$user_hit_count) {
512
+ $user_hit_count[$date] = 1;
513
+ update_option('user_hit_count', $user_hit_count);
514
+ } else {
515
+ $dated_keys = array_keys($user_hit_count);
516
+ $last_visit_date = $dated_keys[count($dated_keys) - 1];
517
+
518
+ $days = intval((strtotime($date) - strtotime($last_visit_date)) / 60 / 60 / 24);
519
+
520
+ if ($days > 1) {
521
+ $date_to_add = date('Y-m-d', strtotime($last_visit_date));
522
+
523
+ for ($i = 1; $i < $days; $i++) {
524
+ if (count($user_hit_count) > 14) {
525
+ $shifted = @array_shift($user_hit_count);
526
+ }
527
+
528
+ $next_key = strtotime('+1 day', strtotime($date_to_add));
529
+ if ($next_key == $date) {
530
+ break;
531
+ } else {
532
+ $user_hit_count[$next_key] = 0;
533
+ }
534
+ }
535
+
536
+ }
537
+
538
+ if (!isset($user_hit_count[$date])) {
539
+ $user_hit_count[$date] = 0;
540
+ }
541
+ if (!$fix_count)
542
+ $user_hit_count[$date] = ((int) $user_hit_count[$date]) + 1;
543
+
544
+ if (count($user_hit_count) > 14) {
545
+ $shifted = @array_shift($user_hit_count);
546
+ }
547
+
548
+ update_option('user_hit_count', $user_hit_count);
549
+
550
+ }
551
+ }
552
+ }
553
+
554
+ function get_hit_count()
555
+ {
556
+ // Check if there are no hits on last key date
557
+ $mmb_user_hits = get_option('user_hit_count');
558
+ if (is_array($mmb_user_hits)) {
559
+ end($mmb_user_hits);
560
+ $last_key_date = key($mmb_user_hits);
561
+ $current_date = date('Y-m-d');
562
+ if ($last_key_date != $curent_date)
563
+ $this->set_hit_count(true);
564
+ }
565
+
566
+ return get_option('user_hit_count');
567
+ }
568
+
569
+ function is_bot()
570
+ {
571
+ $agent = $_SERVER['HTTP_USER_AGENT'];
572
+
573
+ if ($agent == '')
574
+ return false;
575
+
576
+ $bot_list = array(
577
+ "Teoma",
578
+ "alexa",
579
+ "froogle",
580
+ "Gigabot",
581
+ "inktomi",
582
+ "looksmart",
583
+ "URL_Spider_SQL",
584
+ "Firefly",
585
+ "NationalDirectory",
586
+ "Ask Jeeves",
587
+ "TECNOSEEK",
588
+ "InfoSeek",
589
+ "WebFindBot",
590
+ "girafabot",
591
+ "crawler",
592
+ "www.galaxy.com",
593
+ "Googlebot",
594
+ "Scooter",
595
+ "Slurp",
596
+ "msnbot",
597
+ "appie",
598
+ "FAST",
599
+ "WebBug",
600
+ "Spade",
601
+ "ZyBorg",
602
+ "rabaz",
603
+ "Baiduspider",
604
+ "Feedfetcher-Google",
605
+ "TechnoratiSnoop",
606
+ "Rankivabot",
607
+ "Mediapartners-Google",
608
+ "Sogou web spider",
609
+ "WebAlta Crawler",
610
+ "aolserver"
611
+ );
612
+
613
+ foreach ($bot_list as $bot)
614
+ if (strpos($agent, $bot) !== false)
615
+ return true;
616
+
617
+ return false;
618
+ }
619
+
620
+
621
+ function set_notifications($params)
622
+ {
623
+ if (empty($params))
624
+ return false;
625
+
626
+ extract($params);
627
+
628
+ if (!isset($delete)) {
629
+ $mwp_notifications = array(
630
+ 'plugins' => $plugins,
631
+ 'themes' => $themes,
632
+ 'wp' => $wp,
633
+ 'backups' => $backups,
634
+ 'url' => $url,
635
+ 'notification_key' => $notification_key
636
+ );
637
+ update_option('mwp_notifications', $mwp_notifications);
638
+ } else {
639
+ delete_option('mwp_notifications');
640
+ }
641
+
642
+ return true;
643
+
644
+ }
645
+
646
+ //Cron update check for notifications
647
+ function check_notifications()
648
+ {
649
+ global $wpdb, $mmb_wp_version, $mmb_plugin_dir, $wp_version, $wp_local_package;
650
+
651
+ $mwp_notifications = get_option('mwp_notifications', true);
652
+
653
+ $args = array();
654
+ $updates = array();
655
+ $send = 0;
656
+ if (is_array($mwp_notifications) && $mwp_notifications != false) {
657
+ include_once(ABSPATH . 'wp-includes/update.php');
658
+ include_once(ABSPATH . '/wp-admin/includes/update.php');
659
+ extract($mwp_notifications);
660
+
661
+ //Check wordpress core updates
662
+ if ($wp) {
663
+ @wp_version_check();
664
+ if (function_exists('get_core_updates')) {
665
+ $wp_updates = get_core_updates();
666
+ if (!empty($wp_updates)) {
667
+ $current_transient = $wp_updates[0];
668
+ if ($current_transient->response == "development" || version_compare($wp_version, $current_transient->current, '<')) {
669
+ $current_transient->current_version = $wp_version;
670
+ $updates['core_updates'] = $current_transient;
671
+ } else
672
+ $updates['core_updates'] = array();
673
+ } else
674
+ $updates['core_updates'] = array();
675
+ }
676
+ }
677
+
678
+ //Check plugin updates
679
+ if ($plugins) {
680
+ @wp_update_plugins();
681
+ $this->get_installer_instance();
682
+ $updates['upgradable_plugins'] = $this->installer_instance->get_upgradable_plugins();
683
+ }
684
+
685
+ //Check theme updates
686
+ if ($themes) {
687
+ @wp_update_themes();
688
+ $this->get_installer_instance();
689
+
690
+ $updates['upgradable_themes'] = $this->installer_instance->get_upgradable_themes();
691
+ }
692
+
693
+ if ($backups) {
694
+ $this->get_backup_instance();
695
+ $backups = $this->backup_instance->get_backup_stats();
696
+ $updates['backups'] = $backups;
697
+ foreach ($backups as $task_name => $backup_results) {
698
+ foreach ($backup_results as $k => $backup) {
699
+ if (isset($backups[$task_name][$k]['server']['file_path'])) {
700
+ unset($backups[$task_name][$k]['server']['file_path']);
701
+ }
702
+ }
703
+ }
704
+ $updates['backups'] = $backups;
705
+ }
706
+
707
+
708
+ if (!empty($updates)) {
709
+ $args['body']['updates'] = $updates;
710
+ $args['body']['notification_key'] = $notification_key;
711
+ $send = 1;
712
+ }
713
+
714
+ }
715
+
716
+
717
+ $alert_data = get_option('mwp_pageview_alerts',true);
718
+ if(is_array($alert_data) && $alert_data['alert']){
719
+ $pageviews = get_option('user_hit_count');
720
+ $args['body']['alerts']['pageviews'] = $pageviews;
721
+ $args['body']['alerts']['site_id'] = $alert_data['site_id'];
722
+ if(!isset($url)){
723
+ $url = $alert_data['url'];
724
+ }
725
+ $send = 1;
726
+ }
727
+
728
+ if($send){
729
+ if (!class_exists('WP_Http')) {
730
+ include_once(ABSPATH . WPINC . '/class-http.php');
731
+ }
732
+ $result = wp_remote_post($url, $args);
733
+
734
+ if (is_array($result) && $result['body'] == 'mwp_delete_alert') {
735
+ delete_option('mwp_pageview_alerts');
736
+ }
737
+ }
738
+
739
+
740
+ }
741
+
742
+
743
+ function cmp_posts_worker($a, $b)
744
+ {
745
+ return ($a->post_date < $b->post_date);
746
+ }
747
+
748
+ function trim_content($content = '', $length = 200)
749
+ {
750
+ if (function_exists('mb_strlen') && function_exists('mb_substr'))
751
+ $content = (mb_strlen($content) > ($length + 3)) ? mb_substr($content, 0, $length) . '...' : $content;
752
+ else
753
+ $content = (strlen($content) > ($length + 3)) ? substr($content, 0, $length) . '...' : $content;
754
+
755
+ return $content;
756
+ }
757
+
758
+ function set_alerts($args){
759
+ extract($args);
760
+ update_option('mwp_pageview_alerts',array('site_id' => $site_id,'alert' => $alert,'url' => $url));
761
+ }
762
+
763
+ }
764
  ?>
user.class.php CHANGED
@@ -1,213 +1,213 @@
1
- <?php
2
- /*************************************************************
3
- *
4
- * user.class.php
5
- *
6
- * Add Users
7
- *
8
- *
9
- * Copyright (c) 2011 Prelovac Media
10
- * www.prelovac.com
11
- **************************************************************/
12
-
13
- class MMB_User extends MMB_Core
14
- {
15
- function __construct()
16
- {
17
- parent::__construct();
18
- }
19
-
20
- function get_users($args){
21
- global $wpdb;
22
-
23
- //$args: $user_roles;
24
- if(empty($args))
25
- return false;
26
-
27
- extract($args);
28
-
29
- $userlevels = array();
30
- $level_strings = array();
31
- foreach($user_roles as $user_role){
32
- switch(strtolower($user_role)){
33
- case 'subscriber' : $userlevels[] = 0; $level_strings[] = $user_role; break;
34
- case 'contributor' : $userlevels[] = 1; $level_strings[] = $user_role; break;
35
- case 'author' : $userlevels[] = 2; $level_strings[] = $user_role; break;
36
- case 'editor' : $userlevels[] = 7; $level_strings[] = $user_role; break;
37
- case 'administrator' : $userlevels[] = 10; $level_strings[] = $user_role; break;
38
- default: break;
39
- }
40
- }
41
-
42
- $users = array();
43
- $userlevel_qry = "('".implode("','",$userlevels)."')";
44
- $userlevel_fallback_qry = "('%".implode("%','%",$level_strings)."%')";
45
- $field = $wpdb->prefix."capabilities";
46
-
47
- $user_metas = $wpdb->get_results("SELECT * from $wpdb->usermeta WHERE meta_key = '$field' AND meta_value IN $userlevel_fallback_qry");
48
- if($user_metas == false || empty($user_metas)){
49
- $user_metas = $wpdb->get_results("SELECT * from $wpdb->usermeta WHERE meta_key = 'wp_user_level' AND meta_value IN $userlevel_qry");
50
- }
51
-
52
- $include = array();
53
- if(is_array($user_metas) && !empty($user_metas)){
54
- foreach($user_metas as $user_meta){
55
- $include[] = $user_meta->user_id;
56
- }
57
- }
58
-
59
- $args = array();
60
- $args['include'] = $include;
61
- $args['fields'] = 'all_with_meta';
62
- $temp_users = get_users($args);
63
- $user = array();
64
- foreach ((array)$temp_users as $temp){
65
- $user['user_id'] = $temp->ID;
66
- $user['user_login'] = $temp->user_login;
67
- $user['wp_capabilities'] = array_keys($temp->$field);
68
- $users[] = $user;
69
- }
70
-
71
- return array('users' => $users);
72
- }
73
-
74
- function add_user($args)
75
- {
76
-
77
- if(!function_exists('username_exists') || !function_exists('email_exists'))
78
- include_once(ABSPATH . WPINC . '/registration.php');
79
-
80
- if(username_exists($args['user_login']))
81
- return array('error' => 'Username already exists');
82
-
83
- if (email_exists($args['user_email']))
84
- return array('error' => 'Email already exists');
85
-
86
- if(!function_exists('wp_insert_user'))
87
- include_once (ABSPATH . 'wp-admin/includes/user.php');
88
-
89
- $user_id = wp_insert_user($args);
90
-
91
- if($user_id){
92
-
93
- if($args['email_notify']){
94
- //require_once ABSPATH . WPINC . '/pluggable.php';
95
- wp_new_user_notification($user_id, $args['user_pass']);
96
- }
97
- return $user_id;
98
- }else{
99
- return array('error' => 'User not added. Please try again.');
100
- }
101
-
102
- }
103
-
104
- function edit_users($args){
105
-
106
- if(empty($args))
107
- return false;
108
- if(!function_exists('get_user_to_edit'))
109
- include_once (ABSPATH . 'wp-admin/includes/user.php');
110
- if(!function_exists('wp_update_user'))
111
- include_once (ABSPATH . WPINC.'/user.php');
112
-
113
- extract($args);
114
- //$args: $users, $new_role, $new_password, $user_edit_action
115
-
116
- $return = array();
117
- if(count($users)){
118
- foreach($users as $user){
119
- $result = '';
120
- $user_obj = $this->mmb_get_user_info( $user );
121
- if($user_obj != false){
122
- switch($user_edit_action){
123
- case 'change-password':
124
- if($new_password){
125
- $user_data = array();
126
- $userdata['user_pass'] = $new_password;
127
- $userdata['ID'] = $user_obj->ID;
128
- $result = wp_update_user($userdata);
129
- } else {
130
- $result = array('error' => 'No password provided.');
131
- }
132
- break;
133
- case 'change-role':
134
- if($new_role){
135
- if($user != $username){
136
- if(!$this->last_admin($user_obj)){
137
- $user_data = array();
138
- $userdata['ID'] = $user_obj->ID;
139
- $userdata['role'] = strtolower($new_role);
140
- $result = wp_update_user($userdata);
141
- } else {
142
- $result = array('error' => 'Cannot change role to the only one left admin user.');
143
- }
144
- } else {
145
- $result = array('error' => 'Cannot change role to user assigned for ManageWP.');
146
- }
147
- } else {
148
- $result = array('error' => 'No role provided.');
149
- }
150
- break;
151
- case 'delete-user':
152
- if($user != $username){
153
- if(!$this->last_admin($user_obj)){
154
- if($reassign_user){
155
- $to_user = $this->mmb_get_user_info( $reassign_user );
156
- if($to_user != false){
157
- $result = wp_delete_user($user_obj->ID, $to_user->ID);
158
- } else {
159
- $result = array('error' => 'User not deleted. User to reassign posts doesn\'t exist.');
160
- }
161
- } else {
162
- $result = wp_delete_user($user_obj->ID);
163
- }
164
- } else {
165
- $result = array('error' => 'Cannot delete the only one left admin user.');
166
- }
167
- } else {
168
- $result = array('error' => 'Cannot delete user assigned for ManageWP.');
169
- }
170
-
171
- break;
172
- default:
173
- $result = array('error' => 'Wrong action provided. Please try again.');
174
- break;
175
- }
176
- } else {
177
- $result = array('error' => 'User not found.');
178
- }
179
-
180
- if(is_wp_error($result)){
181
- $result = array('error' => $result->get_error_message());
182
- }
183
-
184
- $return[$user] = $result;
185
- }
186
- }
187
-
188
- return $return;
189
-
190
- }
191
-
192
- //Check if user is the only one admin on the site
193
- function last_admin($user_obj){
194
- global $wpdb;
195
- $field = $wpdb->prefix."capabilities";
196
- $capabilities = array_map('strtolower',array_keys($user_obj->$field));
197
- $result = count_users();
198
- if(in_array('administrator',$capabilities)){
199
-
200
- if(!function_exists('count_users')){
201
- include_once (ABSPATH . WPINC. '/user.php');
202
- }
203
-
204
- $result = count_users();
205
- if($result['avail_roles']['administrator'] == 1){
206
- return true;
207
- }
208
- }
209
- return false;
210
- }
211
-
212
- }
213
  ?>
1
+ <?php
2
+ /*************************************************************
3
+ *
4
+ * user.class.php
5
+ *
6
+ * Add Users
7
+ *
8
+ *
9
+ * Copyright (c) 2011 Prelovac Media
10
+ * www.prelovac.com
11
+ **************************************************************/
12
+
13
+ class MMB_User extends MMB_Core
14
+ {
15
+ function __construct()
16
+ {
17
+ parent::__construct();
18
+ }
19
+
20
+ function get_users($args){
21
+ global $wpdb;
22
+
23
+ //$args: $user_roles;
24
+ if(empty($args))
25
+ return false;
26
+
27
+ extract($args);
28
+
29
+ $userlevels = array();
30
+ $level_strings = array();
31
+ foreach($user_roles as $user_role){
32
+ switch(strtolower($user_role)){
33
+ case 'subscriber' : $userlevels[] = 0; $level_strings[] = $user_role; break;
34
+ case 'contributor' : $userlevels[] = 1; $level_strings[] = $user_role; break;
35
+ case 'author' : $userlevels[] = 2; $level_strings[] = $user_role; break;
36
+ case 'editor' : $userlevels[] = 7; $level_strings[] = $user_role; break;
37
+ case 'administrator' : $userlevels[] = 10; $level_strings[] = $user_role; break;
38
+ default: break;
39
+ }
40
+ }
41
+
42
+ $users = array();
43
+ $userlevel_qry = "('".implode("','",$userlevels)."')";
44
+ $userlevel_fallback_qry = "('%".implode("%','%",$level_strings)."%')";
45
+ $field = $wpdb->prefix."capabilities";
46
+
47
+ $user_metas = $wpdb->get_results("SELECT * from $wpdb->usermeta WHERE meta_key = '$field' AND meta_value IN $userlevel_fallback_qry");
48
+ if($user_metas == false || empty($user_metas)){
49
+ $user_metas = $wpdb->get_results("SELECT * from $wpdb->usermeta WHERE meta_key = 'wp_user_level' AND meta_value IN $userlevel_qry");
50
+ }
51
+
52
+ $include = array();
53
+ if(is_array($user_metas) && !empty($user_metas)){
54
+ foreach($user_metas as $user_meta){
55
+ $include[] = $user_meta->user_id;
56
+ }
57
+ }
58
+
59
+ $args = array();
60
+ $args['include'] = $include;
61
+ $args['fields'] = 'all_with_meta';
62
+ $temp_users = get_users($args);
63
+ $user = array();
64
+ foreach ((array)$temp_users as $temp){
65
+ $user['user_id'] = $temp->ID;
66
+ $user['user_login'] = $temp->user_login;
67
+ $user['wp_capabilities'] = array_keys($temp->$field);
68
+ $users[] = $user;
69
+ }
70
+
71
+ return array('users' => $users);
72
+ }
73
+
74
+ function add_user($args)
75
+ {
76
+
77
+ if(!function_exists('username_exists') || !function_exists('email_exists'))
78
+ include_once(ABSPATH . WPINC . '/registration.php');
79
+
80
+ if(username_exists($args['user_login']))
81
+ return array('error' => 'Username already exists');
82
+
83
+ if (email_exists($args['user_email']))
84
+ return array('error' => 'Email already exists');
85
+
86
+ if(!function_exists('wp_insert_user'))
87
+ include_once (ABSPATH . 'wp-admin/includes/user.php');
88
+
89
+ $user_id = wp_insert_user($args);
90
+
91
+ if($user_id){
92
+
93
+ if($args['email_notify']){
94
+ //require_once ABSPATH . WPINC . '/pluggable.php';
95
+ wp_new_user_notification($user_id, $args['user_pass']);
96
+ }
97
+ return $user_id;
98
+ }else{
99
+ return array('error' => 'User not added. Please try again.');
100
+ }
101
+
102
+ }
103
+
104
+ function edit_users($args){
105
+
106
+ if(empty($args))
107
+ return false;
108
+ if(!function_exists('get_user_to_edit'))
109
+ include_once (ABSPATH . 'wp-admin/includes/user.php');
110
+ if(!function_exists('wp_update_user'))
111
+ include_once (ABSPATH . WPINC.'/user.php');
112
+
113
+ extract($args);
114
+ //$args: $users, $new_role, $new_password, $user_edit_action
115
+
116
+ $return = array();
117
+ if(count($users)){
118
+ foreach($users as $user){
119
+ $result = '';
120
+ $user_obj = $this->mmb_get_user_info( $user );
121
+ if($user_obj != false){
122
+ switch($user_edit_action){
123
+ case 'change-password':
124
+ if($new_password){
125
+ $user_data = array();
126
+ $userdata['user_pass'] = $new_password;
127
+ $userdata['ID'] = $user_obj->ID;
128
+ $result = wp_update_user($userdata);
129
+ } else {
130
+ $result = array('error' => 'No password provided.');
131
+ }
132
+ break;
133
+ case 'change-role':
134
+ if($new_role){
135
+ if($user != $username){
136
+ if(!$this->last_admin($user_obj)){
137
+ $user_data = array();
138
+ $userdata['ID'] = $user_obj->ID;
139
+ $userdata['role'] = strtolower($new_role);
140
+ $result = wp_update_user($userdata);
141
+ } else {
142
+ $result = array('error' => 'Cannot change role to the only one left admin user.');
143
+ }
144
+ } else {
145
+ $result = array('error' => 'Cannot change role to user assigned for ManageWP.');
146
+ }
147
+ } else {
148
+ $result = array('error' => 'No role provided.');
149
+ }
150
+ break;
151
+ case 'delete-user':
152
+ if($user != $username){
153
+ if(!$this->last_admin($user_obj)){
154
+ if($reassign_user){
155
+ $to_user = $this->mmb_get_user_info( $reassign_user );
156
+ if($to_user != false){
157
+ $result = wp_delete_user($user_obj->ID, $to_user->ID);
158
+ } else {
159
+ $result = array('error' => 'User not deleted. User to reassign posts doesn\'t exist.');
160
+ }
161
+ } else {
162
+ $result = wp_delete_user($user_obj->ID);
163
+ }
164
+ } else {
165
+ $result = array('error' => 'Cannot delete the only one left admin user.');
166
+ }
167
+ } else {
168
+ $result = array('error' => 'Cannot delete user assigned for ManageWP.');
169
+ }
170
+
171
+ break;
172
+ default:
173
+ $result = array('error' => 'Wrong action provided. Please try again.');
174
+ break;
175
+ }
176
+ } else {
177
+ $result = array('error' => 'User not found.');
178
+ }
179
+
180
+ if(is_wp_error($result)){
181
+ $result = array('error' => $result->get_error_message());
182
+ }
183
+
184
+ $return[$user] = $result;
185
+ }
186
+ }
187
+
188
+ return $return;
189
+
190
+ }
191
+
192
+ //Check if user is the only one admin on the site
193
+ function last_admin($user_obj){
194
+ global $wpdb;
195
+ $field = $wpdb->prefix."capabilities";
196
+ $capabilities = array_map('strtolower',array_keys($user_obj->$field));
197
+ $result = count_users();
198
+ if(in_array('administrator',$capabilities)){
199
+
200
+ if(!function_exists('count_users')){
201
+ include_once (ABSPATH . WPINC. '/user.php');
202
+ }
203
+
204
+ $result = count_users();
205
+ if($result['avail_roles']['administrator'] == 1){
206
+ return true;
207
+ }
208
+ }
209
+ return false;
210
+ }
211
+
212
+ }
213
  ?>
version CHANGED
@@ -1 +1 @@
1
- 3.9.16
1
+ 3.9.17
widget.class.php CHANGED
@@ -1,52 +1,52 @@
1
- <?php
2
- /**
3
- * ManageWP_Widget Class
4
- */
5
- class ManageWP_Widget extends WP_Widget {
6
-
7
-
8
- /** constructor -- name this the same as the class above */
9
- function ManageWP_Widget() {
10
- parent::WP_Widget(false, $name = 'ManageWP', array('description' => 'ManageWP widget.'));
11
- }
12
-
13
- /** @see WP_Widget::widget -- do not rename this */
14
- function widget($args, $instance) {
15
- extract( $args );
16
- $instance['title'] = 'ManageWP';
17
- $instance['message'] = 'We are happily using <a href="http://managewp.com" target="_blank">ManageWP</a>';
18
- $title = apply_filters('widget_title', $instance['title']);
19
- $message = $instance['message'];
20
- ?>
21
- <?php echo $before_widget; ?>
22
- <?php if ( $title )
23
- echo $before_title . $title . $after_title; ?>
24
- <ul>
25
- <li><?php echo $message; ?></li>
26
- </ul>
27
- <?php echo $after_widget; ?>
28
- <?php
29
- }
30
-
31
- /** @see WP_Widget::form -- do not rename this */
32
- function form($instance) {
33
- $title = 'ManageWP';
34
- $message = 'We are happily using <a href="http://managewp.com" target="_blank">ManageWP</a>';
35
- echo '<p>'.$message.'</p>';
36
- }
37
-
38
-
39
- } // end class example_widget
40
-
41
- $mwp_worker_brand = get_option("mwp_worker_brand");
42
- $worker_brand = 0;
43
- if(is_array($mwp_worker_brand)){
44
- if($mwp_worker_brand['name'] || $mwp_worker_brand['desc'] || $mwp_worker_brand['author'] || $mwp_worker_brand['author_url']){
45
- $worker_brand= 1;
46
- }
47
- }
48
- if(!$worker_brand){
49
- add_action('widgets_init', create_function('', 'return register_widget("ManageWP_Widget");'));
50
- }
51
-
52
  ?>
1
+ <?php
2
+ /**
3
+ * ManageWP_Widget Class
4
+ */
5
+ class ManageWP_Widget extends WP_Widget {
6
+
7
+
8
+ /** constructor -- name this the same as the class above */
9
+ function ManageWP_Widget() {
10
+ parent::WP_Widget(false, $name = 'ManageWP', array('description' => 'ManageWP widget.'));
11
+ }
12
+
13
+ /** @see WP_Widget::widget -- do not rename this */
14
+ function widget($args, $instance) {
15
+ extract( $args );
16
+ $instance['title'] = 'ManageWP';
17
+ $instance['message'] = 'We are happily using <a href="http://managewp.com" target="_blank">ManageWP</a>';
18
+ $title = apply_filters('widget_title', $instance['title']);
19
+ $message = $instance['message'];
20
+ ?>
21
+ <?php echo $before_widget; ?>
22
+ <?php if ( $title )
23
+ echo $before_title . $title . $after_title; ?>
24
+ <ul>
25
+ <li><?php echo $message; ?></li>
26
+ </ul>
27
+ <?php echo $after_widget; ?>
28
+ <?php
29
+ }
30
+
31
+ /** @see WP_Widget::form -- do not rename this */
32
+ function form($instance) {
33
+ $title = 'ManageWP';
34
+ $message = 'We are happily using <a href="http://managewp.com" target="_blank">ManageWP</a>';
35
+ echo '<p>'.$message.'</p>';
36
+ }
37
+
38
+
39
+ } // end class example_widget
40
+
41
+ $mwp_worker_brand = get_option("mwp_worker_brand");
42
+ $worker_brand = 0;
43
+ if(is_array($mwp_worker_brand)){
44
+ if($mwp_worker_brand['name'] || $mwp_worker_brand['desc'] || $mwp_worker_brand['author'] || $mwp_worker_brand['author_url']){
45
+ $worker_brand= 1;
46
+ }
47
+ }
48
+ if(!$worker_brand){
49
+ add_action('widgets_init', create_function('', 'return register_widget("ManageWP_Widget");'));
50
+ }
51
+
52
  ?>