ManageWP Worker - Version 3.9.9

Version Description

  • New widget on the dashboard - Backup status
  • New screen for managing plugins and themes (activate, deactivate, delete, add to favorites, install) across all sites
  • New screen for managing users (change role or password, delete user) across all sites
  • Option to overwrite old plugins and themes during bulk installation
  • Your website admin now loads faster in ManageWP
  • Added API for premium theme and plugin updates
Download this release

Release Info

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

Code changes from version 3.9.8 to 3.9.9

Files changed (17) hide show
  1. api.php +40 -37
  2. backup.class.php +1456 -1456
  3. comment.class.php +42 -42
  4. core.class.php +440 -443
  5. helper.class.php +437 -433
  6. init.php +719 -669
  7. installer.class.php +744 -460
  8. lib/dropbox.php +144 -144
  9. lib/s3.php +1922 -1922
  10. link.class.php +38 -38
  11. plugins/cleanup/cleanup.php +175 -175
  12. plugins/extra_html_example/extra_html_example.php +17 -17
  13. plugins/search/search.php +129 -129
  14. post.class.php +344 -339
  15. readme.txt +25 -4
  16. stats.class.php +487 -464
  17. user.class.php +205 -52
api.php CHANGED
@@ -1,38 +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
-
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
-
26
- function mmb_function_exists($callback)
27
- {
28
- global $mwp_core;
29
- if (count($callback) === 2) {
30
- if (!method_exists($callback[0], $callback[1]))
31
- wp_die($mwp_core->mwp_dashboard_widget('Information', '', '<p>Class ' . get_class($callback[0]) . ' does not contain <b>"' . $callback[1] . '"</b> function</p>', '', '50%'));
32
- } else {
33
- if (!function_exists($callback))
34
- wp_die($mwp_core->mwp_dashboard_widget('Information', '', '<p>Function <b>"' . $callback . '"</b> does not exists.</p>', '', '50%'));
35
- }
36
- }
37
-
 
 
 
38
  ?>
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,1457 +1,1457 @@
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
-
13
- class MMB_Backup extends MMB_Core
14
- {
15
- var $site_name;
16
- function __construct()
17
- {
18
- parent::__construct();
19
- $this->site_name = str_replace("/","-",rtrim($this->remove_http(get_bloginfo('home')),"/"));
20
- }
21
-
22
- function get_backup_settings()
23
- {
24
- $backup_settings = get_option('mwp_backup_tasks');
25
- if (!empty($backup_settings))
26
- return $backup_settings;
27
- else
28
- return false;
29
- }
30
-
31
- function set_backup_task($params)
32
- {
33
- //$params => [$task_name, $args, $error]
34
- if (!empty($params)) {
35
- extract($params);
36
-
37
- $before = $this->get_backup_settings();
38
- if (!$before || empty($before))
39
- $before = array();
40
-
41
- if (isset($args['remove'])) {
42
- unset($before[$task_name]);
43
- $return = array(
44
- 'removed' => true
45
- );
46
- } else {
47
- if(is_array($params['account_info'])){ //only if sends from master first time(secure data)
48
- $args['account_info'] = $account_info;
49
- }
50
-
51
- $before[$task_name]['task_args'] = $args;
52
- if (strlen($args['schedule']))
53
- $before[$task_name]['task_args']['next'] = $this->schedule_next($args['type'], $args['schedule']);
54
-
55
- $return = $before[$task_name];
56
- }
57
-
58
- if ($error) {
59
- if(is_array($error)){
60
- $before[$task_name]['task_results'][count($before[$task_name]['task_results'])-1]['error'] = $error['error'];
61
- } else {
62
- $before[$task_name]['task_results'][count($before[$task_name]['task_results'])]['error'] = $error;
63
- }
64
- }
65
- update_option('mwp_backup_tasks', $before);
66
-
67
- if ($task_name == 'Backup Now') {
68
- $result = $this->backup($args, $task_name);
69
- $backup_settings = $this->get_backup_settings();
70
- if (is_array($result) && array_key_exists('error', $result)) {
71
- $return = $result;
72
- } else {
73
- $return = $backup_settings[$task_name];
74
- }
75
- }
76
- return $return;
77
- }
78
- return false;
79
- }
80
-
81
- //Cron check
82
- function check_backup_tasks()
83
- {
84
- $settings = $this->get_backup_settings();
85
- if (is_array($settings) && !empty($settings)) {
86
- foreach ($settings as $task_name => $setting) {
87
- if ($setting['task_args']['next'] && $setting['task_args']['next'] < time()) {
88
- //Update task with next schedule
89
- $this->set_backup_task(array(
90
- 'task_name' => $task_name,
91
- 'args' => $settings[$task_name]['task_args']
92
- ));
93
-
94
- $result = $this->backup($setting['task_args'], $task_name);
95
- $error = '';
96
- if (is_array($result) && array_key_exists('error', $result)) {
97
- $error = $result;
98
- $this->set_backup_task(array(
99
- 'task_name' => $task_name,
100
- 'args' => $settings[$task_name]['task_args'],
101
- 'error' => $error
102
- ));
103
- } else {
104
- $error = '';
105
- }
106
-
107
-
108
- break;
109
- }
110
- }
111
- }
112
-
113
- }
114
-
115
-
116
-
117
- /*
118
- * If Task Name not set then it's manual backup
119
- * Backup args:
120
- * type -> db, full
121
- * what -> daily, weekly, monthly
122
- * account_info -> ftp, amazons3, dropbox
123
- * exclude-> array of paths to exclude from backup
124
- */
125
-
126
- function backup($args, $task_name = false)
127
- {
128
- if (!$args || empty($args))
129
- return false;
130
-
131
- extract($args); //extract settings
132
-
133
- //try increase memory limit
134
- @ini_set('memory_limit', '1000M');
135
- @set_time_limit(600); //ten minutes
136
-
137
- //Remove old backup(s)
138
- if ($type == 'manual') {
139
- $old = get_option('mwp_manual_backup');
140
- if ($old['file_path'] && file_exists($old['file_path']))
141
- @unlink($old['file_path']);
142
- } else {
143
- $this->remove_old_backups($task_name);
144
- }
145
-
146
- $sec_string = md5('mmb-worker');
147
- $file = "/$sec_string/mwp_backups";
148
- $new_file_path = WP_CONTENT_DIR . $file;
149
-
150
- if (!file_exists($new_file_path)) {
151
- if (!mkdir($new_file_path, 0755, true))
152
- return array(
153
- 'error' => 'Permission denied, make sure you have write permission to wp-content folder.'
154
- );
155
- }
156
-
157
- @file_put_contents($new_file_path . '/index.php', ''); //safe
158
-
159
- //Delete possible breaked previous backups - don't need it anymore (works only for previous wrokers)
160
- foreach (glob($new_file_path . "/*.zip") as $filename) {
161
- $short = basename($filename);
162
- preg_match('/^wp\-content(.*)/Ui', $short, $matches);
163
- if ($matches)
164
- @unlink($filename);
165
- }
166
-
167
- //Prepare .zip file name
168
- $site_name = $this->remove_http(get_bloginfo('url'));
169
- $site_name = str_replace(array(
170
- "_",
171
- "/"
172
- ), array(
173
- "",
174
- "-"
175
- ), $site_name);
176
-
177
- $hash = md5(time());
178
- $label = $type ? $type : 'manual';
179
- $backup_file = $new_file_path . '/' . $site_name . '_' . $label . '_' . $what . '_' . date('Y-m-d') . '_' . $hash . '.zip';
180
- $backup_url = WP_CONTENT_URL . $file . '/' . $site_name . '_' . $label . '_' . $what . '_' . date('Y-m-d') . '_' . $hash . '.zip';
181
-
182
-
183
- //What to backup - db or full
184
- if (trim($what) == 'db') {
185
- //take database backup
186
-
187
- $db_result = $this->backup_db();
188
- if ($db_result == false) {
189
- return array(
190
- 'error' => 'Failed to backup database.'
191
- );
192
- } else if (is_array($db_result) && isset($db_result['error'])) {
193
- return array(
194
- 'error' => $db_result['error']
195
- );
196
-
197
- } else {
198
- if ($this->mmb_exec('which zip')) {
199
- chdir(WP_CONTENT_DIR);
200
- $command = "zip -r $backup_file 'mwp_db'";
201
-
202
- ob_start();
203
- $result = $this->mmb_exec($command);
204
- ob_get_clean();
205
- } else {
206
- require_once ABSPATH . '/wp-admin/includes/class-pclzip.php';
207
- $archive = new PclZip($backup_file);
208
- $result = $archive->add($db_result, PCLZIP_OPT_REMOVE_PATH, WP_CONTENT_DIR);
209
- }
210
-
211
- @unlink($db_result);
212
- if (!$result)
213
- return array(
214
- 'error' => 'Failed to zip database.'
215
- );
216
- }
217
- } elseif (trim($what) == 'full') {
218
- $content_backup = $this->backup_full($backup_file, $exclude);
219
- if (is_array($content_backup) && array_key_exists('error', $content_backup)) {
220
- return array(
221
- 'error' => $content_backup['error']
222
- );
223
- }
224
- }
225
-
226
- //Update backup info
227
- if ($task_name) {
228
- //backup task (scheduled)
229
- $backup_settings = $this->get_backup_settings();
230
- $paths = array();
231
- $size = ceil(filesize($backup_file) / 1024);
232
-
233
- if ($size > 1000) {
234
- $paths['size'] = ceil($size / 1024) . 'Mb';
235
- } else {
236
- $paths['size'] = $size . 'kb';
237
- }
238
- $paths['time'] = time();
239
-
240
- if ($task_name != 'Backup Now') {
241
- if (!$backup_settings[$task_name]['task_args']['del_host_file']) {
242
- $paths['server'] = array(
243
- 'file_path' => $backup_file,
244
- 'file_url' => $backup_url
245
- );
246
- }
247
- } else {
248
- $paths['server'] = array(
249
- 'file_path' => $backup_file,
250
- 'file_url' => $backup_url
251
- );
252
- }
253
-
254
- if (isset($backup_settings[$task_name]['task_args']['account_info']['mwp_ftp'])) {
255
- $paths['ftp'] = basename($backup_url);
256
- }
257
-
258
- if (isset($backup_settings[$task_name]['task_args']['account_info']['mwp_amazon_s3'])) {
259
- $paths['amazons3'] = basename($backup_url);
260
- }
261
-
262
- if (isset($backup_settings[$task_name]['task_args']['account_info']['mwp_dropbox'])) {
263
- $paths['dropbox'] = basename($backup_url);
264
- }
265
-
266
- if ($backup_settings[$task_name]['task_args']['email_backup']) {
267
- $paths['email'] = $backup_settings[$task_name]['task_args']['email_backup'];
268
- }
269
-
270
- $temp = $backup_settings[$task_name]['task_results'];
271
- $temp['temp'] = $paths;
272
- $backup_settings[$task_name]['task_results'] = array_values($temp);
273
- update_option('mwp_backup_tasks', $backup_settings);
274
- } else {
275
- //manual - predefined backup used for cloning
276
- $manual_backup = $args;
277
- $manual_backup['file_path'] = $backup_file;
278
- $manual_backup['file_url'] = $backup_url;
279
- update_option('mwp_manual_backup', $manual_backup);
280
- }
281
-
282
-
283
- //Additional: Email, ftp, amazon_s3, dropbox...
284
- if (isset($optimize_tables) && !empty($optimize_tables)) {
285
- $this->optimize_tables();
286
- }
287
-
288
- if ($task_name != 'Backup Now') {
289
- if (isset($account_info['mwp_ftp']) && !empty($account_info['mwp_ftp'])) {
290
- $account_info['mwp_ftp']['backup_file'] = $backup_file;
291
- $ftp_result = $this->ftp_backup($account_info['mwp_ftp']);
292
- if(is_array($ftp_result) && isset($ftp_result['error'])){
293
- return $ftp_result;
294
- }
295
- }
296
-
297
- if (isset($account_info['mwp_amazon_s3']) && !empty($account_info['mwp_amazon_s3'])) {
298
- $account_info['mwp_amazon_s3']['backup_file'] = $backup_file;
299
- $amazons3_result = $this->amazons3_backup($account_info['mwp_amazon_s3']);
300
- if(is_array($amazons3_result) && isset($amazons3_result['error'])){
301
- return $amazons3_result;
302
- }
303
- }
304
-
305
- if (isset($account_info['mwp_dropbox']) && !empty($account_info['mwp_dropbox'])) {
306
- $account_info['mwp_dropbox']['backup_file'] = $backup_file;
307
- $dropbox_result = $this->dropbox_backup($account_info['mwp_dropbox']);
308
- if(is_array($dropbox_result) && isset($dropbox_result['error'])){
309
- return $dropbox_result;
310
- }
311
- }
312
-
313
- if (isset($email_backup) && is_email($email_backup)) {
314
- $mail_args = array(
315
- 'email' => $email_backup,
316
- 'task_name' => $task_name,
317
- 'file_path' => $backup_file
318
- );
319
- $this->email_backup($mail_args);
320
- }
321
-
322
- if ($del_host_file) {
323
- @unlink($backup_file);
324
- }
325
-
326
- } //end additional
327
-
328
- return $backup_url; //Return url to backup file (we need return only for manual backup)
329
- }
330
-
331
- function backup_full($backup_file, $exclude = array())
332
- {
333
- $db_result = $this->backup_db();
334
- if ($db_result == false) {
335
- return array(
336
- 'error' => 'Failed to backup database.'
337
- );
338
- } else if (is_array($db_result) && isset($db_result['error'])) {
339
- return array(
340
- 'error' => $db_result['error']
341
- );
342
- }
343
-
344
- $sec_string = md5('mmb-worker');
345
- $remove = array(
346
- "wp-content/$sec_string/mwp_backups",
347
- "wp-content/mwp_db"
348
- );
349
-
350
- if ($this->mmb_exec('which zip')) {
351
- chdir(ABSPATH);
352
-
353
- //exclude paths
354
- $exclude_data = "-x";
355
- if (!empty($exclude)) {
356
- foreach ($exclude as $data) {
357
- if ($data)
358
- $exclude_data .= " '$data/*'";
359
- }
360
- }
361
-
362
- foreach ($remove as $data) {
363
- $exclude_data .= " '$data/*'";
364
- }
365
-
366
- $command = "zip -r $backup_file './' $exclude_data";
367
- ob_start();
368
- $result = $this->mmb_exec($command);
369
- ob_get_clean();
370
-
371
- //Add database file
372
- chdir(WP_CONTENT_DIR);
373
- $command = "zip -r $backup_file 'mwp_db'";
374
- ob_start();
375
- $result = $this->mmb_exec($command);
376
- ob_get_clean();
377
-
378
- @unlink($db_result);
379
-
380
- if ($result) {
381
- return true;
382
- } else {
383
- return array(
384
- 'error' => 'Failed to backup site.'
385
- );
386
- }
387
-
388
- } else { //php zip
389
-
390
- require_once ABSPATH . '/wp-admin/includes/class-pclzip.php';
391
- $archive = new PclZip($backup_file);
392
- $result = $archive->add(ABSPATH, PCLZIP_OPT_REMOVE_PATH, ABSPATH);
393
- $result = $archive->add($db_result, PCLZIP_OPT_REMOVE_PATH, WP_CONTENT_DIR);
394
- $exclude_data = array();
395
- if (!empty($exclude) && $result) {
396
- $exclude_data = array();
397
- foreach ($exclude as $data) {
398
- if ($data)
399
- $exclude_data[] = $data . '/';
400
- }
401
- }
402
- foreach ($remove as $rem) {
403
- $exclude_data[] = $rem . '/';
404
- }
405
-
406
- $result = $archive->delete(PCLZIP_OPT_BY_NAME, $exclude_data);
407
-
408
- @unlink($db_result);
409
- if ($result) {
410
- return true;
411
- } else {
412
- if ($archive->error_code == '-10') {
413
- return array(
414
- 'error' => 'Failed to backup site. Try increasing memory limit and/or free space on your server.'
415
- );
416
- } else {
417
- return array(
418
- 'error' => 'Failed to backup site. Try to enable Zip on your server.'
419
- );
420
- }
421
- }
422
- }
423
- }
424
-
425
-
426
- function backup_db()
427
- {
428
- $db_folder = ABSPATH . 'wp-content/mwp_db/';
429
- if (!file_exists($db_folder)) {
430
- if (!mkdir($db_folder, 0755, true))
431
- return array(
432
- 'error' => 'Error creating database backup folder. Make sure you have write permissions to your site root folder.'
433
- );
434
- }
435
-
436
- $file = $db_folder . DB_NAME . '.sql';
437
- $mysqldump = $this->check_mysqldump();
438
- if (is_array($mysqldump)) {
439
- $result = $this->backup_db_dump($file, $mysqldump);
440
-
441
- } else {
442
- $result = $this->backup_db_php($file);
443
- }
444
- return $result;
445
- }
446
-
447
- function backup_db_dump($file, $mysqldump)
448
- {
449
- global $wpdb;
450
- $brace = (substr(PHP_OS, 0, 3) == 'WIN') ? '"' : '';
451
- $command = $brace . $mysqldump['mysqldump'] . $brace . ' --host="' . DB_HOST . '" --user="' . DB_USER . '" --password="' . DB_PASSWORD . '" --add-drop-table --skip-lock-tables "' . DB_NAME . '" > ' . $brace . $file . $brace;
452
-
453
- ob_start();
454
- $result = $this->mmb_exec($command);
455
- ob_get_clean();
456
- if (!$result) {
457
- $result = $this->backup_db_php($file);
458
- return $result;
459
- }
460
-
461
- if (filesize($file) == 0 || !is_file($file) || !$result) {
462
- @unlink($file);
463
- return false;
464
- } else {
465
- return $file;
466
- }
467
- }
468
-
469
- function backup_db_php($file)
470
- {
471
- global $wpdb;
472
- $tables = $wpdb->get_results('SHOW TABLES', ARRAY_N);
473
- foreach ($tables as $table) {
474
- //drop existing table
475
- $dump_data = "DROP TABLE IF EXISTS $table[0];";
476
- //create table
477
- $create_table = $wpdb->get_row("SHOW CREATE TABLE $table[0]", ARRAY_N);
478
- $dump_data .= "\n\n" . $create_table[1] . ";\n\n";
479
-
480
- $count = $wpdb->get_var("SELECT count(*) FROM $table[0]");
481
- if ($count > 100)
482
- $count = ceil($count / 100) - 1;
483
- else
484
- $count = 1;
485
- for ($i = 0; $i < $count; $i++) {
486
- $low_limit = $i * 100;
487
- $qry = "SELECT * FROM $table[0] LIMIT $low_limit, 100";
488
- $rows = $wpdb->get_results($qry, ARRAY_A);
489
- if (is_array($rows)) {
490
- foreach ($rows as $row) {
491
- //insert single row
492
- $dump_data .= "INSERT INTO $table[0] VALUES(";
493
- $num_values = count($row);
494
- $j = 1;
495
- foreach ($row as $value) {
496
- $value = addslashes($value);
497
- $value = preg_replace("/\n/Ui", "\\n", $value);
498
- $num_values == $j ? $dump_data .= "'" . $value . "'" : $dump_data .= "'" . $value . "', ";
499
- $j++;
500
- unset($value);
501
- }
502
- $dump_data .= ");\n";
503
- }
504
- }
505
- }
506
- $dump_data .= "\n\n\n";
507
-
508
- unset($rows);
509
- file_put_contents($file, $dump_data, FILE_APPEND);
510
- unset($dump_data);
511
- }
512
-
513
- if (filesize($file) == 0 || !is_file($file)) {
514
- @unlink($file);
515
- return false;
516
- }
517
-
518
- return $file;
519
-
520
- }
521
-
522
- function restore($args)
523
- {
524
- global $wpdb;
525
- if (empty($args)) {
526
- return false;
527
- }
528
-
529
- extract($args);
530
- @ini_set('memory_limit', '300M');
531
- @set_time_limit(300);
532
-
533
- $unlink_file = true; //Delete file after restore
534
-
535
- //Detect source
536
- if ($backup_url) {
537
- //This is for clone (overwrite)
538
- include_once ABSPATH . 'wp-admin/includes/file.php';
539
- $backup_file = download_url($backup_url);
540
- if (is_wp_error($backup_file)) {
541
- return array(
542
- 'error' => $backup_file->get_error_message()
543
- );
544
- }
545
- $what = 'full';
546
- } else {
547
- $tasks = $this->get_backup_settings();
548
- $task = $tasks[$task_name];
549
- if (isset($task['task_results'][$result_id]['server'])) {
550
- $backup_file = $task['task_results'][$result_id]['server']['file_path'];
551
- $unlink_file = false; //Don't delete file if stored on server
552
- } elseif (isset($task['task_results'][$result_id]['ftp'])) {
553
- $ftp_file = $task['task_results'][$result_id]['ftp'];
554
- $args = $task['task_args']['account_info']['mwp_ftp'];
555
- $args['backup_file'] = $ftp_file;
556
- $backup_file = $this->get_ftp_backup($args);
557
- if ($backup_file == false) {
558
- return array(
559
- 'error' => 'Failed to download file from FTP'
560
- );
561
- }
562
- } elseif (isset($task['task_results'][$result_id]['amazons3'])) {
563
- $amazons3_file = $task['task_results'][$result_id]['amazons3'];
564
- $args = $task['task_args']['account_info']['mwp_amazon_s3'];
565
- $args['backup_file'] = $ftp_file;
566
- $backup_file = $this->get_amazons3_backup($args);
567
- if ($backup_file == false) {
568
- return array(
569
- 'error' => 'Failed to download file from Amazon S3'
570
- );
571
- }
572
- }
573
-
574
- $what = $tasks[$task_name]['task_args']['what'];
575
- }
576
-
577
- if ($backup_file && file_exists($backup_file)) {
578
- if ($overwrite) {
579
- //Keep old db credentials before overwrite
580
- if (!rename(ABSPATH . 'wp-config.php', ABSPATH . 'mwp-temp-wp-config.php')) {
581
- return array(
582
- 'error' => 'Error creating wp-config. Please check your write permisions.'
583
- );
584
- }
585
-
586
- $db_host = DB_HOST;
587
- $db_user = DB_USER;
588
- $db_password = DB_PASSWORD;
589
- $home = rtrim(get_option('home'),"/");
590
- $site_url = get_option('site_url');
591
- }
592
-
593
- if ($this->mmb_exec('which unzip')) {
594
- chdir(ABSPATH);
595
- $command = "unzip -o $backup_file";
596
- ob_start();
597
- $result = $this->mmb_exec($command);
598
- ob_get_clean();
599
-
600
- } else {
601
- require_once ABSPATH . '/wp-admin/includes/class-pclzip.php';
602
- $archive = new PclZip($backup_file);
603
- $result = $archive->extract(PCLZIP_OPT_PATH, ABSPATH);
604
- }
605
-
606
- if ($unlink_file) {
607
- @unlink($backup_file);
608
- }
609
-
610
- if (!$result) {
611
- return array(
612
- 'error' => 'Error extracting backup file.'
613
- );
614
- }
615
-
616
- $db_result = $this->restore_db();
617
-
618
- if (!$db_result) {
619
- return array(
620
- 'error' => 'Error restoring database.'
621
- );
622
- }
623
-
624
-
625
-
626
- } else {
627
- return array(
628
- 'error' => 'Error restoring. Cannot find backup file.'
629
- );
630
- }
631
-
632
- //Replace options and content urls
633
- if ($overwrite) {
634
- //Get New Table prefix
635
- $new_table_prefix = trim($this->get_table_prefix());
636
-
637
- //Retrieve old wp_config
638
- @unlink(ABSPATH . 'wp-config.php');
639
-
640
- //Replace table prefix
641
- $lines = file(ABSPATH . 'mwp-temp-wp-config.php');
642
- foreach ($lines as $line) {
643
- if (strstr($line, '$table_prefix')) {
644
- $line = '$table_prefix = "' . $new_table_prefix . '";' . PHP_EOL;
645
- }
646
- file_put_contents(ABSPATH . 'wp-config.php', $line, FILE_APPEND);
647
- }
648
-
649
- @unlink(ABSPATH . 'mwp-temp-wp-config.php');
650
-
651
- //Replace options
652
- $query = "SELECT option_value FROM " . $new_table_prefix . "options WHERE option_name = 'home'";
653
- $old = $wpdb->get_var($wpdb->prepare($query));
654
- $old = rtrim($old,"/");
655
- $query = "UPDATE " . $new_table_prefix . "options SET option_value = '$home' WHERE option_name = 'home'";
656
- $wpdb->query($wpdb->prepare($query));
657
- $query = "UPDATE " . $new_table_prefix . "options SET option_value = '$home' WHERE option_name = 'siteurl'";
658
- $wpdb->query($wpdb->prepare($query));
659
- //Replace content urls
660
- $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(.*)\"'";
661
- $wpdb->query($wpdb->prepare($query));
662
- }
663
-
664
- return true;
665
- }
666
-
667
- function restore_db()
668
- {
669
- global $wpdb;
670
- $mysqldump = $this->check_mysqldump();
671
- $file_path = ABSPATH . 'mwp_db';
672
- $file_name = glob($file_path . '/*.sql');
673
- $file_name = $file_name[0];
674
-
675
- if (is_array($mysqldump)) {
676
- $brace = (substr(PHP_OS, 0, 3) == 'WIN') ? '"' : '';
677
- $command = $brace . $mysqldump['mysql'] . $brace . ' --host="' . DB_HOST . '" --user="' . DB_USER . '" --password="' . DB_PASSWORD . '" ' . DB_NAME . ' < ' . $brace . $file_name . $brace;
678
-
679
- ob_start();
680
- $result = $this->mmb_exec($command);
681
- ob_get_clean();
682
- if (!$result) {
683
- //try php
684
- $this->restore_db_php($file_name);
685
- }
686
-
687
- } else {
688
- $this->restore_db_php($file_name);
689
- }
690
-
691
- @unlink($file_name);
692
- return true;
693
- }
694
-
695
- function restore_db_php($file_name)
696
- {
697
- $current_query = '';
698
- // Read in entire file
699
- $lines = file($file_name);
700
- // Loop through each line
701
- foreach ($lines as $line) {
702
- // Skip it if it's a comment
703
- if (substr($line, 0, 2) == '--' || $line == '')
704
- continue;
705
-
706
- // Add this line to the current query
707
- $current_query .= $line;
708
- // If it has a semicolon at the end, it's the end of the query
709
- if (substr(trim($line), -1, 1) == ';') {
710
- // Perform the query
711
- $result = $wpdb->query($current_query);
712
- if ($result === false)
713
- return FALSE;
714
- // Reset temp variable to empty
715
- $current_query = '';
716
- }
717
- }
718
-
719
- @unlink($file_name);
720
- return true;
721
- }
722
-
723
- function get_table_prefix()
724
- {
725
- $lines = file(ABSPATH . 'wp-config.php');
726
- foreach ($lines as $line) {
727
- if (strstr($line, '$table_prefix')) {
728
- $pattern = "/(\'|\")[^(\'|\")]*/";
729
- preg_match($pattern, $line, $matches);
730
- $prefix = substr($matches[0], 1);
731
- return $prefix;
732
- break;
733
- }
734
- }
735
- return 'wp_'; //default
736
- }
737
-
738
- function optimize_tables()
739
- {
740
- global $wpdb;
741
- $query = 'SHOW TABLE STATUS FROM ' . DB_NAME;
742
- $tables = $wpdb->get_results($wpdb->prepare($query), ARRAY_A);
743
- foreach ($tables as $table) {
744
- if (in_array($table['Engine'], array(
745
- 'MyISAM',
746
- 'ISAM',
747
- 'HEAP',
748
- 'MEMORY',
749
- 'ARCHIVE'
750
- )))
751
- $table_string .= $table['Name'] . ",";
752
- elseif ($table['Engine'] == 'InnoDB') {
753
- $optimize = $wpdb->query("ALTER TABLE {$table['Name']} ENGINE=InnoDB");
754
- }
755
- }
756
-
757
- $table_string = rtrim($table_string);
758
- $optimize = $wpdb->query("OPTIMIZE TABLE $table_string");
759
-
760
- return $optimize ? true : false;
761
- }
762
-
763
- ### Function: Auto Detect MYSQL and MYSQL Dump Paths
764
- function check_mysqldump()
765
- {
766
- global $wpdb;
767
- $paths = array(
768
- 'mysq' => '',
769
- 'mysqldump' => ''
770
- );
771
- if (substr(PHP_OS, 0, 3) == 'WIN') {
772
- $mysql_install = $wpdb->get_row("SHOW VARIABLES LIKE 'basedir'");
773
- if ($mysql_install) {
774
- $install_path = str_replace('\\', '/', $mysql_install->Value);
775
- $paths['mysql'] = $install_path . 'bin/mysql.exe';
776
- $paths['mysqldump'] = $install_path . 'bin/mysqldump.exe';
777
- } else {
778
- $paths['mysql'] = 'mysql.exe';
779
- $paths['mysqldump'] = 'mysqldump.exe';
780
- }
781
- } else {
782
- if ($this->check_sys()) {
783
- $paths['mysql'] = $this->mmb_exec('which mysql', true);
784
- $paths['mysqldump'] = $this->mmb_exec('which mysqldump', true);
785
- } else {
786
- $paths['mysql'] = 'mysql';
787
- $paths['mysqldump'] = 'mysqldump';
788
- }
789
- }
790
-
791
- if (!@file_exists(stripslashes($paths['mysqldump']))) {
792
- return false;
793
- }
794
- if (!@file_exists(stripslashes($paths['mysql']))) {
795
- return false;
796
- }
797
-
798
- return $paths;
799
- }
800
-
801
- //Check if exec, system, passthru functions exist
802
- function check_sys()
803
- {
804
- if ($this->mmb_function_exists('exec'))
805
- return 'exec';
806
-
807
- if ($this->mmb_function_exists('system'))
808
- return 'system';
809
-
810
- if ($this->mmb_function_exists('passhtru'))
811
- return 'passthru';
812
-
813
- return false;
814
-
815
- }
816
-
817
- function mmb_exec($command, $string = false)
818
- {
819
- if ($command == '')
820
- return false;
821
-
822
- if ($this->mmb_function_exists('exec')) {
823
- $log = @exec($command, $output, $return);
824
-
825
- if ($string)
826
- return $log;
827
- return $return ? false : true;
828
- } elseif ($this->mmb_function_exists('system')) {
829
- $log = @system($command, $return);
830
-
831
- if ($string)
832
- return $log;
833
- return $return ? false : true;
834
- } elseif ($this->mmb_function_exists('passthru')) {
835
- $log = passthru($command, $return);
836
-
837
- return $return ? false : true;
838
- } else {
839
- return false;
840
- }
841
- }
842
-
843
- function check_backup_compat()
844
- {
845
- $reqs = array();
846
- if (strpos($_SERVER['DOCUMENT_ROOT'], '/') === 0) {
847
- $reqs['Server OS']['status'] = 'Linux (or compatible)';
848
- $reqs['Server OS']['pass'] = true;
849
- } else {
850
- $reqs['Server OS']['status'] = 'Windows';
851
- $reqs['Server OS']['pass'] = false;
852
- $pass = false;
853
- }
854
- $reqs['PHP Version']['status'] = phpversion();
855
- if ((float) phpversion() >= 5.1) {
856
- $reqs['PHP Version']['pass'] = true;
857
- } else {
858
- $reqs['PHP Version']['pass'] = false;
859
- $pass = false;
860
- }
861
-
862
-
863
- if (is_writable(WP_CONTENT_DIR)) {
864
- $reqs['Backup Folder']['status'] = "writable";
865
- $reqs['Backup Folder']['pass'] = true;
866
- } else {
867
- $reqs['Backup Folder']['status'] = "not writable";
868
- $reqs['Backup Folder']['pass'] = false;
869
- }
870
-
871
- $sec_string = md5('mmb-worker');
872
- $file = "/$sec_string/mwp_backups";
873
- $file_path = WP_CONTENT_DIR . $file;
874
- $reqs['Backup Folder']['status'] .= ' (' . $file_path . ')';
875
-
876
- if ($func = $this->check_sys()) {
877
- $reqs['Execute Function']['status'] = $func;
878
- $reqs['Execute Function']['pass'] = true;
879
- } else {
880
- $reqs['Execute Function']['status'] = "not found";
881
- $reqs['Execute Function']['info'] = "(will try with PHP)";
882
- $reqs['Execute Function']['pass'] = false;
883
- }
884
-
885
- if ($this->mmb_exec('which zip')) {
886
- $reqs['Zip']['status'] = "enabled";
887
- $reqs['Zip']['pass'] = true;
888
- } else {
889
- $reqs['Zip']['status'] = "not found";
890
- $reqs['Zip']['info'] = "(will try with PHP pclZip class)";
891
- $reqs['Zip']['pass'] = false;
892
- }
893
-
894
- if ($this->mmb_exec('which unzip')) {
895
- $reqs['Unzip']['status'] = "enabled";
896
- $reqs['Unzip']['pass'] = true;
897
- } else {
898
- $reqs['Unzip']['status'] = "not found";
899
- $reqs['Unzip']['info'] = "(will try with PHP pclZip class)";
900
- $reqs['Unzip']['pass'] = false;
901
- }
902
- if (is_array($this->check_mysqldump())) {
903
- $reqs['MySQL Dump']['status'] = "enabled";
904
- $reqs['MySQL Dump']['pass'] = true;
905
- } else {
906
- $reqs['MySQL Dump']['status'] = "not found";
907
- $reqs['MySQL Dump']['info'] = "(will try PHP)";
908
- $reqs['MySQL Dump']['pass'] = false;
909
- }
910
-
911
-
912
-
913
- return $reqs;
914
- }
915
-
916
- function email_backup($args)
917
- {
918
- $email = $args['email'];
919
- $backup_file = $args['file_path'];
920
- $task_name = isset($args['task_name']) ? $args['task_name'] . ' on ' : '';
921
- if (file_exists($backup_file) && $email) {
922
- $attachments = array(
923
- $backup_file
924
- );
925
- $headers = 'From: ManageWP <no-reply@managewp.com>' . "\r\n";
926
- $subject = "ManageWP Backup - " . $task_name . date('F jS, G:i');
927
- ob_start();
928
- wp_mail($email, $subject, $subject, $headers, $attachments);
929
- ob_end_clean();
930
-
931
- }
932
-
933
- return true;
934
-
935
- }
936
-
937
- function ftp_backup($args)
938
- {
939
- extract($args);
940
- //Args: $ftp_username, $ftp_password, $ftp_hostname, $backup_file, $ftp_remote_folder, $ftp_site_folder
941
- if($ftp_site_folder)
942
- $ftp_remote_folder .= '/'.$this->site_name;
943
-
944
-
945
- if ($ftp_ssl && function_exists('ftp_ssl_connect')) {
946
- $conn_id = ftp_ssl_connect($ftp_hostname);
947
- } else if (function_exists('ftp_connect')) {
948
- $conn_id = ftp_connect($ftp_hostname);
949
- if ($conn_id === false) {
950
- return array(
951
- 'error' => 'Failed to connect to ' . $ftp_hostname,
952
- 'partial' => 1
953
- );
954
- }
955
- } else {
956
- return array(
957
- 'error' => 'Your server doesn\'t support FTP',
958
- 'partial' => 1
959
- );
960
- }
961
-
962
- $login = @ftp_login($conn_id, $ftp_username, $ftp_password);
963
- if ($login === false) {
964
- return array(
965
- 'error' => 'FTP login failed for ' . $ftp_username . ', ' . $ftp_password,
966
- 'partial' => 1
967
- );
968
- }
969
-
970
- @ftp_mkdir($conn_id, $ftp_remote_folder);
971
-
972
-
973
- $upload = @ftp_put($conn_id, $ftp_remote_folder . '/' . basename($backup_file), $backup_file, FTP_BINARY);
974
- if ($upload === false) {
975
- return array(
976
- 'error' => 'Failed to upload file to FTP. Please check your specified path.',
977
- 'partial' => 1
978
- );
979
- }
980
-
981
- ftp_close($conn_id);
982
-
983
- return true;
984
- }
985
-
986
- function remove_ftp_backup($args)
987
- {
988
- extract($args);
989
- //Args: $ftp_username, $ftp_password, $ftp_hostname, $backup_file, $ftp_remote_folder
990
- if ($ftp_ssl && function_exists('ftp_ssl_connect')) {
991
- $conn_id = ftp_ssl_connect($ftp_hostname);
992
-
993
- } else if (function_exists('ftp_connect')) {
994
- $conn_id = ftp_connect($ftp_hostname);
995
- if ($conn_id === false) {
996
- }
997
- } else {
998
- }
999
- $login = @ftp_login($conn_id, $ftp_username, $ftp_password);
1000
- if ($login === false) {
1001
- } else {
1002
- }
1003
-
1004
- if($ftp_site_folder)
1005
- $ftp_remote_folder .= '/'.$this->site_name;
1006
-
1007
- $delete = ftp_delete($conn_id, $ftp_remote_folder . '/' . $backup_file);
1008
- if ($delete === false) {
1009
- } else {
1010
- }
1011
- ftp_close($conn_id);
1012
-
1013
- }
1014
-
1015
- function get_ftp_backup($args)
1016
- {
1017
- extract($args);
1018
- //Args: $ftp_username, $ftp_password, $ftp_hostname, $backup_file, $ftp_remote_folder
1019
- if ($ftp_ssl && function_exists('ftp_ssl_connect')) {
1020
- $conn_id = ftp_ssl_connect($ftp_hostname);
1021
-
1022
- } else if (function_exists('ftp_connect')) {
1023
- $conn_id = ftp_connect($ftp_hostname);
1024
- if ($conn_id === false) {
1025
- return false;
1026
- }
1027
- } else {
1028
- }
1029
- $login = @ftp_login($conn_id, $ftp_username, $ftp_password);
1030
- if ($login === false) {
1031
- return false;
1032
- } else {
1033
- }
1034
-
1035
- if($ftp_site_folder)
1036
- $ftp_remote_folder .= '/'.$this->site_name;
1037
-
1038
- $temp = ABSPATH . 'mwp_temp_backup.zip';
1039
- $get = ftp_get($conn_id, $temp, $ftp_remote_folder . '/' . $backup_file, FTP_BINARY);
1040
- if ($get === false) {
1041
- return false;
1042
- } else {
1043
- }
1044
- ftp_close($conn_id);
1045
-
1046
- return $temp;
1047
- }
1048
-
1049
- function dropbox_backup($args)
1050
- {
1051
- require_once('lib/dropbox.php');
1052
- extract($args);
1053
-
1054
- //$email, $password, $backup_file, $destination, $dropbox_site_folder
1055
- if($dropbox_site_folder == true)
1056
- $dropbox_destination .= '/'.$this->site_name;
1057
-
1058
- try {
1059
- $uploader = new DropboxUploader($dropbox_username, $dropbox_password);
1060
- $uploader->upload($backup_file, $dropbox_destination);
1061
- }
1062
- catch (Exception $e) {
1063
- return array(
1064
- 'error' => $e->getMessage(),
1065
- 'partial' => 1
1066
- );
1067
- }
1068
-
1069
- return true;
1070
-
1071
- }
1072
-
1073
- function amazons3_backup($args)
1074
- {
1075
- require_once('lib/s3.php');
1076
- extract($args);
1077
-
1078
- if($as3_site_folder == true)
1079
- $as3_directory .= '/'.$this->site_name;
1080
-
1081
-
1082
- $s3 = new S3($as3_access_key, str_replace(' ', '+', $as3_secure_key));
1083
-
1084
- $s3->putBucket($as3_bucket, S3::ACL_PUBLIC_READ);
1085
-
1086
- if ($s3->putObjectFile($backup_file, $as3_bucket, $as3_directory . '/' . basename($backup_file), S3::ACL_PRIVATE)) {
1087
- return true;
1088
- } else {
1089
- return array(
1090
- 'error' => 'Failed to upload to Amazon S3. Please check your details and set upload/delete permissions on your bucket.',
1091
- 'partial' => 1
1092
- );
1093
- }
1094
-
1095
- }
1096
-
1097
- function remove_amazons3_backup($args)
1098
- {
1099
- require_once('lib/s3.php');
1100
- extract($args);
1101
- if($as3_site_folder == true)
1102
- $as3_directory .= '/'.$this->site_name;
1103
-
1104
- $s3 = new S3($as3_access_key, str_replace(' ', '+', $as3_secure_key));
1105
- $s3->deleteObject($as3_bucket, $as3_directory . '/' . $backup_file);
1106
- }
1107
-
1108
- function get_amazons3_backup($args)
1109
- {
1110
- require_once('lib/s3.php');
1111
- extract($args);
1112
- $s3 = new S3($as3_access_key, str_replace(' ', '+', $as3_secure_key));
1113
- if($as3_site_folder == true)
1114
- $as3_directory .= '/'.$this->site_name;
1115
-
1116
- $s3->getObject($as3_bucket, $as3_directory . '/' . $backup_file, $temp);
1117
- $temp = ABSPATH . 'mwp_temp_backup.zip';
1118
- return $temp;
1119
- }
1120
-
1121
- function schedule_next($type, $schedule)
1122
- {
1123
- $schedule = explode("|", $schedule);
1124
- if (empty($schedule))
1125
- return false;
1126
- switch ($type) {
1127
-
1128
- case 'daily':
1129
-
1130
- if ($schedule[1]) {
1131
- $delay_time = $schedule[1] * 60;
1132
- }
1133
-
1134
- $current_hour = date("H");
1135
- $schedule_hour = $schedule[0];
1136
- if ($current_hour >= $schedule_hour)
1137
- $time = mktime($schedule_hour, 0, 0, date("m"), date("d") + 1, date("Y"));
1138
- else
1139
- $time = mktime($schedule_hour, 0, 0, date("m"), date("d"), date("Y"));
1140
- break;
1141
-
1142
-
1143
- case 'weekly':
1144
- if ($schedule[2]) {
1145
- $delay_time = $schedule[2] * 60;
1146
- }
1147
- $current_weekday = date('w');
1148
- $schedule_weekday = $schedule[1];
1149
- $current_hour = date("H");
1150
- $schedule_hour = $schedule[0];
1151
-
1152
- if ($current_weekday > $schedule_weekday)
1153
- $weekday_offset = 7 - ($week_day - $task_schedule[1]);
1154
- else
1155
- $weekday_offset = $schedule_weekday - $current_weekday;
1156
-
1157
-
1158
- if (!$weekday_offset) { //today is scheduled weekday
1159
- if ($current_hour >= $schedule_hour)
1160
- $time = mktime($schedule_hour, 0, 0, date("m"), date("d") + 7, date("Y"));
1161
- else
1162
- $time = mktime($schedule_hour, 0, 0, date("m"), date("d"), date("Y"));
1163
- } else {
1164
- $time = mktime($schedule_hour, 0, 0, date("m"), date("d") + $weekday_offset, date("Y"));
1165
- }
1166
-
1167
- break;
1168
-
1169
- case 'monthly':
1170
- if ($schedule[2]) {
1171
- $delay_time = $schedule[2] * 60;
1172
- }
1173
- $current_monthday = date('j');
1174
- $schedule_monthday = $schedule[1];
1175
- $current_hour = date("H");
1176
- $schedule_hour = $schedule[0];
1177
-
1178
- if ($current_monthday > $schedule_monthday) {
1179
- $time = mktime($schedule_hour, 0, 0, date("m") + 1, $schedule_monthday, date("Y"));
1180
- } else if ($current_monthday < $schedule_monthday) {
1181
- $time = mktime($schedule_hour, 0, 0, date("m"), $schedule_monthday, date("Y"));
1182
- } else if ($current_monthday == $schedule_monthday) {
1183
- if ($current_hour >= $schedule_hour)
1184
- $time = mktime($schedule_hour, 0, 0, date("m") + 1, $schedule_monthday, date("Y"));
1185
- else
1186
- $time = mktime($schedule_hour, 0, 0, date("m"), $schedule_monthday, date("Y"));
1187
- break;
1188
- }
1189
-
1190
- break;
1191
- default:
1192
- break;
1193
- }
1194
-
1195
- if ($delay_time) {
1196
- $time += $delay_time;
1197
- }
1198
-
1199
-
1200
- return $time;
1201
-
1202
- }
1203
-
1204
- //Parse task arguments for info on master
1205
- function get_backup_stats()
1206
- {
1207
- $stats = array();
1208
- $tasks = get_option('mwp_backup_tasks');
1209
- if (is_array($tasks) && !empty($tasks)) {
1210
- foreach ($tasks as $task_name => $info) {
1211
-
1212
- if(is_array($info['task_results']) && !empty($info['task_results']))
1213
- {
1214
- foreach($info['task_results'] as $key => $result){
1215
- if(isset($result['server'])){
1216
- if(!file_exists($result['server']['file_path'])){
1217
- unset($info['task_results'][$key]);
1218
- }
1219
- }
1220
- }
1221
- }
1222
-
1223
- $stats[$task_name] = $info['task_results'];
1224
-
1225
- }
1226
- }
1227
- return $stats;
1228
- }
1229
-
1230
- function get_next_schedules(){
1231
- $stats = array();
1232
- $tasks = get_option('mwp_backup_tasks');
1233
- if (is_array($tasks) && !empty($tasks)) {
1234
- foreach ($tasks as $task_name => $info) {
1235
- $stats[$task_name] = $info['task_args']['next'];
1236
- }
1237
- }
1238
- return $stats;
1239
- }
1240
-
1241
- function remove_old_backups($task_name)
1242
- {
1243
- $backups = $this->get_backup_settings();
1244
- if (count($backups[$task_name]['task_results']) >= $backups[$task_name]['task_args']['limit']) {
1245
- // ? how many to remove
1246
- $remove_num = (count($backups[$task_name]['task_results']) - $backups[$task_name]['task_args']['limit']) + 1;
1247
-
1248
- for ($i = 0; $i < $remove_num; $i++) {
1249
- if (!isset($backups[$task_name]['task_results'][$i]['error'])) {
1250
- //Remove from the server
1251
- if (isset($backups[$task_name]['task_results'][$i]['server'])) {
1252
- @unlink($backups[$task_name]['task_results'][$i]['server']['file_path']);
1253
- }
1254
-
1255
- //Remove from ftp
1256
- if (isset($backups[$task_name]['task_results'][$i]['ftp'])) {
1257
- $ftp_file = $backups[$task_name]['task_results'][$i]['ftp'];
1258
- $args = $backups[$task_name]['task_args']['account_info']['mwp_ftp'];
1259
- $args['backup_file'] = $ftp_file;
1260
- $this->remove_ftp_backup($args);
1261
- }
1262
-
1263
- if (isset($backups[$task_name]['task_results'][$i]['amazons3'])) {
1264
- $amazons3_file = $backups[$task_name]['task_results'][$i]['amazons3'];
1265
- $args = $backups[$task_name]['task_args']['account_info']['mwp_amazon_s3'];
1266
- $args['backup_file'] = $amazons3_file;
1267
- $this->remove_amazons3_backup($args);
1268
- }
1269
-
1270
- if (isset($backups[$task_name]['task_results'][$i]['dropbox'])) {
1271
- }
1272
-
1273
- }
1274
- //Remove database backup info
1275
- unset($backups[$task_name]['task_results'][$i]);
1276
- update_option('mwp_backup_tasks', $backups);
1277
-
1278
- } //end foreach
1279
- }
1280
- }
1281
-
1282
- /**
1283
- * Delete specified backup
1284
- * Args: $task_name, $result_id
1285
- */
1286
-
1287
- function delete_backup($args)
1288
- {
1289
- if (empty($args))
1290
- return false;
1291
- extract($args);
1292
-
1293
- $tasks = $this->get_backup_settings();
1294
- $task = $tasks[$task_name];
1295
- $backups = $task['task_results'];
1296
- $backup = $backups[$result_id];
1297
-
1298
- if (isset($backup['server'])) {
1299
- @unlink($backup['server']['file_path']);
1300
- }
1301
-
1302
- //Remove from ftp
1303
- if (isset($backup['ftp'])) {
1304
- $ftp_file = $backup['ftp'];
1305
- $args = $tasks[$task_name]['task_args']['account_info']['mwp_ftp'];
1306
- $args['backup_file'] = $ftp_file;
1307
- $this->remove_ftp_backup($args);
1308
- }
1309
-
1310
- if (isset($backup['amazons3'])) {
1311
- $amazons3_file = $backup['amazons3'];
1312
- $args = $tasks[$task_name]['task_args']['account_info']['mwp_amazon_s3'];
1313
- $args['backup_file'] = $amazons3_file;
1314
- $this->remove_amazons3_backup($args);
1315
- }
1316
-
1317
- if (isset($backup['dropbox'])) {
1318
- }
1319
-
1320
- unset($backups[$result_id]);
1321
-
1322
- if (count($backups)) {
1323
- $tasks[$task_name]['task_results'] = $backups;
1324
- } else {
1325
- unset($tasks[$task_name]['task_results']);
1326
- }
1327
-
1328
- update_option('mwp_backup_tasks', $tasks);
1329
- return true;
1330
-
1331
- }
1332
-
1333
- function cleanup()
1334
- {
1335
- $tasks = $this->get_backup_settings();
1336
- $backup_folder = WP_CONTENT_DIR . '/' . md5('mmb-worker') . '/mwp_backups/';
1337
- $files = glob($backup_folder . "*.*");
1338
- $deleted = array();
1339
- $clone_backup = get_option('mwp_manual_backup');
1340
- if(isset($clone_backup['file_path'])){
1341
- $clone_backup = $clone_backup['file_path'];
1342
- }
1343
-
1344
- if (is_array($files) && count($files)) {
1345
- $results = array();
1346
- if (count($tasks)) {
1347
- foreach ($tasks as $task) {
1348
- if (isset($task['task_results']) && count($task['task_results'])) {
1349
- foreach ($task['task_results'] as $backup) {
1350
- if (isset($backup['server'])) {
1351
- $results[] = $backup['server']['file_path'];
1352
- }
1353
- }
1354
- }
1355
- }
1356
- }
1357
-
1358
- $num_deleted = 0;
1359
- foreach ($files as $file) {
1360
- if (!in_array($file, $results) && basename($file) != 'index.php' && basename($file) != basename($clone_backup)) {
1361
- @unlink($file);
1362
- $deleted[] = basename($file);
1363
- $num_deleted++;
1364
- }
1365
- }
1366
- }
1367
-
1368
- //Failed db files?
1369
- $db_folder = WP_CONTENT_DIR . '/mwp_db/';
1370
- $files = glob($db_folder . "*.*");
1371
- if (is_array($files) && count($files)) {
1372
- foreach ($files as $file) {
1373
- @unlink($file);
1374
- }
1375
- }
1376
-
1377
- return $deleted;
1378
- }
1379
-
1380
-
1381
- function remote_backup_now($args)
1382
- {
1383
-
1384
- if (!empty($args))
1385
- extract($args);
1386
- $tasks = $this->get_backup_settings();
1387
- $task = $tasks['Backup Now'];
1388
-
1389
- if (!empty($task)) {
1390
- extract($task['task_args']);
1391
- }
1392
-
1393
- $results = $task['task_results'];
1394
-
1395
- if (is_array($results) && count($results)) {
1396
- $backup_file = $results[count($results) - 1]['server']['file_path'];
1397
- }
1398
-
1399
- if ($backup_file && file_exists($backup_file)) {
1400
- if ($email) {
1401
- $mail_args = array(
1402
- 'email' => $email_backup,
1403
- 'task_name' => 'Backup Now',
1404
- 'file_path' => $backup_file
1405
- );
1406
-
1407
-
1408
-
1409
- $return = $this->email_backup($mail_args);
1410
-
1411
- //delete from server?
1412
- if ($return == true && $del_host_file) {
1413
- @unlink($backup_file);
1414
-
1415
- unset($tasks['Backup Now']['task_results'][count($results) - 1]['server']);
1416
- update_option('mwp_backup_tasks', $tasks);
1417
-
1418
- }
1419
- } else {
1420
- //FTP, Amazon S3 or Dropbox
1421
- if (isset($account_info['mwp_ftp']) && !empty($account_info['mwp_ftp'])) {
1422
- $account_info['mwp_ftp']['backup_file'] = $backup_file;
1423
- $return = $this->ftp_backup($account_info['mwp_ftp']);
1424
- }
1425
-
1426
- if (isset($account_info['mwp_amazon_s3']) && !empty($account_info['mwp_amazon_s3'])) {
1427
- $account_info['mwp_amazon_s3']['backup_file'] = $backup_file;
1428
- $return = $this->amazons3_backup($account_info['mwp_amazon_s3']);
1429
- }
1430
-
1431
- if (isset($account_info['mwp_dropbox']) && !empty($account_info['mwp_dropbox'])) {
1432
- $account_info['mwp_dropbox']['backup_file'] = $backup_file;
1433
- $return = $this->dropbox_backup($account_info['mwp_dropbox']);
1434
- }
1435
-
1436
- if ($return == true && $del_host_file && !$email_backup) {
1437
- @unlink($backup_file);
1438
- unset($tasks['Backup Now']['task_results'][count($results) - 1]['server']);
1439
-
1440
- update_option('mwp_backup_tasks', $tasks);
1441
- }
1442
-
1443
- }
1444
-
1445
- } else {
1446
- $return = array(
1447
- 'error' => 'Backup file not found on your server. Please try again.'
1448
- );
1449
- }
1450
-
1451
- return $return;
1452
-
1453
- }
1454
-
1455
- }
1456
-
1457
  ?>
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
+
13
+ class MMB_Backup extends MMB_Core
14
+ {
15
+ var $site_name;
16
+ function __construct()
17
+ {
18
+ parent::__construct();
19
+ $this->site_name = str_replace("/","-",rtrim($this->remove_http(get_bloginfo('home')),"/"));
20
+ }
21
+
22
+ function get_backup_settings()
23
+ {
24
+ $backup_settings = get_option('mwp_backup_tasks');
25
+ if (!empty($backup_settings))
26
+ return $backup_settings;
27
+ else
28
+ return false;
29
+ }
30
+
31
+ function set_backup_task($params)
32
+ {
33
+ //$params => [$task_name, $args, $error]
34
+ if (!empty($params)) {
35
+ extract($params);
36
+
37
+ $before = $this->get_backup_settings();
38
+ if (!$before || empty($before))
39
+ $before = array();
40
+
41
+ if (isset($args['remove'])) {
42
+ unset($before[$task_name]);
43
+ $return = array(
44
+ 'removed' => true
45
+ );
46
+ } else {
47
+ if(is_array($params['account_info'])){ //only if sends from master first time(secure data)
48
+ $args['account_info'] = $account_info;
49
+ }
50
+
51
+ $before[$task_name]['task_args'] = $args;
52
+ if (strlen($args['schedule']))
53
+ $before[$task_name]['task_args']['next'] = $this->schedule_next($args['type'], $args['schedule']);
54
+
55
+ $return = $before[$task_name];
56
+ }
57
+
58
+ if ($error) {
59
+ if(is_array($error)){
60
+ $before[$task_name]['task_results'][count($before[$task_name]['task_results'])-1]['error'] = $error['error'];
61
+ } else {
62
+ $before[$task_name]['task_results'][count($before[$task_name]['task_results'])]['error'] = $error;
63
+ }
64
+ }
65
+ update_option('mwp_backup_tasks', $before);
66
+
67
+ if ($task_name == 'Backup Now') {
68
+ $result = $this->backup($args, $task_name);
69
+ $backup_settings = $this->get_backup_settings();
70
+ if (is_array($result) && array_key_exists('error', $result)) {
71
+ $return = $result;
72
+ } else {
73
+ $return = $backup_settings[$task_name];
74
+ }
75
+ }
76
+ return $return;
77
+ }
78
+ return false;
79
+ }
80
+
81
+ //Cron check
82
+ function check_backup_tasks()
83
+ {
84
+ $settings = $this->get_backup_settings();
85
+ if (is_array($settings) && !empty($settings)) {
86
+ foreach ($settings as $task_name => $setting) {
87
+ if ($setting['task_args']['next'] && $setting['task_args']['next'] < time()) {
88
+ //Update task with next schedule
89
+ $this->set_backup_task(array(
90
+ 'task_name' => $task_name,
91
+ 'args' => $settings[$task_name]['task_args']
92
+ ));
93
+
94
+ $result = $this->backup($setting['task_args'], $task_name);
95
+ $error = '';
96
+ if (is_array($result) && array_key_exists('error', $result)) {
97
+ $error = $result;
98
+ $this->set_backup_task(array(
99
+ 'task_name' => $task_name,
100
+ 'args' => $settings[$task_name]['task_args'],
101
+ 'error' => $error
102
+ ));
103
+ } else {
104
+ $error = '';
105
+ }
106
+
107
+
108
+ break;
109
+ }
110
+ }
111
+ }
112
+
113
+ }
114
+
115
+
116
+
117
+ /*
118
+ * If Task Name not set then it's manual backup
119
+ * Backup args:
120
+ * type -> db, full
121
+ * what -> daily, weekly, monthly
122
+ * account_info -> ftp, amazons3, dropbox
123
+ * exclude-> array of paths to exclude from backup
124
+ */
125
+
126
+ function backup($args, $task_name = false)
127
+ {
128
+ if (!$args || empty($args))
129
+ return false;
130
+
131
+ extract($args); //extract settings
132
+
133
+ //try increase memory limit
134
+ @ini_set('memory_limit', '1000M');
135
+ @set_time_limit(600); //ten minutes
136
+
137
+ //Remove old backup(s)
138
+ if ($type == 'manual') {
139
+ $old = get_option('mwp_manual_backup');
140
+ if ($old['file_path'] && file_exists($old['file_path']))
141
+ @unlink($old['file_path']);
142
+ } else {
143
+ $this->remove_old_backups($task_name);
144
+ }
145
+
146
+ $sec_string = md5('mmb-worker');
147
+ $file = "/$sec_string/mwp_backups";
148
+ $new_file_path = WP_CONTENT_DIR . $file;
149
+
150
+ if (!file_exists($new_file_path)) {
151
+ if (!mkdir($new_file_path, 0755, true))
152
+ return array(
153
+ 'error' => 'Permission denied, make sure you have write permission to wp-content folder.'
154
+ );
155
+ }
156
+
157
+ @file_put_contents($new_file_path . '/index.php', ''); //safe
158
+
159
+ //Delete possible breaked previous backups - don't need it anymore (works only for previous wrokers)
160
+ foreach (glob($new_file_path . "/*.zip") as $filename) {
161
+ $short = basename($filename);
162
+ preg_match('/^wp\-content(.*)/Ui', $short, $matches);
163
+ if ($matches)
164
+ @unlink($filename);
165
+ }
166
+
167
+ //Prepare .zip file name
168
+ $site_name = $this->remove_http(get_bloginfo('url'));
169
+ $site_name = str_replace(array(
170
+ "_",
171
+ "/"
172
+ ), array(
173
+ "",
174
+ "-"
175
+ ), $site_name);
176
+
177
+ $hash = md5(time());
178
+ $label = $type ? $type : 'manual';
179
+ $backup_file = $new_file_path . '/' . $site_name . '_' . $label . '_' . $what . '_' . date('Y-m-d') . '_' . $hash . '.zip';
180
+ $backup_url = WP_CONTENT_URL . $file . '/' . $site_name . '_' . $label . '_' . $what . '_' . date('Y-m-d') . '_' . $hash . '.zip';
181
+
182
+
183
+ //What to backup - db or full
184
+ if (trim($what) == 'db') {
185
+ //take database backup
186
+
187
+ $db_result = $this->backup_db();
188
+ if ($db_result == false) {
189
+ return array(
190
+ 'error' => 'Failed to backup database.'
191
+ );
192
+ } else if (is_array($db_result) && isset($db_result['error'])) {
193
+ return array(
194
+ 'error' => $db_result['error']
195
+ );
196
+
197
+ } else {
198
+ if ($this->mmb_exec('which zip')) {
199
+ chdir(WP_CONTENT_DIR);
200
+ $command = "zip -r $backup_file 'mwp_db'";
201
+
202
+ ob_start();
203
+ $result = $this->mmb_exec($command);
204
+ ob_get_clean();
205
+ } else {
206
+ require_once ABSPATH . '/wp-admin/includes/class-pclzip.php';
207
+ $archive = new PclZip($backup_file);
208
+ $result = $archive->add($db_result, PCLZIP_OPT_REMOVE_PATH, WP_CONTENT_DIR);
209
+ }
210
+
211
+ @unlink($db_result);
212
+ if (!$result)
213
+ return array(
214
+ 'error' => 'Failed to zip database.'
215
+ );
216
+ }
217
+ } elseif (trim($what) == 'full') {
218
+ $content_backup = $this->backup_full($backup_file, $exclude);
219
+ if (is_array($content_backup) && array_key_exists('error', $content_backup)) {
220
+ return array(
221
+ 'error' => $content_backup['error']
222
+ );
223
+ }
224
+ }
225
+
226
+ //Update backup info
227
+ if ($task_name) {
228
+ //backup task (scheduled)
229
+ $backup_settings = $this->get_backup_settings();
230
+ $paths = array();
231
+ $size = ceil(filesize($backup_file) / 1024);
232
+
233
+ if ($size > 1000) {
234
+ $paths['size'] = ceil($size / 1024) . 'Mb';
235
+ } else {
236
+ $paths['size'] = $size . 'kb';
237
+ }
238
+ $paths['time'] = time();
239
+
240
+ if ($task_name != 'Backup Now') {
241
+ if (!$backup_settings[$task_name]['task_args']['del_host_file']) {
242
+ $paths['server'] = array(
243
+ 'file_path' => $backup_file,
244
+ 'file_url' => $backup_url
245
+ );
246
+ }
247
+ } else {
248
+ $paths['server'] = array(
249
+ 'file_path' => $backup_file,
250
+ 'file_url' => $backup_url
251
+ );
252
+ }
253
+
254
+ if (isset($backup_settings[$task_name]['task_args']['account_info']['mwp_ftp'])) {
255
+ $paths['ftp'] = basename($backup_url);
256
+ }
257
+
258
+ if (isset($backup_settings[$task_name]['task_args']['account_info']['mwp_amazon_s3'])) {
259
+ $paths['amazons3'] = basename($backup_url);
260
+ }
261
+
262
+ if (isset($backup_settings[$task_name]['task_args']['account_info']['mwp_dropbox'])) {
263
+ $paths['dropbox'] = basename($backup_url);
264
+ }
265
+
266
+ if ($backup_settings[$task_name]['task_args']['email_backup']) {
267
+ $paths['email'] = $backup_settings[$task_name]['task_args']['email_backup'];
268
+ }
269
+
270
+ $temp = $backup_settings[$task_name]['task_results'];
271
+ $temp['temp'] = $paths;
272
+ $backup_settings[$task_name]['task_results'] = array_values($temp);
273
+ update_option('mwp_backup_tasks', $backup_settings);
274
+ } else {
275
+ //manual - predefined backup used for cloning
276
+ $manual_backup = $args;
277
+ $manual_backup['file_path'] = $backup_file;
278
+ $manual_backup['file_url'] = $backup_url;
279
+ update_option('mwp_manual_backup', $manual_backup);
280
+ }
281
+
282
+
283
+ //Additional: Email, ftp, amazon_s3, dropbox...
284
+ if (isset($optimize_tables) && !empty($optimize_tables)) {
285
+ $this->optimize_tables();
286
+ }
287
+
288
+ if ($task_name != 'Backup Now') {
289
+ if (isset($account_info['mwp_ftp']) && !empty($account_info['mwp_ftp'])) {
290
+ $account_info['mwp_ftp']['backup_file'] = $backup_file;
291
+ $ftp_result = $this->ftp_backup($account_info['mwp_ftp']);
292
+ if(is_array($ftp_result) && isset($ftp_result['error'])){
293
+ return $ftp_result;
294
+ }
295
+ }
296
+
297
+ if (isset($account_info['mwp_amazon_s3']) && !empty($account_info['mwp_amazon_s3'])) {
298
+ $account_info['mwp_amazon_s3']['backup_file'] = $backup_file;
299
+ $amazons3_result = $this->amazons3_backup($account_info['mwp_amazon_s3']);
300
+ if(is_array($amazons3_result) && isset($amazons3_result['error'])){
301
+ return $amazons3_result;
302
+ }
303
+ }
304
+
305
+ if (isset($account_info['mwp_dropbox']) && !empty($account_info['mwp_dropbox'])) {
306
+ $account_info['mwp_dropbox']['backup_file'] = $backup_file;
307
+ $dropbox_result = $this->dropbox_backup($account_info['mwp_dropbox']);
308
+ if(is_array($dropbox_result) && isset($dropbox_result['error'])){
309
+ return $dropbox_result;
310
+ }
311
+ }
312
+
313
+ if (isset($email_backup) && is_email($email_backup)) {
314
+ $mail_args = array(
315
+ 'email' => $email_backup,
316
+ 'task_name' => $task_name,
317
+ 'file_path' => $backup_file
318
+ );
319
+ $this->email_backup($mail_args);
320
+ }
321
+
322
+ if ($del_host_file) {
323
+ @unlink($backup_file);
324
+ }
325
+
326
+ } //end additional
327
+
328
+ return $backup_url; //Return url to backup file (we need return only for manual backup)
329
+ }
330
+
331
+ function backup_full($backup_file, $exclude = array())
332
+ {
333
+ $db_result = $this->backup_db();
334
+ if ($db_result == false) {
335
+ return array(
336
+ 'error' => 'Failed to backup database.'
337
+ );
338
+ } else if (is_array($db_result) && isset($db_result['error'])) {
339
+ return array(
340
+ 'error' => $db_result['error']
341
+ );
342
+ }
343
+
344
+ $sec_string = md5('mmb-worker');
345
+ $remove = array(
346
+ "wp-content/$sec_string/mwp_backups",
347
+ "wp-content/mwp_db"
348
+ );
349
+
350
+ if ($this->mmb_exec('which zip')) {
351
+ chdir(ABSPATH);
352
+
353
+ //exclude paths
354
+ $exclude_data = "-x";
355
+ if (!empty($exclude)) {
356
+ foreach ($exclude as $data) {
357
+ if ($data)
358
+ $exclude_data .= " '$data/*'";
359
+ }
360
+ }
361
+
362
+ foreach ($remove as $data) {
363
+ $exclude_data .= " '$data/*'";
364
+ }
365
+
366
+ $command = "zip -r $backup_file './' $exclude_data";
367
+ ob_start();
368
+ $result = $this->mmb_exec($command);
369
+ ob_get_clean();
370
+
371
+ //Add database file
372
+ chdir(WP_CONTENT_DIR);
373
+ $command = "zip -r $backup_file 'mwp_db'";
374
+ ob_start();
375
+ $result = $this->mmb_exec($command);
376
+ ob_get_clean();
377
+
378
+ @unlink($db_result);
379
+
380
+ if ($result) {
381
+ return true;
382
+ } else {
383
+ return array(
384
+ 'error' => 'Failed to backup site.'
385
+ );
386
+ }
387
+
388
+ } else { //php zip
389
+
390
+ require_once ABSPATH . '/wp-admin/includes/class-pclzip.php';
391
+ $archive = new PclZip($backup_file);
392
+ $result = $archive->add(ABSPATH, PCLZIP_OPT_REMOVE_PATH, ABSPATH);
393
+ $result = $archive->add($db_result, PCLZIP_OPT_REMOVE_PATH, WP_CONTENT_DIR);
394
+ $exclude_data = array();
395
+ if (!empty($exclude) && $result) {
396
+ $exclude_data = array();
397
+ foreach ($exclude as $data) {
398
+ if ($data)
399
+ $exclude_data[] = $data . '/';
400
+ }
401
+ }
402
+ foreach ($remove as $rem) {
403
+ $exclude_data[] = $rem . '/';
404
+ }
405
+
406
+ $result = $archive->delete(PCLZIP_OPT_BY_NAME, $exclude_data);
407
+
408
+ @unlink($db_result);
409
+ if ($result) {
410
+ return true;
411
+ } else {
412
+ if ($archive->error_code == '-10') {
413
+ return array(
414
+ 'error' => 'Failed to backup site. Try increasing memory limit and/or free space on your server.'
415
+ );
416
+ } else {
417
+ return array(
418
+ 'error' => 'Failed to backup site. Try to enable Zip on your server.'
419
+ );
420
+ }
421
+ }
422
+ }
423
+ }
424
+
425
+
426
+ function backup_db()
427
+ {
428
+ $db_folder = ABSPATH . 'wp-content/mwp_db/';
429
+ if (!file_exists($db_folder)) {
430
+ if (!mkdir($db_folder, 0755, true))
431
+ return array(
432
+ 'error' => 'Error creating database backup folder. Make sure you have write permissions to your site root folder.'
433
+ );
434
+ }
435
+
436
+ $file = $db_folder . DB_NAME . '.sql';
437
+ $mysqldump = $this->check_mysqldump();
438
+ if (is_array($mysqldump)) {
439
+ $result = $this->backup_db_dump($file, $mysqldump);
440
+
441
+ } else {
442
+ $result = $this->backup_db_php($file);
443
+ }
444
+ return $result;
445
+ }
446
+
447
+ function backup_db_dump($file, $mysqldump)
448
+ {
449
+ global $wpdb;
450
+ $brace = (substr(PHP_OS, 0, 3) == 'WIN') ? '"' : '';
451
+ $command = $brace . $mysqldump['mysqldump'] . $brace . ' --host="' . DB_HOST . '" --user="' . DB_USER . '" --password="' . DB_PASSWORD . '" --add-drop-table --skip-lock-tables "' . DB_NAME . '" > ' . $brace . $file . $brace;
452
+
453
+ ob_start();
454
+ $result = $this->mmb_exec($command);
455
+ ob_get_clean();
456
+ if (!$result) {
457
+ $result = $this->backup_db_php($file);
458
+ return $result;
459
+ }
460
+
461
+ if (filesize($file) == 0 || !is_file($file) || !$result) {
462
+ @unlink($file);
463
+ return false;
464
+ } else {
465
+ return $file;
466
+ }
467
+ }
468
+
469
+ function backup_db_php($file)
470
+ {
471
+ global $wpdb;
472
+ $tables = $wpdb->get_results('SHOW TABLES', ARRAY_N);
473
+ foreach ($tables as $table) {
474
+ //drop existing table
475
+ $dump_data = "DROP TABLE IF EXISTS $table[0];";
476
+ //create table
477
+ $create_table = $wpdb->get_row("SHOW CREATE TABLE $table[0]", ARRAY_N);
478
+ $dump_data .= "\n\n" . $create_table[1] . ";\n\n";
479
+
480
+ $count = $wpdb->get_var("SELECT count(*) FROM $table[0]");
481
+ if ($count > 100)
482
+ $count = ceil($count / 100) - 1;
483
+ else
484
+ $count = 1;
485
+ for ($i = 0; $i < $count; $i++) {
486
+ $low_limit = $i * 100;
487
+ $qry = "SELECT * FROM $table[0] LIMIT $low_limit, 100";
488
+ $rows = $wpdb->get_results($qry, ARRAY_A);
489
+ if (is_array($rows)) {
490
+ foreach ($rows as $row) {
491
+ //insert single row
492
+ $dump_data .= "INSERT INTO $table[0] VALUES(";
493
+ $num_values = count($row);
494
+ $j = 1;
495
+ foreach ($row as $value) {
496
+ $value = addslashes($value);
497
+ $value = preg_replace("/\n/Ui", "\\n", $value);
498
+ $num_values == $j ? $dump_data .= "'" . $value . "'" : $dump_data .= "'" . $value . "', ";
499
+ $j++;
500
+ unset($value);
501
+ }
502
+ $dump_data .= ");\n";
503
+ }
504
+ }
505
+ }
506
+ $dump_data .= "\n\n\n";
507
+
508
+ unset($rows);
509
+ file_put_contents($file, $dump_data, FILE_APPEND);
510
+ unset($dump_data);
511
+ }
512
+
513
+ if (filesize($file) == 0 || !is_file($file)) {
514
+ @unlink($file);
515
+ return false;
516
+ }
517
+
518
+ return $file;
519
+
520
+ }
521
+
522
+ function restore($args)
523
+ {
524
+ global $wpdb;
525
+ if (empty($args)) {
526
+ return false;
527
+ }
528
+
529
+ extract($args);
530
+ @ini_set('memory_limit', '300M');
531
+ @set_time_limit(300);
532
+
533
+ $unlink_file = true; //Delete file after restore
534
+
535
+ //Detect source
536
+ if ($backup_url) {
537
+ //This is for clone (overwrite)
538
+ include_once ABSPATH . 'wp-admin/includes/file.php';
539
+ $backup_file = download_url($backup_url);
540
+ if (is_wp_error($backup_file)) {
541
+ return array(
542
+ 'error' => $backup_file->get_error_message()
543
+ );
544
+ }
545
+ $what = 'full';
546
+ } else {
547
+ $tasks = $this->get_backup_settings();
548
+ $task = $tasks[$task_name];
549
+ if (isset($task['task_results'][$result_id]['server'])) {
550
+ $backup_file = $task['task_results'][$result_id]['server']['file_path'];
551
+ $unlink_file = false; //Don't delete file if stored on server
552
+ } elseif (isset($task['task_results'][$result_id]['ftp'])) {
553
+ $ftp_file = $task['task_results'][$result_id]['ftp'];
554
+ $args = $task['task_args']['account_info']['mwp_ftp'];
555
+ $args['backup_file'] = $ftp_file;
556
+ $backup_file = $this->get_ftp_backup($args);
557
+ if ($backup_file == false) {
558
+ return array(
559
+ 'error' => 'Failed to download file from FTP'
560
+ );
561
+ }
562
+ } elseif (isset($task['task_results'][$result_id]['amazons3'])) {
563
+ $amazons3_file = $task['task_results'][$result_id]['amazons3'];
564
+ $args = $task['task_args']['account_info']['mwp_amazon_s3'];
565
+ $args['backup_file'] = $ftp_file;
566
+ $backup_file = $this->get_amazons3_backup($args);
567
+ if ($backup_file == false) {
568
+ return array(
569
+ 'error' => 'Failed to download file from Amazon S3'
570
+ );
571
+ }
572
+ }
573
+
574
+ $what = $tasks[$task_name]['task_args']['what'];
575
+ }
576
+
577
+ if ($backup_file && file_exists($backup_file)) {
578
+ if ($overwrite) {
579
+ //Keep old db credentials before overwrite
580
+ if (!rename(ABSPATH . 'wp-config.php', ABSPATH . 'mwp-temp-wp-config.php')) {
581
+ return array(
582
+ 'error' => 'Error creating wp-config. Please check your write permisions.'
583
+ );
584
+ }
585
+
586
+ $db_host = DB_HOST;
587
+ $db_user = DB_USER;
588
+ $db_password = DB_PASSWORD;
589
+ $home = rtrim(get_option('home'),"/");
590
+ $site_url = get_option('site_url');
591
+ }
592
+
593
+ if ($this->mmb_exec('which unzip')) {
594
+ chdir(ABSPATH);
595
+ $command = "unzip -o $backup_file";
596
+ ob_start();
597
+ $result = $this->mmb_exec($command);
598
+ ob_get_clean();
599
+
600
+ } else {
601
+ require_once ABSPATH . '/wp-admin/includes/class-pclzip.php';
602
+ $archive = new PclZip($backup_file);
603
+ $result = $archive->extract(PCLZIP_OPT_PATH, ABSPATH);
604
+ }
605
+
606
+ if ($unlink_file) {
607
+ @unlink($backup_file);
608
+ }
609
+
610
+ if (!$result) {
611
+ return array(
612
+ 'error' => 'Error extracting backup file.'
613
+ );
614
+ }
615
+
616
+ $db_result = $this->restore_db();
617
+
618
+ if (!$db_result) {
619
+ return array(
620
+ 'error' => 'Error restoring database.'
621
+ );
622
+ }
623
+
624
+
625
+
626
+ } else {
627
+ return array(
628
+ 'error' => 'Error restoring. Cannot find backup file.'
629
+ );
630
+ }
631
+
632
+ //Replace options and content urls
633
+ if ($overwrite) {
634
+ //Get New Table prefix
635
+ $new_table_prefix = trim($this->get_table_prefix());
636
+
637
+ //Retrieve old wp_config
638
+ @unlink(ABSPATH . 'wp-config.php');
639
+
640
+ //Replace table prefix
641
+ $lines = file(ABSPATH . 'mwp-temp-wp-config.php');
642
+ foreach ($lines as $line) {
643
+ if (strstr($line, '$table_prefix')) {
644
+ $line = '$table_prefix = "' . $new_table_prefix . '";' . PHP_EOL;
645
+ }
646
+ file_put_contents(ABSPATH . 'wp-config.php', $line, FILE_APPEND);
647
+ }
648
+
649
+ @unlink(ABSPATH . 'mwp-temp-wp-config.php');
650
+
651
+ //Replace options
652
+ $query = "SELECT option_value FROM " . $new_table_prefix . "options WHERE option_name = 'home'";
653
+ $old = $wpdb->get_var($wpdb->prepare($query));
654
+ $old = rtrim($old,"/");
655
+ $query = "UPDATE " . $new_table_prefix . "options SET option_value = '$home' WHERE option_name = 'home'";
656
+ $wpdb->query($wpdb->prepare($query));
657
+ $query = "UPDATE " . $new_table_prefix . "options SET option_value = '$home' WHERE option_name = 'siteurl'";
658
+ $wpdb->query($wpdb->prepare($query));
659
+ //Replace content urls
660
+ $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(.*)\"'";
661
+ $wpdb->query($wpdb->prepare($query));
662
+ }
663
+
664
+ return true;
665
+ }
666
+
667
+ function restore_db()
668
+ {
669
+ global $wpdb;
670
+ $mysqldump = $this->check_mysqldump();
671
+ $file_path = ABSPATH . 'mwp_db';
672
+ $file_name = glob($file_path . '/*.sql');
673
+ $file_name = $file_name[0];
674
+
675
+ if (is_array($mysqldump)) {
676
+ $brace = (substr(PHP_OS, 0, 3) == 'WIN') ? '"' : '';
677
+ $command = $brace . $mysqldump['mysql'] . $brace . ' --host="' . DB_HOST . '" --user="' . DB_USER . '" --password="' . DB_PASSWORD . '" ' . DB_NAME . ' < ' . $brace . $file_name . $brace;
678
+
679
+ ob_start();
680
+ $result = $this->mmb_exec($command);
681
+ ob_get_clean();
682
+ if (!$result) {
683
+ //try php
684
+ $this->restore_db_php($file_name);
685
+ }
686
+
687
+ } else {
688
+ $this->restore_db_php($file_name);
689
+ }
690
+
691
+ @unlink($file_name);
692
+ return true;
693
+ }
694
+
695
+ function restore_db_php($file_name)
696
+ {
697
+ $current_query = '';
698
+ // Read in entire file
699
+ $lines = file($file_name);
700
+ // Loop through each line
701
+ foreach ($lines as $line) {
702
+ // Skip it if it's a comment
703
+ if (substr($line, 0, 2) == '--' || $line == '')
704
+ continue;
705
+
706
+ // Add this line to the current query
707
+ $current_query .= $line;
708
+ // If it has a semicolon at the end, it's the end of the query
709
+ if (substr(trim($line), -1, 1) == ';') {
710
+ // Perform the query
711
+ $result = $wpdb->query($current_query);
712
+ if ($result === false)
713
+ return FALSE;
714
+ // Reset temp variable to empty
715
+ $current_query = '';
716
+ }
717
+ }
718
+
719
+ @unlink($file_name);
720
+ return true;
721
+ }
722
+
723
+ function get_table_prefix()
724
+ {
725
+ $lines = file(ABSPATH . 'wp-config.php');
726
+ foreach ($lines as $line) {
727
+ if (strstr($line, '$table_prefix')) {
728
+ $pattern = "/(\'|\")[^(\'|\")]*/";
729
+ preg_match($pattern, $line, $matches);
730
+ $prefix = substr($matches[0], 1);
731
+ return $prefix;
732
+ break;
733
+ }
734
+ }
735
+ return 'wp_'; //default
736
+ }
737
+
738
+ function optimize_tables()
739
+ {
740
+ global $wpdb;
741
+ $query = 'SHOW TABLE STATUS FROM ' . DB_NAME;
742
+ $tables = $wpdb->get_results($wpdb->prepare($query), ARRAY_A);
743
+ foreach ($tables as $table) {
744
+ if (in_array($table['Engine'], array(
745
+ 'MyISAM',
746
+ 'ISAM',
747
+ 'HEAP',
748
+ 'MEMORY',
749
+ 'ARCHIVE'
750
+ )))
751
+ $table_string .= $table['Name'] . ",";
752
+ elseif ($table['Engine'] == 'InnoDB') {
753
+ $optimize = $wpdb->query("ALTER TABLE {$table['Name']} ENGINE=InnoDB");
754
+ }
755
+ }
756
+
757
+ $table_string = rtrim($table_string);
758
+ $optimize = $wpdb->query("OPTIMIZE TABLE $table_string");
759
+
760
+ return $optimize ? true : false;
761
+ }
762
+
763
+ ### Function: Auto Detect MYSQL and MYSQL Dump Paths
764
+ function check_mysqldump()
765
+ {
766
+ global $wpdb;
767
+ $paths = array(
768
+ 'mysq' => '',
769
+ 'mysqldump' => ''
770
+ );
771
+ if (substr(PHP_OS, 0, 3) == 'WIN') {
772
+ $mysql_install = $wpdb->get_row("SHOW VARIABLES LIKE 'basedir'");
773
+ if ($mysql_install) {
774
+ $install_path = str_replace('\\', '/', $mysql_install->Value);
775
+ $paths['mysql'] = $install_path . 'bin/mysql.exe';
776
+ $paths['mysqldump'] = $install_path . 'bin/mysqldump.exe';
777
+ } else {
778
+ $paths['mysql'] = 'mysql.exe';
779
+ $paths['mysqldump'] = 'mysqldump.exe';
780
+ }
781
+ } else {
782
+ if ($this->check_sys()) {
783
+ $paths['mysql'] = $this->mmb_exec('which mysql', true);
784
+ $paths['mysqldump'] = $this->mmb_exec('which mysqldump', true);
785
+ } else {
786
+ $paths['mysql'] = 'mysql';
787
+ $paths['mysqldump'] = 'mysqldump';
788
+ }
789
+ }
790
+
791
+ if (!@file_exists(stripslashes($paths['mysqldump']))) {
792
+ return false;
793
+ }
794
+ if (!@file_exists(stripslashes($paths['mysql']))) {
795
+ return false;
796
+ }
797
+
798
+ return $paths;
799
+ }
800
+
801
+ //Check if exec, system, passthru functions exist
802
+ function check_sys()
803
+ {
804
+ if ($this->mmb_function_exists('exec'))
805
+ return 'exec';
806
+
807
+ if ($this->mmb_function_exists('system'))
808
+ return 'system';
809
+
810
+ if ($this->mmb_function_exists('passhtru'))
811
+ return 'passthru';
812
+
813
+ return false;
814
+
815
+ }
816
+
817
+ function mmb_exec($command, $string = false)
818
+ {
819
+ if ($command == '')
820
+ return false;
821
+
822
+ if ($this->mmb_function_exists('exec')) {
823
+ $log = @exec($command, $output, $return);
824
+
825
+ if ($string)
826
+ return $log;
827
+ return $return ? false : true;
828
+ } elseif ($this->mmb_function_exists('system')) {
829
+ $log = @system($command, $return);
830
+
831
+ if ($string)
832
+ return $log;
833
+ return $return ? false : true;
834
+ } elseif ($this->mmb_function_exists('passthru')) {
835
+ $log = passthru($command, $return);
836
+
837
+ return $return ? false : true;
838
+ } else {
839
+ return false;
840
+ }
841
+ }
842
+
843
+ function check_backup_compat()
844
+ {
845
+ $reqs = array();
846
+ if (strpos($_SERVER['DOCUMENT_ROOT'], '/') === 0) {
847
+ $reqs['Server OS']['status'] = 'Linux (or compatible)';
848
+ $reqs['Server OS']['pass'] = true;
849
+ } else {
850
+ $reqs['Server OS']['status'] = 'Windows';
851
+ $reqs['Server OS']['pass'] = false;
852
+ $pass = false;
853
+ }
854
+ $reqs['PHP Version']['status'] = phpversion();
855
+ if ((float) phpversion() >= 5.1) {
856
+ $reqs['PHP Version']['pass'] = true;
857
+ } else {
858
+ $reqs['PHP Version']['pass'] = false;
859
+ $pass = false;
860
+ }
861
+
862
+
863
+ if (is_writable(WP_CONTENT_DIR)) {
864
+ $reqs['Backup Folder']['status'] = "writable";
865
+ $reqs['Backup Folder']['pass'] = true;
866
+ } else {
867
+ $reqs['Backup Folder']['status'] = "not writable";
868
+ $reqs['Backup Folder']['pass'] = false;
869
+ }
870
+
871
+ $sec_string = md5('mmb-worker');
872
+ $file = "/$sec_string/mwp_backups";
873
+ $file_path = WP_CONTENT_DIR . $file;
874
+ $reqs['Backup Folder']['status'] .= ' (' . $file_path . ')';
875
+
876
+ if ($func = $this->check_sys()) {
877
+ $reqs['Execute Function']['status'] = $func;
878
+ $reqs['Execute Function']['pass'] = true;
879
+ } else {
880
+ $reqs['Execute Function']['status'] = "not found";
881
+ $reqs['Execute Function']['info'] = "(will try with PHP)";
882
+ $reqs['Execute Function']['pass'] = false;
883
+ }
884
+
885
+ if ($this->mmb_exec('which zip')) {
886
+ $reqs['Zip']['status'] = "enabled";
887
+ $reqs['Zip']['pass'] = true;
888
+ } else {
889
+ $reqs['Zip']['status'] = "not found";
890
+ $reqs['Zip']['info'] = "(will try with PHP pclZip class)";
891
+ $reqs['Zip']['pass'] = false;
892
+ }
893
+
894
+ if ($this->mmb_exec('which unzip')) {
895
+ $reqs['Unzip']['status'] = "enabled";
896
+ $reqs['Unzip']['pass'] = true;
897
+ } else {
898
+ $reqs['Unzip']['status'] = "not found";
899
+ $reqs['Unzip']['info'] = "(will try with PHP pclZip class)";
900
+ $reqs['Unzip']['pass'] = false;
901
+ }
902
+ if (is_array($this->check_mysqldump())) {
903
+ $reqs['MySQL Dump']['status'] = "enabled";
904
+ $reqs['MySQL Dump']['pass'] = true;
905
+ } else {
906
+ $reqs['MySQL Dump']['status'] = "not found";
907
+ $reqs['MySQL Dump']['info'] = "(will try PHP)";
908
+ $reqs['MySQL Dump']['pass'] = false;
909
+ }
910
+
911
+
912
+
913
+ return $reqs;
914
+ }
915
+
916
+ function email_backup($args)
917
+ {
918
+ $email = $args['email'];
919
+ $backup_file = $args['file_path'];
920
+ $task_name = isset($args['task_name']) ? $args['task_name'] . ' on ' : '';
921
+ if (file_exists($backup_file) && $email) {
922
+ $attachments = array(
923
+ $backup_file
924
+ );
925
+ $headers = 'From: ManageWP <no-reply@managewp.com>' . "\r\n";
926
+ $subject = "ManageWP Backup - " . $task_name . date('F jS, G:i');
927
+ ob_start();
928
+ wp_mail($email, $subject, $subject, $headers, $attachments);
929
+ ob_end_clean();
930
+
931
+ }
932
+
933
+ return true;
934
+
935
+ }
936
+
937
+ function ftp_backup($args)
938
+ {
939
+ extract($args);
940
+ //Args: $ftp_username, $ftp_password, $ftp_hostname, $backup_file, $ftp_remote_folder, $ftp_site_folder
941
+ if($ftp_site_folder)
942
+ $ftp_remote_folder .= '/'.$this->site_name;
943
+
944
+
945
+ if ($ftp_ssl && function_exists('ftp_ssl_connect')) {
946
+ $conn_id = ftp_ssl_connect($ftp_hostname);
947
+ } else if (function_exists('ftp_connect')) {
948
+ $conn_id = ftp_connect($ftp_hostname);
949
+ if ($conn_id === false) {
950
+ return array(
951
+ 'error' => 'Failed to connect to ' . $ftp_hostname,
952
+ 'partial' => 1
953
+ );
954
+ }
955
+ } else {
956
+ return array(
957
+ 'error' => 'Your server doesn\'t support FTP',
958
+ 'partial' => 1
959
+ );
960
+ }
961
+
962
+ $login = @ftp_login($conn_id, $ftp_username, $ftp_password);
963
+ if ($login === false) {
964
+ return array(
965
+ 'error' => 'FTP login failed for ' . $ftp_username . ', ' . $ftp_password,
966
+ 'partial' => 1
967
+ );
968
+ }
969
+
970
+ @ftp_mkdir($conn_id, $ftp_remote_folder);
971
+
972
+
973
+ $upload = @ftp_put($conn_id, $ftp_remote_folder . '/' . basename($backup_file), $backup_file, FTP_BINARY);
974
+ if ($upload === false) {
975
+ return array(
976
+ 'error' => 'Failed to upload file to FTP. Please check your specified path.',
977
+ 'partial' => 1
978
+ );
979
+ }
980
+
981
+ ftp_close($conn_id);
982
+
983
+ return true;
984
+ }
985
+
986
+ function remove_ftp_backup($args)
987
+ {
988
+ extract($args);
989
+ //Args: $ftp_username, $ftp_password, $ftp_hostname, $backup_file, $ftp_remote_folder
990
+ if ($ftp_ssl && function_exists('ftp_ssl_connect')) {
991
+ $conn_id = ftp_ssl_connect($ftp_hostname);
992
+
993
+ } else if (function_exists('ftp_connect')) {
994
+ $conn_id = ftp_connect($ftp_hostname);
995
+ if ($conn_id === false) {
996
+ }
997
+ } else {
998
+ }
999
+ $login = @ftp_login($conn_id, $ftp_username, $ftp_password);
1000
+ if ($login === false) {
1001
+ } else {
1002
+ }
1003
+
1004
+ if($ftp_site_folder)
1005
+ $ftp_remote_folder .= '/'.$this->site_name;
1006
+
1007
+ $delete = ftp_delete($conn_id, $ftp_remote_folder . '/' . $backup_file);
1008
+ if ($delete === false) {
1009
+ } else {
1010
+ }
1011
+ ftp_close($conn_id);
1012
+
1013
+ }
1014
+
1015
+ function get_ftp_backup($args)
1016
+ {
1017
+ extract($args);
1018
+ //Args: $ftp_username, $ftp_password, $ftp_hostname, $backup_file, $ftp_remote_folder
1019
+ if ($ftp_ssl && function_exists('ftp_ssl_connect')) {
1020
+ $conn_id = ftp_ssl_connect($ftp_hostname);
1021
+
1022
+ } else if (function_exists('ftp_connect')) {
1023
+ $conn_id = ftp_connect($ftp_hostname);
1024
+ if ($conn_id === false) {
1025
+ return false;
1026
+ }
1027
+ } else {
1028
+ }
1029
+ $login = @ftp_login($conn_id, $ftp_username, $ftp_password);
1030
+ if ($login === false) {
1031
+ return false;
1032
+ } else {
1033
+ }
1034
+
1035
+ if($ftp_site_folder)
1036
+ $ftp_remote_folder .= '/'.$this->site_name;
1037
+
1038
+ $temp = ABSPATH . 'mwp_temp_backup.zip';
1039
+ $get = ftp_get($conn_id, $temp, $ftp_remote_folder . '/' . $backup_file, FTP_BINARY);
1040
+ if ($get === false) {
1041
+ return false;
1042
+ } else {
1043
+ }
1044
+ ftp_close($conn_id);
1045
+
1046
+ return $temp;
1047
+ }
1048
+
1049
+ function dropbox_backup($args)
1050
+ {
1051
+ require_once('lib/dropbox.php');
1052
+ extract($args);
1053
+
1054
+ //$email, $password, $backup_file, $destination, $dropbox_site_folder
1055
+ if($dropbox_site_folder == true)
1056
+ $dropbox_destination .= '/'.$this->site_name;
1057
+
1058
+ try {
1059
+ $uploader = new DropboxUploader($dropbox_username, $dropbox_password);
1060
+ $uploader->upload($backup_file, $dropbox_destination);
1061
+ }
1062
+ catch (Exception $e) {
1063
+ return array(
1064
+ 'error' => $e->getMessage(),
1065
+ 'partial' => 1
1066
+ );
1067
+ }
1068
+
1069
+ return true;
1070
+
1071
+ }
1072
+
1073
+ function amazons3_backup($args)
1074
+ {
1075
+ require_once('lib/s3.php');
1076
+ extract($args);
1077
+
1078
+ if($as3_site_folder == true)
1079
+ $as3_directory .= '/'.$this->site_name;
1080
+
1081
+
1082
+ $s3 = new S3($as3_access_key, str_replace(' ', '+', $as3_secure_key));
1083
+
1084
+ $s3->putBucket($as3_bucket, S3::ACL_PUBLIC_READ);
1085
+
1086
+ if ($s3->putObjectFile($backup_file, $as3_bucket, $as3_directory . '/' . basename($backup_file), S3::ACL_PRIVATE)) {
1087
+ return true;
1088
+ } else {
1089
+ return array(
1090
+ 'error' => 'Failed to upload to Amazon S3. Please check your details and set upload/delete permissions on your bucket.',
1091
+ 'partial' => 1
1092
+ );
1093
+ }
1094
+
1095
+ }
1096
+
1097
+ function remove_amazons3_backup($args)
1098
+ {
1099
+ require_once('lib/s3.php');
1100
+ extract($args);
1101
+ if($as3_site_folder == true)
1102
+ $as3_directory .= '/'.$this->site_name;
1103
+
1104
+ $s3 = new S3($as3_access_key, str_replace(' ', '+', $as3_secure_key));
1105
+ $s3->deleteObject($as3_bucket, $as3_directory . '/' . $backup_file);
1106
+ }
1107
+
1108
+ function get_amazons3_backup($args)
1109
+ {
1110
+ require_once('lib/s3.php');
1111
+ extract($args);
1112
+ $s3 = new S3($as3_access_key, str_replace(' ', '+', $as3_secure_key));
1113
+ if($as3_site_folder == true)
1114
+ $as3_directory .= '/'.$this->site_name;
1115
+
1116
+ $s3->getObject($as3_bucket, $as3_directory . '/' . $backup_file, $temp);
1117
+ $temp = ABSPATH . 'mwp_temp_backup.zip';
1118
+ return $temp;
1119
+ }
1120
+
1121
+ function schedule_next($type, $schedule)
1122
+ {
1123
+ $schedule = explode("|", $schedule);
1124
+ if (empty($schedule))
1125
+ return false;
1126
+ switch ($type) {
1127
+
1128
+ case 'daily':
1129
+
1130
+ if ($schedule[1]) {
1131
+ $delay_time = $schedule[1] * 60;
1132
+ }
1133
+
1134
+ $current_hour = date("H");
1135
+ $schedule_hour = $schedule[0];
1136
+ if ($current_hour >= $schedule_hour)
1137
+ $time = mktime($schedule_hour, 0, 0, date("m"), date("d") + 1, date("Y"));
1138
+ else
1139
+ $time = mktime($schedule_hour, 0, 0, date("m"), date("d"), date("Y"));
1140
+ break;
1141
+
1142
+
1143
+ case 'weekly':
1144
+ if ($schedule[2]) {
1145
+ $delay_time = $schedule[2] * 60;
1146
+ }
1147
+ $current_weekday = date('w');
1148
+ $schedule_weekday = $schedule[1];
1149
+ $current_hour = date("H");
1150
+ $schedule_hour = $schedule[0];
1151
+
1152
+ if ($current_weekday > $schedule_weekday)
1153
+ $weekday_offset = 7 - ($week_day - $task_schedule[1]);
1154
+ else
1155
+ $weekday_offset = $schedule_weekday - $current_weekday;
1156
+
1157
+
1158
+ if (!$weekday_offset) { //today is scheduled weekday
1159
+ if ($current_hour >= $schedule_hour)
1160
+ $time = mktime($schedule_hour, 0, 0, date("m"), date("d") + 7, date("Y"));
1161
+ else
1162
+ $time = mktime($schedule_hour, 0, 0, date("m"), date("d"), date("Y"));
1163
+ } else {
1164
+ $time = mktime($schedule_hour, 0, 0, date("m"), date("d") + $weekday_offset, date("Y"));
1165
+ }
1166
+
1167
+ break;
1168
+
1169
+ case 'monthly':
1170
+ if ($schedule[2]) {
1171
+ $delay_time = $schedule[2] * 60;
1172
+ }
1173
+ $current_monthday = date('j');
1174
+ $schedule_monthday = $schedule[1];
1175
+ $current_hour = date("H");
1176
+ $schedule_hour = $schedule[0];
1177
+
1178
+ if ($current_monthday > $schedule_monthday) {
1179
+ $time = mktime($schedule_hour, 0, 0, date("m") + 1, $schedule_monthday, date("Y"));
1180
+ } else if ($current_monthday < $schedule_monthday) {
1181
+ $time = mktime($schedule_hour, 0, 0, date("m"), $schedule_monthday, date("Y"));
1182
+ } else if ($current_monthday == $schedule_monthday) {
1183
+ if ($current_hour >= $schedule_hour)
1184
+ $time = mktime($schedule_hour, 0, 0, date("m") + 1, $schedule_monthday, date("Y"));
1185
+ else
1186
+ $time = mktime($schedule_hour, 0, 0, date("m"), $schedule_monthday, date("Y"));
1187
+ break;
1188
+ }
1189
+
1190
+ break;
1191
+ default:
1192
+ break;
1193
+ }
1194
+
1195
+ if ($delay_time) {
1196
+ $time += $delay_time;
1197
+ }
1198
+
1199
+
1200
+ return $time;
1201
+
1202
+ }
1203
+
1204
+ //Parse task arguments for info on master
1205
+ function get_backup_stats()
1206
+ {
1207
+ $stats = array();
1208
+ $tasks = get_option('mwp_backup_tasks');
1209
+ if (is_array($tasks) && !empty($tasks)) {
1210
+ foreach ($tasks as $task_name => $info) {
1211
+
1212
+ if(is_array($info['task_results']) && !empty($info['task_results']))
1213
+ {
1214
+ foreach($info['task_results'] as $key => $result){
1215
+ if(isset($result['server'])){
1216
+ if(!file_exists($result['server']['file_path'])){
1217
+ unset($info['task_results'][$key]);
1218
+ }
1219
+ }
1220
+ }
1221
+ }
1222
+
1223
+ $stats[$task_name] = $info['task_results'];
1224
+
1225
+ }
1226
+ }
1227
+ return $stats;
1228
+ }
1229
+
1230
+ function get_next_schedules(){
1231
+ $stats = array();
1232
+ $tasks = get_option('mwp_backup_tasks');
1233
+ if (is_array($tasks) && !empty($tasks)) {
1234
+ foreach ($tasks as $task_name => $info) {
1235
+ $stats[$task_name] = $info['task_args']['next'];
1236
+ }
1237
+ }
1238
+ return $stats;
1239
+ }
1240
+
1241
+ function remove_old_backups($task_name)
1242
+ {
1243
+ $backups = $this->get_backup_settings();
1244
+ if (count($backups[$task_name]['task_results']) >= $backups[$task_name]['task_args']['limit']) {
1245
+ // ? how many to remove
1246
+ $remove_num = (count($backups[$task_name]['task_results']) - $backups[$task_name]['task_args']['limit']) + 1;
1247
+
1248
+ for ($i = 0; $i < $remove_num; $i++) {
1249
+ if (!isset($backups[$task_name]['task_results'][$i]['error'])) {
1250
+ //Remove from the server
1251
+ if (isset($backups[$task_name]['task_results'][$i]['server'])) {
1252
+ @unlink($backups[$task_name]['task_results'][$i]['server']['file_path']);
1253
+ }
1254
+
1255
+ //Remove from ftp
1256
+ if (isset($backups[$task_name]['task_results'][$i]['ftp'])) {
1257
+ $ftp_file = $backups[$task_name]['task_results'][$i]['ftp'];
1258
+ $args = $backups[$task_name]['task_args']['account_info']['mwp_ftp'];
1259
+ $args['backup_file'] = $ftp_file;
1260
+ $this->remove_ftp_backup($args);
1261
+ }
1262
+
1263
+ if (isset($backups[$task_name]['task_results'][$i]['amazons3'])) {
1264
+ $amazons3_file = $backups[$task_name]['task_results'][$i]['amazons3'];
1265
+ $args = $backups[$task_name]['task_args']['account_info']['mwp_amazon_s3'];
1266
+ $args['backup_file'] = $amazons3_file;
1267
+ $this->remove_amazons3_backup($args);
1268
+ }
1269
+
1270
+ if (isset($backups[$task_name]['task_results'][$i]['dropbox'])) {
1271
+ }
1272
+
1273
+ }
1274
+ //Remove database backup info
1275
+ unset($backups[$task_name]['task_results'][$i]);
1276
+ update_option('mwp_backup_tasks', $backups);
1277
+
1278
+ } //end foreach
1279
+ }
1280
+ }
1281
+
1282
+ /**
1283
+ * Delete specified backup
1284
+ * Args: $task_name, $result_id
1285
+ */
1286
+
1287
+ function delete_backup($args)
1288
+ {
1289
+ if (empty($args))
1290
+ return false;
1291
+ extract($args);
1292
+
1293
+ $tasks = $this->get_backup_settings();
1294
+ $task = $tasks[$task_name];
1295
+ $backups = $task['task_results'];
1296
+ $backup = $backups[$result_id];
1297
+
1298
+ if (isset($backup['server'])) {
1299
+ @unlink($backup['server']['file_path']);
1300
+ }
1301
+
1302
+ //Remove from ftp
1303
+ if (isset($backup['ftp'])) {
1304
+ $ftp_file = $backup['ftp'];
1305
+ $args = $tasks[$task_name]['task_args']['account_info']['mwp_ftp'];
1306
+ $args['backup_file'] = $ftp_file;
1307
+ $this->remove_ftp_backup($args);
1308
+ }
1309
+
1310
+ if (isset($backup['amazons3'])) {
1311
+ $amazons3_file = $backup['amazons3'];
1312
+ $args = $tasks[$task_name]['task_args']['account_info']['mwp_amazon_s3'];
1313
+ $args['backup_file'] = $amazons3_file;
1314
+ $this->remove_amazons3_backup($args);
1315
+ }
1316
+
1317
+ if (isset($backup['dropbox'])) {
1318
+ }
1319
+
1320
+ unset($backups[$result_id]);
1321
+
1322
+ if (count($backups)) {
1323
+ $tasks[$task_name]['task_results'] = $backups;
1324
+ } else {
1325
+ unset($tasks[$task_name]['task_results']);
1326
+ }
1327
+
1328
+ update_option('mwp_backup_tasks', $tasks);
1329
+ return true;
1330
+
1331
+ }
1332
+
1333
+ function cleanup()
1334
+ {
1335
+ $tasks = $this->get_backup_settings();
1336
+ $backup_folder = WP_CONTENT_DIR . '/' . md5('mmb-worker') . '/mwp_backups/';
1337
+ $files = glob($backup_folder . "*");
1338
+ $deleted = array();
1339
+ $clone_backup = get_option('mwp_manual_backup');
1340
+ if(isset($clone_backup['file_path'])){
1341
+ $clone_backup = $clone_backup['file_path'];
1342
+ }
1343
+
1344
+ if (is_array($files) && count($files)) {
1345
+ $results = array();
1346
+ if (count($tasks)) {
1347
+ foreach ($tasks as $task) {
1348
+ if (isset($task['task_results']) && count($task['task_results'])) {
1349
+ foreach ($task['task_results'] as $backup) {
1350
+ if (isset($backup['server'])) {
1351
+ $results[] = $backup['server']['file_path'];
1352
+ }
1353
+ }
1354
+ }
1355
+ }
1356
+ }
1357
+
1358
+ $num_deleted = 0;
1359
+ foreach ($files as $file) {
1360
+ if (!in_array($file, $results) && basename($file) != 'index.php' && basename($file) != basename($clone_backup)) {
1361
+ @unlink($file);
1362
+ $deleted[] = basename($file);
1363
+ $num_deleted++;
1364
+ }
1365
+ }
1366
+ }
1367
+
1368
+ //Failed db files?
1369
+ $db_folder = WP_CONTENT_DIR . '/mwp_db/';
1370
+ $files = glob($db_folder . "*.*");
1371
+ if (is_array($files) && count($files)) {
1372
+ foreach ($files as $file) {
1373
+ @unlink($file);
1374
+ }
1375
+ }
1376
+
1377
+ return $deleted;
1378
+ }
1379
+
1380
+
1381
+ function remote_backup_now($args)
1382
+ {
1383
+
1384
+ if (!empty($args))
1385
+ extract($args);
1386
+ $tasks = $this->get_backup_settings();
1387
+ $task = $tasks['Backup Now'];
1388
+
1389
+ if (!empty($task)) {
1390
+ extract($task['task_args']);
1391
+ }
1392
+
1393
+ $results = $task['task_results'];
1394
+
1395
+ if (is_array($results) && count($results)) {
1396
+ $backup_file = $results[count($results) - 1]['server']['file_path'];
1397
+ }
1398
+
1399
+ if ($backup_file && file_exists($backup_file)) {
1400
+ if ($email) {
1401
+ $mail_args = array(
1402
+ 'email' => $email_backup,
1403
+ 'task_name' => 'Backup Now',
1404
+ 'file_path' => $backup_file
1405
+ );
1406
+
1407
+
1408
+
1409
+ $return = $this->email_backup($mail_args);
1410
+
1411
+ //delete from server?
1412
+ if ($return == true && $del_host_file) {
1413
+ @unlink($backup_file);
1414
+
1415
+ unset($tasks['Backup Now']['task_results'][count($results) - 1]['server']);
1416
+ update_option('mwp_backup_tasks', $tasks);
1417
+
1418
+ }
1419
+ } else {
1420
+ //FTP, Amazon S3 or Dropbox
1421
+ if (isset($account_info['mwp_ftp']) && !empty($account_info['mwp_ftp'])) {
1422
+ $account_info['mwp_ftp']['backup_file'] = $backup_file;
1423
+ $return = $this->ftp_backup($account_info['mwp_ftp']);
1424
+ }
1425
+
1426
+ if (isset($account_info['mwp_amazon_s3']) && !empty($account_info['mwp_amazon_s3'])) {
1427
+ $account_info['mwp_amazon_s3']['backup_file'] = $backup_file;
1428
+ $return = $this->amazons3_backup($account_info['mwp_amazon_s3']);
1429
+ }
1430
+
1431
+ if (isset($account_info['mwp_dropbox']) && !empty($account_info['mwp_dropbox'])) {
1432
+ $account_info['mwp_dropbox']['backup_file'] = $backup_file;
1433
+ $return = $this->dropbox_backup($account_info['mwp_dropbox']);
1434
+ }
1435
+
1436
+ if ($return == true && $del_host_file && !$email_backup) {
1437
+ @unlink($backup_file);
1438
+ unset($tasks['Backup Now']['task_results'][count($results) - 1]['server']);
1439
+
1440
+ update_option('mwp_backup_tasks', $tasks);
1441
+ }
1442
+
1443
+ }
1444
+
1445
+ } else {
1446
+ $return = array(
1447
+ 'error' => 'Backup file not found on your server. Please try again.'
1448
+ );
1449
+ }
1450
+
1451
+ return $return;
1452
+
1453
+ }
1454
+
1455
+ }
1456
+
1457
  ?>
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,444 +1,441 @@
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 = false;
30
-
31
-
32
- function __construct()
33
- {
34
- global $mmb_plugin_dir, $wpmu_version, $blog_id;
35
-
36
- $this->name = 'Manage Multiple Blogs';
37
- $this->slug = 'manage-multiple-blogs';
38
- $this->settings = get_option($this->slug);
39
- if (!$this->settings) {
40
- $this->settings = array(
41
- 'blogs' => array(),
42
- 'current_blog' => array(
43
- 'type' => null
44
- )
45
- );
46
- $this->save_options();
47
- }
48
-
49
-
50
-
51
- if (function_exists('is_multisite')) {
52
- if (is_multisite()) {
53
- $this->mmb_multisite = $blog_id;
54
- }
55
- } else if (!empty($wpmu_version)) {
56
- $this->mmb_multisite = $blog_id;
57
- }
58
-
59
- add_action('rightnow_end', array(
60
- $this,
61
- 'add_right_now_info'
62
- ));
63
- add_action('wp_footer', array(
64
- 'MMB_Stats',
65
- 'set_hit_count'
66
- ));
67
- register_activation_hook($mmb_plugin_dir . '/init.php', array(
68
- $this,
69
- 'install'
70
- ));
71
- add_action('init', array(
72
- $this,
73
- 'automatic_login'
74
- ));
75
-
76
- if (!get_option('_worker_public_key'))
77
- add_action('admin_notices', array(
78
- $this,
79
- 'admin_notice'
80
- ));
81
-
82
-
83
- }
84
-
85
- /**
86
- * Add notice to admin dashboard for security reasons
87
- *
88
- */
89
- function admin_notice()
90
- {
91
- echo '<div class="error" style="text-align: center;"><p style="color: red; font-size: 14px; font-weight: bold;">Attention !</p><p>
92
- Please add this site to your <a target="_blank" href="http://managewp.com/user-guide#security">ManageWP.com</a> account now to remove this notice or deactivate the Worker plugin to avoid <a target="_blank" href="http://managewp.com/user-guide#security">security issues</a>.
93
- </p></div>';
94
- }
95
-
96
- /**
97
- * Add an item into the Right Now Dashboard widget
98
- * to inform that the blog can be managed remotely
99
- *
100
- */
101
- function add_right_now_info()
102
- {
103
- echo '<div class="mmb-slave-info">
104
- <p>This site can be managed remotely.</p>
105
- </div>';
106
- }
107
-
108
- /**
109
- * Gets an instance of the Comment class
110
- *
111
- */
112
- function get_comment_instance()
113
- {
114
- if (!isset($this->comment_instance)) {
115
- $this->comment_instance = new MMB_Comment();
116
- }
117
-
118
- return $this->comment_instance;
119
- }
120
-
121
- /**
122
- * Gets an instance of the Plugin class
123
- *
124
- */
125
- function get_plugin_instance()
126
- {
127
- if (!isset($this->plugin_instance)) {
128
- $this->plugin_instance = new MMB_Plugin();
129
- }
130
-
131
- return $this->plugin_instance;
132
- }
133
-
134
- /**
135
- * Gets an instance of the Theme class
136
- *
137
- */
138
- function get_theme_instance()
139
- {
140
- if (!isset($this->theme_instance)) {
141
- $this->theme_instance = new MMB_Theme();
142
- }
143
-
144
- return $this->theme_instance;
145
- }
146
-
147
-
148
- /**
149
- * Gets an instance of MMB_Post class
150
- *
151
- */
152
- function get_post_instance()
153
- {
154
- if (!isset($this->post_instance)) {
155
- $this->post_instance = new MMB_Post();
156
- }
157
-
158
- return $this->post_instance;
159
- }
160
-
161
- /**
162
- * Gets an instance of Blogroll class
163
- *
164
- */
165
- function get_blogroll_instance()
166
- {
167
- if (!isset($this->blogroll_instance)) {
168
- $this->blogroll_instance = new MMB_Blogroll();
169
- }
170
-
171
- return $this->blogroll_instance;
172
- }
173
-
174
-
175
-
176
- /**
177
- * Gets an instance of the WP class
178
- *
179
- */
180
- function get_wp_instance()
181
- {
182
- if (!isset($this->wp_instance)) {
183
- $this->wp_instance = new MMB_WP();
184
- }
185
-
186
- return $this->wp_instance;
187
- }
188
-
189
- /**
190
- * Gets an instance of User
191
- *
192
- */
193
- function get_user_instance()
194
- {
195
- if (!isset($this->user_instance)) {
196
- $this->user_instance = new MMB_User();
197
- }
198
-
199
- return $this->user_instance;
200
- }
201
-
202
- /**
203
- * Gets an instance of stats class
204
- *
205
- */
206
- function get_stats_instance()
207
- {
208
- if (!isset($this->stats_instance)) {
209
- $this->stats_instance = new MMB_Stats();
210
- }
211
- return $this->stats_instance;
212
- }
213
- /**
214
- * Gets an instance of search class
215
- *
216
- */
217
- function get_search_instance()
218
- {
219
- if (!isset($this->search_instance)) {
220
- $this->search_instance = new MMB_Search();
221
- }
222
- //return $this->search_instance;
223
- return $this->search_instance;
224
- }
225
- /**
226
- * Gets an instance of stats class
227
- *
228
- */
229
- function get_backup_instance()
230
- {
231
- if (!isset($this->backup_instance)) {
232
- $this->backup_instance = new MMB_Backup();
233
- }
234
-
235
- return $this->backup_instance;
236
- }
237
-
238
- /**
239
- * Gets an instance of links class
240
- *
241
- */
242
- function get_link_instance()
243
- {
244
- if (!isset($this->link_instance)) {
245
- $this->link_instance = new MMB_Link();
246
- }
247
-
248
- return $this->link_instance;
249
- }
250
-
251
- function get_installer_instance()
252
- {
253
- if (!isset($this->installer_instance)) {
254
- $this->installer_instance = new MMB_Installer();
255
- }
256
- return $this->installer_instance;
257
- }
258
-
259
- /**
260
- * Plugin install callback function
261
- * Check PHP version
262
- */
263
- function install()
264
- {
265
- global $wp_object_cache, $wpdb;
266
- if (!empty($wp_object_cache))
267
- @$wp_object_cache->flush();
268
-
269
- //delete plugin options, just in case
270
- if ($this->mmb_multisite != false) {
271
- $blog_ids = $wpdb->get_results($wpdb->prepare('SELECT blog_id FROM `wp_blogs`'));
272
- if (!empty($blog_ids)) {
273
- foreach ($blog_ids as $blog_id) {
274
- $wpdb->query($wpdb->prepare('DELETE FROM ' . $wpdb->prefix . $blog->blog_id . '_options WHERE `option_name` = "_worker_nossl_key";'));
275
- $wpdb->query($wpdb->prepare('DELETE FROM ' . $wpdb->prefix . $blog->blog_id . '_options WHERE `option_name` = "_worker_public_key";'));
276
- $wpdb->query($wpdb->prepare('DELETE FROM ' . $wpdb->prefix . $blog->blog_id . '_options WHERE `option_name` = "_action_message_id";'));
277
- }
278
- }
279
- } else {
280
- delete_option('_worker_nossl_key');
281
- delete_option('_worker_public_key');
282
- delete_option('_action_message_id');
283
- }
284
-
285
- delete_option('mwp_backup_tasks');
286
- delete_option('mwp_notifications');
287
-
288
- }
289
-
290
- /**
291
- * Saves the (modified) options into the database
292
- *
293
- */
294
- function save_options()
295
- {
296
- if (get_option($this->slug)) {
297
- update_option($this->slug, $this->settings);
298
- } else {
299
- add_option($this->slug, $this->settings);
300
- }
301
- }
302
-
303
- /**
304
- * Deletes options for communication with master
305
- *
306
- */
307
- function uninstall()
308
- {
309
- global $wp_object_cache, $wpdb;
310
- if (!empty($wp_object_cache))
311
- @$wp_object_cache->flush();
312
-
313
- if ($this->mmb_multisite != false) {
314
- $blog_ids = $wpdb->get_results($wpdb->prepare('SELECT blog_id FROM `wp_blogs`'));
315
- if (!empty($blog_ids)) {
316
- foreach ($blog_ids as $blog) {
317
- $wpdb->query($wpdb->prepare('DELETE FROM ' . $wpdb->prefix . $blog->blog_id . '_options WHERE `option_name` = "_worker_nossl_key";'));
318
- $wpdb->query($wpdb->prepare('DELETE FROM ' . $wpdb->prefix . $blog->blog_id . '_options WHERE `option_name` = "_worker_public_key";'));
319
- $wpdb->query($wpdb->prepare('DELETE FROM ' . $wpdb->prefix . $blog->blog_id . '_options WHERE `option_name` = "_action_message_id";'));
320
- }
321
- }
322
- } else {
323
- delete_option('_worker_nossl_key');
324
- delete_option('_worker_public_key');
325
- delete_option('_action_message_id');
326
- }
327
-
328
- //Delete backup tasks
329
- delete_option('mwp_backup_tasks');
330
- wp_clear_scheduled_hook('mwp_backup_tasks');
331
-
332
- //Delete notifications
333
- delete_option('mwp_notifications');
334
- wp_clear_scheduled_hook('mwp_notifications');
335
-
336
- }
337
-
338
-
339
- /**
340
- * Constructs a url (for ajax purpose)
341
- *
342
- * @param mixed $base_page
343
- */
344
- function construct_url($params = array(), $base_page = 'index.php')
345
- {
346
- $url = "$base_page?_wpnonce=" . wp_create_nonce($this->slug);
347
- foreach ($params as $key => $value) {
348
- $url .= "&$key=$value";
349
- }
350
-
351
- return $url;
352
- }
353
-
354
- /**
355
- * Worker update
356
- *
357
- */
358
- function update_worker_plugin($params)
359
- {
360
- extract($params);
361
- if ($download_url) {
362
- @include_once ABSPATH . 'wp-admin/includes/file.php';
363
- @include_once ABSPATH . 'wp-admin/includes/misc.php';
364
- @include_once ABSPATH . 'wp-admin/includes/template.php';
365
- @include_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
366
- @include_once ABSPATH . 'wp-admin/includes/screen.php';
367
-
368
- if (!$this->is_server_writable()) {
369
- return array(
370
- 'error' => 'Failed, please <a target="_blank" href="http://managewp.com/user-guide#ftp">add FTP details for automatic upgrades.</a></a>'
371
- );
372
- }
373
-
374
- ob_start();
375
- @unlink(dirname(__FILE__));
376
- $upgrader = new Plugin_Upgrader();
377
- $result = $upgrader->run(array(
378
- 'package' => $download_url,
379
- 'destination' => WP_PLUGIN_DIR,
380
- 'clear_destination' => true,
381
- 'clear_working' => true,
382
- 'hook_extra' => array(
383
- 'plugin' => 'worker/init.php'
384
- )
385
- ));
386
- ob_end_clean();
387
- if (is_wp_error($result) || !$result) {
388
- return array(
389
- 'error' => 'ManageWP Worker plugin could not be updated.'
390
- );
391
- } else {
392
- return array(
393
- 'success' => 'ManageWP Worker plugin successfully updated.'
394
- );
395
- }
396
- }
397
- return array(
398
- 'error' => 'Bad download path for worker installation file.'
399
- );
400
- }
401
-
402
- /**
403
- * Automatically logs in when called from Master
404
- *
405
- */
406
- function automatic_login()
407
- {
408
- global $current_user;
409
-
410
- $where = isset($_GET['mwp_goto']) ? $_GET['mwp_goto'] : '';
411
- $username = isset($_GET['username']) ? $_GET['username'] : '';
412
- $auto_login = isset($_GET['auto_login']) ? $_GET['auto_login'] : 0;
413
-
414
- if ((!is_user_logged_in() || ($this->mmb_multisite && $username != $current_user->user_login)) && $auto_login) {
415
- $signature = base64_decode($_GET['signature']);
416
- $message_id = trim($_GET['message_id']);
417
-
418
- $auth = $this->authenticate_message($where . $message_id, $signature, $message_id);
419
- if ($auth === true) {
420
- if (isset($current_user->user_login))
421
- do_action('wp_logout');
422
- $user = get_user_by('login', $username);
423
- $user_id = $user->ID;
424
- wp_set_current_user($user_id, $username);
425
- wp_set_auth_cookie($user_id);
426
- do_action('wp_login', $username);
427
- } else {
428
- unset($_SESSION['mwp_frame_options_header']);
429
- wp_die($auth['error']);
430
- }
431
- }
432
-
433
- if ($auto_login) {
434
- update_option('mwp_iframe_options_header', microtime(true));
435
- if (!headers_sent())
436
- header('P3P: CP="CAO PSA OUR"'); // IE redirect iframe header
437
- wp_redirect(get_option('siteurl') . "/wp-admin/" . $where);
438
- exit();
439
- }
440
- }
441
-
442
-
443
- }
444
  ?>
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 = false;
30
+
31
+
32
+ function __construct()
33
+ {
34
+ global $mmb_plugin_dir, $wpmu_version, $blog_id;
35
+
36
+ $this->name = 'Manage Multiple Blogs';
37
+ $this->slug = 'manage-multiple-blogs';
38
+ $this->settings = get_option($this->slug);
39
+ if (!$this->settings) {
40
+ $this->settings = array(
41
+ 'blogs' => array(),
42
+ 'current_blog' => array(
43
+ 'type' => null
44
+ )
45
+ );
46
+ $this->save_options();
47
+ }
48
+
49
+
50
+
51
+ if (function_exists('is_multisite')) {
52
+ if (is_multisite()) {
53
+ $this->mmb_multisite = $blog_id;
54
+ }
55
+ } else if (!empty($wpmu_version)) {
56
+ $this->mmb_multisite = $blog_id;
57
+ }
58
+
59
+ add_action('rightnow_end', array(
60
+ $this,
61
+ 'add_right_now_info'
62
+ ));
63
+ add_action('wp_footer', array(
64
+ 'MMB_Stats',
65
+ 'set_hit_count'
66
+ ));
67
+ register_activation_hook($mmb_plugin_dir . '/init.php', array(
68
+ $this,
69
+ 'install'
70
+ ));
71
+ if (!get_option('_worker_public_key'))
72
+ add_action('admin_notices', array(
73
+ $this,
74
+ 'admin_notice'
75
+ ));
76
+
77
+
78
+ }
79
+
80
+ /**
81
+ * Add notice to admin dashboard for security reasons
82
+ *
83
+ */
84
+ function admin_notice()
85
+ {
86
+ echo '<div class="error" style="text-align: center;"><p style="color: red; font-size: 14px; font-weight: bold;">Attention !</p><p>
87
+ Please add this site to your <a target="_blank" href="http://managewp.com/user-guide#security">ManageWP.com</a> account now to remove this notice or deactivate the Worker plugin to avoid <a target="_blank" href="http://managewp.com/user-guide#security">security issues</a>.
88
+ </p></div>';
89
+ }
90
+
91
+ /**
92
+ * Add an item into the Right Now Dashboard widget
93
+ * to inform that the blog can be managed remotely
94
+ *
95
+ */
96
+ function add_right_now_info()
97
+ {
98
+ echo '<div class="mmb-slave-info">
99
+ <p>This site can be managed remotely.</p>
100
+ </div>';
101
+ }
102
+
103
+ /**
104
+ * Gets an instance of the Comment class
105
+ *
106
+ */
107
+ function get_comment_instance()
108
+ {
109
+ if (!isset($this->comment_instance)) {
110
+ $this->comment_instance = new MMB_Comment();
111
+ }
112
+
113
+ return $this->comment_instance;
114
+ }
115
+
116
+ /**
117
+ * Gets an instance of the Plugin class
118
+ *
119
+ */
120
+ function get_plugin_instance()
121
+ {
122
+ if (!isset($this->plugin_instance)) {
123
+ $this->plugin_instance = new MMB_Plugin();
124
+ }
125
+
126
+ return $this->plugin_instance;
127
+ }
128
+
129
+ /**
130
+ * Gets an instance of the Theme class
131
+ *
132
+ */
133
+ function get_theme_instance()
134
+ {
135
+ if (!isset($this->theme_instance)) {
136
+ $this->theme_instance = new MMB_Theme();
137
+ }
138
+
139
+ return $this->theme_instance;
140
+ }
141
+
142
+
143
+ /**
144
+ * Gets an instance of MMB_Post class
145
+ *
146
+ */
147
+ function get_post_instance()
148
+ {
149
+ if (!isset($this->post_instance)) {
150
+ $this->post_instance = new MMB_Post();
151
+ }
152
+
153
+ return $this->post_instance;
154
+ }
155
+
156
+ /**
157
+ * Gets an instance of Blogroll class
158
+ *
159
+ */
160
+ function get_blogroll_instance()
161
+ {
162
+ if (!isset($this->blogroll_instance)) {
163
+ $this->blogroll_instance = new MMB_Blogroll();
164
+ }
165
+
166
+ return $this->blogroll_instance;
167
+ }
168
+
169
+
170
+
171
+ /**
172
+ * Gets an instance of the WP class
173
+ *
174
+ */
175
+ function get_wp_instance()
176
+ {
177
+ if (!isset($this->wp_instance)) {
178
+ $this->wp_instance = new MMB_WP();
179
+ }
180
+
181
+ return $this->wp_instance;
182
+ }
183
+
184
+ /**
185
+ * Gets an instance of User
186
+ *
187
+ */
188
+ function get_user_instance()
189
+ {
190
+ if (!isset($this->user_instance)) {
191
+ $this->user_instance = new MMB_User();
192
+ }
193
+
194
+ return $this->user_instance;
195
+ }
196
+
197
+ /**
198
+ * Gets an instance of stats class
199
+ *
200
+ */
201
+ function get_stats_instance()
202
+ {
203
+ if (!isset($this->stats_instance)) {
204
+ $this->stats_instance = new MMB_Stats();
205
+ }
206
+ return $this->stats_instance;
207
+ }
208
+ /**
209
+ * Gets an instance of search class
210
+ *
211
+ */
212
+ function get_search_instance()
213
+ {
214
+ if (!isset($this->search_instance)) {
215
+ $this->search_instance = new MMB_Search();
216
+ }
217
+ //return $this->search_instance;
218
+ return $this->search_instance;
219
+ }
220
+ /**
221
+ * Gets an instance of stats class
222
+ *
223
+ */
224
+ function get_backup_instance()
225
+ {
226
+ if (!isset($this->backup_instance)) {
227
+ $this->backup_instance = new MMB_Backup();
228
+ }
229
+
230
+ return $this->backup_instance;
231
+ }
232
+
233
+ /**
234
+ * Gets an instance of links class
235
+ *
236
+ */
237
+ function get_link_instance()
238
+ {
239
+ if (!isset($this->link_instance)) {
240
+ $this->link_instance = new MMB_Link();
241
+ }
242
+
243
+ return $this->link_instance;
244
+ }
245
+
246
+ function get_installer_instance()
247
+ {
248
+ if (!isset($this->installer_instance)) {
249
+ $this->installer_instance = new MMB_Installer();
250
+ }
251
+ return $this->installer_instance;
252
+ }
253
+
254
+ /**
255
+ * Plugin install callback function
256
+ * Check PHP version
257
+ */
258
+ function install()
259
+ {
260
+ global $wp_object_cache, $wpdb;
261
+ if (!empty($wp_object_cache))
262
+ @$wp_object_cache->flush();
263
+
264
+ //delete plugin options, just in case
265
+ if ($this->mmb_multisite != false) {
266
+ $blog_ids = $wpdb->get_results($wpdb->prepare('SELECT blog_id FROM `wp_blogs`'));
267
+ if (!empty($blog_ids)) {
268
+ foreach ($blog_ids as $blog_id) {
269
+ $wpdb->query($wpdb->prepare('DELETE FROM ' . $wpdb->prefix . $blog->blog_id . '_options WHERE `option_name` = "_worker_nossl_key";'));
270
+ $wpdb->query($wpdb->prepare('DELETE FROM ' . $wpdb->prefix . $blog->blog_id . '_options WHERE `option_name` = "_worker_public_key";'));
271
+ $wpdb->query($wpdb->prepare('DELETE FROM ' . $wpdb->prefix . $blog->blog_id . '_options WHERE `option_name` = "_action_message_id";'));
272
+ }
273
+ }
274
+ } else {
275
+ delete_option('_worker_nossl_key');
276
+ delete_option('_worker_public_key');
277
+ delete_option('_action_message_id');
278
+ }
279
+
280
+ delete_option('mwp_backup_tasks');
281
+ delete_option('mwp_notifications');
282
+
283
+ }
284
+
285
+ /**
286
+ * Saves the (modified) options into the database
287
+ *
288
+ */
289
+ function save_options()
290
+ {
291
+ if (get_option($this->slug)) {
292
+ update_option($this->slug, $this->settings);
293
+ } else {
294
+ add_option($this->slug, $this->settings);
295
+ }
296
+ }
297
+
298
+ /**
299
+ * Deletes options for communication with master
300
+ *
301
+ */
302
+ function uninstall()
303
+ {
304
+ global $wp_object_cache, $wpdb;
305
+ if (!empty($wp_object_cache))
306
+ @$wp_object_cache->flush();
307
+
308
+ if ($this->mmb_multisite != false) {
309
+ $blog_ids = $wpdb->get_results($wpdb->prepare('SELECT blog_id FROM `wp_blogs`'));
310
+ if (!empty($blog_ids)) {
311
+ foreach ($blog_ids as $blog) {
312
+ $wpdb->query($wpdb->prepare('DELETE FROM ' . $wpdb->prefix . $blog->blog_id . '_options WHERE `option_name` = "_worker_nossl_key";'));
313
+ $wpdb->query($wpdb->prepare('DELETE FROM ' . $wpdb->prefix . $blog->blog_id . '_options WHERE `option_name` = "_worker_public_key";'));
314
+ $wpdb->query($wpdb->prepare('DELETE FROM ' . $wpdb->prefix . $blog->blog_id . '_options WHERE `option_name` = "_action_message_id";'));
315
+ }
316
+ }
317
+ } else {
318
+ delete_option('_worker_nossl_key');
319
+ delete_option('_worker_public_key');
320
+ delete_option('_action_message_id');
321
+ }
322
+
323
+ //Delete backup tasks
324
+ delete_option('mwp_backup_tasks');
325
+ wp_clear_scheduled_hook('mwp_backup_tasks');
326
+
327
+ //Delete notifications
328
+ delete_option('mwp_notifications');
329
+ wp_clear_scheduled_hook('mwp_notifications');
330
+
331
+ }
332
+
333
+
334
+ /**
335
+ * Constructs a url (for ajax purpose)
336
+ *
337
+ * @param mixed $base_page
338
+ */
339
+ function construct_url($params = array(), $base_page = 'index.php')
340
+ {
341
+ $url = "$base_page?_wpnonce=" . wp_create_nonce($this->slug);
342
+ foreach ($params as $key => $value) {
343
+ $url .= "&$key=$value";
344
+ }
345
+
346
+ return $url;
347
+ }
348
+
349
+ /**
350
+ * Worker update
351
+ *
352
+ */
353
+ function update_worker_plugin($params)
354
+ {
355
+ extract($params);
356
+ if ($download_url) {
357
+ @include_once ABSPATH . 'wp-admin/includes/file.php';
358
+ @include_once ABSPATH . 'wp-admin/includes/misc.php';
359
+ @include_once ABSPATH . 'wp-admin/includes/template.php';
360
+ @include_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
361
+ @include_once ABSPATH . 'wp-admin/includes/screen.php';
362
+
363
+ if (!$this->is_server_writable()) {
364
+ return array(
365
+ 'error' => 'Failed, please <a target="_blank" href="http://managewp.com/user-guide#ftp">add FTP details for automatic upgrades.</a></a>'
366
+ );
367
+ }
368
+
369
+ ob_start();
370
+ @unlink(dirname(__FILE__));
371
+ $upgrader = new Plugin_Upgrader();
372
+ $result = $upgrader->run(array(
373
+ 'package' => $download_url,
374
+ 'destination' => WP_PLUGIN_DIR,
375
+ 'clear_destination' => true,
376
+ 'clear_working' => true,
377
+ 'hook_extra' => array(
378
+ 'plugin' => 'worker/init.php'
379
+ )
380
+ ));
381
+ ob_end_clean();
382
+ if (is_wp_error($result) || !$result) {
383
+ return array(
384
+ 'error' => 'ManageWP Worker plugin could not be updated.'
385
+ );
386
+ } else {
387
+ return array(
388
+ 'success' => 'ManageWP Worker plugin successfully updated.'
389
+ );
390
+ }
391
+ }
392
+ return array(
393
+ 'error' => 'Bad download path for worker installation file.'
394
+ );
395
+ }
396
+
397
+ /**
398
+ * Automatically logs in when called from Master
399
+ *
400
+ */
401
+ function automatic_login()
402
+ {
403
+ $where = isset($_GET['mwp_goto']) ? $_GET['mwp_goto'] : false;
404
+ $username = isset($_GET['username']) ? $_GET['username'] : '';
405
+ $auto_login = isset($_GET['auto_login']) ? $_GET['auto_login'] : 0;
406
+
407
+ if( !function_exists('is_user_logged_in') )
408
+ include_once( ABSPATH.'wp-includes/pluggable.php' );
409
+
410
+ if (( $auto_login && strlen(trim($username)) && !is_user_logged_in() ) || (isset($this->mmb_multisite) && $this->mmb_multisite )) {
411
+ $signature = base64_decode($_GET['signature']);
412
+ $message_id = trim($_GET['message_id']);
413
+
414
+ $auth = $this->authenticate_message($where . $message_id, $signature, $message_id);
415
+ if ($auth === true) {
416
+ update_option('mwp_iframe_options_header', microtime(true));
417
+
418
+ if (!headers_sent())
419
+ header('P3P: CP="CAO PSA OUR"');
420
+
421
+ $siteurl = get_site_option( 'siteurl' );
422
+ $user = get_user_by('login', $username);
423
+ wp_set_current_user($user->ID);
424
+
425
+ $expiration = time() + apply_filters('auth_cookie_expiration', 21600, $user->ID, false);
426
+ $auth_cookie = wp_generate_auth_cookie($user->ID, $expiration, 'auth');
427
+ $logged_in_cookie = wp_generate_auth_cookie($user->ID, $expiration, 'logged_in');
428
+
429
+ $_COOKIE['wordpress_'.md5( $siteurl )] = $auth_cookie;
430
+ $_COOKIE['wordpress_logged_in_'.md5( $siteurl )] = $logged_in_cookie;
431
+
432
+ wp_set_auth_cookie($user->ID);
433
+
434
+
435
+ } else {
436
+ wp_die($auth['error']);
437
+ }
438
+ }
439
+ }
440
+ }
 
 
 
441
  ?>
helper.class.php CHANGED
@@ -1,434 +1,438 @@
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_function_exists($function_callback){
79
-
80
- if(!function_exists($function_callback))
81
- return false;
82
-
83
- if (extension_loaded('suhosin')) {
84
- $suhosin = @ini_get("suhosin.executor.func.blacklist");
85
- if (empty($suhosin) == false) {
86
- $suhosin = explode(',', $suhosin);
87
- $blacklist = array_map('trim', $suhosin);
88
- $blacklist = array_map('strtolower', $blacklist);
89
- if(in_array($function_callback, $blacklist))
90
- return false;
91
- }
92
- }
93
- return true;
94
- }
95
-
96
- /**
97
- * Gets transient based on WP version
98
- *
99
- * @global string $wp_version
100
- * @param string $option_name
101
- * @return mixed
102
- */
103
-
104
- function mmb_set_transient($option_name = false, $data = false){
105
-
106
- if (!$option_name || !$data) {
107
- return false;
108
- }
109
- if($this->mmb_multisite)
110
- return $this->mmb_set_sitemeta_transient($option_name, $data);
111
-
112
- global $wp_version;
113
-
114
- if (version_compare($wp_version, '2.7.9', '<=')) {
115
- update_option($option_name, $data);
116
- } else if (version_compare($wp_version, '2.9.9', '<=')) {
117
- update_option('_transient_' . $option_name, $data);
118
- } else {
119
- update_option('_site_transient_' . $option_name, $data);
120
- }
121
-
122
- }
123
- function mmb_get_transient($option_name)
124
- {
125
- if (trim($option_name) == '') {
126
- return FALSE;
127
- }
128
- if($this->mmb_multisite)
129
- return $this->mmb_get_sitemeta_transient($option_name);
130
-
131
- global $wp_version;
132
-
133
-
134
- if (version_compare($wp_version, '2.7.9', '<=')) {
135
- return get_option($option_name);
136
- } else if (version_compare($wp_version, '2.9.9', '<=')) {
137
- return get_option('_transient_' . $option_name);
138
- } else {
139
- return get_option('_site_transient_' . $option_name);
140
- }
141
- }
142
-
143
- function mmb_delete_transient($option_name)
144
- {
145
- if (trim($option_name) == '') {
146
- return FALSE;
147
- }
148
-
149
- global $wp_version;
150
-
151
- if (version_compare($wp_version, '2.7.9', '<=')) {
152
- delete_option($option_name);
153
- } else if (version_compare($wp_version, '2.9.9', '<=')) {
154
- delete_option('_transient_' . $option_name);
155
- } else {
156
- delete_option('_site_transient_' . $option_name);
157
- }
158
- }
159
-
160
- function mmb_get_sitemeta_transient($option_name){
161
- global $wpdb;
162
- $option_name = '_site_transient_'. $option_name;
163
-
164
- $result = $wpdb->get_var( $wpdb->prepare("SELECT `meta_value` FROM `{$wpdb->sitemeta}` WHERE meta_key = '{$option_name}' AND `site_id` = '{$this->mmb_multisite}' "));
165
- $result = maybe_unserialize($result);
166
- return $result;
167
- }
168
-
169
- function mmb_set_sitemeta_transient($option_name, $option_value){
170
- global $wpdb;
171
- $option_name = '_site_transient_'. $option_name;
172
-
173
- if($this->mmb_get_sitemeta_transient($option_name)){
174
- $result = $wpdb->update( $wpdb->sitemeta,
175
- array(
176
- 'meta_value' => maybe_serialize($option_value)
177
- ),
178
- array(
179
- 'meta_key' => $option_name,
180
- 'site_id' => $this->mmb_multisite
181
- )
182
- );
183
- }else {
184
- $result = $wpdb->insert( $wpdb->sitemeta,
185
- array(
186
- 'meta_key' => $option_name,
187
- 'meta_value' => maybe_serialize($option_value),
188
- 'site_id' => $this->mmb_multisite
189
- )
190
- );
191
- }
192
- return $result;
193
- }
194
-
195
- function delete_temp_dir($directory)
196
- {
197
- if (substr($directory, -1) == "/") {
198
- $directory = substr($directory, 0, -1);
199
- }
200
- if (!file_exists($directory) || !is_dir($directory)) {
201
- return false;
202
- } elseif (!is_readable($directory)) {
203
- return false;
204
- } else {
205
- $directoryHandle = opendir($directory);
206
-
207
- while ($contents = readdir($directoryHandle)) {
208
- if ($contents != '.' && $contents != '..') {
209
- $path = $directory . "/" . $contents;
210
-
211
- if (is_dir($path)) {
212
- $this->delete_temp_dir($path);
213
- } else {
214
- unlink($path);
215
- }
216
- }
217
- }
218
- closedir($directoryHandle);
219
- rmdir($directory);
220
- return true;
221
- }
222
- }
223
-
224
- function set_worker_message_id($message_id = false)
225
- {
226
- if ($message_id) {
227
- add_option('_action_message_id', $message_id) or update_option('_action_message_id', $message_id);
228
- return $message_id;
229
- }
230
- return false;
231
- }
232
-
233
- function get_worker_message_id()
234
- {
235
- return (int) get_option('_action_message_id');
236
- }
237
-
238
- function set_master_public_key($public_key = false)
239
- {
240
- if ($public_key && !get_option('_worker_public_key')) {
241
- add_option('_worker_public_key', base64_encode($public_key));
242
- return true;
243
- }
244
- return false;
245
- }
246
-
247
- function get_master_public_key()
248
- {
249
- if (!get_option('_worker_public_key'))
250
- return false;
251
- return base64_decode(get_option('_worker_public_key'));
252
- }
253
-
254
-
255
- function get_random_signature()
256
- {
257
- if (!get_option('_worker_nossl_key'))
258
- return false;
259
- return base64_decode(get_option('_worker_nossl_key'));
260
- }
261
-
262
- function set_random_signature($random_key = false)
263
- {
264
- if ($random_key && !get_option('_worker_nossl_key')) {
265
- add_option('_worker_nossl_key', base64_encode($random_key));
266
- return true;
267
- }
268
- return false;
269
- }
270
-
271
-
272
- function authenticate_message($data = false, $signature = false, $message_id = false)
273
- {
274
- if (!$data && !$signature) {
275
- return array(
276
- 'error' => 'Authentication failed.'
277
- );
278
- }
279
-
280
- $current_message = $this->get_worker_message_id();
281
-
282
- if ((int) $current_message > (int) $message_id)
283
- return array(
284
- '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.'
285
- );
286
-
287
- $pl_key = $this->get_master_public_key();
288
- if (!$pl_key) {
289
- return array(
290
- '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.'
291
- );
292
- }
293
-
294
- if (function_exists('openssl_verify') && !$this->get_random_signature()) {
295
- $verify = openssl_verify($data, $signature, $pl_key);
296
- if ($verify == 1) {
297
- $message_id = $this->set_worker_message_id($message_id);
298
- return true;
299
- } else if ($verify == 0) {
300
- return array(
301
- '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.'
302
- );
303
- } else {
304
- return array(
305
- 'error' => 'Command not successful! Please try again.'
306
- );
307
- }
308
- } else if ($this->get_random_signature()) {
309
- if (md5($data . $this->get_random_signature()) == $signature) {
310
- $message_id = $this->set_worker_message_id($message_id);
311
- return true;
312
- }
313
- return array(
314
- '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.'
315
- );
316
- }
317
- // no rand key - deleted in get_stat maybe
318
- else
319
- return array(
320
- '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.'
321
- );
322
- }
323
-
324
- function _secure_data($data = false){
325
- if($data == false)
326
- return false;
327
-
328
- $pl_key = $this->get_master_public_key();
329
- if (!$pl_key)
330
- return false;
331
-
332
- $secure = '';
333
- if( function_exists('openssl_public_decrypt') && !$this->get_random_signature()){
334
- if(is_array($data) && !empty($data)){
335
- foreach($data as $input){
336
- openssl_public_decrypt($input, $decrypted, $pl_key);
337
- $secure .= $decrypted;
338
- }
339
- } else {
340
- openssl_public_decrypt($input, $decrypted, $pl_key);
341
- $secure = $decrypted;
342
- }
343
- return $secure;
344
- }
345
- return false;
346
-
347
- }
348
-
349
- function check_if_user_exists($username = false)
350
- {
351
- global $wpdb;
352
- if ($username) {
353
- require_once(ABSPATH . WPINC . '/registration.php');
354
- include_once(ABSPATH . 'wp-includes/pluggable.php');
355
-
356
- if (username_exists($username) == null) {
357
- return false;
358
- }
359
- $user = (array) get_userdatabylogin($username);
360
-
361
- if ($user[$wpdb->prefix . 'user_level'] == 10 || isset($user[$wpdb->prefix . 'capabilities']['administrator']) ||
362
- (isset($user['caps']['administrator']) && $user['caps']['administrator'] == 1)){
363
- define('MMB_USER_CAPABILITIES', $user->wp_user_level);
364
- return true;
365
- }
366
- return false;
367
- }
368
- return false;
369
- }
370
-
371
- function refresh_updates()
372
- {
373
- if (rand(1, 3) == '2') {
374
- require_once(ABSPATH . WPINC . '/update.php');
375
- wp_update_plugins();
376
- wp_update_themes();
377
- wp_version_check();
378
- }
379
- }
380
-
381
- function remove_http($url = '')
382
- {
383
- if ($url == 'http://' OR $url == 'https://') {
384
- return $url;
385
- }
386
- return preg_replace('/^(http|https)\:\/\/(www.)?/i', '', $url);
387
-
388
- }
389
-
390
- function mmb_get_error($error_object)
391
- {
392
- if (!is_wp_error($error_object)) {
393
- return $error_object != '' ? $error_object : '';
394
- } else {
395
- $errors = array();
396
- if(!empty($error_object->error_data)) {
397
- foreach ($error_object->error_data as $error_key => $error_string) {
398
- $errors[] = str_replace('_', ' ', ucfirst($error_key)) . ': ' . $error_string;
399
- }
400
- } elseif (!empty($error_object->errors)){
401
- foreach ($error_object->errors as $error_key => $err) {
402
- $errors[] = 'Error: '.str_replace('_', ' ', strtolower($error_key));
403
- }
404
- }
405
- return implode('<br />', $errors);
406
- }
407
- }
408
-
409
- function is_server_writable(){
410
- if((!defined('FTP_HOST') || !defined('FTP_USER') || !defined('FTP_PASS')) && (get_filesystem_method(array(), false) != 'direct'))
411
- return false;
412
- else
413
- return true;
414
- }
415
-
416
- function mmb_download_url($url, $file_name)
417
- {
418
- if (function_exists('fopen') && function_exists('ini_get') && ini_get('allow_url_fopen') == true && ($destination = @fopen($file_name, 'wb')) && ($source = @fopen($url, "r")) ) {
419
-
420
-
421
- while ($a = @fread($source, 1024* 1024)) {
422
- @fwrite($destination, $a);
423
- }
424
-
425
- fclose($source);
426
- fclose($destination);
427
- } else
428
- if (!fsockopen_download($url, $file_name))
429
- die('Error downloading file ' . $url);
430
- return $file_name;
431
- }
432
-
433
- }
 
 
 
 
434
  ?>
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_function_exists($function_callback){
79
+
80
+ if(!function_exists($function_callback))
81
+ return false;
82
+
83
+ if (extension_loaded('suhosin')) {
84
+ $suhosin = @ini_get("suhosin.executor.func.blacklist");
85
+ if (empty($suhosin) == false) {
86
+ $suhosin = explode(',', $suhosin);
87
+ $blacklist = array_map('trim', $suhosin);
88
+ $blacklist = array_map('strtolower', $blacklist);
89
+ if(in_array($function_callback, $blacklist))
90
+ return false;
91
+ }
92
+ }
93
+ return true;
94
+ }
95
+
96
+ /**
97
+ * Gets transient based on WP version
98
+ *
99
+ * @global string $wp_version
100
+ * @param string $option_name
101
+ * @return mixed
102
+ */
103
+
104
+ function mmb_set_transient($option_name = false, $data = false){
105
+
106
+ if (!$option_name || !$data) {
107
+ return false;
108
+ }
109
+ if($this->mmb_multisite)
110
+ return $this->mmb_set_sitemeta_transient($option_name, $data);
111
+
112
+ global $wp_version;
113
+
114
+ if (version_compare($wp_version, '2.7.9', '<=')) {
115
+ update_option($option_name, $data);
116
+ } else if (version_compare($wp_version, '2.9.9', '<=')) {
117
+ update_option('_transient_' . $option_name, $data);
118
+ } else {
119
+ update_option('_site_transient_' . $option_name, $data);
120
+ }
121
+
122
+ }
123
+ function mmb_get_transient($option_name)
124
+ {
125
+ if (trim($option_name) == '') {
126
+ return FALSE;
127
+ }
128
+ if($this->mmb_multisite)
129
+ return $this->mmb_get_sitemeta_transient($option_name);
130
+
131
+ global $wp_version;
132
+
133
+
134
+ if (version_compare($wp_version, '2.7.9', '<=')) {
135
+ return get_option($option_name);
136
+ } else if (version_compare($wp_version, '2.9.9', '<=')) {
137
+ return get_option('_transient_' . $option_name);
138
+ } else {
139
+ return get_option('_site_transient_' . $option_name);
140
+ }
141
+ }
142
+
143
+ function mmb_delete_transient($option_name)
144
+ {
145
+ if (trim($option_name) == '') {
146
+ return FALSE;
147
+ }
148
+
149
+ global $wp_version;
150
+
151
+ if (version_compare($wp_version, '2.7.9', '<=')) {
152
+ delete_option($option_name);
153
+ } else if (version_compare($wp_version, '2.9.9', '<=')) {
154
+ delete_option('_transient_' . $option_name);
155
+ } else {
156
+ delete_option('_site_transient_' . $option_name);
157
+ }
158
+ }
159
+
160
+ function mmb_get_sitemeta_transient($option_name){
161
+ global $wpdb;
162
+ $option_name = '_site_transient_'. $option_name;
163
+
164
+ $result = $wpdb->get_var( $wpdb->prepare("SELECT `meta_value` FROM `{$wpdb->sitemeta}` WHERE meta_key = '{$option_name}' AND `site_id` = '{$this->mmb_multisite}' "));
165
+ $result = maybe_unserialize($result);
166
+ return $result;
167
+ }
168
+
169
+ function mmb_set_sitemeta_transient($option_name, $option_value){
170
+ global $wpdb;
171
+ $option_name = '_site_transient_'. $option_name;
172
+
173
+ if($this->mmb_get_sitemeta_transient($option_name)){
174
+ $result = $wpdb->update( $wpdb->sitemeta,
175
+ array(
176
+ 'meta_value' => maybe_serialize($option_value)
177
+ ),
178
+ array(
179
+ 'meta_key' => $option_name,
180
+ 'site_id' => $this->mmb_multisite
181
+ )
182
+ );
183
+ }else {
184
+ $result = $wpdb->insert( $wpdb->sitemeta,
185
+ array(
186
+ 'meta_key' => $option_name,
187
+ 'meta_value' => maybe_serialize($option_value),
188
+ 'site_id' => $this->mmb_multisite
189
+ )
190
+ );
191
+ }
192
+ return $result;
193
+ }
194
+
195
+ function delete_temp_dir($directory)
196
+ {
197
+ if (substr($directory, -1) == "/") {
198
+ $directory = substr($directory, 0, -1);
199
+ }
200
+ if (!file_exists($directory) || !is_dir($directory)) {
201
+ return false;
202
+ } elseif (!is_readable($directory)) {
203
+ return false;
204
+ } else {
205
+ $directoryHandle = opendir($directory);
206
+
207
+ while ($contents = readdir($directoryHandle)) {
208
+ if ($contents != '.' && $contents != '..') {
209
+ $path = $directory . "/" . $contents;
210
+
211
+ if (is_dir($path)) {
212
+ $this->delete_temp_dir($path);
213
+ } else {
214
+ unlink($path);
215
+ }
216
+ }
217
+ }
218
+ closedir($directoryHandle);
219
+ rmdir($directory);
220
+ return true;
221
+ }
222
+ }
223
+
224
+ function set_worker_message_id($message_id = false)
225
+ {
226
+ if ($message_id) {
227
+ add_option('_action_message_id', $message_id) or update_option('_action_message_id', $message_id);
228
+ return $message_id;
229
+ }
230
+ return false;
231
+ }
232
+
233
+ function get_worker_message_id()
234
+ {
235
+ return (int) get_option('_action_message_id');
236
+ }
237
+
238
+ function set_master_public_key($public_key = false)
239
+ {
240
+ if ($public_key && !get_option('_worker_public_key')) {
241
+ add_option('_worker_public_key', base64_encode($public_key));
242
+ return true;
243
+ }
244
+ return false;
245
+ }
246
+
247
+ function get_master_public_key()
248
+ {
249
+ if (!get_option('_worker_public_key'))
250
+ return false;
251
+ return base64_decode(get_option('_worker_public_key'));
252
+ }
253
+
254
+
255
+ function get_random_signature()
256
+ {
257
+ if (!get_option('_worker_nossl_key'))
258
+ return false;
259
+ return base64_decode(get_option('_worker_nossl_key'));
260
+ }
261
+
262
+ function set_random_signature($random_key = false)
263
+ {
264
+ if ($random_key && !get_option('_worker_nossl_key')) {
265
+ add_option('_worker_nossl_key', base64_encode($random_key));
266
+ return true;
267
+ }
268
+ return false;
269
+ }
270
+
271
+
272
+ function authenticate_message($data = false, $signature = false, $message_id = false)
273
+ {
274
+ if (!$data && !$signature) {
275
+ return array(
276
+ 'error' => 'Authentication failed.'
277
+ );
278
+ }
279
+
280
+ $current_message = $this->get_worker_message_id();
281
+
282
+ if ((int) $current_message > (int) $message_id)
283
+ return array(
284
+ '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.'
285
+ );
286
+
287
+ $pl_key = $this->get_master_public_key();
288
+ if (!$pl_key) {
289
+ return array(
290
+ '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.'
291
+ );
292
+ }
293
+
294
+ if (function_exists('openssl_verify') && !$this->get_random_signature()) {
295
+ $verify = openssl_verify($data, $signature, $pl_key);
296
+ if ($verify == 1) {
297
+ $message_id = $this->set_worker_message_id($message_id);
298
+ return true;
299
+ } else if ($verify == 0) {
300
+ return array(
301
+ '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.'
302
+ );
303
+ } else {
304
+ return array(
305
+ 'error' => 'Command not successful! Please try again.'
306
+ );
307
+ }
308
+ } else if ($this->get_random_signature()) {
309
+ if (md5($data . $this->get_random_signature()) == $signature) {
310
+ $message_id = $this->set_worker_message_id($message_id);
311
+ return true;
312
+ }
313
+ return array(
314
+ '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.'
315
+ );
316
+ }
317
+ // no rand key - deleted in get_stat maybe
318
+ else
319
+ return array(
320
+ '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.'
321
+ );
322
+ }
323
+
324
+ function _secure_data($data = false){
325
+ if($data == false)
326
+ return false;
327
+
328
+ $pl_key = $this->get_master_public_key();
329
+ if (!$pl_key)
330
+ return false;
331
+
332
+ $secure = '';
333
+ if( function_exists('openssl_public_decrypt') && !$this->get_random_signature()){
334
+ if(is_array($data) && !empty($data)){
335
+ foreach($data as $input){
336
+ openssl_public_decrypt($input, $decrypted, $pl_key);
337
+ $secure .= $decrypted;
338
+ }
339
+ } else {
340
+ openssl_public_decrypt($input, $decrypted, $pl_key);
341
+ $secure = $decrypted;
342
+ }
343
+ return $secure;
344
+ }
345
+ return false;
346
+
347
+ }
348
+
349
+ function check_if_user_exists($username = false)
350
+ {
351
+ global $wpdb;
352
+ if ($username) {
353
+ require_once(ABSPATH . WPINC . '/registration.php');
354
+ include_once(ABSPATH . 'wp-includes/pluggable.php');
355
+
356
+ if (username_exists($username) == null) {
357
+ return false;
358
+ }
359
+ $user = (array) get_userdatabylogin($username);
360
+
361
+ if ($user[$wpdb->prefix . 'user_level'] == 10 || isset($user[$wpdb->prefix . 'capabilities']['administrator']) ||
362
+ (isset($user['caps']['administrator']) && $user['caps']['administrator'] == 1)){
363
+ define('MMB_USER_CAPABILITIES', $user->wp_user_level);
364
+ return true;
365
+ }
366
+ return false;
367
+ }
368
+ return false;
369
+ }
370
+
371
+ function refresh_updates()
372
+ {
373
+ if (rand(1, 3) == '2') {
374
+ require_once(ABSPATH . WPINC . '/update.php');
375
+ wp_update_plugins();
376
+ wp_update_themes();
377
+ wp_version_check();
378
+ }
379
+ }
380
+
381
+ function remove_http($url = '')
382
+ {
383
+ if ($url == 'http://' OR $url == 'https://') {
384
+ return $url;
385
+ }
386
+ return preg_replace('/^(http|https)\:\/\/(www.)?/i', '', $url);
387
+
388
+ }
389
+
390
+ function mmb_get_error($error_object)
391
+ {
392
+ if (!is_wp_error($error_object)) {
393
+ return $error_object != '' ? $error_object : '';
394
+ } else {
395
+ $errors = array();
396
+ if(!empty($error_object->error_data)) {
397
+ foreach ($error_object->error_data as $error_key => $error_string) {
398
+ $errors[] = str_replace('_', ' ', ucfirst($error_key)) . ': ' . $error_string;
399
+ }
400
+ } elseif (!empty($error_object->errors)){
401
+ foreach ($error_object->errors as $error_key => $err) {
402
+ $errors[] = 'Error: '.str_replace('_', ' ', strtolower($error_key));
403
+ }
404
+ }
405
+ return implode('<br />', $errors);
406
+ }
407
+ }
408
+
409
+ function is_server_writable(){
410
+ if((!defined('FTP_HOST') || !defined('FTP_USER') || !defined('FTP_PASS')) && (get_filesystem_method(array(), false) != 'direct'))
411
+ return false;
412
+ else
413
+ return true;
414
+ }
415
+
416
+ function mmb_download_url($url, $file_name)
417
+ {
418
+ if (function_exists('fopen') && function_exists('ini_get') && ini_get('allow_url_fopen') == true && ($destination = @fopen($file_name, 'wb')) && ($source = @fopen($url, "r")) ) {
419
+
420
+
421
+ while ($a = @fread($source, 1024* 1024)) {
422
+ @fwrite($destination, $a);
423
+ }
424
+
425
+ fclose($source);
426
+ fclose($destination);
427
+ } else
428
+ if (!fsockopen_download($url, $file_name))
429
+ die('Error downloading file ' . $url);
430
+ return $file_name;
431
+ }
432
+
433
+
434
+
435
+
436
+
437
+ }
438
  ?>
init.php CHANGED
@@ -1,669 +1,719 @@
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.8
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
-
23
- define('MMB_WORKER_VERSION', '3.9.8');
24
-
25
- global $wpdb, $mmb_plugin_dir, $mmb_plugin_url;
26
-
27
- if (version_compare(PHP_VERSION, '5.0.0', '<')) // min version 5 supported
28
- exit("<p>ManageWP Worker plugin requires PHP 5 or higher.</p>");
29
-
30
-
31
-
32
- global $wp_version;
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
- $mmb_actions = array(
39
- 'remove_site' => 'mmb_remove_site',
40
- 'get_stats' => 'mmb_stats_get',
41
- 'backup_clone' => 'mmb_backup_now',
42
- 'restore' => 'mmb_restore_now',
43
- 'optimize_tables' => 'mmb_optimize_tables',
44
- 'check_wp_version' => 'mmb_wp_checkversion',
45
- 'create_post' => 'mmb_post_create',
46
- 'update_worker' => 'mmb_update_worker_plugin',
47
- 'change_comment_status' => 'mmb_change_comment_status',
48
- 'change_post_status' => 'mmb_change_post_status',
49
- 'get_comment_stats' => 'mmb_comment_stats_get',
50
- 'install_addon' => 'mmb_install_addon',
51
- 'do_upgrade' => 'mmb_do_upgrade',
52
- 'add_link' => 'mmb_add_link',
53
- 'add_user' => 'mmb_add_user',
54
- 'email_backup' => 'mmb_email_backup',
55
- 'check_backup_compat' => 'mmb_check_backup_compat',
56
- 'scheduled_backup' => 'mmb_scheduled_backup',
57
- 'execute_php_code' => 'mmb_execute_php_code',
58
- 'delete_backup' => 'mmm_delete_backup',
59
- 'remote_backup_now' => 'mmb_remote_backup_now',
60
- 'set_notifications' => 'mmb_set_notifications',
61
- 'clean_orphan_backups' => 'mmb_clean_orphan_backups'
62
- );
63
-
64
- require_once("$mmb_plugin_dir/helper.class.php");
65
- require_once("$mmb_plugin_dir/core.class.php");
66
- require_once("$mmb_plugin_dir/post.class.php");
67
- require_once("$mmb_plugin_dir/comment.class.php");
68
- require_once("$mmb_plugin_dir/stats.class.php");
69
- require_once("$mmb_plugin_dir/backup.class.php");
70
- require_once("$mmb_plugin_dir/installer.class.php");
71
- require_once("$mmb_plugin_dir/link.class.php");
72
- require_once("$mmb_plugin_dir/user.class.php");
73
- require_once("$mmb_plugin_dir/api.php");
74
-
75
- require_once("$mmb_plugin_dir/plugins/search/search.php");
76
- require_once("$mmb_plugin_dir/plugins/cleanup/cleanup.php");
77
-
78
- //this is an exmaple plugin for extra_html element
79
- //require_once("$mmb_plugin_dir/plugins/extra_html_example/extra_html_example.php");
80
-
81
- $mmb_core = new MMB_Core();
82
- if( microtime(true) - (double)get_option('mwp_iframe_options_header') < 3600 ){
83
- remove_action( 'admin_init', 'send_frame_options_header');
84
- remove_action( 'login_init', 'send_frame_options_header');
85
- }
86
-
87
- add_action('init', 'mmb_parse_request');
88
-
89
-
90
- if (function_exists('register_activation_hook'))
91
- register_activation_hook(__FILE__, array(
92
- $mmb_core,
93
- 'install'
94
- ));
95
-
96
- if (function_exists('register_deactivation_hook'))
97
- register_deactivation_hook(__FILE__, array(
98
- $mmb_core,
99
- 'uninstall'
100
- ));
101
- do_action('after_db_upgrade');
102
- if( !function_exists ( 'mmb_parse_request' )) {
103
-
104
- function mmb_parse_request()
105
- {
106
-
107
- if (!isset($HTTP_RAW_POST_DATA)) {
108
- $HTTP_RAW_POST_DATA = file_get_contents('php://input');
109
- }
110
- ob_start();
111
-
112
- global $mmb_core, $mmb_actions, $new_actions, $wp_db_version, $wpmu_version, $_wp_using_ext_object_cache;
113
-
114
- $data = base64_decode($HTTP_RAW_POST_DATA);
115
- if ($data)
116
- $num = @extract(unserialize($data));
117
-
118
- if ($action) {
119
- $_wp_using_ext_object_cache = false;
120
- @set_time_limit(600);
121
-
122
- update_option('mwp_iframe_options_header', microtime(true));
123
- // mmb_response($mmb_actions, false);
124
- if (!$mmb_core->check_if_user_exists($params['username']))
125
- mmb_response('Username <b>' . $params['username'] . '</b> does not have administrator capabilities. Enter the correct username in the site options.', false);
126
-
127
- /* in case database upgrade required, do database backup and perform upgrade ( wordpress wp_upgrade() function ) */
128
- if( strlen(trim($wp_db_version)) ){
129
- if ( get_option('db_version') != $wp_db_version ) {
130
- /* in multisite network, please update database manualy */
131
- if (empty($wpmu_version) || (function_exists('is_multisite') && !is_multisite())){
132
- if( ! function_exists('wp_upgrade'))
133
- include_once(ABSPATH.'wp-admin/includes/upgrade.php');
134
-
135
- ob_clean();
136
- @wp_upgrade();
137
- @do_action('after_db_upgrade');
138
- ob_end_clean();
139
- }
140
- }
141
- }
142
-
143
- if ($action == 'add_site') {
144
- mmb_add_site($params);
145
- mmb_response('You should never see this.', false);
146
- }
147
- $auth = $mmb_core->authenticate_message($action . $id, $signature, $id);
148
- if ($auth === true) {
149
- if(isset($params['secure'])){
150
- if($decrypted = $mmb_core->_secure_data($params['secure'])){
151
- $decrypted = maybe_unserialize($decrypted);
152
- if(is_array($decrypted)){
153
- foreach($decrypted as $key => $val){
154
- if(!is_numeric($key))
155
- $params[$key] = $val;
156
- }
157
- unset($params['secure']);
158
- } else $params['secure'] = $decrypted;
159
- }
160
- }
161
-
162
- if (array_key_exists($action, $mmb_actions) && function_exists($mmb_actions[$action]))
163
- call_user_func($mmb_actions[$action], $params);
164
- else
165
- mmb_response('Action "' . $action . '" does not exist. Please update your Worker plugin.', false);
166
- } else {
167
- mmb_response($auth['error'], false);
168
- }
169
- }
170
-
171
-
172
- ob_end_clean();
173
- }
174
- }
175
- /* Main response function */
176
- if( !function_exists ( 'mmb_response' )) {
177
-
178
- function mmb_response($response = false, $success = true)
179
- {
180
- $return = array();
181
-
182
- if ((is_array($response) && empty($response)) || (!is_array($response) && strlen($response) == 0))
183
- $return['error'] = 'Empty response.';
184
- else if ($success)
185
- $return['success'] = $response;
186
- else
187
- $return['error'] = $response;
188
-
189
- if( !headers_sent() ){
190
- header('HTTP/1.0 200 OK');
191
- header('Content-Type: text/plain');
192
- }
193
- exit("<MWPHEADER>" . base64_encode(serialize($return))."<ENDMWPHEADER>");
194
- }
195
- }
196
-
197
-
198
-
199
- if( !function_exists ( 'mmb_add_site' )) {
200
- function mmb_add_site($params)
201
- {
202
- global $mmb_core;
203
-
204
- $num = extract($params);
205
-
206
-
207
- if ($num) {
208
- if (!get_option('_action_message_id') && !get_option('_worker_public_key')) {
209
- $public_key = base64_decode($public_key);
210
-
211
- if (function_exists('openssl_verify')) {
212
- $verify = openssl_verify($action . $id, base64_decode($signature), $public_key);
213
- if ($verify == 1) {
214
- $mmb_core->set_master_public_key($public_key);
215
- $mmb_core->set_worker_message_id($id);
216
- $mmb_core->get_stats_instance();
217
- if(is_array($notifications) && !empty($notifications)){
218
- $mmb_core->stats_instance->set_notifications($notifications);
219
- }
220
- mmb_response($mmb_core->stats_instance->get_initial_stats(), true);
221
- } else if ($verify == 0) {
222
- mmb_response('Invalid message signature. Please contact us if you see this message often.', false);
223
- } else {
224
- mmb_response('Command not successful. Please try again.', false);
225
- }
226
- } else {
227
- if (!get_option('_worker_nossl_key')) {
228
- srand();
229
-
230
- $random_key = md5(base64_encode($public_key) . rand(0, getrandmax()));
231
-
232
- $mmb_core->set_random_signature($random_key);
233
- $mmb_core->set_worker_message_id($id);
234
- $mmb_core->set_master_public_key($public_key);
235
- $mmb_core->get_stats_instance();
236
- $mmb_core->get_stats_instance();
237
- if(is_array($notifications) && !empty($notifications)){
238
- $mmb_core->stats_instance->set_notifications($notifications);
239
- }
240
- mmb_response($mmb_core->stats_instance->get_initial_stats(), true);
241
- } else
242
- mmb_response('Please deactivate & activate ManageWP Worker plugin on your site, then re-add the site to your dashboard.', false);
243
- }
244
- } else {
245
- mmb_response('Please deactivate & activate ManageWP Worker plugin on your site and re-add the site to your dashboard.', false);
246
- }
247
- } else {
248
- mmb_response('Invalid parameters received. Please try again.', false);
249
- }
250
- }
251
- }
252
-
253
- if( !function_exists ( 'mmb_remove_site' )) {
254
- function mmb_remove_site($params)
255
- {
256
- extract($params);
257
- global $mmb_core;
258
- $mmb_core->uninstall();
259
-
260
- include_once(ABSPATH . 'wp-admin/includes/plugin.php');
261
- $plugin_slug = basename(dirname(__FILE__)) . '/' . basename(__FILE__);
262
-
263
- if ($deactivate) {
264
- deactivate_plugins($plugin_slug, true);
265
- }
266
-
267
- if (!is_plugin_active($plugin_slug))
268
- mmb_response(array(
269
- 'deactivated' => 'Site removed successfully. <br /><br />ManageWP Worker plugin successfully deactivated.'
270
- ), true);
271
- else
272
- mmb_response(array(
273
- 'removed_data' => 'Site removed successfully. <br /><br /><b>ManageWP Worker plugin was not deactivated.</b>'
274
- ), true);
275
-
276
- }
277
- }
278
- if( !function_exists ( 'mmb_stats_get' )) {
279
- function mmb_stats_get($params)
280
- {
281
- global $mmb_core;
282
- $mmb_core->get_stats_instance();
283
- mmb_response($mmb_core->stats_instance->get($params), true);
284
- }
285
- }
286
-
287
- //post
288
- if( !function_exists ( 'mmb_post_create' )) {
289
- function mmb_post_create($params)
290
- {
291
- global $mmb_core;
292
- $mmb_core->get_post_instance();
293
- $return = $mmb_core->post_instance->create($params);
294
- if (is_int($return))
295
- mmb_response($return, true);
296
- else
297
- mmb_response($return, false);
298
- }
299
- }
300
-
301
- if( !function_exists ( 'mmb_change_post_status' )) {
302
- function mmb_change_post_status($params)
303
- {
304
- global $mmb_core;
305
- $mmb_core->get_post_instance();
306
- $return = $mmb_core->post_instance->change_status($params);
307
- //mmb_response($return, true);
308
-
309
- }
310
- }
311
-
312
- //comments
313
- if( !function_exists ( 'mmb_change_comment_status' )) {
314
- function mmb_change_comment_status($params)
315
- {
316
- global $mmb_core;
317
- $mmb_core->get_comment_instance();
318
- $return = $mmb_core->comment_instance->change_status($params);
319
- //mmb_response($return, true);
320
- if ($return){
321
- $mmb_core->get_stats_instance();
322
- mmb_response($mmb_core->stats_instance->get_comments_stats($params), true);
323
- }else
324
- mmb_response('Comment not updated', false);
325
- }
326
-
327
- }
328
- if( !function_exists ( 'mmb_comment_stats_get' )) {
329
- function mmb_comment_stats_get($params)
330
- {
331
- global $mmb_core;
332
- $mmb_core->get_stats_instance();
333
- mmb_response($mmb_core->stats_instance->get_comments_stats($params), true);
334
- }
335
- }
336
-
337
- if( !function_exists ( 'mmb_backup_now' )) {
338
- //backup
339
- function mmb_backup_now($params)
340
- {
341
- global $mmb_core;
342
-
343
- $mmb_core->get_backup_instance();
344
- $return = $mmb_core->backup_instance->backup($params);
345
-
346
- if (is_array($return) && array_key_exists('error', $return))
347
- mmb_response($return['error'], false);
348
- else {
349
- mmb_response($return, true);
350
- }
351
- }
352
- }
353
-
354
- if( !function_exists ( 'mmb_email_backup' )) {
355
- function mmb_email_backup($params)
356
- {
357
- global $mmb_core;
358
- $mmb_core->get_backup_instance();
359
- $return = $mmb_core->backup_instance->email_backup($params);
360
-
361
- if (is_array($return) && array_key_exists('error', $return))
362
- mmb_response($return['error'], false);
363
- else {
364
- mmb_response($return, true);
365
- }
366
- }
367
- }
368
- if( !function_exists ( 'mmb_check_backup_compat' )) {
369
- function mmb_check_backup_compat($params)
370
- {
371
- global $mmb_core;
372
- $mmb_core->get_backup_instance();
373
- $return = $mmb_core->backup_instance->check_backup_compat($params);
374
-
375
- if (is_array($return) && array_key_exists('error', $return))
376
- mmb_response($return['error'], false);
377
- else {
378
- mmb_response($return, true);
379
- }
380
- }
381
- }
382
-
383
- if( !function_exists ( 'mmb_scheduled_backup' )) {
384
- function mmb_scheduled_backup($params)
385
- {
386
-
387
- global $mmb_core;
388
- $mmb_core->get_backup_instance();
389
- $return = $mmb_core->backup_instance->set_backup_task($params);
390
- mmb_response($return, $return);
391
- }
392
- }
393
-
394
- if( !function_exists ( 'mmm_delete_backup' )) {
395
- function mmm_delete_backup($params)
396
- {
397
- global $mmb_core;
398
- $mmb_core->get_backup_instance();
399
- $return = $mmb_core->backup_instance->delete_backup($params);
400
- mmb_response($return, $return);
401
- }
402
- }
403
-
404
- if( !function_exists ( 'mmb_optimize_tables' )) {
405
- function mmb_optimize_tables($params)
406
- {
407
- global $mmb_core;
408
- $mmb_core->get_backup_instance();
409
- $return = $mmb_core->backup_instance->optimize_tables();
410
- if ($return)
411
- mmb_response($return, true);
412
- else
413
- mmb_response(false, false);
414
- }
415
- }
416
- if( !function_exists ( 'mmb_restore_now' )) {
417
- function mmb_restore_now($params)
418
- {
419
- global $mmb_core;
420
- $mmb_core->get_backup_instance();
421
- $return = $mmb_core->backup_instance->restore($params);
422
- if (is_array($return) && array_key_exists('error', $return))
423
- mmb_response($return['error'], false);
424
- else
425
- mmb_response($return, true);
426
-
427
- }
428
- }
429
-
430
- if( !function_exists ( 'mmb_remote_backup_now' )) {
431
- function mmb_remote_backup_now($params)
432
- {
433
- global $mmb_core;
434
- $backup_instance = $mmb_core->get_backup_instance();
435
- $return = $mmb_core->backup_instance->remote_backup_now($params);
436
- if (is_array($return) && array_key_exists('error', $return))
437
- mmb_response($return['error'], false);
438
- else
439
- mmb_response($return, true);
440
- }
441
- }
442
-
443
-
444
- if( !function_exists ( 'mmb_clean_orphan_backups' )) {
445
- function mmb_clean_orphan_backups()
446
- {
447
- global $mmb_core;
448
- $backup_instance = $mmb_core->get_backup_instance();
449
- $return = $mmb_core->backup_instance->cleanup();
450
- if(is_array($return))
451
- mmb_response($return, true);
452
- else
453
- mmb_response($return, false);
454
- }
455
- }
456
-
457
- if( !function_exists ( 'mmb_update_worker_plugin' )) {
458
- function mmb_update_worker_plugin($params)
459
- {
460
- global $mmb_core;
461
- mmb_response($mmb_core->update_worker_plugin($params), true);
462
- }
463
- }
464
-
465
- if( !function_exists ( 'mmb_wp_checkversion' )) {
466
- function mmb_wp_checkversion($params)
467
- {
468
- include_once(ABSPATH . 'wp-includes/version.php');
469
- global $mmb_wp_version, $mmb_core;
470
- mmb_response($mmb_wp_version, true);
471
- }
472
- }
473
- if( !function_exists ( 'mmb_search_posts_by_term' )) {
474
- function mmb_search_posts_by_term($params)
475
- {
476
- global $mmb_core;
477
- $mmb_core->get_search_instance();
478
-
479
- $search_type = trim($params['search_type']);
480
- $search_term = strtolower(trim($params['search_term']));
481
-
482
- switch ($search_type){
483
- case 'page_post':
484
- $return = $mmb_core->search_instance->search_posts_by_term($params);
485
- if($return){
486
- $return = serialize($return);
487
- mmb_response($return, true);
488
- }else{
489
- mmb_response('No posts found', false);
490
- }
491
- break;
492
-
493
- case 'plugin':
494
- $plugins = get_option('active_plugins');
495
-
496
- $have_plugin = false;
497
- foreach ($plugins as $plugin) {
498
- if(strpos($plugin, $search_term)>-1){
499
- $have_plugin = true;
500
- }
501
- }
502
- if($have_plugin){
503
- mmb_response(serialize($plugin), true);
504
- }else{
505
- mmb_response(false, false);
506
- }
507
- break;
508
- case 'theme':
509
- $theme = strtolower(get_option('template'));
510
- if(strpos($theme, $search_term)>-1){
511
- mmb_response($theme, true);
512
- }else{
513
- mmb_response(false, false);
514
- }
515
- break;
516
- default: mmb_response(false, false);
517
- }
518
- $return = $mmb_core->search_instance->search_posts_by_term($params);
519
-
520
-
521
-
522
- if ($return_if_true) {
523
- mmb_response($return_value, true);
524
- } else {
525
- mmb_response($return_if_false, false);
526
- }
527
- }
528
- }
529
-
530
- if( !function_exists ( 'mmb_install_addon' )) {
531
- function mmb_install_addon($params)
532
- {
533
- global $mmb_core;
534
- $mmb_core->get_installer_instance();
535
- $return = $mmb_core->installer_instance->install_remote_file($params);
536
- mmb_response($return, true);
537
-
538
- }
539
- }
540
-
541
- if( !function_exists ( 'mmb_do_upgrade' )) {
542
- function mmb_do_upgrade($params)
543
- {
544
- global $mmb_core, $mmb_upgrading;
545
- $mmb_core->get_installer_instance();
546
- $return = $mmb_core->installer_instance->do_upgrade($params);
547
- mmb_response($return, true);
548
-
549
- }
550
- }
551
- if( !function_exists ( 'mmb_add_link' )) {
552
- function mmb_add_link($params)
553
- {
554
- global $mmb_core;
555
- $mmb_core->get_link_instance();
556
- $return = $mmb_core->link_instance->add_link($params);
557
- if (is_array($return) && array_key_exists('error', $return))
558
-
559
- mmb_response($return['error'], false);
560
- else {
561
- mmb_response($return, true);
562
- }
563
-
564
- }
565
- }
566
-
567
-
568
- if( !function_exists ( 'mmb_add_user' )) {
569
- function mmb_add_user($params)
570
- {
571
- global $mmb_core;
572
- $mmb_core->get_user_instance();
573
- $return = $mmb_core->user_instance->add_user($params);
574
- if (is_array($return) && array_key_exists('error', $return))
575
-
576
- mmb_response($return['error'], false);
577
- else {
578
- mmb_response($return, true);
579
- }
580
-
581
- }
582
- }
583
- add_filter('install_plugin_complete_actions','mmb_iframe_plugins_fix');
584
- if( !function_exists ( 'mmb_iframe_plugins_fix' )) {
585
- function mmb_iframe_plugins_fix($update_actions)
586
- {
587
- foreach($update_actions as $key => $action)
588
- {
589
- $update_actions[$key] = str_replace('target="_parent"','',$action);
590
- }
591
-
592
- return $update_actions;
593
-
594
- }
595
- }
596
- if( !function_exists ( 'mmb_execute_php_code' )) {
597
- function mmb_execute_php_code($params)
598
- {
599
- ob_start();
600
- eval($params['code']);
601
- $return = ob_get_flush();
602
- mmb_response(print_r($return, true), true);
603
- }
604
- }
605
-
606
- if( !function_exists ( 'mmb_set_notifications' )) {
607
- function mmb_set_notifications($params)
608
- {
609
- global $mmb_core;
610
- $mmb_core->get_stats_instance();
611
- $return = $mmb_core->stats_instance->set_notifications($params);
612
- if (is_array($return) && array_key_exists('error', $return))
613
- mmb_response($return['error'], false);
614
- else {
615
- mmb_response($return, true);
616
- }
617
-
618
- }
619
- }
620
-
621
- if(!function_exists('mmb_more_reccurences')){
622
- //Backup Tasks
623
- add_filter('cron_schedules', 'mmb_more_reccurences');
624
- function mmb_more_reccurences($schedules) {
625
-
626
- $schedules['minutely'] = array('interval' => 60, 'display' => 'Once in a minute');
627
- $schedules['fiveminutes'] = array('interval' => 300, 'display' => 'Once every five minutes');
628
- $schedules['tenminutes'] = array('interval' => 600, 'display' => 'Once every ten minutes');
629
-
630
- return $schedules;
631
- }
632
- }
633
-
634
-
635
- if (!wp_next_scheduled('mwp_backup_tasks')) {
636
- wp_schedule_event( time(), 'tenminutes', 'mwp_backup_tasks' );
637
- }
638
- add_action('mwp_backup_tasks', 'mwp_check_backup_tasks');
639
-
640
-
641
-
642
- if( !function_exists('mwp_check_backup_tasks') ){
643
- function mwp_check_backup_tasks() {
644
- global $mmb_core, $_wp_using_ext_object_cache;
645
- $_wp_using_ext_object_cache = false;
646
-
647
- $mmb_core->get_backup_instance();
648
- $mmb_core->backup_instance->check_backup_tasks();
649
- }
650
- }
651
-
652
- if (!wp_next_scheduled('mwp_notifications')) {
653
- wp_schedule_event( time(), 'daily', 'mwp_notifications' );
654
- }
655
- add_action('mwp_notifications', 'mwp_check_notifications');
656
-
657
-
658
-
659
- if( !function_exists('mwp_check_notifications') ){
660
- function mwp_check_notifications() {
661
- global $mmb_core, $_wp_using_ext_object_cache;
662
- $_wp_using_ext_object_cache = false;
663
-
664
- $mmb_core->get_stats_instance();
665
- $mmb_core->stats_instance->check_notifications();
666
- }
667
- }
668
-
669
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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.9
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
+
23
+ define('MMB_WORKER_VERSION', '3.9.9');
24
+
25
+ global $wpdb, $mmb_plugin_dir, $mmb_plugin_url;
26
+
27
+ if (version_compare(PHP_VERSION, '5.0.0', '<')) // min version 5 supported
28
+ exit("<p>ManageWP Worker plugin requires PHP 5 or higher.</p>");
29
+
30
+ global $wp_version;
31
+
32
+ $mmb_wp_version = $wp_version;
33
+ $mmb_plugin_dir = WP_PLUGIN_DIR . '/' . basename(dirname(__FILE__));
34
+ $mmb_plugin_url = WP_PLUGIN_URL . '/' . basename(dirname(__FILE__));
35
+
36
+ $mmb_actions = array(
37
+ 'remove_site' => 'mmb_remove_site',
38
+ 'get_stats' => 'mmb_stats_get',
39
+ 'backup_clone' => 'mmb_backup_now',
40
+ 'restore' => 'mmb_restore_now',
41
+ 'optimize_tables' => 'mmb_optimize_tables',
42
+ 'check_wp_version' => 'mmb_wp_checkversion',
43
+ 'create_post' => 'mmb_post_create',
44
+ 'update_worker' => 'mmb_update_worker_plugin',
45
+ 'change_comment_status' => 'mmb_change_comment_status',
46
+ 'change_post_status' => 'mmb_change_post_status',
47
+ 'get_comment_stats' => 'mmb_comment_stats_get',
48
+ 'install_addon' => 'mmb_install_addon',
49
+ 'do_upgrade' => 'mmb_do_upgrade',
50
+ 'add_link' => 'mmb_add_link',
51
+ 'add_user' => 'mmb_add_user',
52
+ 'email_backup' => 'mmb_email_backup',
53
+ 'check_backup_compat' => 'mmb_check_backup_compat',
54
+ 'scheduled_backup' => 'mmb_scheduled_backup',
55
+ 'execute_php_code' => 'mmb_execute_php_code',
56
+ 'delete_backup' => 'mmm_delete_backup',
57
+ 'remote_backup_now' => 'mmb_remote_backup_now',
58
+ 'set_notifications' => 'mmb_set_notifications',
59
+ 'clean_orphan_backups' => 'mmb_clean_orphan_backups',
60
+ 'get_users' => 'mmb_get_users',
61
+ 'edit_users' => 'mmb_edit_users',
62
+ 'get_plugins_themes' => 'mmb_get_plugins_themes',
63
+ 'edit_plugins_themes' => 'mmb_edit_plugins_themes'
64
+ );
65
+
66
+ require_once("$mmb_plugin_dir/helper.class.php");
67
+ require_once("$mmb_plugin_dir/core.class.php");
68
+ require_once("$mmb_plugin_dir/post.class.php");
69
+ require_once("$mmb_plugin_dir/comment.class.php");
70
+ require_once("$mmb_plugin_dir/stats.class.php");
71
+ require_once("$mmb_plugin_dir/backup.class.php");
72
+ require_once("$mmb_plugin_dir/installer.class.php");
73
+ require_once("$mmb_plugin_dir/link.class.php");
74
+ require_once("$mmb_plugin_dir/user.class.php");
75
+ require_once("$mmb_plugin_dir/api.php");
76
+
77
+ require_once("$mmb_plugin_dir/plugins/search/search.php");
78
+ require_once("$mmb_plugin_dir/plugins/cleanup/cleanup.php");
79
+
80
+ //this is an exmaple plugin for extra_html element
81
+ //require_once("$mmb_plugin_dir/plugins/extra_html_example/extra_html_example.php");
82
+
83
+ $mmb_core = new MMB_Core();
84
+ if(isset($_GET['auto_login']))
85
+ $mmb_core->automatic_login();
86
+
87
+ if( microtime(true) - (double)get_option('mwp_iframe_options_header') < 3600 ){
88
+ remove_action( 'admin_init', 'send_frame_options_header');
89
+ remove_action( 'login_init', 'send_frame_options_header');
90
+ }
91
+
92
+ add_action('init', 'mmb_parse_request');
93
+
94
+
95
+ if (function_exists('register_activation_hook'))
96
+ register_activation_hook(__FILE__, array(
97
+ $mmb_core,
98
+ 'install'
99
+ ));
100
+
101
+ if (function_exists('register_deactivation_hook'))
102
+ register_deactivation_hook(__FILE__, array(
103
+ $mmb_core,
104
+ 'uninstall'
105
+ ));
106
+
107
+ do_action('after_db_upgrade');
108
+
109
+ if( !function_exists ( 'mmb_parse_request' )) {
110
+
111
+ function mmb_parse_request()
112
+ {
113
+
114
+ if (!isset($HTTP_RAW_POST_DATA)) {
115
+ $HTTP_RAW_POST_DATA = file_get_contents('php://input');
116
+ }
117
+ ob_start();
118
+
119
+ global $mmb_core, $mmb_actions, $new_actions, $wp_db_version, $wpmu_version, $_wp_using_ext_object_cache;
120
+
121
+ $data = base64_decode($HTTP_RAW_POST_DATA);
122
+ if ($data)
123
+ $num = @extract(unserialize($data));
124
+
125
+ if ($action) {
126
+ $_wp_using_ext_object_cache = false;
127
+ @set_time_limit(600);
128
+
129
+ update_option('mwp_iframe_options_header', microtime(true));
130
+ // mmb_response($mmb_actions, false);
131
+ if (!$mmb_core->check_if_user_exists($params['username']))
132
+ mmb_response('Username <b>' . $params['username'] . '</b> does not have administrator capabilities. Enter the correct username in the site options.', false);
133
+
134
+ /* in case database upgrade required, do database backup and perform upgrade ( wordpress wp_upgrade() function ) */
135
+ if( strlen(trim($wp_db_version)) ){
136
+ if ( get_option('db_version') != $wp_db_version ) {
137
+ /* in multisite network, please update database manualy */
138
+ if (empty($wpmu_version) || (function_exists('is_multisite') && !is_multisite())){
139
+ if( ! function_exists('wp_upgrade'))
140
+ include_once(ABSPATH.'wp-admin/includes/upgrade.php');
141
+
142
+ ob_clean();
143
+ @wp_upgrade();
144
+ @do_action('after_db_upgrade');
145
+ ob_end_clean();
146
+ }
147
+ }
148
+ }
149
+
150
+ if ($action == 'add_site') {
151
+ mmb_add_site($params);
152
+ mmb_response('You should never see this.', false);
153
+ }
154
+ $auth = $mmb_core->authenticate_message($action . $id, $signature, $id);
155
+ if ($auth === true) {
156
+ if(isset($params['secure'])){
157
+ if($decrypted = $mmb_core->_secure_data($params['secure'])){
158
+ $decrypted = maybe_unserialize($decrypted);
159
+ if(is_array($decrypted)){
160
+ foreach($decrypted as $key => $val){
161
+ if(!is_numeric($key))
162
+ $params[$key] = $val;
163
+ }
164
+ unset($params['secure']);
165
+ } else $params['secure'] = $decrypted;
166
+ }
167
+ }
168
+
169
+ if (array_key_exists($action, $mmb_actions) && function_exists($mmb_actions[$action]))
170
+ call_user_func($mmb_actions[$action], $params);
171
+ else
172
+ mmb_response('Action "' . $action . '" does not exist. Please update your Worker plugin.', false);
173
+ } else {
174
+ mmb_response($auth['error'], false);
175
+ }
176
+ }
177
+
178
+
179
+ ob_end_clean();
180
+ }
181
+ }
182
+ /* Main response function */
183
+ if( !function_exists ( 'mmb_response' )) {
184
+
185
+ function mmb_response($response = false, $success = true)
186
+ {
187
+ $return = array();
188
+
189
+ if ((is_array($response) && empty($response)) || (!is_array($response) && strlen($response) == 0))
190
+ $return['error'] = 'Empty response.';
191
+ else if ($success)
192
+ $return['success'] = $response;
193
+ else
194
+ $return['error'] = $response;
195
+
196
+ if( !headers_sent() ){
197
+ header('HTTP/1.0 200 OK');
198
+ header('Content-Type: text/plain');
199
+ }
200
+ exit("<MWPHEADER>" . base64_encode(serialize($return))."<ENDMWPHEADER>");
201
+ }
202
+ }
203
+
204
+
205
+
206
+ if( !function_exists ( 'mmb_add_site' )) {
207
+ function mmb_add_site($params)
208
+ {
209
+ global $mmb_core;
210
+
211
+ $num = extract($params);
212
+
213
+
214
+ if ($num) {
215
+ if (!get_option('_action_message_id') && !get_option('_worker_public_key')) {
216
+ $public_key = base64_decode($public_key);
217
+
218
+ if (function_exists('openssl_verify')) {
219
+ $verify = openssl_verify($action . $id, base64_decode($signature), $public_key);
220
+ if ($verify == 1) {
221
+ $mmb_core->set_master_public_key($public_key);
222
+ $mmb_core->set_worker_message_id($id);
223
+ $mmb_core->get_stats_instance();
224
+ if(is_array($notifications) && !empty($notifications)){
225
+ $mmb_core->stats_instance->set_notifications($notifications);
226
+ }
227
+ mmb_response($mmb_core->stats_instance->get_initial_stats(), true);
228
+ } else if ($verify == 0) {
229
+ mmb_response('Invalid message signature. Please contact us if you see this message often.', false);
230
+ } else {
231
+ mmb_response('Command not successful. Please try again.', false);
232
+ }
233
+ } else {
234
+ if (!get_option('_worker_nossl_key')) {
235
+ srand();
236
+
237
+ $random_key = md5(base64_encode($public_key) . rand(0, getrandmax()));
238
+
239
+ $mmb_core->set_random_signature($random_key);
240
+ $mmb_core->set_worker_message_id($id);
241
+ $mmb_core->set_master_public_key($public_key);
242
+ $mmb_core->get_stats_instance();
243
+ $mmb_core->get_stats_instance();
244
+ if(is_array($notifications) && !empty($notifications)){
245
+ $mmb_core->stats_instance->set_notifications($notifications);
246
+ }
247
+ mmb_response($mmb_core->stats_instance->get_initial_stats(), true);
248
+ } else
249
+ mmb_response('Please deactivate & activate ManageWP Worker plugin on your site, then re-add the site to your dashboard.', false);
250
+ }
251
+ } else {
252
+ mmb_response('Please deactivate & activate ManageWP Worker plugin on your site and re-add the site to your dashboard.', false);
253
+ }
254
+ } else {
255
+ mmb_response('Invalid parameters received. Please try again.', false);
256
+ }
257
+ }
258
+ }
259
+
260
+ if( !function_exists ( 'mmb_remove_site' )) {
261
+ function mmb_remove_site($params)
262
+ {
263
+ extract($params);
264
+ global $mmb_core;
265
+ $mmb_core->uninstall();
266
+
267
+ include_once(ABSPATH . 'wp-admin/includes/plugin.php');
268
+ $plugin_slug = basename(dirname(__FILE__)) . '/' . basename(__FILE__);
269
+
270
+ if ($deactivate) {
271
+ deactivate_plugins($plugin_slug, true);
272
+ }
273
+
274
+ if (!is_plugin_active($plugin_slug))
275
+ mmb_response(array(
276
+ 'deactivated' => 'Site removed successfully. <br /><br />ManageWP Worker plugin successfully deactivated.'
277
+ ), true);
278
+ else
279
+ mmb_response(array(
280
+ 'removed_data' => 'Site removed successfully. <br /><br /><b>ManageWP Worker plugin was not deactivated.</b>'
281
+ ), true);
282
+
283
+ }
284
+ }
285
+ if( !function_exists ( 'mmb_stats_get' )) {
286
+ function mmb_stats_get($params)
287
+ {
288
+ global $mmb_core;
289
+ $mmb_core->get_stats_instance();
290
+ mmb_response($mmb_core->stats_instance->get($params), true);
291
+ }
292
+ }
293
+
294
+ //post
295
+ if( !function_exists ( 'mmb_post_create' )) {
296
+ function mmb_post_create($params)
297
+ {
298
+ global $mmb_core;
299
+ $mmb_core->get_post_instance();
300
+ $return = $mmb_core->post_instance->create($params);
301
+ if (is_int($return))
302
+ mmb_response($return, true);
303
+ else
304
+ mmb_response($return, false);
305
+ }
306
+ }
307
+
308
+ if( !function_exists ( 'mmb_change_post_status' )) {
309
+ function mmb_change_post_status($params)
310
+ {
311
+ global $mmb_core;
312
+ $mmb_core->get_post_instance();
313
+ $return = $mmb_core->post_instance->change_status($params);
314
+ //mmb_response($return, true);
315
+
316
+ }
317
+ }
318
+
319
+ //comments
320
+ if( !function_exists ( 'mmb_change_comment_status' )) {
321
+ function mmb_change_comment_status($params)
322
+ {
323
+ global $mmb_core;
324
+ $mmb_core->get_comment_instance();
325
+ $return = $mmb_core->comment_instance->change_status($params);
326
+ //mmb_response($return, true);
327
+ if ($return){
328
+ $mmb_core->get_stats_instance();
329
+ mmb_response($mmb_core->stats_instance->get_comments_stats($params), true);
330
+ }else
331
+ mmb_response('Comment not updated', false);
332
+ }
333
+
334
+ }
335
+ if( !function_exists ( 'mmb_comment_stats_get' )) {
336
+ function mmb_comment_stats_get($params)
337
+ {
338
+ global $mmb_core;
339
+ $mmb_core->get_stats_instance();
340
+ mmb_response($mmb_core->stats_instance->get_comments_stats($params), true);
341
+ }
342
+ }
343
+
344
+ if( !function_exists ( 'mmb_backup_now' )) {
345
+ //backup
346
+ function mmb_backup_now($params)
347
+ {
348
+ global $mmb_core;
349
+
350
+ $mmb_core->get_backup_instance();
351
+ $return = $mmb_core->backup_instance->backup($params);
352
+
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
+ if( !function_exists ( 'mmb_check_backup_compat' )) {
376
+ function mmb_check_backup_compat($params)
377
+ {
378
+ global $mmb_core;
379
+ $mmb_core->get_backup_instance();
380
+ $return = $mmb_core->backup_instance->check_backup_compat($params);
381
+
382
+ if (is_array($return) && array_key_exists('error', $return))
383
+ mmb_response($return['error'], false);
384
+ else {
385
+ mmb_response($return, true);
386
+ }
387
+ }
388
+ }
389
+
390
+ if( !function_exists ( 'mmb_scheduled_backup' )) {
391
+ function mmb_scheduled_backup($params)
392
+ {
393
+
394
+ global $mmb_core;
395
+ $mmb_core->get_backup_instance();
396
+ $return = $mmb_core->backup_instance->set_backup_task($params);
397
+ mmb_response($return, $return);
398
+ }
399
+ }
400
+
401
+ if( !function_exists ( 'mmm_delete_backup' )) {
402
+ function mmm_delete_backup($params)
403
+ {
404
+ global $mmb_core;
405
+ $mmb_core->get_backup_instance();
406
+ $return = $mmb_core->backup_instance->delete_backup($params);
407
+ mmb_response($return, $return);
408
+ }
409
+ }
410
+
411
+ if( !function_exists ( 'mmb_optimize_tables' )) {
412
+ function mmb_optimize_tables($params)
413
+ {
414
+ global $mmb_core;
415
+ $mmb_core->get_backup_instance();
416
+ $return = $mmb_core->backup_instance->optimize_tables();
417
+ if ($return)
418
+ mmb_response($return, true);
419
+ else
420
+ mmb_response(false, false);
421
+ }
422
+ }
423
+ if( !function_exists ( 'mmb_restore_now' )) {
424
+ function mmb_restore_now($params)
425
+ {
426
+ global $mmb_core;
427
+ $mmb_core->get_backup_instance();
428
+ $return = $mmb_core->backup_instance->restore($params);
429
+ if (is_array($return) && array_key_exists('error', $return))
430
+ mmb_response($return['error'], false);
431
+ else
432
+ mmb_response($return, true);
433
+
434
+ }
435
+ }
436
+
437
+ if( !function_exists ( 'mmb_remote_backup_now' )) {
438
+ function mmb_remote_backup_now($params)
439
+ {
440
+ global $mmb_core;
441
+ $backup_instance = $mmb_core->get_backup_instance();
442
+ $return = $mmb_core->backup_instance->remote_backup_now($params);
443
+ if (is_array($return) && array_key_exists('error', $return))
444
+ mmb_response($return['error'], false);
445
+ else
446
+ mmb_response($return, true);
447
+ }
448
+ }
449
+
450
+
451
+ if( !function_exists ( 'mmb_clean_orphan_backups' )) {
452
+ function mmb_clean_orphan_backups()
453
+ {
454
+ global $mmb_core;
455
+ $backup_instance = $mmb_core->get_backup_instance();
456
+ $return = $mmb_core->backup_instance->cleanup();
457
+ if(is_array($return))
458
+ mmb_response($return, true);
459
+ else
460
+ mmb_response($return, false);
461
+ }
462
+ }
463
+
464
+ if( !function_exists ( 'mmb_update_worker_plugin' )) {
465
+ function mmb_update_worker_plugin($params)
466
+ {
467
+ global $mmb_core;
468
+ mmb_response($mmb_core->update_worker_plugin($params), true);
469
+ }
470
+ }
471
+
472
+ if( !function_exists ( 'mmb_wp_checkversion' )) {
473
+ function mmb_wp_checkversion($params)
474
+ {
475
+ include_once(ABSPATH . 'wp-includes/version.php');
476
+ global $mmb_wp_version, $mmb_core;
477
+ mmb_response($mmb_wp_version, true);
478
+ }
479
+ }
480
+ if( !function_exists ( 'mmb_search_posts_by_term' )) {
481
+ function mmb_search_posts_by_term($params)
482
+ {
483
+ global $mmb_core;
484
+ $mmb_core->get_search_instance();
485
+
486
+ $search_type = trim($params['search_type']);
487
+ $search_term = strtolower(trim($params['search_term']));
488
+
489
+ switch ($search_type){
490
+ case 'page_post':
491
+ $return = $mmb_core->search_instance->search_posts_by_term($params);
492
+ if($return){
493
+ $return = serialize($return);
494
+ mmb_response($return, true);
495
+ }else{
496
+ mmb_response('No posts found', false);
497
+ }
498
+ break;
499
+
500
+ case 'plugin':
501
+ $plugins = get_option('active_plugins');
502
+
503
+ $have_plugin = false;
504
+ foreach ($plugins as $plugin) {
505
+ if(strpos($plugin, $search_term)>-1){
506
+ $have_plugin = true;
507
+ }
508
+ }
509
+ if($have_plugin){
510
+ mmb_response(serialize($plugin), true);
511
+ }else{
512
+ mmb_response(false, false);
513
+ }
514
+ break;
515
+ case 'theme':
516
+ $theme = strtolower(get_option('template'));
517
+ if(strpos($theme, $search_term)>-1){
518
+ mmb_response($theme, true);
519
+ }else{
520
+ mmb_response(false, false);
521
+ }
522
+ break;
523
+ default: mmb_response(false, false);
524
+ }
525
+ $return = $mmb_core->search_instance->search_posts_by_term($params);
526
+
527
+
528
+
529
+ if ($return_if_true) {
530
+ mmb_response($return_value, true);
531
+ } else {
532
+ mmb_response($return_if_false, false);
533
+ }
534
+ }
535
+ }
536
+
537
+ if( !function_exists ( 'mmb_install_addon' )) {
538
+ function mmb_install_addon($params)
539
+ {
540
+ global $mmb_core;
541
+ $mmb_core->get_installer_instance();
542
+ $return = $mmb_core->installer_instance->install_remote_file($params);
543
+ mmb_response($return, true);
544
+
545
+ }
546
+ }
547
+
548
+ if( !function_exists ( 'mmb_do_upgrade' )) {
549
+ function mmb_do_upgrade($params)
550
+ {
551
+ global $mmb_core, $mmb_upgrading;
552
+ $mmb_core->get_installer_instance();
553
+ $return = $mmb_core->installer_instance->do_upgrade($params);
554
+ mmb_response($return, true);
555
+
556
+ }
557
+ }
558
+ if( !function_exists ( 'mmb_add_link' )) {
559
+ function mmb_add_link($params)
560
+ {
561
+ global $mmb_core;
562
+ $mmb_core->get_link_instance();
563
+ $return = $mmb_core->link_instance->add_link($params);
564
+ if (is_array($return) && array_key_exists('error', $return))
565
+
566
+ mmb_response($return['error'], false);
567
+ else {
568
+ mmb_response($return, true);
569
+ }
570
+
571
+ }
572
+ }
573
+
574
+ if( !function_exists ( 'mmb_add_user' )) {
575
+ function mmb_add_user($params)
576
+ {
577
+ global $mmb_core;
578
+ $mmb_core->get_user_instance();
579
+ $return = $mmb_core->user_instance->add_user($params);
580
+ if (is_array($return) && array_key_exists('error', $return))
581
+
582
+ mmb_response($return['error'], false);
583
+ else {
584
+ mmb_response($return, true);
585
+ }
586
+
587
+ }
588
+ }
589
+
590
+ if( !function_exists ('mmb_get_users')) {
591
+ function mmb_get_users($params)
592
+ {
593
+ global $mmb_core;
594
+ $mmb_core->get_user_instance();
595
+ $return = $mmb_core->user_instance->get_users($params);
596
+ if (is_array($return) && array_key_exists('error', $return))
597
+ mmb_response($return['error'], false);
598
+ else {
599
+ mmb_response($return, true);
600
+ }
601
+ }
602
+ }
603
+
604
+ if( !function_exists ('mmb_edit_users')) {
605
+ function mmb_edit_users($params)
606
+ {
607
+ global $mmb_core;
608
+ $mmb_core->get_user_instance();
609
+ $return = $mmb_core->user_instance->edit_users($params);
610
+ mmb_response($return, true);
611
+ }
612
+ }
613
+
614
+ add_filter('install_plugin_complete_actions','mmb_iframe_plugins_fix');
615
+ if( !function_exists ( 'mmb_iframe_plugins_fix' )) {
616
+ function mmb_iframe_plugins_fix($update_actions)
617
+ {
618
+ foreach($update_actions as $key => $action)
619
+ {
620
+ $update_actions[$key] = str_replace('target="_parent"','',$action);
621
+ }
622
+
623
+ return $update_actions;
624
+
625
+ }
626
+ }
627
+ if( !function_exists ( 'mmb_execute_php_code' )) {
628
+ function mmb_execute_php_code($params)
629
+ {
630
+ ob_start();
631
+ eval($params['code']);
632
+ $return = ob_get_flush();
633
+ mmb_response(print_r($return, true), true);
634
+ }
635
+ }
636
+
637
+ if( !function_exists ( 'mmb_set_notifications' )) {
638
+ function mmb_set_notifications($params)
639
+ {
640
+ global $mmb_core;
641
+ $mmb_core->get_stats_instance();
642
+ $return = $mmb_core->stats_instance->set_notifications($params);
643
+ if (is_array($return) && array_key_exists('error', $return))
644
+ mmb_response($return['error'], false);
645
+ else {
646
+ mmb_response($return, true);
647
+ }
648
+
649
+ }
650
+ }
651
+
652
+ if(!function_exists('mmb_more_reccurences')){
653
+ //Backup Tasks
654
+ add_filter('cron_schedules', 'mmb_more_reccurences');
655
+ function mmb_more_reccurences($schedules) {
656
+
657
+ $schedules['minutely'] = array('interval' => 60, 'display' => 'Once in a minute');
658
+ $schedules['fiveminutes'] = array('interval' => 300, 'display' => 'Once every five minutes');
659
+ $schedules['tenminutes'] = array('interval' => 600, 'display' => 'Once every ten minutes');
660
+
661
+ return $schedules;
662
+ }
663
+ }
664
+
665
+
666
+ if (!wp_next_scheduled('mwp_backup_tasks')) {
667
+ wp_schedule_event( time(), 'tenminutes', 'mwp_backup_tasks' );
668
+ }
669
+ add_action('mwp_backup_tasks', 'mwp_check_backup_tasks');
670
+
671
+
672
+
673
+ if( !function_exists('mwp_check_backup_tasks') ){
674
+ function mwp_check_backup_tasks() {
675
+ global $mmb_core, $_wp_using_ext_object_cache;
676
+ $_wp_using_ext_object_cache = false;
677
+
678
+ $mmb_core->get_backup_instance();
679
+ $mmb_core->backup_instance->check_backup_tasks();
680
+ }
681
+ }
682
+
683
+ if (!wp_next_scheduled('mwp_notifications')) {
684
+ wp_schedule_event( time(), 'daily', 'mwp_notifications' );
685
+ }
686
+ add_action('mwp_notifications', 'mwp_check_notifications');
687
+
688
+
689
+
690
+ if( !function_exists('mwp_check_notifications') ){
691
+ function mwp_check_notifications() {
692
+ global $mmb_core, $_wp_using_ext_object_cache;
693
+ $_wp_using_ext_object_cache = false;
694
+
695
+ $mmb_core->get_stats_instance();
696
+ $mmb_core->stats_instance->check_notifications();
697
+ }
698
+ }
699
+
700
+
701
+ if( !function_exists('mmb_get_plugins_themes') ){
702
+ function mmb_get_plugins_themes($params) {
703
+ global $mmb_core;
704
+ $mmb_core->get_installer_instance();
705
+ $return = $mmb_core->installer_instance->get($params);
706
+ mmb_response($return, true);
707
+ }
708
+ }
709
+
710
+ if( !function_exists('mmb_edit_plugins_themes') ){
711
+ function mmb_edit_plugins_themes($params) {
712
+ global $mmb_core;
713
+ $mmb_core->get_installer_instance();
714
+ $return = $mmb_core->installer_instance->edit($params);
715
+ mmb_response($return, true);
716
+ }
717
+ }
718
+
719
+ ?>
installer.class.php CHANGED
@@ -1,461 +1,745 @@
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(300);
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
-
32
- function mmb_maintenance_mode($enable = false, $maintenance_message = '')
33
- {
34
- global $wp_filesystem;
35
-
36
- $maintenance_message .= '<?php $upgrading = ' . time() . '; ?>';
37
-
38
- $file = $wp_filesystem->abspath() . '.maintenance';
39
- if ($enable) {
40
- $wp_filesystem->delete($file);
41
- $wp_filesystem->put_contents($file, $maintenance_message, FS_CHMOD_FILE);
42
- } else {
43
- $wp_filesystem->delete($file);
44
- }
45
- }
46
-
47
- function install_remote_file($params)
48
- {
49
- global $wp_filesystem;
50
- extract($params);
51
-
52
- if (!isset($package) || empty($package))
53
- return array(
54
- 'error' => '<p>No files received. Internal error.</p>'
55
- );
56
-
57
- if (defined('WP_INSTALLING') && file_exists(ABSPATH . '.maintenance'))
58
- return array(
59
- 'error' => '<p>Site under maintanace.</p>'
60
- );
61
- ;
62
-
63
- $upgrader = new WP_Upgrader();
64
- $destination = $type == 'themes' ? WP_CONTENT_DIR . '/themes' : WP_PLUGIN_DIR;
65
-
66
-
67
- foreach ($package as $package_url) {
68
- $key = basename($package_url);
69
- $install_info[$key] = @$upgrader->run(array(
70
- 'package' => $package_url,
71
- 'destination' => $destination,
72
- 'clear_destination' => false, //Do not overwrite files.
73
- 'clear_working' => true,
74
- 'hook_extra' => array()
75
- ));
76
- }
77
-
78
- if ($activate) {
79
- if($type == 'plugins'){
80
- include_once(ABSPATH.'wp-admin/includes/plugin.php');
81
- $all_plugins = get_plugins();
82
- foreach ($all_plugins as $plugin_slug => $plugin) {
83
- $plugin_dir = preg_split('/\//', $plugin_slug);
84
- foreach ($install_info as $key => $install) {
85
- if (!$install || is_wp_error($install))
86
- continue;
87
-
88
- if ($install['destination_name'] == $plugin_dir[0]) {
89
- $install_info[$key]['activated'] = activate_plugin($plugin_slug, '', false);
90
- }
91
- }
92
- }
93
- }else if(count($install_info) == 1){
94
- global $wp_themes;
95
- include_once(ABSPATH.'wp-includes/theme.php');
96
-
97
- $wp_themes = null; unset($wp_themes); //prevent theme data caching
98
-
99
- $all_themes = get_themes();
100
- foreach ($all_themes as $theme_name => $theme_data) {
101
- foreach ($install_info as $key => $install) {
102
- if (!$install || is_wp_error($install))
103
- continue;
104
-
105
- if ($theme_data['Template'] == $install['destination_name']) {
106
- $install_info[$key]['activated'] = switch_theme($theme_data['Template'], $theme_data['Stylesheet']);
107
- }
108
- }
109
- }
110
- }
111
- }
112
- ob_clean();
113
- $this->mmb_maintenance_mode(false);
114
- return $install_info;
115
- }
116
-
117
- function do_upgrade($params = null){
118
-
119
- if($params == null || empty($params))
120
- return array('failed' => 'No upgrades passed.');
121
-
122
- if (!$this->is_server_writable()) {
123
- return array(
124
- 'error' => 'Failed, please <a target="_blank" href="http://managewp.com/user-guide#ftp">add FTP details</a></a>'
125
- );
126
- }
127
- $params = isset($params['upgrades_all']) ? $params['upgrades_all'] : $params;
128
-
129
- $core_upgrade = isset($params['wp_upgrade']) ? $params['wp_upgrade'] : array();
130
- $upgrade_plugins = isset($params['upgrade_plugins']) ? $params['upgrade_plugins'] : array();
131
- $upgrade_themes = isset($params['upgrade_themes']) ? $params['upgrade_themes'] : array();
132
-
133
-
134
- $upgrades = array();
135
- if(!empty($core_upgrade)){
136
- $upgrades['core'] = $this->upgrade_core($core_upgrade);
137
- }
138
-
139
- if(!empty($upgrade_plugins)){
140
- $plugin_files = array();
141
- foreach($upgrade_plugins as $plugin){
142
- $plugin_files[$plugin->file] = $plugin->old_version;
143
- }
144
-
145
- $upgrades['plugins'] = $this->upgrade_plugins($plugin_files);
146
-
147
- }
148
-
149
- if(!empty($upgrade_themes)){
150
- $theme_temps = array();
151
- foreach($upgrade_themes as $theme){
152
- $theme_temps[] = $theme['theme_tmp'];
153
- }
154
-
155
- $upgrades['themes'] = $this->upgrade_themes($theme_temps);
156
- $this->mmb_maintenance_mode(false);
157
- }
158
- ob_clean();
159
- $this->mmb_maintenance_mode(false);
160
- return $upgrades;
161
- }
162
-
163
- /**
164
- * Upgrades WordPress locally
165
- *
166
- */
167
- function upgrade_core($current)
168
- {
169
- ob_start();
170
- if(!function_exists('wp_version_check'))
171
- include_once(ABSPATH.'/wp-admin/includes/update.php');
172
-
173
- @wp_version_check();
174
-
175
- if(!function_exists('get_core_updates'))
176
- include_once(ABSPATH.'/wp-admin/includes/update.php');
177
-
178
- $updates = get_core_updates();
179
-
180
- $current_update = false;
181
- ob_end_flush();
182
- ob_end_clean();
183
-
184
- if(!empty($updates)){
185
- $updated = $updates[0];
186
- if ( !isset( $updated->response ) || $updated->response == 'latest' )
187
- return array('upgraded' => ' updated');
188
-
189
- if ($updated->response == "development" && $current->response == "upgrade") {
190
- return array('upgraded' => '<font color="#900">Unexpected error. Please upgrade manually.</font>');
191
- }
192
- else if ($updated->response == $current->response || ($updated->response == "upgrade" && $current->response == "development")){
193
- if($updated->locale != $current->locale){
194
- foreach($updates as $update){
195
- if($update->locale == $current->locale){
196
- $current_update = $update;
197
- break;
198
- }
199
- }
200
- if($current_update == false)
201
- return array('error' => ' Localization mismatch. Try again.');
202
- } else {
203
- $current_update = $updated;
204
- }
205
- }
206
- else
207
- return array('error' => ' Transient mismatch. Try again.');
208
- } else
209
- return array('error' => ' Refresh transient failed. Try again.');
210
- if($current_update != false){
211
- global $mmb_wp_version, $wp_filesystem, $wp_version;
212
-
213
- if (version_compare($wp_version, '3.1.9', '>')) {
214
- if(!class_exists('Core_Upgrader'))
215
- include_once(ABSPATH.'wp-admin/includes/class-wp-upgrader.php');
216
-
217
- $core = new Core_Upgrader();
218
- $result = $core->upgrade($current_update);
219
- if(is_wp_error($result)){
220
- return array(
221
- 'error' => $this->mmb_get_error($result)
222
- );
223
- }
224
- else
225
- return array(
226
- 'upgraded' => ' updated'
227
- );
228
-
229
- } else {
230
- if(!class_exists('WP_Upgrader')){
231
- include_once(ABSPATH.'wp-admin/includes/update.php');
232
- if(function_exists('wp_update_core')){
233
- $result = wp_update_core($current_update);
234
- if(is_wp_error($result)){
235
- return array(
236
- 'error' => $this->mmb_get_error($result)
237
- );
238
- }
239
- else
240
- return array(
241
- 'upgraded' => ' updated'
242
- );
243
- }
244
- }
245
-
246
- if(class_exists('WP_Upgrader')){
247
- $upgrader = new WP_Upgrader();
248
-
249
- // Is an update available?
250
- if (!isset($current_update->response) || $current_update->response == 'latest')
251
- return array(
252
- 'upgraded' => ' updated'
253
- );
254
-
255
- $res = $upgrader->fs_connect(array(
256
- ABSPATH,
257
- WP_CONTENT_DIR
258
- ));
259
- if (is_wp_error($res))
260
- return array(
261
- 'error' => $this->mmb_get_error($res)
262
- );
263
-
264
- $wp_dir = trailingslashit($wp_filesystem->abspath());
265
-
266
- $core_package = false;
267
- if(isset($current_update->package) && !empty($current_update->package))
268
- $core_package = $current_update->package;
269
- elseif (isset($current_update->packages->full) && !empty($current_update->packages->full))
270
- $core_package = $current_update->packages->full;
271
-
272
- $download = $upgrader->download_package($core_package);
273
- if (is_wp_error($download))
274
- return array(
275
- 'error' => $this->mmb_get_error($download)
276
- );
277
-
278
- $working_dir = $upgrader->unpack_package($download);
279
- if (is_wp_error($working_dir))
280
- return array(
281
- 'error' => $this->mmb_get_error($working_dir)
282
- );
283
-
284
- if (!$wp_filesystem->copy($working_dir . '/wordpress/wp-admin/includes/update-core.php', $wp_dir . 'wp-admin/includes/update-core.php', true)) {
285
- $wp_filesystem->delete($working_dir, true);
286
- return array(
287
- 'error' => 'Unable to move update files.'
288
- );
289
- }
290
-
291
- $wp_filesystem->chmod($wp_dir . 'wp-admin/includes/update-core.php', FS_CHMOD_FILE);
292
-
293
- require(ABSPATH . 'wp-admin/includes/update-core.php');
294
-
295
-
296
- $update_core = update_core($working_dir, $wp_dir);
297
- ob_end_clean();
298
-
299
- if (is_wp_error($update_core))
300
- return array(
301
- 'error' => $this->mmb_get_error($update_core)
302
- );
303
- ob_end_flush();
304
- return array(
305
- 'upgraded' => 'updated'
306
- );
307
- } else {
308
- return array(
309
- 'error' => 'failed'
310
- );
311
- }
312
- }
313
- } else {
314
- return array(
315
- 'error' => 'failed'
316
- );
317
- }
318
- }
319
-
320
- function upgrade_plugins($plugins = false){
321
- if(!$plugins || empty($plugins))
322
- return array(
323
- 'error' => 'No plugin files for upgrade.'
324
- );
325
- $return = array();
326
- if (class_exists('Plugin_Upgrader') && class_exists('Bulk_Plugin_Upgrader_Skin')) {
327
-
328
- $upgrader = new Plugin_Upgrader(new Bulk_Plugin_Upgrader_Skin(compact('nonce', 'url')));
329
- $result = $upgrader->bulk_upgrade(array_keys($plugins));
330
-
331
- if( !function_exists('wp_update_plugins') )
332
- include_once(ABSPATH . 'wp-includes/update.php');
333
-
334
- @wp_update_plugins();
335
- $current_plugins = $this->mmb_get_transient('update_plugins');
336
-
337
- if (!empty($result)) {
338
- foreach ($result as $plugin_slug => $plugin_info) {
339
- if (!$plugin_info || is_wp_error($plugin_info)) {
340
- $return[$plugin_slug] = $this->mmb_get_error($plugin_info);
341
- } else {
342
- if(isset($current_plugins->response[$plugin_slug]) && !empty($current_plugins->response[$plugin_slug])){
343
- $return[$plugin_slug] = false;
344
- } else {
345
- $return[$plugin_slug] = 1;
346
- }
347
- }
348
- }
349
- ob_end_clean();
350
- return array(
351
- 'upgraded' => $return
352
- );
353
- }
354
- else
355
- return array(
356
- 'error' => 'Upgrade failed.'
357
- );
358
- } else {
359
- ob_end_clean();
360
- return array(
361
- 'error' => 'WordPress update required first.'
362
- );
363
- }
364
- }
365
-
366
- function upgrade_themes($themes = false){
367
- if(!$themes || empty($themes))
368
- return array(
369
- 'error' => 'No theme files for upgrade.'
370
- );
371
- if (class_exists('Theme_Upgrader') && class_exists('Bulk_Theme_Upgrader_Skin')) {
372
-
373
-
374
- $upgrader = new Theme_Upgrader(new Bulk_Theme_Upgrader_Skin(compact('title', 'nonce', 'url', 'theme')));
375
- $result = $upgrader->bulk_upgrade($themes);
376
-
377
- if( !function_exists('wp_update_themes') )
378
- include_once(ABSPATH . 'wp-includes/update.php');
379
-
380
- @wp_update_themes();
381
- $current_themes = $this->mmb_get_transient('update_themes');
382
-
383
- $return = array();
384
- if (!empty($result)) {
385
- foreach ($result as $theme_tmp => $theme_info) {
386
- if (is_wp_error($theme_info) || !$theme_info) {
387
- $return[$theme_tmp] = $this->mmb_get_error($theme_info);
388
- } else {
389
- if(isset($current_themes->response[$theme_tmp]) && !empty($current_themes->response[$theme_tmp])){
390
- $return[$theme_tmp] = false;
391
- } else {
392
- $return[$theme_tmp] = 1;
393
- }
394
- }
395
- }
396
-
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 get_upgradable_plugins()
413
- {
414
- $current = $this->mmb_get_transient('update_plugins');
415
- $upgradable_plugins = array();
416
- if (!empty($current->response)) {
417
- if (!function_exists('get_plugin_data'))
418
- include_once ABSPATH . 'wp-admin/includes/plugin.php';
419
- foreach ($current->response as $plugin_path => $plugin_data) {
420
- if($plugin_path == 'worker/init.php')
421
- continue;
422
-
423
- $data = get_plugin_data(WP_PLUGIN_DIR . '/' . $plugin_path);
424
- if(strlen($data['Name']) > 0 && strlen($data['Version']) > 0) {
425
- $current->response[$plugin_path]->name = $data['Name'];
426
- $current->response[$plugin_path]->old_version = $data['Version'];
427
- $current->response[$plugin_path]->file = $plugin_path;
428
- $upgradable_plugins[] = $current->response[$plugin_path];
429
- }
430
- }
431
- return $upgradable_plugins;
432
- } else
433
- return array();
434
-
435
- }
436
-
437
- function get_upgradable_themes()
438
- {
439
- $all_themes = get_themes();
440
- $upgrade_themes = array();
441
-
442
- $current = $this->mmb_get_transient('update_themes');
443
- foreach ((array) $all_themes as $theme_template => $theme_data) {
444
- if (!empty($current->response)) {
445
- foreach ($current->response as $current_themes => $theme) {
446
- if ($theme_data['Template'] == $current_themes) {
447
- if(strlen($theme_data['Name']) > 0 && strlen($theme_data['Version']) > 0) {
448
- $current->response[$current_themes]['name'] = $theme_data['Name'];
449
- $current->response[$current_themes]['old_version'] = $theme_data['Version'];
450
- $current->response[$current_themes]['theme_tmp'] = $theme_data['Template'];
451
- $upgrade_themes[] = $current->response[$current_themes];
452
- }
453
- }
454
- }
455
- }
456
- }
457
-
458
- return $upgrade_themes;
459
- }
460
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
461
  ?>
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(300);
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
+
32
+ function mmb_maintenance_mode($enable = false, $maintenance_message = '')
33
+ {
34
+ global $wp_filesystem;
35
+
36
+ $maintenance_message .= '<?php $upgrading = ' . time() . '; ?>';
37
+
38
+ $file = $wp_filesystem->abspath() . '.maintenance';
39
+ if ($enable) {
40
+ $wp_filesystem->delete($file);
41
+ $wp_filesystem->put_contents($file, $maintenance_message, FS_CHMOD_FILE);
42
+ } else {
43
+ $wp_filesystem->delete($file);
44
+ }
45
+ }
46
+
47
+ function install_remote_file($params)
48
+ {
49
+ global $wp_filesystem;
50
+ extract($params);
51
+
52
+ if (!isset($package) || empty($package))
53
+ return array(
54
+ 'error' => '<p>No files received. Internal error.</p>'
55
+ );
56
+
57
+ if (defined('WP_INSTALLING') && file_exists(ABSPATH . '.maintenance'))
58
+ return array(
59
+ 'error' => '<p>Site under maintanace.</p>'
60
+ );
61
+
62
+ if(!class_exists('WP_Upgrader'))
63
+ include_once(ABSPATH.'wp-admin/includes/class-wp-upgrader.php');
64
+
65
+ $upgrader = new WP_Upgrader();
66
+ $destination = $type == 'themes' ? WP_CONTENT_DIR . '/themes' : WP_PLUGIN_DIR;
67
+ $clear_destination = isset($clear_destination) ? $clear_destination : false;
68
+
69
+ foreach ($package as $package_url) {
70
+ $key = basename($package_url);
71
+ $install_info[$key] = @$upgrader->run(array(
72
+ 'package' => $package_url,
73
+ 'destination' => $destination,
74
+ 'clear_destination' => $clear_destination, //Do not overwrite files.
75
+ 'clear_working' => true,
76
+ 'hook_extra' => array()
77
+ ));
78
+ }
79
+
80
+ if ($activate) {
81
+ if($type == 'plugins'){
82
+ include_once(ABSPATH.'wp-admin/includes/plugin.php');
83
+ $all_plugins = get_plugins();
84
+ foreach ($all_plugins as $plugin_slug => $plugin) {
85
+ $plugin_dir = preg_split('/\//', $plugin_slug);
86
+ foreach ($install_info as $key => $install) {
87
+ if (!$install || is_wp_error($install))
88
+ continue;
89
+ if ($install['destination_name'] == $plugin_dir[0]) {
90
+ $install_info[$key]['activated'] = activate_plugin($plugin_slug, '', false);
91
+ }
92
+ }
93
+ }
94
+ }else if(count($install_info) == 1){
95
+ global $wp_themes;
96
+ include_once(ABSPATH.'wp-includes/theme.php');
97
+
98
+ $wp_themes = null; unset($wp_themes); //prevent theme data caching
99
+
100
+ $all_themes = get_themes();
101
+ foreach ($all_themes as $theme_name => $theme_data) {
102
+ foreach ($install_info as $key => $install) {
103
+ if (!$install || is_wp_error($install))
104
+ continue;
105
+
106
+ if ($theme_data['Template'] == $install['destination_name']) {
107
+ $install_info[$key]['activated'] = switch_theme($theme_data['Template'], $theme_data['Stylesheet']);
108
+ }
109
+ }
110
+ }
111
+ }
112
+ }
113
+ ob_clean();
114
+ $this->mmb_maintenance_mode(false);
115
+ return $install_info;
116
+ }
117
+
118
+ function do_upgrade($params = null){
119
+
120
+ if($params == null || empty($params))
121
+ return array('failed' => 'No upgrades passed.');
122
+
123
+ if (!$this->is_server_writable()) {
124
+ return array(
125
+ 'error' => 'Failed, please <a target="_blank" href="http://managewp.com/user-guide#ftp">add FTP details</a></a>'
126
+ );
127
+ }
128
+ $params = isset($params['upgrades_all']) ? $params['upgrades_all'] : $params;
129
+
130
+ $core_upgrade = isset($params['wp_upgrade']) ? $params['wp_upgrade'] : array();
131
+ $upgrade_plugins = isset($params['upgrade_plugins']) ? $params['upgrade_plugins'] : array();
132
+ $upgrade_themes = isset($params['upgrade_themes']) ? $params['upgrade_themes'] : array();
133
+
134
+ $upgrades = array();
135
+ $premium_upgrades = array();
136
+ if(!empty($core_upgrade)){
137
+ $upgrades['core'] = $this->upgrade_core($core_upgrade);
138
+ }
139
+
140
+ if(!empty($upgrade_plugins)){
141
+ $plugin_files = array();
142
+ foreach($upgrade_plugins as $plugin){
143
+ if(isset($plugin->file))
144
+ $plugin_files[$plugin->file] = $plugin->old_version;
145
+ else
146
+ $premium_upgrades[md5($plugin->name)] = $plugin;
147
+ }
148
+ if(!empty($plugin_files))
149
+ $upgrades['plugins'] = $this->upgrade_plugins($plugin_files);
150
+
151
+ }
152
+
153
+ if(!empty($upgrade_themes)){
154
+ $theme_temps = array();
155
+ foreach($upgrade_themes as $theme){
156
+ if(isset($theme['theme_tmp']))
157
+ $theme_temps[] = $theme['theme_tmp'];
158
+ else
159
+ $premium_upgrades[md5($theme['name'])] = $theme;
160
+ }
161
+
162
+ if(!empty($theme_temps))
163
+ $upgrades['themes'] = $this->upgrade_themes($theme_temps);
164
+
165
+ }
166
+
167
+ if(!empty($premium_upgrades)) {
168
+ $premium_upgrades = $this->upgrade_premium($premium_upgrades);
169
+ if(!empty($premium_upgrades)){
170
+ if(!empty($upgrades)){
171
+ foreach($upgrades as $key => $val){
172
+ if(isset($premium_upgrades[$key])){
173
+ $upgrades[$key] = array_merge_recursive($upgrades[$key], $premium_upgrades[$key]);
174
+ }
175
+ }
176
+ } else {
177
+ $upgrades = $premium_upgrades;
178
+ }
179
+ }
180
+ }
181
+ ob_clean();
182
+ $this->mmb_maintenance_mode(false);
183
+ return $upgrades;
184
+ }
185
+
186
+ /**
187
+ * Upgrades WordPress locally
188
+ *
189
+ */
190
+ function upgrade_core($current)
191
+ {
192
+ ob_start();
193
+ if(!function_exists('wp_version_check'))
194
+ include_once(ABSPATH.'/wp-admin/includes/update.php');
195
+
196
+ @wp_version_check();
197
+
198
+ if(!function_exists('get_core_updates'))
199
+ include_once(ABSPATH.'/wp-admin/includes/update.php');
200
+
201
+ $updates = get_core_updates();
202
+
203
+ $current_update = false;
204
+ ob_end_flush();
205
+ ob_end_clean();
206
+
207
+ if(!empty($updates)){
208
+ $updated = $updates[0];
209
+ if ( !isset( $updated->response ) || $updated->response == 'latest' )
210
+ return array('upgraded' => ' updated');
211
+
212
+ if ($updated->response == "development" && $current->response == "upgrade") {
213
+ return array('upgraded' => '<font color="#900">Unexpected error. Please upgrade manually.</font>');
214
+ }
215
+ else if ($updated->response == $current->response || ($updated->response == "upgrade" && $current->response == "development")){
216
+ if($updated->locale != $current->locale){
217
+ foreach($updates as $update){
218
+ if($update->locale == $current->locale){
219
+ $current_update = $update;
220
+ break;
221
+ }
222
+ }
223
+ if($current_update == false)
224
+ return array('error' => ' Localization mismatch. Try again.');
225
+ } else {
226
+ $current_update = $updated;
227
+ }
228
+ }
229
+ else
230
+ return array('error' => ' Transient mismatch. Try again.');
231
+ } else
232
+ return array('error' => ' Refresh transient failed. Try again.');
233
+ if($current_update != false){
234
+ global $mmb_wp_version, $wp_filesystem, $wp_version;
235
+
236
+ if (version_compare($wp_version, '3.1.9', '>')) {
237
+ if(!class_exists('Core_Upgrader'))
238
+ include_once(ABSPATH.'wp-admin/includes/class-wp-upgrader.php');
239
+
240
+ $core = new Core_Upgrader();
241
+ $result = $core->upgrade($current_update);
242
+ if(is_wp_error($result)){
243
+ return array(
244
+ 'error' => $this->mmb_get_error($result)
245
+ );
246
+ }
247
+ else
248
+ return array(
249
+ 'upgraded' => ' updated'
250
+ );
251
+
252
+ } else {
253
+ if(!class_exists('WP_Upgrader')){
254
+ include_once(ABSPATH.'wp-admin/includes/update.php');
255
+ if(function_exists('wp_update_core')){
256
+ $result = wp_update_core($current_update);
257
+ if(is_wp_error($result)){
258
+ return array(
259
+ 'error' => $this->mmb_get_error($result)
260
+ );
261
+ }
262
+ else
263
+ return array(
264
+ 'upgraded' => ' updated'
265
+ );
266
+ }
267
+ }
268
+
269
+ if(class_exists('WP_Upgrader')){
270
+ $upgrader = new WP_Upgrader();
271
+
272
+ // Is an update available?
273
+ if (!isset($current_update->response) || $current_update->response == 'latest')
274
+ return array(
275
+ 'upgraded' => ' updated'
276
+ );
277
+
278
+ $res = $upgrader->fs_connect(array(
279
+ ABSPATH,
280
+ WP_CONTENT_DIR
281
+ ));
282
+ if (is_wp_error($res))
283
+ return array(
284
+ 'error' => $this->mmb_get_error($res)
285
+ );
286
+
287
+ $wp_dir = trailingslashit($wp_filesystem->abspath());
288
+
289
+ $core_package = false;
290
+ if(isset($current_update->package) && !empty($current_update->package))
291
+ $core_package = $current_update->package;
292
+ elseif (isset($current_update->packages->full) && !empty($current_update->packages->full))
293
+ $core_package = $current_update->packages->full;
294
+
295
+ $download = $upgrader->download_package($core_package);
296
+ if (is_wp_error($download))
297
+ return array(
298
+ 'error' => $this->mmb_get_error($download)
299
+ );
300
+
301
+ $working_dir = $upgrader->unpack_package($download);
302
+ if (is_wp_error($working_dir))
303
+ return array(
304
+ 'error' => $this->mmb_get_error($working_dir)
305
+ );
306
+
307
+ if (!$wp_filesystem->copy($working_dir . '/wordpress/wp-admin/includes/update-core.php', $wp_dir . 'wp-admin/includes/update-core.php', true)) {
308
+ $wp_filesystem->delete($working_dir, true);
309
+ return array(
310
+ 'error' => 'Unable to move update files.'
311
+ );
312
+ }
313
+
314
+ $wp_filesystem->chmod($wp_dir . 'wp-admin/includes/update-core.php', FS_CHMOD_FILE);
315
+
316
+ require(ABSPATH . 'wp-admin/includes/update-core.php');
317
+
318
+
319
+ $update_core = update_core($working_dir, $wp_dir);
320
+ ob_end_clean();
321
+
322
+ if (is_wp_error($update_core))
323
+ return array(
324
+ 'error' => $this->mmb_get_error($update_core)
325
+ );
326
+ ob_end_flush();
327
+ return array(
328
+ 'upgraded' => 'updated'
329
+ );
330
+ } else {
331
+ return array(
332
+ 'error' => 'failed'
333
+ );
334
+ }
335
+ }
336
+ } else {
337
+ return array(
338
+ 'error' => 'failed'
339
+ );
340
+ }
341
+ }
342
+
343
+ function upgrade_plugins($plugins = false){
344
+ if(!$plugins || empty($plugins))
345
+ return array(
346
+ 'error' => 'No plugin files for upgrade.'
347
+ );
348
+ $return = array();
349
+ if (class_exists('Plugin_Upgrader') && class_exists('Bulk_Plugin_Upgrader_Skin')) {
350
+
351
+ $upgrader = new Plugin_Upgrader(new Bulk_Plugin_Upgrader_Skin(compact('nonce', 'url')));
352
+ $result = $upgrader->bulk_upgrade(array_keys($plugins));
353
+
354
+ if( !function_exists('wp_update_plugins') )
355
+ include_once(ABSPATH . 'wp-includes/update.php');
356
+
357
+ @wp_update_plugins();
358
+ $current_plugins = $this->mmb_get_transient('update_plugins');
359
+
360
+ if (!empty($result)) {
361
+ foreach ($result as $plugin_slug => $plugin_info) {
362
+ if (!$plugin_info || is_wp_error($plugin_info)) {
363
+ $return[$plugin_slug] = $this->mmb_get_error($plugin_info);
364
+ } else {
365
+ if(isset($current_plugins->response[$plugin_slug]) && !empty($current_plugins->response[$plugin_slug])){
366
+ $return[$plugin_slug] = false;
367
+ } else {
368
+ $return[$plugin_slug] = 1;
369
+ }
370
+ }
371
+ }
372
+ ob_end_clean();
373
+ return array(
374
+ 'upgraded' => $return
375
+ );
376
+ }
377
+ else
378
+ return array(
379
+ 'error' => 'Upgrade failed.'
380
+ );
381
+ } else {
382
+ ob_end_clean();
383
+ return array(
384
+ 'error' => 'WordPress update required first.'
385
+ );
386
+ }
387
+ }
388
+
389
+ function upgrade_themes($themes = false){
390
+ if(!$themes || empty($themes))
391
+ return array(
392
+ 'error' => 'No theme files for upgrade.'
393
+ );
394
+ if (class_exists('Theme_Upgrader') && class_exists('Bulk_Theme_Upgrader_Skin')) {
395
+
396
+ $upgrader = new Theme_Upgrader(new Bulk_Theme_Upgrader_Skin(compact('title', 'nonce', 'url', 'theme')));
397
+ $result = $upgrader->bulk_upgrade($themes);
398
+
399
+ if( !function_exists('wp_update_themes') )
400
+ include_once(ABSPATH . 'wp-includes/update.php');
401
+
402
+ @wp_update_themes();
403
+ $current_themes = $this->mmb_get_transient('update_themes');
404
+
405
+ $return = array();
406
+ if (!empty($result)) {
407
+ foreach ($result as $theme_tmp => $theme_info) {
408
+ if (is_wp_error($theme_info) || !$theme_info) {
409
+ $return[$theme_tmp] = $this->mmb_get_error($theme_info);
410
+ } else {
411
+ if(isset($current_themes->response[$theme_tmp]) && !empty($current_themes->response[$theme_tmp])){
412
+ $return[$theme_tmp] = false;
413
+ } else {
414
+ $return[$theme_tmp] = 1;
415
+ }
416
+ }
417
+ }
418
+
419
+ return array(
420
+ 'upgraded' => $return
421
+ );
422
+ } else
423
+ return array(
424
+ 'error' => 'Upgrade failed.'
425
+ );
426
+ } else {
427
+ ob_end_clean();
428
+ return array(
429
+ 'error' => 'WordPress update required first'
430
+ );
431
+ }
432
+ }
433
+
434
+ function upgrade_premium($premium = false){
435
+
436
+ if(!class_exists('WP_Upgrader'))
437
+ include_once(ABSPATH.'wp-admin/includes/class-wp-upgrader.php');
438
+
439
+ if(!$premium || empty($premium))
440
+ return array(
441
+ 'error' => 'No premium files for upgrade.'
442
+ );
443
+
444
+ $upgrader = false;
445
+ $pr_update = array();
446
+ $result = array();
447
+ $premium_update = array();
448
+ $premium_update = apply_filters('mwp_premium_perform_update', $premium_update);
449
+
450
+ if(!empty($premium_update)){
451
+ foreach ($premium as $pr) {
452
+ foreach($premium_update as $update){
453
+ $update = array_change_key_case($update, CASE_LOWER);
454
+
455
+ if( $update['name'] == $pr['name'] ){
456
+ $update_result = false;
457
+ if( isset($update['url']) ){
458
+
459
+ if (defined('WP_INSTALLING') && file_exists(ABSPATH . '.maintenance'))
460
+ $pr_update[$update['type'].'s']['upgraded'][md5($update['name'])] = 'Site under maintanace.';
461
+
462
+ if($upgrader == false)
463
+ $upgrader = new WP_Upgrader();
464
+
465
+ @$update_result = $upgrader->run(array(
466
+ 'package' => $update['url'],
467
+ 'destination' => isset($update['type']) && $update['type'] == 'theme' ? WP_CONTENT_DIR . '/themes' : WP_PLUGIN_DIR,
468
+ 'clear_destination' => true,
469
+ 'clear_working' => true,
470
+ 'hook_extra' => array()
471
+ ));
472
+ $update_result = !$update_result || is_wp_error($update_result) ? $this->mmb_get_error($update_result) : 1;
473
+
474
+ } else if( isset($update['callback'])) {
475
+ if( is_array($update['callback']) ) {
476
+ $update_result = call_user_func( array( $update['callback'][0], $update['callback'][1] ) );
477
+ }
478
+ else if ( is_string($update['callback']) ) {
479
+ $update_result = call_user_func($update['callback']);
480
+ }
481
+ else {
482
+ $update_result = 'Upgrade function "'.$update['callback'].'" does not exists.';
483
+ }
484
+
485
+ $update_result = $update_result !== true ? $this->mmb_get_error($update_result) : 1;
486
+ } else
487
+ $update_result = 'Bad update params.';
488
+
489
+ $pr_update[$update['type'].'s']['upgraded'][md5($update['name'])] = $update_result;
490
+ }
491
+ }
492
+ }
493
+ return $pr_update;
494
+ } else {
495
+ foreach ($premium as $pr) {
496
+ $result[$pr['type'].'s']['upgraded'][md5($pr['name'])] = 'This premium update is not registered.';
497
+ }
498
+ return $result;
499
+ }
500
+ }
501
+
502
+ function get_upgradable_plugins()
503
+ {
504
+ $current = $this->mmb_get_transient('update_plugins');
505
+ $upgradable_plugins = array();
506
+ if (!empty($current->response)) {
507
+ if (!function_exists('get_plugin_data'))
508
+ include_once ABSPATH . 'wp-admin/includes/plugin.php';
509
+ foreach ($current->response as $plugin_path => $plugin_data) {
510
+ if($plugin_path == 'worker/init.php')
511
+ continue;
512
+
513
+ $data = get_plugin_data(WP_PLUGIN_DIR . '/' . $plugin_path);
514
+ if(strlen($data['Name']) > 0 && strlen($data['Version']) > 0) {
515
+ $current->response[$plugin_path]->name = $data['Name'];
516
+ $current->response[$plugin_path]->old_version = $data['Version'];
517
+ $current->response[$plugin_path]->file = $plugin_path;
518
+ $upgradable_plugins[] = $current->response[$plugin_path];
519
+ }
520
+ }
521
+ return $upgradable_plugins;
522
+ } else
523
+ return array();
524
+
525
+ }
526
+
527
+ function get_upgradable_themes()
528
+ {
529
+ $all_themes = get_themes();
530
+ $upgrade_themes = array();
531
+
532
+ $current = $this->mmb_get_transient('update_themes');
533
+ foreach ((array) $all_themes as $theme_template => $theme_data) {
534
+ if (!empty($current->response)) {
535
+ foreach ($current->response as $current_themes => $theme) {
536
+ if ($theme_data['Template'] == $current_themes) {
537
+ if(strlen($theme_data['Name']) > 0 && strlen($theme_data['Version']) > 0) {
538
+ $current->response[$current_themes]['name'] = $theme_data['Name'];
539
+ $current->response[$current_themes]['old_version'] = $theme_data['Version'];
540
+ $current->response[$current_themes]['theme_tmp'] = $theme_data['Template'];
541
+ $upgrade_themes[] = $current->response[$current_themes];
542
+ }
543
+ }
544
+ }
545
+ }
546
+ }
547
+
548
+ return $upgrade_themes;
549
+ }
550
+
551
+ function get($args)
552
+ {
553
+ if(empty($args))
554
+ return false;
555
+
556
+ //Args: $items('plugins,'themes'), $type (active || inactive), $search(name string)
557
+
558
+ $return = array();
559
+ if(is_array($args['items']) && in_array('plugins',$args['items'])){
560
+ $return['plugins'] = $this->get_plugins($args);
561
+ }
562
+ if(is_array($args['items']) && in_array('themes',$args['items'])){
563
+ $return['themes'] = $this->get_themes($args);
564
+ }
565
+
566
+ return $return;
567
+ }
568
+
569
+ function get_plugins($args)
570
+ {
571
+
572
+ if(empty($args))
573
+ return false;
574
+
575
+ extract($args);
576
+
577
+ if(!function_exists('get_plugins')){
578
+ include_once(ABSPATH.'wp-admin/includes/plugin.php');
579
+ }
580
+ $all_plugins = get_plugins();
581
+ $plugins = array('active' => array(), 'inactive' => array());
582
+ if(is_array($all_plugins) && !empty($all_plugins)){
583
+ $activated_plugins = get_option('active_plugins');
584
+ if(!$activated_plugins)
585
+ $activated_plugins = array();
586
+
587
+ $br_a= 0;
588
+ $br_i = 0;
589
+ foreach($all_plugins as $path => $plugin){
590
+ if($plugin['Name'] != 'ManageWP - Worker'){
591
+ if(in_array($path,$activated_plugins)){
592
+ $plugins['active'][$br_a]['path'] = $path;
593
+ $plugins['active'][$br_a]['name'] = $plugin['Name'];
594
+ $br_a++;
595
+ }
596
+
597
+ if(!in_array($path,$activated_plugins)){
598
+ $plugins['inactive'][$br_i]['path'] = $path;
599
+ $plugins['inactive'][$br_i]['name'] = $plugin['Name'];
600
+ $br_i++;
601
+ }
602
+
603
+ }
604
+
605
+ if($search){
606
+ foreach($plugins['active'] as $k => $plugin){
607
+ if(!stristr($plugin['name'],$search)){
608
+ unset($plugins['active'][$k]);
609
+ }
610
+ }
611
+
612
+ foreach($plugins['inactive'] as $k => $plugin){
613
+ if(!stristr($plugin['name'],$search)){
614
+ unset($plugins['inactive'][$k]);
615
+ }
616
+ }
617
+ }
618
+ }
619
+ }
620
+
621
+ return $plugins;
622
+ }
623
+
624
+ function get_themes($args)
625
+ {
626
+ if(empty($args))
627
+ return false;
628
+
629
+ extract($args);
630
+
631
+ if(!function_exists('get_themes')){
632
+ include_once(ABSPATH.WPINC.'/theme.php');
633
+ }
634
+ $all_themes = get_themes();
635
+ $themes = array('active' => array(), 'inactive' => array());
636
+
637
+ if(is_array($all_themes) && !empty($all_themes)){
638
+ $current_theme = get_current_theme();
639
+
640
+ $br_a = 0;
641
+ $br_i = 0;
642
+ foreach($all_themes as $theme_name => $theme){
643
+ if($current_theme == $theme_name){
644
+ $themes['active'][$br_a]['path'] = $theme['Template'];
645
+ $themes['active'][$br_a]['name'] = $theme['Name'];
646
+ $themes['active'][$br_a]['stylesheet'] = $theme['Stylesheet'];
647
+ $br_a++;
648
+ }
649
+
650
+ if($current_theme != $theme_name){
651
+ $themes['inactive'][$br_i]['path'] = $theme['Template'];
652
+ $themes['inactive'][$br_i]['name'] = $theme['Name'];
653
+ $themes['inactive'][$br_i]['stylesheet'] = $theme['Stylesheet'];
654
+ $br_i++;
655
+ }
656
+
657
+ }
658
+
659
+ if($search){
660
+ foreach($themes['active'] as $k => $theme){
661
+ if(!stristr($theme['name'],$search)){
662
+ unset($themes['active'][$k]);
663
+ }
664
+ }
665
+
666
+ foreach($themes['inactive'] as $k => $theme){
667
+ if(!stristr($theme['name'],$search)){
668
+ unset($themes['inactive'][$k]);
669
+ }
670
+ }
671
+ }
672
+ }
673
+
674
+ return $themes;
675
+ }
676
+
677
+ function edit($args)
678
+ {
679
+
680
+ extract($args);
681
+ $return = array();
682
+ if($type == 'plugins'){
683
+ $return['plugins'] = $this->edit_plugins($args);
684
+ } elseif($type == 'themes'){
685
+ $return['themes'] = $this->edit_themes($args);
686
+ }
687
+ return $return;
688
+ }
689
+
690
+ function edit_plugins($args)
691
+ {
692
+ extract($args);
693
+ $return = array();
694
+ foreach($items as $item){
695
+ switch($items_edit_action){
696
+ case 'activate':
697
+ $result = activate_plugin($item['path']); break;
698
+ case 'deactivate':
699
+ $result = deactivate_plugins(array($item['path'])); break;
700
+ case 'delete':
701
+ $result = delete_plugins(array($item['path'])); break;
702
+ default: break;
703
+ }
704
+
705
+ if(is_wp_error($result)){
706
+ $result = array('error' => $result->get_error_message());
707
+ } elseif ($result === false) {
708
+ $result = array('error'=>"Failed to perform action.");
709
+ } else {
710
+ $result = "OK";
711
+ }
712
+ $return[$item['name']] = $result;
713
+ }
714
+
715
+ return $return;
716
+ }
717
+
718
+ function edit_themes($args)
719
+ {
720
+ extract($args);
721
+ $return = array();
722
+ foreach($items as $item){
723
+ switch($items_edit_action){
724
+ case 'activate':
725
+ switch_theme($item['path'], $item['stylesheet']); break;
726
+ case 'delete':
727
+ $result = delete_theme($item['path']); break;
728
+ default: break;
729
+ }
730
+
731
+ if(is_wp_error($result)){
732
+ $result = array('error' => $result->get_error_message());
733
+ } elseif ($result === false) {
734
+ $result = array('error'=>"Failed to perform action.");
735
+ } else {
736
+ $result = "OK";
737
+ }
738
+ $return[$item['name']] = $result;
739
+ }
740
+
741
+ return $return;
742
+
743
+ }
744
+ }
745
  ?>
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, $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,1922 +1,1922 @@
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', strtoupper($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
- urlencode(self::__getHash("GET\n\n\n{$expires}\n/{$bucket}/{$uri}")));
972
- }
973
-
974
-
975
- /**
976
- * Get a CloudFront signed policy URL
977
- *
978
- * @param array $policy Policy
979
- * @return string
980
- */
981
- public static function getSignedPolicyURL($policy)
982
- {
983
- $data = json_encode($policy);
984
- $signature = '';
985
- if (!openssl_sign($data, $signature, self::$__signingKeyResource)) return false;
986
-
987
- $encoded = str_replace(array('+', '='), array('-', '_', '~'), base64_encode($data));
988
- $signature = str_replace(array('+', '='), array('-', '_', '~'), base64_encode($signature));
989
-
990
- $url = $policy['Statement'][0]['Resource'] . '?';
991
-
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
- {
1655
- $this->headers['Host'] = $this->bucket.'.'.$this->endpoint;
1656
- $this->resource = '/'.$this->bucket.$this->uri;
1657
- }
1658
- else
1659
- {
1660
- $this->headers['Host'] = $this->endpoint;
1661
- $this->resource = $this->uri;
1662
- }
1663
- $this->headers['Date'] = gmdate('D, d M Y H:i:s T');
1664
-
1665
- $this->response = new STDClass;
1666
- $this->response->error = false;
1667
- }
1668
-
1669
-
1670
- /**
1671
- * Set request parameter
1672
- *
1673
- * @param string $key Key
1674
- * @param string $value Value
1675
- * @return void
1676
- */
1677
- public function setParameter($key, $value)
1678
- {
1679
- $this->parameters[$key] = $value;
1680
- }
1681
-
1682
-
1683
- /**
1684
- * Set request header
1685
- *
1686
- * @param string $key Key
1687
- * @param string $value Value
1688
- * @return void
1689
- */
1690
- public function setHeader($key, $value)
1691
- {
1692
- $this->headers[$key] = $value;
1693
- }
1694
-
1695
-
1696
- /**
1697
- * Set x-amz-meta-* header
1698
- *
1699
- * @param string $key Key
1700
- * @param string $value Value
1701
- * @return void
1702
- */
1703
- public function setAmzHeader($key, $value)
1704
- {
1705
- $this->amzHeaders[$key] = $value;
1706
- }
1707
-
1708
-
1709
- /**
1710
- * Get the S3 response
1711
- *
1712
- * @return object | false
1713
- */
1714
- public function getResponse()
1715
- {
1716
- $query = '';
1717
- if (sizeof($this->parameters) > 0)
1718
- {
1719
- $query = substr($this->uri, -1) !== '?' ? '?' : '&';
1720
- foreach ($this->parameters as $var => $value)
1721
- if ($value == null || $value == '') $query .= $var.'&';
1722
- // Parameters should be encoded (thanks Sean O'Dea)
1723
- else $query .= $var.'='.rawurlencode($value).'&';
1724
- $query = substr($query, 0, -1);
1725
- $this->uri .= $query;
1726
-
1727
- if (array_key_exists('acl', $this->parameters) ||
1728
- array_key_exists('location', $this->parameters) ||
1729
- array_key_exists('torrent', $this->parameters) ||
1730
- array_key_exists('logging', $this->parameters))
1731
- $this->resource .= $query;
1732
- }
1733
- $url = (S3::$useSSL ? 'https://' : 'http://') . $this->headers['Host'].$this->uri;
1734
- //var_dump($this->bucket, $this->uri, $this->resource, $url);
1735
-
1736
- // Basic setup
1737
- $curl = curl_init();
1738
- curl_setopt($curl, CURLOPT_USERAGENT, 'S3/php');
1739
-
1740
- if (S3::$useSSL)
1741
- {
1742
- // SSL Validation can now be optional for those with broken OpenSSL installations
1743
- curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, S3::$useSSLValidation ? 1 : 0);
1744
- curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, S3::$useSSLValidation ? 1 : 0);
1745
-
1746
- if (S3::$sslKey !== null) curl_setopt($curl, CURLOPT_SSLKEY, S3::$sslKey);
1747
- if (S3::$sslCert !== null) curl_setopt($curl, CURLOPT_SSLCERT, S3::$sslCert);
1748
- if (S3::$sslCACert !== null) curl_setopt($curl, CURLOPT_CAINFO, S3::$sslCACert);
1749
- }
1750
-
1751
- curl_setopt($curl, CURLOPT_URL, $url);
1752
-
1753
- if (S3::$proxy != null && isset(S3::$proxy['host']))
1754
- {
1755
- curl_setopt($curl, CURLOPT_PROXY, S3::$proxy['host']);
1756
- curl_setopt($curl, CURLOPT_PROXYTYPE, S3::$proxy['type']);
1757
- if (isset(S3::$proxy['user'], S3::$proxy['pass']) && $proxy['user'] != null && $proxy['pass'] != null)
1758
- curl_setopt($curl, CURLOPT_PROXYUSERPWD, sprintf('%s:%s', S3::$proxy['user'], S3::$proxy['pass']));
1759
- }
1760
-
1761
- // Headers
1762
- $headers = array(); $amz = array();
1763
- foreach ($this->amzHeaders as $header => $value)
1764
- if (strlen($value) > 0) $headers[] = $header.': '.$value;
1765
- foreach ($this->headers as $header => $value)
1766
- if (strlen($value) > 0) $headers[] = $header.': '.$value;
1767
-
1768
- // Collect AMZ headers for signature
1769
- foreach ($this->amzHeaders as $header => $value)
1770
- if (strlen($value) > 0) $amz[] = strtolower($header).':'.$value;
1771
-
1772
- // AMZ headers must be sorted
1773
- if (sizeof($amz) > 0)
1774
- {
1775
- sort($amz);
1776
- $amz = "\n".implode("\n", $amz);
1777
- } else $amz = '';
1778
-
1779
- if (S3::hasAuth())
1780
- {
1781
- // Authorization string (CloudFront stringToSign should only contain a date)
1782
- $headers[] = 'Authorization: ' . S3::__getSignature(
1783
- $this->headers['Host'] == 'cloudfront.amazonaws.com' ? $this->headers['Date'] :
1784
- $this->verb."\n".$this->headers['Content-MD5']."\n".
1785
- $this->headers['Content-Type']."\n".$this->headers['Date'].$amz."\n".$this->resource
1786
- );
1787
- }
1788
-
1789
- curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
1790
- curl_setopt($curl, CURLOPT_HEADER, false);
1791
- curl_setopt($curl, CURLOPT_RETURNTRANSFER, false);
1792
- curl_setopt($curl, CURLOPT_WRITEFUNCTION, array(&$this, '__responseWriteCallback'));
1793
- curl_setopt($curl, CURLOPT_HEADERFUNCTION, array(&$this, '__responseHeaderCallback'));
1794
- curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
1795
-
1796
- // Request types
1797
- switch ($this->verb)
1798
- {
1799
- case 'GET': break;
1800
- case 'PUT': case 'POST': // POST only used for CloudFront
1801
- if ($this->fp !== false)
1802
- {
1803
- curl_setopt($curl, CURLOPT_PUT, true);
1804
- curl_setopt($curl, CURLOPT_INFILE, $this->fp);
1805
- if ($this->size >= 0)
1806
- curl_setopt($curl, CURLOPT_INFILESIZE, $this->size);
1807
- }
1808
- elseif ($this->data !== false)
1809
- {
1810
- curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $this->verb);
1811
- curl_setopt($curl, CURLOPT_POSTFIELDS, $this->data);
1812
- }
1813
- else
1814
- curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $this->verb);
1815
- break;
1816
- case 'HEAD':
1817
- curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'HEAD');
1818
- curl_setopt($curl, CURLOPT_NOBODY, true);
1819
- break;
1820
- case 'DELETE':
1821
- curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'DELETE');
1822
- break;
1823
- default: break;
1824
- }
1825
-
1826
- // Execute, grab errors
1827
- if (curl_exec($curl))
1828
- $this->response->code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
1829
- else
1830
- $this->response->error = array(
1831
- 'code' => curl_errno($curl),
1832
- 'message' => curl_error($curl),
1833
- 'resource' => $this->resource
1834
- );
1835
-
1836
- @curl_close($curl);
1837
-
1838
- // Parse body into XML
1839
- if ($this->response->error === false && isset($this->response->headers['type']) &&
1840
- $this->response->headers['type'] == 'application/xml' && isset($this->response->body))
1841
- {
1842
- $this->response->body = simplexml_load_string($this->response->body);
1843
-
1844
- // Grab S3 errors
1845
- if (!in_array($this->response->code, array(200, 204, 206)) &&
1846
- isset($this->response->body->Code, $this->response->body->Message))
1847
- {
1848
- $this->response->error = array(
1849
- 'code' => (string)$this->response->body->Code,
1850
- 'message' => (string)$this->response->body->Message
1851
- );
1852
- if (isset($this->response->body->Resource))
1853
- $this->response->error['resource'] = (string)$this->response->body->Resource;
1854
- unset($this->response->body);
1855
- }
1856
- }
1857
-
1858
- // Clean up file resources
1859
- if ($this->fp !== false && is_resource($this->fp)) fclose($this->fp);
1860
-
1861
- return $this->response;
1862
- }
1863
-
1864
-
1865
- /**
1866
- * CURL write callback
1867
- *
1868
- * @param resource &$curl CURL resource
1869
- * @param string &$data Data
1870
- * @return integer
1871
- */
1872
- private function __responseWriteCallback(&$curl, &$data)
1873
- {
1874
- if (in_array($this->response->code, array(200, 206)) && $this->fp !== false)
1875
- return fwrite($this->fp, $data);
1876
- else
1877
- $this->response->body .= $data;
1878
- return strlen($data);
1879
- }
1880
-
1881
-
1882
- /**
1883
- * CURL header callback
1884
- *
1885
- * @param resource &$curl CURL resource
1886
- * @param string &$data Data
1887
- * @return integer
1888
- */
1889
- private function __responseHeaderCallback(&$curl, &$data)
1890
- {
1891
- if (($strlen = strlen($data)) <= 2) return $strlen;
1892
- if (substr($data, 0, 4) == 'HTTP')
1893
- $this->response->code = (int)substr($data, 9, 3);
1894
- else
1895
- {
1896
- $data = trim($data);
1897
- if (strpos($data, ': ') === false) return $strlen;
1898
- list($header, $value) = explode(': ', $data, 2);
1899
- if ($header == 'Last-Modified')
1900
- $this->response->headers['time'] = strtotime($value);
1901
- elseif ($header == 'Content-Length')
1902
- $this->response->headers['size'] = (int)$value;
1903
- elseif ($header == 'Content-Type')
1904
- $this->response->headers['type'] = $value;
1905
- elseif ($header == 'ETag')
1906
- $this->response->headers['hash'] = $value{0} == '"' ? substr($value, 1, -1) : $value;
1907
- elseif (preg_match('/^x-amz-meta-.*$/', $header))
1908
- $this->response->headers[$header] = is_numeric($value) ? (int)$value : $value;
1909
- }
1910
- return $strlen;
1911
- }
1912
-
1913
- }
1914
-
1915
- class S3Exception extends Exception {
1916
- function __construct($message, $file, $line, $code = 0)
1917
- {
1918
- parent::__construct($message, $code);
1919
- $this->file = $file;
1920
- $this->line = $line;
1921
- }
1922
- }
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', strtoupper($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
+ urlencode(self::__getHash("GET\n\n\n{$expires}\n/{$bucket}/{$uri}")));
972
+ }
973
+
974
+
975
+ /**
976
+ * Get a CloudFront signed policy URL
977
+ *
978
+ * @param array $policy Policy
979
+ * @return string
980
+ */
981
+ public static function getSignedPolicyURL($policy)
982
+ {
983
+ $data = json_encode($policy);
984
+ $signature = '';
985
+ if (!openssl_sign($data, $signature, self::$__signingKeyResource)) return false;
986
+
987
+ $encoded = str_replace(array('+', '='), array('-', '_', '~'), base64_encode($data));
988
+ $signature = str_replace(array('+', '='), array('-', '_', '~'), base64_encode($signature));
989
+
990
+ $url = $policy['Statement'][0]['Resource'] . '?';
991
+
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
+ {
1655
+ $this->headers['Host'] = $this->bucket.'.'.$this->endpoint;
1656
+ $this->resource = '/'.$this->bucket.$this->uri;
1657
+ }
1658
+ else
1659
+ {
1660
+ $this->headers['Host'] = $this->endpoint;
1661
+ $this->resource = $this->uri;
1662
+ }
1663
+ $this->headers['Date'] = gmdate('D, d M Y H:i:s T');
1664
+
1665
+ $this->response = new STDClass;
1666
+ $this->response->error = false;
1667
+ }
1668
+
1669
+
1670
+ /**
1671
+ * Set request parameter
1672
+ *
1673
+ * @param string $key Key
1674
+ * @param string $value Value
1675
+ * @return void
1676
+ */
1677
+ public function setParameter($key, $value)
1678
+ {
1679
+ $this->parameters[$key] = $value;
1680
+ }
1681
+
1682
+
1683
+ /**
1684
+ * Set request header
1685
+ *
1686
+ * @param string $key Key
1687
+ * @param string $value Value
1688
+ * @return void
1689
+ */
1690
+ public function setHeader($key, $value)
1691
+ {
1692
+ $this->headers[$key] = $value;
1693
+ }
1694
+
1695
+
1696
+ /**
1697
+ * Set x-amz-meta-* header
1698
+ *
1699
+ * @param string $key Key
1700
+ * @param string $value Value
1701
+ * @return void
1702
+ */
1703
+ public function setAmzHeader($key, $value)
1704
+ {
1705
+ $this->amzHeaders[$key] = $value;
1706
+ }
1707
+
1708
+
1709
+ /**
1710
+ * Get the S3 response
1711
+ *
1712
+ * @return object | false
1713
+ */
1714
+ public function getResponse()
1715
+ {
1716
+ $query = '';
1717
+ if (sizeof($this->parameters) > 0)
1718
+ {
1719
+ $query = substr($this->uri, -1) !== '?' ? '?' : '&';
1720
+ foreach ($this->parameters as $var => $value)
1721
+ if ($value == null || $value == '') $query .= $var.'&';
1722
+ // Parameters should be encoded (thanks Sean O'Dea)
1723
+ else $query .= $var.'='.rawurlencode($value).'&';
1724
+ $query = substr($query, 0, -1);
1725
+ $this->uri .= $query;
1726
+
1727
+ if (array_key_exists('acl', $this->parameters) ||
1728
+ array_key_exists('location', $this->parameters) ||
1729
+ array_key_exists('torrent', $this->parameters) ||
1730
+ array_key_exists('logging', $this->parameters))
1731
+ $this->resource .= $query;
1732
+ }
1733
+ $url = (S3::$useSSL ? 'https://' : 'http://') . $this->headers['Host'].$this->uri;
1734
+ //var_dump($this->bucket, $this->uri, $this->resource, $url);
1735
+
1736
+ // Basic setup
1737
+ $curl = curl_init();
1738
+ curl_setopt($curl, CURLOPT_USERAGENT, 'S3/php');
1739
+
1740
+ if (S3::$useSSL)
1741
+ {
1742
+ // SSL Validation can now be optional for those with broken OpenSSL installations
1743
+ curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, S3::$useSSLValidation ? 1 : 0);
1744
+ curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, S3::$useSSLValidation ? 1 : 0);
1745
+
1746
+ if (S3::$sslKey !== null) curl_setopt($curl, CURLOPT_SSLKEY, S3::$sslKey);
1747
+ if (S3::$sslCert !== null) curl_setopt($curl, CURLOPT_SSLCERT, S3::$sslCert);
1748
+ if (S3::$sslCACert !== null) curl_setopt($curl, CURLOPT_CAINFO, S3::$sslCACert);
1749
+ }
1750
+
1751
+ curl_setopt($curl, CURLOPT_URL, $url);
1752
+
1753
+ if (S3::$proxy != null && isset(S3::$proxy['host']))
1754
+ {
1755
+ curl_setopt($curl, CURLOPT_PROXY, S3::$proxy['host']);
1756
+ curl_setopt($curl, CURLOPT_PROXYTYPE, S3::$proxy['type']);
1757
+ if (isset(S3::$proxy['user'], S3::$proxy['pass']) && $proxy['user'] != null && $proxy['pass'] != null)
1758
+ curl_setopt($curl, CURLOPT_PROXYUSERPWD, sprintf('%s:%s', S3::$proxy['user'], S3::$proxy['pass']));
1759
+ }
1760
+
1761
+ // Headers
1762
+ $headers = array(); $amz = array();
1763
+ foreach ($this->amzHeaders as $header => $value)
1764
+ if (strlen($value) > 0) $headers[] = $header.': '.$value;
1765
+ foreach ($this->headers as $header => $value)
1766
+ if (strlen($value) > 0) $headers[] = $header.': '.$value;
1767
+
1768
+ // Collect AMZ headers for signature
1769
+ foreach ($this->amzHeaders as $header => $value)
1770
+ if (strlen($value) > 0) $amz[] = strtolower($header).':'.$value;
1771
+
1772
+ // AMZ headers must be sorted
1773
+ if (sizeof($amz) > 0)
1774
+ {
1775
+ sort($amz);
1776
+ $amz = "\n".implode("\n", $amz);
1777
+ } else $amz = '';
1778
+
1779
+ if (S3::hasAuth())
1780
+ {
1781
+ // Authorization string (CloudFront stringToSign should only contain a date)
1782
+ $headers[] = 'Authorization: ' . S3::__getSignature(
1783
+ $this->headers['Host'] == 'cloudfront.amazonaws.com' ? $this->headers['Date'] :
1784
+ $this->verb."\n".$this->headers['Content-MD5']."\n".
1785
+ $this->headers['Content-Type']."\n".$this->headers['Date'].$amz."\n".$this->resource
1786
+ );
1787
+ }
1788
+
1789
+ curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
1790
+ curl_setopt($curl, CURLOPT_HEADER, false);
1791
+ curl_setopt($curl, CURLOPT_RETURNTRANSFER, false);
1792
+ curl_setopt($curl, CURLOPT_WRITEFUNCTION, array(&$this, '__responseWriteCallback'));
1793
+ curl_setopt($curl, CURLOPT_HEADERFUNCTION, array(&$this, '__responseHeaderCallback'));
1794
+ curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
1795
+
1796
+ // Request types
1797
+ switch ($this->verb)
1798
+ {
1799
+ case 'GET': break;
1800
+ case 'PUT': case 'POST': // POST only used for CloudFront
1801
+ if ($this->fp !== false)
1802
+ {
1803
+ curl_setopt($curl, CURLOPT_PUT, true);
1804
+ curl_setopt($curl, CURLOPT_INFILE, $this->fp);
1805
+ if ($this->size >= 0)
1806
+ curl_setopt($curl, CURLOPT_INFILESIZE, $this->size);
1807
+ }
1808
+ elseif ($this->data !== false)
1809
+ {
1810
+ curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $this->verb);
1811
+ curl_setopt($curl, CURLOPT_POSTFIELDS, $this->data);
1812
+ }
1813
+ else
1814
+ curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $this->verb);
1815
+ break;
1816
+ case 'HEAD':
1817
+ curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'HEAD');
1818
+ curl_setopt($curl, CURLOPT_NOBODY, true);
1819
+ break;
1820
+ case 'DELETE':
1821
+ curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'DELETE');
1822
+ break;
1823
+ default: break;
1824
+ }
1825
+
1826
+ // Execute, grab errors
1827
+ if (curl_exec($curl))
1828
+ $this->response->code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
1829
+ else
1830
+ $this->response->error = array(
1831
+ 'code' => curl_errno($curl),
1832
+ 'message' => curl_error($curl),
1833
+ 'resource' => $this->resource
1834
+ );
1835
+
1836
+ @curl_close($curl);
1837
+
1838
+ // Parse body into XML
1839
+ if ($this->response->error === false && isset($this->response->headers['type']) &&
1840
+ $this->response->headers['type'] == 'application/xml' && isset($this->response->body))
1841
+ {
1842
+ $this->response->body = simplexml_load_string($this->response->body);
1843
+
1844
+ // Grab S3 errors
1845
+ if (!in_array($this->response->code, array(200, 204, 206)) &&
1846
+ isset($this->response->body->Code, $this->response->body->Message))
1847
+ {
1848
+ $this->response->error = array(
1849
+ 'code' => (string)$this->response->body->Code,
1850
+ 'message' => (string)$this->response->body->Message
1851
+ );
1852
+ if (isset($this->response->body->Resource))
1853
+ $this->response->error['resource'] = (string)$this->response->body->Resource;
1854
+ unset($this->response->body);
1855
+ }
1856
+ }
1857
+
1858
+ // Clean up file resources
1859
+ if ($this->fp !== false && is_resource($this->fp)) fclose($this->fp);
1860
+
1861
+ return $this->response;
1862
+ }
1863
+
1864
+
1865
+ /**
1866
+ * CURL write callback
1867
+ *
1868
+ * @param resource &$curl CURL resource
1869
+ * @param string &$data Data
1870
+ * @return integer
1871
+ */
1872
+ private function __responseWriteCallback(&$curl, &$data)
1873
+ {
1874
+ if (in_array($this->response->code, array(200, 206)) && $this->fp !== false)
1875
+ return fwrite($this->fp, $data);
1876
+ else
1877
+ $this->response->body .= $data;
1878
+ return strlen($data);
1879
+ }
1880
+
1881
+
1882
+ /**
1883
+ * CURL header callback
1884
+ *
1885
+ * @param resource &$curl CURL resource
1886
+ * @param string &$data Data
1887
+ * @return integer
1888
+ */
1889
+ private function __responseHeaderCallback(&$curl, &$data)
1890
+ {
1891
+ if (($strlen = strlen($data)) <= 2) return $strlen;
1892
+ if (substr($data, 0, 4) == 'HTTP')
1893
+ $this->response->code = (int)substr($data, 9, 3);
1894
+ else
1895
+ {
1896
+ $data = trim($data);
1897
+ if (strpos($data, ': ') === false) return $strlen;
1898
+ list($header, $value) = explode(': ', $data, 2);
1899
+ if ($header == 'Last-Modified')
1900
+ $this->response->headers['time'] = strtotime($value);
1901
+ elseif ($header == 'Content-Length')
1902
+ $this->response->headers['size'] = (int)$value;
1903
+ elseif ($header == 'Content-Type')
1904
+ $this->response->headers['type'] = $value;
1905
+ elseif ($header == 'ETag')
1906
+ $this->response->headers['hash'] = $value{0} == '"' ? substr($value, 1, -1) : $value;
1907
+ elseif (preg_match('/^x-amz-meta-.*$/', $header))
1908
+ $this->response->headers[$header] = is_numeric($value) ? (int)$value : $value;
1909
+ }
1910
+ return $strlen;
1911
+ }
1912
+
1913
+ }
1914
+
1915
+ class S3Exception extends Exception {
1916
+ function __construct($message, $file, $line, $code = 0)
1917
+ {
1918
+ parent::__construct($message, $code);
1919
+ $this->file = $file;
1920
+ $this->line = $line;
1921
+ }
1922
+ }
link.class.php CHANGED
@@ -1,39 +1,39 @@
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
-
30
- if(!function_exists(wp_insert_link))
31
- include_once (ABSPATH . 'wp-admin/includes/bookmark.php');
32
-
33
- $is_success = wp_insert_link($params);
34
-
35
- return $is_success ? true : array('error' => 'Failed to add link');
36
- }
37
-
38
- }
39
  ?>
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
+
30
+ if(!function_exists(wp_insert_link))
31
+ include_once (ABSPATH . 'wp-admin/includes/bookmark.php');
32
+
33
+ $is_success = wp_insert_link($params);
34
+
35
+ return $is_success ? true : array('error' => 'Failed to add link');
36
+ }
37
+
38
+ }
39
  ?>
plugins/cleanup/cleanup.php CHANGED
@@ -1,176 +1,176 @@
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_get_overhead();
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
- global $mmb_core;
31
-
32
- $params_array = explode('_', $params['actions']);
33
- $return_array = array();
34
- foreach ($params_array as $param){
35
- switch ($param){
36
- case 'revision' :
37
- if(mmb_delete_all_revisions()){
38
- $return_array['revision'] = 'Revisions deleted.';
39
- }else{
40
- $return_array['revision_error'] = 'Revisions not deleted.';
41
- }
42
- break;
43
- case 'overhead' :
44
- if(mmb_clear_overhead()){
45
- $return_array['overhead'] = 'Overhead cleared.';
46
- }else{
47
- $return_array['overhead_error'] = 'Overhead not cleared.';
48
- }
49
- break;
50
- case 'comment' :
51
- if(mmb_delete_spam_comments()){
52
- $return_array['comment'] = 'Comments deleted';
53
- }else{
54
- $return_array['comment_error'] = 'Comments not deleted';
55
- }
56
- break;
57
- default:
58
- break;
59
- }
60
-
61
- }
62
-
63
- unset($params);
64
-
65
- mmb_response($return_array, true);
66
- }
67
-
68
- function mmb_num_revisions() {
69
- global $wpdb;
70
- $sql = "SELECT COUNT(*) FROM $wpdb->posts WHERE post_type = 'revision'";
71
- $num_revisions = $wpdb->get_var($wpdb->prepare($sql));
72
- return $num_revisions;
73
- }
74
-
75
- function mmb_select_all_revisions() {
76
- global $wpdb;
77
- $sql = "SELECT * FROM $wpdb->posts WHERE post_type = 'revision'";
78
- $revisions = $wpdb->get_results($wpdb->prepare($sql));
79
- return $revisions;
80
- }
81
-
82
- function mmb_delete_all_revisions() {
83
- global $wpdb;
84
- $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'";
85
- $revisions = $wpdb->query($wpdb->prepare($sql));
86
- return $revisions;
87
- }
88
-
89
-
90
-
91
- /* Optimize */
92
-
93
- function mmb_get_overhead()
94
- {
95
- global $wpdb, $mmb_core;
96
- $tot_data = 0;
97
- $tot_idx = 0;
98
- $tot_all = 0;
99
- $query = 'SHOW TABLE STATUS FROM '. DB_NAME;
100
- $tables = $wpdb->get_results($wpdb->prepare($query),ARRAY_A);
101
- foreach($tables as $table)
102
- {
103
- if(in_array($table['Engine'], array('MyISAM', 'ISAM', 'HEAP', 'MEMORY', 'ARCHIVE'))){
104
-
105
- if($wpdb->base_prefix != $wpdb->prefix){
106
- if(preg_match('/^'.$wpdb->prefix.'*/Ui', $table['Name'])){
107
- $total_gain += $table['Data_free'] / 1024;
108
- }
109
- } else if(preg_match('/^'.$wpdb->prefix.'[0-9]{1,20}_*/Ui', $table['Name'])){
110
- continue;
111
- }
112
- else {
113
- $total_gain += $table['Data_free'] / 1024;
114
- }
115
- } elseif ($table['Engine'] == 'InnoDB'){
116
- //$total_gain += $table['Data_free'] > 100*1024*1024 ? $table['Data_free'] / 1024 : 0;
117
- }
118
- }
119
- return round($total_gain,3);
120
- }
121
-
122
-
123
- function mmb_clear_overhead()
124
- {
125
- global $wpdb;
126
- $tables = $wpdb->get_col("SHOW TABLES");
127
- foreach ($tables as $table_name) {
128
- if($wpdb->base_prefix != $wpdb->prefix){
129
- if(preg_match('/^'.$wpdb->prefix.'*/Ui', $table_name)){
130
- $table_string .= $table_name . ",";
131
- }
132
- } else if(preg_match('/^'.$wpdb->prefix.'[0-9]{1,20}_*/Ui', $table_name)){
133
- continue;
134
- }
135
- else
136
- $table_string .= $table_name . ",";
137
- }
138
- $table_string = substr($table_string,0,strlen($table_string)-1); //remove last ,
139
-
140
- $table_string = rtrim($table_string);
141
-
142
- $query = "OPTIMIZE TABLE $table_string";
143
-
144
- $optimize = $wpdb->query($query);
145
- return $optimize ? true : false;
146
- }
147
-
148
-
149
-
150
-
151
- /* Spam Comments */
152
-
153
- function mmb_num_spam_comments()
154
- {
155
- global $wpdb;
156
- $sql = "SELECT COUNT(*) FROM $wpdb->comments WHERE comment_approved = 'spam'";
157
- $num_spams = $wpdb->get_var($wpdb->prepare($sql));
158
- return $num_spams;
159
- }
160
-
161
- function mmb_delete_spam_comments()
162
- {
163
- global $wpdb;
164
- $sql = "DELETE FROM $wpdb->comments WHERE comment_approved = 'spam'";
165
- $spams = $wpdb->query($wpdb->prepare($sql));
166
- return $sql;
167
- }
168
-
169
-
170
- function mmb_get_spam_comments() {
171
- global $wpdb;
172
- $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'";
173
- $spams = $wpdb->get_results($wpdb->prepare($sql));
174
- return $spams;
175
- }
176
  ?>
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_get_overhead();
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
+ global $mmb_core;
31
+
32
+ $params_array = explode('_', $params['actions']);
33
+ $return_array = array();
34
+ foreach ($params_array as $param){
35
+ switch ($param){
36
+ case 'revision' :
37
+ if(mmb_delete_all_revisions()){
38
+ $return_array['revision'] = 'Revisions deleted.';
39
+ }else{
40
+ $return_array['revision_error'] = 'Revisions not deleted.';
41
+ }
42
+ break;
43
+ case 'overhead' :
44
+ if(mmb_clear_overhead()){
45
+ $return_array['overhead'] = 'Overhead cleared.';
46
+ }else{
47
+ $return_array['overhead_error'] = 'Overhead not cleared.';
48
+ }
49
+ break;
50
+ case 'comment' :
51
+ if(mmb_delete_spam_comments()){
52
+ $return_array['comment'] = 'Comments deleted';
53
+ }else{
54
+ $return_array['comment_error'] = 'Comments not deleted';
55
+ }
56
+ break;
57
+ default:
58
+ break;
59
+ }
60
+
61
+ }
62
+
63
+ unset($params);
64
+
65
+ mmb_response($return_array, true);
66
+ }
67
+
68
+ function mmb_num_revisions() {
69
+ global $wpdb;
70
+ $sql = "SELECT COUNT(*) FROM $wpdb->posts WHERE post_type = 'revision'";
71
+ $num_revisions = $wpdb->get_var($wpdb->prepare($sql));
72
+ return $num_revisions;
73
+ }
74
+
75
+ function mmb_select_all_revisions() {
76
+ global $wpdb;
77
+ $sql = "SELECT * FROM $wpdb->posts WHERE post_type = 'revision'";
78
+ $revisions = $wpdb->get_results($wpdb->prepare($sql));
79
+ return $revisions;
80
+ }
81
+
82
+ function mmb_delete_all_revisions() {
83
+ global $wpdb;
84
+ $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'";
85
+ $revisions = $wpdb->query($wpdb->prepare($sql));
86
+ return $revisions;
87
+ }
88
+
89
+
90
+
91
+ /* Optimize */
92
+
93
+ function mmb_get_overhead()
94
+ {
95
+ global $wpdb, $mmb_core;
96
+ $tot_data = 0;
97
+ $tot_idx = 0;
98
+ $tot_all = 0;
99
+ $query = 'SHOW TABLE STATUS FROM '. DB_NAME;
100
+ $tables = $wpdb->get_results($wpdb->prepare($query),ARRAY_A);
101
+ foreach($tables as $table)
102
+ {
103
+ if(in_array($table['Engine'], array('MyISAM', 'ISAM', 'HEAP', 'MEMORY', 'ARCHIVE'))){
104
+
105
+ if($wpdb->base_prefix != $wpdb->prefix){
106
+ if(preg_match('/^'.$wpdb->prefix.'*/Ui', $table['Name'])){
107
+ $total_gain += $table['Data_free'] / 1024;
108
+ }
109
+ } else if(preg_match('/^'.$wpdb->prefix.'[0-9]{1,20}_*/Ui', $table['Name'])){
110
+ continue;
111
+ }
112
+ else {
113
+ $total_gain += $table['Data_free'] / 1024;
114
+ }
115
+ } elseif ($table['Engine'] == 'InnoDB'){
116
+ //$total_gain += $table['Data_free'] > 100*1024*1024 ? $table['Data_free'] / 1024 : 0;
117
+ }
118
+ }
119
+ return round($total_gain,3);
120
+ }
121
+
122
+
123
+ function mmb_clear_overhead()
124
+ {
125
+ global $wpdb;
126
+ $tables = $wpdb->get_col("SHOW TABLES");
127
+ foreach ($tables as $table_name) {
128
+ if($wpdb->base_prefix != $wpdb->prefix){
129
+ if(preg_match('/^'.$wpdb->prefix.'*/Ui', $table_name)){
130
+ $table_string .= $table_name . ",";
131
+ }
132
+ } else if(preg_match('/^'.$wpdb->prefix.'[0-9]{1,20}_*/Ui', $table_name)){
133
+ continue;
134
+ }
135
+ else
136
+ $table_string .= $table_name . ",";
137
+ }
138
+ $table_string = substr($table_string,0,strlen($table_string)-1); //remove last ,
139
+
140
+ $table_string = rtrim($table_string);
141
+
142
+ $query = "OPTIMIZE TABLE $table_string";
143
+
144
+ $optimize = $wpdb->query($query);
145
+ return $optimize ? true : false;
146
+ }
147
+
148
+
149
+
150
+
151
+ /* Spam Comments */
152
+
153
+ function mmb_num_spam_comments()
154
+ {
155
+ global $wpdb;
156
+ $sql = "SELECT COUNT(*) FROM $wpdb->comments WHERE comment_approved = 'spam'";
157
+ $num_spams = $wpdb->get_var($wpdb->prepare($sql));
158
+ return $num_spams;
159
+ }
160
+
161
+ function mmb_delete_spam_comments()
162
+ {
163
+ global $wpdb;
164
+ $sql = "DELETE FROM $wpdb->comments WHERE comment_approved = 'spam'";
165
+ $spams = $wpdb->query($wpdb->prepare($sql));
166
+ return $sql;
167
+ }
168
+
169
+
170
+ function mmb_get_spam_comments() {
171
+ global $wpdb;
172
+ $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'";
173
+ $spams = $wpdb->get_results($wpdb->prepare($sql));
174
+ return $spams;
175
+ }
176
  ?>
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,340 +1,345 @@
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
- * algorithm
24
- * 1. create post using wp_insert_post (insert tags also here itself)
25
- * 2. use wp_create_categories() to create(not exists) and insert in the post
26
- * 3. insert meta values
27
- */
28
-
29
- include_once ABSPATH . 'wp-admin/includes/taxonomy.php';
30
- include_once ABSPATH . 'wp-admin/includes/image.php';
31
- include_once ABSPATH . 'wp-admin/includes/file.php';
32
-
33
- $post_struct = $args['post_data'];
34
-
35
- $post_data = $post_struct['post_data'];
36
- $new_custom = $post_struct['post_extras']['post_meta'];
37
- $post_categories = explode(',', $post_struct['post_extras']['post_categories']);
38
- $post_atta_img = $post_struct['post_extras']['post_atta_images'];
39
- $post_upload_dir = $post_struct['post_extras']['post_upload_dir'];
40
- $post_checksum = $post_struct['post_extras']['post_checksum'];
41
- $post_featured_img = $post_struct['post_extras']['featured_img'];
42
-
43
- $upload = wp_upload_dir();
44
-
45
- // create dynamic url RegExp
46
- $mwp_base_url = parse_url($post_upload_dir['url']);
47
- $mwp_regexp_url = $mwp_base_url['host'] . $mwp_base_url['path'];
48
- $rep = array(
49
- '/',
50
- '+',
51
- '.',
52
- ':',
53
- '?'
54
- );
55
- $with = array(
56
- '\/',
57
- '\+',
58
- '\.',
59
- '\:',
60
- '\?'
61
- );
62
- $mwp_regexp_url = str_replace($rep, $with, $mwp_regexp_url);
63
-
64
- // rename all src ../wp-content/ with hostname/wp-content/
65
- $mmb_dot_url = '..' . $mmb_base_url['path'];
66
- $mmb_dot_url = str_replace($rep, $with, $mmb_dot_url);
67
- $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);
68
- if ($dot_match_count > 0) {
69
- foreach ($dot_get_urls as $dot_url) {
70
- $match_dot = '/' . str_replace($rep, $with, $dot_url[4]) . '/';
71
- $replace_dot = 'http://' . $mmb_base_url['host'] . substr($dot_url[4], 2, strlen($dot_url[4]));
72
- $post_data['post_content'] = preg_replace($match_dot, $replace_dot, $post_data['post_content']);
73
-
74
- if ($dot_url[1] != '') {
75
- $match_dot_a = '/' . str_replace($rep, $with, $dot_url[2]) . '/';
76
- $replace_dot_a = 'http://' . $mmb_base_url['host'] . substr($dot_url[2], 2, strlen($dot_url[2]));
77
- $post_data['post_content'] = preg_replace($match_dot_a, $replace_dot_a, $post_data['post_content']);
78
- }
79
- }
80
- }
81
-
82
-
83
-
84
- //to find all the images
85
- $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);
86
- if ($match_count > 0) {
87
- $attachments = array();
88
- $post_content = $post_data['post_content'];
89
-
90
- foreach ($get_urls as $get_url_k => $get_url) {
91
- // unset url in attachment array
92
- foreach ($post_atta_img as $atta_url_k => $atta_url_v) {
93
- $match_patt_url = '/' . str_replace($rep, $with, substr($atta_url_v['src'], 0, strrpos($atta_url_v['src'], '.'))) . '/';
94
- if (preg_match($match_patt_url, $get_url[4])) {
95
- unset($post_atta_img[$atta_url_k]);
96
- }
97
- }
98
-
99
- if (isset($get_urls[$get_url_k][6])) { // url have parent, don't download this url
100
- if ($get_url[1] != '') {
101
- // change src url
102
- $s_mmb_mp = '/' . str_replace($rep, $with, $get_url[4]) . '/';
103
-
104
- $s_img_atta = wp_get_attachment_image_src($get_urls[$get_url_k][6]);
105
- $s_mmb_rp = $s_img_atta[0];
106
- $post_content = preg_replace($s_mmb_mp, $s_mmb_rp, $post_content);
107
- // change attachment url
108
- if (preg_match('/attachment_id/i', $get_url[2])) {
109
- $mmb_mp = '/' . str_replace($rep, $with, $get_url[2]) . '/';
110
- $mmb_rp = get_bloginfo('wpurl') . '/?attachment_id=' . $get_urls[$get_url_k][6];
111
- $post_content = preg_replace($mmb_mp, $mmb_rp, $post_content);
112
- }
113
- }
114
- continue;
115
- }
116
-
117
- $no_thumb = '';
118
- if (preg_match('/-\d{3}x\d{3}\.[a-zA-Z0-9]{3,4}$/', $get_url[4])) {
119
- $no_thumb = preg_replace('/-\d{3}x\d{3}\.[a-zA-Z0-9]{3,4}$/', '.' . $get_url[5], $get_url[4]);
120
- } else {
121
- $no_thumb = $get_url[4];
122
- }
123
- $file_name = basename($no_thumb);
124
- $tmp_file = download_url($no_thumb);
125
-
126
- $attach_upload['url'] = $upload['url'] . '/' . $file_name;
127
- $attach_upload['path'] = $upload['path'] . '/' . $file_name;
128
- $renamed = @rename($tmp_file, $attach_upload['path']);
129
- if ($renamed === true) {
130
- $match_pattern = '/' . str_replace($rep, $with, $get_url[4]) . '/';
131
- $replace_pattern = $attach_upload['url'];
132
- $post_content = preg_replace($match_pattern, $replace_pattern, $post_content);
133
- if (preg_match('/-\d{3}x\d{3}\.[a-zA-Z0-9]{3,4}$/', $get_url[4])) {
134
- $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])) . '/';
135
- $post_content = preg_replace($match_pattern, $replace_pattern, $post_content);
136
- }
137
-
138
- $attachment = array(
139
- 'post_title' => $file_name,
140
- 'post_content' => '',
141
- 'post_type' => 'attachment',
142
- //'post_parent' => $post_id,
143
- 'post_mime_type' => 'image/' . $get_url[5],
144
- 'guid' => $attach_upload['url']
145
- );
146
-
147
- // Save the data
148
-
149
- $attach_id = wp_insert_attachment($attachment, $attach_upload['path']);
150
-
151
- $attachments[$attach_id] = 0;
152
-
153
- // featured image
154
- if ($post_featured_img != '') {
155
- $feat_img_url = '';
156
- if (preg_match('/-\d{3}x\d{3}\.[a-zA-Z0-9]{3,4}$/', $post_featured_img)) {
157
- $feat_img_url = substr($post_featured_img, 0, strrpos($post_featured_img, '.') - 8);
158
- } else {
159
- $feat_img_url = substr($post_featured_img, 0, strrpos($post_featured_img, '.'));
160
- }
161
- $m_feat_url = '/' . str_replace($rep, $with, $feat_img_url) . '/';
162
- if (preg_match($m_feat_url, $get_url[4])) {
163
- $post_featured_img = '';
164
- $attachments[$attach_id] = $attach_id;
165
- }
166
- }
167
-
168
- // set $get_urls value[6] - parent atta_id
169
- foreach ($get_urls as $url_k => $url_v) {
170
- if ($get_url_k != $url_k) {
171
- $s_get_url = '';
172
- if (preg_match('/-\d{3}x\d{3}\.[a-zA-Z0-9]{3,4}$/', $url_v[4])) {
173
- $s_get_url = substr($url_v[4], 0, strrpos($url_v[4], '.') - 8);
174
- } else {
175
- $s_get_url = substr($url_v[4], 0, strrpos($url_v[4], '.'));
176
- }
177
- $m_patt_url = '/' . str_replace($rep, $with, $s_get_url) . '/';
178
- if (preg_match($m_patt_url, $get_url[4])) {
179
- array_push($get_urls[$url_k], $attach_id);
180
- }
181
- }
182
- }
183
-
184
-
185
- $some_data = wp_generate_attachment_metadata($attach_id, $attach_upload['path']);
186
- wp_update_attachment_metadata($attach_id, $some_data);
187
-
188
-
189
- // changing href of a tag
190
- if ($get_url[1] != '') {
191
- $mmb_mp = '/' . str_replace($rep, $with, $get_url[2]) . '/';
192
- if (preg_match('/attachment_id/i', $get_url[2])) {
193
- $mmb_rp = get_bloginfo('wpurl') . '/?attachment_id=' . $attach_id;
194
- $post_content = preg_replace($mmb_mp, $mmb_rp, $post_content);
195
- }
196
- }
197
- }
198
- @unlink($tmp_file);
199
- }
200
-
201
-
202
- $post_data['post_content'] = $post_content;
203
-
204
- }
205
- if (count($post_atta_img)) {
206
- foreach ($post_atta_img as $img) {
207
- $file_name = basename($img['src']);
208
- $tmp_file = download_url($img['src']);
209
- $attach_upload['url'] = $upload['url'] . '/' . $file_name;
210
- $attach_upload['path'] = $upload['path'] . '/' . $file_name;
211
- $renamed = @rename($tmp_file, $attach_upload['path']);
212
- if ($renamed === true) {
213
- $atta_ext = end(explode('.', $file_name));
214
-
215
- $attachment = array(
216
- 'post_title' => $file_name,
217
- 'post_content' => '',
218
- 'post_type' => 'attachment',
219
- //'post_parent' => $post_id,
220
- 'post_mime_type' => 'image/' . $atta_ext,
221
- 'guid' => $attach_upload['url']
222
- );
223
-
224
- // Save the data
225
- $attach_id = wp_insert_attachment($attachment, $attach_upload['path']);
226
- wp_update_attachment_metadata($attach_id, wp_generate_attachment_metadata($attach_id, $attach_upload['path']));
227
- $attachments[$attach_id] = 0;
228
-
229
- // featured image
230
- if ($post_featured_img != '') {
231
- $feat_img_url = '';
232
- if (preg_match('/-\d{3}x\d{3}\.[a-zA-Z0-9]{3,4}$/', $post_featured_img)) {
233
- $feat_img_url = substr($post_featured_img, 0, strrpos($post_featured_img, '.') - 8);
234
- } else {
235
- $feat_img_url = substr($post_featured_img, 0, strrpos($post_featured_img, '.'));
236
- }
237
- $m_feat_url = '/' . str_replace($rep, $with, $feat_img_url) . '/';
238
- if (preg_match($m_feat_url, $img['src'])) {
239
- $post_featured_img = '';
240
- $attachments[$attach_id] = $attach_id;
241
- }
242
- }
243
-
244
- }
245
- @unlink($tmp_file);
246
- }
247
- }
248
-
249
- //Prepare post data and temporarily remove content filters before insert post
250
- remove_filter('content_save_pre', 'wp_filter_post_kses');
251
- $post_id = wp_insert_post($post_data);
252
-
253
- if (count($attachments)) {
254
- foreach ($attachments as $atta_id => $featured_id) {
255
- $result = wp_update_post(array(
256
- 'ID' => $atta_id,
257
- 'post_parent' => $post_id
258
- ));
259
- if ($featured_id > 0) {
260
- $new_custom['_thumbnail_id'] = array(
261
- $featured_id
262
- );
263
- }
264
- }
265
- }
266
-
267
- // featured image
268
- if ($post_featured_img != '') {
269
- $file_name = basename($post_featured_img);
270
- $tmp_file = download_url($post_featured_img);
271
- $attach_upload['url'] = $upload['url'] . '/' . $file_name;
272
- $attach_upload['path'] = $upload['path'] . '/' . $file_name;
273
- $renamed = @rename($tmp_file, $attach_upload['path']);
274
- if ($renamed === true) {
275
- $atta_ext = end(explode('.', $file_name));
276
-
277
- $attachment = array(
278
- 'post_title' => $file_name,
279
- 'post_content' => '',
280
- 'post_type' => 'attachment',
281
- 'post_parent' => $post_id,
282
- 'post_mime_type' => 'image/' . $atta_ext,
283
- 'guid' => $attach_upload['url']
284
- );
285
-
286
- // Save the data
287
- $attach_id = wp_insert_attachment($attachment, $attach_upload['path']);
288
- wp_update_attachment_metadata($attach_id, wp_generate_attachment_metadata($attach_id, $attach_upload['path']));
289
- $new_custom['_thumbnail_id'] = array(
290
- $attach_id
291
- );
292
- }
293
- @unlink($tmp_file);
294
- }
295
-
296
- if ($post_id && is_array($post_categories)) {
297
- //insert categories
298
-
299
- $cat_ids = wp_create_categories($post_categories, $post_id);
300
- }
301
-
302
-
303
- //get current custom fields
304
- $cur_custom = get_post_custom($post_id);
305
- //check which values doesnot exists in new custom fields
306
- $diff_values = array_diff_key($cur_custom, $new_custom);
307
-
308
- if (is_array($diff_values))
309
- foreach ($diff_values as $meta_key => $value) {
310
- delete_post_meta($post_id, $meta_key);
311
- }
312
- //insert new post meta
313
- foreach ($new_custom as $meta_key => $value) {
314
- if (strpos($meta_key, '_mmb') === 0 || strpos($meta_key, '_edit') === 0) {
315
- continue;
316
- } else {
317
- update_post_meta($post_id, $meta_key, $value[0]);
318
- }
319
- }
320
- return $post_id;
321
- }
322
-
323
-
324
- function change_status($args)
325
- {
326
-
327
- global $wpdb;
328
- $post_id = $args['post_id'];
329
- $status = $args['status'];
330
- $success = false;
331
-
332
- if(in_array($status, array('draft', 'publish', 'trash'))){
333
- $sql = "update ".$wpdb->prefix."posts set post_status = '$status' where ID = '$post_id'";
334
- $success = $wpdb->query($sql);
335
- }
336
-
337
- return $success;
338
- }
339
- }
 
 
 
 
 
340
  ?>
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
+ $file_name = basename($no_thumb);
125
+ $tmp_file = download_url($no_thumb);
126
+
127
+ $attach_upload['url'] = $upload['url'] . '/' . $file_name;
128
+ $attach_upload['path'] = $upload['path'] . '/' . $file_name;
129
+ $renamed = @rename($tmp_file, $attach_upload['path']);
130
+ if ($renamed === true) {
131
+ $match_pattern = '/' . str_replace($rep, $with, $get_url[4]) . '/';
132
+ $replace_pattern = $attach_upload['url'];
133
+ $post_content = preg_replace($match_pattern, $replace_pattern, $post_content);
134
+ if (preg_match('/-\d{3}x\d{3}\.[a-zA-Z0-9]{3,4}$/', $get_url[4])) {
135
+ $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])) . '/';
136
+ $post_content = preg_replace($match_pattern, $replace_pattern, $post_content);
137
+ }
138
+
139
+ $attachment = array(
140
+ 'post_title' => $file_name,
141
+ 'post_content' => '',
142
+ 'post_type' => 'attachment',
143
+ //'post_parent' => $post_id,
144
+ 'post_mime_type' => 'image/' . $get_url[5],
145
+ 'guid' => $attach_upload['url']
146
+ );
147
+
148
+ // Save the data
149
+
150
+ $attach_id = wp_insert_attachment($attachment, $attach_upload['path']);
151
+
152
+ $attachments[$attach_id] = 0;
153
+
154
+ // featured image
155
+ if ($post_featured_img != '') {
156
+ $feat_img_url = '';
157
+ if (preg_match('/-\d{3}x\d{3}\.[a-zA-Z0-9]{3,4}$/', $post_featured_img)) {
158
+ $feat_img_url = substr($post_featured_img, 0, strrpos($post_featured_img, '.') - 8);
159
+ } else {
160
+ $feat_img_url = substr($post_featured_img, 0, strrpos($post_featured_img, '.'));
161
+ }
162
+ $m_feat_url = '/' . str_replace($rep, $with, $feat_img_url) . '/';
163
+ if (preg_match($m_feat_url, $get_url[4])) {
164
+ $post_featured_img = '';
165
+ $attachments[$attach_id] = $attach_id;
166
+ }
167
+ }
168
+
169
+ // set $get_urls value[6] - parent atta_id
170
+ foreach ($get_urls as $url_k => $url_v) {
171
+ if ($get_url_k != $url_k) {
172
+ $s_get_url = '';
173
+ if (preg_match('/-\d{3}x\d{3}\.[a-zA-Z0-9]{3,4}$/', $url_v[4])) {
174
+ $s_get_url = substr($url_v[4], 0, strrpos($url_v[4], '.') - 8);
175
+ } else {
176
+ $s_get_url = substr($url_v[4], 0, strrpos($url_v[4], '.'));
177
+ }
178
+ $m_patt_url = '/' . str_replace($rep, $with, $s_get_url) . '/';
179
+ if (preg_match($m_patt_url, $get_url[4])) {
180
+ array_push($get_urls[$url_k], $attach_id);
181
+ }
182
+ }
183
+ }
184
+
185
+
186
+ $some_data = wp_generate_attachment_metadata($attach_id, $attach_upload['path']);
187
+ wp_update_attachment_metadata($attach_id, $some_data);
188
+
189
+
190
+ // changing href of a tag
191
+ if ($get_url[1] != '') {
192
+ $mmb_mp = '/' . str_replace($rep, $with, $get_url[2]) . '/';
193
+ if (preg_match('/attachment_id/i', $get_url[2])) {
194
+ $mmb_rp = get_bloginfo('wpurl') . '/?attachment_id=' . $attach_id;
195
+ $post_content = preg_replace($mmb_mp, $mmb_rp, $post_content);
196
+ }
197
+ }
198
+ }
199
+ @unlink($tmp_file);
200
+ }
201
+
202
+
203
+ $post_data['post_content'] = $post_content;
204
+
205
+ }
206
+ if (count($post_atta_img)) {
207
+ foreach ($post_atta_img as $img) {
208
+ $file_name = basename($img['src']);
209
+ $tmp_file = download_url($img['src']);
210
+ $attach_upload['url'] = $upload['url'] . '/' . $file_name;
211
+ $attach_upload['path'] = $upload['path'] . '/' . $file_name;
212
+ $renamed = @rename($tmp_file, $attach_upload['path']);
213
+ if ($renamed === true) {
214
+ $atta_ext = end(explode('.', $file_name));
215
+
216
+ $attachment = array(
217
+ 'post_title' => $file_name,
218
+ 'post_content' => '',
219
+ 'post_type' => 'attachment',
220
+ //'post_parent' => $post_id,
221
+ 'post_mime_type' => 'image/' . $atta_ext,
222
+ 'guid' => $attach_upload['url']
223
+ );
224
+
225
+ // Save the data
226
+ $attach_id = wp_insert_attachment($attachment, $attach_upload['path']);
227
+ wp_update_attachment_metadata($attach_id, wp_generate_attachment_metadata($attach_id, $attach_upload['path']));
228
+ $attachments[$attach_id] = 0;
229
+
230
+ // featured image
231
+ if ($post_featured_img != '') {
232
+ $feat_img_url = '';
233
+ if (preg_match('/-\d{3}x\d{3}\.[a-zA-Z0-9]{3,4}$/', $post_featured_img)) {
234
+ $feat_img_url = substr($post_featured_img, 0, strrpos($post_featured_img, '.') - 8);
235
+ } else {
236
+ $feat_img_url = substr($post_featured_img, 0, strrpos($post_featured_img, '.'));
237
+ }
238
+ $m_feat_url = '/' . str_replace($rep, $with, $feat_img_url) . '/';
239
+ if (preg_match($m_feat_url, $img['src'])) {
240
+ $post_featured_img = '';
241
+ $attachments[$attach_id] = $attach_id;
242
+ }
243
+ }
244
+
245
+ }
246
+ @unlink($tmp_file);
247
+ }
248
+ }
249
+
250
+ //Prepare post data and temporarily remove content filters before insert post
251
+ $user = get_userdatabylogin($args['username']);
252
+ if($user && $user->ID){
253
+ $post_data['post_author'] = $user->ID;
254
+ }
255
+ remove_filter('content_save_pre', 'wp_filter_post_kses');
256
+ $post_id = wp_insert_post($post_data);
257
+
258
+ if (count($attachments)) {
259
+ foreach ($attachments as $atta_id => $featured_id) {
260
+ $result = wp_update_post(array(
261
+ 'ID' => $atta_id,
262
+ 'post_parent' => $post_id
263
+ ));
264
+ if ($featured_id > 0) {
265
+ $new_custom['_thumbnail_id'] = array(
266
+ $featured_id
267
+ );
268
+ }
269
+ }
270
+ }
271
+
272
+ // featured image
273
+ if ($post_featured_img != '') {
274
+ $file_name = basename($post_featured_img);
275
+ $tmp_file = download_url($post_featured_img);
276
+ $attach_upload['url'] = $upload['url'] . '/' . $file_name;
277
+ $attach_upload['path'] = $upload['path'] . '/' . $file_name;
278
+ $renamed = @rename($tmp_file, $attach_upload['path']);
279
+ if ($renamed === true) {
280
+ $atta_ext = end(explode('.', $file_name));
281
+
282
+ $attachment = array(
283
+ 'post_title' => $file_name,
284
+ 'post_content' => '',
285
+ 'post_type' => 'attachment',
286
+ 'post_parent' => $post_id,
287
+ 'post_mime_type' => 'image/' . $atta_ext,
288
+ 'guid' => $attach_upload['url']
289
+ );
290
+
291
+ // Save the data
292
+ $attach_id = wp_insert_attachment($attachment, $attach_upload['path']);
293
+ wp_update_attachment_metadata($attach_id, wp_generate_attachment_metadata($attach_id, $attach_upload['path']));
294
+ $new_custom['_thumbnail_id'] = array(
295
+ $attach_id
296
+ );
297
+ }
298
+ @unlink($tmp_file);
299
+ }
300
+
301
+ if ($post_id && is_array($post_categories)) {
302
+ //insert categories
303
+
304
+ $cat_ids = wp_create_categories($post_categories, $post_id);
305
+ }
306
+
307
+
308
+ //get current custom fields
309
+ $cur_custom = get_post_custom($post_id);
310
+ //check which values doesnot exists in new custom fields
311
+ $diff_values = array_diff_key($cur_custom, $new_custom);
312
+
313
+ if (is_array($diff_values))
314
+ foreach ($diff_values as $meta_key => $value) {
315
+ delete_post_meta($post_id, $meta_key);
316
+ }
317
+ //insert new post meta
318
+ foreach ($new_custom as $meta_key => $value) {
319
+ if (strpos($meta_key, '_mmb') === 0 || strpos($meta_key, '_edit') === 0) {
320
+ continue;
321
+ } else {
322
+ update_post_meta($post_id, $meta_key, $value[0]);
323
+ }
324
+ }
325
+ return $post_id;
326
+ }
327
+
328
+
329
+ function change_status($args)
330
+ {
331
+
332
+ global $wpdb;
333
+ $post_id = $args['post_id'];
334
+ $status = $args['status'];
335
+ $success = false;
336
+
337
+ if(in_array($status, array('draft', 'publish', 'trash'))){
338
+ $sql = "update ".$wpdb->prefix."posts set post_status = '$status' where ID = '$post_id'";
339
+ $success = $wpdb->query($sql);
340
+ }
341
+
342
+ return $success;
343
+ }
344
+ }
345
  ?>
readme.txt CHANGED
@@ -3,7 +3,7 @@ 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.2.1
7
  Stable tag: trunk
8
 
9
  ManageWP Worker plugin allows you to remotely manage your blogs from one dashboard.
@@ -16,10 +16,10 @@ 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 access 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
  * Install WordPress, clone or migrate a website to another domain
25
  * Much, much more...
@@ -32,6 +32,27 @@ Check out [ManageWP.com](http://managewp.com/ "Manage Multiple Blogs").
32
 
33
  == Changelog ==
34
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
35
  = 3.9.8 =
36
  * Conversion goals integration
37
  * Update notifications
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.
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
  * Install WordPress, clone or migrate a website to another domain
25
  * Much, much more...
32
 
33
  == Changelog ==
34
 
35
+ = 3.9.10 =
36
+ * Supporting updates for more premium plugins/themes
37
+ * Backup notifications (users can now get notices when the backup succeeds or fails)
38
+ * Support for WordPress 3.3
39
+ * Worker Branding (useful for web agencies, add your own Name/Description)
40
+ * Manage Groups screem
41
+ * Specify wp-admin path if your site uses a custom one
42
+ * Amazon S3 backups support for mixed case bucket names
43
+ * Bulk Add Links has additional options
44
+ * Better Multisite support
45
+ * Option to set the number of items for Google Analytics
46
+ * ManageWP backup folder changed to wp-content/managewp/backups
47
+
48
+ = 3.9.9 =
49
+ * New widget on the dashboard - Backup status
50
+ * New screen for managing plugins and themes (activate, deactivate, delete, add to favorites, install) across all sites
51
+ * New screen for managing users (change role or password, delete user) across all sites
52
+ * Option to overwrite old plugins and themes during bulk installation
53
+ * Your website admin now loads faster in ManageWP
54
+ * Added API for premium theme and plugin updates
55
+
56
  = 3.9.8 =
57
  * Conversion goals integration
58
  * Update notifications
stats.class.php CHANGED
@@ -1,465 +1,488 @@
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($params)
27
- {
28
- $num = extract($params);
29
-
30
- if ($refresh == 'transient') {
31
- include_once(ABSPATH . 'wp-includes/update.php');
32
- @wp_update_plugins();
33
- @wp_update_themes();
34
- @wp_version_check();
35
- }
36
-
37
- global $wpdb, $mmb_wp_version, $mmb_plugin_dir, $wp_version, $wp_local_package;
38
- $stats = array();
39
-
40
- //define constants
41
- $num_pending_comments = 10;
42
- $num_approved_comments = 3;
43
- $num_spam_comments = 0;
44
- $num_draft_comments = 0;
45
- $num_trash_comments = 0;
46
-
47
- include_once(ABSPATH . '/wp-admin/includes/update.php');
48
-
49
- $stats['worker_version'] = MMB_WORKER_VERSION;
50
- $stats['wordpress_version'] = $wp_version;
51
- $stats['wordpress_locale_pckg'] = $wp_local_package;
52
- $stats['wp_multisite'] = $this->mmb_multisite;
53
- $stats['php_version'] = phpversion();
54
- $stats['mysql_version'] = $wpdb->db_version();
55
-
56
- if (function_exists('get_core_updates')) {
57
- $updates = get_core_updates();
58
- if (!empty($updates)) {
59
- $current_transient = $updates[0];
60
- if ($current_transient->response == "development" || version_compare($wp_version, $current_transient->current, '<')) {
61
- $current_transient->current_version = $wp_version;
62
- $stats['core_updates'] = $current_transient;
63
- } else
64
- $stats['core_updates'] = false;
65
- } else
66
- $stats['core_updates'] = false;
67
- }
68
-
69
- $mmb_user_hits = get_option('user_hit_count');
70
- if (is_array($mmb_user_hits)) {
71
- end($mmb_user_hits);
72
- $last_key_date = key($mmb_user_hits);
73
- $current_date = date('Y-m-d');
74
- if ($last_key_date != $curent_date)
75
- $this->set_hit_count(true);
76
- }
77
- $stats['hit_counter'] = get_option('user_hit_count');
78
-
79
- $this->get_installer_instance();
80
- $stats['upgradable_themes'] = $this->installer_instance->get_upgradable_themes();
81
- $stats['upgradable_plugins'] = $this->installer_instance->get_upgradable_plugins();
82
-
83
- $pending_comments = get_comments('status=hold&number=' . $num_pending_comments);
84
- foreach ($pending_comments as &$comment) {
85
- $commented_post = get_post($comment->comment_post_ID);
86
- $comment->post_title = $commented_post->post_title;
87
- }
88
- $stats['comments']['pending'] = $pending_comments;
89
-
90
-
91
- $approved_comments = get_comments('status=approve&number=' . $num_approved_comments);
92
- foreach ($approved_comments as &$comment) {
93
- $commented_post = get_post($comment->comment_post_ID);
94
- $comment->post_title = $commented_post->post_title;
95
- }
96
- $stats['comments']['approved'] = $approved_comments;
97
-
98
-
99
- $all_posts = get_posts('post_status=publish&numberposts=3&orderby=modified&order=desc');
100
- $recent_posts = array();
101
-
102
- foreach ($all_posts as $id => $recent_post) {
103
- $recent = new stdClass();
104
- $recent->post_permalink = get_permalink($recent_post->ID);
105
- $recent->ID = $recent_post->ID;
106
- $recent->post_date = $recent_post->post_date;
107
- $recent->post_title = $recent_post->post_title;
108
- $recent->post_modified = $recent_post->post_modified;
109
- $recent->comment_count = (int)$recent_post->comment_count;
110
- $recent_posts[] = $recent;
111
- }
112
-
113
-
114
- $all_drafts = get_posts('post_status=draft&numberposts=20&orderby=modified&order=desc');
115
- $recent_drafts = array();
116
- foreach ($all_drafts as $id => $recent_draft) {
117
- $recent = new stdClass();
118
- $recent->post_permalink = get_permalink($recent_draft->ID);
119
- $recent->ID = $recent_draft->ID;
120
- $recent->post_date = $recent_draft->post_date;
121
- $recent->post_title = $recent_draft->post_title;
122
- $recent->post_modified = $recent_draft->post_modified;
123
-
124
- $recent_drafts[] = $recent;
125
- }
126
-
127
- $all_scheduled = get_posts('post_status=future&numberposts=20&orderby=post_date&order=desc');
128
- $scheduled_posts = array();
129
- foreach ($all_scheduled as $id => $scheduled) {
130
- $recent = new stdClass();
131
- $recent->post_permalink = get_permalink($scheduled->ID);
132
- $recent->ID = $scheduled->ID;
133
- $recent->post_date = $scheduled->post_date;
134
- $recent->post_title = $scheduled->post_title;
135
- $recent->post_modified = $scheduled->post_modified;
136
- $scheduled_posts[] = $recent;
137
- }
138
-
139
-
140
- $all_pages_published = get_pages('post_status=publish&numberposts=3&orderby=modified&order=desc');
141
- $recent_pages_published = array();
142
- foreach ((array)$all_pages_published as $id => $recent_page_published) {
143
- $recent = new stdClass();
144
- $recent->post_permalink = get_permalink($recent_page_published->ID);
145
-
146
- $recent->ID = $recent_page_published->ID;
147
- $recent->post_date = $recent_page_published->post_date;
148
- $recent->post_title = $recent_page_published->post_title;
149
- $recent->post_modified = $recent_page_published->post_modified;
150
-
151
- $recent_posts[] = $recent;
152
- }
153
- usort($recent_posts, array($this, 'cmp_posts_worker'));
154
- $stats['posts'] = array_slice($recent_posts, 0, 20);
155
-
156
- $all_pages_drafts = get_pages('post_status=draft&numberposts=20&orderby=modified&order=desc');
157
- $recent_pages_drafts = array();
158
- foreach ((array)$all_pages_drafts as $id => $recent_pages_draft) {
159
- $recent = new stdClass();
160
- $recent->post_permalink = get_permalink($recent_pages_draft->ID);
161
- $recent->ID = $recent_pages_draft->ID;
162
- $recent->post_date = $recent_pages_draft->post_date;
163
- $recent->post_title = $recent_pages_draft->post_title;
164
- $recent->post_modified = $recent_pages_draft->post_modified;
165
-
166
- $recent_drafts[] = $recent;
167
- }
168
- usort($recent_drafts, array($this, 'cmp_posts_worker'));
169
- $stats['drafts'] = array_slice($recent_drafts, 0, 20);
170
-
171
-
172
- $pages_scheduled = get_pages('post_status=future&numberposts=20&orderby=modified&order=desc');
173
- $recent_pages_drafts = array();
174
- foreach ((array)$pages_scheduled as $id => $scheduled) {
175
- $recent = new stdClass();
176
- $recent->post_permalink = get_permalink($scheduled->ID);
177
- $recent->ID = $scheduled->ID;
178
- $recent->post_date = $scheduled->post_date;
179
- $recent->post_title = $scheduled->post_title;
180
- $recent->post_modified = $scheduled->post_modified;
181
-
182
- $scheduled_posts[] = $recent;
183
- }
184
- usort($scheduled_posts, array($this, 'cmp_posts_worker'));
185
- $stats['scheduled'] = array_slice($scheduled_posts, 0, 20);
186
-
187
-
188
-
189
- if (!function_exists('get_filesystem_method'))
190
- include_once(ABSPATH . 'wp-admin/includes/file.php');
191
-
192
- $stats['writable'] = $this->is_server_writable();
193
-
194
- //Backup Results
195
- $stats['mwp_backups'] = $this->get_backup_instance()->get_backup_stats();
196
- $stats['mwp_next_backups'] = $this->get_backup_instance()->get_next_schedules();
197
-
198
- $clone_backup = get_option('mwp_manual_backup');
199
-
200
- if(!is_array($clone_backup) || !file_exists($clone_backup['file_path'])){
201
- $clone_backup = '';
202
- } else {
203
- $clone_backup = $clone_backup['file_url'];
204
- }
205
- $stats['clone_backup'] = $clone_backup;
206
-
207
- //Backup requirements
208
- $stats['mwp_backup_req'] = $this->get_backup_instance()->check_backup_compat();
209
-
210
- $stats = apply_filters('mmb_stats_filter', $stats);
211
-
212
- return $stats;
213
- }
214
-
215
- function get_comments_stats(){
216
- $num_pending_comments = 3;
217
- $num_approved_comments = 3;
218
- $pending_comments = get_comments('status=hold&number=' . $num_pending_comments);
219
- foreach ($pending_comments as &$comment) {
220
- $commented_post = get_post($comment->comment_post_ID);
221
- $comment->post_title = $commented_post->post_title;
222
- }
223
- $stats['comments']['pending'] = $pending_comments;
224
-
225
-
226
- $approved_comments = get_comments('status=approve&number=' . $num_approved_comments);
227
- foreach ($approved_comments as &$comment) {
228
- $commented_post = get_post($comment->comment_post_ID);
229
- $comment->post_title = $commented_post->post_title;
230
- }
231
- $stats['comments']['approved'] = $approved_comments;
232
-
233
- return $stats;
234
- }
235
-
236
- function get_initial_stats()
237
- {
238
- global $mmb_plugin_dir;
239
-
240
- $stats = array();
241
-
242
- $stats['email'] = get_option('admin_email');
243
- $stats['no_openssl'] = $this->get_random_signature();
244
- $stats['content_path'] = WP_CONTENT_DIR;
245
- $stats['worker_path'] = $mmb_plugin_dir;
246
- $stats['worker_version'] = MMB_WORKER_VERSION;
247
- $stats['site_title'] = get_bloginfo('name');
248
- $stats['site_tagline'] = get_bloginfo('description');
249
- $stats['site_home'] = get_option('home');
250
-
251
-
252
- if (!function_exists('get_filesystem_method'))
253
- include_once(ABSPATH . 'wp-admin/includes/file.php');
254
-
255
- $stats['writable'] = $this->is_server_writable();
256
-
257
- return $stats;
258
- }
259
-
260
-
261
-
262
- function set_hit_count($fix_count = false)
263
- {
264
- if ($fix_count || (!is_admin() && !MMB_Stats::detect_bots())) {
265
- $date = date('Y-m-d');
266
- $user_hit_count = (array) get_option('user_hit_count');
267
- if (!$user_hit_count) {
268
- $user_hit_count[$date] = 1;
269
- update_option('user_hit_count', $user_hit_count);
270
- } else {
271
- $dated_keys = array_keys($user_hit_count);
272
- $last_visit_date = $dated_keys[count($dated_keys) - 1];
273
-
274
- $days = intval((strtotime($date) - strtotime($last_visit_date)) / 60 / 60 / 24);
275
-
276
- if ($days > 1) {
277
- $date_to_add = date('Y-m-d', strtotime($last_visit_date));
278
-
279
- for ($i = 1; $i < $days; $i++) {
280
- if (count($user_hit_count) > 14) {
281
- $shifted = @array_shift($user_hit_count);
282
- }
283
-
284
- $next_key = strtotime('+1 day', strtotime($date_to_add));
285
- if ($next_key == $date) {
286
- break;
287
- } else {
288
- $user_hit_count[$next_key] = 0;
289
- }
290
- }
291
-
292
- }
293
-
294
- if (!isset($user_hit_count[$date])) {
295
- $user_hit_count[$date] = 0;
296
- }
297
- if (!$fix_count)
298
- $user_hit_count[$date] = ((int)$user_hit_count[$date] ) + 1;
299
-
300
- if (count($user_hit_count) > 14) {
301
- $shifted = @array_shift($user_hit_count);
302
- }
303
-
304
- update_option('user_hit_count', $user_hit_count);
305
-
306
- }
307
- }
308
- }
309
-
310
- function get_hit_count()
311
- {
312
- // Check if there are no hits on last key date
313
- $mmb_user_hits = get_option('user_hit_count');
314
- if (is_array($mmb_user_hits)) {
315
- end($mmb_user_hits);
316
- $last_key_date = key($mmb_user_hits);
317
- $current_date = date('Y-m-d');
318
- if ($last_key_date != $curent_date)
319
- $this->set_hit_count(true);
320
- }
321
-
322
- return get_option('user_hit_count');
323
- }
324
-
325
- function detect_bots()
326
- {
327
- $agent = $_SERVER['HTTP_USER_AGENT'];
328
-
329
- if ($agent == '')
330
- return false;
331
-
332
- $bot_list = array(
333
- "Teoma",
334
- "alexa",
335
- "froogle",
336
- "Gigabot",
337
- "inktomi",
338
- "looksmart",
339
- "URL_Spider_SQL",
340
- "Firefly",
341
- "NationalDirectory",
342
- "Ask Jeeves",
343
- "TECNOSEEK",
344
- "InfoSeek",
345
- "WebFindBot",
346
- "girafabot",
347
- "crawler",
348
- "www.galaxy.com",
349
- "Googlebot",
350
- "Scooter",
351
- "Slurp",
352
- "msnbot",
353
- "appie",
354
- "FAST",
355
- "WebBug",
356
- "Spade",
357
- "ZyBorg",
358
- "rabaz",
359
- "Baiduspider",
360
- "Feedfetcher-Google",
361
- "TechnoratiSnoop",
362
- "Rankivabot",
363
- "Mediapartners-Google",
364
- "Sogou web spider",
365
- "WebAlta Crawler",
366
- "aolserver"
367
- );
368
-
369
- $thebot = '';
370
- foreach ($bot_list as $bot) {
371
- if ((boolean)strpos($bot, $agent)) {
372
- $thebot = $bot;
373
- break;
374
- }
375
- }
376
-
377
- if ($thebot != '') {
378
- return $thebot;
379
- } else
380
- return false;
381
- }
382
-
383
-
384
- function set_notifications($params)
385
- {
386
- if(empty($params))
387
- return false;
388
-
389
- extract($params);
390
-
391
- if(!isset($delete)){
392
- $mwp_notifications = array('plugins' => $plugins, 'themes' => $themes, 'wp' => $wp,'url' => $url, 'notification_key' => $notification_key);
393
- update_option('mwp_notifications',$mwp_notifications);
394
- } else {
395
- delete_option('mwp_notifications');
396
- }
397
-
398
- return true;
399
-
400
- }
401
-
402
- //Cron update check for notifications
403
- function check_notifications(){
404
- global $wpdb, $mmb_wp_version, $mmb_plugin_dir, $wp_version, $wp_local_package;
405
-
406
- $mwp_notifications = get_option('mwp_notifications',true);
407
- $updates = array();
408
-
409
- if(is_array($mwp_notifications) && $mwp_notifications != false){
410
- include_once(ABSPATH . 'wp-includes/update.php');
411
- include_once(ABSPATH . '/wp-admin/includes/update.php');
412
- extract($mwp_notifications);
413
-
414
- //Check wordpress core updates
415
- if($wp){
416
- @wp_version_check();
417
- if (function_exists('get_core_updates')) {
418
- $wp_updates = get_core_updates();
419
- if (!empty($wp_updates)) {
420
- $current_transient = $wp_updates[0];
421
- if ($current_transient->response == "development" || version_compare($wp_version, $current_transient->current, '<')) {
422
- $current_transient->current_version = $wp_version;
423
- $updates['core_updates'] = $current_transient;
424
- } else
425
- $updates['core_updates'] = array();
426
- } else
427
- $updates['core_updates'] = array();
428
- }
429
-
430
- //Check plugin updates
431
- if($plugins){
432
- @wp_update_plugins();
433
- $this->get_installer_instance();
434
- $updates['upgradable_plugins'] = $this->installer_instance->get_upgradable_plugins();
435
- }
436
-
437
- //Check theme updates
438
- if($themes)
439
- {
440
- @wp_update_themes();
441
- $this->get_installer_instance();
442
-
443
- $updates['upgradable_themes'] = $this->installer_instance->get_upgradable_themes();
444
- }
445
-
446
- }
447
-
448
- if( !class_exists( 'WP_Http' ) ){
449
- include_once( ABSPATH . WPINC. '/class-http.php' );
450
- }
451
-
452
- $args = array();
453
- $args['body'] = array('updates' => $updates, 'notification_key' => $notification_key);
454
- $result= wp_remote_post($url, $args);
455
- }
456
- }
457
-
458
-
459
- function cmp_posts_worker($a, $b)
460
- {
461
- return ($a->post_modified < $b->post_modified);
462
- }
463
-
464
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
465
  ?>
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($params)
27
+ {
28
+
29
+ include_once(ABSPATH . 'wp-includes/update.php');
30
+ include_once(ABSPATH . '/wp-admin/includes/update.php');
31
+
32
+ $num = extract($params);
33
+ $stats = array();
34
+ $update_check = array();
35
+ $updates = array();
36
+
37
+ if ($refresh == 'transient') {
38
+ $current = $this->mmb_get_transient('update_core');
39
+ if(isset($current->last_checked)){
40
+ if(time() - $current->last_checked > 1800 ) {
41
+ @wp_update_plugins();
42
+ @wp_update_themes();
43
+ @wp_version_check();
44
+
45
+ $update_check = apply_filters('mwp_premium_update_check', $update_check);
46
+ if(!empty($update_check)){
47
+ foreach($update_check as $update){
48
+ if( is_array($update['callback']) ) {
49
+ $update_result = call_user_func( array( $update['callback'][0], $update['callback'][1] ) );
50
+ }
51
+ else if ( is_string($update['callback']) ) {
52
+ $update_result = call_user_func($update['callback']);
53
+ }
54
+ }
55
+ }
56
+ }
57
+ }
58
+ }
59
+
60
+ global $wpdb, $mmb_wp_version, $mmb_plugin_dir, $wp_version, $wp_local_package;
61
+
62
+ $premium_updates = array();
63
+ $stats['premium_updates'] = apply_filters('mwp_premium_update_notification', $premium_updates);
64
+
65
+ //define constants
66
+ $num_pending_comments = 10;
67
+ $num_approved_comments = 3;
68
+ $num_spam_comments = 0;
69
+ $num_draft_comments = 0;
70
+ $num_trash_comments = 0;
71
+
72
+ $stats['worker_version'] = MMB_WORKER_VERSION;
73
+ $stats['wordpress_version'] = $wp_version;
74
+ $stats['wordpress_locale_pckg'] = $wp_local_package;
75
+ $stats['wp_multisite'] = $this->mmb_multisite;
76
+ $stats['php_version'] = phpversion();
77
+ $stats['mysql_version'] = $wpdb->db_version();
78
+
79
+ if (function_exists('get_core_updates')) {
80
+ $updates = get_core_updates();
81
+ if (!empty($updates)) {
82
+ $current_transient = $updates[0];
83
+ if ($current_transient->response == "development" || version_compare($wp_version, $current_transient->current, '<')) {
84
+ $current_transient->current_version = $wp_version;
85
+ $stats['core_updates'] = $current_transient;
86
+ } else
87
+ $stats['core_updates'] = false;
88
+ } else
89
+ $stats['core_updates'] = false;
90
+ }
91
+
92
+ $mmb_user_hits = get_option('user_hit_count');
93
+ if (is_array($mmb_user_hits)) {
94
+ end($mmb_user_hits);
95
+ $last_key_date = key($mmb_user_hits);
96
+ $current_date = date('Y-m-d');
97
+ if ($last_key_date != $curent_date)
98
+ $this->set_hit_count(true);
99
+ }
100
+ $stats['hit_counter'] = get_option('user_hit_count');
101
+
102
+ $this->get_installer_instance();
103
+ $stats['upgradable_themes'] = $this->installer_instance->get_upgradable_themes();
104
+ $stats['upgradable_plugins'] = $this->installer_instance->get_upgradable_plugins();
105
+
106
+ $pending_comments = get_comments('status=hold&number=' . $num_pending_comments);
107
+ foreach ($pending_comments as &$comment) {
108
+ $commented_post = get_post($comment->comment_post_ID);
109
+ $comment->post_title = $commented_post->post_title;
110
+ }
111
+ $stats['comments']['pending'] = $pending_comments;
112
+
113
+
114
+ $approved_comments = get_comments('status=approve&number=' . $num_approved_comments);
115
+ foreach ($approved_comments as &$comment) {
116
+ $commented_post = get_post($comment->comment_post_ID);
117
+ $comment->post_title = $commented_post->post_title;
118
+ }
119
+ $stats['comments']['approved'] = $approved_comments;
120
+
121
+
122
+ $all_posts = get_posts('post_status=publish&numberposts=3&orderby=modified&order=desc');
123
+ $recent_posts = array();
124
+
125
+ foreach ($all_posts as $id => $recent_post) {
126
+ $recent = new stdClass();
127
+ $recent->post_permalink = get_permalink($recent_post->ID);
128
+ $recent->ID = $recent_post->ID;
129
+ $recent->post_date = $recent_post->post_date;
130
+ $recent->post_title = $recent_post->post_title;
131
+ $recent->post_modified = $recent_post->post_modified;
132
+ $recent->comment_count = (int)$recent_post->comment_count;
133
+ $recent_posts[] = $recent;
134
+ }
135
+
136
+
137
+ $all_drafts = get_posts('post_status=draft&numberposts=20&orderby=modified&order=desc');
138
+ $recent_drafts = array();
139
+ foreach ($all_drafts as $id => $recent_draft) {
140
+ $recent = new stdClass();
141
+ $recent->post_permalink = get_permalink($recent_draft->ID);
142
+ $recent->ID = $recent_draft->ID;
143
+ $recent->post_date = $recent_draft->post_date;
144
+ $recent->post_title = $recent_draft->post_title;
145
+ $recent->post_modified = $recent_draft->post_modified;
146
+
147
+ $recent_drafts[] = $recent;
148
+ }
149
+
150
+ $all_scheduled = get_posts('post_status=future&numberposts=20&orderby=post_date&order=desc');
151
+ $scheduled_posts = array();
152
+ foreach ($all_scheduled as $id => $scheduled) {
153
+ $recent = new stdClass();
154
+ $recent->post_permalink = get_permalink($scheduled->ID);
155
+ $recent->ID = $scheduled->ID;
156
+ $recent->post_date = $scheduled->post_date;
157
+ $recent->post_title = $scheduled->post_title;
158
+ $recent->post_modified = $scheduled->post_modified;
159
+ $scheduled_posts[] = $recent;
160
+ }
161
+
162
+
163
+ $all_pages_published = get_pages('post_status=publish&numberposts=3&orderby=modified&order=desc');
164
+ $recent_pages_published = array();
165
+ foreach ((array)$all_pages_published as $id => $recent_page_published) {
166
+ $recent = new stdClass();
167
+ $recent->post_permalink = get_permalink($recent_page_published->ID);
168
+
169
+ $recent->ID = $recent_page_published->ID;
170
+ $recent->post_date = $recent_page_published->post_date;
171
+ $recent->post_title = $recent_page_published->post_title;
172
+ $recent->post_modified = $recent_page_published->post_modified;
173
+
174
+ $recent_posts[] = $recent;
175
+ }
176
+ usort($recent_posts, array($this, 'cmp_posts_worker'));
177
+ $stats['posts'] = array_slice($recent_posts, 0, 20);
178
+
179
+ $all_pages_drafts = get_pages('post_status=draft&numberposts=20&orderby=modified&order=desc');
180
+ $recent_pages_drafts = array();
181
+ foreach ((array)$all_pages_drafts as $id => $recent_pages_draft) {
182
+ $recent = new stdClass();
183
+ $recent->post_permalink = get_permalink($recent_pages_draft->ID);
184
+ $recent->ID = $recent_pages_draft->ID;
185
+ $recent->post_date = $recent_pages_draft->post_date;
186
+ $recent->post_title = $recent_pages_draft->post_title;
187
+ $recent->post_modified = $recent_pages_draft->post_modified;
188
+
189
+ $recent_drafts[] = $recent;
190
+ }
191
+ usort($recent_drafts, array($this, 'cmp_posts_worker'));
192
+ $stats['drafts'] = array_slice($recent_drafts, 0, 20);
193
+
194
+
195
+ $pages_scheduled = get_pages('post_status=future&numberposts=20&orderby=modified&order=desc');
196
+ $recent_pages_drafts = array();
197
+ foreach ((array)$pages_scheduled as $id => $scheduled) {
198
+ $recent = new stdClass();
199
+ $recent->post_permalink = get_permalink($scheduled->ID);
200
+ $recent->ID = $scheduled->ID;
201
+ $recent->post_date = $scheduled->post_date;
202
+ $recent->post_title = $scheduled->post_title;
203
+ $recent->post_modified = $scheduled->post_modified;
204
+
205
+ $scheduled_posts[] = $recent;
206
+ }
207
+ usort($scheduled_posts, array($this, 'cmp_posts_worker'));
208
+ $stats['scheduled'] = array_slice($scheduled_posts, 0, 20);
209
+
210
+
211
+
212
+ if (!function_exists('get_filesystem_method'))
213
+ include_once(ABSPATH . 'wp-admin/includes/file.php');
214
+
215
+ $stats['writable'] = $this->is_server_writable();
216
+
217
+ //Backup Results
218
+ $stats['mwp_backups'] = $this->get_backup_instance()->get_backup_stats();
219
+ $stats['mwp_next_backups'] = $this->get_backup_instance()->get_next_schedules();
220
+
221
+ $clone_backup = get_option('mwp_manual_backup');
222
+
223
+ if(!is_array($clone_backup) || !file_exists($clone_backup['file_path'])){
224
+ $clone_backup = '';
225
+ } else {
226
+ $clone_backup = $clone_backup['file_url'];
227
+ }
228
+ $stats['clone_backup'] = $clone_backup;
229
+
230
+ //Backup requirements
231
+ $stats['mwp_backup_req'] = $this->get_backup_instance()->check_backup_compat();
232
+
233
+ $stats = apply_filters('mmb_stats_filter', $stats);
234
+
235
+ return $stats;
236
+ }
237
+
238
+ function get_comments_stats(){
239
+ $num_pending_comments = 3;
240
+ $num_approved_comments = 3;
241
+ $pending_comments = get_comments('status=hold&number=' . $num_pending_comments);
242
+ foreach ($pending_comments as &$comment) {
243
+ $commented_post = get_post($comment->comment_post_ID);
244
+ $comment->post_title = $commented_post->post_title;
245
+ }
246
+ $stats['comments']['pending'] = $pending_comments;
247
+
248
+
249
+ $approved_comments = get_comments('status=approve&number=' . $num_approved_comments);
250
+ foreach ($approved_comments as &$comment) {
251
+ $commented_post = get_post($comment->comment_post_ID);
252
+ $comment->post_title = $commented_post->post_title;
253
+ }
254
+ $stats['comments']['approved'] = $approved_comments;
255
+
256
+ return $stats;
257
+ }
258
+
259
+ function get_initial_stats()
260
+ {
261
+ global $mmb_plugin_dir;
262
+
263
+ $stats = array();
264
+
265
+ $stats['email'] = get_option('admin_email');
266
+ $stats['no_openssl'] = $this->get_random_signature();
267
+ $stats['content_path'] = WP_CONTENT_DIR;
268
+ $stats['worker_path'] = $mmb_plugin_dir;
269
+ $stats['worker_version'] = MMB_WORKER_VERSION;
270
+ $stats['site_title'] = get_bloginfo('name');
271
+ $stats['site_tagline'] = get_bloginfo('description');
272
+ $stats['site_home'] = get_option('home');
273
+
274
+
275
+ if (!function_exists('get_filesystem_method'))
276
+ include_once(ABSPATH . 'wp-admin/includes/file.php');
277
+
278
+ $stats['writable'] = $this->is_server_writable();
279
+
280
+ return $stats;
281
+ }
282
+
283
+
284
+
285
+ function set_hit_count($fix_count = false)
286
+ {
287
+ if ($fix_count || (!is_admin() && !MMB_Stats::detect_bots())) {
288
+ $date = date('Y-m-d');
289
+ $user_hit_count = (array) get_option('user_hit_count');
290
+ if (!$user_hit_count) {
291
+ $user_hit_count[$date] = 1;
292
+ update_option('user_hit_count', $user_hit_count);
293
+ } else {
294
+ $dated_keys = array_keys($user_hit_count);
295
+ $last_visit_date = $dated_keys[count($dated_keys) - 1];
296
+
297
+ $days = intval((strtotime($date) - strtotime($last_visit_date)) / 60 / 60 / 24);
298
+
299
+ if ($days > 1) {
300
+ $date_to_add = date('Y-m-d', strtotime($last_visit_date));
301
+
302
+ for ($i = 1; $i < $days; $i++) {
303
+ if (count($user_hit_count) > 14) {
304
+ $shifted = @array_shift($user_hit_count);
305
+ }
306
+
307
+ $next_key = strtotime('+1 day', strtotime($date_to_add));
308
+ if ($next_key == $date) {
309
+ break;
310
+ } else {
311
+ $user_hit_count[$next_key] = 0;
312
+ }
313
+ }
314
+
315
+ }
316
+
317
+ if (!isset($user_hit_count[$date])) {
318
+ $user_hit_count[$date] = 0;
319
+ }
320
+ if (!$fix_count)
321
+ $user_hit_count[$date] = ((int)$user_hit_count[$date] ) + 1;
322
+
323
+ if (count($user_hit_count) > 14) {
324
+ $shifted = @array_shift($user_hit_count);
325
+ }
326
+
327
+ update_option('user_hit_count', $user_hit_count);
328
+
329
+ }
330
+ }
331
+ }
332
+
333
+ function get_hit_count()
334
+ {
335
+ // Check if there are no hits on last key date
336
+ $mmb_user_hits = get_option('user_hit_count');
337
+ if (is_array($mmb_user_hits)) {
338
+ end($mmb_user_hits);
339
+ $last_key_date = key($mmb_user_hits);
340
+ $current_date = date('Y-m-d');
341
+ if ($last_key_date != $curent_date)
342
+ $this->set_hit_count(true);
343
+ }
344
+
345
+ return get_option('user_hit_count');
346
+ }
347
+
348
+ function detect_bots()
349
+ {
350
+ $agent = $_SERVER['HTTP_USER_AGENT'];
351
+
352
+ if ($agent == '')
353
+ return false;
354
+
355
+ $bot_list = array(
356
+ "Teoma",
357
+ "alexa",
358
+ "froogle",
359
+ "Gigabot",
360
+ "inktomi",
361
+ "looksmart",
362
+ "URL_Spider_SQL",
363
+ "Firefly",
364
+ "NationalDirectory",
365
+ "Ask Jeeves",
366
+ "TECNOSEEK",
367
+ "InfoSeek",
368
+ "WebFindBot",
369
+ "girafabot",
370
+ "crawler",
371
+ "www.galaxy.com",
372
+ "Googlebot",
373
+ "Scooter",
374
+ "Slurp",
375
+ "msnbot",
376
+ "appie",
377
+ "FAST",
378
+ "WebBug",
379
+ "Spade",
380
+ "ZyBorg",
381
+ "rabaz",
382
+ "Baiduspider",
383
+ "Feedfetcher-Google",
384
+ "TechnoratiSnoop",
385
+ "Rankivabot",
386
+ "Mediapartners-Google",
387
+ "Sogou web spider",
388
+ "WebAlta Crawler",
389
+ "aolserver"
390
+ );
391
+
392
+ $thebot = '';
393
+ foreach ($bot_list as $bot) {
394
+ if ((boolean)strpos($bot, $agent)) {
395
+ $thebot = $bot;
396
+ break;
397
+ }
398
+ }
399
+
400
+ if ($thebot != '') {
401
+ return $thebot;
402
+ } else
403
+ return false;
404
+ }
405
+
406
+
407
+ function set_notifications($params)
408
+ {
409
+ if(empty($params))
410
+ return false;
411
+
412
+ extract($params);
413
+
414
+ if(!isset($delete)){
415
+ $mwp_notifications = array('plugins' => $plugins, 'themes' => $themes, 'wp' => $wp,'url' => $url, 'notification_key' => $notification_key);
416
+ update_option('mwp_notifications',$mwp_notifications);
417
+ } else {
418
+ delete_option('mwp_notifications');
419
+ }
420
+
421
+ return true;
422
+
423
+ }
424
+
425
+ //Cron update check for notifications
426
+ function check_notifications(){
427
+ global $wpdb, $mmb_wp_version, $mmb_plugin_dir, $wp_version, $wp_local_package;
428
+
429
+ $mwp_notifications = get_option('mwp_notifications',true);
430
+ $updates = array();
431
+
432
+ if(is_array($mwp_notifications) && $mwp_notifications != false){
433
+ include_once(ABSPATH . 'wp-includes/update.php');
434
+ include_once(ABSPATH . '/wp-admin/includes/update.php');
435
+ extract($mwp_notifications);
436
+
437
+ //Check wordpress core updates
438
+ if($wp){
439
+ @wp_version_check();
440
+ if (function_exists('get_core_updates')) {
441
+ $wp_updates = get_core_updates();
442
+ if (!empty($wp_updates)) {
443
+ $current_transient = $wp_updates[0];
444
+ if ($current_transient->response == "development" || version_compare($wp_version, $current_transient->current, '<')) {
445
+ $current_transient->current_version = $wp_version;
446
+ $updates['core_updates'] = $current_transient;
447
+ } else
448
+ $updates['core_updates'] = array();
449
+ } else
450
+ $updates['core_updates'] = array();
451
+ }
452
+
453
+ //Check plugin updates
454
+ if($plugins){
455
+ @wp_update_plugins();
456
+ $this->get_installer_instance();
457
+ $updates['upgradable_plugins'] = $this->installer_instance->get_upgradable_plugins();
458
+ }
459
+
460
+ //Check theme updates
461
+ if($themes)
462
+ {
463
+ @wp_update_themes();
464
+ $this->get_installer_instance();
465
+
466
+ $updates['upgradable_themes'] = $this->installer_instance->get_upgradable_themes();
467
+ }
468
+
469
+ }
470
+
471
+ if( !class_exists( 'WP_Http' ) ){
472
+ include_once( ABSPATH . WPINC. '/class-http.php' );
473
+ }
474
+
475
+ $args = array();
476
+ $args['body'] = array('updates' => $updates, 'notification_key' => $notification_key);
477
+ $result= wp_remote_post($url, $args);
478
+ }
479
+ }
480
+
481
+
482
+ function cmp_posts_worker($a, $b)
483
+ {
484
+ return ($a->post_modified < $b->post_modified);
485
+ }
486
+
487
+ }
488
  ?>
user.class.php CHANGED
@@ -1,53 +1,206 @@
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 add_user($args)
21
- {
22
-
23
- if(!function_exists('username_exists') || !function_exists('email_exists'))
24
- include_once(ABSPATH . WPINC . '/registration.php');
25
-
26
- if(username_exists($args['user_login']))
27
- return array('error' => 'Username already exists');
28
-
29
- if (email_exists($args['user_email']))
30
- return array('error' => 'Email already exists');
31
-
32
- if(!function_exists('wp_insert_user'))
33
- include_once (ABSPATH . 'wp-admin/includes/user.php');
34
-
35
- $user_id = wp_insert_user($args);
36
-
37
- if($user_id){
38
-
39
- if($args['email_notify']){
40
- //require_once ABSPATH . WPINC . '/pluggable.php';
41
- wp_new_user_notification($user_id, $args['user_pass']);
42
-
43
- }
44
-
45
- return $user_id;
46
- }else{
47
- return array('error' => 'User not added. Please try again.');
48
- }
49
-
50
- }
51
-
52
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
53
  ?>
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
+ foreach($user_roles as $user_role){
31
+ switch(strtolower($user_role)){
32
+ case 'subscriber' : $userlevels[] = 0; break;
33
+ case 'contributor' : $userlevels[] = 1; break;
34
+ case 'author' : $userlevels[] = 2; break;
35
+ case 'editor' : $userlevels[] = 7; break;
36
+ case 'administrator' : $userlevels[] = 10; break;
37
+ default: break;
38
+ }
39
+ }
40
+
41
+ $users = array();
42
+ $userlevel_qry = "('".implode("','",$userlevels)."')";
43
+ $user_metas = $wpdb->get_results("SELECT * from $wpdb->usermeta WHERE meta_key = 'wp_user_level' AND meta_value IN $userlevel_qry");
44
+
45
+ $include = array();
46
+ if(is_array($user_metas) && !empty($user_metas)){
47
+ foreach($user_metas as $user_meta){
48
+ $include[] = $user_meta->user_id;
49
+ }
50
+ }
51
+
52
+ $args = array();
53
+
54
+ $args['include'] = $include;
55
+ $args['fields'] = 'all_with_meta';
56
+ $temp_users = get_users($args);
57
+ $user = array();
58
+ foreach ((array)$temp_users as $temp){
59
+ $user['user_id'] = $temp->ID;
60
+ $user['user_login'] = $temp->user_login;
61
+ $user['wp_capabilities'] = array_keys($temp->wp_capabilities);
62
+ $users[] = $user;
63
+ }
64
+
65
+ return array('users' => $users);
66
+ }
67
+
68
+ function add_user($args)
69
+ {
70
+
71
+ if(!function_exists('username_exists') || !function_exists('email_exists'))
72
+ include_once(ABSPATH . WPINC . '/registration.php');
73
+
74
+ if(username_exists($args['user_login']))
75
+ return array('error' => 'Username already exists');
76
+
77
+ if (email_exists($args['user_email']))
78
+ return array('error' => 'Email already exists');
79
+
80
+ if(!function_exists('wp_insert_user'))
81
+ include_once (ABSPATH . 'wp-admin/includes/user.php');
82
+
83
+ $user_id = wp_insert_user($args);
84
+
85
+ if($user_id){
86
+
87
+ if($args['email_notify']){
88
+ //require_once ABSPATH . WPINC . '/pluggable.php';
89
+ wp_new_user_notification($user_id, $args['user_pass']);
90
+ }
91
+ return $user_id;
92
+ }else{
93
+ return array('error' => 'User not added. Please try again.');
94
+ }
95
+
96
+ }
97
+
98
+ function edit_users($args){
99
+
100
+ if(empty($args))
101
+ return false;
102
+ if(!function_exists('get_user_to_edit'))
103
+ include_once (ABSPATH . 'wp-admin/includes/user.php');
104
+ if(!function_exists('wp_update_user'))
105
+ include_once (ABSPATH . WPINC.'/user.php');
106
+
107
+ extract($args);
108
+ //$args: $users, $new_role, $new_password, $user_edit_action
109
+
110
+ $return = array();
111
+ if(count($users)){
112
+ foreach($users as $user){
113
+ $result = '';
114
+ $user_obj = get_userdatabylogin($user);
115
+ if($user_obj != false){
116
+ switch($user_edit_action){
117
+ case 'change-password':
118
+ if($new_password){
119
+ $user_data = array();
120
+ $userdata['user_pass'] = $new_password;
121
+ $userdata['ID'] = $user_obj->ID;
122
+ $result = wp_update_user($userdata);
123
+ } else {
124
+ $result = array('error' => 'No password provided.');
125
+ }
126
+ break;
127
+ case 'change-role':
128
+ if($new_role){
129
+ if($user != $username){
130
+ if(!$this->last_admin($user_obj)){
131
+ $user_data = array();
132
+ $userdata['ID'] = $user_obj->ID;
133
+ $userdata['role'] = strtolower($new_role);
134
+ $result = wp_update_user($userdata);
135
+ } else {
136
+ $result = array('error' => 'Cannot change role to the only one left admin user.');
137
+ }
138
+ } else {
139
+ $result = array('error' => 'Cannot change role to user assigned for ManageWP.');
140
+ }
141
+ } else {
142
+ $result = array('error' => 'No role provided.');
143
+ }
144
+ break;
145
+ case 'delete-user':
146
+ if($user != $username){
147
+ if(!$this->last_admin($user_obj)){
148
+ if($reassign_user){
149
+ $to_user = get_userdatabylogin($reassign_user);
150
+ if($to_user != false){
151
+ $result = wp_delete_user($user_obj->ID, $to_user->ID);
152
+ } else {
153
+ $result = array('error' => 'User not deleted. User to reassign posts doesn\'t exist.');
154
+ }
155
+ } else {
156
+ $result = wp_delete_user($user_obj->ID);
157
+ }
158
+ } else {
159
+ $result = array('error' => 'Cannot delete the only one left admin user.');
160
+ }
161
+ } else {
162
+ $result = array('error' => 'Cannot delete user assigned for ManageWP.');
163
+ }
164
+
165
+ break;
166
+ default:
167
+ $result = array('error' => 'Wrong action provided. Please try again.');
168
+ break;
169
+ }
170
+ } else {
171
+ $result = array('error' => 'User not found.');
172
+ }
173
+
174
+ if(is_wp_error($result)){
175
+ $result = array('error' => $result->get_error_message());
176
+ }
177
+
178
+ $return[$user] = $result;
179
+ }
180
+ }
181
+
182
+ return $return;
183
+
184
+ }
185
+
186
+ //Check if user is the only one admin on the site
187
+ function last_admin($user_obj){
188
+ $capabilities = array_map('strtolower',array_keys($user_obj->wp_capabilities));
189
+ $result = count_users();
190
+ print_r($result);
191
+ if(in_array('administrator',$capabilities)){
192
+
193
+ if(!function_exists('count_users')){
194
+ include_once (ABSPATH . WPINC. '/user.php');
195
+ }
196
+
197
+ $result = count_users();
198
+ if($result['avail_roles']['administrator'] == 1){
199
+ return true;
200
+ }
201
+ }
202
+ return false;
203
+ }
204
+
205
+ }
206
  ?>