MainWP Child - Version 3.4.6

Version Description

  • 2-21-18 =
  • Fixed: Wordfence 7 compatibility issues
  • Added: multiple security enhancements
  • Updated: admin notice text
Download this release

Release Info

Developer mainwp
Plugin Icon 128x128 MainWP Child
Version 3.4.6
Comparing to
See all releases

Version 3.4.6

class/class-mainwp-backup.php ADDED
@@ -0,0 +1,845 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class MainWP_Backup {
4
+ protected static $instance = null;
5
+ protected $excludeZip;
6
+ protected $zip;
7
+ protected $zipArchiveFileCount;
8
+ protected $zipArchiveSizeCount;
9
+ protected $zipArchiveFileName;
10
+ protected $file_descriptors;
11
+ protected $loadFilesBeforeZip;
12
+
13
+ protected $timeout;
14
+ protected $lastRun;
15
+
16
+ /**
17
+ * @var Tar_Archiver
18
+ */
19
+ protected $archiver = null;
20
+
21
+ public static function get() {
22
+ if ( null === self::$instance ) {
23
+ self::$instance = new MainWP_Backup();
24
+ }
25
+
26
+ return self::$instance;
27
+ }
28
+
29
+ /**
30
+ * Create full backup
31
+ */
32
+ public function createFullBackup( $excludes, $filePrefix = '', $addConfig = false, $includeCoreFiles = false, $file_descriptors = 0, $fileSuffix = false, $excludezip = false, $excludenonwp = false, $loadFilesBeforeZip = true, $ext = 'zip', $pid = false, $append = false ) {
33
+ $this->file_descriptors = $file_descriptors;
34
+ $this->loadFilesBeforeZip = $loadFilesBeforeZip;
35
+
36
+ $dirs = MainWP_Helper::getMainWPDir( 'backup' );
37
+ $backupdir = $dirs[0];
38
+ if ( ! defined( 'PCLZIP_TEMPORARY_DIR' ) ) {
39
+ define( 'PCLZIP_TEMPORARY_DIR', $backupdir );
40
+ }
41
+
42
+ if ( false !== $pid ) {
43
+ $pid = trailingslashit( $backupdir ) . 'backup-' . $pid . '.pid';
44
+ }
45
+
46
+ //Verify if another backup is running, if so, return an error
47
+ $files = glob( $backupdir . '*.pid' );
48
+ foreach ( $files as $file ) {
49
+ if ( basename( $file ) == basename( $pid ) ) {
50
+ continue;
51
+ }
52
+
53
+ if ( ( time() - filemtime( $file ) ) < 160 ) {
54
+ MainWP_Helper::error( __( 'Another backup process is running. Please, try again later.', 'mainwp-child' ) );
55
+ }
56
+ }
57
+
58
+ $timestamp = time();
59
+ if ( '' !== $filePrefix ) {
60
+ $filePrefix .= '-';
61
+ }
62
+
63
+ if ( 'zip' == $ext ) {
64
+ $this->archiver = null;
65
+ $ext = '.zip';
66
+ } else {
67
+ $this->archiver = new Tar_Archiver( $this, $ext, $pid );
68
+ $ext = $this->archiver->getExtension();
69
+ }
70
+
71
+ // throw new Exception('Test 1 2 : ' . print_r($append,1));
72
+ if ( ( false !== $fileSuffix ) && ! empty( $fileSuffix ) ) {
73
+ $file = $fileSuffix . ( true === $append ? '' : $ext ); //Append already contains extension!
74
+ } else {
75
+ $file = 'backup-' . $filePrefix . $timestamp . $ext;
76
+ }
77
+ $filepath = $backupdir . $file;
78
+ $fileurl = $file;
79
+
80
+ // if (!$append)
81
+ // {
82
+ // if ($dh = opendir($backupdir))
83
+ // {
84
+ // while (($file = readdir($dh)) !== false)
85
+ // {
86
+ // if ($file != '.' && $file != '..' && preg_match('/(.*).(zip|tar|tar.gz|tar.bz2|pid|done)$/', $file))
87
+ // {
88
+ // @unlink($backupdir . $file);
89
+ // }
90
+ // }
91
+ // closedir($dh);
92
+ // }
93
+ // }
94
+
95
+ if ( ! $addConfig ) {
96
+ if ( ! in_array( str_replace( ABSPATH, '', WP_CONTENT_DIR ), $excludes ) && ! in_array( 'wp-admin', $excludes ) && ! in_array( WPINC, $excludes ) ) {
97
+ $addConfig = true;
98
+ $includeCoreFiles = true;
99
+ }
100
+ }
101
+
102
+ $this->timeout = 20 * 60 * 60; /*20 minutes*/
103
+ $mem = '512M';
104
+ // @codingStandardsIgnoreStart
105
+ @ini_set( 'memory_limit', $mem );
106
+ @set_time_limit( $this->timeout );
107
+ @ini_set( 'max_execution_time', $this->timeout );
108
+ // @codingStandardsIgnoreEnd
109
+
110
+ if ( null !== $this->archiver ) {
111
+ $success = $this->archiver->createFullBackup( $filepath, $excludes, $addConfig, $includeCoreFiles, $excludezip, $excludenonwp, $append );
112
+ } else if ( $this->checkZipSupport() ) {
113
+ $success = $this->createZipFullBackup( $filepath, $excludes, $addConfig, $includeCoreFiles, $excludezip, $excludenonwp );
114
+ } else if ( $this->checkZipConsole() ) {
115
+ $success = $this->createZipConsoleFullBackup( $filepath, $excludes, $addConfig, $includeCoreFiles, $excludezip, $excludenonwp );
116
+ } else {
117
+ $success = $this->createZipPclFullBackup2( $filepath, $excludes, $addConfig, $includeCoreFiles, $excludezip, $excludenonwp );
118
+ }
119
+
120
+ return ( $success ) ? array(
121
+ 'timestamp' => $timestamp,
122
+ 'file' => $fileurl,
123
+ 'filesize' => filesize( $filepath ),
124
+ ) : false;
125
+ }
126
+
127
+ public function zipFile( $files, $archive ) {
128
+ $this->timeout = 20 * 60 * 60; /*20 minutes*/
129
+ $mem = '512M';
130
+ // @codingStandardsIgnoreStart
131
+ @ini_set( 'memory_limit', $mem );
132
+ @set_time_limit( $this->timeout );
133
+ @ini_set( 'max_execution_time', $this->timeout );
134
+ // @codingStandardsIgnoreEnd
135
+
136
+ if ( !is_array( $files ) ) {
137
+ $files = array ($files );
138
+ }
139
+
140
+ if ( null !== $this->archiver ) {
141
+ $success = $this->archiver->zipFile( $files, $archive );
142
+ } else if ( $this->checkZipSupport() ) {
143
+ $success = $this->_zipFile( $files, $archive );
144
+ } else if ( $this->checkZipConsole() ) {
145
+ $success = $this->_zipFileConsole( $files, $archive );
146
+ } else {
147
+ $success = $this->_zipFilePcl( $files, $archive );
148
+ }
149
+
150
+ return $success;
151
+ }
152
+
153
+ function _zipFile( $files, $archive ) {
154
+ $this->zip = new ZipArchive();
155
+ $this->zipArchiveFileCount = 0;
156
+ $this->zipArchiveSizeCount = 0;
157
+
158
+ $zipRes = $this->zip->open( $archive, ZipArchive::CREATE );
159
+ if ( $zipRes ) {
160
+ foreach ( $files as $file ) {
161
+ $this->addFileToZip( $file, basename( $file ) );
162
+ }
163
+
164
+ return $this->zip->close();
165
+ }
166
+
167
+ return false;
168
+ }
169
+
170
+ function _zipFileConsole( $files, $archive ) {
171
+ return false;
172
+ }
173
+
174
+ public function _zipFilePcl( $files, $archive ) {
175
+ //Zip this backup folder..
176
+ require_once( ABSPATH . 'wp-admin/includes/class-pclzip.php' );
177
+ $this->zip = new PclZip( $archive );
178
+
179
+ $error = false;
180
+ foreach ( $files as $file ) {
181
+ if ( 0 === ( $rslt = $this->zip->add( $file, PCLZIP_OPT_REMOVE_PATH, dirname( $file ) ) ) ) {
182
+ $error = true;
183
+ }
184
+ }
185
+
186
+ return !$error;
187
+ }
188
+
189
+ /**
190
+ * Check for default PHP zip support
191
+ *
192
+ * @return bool
193
+ */
194
+ public function checkZipSupport() {
195
+ return class_exists( 'ZipArchive' );
196
+ }
197
+
198
+ /**
199
+ * Check if we could run zip on console
200
+ *
201
+ * @return bool
202
+ */
203
+ public function checkZipConsole() {
204
+ return false;
205
+ // return function_exists('system');
206
+ }
207
+
208
+ /**
209
+ * Create full backup using default PHP zip library
210
+ *
211
+ * @param string $filepath File path to create
212
+ *
213
+ * @return bool
214
+ */
215
+ public function createZipFullBackup( $filepath, $excludes, $addConfig, $includeCoreFiles, $excludezip, $excludenonwp ) {
216
+ $this->excludeZip = $excludezip;
217
+ $this->zip = new ZipArchive();
218
+ $this->zipArchiveFileCount = 0;
219
+ $this->zipArchiveSizeCount = 0;
220
+ $this->zipArchiveFileName = $filepath;
221
+ $zipRes = $this->zip->open( $filepath, ZipArchive::CREATE );
222
+ if ( $zipRes ) {
223
+ $nodes = glob( ABSPATH . '*' );
224
+ if ( ! $includeCoreFiles ) {
225
+ $coreFiles = array(
226
+ 'favicon.ico',
227
+ 'index.php',
228
+ 'license.txt',
229
+ 'readme.html',
230
+ 'wp-activate.php',
231
+ 'wp-app.php',
232
+ 'wp-blog-header.php',
233
+ 'wp-comments-post.php',
234
+ 'wp-config.php',
235
+ 'wp-config-sample.php',
236
+ 'wp-cron.php',
237
+ 'wp-links-opml.php',
238
+ 'wp-load.php',
239
+ 'wp-login.php',
240
+ 'wp-mail.php',
241
+ 'wp-pass.php',
242
+ 'wp-register.php',
243
+ 'wp-settings.php',
244
+ 'wp-signup.php',
245
+ 'wp-trackback.php',
246
+ 'xmlrpc.php',
247
+ );
248
+ foreach ( $nodes as $key => $node ) {
249
+ if ( MainWP_Helper::startsWith( $node, ABSPATH . WPINC ) ) {
250
+ unset( $nodes[ $key ] );
251
+ } else if ( MainWP_Helper::startsWith( $node, ABSPATH . basename( admin_url( '' ) ) ) ) {
252
+ unset( $nodes[ $key ] );
253
+ } else {
254
+ foreach ( $coreFiles as $coreFile ) {
255
+ if ( ABSPATH . $coreFile === $node ) {
256
+ unset( $nodes[ $key ] );
257
+ }
258
+ }
259
+ }
260
+ }
261
+ unset( $coreFiles );
262
+ }
263
+
264
+ $db_files = $this->createBackupDB( dirname( $filepath ) . DIRECTORY_SEPARATOR . 'dbBackup' );
265
+ foreach ( $db_files as $db_file ) {
266
+ $this->addFileToZip( $db_file, basename( WP_CONTENT_DIR ) . '/' . basename( $db_file ) );
267
+ }
268
+
269
+ if ( file_exists( ABSPATH . '.htaccess' ) ) {
270
+ $this->addFileToZip( ABSPATH . '.htaccess', 'mainwp-htaccess' );
271
+ }
272
+
273
+ foreach ( $nodes as $node ) {
274
+ if ( $excludenonwp && is_dir( $node ) ) {
275
+ if ( ! MainWP_Helper::startsWith( $node, WP_CONTENT_DIR ) && ! MainWP_Helper::startsWith( $node, ABSPATH . 'wp-admin' ) && ! MainWP_Helper::startsWith( $node, ABSPATH . WPINC ) ) {
276
+ continue;
277
+ }
278
+ }
279
+
280
+ if ( ! MainWP_Helper::inExcludes( $excludes, str_replace( ABSPATH, '', $node ) ) ) {
281
+ if ( is_dir( $node ) ) {
282
+ $this->zipAddDir( $node, $excludes );
283
+ } else if ( is_file( $node ) ) {
284
+ $this->addFileToZip( $node, str_replace( ABSPATH, '', $node ) );
285
+ }
286
+ }
287
+ }
288
+
289
+ if ( $addConfig ) {
290
+ global $wpdb;
291
+ $plugins = array();
292
+ $dir = WP_CONTENT_DIR . '/plugins/';
293
+ // @codingStandardsIgnoreStart
294
+ $fh = @opendir( $dir );
295
+ while ( $entry = @readdir( $fh ) ) {
296
+ if ( ! @is_dir( $dir . $entry ) ) {
297
+ continue;
298
+ }
299
+ if ( ( $entry == '.' ) || ( $entry == '..' ) ) {
300
+ continue;
301
+ }
302
+ $plugins[] = $entry;
303
+ }
304
+ @closedir( $fh );
305
+ // @codingStandardsIgnoreEnd
306
+
307
+ $themes = array();
308
+ $dir = WP_CONTENT_DIR . '/themes/';
309
+ // @codingStandardsIgnoreStart
310
+ $fh = @opendir( $dir );
311
+ while ( $entry = @readdir( $fh ) ) {
312
+ if ( ! @is_dir( $dir . $entry ) ) {
313
+ continue;
314
+ }
315
+ if ( ( $entry == '.' ) || ( $entry == '..' ) ) {
316
+ continue;
317
+ }
318
+ $themes[] = $entry;
319
+ }
320
+ @closedir( $fh );
321
+ // @codingStandardsIgnoreEnd
322
+
323
+ $string = base64_encode( serialize( array(
324
+ 'siteurl' => get_option( 'siteurl' ),
325
+ 'home' => get_option( 'home' ),
326
+ 'abspath' => ABSPATH,
327
+ 'prefix' => $wpdb->prefix,
328
+ 'lang' => defined( 'WPLANG' ) ? WPLANG : '',
329
+ 'plugins' => $plugins,
330
+ 'themes' => $themes,
331
+ ) ) );
332
+
333
+ $this->addFileFromStringToZip( 'clone/config.txt', $string );
334
+ }
335
+
336
+ $return = $this->zip->close();
337
+ foreach ( $db_files as $db_file ) {
338
+ @unlink( $db_file );
339
+ }
340
+
341
+ return true;
342
+ }
343
+
344
+ return false;
345
+ }
346
+
347
+ /**
348
+ * Create full backup using pclZip library
349
+ *
350
+ * @param string $filepath File path to create
351
+ *
352
+ * @return bool
353
+ */
354
+ public function createZipPclFullBackup( $filepath, $excludes, $addConfig, $includeCoreFiles ) {
355
+ require_once( ABSPATH . 'wp-admin/includes/class-pclzip.php' );
356
+ $this->zip = new PclZip( $filepath );
357
+ $nodes = glob( ABSPATH . '*' );
358
+ if ( ! $includeCoreFiles ) {
359
+ $coreFiles = array(
360
+ 'favicon.ico',
361
+ 'index.php',
362
+ 'license.txt',
363
+ 'readme.html',
364
+ 'wp-activate.php',
365
+ 'wp-app.php',
366
+ 'wp-blog-header.php',
367
+ 'wp-comments-post.php',
368
+ 'wp-config.php',
369
+ 'wp-config-sample.php',
370
+ 'wp-cron.php',
371
+ 'wp-links-opml.php',
372
+ 'wp-load.php',
373
+ 'wp-login.php',
374
+ 'wp-mail.php',
375
+ 'wp-pass.php',
376
+ 'wp-register.php',
377
+ 'wp-settings.php',
378
+ 'wp-signup.php',
379
+ 'wp-trackback.php',
380
+ 'xmlrpc.php',
381
+ );
382
+ foreach ( $nodes as $key => $node ) {
383
+ if ( MainWP_Helper::startsWith( $node, ABSPATH . WPINC ) ) {
384
+ unset( $nodes[ $key ] );
385
+ } else if ( MainWP_Helper::startsWith( $node, ABSPATH . basename( admin_url( '' ) ) ) ) {
386
+ unset( $nodes[ $key ] );
387
+ } else {
388
+ foreach ( $coreFiles as $coreFile ) {
389
+ if ( ABSPATH . $coreFile === $node ) {
390
+ unset( $nodes[ $key ] );
391
+ }
392
+ }
393
+ }
394
+ }
395
+ unset( $coreFiles );
396
+ }
397
+
398
+ $db_files = $this->createBackupDB( dirname( $filepath ) . DIRECTORY_SEPARATOR . 'dbBackup' );
399
+ $error = false;
400
+ foreach ( $db_files as $db_file ) {
401
+ if ( 0 === ( $rslt = $this->zip->add( $db_file, PCLZIP_OPT_REMOVE_PATH, dirname( $db_file ), PCLZIP_OPT_ADD_PATH, basename( WP_CONTENT_DIR ) ) ) ) {
402
+ $error = true;
403
+ }
404
+ }
405
+
406
+ foreach ( $db_files as $db_file ) {
407
+ @unlink( $db_file );
408
+ }
409
+ if ( ! $error ) {
410
+ foreach ( $nodes as $node ) {
411
+ if ( null === $excludes || ! in_array( str_replace( ABSPATH, '', $node ), $excludes ) ) {
412
+ if ( is_dir( $node ) ) {
413
+ if ( ! $this->pclZipAddDir( $node, $excludes ) ) {
414
+ $error = true;
415
+ break;
416
+ }
417
+ } else if ( is_file( $node ) ) {
418
+ if ( 0 === ( $rslt = $this->zip->add( $node, PCLZIP_OPT_REMOVE_PATH, ABSPATH ) ) ) {
419
+ $error = true;
420
+ break;
421
+ }
422
+ }
423
+ }
424
+ }
425
+ }
426
+
427
+ if ( $addConfig ) {
428
+ global $wpdb;
429
+ $string = base64_encode( serialize( array(
430
+ 'siteurl' => get_option( 'siteurl' ),
431
+ 'home' => get_option( 'home' ),
432
+ 'abspath' => ABSPATH,
433
+ 'prefix' => $wpdb->prefix,
434
+ 'lang' => WPLANG,
435
+ ) ) );
436
+
437
+ $this->addFileFromStringToPCLZip( 'clone/config.txt', $string, $filepath );
438
+ }
439
+
440
+ if ( $error ) {
441
+ // @codingStandardsIgnoreStart
442
+ @unlink( $filepath );
443
+ // @codingStandardsIgnoreEnd
444
+
445
+ return false;
446
+ }
447
+
448
+ return true;
449
+ }
450
+
451
+ function copy_dir( $nodes, $excludes, $backupfolder, $excludenonwp, $root ) {
452
+ if ( ! is_array( $nodes ) ) {
453
+ return;
454
+ }
455
+
456
+ foreach ( $nodes as $node ) {
457
+ if ( $excludenonwp && is_dir( $node ) ) {
458
+ if ( ! MainWP_Helper::startsWith( $node, WP_CONTENT_DIR ) && ! MainWP_Helper::startsWith( $node, ABSPATH . 'wp-admin' ) && ! MainWP_Helper::startsWith( $node, ABSPATH . WPINC ) ) {
459
+ continue;
460
+ }
461
+ }
462
+
463
+ if ( ! MainWP_Helper::inExcludes( $excludes, str_replace( ABSPATH, '', $node ) ) ) {
464
+ if ( is_dir( $node ) ) {
465
+ if ( ! file_exists( str_replace( ABSPATH, $backupfolder, $node ) ) ) {
466
+ // @codingStandardsIgnoreStart
467
+ @mkdir( str_replace( ABSPATH, $backupfolder, $node ) );
468
+ // @codingStandardsIgnoreEnd
469
+ }
470
+
471
+ $newnodes = glob( $node . DIRECTORY_SEPARATOR . '*' );
472
+ $this->copy_dir( $newnodes, $excludes, $backupfolder, $excludenonwp, false );
473
+ unset( $newnodes );
474
+ } else if ( is_file( $node ) ) {
475
+ if ( $this->excludeZip && MainWP_Helper::endsWith( $node, '.zip' ) ) {
476
+ continue;
477
+ }
478
+
479
+ // @codingStandardsIgnoreStart
480
+ @copy( $node, str_replace( ABSPATH, $backupfolder, $node ) );
481
+ // @codingStandardsIgnoreEnd
482
+ }
483
+ }
484
+ }
485
+ }
486
+
487
+ public function createZipPclFullBackup2( $filepath, $excludes, $addConfig, $includeCoreFiles, $excludezip, $excludenonwp ) {
488
+ //Create backup folder
489
+ $backupFolder = dirname( $filepath ) . DIRECTORY_SEPARATOR . 'backup' . DIRECTORY_SEPARATOR;
490
+ // @codingStandardsIgnoreStart
491
+ @mkdir( $backupFolder );
492
+ // @codingStandardsIgnoreEnd
493
+
494
+ //Create DB backup
495
+ $db_files = $this->createBackupDB( $backupFolder . 'dbBackup' );
496
+
497
+ //Copy installation to backup folder
498
+ $nodes = glob( ABSPATH . '*' );
499
+ if ( ! $includeCoreFiles ) {
500
+ $coreFiles = array(
501
+ 'favicon.ico',
502
+ 'index.php',
503
+ 'license.txt',
504
+ 'readme.html',
505
+ 'wp-activate.php',
506
+ 'wp-app.php',
507
+ 'wp-blog-header.php',
508
+ 'wp-comments-post.php',
509
+ 'wp-config.php',
510
+ 'wp-config-sample.php',
511
+ 'wp-cron.php',
512
+ 'wp-links-opml.php',
513
+ 'wp-load.php',
514
+ 'wp-login.php',
515
+ 'wp-mail.php',
516
+ 'wp-pass.php',
517
+ 'wp-register.php',
518
+ 'wp-settings.php',
519
+ 'wp-signup.php',
520
+ 'wp-trackback.php',
521
+ 'xmlrpc.php',
522
+ );
523
+ foreach ( $nodes as $key => $node ) {
524
+ if ( MainWP_Helper::startsWith( $node, ABSPATH . WPINC ) ) {
525
+ unset( $nodes[ $key ] );
526
+ } else if ( MainWP_Helper::startsWith( $node, ABSPATH . basename( admin_url( '' ) ) ) ) {
527
+ unset( $nodes[ $key ] );
528
+ } else {
529
+ foreach ( $coreFiles as $coreFile ) {
530
+ if ( ABSPATH . $coreFile == $node ) {
531
+ unset( $nodes[ $key ] );
532
+ }
533
+ }
534
+ }
535
+ }
536
+ unset( $coreFiles );
537
+ }
538
+ $this->copy_dir( $nodes, $excludes, $backupFolder, $excludenonwp, true );
539
+ // to fix bug wrong folder
540
+ // @codingStandardsIgnoreStart
541
+
542
+ foreach ( $db_files as $db_file ) {
543
+ @copy( $db_file, $backupFolder . basename( WP_CONTENT_DIR ) . '/' . basename( $db_file ) );
544
+ @unlink( $db_file );
545
+ }
546
+ // @codingStandardsIgnoreEnd
547
+ unset( $nodes );
548
+
549
+ //Zip this backup folder..
550
+ require_once( ABSPATH . 'wp-admin/includes/class-pclzip.php' );
551
+ $this->zip = new PclZip( $filepath );
552
+ $this->zip->create( $backupFolder, PCLZIP_OPT_REMOVE_PATH, $backupFolder );
553
+ if ( $addConfig ) {
554
+ global $wpdb;
555
+ $string = base64_encode( serialize( array(
556
+ 'siteurl' => get_option( 'siteurl' ),
557
+ 'home' => get_option( 'home' ),
558
+ 'abspath' => ABSPATH,
559
+ 'prefix' => $wpdb->prefix,
560
+ 'lang' => WPLANG,
561
+ ) ) );
562
+
563
+ $this->addFileFromStringToPCLZip( 'clone/config.txt', $string, $filepath );
564
+ }
565
+ //Remove backup folder
566
+ MainWP_Helper::delete_dir( $backupFolder );
567
+
568
+ return true;
569
+ }
570
+
571
+ /**
572
+ * Recursive add directory for default PHP zip library
573
+ */
574
+ public function zipAddDir( $path, $excludes ) {
575
+ $this->zip->addEmptyDir( str_replace( ABSPATH, '', $path ) );
576
+
577
+ if ( file_exists( rtrim( $path, '/' ) . '/.htaccess' ) ) {
578
+ $this->addFileToZip( rtrim( $path, '/' ) . '/.htaccess', rtrim( str_replace( ABSPATH, '', $path ), '/' ) . '/mainwp-htaccess' );
579
+ }
580
+
581
+ $iterator = new RecursiveIteratorIterator( new RecursiveDirectoryIterator( $path ), RecursiveIteratorIterator::SELF_FIRST );
582
+
583
+ foreach ( $iterator as $path ) {
584
+ $name = $path->__toString();
585
+ if ( ( '.' === basename( $name ) ) || ( '..' === basename( $name ) ) ) {
586
+ continue;
587
+ }
588
+
589
+ if ( ! MainWP_Helper::inExcludes( $excludes, str_replace( ABSPATH, '', $name ) ) ) {
590
+ if ( $path->isDir() ) {
591
+ $this->zipAddDir( $name, $excludes );
592
+ } else {
593
+ $this->addFileToZip( $name, str_replace( ABSPATH, '', $name ) );
594
+ }
595
+ }
596
+ $name = null;
597
+ unset( $name );
598
+ }
599
+
600
+ $iterator = null;
601
+ unset( $iterator );
602
+
603
+ // $nodes = glob(rtrim($path, '/') . '/*');
604
+ // if (empty($nodes)) return true;
605
+ //
606
+ // foreach ($nodes as $node)
607
+ // {
608
+ // if (!MainWP_Helper::inExcludes($excludes, str_replace(ABSPATH, '', $node)))
609
+ // {
610
+ // if (is_dir($node))
611
+ // {
612
+ // $this->zipAddDir($node, $excludes);
613
+ // }
614
+ // else if (is_file($node))
615
+ // {
616
+ // $this->addFileToZip($node, str_replace(ABSPATH, '', $node));
617
+ // }
618
+ // }
619
+ // }
620
+ }
621
+
622
+ public function pclZipAddDir( $path, $excludes ) {
623
+ $error = false;
624
+ $nodes = glob( rtrim( $path, '/' ) . '/*' );
625
+ if ( empty( $nodes ) ) {
626
+ return true;
627
+ }
628
+
629
+ foreach ( $nodes as $node ) {
630
+ if ( null === $excludes || ! in_array( str_replace( ABSPATH, '', $node ), $excludes ) ) {
631
+ if ( is_dir( $node ) ) {
632
+ if ( ! $this->pclZipAddDir( $node, $excludes ) ) {
633
+ $error = true;
634
+ break;
635
+ }
636
+ } else if ( is_file( $node ) ) {
637
+ if ( 0 === ( $rslt = $this->zip->add( $node, PCLZIP_OPT_REMOVE_PATH, ABSPATH ) ) ) {
638
+ $error = true;
639
+ break;
640
+ }
641
+ }
642
+ }
643
+ }
644
+
645
+ return ! $error;
646
+ }
647
+
648
+ function addFileFromStringToZip( $file, $string ) {
649
+ return $this->zip->addFromString( $file, $string );
650
+ }
651
+
652
+ public function addFileFromStringToPCLZip( $file, $string, $filepath ) {
653
+ $file = preg_replace( '/(?:\.|\/)*(.*)/', '$1', $file );
654
+ $localpath = dirname( $file );
655
+ $tmpfilename = dirname( $filepath ) . '/' . basename( $file );
656
+ if ( false !== file_put_contents( $tmpfilename, $string ) ) {
657
+ $this->zip->delete( PCLZIP_OPT_BY_NAME, $file );
658
+ $add = $this->zip->add( $tmpfilename,
659
+ PCLZIP_OPT_REMOVE_PATH, dirname( $filepath ),
660
+ PCLZIP_OPT_ADD_PATH, $localpath );
661
+ unlink( $tmpfilename );
662
+ if ( ! empty( $add ) ) {
663
+ return true;
664
+ }
665
+ }
666
+
667
+ return false;
668
+ }
669
+
670
+ protected $gcCnt = 0;
671
+ protected $testContent;
672
+
673
+ function addFileToZip( $path, $zipEntryName ) {
674
+ if ( time() - $this->lastRun > 20 ) {
675
+ // @codingStandardsIgnoreStart
676
+ @set_time_limit( $this->timeout );
677
+ // @codingStandardsIgnoreEnd
678
+ $this->lastRun = time();
679
+ }
680
+
681
+ if ( $this->excludeZip && MainWP_Helper::endsWith( $path, '.zip' ) ) {
682
+ return false;
683
+ }
684
+
685
+ // this would fail with status ZIPARCHIVE::ER_OPEN
686
+ // after certain number of files is added since
687
+ // ZipArchive internally stores the file descriptors of all the
688
+ // added files and only on close writes the contents to the ZIP file
689
+ // see: http://bugs.php.net/bug.php?id=40494
690
+ // and: http://pecl.php.net/bugs/bug.php?id=9443
691
+ // return $zip->addFile( $path, $zipEntryName );
692
+
693
+ $this->zipArchiveSizeCount += filesize( $path );
694
+ $this->gcCnt ++;
695
+
696
+ //5 mb limit!
697
+ if ( ! $this->loadFilesBeforeZip || ( filesize( $path ) > 5 * 1024 * 1024 ) ) {
698
+ $this->zipArchiveFileCount ++;
699
+ $added = $this->zip->addFile( $path, $zipEntryName );
700
+ } else {
701
+ $this->zipArchiveFileCount ++;
702
+
703
+ $this->testContent = file_get_contents( $path );
704
+ if ( $this->testContent === false ) {
705
+ return false;
706
+ }
707
+ $added = $this->zip->addFromString( $zipEntryName, $this->testContent );
708
+ }
709
+
710
+ if ( $this->gcCnt > 20 ) {
711
+ // @codingStandardsIgnoreStart
712
+ if ( function_exists( 'gc_enable' ) ) {
713
+ @gc_enable();
714
+ }
715
+ if ( function_exists( 'gc_collect_cycles' ) ) {
716
+ @gc_collect_cycles();
717
+ }
718
+ // @codingStandardsIgnoreEnd
719
+ $this->gcCnt = 0;
720
+ }
721
+
722
+ //Over limits?
723
+ if ( ( ( $this->file_descriptors > 0 ) && ( $this->zipArchiveFileCount > $this->file_descriptors ) ) ) { // || $this->zipArchiveSizeCount >= (31457280 * 2))
724
+ $this->zip->close();
725
+ $this->zip = null;
726
+ unset( $this->zip );
727
+ // @codingStandardsIgnoreStart
728
+ if ( function_exists( 'gc_enable' ) ) {
729
+ @gc_enable();
730
+ }
731
+ if ( function_exists( 'gc_collect_cycles' ) ) {
732
+ @gc_collect_cycles();
733
+ }
734
+ // @codingStandardsIgnoreEnd
735
+ $this->zip = new ZipArchive();
736
+ $this->zip->open( $this->zipArchiveFileName );
737
+ $this->zipArchiveFileCount = 0;
738
+ $this->zipArchiveSizeCount = 0;
739
+ }
740
+
741
+ return $added;
742
+ }
743
+
744
+ public function createZipConsoleFullBackup( $filepath, $excludes, $addConfig, $includeCoreFiles, $excludezip, $excludenonwp ) {
745
+ // @TODO to work with 'zip' from system if PHP Zip library not available
746
+ //system('zip');
747
+ return false;
748
+ }
749
+
750
+ public function createBackupDB( $filepath_prefix, $archiveExt = false, &$archiver = null ) {
751
+ $timeout = 20 * 60 * 60; //20minutes
752
+ // @codingStandardsIgnoreStart
753
+ @set_time_limit( $timeout );
754
+ @ini_set( 'max_execution_time', $timeout );
755
+ $mem = '512M';
756
+ @ini_set( 'memory_limit', $mem );
757
+ // @codingStandardsIgnoreEnd
758
+
759
+ /** @var $wpdb wpdb */
760
+ global $wpdb;
761
+
762
+ $db_files = array();
763
+ //Get all the tables
764
+ $tables_db = $wpdb->get_results( 'SHOW TABLES FROM `' . DB_NAME . '`', ARRAY_N );
765
+ foreach ( $tables_db as $curr_table ) {
766
+ if ( null !== $archiver ) {
767
+ $archiver->updatePidFile();
768
+ }
769
+
770
+ $table = $curr_table[0];
771
+
772
+ $currentfile = $filepath_prefix . '-' . MainWP_Helper::sanitize_filename( $table ) . '.sql';
773
+ $db_files[] = $currentfile;
774
+ if ( file_exists( $currentfile ) ) {
775
+ continue;
776
+ }
777
+ $fh = fopen( $currentfile . '.tmp', 'w' ); //or error;
778
+
779
+ fwrite( $fh, "\n\n" . 'DROP TABLE IF EXISTS ' . $table . ';' );
780
+ //todo fix this
781
+ //$table_create = $wpdb->get_row( $wpdb->prepare( 'SHOW CREATE TABLE %s', $table ), ARRAY_N );
782
+ $table_create = $wpdb->get_row( 'SHOW CREATE TABLE ' . $table, ARRAY_N );
783
+ fwrite( $fh, "\n" . $table_create[1] . ";\n\n" );
784
+
785
+ // @codingStandardsIgnoreStart
786
+ $rows = @MainWP_Child_DB::_query( 'SELECT * FROM ' . $table, $wpdb->dbh );
787
+ // @codingStandardsIgnoreEnd
788
+
789
+ if ( $rows ) {
790
+ $i = 0;
791
+ $table_insert = 'INSERT INTO `' . $table . '` VALUES (';
792
+
793
+ // @codingStandardsIgnoreStart
794
+ while ( $row = @MainWP_Child_DB::fetch_array( $rows ) ) {
795
+ // @codingStandardsIgnoreEnd
796
+ $query = $table_insert;
797
+ foreach ( $row as $value ) {
798
+ $query .= '"' . MainWP_Child_DB::real_escape_string( $value ) . '", ';
799
+ }
800
+ $query = trim( $query, ', ' ) . ');';
801
+
802
+ fwrite( $fh, "\n" . $query );
803
+ $i ++;
804
+
805
+ if ( $i >= 50 ) {
806
+ fflush( $fh );
807
+ $i = 0;
808
+ }
809
+
810
+ $query = null;
811
+ $row = null;
812
+ }
813
+ }
814
+ $rows = null;
815
+ fflush( $fh );
816
+ fclose( $fh );
817
+ rename( $currentfile . '.tmp', $currentfile );
818
+ }
819
+
820
+ fclose( fopen( $filepath_prefix . '.sql', 'w' ) );
821
+ $db_files[] = $filepath_prefix . '.sql';
822
+
823
+ $archivefilePath = null;
824
+ if ( false !== $archiveExt ) {
825
+ $archivefilePath = $filepath_prefix . '.sql.' . $archiveExt;
826
+
827
+ if ( 'zip' === $archiveExt ) {
828
+ $this->archiver = null;
829
+ } else {
830
+ $this->archiver = new Tar_Archiver( $this, $archiveExt );
831
+ }
832
+
833
+ if ( $this->zipFile( $db_files, $archivefilePath ) && file_exists( $archivefilePath ) ) {
834
+ foreach ( $db_files as $db_file ) {
835
+ @unlink( $db_file );
836
+ }
837
+ } else {
838
+ //todo: throw exception!
839
+ }
840
+ }
841
+
842
+
843
+ return ( false !== $archiveExt ? array( 'filepath' => $archivefilePath ) : $db_files );
844
+ }
845
+ }
class/class-mainwp-child-back-up-buddy.php ADDED
@@ -0,0 +1,2934 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class MainWP_Child_Back_Up_Buddy {
4
+ public static $instance = null;
5
+ public $plugin_translate = 'mainwp-child';
6
+ public $is_backupbuddy_installed = false;
7
+
8
+ static function Instance() {
9
+ if ( null === MainWP_Child_Back_Up_Buddy::$instance ) {
10
+ MainWP_Child_Back_Up_Buddy::$instance = new MainWP_Child_Back_Up_Buddy();
11
+ }
12
+ return MainWP_Child_Back_Up_Buddy::$instance;
13
+ }
14
+
15
+ public function __construct() {
16
+ // To fix bug run dashboard on local machine
17
+ //if ( is_plugin_active( 'backupbuddy/backupbuddy.php' )) {
18
+ if ( class_exists('pb_backupbuddy')) {
19
+ $this->is_backupbuddy_installed = true;
20
+ }
21
+
22
+ if (!$this->is_backupbuddy_installed) {
23
+ return;
24
+ }
25
+
26
+ if ( get_option( 'mainwp_backupbuddy_ext_enabled' ) !== 'Y' ) {
27
+ return;
28
+ }
29
+
30
+ add_action( 'wp_ajax_mainwp_backupbuddy_download_archive', array( $this, 'download_archive' ) );
31
+ add_action( 'mainwp_child_site_stats', array( $this, 'do_site_stats' ) );
32
+
33
+ if ( get_option( 'mainwp_backupbuddy_hide_plugin' ) === 'hide' ) {
34
+ add_filter( 'all_plugins', array( $this, 'all_plugins' ) );
35
+ add_action( 'admin_menu', array( $this, 'admin_menu' ) );
36
+ add_filter( 'site_transient_update_plugins', array( &$this, 'remove_update_nag' ) );
37
+ }
38
+ }
39
+
40
+ function remove_update_nag( $value ) {
41
+ if ( isset( $_POST['mainwpsignature'] ) ) {
42
+ return $value;
43
+ }
44
+ if ( isset( $value->response['backupbuddy/backupbuddy.php'] ) ) {
45
+ unset( $value->response['backupbuddy/backupbuddy.php'] );
46
+ }
47
+
48
+ return $value;
49
+ }
50
+
51
+
52
+
53
+ public function all_plugins( $plugins ) {
54
+ foreach ( $plugins as $key => $value ) {
55
+ $plugin_slug = basename( $key, '.php' );
56
+ if ( 'backupbuddy' === $plugin_slug ) {
57
+ unset( $plugins[ $key ] );
58
+ }
59
+ }
60
+
61
+ return $plugins;
62
+ }
63
+
64
+ public function admin_menu() {
65
+ global $submenu;
66
+ remove_menu_page( 'pb_backupbuddy_backup' );
67
+
68
+ if ( false !== stripos( $_SERVER['REQUEST_URI'], 'admin.php?page=pb_backupbuddy_' ) ) {
69
+ wp_redirect( get_option( 'siteurl' ) . '/wp-admin/index.php' );
70
+ exit();
71
+ }
72
+ }
73
+
74
+
75
+ function do_site_stats() {
76
+ if (has_action('mainwp_child_reports_log')) {
77
+ do_action( 'mainwp_child_reports_log', 'backupbuddy');
78
+ } else {
79
+ $this->do_reports_log('backupbuddy');
80
+ }
81
+ }
82
+
83
+ function do_reports_log($ext = '') {
84
+ if ($ext !== 'backupbuddy')
85
+ return;
86
+
87
+ if (!$this->is_backupbuddy_installed) {
88
+ return;
89
+ }
90
+
91
+ if ( ! class_exists( 'backupbuddy_core' ) ) {
92
+ require_once( pb_backupbuddy::plugin_path() . '/classes/core.php' );
93
+ }
94
+
95
+ // Backup type.
96
+ $pretty_type = array(
97
+ 'full' => 'Full',
98
+ 'db' => 'Database',
99
+ 'files' => 'Files',
100
+ );
101
+
102
+ $recentBackups_list = glob( backupbuddy_core::getLogDirectory() . 'fileoptions/*.txt' );
103
+
104
+ foreach( $recentBackups_list as $backup_fileoptions ) {
105
+
106
+ require_once( pb_backupbuddy::plugin_path() . '/classes/fileoptions.php' );
107
+ pb_backupbuddy::status( 'details', 'Fileoptions instance #1.' );
108
+ $backup = new pb_backupbuddy_fileoptions( $backup_fileoptions, $read_only = true );
109
+ if ( true !== ( $result = $backup->is_ok() ) ) {
110
+ continue;
111
+ }
112
+
113
+ $backup = &$backup->options;
114
+
115
+ if ( !isset( $backup['serial'] ) || ( $backup['serial'] == '' ) ) {
116
+ continue;
117
+ }
118
+
119
+ if ( ( $backup['finish_time'] >= $backup['start_time'] ) && ( 0 != $backup['start_time'] ) ) {
120
+ // it is ok
121
+ } else {
122
+ continue;
123
+ }
124
+
125
+ if ( isset( $backup['profile'] ) && isset( $backup['profile']['type'] ) ) {
126
+ $backupType = pb_backupbuddy::$format->prettify( $backup['profile']['type'], $pretty_type );
127
+ } else {
128
+ $backupType = backupbuddy_core::pretty_backup_type( backupbuddy_core::getBackupTypeFromFile( $backup['archive_file'] ) );
129
+ }
130
+
131
+ if ( '' == $backupType ) {
132
+ $backupType = 'Unknown';
133
+ }
134
+
135
+ $finish_time = $backup['finish_time'];
136
+ $message = 'BackupBuddy ' . $backupType . ' finished';
137
+ if (!empty($finish_time)) {
138
+ do_action( 'mainwp_reports_backupbuddy_backup', $message, $backupType, $finish_time);
139
+ MainWP_Helper::update_lasttime_backup('backupbuddy', $finish_time); // to support backup before update feature
140
+ }
141
+ }
142
+ }
143
+
144
+ public function action() {
145
+ $information = array();
146
+ if ( ! $this->is_backupbuddy_installed ) {
147
+ MainWP_Helper::write( array( 'error' => __( 'Please install the BackupBuddy plugin on the child site.', $this->plugin_translate ) ) );
148
+ }
149
+
150
+ if (get_option( 'mainwp_backupbuddy_ext_enabled' ) !== 'Y')
151
+ MainWP_Helper::update_option( 'mainwp_backupbuddy_ext_enabled', 'Y' );
152
+
153
+ if ( ! class_exists( 'backupbuddy_core' ) ) {
154
+ require_once( pb_backupbuddy::plugin_path() . '/classes/core.php' );
155
+ }
156
+
157
+ if ( !isset( pb_backupbuddy::$options ) ) {
158
+ pb_backupbuddy::load();
159
+ }
160
+
161
+ if ( isset( $_POST['mwp_action'] ) ) {
162
+ switch ( $_POST['mwp_action'] ) {
163
+ case 'set_showhide':
164
+ $information = $this->set_showhide();
165
+ break;
166
+ case 'save_settings':
167
+ $information = $this->save_settings();
168
+ break;
169
+ case 'reset_defaults':
170
+ $information = $this->reset_defaults();
171
+ break;
172
+ case 'get_notifications':
173
+ $information = $this->get_notifications();
174
+ break;
175
+ case 'schedules_list':
176
+ $information = $this->schedules_list();
177
+ break;
178
+ case 'run_scheduled_backup':
179
+ $information = $this->run_scheduled_backup();
180
+ break;
181
+ case 'save_scheduled_backup':
182
+ $information = $this->save_scheduled_backup();
183
+ break;
184
+ case 'delete_scheduled_backup':
185
+ $information = $this->delete_scheduled_backup();
186
+ break;
187
+ case 'save_profile':
188
+ $information = $this->save_profile();
189
+ break;
190
+ case 'delete_profile':
191
+ $information = $this->delete_profile();
192
+ break;
193
+ case 'delete_backup':
194
+ $information = $this->delete_backup();
195
+ break;
196
+ case 'backup_list':
197
+ $information = $this->backup_list();
198
+ break;
199
+ case 'save_note':
200
+ $information = $this->save_note();
201
+ break;
202
+ case 'get_hash':
203
+ $information = $this->get_hash();
204
+ break;
205
+ case 'zip_viewer':
206
+ $information = $this->zip_viewer();
207
+ break;
208
+ case 'exclude_tree':
209
+ $information = $this->exclude_tree();
210
+ break;
211
+ case 'restore_file_view':
212
+ $information = $this->restore_file_view();
213
+ break;
214
+ case 'restore_file_restore':
215
+ $information = $this->restore_file_restore();
216
+ break;
217
+ case 'view_log':
218
+ $information = $this->view_log();
219
+ break;
220
+ case 'view_detail':
221
+ $information = $this->view_detail();
222
+ break;
223
+ case 'reset_integrity':
224
+ $information = $this->reset_integrity();
225
+ break;
226
+ case 'download_archive':
227
+ $information = $this->download_archive();
228
+ break;
229
+ case 'create_backup':
230
+ $information = $this->create_backup();
231
+ break;
232
+ case 'start_backup':
233
+ $information = $this->start_backup();
234
+ break;
235
+ case 'backup_status':
236
+ $information = $this->backup_status();
237
+ break;
238
+ case 'stop_backup':
239
+ $information = $this->stop_backup();
240
+ break;
241
+ case 'remote_save':
242
+ $information = $this->remote_save();
243
+ break;
244
+ case 'remote_delete':
245
+ $information = $this->remote_delete();
246
+ break;
247
+ case 'remote_send':
248
+ $information = $this->remote_send();
249
+ break;
250
+ case 'remote_list':
251
+ $information = $this->remote_list();
252
+ break;
253
+ case 'get_main_log':
254
+ $information = $this->get_main_log();
255
+ break;
256
+ case 'settings_other':
257
+ $information = $this->settings_other();
258
+ break;
259
+ case 'malware_scan':
260
+ $information = $this->malware_scan();
261
+ break;
262
+ case 'live_setup':
263
+ $information = $this->live_setup();
264
+ break;
265
+ case 'live_save_settings':
266
+ $information = $this->live_save_settings();
267
+ break;
268
+ case 'live_action_disconnect':
269
+ $information = $this->live_action_disconnect();
270
+ break;
271
+ case 'live_action':
272
+ $information = $this->live_action();
273
+ break;
274
+ case 'download_troubleshooting':
275
+ $information = $this->download_troubleshooting();
276
+ break;
277
+ case 'get_live_backups':
278
+ $information = $this->get_live_backups();
279
+ break;
280
+ case 'copy_file_to_local':
281
+ $information = $this->copy_file_to_local();
282
+ break;
283
+ case 'delete_file_backup':
284
+ $information = $this->delete_file_backup();
285
+ break;
286
+ case 'get_live_stats':
287
+ $information = $this->get_live_stats();
288
+ break;
289
+ case 'load_products_license':
290
+ $information = $this->load_products_license();
291
+ break;
292
+ case 'save_license_settings':
293
+ $information = $this->save_license_settings();
294
+ break;
295
+ case 'activate_package':
296
+ $information = $this->activate_package();
297
+ break;
298
+ case 'deactivate_package':
299
+ $information = $this->deactivate_package();
300
+ break;
301
+ }
302
+ }
303
+ MainWP_Helper::write( $information );
304
+ }
305
+
306
+
307
+ function set_showhide() {
308
+ $hide = isset( $_POST['showhide'] ) && ( 'hide' === $_POST['showhide'] ) ? 'hide' : '';
309
+ MainWP_Helper::update_option( 'mainwp_backupbuddy_hide_plugin', $hide );
310
+ $information['result'] = 'SUCCESS';
311
+ return $information;
312
+ }
313
+
314
+ function save_settings() {
315
+
316
+ $type = isset($_POST['type']) ? $_POST['type'] : '';
317
+
318
+ if ($type !== 'general_settings' && $type !== 'advanced_settings' && $type !== 'all' ) {
319
+ return array('error' => __('Invalid data!'), 'extra' => 'Invalid settings data!');
320
+ }
321
+
322
+ $filter_advanced_settings = array(
323
+ 'backup_reminders',
324
+ 'archive_name_format',
325
+ 'archive_name_profile',
326
+ 'lock_archives_directory',
327
+ 'include_importbuddy',
328
+ 'default_backup_tab',
329
+ 'disable_localization',
330
+ 'limit_single_cron_per_pass',
331
+ 'use_internal_cron',
332
+ 'cron_request_timeout_override',
333
+ 'remote_send_timeout_retries',
334
+ 'hide_live',
335
+ 'hide_dashboard_widget',
336
+ 'set_greedy_execution_time',
337
+ 'archive_limit_size_big',
338
+ 'max_execution_time',
339
+ 'log_level',
340
+ 'save_backup_sum_log',
341
+ 'max_site_log_size',
342
+ 'max_send_stats_days',
343
+ 'max_send_stats_count',
344
+ 'max_notifications_age_days',
345
+ 'backup_mode',
346
+ 'delete_archives_pre_backup',
347
+ 'disable_https_local_ssl_verify',
348
+ 'prevent_flush',
349
+ 'save_comment_meta',
350
+ 'integrity_check', // profiles#0
351
+ 'backup_cron_rescheduling',
352
+ 'skip_spawn_cron_call',
353
+ 'backup_cron_passed_force_time',
354
+ 'php_runtime_test_minimum_interval',
355
+ 'php_memory_test_minimum_interval',
356
+ 'database_method_strategy',
357
+ 'skip_database_dump', // profiles#0
358
+ 'breakout_tables',
359
+ 'force_single_db_file',
360
+ 'phpmysqldump_maxrows',
361
+ 'ignore_command_length_check',
362
+ 'compression',
363
+ 'zip_method_strategy',
364
+ 'alternative_zip_2',
365
+ 'zip_build_strategy',
366
+ 'zip_step_period',
367
+ 'zip_burst_gap',
368
+ 'zip_min_burst_content',
369
+ 'zip_max_burst_content',
370
+ 'disable_zipmethod_caching',
371
+ 'ignore_zip_warnings',
372
+ 'ignore_zip_symlinks',
373
+ );
374
+
375
+
376
+ $filter_general_settings = array(
377
+ 'importbuddy_pass_hash',
378
+ 'importbuddy_pass_length',
379
+ 'backup_directory',
380
+ 'role_access',
381
+ 'archive_limit_age',
382
+ 'archive_limit_full',
383
+ 'archive_limit',
384
+ 'archive_limit_size',
385
+ 'archive_limit_db',
386
+ 'archive_limit_files',
387
+ 'title_multisite',
388
+ 'multisite_export',
389
+ 'backup_nonwp_tables', // profiles#0
390
+ 'mysqldump_additional_includes', // profiles#0
391
+ 'mysqldump_additional_excludes', // profiles#0
392
+ 'excludes', // profiles#0
393
+ 'email_notify_scheduled_start',
394
+ 'email_notify_scheduled_start_subject',
395
+ 'email_notify_scheduled_start_body',
396
+ 'email_notify_scheduled_complete',
397
+ 'email_notify_scheduled_complete_subject',
398
+ 'email_notify_scheduled_complete_body',
399
+ 'email_notify_send_finish',
400
+ 'email_notify_send_finish_subject',
401
+ 'email_notify_send_finish_body',
402
+ 'no_new_backups_error_days',
403
+ 'email_notify_error',
404
+ 'email_notify_error_subject',
405
+ 'email_notify_error_body',
406
+ 'email_return'
407
+ );
408
+
409
+ $filter_profile0_values = array(
410
+ 'mysqldump_additional_includes',
411
+ 'mysqldump_additional_excludes',
412
+ 'excludes',
413
+ 'integrity_check',
414
+ 'skip_database_dump',
415
+ 'backup_nonwp_tables'
416
+ );
417
+
418
+ $settings = unserialize(base64_decode($_POST['options']));
419
+
420
+ $save_settings = array();
421
+
422
+ if (is_array($settings)) {
423
+ if ($type === 'all' || 'general_settings' === $type) {
424
+ foreach($filter_general_settings as $field) {
425
+ if(isset($settings[$field])) {
426
+ $save_settings[$field] = $settings[$field];
427
+ }
428
+ }
429
+ }
430
+
431
+ if ($type === 'all' || 'advanced_settings' === $type) {
432
+ foreach($filter_advanced_settings as $field) {
433
+ if(isset($settings[$field])) {
434
+ $save_settings[$field] = $settings[$field];
435
+ }
436
+ }
437
+ }
438
+ }
439
+
440
+ if (!empty($save_settings)) {
441
+ $newOptions = pb_backupbuddy::$options;
442
+
443
+ foreach($newOptions as $key => $val) {
444
+ if (isset($save_settings[$key])) {
445
+ $newOptions[$key] = $save_settings[$key];
446
+ }
447
+ }
448
+
449
+ if (isset($newOptions['profiles']) && isset($newOptions['profiles'][0])) {
450
+ foreach ($filter_profile0_values as $field) {
451
+ if (isset($settings[$field])) {
452
+ $newOptions['profiles'][0][$field] = $settings[$field];
453
+ }
454
+ }
455
+ }
456
+
457
+ if ('general_settings' === $type || 'all' === $type ) {
458
+ $newOptions['importbuddy_pass_hash_confirm'] = '';
459
+ }
460
+
461
+ global $wpdb;
462
+ $option = 'pb_' . pb_backupbuddy::settings( 'slug' );
463
+ $newOptions = sanitize_option( $option, $newOptions );
464
+ $newOptions = maybe_serialize( $newOptions );
465
+
466
+ add_site_option( $option, $newOptions, '', 'no'); // 'No' prevents autoload if we wont always need the data loaded.
467
+ $wpdb->update( $wpdb->options, array( 'option_value' => $newOptions ), array( 'option_name' => $option ) );
468
+
469
+ $information['backupDirectoryDefault'] = backupbuddy_core::_getBackupDirectoryDefault();
470
+ $information['result'] = 'SUCCESS';
471
+ }
472
+
473
+ return $information;
474
+ }
475
+
476
+ function reset_defaults() {
477
+ // Keep log serial.
478
+ $old_log_serial = pb_backupbuddy::$options['log_serial'];
479
+
480
+ $keepDestNote = '';
481
+ $remote_destinations = pb_backupbuddy::$options['remote_destinations'];
482
+ pb_backupbuddy::$options = pb_backupbuddy::settings( 'default_options' );
483
+ if ( '1' == $_POST['keep_destinations'] ) {
484
+ pb_backupbuddy::$options['remote_destinations'] = $remote_destinations;
485
+ $keepDestNote = ' ' . __( 'Remote destination settings were not reset.', 'mainwp-child' );
486
+ }
487
+
488
+ // Replace log serial.
489
+ pb_backupbuddy::$options['log_serial'] = $old_log_serial;
490
+
491
+ pb_backupbuddy::save();
492
+
493
+ backupbuddy_core::verify_directories( $skipTempGeneration = true ); // Re-verify directories such as backup dir, temp, etc.
494
+ $resetNote = __( 'Plugin settings have been reset to defaults.', 'mainwp-child' );
495
+ backupbuddy_core::addNotification( 'settings_reset', 'Plugin settings reset', $resetNote . $keepDestNote );
496
+
497
+ $information['message'] = $resetNote . $keepDestNote;
498
+ $information['result'] = 'SUCCESS';
499
+ return $information;
500
+ }
501
+
502
+ function get_notifications() {
503
+ return array('result' => 'SUCCESS', 'notifications' => backupbuddy_core::getNotifications() );
504
+ }
505
+
506
+ function get_schedules_run_time() {
507
+ $schedules_run_time = array();
508
+ foreach ( pb_backupbuddy::$options['schedules'] as $schedule_id => $schedule ) {
509
+ // Determine first run.
510
+ $first_run = pb_backupbuddy::$format->date( pb_backupbuddy::$format->localize_time( $schedule['first_run'] ) );
511
+ // Determine last run.
512
+ if ( isset( $schedule['last_run'] ) ) { // backward compatibility before last run tracking added. Pre v2.2.11. Eventually remove this.
513
+ if ( $schedule['last_run'] == 0 ) {
514
+ $last_run = '<i>' . __( 'Never', 'it-l10n-backupbuddy' ) . '</i>';
515
+ } else {
516
+ $last_run = pb_backupbuddy::$format->date( pb_backupbuddy::$format->localize_time( $schedule['last_run'] ) );
517
+ }
518
+ } else { // backward compatibility for before last run tracking was added.
519
+ $last_run = '<i> ' . __( 'Unknown', 'it-l10n-backupbuddy' ) . '</i>';
520
+ }
521
+
522
+ // Determine next run.
523
+ $next_run = wp_next_scheduled( 'backupbuddy_cron', array( 'run_scheduled_backup', array( (int)$schedule_id ) ) );
524
+ if ( false === $next_run ) {
525
+ $next_run = '<font color=red>Error: Cron event not found</font>';
526
+ } else {
527
+ $next_run = pb_backupbuddy::$format->date( pb_backupbuddy::$format->localize_time( $next_run ) );
528
+ }
529
+
530
+ $run_time = 'First run: ' . $first_run . '<br>' .
531
+ 'Last run: ' . $last_run . '<br>' .
532
+ 'Next run: ' . $next_run;
533
+
534
+ $schedules_run_time[$schedule_id] = $run_time;
535
+
536
+ }
537
+
538
+ return $schedules_run_time;
539
+ }
540
+
541
+ function schedules_list() {
542
+ $information = array();
543
+ $information['schedules'] = pb_backupbuddy::$options['schedules'];
544
+ $information['next_schedule_index'] = pb_backupbuddy::$options['next_schedule_index'];
545
+ $information['schedules_run_time'] = $this->get_schedules_run_time();
546
+ $information['result'] = 'SUCCESS';
547
+ return $information;
548
+ }
549
+
550
+
551
+ function run_scheduled_backup() {
552
+ if ( ! is_main_site() ) { // Only run for main site or standalone. Multisite subsites do not allow schedules.
553
+ return array('error' => __('Only run for main site or standalone. Multisite subsites do not allow schedules', 'mainwp-child') );
554
+ }
555
+
556
+ $schedule_id = (int) $_POST['schedule_id'];
557
+
558
+ if ( !isset( pb_backupbuddy::$options['schedules'][$schedule_id] ) || ! is_array( pb_backupbuddy::$options['schedules'][$schedule_id] ) ) {
559
+ return array('error' => __( 'Error: not found the backup schedule or invalid data', 'mainwp-child' ));
560
+ }
561
+
562
+ pb_backupbuddy::alert( 'Manually running scheduled backup "' . pb_backupbuddy::$options['schedules'][$schedule_id]['title'] . '" in the background.' . '<br>' .
563
+ __( 'Note: If there is no site activity there may be delays between steps in the backup. Access the site or use a 3rd party service, such as a free pinging service, to generate site activity.', 'it-l10n-backupbuddy' ) );
564
+ pb_backupbuddy_cron::_run_scheduled_backup( $schedule_id );
565
+
566
+ $information['result'] = 'SUCCESS';
567
+
568
+ return $information;
569
+ }
570
+
571
+
572
+ function save_scheduled_backup() {
573
+ $schedule_id = intval($_POST['schedule_id']);
574
+ $schedule = unserialize(base64_decode($_POST['data']));
575
+
576
+ if (!is_array($schedule)) {
577
+ return array('error' => __( 'Invalid schedule data', 'mainwp-child' ));
578
+ }
579
+ $information = array();
580
+ // add new
581
+ if (!isset(pb_backupbuddy::$options['schedules'][$schedule_id])) {
582
+ $next_index = pb_backupbuddy::$options['next_schedule_index'];
583
+ pb_backupbuddy::$options['next_schedule_index']++; // This change will be saved in savesettings function below.
584
+ pb_backupbuddy::$options['schedules'][$schedule_id] = $schedule;
585
+ $result = backupbuddy_core::schedule_event( $schedule['first_run'], $schedule['interval'], 'run_scheduled_backup', array( $schedule_id ) );
586
+ if ( $result === false ) {
587
+ return array('error' => 'Error scheduling event with WordPress. Your schedule may not work properly. Please try again. Error #3488439b. Check your BackupBuddy error log for details.');
588
+ }
589
+ } else {
590
+ $first_run = $schedule['first_run'];
591
+ $next_scheduled_time = wp_next_scheduled( 'backupbuddy_cron', array( 'run_scheduled_backup', array( (int)$schedule_id ) ) );
592
+ backupbuddy_core::unschedule_event( $next_scheduled_time, 'backupbuddy_cron', array( 'run_scheduled_backup', array( (int)$schedule_id ) ) );
593
+ backupbuddy_core::schedule_event( $first_run, $schedule['interval'], 'run_scheduled_backup', array( (int)$schedule_id ) ); // Add new schedule.
594
+ pb_backupbuddy::$options['schedules'][$schedule_id] = $schedule;
595
+ }
596
+ pb_backupbuddy::save();
597
+ $information['result'] = 'SUCCESS';
598
+ $information['schedules'] = pb_backupbuddy::$options['schedules'];
599
+ $information['next_schedule_index'] = pb_backupbuddy::$options['next_schedule_index'];
600
+ $information['schedules_run_time'] = $this->get_schedules_run_time();
601
+ return $information;
602
+ }
603
+
604
+
605
+ function save_profile() {
606
+ $profile_id = $_POST['profile_id'];
607
+ $profile = unserialize(base64_decode($_POST['data']));
608
+
609
+ if (!is_array($profile)) {
610
+ return array('error' => __( 'Invalid profile data', 'mainwp-child' ));
611
+ }
612
+
613
+ pb_backupbuddy::$options['profiles'][$profile_id] = $profile;
614
+ pb_backupbuddy::save();
615
+
616
+ $information['result'] = 'SUCCESS';
617
+ return $information;
618
+ }
619
+
620
+
621
+ function delete_profile() {
622
+ $profile_id = $_POST['profile_id'];
623
+
624
+ if (isset(pb_backupbuddy::$options['profiles'][$profile_id]))
625
+ unset(pb_backupbuddy::$options['profiles'][$profile_id]);
626
+
627
+ pb_backupbuddy::save();
628
+ $information['result'] = 'SUCCESS';
629
+ return $information;
630
+ }
631
+
632
+ function delete_backup( $type = 'default', $subsite_mode = false ) {
633
+ $item_ids = $_POST['item_ids'];
634
+ $item_ids = explode(',', $item_ids);
635
+ $information = array();
636
+ if ( is_array( $item_ids ) && count( $item_ids ) > 0 ) {
637
+ $needs_save = false;
638
+ $deleted_files = array();
639
+ foreach( $item_ids as $item ) {
640
+ if ( file_exists( backupbuddy_core::getBackupDirectory() . $item ) ) {
641
+ if ( @unlink( backupbuddy_core::getBackupDirectory() . $item ) === true ) {
642
+ $deleted_files[] = $item;
643
+
644
+ // Cleanup any related fileoptions files.
645
+ $serial = backupbuddy_core::get_serial_from_file( $item );
646
+
647
+ $backup_files = glob( backupbuddy_core::getBackupDirectory() . '*.zip' );
648
+ if ( ! is_array( $backup_files ) ) {
649
+ $backup_files = array();
650
+ }
651
+ if ( count( $backup_files ) > 5 ) { // Keep a minimum number of backups in array for stats.
652
+ $this_serial = backupbuddy_core::get_serial_from_file( $item );
653
+ $fileoptions_file = backupbuddy_core::getLogDirectory() . 'fileoptions/' . $this_serial . '.txt';
654
+ if ( file_exists( $fileoptions_file ) ) {
655
+ @unlink( $fileoptions_file );
656
+ }
657
+ if ( file_exists( $fileoptions_file . '.lock' ) ) {
658
+ @unlink( $fileoptions_file . '.lock' );
659
+ }
660
+ $needs_save = true;
661
+ }
662
+ }
663
+ } // End if file exists.
664
+ } // End foreach.
665
+ if ( $needs_save === true ) {
666
+ pb_backupbuddy::save();
667
+ }
668
+
669
+ $information['result'] = 'SUCCESS';
670
+
671
+ } // End if deleting backup(s).
672
+ return $information;
673
+ }
674
+
675
+
676
+ public function get_sync_data() {
677
+ if ( ! class_exists( 'backupbuddy_core' ) ) {
678
+ if (class_exists( 'pb_backupbuddy' ) && file_exists(pb_backupbuddy::plugin_path() . '/classes/core.php'))
679
+ require_once( pb_backupbuddy::plugin_path() . '/classes/core.php' );
680
+ else
681
+ return false;
682
+ }
683
+
684
+ if (!function_exists('backupbuddy_core::get_plugins_root'))
685
+ return false;
686
+
687
+ $information = array();
688
+ $information['plugins_root'] = backupbuddy_core::get_plugins_root();
689
+ $information['themes_root'] = backupbuddy_core::get_themes_root();
690
+ $information['media_root'] = backupbuddy_core::get_media_root();
691
+ $information['additional_tables'] = $this->pb_additional_tables();
692
+ $information['abspath'] = ABSPATH;
693
+ return $information;
694
+ }
695
+
696
+ function backup_list() {
697
+ require_once( pb_backupbuddy::plugin_path() . '/destinations/bootstrap.php' );
698
+ $information = array();
699
+ $information['backup_list'] = $this->get_backup_list();
700
+ $information['recent_backup_list'] = $this->get_recent_backup_list();
701
+ //$information['destinations_list'] = pb_backupbuddy_destinations::get_destinations_list();
702
+ $backup_directory = backupbuddy_core::getBackupDirectory();
703
+ $backup_directory = str_replace( '\\', '/', $backup_directory );
704
+ $backup_directory = rtrim( $backup_directory, '/\\' ) . '/';
705
+ $information['backupDirectoryWithinSiteRoot'] = (FALSE !== stristr( $backup_directory, ABSPATH )) ? 'yes' : 'no';
706
+ $information['result'] = 'SUCCESS';
707
+ return $information;
708
+ }
709
+
710
+ function save_note() {
711
+ if ( !isset( pb_backupbuddy::$classes['zipbuddy'] ) ) {
712
+ require_once( pb_backupbuddy::plugin_path() . '/lib/zipbuddy/zipbuddy.php' );
713
+ pb_backupbuddy::$classes['zipbuddy'] = new pluginbuddy_zipbuddy( backupbuddy_core::getBackupDirectory() );
714
+ }
715
+ $backup_file = $_POST['backup_file'];
716
+ $note = $_POST['note'];
717
+ $note = preg_replace( "/[[:space:]]+/", ' ', $note );
718
+ $note = preg_replace( "/[^[:print:]]/", '', $note );
719
+ $note = substr( $note, 0, 200 );
720
+
721
+
722
+ // Returns true on success, else the error message.
723
+ $old_comment = pb_backupbuddy::$classes['zipbuddy']->get_comment( $backup_file );
724
+ $comment = backupbuddy_core::normalize_comment_data( $old_comment );
725
+ $comment['note'] = $note;
726
+
727
+ //$new_comment = base64_encode( serialize( $comment ) );
728
+
729
+ $comment_result = pb_backupbuddy::$classes['zipbuddy']->set_comment( $backup_file, $comment );
730
+
731
+ $information = array();
732
+ if ( $comment_result === true ) {
733
+ $information['result'] = 'SUCCESS';
734
+ }
735
+
736
+ // Even if we cannot save the note into the archive file, store it in internal settings.
737
+ $serial = backupbuddy_core::get_serial_from_file( $backup_file );
738
+
739
+ require_once( pb_backupbuddy::plugin_path() . '/classes/fileoptions.php' );
740
+ pb_backupbuddy::status( 'details', 'Fileoptions instance #24.' );
741
+ $backup_options = new pb_backupbuddy_fileoptions( backupbuddy_core::getLogDirectory() . 'fileoptions/' . $serial . '.txt' );
742
+ if ( true === ( $result = $backup_options->is_ok() ) ) {
743
+ $backup_options->options['integrity']['comment'] = $note;
744
+ $backup_options->save();
745
+ }
746
+ return $information;
747
+ }
748
+
749
+ function get_hash() {
750
+ $callback_data = $_POST['callback_data'];
751
+ $file = backupbuddy_core::getBackupDirectory() . $callback_data;
752
+ if (file_exists($file))
753
+ return array( 'result' =>'SUCCESS', 'hash' => md5_file( $file ) );
754
+ else
755
+ return array( 'error' =>'Not found the file' );
756
+ }
757
+
758
+ function zip_viewer() {
759
+
760
+ // How long to cache the specific backup file tree information for (seconds)
761
+ $max_cache_time = 86400;
762
+
763
+ // This is the root directory we want the listing for
764
+ $root = $_POST[ 'dir' ];
765
+ $root_len = strlen( $root );
766
+
767
+ // This will identify the backup zip file we want to list
768
+ $serial = $_POST[ 'serial' ];
769
+ $alerts = array();
770
+ // The fileoptions file that contains the file tree information
771
+ require_once( pb_backupbuddy::plugin_path() . '/classes/fileoptions.php' );
772
+ $fileoptions_file = backupbuddy_core::getLogDirectory() . 'fileoptions/' . $serial . '-filetree.txt';
773
+
774
+ // Purge cache if too old.
775
+ if ( file_exists( $fileoptions_file ) && ( ( time() - filemtime( $fileoptions_file ) ) > $max_cache_time ) ) {
776
+ if ( false === unlink( $fileoptions_file ) ) {
777
+ $alerts[] = 'Error #456765545. Unable to wipe cached fileoptions file `' . $fileoptions_file . '`.' ;
778
+ }
779
+ }
780
+
781
+ pb_backupbuddy::status( 'details', 'Fileoptions instance #28.' );
782
+ $fileoptions = new pb_backupbuddy_fileoptions( $fileoptions_file );
783
+ $zip_viewer = $_POST[ 'zip_viewer' ];
784
+ // Either we are getting cached file tree information or we need to create afresh
785
+ if ( true !== ( $result = $fileoptions->is_ok() ) ) {
786
+ // Get file listing.
787
+ require_once( pb_backupbuddy::plugin_path() . '/lib/zipbuddy/zipbuddy.php' );
788
+ pb_backupbuddy::$classes['zipbuddy'] = new pluginbuddy_zipbuddy( ABSPATH, array(), 'unzip' );
789
+ $files = pb_backupbuddy::$classes['zipbuddy']->get_file_list( backupbuddy_core::getBackupDirectory() . str_replace( '\\/', '', $zip_viewer ) );
790
+ $fileoptions->options = $files;
791
+ $fileoptions->save();
792
+ } else {
793
+ $files = &$fileoptions->options;
794
+ }
795
+
796
+ // Just make sure we have a sensible files listing
797
+ if ( ! is_array( $files ) ) {
798
+ return array( 'error' => 'Error #548484. Unable to retrieve file listing from backup file `' . htmlentities( $zip_viewer ) . '`.' );
799
+ }
800
+
801
+ // To record subdirs of this root
802
+ $subdirs = array();
803
+
804
+ // Strip out any files/subdirs that are not actually directly under the given root
805
+ foreach( $files as $key => $file ) {
806
+
807
+ // If shorter than root length then certainly is not within this (root) directory.
808
+ // It's a quick test that is more effective the longer the root (the deeper you go
809
+ // into the tree)
810
+ if ( strlen( $file[ 0 ] ) < $root_len ) {
811
+
812
+ unset( $files[ $key ] );
813
+ continue;
814
+
815
+ }
816
+
817
+ // The root must be prefix of this file otherwise it's not under the root
818
+ // e.g., with root=this/dir/path/
819
+ // these will fail: file=this/dir/file; file=this/dir/otherpath/; file=that/dir/path/file
820
+ // and these would succeed: file=this/dir/path/; file=this/dir/path/file; file=this/dir/path/otherpath/
821
+ if ( substr( $file[ 0 ], 0, $root_len ) != $root ) {
822
+
823
+ unset( $files[ $key ] );
824
+ continue;
825
+
826
+ }
827
+
828
+ // If the file _is_ the root then we don't want to list it
829
+ // Don't want to do this on _every_ file as very specific so do it here after we have
830
+ // weeded out files for more common reasons
831
+ if ( 0 == strcmp( $file[ 0 ], $root ) ) {
832
+
833
+ unset( $files[ $key ] );
834
+ continue;
835
+
836
+ }
837
+
838
+ // Interesting file, get the path with the root prefix removed
839
+ // Note: root may be empty in which case the result will be the original filename
840
+ $unrooted_file = substr( $file[ 0 ], $root_len );
841
+
842
+ // We must ensure that we list the subdir/ even if subdir/ does not appear
843
+ // as a distinct entry in the list but only subdir/file or subdir/subsubdir/ or
844
+ // subdir/subsubdir/file. Find if we have any directory separator(s) in the filename
845
+ // and if so remember where the first is
846
+ if ( false !== ( $pos = strpos( $unrooted_file, '/' ) ) ) {
847
+
848
+ // Get the subdir/ prefix part, discarding everything after the first /
849
+ $subdir = substr( $unrooted_file, 0, ( $pos + 1 ) );
850
+
851
+ // Have we already seen it
852
+ if ( !in_array( $subdir, $subdirs ) ) {
853
+
854
+ // Not already seen so record we have seen it and modify this entry to be
855
+ // specific for the subdir/
856
+ $subdirs[] = $subdir;
857
+
858
+ // Replace the original (rooted) file name
859
+ $files[ $key ][ 0 ] = $subdir;
860
+
861
+ } else {
862
+
863
+ // We already know about the subdir/ so remove this entry
864
+ unset( $files[ $key ] );
865
+ continue;
866
+
867
+ }
868
+
869
+ } else {
870
+
871
+ // This is just like file within the root
872
+ // Replace the original (rooted) file name
873
+ $files[ $key ][ 0 ] = $unrooted_file;
874
+
875
+ }
876
+
877
+ }
878
+
879
+ return array('result' => 'SUCCESS', 'files' => $files, 'message' => implode('<br/>', $alerts));
880
+
881
+ }
882
+
883
+ function exclude_tree() {
884
+ $root = substr( ABSPATH, 0, strlen( ABSPATH ) - 1 ) . '/' . ltrim( urldecode( $_POST['dir'] ), '/\\' );
885
+ if( file_exists( $root ) ) {
886
+ $files = scandir( $root );
887
+
888
+ natcasesort( $files );
889
+
890
+ // Sort with directories first.
891
+ $sorted_files = array(); // Temporary holder for sorting files.
892
+ $sorted_directories = array(); // Temporary holder for sorting directories.
893
+ foreach( $files as $file ) {
894
+ if ( ( $file == '.' ) || ( $file == '..' ) ) {
895
+ continue;
896
+ }
897
+ if( is_file( str_replace( '//', '/', $root . $file ) ) ) {
898
+ array_push( $sorted_files, $file );
899
+ } else {
900
+ array_unshift( $sorted_directories, $file );
901
+ }
902
+ }
903
+ $files = array_merge( array_reverse( $sorted_directories ), $sorted_files );
904
+ unset( $sorted_files );
905
+ unset( $sorted_directories );
906
+ unset( $file );
907
+
908
+ ob_start();
909
+
910
+ if( count( $files ) > 0 ) { // Files found.
911
+ echo '<ul class="jqueryFileTree" style="display: none;">';
912
+ foreach( $files as $file ) {
913
+ if( file_exists( str_replace( '//', '/', $root . $file ) ) ) {
914
+ if ( is_dir( str_replace( '//', '/', $root . $file ) ) ) { // Directory.
915
+ echo '<li class="directory collapsed">';
916
+ $return = '';
917
+ $return .= '<div class="pb_backupbuddy_treeselect_control">';
918
+ $return .= '<img src="' . pb_backupbuddy::plugin_url() . '/images/redminus.png" style="vertical-align: -3px;" title="Add to exclusions..." class="pb_backupbuddy_filetree_exclude">';
919
+ $return .= '</div>';
920
+ echo '<a href="#" rel="' . htmlentities( str_replace( ABSPATH, '', $root ) . $file) . '/" title="Toggle expand...">' . htmlentities($file) . $return . '</a>';
921
+ echo '</li>';
922
+ } else { // File.
923
+ echo '<li class="file collapsed">';
924
+ $return = '';
925
+ $return .= '<div class="pb_backupbuddy_treeselect_control">';
926
+ $return .= '<img src="' . pb_backupbuddy::plugin_url() . '/images/redminus.png" style="vertical-align: -3px;" title="Add to exclusions..." class="pb_backupbuddy_filetree_exclude">';
927
+ $return .= '</div>';
928
+ echo '<a href="#" rel="' . htmlentities( str_replace( ABSPATH, '', $root ) . $file) . '">' . htmlentities($file) . $return . '</a>';
929
+ echo '</li>';
930
+ }
931
+ }
932
+ }
933
+ echo '</ul>';
934
+ } else {
935
+ echo '<ul class="jqueryFileTree" style="display: none;">';
936
+ echo '<li><a href="#" rel="' . htmlentities( pb_backupbuddy::_POST( 'dir' ) . 'NONE' ) . '"><i>Empty Directory ...</i></a></li>';
937
+ echo '</ul>';
938
+ }
939
+
940
+ $html = ob_get_clean();
941
+ return array('result' => $html) ;
942
+ } else {
943
+ return array('error' => 'Error #1127555. Unable to read child site root.') ;
944
+ }
945
+
946
+ }
947
+
948
+
949
+ function pb_additional_tables( $display_size = false ) {
950
+
951
+ $return = '';
952
+ $size_string = '';
953
+
954
+ global $wpdb;
955
+ if ( true === $display_size ) {
956
+ $results = $wpdb->get_results( "SHOW TABLE STATUS", ARRAY_A );
957
+ } else {
958
+ $results = $wpdb->get_results( "SELECT table_name FROM information_schema.tables WHERE table_schema = DATABASE()", ARRAY_A );
959
+ }
960
+ foreach( $results as $result ) {
961
+
962
+ if ( true === $display_size ) {
963
+ // Fix up row count and average row length for InnoDB engine which returns inaccurate (and changing) values for these.
964
+ if ( 'InnoDB' === $result[ 'Engine' ] ) {
965
+ if ( false !== ( $rowCount = $wpdb->get_var( "SELECT COUNT(1) as rowCount FROM `{$rs[ 'Name' ]}`", ARRAY_A ) ) ) {
966
+ if ( 0 < ( $result[ 'Rows' ] = $rowCount ) ) {
967
+ $result[ 'Avg_row_length' ] = ( $result[ 'Data_length' ] / $result[ 'Rows' ] );
968
+ }
969
+ }
970
+ unset( $rowCount );
971
+ }
972
+
973
+ // Table size.
974
+ $size_string = ' (' . pb_backupbuddy::$format->file_size( ( $result['Data_length'] + $result['Index_length'] ) ) . ') ';
975
+
976
+ } // end if display size enabled.
977
+
978
+ $return .= '<li class="file ext_sql collapsed">';
979
+ $return .= '<a rel="/" alt="' . $result['table_name'] . '">' . $result['table_name'] . $size_string;
980
+ $return .= '<div class="pb_backupbuddy_treeselect_control">';
981
+ $return .= '<img src="' . pb_backupbuddy::plugin_url() . '/images/redminus.png" style="vertical-align: -3px;" title="Add to exclusions..." class="pb_backupbuddy_table_addexclude"> <img src="' . pb_backupbuddy::plugin_url() . '/images/greenplus.png" style="vertical-align: -3px;" title="Add to inclusions..." class="pb_backupbuddy_table_addinclude">';
982
+ $return .= '</div>';
983
+ $return .= '</a>';
984
+ $return .= '</li>';
985
+ }
986
+
987
+ return '<div class="jQueryOuterTree" style="position: absolute; height: 160px;"><ul class="jqueryFileTree">' . $return . '</ul></div>';
988
+ }
989
+
990
+ function restore_file_view() {
991
+
992
+ $archive_file = $_POST[ 'archive' ]; // archive to extract from.
993
+ $file = $_POST[ 'file' ]; // file to extract.
994
+ $serial = backupbuddy_core::get_serial_from_file( $archive_file ); // serial of archive.
995
+ $temp_file = uniqid(); // temp filename to extract into.
996
+
997
+ require_once( pb_backupbuddy::plugin_path() . '/lib/zipbuddy/zipbuddy.php' );
998
+ $zipbuddy = new pluginbuddy_zipbuddy( backupbuddy_core::getBackupDirectory() );
999
+
1000
+ // Calculate temp directory & lock it down.
1001
+ $temp_dir = get_temp_dir();
1002
+ $destination = $temp_dir . 'backupbuddy-' . $serial;
1003
+ if ( ( ( ! file_exists( $destination ) ) && ( false === mkdir( $destination ) ) ) ) {
1004
+ $error = 'Error #458485945b: Unable to create temporary location.';
1005
+ pb_backupbuddy::status( 'error', $error );
1006
+ return array('error' => $error);
1007
+ }
1008
+
1009
+ // If temp directory is within webroot then lock it down.
1010
+ $temp_dir = str_replace( '\\', '/', $temp_dir ); // Normalize for Windows.
1011
+ $temp_dir = rtrim( $temp_dir, '/\\' ) . '/'; // Enforce single trailing slash.
1012
+ if ( FALSE !== stristr( $temp_dir, ABSPATH ) ) { // Temp dir is within webroot.
1013
+ pb_backupbuddy::anti_directory_browsing( $destination );
1014
+ }
1015
+ unset( $temp_dir );
1016
+
1017
+ $message = 'Extracting "' . $file . '" from archive "' . $archive_file . '" into temporary file "' . $destination . '". ';
1018
+ //echo '<!-- ';
1019
+ pb_backupbuddy::status( 'details', $message );
1020
+ //echo $message;
1021
+
1022
+ $file_content = '';
1023
+
1024
+ $extractions = array( $file => $temp_file );
1025
+ $extract_result = $zipbuddy->extract( backupbuddy_core::getBackupDirectory() . $archive_file, $destination, $extractions );
1026
+ if ( false === $extract_result ) { // failed.
1027
+ //echo ' -->';
1028
+ $error = 'Error #584984458. Unable to extract.';
1029
+ pb_backupbuddy::status( 'error', $error );
1030
+ return array( 'error' => $error );
1031
+ } else { // success.
1032
+ $file_content = file_get_contents( $destination . '/' . $temp_file );
1033
+ }
1034
+
1035
+ // Try to cleanup.
1036
+ if ( file_exists( $destination ) ) {
1037
+ if ( false === pb_backupbuddy::$filesystem->unlink_recursive( $destination ) ) {
1038
+ pb_backupbuddy::status( 'details', 'Unable to delete temporary holding directory `' . $destination . '`.' );
1039
+ } else {
1040
+ pb_backupbuddy::status( 'details', 'Cleaned up temporary files.' );
1041
+ }
1042
+ }
1043
+
1044
+ return array( 'result' => 'SUCCESS', 'file_content' => $file_content );
1045
+ }
1046
+
1047
+
1048
+ function restore_file_restore() {
1049
+
1050
+ $files = $_POST[ 'files' ]; // file to extract.
1051
+ $archive_file = $_POST[ 'archive' ]; // archive to extract from.
1052
+
1053
+ $files_array = explode( ',', $files );
1054
+ $files = array();
1055
+ foreach( $files_array as $file ) {
1056
+ if ( substr( $file, -1 ) == '/' ) { // If directory then add wildcard.
1057
+ $file = $file . '*';
1058
+ }
1059
+ $files[$file] = $file;
1060
+ }
1061
+ unset( $files_array );
1062
+
1063
+ $success = false;
1064
+
1065
+ global $pb_backupbuddy_js_status;
1066
+ $pb_backupbuddy_js_status = true;
1067
+ pb_backupbuddy::set_status_serial( 'restore' );
1068
+ global $wp_version;
1069
+ pb_backupbuddy::status( 'details', 'BackupBuddy v' . pb_backupbuddy::settings( 'version' ) . ' using WordPress v' . $wp_version . ' on ' . PHP_OS . '.' );
1070
+
1071
+ require( pb_backupbuddy::plugin_path() . '/classes/_restoreFiles.php' );
1072
+
1073
+ ob_start();
1074
+ $result = backupbuddy_restore_files::restore( backupbuddy_core::getBackupDirectory() . $archive_file, $files, $finalPath = ABSPATH );
1075
+ $restore_result = ob_get_clean();
1076
+ pb_backupbuddy::flush();
1077
+ return array('restore_result' => $restore_result);
1078
+ }
1079
+
1080
+ function get_backup_list( $type = 'default', $subsite_mode = false ) {
1081
+ $backups = array();
1082
+ $backup_sort_dates = array();
1083
+
1084
+ $files = glob( backupbuddy_core::getBackupDirectory() . 'backup*.zip' );
1085
+ if ( ! is_array( $files ) ) {
1086
+ $files = array();
1087
+ }
1088
+
1089
+ $files2 = glob( backupbuddy_core::getBackupDirectory() . 'snapshot*.zip' );
1090
+ if ( ! is_array( $files2 ) ) {
1091
+ $files2 = array();
1092
+ }
1093
+
1094
+ $files = array_merge( $files, $files2 );
1095
+
1096
+ if ( is_array( $files ) && !empty( $files ) ) { // For robustness. Without open_basedir the glob() function returns an empty array for no match. With open_basedir in effect the glob() function returns a boolean false for no match.
1097
+
1098
+ $backup_prefix = backupbuddy_core::backup_prefix(); // Backup prefix for this site. Used for MS checking that this user can see this backup.
1099
+ foreach( $files as $file_id => $file ) {
1100
+
1101
+ if ( ( $subsite_mode === true ) && is_multisite() ) { // If a Network and NOT the superadmin must make sure they can only see the specific subsite backups for security purposes.
1102
+
1103
+ // Only allow viewing of their own backups.
1104
+ if ( ! strstr( $file, $backup_prefix ) ) {
1105
+ unset( $files[$file_id] ); // Remove this backup from the list. This user does not have access to it.
1106
+ continue; // Skip processing to next file.
1107
+ }
1108
+ }
1109
+
1110
+ $serial = backupbuddy_core::get_serial_from_file( $file );
1111
+
1112
+ $options = array();
1113
+ if ( file_exists( backupbuddy_core::getLogDirectory() . 'fileoptions/' . $serial . '.txt' ) ) {
1114
+ require_once( pb_backupbuddy::plugin_path() . '/classes/fileoptions.php' );
1115
+ pb_backupbuddy::status( 'details', 'Fileoptions instance #33.' );
1116
+ $backup_options = new pb_backupbuddy_fileoptions( backupbuddy_core::getLogDirectory() . 'fileoptions/' . $serial . '.txt', $read_only = false, $ignore_lock = false, $create_file = true ); // Will create file to hold integrity data if nothing exists.
1117
+ } else {
1118
+ $backup_options = '';
1119
+ }
1120
+ $backup_integrity = backupbuddy_core::backup_integrity_check( $file, $backup_options, $options );
1121
+
1122
+ // Backup status.
1123
+ $pretty_status = array(
1124
+ true => '<span class="pb_label pb_label-success">Good</span>', // v4.0+ Good.
1125
+ 'pass' => '<span class="pb_label pb_label-success">Good</span>', // Pre-v4.0 Good.
1126
+ false => '<span class="pb_label pb_label-important">Bad</span>', // v4.0+ Bad.
1127
+ 'fail' => '<span class="pb_label pb_label-important">Bad</span>', // Pre-v4.0 Bad.
1128
+ );
1129
+
1130
+ // Backup type.
1131
+ $pretty_type = array(
1132
+ 'full' => 'Full',
1133
+ 'db' => 'Database',
1134
+ 'files' => 'Files',
1135
+ 'themes' => 'Themes',
1136
+ 'plugins' => 'Plugins',
1137
+ );
1138
+
1139
+
1140
+ // Defaults...
1141
+ $detected_type = '';
1142
+ $file_size = '';
1143
+ $modified = '';
1144
+ $modified_time = 0;
1145
+ $integrity = '';
1146
+
1147
+ $main_string = 'Warn#284.';
1148
+ if ( is_array( $backup_integrity ) ) { // Data intact... put it all together.
1149
+ // Calculate time ago.
1150
+ $time_ago = '';
1151
+ if ( isset( $backup_integrity['modified'] ) ) {
1152
+ $time_ago = pb_backupbuddy::$format->time_ago( $backup_integrity['modified'] ) . ' ago';
1153
+ }
1154
+
1155
+ $detected_type = pb_backupbuddy::$format->prettify( $backup_integrity['detected_type'], $pretty_type );
1156
+ if ( $detected_type == '' ) {
1157
+ $detected_type = backupbuddy_core::pretty_backup_type( backupbuddy_core::getBackupTypeFromFile( $file ) );
1158
+ if ( '' == $detected_type ) {
1159
+ $detected_type = '<span class="description">Unknown</span>';
1160
+ }
1161
+ } else {
1162
+ if ( isset( $backup_options->options['profile'] ) ) {
1163
+ $detected_type = '
1164
+ <div>
1165
+ <span style="color: #AAA; float: left;">' . $detected_type . '</span>
1166
+ <span style="display: inline-block; float: left; height: 15px; border-right: 1px solid #EBEBEB; margin-left: 6px; margin-right: 6px;"></span>
1167
+ ' . htmlentities( $backup_options->options['profile']['title'] ) . '
1168
+ </div>
1169
+ '
1170
+ ;
1171
+ }
1172
+ }
1173
+
1174
+ $file_size = pb_backupbuddy::$format->file_size( $backup_integrity['size'] );
1175
+ $modified = pb_backupbuddy::$format->date( pb_backupbuddy::$format->localize_time( $backup_integrity['modified'] ), 'l, F j, Y - g:i:s a' );
1176
+ $modified_time = $backup_integrity['modified'];
1177
+ if ( isset( $backup_integrity['status'] ) ) { // Pre-v4.0.
1178
+ $status = $backup_integrity['status'];
1179
+ } else { // v4.0+
1180
+ $status = $backup_integrity['is_ok'];
1181
+ }
1182
+
1183
+
1184
+ // Calculate main row string.
1185
+ if ( $type == 'default' ) { // Default backup listing.
1186
+ $download_url = '/wp-admin/admin-ajax.php?action=mainwp_backupbuddy_download_archive&backupbuddy_backup=' . basename( $file ) . '&_wpnonce=' . MainWP_Helper::create_nonce_without_session( 'mainwp_download_backup' );
1187
+ $main_string = '<a href="#" download-url="' . $download_url . '"class="backupbuddyFileTitle mwp_bb_download_backup_lnk" title="' . basename( $file ) . '">' . $modified . ' (' . $time_ago . ')</a>';
1188
+ } elseif ( $type == 'migrate' ) { // Migration backup listing.
1189
+ $main_string = '<a class="pb_backupbuddy_hoveraction_migrate backupbuddyFileTitle" rel="' . basename( $file ) . '" href="' . pb_backupbuddy::page_url() . '&migrate=' . basename( $file ) . '&value=' . basename( $file ) . '" title="' . basename( $file ) . '">' . $modified . ' (' . $time_ago . ')</a>';
1190
+ } else {
1191
+ $main_string = '{Unknown type.}';
1192
+ }
1193
+ // Add comment to main row string if applicable.
1194
+ if ( isset( $backup_integrity['comment'] ) && ( $backup_integrity['comment'] !== false ) && ( $backup_integrity['comment'] !== '' ) ) {
1195
+ $main_string .= '<br><span class="description">Note: <span class="pb_backupbuddy_notetext">' . htmlentities( $backup_integrity['comment'] ) . '</span></span>';
1196
+ }
1197
+
1198
+
1199
+ $integrity = pb_backupbuddy::$format->prettify( $status, $pretty_status ) . ' ';
1200
+ if ( isset( $backup_integrity['scan_notes'] ) && count( (array)$backup_integrity['scan_notes'] ) > 0 ) {
1201
+ foreach( (array)$backup_integrity['scan_notes'] as $scan_note ) {
1202
+ $integrity .= $scan_note . ' ';
1203
+ }
1204
+ }
1205
+ $integrity .= '<a href="#" serial="' . $serial . '" class="mwp_bb_reset_integrity_lnk" file-name="' . basename( $file ) . '" title="Rescan integrity. Last checked ' . pb_backupbuddy::$format->date( $backup_integrity['scan_time'] ) . '."> <i class="fa fa-refresh" aria-hidden="true"></i></a>';
1206
+ $integrity .= '<div class="row-actions"><a title="' . __( 'Backup Status', 'mainwp-child' ) . '" href="#" serial="' . $serial . '" class="mainwp_bb_view_details_lnk thickbox">' . __( 'View Details', 'mainwp-child' ) . '</a></div>';
1207
+
1208
+ $sumLogFile = backupbuddy_core::getLogDirectory() . 'status-' . $serial . '_' . pb_backupbuddy::$options['log_serial'] . '.txt';
1209
+ if ( file_exists( $sumLogFile ) ) {
1210
+ $integrity .= '<div class="row-actions"><a title="' . __( 'View Backup Log', 'mainwp-child' ) . '" href="#" serial="' . $serial . '" class="mainwp_bb_view_log_lnk thickbox">' . __( 'View Log', 'mainwp-child' ) . '</a></div>';
1211
+ }
1212
+
1213
+ } // end if is_array( $backup_options ).
1214
+
1215
+ // No integrity check for themes or plugins types.
1216
+ $raw_type = backupbuddy_core::getBackupTypeFromFile( $file );
1217
+ if ( ( 'themes' == $raw_type ) || ( 'plugins' == $raw_type ) ) {
1218
+ $integrity = 'n/a';
1219
+ }
1220
+
1221
+ $backups[basename( $file )] = array(
1222
+ array( basename( $file ), $main_string . '<br><span class="description" style="color: #AAA; display: inline-block; margin-top: 5px;">' . basename( $file ) . '</span>' ),
1223
+ $detected_type,
1224
+ $file_size,
1225
+ $integrity,
1226
+ );
1227
+
1228
+
1229
+ $backup_sort_dates[basename( $file)] = $modified_time;
1230
+
1231
+ } // End foreach().
1232
+
1233
+ } // End if.
1234
+
1235
+ // Sort backup by date.
1236
+ arsort( $backup_sort_dates );
1237
+ // Re-arrange backups based on sort dates.
1238
+ $sorted_backups = array();
1239
+ foreach( $backup_sort_dates as $backup_file => $backup_sort_date ) {
1240
+ $sorted_backups[$backup_file] = $backups[$backup_file];
1241
+ unset( $backups[$backup_file] );
1242
+ }
1243
+ unset( $backups );
1244
+ return $sorted_backups;
1245
+
1246
+ } // End backups_list().
1247
+
1248
+ function get_recent_backup_list () {
1249
+ $recentBackups_list = glob( backupbuddy_core::getLogDirectory() . 'fileoptions/*.txt' );
1250
+ if ( ! is_array( $recentBackups_list ) ) {
1251
+ $recentBackups_list = array();
1252
+ }
1253
+
1254
+ $recentBackups = array();
1255
+ if ( count( $recentBackups_list ) > 0 ) {
1256
+
1257
+ // Backup type.
1258
+ $pretty_type = array(
1259
+ 'full' => 'Full',
1260
+ 'db' => 'Database',
1261
+ 'files' => 'Files',
1262
+ );
1263
+
1264
+ foreach( $recentBackups_list as $backup_fileoptions ) {
1265
+
1266
+ require_once( pb_backupbuddy::plugin_path() . '/classes/fileoptions.php' );
1267
+ pb_backupbuddy::status( 'details', 'Fileoptions instance #1.' );
1268
+ $backup = new pb_backupbuddy_fileoptions( $backup_fileoptions, $read_only = true );
1269
+ if ( true !== ( $result = $backup->is_ok() ) ) {
1270
+ pb_backupbuddy::status( 'error', __('Unable to access fileoptions data file.', 'mainwp-child' ) . ' Error: ' . $result );
1271
+ continue;
1272
+ }
1273
+ $backup = &$backup->options;
1274
+
1275
+ if ( !isset( $backup['serial'] ) || ( $backup['serial'] == '' ) ) {
1276
+ continue;
1277
+ }
1278
+ if ( ( $backup['finish_time'] >= $backup['start_time'] ) && ( 0 != $backup['start_time'] ) ) {
1279
+ $status = '<span class="pb_label pb_label-success">Completed</span>';
1280
+ } elseif ( $backup['finish_time'] == -1 ) {
1281
+ $status = '<span class="pb_label pb_label-warning">Cancelled</span>';
1282
+ } elseif ( FALSE === $backup['finish_time'] ) {
1283
+ $status = '<span class="pb_label pb_label-error">Failed (timeout?)</span>';
1284
+ } elseif ( ( time() - $backup['updated_time'] ) > backupbuddy_constants::TIME_BEFORE_CONSIDERED_TIMEOUT ) {
1285
+ $status = '<span class="pb_label pb_label-error">Failed (likely timeout)</span>';
1286
+ } else {
1287
+ $status = '<span class="pb_label pb_label-warning">In progress or timed out</span>';
1288
+ }
1289
+ $status .= '<br>';
1290
+
1291
+
1292
+ // Technical details link.
1293
+ $status .= '<div class="row-actions">';
1294
+ $status .= '<a title="' . __( 'Backup Process Technical Details', 'mainwp-child' ) . '" href="#" serial="' . $backup['serial'] . '" class="mainwp_bb_view_details_lnk thickbox">View Details</a>';
1295
+
1296
+ $sumLogFile = backupbuddy_core::getLogDirectory() . 'status-' . $backup['serial'] . '_' . pb_backupbuddy::$options['log_serial'] . '.txt';
1297
+ if ( file_exists( $sumLogFile ) ) {
1298
+ $status .= '<div class="row-actions"><a title="' . __( 'View Backup Log', 'mainwp-child' ) . '" href="#" serial="' . $backup['serial'] . '" class="mainwp_bb_view_log_lnk thickbox">' . __( 'View Log', 'mainwp-child' ) . '</a></div>';
1299
+ }
1300
+
1301
+ $status .= '</div>';
1302
+
1303
+ // Calculate finish time (if finished).
1304
+ if ( $backup['finish_time'] > 0 ) {
1305
+ $finish_time = pb_backupbuddy::$format->date( pb_backupbuddy::$format->localize_time( $backup['finish_time'] ) ) . '<br><span class="description">' . pb_backupbuddy::$format->time_ago( $backup['finish_time'] ) . ' ago</span>';
1306
+ } else { // unfinished.
1307
+ $finish_time = '<i>Unfinished</i>';
1308
+ }
1309
+
1310
+ $backupTitle = '<span class="backupbuddyFileTitle" style="color: #000;" title="' . basename( $backup['archive_file'] ) . '">' . pb_backupbuddy::$format->date( pb_backupbuddy::$format->localize_time( $backup['start_time'] ), 'l, F j, Y - g:i:s a' ) . ' (' . pb_backupbuddy::$format->time_ago( $backup['start_time'] ) . ' ago)</span><br><span class="description">' . basename( $backup['archive_file'] ) . '</span>';
1311
+
1312
+ if ( isset( $backup['profile'] ) && isset( $backup['profile']['type'] ) ) {
1313
+ $backupType = '<div>
1314
+ <span style="color: #AAA; float: left;">' . pb_backupbuddy::$format->prettify( $backup['profile']['type'], $pretty_type ) . '</span>
1315
+ <span style="display: inline-block; float: left; height: 15px; border-right: 1px solid #EBEBEB; margin-left: 6px; margin-right: 6px;"></span>'
1316
+ . $backup['profile']['title'] .
1317
+ '</div>';
1318
+ } else {
1319
+ $backupType = backupbuddy_core::pretty_backup_type( backupbuddy_core::getBackupTypeFromFile( $backup['archive_file'] ) );
1320
+ if ( '' == $backupType ) {
1321
+ $backupType = '<span class="description">Unknown</span>';
1322
+ }
1323
+ }
1324
+
1325
+ if ( isset( $backup['archive_size'] ) && ( $backup['archive_size'] > 0 ) ) {
1326
+ $archive_size = pb_backupbuddy::$format->file_size( $backup['archive_size'] );
1327
+ } else {
1328
+ $archive_size = 'n/a';
1329
+ }
1330
+
1331
+ // No integrity check for themes or plugins types.
1332
+ $raw_type = backupbuddy_core::getBackupTypeFromFile( $backup['archive_file'] );
1333
+ if ( ( 'themes' == $raw_type ) || ( 'plugins' == $raw_type ) ) {
1334
+ $status = 'n/a';
1335
+ }
1336
+
1337
+ // Append to list.
1338
+ $recentBackups[ $backup['serial'] ] = array(
1339
+ array( basename( $backup['archive_file'] ), $backupTitle ),
1340
+ $backupType,
1341
+ $archive_size,
1342
+ ucfirst( $backup['trigger'] ),
1343
+ $status,
1344
+ 'start_timestamp' => $backup['start_time'], // Used by array sorter later to put backups in proper order.
1345
+ );
1346
+
1347
+ }
1348
+
1349
+ $columns = array(
1350
+ __('Recently Made Backups (Start Time)', 'mainwp-child' ),
1351
+ __('Type | Profile', 'mainwp-child' ),
1352
+ __('File Size', 'mainwp-child' ),
1353
+ __('Trigger', 'mainwp-child' ),
1354
+ __('Status', 'mainwp-child' ) . ' <span class="description">(hover for options)</span>',
1355
+ );
1356
+
1357
+ function pb_backupbuddy_aasort (&$array, $key) {
1358
+ $sorter=array();
1359
+ $ret=array();
1360
+ reset($array);
1361
+ foreach ($array as $ii => $va) {
1362
+ $sorter[$ii]=$va[$key];
1363
+ }
1364
+ asort($sorter);
1365
+ foreach ($sorter as $ii => $va) {
1366
+ $ret[$ii]=$array[$ii];
1367
+ }
1368
+ $array=$ret;
1369
+ }
1370
+
1371
+ pb_backupbuddy_aasort( $recentBackups, 'start_timestamp' ); // Sort by multidimensional array with key start_timestamp.
1372
+ $recentBackups = array_reverse( $recentBackups ); // Reverse array order to show newest first.
1373
+ }
1374
+
1375
+ return $recentBackups;
1376
+ }
1377
+
1378
+ function delete_scheduled_backup() {
1379
+ $schedule_ids = $_POST['schedule_ids'];
1380
+ $schedule_ids = explode(',', $schedule_ids);
1381
+
1382
+ if (empty($schedule_ids)) {
1383
+ return array('error' => __( 'Empty schedule ids', 'mainwp-child' ));
1384
+ }
1385
+ foreach ($schedule_ids as $sch_id) {
1386
+ if ( isset( pb_backupbuddy::$options['schedules'][$sch_id] ) ) {
1387
+ unset( pb_backupbuddy::$options['schedules'][$sch_id] );
1388
+ }
1389
+ }
1390
+ pb_backupbuddy::save();
1391
+ $information['result'] = 'SUCCESS';
1392
+ return $information;
1393
+ }
1394
+
1395
+ function view_log() {
1396
+ $serial = $_POST[ 'serial' ];
1397
+ $logFile = backupbuddy_core::getLogDirectory() . 'status-' . $serial . '_sum_' . pb_backupbuddy::$options['log_serial'] . '.txt';
1398
+
1399
+ if ( ! file_exists( $logFile ) ) {
1400
+ return array('error' => 'Error #858733: Log file `' . $logFile . '` not found or access denied.' );
1401
+ }
1402
+
1403
+ $lines = file_get_contents( $logFile );
1404
+ $lines = explode( "\n", $lines );
1405
+ ob_start();
1406
+ ?>
1407
+
1408
+ <textarea readonly="readonly" id="backupbuddy_messages" wrap="off" style="width: 100%; min-height: 400px; height: 500px; height: 80%; background: #FFF;"><?php
1409
+ foreach( (array)$lines as $rawline ) {
1410
+ $line = json_decode( $rawline, true );
1411
+ //print_r( $line );
1412
+ if ( is_array( $line ) ) {
1413
+ $u = '';
1414
+ if ( isset( $line['u'] ) ) { // As off v4.2.15.6. TODO: Remove this in a couple of versions once old logs without this will have cycled out.
1415
+ $u = '.' . $line['u'];
1416
+ }
1417
+ echo pb_backupbuddy::$format->date( $line['time'], 'G:i:s' ) . $u . "\t\t";
1418
+ echo $line['run'] . "sec\t";
1419
+ echo $line['mem'] . "MB\t";
1420
+ echo $line['event'] . "\t";
1421
+ echo $line['data'] . "\n";
1422
+ } else {
1423
+ echo $rawline . "\n";
1424
+ }
1425
+ }
1426
+ ?></textarea><br><br>
1427
+ <small>Log file: <?php echo $logFile; ?></small>
1428
+ <br>
1429
+ <?php
1430
+ echo '<small>Last modified: ' . pb_backupbuddy::$format->date( filemtime( $logFile ) ) . ' (' . pb_backupbuddy::$format->time_ago( filemtime( $logFile ) ) . ' ago)';
1431
+ ?>
1432
+ <br><br>
1433
+ <?php
1434
+ $html = ob_get_clean();
1435
+ pb_backupbuddy::flush();
1436
+ return array('result' => 'SUCCESS', 'html_log' => $html);
1437
+ }
1438
+
1439
+ function view_detail() {
1440
+
1441
+ $serial = $_POST['serial'];
1442
+ $serial = str_replace( '/\\', '', $serial );
1443
+ pb_backupbuddy::load();
1444
+
1445
+ require_once( pb_backupbuddy::plugin_path() . '/classes/fileoptions.php' );
1446
+ pb_backupbuddy::status( 'details', 'Fileoptions instance #27.' );
1447
+ $optionsFile = backupbuddy_core::getLogDirectory() . 'fileoptions/' . $serial . '.txt';
1448
+ $backup_options = new pb_backupbuddy_fileoptions( $optionsFile, $read_only = true );
1449
+ if ( true !== ( $result = $backup_options->is_ok() ) ) {
1450
+ return array('error' => __('Unable to access fileoptions data file.', 'mainwp-child' ) . ' Error: ' . $result );
1451
+ }
1452
+ ob_start();
1453
+ $integrity = $backup_options->options['integrity'];
1454
+
1455
+ $start_time = 'Unknown';
1456
+ $finish_time = 'Unknown';
1457
+ if ( isset( $backup_options->options['start_time'] ) ) {
1458
+ $start_time = pb_backupbuddy::$format->date( pb_backupbuddy::$format->localize_time( $backup_options->options['start_time'] ) ) . ' <span class="description">(' . pb_backupbuddy::$format->time_ago( $backup_options->options['start_time'] ) . ' ago)</span>';
1459
+ if ( $backup_options->options['finish_time'] > 0 ) {
1460
+ $finish_time = pb_backupbuddy::$format->date( pb_backupbuddy::$format->localize_time( $backup_options->options['finish_time'] ) ) . ' <span class="description">(' . pb_backupbuddy::$format->time_ago( $backup_options->options['finish_time'] ) . ' ago)</span>';
1461
+ } else { // unfinished.
1462
+ $finish_time = '<i>Unfinished</i>';
1463
+ }
1464
+ }
1465
+
1466
+
1467
+ //***** BEGIN TESTS AND RESULTS.
1468
+ if ( isset( $integrity['status_details'] ) ) { // $integrity['status_details'] is NOT array (old, pre-3.1.9).
1469
+ echo '<h3>Integrity Technical Details</h3>';
1470
+ echo '<textarea style="width: 100%; height: 175px;" wrap="off">';
1471
+ foreach( $integrity as $item_name => $item_value ) {
1472
+ $item_value = str_replace( '<br />', '<br>', $item_value );
1473
+ $item_value = str_replace( '<br><br>', '<br>', $item_value );
1474
+ $item_value = str_replace( '<br>', "\n ", $item_value );
1475
+ echo $item_name . ' => ' . $item_value . "\n";
1476
+ }
1477
+ echo '</textarea><br><br><b>Note:</b> It is normal to see several "file not found" entries as BackupBuddy checks for expected files in multiple locations, expecting to only find each file once in one of those locations.';
1478
+ } else { // $integrity['status_details'] is array.
1479
+
1480
+ echo '<br>';
1481
+
1482
+ if ( isset( $integrity['status_details'] ) ) { // PRE-v4.0 Tests.
1483
+ function pb_pretty_results( $value ) {
1484
+ if ( $value === true ) {
1485
+ return '<span class="pb_label pb_label-success">Pass</span>';
1486
+ } else {
1487
+ return '<span class="pb_label pb_label-important">Fail</span>';
1488
+ }
1489
+ }
1490
+
1491
+ // The tests & their status..
1492
+ $tests = array();
1493
+ $tests[] = array( 'BackupBackup data file exists', pb_pretty_results( $integrity['status_details']['found_dat'] ) );
1494
+ $tests[] = array( 'Database SQL file exists', pb_pretty_results( $integrity['status_details']['found_sql'] ) );
1495
+ if ( $integrity['detected_type'] == 'full' ) { // Full backup.
1496
+ $tests[] = array( 'WordPress wp-config.php exists (full/files backups only)', pb_pretty_results( $integrity['status_details']['found_wpconfig'] ) );
1497
+ } elseif ( $integrity['detected_type'] == 'files' ) { // Files only backup.
1498
+ $tests[] = array( 'WordPress wp-config.php exists (full/files backups only)', pb_pretty_results( $integrity['status_details']['found_wpconfig'] ) );
1499
+ } else { // DB only.
1500
+ $tests[] = array( 'WordPress wp-config.php exists (full/files backups only)', '<span class="pb_label pb_label-success">N/A</span>' );
1501
+ }
1502
+ } else { // 4.0+ Tests.
1503
+ $tests = array();
1504
+ if ( isset( $integrity['tests'] ) ) {
1505
+ foreach( (array)$integrity['tests'] as $test ) {
1506
+ if ( true === $test['pass'] ) {
1507
+ $status_text = '<span class="pb_label pb_label-success">Pass</span>';
1508
+ } else {
1509
+ $status_text = '<span class="pb_label pb_label-important">Fail</span>';
1510
+ }
1511
+ $tests[] = array( $test['test'], $status_text );
1512
+ }
1513
+ }
1514
+ }
1515
+
1516
+ $columns = array(
1517
+ __( 'Integrity Test', 'mainwp-child' ),
1518
+ __( 'Status', 'mainwp-child' ),
1519
+ );
1520
+
1521
+ pb_backupbuddy::$ui->list_table(
1522
+ $tests,
1523
+ array(
1524
+ 'columns' => $columns,
1525
+ 'css' => 'width: 100%; min-width: 200px;',
1526
+ )
1527
+ );
1528
+
1529
+ } // end $integrity['status_details'] is an array.
1530
+ echo '<br><br>';
1531
+ //***** END TESTS AND RESULTS.
1532
+
1533
+
1534
+ // Output meta info table (if any).
1535
+ $metaInfo = array();
1536
+ if ( isset( $integrity['file'] ) && ( false === ( $metaInfo = backupbuddy_core::getZipMeta( backupbuddy_core::getBackupDirectory() . $integrity['file'] ) ) ) ) { // $backup_options->options['archive_file']
1537
+ echo '<i>No meta data found in zip comment. Skipping meta information display.</i>';
1538
+ } else {
1539
+ pb_backupbuddy::$ui->list_table(
1540
+ $metaInfo,
1541
+ array(
1542
+ 'columns' => array( 'Backup Details', 'Value' ),
1543
+ 'css' => 'width: 100%; min-width: 200px;',
1544
+ )
1545
+ );
1546
+ }
1547
+ echo '<br><br>';
1548
+
1549
+
1550
+ //***** BEGIN STEPS.
1551
+ $steps = array();
1552
+ $steps[] = array( 'Start Time', $start_time, '' );
1553
+ if ( isset( $backup_options->options['steps'] ) ) {
1554
+ foreach( $backup_options->options['steps'] as $step ) {
1555
+ if ( isset( $step['finish_time'] ) && ( $step['finish_time'] != 0 ) ) {
1556
+
1557
+ // Step name.
1558
+ if ( $step['function'] == 'backup_create_database_dump' ) {
1559
+ if ( count( $step['args'][0] ) == 1 ) {
1560
+ $step_name = 'Database dump (breakout: ' . $step['args'][0][0] . ')';
1561
+ } else {
1562
+ $step_name = 'Database dump';
1563
+ }
1564
+ } elseif ( $step['function'] == 'backup_zip_files' ) {
1565
+ if ( isset( $backup_options->options['steps']['backup_zip_files'] ) ) {
1566
+ $zip_time = $backup_options->options['steps']['backup_zip_files'];
1567
+ } else {
1568
+ $zip_time = 0;
1569
+ }
1570
+
1571
+ // Calculate write speed in MB/sec for this backup.
1572
+ if ( $zip_time == '0' ) { // Took approx 0 seconds to backup so report this speed.
1573
+ $write_speed = '> ' . pb_backupbuddy::$format->file_size( $backup_options->options['integrity']['size'] );
1574
+ } else {
1575
+ if ( $zip_time == 0 ) {
1576
+ $write_speed = '';
1577
+ } else {
1578
+ $write_speed = pb_backupbuddy::$format->file_size( $backup_options->options['integrity']['size'] / $zip_time ) . '/sec';
1579
+ }
1580
+ }
1581
+ $step_name = 'Zip archive creation (Write speed: ' . $write_speed . ')';
1582
+ } elseif ( $step['function'] == 'post_backup' ) {
1583
+ $step_name = 'Post-backup cleanup';
1584
+ } elseif( $step['function'] == 'integrity_check' ) {
1585
+ $step_name = 'Integrity Check';
1586
+ } else {
1587
+ $step_name = $step['function'];
1588
+ }
1589
+
1590
+ // Step time taken.
1591
+ $seconds = (int)( $step['finish_time'] - $step['start_time'] );
1592
+ if ( $seconds < 1 ) {
1593
+ $step_time = '< 1 second';
1594
+ } else {
1595
+ $step_time = $seconds . ' seconds';
1596
+ }
1597
+
1598
+
1599
+ // Compile details for this step into array.
1600
+ $steps[] = array(
1601
+ $step_name,
1602
+ $step_time,
1603
+ $step['attempts'],
1604
+ );
1605
+
1606
+ }
1607
+ } // End foreach.
1608
+ } else { // End if serial in array is set.
1609
+ $step_times[] = 'unknown';
1610
+ } // End if serial in array is NOT set.
1611
+
1612
+
1613
+ // Total overall time from initiation to end.
1614
+ if ( isset( $backup_options->options['finish_time'] ) && isset( $backup_options->options['start_time'] ) && ( $backup_options->options['finish_time'] != 0 ) && ( $backup_options->options['start_time'] != 0 ) ) {
1615
+ $seconds = ( $backup_options->options['finish_time'] - $backup_options->options['start_time'] );
1616
+ if ( $seconds < 1 ) {
1617
+ $total_time = '< 1 second';
1618
+ } else {
1619
+ $total_time = $seconds . ' seconds';
1620
+ }
1621
+ } else {
1622
+ $total_time = '<i>Unknown</i>';
1623
+ }
1624
+ $steps[] = array( 'Finish Time', $finish_time, '' );
1625
+ $steps[] = array(
1626
+ '<b>Total Overall Time</b>',
1627
+ $total_time,
1628
+ '',
1629
+ );
1630
+
1631
+ $columns = array(
1632
+ __( 'Backup Steps', 'mainwp-child' ),
1633
+ __( 'Time', 'mainwp-child' ),
1634
+ __( 'Attempts', 'mainwp-child' ),
1635
+ );
1636
+
1637
+ if ( count( $steps ) == 0 ) {
1638
+ _e( 'No step statistics were found for this backup.', 'mainwp-child' );
1639
+ } else {
1640
+ pb_backupbuddy::$ui->list_table(
1641
+ $steps,
1642
+ array(
1643
+ 'columns' => $columns,
1644
+ 'css' => 'width: 100%; min-width: 200px;',
1645
+ )
1646
+ );
1647
+ }
1648
+ echo '<br><br>';
1649
+ //***** END STEPS.
1650
+
1651
+ if ( isset( $backup_options->options['trigger'] ) ) {
1652
+ $trigger = $backup_options->options['trigger'];
1653
+ } else {
1654
+ $trigger = 'Unknown trigger';
1655
+ }
1656
+ if ( isset( $integrity['scan_time'] ) ) {
1657
+ $scanned = pb_backupbuddy::$format->date( pb_backupbuddy::$format->localize_time( $integrity['scan_time'] ) );
1658
+ echo ucfirst( $trigger ) . " backup {$integrity['file']} last scanned {$scanned}.";
1659
+ }
1660
+ echo '<br><br><br>';
1661
+
1662
+ echo '<a class="button secondary-button" onclick="jQuery(\'#pb_backupbuddy_advanced_debug\').slideToggle();">Display Advanced Debugging</a>';
1663
+ echo '<div id="pb_backupbuddy_advanced_debug" style="display: none;">From options file: `' . $optionsFile . '`.<br>';
1664
+ echo '<textarea style="width: 100%; height: 400px;" wrap="on">';
1665
+ echo print_r( $backup_options->options, true );
1666
+ echo '</textarea><br><br>';
1667
+ echo '</div><br><br>';
1668
+
1669
+ $html = ob_get_clean();
1670
+ pb_backupbuddy::flush();
1671
+ return array('result' => 'SUCCESS', 'html_detail' => $html);
1672
+ }
1673
+
1674
+ function reset_integrity() {
1675
+ $_GET['reset_integrity'] = $_POST['reset_integrity'];
1676
+ $information['backup_list'] = $this->get_backup_list();
1677
+ $information['result'] = 'SUCCESS';
1678
+ return $information;
1679
+ }
1680
+
1681
+ function download_archive() {
1682
+
1683
+ if ( ! isset( $_GET['_wpnonce'] ) || empty( $_GET['_wpnonce'] ) ) {
1684
+ die( '-1' );
1685
+ }
1686
+
1687
+ if ( ! MainWP_Helper::verify_nonce_without_session( $_GET['_wpnonce'], 'mainwp_download_backup' ) ) {
1688
+ die( '-2' );
1689
+ }
1690
+
1691
+ backupbuddy_core::verifyAjaxAccess();
1692
+
1693
+ if ( is_multisite() && !current_user_can( 'manage_network' ) ) { // If a Network and NOT the superadmin must make sure they can only download the specific subsite backups for security purposes.
1694
+
1695
+ if ( !strstr( pb_backupbuddy::_GET( 'backupbuddy_backup' ), backupbuddy_core::backup_prefix() ) ) {
1696
+ die( 'Access Denied. You may only download backups specific to your Multisite Subsite. Only Network Admins may download backups for another subsite in the network.' );
1697
+ }
1698
+ }
1699
+
1700
+ if ( !file_exists( backupbuddy_core::getBackupDirectory() . pb_backupbuddy::_GET( 'backupbuddy_backup' ) ) ) { // Does not exist.
1701
+ die( 'Error #548957857584784332. The requested backup file does not exist. It may have already been deleted.' );
1702
+ }
1703
+
1704
+ $abspath = str_replace( '\\', '/', ABSPATH );
1705
+ $backup_dir = str_replace( '\\', '/', backupbuddy_core::getBackupDirectory() );
1706
+
1707
+ if ( FALSE === stristr( $backup_dir, $abspath ) ) {
1708
+ die( 'Error #5432532. You cannot download backups stored outside of the WordPress web root. Please use FTP or other means.' );
1709
+ }
1710
+
1711
+ $sitepath = str_replace( $abspath, '', $backup_dir );
1712
+ $download_url = rtrim( site_url(), '/\\' ) . '/' . trim( $sitepath, '/\\' ) . '/' . pb_backupbuddy::_GET( 'backupbuddy_backup' );
1713
+
1714
+ if ( pb_backupbuddy::$options['lock_archives_directory'] == '1' ) {
1715
+
1716
+ if ( file_exists( backupbuddy_core::getBackupDirectory() . '.htaccess' ) ) {
1717
+ $unlink_status = @unlink( backupbuddy_core::getBackupDirectory() . '.htaccess' );
1718
+ if ( $unlink_status === false ) {
1719
+ die( 'Error #844594. Unable to temporarily remove .htaccess security protection on archives directory to allow downloading. Please verify permissions of the BackupBuddy archives directory or manually download via FTP.' );
1720
+ }
1721
+ }
1722
+
1723
+ header( 'Location: ' . $download_url );
1724
+ ob_clean();
1725
+ flush();
1726
+ sleep( 8 );
1727
+
1728
+ $htaccess_creation_status = @file_put_contents( backupbuddy_core::getBackupDirectory() . '.htaccess', 'deny from all' );
1729
+ if ( $htaccess_creation_status === false ) {
1730
+ die( 'Error #344894545. Security Warning! Unable to create security file (.htaccess) in backups archive directory. This file prevents unauthorized downloading of backups should someone be able to guess the backup location and filenames. This is unlikely but for best security should be in place. Please verify permissions on the backups directory.' );
1731
+ }
1732
+
1733
+ } else {
1734
+ header( 'Location: ' . $download_url );
1735
+ }
1736
+ die();
1737
+ }
1738
+
1739
+ function create_backup() {
1740
+ $requested_profile = $_POST['profile_id'];
1741
+
1742
+ if (!isset(pb_backupbuddy::$options['profiles'][ $requested_profile ])) {
1743
+ return array('error' => 'Invalid Profile. Not found.');
1744
+ }
1745
+
1746
+ require_once( pb_backupbuddy::plugin_path() . '/classes/backup.php' );
1747
+ $newBackup = new pb_backupbuddy_backup();
1748
+
1749
+ $profile_array = pb_backupbuddy::$options['profiles'][ $requested_profile ];
1750
+ $serial_override = pb_backupbuddy::random_string( 10 );
1751
+
1752
+ if ( $newBackup->start_backup_process(
1753
+ $profile_array,
1754
+ 'manual', // trigger
1755
+ array(),
1756
+ isset($_POST['post_backup_steps']) && is_array($_POST['post_backup_steps']) ? $_POST['post_backup_steps'] : array(),
1757
+ '',
1758
+ $serial_override,
1759
+ '', // export_plugins
1760
+ '', // direction
1761
+ '' // deployDestination
1762
+ ) !== true ) {
1763
+ return array('error' => __('Fatal Error #4344443: Backup failure. Please see any errors listed in the Status Log for details.', 'it-l10n-backupbuddy' ));
1764
+ }
1765
+ return array('result' => 'SUCCESS');
1766
+ }
1767
+
1768
+ function start_backup() {
1769
+ require_once( pb_backupbuddy::plugin_path() . '/classes/backup.php' );
1770
+ $newBackup = new pb_backupbuddy_backup();
1771
+ $data = $_POST['data'];
1772
+ if (is_array($data) && isset($data['serial_override'])) {
1773
+ if ( $newBackup->start_backup_process(
1774
+ $data['profile_array'],
1775
+ $data['trigger'],
1776
+ array(),
1777
+ isset($data['post_backup_steps']) && is_array($data['post_backup_steps']) ? $data['post_backup_steps'] : array(),
1778
+ '',
1779
+ $data['serial_override'],
1780
+ isset($data['export_plugins']) ? $data['export_plugins'] : '',
1781
+ $data['direction'],
1782
+ isset($data['deployDestination']) ? $data['deployDestination'] : ''
1783
+ ) !== true ) {
1784
+ return array('error' => __('Fatal Error #4344443: Backup failure. Please see any errors listed in the Status Log for details.', 'it-l10n-backupbuddy' ));
1785
+ }
1786
+ } else {
1787
+ return array('error' => 'Invalid backup request.');
1788
+ }
1789
+
1790
+ return array('ok' => 1);
1791
+
1792
+ }
1793
+
1794
+ function backup_status() {
1795
+ $data = $_POST['data'];
1796
+ $result = '';
1797
+ if (is_array($data) && isset($data['serial'])) {
1798
+ ob_start();
1799
+ backupbuddy_api::getBackupStatus( $data['serial'], $data['specialAction'], $data['initwaitretrycount'], $data['sqlFile'], $echo = true );
1800
+ $result = ob_get_clean();
1801
+ } else {
1802
+ return array('error' => 'Invalid backup request.');
1803
+ }
1804
+ return array('ok' => 1, 'result' => $result);
1805
+ }
1806
+
1807
+ function stop_backup() {
1808
+ $serial = $_POST['serial'];
1809
+ set_transient( 'pb_backupbuddy_stop_backup-' . $serial, true, ( 60*60*24 ) );
1810
+ return array('ok' => 1);
1811
+ }
1812
+
1813
+ function remote_save() {
1814
+ $data = isset($_POST['data']) ? $_POST['data'] : false;
1815
+ $destination_id = isset($_POST['destination_id']) ? $_POST['destination_id'] : 0;
1816
+
1817
+ if (is_array($data) && isset($data['do_not_override'])) {
1818
+
1819
+ if (true == $data['do_not_override']) {
1820
+ if (($data['type'] == 's32' || $data['type'] == 's33')) {
1821
+ $not_override = array(
1822
+ 'accesskey',
1823
+ 'secretkey',
1824
+ 'bucket',
1825
+ 'region'
1826
+ );
1827
+ foreach($not_override as $opt) {
1828
+ if (isset($data[$opt])) {
1829
+ unset($data[$opt]);
1830
+ }
1831
+ }
1832
+ }
1833
+ }
1834
+
1835
+ unset($data['do_not_override']);
1836
+ }
1837
+
1838
+
1839
+ if (is_array($data)) {
1840
+ if (isset(pb_backupbuddy::$options['remote_destinations'][$destination_id])) { // update
1841
+ pb_backupbuddy::$options['remote_destinations'][$destination_id] = array_merge( pb_backupbuddy::$options['remote_destinations'][$destination_id], $data );
1842
+ } else { // add new
1843
+ $data['token'] = pb_backupbuddy::$options['dropboxtemptoken'];
1844
+ pb_backupbuddy::$options['remote_destinations'][$destination_id] = $data;
1845
+ }
1846
+ pb_backupbuddy::save();
1847
+ return array('ok' => 1);
1848
+ } else {
1849
+ return array('error' => 'Invalid request.');
1850
+ }
1851
+ }
1852
+
1853
+ function remote_list() {
1854
+ $information = array();
1855
+ if (isset(pb_backupbuddy::$options['remote_destinations'])) { // update
1856
+ $information['remote_destinations'] = pb_backupbuddy::$options['remote_destinations'];
1857
+ }
1858
+ $information['result'] = 'SUCCESS';
1859
+ return $information;
1860
+ }
1861
+
1862
+ function remote_delete() {
1863
+ $destination_id = isset($_POST['destination_id']) ? $_POST['destination_id'] : null;
1864
+ if ($destination_id !== null) {
1865
+ require_once( pb_backupbuddy::plugin_path() . '/destinations/bootstrap.php' );
1866
+ $delete_response = pb_backupbuddy_destinations::delete_destination( $destination_id, true );
1867
+
1868
+ if ( $delete_response !== true ) {
1869
+ return array('error' => $delete_response);
1870
+ } else {
1871
+ return array('ok' => 1);
1872
+ }
1873
+ } else {
1874
+ return array('error' => 'Invalid request.');
1875
+ }
1876
+ }
1877
+
1878
+ function remote_send() {
1879
+
1880
+ $destination_id = isset($_POST['destination_id']) ? $_POST['destination_id'] : null;
1881
+ $file = isset($_POST['file']) ? $_POST['file'] : null;
1882
+ $trigger = isset($_POST['trigger']) ? $_POST['trigger'] : 'manual';
1883
+
1884
+ if ( $file != 'importbuddy.php' ) {
1885
+ $backup_file = backupbuddy_core::getBackupDirectory() . $file;
1886
+ if ( ! file_exists( $backup_file ) ) { // Error if file to send did not exist!
1887
+ $error_message = 'Unable to find file `' . $backup_file . '` to send. File does not appear to exist. You can try again in a moment or turn on full error logging and try again to log for support.';
1888
+ pb_backupbuddy::status( 'error', $error_message );
1889
+ return array( 'error' => $error_message);
1890
+ }
1891
+ if ( is_dir( $backup_file ) ) { // Error if a directory is trying to be sent.
1892
+ $error_message = 'You are attempting to send a directory, `' . $backup_file . '`. Try again and verify there were no javascript errors.';
1893
+ pb_backupbuddy::status( 'error', $error_message );
1894
+ return array( 'error' => $error_message);
1895
+ }
1896
+ } else {
1897
+ $backup_file = '';
1898
+ }
1899
+
1900
+ if ( isset($_POST['send_importbuddy']) && $_POST['send_importbuddy'] == '1' ) {
1901
+ $send_importbuddy = true;
1902
+ pb_backupbuddy::status( 'details', 'Cron send to be scheduled with importbuddy sending.' );
1903
+ } else {
1904
+ $send_importbuddy = false;
1905
+ pb_backupbuddy::status( 'details', 'Cron send to be scheduled WITHOUT importbuddy sending.' );
1906
+ }
1907
+
1908
+ if ( isset($_POST['delete_after']) && $_POST['delete_after'] == '1' ) {
1909
+ $delete_after = true;
1910
+ pb_backupbuddy::status( 'details', 'Remote send set to delete after successful send.' );
1911
+ } else {
1912
+ $delete_after = false;
1913
+ pb_backupbuddy::status( 'details', 'Remote send NOT set to delete after successful send.' );
1914
+ }
1915
+
1916
+ if ( !isset( pb_backupbuddy::$options['remote_destinations'][$destination_id] ) ) {
1917
+ return array( 'error' => 'Error #833383: Invalid destination ID `' . htmlentities( $destination_id ) . '`.' );
1918
+ }
1919
+
1920
+
1921
+ // For Stash we will check the quota prior to initiating send.
1922
+ if ( pb_backupbuddy::$options['remote_destinations'][$destination_id]['type'] == 'stash' ) {
1923
+ // Pass off to destination handler.
1924
+ require_once( pb_backupbuddy::plugin_path() . '/destinations/bootstrap.php' );
1925
+ $send_result = pb_backupbuddy_destinations::get_info( 'stash' ); // Used to kick the Stash destination into life.
1926
+ $stash_quota = pb_backupbuddy_destination_stash::get_quota( pb_backupbuddy::$options['remote_destinations'][$destination_id], true );
1927
+
1928
+ if ( isset( $stash_quota['error'] ) ) {
1929
+ return array( 'error' => ' Error accessing Stash account. Send aborted. Details: `' . implode( ' - ', $stash_quota['error'] ) . '`.');
1930
+ }
1931
+
1932
+ if ( $backup_file != '' ) {
1933
+ $backup_file_size = filesize( $backup_file );
1934
+ } else {
1935
+ $backup_file_size = 50000;
1936
+ }
1937
+ if ( ( $backup_file_size + $stash_quota['quota_used'] ) > $stash_quota['quota_total'] ) {
1938
+ ob_start();
1939
+ echo "You do not have enough Stash storage space to send this file. Please upgrade your Stash storage or delete files to make space.\n\n";
1940
+ echo 'Attempting to send file of size ' . pb_backupbuddy::$format->file_size( $backup_file_size ) . ' but you only have ' . $stash_quota['quota_available_nice'] . ' available. ';
1941
+ echo 'Currently using ' . $stash_quota['quota_used_nice'] . ' of ' . $stash_quota['quota_total_nice'] . ' (' . $stash_quota['quota_used_percent'] . '%).';
1942
+ $error = ob_get_clean();
1943
+ return array( 'error' => $error );
1944
+ } else {
1945
+ if ( isset( $stash_quota['quota_warning'] ) && ( $stash_quota['quota_warning'] != '' ) ) {
1946
+ $warning = 'Warning: ' . $stash_quota['quota_warning'] . "\n\n";
1947
+ $success_output = true;
1948
+ }
1949
+ }
1950
+
1951
+ } // end if Stash.
1952
+
1953
+ pb_backupbuddy::status( 'details', 'Scheduling cron to send to this remote destination...' );
1954
+
1955
+ $schedule_result = backupbuddy_core::schedule_single_event( time(), 'remote_send', array( $destination_id, $backup_file, $trigger, $send_importbuddy, $delete_after ) );
1956
+ if ( $schedule_result === FALSE ) {
1957
+ $error = 'Error scheduling file transfer. Please check your BackupBuddy error log for details. A plugin may have prevented scheduling or the database rejected it.';
1958
+ pb_backupbuddy::status( 'error', $error );
1959
+ return array( 'error' => $error);
1960
+ } else {
1961
+ pb_backupbuddy::status( 'details', 'Cron to send to remote destination scheduled.' );
1962
+ }
1963
+ if ( '1' != pb_backupbuddy::$options['skip_spawn_cron_call'] ) {
1964
+ update_option( '_transient_doing_cron', 0 ); // Prevent cron-blocking for next item.
1965
+ spawn_cron( time() + 150 ); // Adds > 60 seconds to get around once per minute cron running limit.
1966
+ }
1967
+ return array( 'ok' => 1);
1968
+ }
1969
+
1970
+ function get_main_log() {
1971
+ $log_file = backupbuddy_core::getLogDirectory() . 'log-' . pb_backupbuddy::$options['log_serial'] . '.txt';
1972
+ ob_start();
1973
+ if ( file_exists( $log_file ) ) {
1974
+ readfile( $log_file );
1975
+ } else {
1976
+ echo __('Nothing has been logged.', 'it-l10n-backupbuddy' );
1977
+ }
1978
+ $result = ob_get_clean();
1979
+ return array('result' => $result );
1980
+ }
1981
+
1982
+ function settings_other() {
1983
+
1984
+ $other_action = $_POST['other_action'];
1985
+
1986
+ $message = '';
1987
+ $error = '';
1988
+
1989
+ if ( 'cleanup_now' == $other_action ) {
1990
+ $message = 'Performing cleanup procedures now trimming old files and data.';
1991
+ require_once( pb_backupbuddy::plugin_path() . '/classes/housekeeping.php' );
1992
+ backupbuddy_housekeeping::run_periodic( 0 ); // 0 cleans up everything even if not very old.
1993
+
1994
+ } else if ( 'delete_tempfiles_now' == $other_action) {
1995
+ $tempDir = backupbuddy_core::getTempDirectory();
1996
+ $logDir = backupbuddy_core::getLogDirectory();
1997
+ $message = 'Deleting all files contained within `' . $tempDir . '` and `' . $logDir . '`.' ;
1998
+ pb_backupbuddy::$filesystem->unlink_recursive( $tempDir );
1999
+ pb_backupbuddy::$filesystem->unlink_recursive( $logDir );
2000
+ pb_backupbuddy::anti_directory_browsing( $logDir, $die = false ); // Put log dir back in place.
2001
+ } else if ( 'reset_log' == $other_action ) {
2002
+ $log_file = backupbuddy_core::getLogDirectory() . 'log-' . pb_backupbuddy::$options['log_serial'] . '.txt';
2003
+ if ( file_exists( $log_file ) ) {
2004
+ @unlink( $log_file );
2005
+ }
2006
+ if ( file_exists( $log_file ) ) { // Didnt unlink.
2007
+ $error = 'Unable to clear log file. Please verify permissions on file `' . $log_file . '`.';
2008
+ } else { // Unlinked.
2009
+ $message = 'Cleared log file.';
2010
+ }
2011
+ } else if ( 'reset_disalerts' == $other_action) {
2012
+ pb_backupbuddy::$options['disalerts'] = array();
2013
+ pb_backupbuddy::save();
2014
+ $message = 'Dismissed alerts have been reset. They may now be visible again.';
2015
+
2016
+ } else if ( 'cancel_running_backups' == $other_action) {
2017
+ require_once( pb_backupbuddy::plugin_path() . '/classes/fileoptions.php' );
2018
+
2019
+ $fileoptions_directory = backupbuddy_core::getLogDirectory() . 'fileoptions/';
2020
+ $files = glob( $fileoptions_directory . '*.txt' );
2021
+ if ( ! is_array( $files ) ) {
2022
+ $files = array();
2023
+ }
2024
+ $cancelCount = 0;
2025
+ for ($x = 0; $x <= 3; $x++) { // Try this a few times since there may be race conditions on an open file.
2026
+ foreach( $files as $file ) {
2027
+ pb_backupbuddy::status( 'details', 'Fileoptions instance #383.' );
2028
+
2029
+ $backup_options = new pb_backupbuddy_fileoptions( $file, $read_only = false );
2030
+ if ( true !== ( $result = $backup_options->is_ok() ) ) {
2031
+ pb_backupbuddy::status( 'error', 'Error retrieving fileoptions file `' . $file . '`. Err 335353266.' );
2032
+ } else {
2033
+ if ( empty( $backup_options->options['finish_time'] ) || ( ( FALSE !== $backup_options->options['finish_time'] ) && ( '-1' != $backup_options->options['finish_time'] ) ) ) {
2034
+ $backup_options->options['finish_time'] = -1; // Force marked as cancelled by user.
2035
+ $backup_options->save();
2036
+ $cancelCount++;
2037
+ }
2038
+ }
2039
+ }
2040
+ sleep( 1 );
2041
+ }
2042
+
2043
+ $message = 'Marked all timed out or running backups & transfers as officially cancelled (`' . $cancelCount . '` total found).';
2044
+ }
2045
+
2046
+ return array('_error' => $error, '_message' => $message);
2047
+ }
2048
+
2049
+ function malware_scan() {
2050
+
2051
+ backupbuddy_core::schedule_single_event( time(), 'housekeeping', array() );
2052
+ update_option( '_transient_doing_cron', 0 );
2053
+ spawn_cron( time() + 150 );
2054
+
2055
+ ob_start();
2056
+
2057
+ if ( ! defined( 'pluginbuddy_importbuddy' ) ) {
2058
+ $url = home_url();
2059
+ } else {
2060
+ $url = str_replace( $_SERVER['QUERY_STRING'], '', $_SERVER['REQUEST_URI'] );
2061
+ $url = str_replace( basename( $url ) , '', $url );
2062
+ $url = 'http://' . $_SERVER['HTTP_HOST'] . $url;
2063
+ }
2064
+ ?>
2065
+ <style type="text/css">
2066
+ .inside label {
2067
+ display: block;
2068
+ vertical-align: top;
2069
+ width: 140px;
2070
+ font-weight: bold;
2071
+ }
2072
+ </style>
2073
+
2074
+
2075
+ <?php
2076
+ pb_backupbuddy::$ui->start_metabox( __( 'Malware Scan URL', 'it-l10n-backupbuddy' ), true, 'width: 100%;' );
2077
+
2078
+ ?>
2079
+
2080
+ <?php echo $url; ?>
2081
+
2082
+ <?php
2083
+
2084
+ $continue_1 = true;
2085
+ if ( $url == 'http://localhost' ) {
2086
+ _e('ERROR: You are currently running your site locally. Your site must be internet accessible to scan.', 'it-l10n-backupbuddy' );
2087
+ $continue_1 = false;
2088
+ }
2089
+
2090
+ if ( $continue_1 === true ) {
2091
+
2092
+ if ( !empty( $_POST['refresh'] ) ) {
2093
+ delete_transient( 'pb_backupbuddy_malwarescan' );
2094
+ }
2095
+
2096
+ //echo '<br />Scanning `' . $url . '`.<br /><br />';
2097
+ if ( !defined( 'pluginbuddy_importbuddy' ) ) {
2098
+ $scan = get_transient( 'pb_backupbuddy_malwarescan' );
2099
+ } else {
2100
+ $scan = false;
2101
+ }
2102
+
2103
+ if ( false === $scan ) {
2104
+ flush();
2105
+
2106
+ $scan = wp_remote_get(
2107
+ 'http://sitecheck.sucuri.net/scanner/?scan=' . urlencode( $url ) . '&serialized&clear=true',
2108
+ array(
2109
+ 'method' => 'GET',
2110
+ 'timeout' => 45,
2111
+ 'redirection' => 5,
2112
+ 'httpversion' => '1.0',
2113
+ 'blocking' => true,
2114
+ 'headers' => array(),
2115
+ 'body' => null,
2116
+ 'cookies' => array()
2117
+ )
2118
+ );
2119
+
2120
+ if ( is_wp_error( $scan ) ) {
2121
+ pb_backupbuddy::alert( __('ERROR #24452. Unable to load Malware Scan results. Details:', 'it-l10n-backupbuddy' ). ' ' . $scan->get_error_message(), true );
2122
+ $scan = 'N;';
2123
+ } else {
2124
+ $scan = $scan['body'];
2125
+ set_transient( 'pb_backupbuddy_malwarescan', $scan, 60*60*1 ); // 1 hour cache.
2126
+ }
2127
+
2128
+ }
2129
+
2130
+ $continue_2 = true;
2131
+ if ( substr( $scan, 0, 2 ) == 'N;' ) {
2132
+ echo __('An error was encountered attempting to scan this site.','it-l10n-backupbuddy' ), '<br />';
2133
+ echo __('An internet connection is required and this site must be accessible on the public internet.', 'it-l10n-backupbuddy' );
2134
+ echo '<br>';
2135
+ $scan = array();
2136
+ $continue_2 = false;
2137
+ } else {
2138
+ $scan = maybe_unserialize( $scan );
2139
+ //echo '<pre>';
2140
+ //print_r( $scan );
2141
+ //echo '</pre>';
2142
+ }
2143
+
2144
+ }
2145
+
2146
+ pb_backupbuddy::$ui->end_metabox();
2147
+ ?>
2148
+
2149
+
2150
+
2151
+ <?php
2152
+
2153
+
2154
+ if ( $continue_2 === true ) {
2155
+ function lined_array( $array ) {
2156
+ if ( is_array( $array ) ) {
2157
+ foreach( $array as $array_key => $array_item ) {
2158
+ if ( is_array( $array_item ) ) {
2159
+ $array[$array_key] = lined_array( $array_item );
2160
+ }
2161
+ }
2162
+ //return implode( '<br />', $array );
2163
+ $return = '';
2164
+ foreach( $array as $array_item ) {
2165
+ $return .= $array_item . '<br />';
2166
+ }
2167
+ return $return;
2168
+ } else {
2169
+ if ( empty( $array ) ) {
2170
+ return '<i>'.__('none', 'it-l10n-backupbuddy' ).'</i><br />';
2171
+ } else {
2172
+ return $array . '<br />';
2173
+ }
2174
+ }
2175
+ }
2176
+
2177
+ if ( !empty( $scan['MALWARE'] ) && ( $scan['MALWARE'] != 'E' ) ) {
2178
+ echo '<table><tr><td><i class="fa fa-exclamation-circle fa-5x" style="color: red"></i></td><td><h1>', __('Warning: Possible Malware Detected!', 'it-l10n-backupbuddy' ), '</h1>',__('See details below.', 'it-l10n-backupbuddy' ), '</td></tr></table>';
2179
+ }
2180
+
2181
+ ?>
2182
+
2183
+
2184
+ <div class="postbox-container" style="width: 100%; min-width: 750px;">
2185
+ <div class="metabox-holder">
2186
+ <div class="meta-box-sortables">
2187
+
2188
+ <div id="breadcrumbslike" class="postbox">
2189
+ <div class="handlediv" title="<?php _e('Click to toggle', 'it-l10n-backupbuddy' );?>"><br /></div>
2190
+ <h3 class="hndle"><span><?php _e('Malware Detection', 'it-l10n-backupbuddy' );?></span></h3>
2191
+ <div class="inside">
2192
+ <label><?php _e('Malware', 'it-l10n-backupbuddy' );?></label>
2193
+ <?php
2194
+ if ( !empty( $scan['MALWARE']['WARN'] ) ) { // Malware found.
2195
+ echo lined_array( $scan['MALWARE']['WARN'] );
2196
+ backupbuddy_core::addNotification( 'malware_found', 'Malware detected on `' . $url . '`.', 'A malware scan was run on the site and detected malware.', array(), true ); // Urgent
2197
+ } else { // No malware found.
2198
+ echo '<i>', __('none', 'it-l10n-backupbuddy' ), '</i><br />';
2199
+ backupbuddy_core::addNotification( 'malware_not_found', 'No malware detected on `' . $url . '`.', 'A malware scan was run on the site and did not detect malware.' );
2200
+ } ?><br />
2201
+ </div>
2202
+ </div>
2203
+
2204
+ <div id="breadcrumbslike" class="postbox">
2205
+ <div class="handlediv" title="<?php _e('Click to toggle', 'it-l10n-backupbuddy' );?>"><br /></div>
2206
+ <h3 class="hndle"><span><?php _e('Web server details', 'it-l10n-backupbuddy' );?></span></h3>
2207
+ <div class="inside">
2208
+ <label><?php _e('Site', 'it-l10n-backupbuddy' );?></label> <?php if ( !empty( $scan['SCAN']['SITE'] ) ) { echo lined_array( $scan['SCAN']['SITE'] ); } else { echo '<i>', __('none', 'it-l10n-backupbuddy' ),'</i><br />'; } ?><br />
2209
+ <label><?php _e('Hostname', 'it-l10n-backupbuddy' );?></label> <?php if ( !empty( $scan['SCAN']['DOMAIN'] ) ) { echo lined_array( $scan['SCAN']['DOMAIN'] ); } else { echo '<i>',__('none', 'it-l10n-backupbuddy' ),'</i><br />'; } ?><br />
2210
+ <label><?php _e('IP Address', 'it-l10n-backupbuddy' );?></label> <?php if ( !empty( $scan['SCAN']['IP'] ) ) { echo lined_array( $scan['SCAN']['IP'] ); } else { echo '<i>',__('none', 'it-l10n-backupbuddy' ),'</i><br />'; } ?><br />
2211
+ <label><?php _e('System details', 'it-l10n-backupbuddy' );?></label> <?php if ( !empty( $scan['SYSTEM']['NOTICE'] ) ) { echo lined_array( $scan['SYSTEM']['NOTICE'] ); } else { echo '<i>', __('none','it-l10n-backupbuddy' ), '</i><br />'; } ?><br />
2212
+ <label><?php _e('Information', 'it-l10n-backupbuddy' );?></label> <?php if ( !empty( $scan['SYSTEM']['INFO'] ) ) { echo lined_array( $scan['SYSTEM']['INFO'] ); } else { echo '<i>', __('none', 'it-l10n-backupbuddy' ), '</i><br />'; } ?><br />
2213
+ </div>
2214
+ </div>
2215
+
2216
+ <div id="breadcrumbslike" class="postbox">
2217
+ <div class="handlediv" title="Click to toggle"><br /></div>
2218
+ <h3 class="hndle"><span><?php _e('Web application', 'it-l10n-backupbuddy' );?></span></h3>
2219
+ <div class="inside">
2220
+ <label><?php _e('Details', 'it-l10n-backupbuddy' );?></label> <?php if ( !empty( $scan['WEBAPP']['INFO'] ) ) { echo lined_array( $scan['WEBAPP']['INFO'] ); } else { echo '<i>', __('none', 'it-l10n-backupbuddy' ),'</i><br />'; } ?><br />
2221
+ <label><?php _e('Versions', 'it-l10n-backupbuddy' );?></label> <?php if ( !empty( $scan['WEBAPP']['VERSION'] ) ) { echo lined_array( $scan['WEBAPP']['VERSION'] ); } else { echo '<i>',__('none', 'it-l10n-backupbuddy' ),'</i><br />'; } ?><br />
2222
+ <label><?php _e('Notices', 'it-l10n-backupbuddy' );?></label> <?php if ( !empty( $scan['WEBAPP']['NOTICE'] ) ) { echo lined_array( $scan['WEBAPP']['NOTICE'] ); } else { echo '<i>', __('none', 'it-l10n-backupbuddy' ), '</i><br />'; } ?><br />
2223
+ <label><?php _e('Errors', 'it-l10n-backupbuddy' );?></label> <?php if ( !empty( $scan['WEBAPP']['ERROR'] ) ) { echo lined_array( $scan['WEBAPP']['ERROR'] ); } else { echo '<i>',__('none', 'it-l10n-backupbuddy' ),'</i><br />'; } ?><br />
2224
+ <label><?php _e('Warnings', 'it-l10n-backupbuddy' );?></label> <?php if ( !empty( $scan['WEBAPP']['WARN'] ) ) { echo lined_array( $scan['WEBAPP']['WARN'] ); } else { echo '<i>', __('none', 'it-l10n-backupbuddy' ), '</i><br />'; } ?><br />
2225
+ </div>
2226
+ </div>
2227
+
2228
+ <div id="breadcrumbslike" class="postbox">
2229
+ <div class="handlediv" title="<?php _e('Click to toggle', 'it-l10n-backupbuddy' );?>"><br /></div>
2230
+ <h3 class="hndle"><span><?php _e('Links', 'it-l10n-backupbuddy' );?></span></h3>
2231
+ <div class="inside">
2232
+ <?php if ( !empty( $scan['LINKS']['URL'] ) ) { echo lined_array( $scan['LINKS']['URL'] ); } else { echo '<i>', __('none', 'it-l10n-backupbuddy' ), '</i><br />'; } ?>
2233
+ </div>
2234
+ </div>
2235
+
2236
+ <div id="breadcrumbslike" class="postbox">
2237
+ <div class="handlediv" title="<?php _e('Click to toggle', 'it-l10n-backupbuddy' );?>"><br /></div>
2238
+ <h3 class="hndle"><span><?php _e('Local Javascript', 'it-l10n-backupbuddy' );?></span></h3>
2239
+ <div class="inside">
2240
+ <?php if ( !empty( $scan['LINKS']['JSLOCAL'] ) ) { echo lined_array( $scan['LINKS']['JSLOCAL'] ); } else { echo '<i>', __('none', 'it-l10n-backupbuddy' ),'</i><br />'; } ?>
2241
+ </div>
2242
+ </div>
2243
+
2244
+ <div id="breadcrumbslike" class="postbox">
2245
+ <div class="handlediv" title="<?php _e('Click to toggle', 'it-l10n-backupbuddy' );?>"><br /></div>
2246
+ <h3 class="hndle"><span><?php _e('External Javascript', 'it-l10n-backupbuddy' );?></span></h3>
2247
+ <div class="inside">
2248
+ <?php if ( !empty( $scan['LINKS']['JSEXTERNAL'] ) ) { echo lined_array( $scan['LINKS']['JSEXTERNAL'] ); } else { echo '<i>', __('none', 'it-l10n-backupbuddy' ), '</i><br />'; } ?>
2249
+ </div>
2250
+ </div>
2251
+
2252
+ <div id="breadcrumbslike" class="postbox">
2253
+ <div class="handlediv" title="<?php _e('Click to toggle', 'it-l10n-backupbuddy' );?>"><br /></div>
2254
+ <h3 class="hndle"><span><?php _e('Iframes Included', 'it-l10n-backupbuddy' );?></span></h3>
2255
+ <div class="inside">
2256
+ <?php if ( !empty( $scan['LINKS']['IFRAME'] ) ) { echo lined_array( $scan['LINKS']['IFRAME'] ); } else { echo '<i>', __('none', 'it-l10n-backupbuddy' ), '</i><br />'; } ?>
2257
+ </div>
2258
+ </div>
2259
+
2260
+ <div id="breadcrumbslike" class="postbox">
2261
+ <div class="handlediv" title="<?php _e('Click to toggle', 'it-l10n-backupbuddy' );?>"><br /></div>
2262
+ <h3 class="hndle"><span><?php _e('Blacklisting Status', 'it-l10n-backupbuddy' );?></span></h3>
2263
+ <div class="inside">
2264
+ <?php if ( !empty( $scan['BLACKLIST']['INFO'] ) ) { echo lined_array( $scan['BLACKLIST']['INFO'] ); } else { echo '<i>', __('none', 'it-l10n-backupbuddy' ), '</i><br />'; } ?>
2265
+ </div>
2266
+ </div>
2267
+
2268
+ </div>
2269
+ </div>
2270
+ </div>
2271
+ <?php
2272
+
2273
+
2274
+ }
2275
+ $result = ob_get_clean();
2276
+
2277
+ return array('result' => $result);
2278
+ }
2279
+
2280
+
2281
+ function live_setup() {
2282
+
2283
+ $errors = array();
2284
+
2285
+ $archive_types = array(
2286
+ 'db' => __( 'Database Backup', 'it-l10n-backupbuddy' ),
2287
+ 'full' => __( 'Full Backup', 'it-l10n-backupbuddy' ),
2288
+ 'plugins' => __( 'Plugins Backup', 'it-l10n-backupbuddy' ),
2289
+ 'themes' => __( 'Themes Backup', 'it-l10n-backupbuddy' ),
2290
+ );
2291
+
2292
+ $archive_periods = array(
2293
+ 'daily',
2294
+ 'weekly',
2295
+ 'monthly',
2296
+ 'yearly',
2297
+ );
2298
+
2299
+
2300
+ if ( ( '' == $_POST['live_username'] ) || ( '' == $_POST['live_password'] ) ) { // A field is blank.
2301
+ $errors[] = 'You must enter your iThemes username & password to log in to BackupBuddy Stash Live.';
2302
+ } else { // Username and password provided.
2303
+
2304
+ require_once( pb_backupbuddy::plugin_path() . '/destinations/stash2/class.itx_helper2.php' );
2305
+ require_once( pb_backupbuddy::plugin_path() . '/destinations/stash2/init.php' );
2306
+ require_once( pb_backupbuddy::plugin_path() . '/destinations/live/init.php' );
2307
+ global $wp_version;
2308
+
2309
+ $itxapi_username = strtolower( $_POST['live_username'] );
2310
+ $password_hash = iThemes_Credentials::get_password_hash( $itxapi_username, $_POST['live_password'] );
2311
+ $access_token = ITXAPI_Helper2::get_access_token( $itxapi_username, $password_hash, site_url(), $wp_version );
2312
+
2313
+ $settings = array(
2314
+ 'itxapi_username' => $itxapi_username,
2315
+ 'itxapi_password' => $access_token,
2316
+ );
2317
+ $response = pb_backupbuddy_destination_stash2::stashAPI( $settings, 'connect' );
2318
+
2319
+ if ( ! is_array( $response ) ) { // Error message.
2320
+ $errors[] = print_r( $response, true );
2321
+ } else {
2322
+ if ( isset( $response['error'] ) ) {
2323
+ $errors[] = $response['error']['message'];
2324
+ } else {
2325
+ if ( isset( $response['token'] ) ) {
2326
+ $itxapi_token = $response['token'];
2327
+ } else {
2328
+ $errors[] = 'Error #2308832: Unexpected server response. Token missing. Check your BackupBuddy Stash Live login and try again. Detailed response: `' . print_r( $response, true ) .'`.';
2329
+ }
2330
+ }
2331
+ }
2332
+
2333
+ // If we have the token then create the Live destination.
2334
+ if ( isset( $itxapi_token ) ) {
2335
+ if ( count( pb_backupbuddy::$options['remote_destinations'] ) > 0 ) {
2336
+ $nextDestKey = max( array_keys( pb_backupbuddy::$options['remote_destinations'] ) ) + 1;
2337
+ } else { // no destinations yet. first index.
2338
+ $nextDestKey = 0;
2339
+ }
2340
+
2341
+ pb_backupbuddy::$options['remote_destinations'][ $nextDestKey ] = pb_backupbuddy_destination_live::$default_settings;
2342
+ pb_backupbuddy::$options['remote_destinations'][ $nextDestKey ]['itxapi_username'] = $_POST['live_username'];
2343
+ pb_backupbuddy::$options['remote_destinations'][ $nextDestKey ]['itxapi_token'] = $itxapi_token;
2344
+ pb_backupbuddy::$options['remote_destinations'][ $nextDestKey ]['title'] = 'My BackupBuddy Stash Live';
2345
+
2346
+ // Notification email.
2347
+ pb_backupbuddy::$options['remote_destinations'][ $nextDestKey ]['email'] = $_POST['email'];
2348
+
2349
+ // Archive limits.
2350
+ foreach( $archive_types as $archive_type => $archive_type_name ) {
2351
+ foreach( $archive_periods as $archive_period ) {
2352
+ $settings_name = 'limit_' . $archive_type . '_' . $archive_period;
2353
+ pb_backupbuddy::$options['remote_destinations'][ $nextDestKey ][ $settings_name ] = $_POST['live_settings'][$settings_name];
2354
+ }
2355
+ }
2356
+
2357
+ if ( '1' == $_POST['send_snapshot_notification'] ) {
2358
+ pb_backupbuddy::$options['remote_destinations'][ $nextDestKey ]['send_snapshot_notification'] = $_POST['send_snapshot_notification'];
2359
+ } else {
2360
+ pb_backupbuddy::$options['remote_destinations'][ $nextDestKey ]['send_snapshot_notification'] = '0';
2361
+ }
2362
+
2363
+ pb_backupbuddy::save();
2364
+ $destination_id = $nextDestKey;
2365
+
2366
+ // Send new settings for archive limiting to Stash API.
2367
+ backupbuddy_live::send_trim_settings();
2368
+
2369
+
2370
+
2371
+ // Set first run of BackupBuddy Stash Live so it begins immediately.
2372
+ $cronArgs = array();
2373
+ $schedule_result = backupbuddy_core::schedule_single_event( time(), 'live_periodic', $cronArgs );
2374
+ if ( true === $schedule_result ) {
2375
+ pb_backupbuddy::status( 'details', 'Next Live Periodic chunk step cron event scheduled.' );
2376
+ } else {
2377
+ pb_backupbuddy::status( 'error', 'Next Live Periodic chunk step cron event FAILED to be scheduled.' );
2378
+ }
2379
+ if ( '1' != pb_backupbuddy::$options['skip_spawn_cron_call'] ) {
2380
+ pb_backupbuddy::status( 'details', 'Spawning cron now.' );
2381
+ update_option( '_transient_doing_cron', 0 ); // Prevent cron-blocking for next item.
2382
+ spawn_cron( time() + 150 ); // Adds > 60 seconds to get around once per minute cron running limit.
2383
+ }
2384
+
2385
+ }
2386
+
2387
+ } // end if user and pass set.
2388
+
2389
+
2390
+ if ( 0 == count( $errors ) ) {
2391
+ pb_backupbuddy::save();
2392
+ $data = pb_backupbuddy::$options['remote_destinations'][ $destination_id ];
2393
+ return array( 'destination_id' => $destination_id, 'data' => $data);
2394
+ } else {
2395
+ return array( 'errors' => $errors );
2396
+ }
2397
+
2398
+ }
2399
+
2400
+ function live_save_settings() {
2401
+ $data = $_POST['data'];
2402
+ $new_destination_id = $_POST['destination_id'];
2403
+
2404
+
2405
+ require_once( pb_backupbuddy::plugin_path() . '/destinations/bootstrap.php' );
2406
+ require_once( pb_backupbuddy::plugin_path() . '/destinations/live/live.php' );
2407
+ require_once( pb_backupbuddy::plugin_path() . '/destinations/live/live_periodic.php' );
2408
+
2409
+ $destination_id = backupbuddy_live::getLiveID();
2410
+ $destination_settings = isset(pb_backupbuddy::$options['remote_destinations'][$destination_id]) ? pb_backupbuddy::$options['remote_destinations'][$destination_id] : array();
2411
+
2412
+ $check_current = !empty($destination_settings) ? true : false;
2413
+
2414
+ $error = '';
2415
+ if ( $new_destination_id && is_array($data) ) {
2416
+ $itxapi_username = isset($destination_settings['itxapi_username']) ? $destination_settings['itxapi_username'] : '';
2417
+ $itxapi_token = isset($destination_settings['itxapi_token']) ? $destination_settings['itxapi_token'] : '';
2418
+ $destination_settings = array_merge( $destination_settings, $data );
2419
+ $destination_settings['itxapi_username'] = $itxapi_username;
2420
+ $destination_settings['itxapi_token'] = $itxapi_token;
2421
+ pb_backupbuddy::$options['remote_destinations'][$new_destination_id] = $destination_settings;
2422
+
2423
+ if ($check_current && $destination_id != $new_destination_id) {
2424
+ unset(pb_backupbuddy::$options['remote_destinations'][$destination_id]);
2425
+ }
2426
+
2427
+ pb_backupbuddy::save();
2428
+ //pb_backupbuddy::alert( __( 'Settings saved. Restarting Live process so they take immediate effect.', 'it-l10n-backupbuddy' ) );
2429
+ set_transient( 'backupbuddy_live_jump', array( 'daily_init', array() ), 60*60*48 ); // Tells Live process to restart from the beginning (if mid-process) so new settigns apply.
2430
+
2431
+ backupbuddy_live::send_trim_settings();
2432
+ return array('ok' => 1);
2433
+ } else {
2434
+ $error = 'Invalid data.';
2435
+ }
2436
+ return array('error' => $error);
2437
+ }
2438
+
2439
+ function live_action_disconnect() {
2440
+ $error = '';
2441
+ $liveDestinationID = $_POST['destination_id'];
2442
+
2443
+ $return = array();
2444
+ if ($liveDestinationID) {
2445
+ if (isset(pb_backupbuddy::$options['remote_destinations'][ $liveDestinationID ])) {
2446
+ // Clear destination settings.
2447
+ unset( pb_backupbuddy::$options['remote_destinations'][ $liveDestinationID ] );
2448
+ pb_backupbuddy::save();
2449
+ // Clear cached Live credentials.
2450
+ require_once( pb_backupbuddy::plugin_path() . '/destinations/live/init.php' );
2451
+ delete_transient( pb_backupbuddy_destination_live::LIVE_ACTION_TRANSIENT_NAME );
2452
+ } else {
2453
+ $error = 'Error: Not found.';
2454
+ }
2455
+ $return['ok'] = 1;
2456
+ } else {
2457
+ $error = 'Error: Empty destination id.';
2458
+ }
2459
+
2460
+ if (!empty($error))
2461
+ $return['error'] = $error;
2462
+
2463
+ return $return;
2464
+ }
2465
+
2466
+ function live_action() {
2467
+ $action = $_POST['live_action'];
2468
+ $error = $message = '';
2469
+
2470
+ require_once( pb_backupbuddy::plugin_path() . '/destinations/live/live_periodic.php' );
2471
+ $state = backupbuddy_live_periodic::get_stats();
2472
+
2473
+ $destination_id = backupbuddy_live::getLiveID();
2474
+ $destination = backupbuddy_live_periodic::get_destination_settings();
2475
+
2476
+ if ( 'clear_log' == $action ) {
2477
+ $sumLogFile = backupbuddy_core::getLogDirectory() . 'status-live_periodic_' . pb_backupbuddy::$options['log_serial'] . '.txt';
2478
+ @unlink( $sumLogFile );
2479
+ if ( file_exists( $sumLogFile ) ) {
2480
+ $error = 'Error #893489322: Unable to clear log file `' . $sumLogFile . '`. Check permissions or manually delete.' ;
2481
+ } else {
2482
+ $message = 'Log file cleared.';
2483
+ }
2484
+
2485
+ } else if ( 'create_snapshot' == $action ) { // < 100% backed up _OR_ ( we are on a step other than daily_init and the last_activity is more recent than the php runtime )
2486
+ if ( true === backupbuddy_api::runLiveSnapshot() ) {
2487
+ //pb_backupbuddy::alert( '<h3>' . __( 'Verifying everything is up to date before Snapshot', 'it-l10n-backupbuddy' ) . '</h3><p class="description" style="max-width: 700px; display: inline-block;">' . __( 'Please wait while we verify your backup is completely up to date before we create the Snapshot. This may take a few minutes...', 'it-l10n-backupbuddy' ) . '</p>', false, '', 'backupbuddy_live_snapshot_verify_uptodate' );
2488
+ $message = '<h3>' . __( 'Verifying everything is up to date before Snapshot', 'it-l10n-backupbuddy' ) . '</h3><p class="description" style="max-width: 700px; display: inline-block;">' . __( 'Please wait while we verify your backup is completely up to date before we create the Snapshot. This may take a few minutes...', 'it-l10n-backupbuddy' ) . '</p>';
2489
+ require( pb_backupbuddy::plugin_path() . '/destinations/live/_manual_snapshot.php' );
2490
+ }
2491
+
2492
+ } else if ( 'pause_periodic' == $action ) {
2493
+ backupbuddy_api::setLiveStatus( $pause_continuous = '', $pause_periodic = true );
2494
+ $destination = pb_backupbuddy::$options['remote_destinations'][$destination_id]; // Update local var.
2495
+ //pb_backupbuddy::disalert( '', __( 'Live File Backup paused. It may take a moment for current processes to finish.', 'it-l10n-backupbuddy' ) );
2496
+ $message = __( 'Live File Backup paused. It may take a moment for current processes to finish.', 'it-l10n-backupbuddy' );
2497
+ include( pb_backupbuddy::plugin_path() . '/destinations/live/_stats.php' ); // Recalculate stats.
2498
+ } else if ( 'resume_periodic' == $action ) {
2499
+ $launchNowText = ' ' . __( 'Unpaused but not running now.', 'it-l10n-backupbuddy' );
2500
+ $start_run = false;
2501
+ if ( '1' != pb_backupbuddy::_GET( 'skip_run_live_now' ) ) {
2502
+ $launchNowText = '';
2503
+ $start_run = true;
2504
+ }
2505
+
2506
+ backupbuddy_api::setLiveStatus( $pause_continuous = '', $pause_periodic = false, $start_run );
2507
+ //pb_backupbuddy::disalert( '', __( 'Live File Backup has resumed.', 'it-l10n-backupbuddy' ) . $launchNowText );
2508
+ $message = __( 'Live File Backup has resumed.', 'it-l10n-backupbuddy' ) . $launchNowText;
2509
+ include( pb_backupbuddy::plugin_path() . '/destinations/live/_stats.php' ); // Recalculate stats.
2510
+ } else if ( 'pause_continuous' == $action ) {
2511
+ backupbuddy_api::setLiveStatus( $pause_continuous = true, $pause_periodic = '' );
2512
+ $destination = pb_backupbuddy::$options['remote_destinations'][$destination_id]; // Update local var.
2513
+ include( pb_backupbuddy::plugin_path() . '/destinations/live/_stats.php' ); // Recalculate stats.
2514
+ //pb_backupbuddy::disalert( '', __( 'Live Database Backup paused.', 'it-l10n-backupbuddy' ) );
2515
+ $message = __( 'Live Database Backup paused.', 'it-l10n-backupbuddy' );
2516
+ } else if ( 'resume_continuous' == $action ) {
2517
+ backupbuddy_api::setLiveStatus( $pause_continuous = false, $pause_periodic = '' );
2518
+ $destination = pb_backupbuddy::$options['remote_destinations'][$destination_id]; // Update local var.
2519
+ include( pb_backupbuddy::plugin_path() . '/destinations/live/_stats.php' ); // Recalculate stats.
2520
+ //pb_backupbuddy::disalert( '', __( 'Live Database Backup resumed.', 'it-l10n-backupbuddy' ) );
2521
+ $message = __( 'Live Database Backup resumed.', 'it-l10n-backupbuddy' );
2522
+ } else {
2523
+ $error = 'Error #1000. Invalid request.';
2524
+ }
2525
+
2526
+ return array( 'ok' => 1, '_error' => $error, '_message' => $message );
2527
+ }
2528
+
2529
+
2530
+
2531
+ function download_troubleshooting() {
2532
+ require( pb_backupbuddy::plugin_path() . '/destinations/live/_troubleshooting.php' );
2533
+ backupbuddy_live_troubleshooting::run();
2534
+ $output = "**File best viewed with wordwrap OFF**\n\n" . print_r( backupbuddy_live_troubleshooting::get_raw_results(), true );
2535
+ $backup_prefix = backupbuddy_core::backup_prefix();
2536
+ return array( 'output' => $output, 'backup_prefix' => $backup_prefix );
2537
+ }
2538
+
2539
+ function get_live_backups() {
2540
+ $destination_id = $_POST['destination_id'];
2541
+ // Load required files.
2542
+ require_once( pb_backupbuddy::plugin_path() . '/destinations/s32/init.php' );
2543
+
2544
+ if ( ! isset( pb_backupbuddy::$options['remote_destinations'][ $destination_id ] ) ) {
2545
+ return array( 'error' => 'Error #9828332: Destination not found with id `' . htmlentities( $destination_id ) . '`.' );
2546
+ }
2547
+ require_once( pb_backupbuddy::plugin_path() . '/destinations/stash2/init.php' );
2548
+ $settings = &pb_backupbuddy::$options['remote_destinations'][ $destination_id ];
2549
+ $settings = pb_backupbuddy_destination_stash2::_formatSettings( $settings );
2550
+
2551
+ $destination = pb_backupbuddy::$options['remote_destinations'][ $destination_id ];
2552
+
2553
+ if ( 'live' == $destination['type'] ) {
2554
+ $remotePath = 'snapshot-';// . backupbuddy_core::backup_prefix();
2555
+ $site_only = true;
2556
+ } else {
2557
+ // Get list of files for this site.
2558
+ $remotePath = 'backup-';// . backupbuddy_core::backup_prefix();
2559
+ $site_only = true;
2560
+ }
2561
+
2562
+ $files = pb_backupbuddy_destination_stash2::listFiles( $settings, '', $site_only ); //2nd param was $remotePath.
2563
+ if ( ! is_array( $files ) ) {
2564
+ return array( 'error' => 'Error #892329c: ' . $files );
2565
+ }
2566
+
2567
+ $backup_list_temp = array();
2568
+ foreach( (array)$files as $file ) {
2569
+
2570
+ if ( ( '' != $remotePath ) && ( ! backupbuddy_core::startsWith( basename( $file['filename'] ), $remotePath ) ) ) { // Only show backups for this site unless set to show all.
2571
+ continue;
2572
+ }
2573
+
2574
+ $last_modified = $file['uploaded_timestamp'];
2575
+ $size = (double) $file['size'];
2576
+ $backup_type = backupbuddy_core::getBackupTypeFromFile( $file['filename'], $quiet = false, $skip_fileoptions = true );
2577
+
2578
+ // Generate array of table rows.
2579
+ while( isset( $backup_list_temp[$last_modified] ) ) { // Avoid collisions.
2580
+ $last_modified += 0.1;
2581
+ }
2582
+
2583
+ if ( 'live' == $destination['type'] ) {
2584
+ $backup_list_temp[$last_modified] = array(
2585
+ array( base64_encode( $file['url'] ), '<span class="backupbuddy-stash-file-list-title">' . pb_backupbuddy::$format->date( pb_backupbuddy::$format->localize_time( $last_modified ) ) . ' <span class="description">(' . pb_backupbuddy::$format->time_ago( $last_modified ) . ' ago)</span></span><br><span title="' . $file['filename'] . '">' . basename( $file['filename'] ) . '</span>' ),
2586
+ pb_backupbuddy::$format->date( pb_backupbuddy::$format->localize_time( $last_modified ) ) . '<br /><span class="description">(' . pb_backupbuddy::$format->time_ago( $last_modified ) . ' ago)</span>',
2587
+ pb_backupbuddy::$format->file_size( $size ),
2588
+ backupbuddy_core::pretty_backup_type( $backup_type ),
2589
+ );
2590
+ } else {
2591
+ $backup_list_temp[$last_modified] = array(
2592
+ array( base64_encode( $file['url'] ), '<span title="' . $file['filename'] . '">' . basename( $file['filename'] ) . '</span>' ),
2593
+ pb_backupbuddy::$format->date( pb_backupbuddy::$format->localize_time( $last_modified ) ) . '<br /><span class="description">(' . pb_backupbuddy::$format->time_ago( $last_modified ) . ' ago)</span>',
2594
+ pb_backupbuddy::$format->file_size( $size ),
2595
+ backupbuddy_core::pretty_backup_type( $backup_type ),
2596
+ );
2597
+ }
2598
+
2599
+ }
2600
+
2601
+ krsort( $backup_list_temp );
2602
+ $backup_list = array();
2603
+ foreach( $backup_list_temp as $backup_item ) {
2604
+ $backup_list[ $backup_item[0][0] ] = $backup_item;
2605
+ }
2606
+ unset( $backup_list_temp );
2607
+
2608
+ return array( 'backup_list' => $backup_list );
2609
+ }
2610
+
2611
+ function copy_file_to_local() {
2612
+
2613
+ $file = base64_decode( $_POST['cpy_file'] );
2614
+ $destination_id = $_POST['destination_id'];
2615
+
2616
+ // Load required files.
2617
+ require_once( pb_backupbuddy::plugin_path() . '/destinations/s32/init.php' );
2618
+ if ( ! isset( pb_backupbuddy::$options['remote_destinations'][ $destination_id ] ) ) {
2619
+ return array( 'error' => 'Error #9828332: Destination not found with id `' . htmlentities( $destination_id ) . '`.' );
2620
+ }
2621
+
2622
+ $settings = &pb_backupbuddy::$options['remote_destinations'][ $destination_id ];
2623
+ $settings = pb_backupbuddy_destination_stash2::_formatSettings( $settings );
2624
+
2625
+ pb_backupbuddy::status( 'details', 'Scheduling Cron for creating Stash copy.' );
2626
+ backupbuddy_core::schedule_single_event( time(), 'process_remote_copy', array( 'stash2', $file, $settings ) );
2627
+ if ( '1' != pb_backupbuddy::$options['skip_spawn_cron_call'] ) {
2628
+ update_option( '_transient_doing_cron', 0 ); // Prevent cron-blocking for next item.
2629
+ spawn_cron( time() + 150 ); // Adds > 60 seconds to get around once per minute cron running limit.
2630
+ }
2631
+ return array( 'ok' => 1 );
2632
+
2633
+ }
2634
+
2635
+ function delete_file_backup() {
2636
+ // Handle deletion.
2637
+ $files = $_POST['items'];
2638
+ $destination_id = $_POST['destination_id'];
2639
+
2640
+ // Load required files.
2641
+ require_once( pb_backupbuddy::plugin_path() . '/destinations/s32/init.php' );
2642
+ if ( ! isset( pb_backupbuddy::$options['remote_destinations'][ $destination_id ] ) ) {
2643
+ return array( 'error' => 'Error #9828332: Destination not found with id `' . htmlentities( $destination_id ) . '`.' );
2644
+ }
2645
+
2646
+ $settings = &pb_backupbuddy::$options['remote_destinations'][ $destination_id ];
2647
+ $settings = pb_backupbuddy_destination_stash2::_formatSettings( $settings );
2648
+
2649
+ $deleteFiles = array();
2650
+ foreach( (array)$files as $file ) {
2651
+ $file = base64_decode( $file );
2652
+
2653
+ $startPos = pb_backupbuddy_destination_stash2::strrpos_count( $file, '/', 2 ) + 1; // next to last slash.
2654
+ $file = substr( $file, $startPos );
2655
+ if ( FALSE !== strstr( $file, '?' ) ) {
2656
+ $file = substr( $file, 0, strpos( $file, '?' ) );
2657
+ }
2658
+ $deleteFiles[] = $file;
2659
+ }
2660
+ $response = pb_backupbuddy_destination_stash2::deleteFiles( $settings, $deleteFiles );
2661
+
2662
+ if ( true === $response ) {
2663
+ $msg = 'Deleted ' . implode( ', ', $deleteFiles ) . '.';
2664
+ } else {
2665
+ $msg = 'Failed to delete one or more files. Details: `' . $response . '`.';
2666
+ }
2667
+
2668
+ return array( 'ok' => 1, 'msg' => $msg );
2669
+ }
2670
+
2671
+ function get_live_stats() {
2672
+
2673
+ // Check if running PHP 5.3+.
2674
+ $php_minimum = 5.3;
2675
+ if ( version_compare( PHP_VERSION, $php_minimum, '<' ) ) { // Server's PHP is insufficient.
2676
+ return array('error' => '-1');
2677
+ }
2678
+
2679
+ if ( false === ( $stats = backupbuddy_api::getLiveStats() ) ) { // Live is disconnected.
2680
+ return array('error' => '-1');
2681
+ }
2682
+
2683
+ // If there is more to do and too long of time has passed since activity then try to jumpstart the process at the beginning.
2684
+ if ( ( ( 0 == $stats['files_total'] ) || ( $stats['files_sent'] < $stats['files_total'] ) ) && ( 'wait_on_transfers' != $stats['current_function'] ) ) { // ( Files to send not yet calculated OR more remain to send ) AND not on the wait_on_transfers step.
2685
+ $time_since_last_activity = microtime( true ) - $stats['last_periodic_activity'];
2686
+
2687
+ if ( $time_since_last_activity < 30 ) { // Don't even bother getting max execution time if it's been less than 30 seconds since run.
2688
+ // do nothing
2689
+ } else { // More than 30 seconds since last activity.
2690
+
2691
+ // Detect max PHP execution time. If TESTED value is higher than PHP value then go with that since we want to err on not overlapping processes here.
2692
+ $detected_execution = backupbuddy_core::detectLikelyHighestExecutionTime();
2693
+
2694
+ if ( $time_since_last_activity > ( $detected_execution + backupbuddy_constants::TIMED_OUT_PROCESS_RESUME_WIGGLE_ROOM ) ) { // Enough time has passed to assume timed out.
2695
+
2696
+ require_once( pb_backupbuddy::plugin_path() . '/destinations/live/live.php' );
2697
+ if ( false === ( $liveID = backupbuddy_live::getLiveID() ) ) {
2698
+ die( '-1' );
2699
+ }
2700
+ if ( '1' != pb_backupbuddy::$options['remote_destinations'][ $liveID ]['pause_periodic'] ) { // Only proceed if NOT paused.
2701
+
2702
+ pb_backupbuddy::status( 'warning', 'BackupBuddy Stash Live process appears timed out while user it viewing Live page. Forcing run now.' );
2703
+
2704
+ $cronArgs = array();
2705
+ $schedule_result = backupbuddy_core::schedule_single_event( time(), 'live_periodic', $cronArgs );
2706
+ if ( true === $schedule_result ) {
2707
+ pb_backupbuddy::status( 'details', 'Next Live Periodic chunk step cron event scheduled.' );
2708
+ } else {
2709
+ pb_backupbuddy::status( 'error', 'Next Live Periodic chunk step cron event FAILED to be scheduled.' );
2710
+ }
2711
+ if ( '1' != pb_backupbuddy::$options['skip_spawn_cron_call'] ) {
2712
+ pb_backupbuddy::status( 'details', 'Spawning cron now.' );
2713
+ update_option( '_transient_doing_cron', 0 ); // Prevent cron-blocking for next item.
2714
+ spawn_cron( time() + 150 ); // Adds > 60 seconds to get around once per minute cron running limit.
2715
+ }
2716
+ }
2717
+
2718
+ }
2719
+ }
2720
+
2721
+ }
2722
+
2723
+ return array('result' => json_encode( $stats ));
2724
+ }
2725
+
2726
+ function save_license_settings() {
2727
+ $settings = $_POST['settings'];
2728
+ if (is_array($settings) && isset($GLOBALS['ithemes-updater-settings'])) {
2729
+ $GLOBALS['ithemes-updater-settings']->update_options( $settings );
2730
+ return array('ok' => 1);
2731
+ }
2732
+ return false;
2733
+ }
2734
+
2735
+ function load_products_license() {
2736
+ $packages = array();
2737
+ $packages_name = array();
2738
+ if (isset($GLOBALS['ithemes_updater_path'])) {
2739
+
2740
+ require_once( $GLOBALS['ithemes_updater_path'] . '/functions.php' );
2741
+ require_once( $GLOBALS['ithemes_updater_path'] . '/api.php' );
2742
+ require_once( $GLOBALS['ithemes_updater_path'] . '/keys.php' );
2743
+
2744
+ require_once( $GLOBALS['ithemes_updater_path'] . '/packages.php' );
2745
+
2746
+ $details = Ithemes_Updater_Packages::get_full_details();
2747
+ $packages = isset($details['packages']) ? $details['packages'] : array();
2748
+ if (is_array($packages)) {
2749
+ foreach ( $packages as $path => $data ) {
2750
+ $packages_name[$path] = Ithemes_Updater_Functions::get_package_name( $data['package'] );
2751
+ }
2752
+ }
2753
+
2754
+ }
2755
+ return array('ok' => 1, 'packages' => $packages, 'packages_name' => $packages_name);
2756
+ }
2757
+
2758
+ function activate_package() {
2759
+
2760
+ $username = $_POST['username'];
2761
+ $password = $_POST['password'];
2762
+ $packages = $_POST['packages'];
2763
+
2764
+ $return = array( 'ok' => 1 );
2765
+ if (isset($GLOBALS['ithemes_updater_path'])) {
2766
+
2767
+ require_once( $GLOBALS['ithemes_updater_path'] . '/functions.php' );
2768
+ require_once( $GLOBALS['ithemes_updater_path'] . '/api.php' );
2769
+ require_once( $GLOBALS['ithemes_updater_path'] . '/keys.php' );
2770
+
2771
+ require_once( $GLOBALS['ithemes_updater_path'] . '/packages.php' );
2772
+
2773
+
2774
+ $response = Ithemes_Updater_API::activate_package( $username, $password, $packages );
2775
+
2776
+ if ( is_wp_error( $response ) ) {
2777
+ $errors[] = $this->get_error_explanation( $response );
2778
+ $return['errors'] = $errors;
2779
+ return $return;
2780
+ }
2781
+
2782
+ if ( empty( $response['packages'] ) ) {
2783
+ $errors[] = __( 'An unknown server error occurred. Please try to license your products again at another time.', 'it-l10n-backupbuddy' );
2784
+ $return['errors'] = $errors;
2785
+ return $return;
2786
+ }
2787
+
2788
+ uksort( $response['packages'], 'strnatcasecmp' );
2789
+
2790
+ $success = array();
2791
+ $warn = array();
2792
+ $fail = array();
2793
+
2794
+ foreach ( $response['packages'] as $package => $data ) {
2795
+ if ( preg_match( '/ \|\|\| \d+$/', $package ) )
2796
+ continue;
2797
+
2798
+ $name = Ithemes_Updater_Functions::get_package_name( $package );
2799
+
2800
+ if ( ! empty( $data['key'] ) )
2801
+ $success[] = $name;
2802
+ else if ( ! empty( $data['status'] ) && ( 'expired' == $data['status'] ) )
2803
+ $warn[$name] = __( 'Your product subscription has expired', 'it-l10n-backupbuddy' );
2804
+ else
2805
+ $fail[$name] = $data['error']['message'];
2806
+ }
2807
+
2808
+
2809
+ if ( ! empty( $success ) ) {
2810
+ $messages[] = wp_sprintf( __( 'Successfully licensed %l.', 'it-l10n-backupbuddy' ), $success );
2811
+ $return['messages'] = $messages;
2812
+ }
2813
+
2814
+ if ( ! empty( $fail ) ) {
2815
+ foreach ( $fail as $name => $reason )
2816
+ $errors[] = sprintf( __( 'Unable to license %1$s. Reason: %2$s', 'it-l10n-backupbuddy' ), $name, $reason );
2817
+ $return['errors'] = $errors;
2818
+ }
2819
+
2820
+ if ( ! empty( $warn ) ) {
2821
+ foreach ( $warn as $name => $reason )
2822
+ $soft_errors[] = sprintf( __( 'Unable to license %1$s. Reason: %2$s', 'it-l10n-backupbuddy' ), $name, $reason );
2823
+ $return['soft_errors'] = $soft_errors;
2824
+ }
2825
+
2826
+ }
2827
+ return $return;
2828
+ }
2829
+
2830
+ function deactivate_package( $data ) {
2831
+
2832
+ $username = $_POST['username'];
2833
+ $password = $_POST['password'];
2834
+ $packages = $_POST['packages'];
2835
+
2836
+ $return = array( 'ok' => 1 );
2837
+
2838
+ if (isset($GLOBALS['ithemes_updater_path'])) {
2839
+
2840
+ require_once( $GLOBALS['ithemes_updater_path'] . '/functions.php' );
2841
+ require_once( $GLOBALS['ithemes_updater_path'] . '/api.php' );
2842
+ require_once( $GLOBALS['ithemes_updater_path'] . '/keys.php' );
2843
+
2844
+ require_once( $GLOBALS['ithemes_updater_path'] . '/packages.php' );
2845
+
2846
+ $response = Ithemes_Updater_API::deactivate_package($username, $password, $packages );
2847
+
2848
+ if ( is_wp_error( $response ) ) {
2849
+ $errors[] = $this->get_error_explanation( $response );
2850
+ $return['errors'] = $errors;
2851
+ return $return;
2852
+ }
2853
+
2854
+ if ( empty( $response['packages'] ) ) {
2855
+ $errors[] = __( 'An unknown server error occurred. Please try to remove licenses from your products again at another time.', 'it-l10n-mainwp-backupbuddy' );
2856
+ $return['errors'] = $errors;
2857
+ return $return;
2858
+ }
2859
+
2860
+
2861
+ uksort( $response['packages'], 'strnatcasecmp' );
2862
+
2863
+ $success = array();
2864
+ $fail = array();
2865
+
2866
+ foreach ( $response['packages'] as $package => $data ) {
2867
+ if ( preg_match( '/ \|\|\| \d+$/', $package ) )
2868
+ continue;
2869
+
2870
+ $name = Ithemes_Updater_Functions::get_package_name( $package );
2871
+
2872
+ if ( isset( $data['status'] ) && ( 'inactive' == $data['status'] ) )
2873
+ $success[] = $name;
2874
+ else if ( isset( $data['error'] ) && isset( $data['error']['message'] ) )
2875
+ $fail[$name] = $data['error']['message'];
2876
+ else
2877
+ $fail[$name] = __( 'Unknown server error.', 'it-l10n-mainwp-backupbuddy' );
2878
+ }
2879
+
2880
+
2881
+ if ( ! empty( $success ) ) {
2882
+ $messages[] = wp_sprintf( _n( 'Successfully removed license from %l.', 'Successfully removed licenses from %l.', count( $success ), 'it-l10n-mainwp-backupbuddy' ), $success );
2883
+ $return['messages'] = $messages;
2884
+ }
2885
+
2886
+ if ( ! empty( $fail ) ) {
2887
+ foreach ( $fail as $name => $reason )
2888
+ $errors[] = sprintf( __( 'Unable to remove license from %1$s. Reason: %2$s', 'it-l10n-mainwp-backupbuddy' ), $name, $reason );
2889
+ $return['errors'] = $errors;
2890
+
2891
+ }
2892
+
2893
+ }
2894
+ return $return;
2895
+ }
2896
+
2897
+ private function get_error_explanation( $error, $package = '' ) {
2898
+ $code = $error->get_error_code();
2899
+ $package_name = Ithemes_Updater_Functions::get_package_name( $package );
2900
+ $message = '';
2901
+
2902
+ switch( $code ) {
2903
+ case 'ITXAPI_Updater_Bad_Login':
2904
+ $message = __( 'Incorrect password. Please make sure that you are supplying your iThemes membership username and password details.', 'it-l10n-mainwp-backupbuddy' );
2905
+ break;
2906
+ case 'ITXAPI_Updater_Username_Unknown':
2907
+ case 'ITXAPI_Updater_Username_Invalid':
2908
+ $message = __( 'Invalid username. Please make sure that you are supplying your iThemes membership username and password details.', 'it-l10n-mainwp-backupbuddy' );
2909
+ break;
2910
+ case 'ITXAPI_Product_Package_Unknown':
2911
+ $message = sprintf( __( 'The licensing server reports that the %1$s (%2$s) product is unknown. Please contact support for assistance.', 'it-l10n-mainwp-backupbuddy' ), $package_name, $package );
2912
+ break;
2913
+ case 'ITXAPI_Updater_Too_Many_Sites':
2914
+ $message = sprintf( __( '%1$s could not be licensed since the membership account is out of available licenses for this product. You can unlicense the product on other sites or upgrade your membership to one with a higher number of licenses in order to increase the amount of available licenses.', 'it-l10n-mainwp-backupbuddy' ), $package_name );
2915
+ break;
2916
+ case 'ITXAPI_License_Key_Generate_Failed':
2917
+ $message = sprintf( __( '%s could not be licensed due to an internal error. Please try to license %s again at a later time. If this problem continues, please contact iThemes support.', 'it-l10n-mainwp-backupbuddy' ), $package_name );
2918
+ break;
2919
+ }
2920
+
2921
+ if ( empty( $message ) ) {
2922
+ if ( ! empty( $package ) )
2923
+ $message = sprintf( __( 'An unknown error relating to the %1$s product occurred. Please contact iThemes support. Error details: %2$s', 'it-l10n-mainwp-backupbuddy' ), $package_name, $error->get_error_message() . " ($code)" );
2924
+ else
2925
+ $message = sprintf( __( 'An unknown error occurred. Please contact iThemes support. Error details: %s', 'it-l10n-mainwp-backupbuddy' ), $error->get_error_message() . " ($code)" );
2926
+ }
2927
+
2928
+ return $message;
2929
+ }
2930
+
2931
+
2932
+
2933
+ }
2934
+
class/class-mainwp-child-back-up-wordpress.php ADDED
@@ -0,0 +1,1187 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class MainWP_Child_Back_Up_Wordpress {
4
+ public static $instance = null;
5
+ public $is_plugin_installed = false;
6
+ static function Instance() {
7
+ if ( null === MainWP_Child_Back_Up_Wordpress::$instance ) {
8
+ MainWP_Child_Back_Up_Wordpress::$instance = new MainWP_Child_Back_Up_Wordpress();
9
+ }
10
+
11
+ return MainWP_Child_Back_Up_Wordpress::$instance;
12
+ }
13
+
14
+ public function __construct() {
15
+ require_once( ABSPATH . 'wp-admin/includes/plugin.php' );
16
+ if ( is_plugin_active( 'backupwordpress/backupwordpress.php' ) ) {
17
+ $this->is_plugin_installed = true;
18
+ }
19
+ }
20
+
21
+ public function init() {
22
+ if ( get_option( 'mainwp_backupwordpress_ext_enabled' ) !== 'Y' ) return;
23
+ if (!$this->is_plugin_installed) return;
24
+
25
+ add_action( 'mainwp_child_site_stats', array( $this, 'do_site_stats' ) );
26
+
27
+ if ( get_option( 'mainwp_backupwordpress_hide_plugin' ) === 'hide' ) {
28
+ add_filter( 'all_plugins', array( $this, 'all_plugins' ) );
29
+ add_action( 'admin_menu', array( $this, 'remove_menu' ) );
30
+ add_filter( 'site_transient_update_plugins', array( &$this, 'remove_update_nag' ) );
31
+ }
32
+ }
33
+
34
+ function remove_update_nag( $value ) {
35
+ if ( isset( $_POST['mainwpsignature'] ) ) {
36
+ return $value;
37
+ }
38
+ if ( isset( $value->response['backupwordpress/backupwordpress.php'] ) ) {
39
+ unset( $value->response['backupwordpress/backupwordpress.php'] );
40
+ }
41
+
42
+ return $value;
43
+ }
44
+
45
+ public function action() {
46
+ $information = array();
47
+ if ( ! self::isActivated() ) {
48
+ $information['error'] = 'NO_BACKUPWORDPRESS';
49
+ MainWP_Helper::write( $information );
50
+ }
51
+
52
+ if (false === get_option('mainwp_backupwordpress_ext_enabled'))
53
+ MainWP_Helper::update_option( 'mainwp_backupwordpress_ext_enabled', 'Y' );
54
+
55
+ if ( isset( $_POST['mwp_action'] ) ) {
56
+ switch ( $_POST['mwp_action'] ) {
57
+ case 'set_showhide':
58
+ $information = $this->set_showhide();
59
+ break;
60
+ case 'delete_schedule':
61
+ $information = $this->delete_schedule();
62
+ break;
63
+ case 'cancel_schedule':
64
+ $information = $this->hmbkp_request_cancel_backup();
65
+ break;
66
+ case 'get_backup_status':
67
+ $information = $this->get_backup_status();
68
+ break;
69
+ case 'reload_backupslist':
70
+ $information = $this->reload_backups();
71
+ break;
72
+ case 'delete_backup':
73
+ $information = $this->hmbkp_request_delete_backup();
74
+ break;
75
+ case 'run_schedule':
76
+ $information = $this->run_schedule();
77
+ break;
78
+ case 'save_all_schedules':
79
+ $information = $this->save_all_schedules();
80
+ break;
81
+ case 'update_schedule':
82
+ $information = $this->update_schedule();
83
+ break;
84
+ case 'get_excluded':
85
+ $information = $this->get_excluded();
86
+ break;
87
+ case 'directory_browse':
88
+ $information = $this->directory_browse();
89
+ break;
90
+ case 'exclude_add_rule':
91
+ $information = $this->hmbkp_add_exclude_rule();
92
+ break;
93
+ case 'exclude_remove_rule':
94
+ $information = $this->hmbkp_remove_exclude_rule();
95
+ break;
96
+ }
97
+ }
98
+ MainWP_Helper::write( $information );
99
+ }
100
+
101
+
102
+ function check_schedule() {
103
+ $schedule_id = ( isset( $_POST['schedule_id'] ) && ! empty( $_POST['schedule_id'] ) ) ? $_POST['schedule_id'] : '';
104
+ if ( empty( $schedule_id ) ) {
105
+ $information = array( 'error' => 'Empty schedule id' );
106
+ MainWP_Helper::write( $information );
107
+ } else {
108
+ $schedule_id = sanitize_text_field( urldecode( $schedule_id ) );
109
+ HM\BackUpWordPress\Schedules::get_instance()->refresh_schedules();
110
+ if ( ! HM\BackUpWordPress\Schedules::get_instance()->get_schedule( $schedule_id ) ) {
111
+ $information = array( 'result' => 'NOTFOUND' );
112
+ MainWP_Helper::write( $information );
113
+ }
114
+ }
115
+
116
+ return $schedule_id;
117
+ }
118
+
119
+ public function syncData() {
120
+ if ( ! self::isActivated() ) {
121
+ return '';
122
+ }
123
+
124
+ return $this->get_sync_data();
125
+ }
126
+
127
+ private function get_sync_data() {
128
+ HM\BackUpWordPress\Schedules::get_instance()->refresh_schedules();
129
+ $schedules = HM\BackUpWordPress\Schedules::get_instance()->get_schedules();
130
+ $backups_time = array();
131
+ foreach ( $schedules as $sche ) {
132
+ $existing_backup = $sche->get_backups();
133
+ if ( ! empty( $existing_backup ) ) {
134
+ $backups_time = array_merge( $backups_time, array_keys( $existing_backup ) );
135
+ }
136
+ }
137
+
138
+ $lasttime_backup = 0;
139
+ if ( ! empty( $backups_time ) ) {
140
+ $lasttime_backup = max( $backups_time );
141
+ }
142
+
143
+ $return = array( 'lasttime_backup' => $lasttime_backup );
144
+
145
+ return $return;
146
+ }
147
+
148
+ function do_site_stats() {
149
+ if (has_action('mainwp_child_reports_log')) {
150
+ do_action( 'mainwp_child_reports_log', 'backupwordpress');
151
+ } else {
152
+ $this->do_reports_log('backupwordpress');
153
+ }
154
+ }
155
+
156
+ public function do_reports_log($ext = '') {
157
+ if ( $ext !== 'backupwordpress' ) return;
158
+ if (!$this->is_plugin_installed) return;
159
+
160
+ // Refresh the schedules from the database to make sure we have the latest changes
161
+ HM\BackUpWordPress\Schedules::get_instance()->refresh_schedules();
162
+ $schedules = HM\BackUpWordPress\Schedules::get_instance()->get_schedules();
163
+ foreach($schedules as $schedule) {
164
+ foreach ( $schedule->get_backups() as $file ) {
165
+ $backup_type = $schedule->get_type();
166
+ $message = "BackupWordpres backup " . $backup_type . ' finished';
167
+ $destination = "N/A";
168
+ if ( file_exists( $file ) ) {
169
+ $date = @filemtime( $file );
170
+ if ( !empty( $date ) ) {
171
+ do_action( "backupwordpress_backup", $destination, $message, 'finished', $backup_type, $date );
172
+ MainWP_Helper::update_lasttime_backup('backupwordpress', $date); // to support backup before update feature
173
+ }
174
+ }
175
+ }
176
+ }
177
+ }
178
+
179
+ function set_showhide() {
180
+ $hide = isset( $_POST['showhide'] ) && ( 'hide' === $_POST['showhide'] ) ? 'hide' : '';
181
+ MainWP_Helper::update_option( 'mainwp_backupwordpress_hide_plugin', $hide );
182
+ $information['result'] = 'SUCCESS';
183
+
184
+ return $information;
185
+ }
186
+
187
+ function delete_schedule() {
188
+ $schedule_id = $this->check_schedule();
189
+ $schedule = new HM\BackUpWordPress\Scheduled_Backup( sanitize_text_field( urldecode( $schedule_id ) ) );
190
+
191
+ if ( $schedule ) {
192
+ $schedule->cancel( true );
193
+ $information['result'] = 'SUCCESS';
194
+ } else {
195
+ $information['result'] = 'NOTFOUND';
196
+ }
197
+
198
+ return $information;
199
+ }
200
+
201
+ function hmbkp_request_cancel_backup() {
202
+ $schedule_id = $this->check_schedule();
203
+ $schedule = new HM\BackUpWordPress\Scheduled_Backup( sanitize_text_field( urldecode( $schedule_id ) ) );
204
+
205
+
206
+ // Delete the running backup
207
+ if (method_exists($schedule, 'get_running_backup_filename' )) {
208
+ if ( $schedule->get_running_backup_filename() && file_exists( trailingslashit( hmbkp_path() ) . $schedule->get_running_backup_filename() ) ) {
209
+ unlink( trailingslashit( hmbkp_path() ) . $schedule->get_running_backup_filename() );
210
+ }
211
+ if ( $schedule->get_schedule_running_path() && file_exists( $schedule->get_schedule_running_path() ) ) {
212
+ unlink( $schedule->get_schedule_running_path() );
213
+ }
214
+ } else {
215
+ $status = $schedule->get_status();
216
+ // Delete the running backup
217
+ if ( $status->get_backup_filename() && file_exists( trailingslashit( HM\BackUpWordPress\Path::get_path() ) . $status->get_backup_filename() ) ) {
218
+ unlink( trailingslashit( HM\BackUpWordPress\Path::get_path() ) . $status->get_backup_filename() );
219
+ }
220
+ if ( file_exists( $status->get_status_filepath() ) ) {
221
+ unlink( $status->get_status_filepath() );
222
+ }
223
+
224
+ }
225
+
226
+ HM\BackUpWordPress\Path::get_instance()->cleanup();
227
+
228
+ if ($status === null) {
229
+ $information['scheduleStatus'] = $schedule->get_status();
230
+ } else {
231
+ $information['scheduleStatus'] = $status->get_status();
232
+ }
233
+
234
+ $information['result'] = 'SUCCESS';
235
+
236
+ return $information;
237
+ }
238
+
239
+ function get_backup_status() {
240
+ $schedule_id = $this->check_schedule();
241
+ $schedule = new HM\BackUpWordPress\Scheduled_Backup( sanitize_text_field( urldecode( $schedule_id ) ) );
242
+
243
+ if (method_exists($schedule, 'get_running_backup_filename' )) {
244
+ $information['scheduleStatus'] = $schedule->get_status();
245
+ } else {
246
+ $status = $schedule->get_status();
247
+ $information['scheduleStatus'] = $status->get_status();
248
+ }
249
+
250
+ $information['result'] = 'SUCCESS';
251
+
252
+ return $information;
253
+ }
254
+
255
+ function run_schedule() {
256
+ $schedule_id = $this->check_schedule();
257
+ if (function_exists('hmbkp_run_schedule_async')) {
258
+ hmbkp_run_schedule_async($schedule_id);
259
+ } else if (function_exists('\HM\BackUpWordPress\run_schedule_async')) {
260
+ HM\BackUpWordPress\Path::get_instance()->cleanup();
261
+ // Fixes an issue on servers which only allow a single session per client
262
+ session_write_close();
263
+ $task = new \HM\Backdrop\Task( '\HM\BackUpWordPress\run_schedule_async', $schedule_id );
264
+ $task->schedule();
265
+ } else
266
+ return array( 'error' => __('Error while trying to trigger the schedule', 'mainwp-child') );
267
+ return array( 'result' => 'SUCCESS' );
268
+ }
269
+
270
+ function reload_backups() {
271
+
272
+ $scheduleIds = isset( $_POST['schedule_ids'] ) ? $_POST['schedule_ids'] : array();
273
+ HM\BackUpWordPress\Schedules::get_instance()->refresh_schedules();
274
+
275
+ $all_schedules_ids = array();
276
+ $schedules = HM\BackUpWordPress\Schedules::get_instance()->get_schedules();
277
+ foreach ( $schedules as $sch ) {
278
+ $all_schedules_ids[] = $sch->get_id();
279
+ }
280
+
281
+ if ( empty( $all_schedules_ids ) ) {
282
+ return array( 'error' => 'Schedules could not be found.' );
283
+ }
284
+
285
+ foreach ( $all_schedules_ids as $schedule_id ) {
286
+ if ( ! HM\BackUpWordPress\Schedules::get_instance()->get_schedule( $schedule_id ) ) {
287
+ continue;
288
+ }
289
+
290
+ $schedule = new HM\BackUpWordPress\Scheduled_Backup( sanitize_text_field( urldecode( $schedule_id ) ) );
291
+ $started_ago = method_exists($schedule, 'get_schedule_running_start_time') ? $schedule->get_schedule_running_start_time() : $schedule->get_schedule_start_time();
292
+ $out = array(
293
+ 'b' => $this->get_backupslist_html( $schedule ),
294
+ 'count' => count( $schedule->get_backups() ),
295
+ 'file_size_text' => $this->hmbkp_get_site_size_text( $schedule ),
296
+ 'started_ago' => human_time_diff( $started_ago ),
297
+ );
298
+
299
+ if (method_exists($schedule, 'get_running_backup_filename' )) {
300
+ $out['scheduleStatus'] = $schedule->get_status();
301
+ } else {
302
+ $status = $schedule->get_status();
303
+ $out['scheduleStatus'] = $status->get_status();
304
+ }
305
+
306
+ $information['backups'][ $schedule_id ] = $out;
307
+ }
308
+
309
+ $send_back_schedules = array();
310
+
311
+ $schedules = HM\BackUpWordPress\Schedules::get_instance()->get_schedules();
312
+ foreach ( $schedules as $schedule ) {
313
+ $sch_id = $schedule->get_id();
314
+ if ( ! in_array( $sch_id, $scheduleIds ) ) {
315
+ $current_option = get_option( 'hmbkp_schedule_' . $sch_id );
316
+ if ( is_array( $current_option ) ) {
317
+ unset( $current_option['excludes'] ); // not send this value
318
+ $started_ago = method_exists($schedule, 'get_schedule_running_start_time') ? $schedule->get_schedule_running_start_time() : $schedule->get_schedule_start_time();
319
+ $send_back_schedules[ $sch_id ] = array(
320
+ 'options' => $current_option,
321
+ 'b' => $this->get_backupslist_html( $schedule ),
322
+ 'count' => count( $schedule->get_backups() ),
323
+ 'file_size_text' => $this->hmbkp_get_site_size_text( $schedule ),
324
+ 'scheduleStatus' => $schedule->get_status(),
325
+ 'started_ago' => human_time_diff( $started_ago ),
326
+ );
327
+ if (method_exists($schedule, 'get_running_backup_filename' )) {
328
+ $send_back_schedules['scheduleStatus'] = $schedule->get_status();
329
+ } else {
330
+ $status = $schedule->get_status();
331
+ $send_back_schedules['scheduleStatus'] = $status->get_status();
332
+ }
333
+ }
334
+ }
335
+ }
336
+
337
+ if (function_exists('HM\BackUpWordPress\Backup::get_home_path'))
338
+ $backups_path = str_replace( HM\BackUpWordPress\Backup::get_home_path(), '', hmbkp_path() );
339
+ else
340
+ $backups_path = str_replace( HM\BackUpWordPress\Path::get_home_path(), '', HM\BackUpWordPress\Path::get_path() );
341
+
342
+ $information['backups_path'] = $backups_path;
343
+ $information['send_back_schedules'] = $send_back_schedules;
344
+ $information['result'] = 'SUCCESS';
345
+
346
+ return $information;
347
+ }
348
+
349
+ function hmbkp_request_delete_backup() {
350
+ if ( ! isset( $_POST['hmbkp_backuparchive'] ) || empty( $_POST['hmbkp_backuparchive'] ) ) {
351
+ return array( 'error' => __( 'Invalid data!', 'mainwp-child' ) );
352
+ }
353
+
354
+ $schedule_id = $this->check_schedule();
355
+
356
+ $schedule = new HM\BackUpWordPress\Scheduled_Backup( sanitize_text_field( urldecode( $schedule_id ) ) );
357
+
358
+ $deleted = $schedule->delete_backup(base64_decode( urldecode($_POST['hmbkp_backuparchive'] )));
359
+
360
+ if ( is_wp_error( $deleted ) ) {
361
+ return array( 'error' => $deleted->get_error_message() );
362
+ }
363
+
364
+ $ret = array(
365
+ 'result' => 'SUCCESS',
366
+ 'b' => $this->get_backupslist_html( $schedule ),
367
+ 'count' => count( $schedule->get_backups() ),
368
+ 'file_size_text' => $this->hmbkp_get_site_size_text( $schedule ),
369
+ );
370
+ if (method_exists($schedule, 'get_running_backup_filename' )) {
371
+ $ret['scheduleStatus'] = $schedule->get_status();
372
+ } else {
373
+ $status = $schedule->get_status();
374
+ $ret['scheduleStatus'] = $status->get_status();
375
+ }
376
+ return $ret;
377
+ }
378
+
379
+ function get_backupslist_html( $schedule ) {
380
+ ob_start();
381
+ ?>
382
+ <table class="widefat">
383
+
384
+ <thead>
385
+
386
+ <tr>
387
+
388
+ <th scope="col"><?php function_exists('hmbkp_backups_number') ? hmbkp_backups_number( $schedule ) : ( function_exists('backups_number') ? backups_number( $schedule ) : "" ) ; ?></th>
389
+ <th scope="col"><?php esc_html_e( 'Size', 'mainwp-backupwordpress-extension' ); ?></th>
390
+ <th scope="col"><?php esc_html_e( 'Type', 'mainwp-backupwordpress-extension' ); ?></th>
391
+ <th scope="col"><?php esc_html_e( 'Actions', 'mainwp-backupwordpress-extension' ); ?></th>
392
+
393
+ </tr>
394
+
395
+ </thead>
396
+
397
+ <tbody>
398
+
399
+ <?php if ( $schedule->get_backups() ) {
400
+
401
+ $schedule->delete_old_backups();
402
+
403
+ foreach ( $schedule->get_backups() as $file ) {
404
+
405
+ if ( ! file_exists( $file ) ) {
406
+ continue;
407
+ }
408
+
409
+ $this->hmbkp_get_backup_row( $file, $schedule );
410
+
411
+ }
412
+ } else { ?>
413
+
414
+ <tr>
415
+ <td class="hmbkp-no-backups"
416
+ colspan="4"><?php esc_html_e( 'This is where your backups will appear once you have some.', 'mainwp-backupwordpress-extension' ); ?></td>
417
+ </tr>
418
+
419
+ <?php } ?>
420
+
421
+ </tbody>
422
+
423
+ </table>
424
+ <?php
425
+ $html = ob_get_clean();
426
+
427
+ return $html;
428
+ }
429
+
430
+
431
+ function hmbkp_get_site_size_text( HM\BackUpWordPress\Scheduled_Backup $schedule ) {
432
+ if (method_exists($schedule, 'is_site_size_cached')) {
433
+ if ( ( 'database' === $schedule->get_type() ) || $schedule->is_site_size_cached() ) {
434
+ return sprintf( '(<code title="' . __( 'Backups will be compressed and should be smaller than this.', 'mainwp-backupwordpress-extension' ) . '">%s</code>)', esc_attr( $schedule->get_formatted_site_size() ) );
435
+ }
436
+ } else {
437
+ $site_size = new HM\BackUpWordPress\Site_Size( $schedule->get_type(), $schedule->get_excludes() );
438
+ if ( ( 'database' === $schedule->get_type() ) || $site_size->is_site_size_cached() ) {
439
+ return sprintf( '(<code title="' . __( 'Backups will be compressed and should be smaller than this.', 'backupwordpress' ) . '">%s</code>)', esc_attr( $site_size->get_formatted_site_size() ) );
440
+ }
441
+ }
442
+
443
+ return sprintf( '(<code class="calculating" title="' . __( 'this shouldn\'t take long&hellip;', 'mainwp-backupwordpress-extension' ) . '">' . __( 'calculating the size of your backup&hellip;', 'mainwp-backupwordpress-extension' ) . '</code>)' );
444
+
445
+ }
446
+
447
+ function hmbkp_get_backup_row( $file, HM\BackUpWordPress\Scheduled_Backup $schedule ) {
448
+
449
+ $encoded_file = urlencode( base64_encode( $file ) );
450
+ $offset = get_option( 'gmt_offset' ) * 3600;
451
+
452
+ ?>
453
+
454
+ <tr class="hmbkp_manage_backups_row">
455
+
456
+ <th scope="row">
457
+ <?php echo esc_html( date_i18n( get_option( 'date_format' ) . ' - ' . get_option( 'time_format' ), @filemtime( $file ) + $offset ) ); ?>
458
+ </th>
459
+
460
+ <td class="code">
461
+ <?php echo esc_html( size_format( @filesize( $file ) ) ); ?>
462
+ </td>
463
+
464
+ <td><?php echo function_exists('hmbkp_human_get_type') ? esc_html( hmbkp_human_get_type( $file, $schedule ) ) : esc_html( HM\BackUpWordPress\human_get_type( $file, $schedule)); ?></td>
465
+
466
+ <td>
467
+
468
+ <?php if (function_exists('hmbkp_is_path_accessible')) {
469
+ if ( hmbkp_is_path_accessible( hmbkp_path() ) ) {
470
+ ?>
471
+ <a href="#"
472
+ onclick="event.preventDefault(); mainwp_backupwp_download_backup('<?php echo $encoded_file; ?>', <?php echo esc_attr( $schedule->get_id() ); ?>, this);"
473
+ class="download-action"><?php esc_html_e( 'Download', 'backupwordpress' ); ?></a> |
474
+ <?php };
475
+ } else if (function_exists('HM\BackUpWordPress\is_path_accessible') ) {
476
+ if (HM\BackUpWordPress\is_path_accessible(HM\BackUpWordPress\Path::get_path())) {
477
+ ?>
478
+ <a href="#"
479
+ onclick="event.preventDefault(); mainwp_backupwp_download_backup('<?php echo $encoded_file; ?>', <?php echo esc_attr( $schedule->get_id() ); ?>, this);"
480
+ class="download-action"><?php esc_html_e( 'Download', 'backupwordpress' ); ?></a> |
481
+ <?php };
482
+ }
483
+ ?>
484
+
485
+ <a href="#"
486
+ onclick="event.preventDefault(); mainwp_backupwp_delete_backup('<?php echo $encoded_file; ?>', <?php echo esc_attr( $schedule->get_id() ); ?>, this);"
487
+ class="delete-action"><?php esc_html_e( 'Delete', 'backupwordpress' ); ?></a>
488
+
489
+ </td>
490
+
491
+ </tr>
492
+
493
+ <?php }
494
+
495
+ function get_excluded( $browse_dir = null ) {
496
+
497
+ $schedule_id = $this->check_schedule();
498
+ $schedule = new HM\BackUpWordPress\Scheduled_Backup( sanitize_text_field( urldecode( $schedule_id ) ) );
499
+
500
+ $new_version = true;
501
+ if (method_exists($schedule, 'get_running_backup_filename' )) {
502
+ $new_version = false;
503
+ $user_excludes = array_diff( $schedule->get_excludes(), $schedule->backup->default_excludes() );
504
+ $root_dir = $schedule->backup->get_root();
505
+ $is_size_calculated = $schedule->is_site_size_being_calculated();
506
+ } else {
507
+ $excludes = $schedule->get_excludes();
508
+ $user_excludes = $excludes->get_user_excludes();
509
+ $root_dir = HM\BackUpWordPress\Path::get_root();
510
+ $is_size_calculated = HM\BackUpWordPress\Site_Size::is_site_size_being_calculated();
511
+ }
512
+
513
+ ob_start();
514
+
515
+ ?>
516
+ <div class="hmbkp-exclude-settings">
517
+
518
+ <?php //if ( $schedule->get_excludes() ) : ?>
519
+
520
+ <h3>
521
+ <?php esc_html_e( 'Currently Excluded', 'backupwordpress' ); ?>
522
+ </h3>
523
+
524
+ <p><?php esc_html_e( 'We automatically detect and ignore common <abbr title="Version Control Systems">VCS</abbr> folders and other backup plugin folders.', 'backupwordpress' ); ?></p>
525
+
526
+ <table class="widefat">
527
+
528
+ <tbody>
529
+ <?php foreach ( $user_excludes as $key => $exclude ) : ?>
530
+
531
+ <?php $exclude_path = new SplFileInfo( trailingslashit( $root_dir ) . ltrim( str_ireplace( $root_dir, '', $exclude ), '/' ) ); ?>
532
+
533
+ <tr>
534
+
535
+ <th scope="row">
536
+
537
+ <?php if ( $exclude_path->isFile() ) { ?>
538
+
539
+ <div class="dashicons dashicons-media-default"></div>
540
+
541
+ <?php } elseif ( $exclude_path->isDir() ) { ?>
542
+
543
+ <div class="dashicons dashicons-portfolio"></div>
544
+
545
+ <?php } ?>
546
+
547
+ </th>
548
+
549
+ <td>
550
+ <code>
551
+ <?php echo esc_html( str_ireplace( $root_dir, '', $exclude ) ); ?>
552
+ </code>
553
+
554
+ </td>
555
+
556
+ <td>
557
+ <?php
558
+ if ($new_version)
559
+ $is_default_rule = ( in_array( $exclude, $excludes->get_default_excludes() ) ) || ( HM\BackUpWordPress\Path::get_path() === trailingslashit( HM\BackUpWordPress\Path::get_root() ) . untrailingslashit( $exclude ) );
560
+ else
561
+ $is_default_rule = ( in_array( $exclude, $schedule->backup->default_excludes() ) ) || ( hmbkp_path() === untrailingslashit( $exclude ) ) ;
562
+
563
+ if ( $is_default_rule ) : ?>
564
+ <?php esc_html_e( 'Default rule', 'backupwordpress' ); ?>
565
+
566
+ <?php elseif ( defined( 'HMBKP_EXCLUDE' ) && false !== strpos( HMBKP_EXCLUDE, $exclude ) ) : ?>
567
+
568
+ <?php esc_html_e( 'Defined in wp-config.php', 'backupwordpress' ); ?>
569
+
570
+ <?php else : ?>
571
+
572
+ <a href="#"
573
+ onclick="event.preventDefault(); mainwp_backupwp_remove_exclude_rule('<?php esc_attr_e( $exclude ); ?>', this);"
574
+ class="delete-action"><?php esc_html_e( 'Stop excluding', 'backupwordpress' ); ?></a>
575
+
576
+ <?php endif; ?>
577
+
578
+ </td>
579
+
580
+ </tr>
581
+
582
+ <?php endforeach; ?>
583
+
584
+ </tbody>
585
+
586
+ </table>
587
+
588
+ <?php //endif; ?>
589
+
590
+ <h3 id="directory-listing"><?php esc_html_e( 'Your Site', 'backupwordpress' ); ?></h3>
591
+
592
+ <p><?php esc_html_e( 'Here\'s a directory listing of all files on your site, you can browse through and exclude files or folders that you don\'t want included in your backup.', 'backupwordpress' ); ?></p>
593
+
594
+ <?php
595
+ // The directory to display
596
+ $directory = $root_dir;
597
+
598
+ if ( isset( $browse_dir ) ) {
599
+
600
+ $untrusted_directory = urldecode( $browse_dir );
601
+
602
+ // Only allow real sub directories of the site root to be browsed
603
+ if ( false !== strpos( $untrusted_directory, $root_dir ) && is_dir( $untrusted_directory ) ) {
604
+ $directory = $untrusted_directory;
605
+ }
606
+ }
607
+
608
+ // Kick off a recursive filesize scan
609
+ if ($new_version) {
610
+
611
+ $site_size = new HM\BackUpWordPress\Site_Size;
612
+
613
+ $exclude_string = implode( '|', $excludes->get_excludes_for_regex() );
614
+
615
+ if (function_exists('HM\BackUpWordPress\list_directory_by_total_filesize'))
616
+ $files = HM\BackUpWordPress\list_directory_by_total_filesize( $directory, $excludes );
617
+
618
+ } else {
619
+ $files = $schedule->list_directory_by_total_filesize( $directory );
620
+ $exclude_string = $schedule->backup->exclude_string( 'regex' );
621
+ }
622
+
623
+ if ( $files ) { ?>
624
+
625
+ <table class="widefat">
626
+ <thead>
627
+ <tr>
628
+ <th></th>
629
+ <th scope="col"><?php esc_html_e( 'Name', 'backupwordpress' ); ?></th>
630
+ <th scope="col" class="column-format"><?php esc_html_e( 'Size', 'backupwordpress' ); ?></th>
631
+ <th scope="col"
632
+ class="column-format"><?php esc_html_e( 'Permissions', 'backupwordpress' ); ?></th>
633
+ <th scope="col" class="column-format"><?php esc_html_e( 'Type', 'backupwordpress' ); ?></th>
634
+ <th scope="col" class="column-format"><?php esc_html_e( 'Status', 'backupwordpress' ); ?></th>
635
+ </tr>
636
+
637
+ <tr>
638
+
639
+ <th scope="row">
640
+ <div class="dashicons dashicons-admin-home"></div>
641
+ </th>
642
+
643
+ <th scope="col">
644
+
645
+ <?php if ( $root_dir !== $directory ) {
646
+ // echo esc_url( remove_query_arg( 'hmbkp_directory_browse' ) );
647
+ ?>
648
+ <a href="#"
649
+ onclick="event.preventDefault(); mainwp_backupwp_directory_browse('', this)"><?php echo esc_html( $root_dir ); ?></a>
650
+ <code>/</code>
651
+
652
+ <?php $parents = array_filter( explode( '/', str_replace( trailingslashit( $root_dir ), '', trailingslashit( dirname( $directory ) ) ) ) );
653
+
654
+ foreach ( $parents as $directory_basename ) { ?>
655
+
656
+ <a href="#"
657
+ onclick="event.preventDefault(); mainwp_backupwp_directory_browse('<?php echo urlencode( substr( $directory, 0, strpos( $directory, $directory_basename ) ) . $directory_basename ); ?>', this)"><?php echo esc_html( $directory_basename ); ?></a>
658
+ <code>/</code>
659
+
660
+ <?php } ?>
661
+
662
+ <?php echo esc_html( basename( $directory ) ); ?>
663
+
664
+ <?php } else { ?>
665
+
666
+ <?php echo esc_html( $root_dir ); ?>
667
+
668
+ <?php } ?>
669
+
670
+ </th>
671
+
672
+ <td class="column-filesize">
673
+
674
+ <?php if ( $is_size_calculated ) : ?>
675
+
676
+ <span class="spinner "></span>
677
+
678
+ <?php
679
+ else :
680
+
681
+ $root = new SplFileInfo( $root_dir );
682
+
683
+ if ($new_version) {
684
+ $size = $site_size->filesize( $root );
685
+ } else {
686
+ $size = $schedule->filesize( $root, true );
687
+ }
688
+
689
+ if ( false !== $size ) {
690
+
691
+ $size = size_format( $size );
692
+
693
+ if ( ! $size ) {
694
+ $size = '0 B';
695
+ }
696
+ ?>
697
+
698
+ <code>
699
+
700
+ <?php echo esc_html( $size ); ?>
701
+
702
+ <a class="dashicons dashicons-update"
703
+ href="<?php echo esc_attr( wp_nonce_url( add_query_arg( 'hmbkp_recalculate_directory_filesize', urlencode( $root_dir ) ), 'hmbkp-recalculate_directory_filesize' ) ); ?>"><span><?php esc_html_e( 'Refresh', 'backupwordpress' ); ?></span></a>
704
+
705
+ </code>
706
+
707
+
708
+ <?php } ?>
709
+
710
+ <?php endif; ?>
711
+
712
+ <td>
713
+ <?php echo esc_html( substr( sprintf( '%o', fileperms( $root_dir ) ), - 4 ) ); ?>
714
+ </td>
715
+
716
+ <td>
717
+
718
+ <?php
719
+ if ( is_link( $root_dir ) ) {
720
+ esc_html_e( 'Symlink', 'backupwordpress' );
721
+ } elseif ( is_dir( $root_dir ) ) {
722
+ esc_html_e( 'Folder', 'backupwordpress' );
723
+ }
724
+ ?>
725
+
726
+ </td>
727
+
728
+ <td></td>
729
+
730
+ </tr>
731
+
732
+ </thead>
733
+
734
+ <tbody>
735
+
736
+ <?php foreach ( $files as $size => $file ) {
737
+
738
+ $is_excluded = $is_unreadable = false;
739
+
740
+ // Check if the file is excluded
741
+ if ($new_version) {
742
+ if ( $exclude_string && preg_match( '(' . $exclude_string . ')', str_ireplace( trailingslashit( $root_dir ), '', wp_normalize_path( $file->getPathname() ) ) ) ) {
743
+ $is_excluded = true;
744
+ }
745
+ } else {
746
+ if ( $exclude_string && preg_match( '(' . $exclude_string . ')', str_ireplace( trailingslashit( $root_dir ), '', HM\BackUpWordPress\Backup::conform_dir( $file->getPathname() ) ) ) ) {
747
+ $is_excluded = true;
748
+ }
749
+ }
750
+
751
+ // Skip unreadable files
752
+ if ( ! @realpath( $file->getPathname() ) || ! $file->isReadable() ) {
753
+ $is_unreadable = true;
754
+ } ?>
755
+
756
+ <tr>
757
+
758
+ <td>
759
+
760
+ <?php if ( $is_unreadable ) { ?>
761
+
762
+ <div class="dashicons dashicons-dismiss"></div>
763
+
764
+ <?php } elseif ( $file->isFile() ) { ?>
765
+
766
+ <div class="dashicons dashicons-media-default"></div>
767
+
768
+ <?php } elseif ( $file->isDir() ) { ?>
769
+
770
+ <div class="dashicons dashicons-portfolio"></div>
771
+
772
+ <?php } ?>
773
+
774
+ </td>
775
+
776
+ <td>
777
+ <?php
778
+ if ($new_version) {
779
+ if ( $is_unreadable ) { ?>
780
+
781
+ <code class="strikethrough"
782
+ title="<?php echo esc_attr( wp_normalize_path( $file->getRealPath() ) ); ?>"><?php echo esc_html( $file->getBasename() ); ?></code>
783
+
784
+ <?php } elseif ( $file->isFile() ) { ?>
785
+
786
+ <code
787
+ title="<?php echo esc_attr( wp_normalize_path( $file->getRealPath() ) ); ?>"><?php echo esc_html( $file->getBasename() ); ?></code>
788
+
789
+ <?php } elseif ( $file->isDir() ) { ?>
790
+ <code title="<?php echo esc_attr( $file->getRealPath() ); ?>"><a
791
+ href="#"
792
+ onclick="event.preventDefault(); mainwp_backupwp_directory_browse('<?php echo urlencode( wp_normalize_path( $file->getPathname()) ); ?>', this)"><?php echo esc_html( $file->getBasename() ); ?></a></code>
793
+
794
+
795
+ <?php }
796
+ } else {
797
+ if ( $is_unreadable ) { ?>
798
+
799
+ <code class="strikethrough"
800
+ title="<?php echo esc_attr( $file->getRealPath() ); ?>"><?php echo esc_html( $file->getBasename() ); ?></code>
801
+
802
+ <?php } elseif ( $file->isFile() ) { ?>
803
+
804
+ <code
805
+ title="<?php echo esc_attr( $file->getRealPath() ); ?>"><?php echo esc_html( $file->getBasename() ); ?></code>
806
+
807
+ <?php } elseif ( $file->isDir() ) {
808
+ //echo add_query_arg( 'hmbkp_directory_browse', urlencode( $file->getPathname() ) );
809
+ ?>
810
+ <code title="<?php echo esc_attr( $file->getRealPath() ); ?>"><a
811
+ href="#"
812
+ onclick="event.preventDefault(); mainwp_backupwp_directory_browse('<?php echo urlencode( $file->getPathname() ); ?>', this)"><?php echo esc_html( $file->getBasename() ); ?></a></code>
813
+
814
+ <?php }
815
+ }
816
+ ?>
817
+
818
+ </td>
819
+
820
+ <td class="column-format column-filesize">
821
+
822
+ <?php if ( $file->isDir() && $is_size_calculated ) : ?>
823
+
824
+ <span class="spinner"></span>
825
+
826
+ <?php
827
+ else :
828
+ if ($new_version) {
829
+ $size = $site_size->filesize( $file );
830
+ } else {
831
+ $size = $schedule->filesize( $file );
832
+ }
833
+
834
+ if ( false !== $size ) {
835
+
836
+ $size = size_format( $size );
837
+
838
+ if ( ! $size ) {
839
+ $size = '0 B';
840
+ } ?>
841
+
842
+ <code>
843
+
844
+ <?php echo esc_html( $size ); ?>
845
+
846
+ <?php if ( $file->isDir() ) { ?>
847
+
848
+ <a title="<?php esc_attr_e( 'Recalculate the size of this directory', 'backupwordpress' ); ?>"
849
+ class="dashicons dashicons-update"
850
+ href="<?php echo esc_attr( wp_nonce_url( add_query_arg( 'hmbkp_recalculate_directory_filesize', urlencode( wp_normalize_path( $file->getPathname() ) ) ), 'hmbkp-recalculate_directory_filesize' ) ); ?>"><span><?php esc_html_e( 'Refresh', 'backupwordpress' ); ?></span></a>
851
+
852
+ <?php } ?>
853
+
854
+ </code>
855
+
856
+
857
+ <?php } else { ?>
858
+
859
+ <code>--</code>
860
+
861
+ <?php }
862
+ endif;
863
+ ?>
864
+
865
+ </td>
866
+
867
+ <td>
868
+ <?php echo esc_html( substr( sprintf( '%o', $file->getPerms() ), - 4 ) ); ?>
869
+ </td>
870
+
871
+ <td>
872
+
873
+ <?php if ( $file->isLink() ) : ?>
874
+
875
+ <span
876
+ title="<?php echo esc_attr( wp_normalize_path( $file->GetRealPath() ) ); ?>"><?php esc_html_e( 'Symlink', 'backupwordpress' ); ?></span>
877
+
878
+ <?php elseif ( $file->isDir() ) :
879
+
880
+ esc_html_e( 'Folder', 'backupwordpress' );
881
+
882
+ else :
883
+
884
+ esc_html_e( 'File', 'backupwordpress' );
885
+
886
+ endif;
887
+ ?>
888
+
889
+ </td>
890
+
891
+ <td class="column-format">
892
+
893
+ <?php if ( $is_unreadable ) : ?>
894
+
895
+ <strong
896
+ title="<?php esc_attr_e( 'Unreadable files won\'t be backed up.', 'backupwordpress' ); ?>"><?php esc_html_e( 'Unreadable', 'backupwordpress' ); ?></strong>
897
+
898
+ <?php elseif ( $is_excluded ) : ?>
899
+
900
+ <strong><?php esc_html_e( 'Excluded', 'backupwordpress' ); ?></strong>
901
+
902
+ <?php
903
+ else :
904
+
905
+ $exclude_path = $file->getPathname();
906
+
907
+ // Excluded directories need to be trailingslashed
908
+ if ( $file->isDir() ) {
909
+ $exclude_path = trailingslashit( wp_normalize_path( $file->getPathname() ) );
910
+ }
911
+
912
+ ?>
913
+
914
+ <a href="#"
915
+ onclick="event.preventDefault(); mainwp_backupwp_exclude_add_rule('<?php echo urlencode( $exclude_path ); ?>', this)"
916
+ class="button-secondary"><?php esc_html_e( 'Exclude &rarr;', 'backupwordpress' ); ?></a>
917
+
918
+ <?php endif; ?>
919
+
920
+ </td>
921
+
922
+ </tr>
923
+
924
+ <?php } ?>
925
+ </tbody>
926
+ </table>
927
+
928
+ <?php } ?>
929
+
930
+ <p class="submit">
931
+ <a href="#" onclick="event.preventDefault(); mainwp_backupwp_edit_exclude_done()"
932
+ class="button-primary"><?php esc_html_e( 'Done', 'backupwordpress' ); ?></a>
933
+ </p>
934
+
935
+ </div>
936
+
937
+ <?php
938
+ $output = ob_get_clean();
939
+ $information['e'] = $output;
940
+
941
+ return $information;
942
+
943
+ }
944
+
945
+ function directory_browse() {
946
+ $browse_dir = $_POST['browse_dir'];
947
+ $out = array();
948
+ $return = $this->get_excluded( $browse_dir );
949
+ $out['e'] = $return['e'];
950
+ $out['current_browse_dir'] = $browse_dir;
951
+
952
+ return $out;
953
+ }
954
+
955
+ function hmbkp_add_exclude_rule() {
956
+
957
+ if ( ! isset( $_POST['exclude_pathname'] ) || empty( $_POST['exclude_pathname'] ) ) {
958
+ return array( 'error' => __( 'Error: Empty exclude directory path.' ) );
959
+ }
960
+
961
+ $schedule_id = $this->check_schedule();
962
+ $schedule = new HM\BackUpWordPress\Scheduled_Backup( sanitize_text_field( $schedule_id ) );
963
+
964
+ $exclude_rule = urldecode( $_POST['exclude_pathname'] );
965
+
966
+ $schedule->set_excludes( $exclude_rule, true );
967
+
968
+ $schedule->save();
969
+
970
+ $current_path = urldecode( $_POST['browse_dir'] );
971
+
972
+ if ( empty( $current_path ) ) {
973
+ $current_path = null;
974
+ }
975
+
976
+ $return = $this->get_excluded( $current_path );
977
+ $out['e'] = $return['e'];
978
+ $out['current_browse_dir'] = $_POST['browse_dir'];
979
+
980
+ return $out;
981
+
982
+ }
983
+
984
+ function hmbkp_remove_exclude_rule() {
985
+
986
+ if ( ! isset( $_POST['remove_rule'] ) || empty( $_POST['remove_rule'] ) ) {
987
+ return array( 'error' => __( 'Error: Empty exclude directory path.' ) );
988
+ }
989
+
990
+ $schedule_id = $this->check_schedule();
991
+ $schedule = new HM\BackUpWordPress\Scheduled_Backup( sanitize_text_field( $schedule_id ) );
992
+
993
+ $excludes = $schedule->get_excludes();
994
+ $exclude_rule_to_remove = stripslashes( sanitize_text_field( $_POST['remove_rule'] ) );
995
+
996
+ if (method_exists($excludes, 'get_user_excludes')) {
997
+ $schedule->set_excludes( array_diff( $excludes->get_user_excludes(), (array) $exclude_rule_to_remove ) );
998
+ } else
999
+ $schedule->set_excludes( array_diff( $excludes, $exclude_rule_to_remove ) );
1000
+
1001
+ $schedule->save();
1002
+
1003
+ $current_path = urldecode( $_POST['browse_dir'] );
1004
+
1005
+ if ( empty( $current_path ) ) {
1006
+ $current_path = null;
1007
+ }
1008
+
1009
+ $return = $this->get_excluded( $current_path );
1010
+
1011
+ $out['e'] = $return['e'];
1012
+ $out['current_browse_dir'] = $_POST['browse_dir'];
1013
+
1014
+ return $out;
1015
+ }
1016
+
1017
+ function remove_exclude_rule() {
1018
+
1019
+ check_admin_referer( 'hmbkp_remove_exclude_rule', 'hmbkp-remove_exclude_rule_nonce' );
1020
+
1021
+ if ( ! isset( $_GET['hmbkp_remove_exclude'] ) ) {
1022
+ die;
1023
+ }
1024
+
1025
+ $schedule = new Scheduled_Backup( sanitize_text_field( $_GET['hmbkp_schedule_id'] ) );
1026
+
1027
+ $excludes = $schedule->get_excludes();
1028
+ $exclude_rule_to_remove = stripslashes( sanitize_text_field( $_GET['hmbkp_remove_exclude'] ) );
1029
+
1030
+ $schedule->set_excludes( array_diff( $excludes->get_user_excludes(), (array) $exclude_rule_to_remove ) );
1031
+
1032
+ $schedule->save();
1033
+
1034
+ wp_safe_redirect( wp_get_referer(), '303' );
1035
+
1036
+ die;
1037
+
1038
+ }
1039
+
1040
+ function update_schedule() {
1041
+ $sch_id = isset( $_POST['schedule_id'] ) ? $_POST['schedule_id'] : 0;
1042
+ $sch_id = sanitize_text_field( urldecode( $sch_id ) );
1043
+ $options = isset( $_POST['options'] ) ? maybe_unserialize( base64_decode( $_POST['options'] ) ) : false;
1044
+
1045
+ if ( ! is_array( $options ) || empty( $options ) || empty( $sch_id ) ) {
1046
+ return array( 'error' => 'Error: Schedule data' );
1047
+ }
1048
+
1049
+ // $current_value = get_option( 'hmbkp_schedule_' . $sch_id );
1050
+ // if ( is_array( $current_value ) && isset( $current_value['excludes'] ) ) {
1051
+ // // do not update 'excludes' value
1052
+ // $options['excludes'] = $current_value['excludes'];
1053
+ // }
1054
+
1055
+ $filter_opts = array(
1056
+ 'type',
1057
+ 'email',
1058
+ 'reoccurrence',
1059
+ 'max_backups',
1060
+ 'schedule_start_time',
1061
+ );
1062
+
1063
+ $out = array();
1064
+ if ( is_array( $options ) ) {
1065
+ $old_options = get_option( 'hmbkp_schedule_' . $sch_id );
1066
+ if ( is_array( $old_options ) ) {
1067
+ foreach ( $old_options as $key => $val ) {
1068
+ if ( ! in_array( $key, $filter_opts ) ) {
1069
+ $options[ $key ] = $old_options[ $key ];
1070
+ }
1071
+ }
1072
+ }
1073
+
1074
+ update_option( 'hmbkp_schedule_' . $sch_id, $options );
1075
+ delete_transient( 'hmbkp_schedules' );
1076
+ $out['result'] = 'SUCCESS';
1077
+ } else {
1078
+ $out['result'] = 'NOTCHANGE';
1079
+ }
1080
+
1081
+ $schedule = new HM\BackUpWordPress\Scheduled_Backup( sanitize_text_field( $sch_id ) );
1082
+
1083
+ if ( ! empty( $options['reoccurrence'] ) && ! empty( $options['schedule_start_time'] ) ) {
1084
+ // Calculate the start time depending on the recurrence
1085
+ $start_time = $options['schedule_start_time'];
1086
+ if ( $start_time ) {
1087
+ $schedule->set_schedule_start_time( $start_time );
1088
+ }
1089
+ }
1090
+
1091
+ if ( ! empty( $options['reoccurrence'] ) ) {
1092
+ $schedule->set_reoccurrence( $options['reoccurrence'] );
1093
+ }
1094
+ $out['next_occurrence'] = $schedule->get_next_occurrence( false );
1095
+
1096
+ return $out;
1097
+ }
1098
+
1099
+ public function save_all_schedules() {
1100
+ $schedules = isset( $_POST['all_schedules'] ) ? maybe_unserialize( base64_decode( $_POST['all_schedules'] ) ) : false;
1101
+
1102
+ if ( ! is_array( $schedules ) || empty( $schedules ) ) {
1103
+ return array( 'error' => 'Error: Schedule data' );
1104
+ }
1105
+
1106
+ $out = array();
1107
+ foreach($schedules as $sch_id => $sch) {
1108
+ if ( empty($sch_id) || !isset( $sch['options'] ) || ! is_array( $sch['options'] ) )
1109
+ continue;
1110
+ $options = $sch['options'];
1111
+ $filter_opts = array(
1112
+ 'type',
1113
+ 'email',
1114
+ 'reoccurrence',
1115
+ 'max_backups',
1116
+ 'schedule_start_time',
1117
+ );
1118
+ if ( is_array( $options ) ) {
1119
+ $old_options = get_option( 'hmbkp_schedule_' . $sch_id );
1120
+ if ( is_array( $old_options ) ) {
1121
+ foreach ( $old_options as $key => $val ) {
1122
+ if ( ! in_array( $key, $filter_opts ) ) {
1123
+ $options[ $key ] = $old_options[ $key ];
1124
+ }
1125
+ }
1126
+ }
1127
+ update_option( 'hmbkp_schedule_' . $sch_id, $options );
1128
+ }
1129
+
1130
+ $schedule = new HM\BackUpWordPress\Scheduled_Backup( sanitize_text_field( $sch_id ) );
1131
+
1132
+ if ( ! empty( $options['reoccurrence'] ) && ! empty( $options['schedule_start_time'] ) ) {
1133
+ // Calculate the start time depending on the recurrence
1134
+ $start_time = $options['schedule_start_time'];
1135
+ if ( $start_time ) {
1136
+ $schedule->set_schedule_start_time( $start_time );
1137
+ }
1138
+ }
1139
+
1140
+ if ( ! empty( $options['reoccurrence'] ) ) {
1141
+ $schedule->set_reoccurrence( $options['reoccurrence'] );
1142
+ }
1143
+ $out['result'] = 'SUCCESS';
1144
+ }
1145
+ delete_transient( 'hmbkp_schedules' );
1146
+ return $out;
1147
+ }
1148
+
1149
+ public static function isActivated() {
1150
+ if ( ! defined( 'HMBKP_PLUGIN_PATH' ) || ! class_exists( 'HM\BackUpWordPress\Plugin' ) ) {
1151
+ return false;
1152
+ }
1153
+
1154
+ return true;
1155
+ }
1156
+
1157
+
1158
+ public function all_plugins( $plugins ) {
1159
+ foreach ( $plugins as $key => $value ) {
1160
+ $plugin_slug = basename( $key, '.php' );
1161
+ if ( 'backupwordpress' === $plugin_slug ) {
1162
+ unset( $plugins[ $key ] );
1163
+ }
1164
+ }
1165
+
1166
+ return $plugins;
1167
+ }
1168
+
1169
+ public function remove_menu() {
1170
+ global $submenu;
1171
+ if ( isset( $submenu['tools.php'] ) ) {
1172
+ foreach ( $submenu['tools.php'] as $index => $item ) {
1173
+ if ( 'backupwordpress' === $item[2] ) {
1174
+ unset( $submenu['tools.php'][ $index ] );
1175
+ break;
1176
+ }
1177
+ }
1178
+ }
1179
+
1180
+ $pos = stripos( $_SERVER['REQUEST_URI'], 'tools.php?page=backupwordpress' );
1181
+ if ( false !== $pos ) {
1182
+ wp_redirect( get_option( 'siteurl' ) . '/wp-admin/index.php' );
1183
+ exit();
1184
+ }
1185
+ }
1186
+ }
1187
+
class/class-mainwp-child-back-wp-up.php ADDED
@@ -0,0 +1,1396 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ if ( ! defined( 'MAINWP_BACKWPUP_DEVELOPMENT' ) ) {
4
+ define( 'MAINWP_BACKWPUP_DEVELOPMENT', false );
5
+ }
6
+
7
+ class MainWP_Child_Back_WP_Up {
8
+ public $is_backwpup_installed = false;
9
+ public $is_backwpup_pro = false;
10
+ public $plugin_translate = 'mainwp-backwpup-extension';
11
+ public static $instance = null;
12
+ protected $software_version = '0.1';
13
+ public static $information = array();
14
+
15
+ protected $exclusions = array(
16
+ 'cron' => array(
17
+ 'cronminutes',
18
+ 'cronhours',
19
+ 'cronmday',
20
+ 'cronmon',
21
+ 'cronwday',
22
+ 'moncronminutes',
23
+ 'moncronhours',
24
+ 'moncronmday',
25
+ 'weekcronminutes',
26
+ 'weekcronhours',
27
+ 'weekcronwday',
28
+ 'daycronminutes',
29
+ 'daycronhours',
30
+ 'hourcronminutes',
31
+ 'cronbtype',
32
+ ),
33
+ 'dest-EMAIL' => array( 'emailpass' ),
34
+ 'dest-DBDUMP' => array( 'dbdumpspecialsetalltables' ),
35
+ 'dest-FTP' => array( 'ftppass' ),
36
+ 'dest-S3' => array( 's3secretkey' ),
37
+ 'dest-MSAZURE' => array( 'msazurekey' ),
38
+ 'dest-SUGARSYNC' => array( 'sugaremail', 'sugarpass', 'sugarrefreshtoken' ),
39
+ 'dest-GDRIVE' => array( 'gdriverefreshtoken' ),
40
+ 'dest-RSC' => array( 'rscapikey' ),
41
+ 'dest-GLACIER' => array( 'glaciersecretkey' ),
42
+ );
43
+
44
+ static function Instance() {
45
+ if ( MainWP_Child_Back_WP_Up::$instance == null ) {
46
+ MainWP_Child_Back_WP_Up::$instance = new MainWP_Child_Back_WP_Up();
47
+ }
48
+
49
+ return MainWP_Child_Back_WP_Up::$instance;
50
+ }
51
+
52
+ public function __construct() {
53
+ require_once( ABSPATH . 'wp-admin/includes/plugin.php' );
54
+
55
+ if ( is_plugin_active( 'backwpup-pro/backwpup.php' ) && file_exists( plugin_dir_path( __FILE__ ) . '../../backwpup-pro/backwpup.php' ) ) {
56
+ require_once( plugin_dir_path( __FILE__ ) . '../../backwpup-pro/backwpup.php' );
57
+ require_once( plugin_dir_path( __FILE__ ) . '../../backwpup-pro/inc/pro/class-pro.php' );
58
+ BackWPup::get_instance();
59
+ $this->is_backwpup_installed = true;
60
+ $this->is_backwpup_pro = true;
61
+ } else if ( is_plugin_active( 'backwpup/backwpup.php' ) && file_exists( plugin_dir_path( __FILE__ ) . '../../backwpup/backwpup.php' ) ) {
62
+ require_once( plugin_dir_path( __FILE__ ) . '../../backwpup/backwpup.php' );
63
+ BackWPup::get_instance();
64
+ $this->is_backwpup_installed = true;
65
+ }
66
+
67
+ if ( $this->is_backwpup_installed ) {
68
+ add_action( 'wp_ajax_mainwp_backwpup_download_backup', array( $this, 'download_backup' ) );
69
+ }
70
+ }
71
+
72
+ public function action() {
73
+ if ( ! $this->is_backwpup_installed ) {
74
+ MainWP_Helper::write( array( 'error' => __( 'Please install BackWPup plugin on child website', $this->plugin_translate ) ) );
75
+
76
+ return;
77
+ }
78
+
79
+ error_reporting( 0 );
80
+ function mainwp_backwpup_handle_fatal_error() {
81
+ $error = error_get_last();
82
+ $info = MainWP_Child_Back_WP_Up::$information;
83
+ if ( isset( $error['type'] ) && E_ERROR === $error['type'] && isset( $error['message'] ) ) {
84
+ MainWP_Helper::write( array( 'error' => 'MainWP_Child fatal error : ' . $error['message'] . ' Line: ' . $error['line'] . ' File: ' . $error['file'] ) );
85
+ } else if ( ! empty( $info ) ) {
86
+ MainWP_Helper::write( MainWP_Child_Back_WP_Up::$information );
87
+ } else {
88
+ MainWP_Helper::write( array( 'error' => 'Missing information array inside fatal_error' ) );
89
+ }
90
+ }
91
+
92
+ register_shutdown_function( 'mainwp_backwpup_handle_fatal_error' );
93
+
94
+ $information = array();
95
+
96
+ if ( ! isset( $_POST['action'] ) ) {
97
+ $information = array( 'error' => __( 'Missing action.', $this->plugin_translate ) );
98
+ } else {
99
+ MainWP_Helper::update_option( 'mainwp_backwpup_ext_enabled', 'Y' );
100
+ switch ( $_POST['action'] ) {
101
+ case 'backwpup_update_settings':
102
+ $information = $this->update_settings();
103
+ break;
104
+
105
+ case 'backwpup_insert_or_update_jobs':
106
+ $information = $this->insert_or_update_jobs();
107
+ break;
108
+
109
+ case 'backwpup_insert_or_update_jobs_global':
110
+ $information = $this->insert_or_update_jobs_global();
111
+ break;
112
+
113
+ case 'backwpup_get_child_tables':
114
+ $information = $this->get_child_tables();
115
+ break;
116
+
117
+ case 'backwpup_get_job_files':
118
+ $information = $this->get_job_files();
119
+ break;
120
+
121
+ case 'backwpup_destination_email_check_email':
122
+ $information = $this->destination_email_check_email();
123
+ break;
124
+
125
+ case 'backwpup_backup_now':
126
+ $information = $this->backup_now();
127
+ break;
128
+
129
+ case 'backwpup_ajax_working':
130
+ $information = $this->ajax_working();
131
+ break;
132
+
133
+ case 'backwpup_backup_abort':
134
+ $information = $this->backup_abort();
135
+ break;
136
+
137
+ case 'backwpup_tables':
138
+ $information = $this->tables();
139
+ break;
140
+
141
+ case 'backwpup_view_log':
142
+ $information = $this->view_log();
143
+ break;
144
+
145
+ case 'backwpup_delete_log':
146
+ $information = $this->delete_log();
147
+ break;
148
+
149
+ case 'backwpup_delete_job':
150
+ $information = $this->delete_job();
151
+ break;
152
+
153
+ case 'backwpup_delete_backup':
154
+ $information = $this->delete_backup();
155
+ break;
156
+
157
+ case 'backwpup_information':
158
+ $information = $this->information();
159
+ break;
160
+
161
+ case 'backwpup_wizard_system_scan':
162
+ $information = $this->wizard_system_scan();
163
+ break;
164
+
165
+ case 'backwpup_is_pro':
166
+ $information = array( 'is_pro' => $this->is_backwpup_pro );
167
+ break;
168
+
169
+ case 'backwpup_show_hide':
170
+ $information = $this->show_hide();
171
+ break;
172
+
173
+ default:
174
+ $information = array( 'error' => __( 'Wrong action.', $this->plugin_translate ) );
175
+ }
176
+ }
177
+
178
+ MainWP_Child_Back_WP_Up::$information = $information;
179
+ exit();
180
+ }
181
+
182
+ public function init() {
183
+ if ( get_option( 'mainwp_backwpup_ext_enabled' ) !== 'Y' ) {
184
+ return;
185
+ }
186
+
187
+ if (!$this->is_backwpup_installed)
188
+ return;
189
+
190
+ add_action( 'mainwp_child_site_stats', array( $this, 'do_site_stats' ) );
191
+
192
+ if ( get_option( 'mainwp_backwpup_hide_plugin' ) === 'hide' ) {
193
+ add_filter( 'all_plugins', array( $this, 'all_plugins' ) );
194
+ add_action( 'admin_menu', array( $this, 'remove_menu' ) );
195
+ }
196
+ }
197
+
198
+ function do_site_stats() {
199
+ if (has_action('mainwp_child_reports_log')) {
200
+ do_action( 'mainwp_child_reports_log', 'backwpup');
201
+ } else {
202
+ $this->do_reports_log('backwpup');
203
+ }
204
+ }
205
+
206
+ public function do_reports_log($ext = '') {
207
+ if ( $ext !== 'backwpup' ) return;
208
+ if (!$this->is_backwpup_installed)
209
+ return;
210
+
211
+ $destinations = BackWPup::get_registered_destinations();
212
+ $jobdests = $this->get_destinations_list();
213
+
214
+ if ( !empty( $jobdests ) ) {
215
+ foreach ($jobdests as $jobdest) {
216
+ list( $jobid, $dest ) = explode( '_', $jobdest );
217
+ if ( ! empty( $destinations[ $dest ][ 'class' ] ) ) {
218
+ $dest_object = BackWPup::get_destination( $dest );
219
+ $items = $dest_object->file_get_list( $jobdest );
220
+ //if no items brake
221
+ if ( $items ) {
222
+ foreach ( $items as $ma ) {
223
+ if (isset($ma['time'])) {
224
+ $backup_time = $ma[ "time" ];
225
+ $message = 'BackWPup backup finished';
226
+ $backup_type = 'BackWPup';
227
+ $destination = "N/A";
228
+ if (!empty($backup_time)) {
229
+ do_action( 'mainwp_backwpup_backup', $message, $backup_type, $backup_time );
230
+ MainWP_Helper::update_lasttime_backup( 'backwpup', $backup_time ); // to support backup before update feature
231
+ }
232
+ }
233
+ }
234
+ }
235
+ }
236
+ }
237
+ }
238
+ }
239
+
240
+ function get_destinations_list() {
241
+
242
+ $jobdest = array();
243
+ $jobids = BackWPup_Option::get_job_ids();
244
+ $destinations = BackWPup::get_registered_destinations();
245
+ foreach ( $jobids as $jobid ) {
246
+ if ( BackWPup_Option::get( $jobid, 'backuptype' ) === 'sync' ) {
247
+ continue;
248
+ }
249
+ $dests = BackWPup_Option::get( $jobid, 'destinations' );
250
+ foreach ( $dests as $dest ) {
251
+ if ( ! $destinations[ $dest ][ 'class' ] ) {
252
+ continue;
253
+ }
254
+ $dest_class = BackWPup::get_destination( $dest );
255
+ $can_do_dest = $dest_class->file_get_list( $jobid . '_' . $dest );
256
+ if ( ! empty( $can_do_dest ) ) {
257
+ $jobdest[ ] = $jobid . '_' . $dest;
258
+ }
259
+ }
260
+ }
261
+
262
+ return $jobdest;
263
+ }
264
+
265
+ public function all_plugins( $plugins ) {
266
+ foreach ( $plugins as $key => $value ) {
267
+ $plugin_slug = basename( $key, '.php' );
268
+ if ( 'backwpup' === $plugin_slug ) {
269
+ unset( $plugins[ $key ] );
270
+ }
271
+ }
272
+
273
+ return $plugins;
274
+ }
275
+
276
+ public function remove_menu() {
277
+ global $submenu;
278
+
279
+ if ( isset( $submenu['backwpup'] ) ) {
280
+ unset( $submenu['backwpup'] );
281
+ }
282
+
283
+ remove_menu_page( 'backwpup' );
284
+
285
+ $pos = stripos( $_SERVER['REQUEST_URI'], 'admin.php?page=backwpup' );
286
+ if ( false !== $pos ) {
287
+ wp_redirect( get_option( 'siteurl' ) . '/wp-admin/index.php' );
288
+ exit();
289
+ }
290
+ }
291
+
292
+ protected function show_hide() {
293
+
294
+ $hide = isset( $_POST['show_hide'] ) && ( '1' === $_POST['show_hide'] ) ? 'hide' : '';
295
+
296
+ MainWP_Helper::update_option( 'mainwp_backwpup_hide_plugin', $hide, 'yes' );
297
+
298
+ return array( 'success' => 1 );
299
+ }
300
+
301
+ protected function information() {
302
+ global $wpdb;
303
+ // Copied from BackWPup_Page_Settings
304
+ ob_start();
305
+ echo '<table class="wp-list-table widefat fixed" cellspacing="0" style="width: 85%;margin-left:auto;;margin-right:auto;">';
306
+ echo '<thead><tr><th width="35%">' . __( 'Setting', 'backwpup' ) . '</th><th>' . __( 'Value', 'backwpup' ) . '</th></tr></thead>';
307
+ echo '<tfoot><tr><th>' . __( 'Setting', 'backwpup' ) . '</th><th>' . __( 'Value', 'backwpup' ) . '</th></tr></tfoot>';
308
+ echo '<tr title="&gt;=3.2"><td>' . __( 'WordPress version', 'backwpup' ) . '</td><td>' . esc_html( BackWPup::get_plugin_data( 'wp_version' ) ) . '</td></tr>';
309
+ if ( ! class_exists( 'BackWPup_Pro', false ) ) {
310
+ echo '<tr title=""><td>' . __( 'BackWPup version', 'backwpup' ) . '</td><td>' . esc_html( BackWPup::get_plugin_data( 'Version' ) ) . ' <a href="' . esc_url( translate( BackWPup::get_plugin_data( 'pluginuri' ), 'backwpup' ) ) . '">' . __( 'Get pro.', 'backwpup' ) . '</a></td></tr>';
311
+ } else {
312
+ echo '<tr title=""><td>' . __( 'BackWPup Pro version', 'backwpup' ) . '</td><td>' . esc_html( BackWPup::get_plugin_data( 'Version' ) ) . '</td></tr>';
313
+ }
314
+
315
+ echo '<tr title="&gt;=5.3.3"><td>' . __( 'PHP version', 'backwpup' ) . '</td><td>' . esc_html( PHP_VERSION ) . '</td></tr>';
316
+ echo '<tr title="&gt;=5.0.7"><td>' . __( 'MySQL version', 'backwpup' ) . '</td><td>' . esc_html( $wpdb->get_var( 'SELECT VERSION() AS version' ) ) . '</td></tr>';
317
+ if ( function_exists( 'curl_version' ) ) {
318
+ $curlversion = curl_version();
319
+ echo '<tr title=""><td>' . __( 'cURL version', 'backwpup' ) . '</td><td>' . esc_html( $curlversion['version'] ) . '</td></tr>';
320
+ echo '<tr title=""><td>' . __( 'cURL SSL version', 'backwpup' ) . '</td><td>' . esc_html( $curlversion['ssl_version'] ) . '</td></tr>';
321
+ } else {
322
+ echo '<tr title=""><td>' . __( 'cURL version', 'backwpup' ) . '</td><td>' . __( 'unavailable', 'backwpup' ) . '</td></tr>';
323
+ }
324
+ echo '<tr title=""><td>' . __( 'WP-Cron url:', 'backwpup' ) . '</td><td>' . esc_html( site_url( 'wp-cron.php' ) ) . '</td></tr>';
325
+
326
+ echo '<tr><td>' . __( 'Server self connect:', 'backwpup' ) . '</td><td>';
327
+ $raw_response = BackWPup_Job::get_jobrun_url( 'test' );
328
+ $test_result = '';
329
+ if ( is_wp_error( $raw_response ) ) {
330
+ $test_result .= sprintf( __( 'The HTTP response test get an error "%s"', 'backwpup' ), esc_html( $raw_response->get_error_message() ) );
331
+ } elseif ( 200 !== (int) wp_remote_retrieve_response_code( $raw_response ) && 204 !== (int) wp_remote_retrieve_response_code( $raw_response ) ) {
332
+ $test_result .= sprintf( __( 'The HTTP response test get a false http status (%s)', 'backwpup' ), esc_html( wp_remote_retrieve_response_code( $raw_response ) ) );
333
+ }
334
+ $headers = wp_remote_retrieve_headers( $raw_response );
335
+ if ( isset( $headers['x-backwpup-ver'] ) && BackWPup::get_plugin_data( 'version' ) !== $headers['x-backwpup-ver'] ) {
336
+ $test_result .= sprintf( __( 'The BackWPup HTTP response header returns a false value: "%s"', 'backwpup' ), esc_html( $headers['x-backwpup-ver'] ) );
337
+ }
338
+
339
+ if ( empty( $test_result ) ) {
340
+ esc_html_e( 'Response Test O.K.', 'backwpup' );
341
+ } else {
342
+ echo esc_html( $test_result );
343
+ }
344
+ echo '</td></tr>';
345
+
346
+ echo '<tr><td>' . __( 'Temp folder:', 'backwpup' ) . '</td><td>';
347
+ if ( ! is_dir( BackWPup::get_plugin_data( 'TEMP' ) ) ) {
348
+ echo sprintf( __( 'Temp folder %s doesn\'t exist.', 'backwpup' ), esc_html( BackWPup::get_plugin_data( 'TEMP' ) ) );
349
+ } elseif ( ! is_writable( BackWPup::get_plugin_data( 'TEMP' ) ) ) {
350
+ echo sprintf( __( 'Temporary folder %s is not writable.', 'backwpup' ), esc_html( BackWPup::get_plugin_data( 'TEMP' ) ) );
351
+ } else {
352
+ echo esc_html( BackWPup::get_plugin_data( 'TEMP' ) );
353
+ }
354
+ echo '</td></tr>';
355
+
356
+ echo '<tr><td>' . __( 'Log folder:', 'backwpup' ) . '</td><td>';
357
+
358
+ $log_folder = BackWPup_File::get_absolute_path( get_site_option( 'backwpup_cfg_logfolder' ) );
359
+
360
+ if ( ! is_dir( $log_folder ) ) {
361
+ echo sprintf( __( 'Logs folder %s not exist.', 'backwpup' ), esc_html( $log_folder ) );
362
+ } elseif ( ! is_writable( $log_folder ) ) {
363
+ echo sprintf( __( 'Log folder %s is not writable.', 'backwpup' ), esc_html( $log_folder ) );
364
+ } else {
365
+ echo esc_html( $log_folder );
366
+ }
367
+ echo '</td></tr>';
368
+ echo '<tr title=""><td>' . __( 'Server', 'backwpup' ) . '</td><td>' . esc_html( $_SERVER['SERVER_SOFTWARE'] ) . '</td></tr>';
369
+ echo '<tr title=""><td>' . __( 'Operating System', 'backwpup' ) . '</td><td>' . esc_html( PHP_OS ) . '</td></tr>';
370
+ echo '<tr title=""><td>' . __( 'PHP SAPI', 'backwpup' ) . '</td><td>' . esc_html( PHP_SAPI ) . '</td></tr>';
371
+ echo '<tr title=""><td>' . __( 'Current PHP user', 'backwpup' ) . '</td><td>' . esc_html( get_current_user() ) . '</td></tr>';
372
+ $text = version_compare(phpversion(), '5.3.0') < 0 && (bool) ini_get( 'safe_mode' ) ? __( 'On', 'backwpup' ) : __( 'Off', 'backwpup' );
373
+ echo '<tr title=""><td>' . __( 'Safe Mode', 'backwpup' ) . '</td><td>' . $text . '</td></tr>';
374
+ echo '<tr title="&gt;=30"><td>' . __( 'Maximum execution time', 'backwpup' ) . '</td><td>' . ini_get( 'max_execution_time' ) . ' ' . __( 'seconds', 'backwpup' ) . '</td></tr>';
375
+ if ( defined( 'ALTERNATE_WP_CRON' ) && ALTERNATE_WP_CRON ) {
376
+ echo '<tr title="ALTERNATE_WP_CRON"><td>' . __( 'Alternative WP Cron', 'backwpup' ) . '</td><td>' . __( 'On', 'backwpup' ) . '</td></tr>';
377
+ } else {
378
+ echo '<tr title="ALTERNATE_WP_CRON"><td>' . __( 'Alternative WP Cron', 'backwpup' ) . '</td><td>' . __( 'Off', 'backwpup' ) . '</td></tr>';
379
+ }
380
+ if ( defined( 'DISABLE_WP_CRON' ) && DISABLE_WP_CRON ) {
381
+ echo '<tr title="DISABLE_WP_CRON"><td>' . __( 'Disabled WP Cron', 'backwpup' ) . '</td><td>' . __( 'On', 'backwpup' ) . '</td></tr>';
382
+ } else {
383
+ echo '<tr title="DISABLE_WP_CRON"><td>' . __( 'Disabled WP Cron', 'backwpup' ) . '</td><td>' . __( 'Off', 'backwpup' ) . '</td></tr>';
384
+ }
385
+ if ( defined( 'FS_CHMOD_DIR' ) ) {
386
+ echo '<tr title="FS_CHMOD_DIR"><td>' . __( 'CHMOD Dir', 'backwpup' ) . '</td><td>' . FS_CHMOD_DIR . '</td></tr>';
387
+ } else {
388
+ echo '<tr title="FS_CHMOD_DIR"><td>' . __( 'CHMOD Dir', 'backwpup' ) . '</td><td>0755</td></tr>';
389
+ }
390
+
391
+ $now = localtime( time(), true );
392
+ echo '<tr title=""><td>' . __( 'Server Time', 'backwpup' ) . '</td><td>' . esc_html( $now['tm_hour'] ) . ':' . esc_html( $now['tm_min'] ) . '</td></tr>';
393
+ echo '<tr title=""><td>' . __( 'Blog Time', 'backwpup' ) . '</td><td>' . esc_html( date_i18n( 'H:i' ) ) . '</td></tr>';
394
+ echo '<tr title=""><td>' . __( 'Blog Timezone', 'backwpup' ) . '</td><td>' . esc_html( get_option( 'timezone_string' ) ) . '</td></tr>';
395
+ echo '<tr title=""><td>' . __( 'Blog Time offset', 'backwpup' ) . '</td><td>' . sprintf( __( '%s hours', 'backwpup' ), esc_html( get_option( 'gmt_offset' ) ) ) . '</td></tr>';
396
+ echo '<tr title="WPLANG"><td>' . __( 'Blog language', 'backwpup' ) . '</td><td>' . esc_html( get_bloginfo( 'language' ) ) . '</td></tr>';
397
+ echo '<tr title="utf8"><td>' . __( 'MySQL Client encoding', 'backwpup' ) . '</td><td>';
398
+ echo defined( 'DB_CHARSET' ) ? esc_html( DB_CHARSET ) : '';
399
+ echo '</td></tr>';
400
+ echo '<tr title="URF-8"><td>' . __( 'Blog charset', 'backwpup' ) . '</td><td>' . esc_html( get_bloginfo( 'charset' ) ) . '</td></tr>';
401
+ echo '<tr title="&gt;=128M"><td>' . __( 'PHP Memory limit', 'backwpup' ) . '</td><td>' . esc_html( ini_get( 'memory_limit' ) ) . '</td></tr>';
402
+ echo '<tr title="WP_MEMORY_LIMIT"><td>' . __( 'WP memory limit', 'backwpup' ) . '</td><td>' . esc_html( WP_MEMORY_LIMIT ) . '</td></tr>';
403
+ echo '<tr title="WP_MAX_MEMORY_LIMIT"><td>' . __( 'WP maximum memory limit', 'backwpup' ) . '</td><td>' . esc_html( WP_MAX_MEMORY_LIMIT ) . '</td></tr>';
404
+ echo '<tr title=""><td>' . __( 'Memory in use', 'backwpup' ) . '</td><td>' . esc_html( size_format( @memory_get_usage( true ), 2 ) ) . '</td></tr>';
405
+ //disabled PHP functions
406
+ $disabled = ini_get( 'disable_functions' );
407
+ if ( ! empty( $disabled ) ) {
408
+ $disabledarry = explode( ',', $disabled );
409
+ echo '<tr title=""><td>' . __( 'Disabled PHP Functions:', 'backwpup' ) . '</td><td>';
410
+ echo esc_html( implode( ', ', $disabledarry ) );
411
+ echo '</td></tr>';
412
+ }
413
+ //Loaded PHP Extensions
414
+ echo '<tr title=""><td>' . __( 'Loaded PHP Extensions:', 'backwpup' ) . '</td><td>';
415
+ $extensions = get_loaded_extensions();
416
+ sort( $extensions );
417
+ echo esc_html( implode( ', ', $extensions ) );
418
+ echo '</td></tr>';
419
+ echo '</table>';
420
+
421
+ $output = ob_get_contents();
422
+
423
+ ob_end_clean();
424
+
425
+ return array( 'success' => 1, 'response' => $output );
426
+ }
427
+
428
+ protected function delete_log() {
429
+ if ( ! isset( $_POST['settings']['logfile'] ) || ! is_array( $_POST['settings']['logfile'] ) ) {
430
+ return array( 'error' => __( 'Missing logfile.', $this->plugin_translate ) );
431
+ }
432
+
433
+ $dir = get_site_option( 'backwpup_cfg_logfolder' );
434
+ $dir = BackWPup_File::get_absolute_path( $dir );
435
+
436
+ foreach ( $_POST['settings']['logfile'] as $logfile ) {
437
+ $logfile = basename( $logfile );
438
+
439
+ if ( ! is_writeable( $dir ) ) {
440
+ return array( 'error' => __( 'Directory not writable:', $this->plugin_translate ) . $dir );
441
+ }
442
+ if ( ! is_file( $dir . $logfile ) ) {
443
+ return array( 'error' => __( 'Not file:', $this->plugin_translate ) . $dir . $logfile );
444
+ }
445
+
446
+ unlink( $dir . $logfile );
447
+
448
+ }
449
+
450
+ return array( 'success' => 1 );
451
+ }
452
+
453
+ protected function delete_job() {
454
+ if ( ! isset( $_POST['job_id'] ) ) {
455
+ return array( 'error' => __( 'Missing job_id.', $this->plugin_translate ) );
456
+ }
457
+
458
+ $job_id = (int) $_POST['job_id'];
459
+
460
+ wp_clear_scheduled_hook( 'backwpup_cron', array( 'id' => $job_id ) );
461
+ if ( ! BackWPup_Option::delete_job( $job_id ) ) {
462
+ return array( 'error' => __( 'Cannot delete job', $this->plugin_translate ) );
463
+ }
464
+
465
+ return array( 'success' => 1 );
466
+ }
467
+
468
+ protected function delete_backup() {
469
+ if ( ! isset( $_POST['settings']['backupfile'] ) ) {
470
+ return array( 'error' => __( 'Missing backupfile.', $this->plugin_translate ) );
471
+ }
472
+
473
+ if ( ! isset( $_POST['settings']['dest'] ) ) {
474
+ return array( 'error' => __( 'Missing dest.', $this->plugin_translate ) );
475
+ }
476
+
477
+ $backupfile = $_POST['settings']['backupfile'];
478
+ $dest = $_POST['settings']['dest'];
479
+
480
+ list( $dest_id, $dest_name ) = explode( '_', $dest );
481
+
482
+ $dest_class = BackWPup::get_destination( $dest_name );
483
+
484
+ if ( is_null( $dest_class ) ) {
485
+ return array( 'error' => __( 'Invalid dest class.', $this->plugin_translate ) );
486
+ }
487
+
488
+ $files = $dest_class->file_get_list( $dest );
489
+
490
+ foreach ( $files as $file ) {
491
+ if ( is_array( $file ) && $file['file'] == $backupfile ) {
492
+ $dest_class->file_delete( $dest, $backupfile );
493
+
494
+ return array( 'success' => 1, 'response' => 'DELETED' );
495
+ }
496
+ }
497
+
498
+ return array( 'success' => 1, 'response' => 'Not found' );
499
+ }
500
+
501
+ protected function view_log() {
502
+ if ( ! isset( $_POST['settings']['logfile'] ) ) {
503
+ return array( 'error' => __( 'Missing logfile.', $this->plugin_translate ) );
504
+ }
505
+
506
+ $log_folder = get_site_option( 'backwpup_cfg_logfolder' );
507
+ $log_folder = BackWPup_File::get_absolute_path( $log_folder );
508
+ $log_file = $log_folder . basename( $_POST['settings']['logfile'] );
509
+
510
+ if ( ! is_readable( $log_file ) && ! is_readable( $log_file . '.gz' ) && ! is_readable( $log_file . '.bz2' ) ) {
511
+ $output = __( 'Log file doesn\'t exists', $this->plugin_translate );
512
+ } else {
513
+ if ( ! file_exists( $log_file ) && file_exists( $log_file . '.gz' ) ) {
514
+ $log_file = $log_file . '.gz';
515
+ }
516
+
517
+ if ( ! file_exists( $log_file ) && file_exists( $log_file . '.bz2' ) ) {
518
+ $log_file = $log_file . '.bz2';
519
+ }
520
+
521
+ if ( '.gz' == substr( $log_file, - 3 ) ) {
522
+ $output = file_get_contents( 'compress.zlib://' . $log_file, false );
523
+ } else {
524
+ $output = file_get_contents( $log_file, false );
525
+ }
526
+ }
527
+
528
+ return array( 'success' => 1, 'response' => $output );
529
+ }
530
+
531
+ protected function tables() {
532
+ if ( ! isset( $_POST['settings']['type'] ) ) {
533
+ return array( 'error' => __( 'Missing type.', $this->plugin_translate ) );
534
+ }
535
+
536
+ if ( ! isset( $_POST['settings']['website_id'] ) ) {
537
+ return array( 'error' => __( 'Missing website id.', $this->plugin_translate ) );
538
+ }
539
+
540
+ $type = $_POST['settings']['type'];
541
+ $website_id = $_POST['settings']['website_id'];
542
+
543
+ $this->wp_list_table_dependency();
544
+
545
+ $array = array();
546
+
547
+ switch ( $type ) {
548
+ case 'logs':
549
+ $log_folder = get_site_option( 'backwpup_cfg_logfolder' );
550
+ $log_folder = BackWPup_File::get_absolute_path( $log_folder );
551
+ $log_folder = untrailingslashit( $log_folder );
552
+
553
+ if ( ! is_dir( $log_folder ) ) {
554
+ return array( 'success' => 1, 'response' => $array );
555
+ }
556
+ update_user_option( get_current_user_id(), 'backwpuplogs_per_page', 99999999 );
557
+ $output = new BackWPup_Page_Logs();
558
+ $output->prepare_items();
559
+ break;
560
+
561
+ case 'backups':
562
+ update_user_option( get_current_user_id(), 'backwpupbackups_per_page', 99999999 );
563
+ $output = new BackWPup_Page_Backups();
564
+ $output->items = array();
565
+
566
+ $jobids = BackWPup_Option::get_job_ids();
567
+
568
+ if ( ! empty( $jobids ) ) {
569
+ foreach ( $jobids as $jobid ) {
570
+ if ( BackWPup_Option::get( $jobid, 'backuptype' ) == 'sync' ) {
571
+ continue;
572
+ }
573
+
574
+ $dests = BackWPup_Option::get( $jobid, 'destinations' );
575
+ foreach ( $dests as $dest ) {
576
+ $dest_class = BackWPup::get_destination( $dest );
577
+ if ( is_null($dest_class) ) {
578
+ continue;
579
+ }
580
+ $items = $dest_class->file_get_list( $jobid . '_' . $dest );
581
+ if ( ! empty( $items ) ) {
582
+ foreach ( $items as $item ) {
583
+ $temp_single_item = $item;
584
+ $temp_single_item['dest'] = $jobid . '_' . $dest;
585
+ $output->items[] = $temp_single_item;
586
+ }
587
+ }
588
+ }
589
+ }
590
+ }
591
+
592
+ break;
593
+
594
+ case 'jobs':
595
+ $output = new BackWPup_Page_Jobs();
596
+ $output->prepare_items();
597
+ break;
598
+ }
599
+
600
+ if ( is_array( $output->items ) ) {
601
+ if ( $type == 'jobs' ) {
602
+ foreach ( $output->items as $key => $val ) {
603
+ $temp_array = array();
604
+ $temp_array['id'] = $val;
605
+ $temp_array['name'] = BackWPup_Option::get( $val, 'name' );
606
+ $temp_array['type'] = BackWPup_Option::get( $val, 'type' );
607
+ $temp_array['destinations'] = BackWPup_Option::get( $val, 'destinations' );
608
+
609
+ if ( $this->is_backwpup_pro ) {
610
+ $temp_array['export'] = str_replace( '&amp;', '&', wp_nonce_url( network_admin_url( 'admin.php' ) . '?page=backwpupjobs&action=export&jobs[]=' . $val, 'bulk-jobs' ) );
611
+ }
612
+
613
+ if ( BackWPup_Option::get( $val, 'activetype' ) == 'wpcron' ) {
614
+ if ( $nextrun = wp_next_scheduled( 'backwpup_cron', array( 'id' => $val ) ) + ( get_option( 'gmt_offset' ) * 3600 ) ) {
615
+ $temp_array['nextrun'] = sprintf( __( '%1$s at %2$s by WP-Cron', 'backwpup' ), date_i18n( get_option( 'date_format' ), $nextrun, true ), date_i18n( get_option( 'time_format' ), $nextrun, true ) );
616
+ } else {
617
+ $temp_array['nextrun'] = __( 'Not scheduled!', 'backwpup' );
618
+ }
619
+ } else {
620
+ $temp_array['nextrun'] = __( 'Inactive', 'backwpup' );
621
+ }
622
+
623
+ if ( BackWPup_Option::get( $val, 'lastrun' ) ) {
624
+ $lastrun = BackWPup_Option::get( $val, 'lastrun' );
625
+ $temp_array['lastrun'] = sprintf( __( '%1$s at %2$s', 'backwpup' ), date_i18n( get_option( 'date_format' ), $lastrun, true ), date_i18n( get_option( 'time_format' ), $lastrun, true ) );
626
+ if ( BackWPup_Option::get( $val, 'lastruntime' ) ) {
627
+ $temp_array['lastrun'] .= ' ' . sprintf( __( 'Runtime: %d seconds', 'backwpup' ), BackWPup_Option::get( $val, 'lastruntime' ) );
628
+ }
629
+ } else {
630
+ $temp_array['lastrun'] = __( 'not yet', 'backwpup' );
631
+ }
632
+
633
+ $temp_array['website_id'] = $website_id;
634
+ $array[] = $temp_array;
635
+ }
636
+ } else if ( $type == 'backups' ) {
637
+ $without_dupes = array();
638
+ foreach ( $output->items as $key ) {
639
+ $temp_array = $key;
640
+ $temp_array['downloadurl'] = str_replace( array(
641
+ '&amp;',
642
+ network_admin_url( 'admin.php' ) . '?page=backwpupbackups&action=',
643
+ ), array(
644
+ '&',
645
+ admin_url( 'admin-ajax.php' ) . '?action=mainwp_backwpup_download_backup&type=',
646
+ ), $temp_array['downloadurl'] . '&_wpnonce=' . $this->create_nonce_without_session( 'mainwp_download_backup' ) );
647
+ $temp_array['website_id'] = $website_id;
648
+
649
+ if ( ! isset( $without_dupes[ $temp_array['file'] ] ) ) {
650
+ $array[] = $temp_array;
651
+ $without_dupes[ $temp_array['file'] ] = 1;
652
+ }
653
+ }
654
+ } else {
655
+ foreach ( $output->items as $key => $val ) {
656
+ $array[] = $val;
657
+ }
658
+ }
659
+ }
660
+
661
+ return array( 'success' => 1, 'response' => $array );
662
+ }
663
+
664
+ public function download_backup() {
665
+ if ( ! isset( $_GET['type'] ) || empty( $_GET['type'] ) || ! isset( $_GET['_wpnonce'] ) || empty( $_GET['_wpnonce'] ) ) {
666
+ die( '-1' );
667
+ }
668
+
669
+ if ( ! current_user_can( 'backwpup_backups_download' ) ) {
670
+ die( '-2' );
671
+ }
672
+
673
+ if ( ! $this->verify_nonce_without_session( $_GET['_wpnonce'], 'mainwp_download_backup' ) ) {
674
+ die( '-3' );
675
+ }
676
+
677
+ $dest = strtoupper( str_replace( 'download', '', $_GET['type'] ) );
678
+ if ( ! empty( $dest ) && strstr( $_GET['type'], 'download' ) ) {
679
+ $dest_class = BackWPup::get_destination( $dest );
680
+ if ( is_null( $dest_class ) ) {
681
+ die( '-4' );
682
+ }
683
+
684
+ $dest_class->file_download( (int) $_GET['jobid'], $_GET['file'] );
685
+ } else {
686
+ die( '-5' );
687
+ }
688
+
689
+ die();
690
+ }
691
+
692
+ protected function create_nonce_without_session( $action = - 1 ) {
693
+ $user = wp_get_current_user();
694
+ $uid = (int) $user->ID;
695
+ if ( ! $uid ) {
696
+ $uid = apply_filters( 'nonce_user_logged_out', $uid, $action );
697
+ }
698
+
699
+ $i = wp_nonce_tick();
700
+
701
+ return substr( wp_hash( $i . '|' . $action . '|' . $uid, 'nonce' ), - 12, 10 );
702
+ }
703
+
704
+ protected function verify_nonce_without_session( $nonce, $action = - 1 ) {
705
+ $nonce = (string) $nonce;
706
+ $user = wp_get_current_user();
707
+ $uid = (int) $user->ID;
708
+ if ( ! $uid ) {
709
+ $uid = apply_filters( 'nonce_user_logged_out', $uid, $action );
710
+ }
711
+
712
+ if ( empty( $nonce ) ) {
713
+ return false;
714
+ }
715
+
716
+ $i = wp_nonce_tick();
717
+
718
+ $expected = substr( wp_hash( $i . '|' . $action . '|' . $uid, 'nonce' ), - 12, 10 );
719
+ if ( hash_equals( $expected, $nonce ) ) {
720
+ return 1;
721
+ }
722
+
723
+ $expected = substr( wp_hash( ( $i - 1 ) . '|' . $action . '|' . $uid, 'nonce' ), - 12, 10 );
724
+ if ( hash_equals( $expected, $nonce ) ) {
725
+ return 2;
726
+ }
727
+
728
+ return false;
729
+ }
730
+
731
+ protected function ajax_working() {
732
+
733
+ if ( ! isset( $_POST['settings'] ) || ! is_array( $_POST['settings'] ) || ! isset( $_POST['settings']['logfile'] ) || ! isset( $_POST['settings']['logpos'] ) ) {
734
+ return array( 'error' => __( 'Missing logfile or logpos.', $this->plugin_translate ) );
735
+ }
736
+
737
+ $_GET['logfile'] = $_POST['settings']['logfile'];
738
+ $_GET['logpos'] = $_POST['settings']['logpos'];
739
+ $_REQUEST['_wpnonce'] = wp_create_nonce( 'backwpupworking_ajax_nonce' );
740
+
741
+ $this->wp_list_table_dependency();
742
+
743
+ function mainwp_backwpup_wp_die_ajax_handler( $message ) {
744
+ return 'mainwp_backwpup_wp_die_ajax_handler';
745
+ }
746
+
747
+ // We do this in order to not die when using wp_die
748
+ if ( ! defined( 'DOING_AJAX' ) ) {
749
+ define( 'DOING_AJAX', true );
750
+ }
751
+
752
+ add_filter( 'wp_die_ajax_handler', 'mainwp_backwpup_wp_die_ajax_handler' );
753
+ remove_filter( 'wp_die_ajax_handler', '_ajax_wp_die_handler' );
754
+
755
+ ob_start();
756
+ BackWPup_Page_Jobs::ajax_working();
757
+
758
+ $output = ob_get_contents();
759
+
760
+ ob_end_clean();
761
+
762
+ return array( 'success' => 1, 'response' => $output );
763
+ }
764
+
765
+ protected function backup_now() {
766
+
767
+ if ( ! isset( $_POST['settings']['job_id'] ) ) {
768
+ return array( 'error' => __( 'Missing job_id', $this->plugin_translate ) );
769
+ }
770
+
771
+ // Simulate http://wp/wp-admin/admin.php?jobid=1&page=backwpupjobs&action=runnow
772
+ $_GET['jobid'] = $_POST['settings']['job_id'];
773
+
774
+ $_REQUEST['action'] = 'runnow';
775
+ $_REQUEST['_wpnonce'] = wp_create_nonce( 'backwpup_job_run-runnowlink' );
776
+
777
+ update_site_option( 'backwpup_messages', array() );
778
+
779
+ $this->wp_list_table_dependency();
780
+
781
+ ob_start();
782
+ BackWPup_Page_Jobs::load();
783
+ ob_end_clean();
784
+
785
+ $output = $this->check_backwpup_messages();
786
+
787
+ if ( isset( $output['error'] ) ) {
788
+ return array( 'error' => 'BackWPup_Page_Jobs::load fail: ' . $output['error'] );
789
+ } else {
790
+ $job_object = BackWPup_Job::get_working_data();
791
+ if ( is_object( $job_object ) ) {
792
+ return array(
793
+ 'success' => 1,
794
+ 'response' => $output['message'],
795
+ 'logfile' => basename( $job_object->logfile ),
796
+ );
797
+ } else {
798
+ return array( 'success' => 1, 'response' => $output['message'] );
799
+ }
800
+ }
801
+ }
802
+
803
+ protected function backup_abort() {
804
+ $_REQUEST['action'] = 'abort';
805
+ $_REQUEST['_wpnonce'] = wp_create_nonce( 'abort-job' );
806
+
807
+ update_site_option( 'backwpup_messages', array() );
808
+
809
+ $this->wp_list_table_dependency();
810
+
811
+ ob_start();
812
+ BackWPup_Page_Jobs::load();
813
+ ob_end_clean();
814
+
815
+ $output = $this->check_backwpup_messages();
816
+
817
+ if ( isset( $output['error'] ) ) {
818
+ return array( 'error' => 'Cannot abort: ' . $output['error'] );
819
+ } else {
820
+ return array( 'success' => 1, 'response' => $output['message'] );
821
+ }
822
+ }
823
+
824
+ protected function wp_list_table_dependency() {
825
+ if ( ! function_exists( 'convert_to_screen' ) ) {
826
+ // We need this because BackWPup_Page_Jobs extends WP_List_Table which uses convert_to_screen
827
+ function convert_to_screen( $hook_name ) {
828
+ return new MainWP_Fake_Wp_Screen();
829
+ }
830
+ }
831
+
832
+ if ( ! function_exists( 'add_screen_option' ) ) {
833
+ function add_screen_option( $option, $args = array() ) {
834
+
835
+ }
836
+ }
837
+
838
+ if ( ! class_exists( 'WP_List_Table' ) ) {
839
+ require_once( ABSPATH . 'wp-admin/includes/class-wp-list-table.php' );
840
+ }
841
+ }
842
+
843
+ protected function wizard_system_scan() {
844
+ if ( class_exists( 'BackWPup_Pro_Wizard_SystemTest' ) ) {
845
+ ob_start();
846
+
847
+ $system_test = new BackWPup_Pro_Wizard_SystemTest();
848
+ $system_test->execute( null );
849
+
850
+ $output = ob_get_contents();
851
+
852
+ ob_end_clean();
853
+
854
+ return array( 'success' => 1, 'response' => $output );
855
+ } else {
856
+ return array( 'error' => 'Missing BackWPup_Pro_Wizard_SystemTest' );
857
+ }
858
+ }
859
+
860
+ protected function destination_email_check_email() {
861
+ $settings = $_POST['settings'];
862
+
863
+ $message = '';
864
+
865
+ $emailmethod = ( isset( $settings['emailmethod'] ) ? $settings['emailmethod'] : '' );
866
+ $emailsendmail = ( isset( $settings['emailsendmail'] ) ? $settings['emailsendmail'] : '' );
867
+ $emailhost = ( isset( $settings['emailhost'] ) ? $settings['emailhost'] : '' );
868
+ $emailhostport = ( isset( $settings['emailhostport'] ) ? $settings['emailhostport'] : '' );
869
+ $emailsecure = ( isset( $settings['emailsecure'] ) ? $settings['emailsecure'] : '' );
870
+ $emailuser = ( isset( $settings['emailuser'] ) ? $settings['emailuser'] : '' );
871
+ $emailpass = ( isset( $settings['emailpass'] ) ? $settings['emailpass'] : '' );
872
+
873
+ if ( ! isset( $settings['emailaddress'] ) || strlen( $settings['emailaddress'] ) < 2 ) {
874
+ $message = __( 'Missing email address.', 'backwpup' );
875
+ } else {
876
+
877
+ // From BackWPup_Destination_Email::edit_ajax
878
+ if ( $emailmethod ) {
879
+ //do so if i'm the wp_mail to get the settings
880
+ global $phpmailer;
881
+ // (Re)create it, if it's gone missing
882
+ if ( ! is_object( $phpmailer ) || ! $phpmailer instanceof PHPMailer ) {
883
+ require_once ABSPATH . WPINC . '/class-phpmailer.php';
884
+ require_once ABSPATH . WPINC . '/class-smtp.php';
885
+ $phpmailer = new PHPMailer( true );
886
+ }
887
+ //only if PHPMailer really used
888
+ if ( is_object( $phpmailer ) ) {
889
+ do_action_ref_array( 'phpmailer_init', array( &$phpmailer ) );
890
+ //get settings from PHPMailer
891
+ $emailmethod = $phpmailer->Mailer;
892
+ $emailsendmail = $phpmailer->Sendmail;
893
+ $emailhost = $phpmailer->Host;
894
+ $emailhostport = $phpmailer->Port;
895
+ $emailsecure = $phpmailer->SMTPSecure;
896
+ $emailuser = $phpmailer->Username;
897
+ $emailpass = $phpmailer->Password;
898
+ }
899
+ }
900
+
901
+ //Generate mail with Swift Mailer
902
+ if ( ! class_exists( 'Swift', false ) ) {
903
+ require BackWPup::get_plugin_data( 'plugindir' ) . '/vendor/SwiftMailer/swift_required.php';
904
+ }
905
+
906
+ if ( function_exists( 'mb_internal_encoding' ) && ( (int) ini_get( 'mbstring.func_overload' ) ) & 2 ) {
907
+ $mbEncoding = mb_internal_encoding();
908
+ mb_internal_encoding( 'ASCII' );
909
+ }
910
+
911
+ try {
912
+ // Create the Transport
913
+ if ( $emailmethod == 'smtp' ) {
914
+ $transport = Swift_SmtpTransport::newInstance( $emailhost, $emailhostport );
915
+ $transport->setUsername( $emailuser );
916
+ $transport->setPassword( $emailpass );
917
+ if ( $emailsecure == 'ssl' ) {
918
+ $transport->setEncryption( 'ssl' );
919
+ }
920
+ if ( $emailsecure == 'tls' ) {
921
+ $transport->setEncryption( 'tls' );
922
+ }
923
+ } elseif ( $emailmethod == 'sendmail' ) {
924
+ $transport = Swift_SendmailTransport::newInstance( $emailsendmail );
925
+ } else {
926
+ $transport = Swift_MailTransport::newInstance();
927
+ }
928
+ // Create the Mailer using your created Transport
929
+ $emailer = Swift_Mailer::newInstance( $transport );
930
+
931
+ // Create a message
932
+ $message = Swift_Message::newInstance( __( 'BackWPup archive sending TEST Message', 'backwpup' ) );
933
+ $message->setFrom( array( ( isset( $settings['emailsndemail'] ) ? $settings['emailsndemail'] : 'from@example.com' ) => isset( $settings['emailsndemailname'] ) ? $settings['emailsndemailname'] : '' ) );
934
+ $message->setTo( array( $settings['emailaddress'] ) );
935
+ $message->setBody( __( 'If this message reaches your inbox, sending backup archives via email should work for you.', 'backwpup' ) );
936
+ // Send the message
937
+ $result = $emailer->send( $message );
938
+ } catch ( Exception $e ) {
939
+ $message = 'Swift Mailer: ' . $e->getMessage();
940
+ }
941
+
942
+ if ( isset( $mbEncoding ) ) {
943
+ mb_internal_encoding( $mbEncoding );
944
+ }
945
+
946
+ if ( ! isset( $result ) || ! $result ) {
947
+ $message = __( 'Error while sending email!', 'backwpup' );
948
+ } else {
949
+ $message = __( 'Email sent.', 'backwpup' );
950
+ }
951
+ }
952
+
953
+ return array( 'success' => 1, 'message' => $message );
954
+ }
955
+
956
+ protected function get_job_files() {
957
+ // From BackWPup_JobType_File::get_exclude_dirs
958
+ function mainwp_backwpup_get_exclude_dirs( $folder ) {
959
+ $folder = trailingslashit( str_replace( '\\', '/', realpath( $folder ) ) );
960
+ $exclude_dir_array = array();
961
+
962
+ if ( false !== strpos( trailingslashit( str_replace( '\\', '/', realpath( ABSPATH ) ) ), $folder ) && trailingslashit( str_replace( '\\', '/', realpath( ABSPATH ) ) ) != $folder ) {
963
+ $exclude_dir_array[] = trailingslashit( str_replace( '\\', '/', realpath( ABSPATH ) ) );
964
+ }
965
+ if ( false !== strpos( trailingslashit( str_replace( '\\', '/', realpath( WP_CONTENT_DIR ) ) ), $folder ) && trailingslashit( str_replace( '\\', '/', realpath( WP_CONTENT_DIR ) ) ) != $folder ) {
966
+ $exclude_dir_array[] = trailingslashit( str_replace( '\\', '/', realpath( WP_CONTENT_DIR ) ) );
967
+ }
968
+ if ( false !== strpos( trailingslashit( str_replace( '\\', '/', realpath( WP_PLUGIN_DIR ) ) ), $folder ) && trailingslashit( str_replace( '\\', '/', realpath( WP_PLUGIN_DIR ) ) ) != $folder ) {
969
+ $exclude_dir_array[] = trailingslashit( str_replace( '\\', '/', realpath( WP_PLUGIN_DIR ) ) );
970
+ }
971
+ if ( false !== strpos( trailingslashit( str_replace( '\\', '/', realpath( get_theme_root() ) ) ), $folder ) && trailingslashit( str_replace( '\\', '/', realpath( get_theme_root() ) ) ) != $folder ) {
972
+ $exclude_dir_array[] = trailingslashit( str_replace( '\\', '/', realpath( get_theme_root() ) ) );
973
+ }
974
+ if ( false !== strpos( trailingslashit( str_replace( '\\', '/', realpath( BackWPup_File::get_upload_dir() ) ) ), $folder ) && trailingslashit( str_replace( '\\', '/', realpath( BackWPup_File::get_upload_dir() ) ) ) != $folder ) {
975
+ $exclude_dir_array[] = trailingslashit( str_replace( '\\', '/', realpath( BackWPup_File::get_upload_dir() ) ) );
976
+ }
977
+
978
+ return array_unique( $exclude_dir_array );
979
+ }
980
+
981
+ $return = array();
982
+
983
+ $folders = array(
984
+ 'abs' => ABSPATH,
985
+ 'content' => WP_CONTENT_DIR,
986
+ 'plugin' => WP_PLUGIN_DIR,
987
+ 'theme' => get_theme_root(),
988
+ 'upload' => BackWPup_File::get_upload_dir(),
989
+ );
990
+
991
+ foreach ( $folders as $key => $folder ) {
992
+ $return_temp = array();
993
+ $main_folder_name = realpath( $folder );
994
+
995
+ if ( $main_folder_name ) {
996
+ $main_folder_name = untrailingslashit( str_replace( '\\', '/', $main_folder_name ) );
997
+ $main_folder_size = '(' . size_format( BackWPup_File::get_folder_size( $main_folder_name, false ), 2 ) . ')';
998
+
999
+ if ( $dir = @opendir( $main_folder_name ) ) {
1000
+ while ( ( $file = readdir( $dir ) ) !== false ) {
1001
+ if ( ! in_array( $file, array(
1002
+ '.',
1003
+ '..',
1004
+ ) ) && is_dir( $main_folder_name . '/' . $file ) && ! in_array( trailingslashit( $main_folder_name . '/' . $file ), mainwp_backwpup_get_exclude_dirs( $main_folder_name ) )
1005
+ ) {
1006
+ $folder_size = ' (' . size_format( BackWPup_File::get_folder_size( $main_folder_name . '/' . $file ), 2 ) . ')';
1007
+
1008
+ $return_temp[] = array(
1009
+ 'size' => $folder_size,
1010
+ 'name' => $file,
1011
+ );
1012
+
1013
+ }
1014
+ }
1015
+
1016
+ @closedir( $dir );
1017
+ }
1018
+
1019
+ $return[ $key ] = array( 'size' => $main_folder_size, 'name' => $folder, 'folders' => $return_temp );
1020
+ }
1021
+ }
1022
+
1023
+ return array( 'success' => 1, 'folders' => $return );
1024
+ }
1025
+
1026
+ protected function get_child_tables() {
1027
+ global $wpdb;
1028
+
1029
+ $return = array();
1030
+
1031
+ $settings = $_POST['settings'];
1032
+
1033
+ if ( ! empty( $settings['dbhost'] ) && ! empty( $settings['dbuser'] ) ) {
1034
+ $mysqli = @new mysqli( $settings['dbhost'], $settings['dbuser'], ( isset( $settings['dbpassword'] ) ? $settings['dbpassword'] : '' ) );
1035
+
1036
+ if ( $mysqli->connect_error ) {
1037
+ $return['message'] = $mysqli->connect_error;
1038
+ } else {
1039
+ if ( ! empty( $settings['dbname'] ) ) {
1040
+ if ( $res = $mysqli->query( 'SHOW FULL TABLES FROM `' . $mysqli->real_escape_string( $settings['dbname'] ) . '`' ) ) {
1041
+ $tables_temp = array();
1042
+ while ( $table = $res->fetch_array( MYSQLI_NUM ) ) {
1043
+ $tables_temp[] = $table[0];
1044
+ }
1045
+
1046
+ $res->close();
1047
+ $return['tables'] = $tables_temp;
1048
+ }
1049
+ }
1050
+
1051
+ if ( empty( $settings['dbname'] ) || ! empty( $settings['first'] ) ) {
1052
+ if ( $res = $mysqli->query( 'SHOW DATABASES' ) ) {
1053
+ $databases_temp = array();
1054
+ while ( $db = $res->fetch_array() ) {
1055
+ $databases_temp[] = $db['Database'];
1056
+ }
1057
+
1058
+ $res->close();
1059
+ $return['databases'] = $databases_temp;
1060
+ }
1061
+ }
1062
+ }
1063
+ $mysqli->close();
1064
+ } else {
1065
+ $tables_temp = array();
1066
+
1067
+ $tables = $wpdb->get_results( 'SHOW FULL TABLES FROM `' . DB_NAME . '`', ARRAY_N );
1068
+ foreach ( $tables as $table ) {
1069
+ $tables_temp[] = $table[0];
1070
+ }
1071
+
1072
+ $return['tables'] = $tables_temp;
1073
+ }
1074
+
1075
+ if (isset($settings['job_id'])) {
1076
+ $return['dbdumpexclude'] = BackWPup_Option::get( $settings['job_id'], 'dbdumpexclude' );
1077
+ }
1078
+ return array( 'success' => 1, 'return' => $return );
1079
+ }
1080
+
1081
+ protected function insert_or_update_jobs_global() {
1082
+ $settings = $_POST['settings'];
1083
+
1084
+ if ( ! is_array( $settings ) ) {
1085
+ return array( 'error' => __( 'Missing array settings', $this->plugin_translate ) );
1086
+ }
1087
+
1088
+ if ( ! isset( $settings['job_id'] ) ) {
1089
+ return array( 'error' => __( 'Missing job_id', $this->plugin_translate ) );
1090
+ }
1091
+
1092
+ if ( $settings['job_id'] > 0 ) {
1093
+ $new_job_id = intval( $settings['job_id'] );
1094
+ } else {
1095
+ $new_job_id = null;
1096
+ }
1097
+
1098
+ $changes_array = array();
1099
+ $message_array = array();
1100
+
1101
+ foreach ( $settings['value'] as $key => $val ) {
1102
+ $temp_array = array();
1103
+ $temp_array['tab'] = $key;
1104
+ $temp_array['value'] = $val;
1105
+ if ( ! is_null( $new_job_id ) ) {
1106
+ $temp_array['job_id'] = $new_job_id;
1107
+ } else {
1108
+ $temp_array['job_id'] = $settings['job_id'];
1109
+ }
1110
+
1111
+ $_POST['settings'] = $temp_array;
1112
+ $return = $this->insert_or_update_jobs();
1113
+
1114
+ if ( is_null( $new_job_id ) ) {
1115
+ if ( ! isset( $return['job_id'] ) ) {
1116
+ return array( 'error' => __( 'Missing new job_id', $this->plugin_translate ) );
1117
+ }
1118
+
1119
+ $new_job_id = $return['job_id'];
1120
+ }
1121
+
1122
+ // We want to exit gracefully
1123
+ if ( isset( $return['error_message'] ) ) {
1124
+ $message_array[ $return['error_message'] ] = 1;
1125
+ }
1126
+
1127
+ if ( isset( $return['changes'] ) ) {
1128
+ $changes_array = array_merge( $changes_array, $return['changes'] );
1129
+ }
1130
+
1131
+ if ( isset( $return['message'] ) ) {
1132
+ // Some kind of array_unique
1133
+ foreach ( $return['message'] as $message ) {
1134
+ if ( ! isset( $message_array[ $message ] ) ) {
1135
+ $message_array[ $message ] = 1;
1136
+ }
1137
+ }
1138
+ }
1139
+ }
1140
+
1141
+ return array(
1142
+ 'success' => 1,
1143
+ 'job_id' => $new_job_id,
1144
+ 'changes' => $changes_array,
1145
+ 'message' => array_keys( $message_array ),
1146
+ );
1147
+ }
1148
+
1149
+ // From BackWPup_JobType_File::edit_form_post_save with some tweaks
1150
+ public function edit_form_post_save( $post_data, $id ) {
1151
+ // Parse and save files to exclude
1152
+ $exclude_input = $post_data['fileexclude'];
1153
+ $to_exclude_list = $exclude_input ? str_replace( array( "\r\n", "\r" ), ',', $exclude_input ) : array();
1154
+ $to_exclude_list and $to_exclude_list = sanitize_text_field( stripslashes( $to_exclude_list ) );
1155
+ $to_exclude = $to_exclude_list ? explode( ',', $to_exclude_list ) : array();
1156
+ $to_exclude_parsed = array();
1157
+ foreach ( $to_exclude as $key => $value ) {
1158
+ $normalized = wp_normalize_path( trim( $value ) );
1159
+ $normalized and $to_exclude_parsed[$key] = $normalized;
1160
+ }
1161
+ sort( $to_exclude_parsed );
1162
+ BackWPup_Option::update( $id, 'fileexclude', implode( ',', $to_exclude_parsed ) );
1163
+ unset( $exclude_input, $to_exclude_list, $to_exclude, $to_exclude_parsed, $normalized );
1164
+
1165
+ // Parse and save folders to include
1166
+ $include_input = $post_data['dirinclude'];
1167
+ $include_list = $include_input ? str_replace( array( "\r\n", "\r" ), ',', $include_input ) : array();
1168
+ $to_include = $include_list ? explode( ',', $include_list ) : array();
1169
+ $to_include_parsed = array();
1170
+ foreach ( $to_include as $key => $value ) {
1171
+ $normalized = trailingslashit( wp_normalize_path( trim( $value ) ) );
1172
+ $normalized and $normalized = filter_var( $normalized, FILTER_SANITIZE_URL );
1173
+ $realpath = $normalized && $normalized !== '/' ? realpath( $normalized ) : false;
1174
+ $realpath and $to_include_parsed[$key] = $realpath;
1175
+ }
1176
+ sort( $to_include_parsed );
1177
+ BackWPup_Option::update( $id, 'dirinclude', implode( ',', $to_include_parsed ) );
1178
+ unset( $include_input, $include_list, $to_include, $to_include_parsed, $normalized, $realpath );
1179
+
1180
+ // Parse and save boolean fields
1181
+ $boolean_fields_def = array(
1182
+ 'backupexcludethumbs' => FILTER_VALIDATE_BOOLEAN,
1183
+ 'backupspecialfiles' => FILTER_VALIDATE_BOOLEAN,
1184
+ 'backuproot' => FILTER_VALIDATE_BOOLEAN,
1185
+ 'backupabsfolderup' => FILTER_VALIDATE_BOOLEAN,
1186
+ 'backupcontent' => FILTER_VALIDATE_BOOLEAN,
1187
+ 'backupplugins' => FILTER_VALIDATE_BOOLEAN,
1188
+ 'backupthemes' => FILTER_VALIDATE_BOOLEAN,
1189
+ 'backupuploads' => FILTER_VALIDATE_BOOLEAN,
1190
+ );
1191
+
1192
+ foreach( $boolean_fields_def as $key => $value ) {
1193
+ BackWPup_Option::update( $id, $key, ! empty( $post_data[$key] ) );
1194
+ }
1195
+ // Parse and save directories to exclude
1196
+ $exclude_dirs_def = array(
1197
+ 'backuprootexcludedirs' => array( 'filter' => FILTER_SANITIZE_URL, 'flags' => FILTER_FORCE_ARRAY ),
1198
+ 'backuppluginsexcludedirs' => array( 'filter' => FILTER_SANITIZE_URL, 'flags' => FILTER_FORCE_ARRAY ),
1199
+ 'backupcontentexcludedirs' => array( 'filter' => FILTER_SANITIZE_URL, 'flags' => FILTER_FORCE_ARRAY ),
1200
+ 'backupthemesexcludedirs' => array( 'filter' => FILTER_SANITIZE_URL, 'flags' => FILTER_FORCE_ARRAY ),
1201
+ 'backupuploadsexcludedirs' => array( 'filter' => FILTER_SANITIZE_URL, 'flags' => FILTER_FORCE_ARRAY ),
1202
+ );
1203
+ foreach( $exclude_dirs_def as $key => $filter ) {
1204
+ $value = ! empty( $post_data[$key] ) && is_array( $post_data[$key] ) ? $post_data[$key] : array();
1205
+ BackWPup_Option::update( $id, $key, $value );
1206
+ }
1207
+ }
1208
+
1209
+ protected function insert_or_update_jobs() {
1210
+
1211
+ $settings = $_POST['settings'];
1212
+
1213
+ if ( ! is_array( $settings ) || ! isset( $settings['value'] ) ) {
1214
+ return array( 'error' => __( 'Missing array settings', $this->plugin_translate ) );
1215
+ }
1216
+
1217
+ if ( ! isset( $settings['tab'] ) ) {
1218
+ return array( 'error' => __( 'Missing tab', $this->plugin_translate ) );
1219
+ }
1220
+
1221
+ if ( ! isset( $settings['job_id'] ) ) {
1222
+ return array( 'error' => __( 'Missing job_id', $this->plugin_translate ) );
1223
+ }
1224
+
1225
+ if ( ! class_exists( 'BackWPup' ) ) {
1226
+ return array( 'error' => __( 'Install BackWPup on child website', $this->plugin_translate ) );
1227
+ }
1228
+
1229
+ if ( $settings['job_id'] > 0 ) {
1230
+ $job_id = intval( $settings['job_id'] );
1231
+ } else {
1232
+ //generate jobid if not exists
1233
+ $newjobid = BackWPup_Option::get_job_ids();
1234
+ sort( $newjobid );
1235
+ $job_id = end( $newjobid ) + 1;
1236
+ }
1237
+
1238
+ update_site_option( 'backwpup_messages', array() );
1239
+
1240
+ if (isset($settings['value']['backupdir']) && empty($settings['value']['backupdir'])) {
1241
+ $backupdir = BackWPup_Option::get( (int)$job_id, 'backupdir' );
1242
+ if (!empty($backupdir)) {
1243
+ $settings['value']['backupdir'] = $backupdir;
1244
+ }
1245
+ }
1246
+
1247
+ foreach ( $settings['value'] as $key => $val ) {
1248
+ $_POST[ $key ] = $val;
1249
+ }
1250
+
1251
+ if ($settings['tab'] == 'jobtype-FILE') {
1252
+ // to fix
1253
+ $this->edit_form_post_save($settings['value'], $job_id);
1254
+ //saved message
1255
+ $messages = BackWPup_Admin::get_messages();
1256
+ if ( empty( $messages['error'] ) ) {
1257
+ $url = BackWPup_Job::get_jobrun_url( 'runnowlink', $job_id );
1258
+ BackWPup_Admin::message( sprintf( __( 'Changes for job <i>%s</i> saved.', 'backwpup' ), BackWPup_Option::get( $job_id, 'name' ) ) . ' <a href="' . network_admin_url( 'admin.php' ) . '?page=backwpupjobs">' . __( 'Jobs overview', 'backwpup' ) . '</a> | <a href="' . $url['url'] . '">' . __( 'Run now', 'backwpup' ) . '</a>' );
1259
+ }
1260
+ } else if ($settings['tab'] == 'dest-DROPBOX') {
1261
+ unset($settings['value']); // do not save dropbox settings
1262
+ BackWPup_Page_Editjob::save_post_form( $settings['tab'], $job_id );
1263
+ } else {
1264
+ BackWPup_Page_Editjob::save_post_form( $settings['tab'], $job_id );
1265
+ }
1266
+
1267
+ $return = $this->check_backwpup_messages();
1268
+
1269
+ if ( isset( $return['error'] ) ) {
1270
+ return array(
1271
+ 'success' => 1,
1272
+ 'error_message' => __( 'Cannot save jobs: ' . $return['error'], $this->plugin_translate ),
1273
+ );
1274
+ }
1275
+
1276
+ if ( isset( $settings['value']['sugarrefreshtoken'] ) ) {
1277
+ BackWPup_Option::update( $job_id, 'sugarrefreshtoken', $settings['value']['sugarrefreshtoken'] );
1278
+ }
1279
+
1280
+ if ( isset( $settings['value']['gdriverefreshtoken'] ) ) {
1281
+ BackWPup_Option::update( $job_id, 'gdriverefreshtoken', $settings['value']['gdriverefreshtoken'] );
1282
+ }
1283
+
1284
+ if ( isset( $settings['value']['dbdumpspecialsetalltables'] ) && $settings['value']['dbdumpspecialsetalltables'] ) {
1285
+ BackWPup_Option::update( $job_id, 'dbdumpexclude', array() );
1286
+ }
1287
+
1288
+ if ( isset( $settings['value']['dropboxtoken'] ) && isset( $settings['value']['dropboxroot'] ) ) {
1289
+ BackWPup_Option::update( $job_id, 'dropboxtoken', $settings['value']['dropboxtoken'] );
1290
+ BackWPup_Option::update( $job_id, 'dropboxroot', $settings['value']['dropboxroot'] );
1291
+ }
1292
+
1293
+ $changes_array = array();
1294
+
1295
+ foreach ( $settings['value'] as $key => $val ) {
1296
+ $temp_value = BackWPup_Option::get( $job_id, $key );
1297
+ if ( is_string( $temp_value ) ) {
1298
+ if ( isset( $this->exclusions[ $settings['tab'] ] ) ) {
1299
+ if ( ! in_array( $key, $this->exclusions[ $settings['tab'] ] ) && strcmp( $temp_value, $val ) != 0 ) {
1300
+ $changes_array[ $key ] = $temp_value;
1301
+ }
1302
+ } else if ( strcmp( $temp_value, $val ) != 0 ) {
1303
+ $changes_array[ $key ] = $temp_value;
1304
+ }
1305
+ }
1306
+ }
1307
+
1308
+ return array(
1309
+ 'success' => 1,
1310
+ 'job_id' => $job_id,
1311
+ 'changes' => $changes_array,
1312
+ 'message' => $return['message'],
1313
+ );
1314
+ }
1315
+
1316
+
1317
+ protected function update_settings() {
1318
+ $settings = $_POST['settings'];
1319
+
1320
+ if ( ! is_array( $settings ) || ! isset( $settings['value'] ) ) {
1321
+ return array( 'error' => __( 'Missing array settings', $this->plugin_translate ) );
1322
+ }
1323
+
1324
+ if ( ! class_exists( 'BackWPup' ) ) {
1325
+ return array( 'error' => __( 'Install BackWPup on child website', $this->plugin_translate ) );
1326
+ }
1327
+
1328
+ if ( isset( $settings['value']['is_premium'] ) && $settings['value']['is_premium'] == 1 && $this->is_backwpup_pro == false ) {
1329
+ return array( 'error' => __( 'You try to use pro version settings in non pro plugin version. Please install pro version on child and try again.', $this->plugin_translate ) );
1330
+ }
1331
+
1332
+ foreach ( $settings['value'] as $key => $val ) {
1333
+ $_POST[ $key ] = $val;
1334
+ }
1335
+
1336
+ update_site_option( 'backwpup_messages', array() );
1337
+
1338
+ $backwpup = new BackWPup_Page_Settings();
1339
+ $backwpup->save_post_form();
1340
+
1341
+ if ( class_exists( 'BackWPup_Pro' ) ) {
1342
+ $pro_settings = BackWPup_Pro_Settings_APIKeys::get_instance();
1343
+ $pro_settings->save_form();
1344
+
1345
+ }
1346
+ $return = $this->check_backwpup_messages();
1347
+
1348
+ if ( isset( $return['error'] ) ) {
1349
+ return array( 'error' => __( 'Cannot save settings: ' . $return['error'], $this->plugin_translate ) );
1350
+ }
1351
+
1352
+ $exclusions = array(
1353
+ 'is_premium',
1354
+ 'dropboxappsecret',
1355
+ 'dropboxsandboxappsecret',
1356
+ 'sugarsyncsecret',
1357
+ 'googleclientsecret',
1358
+ 'override',
1359
+ 'httpauthpassword',
1360
+ );
1361
+
1362
+ $changes_array = array();
1363
+
1364
+ foreach ( $settings['value'] as $key => $val ) {
1365
+
1366
+ $temp_value = get_site_option( 'backwpup_cfg_' . $key, '' );
1367
+ if ( ! in_array( $key, $exclusions ) && strcmp( $temp_value, $val ) != 0 ) {
1368
+ $changes_array[ $key ] = $temp_value;
1369
+ }
1370
+ }
1371
+
1372
+ return array( 'success' => 1, 'changes' => $changes_array, 'message' => $return['message'] );
1373
+ }
1374
+
1375
+ protected function check_backwpup_messages() {
1376
+ $message = get_site_option( 'backwpup_messages', array() );
1377
+ update_site_option( 'backwpup_messages', array() );
1378
+
1379
+ if ( isset( $message['error'] ) ) {
1380
+ return array( 'error' => implode( ', ', $message['error'] ) );
1381
+ } else if ( isset( $message['updated'] ) ) {
1382
+ return array( 'message' => $message['updated'] );
1383
+ } else {
1384
+ return array( 'error' => 'Generic error' );
1385
+ }
1386
+
1387
+ }
1388
+ }
1389
+
1390
+ if ( ! class_exists( 'MainWP_Fake_Wp_Screen' ) ) {
1391
+ class MainWP_Fake_Wp_Screen {
1392
+ public $action;
1393
+ public $base;
1394
+ public $id;
1395
+ }
1396
+ }
class/class-mainwp-child-branding.php ADDED
@@ -0,0 +1,872 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class MainWP_Child_Branding {
4
+ public static $instance = null;
5
+ protected $child_plugin_dir;
6
+ protected $settings = null;
7
+
8
+ static function Instance() {
9
+ if ( null === MainWP_Child_Branding::$instance ) {
10
+ MainWP_Child_Branding::$instance = new MainWP_Child_Branding();
11
+ }
12
+
13
+ return MainWP_Child_Branding::$instance;
14
+ }
15
+
16
+ public function __construct() {
17
+ $this->child_plugin_dir = dirname( dirname( __FILE__ ) );
18
+ add_action( 'mainwp_child_deactivation', array( $this, 'child_deactivation' ) );
19
+ add_filter( 'mainwp_child_plugin_row_meta', array( $this, 'plugin_row_meta' ), 10, 3 );
20
+
21
+ $label = get_option( 'mainwp_branding_button_contact_label' );
22
+ if ( ! empty( $label ) ) {
23
+ $label = stripslashes( $label );
24
+ } else {
25
+ $label = 'Contact Support';
26
+ }
27
+
28
+ $this->settings['contact_support_label'] = $label;
29
+ $this->settings['extra_settings'] = get_option( 'mainwp_branding_extra_settings' );
30
+ }
31
+
32
+
33
+ public function plugin_row_meta( $plugin_meta, $plugin_file, $child_plugin_slug ) {
34
+ if ( $child_plugin_slug !== $plugin_file ) {
35
+ return $plugin_meta;
36
+ }
37
+
38
+ if ( ! self::is_branding() ) {
39
+ return $plugin_meta;
40
+ }
41
+ // hide View details links
42
+ $meta_total = count( $plugin_meta );
43
+ for ( $i = 0; $i < $meta_total; $i++ ) {
44
+ $str_meta = $plugin_meta[ $i ];
45
+ if ( strpos( $str_meta, 'plugin-install.php?tab=plugin-information' ) ) {
46
+ unset( $plugin_meta[ $i ] );
47
+ break;
48
+ }
49
+ }
50
+
51
+ return $plugin_meta;
52
+ }
53
+
54
+ public static function admin_init() {
55
+ }
56
+
57
+ public function child_deactivation() {
58
+ $dell_all = array(
59
+ 'mainwp_branding_disable_change',
60
+ 'mainwp_branding_disable_switching_theme',
61
+ 'mainwp_branding_child_hide',
62
+ 'mainwp_branding_show_support',
63
+ 'mainwp_branding_support_email',
64
+ 'mainwp_branding_support_message',
65
+ 'mainwp_branding_remove_restore',
66
+ 'mainwp_branding_remove_setting',
67
+ 'mainwp_branding_remove_server_info',
68
+ 'mainwp_branding_remove_wp_tools',
69
+ 'mainwp_branding_remove_wp_setting',
70
+ 'mainwp_branding_remove_permalink',
71
+ //'mainwp_branding_plugin_header', // don't remove header
72
+ 'mainwp_branding_button_contact_label',
73
+ 'mainwp_branding_send_email_message',
74
+ 'mainwp_branding_message_return_sender',
75
+ 'mainwp_branding_submit_button_title',
76
+ 'mainwp_branding_extra_settings',
77
+ 'mainwp_branding_ext_enabled',
78
+ );
79
+ foreach ( $dell_all as $opt ) {
80
+ delete_option( $opt );
81
+ }
82
+ }
83
+
84
+
85
+ public function action() {
86
+ $information = array();
87
+ switch ( $_POST['action'] ) {
88
+ case 'update_branding':
89
+ $information = $this->update_branding();
90
+ break;
91
+ }
92
+ MainWP_Helper::write( $information );
93
+ }
94
+
95
+ public function update_branding() {
96
+ $information = array();
97
+ $settings = maybe_unserialize( base64_decode( $_POST['settings'] ) );
98
+ if ( ! is_array( $settings ) ) {
99
+ return $information;
100
+ }
101
+ $current_extra_setting = $this->settings['extra_settings'];
102
+ MainWP_Helper::update_option( 'mainwp_branding_ext_enabled', 'Y', 'yes' );
103
+ $header = array(
104
+ 'name' => $settings['child_plugin_name'],
105
+ 'description' => $settings['child_plugin_desc'],
106
+ 'author' => $settings['child_plugin_author'],
107
+ 'authoruri' => $settings['child_plugin_author_uri'],
108
+ 'pluginuri' => $settings['child_plugin_uri'],
109
+ );
110
+ MainWP_Helper::update_option( 'mainwp_branding_preserve_branding', $settings['child_preserve_branding'], 'yes' );
111
+ MainWP_Helper::update_option( 'mainwp_branding_plugin_header', $header, 'yes' );
112
+ MainWP_Helper::update_option( 'mainwp_branding_support_email', $settings['child_support_email'] );
113
+ MainWP_Helper::update_option( 'mainwp_branding_support_message', $settings['child_support_message'] );
114
+ MainWP_Helper::update_option( 'mainwp_branding_remove_restore', $settings['child_remove_restore'] );
115
+ MainWP_Helper::update_option( 'mainwp_branding_remove_setting', $settings['child_remove_setting'], 'yes' );
116
+ MainWP_Helper::update_option( 'mainwp_branding_remove_server_info', $settings['child_remove_server_info'] );
117
+ MainWP_Helper::update_option( 'mainwp_branding_remove_connection_detail', (isset($settings['child_remove_connection_detail']) ? $settings['child_remove_connection_detail'] : 0) );
118
+ MainWP_Helper::update_option( 'mainwp_branding_remove_wp_tools', $settings['child_remove_wp_tools'], 'yes' );
119
+ MainWP_Helper::update_option( 'mainwp_branding_remove_wp_setting', $settings['child_remove_wp_setting'], 'yes' );
120
+ MainWP_Helper::update_option( 'mainwp_branding_remove_permalink', $settings['child_remove_permalink'], 'yes' );
121
+ MainWP_Helper::update_option( 'mainwp_branding_button_contact_label', $settings['child_button_contact_label'], 'yes' );
122
+ MainWP_Helper::update_option( 'mainwp_branding_send_email_message', $settings['child_send_email_message'] );
123
+ MainWP_Helper::update_option( 'mainwp_branding_message_return_sender', $settings['child_message_return_sender'] );
124
+ MainWP_Helper::update_option( 'mainwp_branding_submit_button_title', $settings['child_submit_button_title'] );
125
+ if ( isset( $settings['child_disable_wp_branding'] ) && ( 'Y' === $settings['child_disable_wp_branding'] || 'N' === $settings['child_disable_wp_branding'] ) ) {
126
+ MainWP_Helper::update_option( 'mainwp_branding_disable_wp_branding', $settings['child_disable_wp_branding'] );
127
+ }
128
+
129
+ $extra_setting = array(
130
+ 'show_button_in' => $settings['child_show_support_button_in'],
131
+ 'global_footer' => $settings['child_global_footer'],
132
+ 'dashboard_footer' => $settings['child_dashboard_footer'],
133
+ 'remove_widget_welcome' => $settings['child_remove_widget_welcome'],
134
+ 'remove_widget_glance' => $settings['child_remove_widget_glance'],
135
+ 'remove_widget_activity' => $settings['child_remove_widget_activity'],
136
+ 'remove_widget_quick' => $settings['child_remove_widget_quick'],
137
+ 'remove_widget_news' => $settings['child_remove_widget_news'],
138
+ 'site_generator' => $settings['child_site_generator'],
139
+ 'generator_link' => $settings['child_generator_link'],
140
+ 'admin_css' => $settings['child_admin_css'],
141
+ 'login_css' => $settings['child_login_css'],
142
+ 'texts_replace' => $settings['child_texts_replace'],
143
+ 'hide_nag' => $settings['child_hide_nag'],
144
+ 'hide_screen_opts' => $settings['child_hide_screen_opts'],
145
+ 'hide_help_box' => $settings['child_hide_help_box'],
146
+ 'hide_metabox_post_excerpt' => $settings['child_hide_metabox_post_excerpt'],
147
+ 'hide_metabox_post_slug' => $settings['child_hide_metabox_post_slug'],
148
+ 'hide_metabox_post_tags' => $settings['child_hide_metabox_post_tags'],
149
+ 'hide_metabox_post_author' => $settings['child_hide_metabox_post_author'],
150
+ 'hide_metabox_post_comments' => $settings['child_hide_metabox_post_comments'],
151
+ 'hide_metabox_post_revisions' => $settings['child_hide_metabox_post_revisions'],
152
+ 'hide_metabox_post_discussion' => $settings['child_hide_metabox_post_discussion'],
153
+ 'hide_metabox_post_categories' => $settings['child_hide_metabox_post_categories'],
154
+ 'hide_metabox_post_custom_fields' => $settings['child_hide_metabox_post_custom_fields'],
155
+ 'hide_metabox_post_trackbacks' => $settings['child_hide_metabox_post_trackbacks'],
156
+ 'hide_metabox_page_custom_fields' => $settings['child_hide_metabox_page_custom_fields'],
157
+ 'hide_metabox_page_author' => $settings['child_hide_metabox_page_author'],
158
+ 'hide_metabox_page_discussion' => $settings['child_hide_metabox_page_discussion'],
159
+ 'hide_metabox_page_revisions' => $settings['child_hide_metabox_page_revisions'],
160
+ 'hide_metabox_page_attributes' => $settings['child_hide_metabox_page_attributes'],
161
+ 'hide_metabox_page_slug' => $settings['child_hide_metabox_page_slug'],
162
+ );
163
+
164
+ if ( isset( $settings['child_login_image_url'] ) ) {
165
+ if ( empty( $settings['child_login_image_url'] ) ) {
166
+ $extra_setting['login_image'] = array();
167
+ } else {
168
+ try {
169
+ $upload = $this->uploadImage( $settings['child_login_image_url'] ); //Upload image to WP
170
+ if ( null !== $upload ) {
171
+ $extra_setting['login_image'] = array( 'path' => $upload['path'], 'url' => $upload['url'] );
172
+ if ( isset( $current_extra_setting['login_image']['path'] ) ) {
173
+ $old_file = $current_extra_setting['login_image']['path'];
174
+ if ( ! empty( $old_file ) && file_exists( $old_file ) ) {
175
+ @unlink( $old_file );
176
+ }
177
+ }
178
+ }
179
+ } catch ( Exception $e ) {
180
+ $information['error']['login_image'] = $e->getMessage();
181
+ }
182
+ }
183
+ } else if ( isset( $current_extra_setting['login_image'] ) ) {
184
+ $extra_setting['login_image'] = $current_extra_setting['login_image'];
185
+ }
186
+
187
+ if ( isset( $settings['child_favico_image_url'] ) ) {
188
+ if ( empty( $settings['child_favico_image_url'] ) ) {
189
+ $extra_setting['favico_image'] = array();
190
+ } else {
191
+ try {
192
+ $upload = $this->uploadImage( $settings['child_favico_image_url'] ); //Upload image to WP
193
+ if ( null !== $upload ) {
194
+ $extra_setting['favico_image'] = array( 'path' => $upload['path'], 'url' => $upload['url'] );
195
+ if ( isset( $current_extra_setting['favico_image']['path'] ) ) {
196
+ $old_file = $current_extra_setting['favico_image']['path'];
197
+ if ( ! empty( $old_file ) && file_exists( $old_file ) ) {
198
+ @unlink( $old_file );
199
+ }
200
+ }
201
+ }
202
+ } catch ( Exception $e ) {
203
+ $information['error']['favico_image'] = $e->getMessage();
204
+ }
205
+ }
206
+ } else if ( isset( $current_extra_setting['favico_image'] ) ) {
207
+ $extra_setting['favico_image'] = $current_extra_setting['favico_image'];
208
+ }
209
+
210
+ MainWP_Helper::update_option( 'mainwp_branding_extra_settings', $extra_setting, 'yes' );
211
+
212
+ if ( $settings['child_plugin_hide'] ) {
213
+ MainWP_Helper::update_option( 'mainwp_branding_child_hide', 'T', 'yes' );
214
+ } else {
215
+ MainWP_Helper::update_option( 'mainwp_branding_child_hide', '' );
216
+ }
217
+
218
+ if ( $settings['child_show_support_button'] && ! empty( $settings['child_support_email'] ) ) {
219
+ MainWP_Helper::update_option( 'mainwp_branding_show_support', 'T' );
220
+ } else {
221
+ MainWP_Helper::update_option( 'mainwp_branding_show_support', '' );
222
+ }
223
+
224
+ if ( $settings['child_disable_change'] ) {
225
+ MainWP_Helper::update_option( 'mainwp_branding_disable_change', 'T' );
226
+ } else {
227
+ MainWP_Helper::update_option( 'mainwp_branding_disable_change', '' );
228
+ }
229
+
230
+ if ( $settings['child_disable_switching_theme'] ) {
231
+ MainWP_Helper::update_option( 'mainwp_branding_disable_switching_theme', 'T' );
232
+ } else {
233
+ MainWP_Helper::update_option( 'mainwp_branding_disable_switching_theme', '' );
234
+ }
235
+
236
+ $information['result'] = 'SUCCESS';
237
+
238
+ return $information;
239
+ }
240
+
241
+ static function uploadImage( $img_url ) {
242
+ include_once( ABSPATH . 'wp-admin/includes/file.php' ); //Contains download_url
243
+ global $mainWPChild;
244
+ add_filter( 'http_request_args', array( $mainWPChild, 'http_request_reject_unsafe_urls' ), 99, 2 );
245
+ //Download $img_url
246
+ $temporary_file = download_url( $img_url );
247
+ remove_filter( 'http_request_args', array( $mainWPChild, 'http_request_reject_unsafe_urls' ), 99, 2 );
248
+
249
+ if ( is_wp_error( $temporary_file ) ) {
250
+ throw new Exception( 'Error: ' . $temporary_file->get_error_message() );
251
+ } else {
252
+ $upload_dir = wp_upload_dir();
253
+ $local_img_path = $upload_dir['path'] . DIRECTORY_SEPARATOR . basename( $img_url ); //Local name
254
+ $local_img_path = dirname( $local_img_path ) . '/' . wp_unique_filename( dirname( $local_img_path ), basename( $local_img_path ) );
255
+ $local_img_url = $upload_dir['url'] . '/' . basename( $local_img_path );
256
+ $moved = @rename( $temporary_file, $local_img_path );
257
+ if ( $moved ) {
258
+ return array( 'path' => $local_img_path, 'url' => $local_img_url );
259
+ }
260
+ }
261
+ if ( file_exists( $temporary_file ) ) {
262
+ unlink( $temporary_file );
263
+ }
264
+
265
+ return null;
266
+ }
267
+
268
+
269
+ public function branding_init() {
270
+ $extra_setting = $this->settings['extra_settings'];
271
+ if ( ! is_array( $extra_setting ) ) {
272
+ $extra_setting = array();
273
+ }
274
+ $cancelled_branding = ( get_option( 'mainwp_child_branding_disconnected' ) === 'yes' ) && ! get_option( 'mainwp_branding_preserve_branding' );
275
+ if ( $cancelled_branding ) {
276
+ return;
277
+ }
278
+ // enable branding in case child plugin is deactive
279
+ add_filter( 'all_plugins', array( $this, 'branding_child_plugin' ) );
280
+
281
+ if ( self::is_branding() ) {
282
+ add_filter( 'site_transient_update_plugins', array( &$this, 'remove_update_nag' ) );
283
+ }
284
+
285
+ if ( get_option( 'mainwp_branding_ext_enabled' ) !== 'Y' ) {
286
+ return;
287
+ }
288
+
289
+ add_filter( 'map_meta_cap', array( $this, 'branding_map_meta_cap' ), 10, 5 );
290
+
291
+ // to fix
292
+ add_action( 'admin_menu', array( &$this, 'admin_menu' ) );
293
+ // if ( 'T' === get_option( 'mainwp_branding_show_support' ) ) {
294
+ // $title = $this->settings['contact_support_label'];
295
+ // if ( isset( $extra_setting['show_button_in'] ) && ( 2 === (int) $extra_setting['show_button_in'] || 3 === (int) $extra_setting['show_button_in'] ) ) {
296
+ // $title = $this->settings['contact_support_label'];
297
+ // add_menu_page( $title, $title, 'read', 'ContactSupport2', array(
298
+ // $this,
299
+ // 'contact_support',
300
+ // ), '', '2.0001' );
301
+ // }
302
+ //
303
+ // if ( isset( $extra_setting['show_button_in'] ) && ( 1 === $extra_setting['show_button_in'] || 3 === $extra_setting['show_button_in'] ) ) {
304
+ // add_submenu_page( null, $title, $this->settings['contact_support_label'], 'read', 'ContactSupport', array(
305
+ // $this,
306
+ // 'contact_support',
307
+ // ) );
308
+ // add_action( 'admin_bar_menu', array( $this, 'add_support_button_in_top_admin_bar' ), 100 );
309
+ // }
310
+ // }
311
+ if ( get_option( 'mainwp_branding_disable_wp_branding' ) !== 'Y' ) {
312
+ add_filter( 'wp_footer', array( &$this, 'branding_global_footer' ), 15 );
313
+ add_action( 'wp_dashboard_setup', array( &$this, 'custom_dashboard_widgets' ), 999 );
314
+ // branding site generator
315
+ $types = array( 'html', 'xhtml', 'atom', 'rss2', 'rdf', 'comment', 'export' );
316
+ foreach ( $types as $type ) {
317
+ add_filter( 'get_the_generator_' . $type, array( &$this, 'custom_the_generator' ), 999, 2 );
318
+ }
319
+ add_action( 'admin_head', array( &$this, 'custom_admin_css' ) );
320
+ add_action( 'login_enqueue_scripts', array( &$this, 'custom_login_css' ) );
321
+ add_filter( 'gettext', array( &$this, 'custom_gettext' ), 99, 3 );
322
+ add_action( 'login_head', array( &$this, 'custom_login_logo' ) );
323
+ add_action( 'wp_head', array( &$this, 'custom_favicon_frontend' ) );
324
+ if ( isset( $extra_setting['dashboard_footer'] ) && ! empty( $extra_setting['dashboard_footer'] ) ) {
325
+ remove_filter( 'update_footer', 'core_update_footer' );
326
+ add_filter( 'update_footer', array( &$this, 'update_admin_footer' ), 14 );
327
+ }
328
+
329
+ if ( isset( $extra_setting['hide_nag'] ) && ! empty( $extra_setting['hide_nag'] ) ) {
330
+ add_action( 'admin_init', create_function( '', 'remove_action( \'admin_notices\', \'update_nag\', 3 );' ) );
331
+ }
332
+
333
+ add_action( 'admin_menu', array( &$this, 'remove_default_post_metaboxes' ) );
334
+ add_action( 'admin_menu', array( &$this, 'remove_default_page_metaboxes' ) );
335
+ }
336
+ }
337
+
338
+ // to fix conflict with other plugin
339
+ function admin_menu() {
340
+ if ( !current_user_can( 'administrator' ) ) {
341
+ return false;
342
+ }
343
+ $extra_setting = $this->settings['extra_settings'];
344
+ if ( ! is_array( $extra_setting ) ) {
345
+ $extra_setting = array();
346
+ }
347
+ if ( 'T' === get_option( 'mainwp_branding_show_support' ) ) {
348
+ $title = $this->settings['contact_support_label'];
349
+ if ( isset( $extra_setting['show_button_in'] ) && ( 2 === (int) $extra_setting['show_button_in'] || 3 === (int) $extra_setting['show_button_in'] ) ) {
350
+ $title = $this->settings['contact_support_label'];
351
+ add_menu_page( $title, $title, 'read', 'ContactSupport2', array(
352
+ $this,
353
+ 'contact_support',
354
+ ), '', '2.0001' );
355
+ }
356
+
357
+ if ( isset( $extra_setting['show_button_in'] ) && ( 1 === $extra_setting['show_button_in'] || 3 === $extra_setting['show_button_in'] ) ) {
358
+ add_submenu_page( null, $title, $this->settings['contact_support_label'], 'read', 'ContactSupport', array(
359
+ $this,
360
+ 'contact_support',
361
+ ) );
362
+ add_action( 'admin_bar_menu', array( $this, 'add_support_button_in_top_admin_bar' ), 100 );
363
+ }
364
+ }
365
+
366
+ }
367
+
368
+ function remove_default_post_metaboxes() {
369
+ $extra_setting = $this->settings['extra_settings'];
370
+ if ( ! is_array( $extra_setting ) ) {
371
+ $extra_setting = array();
372
+ }
373
+
374
+ add_filter( 'manage_posts_columns', array( &$this, 'custom_post_columns' ) );
375
+ add_filter( 'manage_edit-post_tag_columns', array( &$this, 'manage_my_category_columns' ) );
376
+ add_filter( 'manage_edit-category_columns', array( &$this, 'manage_my_category_columns' ) );
377
+
378
+ if ( isset( $extra_setting['hide_metabox_post_custom_fields'] ) && $extra_setting['hide_metabox_post_custom_fields'] ) {
379
+ remove_meta_box( 'postcustom', 'post', 'normal' );
380
+ }
381
+ if ( isset( $extra_setting['hide_metabox_post_excerpt'] ) && $extra_setting['hide_metabox_post_excerpt'] ) {
382
+ remove_meta_box( 'postexcerpt', 'post', 'normal' );
383
+ }
384
+ if ( isset( $extra_setting['hide_metabox_post_discussion'] ) && $extra_setting['hide_metabox_post_discussion'] ) {
385
+ remove_meta_box( 'commentstatusdiv', 'post', 'normal' );
386
+ }
387
+ if ( isset( $extra_setting['hide_metabox_post_trackbacks'] ) && $extra_setting['hide_metabox_post_trackbacks'] ) {
388
+ remove_meta_box( 'trackbacksdiv', 'post', 'normal' );
389
+ }
390
+ if ( isset( $extra_setting['hide_metabox_post_slug'] ) && $extra_setting['hide_metabox_post_slug'] ) {
391
+ remove_meta_box( 'slugdiv', 'post', 'normal' );
392
+ }
393
+ if ( isset( $extra_setting['hide_metabox_post_author'] ) && $extra_setting['hide_metabox_post_author'] ) {
394
+ remove_meta_box( 'authordiv', 'post', 'normal' );
395
+ }
396
+ if ( isset( $extra_setting['hide_metabox_post_revisions'] ) && $extra_setting['hide_metabox_post_revisions'] ) {
397
+ remove_meta_box( 'revisionsdiv', 'post', 'normal' );
398
+ }
399
+ if ( isset( $extra_setting['hide_metabox_post_tags'] ) && $extra_setting['hide_metabox_post_tags'] ) {
400
+ remove_meta_box( 'tagsdiv-post_tag', 'post', 'normal' );
401
+ }
402
+ if ( isset( $extra_setting['hide_metabox_post_categories'] ) && $extra_setting['hide_metabox_post_categories'] ) {
403
+ remove_meta_box( 'categorydiv', 'post', 'normal' );
404
+ }
405
+ if ( isset( $extra_setting['hide_metabox_post_comments'] ) && $extra_setting['hide_metabox_post_comments'] ) {
406
+ remove_meta_box( 'commentsdiv', 'post', 'normal' );
407
+ }
408
+ }
409
+
410
+
411
+ function custom_post_columns( $defaults ) {
412
+ $extra_setting = $this->settings['extra_settings'];
413
+ if ( ! is_array( $extra_setting ) ) {
414
+ $extra_setting = array();
415
+ }
416
+
417
+ if ( isset( $extra_setting['hide_metabox_post_comments'] ) && $extra_setting['hide_metabox_post_comments'] ) {
418
+ unset( $defaults['comments'] );
419
+ }
420
+ if ( isset( $extra_setting['hide_metabox_post_author'] ) && $extra_setting['hide_metabox_post_author'] ) {
421
+ unset( $defaults['author'] );
422
+ }
423
+ if ( isset( $extra_setting['hide_metabox_post_categories'] ) && $extra_setting['hide_metabox_post_categories'] ) {
424
+ unset( $defaults['categories'] );
425
+ }
426
+
427
+ return $defaults;
428
+ }
429
+
430
+ function manage_my_category_columns( $defaults ) {
431
+ $extra_setting = $this->settings['extra_settings'];
432
+ if ( ! is_array( $extra_setting ) ) {
433
+ $extra_setting = array();
434
+ }
435
+
436
+ if ( isset( $extra_setting['hide_metabox_post_slug'] ) && $extra_setting['hide_metabox_post_slug'] ) {
437
+ unset( $defaults['slug'] );
438
+ }
439
+
440
+ return $defaults;
441
+ }
442
+
443
+ function remove_default_page_metaboxes() {
444
+ $extra_setting = $this->settings['extra_settings'];
445
+ if ( ! is_array( $extra_setting ) ) {
446
+ $extra_setting = array();
447
+ }
448
+
449
+ add_filter( 'manage_pages_columns', array( &$this, 'custom_pages_columns' ) );
450
+
451
+ if ( isset( $extra_setting['hide_metabox_page_custom_fields'] ) && $extra_setting['hide_metabox_page_custom_fields'] ) { // if (get_option('wlcms_o_page_meta_box_custom'))
452
+ remove_meta_box( 'postcustom', 'page', 'normal' );
453
+ }
454
+ if ( isset( $extra_setting['hide_metabox_page_author'] ) && $extra_setting['hide_metabox_page_author'] ) {
455
+ remove_meta_box( 'authordiv', 'page', 'normal' );
456
+ }
457
+ if ( isset( $extra_setting['hide_metabox_page_discussion'] ) && $extra_setting['hide_metabox_page_discussion'] ) {
458
+ remove_meta_box( 'commentstatusdiv', 'page', 'normal' );
459
+ }
460
+ if ( isset( $extra_setting['hide_metabox_page_slug'] ) && $extra_setting['hide_metabox_page_slug'] ) {
461
+ remove_meta_box( 'slugdiv', 'page', 'normal' );
462
+ }
463
+ if ( isset( $extra_setting['hide_metabox_page_revisions'] ) && $extra_setting['hide_metabox_page_revisions'] ) {
464
+ remove_meta_box( 'revisionsdiv', 'page', 'normal' );
465
+ }
466
+ if ( isset( $extra_setting['hide_metabox_page_attributes'] ) && $extra_setting['hide_metabox_page_attributes'] ) {
467
+ remove_meta_box( 'pageparentdiv', 'page', 'normal' );
468
+ }
469
+ if ( isset( $extra_setting['hide_metabox_page_comments'] ) && $extra_setting['hide_metabox_page_comments'] ) {
470
+ remove_meta_box( 'commentsdiv', 'page', 'normal' );
471
+ }
472
+ }
473
+
474
+ function custom_pages_columns( $defaults ) {
475
+ $extra_setting = $this->settings['extra_settings'];
476
+ if ( ! is_array( $extra_setting ) ) {
477
+ $extra_setting = array();
478
+ }
479
+
480
+ if ( isset( $extra_setting['hide_metabox_page_comments'] ) && $extra_setting['hide_metabox_page_comments'] ) {
481
+ unset( $defaults['comments'] );
482
+ }
483
+ if ( isset( $extra_setting['hide_metabox_page_author'] ) && $extra_setting['hide_metabox_page_author'] ) {
484
+ unset( $defaults['author'] );
485
+ }
486
+
487
+ return $defaults;
488
+ }
489
+
490
+
491
+ function update_admin_footer() {
492
+ $extra_setting = $this->settings['extra_settings'];
493
+ if ( isset( $extra_setting['dashboard_footer'] ) && ! empty( $extra_setting['dashboard_footer'] ) ) {
494
+ echo wp_kses_post( nl2br( stripslashes( $extra_setting['dashboard_footer'] ) ) );
495
+ }
496
+ }
497
+
498
+ function custom_favicon_frontend() {
499
+ $extra_setting = $this->settings['extra_settings'];
500
+ if ( isset( $extra_setting['favico_image']['url'] ) && ! empty( $extra_setting['favico_image']['url'] ) ) {
501
+ $favico = $extra_setting['favico_image']['url'];
502
+ echo '<link rel="shortcut icon" href="' . esc_url( $favico ) . '"/>' . "\n";
503
+ }
504
+ }
505
+
506
+ function custom_login_logo() {
507
+ $extra_setting = $this->settings['extra_settings'];
508
+ if ( isset( $extra_setting['login_image']['url'] ) && ! empty( $extra_setting['login_image']['url'] ) ) {
509
+ $login_logo = $extra_setting['login_image']['url'];
510
+ echo '<style type="text/css">
511
+ #login h1 a { background-image: url(\'' . esc_url( $login_logo ) . '\') !important; height:70px !important; width:310px !important; background-size: auto auto !important; }
512
+ </style>';
513
+ }
514
+ }
515
+
516
+ function custom_gettext( $translations, $text, $domain = 'default' ) {
517
+ $extra_setting = $this->settings['extra_settings'];
518
+ $texts_replace = $extra_setting['texts_replace'];
519
+ if ( is_array( $texts_replace ) && count( $texts_replace ) > 0 ) {
520
+ foreach ( $texts_replace as $text => $replace ) {
521
+ if ( ! empty( $text ) ) {
522
+ $translations = str_replace( $text, $replace, $translations );
523
+ }
524
+ }
525
+ }
526
+
527
+ return $translations;
528
+ }
529
+
530
+ function custom_admin_css() {
531
+ $header_css = '';
532
+ $extra_setting = $this->settings['extra_settings'];
533
+
534
+ if ( is_array( $extra_setting ) && isset( $extra_setting['admin_css'] ) && ! empty( $extra_setting['admin_css'] ) ) {
535
+ $header_css .= $extra_setting['admin_css'];
536
+ }
537
+
538
+ if ( isset( $extra_setting['hide_screen_opts'] ) && ! empty( $extra_setting['hide_screen_opts'] ) ) {
539
+ $header_css .= ' #screen-options-link-wrap { display: none; }';
540
+ }
541
+
542
+ if ( isset( $extra_setting['hide_help_box'] ) && ! empty( $extra_setting['hide_help_box'] ) ) {
543
+ $header_css .= ' #contextual-help-link-wrap { display: none; }';
544
+ $header_css .= ' #contextual-help-link { display: none; }';
545
+ }
546
+
547
+ if ( ! empty( $header_css ) ) {
548
+ echo '<style>' . MainWP_Helper::parse_css( $header_css ) . '</style>';
549
+ }
550
+ }
551
+
552
+ function custom_login_css() {
553
+ $extra_setting = $this->settings['extra_settings'];
554
+ if ( is_array( $extra_setting ) && isset( $extra_setting['login_css'] ) && ! empty( $extra_setting['login_css'] ) ) {
555
+ echo '<style>' . MainWP_Helper::parse_css( $extra_setting['login_css'] ) . '</style>';
556
+ }
557
+ }
558
+
559
+ function custom_the_generator( $generator, $type = '' ) {
560
+ $extra_setting = $this->settings['extra_settings'];
561
+ if ( isset( $extra_setting['site_generator'] ) ) {
562
+ if ( ! empty( $extra_setting['site_generator'] ) ) {
563
+ switch ( $type ) :
564
+ case 'html':
565
+ $generator = '<meta name="generator" content="' . $extra_setting['site_generator'] . '">';
566
+ break;
567
+ case 'xhtml':
568
+ $generator = '<meta name="generator" content="' . $extra_setting['site_generator'] . '" />';
569
+ break;
570
+ case 'atom':
571
+ if ( ! empty( $extra_setting['generator_link'] ) ) {
572
+ $generator = '<generator uri="' . $extra_setting['generator_link'] . '" >' . $extra_setting['site_generator'] . '</generator>';
573
+ }
574
+ break;
575
+ case 'rss2':
576
+ if ( ! empty( $extra_setting['generator_link'] ) ) {
577
+ $generator = '<generator>' . $extra_setting['generator_link'] . '</generator>';
578
+ }
579
+ break;
580
+ case 'rdf':
581
+ if ( ! empty( $extra_setting['generator_link'] ) ) {
582
+ $generator = '<admin:generatorAgent rdf:resource="' . $extra_setting['generator_link'] . '" />';
583
+ }
584
+ break;
585
+ case 'comment':
586
+ $generator = '<!-- generator="' . $extra_setting['site_generator'] . '" -->';
587
+ break;
588
+ case 'export':
589
+ $generator = '<!-- generator="' . $extra_setting['site_generator'] . '" created="' . date( 'Y-m-d H:i' ) . '" -->';
590
+ break;
591
+ endswitch;
592
+
593
+ return $generator;
594
+ }
595
+ }
596
+
597
+ return $generator;
598
+ }
599
+
600
+ function custom_dashboard_widgets() {
601
+ global $wp_meta_boxes;
602
+ $extra_setting = $this->settings['extra_settings'];
603
+ if ( isset( $extra_setting['remove_widget_welcome'] ) && $extra_setting['remove_widget_welcome'] ) {
604
+ remove_action( 'welcome_panel', 'wp_welcome_panel' );
605
+ }
606
+ if ( isset( $extra_setting['remove_widget_glance'] ) && $extra_setting['remove_widget_glance'] ) {
607
+ unset( $wp_meta_boxes['dashboard']['normal']['core']['dashboard_right_now'] );
608
+ }
609
+ if ( isset( $extra_setting['remove_widget_activity'] ) && $extra_setting['remove_widget_activity'] ) {
610
+ unset( $wp_meta_boxes['dashboard']['normal']['core']['dashboard_activity'] );
611
+ }
612
+ if ( isset( $extra_setting['remove_widget_quick'] ) && $extra_setting['remove_widget_quick'] ) {
613
+ unset( $wp_meta_boxes['dashboard']['side']['core']['dashboard_quick_press'] );
614
+ }
615
+ if ( isset( $extra_setting['remove_widget_news'] ) && $extra_setting['remove_widget_news'] ) {
616
+ unset( $wp_meta_boxes['dashboard']['side']['core']['dashboard_primary'] );
617
+ }
618
+ }
619
+
620
+ public function branding_global_footer() {
621
+ $extra_setting = $this->settings['extra_settings'];
622
+ if ( isset( $extra_setting['global_footer'] ) && ! empty( $extra_setting['global_footer'] ) ) {
623
+ echo wp_kses_post( nl2br( stripslashes( $extra_setting['global_footer'] ) ) );
624
+ }
625
+ }
626
+
627
+ public function send_support_mail() {
628
+ $email = get_option( 'mainwp_branding_support_email' );
629
+ $sub = wp_kses_post( nl2br( stripslashes( $_POST['mainwp_branding_contact_message_subject'] ) ) );
630
+ $subject = !empty( $sub ) ? $sub : "MainWP - Support Contact";
631
+ $content = wp_kses_post( nl2br( stripslashes( $_POST['mainwp_branding_contact_message_content'] ) ) );
632
+ if ( ! empty( $_POST['mainwp_branding_contact_message_content'] ) && ! empty( $email ) ) {
633
+ global $current_user;
634
+ $headers .= "Content-Type: text/html;charset=utf-8\r\n";
635
+ $headers .= "From: \"" . $current_user->user_email . "\" <" . $current_user->user_email . ">\r\n";
636
+ $mail .= "<p>Support Email from: <a href='" . site_url() . "'>" . site_url() . "</a></p>\r\n\r\n";
637
+ $mail .= "<p>Sent from WordPress page: " . ( ! empty( $_POST["mainwp_branding_send_from_page"] ) ? "<a href='" . esc_url( $_POST["mainwp_branding_send_from_page"] ) . "'>" . esc_url( $_POST["mainwp_branding_send_from_page"] ) . "</a></p>\r\n\r\n" : "" );
638
+ $mail .= "<p>Client Email: " . $current_user->user_email . " </p>\r\n\r\n";
639
+ $mail .= "<p>Support Text:</p>\r\n\r\n";
640
+ $mail .= "<p>" . $content . "</p>\r\n\r\n";
641
+
642
+ if ( wp_mail( $email, $subject, $mail, $headers ) ) {
643
+ ;
644
+ }
645
+
646
+ return true;
647
+ }
648
+
649
+ return false;
650
+ }
651
+
652
+ function contact_support() {
653
+ if ( !current_user_can('administrator') ) {
654
+ return false;
655
+ }
656
+ ?>
657
+ <style>
658
+ .mainwp_info-box-yellow {
659
+ margin: 5px 0 15px;
660
+ padding: .6em;
661
+ background: #ffffe0;
662
+ border: 1px solid #e6db55;
663
+ border-radius: 3px;
664
+ -moz-border-radius: 3px;
665
+ -webkit-border-radius: 3px;
666
+ clear: both;
667
+ }
668
+ </style>
669
+ <?php
670
+ if ( isset( $_POST['submit'] ) ) {
671
+ if ( ! isset( $_POST['_wpnonce'] ) || ! wp_verify_nonce( $_POST['_wpnonce'], '_contactNonce' ) ) {
672
+ return false;
673
+ }
674
+ $from_page = $_POST['mainwp_branding_send_from_page'];
675
+ $back_link = get_option( 'mainwp_branding_message_return_sender' );
676
+ $back_link = ! empty( $back_link ) ? $back_link : 'Go Back';
677
+ $back_link = ! empty( $from_page ) ? '<a href="' . esc_url( $from_page ) . '" title="' . esc_attr( $back_link ) . '">' . esc_html( $back_link ) . '</a>' : '';
678
+
679
+ if ( $this->send_support_mail() ) {
680
+ $send_email_message = get_option( 'mainwp_branding_send_email_message' );
681
+ if ( ! empty( $send_email_message ) ) {
682
+ $send_email_message = stripslashes( $send_email_message );
683
+ } else {
684
+ $send_email_message = 'Message has been submitted successfully.';
685
+ }
686
+ } else {
687
+ $send_email_message = __( 'Sending email failed!' );
688
+ }
689
+ ?>
690
+ <div
691
+ class="mainwp_info-box-yellow"><?php echo esc_html( $send_email_message ) . "&nbsp;&nbsp" . $back_link; ?></div><?php
692
+ } else {
693
+ $from_page = '';
694
+ if ( isset( $_GET['from_page'] ) ) {
695
+ $from_page = urldecode( $_GET['from_page'] );
696
+ } else {
697
+ $protocol = isset( $_SERVER['HTTPS'] ) && strcasecmp( $_SERVER['HTTPS'], 'off' ) ? 'https://' : 'http://';
698
+ $fullurl = $protocol . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
699
+ $from_page = urldecode( $fullurl );
700
+ }
701
+
702
+ $support_message = get_option( 'mainwp_branding_support_message' );
703
+ $support_message = nl2br( stripslashes( $support_message ) );
704
+ ?>
705
+ <form action="" method="post">
706
+ <div style="width: 99%;">
707
+ <h2><?php echo esc_html( $this->settings['contact_support_label'] ); ?></h2>
708
+
709
+ <div style="height: auto; margin-bottom: 10px; text-align: left">
710
+ <p><?php echo wp_kses_post( $support_message ); ?></p>
711
+ <p><label for="mainwp_branding_contact_message_subject"><?php _e('Subject:', 'mainwp-child'); ?></label><br>
712
+ <input type="text" name="mainwp_branding_contact_message_subject" style="width: 650px;"></p>
713
+ <div style="max-width: 650px;">
714
+ <label for="mainwp_branding_contact_message_content"><?php _e('Your message:', 'mainwp-child'); ?></label><br>
715
+ <?php
716
+ remove_editor_styles(); // stop custom theme styling interfering with the editor
717
+ wp_editor( '', 'mainwp_branding_contact_message_content', array(
718
+ 'textarea_name' => 'mainwp_branding_contact_message_content',
719
+ 'textarea_rows' => 10,
720
+ 'teeny' => true,
721
+ 'wpautop' => true,
722
+ 'media_buttons' => false,
723
+ )
724
+ );
725
+ ?>
726
+ </div>
727
+ </div>
728
+ <br/>
729
+ <?php
730
+ $button_title = get_option( 'mainwp_branding_submit_button_title' );
731
+ $button_title = ! empty( $button_title ) ? $button_title : __( 'Submit' );
732
+ ?>
733
+ <input id="mainwp-branding-contact-support-submit" type="submit" name="submit"
734
+ value="<?php echo esc_attr( $button_title ); ?>"
735
+ class="button-primary button" style="float: left"/>
736
+ </div>
737
+ <input type="hidden" name="mainwp_branding_send_from_page"
738
+ value="<?php echo esc_url( $from_page ); ?>"/>
739
+ <input type="hidden" name="_wpnonce" value="<?php echo esc_attr( wp_create_nonce( '_contactNonce' ) ); ?>"/>
740
+ </form>
741
+ <?php }
742
+ }
743
+
744
+ /**
745
+ * @param WP_Admin_Bar $wp_admin_bar
746
+ */
747
+ public function add_support_button_in_top_admin_bar( $wp_admin_bar ) {
748
+ if ( !current_user_can( 'administrator' ) ) {
749
+ return false;
750
+ }
751
+
752
+ if ( isset( $_GET['from_page'] ) ) {
753
+ $href = admin_url( 'admin.php?page=ContactSupport&from_page=' . urlencode( esc_url( $_GET['from_page'] ) ) );
754
+ } else {
755
+ $protocol = isset( $_SERVER['HTTPS'] ) && strcasecmp( $_SERVER['HTTPS'], 'off' ) ? 'https://' : 'http://';
756
+ $fullurl = $protocol . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
757
+ $href = admin_url( 'admin.php?page=ContactSupport&from_page=' . urlencode( esc_url( $fullurl ) ) );
758
+ }
759
+ $args = array(
760
+ 'id' => 999,
761
+ 'title' => $this->settings['contact_support_label'],
762
+ 'parent' => 'top-secondary',
763
+ 'href' => $href,
764
+ 'meta' => array(
765
+ 'class' => 'mainwp_branding_support_top_bar_button',
766
+ 'title' => $this->settings['contact_support_label'],
767
+ ),
768
+ );
769
+
770
+ $wp_admin_bar->add_node( $args );
771
+ }
772
+
773
+ public static function is_branding() {
774
+ $cancelled_branding = ( get_option( 'mainwp_child_branding_disconnected' ) === 'yes' ) && ! get_option( 'mainwp_branding_preserve_branding' );
775
+ if ( $cancelled_branding ) {
776
+ return false;
777
+ }
778
+
779
+ // hide
780
+ if ( 'T' === get_option( 'mainwp_branding_child_hide' ) ) {
781
+ return true;
782
+ }
783
+ // branding
784
+ $header = get_option( 'mainwp_branding_plugin_header' );
785
+ if ( is_array( $header ) && ! empty( $header['name'] ) ) {
786
+ return true;
787
+ }
788
+
789
+ return false;
790
+ }
791
+
792
+ public static function get_branding() {
793
+ if ( self::is_branding() ) {
794
+ $header = get_option( 'mainwp_branding_plugin_header' );
795
+
796
+ return $header['name'];
797
+ }
798
+
799
+ return 'MainWP';
800
+ }
801
+
802
+ public function branding_map_meta_cap( $caps, $cap, $user_id, $args ) {
803
+ if ( 'T' === get_option( 'mainwp_branding_disable_change' ) ) {
804
+ // disable: edit, update, install, active themes and plugins
805
+ if ( false !== strpos( $cap, 'plugins' ) || false !== strpos( $cap, 'themes' ) || 'edit_theme_options' === $cap ) {
806
+ $caps[0] = 'do_not_allow';
807
+ }
808
+ }
809
+ if ( 'T' === get_option( 'mainwp_branding_disable_switching_theme' ) ) {
810
+ // disable: theme switching
811
+ if ( 'switch_themes' === $cap ) {
812
+ $caps[0] = 'do_not_allow';
813
+ }
814
+ }
815
+ return $caps;
816
+ }
817
+
818
+ public function branding_child_plugin( $plugins ) {
819
+ if ( 'T' === get_option( 'mainwp_branding_child_hide' ) ) {
820
+ foreach ( $plugins as $key => $value ) {
821
+ $plugin_slug = basename( $key, '.php' );
822
+ if ( 'mainwp-child' === $plugin_slug ) {
823
+ unset( $plugins[ $key ] );
824
+ }
825
+ }
826
+
827
+ return $plugins;
828
+ }
829
+
830
+ $header = get_option( 'mainwp_branding_plugin_header' );
831
+ if ( is_array( $header ) && ! empty( $header['name'] ) ) {
832
+ return $this->update_child_header( $plugins, $header );
833
+ } else {
834
+ return $plugins;
835
+ }
836
+ }
837
+
838
+ function remove_update_nag( $value ) {
839
+ if ( isset( $_POST['mainwpsignature'] ) ) {
840
+ return $value;
841
+ }
842
+ if ( isset( $value->response['mainwp-child/mainwp-child.php'] ) ) {
843
+ unset( $value->response['mainwp-child/mainwp-child.php'] );
844
+ }
845
+ return $value;
846
+ }
847
+
848
+ public function update_child_header( $plugins, $header ) {
849
+ $plugin_key = '';
850
+ foreach ( $plugins as $key => $value ) {
851
+ $plugin_slug = basename( $key, '.php' );
852
+ if ( 'mainwp-child' === $plugin_slug ) {
853
+ $plugin_key = $key;
854
+ $plugin_data = $value;
855
+ }
856
+ }
857
+
858
+ if ( ! empty( $plugin_key ) ) {
859
+ $plugin_data['Name'] = stripslashes( $header['name'] );
860
+ $plugin_data['Description'] = stripslashes( $header['description'] );
861
+ $plugin_data['Author'] = stripslashes( $header['author'] );
862
+ $plugin_data['AuthorURI'] = stripslashes( $header['authoruri'] );
863
+ if ( ! empty( $header['pluginuri'] ) ) {
864
+ $plugin_data['PluginURI'] = stripslashes( $header['pluginuri'] );
865
+ }
866
+ $plugins[ $plugin_key ] = $plugin_data;
867
+ }
868
+
869
+ return $plugins;
870
+ }
871
+ }
872
+
class/class-mainwp-child-db.php ADDED
@@ -0,0 +1,101 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class MainWP_Child_DB {
4
+ //Support old & new versions of wordpress (3.9+)
5
+ public static function use_mysqli() {
6
+ /** @var $wpdb wpdb */
7
+ if ( ! function_exists( 'mysqli_connect' ) ) {
8
+ return false;
9
+ }
10
+
11
+ global $wpdb;
12
+
13
+ return ( $wpdb->dbh instanceof mysqli );
14
+ }
15
+
16
+ public static function _query( $query, $link ) {
17
+ if ( self::use_mysqli() ) {
18
+ return mysqli_query( $link, $query );
19
+ } else {
20
+ return mysql_query( $query, $link );
21
+ }
22
+ }
23
+
24
+ public static function fetch_array( $result ) {
25
+ if ( self::use_mysqli() ) {
26
+ return mysqli_fetch_array( $result, MYSQLI_ASSOC );
27
+ } else {
28
+ return mysql_fetch_array( $result, MYSQL_ASSOC );
29
+ }
30
+ }
31
+
32
+ public static function num_rows( $result ) {
33
+ if ( self::use_mysqli() ) {
34
+ return mysqli_num_rows( $result );
35
+ } else {
36
+ return mysql_num_rows( $result );
37
+ }
38
+ }
39
+
40
+ public static function connect( $host, $user, $pass ) {
41
+ if ( self::use_mysqli() ) {
42
+ return mysqli_connect( $host, $user, $pass );
43
+ } else {
44
+ return mysql_connect( $host, $user, $pass );
45
+ }
46
+ }
47
+
48
+ public static function select_db( $db ) {
49
+ if ( self::use_mysqli() ) {
50
+ /** @var $wpdb wpdb */
51
+ global $wpdb;
52
+
53
+ return mysqli_select_db( $wpdb->dbh, $db );
54
+ } else {
55
+ return mysql_select_db( $db );
56
+ }
57
+ }
58
+
59
+ public static function error() {
60
+ if ( self::use_mysqli() ) {
61
+ /** @var $wpdb wpdb */
62
+ global $wpdb;
63
+
64
+ return mysqli_error( $wpdb->dbh );
65
+ } else {
66
+ return mysql_error();
67
+ }
68
+ }
69
+
70
+ public static function real_escape_string( $value ) {
71
+ /** @var $wpdb wpdb */
72
+ global $wpdb;
73
+
74
+ if ( self::use_mysqli() ) {
75
+ return mysqli_real_escape_string( $wpdb->dbh, $value );
76
+ } else {
77
+ return mysql_real_escape_string( $value, $wpdb->dbh );
78
+ }
79
+ }
80
+
81
+ public static function is_result( $result ) {
82
+ if ( self::use_mysqli() ) {
83
+ return ( $result instanceof mysqli_result );
84
+ } else {
85
+ return is_resource( $result );
86
+ }
87
+ }
88
+
89
+ static function get_size() {
90
+ /** @var $wpdb wpdb */
91
+ global $wpdb;
92
+
93
+ $rows = MainWP_Child_DB::_query( 'SHOW table STATUS', $wpdb->dbh );
94
+ $size = 0;
95
+ while ( $row = MainWP_Child_DB::fetch_array( $rows ) ) {
96
+ $size += $row['Data_length'];
97
+ }
98
+
99
+ return $size;
100
+ }
101
+ }
class/class-mainwp-child-ithemes-security.php ADDED
@@ -0,0 +1,1199 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class MainWP_Child_iThemes_Security {
4
+ public static $instance = null;
5
+ public $is_plugin_installed = false;
6
+
7
+ static function Instance() {
8
+ if ( null === MainWP_Child_iThemes_Security::$instance ) {
9
+ MainWP_Child_iThemes_Security::$instance = new MainWP_Child_iThemes_Security();
10
+ }
11
+
12
+ return MainWP_Child_iThemes_Security::$instance;
13
+ }
14
+
15
+ public function __construct() {
16
+ require_once( ABSPATH . 'wp-admin/includes/plugin.php' );
17
+ if ( is_plugin_active( 'better-wp-security/better-wp-security.php') || is_plugin_active( 'ithemes-security-pro/ithemes-security-pro.php' ) ) {
18
+ $this->is_plugin_installed = true;
19
+ }
20
+
21
+ if (!$this->is_plugin_installed)
22
+ return;
23
+
24
+ add_filter( 'mainwp-site-sync-others-data', array( $this, 'syncOthersData' ), 10, 2 );
25
+ }
26
+
27
+ function syncOthersData( $information, $data = array() ) {
28
+ if ( is_array( $data ) && isset( $data['ithemeExtActivated'] ) && ( 'yes' === $data['ithemeExtActivated'] ) ) {
29
+ $information['syncIThemeData'] = array(
30
+ 'users_and_roles' => $this->get_available_admin_users_and_roles()
31
+ );
32
+ //MainWP_Helper::update_option( 'mainwp_ithemes_ext_activated', 'Y' );
33
+ return $information;
34
+
35
+ } else {
36
+ //MainWP_Helper::update_option( 'mainwp_ithemes_ext_activated', '' );
37
+ }
38
+ return $information;
39
+ }
40
+
41
+ public function action() {
42
+ $information = array();
43
+ if ( ! class_exists( 'ITSEC_Core' ) || !class_exists('ITSEC_Modules')) {
44
+ $information['error'] = 'NO_ITHEME';
45
+ MainWP_Helper::write( $information );
46
+ }
47
+
48
+ global $mainwp_itsec_modules_path;
49
+
50
+ $mainwp_itsec_modules_path = ITSEC_Core::get_core_dir() . '/modules/';
51
+ MainWP_Helper::update_option( 'mainwp_ithemes_ext_enabled', 'Y', 'yes' );
52
+
53
+ if ( isset( $_POST['mwp_action'] ) ) {
54
+ switch ( $_POST['mwp_action'] ) {
55
+ case 'set_showhide':
56
+ $information = $this->set_showhide();
57
+ break;
58
+ case 'save_settings':
59
+ $information = $this->save_settings();
60
+ break;
61
+ // case 'whitelist':
62
+ // $information = $this->whitelist();
63
+ // break;
64
+ case 'whitelist_release':
65
+ $information = $this->whitelist_release();
66
+ break;
67
+ case 'backup_db':
68
+ $information = $this->backup_db();
69
+ break;
70
+ case 'admin_user':
71
+ $information = $this->admin_user();
72
+ break;
73
+ case 'database_prefix':
74
+ $information = $this->change_database_prefix();
75
+ break;
76
+ // case 'api_key':
77
+ // $information = $this->api_key();
78
+ // break;
79
+ case 'reset_api_key':
80
+ $information = $this->reset_api_key();
81
+ break;
82
+ case 'malware_scan':
83
+ $information = $this->malware_scan();
84
+ break;
85
+ // case 'malware_get_scan_results':
86
+ // $information = $this->malware_get_scan_results();
87
+ // break;
88
+ case 'clear_all_logs':
89
+ $information = $this->purge_logs();
90
+ break;
91
+ case 'file_change':
92
+ $information = $this->file_change();
93
+ break;
94
+ case 'release_lockout':
95
+ $information = $this->release_lockout();
96
+ break;
97
+ case 'module_status':
98
+ $information = $this->update_module_status();
99
+ break;
100
+ case 'wordpress_salts':
101
+ $information = $this->wordpress_salts();
102
+ break;
103
+ case 'file_permissions':
104
+ $information = $this->file_permissions();
105
+ break;
106
+ case 'reload_backup_exclude':
107
+ $information = $this->reload_backup_exclude();
108
+ break;
109
+ case 'security_site':
110
+ $information = $this->security_site();
111
+ break;
112
+ case 'activate_network_brute_force':
113
+ $information = $this->activate_network_brute_force();
114
+ break;
115
+ }
116
+ }
117
+ MainWP_Helper::write( $information );
118
+ }
119
+
120
+ function set_showhide() {
121
+ $hide = isset( $_POST['showhide'] ) && ( 'hide' === $_POST['showhide'] ) ? 'hide' : '';
122
+ MainWP_Helper::update_option( 'mainwp_ithemes_hide_plugin', $hide );
123
+ $information['result'] = 'success';
124
+
125
+ return $information;
126
+ }
127
+
128
+ public function ithemes_init() {
129
+ if ( get_option( 'mainwp_ithemes_ext_enabled' ) !== 'Y' ) {
130
+ return;
131
+ }
132
+
133
+ if ( get_option( 'mainwp_ithemes_hide_plugin' ) === 'hide' ) {
134
+ add_filter( 'all_plugins', array( $this, 'all_plugins' ) );
135
+ add_action( 'admin_menu', array( $this, 'remove_menu' ) );
136
+ add_action( 'admin_init', array( $this, 'admin_init' ) );
137
+ }
138
+ }
139
+
140
+ public function admin_init() {
141
+ remove_meta_box( 'itsec-dashboard-widget', 'dashboard', 'normal' );
142
+ }
143
+
144
+ public function all_plugins( $plugins ) {
145
+ foreach ( $plugins as $key => $value ) {
146
+ $plugin_slug = basename( $key, '.php' );
147
+ if ( 'better-wp-security' === $plugin_slug || 'ithemes-security-pro' === $plugin_slug ) {
148
+ unset( $plugins[ $key ] );
149
+ }
150
+ }
151
+
152
+ return $plugins;
153
+ }
154
+
155
+ public function remove_menu() {
156
+ remove_menu_page( 'itsec' );
157
+ }
158
+
159
+ function save_settings() {
160
+
161
+ if ( ! class_exists( 'ITSEC_Lib' ) ) {
162
+ require( ITSEC_Core::get_core_dir() . '/core/class-itsec-lib.php' );
163
+ }
164
+
165
+ $_itsec_modules = array(
166
+ 'global',
167
+ 'away-mode',
168
+ 'backup',
169
+ 'hide-backend',
170
+ 'ipcheck',
171
+ 'ban-users',
172
+ 'brute-force',
173
+ 'file-change',
174
+ '404-detection',
175
+ 'network-brute-force',
176
+ 'ssl',
177
+ 'strong-passwords',
178
+ 'system-tweaks',
179
+ 'wordpress-tweaks',
180
+ 'multisite-tweaks',
181
+ 'notification-center'
182
+ //'salts',
183
+ //'content-directory',
184
+ );
185
+
186
+ $require_permalinks = false;
187
+ $updated = false;
188
+ $errors = array();
189
+ $nbf_settings = array();
190
+
191
+ $update_settings = maybe_unserialize( base64_decode( $_POST['settings'] ) );
192
+
193
+ foreach($update_settings as $module => $settings) {
194
+ $do_not_save = false;
195
+ if (in_array($module, $_itsec_modules)) {
196
+ if ($module == 'wordpress-salts') {
197
+ $settings['last_generated'] = ITSEC_Modules::get_setting( $module, 'last_generated' ); // not update
198
+ } else if ($module == 'global') {
199
+ $keep_olds = array( 'did_upgrade', 'log_info', 'show_new_dashboard_notice', 'show_security_check' , 'nginx_file' );
200
+ foreach($keep_olds as $key) {
201
+ $settings[$key] = ITSEC_Modules::get_setting( $module, $key ); // not update
202
+ }
203
+
204
+ if (!isset($settings['log_location']) || empty($settings['log_location']) ) {
205
+ $settings['log_location'] = ITSEC_Modules::get_setting( $module, 'log_location' );
206
+ } else {
207
+ $result = $this->validate_directory('log_location', $settings['log_location']);
208
+ if ($result !== true) {
209
+ $errors[] = $result;
210
+ $settings['log_location'] = ITSEC_Modules::get_setting( $module, 'log_location' ); // no change
211
+ }
212
+ }
213
+
214
+ } else if ($module == 'backup') {
215
+ if (!isset($settings['location']) || empty($settings['location']) ) {
216
+ $settings['location'] = ITSEC_Modules::get_setting( $module, 'location' );
217
+ } else {
218
+ $result = $this->validate_directory('location', $settings['location']);
219
+ if ($result !== true) {
220
+ $errors[] = $result;
221
+ $settings['location'] = ITSEC_Modules::get_setting( $module, 'location' ); // no change
222
+ }
223
+ }
224
+ if (!isset($settings['exclude']) ) {
225
+ $settings['exclude'] = ITSEC_Modules::get_setting( $module, 'exclude' );;
226
+ }
227
+ } else if ($module == 'hide-backend') {
228
+ if (isset($settings['enabled']) && !empty($settings['enabled'])) {
229
+ $permalink_structure = get_option( 'permalink_structure', false );
230
+ if ( empty( $permalink_structure ) && ! is_multisite() ) {
231
+ $errors[] = __( 'You must change <strong>WordPress permalinks</strong> to a setting other than "Plain" in order to use "Hide Backend" feature.', 'better-wp-security' );
232
+ $require_permalinks = true;
233
+ $do_not_save = true;
234
+ }
235
+ }
236
+ } else if ($module == 'network-brute-force') {
237
+
238
+ if ( isset( $settings['email'] ) ) {
239
+ $result = $this->activate_api_key($settings);
240
+ if ($result === false) {
241
+ $nbf_settings = $settings;
242
+ $errors[] = 'Error: Active iThemes Network Brute Force Protection Api Key';
243
+ } else {
244
+ $nbf_settings = $result;
245
+ }
246
+ } else {
247
+ $previous_settings = ITSEC_Modules::get_settings( $module );
248
+ // update 'enable_ban' field only
249
+ if (isset($settings['enable_ban'])) {
250
+ $previous_settings['enable_ban'] = $settings['enable_ban'];
251
+ $nbf_settings = $previous_settings;
252
+ } else {
253
+ $do_not_save = true;
254
+ $nbf_settings = $previous_settings;
255
+ }
256
+ }
257
+ $settings = $nbf_settings;
258
+ } else if ($module == 'notification-center') {
259
+ $current_settings = ITSEC_Modules::get_settings( $module );
260
+ if (isset($settings['notifications'])) {
261
+ $update_fields = array( 'schedule', 'enabled', 'subject');
262
+ if (isset($_POST['is_individual']) && $_POST['is_individual']) {
263
+ $update_fields = array_merge($update_fields, array('user_list', 'email_list'));
264
+ }
265
+ foreach ($settings['notifications'] as $key => $val) {
266
+ foreach ($update_fields as $field) {
267
+ if(isset($val[$field])) {
268
+ $current_settings['notifications'][$key][$field] = $val[$field];
269
+ }
270
+ }
271
+ }
272
+ $updated = true;
273
+ ITSEC_Modules::set_settings( $module, $current_settings );
274
+ }
275
+ continue;
276
+ }
277
+
278
+ if ( !$do_not_save ) {
279
+ ITSEC_Modules::set_settings( $module, $settings );
280
+ $updated = true;
281
+ }
282
+ }
283
+ }
284
+
285
+ if ( isset( $update_settings['itsec_active_modules'] ) ) {
286
+ $current_val = get_site_option( 'itsec_active_modules', array() );
287
+ foreach ($update_settings['itsec_active_modules'] as $mod => $val) {
288
+ $current_val[$mod] = $val;
289
+ }
290
+ update_site_option( 'itsec_active_modules', $current_val );
291
+ }
292
+
293
+ require_once( ITSEC_Core::get_core_dir() . '/lib/class-itsec-lib-config-file.php' );
294
+
295
+ $values = array(
296
+ 'permalink_structure' => get_option( 'permalink_structure' ),
297
+ 'is_multisite' => is_multisite() ? 1 : 0,
298
+ 'users_can_register' => get_site_option( 'users_can_register' ) ? 1 : 0,
299
+ 'server_nginx' => ( ITSEC_Lib::get_server() === 'nginx' ) ? 1 : 0,
300
+ 'has_ssl' => ITSEC_Lib::get_ssl_support_probability(),
301
+ 'jquery_version' => ITSEC_Modules::get_setting( 'wordpress-tweaks', 'jquery_version' ),
302
+ 'server_rules' => ITSEC_Lib_Config_File::get_server_config(),
303
+ 'config_rules' => ITSEC_Lib_Config_File::get_wp_config(),
304
+ 'lockouts_host' => $this->get_lockouts( 'host', true ),
305
+ 'lockouts_user' => $this->get_lockouts( 'user', true ),
306
+ 'lockouts_username' => $this->get_lockouts( 'username', true ),
307
+ 'default_log_location' => ITSEC_Modules::get_default( 'global', 'log_location' ),
308
+ 'default_location' => ITSEC_Modules::get_default( 'backup', 'location' ),
309
+ 'excludable_tables' => $this->get_excludable_tables(),
310
+ 'users_and_roles' => $this->get_available_admin_users_and_roles()
311
+ );
312
+
313
+ $return = array(
314
+ 'site_status' => $values
315
+ );
316
+
317
+ if ($require_permalinks) {
318
+ $return['require_permalinks'] = 1;
319
+ }
320
+
321
+ $return['nbf_settings'] = $nbf_settings;
322
+
323
+ if (!empty($errors)) {
324
+ $return['extra_message'] = $errors;
325
+ }
326
+
327
+ if ($updated)
328
+ $return['result'] = 'success';
329
+ else
330
+ $return['error'] = __('Not Updated', 'mainwp-child' );
331
+
332
+ return $return;
333
+ }
334
+
335
+ public static function activate_network_brute_force() {
336
+ $data = maybe_unserialize( base64_decode( $_POST['data'] ) );
337
+ $information = array();
338
+ if (is_array($data)) {
339
+ $settings = ITSEC_Modules::get_settings( 'network-brute-force' );
340
+ $settings['email'] = $data['email'];
341
+ $settings['updates_optin'] = $data['updates_optin'];
342
+ $settings['api_nag'] = false;
343
+ $results = ITSEC_Modules::set_settings( 'network-brute-force', $settings );
344
+ if ( is_wp_error( $results ) ) {
345
+ $information['error'] = 'Error: Active iThemes Network Brute Force Protection Api Key';
346
+ } else if ( $results['saved'] ) {
347
+ ITSEC_Modules::activate( 'network-brute-force' );
348
+ $nbf_settings = ITSEC_Modules::get_settings( 'network-brute-force' );
349
+ // ITSEC_Response::set_response( '<p>' . __( 'Your site is now using Network Brute Force Protection.', 'better-wp-security' ) . '</p>' );
350
+ }
351
+ }
352
+ if ($nbf_settings !== null) {
353
+ $information['nbf_settings'] = $nbf_settings;
354
+ $information['result'] = 'success';
355
+ }
356
+ return $information;
357
+ }
358
+
359
+ private function validate_directory($name, $folder) {
360
+ require_once( ITSEC_Core::get_core_dir() . 'lib/class-itsec-lib-directory.php' );
361
+ $error = null;
362
+ if ( ! ITSEC_Lib_Directory::is_dir( $folder ) ) {
363
+ $result = ITSEC_Lib_Directory::create( $folder );
364
+
365
+ if ( is_wp_error( $result ) ) {
366
+ $error = sprintf( _x( 'The directory supplied in %1$s cannot be used as a valid directory. %2$s', '%1$s is the input name. %2$s is the error message.', 'better-wp-security' ), $name, $result->get_error_message() );
367
+ }
368
+ }
369
+
370
+ if ( empty( $error ) && ! ITSEC_Lib_Directory::is_writable( $folder ) ) {
371
+ $error = sprintf( __( 'The directory supplied in %1$s is not writable. Please select a directory that can be written to.', 'better-wp-security' ), $name );
372
+ }
373
+
374
+ if ( empty( $error ) ) {
375
+ ITSEC_Lib_Directory::add_file_listing_protection( $folder );
376
+ return true;
377
+ } else {
378
+ return $error;
379
+ }
380
+ }
381
+
382
+ private function activate_api_key($settings) {
383
+ global $mainwp_itsec_modules_path;
384
+ require_once ( $mainwp_itsec_modules_path . 'ipcheck/utilities.php' );
385
+
386
+ $key = ITSEC_Network_Brute_Force_Utilities::get_api_key( $settings['email'], $settings['updates_optin'] );
387
+ if ( is_wp_error( $key ) ) {
388
+ return false;
389
+ // $this->set_can_save( false );
390
+ // $this->add_error( $key );
391
+ } else {
392
+ $secret = ITSEC_Network_Brute_Force_Utilities::activate_api_key( $key );
393
+
394
+ if ( is_wp_error( $secret ) ) {
395
+ return false;
396
+ // $this->set_can_save( false );
397
+ // $this->add_error( $secret );
398
+ } else {
399
+ $settings['api_key'] = $key;
400
+ $settings['api_secret'] = $secret;
401
+
402
+ $settings['api_nag'] = false;
403
+
404
+ ITSEC_Response::reload_module( 'network-brute-force' );
405
+ }
406
+ }
407
+ unset( $settings['email'] );
408
+ return $settings;
409
+ }
410
+ function backup_status() {
411
+ $status = 0;
412
+ if ( ! is_multisite() && class_exists( 'backupbuddy_api' ) && count( backupbuddy_api::getSchedules() ) >= 1 ) {
413
+ $status = 1;
414
+ } elseif ( ! is_multisite() && class_exists( 'backupbuddy_api' ) ) {
415
+ $status = 2;
416
+ } elseif ( $this->has_backup() === true && $this->scheduled_backup() === true ) {
417
+ $status = 3;
418
+ } elseif ( $this->has_backup() === true ) {
419
+ $status = 4;
420
+ }
421
+
422
+ return $status;
423
+ }
424
+
425
+ public function has_backup() {
426
+ $has_backup = false;
427
+
428
+ return apply_filters( 'itsec_has_external_backup', $has_backup );
429
+ }
430
+
431
+ public function scheduled_backup() {
432
+ $sceduled_backup = false;
433
+
434
+ return apply_filters( 'itsec_scheduled_external_backup', $sceduled_backup );
435
+ }
436
+
437
+ public function whitelist() {
438
+
439
+ global $itsec_globals;
440
+ $ip = $_POST['ip'];
441
+ $add_temp = false;
442
+ $temp_ip = get_site_option( 'itsec_temp_whitelist_ip' );
443
+ if ( false !== $temp_ip ) {
444
+ if ( ( $temp_ip['exp'] < $itsec_globals['current_time'] ) || ( $temp_ip['exp'] !== $ip ) ) {
445
+ delete_site_option( 'itsec_temp_whitelist_ip' );
446
+ $add_temp = true;
447
+ }
448
+ } else {
449
+ $add_temp = true;
450
+ }
451
+
452
+ if ( false === $add_temp ) {
453
+ return array( 'error' => 'Not Updated' );
454
+ } else {
455
+ $response = array(
456
+ 'ip' => $ip,
457
+ 'exp' => $itsec_globals['current_time'] + 86400,
458
+ );
459
+ add_site_option( 'itsec_temp_whitelist_ip', $response );
460
+ $response['exp_diff'] = human_time_diff( $itsec_globals['current_time'], $response['exp'] );
461
+ $response['message1'] = __( 'Your IP Address', 'better-wp-security' );
462
+ $response['message2'] = __( 'is whitelisted for', 'better-wp-security' );
463
+
464
+ return $response;
465
+ }
466
+
467
+ }
468
+
469
+ function whitelist_release() {
470
+ delete_site_option( 'itsec_temp_whitelist_ip' );
471
+
472
+ return 'success';
473
+ }
474
+
475
+ function backup_db() {
476
+ global $itsec_backup, $mainwp_itsec_modules_path;
477
+
478
+ if ( ! isset( $itsec_backup ) ) {
479
+ require_once ( $mainwp_itsec_modules_path . 'backup/class-itsec-backup.php' );
480
+ $itsec_backup = new ITSEC_Backup();
481
+ $itsec_backup->run();
482
+ }
483
+
484
+ $return = array();
485
+
486
+ $str_error = '';
487
+ $result = $itsec_backup->do_backup( true );
488
+
489
+ if ( is_wp_error( $result ) ) {
490
+ $errors = ITSEC_Response::get_error_strings( $result );
491
+
492
+ foreach ( $errors as $error ) {
493
+ $str_error .= $error . '<br />';
494
+ }
495
+ } else if ( is_string( $result ) ) {
496
+ $return['result'] = 'success';
497
+ $return['message'] = $result;
498
+ } else {
499
+ $str_error = sprintf( __( 'The backup request returned an unexpected response. It returned a response of type <code>%1$s</code>.', 'better-wp-security' ), gettype( $result ) ) ;
500
+ }
501
+
502
+ if (!empty($str_error)) {
503
+ $return['error'] = $str_error;
504
+ }
505
+
506
+ return $return;
507
+ }
508
+
509
+
510
+ private function wordpress_salts() {
511
+ global $mainwp_itsec_modules_path;
512
+ if ( ! class_exists( 'ITSEC_WordPress_Salts_Utilities' ) ) {
513
+ require( $mainwp_itsec_modules_path . 'salts/utilities.php' );
514
+ }
515
+ $result = ITSEC_WordPress_Salts_Utilities::generate_new_salts();
516
+ $str_error = '';
517
+ if ( is_wp_error( $result ) ) {
518
+ $errors = ITSEC_Response::get_error_strings( $result );
519
+
520
+ foreach ( $errors as $error ) {
521
+ $str_error .= $error . '<br />';
522
+ }
523
+ } else {
524
+ $return['result'] = 'success';
525
+ $return['message'] = __( 'The WordPress salts were successfully regenerated.', 'better-wp-security' ) ;
526
+ $last_generated = ITSEC_Core::get_current_time_gmt();
527
+ ITSEC_Modules::set_setting( 'wordpress-salts', 'last_generated', $last_generated );
528
+ }
529
+ if (!empty($str_error)) {
530
+ $return['error'] = $str_error;
531
+ }
532
+ return $return;
533
+ }
534
+
535
+ private function file_permissions() {
536
+ require_once( ITSEC_Core::get_core_dir() . '/lib/class-itsec-lib-config-file.php' );
537
+
538
+ $wp_upload_dir = ITSEC_Core::get_wp_upload_dir();
539
+
540
+ $path_data = array(
541
+ array(
542
+ ABSPATH,
543
+ 0755,
544
+ ),
545
+ array(
546
+ ABSPATH . WPINC,
547
+ 0755,
548
+ ),
549
+ array(
550
+ ABSPATH . 'wp-admin',
551
+ 0755,
552
+ ),
553
+ array(
554
+ ABSPATH . 'wp-admin/js',
555
+ 0755,
556
+ ),
557
+ array(
558
+ WP_CONTENT_DIR,
559
+ 0755,
560
+ ),
561
+ array(
562
+ get_theme_root(),
563
+ 0755,
564
+ ),
565
+ array(
566
+ WP_PLUGIN_DIR,
567
+ 0755
568
+ ),
569
+ array(
570
+ $wp_upload_dir['basedir'],
571
+ 0755,
572
+ ),
573
+ array(
574
+ ITSEC_Lib_Config_File::get_wp_config_file_path(),
575
+ 0444,
576
+ ),
577
+ array(
578
+ ITSEC_Lib_Config_File::get_server_config_file_path(),
579
+ 0444,
580
+ ),
581
+ );
582
+
583
+
584
+ $rows = array();
585
+
586
+ foreach ( $path_data as $path ) {
587
+ $row = array();
588
+
589
+ list( $path, $suggested_permissions ) = $path;
590
+
591
+ $display_path = preg_replace( '/^' . preg_quote( ABSPATH, '/' ) . '/', '', $path );
592
+ $display_path = ltrim( $display_path, '/' );
593
+
594
+ if ( empty( $display_path ) ) {
595
+ $display_path = '/';
596
+ }
597
+
598
+ $row[] = $display_path;
599
+ $row[] = sprintf( '%o', $suggested_permissions );
600
+
601
+ $permissions = fileperms( $path ) & 0777;
602
+ $row[] = sprintf( '%o', $permissions );
603
+
604
+ if ( ! $permissions || $permissions != $suggested_permissions ) {
605
+ $row[] = __( 'WARNING', 'better-wp-security' );
606
+ $row[] = '<div style="background-color: #FEFF7F; border: 1px solid #E2E2E2;">&nbsp;&nbsp;&nbsp;</div>';
607
+ } else {
608
+ $row[] = __( 'OK', 'better-wp-security' );
609
+ $row[] = '<div style="background-color: #22EE5B; border: 1px solid #E2E2E2;">&nbsp;&nbsp;&nbsp;</div>';
610
+ }
611
+
612
+ $rows[] = $row;
613
+ }
614
+
615
+
616
+ $class = 'entry-row';
617
+ ob_start();
618
+ ?>
619
+ <p><input type="button" id="itsec-file-permissions-reload_file_permissions" name="file-permissions[reload_file_permissions]" class="button-primary itsec-reload-module" value="<?php _e('Reload File Permissions Details', 'mainwp-child'); ?>"></p>
620
+ <table class="widefat">
621
+ <thead>
622
+ <tr>
623
+ <th><?php _e( 'Relative Path', 'better-wp-security' ); ?></th>
624
+ <th><?php _e( 'Suggestion', 'better-wp-security' ); ?></th>
625
+ <th><?php _e( 'Value', 'better-wp-security' ); ?></th>
626
+ <th><?php _e( 'Result', 'better-wp-security' ); ?></th>
627
+ <th><?php _e( 'Status', 'better-wp-security' ); ?></th>
628
+ </tr>
629
+ </thead>
630
+ <tfoot>
631
+ <tr>
632
+ <th><?php _e( 'Relative Path', 'better-wp-security' ); ?></th>
633
+ <th><?php _e( 'Suggestion', 'better-wp-security' ); ?></th>
634
+ <th><?php _e( 'Value', 'better-wp-security' ); ?></th>
635
+ <th><?php _e( 'Result', 'better-wp-security' ); ?></th>
636
+ <th><?php _e( 'Status', 'better-wp-security' ); ?></th>
637
+ </tr>
638
+ </tfoot>
639
+ <tbody>
640
+ <?php foreach ( $rows as $row ) : ?>
641
+ <tr class="<?php echo $class; ?>">
642
+ <?php foreach ( $row as $column ) : ?>
643
+ <td><?php echo $column; ?></td>
644
+ <?php endforeach; ?>
645
+ </tr>
646
+ <?php $class = ( 'entry-row' === $class ) ? 'entry-row alternate' : 'entry-row'; ?>
647
+ <?php endforeach; ?>
648
+ </tbody>
649
+ </table>
650
+ <br />
651
+ <?php
652
+ $html = ob_get_clean();
653
+ return array('html' => $html);
654
+ }
655
+
656
+ public function file_change() {
657
+ global $mainwp_itsec_modules_path;
658
+ if ( ! class_exists( 'ITSEC_File_Change_Scanner' ) ) {
659
+ require_once( $mainwp_itsec_modules_path . 'file-change/scanner.php' );
660
+ }
661
+ $result = ITSEC_File_Change_Scanner::run_scan( false );
662
+ if ($result === false || $result === true || $result === -1) {
663
+ $return['result'] = 'success';
664
+ $return['scan_result'] = $result;
665
+ }
666
+ return $return;
667
+ }
668
+
669
+ function admin_user() {
670
+
671
+ $settings = $_POST['settings'];
672
+
673
+ if (!is_array($settings))
674
+ $settings = array();
675
+
676
+ $new_username = isset( $settings['new_username'] ) ? $settings['new_username'] : '';
677
+ $change_id = isset( $settings['change_id'] ) && $settings['change_id'] ? true : false;
678
+
679
+
680
+ //load utility functions
681
+ if ( ! class_exists( 'ITSEC_Lib' ) ) {
682
+ global $itsec_globals;
683
+ require( ITSEC_Core::get_core_dir() . '/core/class-itsec-lib.php' );
684
+ }
685
+
686
+ $username_exists = username_exists( 'admin' );
687
+ $user_id_exists = ITSEC_Lib::user_id_exists( 1 );
688
+ $msg = '';
689
+ if ( strlen( $new_username ) >= 1) {
690
+ global $current_user;
691
+ if ( ! $username_exists ) {
692
+ $msg = __( 'Admin user already changes.', 'mainwp-child' );
693
+ } else if ($current_user->user_login == 'admin') {
694
+ $return['result'] = 'CHILD_ADMIN';
695
+ return $return;
696
+ }
697
+ }
698
+
699
+
700
+ if ( true === $change_id && ! $user_id_exists ) {
701
+ if ( ! empty( $msg ) ) {
702
+ $msg .= '<br/>';
703
+ }
704
+ $msg .= __( 'Admin user ID already changes.', 'mainwp-child' );
705
+ }
706
+
707
+ // if ( $change_id ) {
708
+ // $user = get_user_by( 'login', $new_username );
709
+ // if ( $user && 1 === (int) $user->ID ) {
710
+ // $return['result'] = 'CHILD_ADMIN';
711
+ // return $return;
712
+ // }
713
+ // }
714
+
715
+ $admin_success = true;
716
+ $return = array();
717
+
718
+ if ( strlen( $new_username ) >= 1 && $username_exists ) {
719
+ $admin_success = $this->change_admin_user( $new_username, $change_id );
720
+ } elseif ( true === $change_id && $user_id_exists ) {
721
+ $admin_success = $this->change_admin_user( null, $change_id );
722
+ }
723
+
724
+ $return['message'] = $msg;
725
+ if ( false === $admin_success ) {
726
+ $return['result'] = 'fail';
727
+ } else {
728
+ $return['result'] = 'success';
729
+ }
730
+ return $return;
731
+ }
732
+
733
+ private function change_admin_user( $username = null, $id = false ) {
734
+
735
+ global $wpdb;
736
+ $itsec_files = ITSEC_Core::get_itsec_files();
737
+
738
+ // do not need to check this
739
+ //if ( $itsec_files->get_file_lock( 'admin_user' ) ) { //make sure it isn't already running
740
+
741
+ //sanitize the username
742
+ $new_user = sanitize_text_field( $username );
743
+
744
+ //Get the full user object
745
+ $user_object = get_user_by( 'id', '1' );
746
+
747
+ if ( null !== $username && validate_username( $new_user ) && false === username_exists( $new_user ) ) { //there is a valid username to change
748
+
749
+ if ( true === $id ) { //we're changing the id too so we'll set the username
750
+
751
+ $user_login = $new_user;
752
+
753
+ } else { // we're only changing the username
754
+
755
+ //query main user table
756
+ $wpdb->query( "UPDATE `" . $wpdb->users . "` SET user_login = '" . esc_sql( $new_user ) . "' WHERE user_login='admin';" );
757
+
758
+ if ( is_multisite() ) { //process sitemeta if we're in a multi-site situation
759
+
760
+ $oldAdmins = $wpdb->get_var( 'SELECT meta_value FROM `' . $wpdb->sitemeta . "` WHERE meta_key = 'site_admins'" );
761
+ $newAdmins = str_replace( '5:"admin"', strlen( $new_user ) . ':"' . esc_sql( $new_user ) . '"', $oldAdmins );
762
+ $wpdb->query( $wpdb->prepare( 'UPDATE `' . $wpdb->sitemeta . "` SET meta_value = %s WHERE meta_key = 'site_admins'", $newAdmins ) );
763
+ }
764
+
765
+ wp_clear_auth_cookie();
766
+ $itsec_files->release_file_lock( 'admin_user' );
767
+
768
+ return true;
769
+
770
+ }
771
+ } elseif ( null !== $username ) { //username didn't validate
772
+
773
+ $itsec_files->release_file_lock( 'admin_user' );
774
+
775
+ return false;
776
+
777
+ } else { //only changing the id
778
+
779
+ $user_login = $user_object->user_login;
780
+
781
+ }
782
+
783
+ if ( true === $id ) { //change the user id
784
+
785
+ $wpdb->query( 'DELETE FROM `' . $wpdb->users . '` WHERE ID = 1;' );
786
+
787
+ $wpdb->insert( $wpdb->users, array(
788
+ 'user_login' => $user_login,
789
+ 'user_pass' => $user_object->user_pass,
790
+ 'user_nicename' => $user_object->user_nicename,
791
+ 'user_email' => $user_object->user_email,
792
+ 'user_url' => $user_object->user_url,
793
+ 'user_registered' => $user_object->user_registered,
794
+ 'user_activation_key' => $user_object->user_activation_key,
795
+ 'user_status' => $user_object->user_status,
796
+ 'display_name' => $user_object->display_name,
797
+ ) );
798
+
799
+ if ( is_multisite() && null !== $username && validate_username( $new_user ) ) { //process sitemeta if we're in a multi-site situation
800
+
801
+ $oldAdmins = $wpdb->get_var( 'SELECT meta_value FROM `' . $wpdb->sitemeta . "` WHERE meta_key = 'site_admins'" );
802
+ $newAdmins = str_replace( '5:"admin"', strlen( $new_user ) . ':"' . esc_sql( $new_user ) . '"', $oldAdmins );
803
+ $wpdb->query( 'UPDATE `' . $wpdb->sitemeta . "` SET meta_value = '" . esc_sql( $newAdmins ) . "' WHERE meta_key = 'site_admins'" );
804
+
805
+ }
806
+
807
+ $new_user = $wpdb->insert_id;
808
+
809
+ $wpdb->query( $wpdb->prepare( 'UPDATE `' . $wpdb->posts . "` SET post_author = %s WHERE post_author = 1;", $new_user ) );
810
+ $wpdb->query( $wpdb->prepare( 'UPDATE `' . $wpdb->usermeta . "` SET user_id = %s WHERE user_id = 1;", $new_user ) );
811
+ $wpdb->query( $wpdb->prepare( 'UPDATE `' . $wpdb->comments . "` SET user_id = %s WHERE user_id = 1;", $new_user ) );
812
+ $wpdb->query( $wpdb->prepare( 'UPDATE `' . $wpdb->links . "` SET link_owner = %s WHERE link_owner = 1;", $new_user ) );
813
+
814
+ wp_clear_auth_cookie();
815
+ $itsec_files->release_file_lock( 'admin_user' );
816
+
817
+ return true;
818
+
819
+ }
820
+ //}
821
+
822
+ return false;
823
+
824
+ }
825
+
826
+ public function build_wpconfig_rules( $rules_array, $input = null ) {
827
+ //Get the rules from the database if input wasn't sent
828
+ if ( null === $input ) {
829
+ return $rules_array;
830
+ }
831
+
832
+ $new_dir = trailingslashit( ABSPATH ) . $input;
833
+
834
+ $rules[] = array(
835
+ 'type' => 'add',
836
+ 'search_text' => '//Do not delete these. Doing so WILL break your site.',
837
+ 'rule' => '//Do not delete these. Doing so WILL break your site.',
838
+ );
839
+
840
+ $rules[] = array(
841
+ 'type' => 'add',
842
+ 'search_text' => 'WP_CONTENT_URL',
843
+ 'rule' => "define( 'WP_CONTENT_URL', '" . trailingslashit( get_option( 'siteurl' ) ) . $input . "' );",
844
+ );
845
+
846
+ $rules[] = array(
847
+ 'type' => 'add',
848
+ 'search_text' => 'WP_CONTENT_DIR',
849
+ 'rule' => "define( 'WP_CONTENT_DIR', '" . $new_dir . "' );",
850
+ );
851
+
852
+ $rules_array[] = array( 'type' => 'wpconfig', 'name' => 'Content Directory', 'rules' => $rules );
853
+
854
+ return $rules_array;
855
+
856
+ }
857
+
858
+
859
+ public function change_database_prefix() {
860
+ global $mainwp_itsec_modules_path;
861
+ require_once( $mainwp_itsec_modules_path . 'database-prefix/utility.php' );
862
+ $str_error = '';
863
+ $return = array();
864
+
865
+ if ( isset( $_POST['change_prefix'] ) && 'yes' === $_POST['change_prefix'] ) {
866
+ $result = ITSEC_Database_Prefix_Utility::change_database_prefix();
867
+ $return = $result['errors'];
868
+ if (is_array($result['errors'])) {
869
+ foreach ($result['errors'] as $error) {
870
+ $arr_errors = ITSEC_Response::get_error_strings( $error );
871
+ foreach ( $arr_errors as $er ) {
872
+ $str_error .= $er . '<br />';
873
+ }
874
+ }
875
+ }
876
+
877
+ ITSEC_Response::reload_module( 'database-prefix' );
878
+
879
+ if ( false === $result['new_prefix'] ) {
880
+ $return['error'] = $str_error;
881
+ } else {
882
+ $return['result'] = 'success';
883
+ $return['message'] = sprintf( __( 'The database table prefix was successfully changed to <code>%1$s</code>.', 'better-wp-security' ), $result['new_prefix'] );
884
+
885
+ }
886
+ }
887
+ return $return;
888
+ }
889
+
890
+ public function api_key() {
891
+ $settings = get_site_option( 'itsec_ipcheck' );
892
+ if ( ! is_array( $settings ) ) {
893
+ $settings = array();
894
+ }
895
+ $settings['reset'] = true;
896
+ $return = array();
897
+ if ( update_site_option( 'itsec_ipcheck', $settings ) ) {
898
+ $return['result'] = 'success';
899
+ } else {
900
+ $return['result'] = 'nochange';
901
+ }
902
+
903
+ return $return;
904
+ }
905
+
906
+ public function reset_api_key() {
907
+
908
+ $defaults = ITSEC_Modules::get_defaults( 'network-brute-force' );
909
+ $results = ITSEC_Modules::set_settings( 'network-brute-force', $defaults );
910
+
911
+ ITSEC_Response::set_response( $results['saved'] );
912
+ ITSEC_Response::add_errors( $results['errors'] );
913
+ ITSEC_Response::add_messages( $results['messages'] );
914
+
915
+ $information = array();
916
+ if ( $results['saved'] ) {
917
+ $information['result'] = 'success';
918
+ $information['nbf_settings'] = ITSEC_Modules::get_settings( 'network-brute-force');
919
+ } else if ( empty( $results['errors'] ) ) {
920
+ $information['error_reset_api'] = 1;
921
+ }
922
+ return $information;
923
+ }
924
+
925
+ public function malware_scan() {
926
+ global $mainwp_itsec_modules_path;
927
+
928
+ if ( ! class_exists( 'ITSEC_Malware_Scanner' ) ) {
929
+ require_once( $mainwp_itsec_modules_path . 'malware/class-itsec-malware-scanner.php' );
930
+ require_once( $mainwp_itsec_modules_path . 'malware/class-itsec-malware-scan-results-template.php' );
931
+ }
932
+
933
+ $response = array();
934
+ if ( ! ITSEC_Core::current_user_can_manage() ) {
935
+ $response['error'] = 'The currently logged in user does not have sufficient permissions to run this scan.';
936
+ } else {
937
+ $results = ITSEC_Malware_Scanner::scan();
938
+ $response['html'] = ITSEC_Malware_Scan_Results_Template::get_html( $results, true );
939
+ }
940
+
941
+ return $response;
942
+ }
943
+
944
+ public function malware_get_scan_results() {
945
+
946
+ global $mainwp_itsec_modules_path;
947
+ if ( ! class_exists( 'ITSEC_Malware_Scanner' ) ) {
948
+ require_once( $mainwp_itsec_modules_path . 'malware/class-itsec-malware-scanner.php' );
949
+ require_once( $mainwp_itsec_modules_path . 'malware/class-itsec-malware-scan-results-template.php' );
950
+ }
951
+ $response = array();
952
+ $results= ITSEC_Malware_Scanner::scan();
953
+ $response['html'] = ITSEC_Malware_Scan_Results_Template::get_html( $results, true );
954
+ return $response;
955
+ }
956
+
957
+ public function purge_logs() {
958
+ global $wpdb;
959
+ $wpdb->query( 'DELETE FROM `' . $wpdb->base_prefix . 'itsec_log`;' );
960
+
961
+ return array( 'result' => 'success' );
962
+ }
963
+
964
+
965
+ public function get_lockouts( $type = 'all', $current = false ) {
966
+
967
+ global $wpdb, $itsec_globals;
968
+
969
+ if ( 'all' !== $type || true === $current ) {
970
+ $where = ' WHERE ';
971
+ } else {
972
+ $where = '';
973
+ }
974
+
975
+ switch ( $type ) {
976
+
977
+ case 'host':
978
+ $type_statement = "`lockout_host` IS NOT NULL && `lockout_host` != ''";
979
+ break;
980
+ case 'user':
981
+ $type_statement = '`lockout_user` != 0';
982
+ break;
983
+ case 'username':
984
+ $type_statement = "`lockout_username` IS NOT NULL && `lockout_username` != ''";
985
+ break;
986
+ default:
987
+ $type_statement = '';
988
+ break;
989
+
990
+ }
991
+
992
+ if ( true === $current ) {
993
+
994
+ if ( '' !== $type_statement ) {
995
+ $and = ' AND ';
996
+ } else {
997
+ $and = '';
998
+ }
999
+
1000
+ $active = $and . " `lockout_active`=1 AND `lockout_expire_gmt` > '" . date( 'Y-m-d H:i:s', $itsec_globals['current_time_gmt'] ) . "'";
1001
+
1002
+ } else {
1003
+
1004
+ $active = '';
1005
+
1006
+ }
1007
+
1008
+ $results = $wpdb->get_results( 'SELECT * FROM `' . $wpdb->base_prefix . 'itsec_lockouts`' . $where . $type_statement . $active . ';', ARRAY_A );
1009
+ $output = array();
1010
+ if ( is_array( $results ) && count( $results ) > 0 ) {
1011
+ switch ( $type ) {
1012
+ case 'host':
1013
+ foreach ( $results as $val ) {
1014
+ $output[] = array(
1015
+ 'lockout_id' => $val['lockout_id'],
1016
+ 'lockout_host' => $val['lockout_host'],
1017
+ 'lockout_expire_gmt' => $val['lockout_expire_gmt'],
1018
+ );
1019
+ }
1020
+ break;
1021
+ case 'user':
1022
+ foreach ( $results as $val ) {
1023
+ $output[] = array(
1024
+ 'lockout_id' => $val['lockout_id'],
1025
+ 'lockout_user' => $val['lockout_user'],
1026
+ 'lockout_expire_gmt' => $val['lockout_expire_gmt'],
1027
+ );
1028
+ }
1029
+ break;
1030
+ case 'username':
1031
+ foreach ( $results as $val ) {
1032
+ $output[] = array(
1033
+ 'lockout_id' => $val['lockout_id'],
1034
+ 'lockout_username' => $val['lockout_username'],
1035
+ 'lockout_expire_gmt' => $val['lockout_expire_gmt'],
1036
+ );
1037
+ }
1038
+ break;
1039
+ default:
1040
+ break;
1041
+ }
1042
+ }
1043
+
1044
+ return $output;
1045
+ }
1046
+
1047
+ public function release_lockout() {
1048
+ global $wpdb;
1049
+
1050
+ if ( ! class_exists( 'ITSEC_Lib' ) ) {
1051
+ require( ITSEC_Core::get_core_dir() . '/core/class-itsec-lib.php' );
1052
+ }
1053
+
1054
+ $lockout_ids = $_POST['lockout_ids'];
1055
+ if ( ! is_array( $lockout_ids ) ) {
1056
+ $lockout_ids = array();
1057
+ }
1058
+
1059
+ $type = 'updated';
1060
+ $message = __( 'The selected lockouts have been cleared.', 'better-wp-security' );
1061
+
1062
+ foreach ( $lockout_ids as $value ) {
1063
+ $wpdb->update(
1064
+ $wpdb->base_prefix . 'itsec_lockouts',
1065
+ array(
1066
+ 'lockout_active' => 0,
1067
+ ),
1068
+ array(
1069
+ 'lockout_id' => intval( $value ),
1070
+ )
1071
+ );
1072
+ }
1073
+
1074
+ ITSEC_Lib::clear_caches();
1075
+
1076
+ if ( ! is_multisite() ) {
1077
+ if ( ! function_exists( 'add_settings_error' ) ) {
1078
+ require_once( ABSPATH . '/wp-admin/includes/template.php' );
1079
+ }
1080
+
1081
+ add_settings_error( 'itsec', esc_attr( 'settings_updated' ), $message, $type );
1082
+ }
1083
+
1084
+ return array(
1085
+ 'result' => 'success',
1086
+ );
1087
+ }
1088
+
1089
+ public function update_module_status() {
1090
+
1091
+ $active_modules = $_POST['active_modules'];
1092
+
1093
+ if (!is_array($active_modules))
1094
+ $active_modules = array();
1095
+
1096
+ $current_val = get_site_option( 'itsec_active_modules', array() );
1097
+ foreach ($active_modules as $mod => $val) {
1098
+ $current_val[$mod] = $val;
1099
+ }
1100
+
1101
+ update_site_option( 'itsec_active_modules', $current_val );
1102
+ return array('result' => 'success');
1103
+
1104
+ }
1105
+
1106
+ private function reload_backup_exclude( ) {
1107
+ return array(
1108
+ 'exclude' => ITSEC_Modules::get_setting( 'backup', 'exclude' ),
1109
+ 'excludable_tables' => $this->get_excludable_tables(),
1110
+ 'result' => 'success'
1111
+ );
1112
+ }
1113
+
1114
+ private function get_excludable_tables( ) {
1115
+ global $wpdb;
1116
+ $all_sites = ITSEC_Modules::get_setting( 'backup', 'all_sites' );
1117
+ $ignored_tables = array(
1118
+ 'commentmeta',
1119
+ 'comments',
1120
+ 'links',
1121
+ 'options',
1122
+ 'postmeta',
1123
+ 'posts',
1124
+ 'term_relationships',
1125
+ 'term_taxonomy',
1126
+ 'terms',
1127
+ 'usermeta',
1128
+ 'users',
1129
+ );
1130
+
1131
+ if ( $all_sites ) {
1132
+ $query = 'SHOW TABLES';
1133
+ } else {
1134
+ $query = $wpdb->prepare( 'SHOW TABLES LIKE %s', "{$wpdb->base_prefix}%" );
1135
+ }
1136
+
1137
+ $tables = $wpdb->get_results( $query, ARRAY_N );
1138
+ $excludes = array();
1139
+
1140
+ foreach ( $tables as $table ) {
1141
+ $short_table = substr( $table[0], strlen( $wpdb->prefix ) );
1142
+
1143
+ if ( in_array( $short_table, $ignored_tables ) ) {
1144
+ continue;
1145
+ }
1146
+
1147
+ $excludes[$short_table] = $table[0];
1148
+ }
1149
+
1150
+ return $excludes ;
1151
+ }
1152
+
1153
+ private function security_site() {
1154
+ global $mainwp_itsec_modules_path;
1155
+ require_once( $mainwp_itsec_modules_path . 'security-check/scanner.php' );
1156
+ require_once( $mainwp_itsec_modules_path . 'security-check/feedback-renderer.php' );
1157
+ // ITSEC_Security_Check_Scanner::run();
1158
+ // $response = ITSEC_Response::get_response();
1159
+ $results = ITSEC_Security_Check_Scanner::get_results();
1160
+ ob_start();
1161
+ ITSEC_Security_Check_Feedback_Renderer::render( $results );
1162
+ $response = ob_get_clean();
1163
+ return array('result' => 'success' , 'response' => $response);
1164
+ }
1165
+
1166
+ // source from itheme plugin
1167
+ public function get_available_admin_users_and_roles() {
1168
+ if ( is_callable( 'wp_roles' ) ) {
1169
+ $roles = wp_roles();
1170
+ } else {
1171
+ $roles = new WP_Roles();
1172
+ }
1173
+
1174
+ $available_roles = array();
1175
+ $available_users = array();
1176
+
1177
+ foreach ( $roles->roles as $role => $details ) {
1178
+ if ( isset( $details['capabilities']['manage_options'] ) && ( true === $details['capabilities']['manage_options'] ) ) {
1179
+ $available_roles["role:$role"] = translate_user_role( $details['name'] );
1180
+
1181
+ $users = get_users( array( 'role' => $role ) );
1182
+
1183
+ foreach ( $users as $user ) {
1184
+ /* translators: 1: user display name, 2: user login */
1185
+ $available_users[ $user->ID ] = sprintf( __( '%1$s (%2$s)', 'better-wp-security' ), $user->display_name, $user->user_login );
1186
+ }
1187
+ }
1188
+ }
1189
+
1190
+ natcasesort( $available_users );
1191
+
1192
+ return array(
1193
+ 'users' => $available_users,
1194
+ 'roles' => $available_roles,
1195
+ );
1196
+ }
1197
+
1198
+ }
1199
+
class/class-mainwp-child-links-checker.php ADDED
@@ -0,0 +1,606 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class MainWP_Child_Links_Checker {
4
+
5
+ public static $instance = null;
6
+ public $is_plugin_installed = false;
7
+
8
+ static function Instance() {
9
+ if ( null === MainWP_Child_Links_Checker::$instance ) {
10
+ MainWP_Child_Links_Checker::$instance = new MainWP_Child_Links_Checker();
11
+ }
12
+
13
+ return MainWP_Child_Links_Checker::$instance;
14
+ }
15
+
16
+ public function __construct() {
17
+ require_once( ABSPATH . 'wp-admin/includes/plugin.php' );
18
+ if ( is_plugin_active( 'broken-link-checker/broken-link-checker.php' ) ) {
19
+ $this->is_plugin_installed = true;
20
+ }
21
+ }
22
+
23
+ public function action() {
24
+ $information = array();
25
+ if ( ! defined( 'BLC_ACTIVE' ) || ! function_exists( 'blc_init' ) ) {
26
+ $information['error'] = 'NO_BROKENLINKSCHECKER';
27
+ MainWP_Helper::write( $information );
28
+ }
29
+ blc_init();
30
+ if ( isset( $_POST['mwp_action'] ) ) {
31
+ switch ( $_POST['mwp_action'] ) {
32
+ case 'set_showhide':
33
+ $information = $this->set_showhide();
34
+ break;
35
+ case 'sync_data':
36
+ $information = $this->sync_data();
37
+ break;
38
+ case 'sync_links_data':
39
+ $information = $this->sync_links_data();
40
+ break;
41
+ case 'edit_link':
42
+ $information = $this->edit_link();
43
+ break;
44
+ case 'unlink':
45
+ $information = $this->unlink();
46
+ break;
47
+ case 'set_dismiss':
48
+ $information = $this->set_link_dismissed();
49
+ break;
50
+ case 'discard':
51
+ $information = $this->discard();
52
+ break;
53
+ case 'save_settings':
54
+ $information = $this->save_settings();
55
+ break;
56
+ case 'force_recheck':
57
+ $information = $this->force_recheck();
58
+ break;
59
+ }
60
+ }
61
+ MainWP_Helper::write( $information );
62
+ }
63
+
64
+
65
+ public function init() {
66
+ if ( get_option( 'mainwp_linkschecker_ext_enabled' ) !== 'Y' ) {
67
+ return;
68
+ }
69
+
70
+ if ( get_option( 'mainwp_linkschecker_hide_plugin' ) === 'hide' ) {
71
+ add_filter( 'all_plugins', array( $this, 'hide_plugin' ) );
72
+ add_filter( 'update_footer', array( &$this, 'update_footer' ), 15 );
73
+ }
74
+ }
75
+
76
+ public static function hook_trashed_comment( $comment_id ) {
77
+ if ( get_option( 'mainwp_linkschecker_ext_enabled' ) !== 'Y' ) {
78
+ return;
79
+ }
80
+
81
+ if ( ! defined( 'BLC_ACTIVE' ) || ! function_exists( 'blc_init' ) ) {
82
+ return;
83
+ }
84
+ blc_init();
85
+ $container = blcContainerHelper::get_container( array( 'comment', $comment_id ) );
86
+ $container->delete();
87
+ blc_cleanup_links();
88
+ }
89
+
90
+ function save_settings() {
91
+ $information = array();
92
+ $check_threshold = intval( $_POST['check_threshold'] );
93
+ if ( $check_threshold > 0 ) {
94
+ $conf = blc_get_configuration();
95
+ $conf->options['check_threshold'] = $check_threshold;
96
+ $conf->save_options();
97
+ }
98
+ $information['result'] = 'SUCCESS';
99
+ return $information;
100
+ }
101
+
102
+ function force_recheck() {
103
+ $this->initiate_recheck();
104
+ $information = array();
105
+ $information['result'] = 'SUCCESS';
106
+
107
+ return $information;
108
+ }
109
+
110
+ function initiate_recheck() {
111
+ global $wpdb;
112
+ /** @var wpdb $wpdb */
113
+
114
+ //Delete all discovered instances
115
+ $wpdb->query( "TRUNCATE {$wpdb->prefix}blc_instances" );
116
+
117
+ //Delete all discovered links
118
+ $wpdb->query( "TRUNCATE {$wpdb->prefix}blc_links" );
119
+
120
+ //Mark all posts, custom fields and bookmarks for processing.
121
+ blc_resynch( true );
122
+ }
123
+
124
+
125
+ public static function hook_post_deleted( $post_id ) {
126
+ if ( get_option( 'mainwp_linkschecker_ext_enabled' ) !== 'Y' ) {
127
+ return;
128
+ }
129
+
130
+ if ( ! defined( 'BLC_ACTIVE' ) || ! function_exists( 'blc_init' ) ) {
131
+ return;
132
+ }
133
+ blc_init();
134
+
135
+ //Get the container type matching the type of the deleted post
136
+ $post = get_post( $post_id );
137
+ if ( ! $post ) {
138
+ return;
139
+ }
140
+ //Get the associated container object
141
+ $post_container = blcContainerHelper::get_container( array( $post->post_type, intval( $post_id ) ) );
142
+
143
+ if ( $post_container ) {
144
+ //Delete it
145
+ $post_container->delete();
146
+ //Clean up any dangling links
147
+ blc_cleanup_links();
148
+ }
149
+ }
150
+
151
+
152
+ public function hide_plugin( $plugins ) {
153
+ foreach ( $plugins as $key => $value ) {
154
+ $plugin_slug = basename( $key, '.php' );
155
+ if ( 'broken-link-checker' === $plugin_slug ) {
156
+ unset( $plugins[ $key ] );
157
+ }
158
+ }
159
+
160
+ return $plugins;
161
+ }
162
+
163
+ function update_footer( $text ) {
164
+ ?>
165
+ <script>
166
+ jQuery( document ).ready( function () {
167
+ jQuery( '#menu-tools a[href="tools.php?page=view-broken-links"]' ).closest( 'li' ).remove();
168
+ jQuery( '#menu-settings a[href="options-general.php?page=link-checker-settings"]' ).closest( 'li' ).remove();
169
+ } );
170
+ </script>
171
+ <?php
172
+ return $text;
173
+ }
174
+
175
+
176
+ function set_showhide() {
177
+ MainWP_Helper::update_option( 'mainwp_linkschecker_ext_enabled', 'Y', 'yes' );
178
+ $hide = isset( $_POST['showhide'] ) && ( 'hide' === $_POST['showhide'] ) ? 'hide' : '';
179
+ MainWP_Helper::update_option( 'mainwp_linkschecker_hide_plugin', $hide );
180
+ $information['result'] = 'SUCCESS';
181
+
182
+ return $information;
183
+ }
184
+
185
+ function sync_data( $strategy = '' ) {
186
+ $information = array();
187
+ $data = $this->get_count_links();
188
+ if (is_array($data))
189
+ $information['data'] = $data;
190
+ return $information;
191
+ }
192
+
193
+ function sync_links_data() {
194
+ if (!defined('BLC_DIRECTORY')) return;
195
+ require_once BLC_DIRECTORY . '/includes/link-query.php';
196
+ require_once BLC_DIRECTORY . '/includes/modules.php';
197
+
198
+ $blc_link_query = blcLinkQuery::getInstance();
199
+ $total = $blc_link_query->get_filter_links( 'all', array( 'count_only' => true ) );
200
+
201
+
202
+ $max_results = isset($_POST['max_results']) ? intval($_POST['max_results']) : 50;
203
+ $offset = isset($_POST['offset']) ? intval($_POST['offset']) : 0;
204
+
205
+ $params = array(
206
+ array( 'load_instances' => true ),
207
+ 'max_results' => $max_results
208
+ );
209
+
210
+ if (empty($offset)) {
211
+ $first_sync = true;
212
+ } else {
213
+ $params['offset'] = $offset;
214
+ }
215
+
216
+ $link_data = $this->do_sync_links_data($params);
217
+
218
+ $information = array('links_data' => $link_data);
219
+
220
+ if ($first_sync) {
221
+ $information['data'] = $this->get_count_links();
222
+ }
223
+
224
+ if ($total > $offset + $max_results ) {
225
+ $information['sync_offset'] = $offset + $max_results;
226
+ } else {
227
+ $information['last_sync'] = 1;
228
+ }
229
+
230
+ $information['result'] = 'success';
231
+ return $information;
232
+ }
233
+
234
+ function get_count_links() {
235
+ if (!defined('BLC_DIRECTORY')) return;
236
+
237
+ require_once BLC_DIRECTORY . '/includes/link-query.php';
238
+ require_once BLC_DIRECTORY . '/includes/modules.php';
239
+
240
+ $data = array();
241
+ $blc_link_query = blcLinkQuery::getInstance();
242
+ $data['broken'] = $blc_link_query->get_filter_links( 'broken', array( 'count_only' => true ) );
243
+ $data['redirects'] = $blc_link_query->get_filter_links( 'redirects', array( 'count_only' => true ) );
244
+ $data['dismissed'] = $blc_link_query->get_filter_links( 'dismissed', array( 'count_only' => true ) );
245
+ $data['warning'] = $blc_link_query->get_filter_links( 'warning', array( 'count_only' => true ) );
246
+ $data['all'] = $blc_link_query->get_filter_links( 'all', array( 'count_only' => true ) );
247
+ return $data;
248
+ }
249
+
250
+ function do_sync_links_data($params) {
251
+
252
+ $links = blc_get_links( $params );
253
+
254
+ $filter_fields = array(
255
+ 'link_id',
256
+ 'url',
257
+ 'being_checked',
258
+ 'last_check',
259
+ 'last_check_attempt',
260
+ 'check_count',
261
+ 'http_code',
262
+ 'request_duration',
263
+ 'timeout',
264
+ 'redirect_count',
265
+ 'final_url',
266
+ 'broken',
267
+ 'warning',
268
+ 'first_failure',
269
+ 'last_success',
270
+ 'may_recheck',
271
+ 'false_positive',
272
+ //'result_hash',
273
+ 'dismissed',
274
+ 'status_text',
275
+ 'status_code',
276
+ 'log'
277
+ );
278
+ $return = '';
279
+
280
+ $blc_option = get_option( 'wsblc_options' );
281
+
282
+ if ( is_string( $blc_option ) && ! empty( $blc_option ) ) {
283
+ $blc_option = json_decode( $blc_option, true );
284
+ }
285
+
286
+ if ( is_array( $links ) ) {
287
+ foreach ( $links as $link ) {
288
+ $new_link = new stdClass();
289
+ foreach ( $filter_fields as $field ) {
290
+ $new_link->$field = $link->$field;
291
+ }
292
+
293
+ $extra_info = array();
294
+
295
+ if ( ! empty( $link->post_date ) ) {
296
+ $extra_info['post_date'] = $link->post_date;
297
+ }
298
+
299
+ $days_broken = 0;
300
+ if ( $link->broken ) {
301
+ //Add a highlight to broken links that appear to be permanently broken
302
+ $days_broken = intval( ( time() - $link->first_failure ) / ( 3600 * 24 ) );
303
+ if ( $days_broken >= $blc_option['failure_duration_threshold'] ) {
304
+ $extra_info['permanently_broken'] = 1;
305
+ if ( $blc_option['highlight_permanent_failures'] ) {
306
+ $extra_info['permanently_broken_highlight'] = 1;
307
+ }
308
+ }
309
+ }
310
+ $extra_info['days_broken'] = $days_broken;
311
+ $instances = false;
312
+
313
+ $get_link = new blcLink( intval( $link->link_id ) );
314
+ if ( $get_link->valid() ) {
315
+ $instances = $get_link->get_instances();
316
+ }
317
+
318
+ if ( ! empty( $instances ) ) {
319
+
320
+ $first_instance = reset( $instances );
321
+ $new_link->link_text = $first_instance->ui_get_link_text();
322
+ $extra_info['count_instance'] = count( $instances );
323
+ $container = $first_instance->get_container();
324
+
325
+ /** @var blcContainer $container */
326
+
327
+ if ( ! empty( $container ) /* && ($container instanceof blcAnyPostContainer) */ ) {
328
+ $extra_info['container_type'] = $container->container_type;
329
+ $extra_info['container_id'] = $container->container_id;
330
+ $extra_info['source_data'] = $this->ui_get_source( $container, $first_instance->container_field );
331
+ }
332
+
333
+ $can_edit_text = false;
334
+ $can_edit_url = false;
335
+ $editable_link_texts = $non_editable_link_texts = array();
336
+
337
+ foreach ( $instances as $instance ) {
338
+ if ( $instance->is_link_text_editable() ) {
339
+ $can_edit_text = true;
340
+ $editable_link_texts[ $instance->link_text ] = true;
341
+ } else {
342
+ $non_editable_link_texts[ $instance->link_text ] = true;
343
+ }
344
+
345
+ if ( $instance->is_url_editable() ) {
346
+ $can_edit_url = true;
347
+ }
348
+ }
349
+
350
+ $link_texts = $can_edit_text ? $editable_link_texts : $non_editable_link_texts;
351
+ $data_link_text = '';
352
+ if ( count( $link_texts ) === 1 ) {
353
+ //All instances have the same text - use it.
354
+ $link_text = key( $link_texts );
355
+ $data_link_text = esc_attr( $link_text );
356
+ }
357
+ $extra_info['data_link_text'] = $data_link_text;
358
+ $extra_info['can_edit_url'] = $can_edit_url;
359
+ $extra_info['can_edit_text'] = $can_edit_text;
360
+ } else {
361
+ $new_link->link_text = '';
362
+ $extra_info['count_instance'] = 0;
363
+ }
364
+ $new_link->extra_info = base64_encode(serialize($extra_info));
365
+ $new_link->synced = 1;
366
+ $return[] = $new_link;
367
+ }
368
+ } else {
369
+ return '';
370
+ }
371
+
372
+ return $return;
373
+
374
+ }
375
+
376
+ function edit_link() {
377
+ $information = array();
378
+ if ( ! current_user_can( 'edit_others_posts' ) ) {
379
+ $information['error'] = 'NOTALLOW';
380
+
381
+ return $information;
382
+ }
383
+ //Load the link
384
+ $link = new blcLink( intval( $_POST['link_id'] ) );
385
+ if ( ! $link->valid() ) {
386
+ $information['error'] = 'NOTFOUNDLINK'; // Oops, I can't find the link
387
+ return $information;
388
+ }
389
+
390
+ //Validate the new URL.
391
+ $new_url = stripslashes( $_POST['new_url'] );
392
+ $parsed = @parse_url( $new_url );
393
+ if ( ! $parsed ) {
394
+ $information['error'] = 'URLINVALID'; // Oops, the new URL is invalid!
395
+ return $information;
396
+ }
397
+
398
+ $new_text = ( isset( $_POST['new_text'] ) && is_string( $_POST['new_text'] ) ) ? stripslashes( $_POST['new_text'] ) : null;
399
+ if ( '' === $new_text ) {
400
+ $new_text = null;
401
+ }
402
+ if ( ! empty( $new_text ) && ! current_user_can( 'unfiltered_html' ) ) {
403
+ $new_text = stripslashes( wp_filter_post_kses( addslashes( $new_text ) ) ); //wp_filter_post_kses expects slashed data.
404
+ }
405
+
406
+ $rez = $link->edit( $new_url, $new_text );
407
+ if ( false === $rez ) {
408
+ $information['error'] = __( 'An unexpected error occurred!', 'mainwp-child' );
409
+
410
+ return $information;
411
+ } else {
412
+ $new_link = $rez['new_link'];
413
+ /** @var blcLink $new_link */
414
+ $new_status = $new_link->analyse_status();
415
+ $ui_link_text = null;
416
+ if ( isset( $new_text ) ) {
417
+ $instances = $new_link->get_instances();
418
+ if ( ! empty( $instances ) ) {
419
+ $first_instance = reset( $instances );
420
+ $ui_link_text = $first_instance->ui_get_link_text();
421
+ }
422
+ }
423
+
424
+ $response = array(
425
+ 'new_link_id' => $rez['new_link_id'],
426
+ 'cnt_okay' => $rez['cnt_okay'],
427
+ 'cnt_error' => $rez['cnt_error'],
428
+ 'status_text' => $new_status['text'],
429
+ 'status_code' => $new_status['code'],
430
+ 'http_code' => empty( $new_link->http_code ) ? '' : $new_link->http_code,
431
+ 'url' => $new_link->url,
432
+ 'link_text' => isset( $new_text ) ? $new_text : null,
433
+ 'ui_link_text' => isset( $new_text ) ? $ui_link_text : null,
434
+ 'errors' => array(),
435
+ );
436
+ //url, status text, status code, link text, editable link text
437
+
438
+ foreach ( $rez['errors'] as $error ) {
439
+ /** @var $error WP_Error */
440
+ array_push( $response['errors'], implode( ', ', $error->get_error_messages() ) );
441
+ }
442
+
443
+ return $response;
444
+ }
445
+ }
446
+
447
+ function unlink() {
448
+ $information = array();
449
+ if ( ! current_user_can( 'edit_others_posts' ) ) {
450
+ $information['error'] = 'NOTALLOW';
451
+
452
+ return $information;
453
+ }
454
+
455
+ if ( isset( $_POST['link_id'] ) ) {
456
+ //Load the link
457
+ $link = new blcLink( intval( $_POST['link_id'] ) );
458
+
459
+ if ( ! $link->valid() ) {
460
+ $information['error'] = 'NOTFOUNDLINK'; // Oops, I can't find the link
461
+ return $information;
462
+ }
463
+
464
+ //Try and unlink it
465
+ $rez = $link->unlink();
466
+
467
+ if ( false === $rez ) {
468
+ $information['error'] = 'UNDEFINEDERROR'; // An unexpected error occured!
469
+ return $information;
470
+ } else {
471
+ $response = array(
472
+ 'cnt_okay' => $rez['cnt_okay'],
473
+ 'cnt_error' => $rez['cnt_error'],
474
+ 'errors' => array(),
475
+ );
476
+ foreach ( $rez['errors'] as $error ) {
477
+ /** @var WP_Error $error */
478
+ array_push( $response['errors'], implode( ', ', $error->get_error_messages() ) );
479
+ }
480
+
481
+ return $response;
482
+ }
483
+ } else {
484
+ $information['error'] = __( 'Error: link_id is not specified.', 'mainwp-child' );
485
+
486
+ return $information;
487
+ }
488
+ }
489
+
490
+ private function set_link_dismissed() {
491
+ $information = array();
492
+ $dismiss = $_POST['dismiss'];
493
+
494
+ if ( ! current_user_can( 'edit_others_posts' ) ) {
495
+ $information['error'] = 'NOTALLOW';
496
+
497
+ return $information;
498
+ }
499
+
500
+ if ( isset( $_POST['link_id'] ) ) {
501
+ //Load the link
502
+ $link = new blcLink( intval( $_POST['link_id'] ) );
503
+
504
+ if ( ! $link->valid() ) {
505
+ $information['error'] = 'NOTFOUNDLINK'; // Oops, I can't find the link
506
+ return $information;
507
+ }
508
+
509
+ $link->dismissed = $dismiss;
510
+
511
+ //Save the changes
512
+ if ( $link->save() ) {
513
+ $information = 'OK';
514
+ } else {
515
+ $information['error'] = 'COULDNOTMODIFY'; // Oops, couldn't modify the link
516
+ }
517
+
518
+ return $information;
519
+ } else {
520
+ $information['error'] = __( 'Error: link_id not specified.', 'mainwp-child' );
521
+
522
+ return $information;
523
+ }
524
+ }
525
+
526
+ private function discard() {
527
+ $information = array();
528
+ if ( ! current_user_can( 'edit_others_posts' ) ) {
529
+ $information['error'] = 'NOTALLOW';
530
+
531
+ return $information;
532
+ }
533
+ if ( isset( $_POST['link_id'] ) ) {
534
+ //Load the link
535
+ $link = new blcLink( intval( $_POST['link_id'] ) );
536
+
537
+ if ( ! $link->valid() ) {
538
+ $information['error'] = 'NOTFOUNDLINK'; // Oops, I can't find the link
539
+ return $information;
540
+ }
541
+
542
+ //Make it appear "not broken"
543
+ $link->broken = false;
544
+ $link->false_positive = true;
545
+ $link->last_check_attempt = time();
546
+ $link->log = __( 'This link was manually marked as working by the user.', 'mainwp-child' );
547
+
548
+ //Save the changes
549
+ if ( $link->save() ) {
550
+ $information['status'] = 'OK';
551
+ $information['last_check_attempt'] = $link->last_check_attempt;
552
+ } else {
553
+ $information['error'] = 'COULDNOTMODIFY'; // Oops, couldn't modify the link
554
+ }
555
+ } else {
556
+ $information['error'] = __( 'Error: link_id is not specified.', 'mainwp-child' );
557
+ }
558
+
559
+ return $information;
560
+ }
561
+
562
+ function ui_get_source( $container, $container_field = '' ) {
563
+ if ( 'comment' === $container->container_type ) {
564
+ return $this->ui_get_source_comment( $container, $container_field );
565
+ } else if ( $container instanceof blcAnyPostContainer ) {
566
+ return $this->ui_get_source_post( $container, $container_field );
567
+ }
568
+
569
+ return array();
570
+ }
571
+
572
+ function ui_get_source_comment( $container, $container_field = '' ) {
573
+ //Display a comment icon.
574
+ if ( 'comment_author_url' === $container_field ) {
575
+ $image = 'font-awesome/font-awesome-user.png';
576
+ } else {
577
+ $image = 'font-awesome/font-awesome-comment-alt.png';
578
+ }
579
+
580
+ $comment = $container->get_wrapped_object();
581
+
582
+ //Display a small text sample from the comment
583
+ $text_sample = strip_tags( $comment->comment_content );
584
+ $text_sample = blcUtility::truncate( $text_sample, 65 );
585
+
586
+ return array(
587
+ 'image' => $image,
588
+ 'text_sample' => $text_sample,
589
+ 'comment_author' => esc_attr( $comment->comment_author ),
590
+ 'comment_id' => esc_attr( $comment->comment_ID ),
591
+ 'comment_status' => wp_get_comment_status( $comment->comment_ID ),
592
+ 'container_post_title' => get_the_title( $comment->comment_post_ID ),
593
+ 'container_post_status' => get_post_status( $comment->comment_post_ID ),
594
+ 'container_post_ID' => $comment->comment_post_ID,
595
+ );
596
+ }
597
+
598
+ function ui_get_source_post( $container, $container_field = '' ) {
599
+ return array(
600
+ 'post_title' => get_the_title( $container->container_id ),
601
+ 'post_status' => get_post_status($container->container_id),
602
+ 'container_anypost' => true,
603
+ );
604
+ }
605
+ }
606
+
class/class-mainwp-child-pagespeed.php ADDED
@@ -0,0 +1,498 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class MainWP_Child_Pagespeed {
4
+
5
+ public static $instance = null;
6
+ public $is_plugin_installed = false;
7
+
8
+ static function Instance() {
9
+ if ( null === MainWP_Child_Pagespeed::$instance ) {
10
+ MainWP_Child_Pagespeed::$instance = new MainWP_Child_Pagespeed();
11
+ }
12
+
13
+ return MainWP_Child_Pagespeed::$instance;
14
+ }
15
+
16
+ public function __construct() {
17
+ require_once( ABSPATH . 'wp-admin/includes/plugin.php' );
18
+ if ( is_plugin_active( 'google-pagespeed-insights/google-pagespeed-insights.php' ) ) {
19
+ $this->is_plugin_installed = true;
20
+ }
21
+
22
+ add_action( 'mainwp_child_deactivation', array( $this, 'child_deactivation' ) );
23
+ }
24
+
25
+ public function action() {
26
+ $information = array();
27
+ if ( ! defined( 'GPI_DIRECTORY' ) ) {
28
+ $information['error'] = 'Please install Google Pagespeed Insights plugin on child website';
29
+ MainWP_Helper::write( $information );
30
+ }
31
+ if ( isset( $_POST['mwp_action'] ) ) {
32
+ MainWP_Helper::update_option('mainwp_pagespeed_ext_enabled', 'Y', 'yes');
33
+ switch ( $_POST['mwp_action'] ) {
34
+ case 'save_settings':
35
+ $information = $this->save_settings();
36
+ break;
37
+ case 'set_showhide':
38
+ $information = $this->set_showhide();
39
+ break;
40
+ case 'sync_data':
41
+ $information = $this->sync_data();
42
+ break;
43
+ case "check_pages":
44
+ $information = $this->check_pages();
45
+ break;
46
+ }
47
+ }
48
+ MainWP_Helper::write( $information );
49
+ }
50
+
51
+ public function child_deactivation() {
52
+ if ( $sched = wp_next_scheduled( 'mainwp_child_pagespeed_cron_check' ) ) {
53
+ wp_unschedule_event( $sched, 'mainwp_child_pagespeed_cron_check' );
54
+ }
55
+ }
56
+
57
+ public function init() {
58
+ if ( get_option( 'mainwp_pagespeed_ext_enabled' ) !== 'Y' ) {
59
+ return;
60
+ }
61
+
62
+ if ( get_option( 'mainwp_pagespeed_hide_plugin' ) === 'hide' ) {
63
+ add_filter( 'all_plugins', array( $this, 'hide_plugin' ) );
64
+ add_action('admin_menu', array($this, 'hide_menu'), 999);
65
+ //add_filter( 'update_footer', array( &$this, 'update_footer' ), 15 );
66
+ }
67
+ $this->init_cron();
68
+ }
69
+
70
+ public function init_cron() {
71
+ add_action( 'mainwp_child_pagespeed_cron_check', array( 'MainWP_Child_Pagespeed', 'pagespeed_cron_check' ) );
72
+ if ( false === ( $sched = wp_next_scheduled( 'mainwp_child_pagespeed_cron_check' ) ) ) {
73
+ wp_schedule_event( time(), 'daily', 'mainwp_child_pagespeed_cron_check' );
74
+ }
75
+ }
76
+
77
+ public static function pagespeed_cron_check() {
78
+ $count = get_option( 'mainwp_child_pagespeed_count_checking' );
79
+ if ( $count >= 7 ) {
80
+ $recheck = true;
81
+ $count = 0;
82
+ } else {
83
+ $recheck = false;
84
+ $count ++;
85
+ }
86
+ update_option( 'mainwp_child_pagespeed_count_checking', $count );
87
+
88
+ $worker_args = array(
89
+ array(),
90
+ false,
91
+ $recheck,
92
+ );
93
+ wp_schedule_single_event( time(), 'googlepagespeedinsightschecknow', $worker_args );
94
+ }
95
+
96
+ public function hide_plugin( $plugins ) {
97
+ foreach ( $plugins as $key => $value ) {
98
+ $plugin_slug = basename( $key, '.php' );
99
+ if ( 'google-pagespeed-insights' === $plugin_slug ) {
100
+ unset( $plugins[ $key ] );
101
+ }
102
+ }
103
+
104
+ return $plugins;
105
+ }
106
+
107
+
108
+ public function hide_menu() {
109
+ global $submenu;
110
+ if (isset($submenu['tools.php'])) {
111
+ foreach($submenu['tools.php'] as $key => $menu) {
112
+ if ($menu[2] == 'google-pagespeed-insights') {
113
+ unset($submenu['tools.php'][$key]);
114
+ break;
115
+ }
116
+ }
117
+ }
118
+ }
119
+
120
+ function update_footer( $text ) {
121
+ ?>
122
+ <script>
123
+ jQuery( document ).ready( function () {
124
+ jQuery( '#menu-tools a[href="tools.php?page=google-pagespeed-insights"]' ).closest( 'li' ).remove();
125
+ } );
126
+ </script>
127
+ <?php
128
+ return $text;
129
+ }
130
+
131
+
132
+ function set_showhide() {
133
+ $hide = isset( $_POST['showhide'] ) && ( 'hide' === $_POST['showhide'] ) ? 'hide' : '';
134
+ MainWP_Helper::update_option( 'mainwp_pagespeed_hide_plugin', $hide );
135
+ $information['result'] = 'SUCCESS';
136
+
137
+ return $information;
138
+ }
139
+
140
+ function save_settings() {
141
+ $current_values = get_option( 'gpagespeedi_options' );
142
+ $checkstatus = apply_filters( 'gpi_check_status', false );
143
+ if ( $checkstatus ) {
144
+ return array( 'result' => 'RUNNING' );
145
+ }
146
+
147
+ $settings = $_POST['settings'];
148
+ $settings = maybe_unserialize( base64_decode( $settings ) );
149
+
150
+ if ( is_array( $settings ) ) {
151
+
152
+ if ( isset( $settings['api_key'] ) && ! empty( $settings['api_key'] ) ) {
153
+ $current_values['google_developer_key'] = $settings['api_key'];
154
+ }
155
+
156
+ if ( isset( $settings['response_language'] ) ) {
157
+ $current_values['response_language'] = $settings['response_language'];
158
+ }
159
+
160
+ if ( isset( $_POST['strategy'] ) ) {
161
+ $current_values['strategy'] = $_POST['strategy'];
162
+ }
163
+
164
+ if ( isset( $settings['max_execution_time'] ) ) {
165
+ $current_values['max_execution_time'] = $settings['max_execution_time'];
166
+ }
167
+
168
+ if ( isset( $settings['max_run_time'] ) ) {
169
+ $current_values['max_run_time'] = $settings['max_run_time'];
170
+ }
171
+
172
+ if ( isset( $settings['heartbeat'] ) ) {
173
+ $current_values['heartbeat'] = $settings['heartbeat'];
174
+ }
175
+
176
+ if ( isset( $settings['delay_time'] ) ) {
177
+ $current_values['sleep_time'] = $settings['delay_time'];
178
+ }
179
+
180
+ if ( isset( $settings['log_exception'] ) ) {
181
+ $current_values['log_api_errors'] = ( $settings['log_exception'] ) ? true : false;
182
+ }
183
+
184
+ if ( isset( $settings['scan_technical'] ) ) {
185
+ $current_values['scan_method'] = $settings['scan_technical'];
186
+ }
187
+
188
+ if ( isset( $settings['report_expiration'] ) ) {
189
+ $current_values['recheck_interval'] = $settings['report_expiration'];
190
+ }
191
+
192
+ if ( isset( $settings['check_report'] ) ) {
193
+ if ( is_array( $settings['check_report'] ) ) {
194
+ $current_values['check_pages'] = in_array( 'page', $settings['check_report'] ) ? true : false;
195
+ $current_values['check_posts'] = in_array( 'post', $settings['check_report'] ) ? true : false;
196
+ $current_values['check_categories'] = in_array( 'category', $settings['check_report'] ) ? true : false;
197
+ } else {
198
+ $current_values['check_pages'] = $current_values['check_posts'] = $current_values['check_categories'] = false;
199
+ }
200
+ }
201
+
202
+ if ( isset( $settings['delete_data'] ) && ! empty( $settings['delete_data'] ) ) {
203
+ $this->delete_data( $settings['delete_data'] );
204
+ }
205
+
206
+ if ( update_option( 'gpagespeedi_options', $current_values ) ) {
207
+ $information['result'] = 'SUCCESS';
208
+ } else {
209
+ $information['result'] = 'NOTCHANGE';
210
+ }
211
+ }
212
+
213
+ $strategy = $current_values['strategy'];
214
+
215
+ $result = $this->sync_data( $strategy );
216
+
217
+ if ( isset( $_POST['doaction'] ) && ( 'check_new_pages' === $_POST['doaction'] || 'recheck_all_pages' === $_POST['doaction'] ) ) {
218
+ if ( 'recheck_all_pages' === $_POST['doaction'] ) {
219
+ $recheck = true;
220
+ } else {
221
+ $recheck = false;
222
+ }
223
+
224
+
225
+ if ($this->do_check_pages($recheck))
226
+ $information['checked_pages'] = 1;
227
+ }
228
+ $information['data'] = $result['data'];
229
+ return $information;
230
+ }
231
+
232
+
233
+ function check_pages() {
234
+ if (isset($_POST['force_recheck']) && !empty($_POST['force_recheck'])) {
235
+ $recheck = true;
236
+ } else {
237
+ $recheck = false;
238
+ }
239
+ $information = $this->do_check_pages($recheck);
240
+ if (isset($information['checked_pages']) && $information['checked_pages']) {
241
+ $information['result'] = 'SUCCESS';
242
+ }
243
+ return $information;
244
+ }
245
+
246
+ function do_check_pages($forceRecheck = false) {
247
+ $information = array();
248
+ if ( defined( 'GPI_DIRECTORY' ) ) {
249
+ $checkstatus = apply_filters( 'gpi_check_status', false );
250
+ if ( $checkstatus ) {
251
+ $information['error'] = __( 'The API is busy checking other pages, please try again later.', 'gpagespeedi' );
252
+ } else {
253
+ do_action( 'googlepagespeedinsightsworker', array(), true );
254
+ $information['checked_pages'] = 1;
255
+ }
256
+ }
257
+ return $information;
258
+ }
259
+
260
+ public function sync_data( $strategy = '' ) {
261
+ if ( empty( $strategy ) ) {
262
+ $strategy = 'both';
263
+ }
264
+
265
+ $current_values = get_option( 'gpagespeedi_options' );
266
+ $checkstatus = apply_filters( 'gpi_check_status', false );
267
+ if ( $checkstatus ) {
268
+ return array( 'result' => 'RUNNING' );
269
+ }
270
+
271
+ $information = array();
272
+ $bad_key = ( $current_values['bad_api_key'] || empty( $current_values['google_developer_key'] ) );
273
+ $data = array( 'bad_api_key' => $bad_key );
274
+
275
+ if ( 'both' === $strategy || 'desktop' === $strategy ) {
276
+ $result = self::cal_pagespeed_data( 'desktop' );
277
+ $data['desktop_score'] = $result['average_score'];
278
+ $data['desktop_total_pages'] = $result['total_pages'];
279
+ $data['desktop_last_modified'] = $result['last_modified'];
280
+ }
281
+ if ( 'both' === $strategy || 'mobile' === $strategy ) {
282
+ $result = self::cal_pagespeed_data( 'mobile' );
283
+ $data['mobile_score'] = $result['average_score'];
284
+ $data['mobile_total_pages'] = $result['total_pages'];
285
+ $data['mobile_last_modified'] = $result['last_modified'];
286
+ }
287
+
288
+ $information['data'] = $data;
289
+
290
+ return $information;
291
+ }
292
+
293
+ static function cal_pagespeed_data( $strategy ) {
294
+ global $wpdb;
295
+ if ( ! defined( 'GPI_DIRECTORY' ) ) {
296
+ return 0;
297
+ }
298
+
299
+ if ( 'desktop' !== $strategy && 'mobile' !== $strategy ) {
300
+ return 0;
301
+ }
302
+
303
+ $score_column = $strategy . '_score';
304
+ $page_stats_column = $strategy . '_page_stats';
305
+
306
+
307
+ $data_typestocheck = self::getTypesToCheck( 'all' );
308
+
309
+ $gpi_page_stats = $wpdb->prefix . 'gpi_page_stats';
310
+ if ( ! empty( $data_typestocheck ) ) {
311
+
312
+ $allpagedata = $wpdb->get_results(
313
+ $wpdb->prepare(
314
+ "SELECT ID, URL, $score_column, $page_stats_column
315
+ FROM $gpi_page_stats
316
+ WHERE ($data_typestocheck[0])",
317
+ $data_typestocheck[1]
318
+ ),
319
+ ARRAY_A
320
+ );
321
+ } else {
322
+ $allpagedata = array();
323
+ }
324
+
325
+ $reports_typestocheck = self::getTypesToCheck( 'all' );
326
+ $gpi_page_reports = $wpdb->prefix . 'gpi_page_reports';
327
+
328
+ if ( ! empty( $reports_typestocheck ) ) {
329
+
330
+ $allpagereports = $wpdb->get_results(
331
+ $wpdb->prepare(
332
+ "SELECT r.rule_key, r.rule_name, r.rule_impact
333
+ FROM $gpi_page_stats d
334
+ INNER JOIN $gpi_page_reports r
335
+ ON r.page_id = d.ID
336
+ AND r.rule_impact > 0
337
+ AND r.strategy = '$strategy'
338
+ WHERE ($reports_typestocheck[0])",
339
+ $reports_typestocheck[1]
340
+ ),
341
+ ARRAY_A
342
+ );
343
+ } else {
344
+ $allpagereports = array();
345
+ }
346
+
347
+ $total_pages = count( $allpagedata );
348
+ $total_scores = 0;
349
+ $average_score = 0;
350
+
351
+ if ( ! empty( $total_pages ) && ! empty( $allpagereports ) ) {
352
+
353
+ foreach ( $allpagedata as $key => $pagedata ) {
354
+ $total_scores = $total_scores + $pagedata[ $score_column ];
355
+ }
356
+
357
+ $average_score = number_format( $total_scores / $total_pages );
358
+ }
359
+
360
+ // Not Null check for Report List scores
361
+ switch ( $strategy ) {
362
+
363
+ // case 'both':
364
+ // $nullcheck = 'desktop_score IS NOT NULL AND mobile_score IS NOT NULL';
365
+ // break;
366
+
367
+ case 'mobile':
368
+ $nullcheck = 'mobile_score IS NOT NULL';
369
+ $_select = ' max(mobile_last_modified) as last_modified ';
370
+ break;
371
+
372
+ case 'desktop':
373
+ $nullcheck = 'desktop_score IS NOT NULL';
374
+ $_select = ' max(desktop_last_modified) as last_modified ';
375
+ break;
376
+
377
+ }
378
+
379
+ // Get our Data
380
+ if ( ! is_null( $reports_typestocheck ) ) {
381
+ $gpi_page_stats = $wpdb->prefix . 'gpi_page_stats';
382
+ $data = $wpdb->get_results(
383
+ $wpdb->prepare(
384
+ "SELECT $_select
385
+ FROM $gpi_page_stats
386
+ WHERE ($reports_typestocheck[0])
387
+ AND $nullcheck",
388
+ $reports_typestocheck[1]
389
+ ),
390
+ ARRAY_A
391
+ );
392
+ }
393
+
394
+ return array(
395
+ 'last_modified' => is_array( $data[0] ) && isset( $data[0]['last_modified'] ) ? $data[0]['last_modified'] : 0,
396
+ 'average_score' => $average_score,
397
+ 'total_pages' => $total_pages,
398
+ );
399
+ }
400
+
401
+ static function getTypesToCheck($restrict_type = 'all') {
402
+
403
+ $types = array();
404
+ $gpi_options = get_option('gpagespeedi_options');
405
+ $typestocheck = array();
406
+
407
+ if($gpi_options['check_pages']) {
408
+ if($restrict_type == 'all' || $restrict_type == 'ignored' || $restrict_type == 'pages') {
409
+ $typestocheck[] = 'type = %s';
410
+ $types[1][] = "page";
411
+ }
412
+ }
413
+
414
+ if($gpi_options['check_posts']) {
415
+ if($restrict_type == 'all' || $restrict_type == 'ignored' || $restrict_type == 'posts') {
416
+ $typestocheck[] = 'type = %s';
417
+ $types[1][] = "post";
418
+ }
419
+ }
420
+
421
+ if($gpi_options['check_categories']) {
422
+ if($restrict_type == 'all' || $restrict_type == 'ignored' || $restrict_type == 'categories') {
423
+ $typestocheck[] = 'type = %s';
424
+ $types[1][] = "category";
425
+ }
426
+ }
427
+ if($gpi_options['cpt_whitelist']) {
428
+ if($restrict_type == 'all' || $restrict_type == 'ignored' || stristr($restrict_type, 'gpi_custom_posts')) {
429
+
430
+ $cpt_whitelist_arr = false;
431
+ if(!empty($gpi_options['cpt_whitelist'])) {
432
+ $cpt_whitelist_arr = unserialize($gpi_options['cpt_whitelist']);
433
+ }
434
+ $args=array(
435
+ 'public' => true,
436
+ '_builtin' => false
437
+ );
438
+ $custom_post_types = get_post_types($args,'names','and');
439
+ if($restrict_type != 'gpi_custom_posts' && $restrict_type != 'all' && $restrict_type != 'ignored') {
440
+ $restrict_type = str_replace('gpi_custom_posts-', '', $restrict_type);
441
+ foreach($custom_post_types as $post_type)
442
+ {
443
+ if($cpt_whitelist_arr && in_array($post_type, $cpt_whitelist_arr)) {
444
+ if($post_type == $restrict_type) {
445
+ $typestocheck[] = 'type = %s';
446
+ $types[1][] = $custom_post_types[$post_type];
447
+ }
448
+ }
449
+ }
450
+ } else {
451
+ foreach($custom_post_types as $post_type)
452
+ {
453
+ if($cpt_whitelist_arr && in_array($post_type, $cpt_whitelist_arr)) {
454
+ $typestocheck[] = 'type = %s';
455
+ $types[1][] = $custom_post_types[$post_type];
456
+ }
457
+ }
458
+ }
459
+ }
460
+ }
461
+
462
+ if(!empty($typestocheck)) {
463
+ $types[0] = '';
464
+ foreach($typestocheck as $type)
465
+ {
466
+ if(!is_array($type)) {
467
+ $types[0] .= $type . ' OR ';
468
+ } else {
469
+ foreach($type as $custom_post_type)
470
+ {
471
+ $types[0] .= 'type = %s OR ';
472
+ $types[1][] = $custom_post_type;
473
+ }
474
+ }
475
+ }
476
+ $types[0] = rtrim($types[0], ' OR ');
477
+ return $types;
478
+ }
479
+ return null;
480
+ }
481
+
482
+ function delete_data( $what ) {
483
+ global $wpdb;
484
+ $gpi_page_stats = $wpdb->prefix . 'gpi_page_stats';
485
+ $gpi_page_reports = $wpdb->prefix . 'gpi_page_reports';
486
+ $gpi_page_blacklist = $wpdb->prefix . 'gpi_page_blacklist';
487
+
488
+ if ( 'purge_reports' === $what ) {
489
+ $wpdb->query( "TRUNCATE TABLE $gpi_page_stats" );
490
+ $wpdb->query( "TRUNCATE TABLE $gpi_page_reports" );
491
+ } elseif ( 'purge_everything' === $what ) {
492
+ $wpdb->query( "TRUNCATE TABLE $gpi_page_stats" );
493
+ $wpdb->query( "TRUNCATE TABLE $gpi_page_reports" );
494
+ $wpdb->query( "TRUNCATE TABLE $gpi_page_blacklist" );
495
+ }
496
+ }
497
+ }
498
+
class/class-mainwp-child-plugins-check.php ADDED
@@ -0,0 +1,370 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ Plugin: Vendi Abandoned Plugin Check
5
+ Description: Provides information about abandoned plugins.
6
+ Version: 3.1.1
7
+ License: GPLv2
8
+ Author: Vendi Advertising (Chris Haas)
9
+ */
10
+
11
+ class MainWP_Child_Plugins_Check {
12
+
13
+ public static $instance = null;
14
+
15
+ private $cron_name_watcher = 'mainwp_child_cron_plugin_health_check_watcher';
16
+
17
+ private $cron_name_daily = 'mainwp_child_cron_plugin_health_check_daily';
18
+
19
+ private $cron_name_batching = 'mainwp_child_cron_plugin_health_check_batching';
20
+
21
+ private $tran_name_plugin_timestamps = 'mainwp_child_tran_name_plugin_timestamps';
22
+
23
+ private $tran_name_plugins_to_batch = 'mainwp_child_tran_name_plugins_to_batch';
24
+
25
+ private $option_name_last_daily_run = 'mainwp_child_plugin_last_daily_run';
26
+
27
+ public static function Instance() {
28
+ if ( null === MainWP_Child_Plugins_Check::$instance ) {
29
+ MainWP_Child_Plugins_Check::$instance = new MainWP_Child_Plugins_Check();
30
+ }
31
+
32
+ return MainWP_Child_Plugins_Check::$instance;
33
+ }
34
+
35
+ public function __construct() {
36
+ $this->schedule_watchdog();
37
+
38
+ add_action( $this->cron_name_batching, array( $this, 'run_check' ) );
39
+ add_action( $this->cron_name_daily, array( $this, 'run_check' ) );
40
+
41
+ add_action( $this->cron_name_watcher, array( $this, 'perform_watchdog' ) );
42
+
43
+ //add_filter( 'plugin_row_meta', array( $this, 'change_plugin_row_meta' ), 10, 4 );
44
+
45
+ add_filter( 'plugins_api_args', array( $this, 'modify_plugin_api_search_query' ), 10, 2 );
46
+
47
+ add_action( 'mainwp_child_deactivation', array( $this, 'cleanup_deactivation' ) );
48
+
49
+ }
50
+
51
+ private function cleanup_basic() {
52
+ wp_clear_scheduled_hook( $this->cron_name_daily );
53
+ wp_clear_scheduled_hook( $this->cron_name_batching );
54
+ delete_transient( $this->tran_name_plugins_to_batch );
55
+ }
56
+
57
+
58
+ public function cleanup_deactivation( $del = true ) {
59
+ $this->cleanup_basic();
60
+ wp_clear_scheduled_hook( $this->cron_name_watcher );
61
+ delete_option( $this->option_name_last_daily_run );
62
+ if ( $del ) {
63
+ delete_transient( $this->tran_name_plugin_timestamps );
64
+ }
65
+ }
66
+
67
+
68
+ public function modify_plugin_api_search_query( $args, $action ) {
69
+ if ( isset( $action ) && 'query_plugins' === $action ) {
70
+
71
+ if ( ! is_object( $args ) ) {
72
+ $args = new \stdClass();
73
+ }
74
+
75
+ if ( ! property_exists( $args, 'fields' ) ) {
76
+ $args->fields = array();
77
+ }
78
+
79
+ $args->fields = array_merge( $args->fields, array( 'last_updated' => true ) );
80
+ }
81
+
82
+ return $args;
83
+ }
84
+
85
+ public function perform_watchdog() {
86
+ if ( false === wp_next_scheduled( $this->cron_name_daily ) && false === wp_next_scheduled( $this->cron_name_batching ) ) {
87
+ $last_run = get_option( $this->option_name_last_daily_run );
88
+
89
+ if ( false === $last_run || ! is_integer( $last_run ) ) {
90
+ $last_run = false;
91
+ } else {
92
+ $last_run = new \DateTime( '@' . $last_run );
93
+ }
94
+
95
+ //Get now
96
+ $now = new \DateTime();
97
+
98
+ if ( false === $last_run || (int) $now->diff( $last_run )->format( '%h' ) >= 24 ) {
99
+ $this->cleanup_basic();
100
+
101
+ wp_schedule_event( time(), 'daily', $this->cron_name_daily );
102
+
103
+ update_option( $this->option_name_last_daily_run, $now->getTimestamp() );
104
+
105
+ }
106
+ }
107
+ }
108
+
109
+ public function schedule_watchdog() {
110
+ //For testing
111
+ //$this->cleanup_deactivation();
112
+
113
+ //Schedule a global watching cron just in case both other crons get killed
114
+ if ( ! wp_next_scheduled( $this->cron_name_watcher ) ) {
115
+ wp_schedule_event( time(), 'hourly', $this->cron_name_watcher );
116
+ }
117
+
118
+ }
119
+
120
+ public function get_plugins_outdate_info() {
121
+ $plugins_outdate = get_transient( $this->tran_name_plugin_timestamps );
122
+ if ( ! is_array( $plugins_outdate ) ) {
123
+ $plugins_outdate = array();
124
+ }
125
+ if ( ! function_exists( 'get_plugins' ) ) {
126
+ require_once ABSPATH . '/wp-admin/includes/plugin.php';
127
+ }
128
+ $plugins = get_plugins();
129
+ $update = false;
130
+ foreach ( $plugins_outdate as $slug => $v ) {
131
+ if ( ! isset( $plugins[ $slug ] ) ) {
132
+ unset( $plugins_outdate[ $slug ] );
133
+ $update = true;
134
+ }
135
+ }
136
+ if ( $update ) {
137
+ set_transient( $this->tran_name_plugin_timestamps, $plugins_outdate, DAY_IN_SECONDS );
138
+ }
139
+
140
+ return $plugins_outdate;
141
+
142
+ }
143
+
144
+ // for testing
145
+ public function change_plugin_row_meta( $plugin_meta, $plugin_file, $plugin_data, $status ) {
146
+ //Grab our previously stored array of known last modified dates
147
+ //Requires WP 2.8.0
148
+ $plugin_info = get_transient( $this->tran_name_plugin_timestamps );
149
+
150
+ //Sanity check the response
151
+ if( false === $plugin_info || ! is_array( $plugin_info ) && 0 === count( $plugin_info ) )
152
+ {
153
+ return $plugin_meta;
154
+ }
155
+
156
+ //See if this specific plugin is in the known list
157
+ if( array_key_exists( $plugin_file, $plugin_info ) )
158
+ {
159
+ //Get now
160
+ $now = new \DateTime();
161
+ $last_updated = $plugin_info[ $plugin_file ]['last_updated'];
162
+
163
+ //Last updated is stored as timestamp, get a real date
164
+ $plugin_last_updated_date = new \DateTime( '@' . $last_updated );
165
+
166
+ //Compute days between now and plugin last updated
167
+ $diff_in_days = $now->diff( $plugin_last_updated_date )->format( '%a' );
168
+
169
+ //Customizable number of days for tolerance
170
+ $tolerance_in_days = get_option( 'mainwp_child_plugintheme_days_outdate', 365 );
171
+
172
+ //If we're outside the window for tolerance show a message
173
+ if( $diff_in_days > $tolerance_in_days )
174
+ {
175
+ $plugin_meta[] = sprintf( '<strong style="color: #f00;">This plugin has not been updated by the author in %1$d days!</strong>', $diff_in_days );
176
+ }
177
+ else
178
+ {
179
+ $plugin_meta[] = sprintf( '<span style="color: #090;">This plugin was last updated by the author in %1$d days ago.</span>', $diff_in_days );
180
+ }
181
+ }
182
+
183
+ return $plugin_meta;
184
+ }
185
+
186
+ public function run_check() {
187
+ if ( ! function_exists( 'get_plugins' ) ) {
188
+ require_once ABSPATH . '/wp-admin/includes/plugin.php';
189
+ }
190
+
191
+ //Get our previous results
192
+ $responses = get_transient( $this->tran_name_plugin_timestamps );
193
+
194
+ if ( false === $responses || ! is_array( $responses ) ) {
195
+ $responses = array();
196
+ }
197
+
198
+ //Get our previous cache of plugins for batching
199
+ $all_plugins = get_transient( $this->tran_name_plugins_to_batch );
200
+
201
+ //If there wasn't a previous cache
202
+ if ( false === $all_plugins || ! is_array( $all_plugins ) ) {
203
+ $plugins = get_plugins();
204
+ if ( is_array( $plugins ) ) {
205
+ foreach ( $plugins as $slug => $plugin ) {
206
+ if ( isset( $plugin['Name'] ) && ! empty( $plugin['Name'] ) ) {
207
+ $all_plugins[ $slug ] = array(
208
+ 'Name' => $plugin['Name'],
209
+ 'PluginURI' => $plugin['PluginURI'],
210
+ 'Version' => $plugin['Version'],
211
+ );
212
+
213
+ }
214
+ }
215
+ }
216
+ $responses = array();
217
+ }
218
+
219
+ $avoid_plugins = array( 'sitepress-multilingual-cms/sitepress.php' );
220
+ //Grab a small number of plugins to scan
221
+ $plugins_to_scan = array_splice( $all_plugins, 0, apply_filters( 'mainwp_child_plugin_health_check_max_plugins_to_batch', 10 ) );
222
+ $tolerance_in_days = get_option( 'mainwp_child_plugintheme_days_outdate', 365 );
223
+
224
+ //Loop through each known plugin
225
+ foreach ( $plugins_to_scan as $slug => $v ) {
226
+ if ( in_array( $slug, $avoid_plugins ) ) {
227
+ continue;
228
+ }
229
+ //Try to get the raw information for this plugin
230
+ $body = $this->try_get_response_body( $slug, false );
231
+
232
+ //We couldn't get any information, skip this plugin
233
+ if ( false === $body ) {
234
+ continue;
235
+ }
236
+
237
+ //Deserialize the response
238
+ $obj = maybe_unserialize( $body );
239
+
240
+ $now = new \DateTime();
241
+
242
+ //Sanity check that deserialization worked and that our property exists
243
+ if ( false !== $obj && is_object( $obj ) && property_exists( $obj, 'last_updated' ) ) {
244
+ if ( version_compare( $v['Version'], $obj->version, '>' ) ) {
245
+ continue;
246
+ }
247
+ $last_updated = strtotime( $obj->last_updated );
248
+ $plugin_last_updated_date = new \DateTime( '@' . $last_updated );
249
+
250
+ $diff_in_days = $now->diff( $plugin_last_updated_date )->format( '%a' );
251
+
252
+ if ( $diff_in_days < $tolerance_in_days ) {
253
+ continue;
254
+ }
255
+ $v['last_updated'] = $last_updated;
256
+ $responses[ $slug ] = $v;
257
+ }
258
+ }
259
+
260
+ if ( ! defined( 'MINUTE_IN_SECONDS' ) ) {
261
+ define( 'MINUTE_IN_SECONDS', 60 );
262
+ }
263
+
264
+ if ( ! defined( 'HOUR_IN_SECONDS' ) ) {
265
+ define( 'HOUR_IN_SECONDS', 60 * MINUTE_IN_SECONDS );
266
+ }
267
+
268
+ if ( ! defined( 'DAY_IN_SECONDS' ) ) {
269
+ define( 'DAY_IN_SECONDS', 24 * HOUR_IN_SECONDS );
270
+ }
271
+
272
+ //Store the master response for usage in the plugin table
273
+ set_transient( $this->tran_name_plugin_timestamps, $responses, DAY_IN_SECONDS );
274
+
275
+ if ( 0 === count( $all_plugins ) ) {
276
+ delete_transient( $this->tran_name_plugins_to_batch );
277
+ //wp_schedule_single_event( time() + DAY_IN_SECONDS, $this->cron_name_daily );
278
+ } else {
279
+ set_transient( $this->tran_name_plugins_to_batch, $all_plugins, DAY_IN_SECONDS );
280
+ wp_schedule_single_event( time(), $this->cron_name_batching );
281
+ }
282
+ }
283
+
284
+ private function try_get_response_body( $plugin, $second_pass ) {
285
+ //Some of this code is lifted from class-wp-upgrader
286
+
287
+ //Get the WordPress current version to be polite in the API call
288
+ include( ABSPATH . WPINC . '/version.php' );
289
+
290
+ if ( ! defined( 'MINUTE_IN_SECONDS' ) ) {
291
+ define( 'MINUTE_IN_SECONDS', 60 );
292
+ }
293
+
294
+ if ( ! defined( 'HOUR_IN_SECONDS' ) ) {
295
+ define( 'HOUR_IN_SECONDS', 60 * MINUTE_IN_SECONDS );
296
+ }
297
+ global $wp_version;
298
+
299
+ //General options to be passed to wp_remote_get
300
+ $options = array(
301
+ 'timeout' => HOUR_IN_SECONDS,
302
+ 'user-agent' => 'WordPress/' . $wp_version . '; ' . get_bloginfo( 'url' ),
303
+ );
304
+
305
+ //The URL for the endpoint
306
+ $url = $http_url = 'http://api.wordpress.org/plugins/info/1.0/';
307
+
308
+ //If we support SSL
309
+ //Requires WP 3.2.0
310
+ if ( $ssl = wp_http_supports( array( 'ssl' ) ) ) {
311
+ //Requires WP 3.4.0
312
+ $url = set_url_scheme( $url, 'https' );
313
+ }
314
+
315
+ $plugin_dir = $plugin;
316
+ if ( strpos( $plugin, '/' ) !== false ) {
317
+ $plugin_dir = dirname( $plugin );
318
+ }
319
+
320
+ //Try to get the response (usually the SSL version)
321
+ //Requires WP 2.7.0
322
+ $raw_response = wp_remote_get( $url . $plugin_dir, $options );
323
+
324
+ //If we don't have an error and we received a valid response code
325
+ //Requires WP 2.7.0
326
+ if ( ! is_wp_error( $raw_response ) && 200 === (int) wp_remote_retrieve_response_code( $raw_response ) ) {
327
+ //Get the actual body
328
+ //Requires WP 2.7.0
329
+ $body = wp_remote_retrieve_body( $raw_response );
330
+
331
+ //Make sure that it isn't empty and also not an empty serialized object
332
+ if ( '' !== $body && 'N;' !== $body ) {
333
+ //If valid, return that
334
+ return $body;
335
+ }
336
+ }
337
+
338
+ //The above valid
339
+ //If we previously tried an SSL version try without SSL
340
+ //Code below same as above block
341
+ if ( $ssl ) {
342
+ $raw_response = wp_remote_get( $http_url . $plugin, $options );
343
+ if ( ! is_wp_error( $raw_response ) && 200 === (int) wp_remote_retrieve_response_code( $raw_response ) ) {
344
+ $body = wp_remote_retrieve_body( $raw_response );
345
+ if ( '' !== $body && 'N;' !== $body ) {
346
+ return $body;
347
+ }
348
+ }
349
+ }
350
+
351
+ //The above failed
352
+ //If we're on a second pass already then there's nothing left to do but bail
353
+ if ( true === $second_pass ) {
354
+ return false;
355
+ }
356
+
357
+ //We're still on the first pass, try to get just the name of the directory of the plugin
358
+ $parts = explode( '/', $plugin );
359
+
360
+ //Sanity check that we have two parts, a directory and a file name
361
+ if ( 2 === count( $parts ) ) {
362
+ //Try this entire function using just the directory name
363
+ return $this->try_get_response_body( $parts[0], true );
364
+ }
365
+
366
+ //Everything above failed, bail
367
+ return false;
368
+ }
369
+ }
370
+
class/class-mainwp-child-reports-connector-backups.php ADDED
@@ -0,0 +1,76 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if ( class_exists( 'MainWP_WP_Stream_Connector' ) ) {
3
+ class MainWP_Child_Reports_Connector_Backups extends MainWP_WP_Stream_Connector {
4
+
5
+ /**
6
+ * Connector slug
7
+ *
8
+ * @var string
9
+ */
10
+ public static $name = 'mainwp_backups';
11
+
12
+ /**
13
+ * Actions registered for this connector
14
+ *
15
+ * @var array
16
+ */
17
+ public static $actions = array(
18
+ 'mainwp_backup',
19
+ );
20
+
21
+ /**
22
+ * Return translated connector label
23
+ *
24
+ * @return string Translated connector label
25
+ */
26
+ public static function get_label() {
27
+ return __( 'MainWP Backups', 'default' );
28
+ }
29
+
30
+ /**
31
+ * Return translated action labels
32
+ *
33
+ * @return array Action label translations
34
+ */
35
+ public static function get_action_labels() {
36
+ return array(
37
+ 'mainwp_backup' => __( 'MainWP Backup', 'default' ),
38
+ );
39
+ }
40
+
41
+ /**
42
+ * Return translated context labels
43
+ *
44
+ * @return array Context label translations
45
+ */
46
+ public static function get_context_labels() {
47
+ return array(
48
+ 'mainwp_backups' => __( 'MainWP Backups', 'mainwp-child' ),
49
+ );
50
+ }
51
+
52
+ /**
53
+ * Add action links to Stream drop row in admin list screen
54
+ *
55
+ * @filter wp_stream_action_links_{connector}
56
+ *
57
+ * @param array $links Previous links registered
58
+ * @param int $record Stream record
59
+ *
60
+ * @return array Action links
61
+ */
62
+ public static function action_links( $links, $record ) {
63
+ return $links;
64
+ }
65
+
66
+ public static function callback_mainwp_backup( $destination, $message, $size, $status, $type ) {
67
+ self::log(
68
+ $message,
69
+ compact( 'destination', 'status', 'type', 'size' ),
70
+ 0,
71
+ array( 'mainwp_backups' => 'mainwp_backup' )
72
+ );
73
+ }
74
+ }
75
+ }
76
+
class/class-mainwp-child-reports-connector-sucuri.php ADDED
@@ -0,0 +1,92 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if ( class_exists( 'MainWP_WP_Stream_Connector' ) ) {
3
+ class MainWP_Child_Reports_Connector_Sucuri extends MainWP_WP_Stream_Connector {
4
+
5
+ /**
6
+ * Connector slug
7
+ *
8
+ * @var string
9
+ */
10
+ public static $name = 'mainwp_sucuri';
11
+
12
+ /**
13
+ * Actions registered for this connector
14
+ *
15
+ * @var array
16
+ */
17
+ public static $actions = array(
18
+ 'mainwp_sucuri_scan',
19
+ );
20
+
21
+ /**
22
+ * Return translated connector label
23
+ *
24
+ * @return string Translated connector label
25
+ */
26
+ public static function get_label() {
27
+ return __( 'MainWP Sucuri', 'default' );
28
+ }
29
+
30
+ /**
31
+ * Return translated action labels
32
+ *
33
+ * @return array Action label translations
34
+ */
35
+ public static function get_action_labels() {
36
+ return array(
37
+ 'mainwp_sucuri_scan' => __( 'Scan', 'default' ),
38
+ );
39
+ }
40
+
41
+ /**
42
+ * Return translated context labels
43
+ *
44
+ * @return array Context label translations
45
+ */
46
+ public static function get_context_labels() {
47
+ return array(
48
+ 'mainwp_sucuri' => __( 'MainWP Sucuri', 'default' ),
49
+ );
50
+ }
51
+
52
+ /**
53
+ * Add action links to Stream drop row in admin list screen
54
+ *
55
+ * @filter wp_stream_action_links_{connector}
56
+ *
57
+ * @param array $links Previous links registered
58
+ * @param int $record Stream record
59
+ *
60
+ * @return array Action links
61
+ */
62
+ public static function action_links( $links, $record ) {
63
+ return $links;
64
+ }
65
+
66
+ public static function callback_mainwp_sucuri_scan( $data, $scan_status, $scan_data ) {
67
+ $message = '';
68
+ if ( 'success' === $scan_status ) {
69
+ $message = __( 'Sucuri scan successful!', 'mainwp-child' );
70
+ $scan_status = 'success';
71
+ } else {
72
+ $message = __( 'Sucuri scan failed!', 'mainwp-child' );
73
+ $scan_status = 'failed';
74
+ }
75
+
76
+ $scan_result = maybe_unserialize( base64_decode( $data ) );
77
+ $status = $webtrust = '';
78
+ if ( is_array( $scan_result ) ) {
79
+ $status = isset( $scan_result['status'] ) ? $scan_result['status'] : '';
80
+ $webtrust = isset( $scan_result['webtrust'] ) ? $scan_result['webtrust'] : '';
81
+ }
82
+
83
+ self::log(
84
+ $message,
85
+ compact( 'scan_status', 'status', 'webtrust', 'scan_data' ),
86
+ 0,
87
+ array( 'mainwp_sucuri' => 'mainwp_sucuri_scan' )
88
+ );
89
+ }
90
+ }
91
+ }
92
+
class/class-mainwp-child-robot.php ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class MainWP_Child_Robot {
4
+ public static $instance = null;
5
+
6
+ static function Instance() {
7
+ if ( null === MainWP_Child_Robot::$instance ) {
8
+ MainWP_Child_Robot::$instance = new MainWP_Child_Robot();
9
+ }
10
+
11
+ return MainWP_Child_Robot::$instance;
12
+ }
13
+
14
+ public function wpr_insertcomments( $postid, $comments ) {
15
+ remove_filter( 'comment_text', 'make_clickable', 9 );
16
+ foreach ( $comments as $comment ) {
17
+ $comment_post_ID = $postid;
18
+ $comment_date = $comment['dts'];
19
+ $comment_date = date( 'Y-m-d H:i:s', $comment_date );
20
+ $comment_date_gmt = $comment_date;
21
+ $rnd = rand( 1, 9999 );
22
+ $comment_author_email = "someone$rnd@domain.com";
23
+ $comment_author = $comment['author'];
24
+ $comment_author_url = '';
25
+ $comment_content = '';
26
+ $comment_content .= $comment['content'];
27
+ $comment_type = '';
28
+ $user_ID = '';
29
+ $comment_approved = 1;
30
+ $commentdata = compact( 'comment_post_ID', 'comment_date', 'comment_date_gmt', 'comment_author', 'comment_author_email', 'comment_author_url', 'comment_content', 'comment_type', 'user_ID', 'comment_approved' );
31
+ $comment_id = wp_insert_comment( $commentdata );
32
+ }
33
+ }
34
+ }
class/class-mainwp-child-server-information.php ADDED
@@ -0,0 +1,1687 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class MainWP_Child_Server_Information {
4
+ const WARNING = 1;
5
+ const ERROR = 2;
6
+
7
+ public static function init() {
8
+ add_action( 'wp_ajax_mainwp-child_dismiss_warnings', array(
9
+ 'MainWP_Child_Server_Information',
10
+ 'dismissWarnings',
11
+ ) );
12
+ }
13
+
14
+ public static function dismissWarnings() {
15
+ if ( isset( $_POST['what'] ) ) {
16
+ $dismissWarnings = get_option( 'mainwp_child_dismiss_warnings' );
17
+ if ( ! is_array( $dismissWarnings ) ) {
18
+ $dismissWarnings = array();
19
+ }
20
+
21
+ if ( $_POST['what'] == 'warning' ) {
22
+ if (isset($_POST['warnings']))
23
+ $warnings = intval($_POST['warnings']);
24
+ else
25
+ $warnings = self::getWarnings();
26
+ $dismissWarnings['warnings'] = $warnings;
27
+ }
28
+ MainWP_Helper::update_option( 'mainwp_child_dismiss_warnings', $dismissWarnings );
29
+ }
30
+ }
31
+
32
+ public static function showWarnings() {
33
+ if ( stristr( $_SERVER['REQUEST_URI'], 'mainwp_child_tab' ) || stristr( $_SERVER['REQUEST_URI'], 'mainwp-reports-page' ) || stristr( $_SERVER['REQUEST_URI'], 'mainwp-reports-settings' )) {
34
+ return;
35
+ }
36
+
37
+ $warnings = self::getWarnings();
38
+
39
+ $dismissWarnings = get_option( 'mainwp_child_dismiss_warnings' );
40
+ if ( ! is_array( $dismissWarnings ) ) {
41
+ $dismissWarnings = array();
42
+ }
43
+
44
+ if ( isset( $dismissWarnings['warnings'] ) && $dismissWarnings['warnings'] >= $warnings ) {
45
+ $warnings = 0;
46
+ }
47
+
48
+ if ( 0 === $warnings ) {
49
+ return;
50
+ }
51
+
52
+ if ( $warnings > 0 ) {
53
+ $dismissWarnings['warnings'] = 0;
54
+ }
55
+
56
+ MainWP_Helper::update_option( 'mainwp_child_dismiss_warnings', $dismissWarnings );
57
+ ?>
58
+ <script language="javascript">
59
+ dismiss_warnings = function ( pElement, pAction ) {
60
+ var table = jQuery( pElement.parents( 'table' )[0] );
61
+ pElement.parents( 'tr' )[0].remove();
62
+ if ( table.find( 'tr' ).length == 0 ) {
63
+ jQuery( '#mainwp-child_server_warnings' ).hide();
64
+ }
65
+
66
+ var data = {
67
+ action: 'mainwp-child_dismiss_warnings',
68
+ what: pAction,
69
+ warnings: <?php echo intval($warnings); ?>
70
+ };
71
+
72
+ jQuery.ajax( {
73
+ type: "POST",
74
+ url: ajaxurl,
75
+ data: data,
76
+ success: function ( resp ) {
77
+ },
78
+ error: function () {
79
+ },
80
+ dataType: 'json'
81
+ } );
82
+
83
+ return false;
84
+ };
85
+ jQuery( document ).on( 'click', '#mainwp-child-connect-warning-dismiss', function () {
86
+ return dismiss_warnings( jQuery( this ), 'warning' );
87
+ } );
88
+ jQuery( document ).on( 'click', '#mainwp-child-all-pages-warning-dismiss', function () {
89
+ return dismiss_warnings( jQuery( this ), 'conflict' );
90
+ } );
91
+ </script>
92
+ <style type="text/css">
93
+ .mainwp-child_info-box-red-warning {
94
+ background-color: rgba(187, 114, 57, 0.2) !important;
95
+ border-bottom: 4px solid #bb7239 !important;
96
+ border-top: 1px solid #bb7239 !important;
97
+ border-left: 1px solid #bb7239 !important;
98
+ border-right: 1px solid #bb7239 !important;
99
+ -webkit-border-radius: 3px;
100
+ -moz-border-radius: 3px;
101
+ border-radius: 3px;
102
+ margin: 1em 0 !important;
103
+
104
+ background-image: url('<?php echo esc_url( plugins_url( 'images/mainwp-icon-orange.png', dirname( __FILE__ ) ) ); ?>') !important;
105
+ background-position: 1.5em 50% !important;
106
+ background-repeat: no-repeat !important;
107
+ background-size: 30px !important;
108
+ }
109
+
110
+ .mainwp-child_info-box-red-warning table {
111
+ background-color: rgba(187, 114, 57, 0) !important;
112
+ border: 0px;
113
+ padding-left: 4.5em;
114
+ background-position: 1.5em 50% !important;
115
+ background-repeat: no-repeat !important;
116
+ background-size: 30px !important;
117
+ }
118
+ </style>
119
+
120
+ <div class="updated mainwp-child_info-box-red-warning" id="mainwp-child_server_warnings">
121
+ <table id="mainwp-table" class="wp-list-table widefat" cellspacing="0">
122
+ <tbody id="the-sites-list" class="list:sites">
123
+ <?php
124
+ $warning = '';
125
+
126
+ if ( $warnings > 0 ) {
127
+ $warning .= '<tr><td colspan="2">This site may not connect to your dashboard or may have other issues. Check your <a href="options-general.php?page=mainwp_child_tab">MainWP server information page</a> to review and <a href="http://docs.mainwp.com/child-site-issues/">check here for more information on possible fixes</a></td><td style="text-align: right;"><a href="#" id="mainwp-child-connect-warning-dismiss">Dismiss</a></td></tr>';
128
+ }
129
+ echo $warning;
130
+ ?>
131
+ </tbody>
132
+ </table>
133
+ </div>
134
+ <?php
135
+ }
136
+
137
+ public static function renderPage() {
138
+ ?>
139
+ <script language="javascript">
140
+
141
+ /* FileSaver.js
142
+ * A saveAs() FileSaver implementation.
143
+ * 2013-01-23
144
+ *
145
+ * By Eli Grey, http://eligrey.com
146
+ * License: X11/MIT
147
+ * See LICENSE.md
148
+ */
149
+
150
+ /*global self */
151
+ /*jslint bitwise: true, regexp: true, confusion: true, es5: true, vars: true, white: true,
152
+ plusplus: true */
153
+
154
+ /*! @source http://purl.eligrey.com/github/FileSaver.js/blob/master/FileSaver.js */
155
+
156
+ var childSaveAs = childSaveAs
157
+ || (navigator.msSaveBlob && navigator.msSaveBlob.bind(navigator))
158
+ || (function(view) {
159
+ "use strict";
160
+ var
161
+ doc = view.document
162
+ // only get URL when necessary in case BlobBuilder.js hasn't overridden it yet
163
+ , get_URL = function() {
164
+ return view.URL || view.webkitURL || view;
165
+ }
166
+ , URL = view.URL || view.webkitURL || view
167
+ , save_link = doc.createElementNS("http://www.w3.org/1999/xhtml", "a")
168
+ , can_use_save_link = "download" in save_link
169
+ , click = function(node) {
170
+ var event = doc.createEvent("MouseEvents");
171
+ event.initMouseEvent(
172
+ "click", true, false, view, 0, 0, 0, 0, 0
173
+ , false, false, false, false, 0, null
174
+ );
175
+ return node.dispatchEvent(event); // false if event was cancelled
176
+ }
177
+ , webkit_req_fs = view.webkitRequestFileSystem
178
+ , req_fs = view.requestFileSystem || webkit_req_fs || view.mozRequestFileSystem
179
+ , throw_outside = function (ex) {
180
+ (view.setImmediate || view.setTimeout)(function() {
181
+ throw ex;
182
+ }, 0);
183
+ }
184
+ , force_saveable_type = "application/octet-stream"
185
+ , fs_min_size = 0
186
+ , deletion_queue = []
187
+ , process_deletion_queue = function() {
188
+ var i = deletion_queue.length;
189
+ while (i--) {
190
+ var file = deletion_queue[i];
191
+ if (typeof file === "string") { // file is an object URL
192
+ URL.revokeObjectURL(file);
193
+ } else { // file is a File
194
+ file.remove();
195
+ }
196
+ }
197
+ deletion_queue.length = 0; // clear queue
198
+ }
199
+ , dispatch = function(filesaver, event_types, event) {
200
+ event_types = [].concat(event_types);
201
+ var i = event_types.length;
202
+ while (i--) {
203
+ var listener = filesaver["on" + event_types[i]];
204
+ if (typeof listener === "function") {
205
+ try {
206
+ listener.call(filesaver, event || filesaver);
207
+ } catch (ex) {
208
+ throw_outside(ex);
209
+ }
210
+ }
211
+ }
212
+ }
213
+ , FileSaver = function(blob, name) {
214
+ // First try a.download, then web filesystem, then object URLs
215
+ var
216
+ filesaver = this
217
+ , type = blob.type
218
+ , blob_changed = false
219
+ , object_url
220
+ , target_view
221
+ , get_object_url = function() {
222
+ var object_url = get_URL().createObjectURL(blob);
223
+ deletion_queue.push(object_url);
224
+ return object_url;
225
+ }
226
+ , dispatch_all = function() {
227
+ dispatch(filesaver, "writestart progress write writeend".split(" "));
228
+ }
229
+ // on any filesys errors revert to saving with object URLs
230
+ , fs_error = function() {
231
+ // don't create more object URLs than needed
232
+ if (blob_changed || !object_url) {
233
+ object_url = get_object_url(blob);
234
+ }
235
+ if (target_view) {
236
+ target_view.location.href = object_url;
237
+ }
238
+ filesaver.readyState = filesaver.DONE;
239
+ dispatch_all();
240
+ }
241
+ , abortable = function(func) {
242
+ return function() {
243
+ if (filesaver.readyState !== filesaver.DONE) {
244
+ return func.apply(this, arguments);
245
+ }
246
+ };
247
+ }
248
+ , create_if_not_found = {create: true, exclusive: false}
249
+ , slice
250
+ ;
251
+ filesaver.readyState = filesaver.INIT;
252
+ if (!name) {
253
+ name = "download";
254
+ }
255
+ if (can_use_save_link) {
256
+ object_url = get_object_url(blob);
257
+ save_link.href = object_url;
258
+ save_link.download = name;
259
+ if (click(save_link)) {
260
+ filesaver.readyState = filesaver.DONE;
261
+ dispatch_all();
262
+ return;
263
+ }
264
+ }
265
+ // Object and web filesystem URLs have a problem saving in Google Chrome when
266
+ // viewed in a tab, so I force save with application/octet-stream
267
+ // http://code.google.com/p/chromium/issues/detail?id=91158
268
+ if (view.chrome && type && type !== force_saveable_type) {
269
+ slice = blob.slice || blob.webkitSlice;
270
+ blob = slice.call(blob, 0, blob.size, force_saveable_type);
271
+ blob_changed = true;
272
+ }
273
+ // Since I can't be sure that the guessed media type will trigger a download
274
+ // in WebKit, I append .download to the filename.
275
+ // https://bugs.webkit.org/show_bug.cgi?id=65440
276
+ if (webkit_req_fs && name !== "download") {
277
+ name += ".download";
278
+ }
279
+ if (type === force_saveable_type || webkit_req_fs) {
280
+ target_view = view;
281
+ } else {
282
+ target_view = view.open();
283
+ }
284
+ if (!req_fs) {
285
+ fs_error();
286
+ return;
287
+ }
288
+ fs_min_size += blob.size;
289
+ req_fs(view.TEMPORARY, fs_min_size, abortable(function(fs) {
290
+ fs.root.getDirectory("saved", create_if_not_found, abortable(function(dir) {
291
+ var save = function() {
292
+ dir.getFile(name, create_if_not_found, abortable(function(file) {
293
+ file.createWriter(abortable(function(writer) {
294
+ writer.onwriteend = function(event) {
295
+ target_view.location.href = file.toURL();
296
+ deletion_queue.push(file);
297
+ filesaver.readyState = filesaver.DONE;
298
+ dispatch(filesaver, "writeend", event);
299
+ };
300
+ writer.onerror = function() {
301
+ var error = writer.error;
302
+ if (error.code !== error.ABORT_ERR) {
303
+ fs_error();
304
+ }
305
+ };
306
+ "writestart progress write abort".split(" ").forEach(function(event) {
307
+ writer["on" + event] = filesaver["on" + event];
308
+ });
309
+ writer.write(blob);
310
+ filesaver.abort = function() {
311
+ writer.abort();
312
+ filesaver.readyState = filesaver.DONE;
313
+ };
314
+ filesaver.readyState = filesaver.WRITING;
315
+ }), fs_error);
316
+ }), fs_error);
317
+ };
318
+ dir.getFile(name, {create: false}, abortable(function(file) {
319
+ // delete file if it already exists
320
+ file.remove();
321
+ save();
322
+ }), abortable(function(ex) {
323
+ if (ex.code === ex.NOT_FOUND_ERR) {
324
+ save();
325
+ } else {
326
+ fs_error();
327
+ }
328
+ }));
329
+ }), fs_error);
330
+ }), fs_error);
331
+ }
332
+ , FS_proto = FileSaver.prototype
333
+ , childSaveAs = function(blob, name) {
334
+ return new FileSaver(blob, name);
335
+ }
336
+ ;
337
+ FS_proto.abort = function() {
338
+ var filesaver = this;
339
+ filesaver.readyState = filesaver.DONE;
340
+ dispatch(filesaver, "abort");
341
+ };
342
+ FS_proto.readyState = FS_proto.INIT = 0;
343
+ FS_proto.WRITING = 1;
344
+ FS_proto.DONE = 2;
345
+
346
+ FS_proto.error =
347
+ FS_proto.onwritestart =
348
+ FS_proto.onprogress =
349
+ FS_proto.onwrite =
350
+ FS_proto.onabort =
351
+ FS_proto.onerror =
352
+ FS_proto.onwriteend =
353
+ null;
354
+
355
+ view.addEventListener("unload", process_deletion_queue, false);
356
+ return childSaveAs;
357
+ }(self));
358
+
359
+
360
+ mwp_child_strCut = function(i,l,s,w) {
361
+ var o = i.toString();
362
+ if (!s) { s = '0'; }
363
+ while (o.length < parseInt(l)) {
364
+ // empty
365
+ if(w == 'undefined'){
366
+ o = s + o;
367
+ }else{
368
+ o = o + s;
369
+ }
370
+ }
371
+ return o;
372
+ };
373
+ jQuery('a.mwp-child-get-system-report-btn').live('click', function(){
374
+ var report = "";
375
+ jQuery('.mwp_server_info_box thead, .mwp_server_info_box tbody').each(function(){
376
+ var td_len = [35, 55, 45, 12, 12];
377
+ var th_count = 0;
378
+ var i;
379
+ if ( jQuery( this ).is('thead') ) {
380
+ i = 0;
381
+ report = report + "\n### ";
382
+ th_count = jQuery( this ).find('th:not(".mwp-not-generate-row")').length;
383
+ jQuery( this ).find('th:not(".mwp-not-generate-row")').each(function(){
384
+ var len = td_len[i];
385
+ if (i == 0 || i == th_count -1)
386
+ len = len - 4;
387
+ report = report + mwp_child_strCut(jQuery.trim( jQuery( this ).text()), len, ' ' );
388
+ i++;
389
+ });
390
+ report = report + " ###\n\n";
391
+ } else {
392
+ jQuery('tr', jQuery( this )).each(function(){
393
+ if (jQuery( this ).hasClass('mwp-not-generate-row'))
394
+ return;
395
+ i = 0;
396
+ jQuery( this ).find('td:not(".mwp-not-generate-row")').each(function(){
397
+ if (jQuery( this ).hasClass('mwp-hide-generate-row')) {
398
+ report = report + mwp_child_strCut(' ', td_len[i], ' ' );
399
+ i++;
400
+ return;
401
+ }
402
+ report = report + mwp_child_strCut(jQuery.trim( jQuery( this ).text()), td_len[i], ' ' );
403
+ i++;
404
+ });
405
+ report = report + "\n";
406
+ });
407
+
408
+ }
409
+ } );
410
+
411
+ try {
412
+ jQuery("#mwp-server-information").slideDown();
413
+ jQuery("#mwp-server-information textarea").val( report ).focus().select();
414
+ jQuery(this).fadeOut();
415
+ jQuery('.mwp_child_close_srv_info').show();
416
+ return false;
417
+ } catch(e){ }
418
+ });
419
+
420
+ jQuery('a#mwp_child_close_srv_info').live('click', function(){
421
+ jQuery('#mwp-server-information').hide();
422
+ jQuery('.mwp_child_close_srv_info').hide();
423
+ jQuery('a.mwp-child-get-system-report-btn').show();
424
+ return false;
425
+ });
426
+ jQuery('#mwp_child_download_srv_info').live('click', function () {
427
+ var server_info = jQuery('#mwp-server-information textarea').val();
428
+ var blob = new Blob([server_info], {type: "text/plain;charset=utf-8"});
429
+ childSaveAs(blob, "server_child_information.txt");
430
+ });
431
+
432
+ </script>
433
+ <style type="text/css">
434
+ #mwp-server-information {
435
+ display: none;
436
+ margin: 10px 0;
437
+ padding: 0;
438
+ position: relative;
439
+ }
440
+
441
+ #mwp-server-information textarea {
442
+ border-radius: 0;
443
+ font-family: monospace;
444
+ font-size: 12px;
445
+ height: 300px;
446
+ line-height: 20px;
447
+ margin: 0;
448
+ outline: 0 none;
449
+ padding: 20px;
450
+ resize: none;
451
+ width: 100%;
452
+ -moz-border-radius:0;
453
+ -webkit-border-radius:0;
454
+ }
455
+
456
+ .mwp_child_close_srv_info {
457
+ display: none;
458
+ float: right;
459
+ margin: 5px 0 5px;
460
+ }
461
+ </style>
462
+ <div class="wrap">
463
+ <div class="updated below-h2">
464
+ <p><?php _e( 'Please include this information when requesting support:', 'mainwp-child' ); ?></p>
465
+ <span class="mwp_child_close_srv_info"><a href="#" id="mwp_child_download_srv_info"><?php _e( 'Download', 'mainwp-child' ); ?></a> | <a href="#" id="mwp_child_close_srv_info"><i class="fa fa-eye-slash"></i> <?php _e( 'Hide', 'mainwp-child' ); ?>
466
+ </a></span>
467
+
468
+ <p class="submit">
469
+ <a class="button-primary mwp-child-get-system-report-btn" href="#"><?php _e( 'Get system report', 'mainwp-child' ); ?></a>
470
+ </p>
471
+
472
+ <div id="mwp-server-information"><textarea readonly="readonly" wrap="off"></textarea></div>
473
+ </div>
474
+ <br/>
475
+ <div class="mwp_server_info_box">
476
+ <h2><?php esc_html_e( 'Server Information' ); ?></h2><?php
477
+ MainWP_Child_Server_Information::render();
478
+ ?><h2><?php esc_html_e( 'Cron Schedules' ); ?></h2><?php
479
+ MainWP_Child_Server_Information::renderCron();
480
+ ?><h2><?php esc_html_e( 'Error Log' ); ?></h2><?php
481
+ MainWP_Child_Server_Information::renderErrorLogPage();
482
+ ?>
483
+ </div>
484
+ </div>
485
+ <?php
486
+ }
487
+
488
+ public static function getWarnings() {
489
+ $i = 0;
490
+
491
+ if ( ! self::check( '>=', '3.4', 'getWordpressVersion' ) ) {
492
+ $i ++;
493
+ }
494
+ if ( ! self::check( '>=', '5.2.4', 'getPHPVersion' ) ) {
495
+ $i ++;
496
+ }
497
+ if ( ! self::check( '>=', '5.0', 'getMySQLVersion' ) ) {
498
+ $i ++;
499
+ }
500
+ if ( ! self::check( '>=', '30', 'getMaxExecutionTime', '=', '0' ) ) {
501
+ $i ++;
502
+ }
503
+ if ( ! self::check( '>=', '2M', 'getUploadMaxFilesize', null, null, true ) ) {
504
+ $i ++;
505
+ }
506
+ if ( ! self::check( '>=', '2M', 'getPostMaxSize', null, null, true ) ) {
507
+ $i ++;
508
+ }
509
+ if ( ! self::check( '>=', '10000', 'getOutputBufferSize' ) ) {
510
+ $i ++;
511
+ }
512
+ // if (!self::check('=', true, 'getSSLSupport')) $i++;
513
+
514
+ if ( ! self::checkDirectoryMainWPDirectory( false ) ) {
515
+ $i ++;
516
+ }
517
+
518
+ return $i;
519
+ }
520
+
521
+ protected static function getFileSystemMethod() {
522
+ if ( defined( 'MAINWP_SAVE_FS_METHOD' ) ) {
523
+ return MAINWP_SAVE_FS_METHOD;
524
+ }
525
+ $fs = get_filesystem_method();
526
+
527
+ return $fs;
528
+ }
529
+
530
+ protected static function getFileSystemMethodCheck() {
531
+ $fsmethod = self::getFileSystemMethod();
532
+ if ( 'direct' === $fsmethod ) {
533
+ echo '<span class="mainwp-pass"><i class="fa fa-check-circle"></i> Pass</span>';
534
+ } else {
535
+ echo '<span class="mainwp-warning"><i class="fa fa-exclamation-circle"></i> Warning</span>';
536
+ }
537
+ }
538
+
539
+ public static function render() {
540
+ $branding_title = 'MainWP Child';
541
+ $isBranding = false;
542
+ if ( MainWP_Child_Branding::is_branding() ) {
543
+ $branding_title = MainWP_Child_Branding::get_branding();
544
+ $isBranding = true;
545
+ }
546
+
547
+ ?>
548
+
549
+ <table id="mainwp-table" class="wp-list-table widefat" cellspacing="0">
550
+ <thead>
551
+ <tr>
552
+ <th scope="col" class="manage-column column-posts mwp-not-generate-row"
553
+ style="width: 1px;"></th>
554
+ <th scope="col" class="manage-column column-posts" style="">
555
+ <span><?php esc_html_e( 'Server configuration', 'mainwp-child' ); ?></span></th>
556
+ <th scope="col" class="manage-column column-posts"
557
+ style=""><?php esc_html_e( 'Required value', 'mainwp-child' ); ?></th>
558
+ <th scope="col" class="manage-column column-posts" style=""><?php esc_html_e( 'Value', 'mainwp-child' ); ?></th>
559
+ <th scope="col" class="manage-column column-posts" style=""><?php esc_html_e( 'Status', 'mainwp-child' ); ?></th>
560
+ </tr>
561
+ </thead>
562
+
563
+ <tbody id="the-sites-list" class="list:sites">
564
+ <tr>
565
+ <td style="background: #333; color: #fff;" colspan="5"><?php echo esc_html( strtoupper( stripslashes( $branding_title ) ) ); ?></td>
566
+ </tr>
567
+ <tr>
568
+ <td></td>
569
+ <td><?php echo esc_html( stripslashes( $branding_title ) ); ?> Version</td>
570
+ <td><?php echo esc_html( self::getMainWPVersion() ); ?></td>
571
+ <td><?php echo esc_html( self::getCurrentVersion() ); ?></td>
572
+ <td><?php echo esc_html( self::getMainWPVersionCheck() ); ?></td>
573
+ </tr>
574
+ <?php
575
+ self::checkDirectoryMainWPDirectory();
576
+ $server = get_option( 'mainwp_child_server' );
577
+ ?>
578
+ <tr>
579
+ <td></td>
580
+ <td><?php _e( 'Currently connected to dashboard URL', 'mainwp-child' ); ?></td>
581
+ <td><?php echo esc_html( $server ); ?></td>
582
+ <td></td>
583
+ <td></td>
584
+ </tr>
585
+ <tr>
586
+ <td style="background: #333; color: #fff;" colspan="5"><?php esc_html_e( 'WORDPRESS', 'mainwp-child' ); ?></td>
587
+ </tr><?php
588
+ self::renderRow( 'WordPress Version', '>=', '3.4', 'getWordpressVersion' );
589
+ self::renderRow( 'WordPress Memory Limit', '>=', '64M', 'getWordpressMemoryLimit' );
590
+ self::renderRow( 'MultiSite Disabled', '=', true, 'checkIfMultisite' );
591
+ ?>
592
+ <tr>
593
+ <td></td>
594
+ <td><?php esc_html_e( 'FileSystem Method', 'mainwp-child' ); ?></td>
595
+ <td><?php echo esc_html( '= direct' ); ?></td>
596
+ <td><?php echo esc_html( self::getFileSystemMethod() ); ?></td>
597
+ <td><?php echo esc_html( self::getFileSystemMethodCheck() ); ?></td>
598
+ </tr>
599
+ <tr>
600
+ <td style="background: #333; color: #fff;"
601
+ colspan="5"><?php esc_html_e( 'PHP SETTINGS', 'mainwp-child' ); ?></td>
602
+ </tr><?php
603
+ self::renderRow( 'PHP Version', '>=', '5.6', 'getPHPVersion' );
604
+ ?>
605
+ <tr>
606
+ <td></td>
607
+ <td><?php esc_html_e( 'PHP Safe Mode Disabled', 'mainwp-child' ); ?></td>
608
+ <td colspan="3"><?php self::getPHPSafeMode(); ?></td>
609
+ </tr>
610
+ <?php
611
+ self::renderRowSec( 'PHP Max Execution Time', '>=', '30', 'getMaxExecutionTime', 'seconds', '=', '0' );
612
+ self::renderRowSec( 'PHP Max Input Time', '>=', '30', 'getMaxInputTime', 'seconds', '=', '0' );
613
+ self::renderRow( 'PHP Memory Limit', '>=', '128M', 'getPHPMemoryLimit', '(256M+ best for big backups)', null, null, true );
614
+ self::renderRow( 'PCRE Backtracking Limit', '>=', '10000', 'getOutputBufferSize' );
615
+ self::renderRow( 'PHP Upload Max Filesize', '>=', '2M', 'getUploadMaxFilesize', '(2MB+ best for upload of big plugins)', null, null, true );
616
+ self::renderRow( 'PHP Post Max Size', '>=', '2M', 'getPostMaxSize', '(2MB+ best for upload of big plugins)', null, null, true );
617
+ self::renderRow( 'SSL Extension Enabled', '=', true, 'getSSLSupport' );
618
+ self::renderRowSec( 'SSL Warnings', '=', '', 'getSSLWarning', 'empty', '' );
619
+ self::renderRowSec( 'cURL Extension Enabled', '=', true, 'getCurlSupport', '', '', null, '', null, self::ERROR );
620
+ self::renderRowSec( 'cURL Timeout', '>=', '300', 'getCurlTimeout', 'seconds', '=', '0' );
621
+ if ( function_exists( 'curl_version' ) ) {
622
+ self::renderRowSec( 'cURL Version', '>=', '7.18.1', 'getCurlVersion', '', '', null );
623
+ self::renderRowSec( 'cURL SSL Version', '>=', array(
624
+ 'version_number' => 0x009080cf,
625
+ 'version' => 'OpenSSL/0.9.8l',
626
+ ), 'getCurlSSLVersion', '', '', null, '', 'curlssl' );
627
+ }
628
+ ?>
629
+ <tr>
630
+ <td style="background: #333; color: #fff;"
631
+ colspan="5"><?php esc_html_e( 'MySQL SETTINGS', 'mainwp-child' ); ?></td>
632
+ </tr><?php
633
+ self::renderRow( 'MySQL Version', '>=', '5.0', 'getMySQLVersion' );
634
+ ?>
635
+ <tr>
636
+ <td style="background: #333; color: #fff;"
637
+ colspan="5"><?php esc_html_e( 'BACKUP ARCHIVE INFORMATION', 'mainwp-child' ); ?></td>
638
+ </tr><?php
639
+ self::renderRow( 'ZipArchive enabled in PHP', '=', true, 'getZipArchiveEnabled' );
640
+ self::renderRow( 'Tar GZip supported', '=', true, 'getGZipEnabled' );
641
+ self::renderRow( 'Tar BZip2 supported', '=', true, 'getBZipEnabled' );
642
+ ?>
643
+
644
+ <tr>
645
+ <td style="background: #333; color: #fff;"
646
+ colspan="5"><?php esc_html_e( 'SERVER INFORMATION', 'mainwp-child' ); ?></td>
647
+ </tr>
648
+ <tr>
649
+ <td></td>
650
+ <td><?php esc_html_e( 'WordPress Root Directory', 'mainwp-child' ); ?></td>
651
+ <td colspan="3"><?php self::getWPRoot(); ?></td>
652
+ </tr>
653
+ <tr>
654
+ <td></td>
655
+ <td><?php esc_html_e( 'Server Name', 'mainwp-child' ); ?></td>
656
+ <td colspan="3"><?php self::getServerName(); ?></td>
657
+ </tr>
658
+ <tr>
659
+ <td></td>
660
+ <td><?php esc_html_e( 'Server Software', 'mainwp-child' ); ?></td>
661
+ <td colspan="3"><?php self::getServerSoftware(); ?></td>
662
+ </tr>
663
+ <tr>
664
+ <td></td>
665
+ <td><?php esc_html_e( 'Operating System', 'mainwp-child' ); ?></td>
666
+ <td colspan="3"><?php self::getOS(); ?></td>
667
+ </tr>
668
+ <tr>
669
+ <td></td>
670
+ <td><?php esc_html_e( 'Architecture', 'mainwp-child' ); ?></td>
671
+ <td colspan="3"><?php self::getArchitecture(); ?></td>
672
+ </tr>
673
+ <tr>
674
+ <td></td>
675
+ <td><?php esc_html_e( 'Server IP', 'mainwp-child' ); ?></td>
676
+ <td colspan="3"><?php self::getServerIP(); ?></td>
677
+ </tr>
678
+ <tr>
679
+ <td></td>
680
+ <td><?php esc_html_e( 'Server Protocol', 'mainwp-child' ); ?></td>
681
+ <td colspan="3"><?php self::getServerProtocol(); ?></td>
682
+ </tr>
683
+ <tr>
684
+ <td></td>
685
+ <td><?php esc_html_e( 'HTTP Host', 'mainwp-child' ); ?></td>
686
+ <td colspan="3"><?php self::getHTTPHost(); ?></td>
687
+ </tr>
688
+ <tr>
689
+ <td></td>
690
+ <td><?php esc_html_e( 'HTTPS', 'mainwp-child' ); ?></td>
691
+ <td colspan="3"><?php self::getHTTPS(); ?></td>
692
+ </tr>
693
+ <tr>
694
+ <td></td>
695
+ <td><?php esc_html_e( 'Server self connect', 'mainwp-child' ); ?></td>
696
+ <td colspan="3"><?php self::serverSelfConnect(); ?></td>
697
+ </tr>
698
+ <tr>
699
+ <td></td>
700
+ <td><?php esc_html_e( 'User Agent', 'mainwp-child' ); ?></td>
701
+ <td colspan="3"><?php self::getUserAgent(); ?></td>
702
+ </tr>
703
+ <tr>
704
+ <td></td>
705
+ <td><?php esc_html_e( 'Server Port', 'mainwp-child' ); ?></td>
706
+ <td colspan="3"><?php self::getServerPort(); ?></td>
707
+ </tr>
708
+ <tr>
709
+ <td></td>
710
+ <td><?php esc_html_e( 'Gateway Interface', 'mainwp-child' ); ?></td>
711
+ <td colspan="3"><?php self::getServerGetawayInterface(); ?></td>
712
+ </tr>
713
+ <tr>
714
+ <td></td>
715
+ <td><?php esc_html_e( 'Memory Usage', 'mainwp-child' ); ?></td>
716
+ <td colspan="3"><?php self::memoryUsage(); ?></td>
717
+ </tr>
718
+ <tr>
719
+ <td></td>
720
+ <td><?php esc_html_e( 'Complete URL', 'mainwp-child' ); ?></td>
721
+ <td colspan="3"><?php self::getCompleteURL(); ?></td>
722
+ </tr>
723
+ <tr>
724
+ <td></td>
725
+ <td><?php esc_html_e( 'Request Time', 'mainwp-child' ); ?></td>
726
+ <td colspan="3"><?php self::getServerRequestTime(); ?></td>
727
+ </tr>
728
+ <tr>
729
+ <td></td>
730
+ <td><?php esc_html_e( 'Accept Content', 'mainwp-child' ); ?></td>
731
+ <td colspan="3"><?php self::getServerHTTPAccept(); ?></td>
732
+ </tr>
733
+ <tr>
734
+ <td></td>
735
+ <td><?php esc_html_e( 'Accept-Charset Content', 'mainwp-child' ); ?></td>
736
+ <td colspan="3"><?php self::getServerAcceptCharset(); ?></td>
737
+ </tr>
738
+ <tr>
739
+ <td></td>
740
+ <td><?php esc_html_e( 'Currently Executing Script Pathname', 'mainwp-child' ); ?></td>
741
+ <td colspan="3"><?php self::getScriptFileName(); ?></td>
742
+ </tr>
743
+ <tr>
744
+ <td></td>
745
+ <td><?php esc_html_e( 'Current Page URI', 'mainwp-child' ); ?></td>
746
+ <td colspan="3"><?php self::getCurrentPageURI(); ?></td>
747
+ </tr>
748
+ <tr>
749
+ <td></td>
750
+ <td><?php esc_html_e( 'Remote Address', 'mainwp-child' ); ?></td>
751
+ <td colspan="3"><?php self::getRemoteAddress(); ?></td>
752
+ </tr>
753
+ <tr>
754
+ <td></td>
755
+ <td><?php esc_html_e( 'Remote Host', 'mainwp-child' ); ?></td>
756
+ <td colspan="3"><?php self::getRemoteHost(); ?></td>
757
+ </tr>
758
+ <tr>
759
+ <td></td>
760
+ <td><?php esc_html_e( 'Remote Port', 'mainwp-child' ); ?></td>
761
+ <td colspan="3"><?php self::getRemotePort(); ?></td>
762
+ </tr>
763
+ <tr>
764
+ <td style="background: #333; color: #fff;" colspan="5"><?php esc_html_e( 'PHP INFORMATION', 'mainwp-child' ); ?></td>
765
+ </tr>
766
+ <tr>
767
+ <td></td>
768
+ <td><?php esc_html_e( 'PHP Allow URL fopen', 'mainwp-child' ); ?></td>
769
+ <td colspan="3"><?php self::getPHPAllowUrlFopen(); ?></td>
770
+ </tr>
771
+ <tr>
772
+ <td></td>
773
+ <td><?php esc_html_e( 'PHP Exif Support', 'mainwp-child' ); ?></td>
774
+ <td colspan="3"><?php self::getPHPExif(); ?></td>
775
+ </tr>
776
+ <tr>
777
+ <td></td>
778
+ <td><?php esc_html_e( 'PHP IPTC Support', 'mainwp-child' ); ?></td>
779
+ <td colspan="3"><?php self::getPHPIPTC(); ?></td>
780
+ </tr>
781
+ <tr>
782
+ <td></td>
783
+ <td><?php esc_html_e( 'PHP XML Support', 'mainwp-child' ); ?></td>
784
+ <td colspan="3"><?php self::getPHPXML(); ?></td>
785
+ </tr>
786
+ <tr>
787
+ <td></td>
788
+ <td><?php esc_html_e( 'PHP Disabled Functions', 'mainwp-child' ); ?></td>
789
+ <td colspan="3"><?php self::mainwpRequiredFunctions(); ?></td>
790
+ </tr>
791
+ <tr>
792
+ <td></td>
793
+ <td><?php esc_html_e( 'PHP Loaded Extensions', 'mainwp-child' ); ?></td>
794
+ <td colspan="3" style="width: 73% !important;"><?php self::getLoadedPHPExtensions(); ?></td>
795
+ </tr>
796
+ <tr>
797
+ <td style="background: #333; color: #fff;"
798
+ colspan="5"><?php esc_html_e( 'MySQL INFORMATION', 'mainwp-child' ); ?></td>
799
+ </tr>
800
+ <tr>
801
+ <td></td>
802
+ <td><?php esc_html_e( 'MySQL Mode', 'mainwp-child' ); ?></td>
803
+ <td colspan="3"><?php self::getSQLMode(); ?></td>
804
+ </tr>
805
+ <tr>
806
+ <td></td>
807
+ <td><?php esc_html_e( 'MySQL Client Encoding', 'mainwp-child' ); ?></td>
808
+ <td colspan="3"><?php echo esc_html( defined( 'DB_CHARSET' ) ? DB_CHARSET : '' ); ?></td>
809
+ </tr>
810
+ <tr>
811
+ <td style="background: #333; color: #fff;" colspan="5"><?php _e( 'WORDPRESS PLUGINS', 'mainwp-child' ); ?></td>
812
+ </tr>
813
+ <?php
814
+ $all_plugins = get_plugins();
815
+ foreach ( $all_plugins as $slug => $plugin) {
816
+ if ( $slug == 'mainwp-child/mainwp-child.php' || $slug == 'mainwp-child-reports/mainwp-child-reports.php' ) {
817
+ if ( $isBranding ) {
818
+ if ( $slug == 'mainwp-child/mainwp-child.php' ) {
819
+ $plugin['Name'] = esc_html( stripslashes( $branding_title ) );
820
+ } else if ($slug == 'mainwp-child-reports/mainwp-child-reports.php') {
821
+ $plugin['Name'] = esc_html( stripslashes( $branding_title ) ) . ' reports';
822
+ }
823
+ }
824
+ }
825
+
826
+ ?>
827
+ <tr>
828
+ <td>&nbsp;</td>
829
+ <td><?php echo $plugin['Name']; ?></td>
830
+ <td><?php echo $plugin['Version']; ?></td>
831
+ <td><?php echo is_plugin_active($slug) ? 'Active' : 'Inactive'; ?></td>
832
+ <td>&nbsp;</td>
833
+ </tr>
834
+ <?php
835
+ }
836
+ ?>
837
+ </tbody>
838
+ </table>
839
+ <br/>
840
+ <?php
841
+ }
842
+
843
+ protected static function getCurlSupport() {
844
+ return function_exists( 'curl_version' );
845
+ }
846
+
847
+ protected static function getCurlTimeout() {
848
+ return ini_get( 'default_socket_timeout' );
849
+ }
850
+
851
+ protected static function getCurlVersion() {
852
+ $curlversion = curl_version();
853
+
854
+ return $curlversion['version'];
855
+ }
856
+
857
+ protected static function curlssl_compare( $value, $operator = null ) {
858
+ if ( isset( $value['version_number'] ) && defined( 'OPENSSL_VERSION_NUMBER' ) ) {
859
+ return version_compare( OPENSSL_VERSION_NUMBER, $value['version_number'], $operator );
860
+ }
861
+
862
+ return false;
863
+ }
864
+
865
+ protected static function getCurlSSLVersion() {
866
+ $curlversion = curl_version();
867
+
868
+ return $curlversion['ssl_version'];
869
+ }
870
+
871
+ public static function mainwpRequiredFunctions() {
872
+ //error_reporting(E_ALL);
873
+ $disabled_functions = ini_get( 'disable_functions' );
874
+ if ( '' !== $disabled_functions ) {
875
+ $arr = explode( ',', $disabled_functions );
876
+ sort( $arr );
877
+ $arr_length = count( $arr );
878
+ for ( $i = 0; $i < $arr_length; $i ++ ) {
879
+ echo esc_html( $arr[ $i ] . ', ' );
880
+ }
881
+ } else {
882
+ echo esc_html__( 'No functions disabled', 'mainwp-child' );
883
+ }
884
+ }
885
+
886
+ protected static function getLoadedPHPExtensions() {
887
+ $extensions = get_loaded_extensions();
888
+ sort( $extensions );
889
+ echo esc_html( implode( ', ', $extensions ) );
890
+ }
891
+
892
+ protected static function getCurrentVersion() {
893
+ $currentVersion = get_option( 'mainwp_child_plugin_version' );
894
+
895
+ return $currentVersion;
896
+ }
897
+
898
+ protected static function getMainwpVersion() {
899
+ include_once( ABSPATH . '/wp-admin/includes/plugin-install.php' );
900
+ $api = plugins_api( 'plugin_information', array(
901
+ 'slug' => 'mainwp-child',
902
+ 'fields' => array( 'sections' => false ),
903
+ 'timeout' => 60,
904
+ ) );
905
+ if ( is_object( $api ) && isset( $api->version ) ) {
906
+ return $api->version;
907
+ }
908
+
909
+ return false;
910
+ }
911
+
912
+ protected static function getMainWPVersionCheck() {
913
+ $current = get_option( 'mainwp_child_plugin_version' );
914
+ $latest = self::getMainwpVersion();
915
+ if ( $current === $latest ) {
916
+ echo '<span class="mainwp-pass"><i class="fa fa-check-circle"></i> Pass</span>';
917
+ } else {
918
+ echo '<span class="mainwp-warning"><i class="fa fa-exclamation-circle"></i> Warning</span>';
919
+ }
920
+ }
921
+
922
+ public static function renderCron() {
923
+ $cron_array = _get_cron_array();
924
+ $schedules = wp_get_schedules();
925
+ ?>
926
+ <table id="mainwp-table" class="wp-list-table widefat" cellspacing="0">
927
+ <thead>
928
+ <tr>
929
+ <th scope="col" class="manage-column column-posts" style="">
930
+ <span><?php esc_html_e( 'Next due', 'mainwp-child' ); ?></span></th>
931
+ <th scope="col" class="manage-column column-posts" style="">
932
+ <span><?php esc_html_e( 'Schedule', 'mainwp-child' ); ?></span></th>
933
+ <th scope="col" class="manage-column column-posts" style="">
934
+ <span><?php esc_html_e( 'Hook', 'mainwp-child' ); ?></span></th>
935
+ </tr>
936
+ </thead>
937
+ <tbody id="the-sites-list" class="list:sites">
938
+ <?php
939
+ foreach ( $cron_array as $time => $cron ) {
940
+ foreach ( $cron as $hook => $cron_info ) {
941
+ foreach ( $cron_info as $key => $schedule ) {
942
+ ?>
943
+ <tr>
944
+ <td><?php echo esc_html( MainWP_Helper::formatTimestamp( MainWP_Helper::getTimestamp( $time ) ) ); ?></td>
945
+ <td><?php echo esc_html( ( isset( $schedule['schedule'] ) && isset( $schedules[ $schedule['schedule'] ] ) && isset( $schedules[ $schedule['schedule'] ]['display'] ) ) ? $schedules[ $schedule['schedule'] ]['display'] : '' ); ?> </td>
946
+ <td><?php echo esc_html( $hook ); ?></td>
947
+ </tr>
948
+ <?php
949
+ }
950
+ }
951
+ }
952
+ ?>
953
+ </tbody>
954
+ </table>
955
+ <?php
956
+ }
957
+
958
+ protected static function checkDirectoryMainWPDirectory( $write = true ) {
959
+ $branding_title = 'MainWP';
960
+ if ( MainWP_Child_Branding::is_branding() ) {
961
+ $branding_title = MainWP_Child_Branding::get_branding();
962
+ }
963
+ $branding_title .= ' Upload Directory';
964
+
965
+ try {
966
+ $dirs = MainWP_Helper::getMainWPDir( null, false );
967
+ $path = $dirs[0];
968
+ } catch ( Exception $e ) {
969
+ return self::renderDirectoryRow( $branding_title, '', 'Writable', $e->getMessage(), false );
970
+ }
971
+
972
+ if ( ! is_dir( dirname( $path ) ) ) {
973
+ if ( $write ) {
974
+ return self::renderDirectoryRow( $branding_title, $path, 'Writable', 'Directory not found', false );
975
+ } else {
976
+ return false;
977
+ }
978
+ }
979
+
980
+ $hasWPFileSystem = MainWP_Helper::getWPFilesystem();
981
+ global $wp_filesystem;
982
+
983
+ if ( $hasWPFileSystem && ! empty( $wp_filesystem ) ) {
984
+ if ( ! $wp_filesystem->is_writable( $path ) ) {
985
+ if ( $write ) {
986
+ return self::renderDirectoryRow( $branding_title, $path, 'Writable', 'Directory not writable', false );
987
+ } else {
988
+ return false;
989
+ }
990
+ }
991
+ } else {
992
+ if ( ! is_writable( $path ) ) {
993
+ if ( $write ) {
994
+ return self::renderDirectoryRow( $branding_title, $path, 'Writable', 'Directory not writable', false );
995
+ } else {
996
+ return false;
997
+ }
998
+ }
999
+ }
1000
+
1001
+ if ( $write ) {
1002
+ return self::renderDirectoryRow( $branding_title, $path, 'Writable', 'Writable', true );
1003
+ } else {
1004
+ return true;
1005
+ }
1006
+ }
1007
+
1008
+ protected static function renderDirectoryRow( $pName, $pDirectory, $pCheck, $pResult, $pPassed ) {
1009
+ ?>
1010
+ <tr class="mwp-not-generate-row">
1011
+ <td></td>
1012
+ <td><?php echo esc_html( stripslashes( $pName ) ); ?><br/><?php echo esc_html( ( MainWP_Child_Branding::is_branding() ) ? '' : $pDirectory ); ?>
1013
+ </td>
1014
+ <td><?php echo esc_html( $pCheck ); ?></td>
1015
+ <td><?php echo esc_html( $pResult ); ?></td>
1016
+ <td><?php echo ( $pPassed ? '<span class="mainwp-pass"><i class="fa fa-check-circle"></i> Pass</span>' : '<span class="mainwp-warning"><i class="fa fa-exclamation-circle"></i> Warning</span>' ); ?></td>
1017
+ </tr>
1018
+ <?php
1019
+ return true;
1020
+ }
1021
+
1022
+ protected static function renderRow( $pConfig, $pCompare, $pVersion, $pGetter, $pExtraText = '', $pExtraCompare = null, $pExtraVersion = null, $sizeCompare = false ) {
1023
+ $currentVersion = call_user_func( array( 'MainWP_Child_Server_Information', $pGetter ) );
1024
+
1025
+ ?>
1026
+ <tr>
1027
+ <td></td>
1028
+ <td><?php echo esc_html( esc_html( $pConfig ) ); ?></td>
1029
+ <td><?php echo esc_html( esc_html( $pCompare ) ); ?><?php echo esc_html( ( true === $pVersion ? 'true' : $pVersion ) . ' ' . $pExtraText ); ?></td>
1030
+ <td><?php echo esc_html( true === $currentVersion ? 'true' : $currentVersion ); ?></td>
1031
+ <td><?php echo ( self::check( $pCompare, $pVersion, $pGetter, $pExtraCompare, $pExtraVersion, $sizeCompare ) ? '<span class="mainwp-pass"><i class="fa fa-check-circle"></i> Pass</span>' : '<span class="mainwp-warning"><i class="fa fa-exclamation-circle"></i> Warning</span>' ); ?></td>
1032
+ </tr>
1033
+ <?php
1034
+ }
1035
+
1036
+ protected static function renderRowSec( $pConfig, $pCompare, $pVersion, $pGetter, $pExtraText = '', $pExtraCompare = null, $pExtraVersion = null, $toolTip = null, $whatType = null, $errorType = self::WARNING ) {
1037
+ $currentVersion = call_user_func( array( 'MainWP_Child_Server_Information', $pGetter ) );
1038
+ ?>
1039
+ <tr>
1040
+ <td></td>
1041
+ <td><?php echo $pConfig; ?></td>
1042
+ <td><?php echo $pCompare; ?><?php echo ( $pVersion === true ? 'true' : ( is_array( $pVersion ) && isset( $pVersion['version'] ) ? $pVersion['version'] : $pVersion ) ) . ' ' . $pExtraText; ?></td>
1043
+ <td><?php echo( $currentVersion === true ? 'true' : $currentVersion ); ?></td>
1044
+ <?php if ( $whatType == 'filesize' ) { ?>
1045
+ <td><?php echo( self::filesize_compare( $currentVersion, $pVersion, $pCompare ) ? '<span class="mainwp-pass"><i class="fa fa-check-circle"></i> Pass</span>' : self::getWarningHTML( $errorType ) ); ?></td>
1046
+ <?php } else if ( $whatType == 'curlssl' ) { ?>
1047
+ <td><?php echo( self::curlssl_compare( $pVersion, $pCompare ) ? '<span class="mainwp-pass"><i class="fa fa-check-circle"></i> Pass</span>' : self::getWarningHTML( $errorType ) ); ?></td>
1048
+ <?php } else if (($pGetter == 'getMaxInputTime' || $pGetter == 'getMaxExecutionTime') && $currentVersion == -1) { ?>
1049
+ <td><?php echo '<span class="mainwp-pass"><i class="fa fa-check-circle"></i> Pass</span>'; ?></td>
1050
+ <?php } else { ?>
1051
+ <td><?php echo (version_compare($currentVersion, $pVersion, $pCompare) || (($pExtraCompare != null) && version_compare($currentVersion, $pExtraVersion, $pExtraCompare)) ? '<span class="mainwp-pass"><i class="fa fa-check-circle"></i> Pass</span>' : self::getWarningHTML( $errorType )); ?></td>
1052
+ <?php } ?>
1053
+ </tr>
1054
+ <?php
1055
+ }
1056
+
1057
+ private static function getWarningHTML($errorType = self::WARNING)
1058
+ {
1059
+ if (self::WARNING == $errorType) {
1060
+ return '<span class="mainwp-warning"><i class="fa fa-exclamation-circle"></i> Warning</span>';
1061
+ }
1062
+ return '<span class="mainwp-fail"><i class="fa fa-exclamation-circle"></i> Fail</span>';
1063
+ }
1064
+
1065
+ protected static function filesize_compare( $value1, $value2, $operator = null ) {
1066
+ if ( strpos( $value1, 'G' ) !== false ) {
1067
+ $value1 = preg_replace( '/[A-Za-z]/', '', $value1 );
1068
+ $value1 = intval( $value1 ) * 1024; // Megabyte number
1069
+ } else {
1070
+ $value1 = preg_replace( '/[A-Za-z]/', '', $value1 ); // Megabyte number
1071
+ }
1072
+
1073
+ if ( strpos( $value2, 'G' ) !== false ) {
1074
+ $value2 = preg_replace( '/[A-Za-z]/', '', $value2 );
1075
+ $value2 = intval( $value2 ) * 1024; // Megabyte number
1076
+ } else {
1077
+ $value2 = preg_replace( '/[A-Za-z]/', '', $value2 ); // Megabyte number
1078
+ }
1079
+
1080
+ return version_compare( $value1, $value2, $operator );
1081
+ }
1082
+
1083
+ protected static function check( $pCompare, $pVersion, $pGetter, $pExtraCompare = null, $pExtraVersion = null, $sizeCompare = false) {
1084
+ $currentVersion = call_user_func( array( 'MainWP_Child_Server_Information', $pGetter ) );
1085
+
1086
+ if ($sizeCompare) {
1087
+ return self::filesize_compare( $currentVersion, $pVersion, $pCompare );
1088
+ } else {
1089
+ return ( version_compare( $currentVersion, $pVersion, $pCompare ) || ( ( null !== $pExtraCompare ) && version_compare( $currentVersion, $pExtraVersion, $pExtraCompare ) ) );
1090
+ }
1091
+ }
1092
+
1093
+ protected static function getZipArchiveEnabled() {
1094
+ return class_exists( 'ZipArchive' );
1095
+ }
1096
+
1097
+ protected static function getGZipEnabled() {
1098
+ return function_exists( 'gzopen' );
1099
+ }
1100
+
1101
+ protected static function getBZipEnabled() {
1102
+ return function_exists( 'bzopen' );
1103
+ }
1104
+
1105
+ protected static function getWordpressVersion() {
1106
+ global $wp_version;
1107
+
1108
+ return $wp_version;
1109
+ }
1110
+
1111
+ protected static function getWordpressMemoryLimit() {
1112
+ return WP_MEMORY_LIMIT;
1113
+ }
1114
+
1115
+ public static function checkIfMultisite() {
1116
+ $isMultisite = ! is_multisite() ? true : false;
1117
+
1118
+ return $isMultisite;
1119
+ }
1120
+
1121
+ protected static function getSSLSupport() {
1122
+ return extension_loaded( 'openssl' );
1123
+ }
1124
+
1125
+ protected static function getSSLWarning() {
1126
+ $conf = array( 'private_key_bits' => 384 );
1127
+ $str = '';
1128
+ if ( function_exists( 'openssl_pkey_new' ) ) {
1129
+ $res = @openssl_pkey_new( $conf );
1130
+ @openssl_pkey_export( $res, $privkey );
1131
+
1132
+ $str = openssl_error_string();
1133
+ }
1134
+ return ( stristr( $str, 'NCONF_get_string:no value' ) ? '' : $str );
1135
+ }
1136
+
1137
+ public static function getPHPVersion() {
1138
+ return phpversion();
1139
+ }
1140
+
1141
+ protected static function getMaxExecutionTime() {
1142
+ return ini_get( 'max_execution_time' );
1143
+ }
1144
+
1145
+ protected static function getUploadMaxFilesize() {
1146
+ return ini_get( 'upload_max_filesize' );
1147
+ }
1148
+
1149
+ protected static function getPostMaxSize() {
1150
+ return ini_get( 'post_max_size' );
1151
+ }
1152
+
1153
+ public static function getMySQLVersion() {
1154
+ /** @var $wpdb wpdb */
1155
+ global $wpdb;
1156
+
1157
+ return $wpdb->get_var( 'SHOW VARIABLES LIKE "version"', 1 );
1158
+ }
1159
+
1160
+ protected static function getMaxInputTime() {
1161
+ return ini_get( 'max_input_time' );
1162
+ }
1163
+
1164
+ public static function getPHPMemoryLimit() {
1165
+ return ini_get( 'memory_limit' );
1166
+ }
1167
+
1168
+ protected static function getOS() {
1169
+ echo esc_html( PHP_OS );
1170
+ }
1171
+
1172
+ protected static function getArchitecture() {
1173
+ echo esc_html( PHP_INT_SIZE * 8 ) ?>&nbsp;bit <?php
1174
+ }
1175
+
1176
+ protected static function memoryUsage() {
1177
+ if ( function_exists( 'memory_get_usage' ) ) {
1178
+ $memory_usage = round( memory_get_usage() / 1024 / 1024, 2 ) . __( ' MB' );
1179
+ } else {
1180
+ $memory_usage = __( 'N/A' );
1181
+ }
1182
+ echo esc_html( $memory_usage );
1183
+ }
1184
+
1185
+ protected static function getOutputBufferSize() {
1186
+ return ini_get( 'pcre.backtrack_limit' );
1187
+ }
1188
+
1189
+ protected static function getPHPSafeMode() {
1190
+ if ( version_compare(phpversion(), '5.3.0') < 0 && ini_get( 'safe_mode' ) ) {
1191
+ $safe_mode = __( 'ON' );
1192
+ } else {
1193
+ $safe_mode = __( 'OFF' );
1194
+ }
1195
+ echo esc_html( $safe_mode );
1196
+ }
1197
+
1198
+ protected static function getSQLMode() {
1199
+ global $wpdb;
1200
+ $mysqlinfo = $wpdb->get_results( "SHOW VARIABLES LIKE 'sql_mode'" );
1201
+ if ( is_array( $mysqlinfo ) ) {
1202
+ $sql_mode = $mysqlinfo[0]->Value;
1203
+ }
1204
+ if ( empty( $sql_mode ) ) {
1205
+ $sql_mode = __( 'NOT SET' );
1206
+ }
1207
+ echo esc_html( $sql_mode );
1208
+ }
1209
+
1210
+ protected static function getPHPAllowUrlFopen() {
1211
+ if ( ini_get( 'allow_url_fopen' ) ) {
1212
+ $allow_url_fopen = __( 'ON' );
1213
+ } else {
1214
+ $allow_url_fopen = __( 'OFF' );
1215
+ }
1216
+ echo esc_html( $allow_url_fopen );
1217
+ }
1218
+
1219
+ protected static function getPHPExif() {
1220
+ if ( is_callable( 'exif_read_data' ) ) {
1221
+ $exif = __( 'YES' ) . ' ( V' . substr( phpversion( 'exif' ), 0, 4 ) . ')';
1222
+ } else {
1223
+ $exif = __( 'NO' );
1224
+ }
1225
+ echo esc_html( $exif );
1226
+ }
1227
+
1228
+ protected static function getPHPIPTC() {
1229
+ if ( is_callable( 'iptcparse' ) ) {
1230
+ $iptc = __( 'YES' );
1231
+ } else {
1232
+ $iptc = __( 'NO' );
1233
+ }
1234
+ echo esc_html( $iptc );
1235
+ }
1236
+
1237
+ protected static function getPHPXML() {
1238
+ if ( is_callable( 'xml_parser_create' ) ) {
1239
+ $xml = __( 'YES' );
1240
+ } else {
1241
+ $xml = __( 'NO' );
1242
+ }
1243
+ echo esc_html( $xml );
1244
+ }
1245
+
1246
+ // new
1247
+
1248
+ protected static function getCurrentlyExecutingScript() {
1249
+ echo esc_html( $_SERVER['PHP_SELF'] );
1250
+ }
1251
+
1252
+ protected static function getServerGetawayInterface() {
1253
+ echo esc_html( $_SERVER['GATEWAY_INTERFACE'] );
1254
+ }
1255
+
1256
+ public static function getServerIP() {
1257
+ echo esc_html( $_SERVER['SERVER_ADDR'] );
1258
+ }
1259
+
1260
+ protected static function getServerName() {
1261
+ echo esc_html( $_SERVER['SERVER_NAME'] );
1262
+ }
1263
+
1264
+ protected static function getServerSoftware() {
1265
+ echo esc_html( $_SERVER['SERVER_SOFTWARE'] );
1266
+ }
1267
+
1268
+ protected static function getServerProtocol() {
1269
+ echo esc_html( $_SERVER['SERVER_PROTOCOL'] );
1270
+ }
1271
+
1272
+ protected static function getServerRequestMethod() {
1273
+ echo esc_html( $_SERVER['REQUEST_METHOD'] );
1274
+ }
1275
+
1276
+ protected static function getServerRequestTime() {
1277
+ echo esc_html( $_SERVER['REQUEST_TIME'] );
1278
+ }
1279
+
1280
+ protected static function getServerQueryString() {
1281
+ echo esc_html( $_SERVER['QUERY_STRING'] );
1282
+ }
1283
+
1284
+ protected static function getServerHTTPAccept() {
1285
+ echo esc_html( $_SERVER['HTTP_ACCEPT'] );
1286
+ }
1287
+
1288
+ protected static function getServerAcceptCharset() {
1289
+ if ( ! isset( $_SERVER['HTTP_ACCEPT_CHARSET'] ) || ( '' === $_SERVER['HTTP_ACCEPT_CHARSET'] ) ) {
1290
+ esc_html_e( 'N/A', 'mainwp-child' );
1291
+ } else {
1292
+ echo esc_html( $_SERVER['HTTP_ACCEPT_CHARSET'] );
1293
+ }
1294
+ }
1295
+
1296
+ protected static function getHTTPHost() {
1297
+ echo esc_html( $_SERVER['HTTP_HOST'] );
1298
+ }
1299
+
1300
+ protected static function getCompleteURL() {
1301
+ echo isset( $_SERVER['HTTP_REFERER'] ) ? esc_html( $_SERVER['HTTP_REFERER'] ) : '';
1302
+ }
1303
+
1304
+ protected static function getUserAgent() {
1305
+ echo esc_html( $_SERVER['HTTP_USER_AGENT'] );
1306
+ }
1307
+
1308
+ protected static function getHTTPS() {
1309
+ if ( isset( $_SERVER['HTTPS'] ) && '' !== $_SERVER['HTTPS'] ) {
1310
+ echo esc_html( __( 'ON', 'mainwp-child' ) . ' - ' . $_SERVER['HTTPS'] );
1311
+ } else {
1312
+ esc_html_e( 'OFF', 'mainwp-child' );
1313
+ }
1314
+ }
1315
+
1316
+ protected static function serverSelfConnect() {
1317
+ $url = site_url( 'wp-cron.php' );
1318
+ $query_args = array('mainwp_child_run' => 'test');
1319
+ $url = add_query_arg( $query_args, $url );
1320
+ $args = array( 'blocking' => TRUE,
1321
+ 'sslverify' => apply_filters( 'https_local_ssl_verify', true ),
1322
+ 'timeout' => 15
1323
+ );
1324
+ $response = wp_remote_post( $url, $args );
1325
+ $test_result = '';
1326
+ if ( is_wp_error( $response ) ) {
1327
+ $test_result .= sprintf( __( 'The HTTP response test get an error "%s"','mainwp-child' ), $response->get_error_message() );
1328
+ }
1329
+ $response_code = wp_remote_retrieve_response_code( $response );
1330
+ if ( $response_code < 200 && $response_code > 204 ) {
1331
+ $test_result .= sprintf( __( 'The HTTP response test get a false http status (%s)','mainwp-child' ), wp_remote_retrieve_response_code( $response ) );
1332
+ } else {
1333
+ $response_body = wp_remote_retrieve_body( $response );
1334
+ if ( FALSE === strstr( $response_body, 'MainWP Test' ) ) {
1335
+ $test_result .= sprintf( __( 'Not expected HTTP response body: %s','mainwp-child' ), esc_attr( strip_tags( $response_body ) ) );
1336
+ }
1337
+ }
1338
+ if ( empty( $test_result ) ) {
1339
+ _e( 'Response Test O.K.', 'mainwp-child' );
1340
+ } else
1341
+ echo $test_result;
1342
+ }
1343
+
1344
+
1345
+ protected static function getRemoteAddress() {
1346
+ echo esc_html( $_SERVER['REMOTE_ADDR'] );
1347
+ }
1348
+
1349
+ protected static function getRemoteHost() {
1350
+ if ( ! isset( $_SERVER['REMOTE_HOST'] ) || ( '' === $_SERVER['REMOTE_HOST'] ) ) {
1351
+ esc_html_e( 'N/A', 'mainwp-child' );
1352
+ } else {
1353
+ echo esc_html( $_SERVER['REMOTE_HOST'] );
1354
+ }
1355
+ }
1356
+
1357
+ protected static function getRemotePort() {
1358
+ echo esc_html( $_SERVER['REMOTE_PORT'] );
1359
+ }
1360
+
1361
+ protected static function getScriptFileName() {
1362
+ echo esc_html( $_SERVER['SCRIPT_FILENAME'] );
1363
+ }
1364
+
1365
+ protected static function getServerAdmin() {
1366
+ echo esc_html( $_SERVER['SERVER_ADMIN'] );
1367
+ }
1368
+
1369
+ protected static function getServerPort() {
1370
+ echo esc_html( $_SERVER['SERVER_PORT'] );
1371
+ }
1372
+
1373
+ protected static function getServerSignature() {
1374
+ echo esc_html( $_SERVER['SERVER_SIGNATURE'] );
1375
+ }
1376
+
1377
+ protected static function getServerPathTranslated() {
1378
+ if ( ! isset( $_SERVER['PATH_TRANSLATED'] ) || ( '' === $_SERVER['PATH_TRANSLATED'] ) ) {
1379
+ esc_html_e( 'N/A', 'mainwp-child' );
1380
+ } else {
1381
+ echo esc_html( $_SERVER['PATH_TRANSLATED'] );
1382
+ }
1383
+ }
1384
+
1385
+ protected static function getScriptName() {
1386
+ echo esc_html( $_SERVER['SCRIPT_NAME'] );
1387
+ }
1388
+
1389
+ protected static function getCurrentPageURI() {
1390
+ echo esc_html( $_SERVER['REQUEST_URI'] );
1391
+ }
1392
+
1393
+ protected static function getWPRoot() {
1394
+ echo esc_html( ABSPATH );
1395
+ }
1396
+
1397
+ function formatSizeUnits( $bytes ) {
1398
+ if ( $bytes >= 1073741824 ) {
1399
+ $bytes = number_format( $bytes / 1073741824, 2 ) . ' GB';
1400
+ } elseif ( $bytes >= 1048576 ) {
1401
+ $bytes = number_format( $bytes / 1048576, 2 ) . ' MB';
1402
+ } elseif ( $bytes >= 1024 ) {
1403
+ $bytes = number_format( $bytes / 1024, 2 ) . ' KB';
1404
+ } elseif ( $bytes > 1 ) {
1405
+ $bytes = $bytes . ' bytes';
1406
+ } elseif ( 1 === $bytes ) {
1407
+ $bytes = $bytes . ' byte';
1408
+ } else {
1409
+ $bytes = '0 bytes';
1410
+ }
1411
+
1412
+ return $bytes;
1413
+
1414
+ }
1415
+
1416
+
1417
+ /*
1418
+ *Plugin Name: Error Log Dashboard Widget
1419
+ *Plugin URI: http://wordpress.org/extend/plugins/error-log-dashboard-widget/
1420
+ *Description: Robust zero-configuration and low-memory way to keep an eye on error log.
1421
+ *Author: Andrey "Rarst" Savchenko
1422
+ *Author URI: http://www.rarst.net/
1423
+ *Version: 1.0.2
1424
+ *License: GPLv2 or later
1425
+
1426
+ *Includes last_lines() function by phant0m, licensed under cc-wiki and GPLv2+
1427
+ */
1428
+
1429
+ public static function renderErrorLogPage() {
1430
+ ?>
1431
+ <table id="mainwp-table" class="wp-list-table widefat" cellspacing="0">
1432
+ <thead title="Click to Toggle" style="cursor: pointer;">
1433
+ <tr>
1434
+ <th scope="col" class="manage-column column-posts" style="width: 10%">
1435
+ <span><?php esc_html_e( 'Time', 'mainwp-child' ); ?></span></th>
1436
+ <th scope="col" class="manage-column column-posts" style="">
1437
+ <span><?php esc_html_e( 'Error', 'mainwp-child' ); ?></span></th>
1438
+ </tr>
1439
+ </thead>
1440
+ <tbody class="list:sites" id="mainwp-error-log-table">
1441
+ <?php self::renderErrorLog(); ?>
1442
+ </tbody>
1443
+ </table>
1444
+ <?php
1445
+ }
1446
+
1447
+ public static function renderErrorLog() {
1448
+ $log_errors = ini_get( 'log_errors' );
1449
+ if ( ! $log_errors ) {
1450
+ echo '<tr><td colspan="2">' . esc_html__( 'Error logging disabled.', 'mainwp-child' ) . '</td></tr>';
1451
+ }
1452
+
1453
+ $error_log = ini_get( 'error_log' );
1454
+ $logs = apply_filters( 'error_log_mainwp_logs', array( $error_log ) );
1455
+ $count = apply_filters( 'error_log_mainwp_lines', 10 );
1456
+ $lines = array();
1457
+
1458
+ foreach ( $logs as $log ) {
1459
+
1460
+ if ( is_readable( $log ) ) {
1461
+ $lines = array_merge( $lines, self::last_lines( $log, $count ) );
1462
+ }
1463
+ }
1464
+
1465
+ $lines = array_map( 'trim', $lines );
1466
+ $lines = array_filter( $lines );
1467
+
1468
+ if ( empty( $lines ) ) {
1469
+ if ( MainWP_Child_Branding::is_branding() ) {
1470
+ $branding_title = MainWP_Child_Branding::get_branding();
1471
+ $msg = esc_html( stripslashes( $branding_title ) ) . ' is unable to find your error logs, please contact your host for server error logs.';
1472
+ } else {
1473
+ $msg = esc_html__( 'MainWP is unable to find your error logs, please contact your host for server error logs.', 'mainwp-child' );
1474
+ }
1475
+ echo '<tr><td colspan="2">' . $msg . '</td></tr>';
1476
+
1477
+ return;
1478
+ }
1479
+
1480
+ foreach ( $lines as $key => $line ) {
1481
+
1482
+ if ( false !== strpos( $line, ']' ) ) {
1483
+ list( $time, $error ) = explode( ']', $line, 2 );
1484
+ } else {
1485
+ list( $time, $error ) = array( '', $line );
1486
+ }
1487
+
1488
+ $time = trim( $time, '[]' );
1489
+ $error = trim( $error );
1490
+ $lines[ $key ] = compact( 'time', 'error' );
1491
+ }
1492
+
1493
+ if ( count( $error_log ) > 1 ) {
1494
+
1495
+ uasort( $lines, array( __CLASS__, 'time_compare' ) );
1496
+ $lines = array_slice( $lines, 0, $count );
1497
+ }
1498
+
1499
+ foreach ( $lines as $line ) {
1500
+
1501
+ $error = esc_html( $line['error'] );
1502
+ $time = esc_html( $line['time'] );
1503
+
1504
+ if ( ! empty( $error ) ) {
1505
+ echo wp_kses_post( "<tr><td>{$time}</td><td>{$error}</td></tr>" );
1506
+ }
1507
+ }
1508
+
1509
+ }
1510
+
1511
+ static function time_compare( $a, $b ) {
1512
+ if ( $a === $b ) {
1513
+ return 0;
1514
+ }
1515
+
1516
+ return ( strtotime( $a['time'] ) > strtotime( $b['time'] ) ) ? - 1 : 1;
1517
+ }
1518
+
1519
+ static function last_lines( $path, $line_count, $block_size = 512 ) {
1520
+ $lines = array();
1521
+
1522
+ // we will always have a fragment of a non-complete line
1523
+ // keep this in here till we have our next entire line.
1524
+ $leftover = '';
1525
+
1526
+ $fh = fopen( $path, 'r' );
1527
+ // go to the end of the file
1528
+ fseek( $fh, 0, SEEK_END );
1529
+
1530
+ do {
1531
+ // need to know whether we can actually go back
1532
+ // $block_size bytes
1533
+ $can_read = $block_size;
1534
+
1535
+ if ( ftell( $fh ) <= $block_size ) {
1536
+ $can_read = ftell( $fh );
1537
+ }
1538
+
1539
+ if ( empty( $can_read ) ) {
1540
+ break;
1541
+ }
1542
+
1543
+ // go back as many bytes as we can
1544
+ // read them to $data and then move the file pointer
1545
+ // back to where we were.
1546
+ fseek( $fh, - $can_read, SEEK_CUR );
1547
+ $data = fread( $fh, $can_read );
1548
+ $data .= $leftover;
1549
+ fseek( $fh, - $can_read, SEEK_CUR );
1550
+
1551
+ // split lines by \n. Then reverse them,
1552
+ // now the last line is most likely not a complete
1553
+ // line which is why we do not directly add it, but
1554
+ // append it to the data read the next time.
1555
+ $split_data = array_reverse( explode( "\n", $data ) );
1556
+ $new_lines = array_slice( $split_data, 0, - 1 );
1557
+ $lines = array_merge( $lines, $new_lines );
1558
+ $leftover = $split_data[ count( $split_data ) - 1 ];
1559
+ } while ( count( $lines ) < $line_count && 0 !== ftell( $fh ) );
1560
+
1561
+ if ( 0 === ftell( $fh ) ) {
1562
+ $lines[] = $leftover;
1563
+ }
1564
+
1565
+ fclose( $fh );
1566
+
1567
+ // Usually, we will read too many lines, correct that here.
1568
+ return array_slice( $lines, 0, $line_count );
1569
+ }
1570
+
1571
+ public static function renderWPConfig() {
1572
+ ?>
1573
+ <style>
1574
+ #mainwp-code-display code {
1575
+ background: none !important;
1576
+ }
1577
+ </style>
1578
+ <div class="postbox" id="mainwp-code-display">
1579
+ <h3 class="hndle" style="padding: 8px 12px; font-size: 14px;"><span>WP-Config.php</span></h3>
1580
+
1581
+ <div style="padding: 1em;">
1582
+ <?php
1583
+ if ( file_exists( ABSPATH . 'wp-config.php' ) ) {
1584
+ @show_source( ABSPATH . 'wp-config.php' );
1585
+ } else {
1586
+ $files = @get_included_files();
1587
+ $configFound = false;
1588
+ if ( is_array( $files ) ) {
1589
+ foreach ( $files as $file ) {
1590
+ if ( stristr( $file, 'wp-config.php' ) ) {
1591
+ $configFound = true;
1592
+ @show_source( $file );
1593
+ break;
1594
+ }
1595
+ }
1596
+ }
1597
+
1598
+ if ( !$configFound ) {
1599
+ _e( 'wp-config.php not found', 'mainwp' );
1600
+ }
1601
+ }
1602
+ ?>
1603
+ </div>
1604
+ </div>
1605
+ <?php
1606
+ }
1607
+
1608
+ public static function renderhtaccess() {
1609
+ ?>
1610
+ <div class="postbox" id="mainwp-code-display">
1611
+ <h3 class="hndle" style="padding: 8px 12px; font-size: 14px;"><span><?php _e( '.htaccess', 'mainwp-child' ); ?></span></h3>
1612
+
1613
+ <div style="padding: 1em;">
1614
+ <?php
1615
+ @show_source( ABSPATH . '.htaccess' );
1616
+ ?>
1617
+ </div>
1618
+ </div>
1619
+ <?php
1620
+ }
1621
+
1622
+ public static function renderConnectionDetails() {
1623
+ global $current_user;
1624
+ $uniqueId = get_option('mainwp_child_uniqueId');
1625
+ $details = array(
1626
+ 'siteurl' => array(
1627
+ 'title' => __('Site URL', 'mainwp-child'),
1628
+ 'value' => get_bloginfo( 'url' ),
1629
+ 'desc' => get_bloginfo( 'url' )
1630
+ ),
1631
+ 'adminuser' => array(
1632
+ 'title' => __('Administrator name', 'mainwp-child'),
1633
+ 'value' => $current_user->user_login,
1634
+ 'desc' => __('This is your Administrator username, however, you can use any existing Administrator username.', 'mainwp-child')
1635
+ ),
1636
+ 'friendly_name' => array(
1637
+ 'title' => __('Friendly site name', 'mainwp-child'),
1638
+ 'value' => get_bloginfo( 'name' ),
1639
+ 'desc' => __('For the friendly site name, you can use any name, this is just a suggestion.', 'mainwp-child')
1640
+ ),
1641
+ 'uniqueid' => array(
1642
+ 'title' => __('Child unique security id', 'mainwp-child'),
1643
+ 'value' => !empty($uniqueId) ? $uniqueId : __('Leave the field blank', 'mainwp-child'),
1644
+ 'desc' => __('Child unique security id is not required, however, since you have enabled it, you need to add it to your MainWP dashboad.', 'mainwp-child')
1645
+ ),
1646
+ 'verify_ssl' => array(
1647
+ 'title' => __('Verify certificate', 'mainwp-child'),
1648
+ 'value' => __('Yes', 'mainwp-child'),
1649
+ 'desc' => __('If there is an issue with SSL certificate on this site, try to set this option to No.', 'mainwp-child')
1650
+ ),
1651
+ 'ssl_version' => array(
1652
+ 'title' => __('SSL version', 'mainwp-child'),
1653
+ 'value' => __('Auto Detect', 'mainwp-child'),
1654
+ 'desc' => __('Auto Detect', 'mainwp-child'),
1655
+ ),
1656
+
1657
+ );
1658
+ ?>
1659
+ <div class="postbox" id="connection_detail">
1660
+ <h3 class="mainwp_box_title"><span><?php _e( 'Connection details', 'mainwp-child' ); ?></span></h3>
1661
+ <div class="inside">
1662
+ <div class="mainwp-postbox-actions-top mainwp-padding-5">
1663
+ <?php
1664
+ _e('If you are trying to connect this child site to your Mainwp Dashboard, you can use following details to do that. Please note that these are only suggested values.', 'mainwp-child');
1665
+ ?>
1666
+ </div>
1667
+ <table id="mainwp-table" class="wp-list-table widefat" cellspacing="0" style="border: 0">
1668
+ <tbody>
1669
+ <?php
1670
+ foreach ($details as $row) {
1671
+ ?>
1672
+ <tr>
1673
+ <th style="width: 20%"><strong><?php echo $row['title']; ?></strong></th>
1674
+ <td style="width: 20%"><strong><?php echo $row['value']; ?></strong></td>
1675
+ <td><?php echo $row['desc']; ?></td>
1676
+ </tr>
1677
+ <?php
1678
+ }
1679
+ ?>
1680
+ </tbody>
1681
+ </table>
1682
+ </div>
1683
+ </div>
1684
+ <?php
1685
+ }
1686
+
1687
+ }
class/class-mainwp-child-skeleton-key.php ADDED
@@ -0,0 +1,237 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+
4
+ class MainWP_Child_Skeleton_Key {
5
+ public static $instance = null;
6
+ public static $information = array();
7
+ public $plugin_translate = 'mainwp-child';
8
+
9
+ static function Instance() {
10
+ if ( null === MainWP_Child_Skeleton_Key::$instance ) {
11
+ MainWP_Child_Skeleton_Key::$instance = new MainWP_Child_Skeleton_Key();
12
+ }
13
+
14
+ return MainWP_Child_Skeleton_Key::$instance;
15
+ }
16
+
17
+ public function action() {
18
+
19
+ error_reporting( 0 );
20
+ function mainwp_skeleton_key_handle_fatal_error() {
21
+ $error = error_get_last();
22
+ if ( isset( $error['type'] ) && in_array($error['type'], array(1, 4, 16, 64, 256) ) && isset( $error['message'] ) ) {
23
+ MainWP_Helper::write( array( 'error' => 'MainWP_Child fatal error : ' . $error['message'] . ' Line: ' . $error['line'] . ' File: ' . $error['file'] ) );
24
+ } else {
25
+ MainWP_Helper::write( MainWP_Child_Skeleton_Key::$information );
26
+ }
27
+ }
28
+
29
+ register_shutdown_function( 'mainwp_skeleton_key_handle_fatal_error' );
30
+
31
+ switch ( $_POST['action'] ) {
32
+ case 'skeleton_key_visit_site_as_browser':
33
+ $information = $this->visit_site_as_browser();
34
+ break;
35
+ case 'save_settings':
36
+ $information = $this->save_settings();
37
+ break;
38
+ default:
39
+ $information = array( 'error' => 'Unknown action' );
40
+ }
41
+
42
+ MainWP_Helper::write( $information );
43
+ //MainWP_Child_Skeleton_Key::$information = $information;
44
+ exit();
45
+ }
46
+
47
+ protected function visit_site_as_browser() {
48
+ if ( ! isset( $_POST['url'] ) || ! is_string( $_POST['url'] ) || strlen( $_POST['url'] ) < 2 ) {
49
+ return array( 'error' => 'Missing url' );
50
+ }
51
+
52
+ if ( ! isset( $_POST['args'] ) || ! is_array( $_POST['args'] ) ) {
53
+ return array( 'error' => 'Missing args' );
54
+ }
55
+
56
+ $_POST = stripslashes_deep( $_POST );
57
+
58
+ $args = $_POST['args'];
59
+
60
+ $current_user = wp_get_current_user();
61
+
62
+ $url = '/' . $_POST['url'];
63
+
64
+ $expiration = time() + 600;
65
+ $manager = WP_Session_Tokens::get_instance( $current_user->ID );
66
+ $token = $manager->create( $expiration );
67
+
68
+
69
+ $secure = is_ssl();
70
+ if ( $secure ) {
71
+ $auth_cookie_name = SECURE_AUTH_COOKIE;
72
+ $scheme = 'secure_auth';
73
+ } else {
74
+ $auth_cookie_name = AUTH_COOKIE;
75
+ $scheme = 'auth';
76
+ }
77
+ $auth_cookie = wp_generate_auth_cookie( $current_user->ID, $expiration, $scheme, $token );
78
+ $logged_in_cookie = wp_generate_auth_cookie( $current_user->ID, $expiration, 'logged_in', $token );
79
+ $_COOKIE[ $auth_cookie_name ] = $auth_cookie;
80
+ $_COOKIE[ LOGGED_IN_COOKIE ] = $logged_in_cookie;
81
+ $post_args = array();
82
+ $post_args['body'] = array();
83
+ $post_args['redirection'] = 5;
84
+ $post_args['decompress'] = false; // For gzinflate() data error bug
85
+ $post_args['cookies'] = array(
86
+ new WP_Http_Cookie( array( 'name' => $auth_cookie_name, 'value' => $auth_cookie ) ),
87
+ new WP_Http_Cookie( array( 'name' => LOGGED_IN_COOKIE, 'value' => $logged_in_cookie ) ),
88
+ );
89
+
90
+ if ( isset( $args['get'] ) ) {
91
+ $get_args = $args['get'];
92
+ parse_str( $args['get'], $get_args );
93
+ }
94
+
95
+ if ( ! isset( $get_args ) || ! is_array( $get_args ) ) {
96
+ $get_args = array();
97
+ }
98
+
99
+ $get_args['skeleton_keyuse_nonce_key'] = intval( time() );
100
+ $get_args['skeleton_keyuse_nonce_hmac'] = hash_hmac( 'sha256', $get_args['skeleton_keyuse_nonce_key'], NONCE_KEY );
101
+
102
+ $good_nonce = null;
103
+ if ( isset( $args['nonce'] ) && ! empty( $args['nonce'] ) ) {
104
+ parse_str( $args['nonce'], $temp_nonce );
105
+ $good_nonce = $this->wp_create_nonce_recursive( $temp_nonce );
106
+ $get_args = array_merge( $get_args, $good_nonce );
107
+ }
108
+
109
+ if ( isset( $args['post'] ) ) {
110
+ parse_str( $args['post'], $temp_post );
111
+ if ( ! isset( $temp_post ) || ! is_array( $temp_post ) ) {
112
+ $temp_post = array();
113
+ }
114
+
115
+ if ( ! empty( $good_nonce ) ) {
116
+ $temp_post = array_merge( $temp_post, $good_nonce );
117
+ }
118
+
119
+ $post_args['body'] = $temp_post;
120
+ }
121
+
122
+ $post_args['timeout'] = 25;
123
+
124
+ $full_url = add_query_arg( $get_args, get_site_url() . $url );
125
+
126
+ $response = wp_remote_post( $full_url, $post_args );
127
+
128
+ if ( is_wp_error( $response ) ) {
129
+ return array( 'error' => 'wp_remote_post error: ' . $response->get_error_message() );
130
+ }
131
+
132
+ $received_content = wp_remote_retrieve_body( $response );
133
+
134
+ if ( preg_match( '/<mainwp>(.*)<\/mainwp>/', $received_content, $received_result ) > 0 ) {
135
+ $received_content_mainwp = json_decode( base64_decode( $received_result[1] ), true );
136
+ if ( isset( $received_content_mainwp['error'] ) ) {
137
+ return array( 'error' => $received_content_mainwp['error'] );
138
+ }
139
+ }
140
+
141
+ $search_ok_counter = 0;
142
+ $search_fail_counter = 0;
143
+
144
+ if ( isset( $args['search']['ok'] ) ) {
145
+ foreach ( $args['search']['ok'] as $search ) {
146
+ if ( preg_match( '/' . preg_quote( $search, '/' ) . '/i', $received_content ) ) {
147
+ ++ $search_ok_counter;
148
+ }
149
+ }
150
+ }
151
+
152
+ if ( isset( $args['search']['fail'] ) ) {
153
+ foreach ( $args['search']['fail'] as $search ) {
154
+ if ( preg_match( '/' . preg_quote( $search, '/' ) . '/i', $received_content ) ) {
155
+ ++ $search_fail_counter;
156
+ }
157
+ }
158
+ }
159
+ unset( $get_args['skeleton_keyuse_nonce_key'] );
160
+ unset( $get_args['skeleton_keyuse_nonce_hmac'] );
161
+
162
+ return array(
163
+ 'success' => 1,
164
+ 'content' => $received_content,
165
+ 'url' => $full_url,
166
+ 'get' => $get_args,
167
+ 'post' => $post_args['body'],
168
+ 'search_ok_counter' => $search_ok_counter,
169
+ 'search_fail_counter' => $search_fail_counter,
170
+ );
171
+ }
172
+
173
+ private function wp_create_nonce_recursive( $array ) {
174
+ foreach ( $array as $key => $value ) {
175
+ if ( is_array( $array[ $key ] ) ) {
176
+ $array[ $key ] = $this->wp_create_nonce_recursive( $array[ $key ] );
177
+ } else {
178
+ $array[ $key ] = wp_create_nonce( $array[ $key ] );
179
+ }
180
+ }
181
+
182
+ return $array;
183
+ }
184
+
185
+ public function save_settings() {
186
+ $settings = isset($_POST['settings']) ? $_POST['settings'] : array();
187
+
188
+ if (!is_array($settings) || empty($settings))
189
+ return array('error' => 'Invalid data');
190
+
191
+ $whitelist_options = array(
192
+ 'general' => array( 'blogname', 'blogdescription', 'gmt_offset', 'date_format', 'time_format', 'start_of_week', 'timezone_string', 'WPLANG' ),
193
+ );
194
+
195
+ if ( !is_multisite() ) {
196
+ if ( !defined( 'WP_SITEURL' ) )
197
+ $whitelist_options['general'][] = 'siteurl';
198
+ if ( !defined( 'WP_HOME' ) )
199
+ $whitelist_options['general'][] = 'home';
200
+
201
+ $whitelist_options['general'][] = 'admin_email';
202
+ $whitelist_options['general'][] = 'users_can_register';
203
+ $whitelist_options['general'][] = 'default_role';
204
+ }
205
+
206
+ //$whitelist_options = apply_filters( 'whitelist_options', $whitelist_options );
207
+ $whitelist_general = $whitelist_options[ 'general' ];
208
+
209
+ // Handle translation install.
210
+ if ( ! empty( $settings['WPLANG'] ) ) {
211
+ require_once( ABSPATH . 'wp-admin/includes/translation-install.php' );
212
+ if ( wp_can_install_language_pack() ) {
213
+ $language = wp_download_language_pack( $settings['WPLANG'] );
214
+ if ( $language ) {
215
+ $settings['WPLANG'] = $language;
216
+ }
217
+ }
218
+ }
219
+
220
+ $updated = false;
221
+ foreach($settings as $option => $value) {
222
+ if (in_array($option, $whitelist_general)) {
223
+ if ( ! is_array( $value ) )
224
+ $value = trim( $value );
225
+ $value = wp_unslash( $value );
226
+ update_option($option, $value);
227
+ $updated = true;
228
+ }
229
+ }
230
+
231
+ if (!$updated)
232
+ return false;
233
+
234
+ return array('result' => 'ok');
235
+ }
236
+
237
+ }
class/class-mainwp-child-staging.php ADDED
@@ -0,0 +1,367 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class MainWP_Child_Staging {
4
+
5
+ public static $instance = null;
6
+ public $is_plugin_installed = false;
7
+
8
+ static function Instance() {
9
+ if ( null === MainWP_Child_Staging::$instance ) {
10
+ MainWP_Child_Staging::$instance = new MainWP_Child_Staging();
11
+ }
12
+ return MainWP_Child_Staging::$instance;
13
+ }
14
+
15
+ public function __construct() {
16
+ require_once( ABSPATH . 'wp-admin/includes/plugin.php' );
17
+ if ( is_plugin_active( 'wp-staging/wp-staging.php' ) && defined('WPSTG_PLUGIN_DIR')) {
18
+ $this->is_plugin_installed = true;
19
+ }
20
+
21
+ if (!$this->is_plugin_installed)
22
+ return;
23
+
24
+ }
25
+
26
+
27
+ public function init() {
28
+ if ( get_option( 'mainwp_wp_staging_ext_enabled' ) !== 'Y' )
29
+ return;
30
+
31
+ if (!$this->is_plugin_installed)
32
+ return;
33
+
34
+ //add_action( 'mainwp_child_site_stats', array( $this, 'do_site_stats' ) );
35
+
36
+ if ( get_option( 'mainwp_wp_staging_hide_plugin' ) === 'hide' ) {
37
+ add_filter( 'all_plugins', array( $this, 'all_plugins' ) );
38
+ add_action( 'admin_menu', array( $this, 'remove_menu' ) );
39
+ add_filter( 'site_transient_update_plugins', array( &$this, 'remove_update_nag' ) );
40
+ }
41
+ }
42
+
43
+ public function get_sync_data() {
44
+ return $this->get_overview();
45
+ }
46
+
47
+ public function action() {
48
+ if (!$this->is_plugin_installed) {
49
+ MainWP_Helper::write( array('error' => 'Please install WP Staging plugin on child website') );
50
+ }
51
+
52
+ if (!class_exists( 'WPStaging\WPStaging' )){
53
+ require_once WPSTG_PLUGIN_DIR . "apps/Core/WPStaging.php";
54
+ }
55
+ \WPStaging\WPStaging::getInstance();
56
+
57
+ $information = array();
58
+ if (get_option( 'mainwp_wp_staging_ext_enabled' ) !== 'Y') {
59
+ MainWP_Helper::update_option( 'mainwp_wp_staging_ext_enabled', 'Y', 'yes' );
60
+ }
61
+
62
+ if ( isset( $_POST['mwp_action'] ) ) {
63
+ switch ( $_POST['mwp_action'] ) {
64
+ case 'set_showhide':
65
+ $information = $this->set_showhide();
66
+ break;
67
+ case 'save_settings':
68
+ $information = $this->save_settings();
69
+ break;
70
+ case 'get_overview':
71
+ $information = $this->get_overview();
72
+ break;
73
+ case 'get_scan':
74
+ $information = $this->get_scan();
75
+ break;
76
+ case 'check_disk_space':
77
+ $information = $this->ajaxCheckFreeSpace();
78
+ break;
79
+ case 'check_clone':
80
+ $information = $this->ajaxCheckCloneName();
81
+ break;
82
+ case 'start_clone':
83
+ $information = $this->ajaxStartClone();
84
+ break;
85
+ case 'clone_database':
86
+ $information = $this->ajaxCloneDatabase();
87
+ break;
88
+ case 'prepare_directories':
89
+ $information = $this->ajaxPrepareDirectories();
90
+ break;
91
+ case 'copy_files':
92
+ $information = $this->ajaxCopyFiles();
93
+ break;
94
+ case 'replace_data':
95
+ $information = $this->ajaxReplaceData();
96
+ break;
97
+ case 'clone_finish':
98
+ $information = $this->ajaxFinish();
99
+ break;
100
+ case 'delete_confirmation':
101
+ $information = $this->ajaxDeleteConfirmation();
102
+ break;
103
+ case 'delete_clone':
104
+ $information = $this->ajaxDeleteClone();
105
+ break;
106
+ case 'cancel_clone':
107
+ $information = $this->ajaxCancelClone();
108
+ break;
109
+ }
110
+ }
111
+ MainWP_Helper::write( $information );
112
+ }
113
+
114
+ function set_showhide() {
115
+ $hide = isset( $_POST['showhide'] ) && ( 'hide' === $_POST['showhide'] ) ? 'hide' : '';
116
+ MainWP_Helper::update_option( 'mainwp_wp_staging_hide_plugin', $hide, 'yes' );
117
+ $information['result'] = 'SUCCESS';
118
+ return $information;
119
+ }
120
+
121
+ function save_settings() {
122
+ $settings = $_POST['settings'];
123
+ $filters = array(
124
+ 'queryLimit',
125
+ 'fileLimit',
126
+ 'batchSize',
127
+ 'cpuLoad',
128
+ 'disableAdminLogin',
129
+ 'wpSubDirectory',
130
+ 'debugMode',
131
+ 'unInstallOnDelete',
132
+ 'checkDirectorySize'
133
+ );
134
+
135
+ $save_fields = array();
136
+ foreach($filters as $field) {
137
+ if (isset($settings[$field])) {
138
+ $save_fields[$field] = $settings[$field];
139
+ }
140
+ }
141
+ update_option('wpstg_settings', $save_fields );
142
+ return array('result' => 'success');
143
+ }
144
+
145
+ public function get_overview() {
146
+ $return = array(
147
+ 'availableClones' => get_option( "wpstg_existing_clones_beta", array())
148
+ );
149
+ return $return;
150
+ }
151
+
152
+ public function get_scan() {
153
+ // Scan
154
+ $scan = new WPStaging\Backend\Modules\Jobs\Scan();
155
+ $scan->start();
156
+
157
+ // Get Options
158
+ $options = $scan->getOptions();
159
+
160
+ $return = array(
161
+ 'options' => serialize($options),
162
+ 'directoryListing' => $scan->directoryListing(),
163
+ 'prefix' => WPStaging\WPStaging::getTablePrefix()
164
+ );
165
+ return $return;
166
+ }
167
+
168
+
169
+ public function ajaxCheckCloneName() {
170
+ $cloneName = sanitize_key( $_POST["cloneID"] );
171
+ $cloneNameLength = strlen( $cloneName );
172
+ $clones = get_option( "wpstg_existing_clones_beta", array() );
173
+
174
+ // Check clone name length
175
+ if( $cloneNameLength < 1 || $cloneNameLength > 16 ) {
176
+ echo array(
177
+ "status" => "failed",
178
+ "message" => "Clone name must be between 1 - 16 characters"
179
+ );
180
+ } elseif( array_key_exists( $cloneName, $clones ) ) {
181
+ return array(
182
+ "status" => "failed",
183
+ "message" => "Clone name is already in use, please choose an another clone name"
184
+ );
185
+ }
186
+
187
+ return array("status" => "success");
188
+ }
189
+
190
+ public function ajaxStartClone() {
191
+
192
+ $cloning = new WPStaging\Backend\Modules\Jobs\Cloning();
193
+
194
+ if( !$cloning->save() ) {
195
+ return;
196
+ }
197
+
198
+ ob_start();
199
+ require_once WPSTG_PLUGIN_DIR . "apps/Backend/views/clone/ajax/start.php";
200
+ $result = ob_get_clean();
201
+ return $result;
202
+ }
203
+
204
+ public function ajaxCloneDatabase() {
205
+
206
+ $cloning = new WPStaging\Backend\Modules\Jobs\Cloning();
207
+
208
+ return $cloning->start();
209
+ }
210
+
211
+ /**
212
+ * Ajax Prepare Directories (get listing of files)
213
+ */
214
+ public function ajaxPrepareDirectories() {
215
+
216
+ $cloning = new WPStaging\Backend\Modules\Jobs\Cloning();
217
+
218
+ return $cloning->start();
219
+ }
220
+
221
+ /**
222
+ * Ajax Clone Files
223
+ */
224
+ public function ajaxCopyFiles() {
225
+
226
+ $cloning = new WPStaging\Backend\Modules\Jobs\Cloning();
227
+
228
+ return $cloning->start();
229
+ }
230
+
231
+ /**
232
+ * Ajax Replace Data
233
+ */
234
+ public function ajaxReplaceData() {
235
+ $cloning = new WPStaging\Backend\Modules\Jobs\Cloning();
236
+ return $cloning->start();
237
+ }
238
+
239
+ /**
240
+ * Ajax Finish
241
+ */
242
+ public function ajaxFinish() {
243
+
244
+ $cloning = new WPStaging\Backend\Modules\Jobs\Cloning();
245
+ $this->url = ''; // to fix warning
246
+ $return = $cloning->start();
247
+ $return->blogInfoName = get_bloginfo("name");
248
+
249
+ return $return;
250
+ }
251
+
252
+ /**
253
+ * Ajax Delete Confirmation
254
+ */
255
+ public function ajaxDeleteConfirmation() {
256
+
257
+ $delete = new WPStaging\Backend\Modules\Jobs\Delete();
258
+ $delete->setData();
259
+ $clone = $delete->getClone();
260
+ $result = array(
261
+ 'clone' => $clone,
262
+ 'deleteTables' => $delete->getTables()
263
+ );
264
+ return $result;
265
+ }
266
+
267
+ /**
268
+ * Delete clone
269
+ */
270
+ public function ajaxDeleteClone() {
271
+
272
+ $delete = new WPStaging\Backend\Modules\Jobs\Delete();
273
+ return $delete->start();
274
+ }
275
+
276
+ /**
277
+ * Delete clone
278
+ */
279
+ public function ajaxCancelClone() {
280
+ $cancel = new WPStaging\Backend\Modules\Jobs\Cancel();
281
+ return $cancel->start();
282
+ }
283
+
284
+
285
+ public function ajaxCheckFreeSpace() {
286
+ return $this->hasFreeDiskSpace();
287
+ }
288
+
289
+ // from wp-staging plugin
290
+ public function hasFreeDiskSpace() {
291
+ if( !function_exists( "disk_free_space" ) ) {
292
+ return null;
293
+ }
294
+ $freeSpace = @disk_free_space( ABSPATH );
295
+ if( false === $freeSpace ) {
296
+ $data = array(
297
+ 'freespace' => false,
298
+ 'usedspace' => $this->formatSize($this->getDirectorySizeInclSubdirs(ABSPATH))
299
+ );
300
+ return $data;
301
+ }
302
+ $data = array(
303
+ 'freespace' => $this->formatSize($freeSpace),
304
+ 'usedspace' => $this->formatSize($this->getDirectorySizeInclSubdirs(ABSPATH))
305
+ );
306
+ return $data;
307
+ }
308
+
309
+ // from wp-staging plugin
310
+ function getDirectorySizeInclSubdirs( $dir ) {
311
+ $size = 0;
312
+ foreach ( glob( rtrim( $dir, '/' ) . '/*', GLOB_NOSORT ) as $each ) {
313
+ $size += is_file( $each ) ? filesize( $each ) : $this->getDirectorySizeInclSubdirs( $each );
314
+ }
315
+ return $size;
316
+ }
317
+
318
+ // from wp-staging plugin
319
+ public function formatSize($bytes, $precision = 2)
320
+ {
321
+ if ((double) $bytes < 1)
322
+ {
323
+ return '';
324
+ }
325
+
326
+ $units = array('B', "KB", "MB", "GB", "TB");
327
+
328
+ $bytes = (double) $bytes;
329
+ $base = log($bytes) / log(1000); // 1024 would be for MiB KiB etc
330
+ $pow = pow(1000, $base - floor($base)); // Same rule for 1000
331
+
332
+ return round($pow, $precision) . ' ' . $units[(int) floor($base)];
333
+ }
334
+
335
+
336
+ public function all_plugins( $plugins ) {
337
+ foreach ( $plugins as $key => $value ) {
338
+ $plugin_slug = basename( $key, '.php' );
339
+ if ( 'wp-staging' === $plugin_slug ) {
340
+ unset( $plugins[ $key ] );
341
+ }
342
+ }
343
+
344
+ return $plugins;
345
+ }
346
+
347
+ public function remove_menu() {
348
+ remove_menu_page( 'wpstg_clone' );
349
+ $pos = stripos( $_SERVER['REQUEST_URI'], 'admin.php?page=wpstg_clone' );
350
+ if ( false !== $pos ) {
351
+ wp_redirect( get_option( 'siteurl' ) . '/wp-admin/index.php' );
352
+ exit();
353
+ }
354
+ }
355
+
356
+ function remove_update_nag( $value ) {
357
+ if ( isset( $_POST['mainwpsignature'] ) ) {
358
+ return $value;
359
+ }
360
+ if ( isset( $value->response['wp-staging/wp-staging.php'] ) ) {
361
+ unset( $value->response['wp-staging/wp-staging.php'] );
362
+ }
363
+
364
+ return $value;
365
+ }
366
+ }
367
+
class/class-mainwp-child-themes-check.php ADDED
@@ -0,0 +1,292 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ Plugin: Vendi Abandoned Plugin Check
5
+ Description: Provides information about abandoned plugins.
6
+ Version: 3.1.1
7
+ License: GPLv2
8
+ Author: Vendi Advertising (Chris Haas)
9
+ */
10
+
11
+ class MainWP_Child_Themes_Check {
12
+
13
+ public static $instance = null;
14
+
15
+ private $cron_name_watcher = 'mainwp_child_cron_theme_health_check_watcher';
16
+
17
+ private $cron_name_daily = 'mainwp_child_cron_theme_health_check_daily';
18
+
19
+ private $cron_name_batching = 'mainwp_child_cron_theme_health_check_batching';
20
+
21
+ private $tran_name_theme_timestamps = 'mainwp_child_tran_name_theme_timestamps';
22
+
23
+ private $tran_name_themes_to_batch = 'mainwp_child_tran_name_themes_to_batch';
24
+
25
+ private $option_name_last_daily_run = 'mainwp_child_theme_last_daily_run';
26
+
27
+ public static function Instance() {
28
+ if ( null === MainWP_Child_Themes_Check::$instance ) {
29
+ MainWP_Child_Themes_Check::$instance = new MainWP_Child_Themes_Check();
30
+ }
31
+
32
+ return MainWP_Child_Themes_Check::$instance;
33
+ }
34
+
35
+ public function __construct() {
36
+ $this->schedule_watchdog();
37
+ add_action( $this->cron_name_batching, array( $this, 'run_check' ) );
38
+ add_action( $this->cron_name_daily, array( $this, 'run_check' ) );
39
+
40
+ add_action( $this->cron_name_watcher, array( $this, 'perform_watchdog' ) );
41
+
42
+ add_filter( 'themes_api_args', array( $this, 'modify_theme_api_search_query' ), 10, 2 );
43
+
44
+ add_action( 'mainwp_child_deactivation', array( $this, 'cleanup_deactivation' ) );
45
+ }
46
+
47
+ private function cleanup_basic() {
48
+ wp_clear_scheduled_hook( $this->cron_name_daily );
49
+ wp_clear_scheduled_hook( $this->cron_name_batching );
50
+ delete_transient( $this->tran_name_themes_to_batch );
51
+ }
52
+
53
+
54
+ public function cleanup_deactivation( $del = true ) {
55
+ $this->cleanup_basic();
56
+ wp_clear_scheduled_hook( $this->cron_name_watcher );
57
+ delete_option( $this->option_name_last_daily_run );
58
+ if ( $del ) {
59
+ delete_transient( $this->tran_name_theme_timestamps );
60
+ }
61
+ }
62
+
63
+
64
+ public function modify_theme_api_search_query( $args, $action ) {
65
+ if ( isset( $action ) && 'query_themes' === $action ) {
66
+
67
+ if ( ! is_object( $args ) ) {
68
+ $args = new \stdClass();
69
+ }
70
+
71
+ if ( ! property_exists( $args, 'fields' ) ) {
72
+ $args->fields = array();
73
+ }
74
+
75
+ $args->fields = array_merge( $args->fields, array( 'last_updated' => true ) );
76
+ }
77
+
78
+ return $args;
79
+ }
80
+
81
+ public function perform_watchdog() {
82
+ if ( false === wp_next_scheduled( $this->cron_name_daily ) && false === wp_next_scheduled( $this->cron_name_batching ) ) {
83
+ $last_run = get_option( $this->option_name_last_daily_run );
84
+
85
+ if ( false === $last_run || ! is_integer( $last_run ) ) {
86
+ $last_run = false;
87
+ } else {
88
+ $last_run = new \DateTime( '@' . $last_run );
89
+ }
90
+
91
+ //Get now
92
+ $now = new \DateTime();
93
+
94
+ if ( false === $last_run || (int) $now->diff( $last_run )->format( '%h' ) >= 24 ) {
95
+ $this->cleanup_basic();
96
+
97
+ wp_schedule_event( time(), 'daily', $this->cron_name_daily );
98
+
99
+ update_option( $this->option_name_last_daily_run, $now->getTimestamp() );
100
+
101
+ }
102
+ }
103
+ }
104
+
105
+ public function schedule_watchdog() {
106
+ //For testing
107
+ //$this->cleanup_deactivation();
108
+
109
+ //Schedule a global watching cron just in case both other crons get killed
110
+ if ( ! wp_next_scheduled( $this->cron_name_watcher ) ) {
111
+ wp_schedule_event( time(), 'hourly', $this->cron_name_watcher );
112
+ }
113
+
114
+ }
115
+
116
+ public function get_themes_outdate_info() {
117
+ $themes_outdate = get_transient( $this->tran_name_theme_timestamps );
118
+ if ( ! is_array( $themes_outdate ) ) {
119
+ $themes_outdate = array();
120
+ }
121
+ if ( ! function_exists( 'wp_get_themes' ) ) {
122
+ require_once( ABSPATH . '/wp-admin/includes/theme.php' );
123
+ }
124
+ $themes = wp_get_themes();
125
+ $update = false;
126
+ foreach ( $themes_outdate as $slug => $v ) {
127
+ if ( ! isset( $themes[ $slug ] ) ) {
128
+ unset( $themes_outdate[ $slug ] );
129
+ $update = true;
130
+ }
131
+ }
132
+ if ( $update ) {
133
+ set_transient( $this->tran_name_theme_timestamps, $themes_outdate, DAY_IN_SECONDS );
134
+ }
135
+
136
+ return $themes_outdate;
137
+ }
138
+
139
+ public function run_check() {
140
+ if ( ! function_exists( 'wp_get_themes' ) ) {
141
+ require_once( ABSPATH . '/wp-admin/includes/theme.php' );
142
+ }
143
+
144
+ //Get our previous results
145
+ $responses = get_transient( $this->tran_name_theme_timestamps );
146
+
147
+ if ( false === $responses || ! is_array( $responses ) ) {
148
+ $responses = array();
149
+ }
150
+
151
+ $all_themes = get_transient( $this->tran_name_themes_to_batch );
152
+ //If there wasn't a previous cache
153
+ if ( false === $all_themes || ! is_array( $all_themes ) ) {
154
+ $all_themes = array();
155
+ $themes = wp_get_themes();
156
+ if ( is_array( $themes ) ) {
157
+ foreach ( $themes as $theme ) {
158
+ $slug = $theme->get_stylesheet();
159
+ $all_themes[ $slug ] = array(
160
+ 'Name' => $theme->get( 'Name' ),
161
+ 'Version' => $theme->display( 'Version', true, false ),
162
+ );
163
+
164
+ }
165
+ }
166
+ $responses = array();
167
+ }
168
+
169
+ $avoid_themes = array( 'superstore' );
170
+ $themes_to_scan = array_splice( $all_themes, 0, apply_filters( 'mainwp_child_theme_health_check_max_themes_to_batch', 10 ) );
171
+ $tolerance_in_days = get_option( 'mainwp_child_plugintheme_days_outdate', 365 );
172
+
173
+ foreach ( $themes_to_scan as $slug => $v ) {
174
+ if ( in_array( $slug, $avoid_themes ) ) continue;
175
+
176
+ $body = $this->try_get_response_body( $slug, false );
177
+
178
+ if ( false === $body ) {
179
+ continue;
180
+ }
181
+
182
+ //Deserialize the response
183
+ $obj = maybe_unserialize( $body );
184
+
185
+ $now = new \DateTime();
186
+
187
+ //Sanity check that deserialization worked and that our property exists
188
+ if ( false !== $obj && is_object( $obj ) && property_exists( $obj, 'last_updated' ) ) {
189
+ $last_updated = strtotime( $obj->last_updated );
190
+ $theme_last_updated_date = new \DateTime( '@' . $last_updated );
191
+
192
+ $diff_in_days = $now->diff( $theme_last_updated_date )->format( '%a' );
193
+
194
+
195
+ if ( $diff_in_days < $tolerance_in_days ) {
196
+ continue;
197
+ }
198
+
199
+ $v['last_updated'] = $last_updated;
200
+
201
+ $responses[ $slug ] = $v;
202
+ }
203
+ }
204
+
205
+ if ( ! defined( 'MINUTE_IN_SECONDS' ) ) {
206
+ define( 'MINUTE_IN_SECONDS', 60 );
207
+ }
208
+
209
+ if ( ! defined( 'HOUR_IN_SECONDS' ) ) {
210
+ define( 'HOUR_IN_SECONDS', 60 * MINUTE_IN_SECONDS );
211
+ }
212
+
213
+ if ( ! defined( 'DAY_IN_SECONDS' ) ) {
214
+ define( 'DAY_IN_SECONDS', 24 * HOUR_IN_SECONDS );
215
+ }
216
+
217
+ //Store the master response for usage in the plugin table
218
+ set_transient( $this->tran_name_theme_timestamps, $responses, DAY_IN_SECONDS );
219
+
220
+ if ( 0 === count( $all_themes ) ) {
221
+ delete_transient( $this->tran_name_themes_to_batch );
222
+ //wp_schedule_single_event( time() + DAY_IN_SECONDS, $this->cron_name_daily );
223
+ } else {
224
+ set_transient( $this->tran_name_themes_to_batch, $all_themes, DAY_IN_SECONDS );
225
+ wp_schedule_single_event( time(), $this->cron_name_batching );
226
+
227
+ }
228
+ }
229
+
230
+
231
+ private function try_get_response_body( $theme ) {
232
+ //Some of this code is lifted from class-wp-upgrader
233
+
234
+ //Get the WordPress current version to be polite in the API call
235
+ include( ABSPATH . WPINC . '/version.php' );
236
+
237
+ if ( ! defined( 'MINUTE_IN_SECONDS' ) ) {
238
+ define( 'MINUTE_IN_SECONDS', 60 );
239
+ }
240
+
241
+ if ( ! defined( 'HOUR_IN_SECONDS' ) ) {
242
+ define( 'HOUR_IN_SECONDS', 60 * MINUTE_IN_SECONDS );
243
+ }
244
+
245
+ $url = $http_url = 'http://api.wordpress.org/themes/info/1.0/';
246
+ if ( $ssl = wp_http_supports( array( 'ssl' ) ) ) {
247
+ $url = set_url_scheme( $url, 'https' );
248
+ }
249
+
250
+ $args = array( 'slug' => $theme, 'fields' => array( 'sections' => false, 'tags' => false ) );
251
+ $args = (object) $args;
252
+
253
+ $http_args = array(
254
+ 'body' => array(
255
+ 'action' => 'theme_information',
256
+ 'request' => serialize( $args ),
257
+ ),
258
+ );
259
+
260
+ $raw_response = wp_remote_post( $url, $http_args );
261
+
262
+ if ( ! is_wp_error( $raw_response ) && 200 === (int) wp_remote_retrieve_response_code( $raw_response ) ) {
263
+ //Get the actual body
264
+ //Requires WP 2.7.0
265
+ $body = wp_remote_retrieve_body( $raw_response );
266
+
267
+ //Make sure that it isn't empty and also not an empty serialized object
268
+ if ( '' !== $body && 'N;' !== $body ) {
269
+ //If valid, return that
270
+ return $body;
271
+ }
272
+ }
273
+
274
+ //The above valid
275
+ //If we previously tried an SSL version try without SSL
276
+ //Code below same as above block
277
+ if ( $ssl ) {
278
+ $raw_response = wp_remote_post( $http_url, $http_args );
279
+
280
+ if ( ! is_wp_error( $raw_response ) && 200 === (int) wp_remote_retrieve_response_code( $raw_response ) ) {
281
+ $body = wp_remote_retrieve_body( $raw_response );
282
+ if ( '' !== $body && 'N;' !== $body ) {
283
+ return $body;
284
+ }
285
+ }
286
+ }
287
+
288
+ //Everything above failed, bail
289
+ return false;
290
+ }
291
+ }
292
+
class/class-mainwp-child-updraft-plus-backups.php ADDED
@@ -0,0 +1,3525 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class MainWP_Child_Updraft_Plus_Backups {
4
+ public static $instance = null;
5
+
6
+ static function Instance() {
7
+ if ( null === MainWP_Child_Updraft_Plus_Backups::$instance ) {
8
+ MainWP_Child_Updraft_Plus_Backups::$instance = new MainWP_Child_Updraft_Plus_Backups();
9
+ }
10
+
11
+ return MainWP_Child_Updraft_Plus_Backups::$instance;
12
+ }
13
+
14
+ public function __construct() {
15
+ add_filter( 'mainwp-site-sync-others-data', array( $this, 'syncOthersData' ), 10, 2 );
16
+ add_filter('updraftplus_save_last_backup', array( __CLASS__, 'hookUpdraftplusSaveLastBackup' ));
17
+ }
18
+
19
+ public static function hookUpdraftplusSaveLastBackup($last_backup) {
20
+ if (!is_array($last_backup))
21
+ return $last_backup;
22
+
23
+ if (isset($last_backup['backup_time'])) {
24
+ $backup_time = $last_backup['backup_time'];
25
+ MainWP_Helper::update_lasttime_backup('updraftplus', $backup_time);
26
+ }
27
+ return $last_backup;
28
+ }
29
+
30
+ function syncOthersData( $information, $data = array() ) {
31
+ if ( isset( $data['syncUpdraftData'] ) && $data['syncUpdraftData'] ) {
32
+ if ( self::isActivatedUpdraftplus() ) {
33
+ $information['syncUpdraftData'] = $this->syncData();
34
+ }
35
+ }
36
+ if ( isset( $data['sync_Updraftvault_quota_text'] ) && $data['sync_Updraftvault_quota_text'] ) {
37
+ if ( self::isActivatedUpdraftplus() ) {
38
+ $information['sync_Updraftvault_quota_text'] = $this->connected_html();
39
+ }
40
+ }
41
+ return $information;
42
+ }
43
+
44
+ public function action() {
45
+ $information = array();
46
+ if ( ! self::isActivatedUpdraftplus() ) {
47
+ $information['error'] = 'NO_UPDRAFTPLUS';
48
+ MainWP_Helper::write( $information );
49
+ }
50
+
51
+ global $updraftplus;
52
+ if ( empty( $updraftplus ) && class_exists( 'UpdraftPlus' ) ) {
53
+ $updraftplus = new UpdraftPlus();
54
+ }
55
+ if ( empty( $updraftplus ) ) {
56
+ $information['error'] = 'Error empty object';
57
+ MainWP_Helper::write( $information );
58
+ }
59
+
60
+ if ( isset( $_POST['mwp_action'] ) ) {
61
+
62
+ if ( get_option( 'mainwp_updraftplus_ext_enabled' ) !== 'Y' ) {
63
+ MainWP_Helper::update_option( 'mainwp_updraftplus_ext_enabled', 'Y', 'yes' );
64
+ }
65
+
66
+ switch ( $_POST['mwp_action'] ) {
67
+ case 'set_showhide':
68
+ $information = $this->set_showhide();
69
+ break;
70
+ case 'save_settings':
71
+ $information = $this->save_settings();
72
+ break;
73
+ case 'addons_connect':
74
+ $information = $this->addons_connect();
75
+ break;
76
+ case 'backup_now':
77
+ $information = $this->backup_now();
78
+ break;
79
+ case 'activejobs_list':
80
+ $information = $this->activejobs_list();
81
+ break;
82
+ case 'diskspaceused':
83
+ $information = $this->diskspaceused();
84
+ break;
85
+ case 'last_backup_html':
86
+ $information = $this->last_backup_html();
87
+ break;
88
+ case 'reload_data':
89
+ $information = $this->get_updraft_data();
90
+ break;
91
+ case 'next_scheduled_backups':
92
+ $information = $this->next_scheduled_backups();
93
+ break;
94
+ case 'forcescheduledresumption':
95
+ $information = $this->forceScheduledResumption();
96
+ break;
97
+ case 'fetch_updraft_log':
98
+ $information = $this->fetch_updraft_log();
99
+ break;
100
+ case 'activejobs_delete':
101
+ $information = $this->activejobs_delete();
102
+ break;
103
+ case 'historystatus':
104
+ $information = $this->historystatus();
105
+ break;
106
+ case 'deleteset':
107
+ $information = $this->deleteset();
108
+ break;
109
+ case 'updraft_download_backup':
110
+ $information = $this->updraft_download_backup();
111
+ break;
112
+ case 'restore_alldownloaded':
113
+ $information = $this->restore_alldownloaded();
114
+ break;
115
+ case 'restorebackup':
116
+ $information = $this->restoreBackup();
117
+ break;
118
+ case 'extradbtestconnection':
119
+ $information = $this->extradb_testconnection();
120
+ break;
121
+ case 'delete_old_dirs':
122
+ $information = $this->delete_old_dirs_go();
123
+ break;
124
+ case 'vault_connect':
125
+ $information = $this->do_vault_connect();
126
+ break;
127
+ case 'vault_disconnect':
128
+ $information = $this->vault_disconnect();
129
+ break;
130
+ }
131
+ }
132
+ MainWP_Helper::write( $information );
133
+ }
134
+
135
+ function set_showhide() {
136
+ $hide = isset( $_POST['showhide'] ) && ( 'hide' === $_POST['showhide'] ) ? 'hide' : '';
137
+ MainWP_Helper::update_option( 'mainwp_updraftplus_hide_plugin', $hide );
138
+ $information['result'] = 'SUCCESS';
139
+
140
+ return $information;
141
+ }
142
+
143
+ public static function isActivatedUpdraftplus() {
144
+ if ( ! defined( 'UPDRAFTPLUS_DIR' ) ) {
145
+ return false;
146
+ }
147
+
148
+ if ( ! class_exists( 'UpdraftPlus' ) ) {
149
+ require_once( UPDRAFTPLUS_DIR . '/class-updraftplus.php' );
150
+ }
151
+
152
+ if ( ! class_exists( 'UpdraftPlus_Options' ) ) {
153
+ require_once( UPDRAFTPLUS_DIR . '/options.php' );
154
+ }
155
+
156
+ return true;
157
+ }
158
+
159
+
160
+ private function get_settings_keys() {
161
+ return array(
162
+ 'updraft_autobackup_default',
163
+ 'updraftplus_dismissedautobackup',
164
+ 'updraftplus_dismissedexpiry',
165
+ 'updraft_interval',
166
+ 'updraft_interval_increments',
167
+ 'updraft_interval_database',
168
+ 'updraft_retain',
169
+ 'updraft_retain_db',
170
+ 'updraft_encryptionphrase',
171
+ //'updraft_service', // will check override to save
172
+ 'updraft_dir',
173
+ 'updraft_email',
174
+ 'updraft_delete_local',
175
+ 'updraft_include_plugins',
176
+ 'updraft_include_themes',
177
+ 'updraft_include_uploads',
178
+ 'updraft_include_others',
179
+ 'updraft_include_wpcore',
180
+ 'updraft_include_wpcore_exclude',
181
+ 'updraft_include_more',
182
+ 'updraft_include_blogs',
183
+ 'updraft_include_mu-plugins',
184
+ 'updraft_include_others_exclude',
185
+ 'updraft_include_uploads_exclude',
186
+ 'updraft_adminlocking',
187
+ 'updraft_starttime_files',
188
+ 'updraft_starttime_db',
189
+ 'updraft_startday_db',
190
+ 'updraft_startday_files',
191
+ 'updraft_googledrive',
192
+ 'updraft_s3',
193
+ 'updraft_s3generic',
194
+ 'updraft_dreamhost',
195
+ 'updraft_disable_ping',
196
+ 'updraft_openstack',
197
+ 'updraft_bitcasa',
198
+ //'updraft_cloudfiles',
199
+ 'updraft_ssl_useservercerts',
200
+ 'updraft_ssl_disableverify',
201
+ 'updraft_report_warningsonly',
202
+ 'updraft_report_wholebackup',
203
+ 'updraft_log_syslog',
204
+ 'updraft_extradatabases',
205
+ 'updraft_split_every',
206
+ 'updraft_ssl_nossl',
207
+ 'updraft_backupdb_nonwp',
208
+ 'updraft_extradbs',
209
+ 'updraft_include_more_path',
210
+ 'updraft_dropbox',
211
+ 'updraft_ftp',
212
+ 'updraft_copycom',
213
+ 'updraft_sftp_settings',
214
+ 'updraft_webdav_settings',
215
+ 'updraft_dreamobjects',
216
+ //'updraft_onedrive', // disalbed
217
+ //'updraft_azure', // disabled
218
+ 'updraft_googlecloud',
219
+ //'updraft_updraftvault',
220
+ 'updraft_retain_extrarules'
221
+ );
222
+ }
223
+
224
+ private function do_vault_connect() {
225
+ $vault_settings = UpdraftPlus_Options::get_updraft_option( 'updraft_updraftvault' );
226
+ if ( is_array( $vault_settings ) && !empty( $vault_settings['token'] ) && !empty( $vault_settings['email'] ) )
227
+ return array( 'connected' => true, 'html' => $this->connected_html() );
228
+
229
+ $connect = $this->vault_connect( $_REQUEST['email'], $_REQUEST['passwd'] );
230
+ if ( true === $connect ) {
231
+ $response = array( 'connected' => true, 'html' => $this->connected_html() );
232
+ } else {
233
+ $response = array(
234
+ 'e' => __( 'An unknown error occurred when trying to connect to UpdraftPlus.Com', 'updraftplus' )
235
+ );
236
+ if ( is_wp_error( $connect ) ) {
237
+ $response['e'] = $connect->get_error_message();
238
+ $response['code'] = $connect->get_error_code();
239
+ $response['data'] = serialize( $connect->get_error_data() );
240
+ }
241
+ }
242
+ return $response;
243
+ }
244
+
245
+
246
+ private function connected_html() {
247
+ $vault_settings = UpdraftPlus_Options::get_updraft_option( 'updraft_updraftvault' );
248
+ if ( !is_array( $vault_settings ) || empty( $vault_settings['token'] ) || empty( $vault_settings['email'] ) ) {
249
+ return '';
250
+ }
251
+
252
+ $ret = '';
253
+ $ret .= '<p style="padding-top: 0px; margin-top: 0px;">';
254
+ $ret .= __( 'This site is <strong>connected</strong> to UpdraftPlus Vault.', 'updraftplus' ).' '.__( "Well done - there's nothing more needed to set up.", 'updraftplus' ).'</p><p><strong>'.__( 'Vault owner', 'updraftplus' ).':</strong> ' . htmlspecialchars( $vault_settings['email'] );
255
+
256
+ $ret .= '<br><strong>' . __( 'Quota:', 'updraftplus' ) . '</strong> ';
257
+ if ( !isset( $vault_settings['quota'] ) || !is_numeric( $vault_settings['quota'] ) || ( $vault_settings['quota'] < 0 ) ) {
258
+ $ret .= __( 'Unknown', 'updraftplus' );
259
+ } else {
260
+ $quota_via_transient = get_transient( 'updraftvault_quota_text' );
261
+ if ( is_string( $quota_via_transient ) && $quota_via_transient ) {
262
+ $ret .= $quota_via_transient;
263
+ }
264
+ }
265
+ $ret .= '</p>';
266
+ $ret .= '<p><button id="updraftvault_disconnect" class="button-primary" style="font-size:18px;">' . __( 'Disconnect', 'updraftplus' ) . '</button></p>';
267
+
268
+ return $ret;
269
+ }
270
+
271
+
272
+ // Returns either true (in which case the Vault token will be stored), or false|WP_Error
273
+ private function vault_connect( $email, $password ) {
274
+ global $updraftplus;
275
+ $vault_mothership = 'https://vault.updraftplus.com/plugin-info/';
276
+
277
+ // Use SSL to prevent snooping
278
+ $result = wp_remote_post( $vault_mothership.'/?udm_action=vault_connect',
279
+ array(
280
+ 'timeout' => 20,
281
+ 'body' => array(
282
+ 'e' => $email,
283
+ 'p' => base64_encode( $password ),
284
+ 'sid' => $updraftplus->siteid(),
285
+ 'su' => base64_encode( home_url() )
286
+ )
287
+ )
288
+ );
289
+
290
+ if ( is_wp_error( $result ) || ( false === $result ) ) return $result;
291
+
292
+ $response = json_decode( $result['body'], true );
293
+
294
+ if ( !is_array( $response ) || !isset( $response['mothership'] ) || !isset( $response['loggedin'] ) ) {
295
+ if ( preg_match( '/has banned your IP address \(([\.:0-9a-f]+)\)/', $result['body'], $matches ) ) {
296
+ return new WP_Error( 'banned_ip', sprintf( __( "UpdraftPlus.com has responded with 'Access Denied'.", 'updraftplus' ) . '<br>' . __( "It appears that your web server's IP Address (%s) is blocked.", 'updraftplus' ) . ' ' . __( 'This most likely means that you share a webserver with a hacked website that has been used in previous attacks.', 'updraftplus' ) . '<br> <a href="https://updraftplus.com/unblock-ip-address/" target="_blank">' . __( 'To remove the block, please go here.', 'updraftplus' ) . '</a> ', $matches[1] ) );
297
+ } else {
298
+ return new WP_Error( 'unknown_response', sprintf( __( 'UpdraftPlus.Com returned a response which we could not understand (data: %s)', 'updraftplus' ), $result['body'] ) );
299
+ }
300
+ }
301
+
302
+ switch ( $response['loggedin'] ) {
303
+ case 'connected':
304
+ if ( !empty( $response['token'] ) ) {
305
+ // Store it
306
+ $vault_settings = UpdraftPlus_Options::get_updraft_option( 'updraft_updraftvault' );
307
+ if ( !is_array( $vault_settings ) ) $vault_settings = array();
308
+ $vault_settings['email'] = $email;
309
+ $vault_settings['token'] = (string) $response['token'];
310
+ $vault_settings['quota'] = -1;
311
+ unset( $vault_settings['last_config'] );
312
+ if ( isset($response['quota'] ) ) $vault_settings['quota'] = $response['quota'];
313
+ UpdraftPlus_Options::update_updraft_option( 'updraft_updraftvault', $vault_settings );
314
+ } elseif ( isset( $response['quota'] ) && !$response['quota'] ) {
315
+ return new WP_Error( 'no_quota', __( 'You do not currently have any UpdraftPlus Vault quota', 'updraftplus' ) );
316
+ } else {
317
+ return new WP_Error( 'unknown_response', __( 'UpdraftPlus.Com returned a response, but we could not understand it', 'updraftplus' ) );
318
+ }
319
+ break;
320
+ case 'authfailed':
321
+
322
+ if ( !empty( $response['authproblem'] ) ) {
323
+ if ( 'invalidpassword' == $response['authproblem'] ) {
324
+ $authfail_error = new WP_Error( 'authfailed', __( 'Your email address was valid, but your password was not recognised by UpdraftPlus.Com.', 'updraftplus' ) . ' <a href="https://updraftplus.com/my-account/lost-password/">' . __( 'If you have forgotten your password, then go here to change your password on updraftplus.com.', 'updraftplus' ) . '</a>' );
325
+ return $authfail_error;
326
+ } elseif ( 'invaliduser' == $response['authproblem'] ) {
327
+ return new WP_Error( 'authfailed', __( 'You entered an email address that was not recognised by UpdraftPlus.Com', 'updraftplus' ) );
328
+ }
329
+ }
330
+
331
+ return new WP_Error( 'authfailed', __( 'Your email address and password were not recognised by UpdraftPlus.Com', 'updraftplus' ) );
332
+ break;
333
+
334
+ default:
335
+ return new WP_Error( 'unknown_response', __( 'UpdraftPlus.Com returned a response, but we could not understand it', 'updraftplus' ) );
336
+ break;
337
+ }
338
+
339
+ return true;
340
+ }
341
+
342
+ // This method also gets called directly, so don't add code that assumes that it's definitely an AJAX situation
343
+ public function vault_disconnect() {
344
+ $vault_settings = UpdraftPlus_Options::get_updraft_option( 'updraft_updraftvault' );
345
+ UpdraftPlus_Options::update_updraft_option( 'updraft_updraftvault', array() );
346
+ global $updraftplus;
347
+ $vault_mothership = 'https://vault.updraftplus.com/plugin-info/';
348
+
349
+ delete_transient( 'udvault_last_config' );
350
+ delete_transient( 'updraftvault_quota_text' );
351
+
352
+ MainWP_Helper::close_connection( array( 'disconnected' => 1,
353
+ 'html' => $this->connected_html() )
354
+ );
355
+
356
+ // If $_POST['reset_hash'] is set, then we were alerted by updraftplus.com - no need to notify back
357
+ if ( is_array( $vault_settings ) && isset( $vault_settings['email'] ) && empty( $_POST['reset_hash'] ) ) {
358
+ $post_body = array(
359
+ 'e' => (string) $vault_settings['email'],
360
+ 'sid' => $updraftplus->siteid(),
361
+ 'su' => base64_encode( home_url() )
362
+ );
363
+
364
+ if ( !empty( $vault_settings['token'] ) ) $post_body['token'] = (string) $vault_settings['token'];
365
+
366
+ // Use SSL to prevent snooping
367
+ wp_remote_post( $vault_mothership.'/?udm_action=vault_disconnect', array(
368
+ 'timeout' => 20,
369
+ 'body' => $post_body,
370
+ ));
371
+ }
372
+ }
373
+
374
+ function save_settings() {
375
+ $settings = maybe_unserialize( base64_decode( $_POST['settings'] ) );
376
+
377
+ $keys_filter = $this->get_settings_keys();
378
+
379
+ $updated = false;
380
+ if ( is_array( $settings ) ) {
381
+ if ( class_exists( 'UpdraftPlus_Options' ) ) {
382
+ foreach ( $keys_filter as $key ) {
383
+ if ( isset( $settings[ $key ] ) ) {
384
+ $settings_key = null;
385
+ if ( 'updraft_dropbox' === $key && is_array($settings[ $key ])) {
386
+ $opts = UpdraftPlus_Options::get_updraft_option( 'updraft_dropbox' );
387
+ if(is_array($opts) && isset($opts['settings'])) {
388
+ $settings_key = key($opts['settings']);
389
+ if (isset($settings['is_general']) && !empty($settings['is_general'])){
390
+ $opts['settings'][$settings_key]['folder'] = $this->replace_tokens($settings[ $key ]['folder']);
391
+ } else {
392
+ // $opts['settings'][$settings_key]['appkey'] = $settings[ $key ]['appkey'];
393
+ // $opts['settings'][$settings_key]['secret'] = $settings[ $key ]['secret'];
394
+ $opts['settings'][$settings_key]['folder'] = $this->replace_tokens($settings[ $key ]['folder']);
395
+ }
396
+ } else {
397
+ if (isset($settings['is_general']) && !empty($settings['is_general'])){
398
+ $opts['folder'] = $this->replace_tokens($settings[ $key ]['folder']);
399
+ } else {
400
+ // $opts['appkey'] = $settings[ $key ]['appkey'];
401
+ // $opts['secret'] = $settings[ $key ]['secret'];
402
+ $opts['folder'] = $this->replace_tokens($settings[ $key ]['folder']);
403
+ }
404
+ }
405
+ UpdraftPlus_Options::update_updraft_option( $key, $opts );
406
+ } else if ( 'updraft_googledrive' === $key ) {
407
+ $opts = UpdraftPlus_Options::get_updraft_option( 'updraft_googledrive' );
408
+ if(is_array($opts) && isset($opts['settings'])) {
409
+ $settings_key = key($opts['settings']);
410
+ // $opts['settings'][$settings_key]['clientid'] = $settings[ $key ]['clientid'];
411
+ // $opts['settings'][$settings_key]['secret'] = $settings[ $key ]['secret'];
412
+ $opts['settings'][$settings_key]['folder'] = $this->replace_tokens($settings[ $key ]['folder']);
413
+ } else {
414
+ // $opts['clientid'] = $settings[ $key ]['clientid'];
415
+ // $opts['secret'] = $settings[ $key ]['secret'];
416
+ $opts['folder'] = $this->replace_tokens($settings[ $key ]['folder']);
417
+ }
418
+ UpdraftPlus_Options::update_updraft_option( $key, $opts );
419
+ } else if ( 'updraft_googlecloud' === $key ) {
420
+ $opts = UpdraftPlus_Options::get_updraft_option( $key );
421
+ if(is_array($opts) && isset($opts['settings'])) {
422
+ $settings_key = key($opts['settings']);
423
+ // $opts['settings'][$settings_key]['clientid'] = $settings[ $key ]['clientid'];
424
+ // $opts['settings'][$settings_key]['secret'] = $settings[ $key ]['secret'];
425
+ // $opts['settings'][$settings_key]['project_id'] = $settings[ $key ]['project_id'];
426
+ // $opts['settings'][$settings_key]['bucket_path'] = $settings[ $key ]['bucket_path'];
427
+ $opts['settings'][$settings_key]['storage_class'] = $settings[ $key ]['storage_class'];
428
+ $opts['settings'][$settings_key]['bucket_location'] = $settings[ $key ]['bucket_location'];
429
+ } else {
430
+ // $opts['clientid'] = $settings[ $key ]['clientid'];
431
+ // $opts['secret'] = $settings[ $key ]['secret'];
432
+ // $opts['project_id'] = $settings[ $key ]['project_id'];
433
+ // $opts['bucket_path'] = $settings[ $key ]['bucket_path'];
434
+ $opts['storage_class'] = $settings[ $key ]['storage_class'];
435
+ $opts['bucket_location'] = $settings[ $key ]['bucket_location'];
436
+ }
437
+ UpdraftPlus_Options::update_updraft_option( $key, $opts );
438
+ } else if ( 'updraft_onedrive' === $key ) {
439
+ $opts = UpdraftPlus_Options::get_updraft_option( 'updraft_onedrive' );
440
+ if(is_array($opts) && isset($opts['settings'])) {
441
+ $settings_key = key($opts['settings']);
442
+ // $opts['settings'][$settings_key]['clientid'] = $settings[ $key ]['clientid'];
443
+ // $opts['settings'][$settings_key]['secret'] = $settings[ $key ]['secret'];
444
+ $opts['settings'][$settings_key]['folder'] = $this->replace_tokens($settings[ $key ]['folder']);
445
+ } else {
446
+ // $opts['clientid'] = $settings[ $key ]['clientid'];
447
+ // $opts['secret'] = $settings[ $key ]['secret'];
448
+ $opts['folder'] = $this->replace_tokens($settings[ $key ]['folder']);
449
+ }
450
+
451
+ UpdraftPlus_Options::update_updraft_option( $key, $opts );
452
+ } else if ( 'updraft_email' === $key ) {
453
+ $value = $settings[ $key ];
454
+ // free version
455
+ if ( ! is_array( $value ) ) {
456
+ if ( ! empty( $value ) ) {
457
+ $value = htmlspecialchars( get_bloginfo( 'admin_email' ) );
458
+ }
459
+ }
460
+ UpdraftPlus_Options::update_updraft_option( $key, $value );
461
+ } else if ( 'updraft_s3' === $key ) {
462
+ $opts = UpdraftPlus_Options::get_updraft_option( 'updraft_s3' );
463
+ if(is_array($opts) && isset($opts['settings'])) {
464
+ $settings_key = key($opts['settings']);
465
+ $opts['settings'][$settings_key]['accesskey'] = $settings[ $key ]['accesskey'];
466
+ $opts['settings'][$settings_key]['secretkey'] = $settings[ $key ]['secretkey'];
467
+ $opts['settings'][$settings_key]['path'] = $this->replace_tokens($settings[ $key ]['path']);
468
+ if (!empty($opts['settings'][$settings_key]['path']) && '/' == substr($opts['settings'][$settings_key]['path'], 0, 1)) {
469
+ $opts['settings'][$settings_key]['path'] = substr($opts['settings'][$settings_key]['path'], 1);
470
+ }
471
+ if (isset($settings[ $key ]['rrs'])) { // premium settings
472
+ $opts['settings'][$settings_key]['rrs'] = $settings[ $key ]['rrs'];
473
+ $opts['settings'][$settings_key]['server_side_encryption'] = $settings[ $key ]['server_side_encryption'];
474
+ }
475
+ } else {
476
+ $opts['accesskey'] = $settings[ $key ]['accesskey'];
477
+ $opts['secretkey'] = $settings[ $key ]['secretkey'];
478
+ $opts['path'] = $this->replace_tokens($settings[ $key ]['path']);
479
+ if (!empty($opts['path']) && '/' == substr($opts['path'], 0, 1)) {
480
+ $opts['path'] = substr($opts['path'], 1);
481
+ }
482
+ if (isset($settings[ $key ]['rrs'])) { // premium settings
483
+ $opts['rrs'] = $settings[ $key ]['rrs'];
484
+ $opts['server_side_encryption'] = $settings[ $key ]['server_side_encryption'];
485
+ }
486
+ }
487
+
488
+ UpdraftPlus_Options::update_updraft_option( $key, $opts );
489
+ } else if ( 'updraft_s3generic' === $key ) {
490
+ $opts = UpdraftPlus_Options::get_updraft_option( 'updraft_s3generic' );
491
+ if(is_array($opts) && isset($opts['settings'])) {
492
+ $settings_key = key($opts['settings']);
493
+ $opts['settings'][$settings_key]['endpoint'] = $settings[ $key ]['endpoint'];
494
+ $opts['settings'][$settings_key]['accesskey'] = $settings[ $key ]['accesskey'];
495
+ $opts['settings'][$settings_key]['secretkey'] = $settings[ $key ]['secretkey'];
496
+ $opts['settings'][$settings_key]['path'] = $this->replace_tokens($settings[ $key ]['path']);
497
+ } else {
498
+ $opts['endpoint'] = $settings[ $key ]['endpoint'];
499
+ $opts['accesskey'] = $settings[ $key ]['accesskey'];
500
+ $opts['secretkey'] = $settings[ $key ]['secretkey'];
501
+ $opts['path'] = $this->replace_tokens($settings[ $key ]['path']);
502
+ }
503
+
504
+ UpdraftPlus_Options::update_updraft_option( $key, $opts );
505
+ } else if ( 'updraft_dreamobjects' === $key ) {
506
+ $opts = UpdraftPlus_Options::get_updraft_option( 'updraft_dreamobjects' );
507
+ if(is_array($opts) && isset($opts['settings'])) {
508
+ $settings_key = key($opts['settings']);
509
+ $opts['settings'][$settings_key]['path'] = $this->replace_tokens($settings[ $key ]['path']);
510
+ } else {
511
+ $opts['path'] = $this->replace_tokens($settings[ $key ]['path']);
512
+ }
513
+ UpdraftPlus_Options::update_updraft_option( $key, $opts );
514
+ } else if ( 'updraft_ftp' === $key ) {
515
+ $opts = UpdraftPlus_Options::get_updraft_option( 'updraft_ftp' );
516
+ if(is_array($opts) && isset($opts['settings'])) {
517
+ $settings_key = key($opts['settings']);
518
+ if ( isset( $settings[ $key ]['path'] ) ) {
519
+ $opts['settings'][$settings_key]['host'] = $settings[ $key ]['host'];
520
+ $opts['settings'][$settings_key]['user'] = $settings[ $key ]['user'];
521
+ $opts['settings'][$settings_key]['pass'] = $settings[ $key ]['pass'];
522
+ $opts['settings'][$settings_key]['path'] = $this->replace_tokens( $settings[ $key ]['path'] );
523
+ $opts['settings'][$settings_key]['passive'] = isset($settings[ $key ]['passive']) ? $settings[ $key ]['passive'] : 0;
524
+ }
525
+ } else {
526
+ if ( isset( $settings[ $key ]['path'] ) ) {
527
+ $opts['host'] = $settings[ $key ]['host'];
528
+ $opts['user'] = $settings[ $key ]['user'];
529
+ $opts['pass'] = $settings[ $key ]['pass'];
530
+ $opts['path'] = $this->replace_tokens( $settings[ $key ]['path'] );
531
+ $opts['passive'] = isset($settings[ $key ]['passive']) ? $settings[ $key ]['passive'] : 0;
532
+ }
533
+ }
534
+
535
+ UpdraftPlus_Options::update_updraft_option( $key, $opts );
536
+ } else if ( 'updraft_sftp_settings' === $key ) {
537
+ $opts = UpdraftPlus_Options::get_updraft_option( 'updraft_sftp' );
538
+ if(is_array($opts) && isset($opts['settings'])) {
539
+ $settings_key = key($opts['settings']);
540
+ if ( isset( $settings[ $key ]['path'] ) ) {
541
+ $opts['settings'][$settings_key]['host'] = $settings[ $key ]['host'];
542
+ $opts['settings'][$settings_key]['port'] = $settings[ $key ]['port'];
543
+ $opts['settings'][$settings_key]['user'] = $settings[ $key ]['user'];
544
+ $opts['settings'][$settings_key]['pass'] = $settings[ $key ]['pass'];
545
+ $opts['settings'][$settings_key]['key'] = $settings[ $key ]['key'];
546
+ $opts['settings'][$settings_key]['path'] = $this->replace_tokens( $settings[ $key ]['path'] );
547
+ $opts['settings'][$settings_key]['scp'] = isset($settings[ $key ]['scp']) ? $settings[ $key ]['scp'] : 0;
548
+ }
549
+ } else {
550
+ if ( isset( $settings[ $key ]['path'] ) ) {
551
+ $opts['host'] = $settings[ $key ]['host'];
552
+ $opts['port'] = $settings[ $key ]['port'];
553
+ $opts['user'] = $settings[ $key ]['user'];
554
+ $opts['pass'] = $settings[ $key ]['pass'];
555
+ $opts['key'] = $settings[ $key ]['key'];
556
+ $opts['path'] = $this->replace_tokens( $settings[ $key ]['path'] );
557
+ $opts['scp'] = isset($settings[ $key ]['scp']) ? $settings[ $key ]['scp'] : 0;
558
+ }
559
+ }
560
+ UpdraftPlus_Options::update_updraft_option( 'updraft_sftp', $opts );
561
+ } else {
562
+ UpdraftPlus_Options::update_updraft_option( $key, $settings[ $key ] );
563
+ }
564
+ $updated = true;
565
+ }
566
+ }
567
+
568
+
569
+ if (!isset($settings['do_not_save_remote_settings']) || empty($settings['do_not_save_remote_settings'])) {
570
+ UpdraftPlus_Options::update_updraft_option( 'updraft_service', $settings['updraft_service'] );
571
+ }
572
+
573
+
574
+ global $updraftplus;
575
+ if ( isset( $settings['updraft_interval'] ) ) {
576
+ // fix for premium version
577
+ $_POST['updraft_interval'] = $settings['updraft_interval'];
578
+ $_POST['updraft_startday_files'] = $settings['updraft_startday_files'];
579
+ $_POST['updraft_starttime_files'] = $settings['updraft_starttime_files'];
580
+ $updraftplus->schedule_backup( $settings['updraft_interval'] );
581
+ }
582
+ if ( isset( $settings['updraft_interval_database'] ) ) {
583
+ // fix for premium version
584
+ $_POST['updraft_interval_database'] = $settings['updraft_interval_database'];
585
+ $_POST['updraft_startday_db'] = $settings['updraft_startday_db'];
586
+ $_POST['updraft_starttime_db'] = $settings['updraft_starttime_db'];
587
+ $updraftplus->schedule_backup_database( $settings['updraft_interval_database'] );
588
+ }
589
+ }
590
+ }
591
+
592
+ $out = array();
593
+ if ( $updated ) {
594
+ $out['result'] = 'success';
595
+ } else {
596
+ $out['result'] = 'noupdate';
597
+ }
598
+
599
+ return $out;
600
+ }
601
+
602
+ function replace_tokens($str = '') {
603
+ if (stripos($str, '%sitename%') !== false) {
604
+ $replace_token = get_bloginfo( 'name' );
605
+ $replace_token = sanitize_file_name($replace_token);
606
+ $replace_token = strtolower($replace_token);
607
+ $str = str_ireplace("%sitename%", $replace_token, $str);
608
+ }
609
+
610
+ if (stripos($str, '%siteurl%') !== false) {
611
+ $replace_token = get_bloginfo( 'url' );
612
+ $replace_token = preg_replace('/^https?:\/\//i', '', $replace_token);
613
+ $replace_token = sanitize_file_name($replace_token);
614
+ $str = str_ireplace("%siteurl%", $replace_token, $str);
615
+ }
616
+ return $str;
617
+ }
618
+
619
+ function addons_connect() {
620
+ if ( ! defined( 'UDADDONS2_SLUG' ) ) {
621
+ return array( 'error' => 'NO_PREMIUM' );
622
+ }
623
+
624
+ $addons_options = maybe_unserialize( base64_decode( $_POST['addons_options'] ) );
625
+ if ( ! is_array( $addons_options ) ) {
626
+ $addons_options = array();
627
+ }
628
+
629
+ $updated = $this->update_wpmu_options( $addons_options );
630
+
631
+ $out = array();
632
+ if ( $updated ) {
633
+ $out['result'] = 'success';
634
+ }
635
+
636
+ return $out;
637
+ }
638
+
639
+ public function update_wpmu_options( $value ) {
640
+
641
+ if ( ! UpdraftPlus_Options::user_can_manage() ) {
642
+ return;
643
+ }
644
+ $options = $this->addons2_get_option( UDADDONS2_SLUG . '_options' );
645
+ if ( ! is_array( $options ) ) {
646
+ $options = array();
647
+ }
648
+
649
+ $options['email'] = isset( $value['email'] ) ? $value['email'] : '';
650
+ $options['password'] = isset( $value['password'] ) ? $value['password'] : '';
651
+
652
+ $options = $this->options_validate( $options );
653
+ $this->addons2_update_option( UDADDONS2_SLUG . '_options', $options );
654
+
655
+ return true;
656
+ }
657
+
658
+ // Funnelling through here a) allows for future flexibility and b) allows us to migrate elegantly from the previous non-MU-friendly setup
659
+ public function addons2_get_option( $option ) {
660
+ $val = get_site_option( $option );
661
+ # On multisite, migrate options into the site options
662
+ if ( false === $val && is_multisite() ) {
663
+ $blog_id = get_current_blog_id();
664
+ if ( $blog_id > 1 ) {
665
+ $val = get_option( $option );
666
+ if ( false !== $val ) {
667
+ delete_option( $option );
668
+ update_site_option( $option, $val );
669
+
670
+ return $val;
671
+ }
672
+ }
673
+ # $val is still false
674
+ switch_to_blog( 1 );
675
+ $val = get_option( $option );
676
+ if ( false !== $val ) {
677
+ delete_option( $option );
678
+ update_site_option( $option, $val );
679
+ }
680
+ restore_current_blog();
681
+ }
682
+
683
+ return $val;
684
+ }
685
+
686
+ public function addons2_update_option( $option, $val ) {
687
+ return update_site_option( $option, $val );
688
+ }
689
+
690
+ public function options_validate( $input ) {
691
+ # See: http://codex.wordpress.org/Function_Reference/add_settings_error
692
+
693
+ // When the options are re-saved, clear any previous cache of the connection status
694
+ $ehash = substr( md5( $input['email'] ), 0, 23 );
695
+ delete_site_transient( 'udaddons_connect_' . $ehash );
696
+
697
+ // add_settings_error( UDADDONS2_SLUG."_options", UDADDONS2_SLUG."_options_nodb", "Whinge, whinge", "error" );
698
+
699
+ return $input;
700
+ }
701
+
702
+
703
+ /*
704
+ *Plugin: UpdraftPlus - Backup/Restore
705
+ *PluginURI: http://updraftplus.com
706
+ *Description: Backup and restore: take backups locally, or backup to Amazon S3, Dropbox, Google Drive, Rackspace, (S)FTP, WebDAV & email, on automatic schedules.
707
+ *Author: UpdraftPlus.Com, DavidAnderson
708
+ *Version: 1.9.60
709
+ *Donate link: http://david.dw-perspective.org.uk/donate
710
+ *License: GPLv3 or later
711
+ *Text Domain: updraftplus
712
+ *Domain Path: /languages
713
+ *Author URI: http://updraftplus.com
714
+ */
715
+
716
+ public function extradb_testconnection() {
717
+
718
+ if ( ! class_exists( 'UpdraftPlus_WPDB_OtherDB_Test' ) ) {
719
+ if ( file_exists( UPDRAFTPLUS_DIR . '/addons/moredatabase.php' ) ) {
720
+ require_once( UPDRAFTPLUS_DIR . '/addons/moredatabase.php' );
721
+ }
722
+ }
723
+
724
+ if ( ! class_exists( 'UpdraftPlus_WPDB_OtherDB_Test' ) ) {
725
+ return array( 'r' => $_POST['row'], 'm' => 'Error: Require premium UpdraftPlus plugin.' );
726
+ }
727
+
728
+ if ( empty( $_POST['user_db'] ) ) {
729
+ return array(
730
+ 'r' => $_POST['row'],
731
+ 'm' => '<p>' . sprintf( __( 'Failure: No %s was given.', 'updraftplus' ) . '</p>', __( 'user', 'updraftplus' ) ),
732
+ );
733
+ }
734
+
735
+ if ( empty( $_POST['host'] ) ) {
736
+ return array(
737
+ 'r' => $_POST['row'],
738
+ 'm' => '<p>' . sprintf( __( 'Failure: No %s was given.', 'updraftplus' ) . '</p>', __( 'host', 'updraftplus' ) ),
739
+ );
740
+ }
741
+
742
+ if ( empty( $_POST['name'] ) ) {
743
+ return array(
744
+ 'r' => $_POST['row'],
745
+ 'm' => '<p>' . sprintf( __( 'Failure: No %s was given.', 'updraftplus' ) . '</p>', __( 'database name', 'updraftplus' ) ),
746
+ );
747
+ }
748
+
749
+ global $updraftplus_admin;
750
+ $updraftplus_admin->logged = array();
751
+
752
+ $ret = '';
753
+ $failed = false;
754
+
755
+ $wpdb_obj = new UpdraftPlus_WPDB_OtherDB_Test( $_POST['user_db'], $_POST['pass'], $_POST['name'], $_POST['host'] );
756
+ if ( ! empty( $wpdb_obj->error ) ) {
757
+ $failed = true;
758
+ $ret .= '<p>';
759
+ $dbinfo['user'] . '@' . $dbinfo['host'] . '/' . $dbinfo['name'] . ' : ' . __( 'database connection attempt failed', 'updraftplus' ) . '</p>';
760
+ if ( is_wp_error( $wpdb_obj->error ) || is_string( $wpdb_obj->error ) ) {
761
+ $ret .= '<ul style="list-style: disc inside;">';
762
+ if ( is_wp_error( $wpdb_obj->error ) ) {
763
+ $codes = $wpdb_obj->error->get_error_codes();
764
+ if ( is_array( $codes ) ) {
765
+ foreach ( $codes as $code ) {
766
+ if ( 'db_connect_fail' === $code ) {
767
+ $ret .= '<li>' . __( 'Connection failed: check your access details, that the database server is up, and that the network connection is not firewalled.', 'updraftplus' ) . '</li>';
768
+ } else {
769
+ $err = $wpdb_obj->error->get_error_message( $code );
770
+ $ret .= '<li>' . $err . '</li>';
771
+ }
772
+ }
773
+ }
774
+ } else {
775
+ $ret .= '<li>' . $wpdb_obj->error . '</li>';
776
+ }
777
+ $ret .= '</ul>';
778
+ }
779
+ }
780
+
781
+ $ret_info = '';
782
+ if ( ! $failed ) {
783
+ $all_tables = $wpdb_obj->get_results( 'SHOW TABLES', ARRAY_N );
784
+ $all_tables = array_map( create_function( '$a', 'return $a[0];' ), $all_tables );
785
+ if ( empty( $_POST['prefix'] ) ) {
786
+ $ret_info .= sprintf( __( '%s table(s) found.', 'updraftplus' ), count( $all_tables ) );
787
+ } else {
788
+ $our_prefix = 0;
789
+ foreach ( $all_tables as $table ) {
790
+ if ( 0 === strpos( $table, $_POST['prefix'] ) ) {
791
+ $our_prefix ++;
792
+ }
793
+ }
794
+ $ret_info .= sprintf( __( '%s total table(s) found; %s with the indicated prefix.', 'updraftplus' ), count( $all_tables ), $our_prefix );
795
+ }
796
+ }
797
+
798
+ $ret_after = '';
799
+
800
+ if ( count( $updraftplus_admin->logged ) > 0 ) {
801
+ $ret_after .= '<p>' . __( 'Messages:', 'updraftplus' );
802
+ $ret_after .= '<ul style="list-style: disc inside;">';
803
+
804
+ foreach ( array_unique( $updraftplus_admin->logged ) as $code => $err ) {
805
+ if ( 'db_connect_fail' === $code ) {
806
+ $failed = true;
807
+ }
808
+ $ret_after .= "<li><strong>$code:</strong> $err</li>";
809
+ }
810
+ $ret_after .= '</ul></p>';
811
+ }
812
+
813
+ if ( ! $failed ) {
814
+ $ret = '<p>' . __( 'Connection succeeded.', 'updraftplus' ) . ' ' . $ret_info . '</p>' . $ret;
815
+ } else {
816
+ $ret = '<p>' . __( 'Connection failed.', 'updraftplus' ) . '</p>' . $ret;
817
+ }
818
+
819
+ restore_error_handler();
820
+
821
+ return array( 'r' => $_POST['row'], 'm' => $ret . $ret_after );
822
+ }
823
+
824
+
825
+ function backup_now() {
826
+ global $updraftplus;
827
+ $backupnow_nocloud = ( empty( $_REQUEST['backupnow_nocloud'] ) ) ? false : true;
828
+ $event = ( ! empty( $_REQUEST['backupnow_nofiles'] ) ) ? 'updraft_backupnow_backup_database' : ( ( ! empty( $_REQUEST['backupnow_nodb'] ) ) ? 'updraft_backupnow_backup' : 'updraft_backupnow_backup_all' );
829
+
830
+ // The call to backup_time_nonce() allows us to know the nonce in advance, and return it
831
+ $nonce = $updraftplus->backup_time_nonce();
832
+
833
+ $msg = array(
834
+ 'nonce' => $nonce,
835
+ 'm' => '<strong>' . __( 'Start backup', 'updraftplus' ) . ':</strong> ' . htmlspecialchars( __( 'OK. You should soon see activity in the "Last log message" field below.', 'updraftplus' ) ),
836
+ );
837
+
838
+ $this->close_browser_connection( $msg );
839
+
840
+ $options = array( 'nocloud' => $backupnow_nocloud, 'use_nonce' => $nonce );
841
+ if ( ! empty( $_REQUEST['onlythisfileentity'] ) && is_string( $_REQUEST['onlythisfileentity'] ) ) {
842
+ // Something to see in the 'last log' field when it first appears, before the backup actually starts
843
+ $updraftplus->log( __( 'Start backup', 'updraftplus' ) );
844
+ $options['restrict_files_to_override'] = explode( ',', $_REQUEST['onlythisfileentity'] );
845
+ }
846
+
847
+ do_action( $event, apply_filters( 'updraft_backupnow_options', $options, array() ) );
848
+
849
+ // not used anymore
850
+ // if (wp_schedule_single_event(time()+5, $event, array($backupnow_nocloud)) === false) {
851
+ // $updraftplus->log("A backup run failed to schedule");
852
+ // //echo __("Failed.", 'updraftplus')."</div>";
853
+ // $result = 'FAILED';
854
+ // } else {
855
+ // $result = 'OK';
856
+ // //echo htmlspecialchars(__('OK. You should soon see activity in the "Last log message" field below.','updraftplus'))." <a href=\"http://updraftplus.com/faqs/my-scheduled-backups-and-pressing-backup-now-does-nothing-however-pressing-debug-backup-does-produce-a-backup/\"><br>".__('Nothing happening? Follow this link for help.','updraftplus')."</a></div>";
857
+ // $updraftplus->log("A backup run has been scheduled");
858
+ // }
859
+ $out = array( 'result' => 'OK' );
860
+
861
+ return $out;
862
+ }
863
+
864
+ function activejobs_list() {
865
+ global $updraftplus;
866
+ $download_status = array();
867
+ if ( ! empty( $_REQUEST['downloaders'] ) ) {
868
+ foreach ( explode( ':', $_REQUEST['downloaders'] ) as $downloader ) {
869
+ # prefix, timestamp, entity, index
870
+ if ( preg_match( '/^([^,]+),(\d+),([-a-z]+|db[0-9]+),(\d+)$/', $downloader, $matches ) ) {
871
+ $updraftplus->nonce = $matches[2];
872
+ $status = $this->download_status( $matches[2], $matches[3], $matches[4] );
873
+ if ( is_array( $status ) ) {
874
+ $status['base'] = $matches[1];
875
+ $status['timestamp'] = $matches[2];
876
+ $status['what'] = $matches[3];
877
+ $status['findex'] = ( empty( $matches[4] ) ) ? '0' : $matches[4];
878
+ $download_status[] = $status;
879
+ }
880
+ }
881
+ }
882
+ }
883
+
884
+ if ( ! empty( $_REQUEST['oneshot'] ) ) {
885
+ $job_id = get_site_option( 'updraft_oneshotnonce', false );
886
+ // print_active_job() for one-shot jobs that aren't in cron
887
+ $active_jobs = ( false === $job_id ) ? '' : $this->print_active_job( $job_id, true );
888
+ } elseif ( ! empty( $_REQUEST['thisjobonly'] ) ) {
889
+ // print_active_jobs() is for resumable jobs where we want the cron info to be included in the output
890
+ $active_jobs = $this->print_active_jobs( $_REQUEST['thisjobonly'] );
891
+ } else {
892
+ $active_jobs = $this->print_active_jobs();
893
+ }
894
+
895
+ $logupdate_array = array();
896
+ if ( ! empty( $_REQUEST['log_fetch'] ) ) {
897
+ if ( isset( $_REQUEST['log_nonce'] ) ) {
898
+ $log_nonce = $_REQUEST['log_nonce'];
899
+ $log_pointer = isset( $_REQUEST['log_pointer'] ) ? absint( $_REQUEST['log_pointer'] ) : 0;
900
+ $logupdate_array = $this->fetch_log( $log_nonce, $log_pointer );
901
+ }
902
+ }
903
+
904
+ return array(
905
+ 'l' => htmlspecialchars( UpdraftPlus_Options::get_updraft_option( 'updraft_lastmessage', '(' . __( 'Nothing yet logged', 'updraftplus' ) . ')' ) ),
906
+ 'j' => $active_jobs,
907
+ 'ds' => $download_status,
908
+ 'u' => $logupdate_array,
909
+ );
910
+
911
+ }
912
+
913
+
914
+ private function last_backup_html() {
915
+
916
+ global $updraftplus;
917
+
918
+ $updraft_last_backup = UpdraftPlus_Options::get_updraft_option( 'updraft_last_backup' );
919
+ $backup_time = 0;
920
+ if ( $updraft_last_backup ) {
921
+
922
+ // Convert to GMT, then to blog time
923
+ $backup_time = (int) $updraft_last_backup['backup_time'];
924
+ $print_time = get_date_from_gmt( gmdate( 'Y-m-d H:i:s', $backup_time ), 'D, F j, Y H:i' );
925
+
926
+ if ( empty( $updraft_last_backup['backup_time_incremental'] ) ) {
927
+ $last_backup_text = '<span style="color:' . ( ( $updraft_last_backup['success'] ) ? 'green' : 'black' ) . ';">' . $print_time . '</span>';
928
+ } else {
929
+ $inc_time = get_date_from_gmt( gmdate( 'Y-m-d H:i:s', $updraft_last_backup['backup_time_incremental'] ), 'D, F j, Y H:i' );
930
+ $last_backup_text = '<span style="color:' . ( ( $updraft_last_backup['success'] ) ? 'green' : 'black' ) . ";\">$inc_time</span> (" . sprintf( __( 'incremental backup; base backup: %s', 'updraftplus' ), $print_time ) . ')';
931
+ }
932
+
933
+ $last_backup_text .= '<br>';
934
+
935
+ // Show errors + warnings
936
+ if ( is_array( $updraft_last_backup['errors'] ) ) {
937
+ foreach ( $updraft_last_backup['errors'] as $err ) {
938
+ $level = ( is_array( $err ) ) ? $err['level'] : 'error';
939
+ $message = ( is_array( $err ) ) ? $err['message'] : $err;
940
+ $last_backup_text .= ( 'warning' === $level ) ? '<span style="color:orange;">' : '<span style="color:red;">';
941
+ if ( 'warning' === $level ) {
942
+ $message = sprintf( __( 'Warning: %s', 'updraftplus' ), make_clickable( htmlspecialchars( $message ) ) );
943
+ } else {
944
+ $message = htmlspecialchars( $message );
945
+ }
946
+ $last_backup_text .= $message;
947
+ $last_backup_text .= '</span>';
948
+ $last_backup_text .= '<br>';
949
+ }
950
+ }
951
+
952
+ // Link log
953
+ if ( ! empty( $updraft_last_backup['backup_nonce'] ) ) {
954
+ $updraft_dir = $updraftplus->backups_dir_location();
955
+
956
+ $potential_log_file = $updraft_dir . '/log.' . $updraft_last_backup['backup_nonce'] . '.txt';
957
+ if ( is_readable( $potential_log_file ) ) {
958
+ $last_backup_text .= "<a href=\"#\" class=\"updraft-log-link\" onclick=\"event.preventDefault(); mainwp_updraft_popuplog('" . $updraft_last_backup['backup_nonce'] . "', this);\">" . __( 'Download log file', 'updraftplus' ) . '</a>';
959
+ }
960
+ }
961
+ } else {
962
+ $last_backup_text = '<span style="color:blue;">' . __( 'No backup has been completed.', 'updraftplus' ) . '</span>';
963
+ }
964
+
965
+ return array( 'b' => $last_backup_text, 'lasttime_gmt' => $backup_time );
966
+
967
+ }
968
+
969
+ private function get_updraft_data() {
970
+ global $updraftplus;
971
+
972
+ if ( empty( $updraftplus ) && class_exists( 'UpdraftPlus' ) ) {
973
+ $updraftplus = new UpdraftPlus();
974
+ }
975
+
976
+ if ( empty( $updraftplus ) ) {
977
+ return false;
978
+ }
979
+
980
+ // UNIX timestamp
981
+ $next_scheduled_backup = wp_next_scheduled( 'updraft_backup' );
982
+ $next_scheduled_backup_gmt = $next_scheduled_backup_database_gmt = 0;
983
+ if ( $next_scheduled_backup ) {
984
+ // Convert to GMT
985
+ $next_scheduled_backup_gmt = gmdate( 'Y-m-d H:i:s', $next_scheduled_backup );
986
+ // Convert to blog time zone
987
+ $next_scheduled_backup = get_date_from_gmt( $next_scheduled_backup_gmt, 'D, F j, Y H:i' );
988
+ } else {
989
+ $next_scheduled_backup = 'Nothing currently scheduled';
990
+ }
991
+
992
+ $next_scheduled_backup_database = wp_next_scheduled( 'updraft_backup_database' );
993
+ if ( UpdraftPlus_Options::get_updraft_option( 'updraft_interval_database', UpdraftPlus_Options::get_updraft_option( 'updraft_interval' ) ) === UpdraftPlus_Options::get_updraft_option( 'updraft_interval' ) ) {
994
+ $next_scheduled_backup_database = ( 'Nothing currently scheduled' === $next_scheduled_backup ) ? $next_scheduled_backup : __( 'At the same time as the files backup', 'updraftplus' );
995
+ } else {
996
+ if ( $next_scheduled_backup_database ) {
997
+ // Convert to GMT
998
+ $next_scheduled_backup_database_gmt = gmdate( 'Y-m-d H:i:s', $next_scheduled_backup_database );
999
+ // Convert to blog time zone
1000
+ $next_scheduled_backup_database = get_date_from_gmt( $next_scheduled_backup_database_gmt, 'D, F j, Y H:i' );
1001
+ } else {
1002
+ $next_scheduled_backup_database = __( 'Nothing currently scheduled', 'updraftplus' );
1003
+ }
1004
+ }
1005
+
1006
+ $updraft_dir = $updraftplus->backups_dir_location();
1007
+ $backup_disabled = ( $updraftplus->really_is_writable( $updraft_dir ) ) ? 0 : 1;
1008
+
1009
+ $current_timegmt = time();
1010
+ $current_time = get_date_from_gmt( gmdate( 'Y-m-d H:i:s', $current_timegmt ), 'D, F j, Y H:i' );
1011
+
1012
+ $out = array(
1013
+ 'updraft_backup_disabled' => $backup_disabled,
1014
+ 'nextsched_files_gmt' => $next_scheduled_backup_gmt,
1015
+ 'nextsched_database_gmt' => $next_scheduled_backup_gmt,
1016
+ 'nextsched_current_timegmt' => $current_timegmt,
1017
+ 'nextsched_current_timezone' => $current_time,
1018
+ );
1019
+
1020
+ if ( $next_scheduled_backup_gmt ) {
1021
+ $out['nextsched_files_timezone'] = $next_scheduled_backup;
1022
+ }
1023
+
1024
+ if ( $next_scheduled_backup_gmt ) {
1025
+ $out['nextsched_database_timezone'] = $next_scheduled_backup_database;
1026
+ }
1027
+
1028
+ $bh = $this->build_historystatus();
1029
+ $out['updraft_historystatus'] = $bh['h'];
1030
+ $out['updraft_count_backups'] = $bh['c'];
1031
+
1032
+ $last_backup = $this->last_backup_html();
1033
+ $out['updraft_lastbackup_html'] = $last_backup['b'];
1034
+ $out['updraft_lastbackup_gmttime'] = $last_backup['lasttime_gmt'];
1035
+
1036
+ return $out;
1037
+ }
1038
+
1039
+
1040
+ private function next_scheduled_backups() {
1041
+ global $updraftplus;
1042
+
1043
+ $next_scheduled_backup_gmt = $next_scheduled_backup_database_gmt = 0;
1044
+
1045
+ // UNIX timestamp
1046
+ $next_scheduled_backup = wp_next_scheduled('updraft_backup');
1047
+ if ($next_scheduled_backup) {
1048
+ // Convert to GMT
1049
+ $next_scheduled_backup_gmt = gmdate('Y-m-d H:i:s', $next_scheduled_backup);
1050
+ // Convert to blog time zone
1051
+ $next_scheduled_backup = get_date_from_gmt($next_scheduled_backup_gmt, 'D, F j, Y H:i');
1052
+ // $next_scheduled_backup = date_i18n('D, F j, Y H:i', $next_scheduled_backup);
1053
+ } else {
1054
+ $next_scheduled_backup = __('Nothing currently scheduled', 'updraftplus');
1055
+ $files_not_scheduled = true;
1056
+ }
1057
+
1058
+ $next_scheduled_backup_database = wp_next_scheduled('updraft_backup_database');
1059
+ if (UpdraftPlus_Options::get_updraft_option('updraft_interval_database',UpdraftPlus_Options::get_updraft_option('updraft_interval')) == UpdraftPlus_Options::get_updraft_option('updraft_interval')) {
1060
+ if (isset($files_not_scheduled)) {
1061
+ $next_scheduled_backup_database = $next_scheduled_backup;
1062
+ $database_not_scheduled = true;
1063
+ } else {
1064
+ $next_scheduled_backup_database = __("At the same time as the files backup", 'updraftplus');
1065
+ $next_scheduled_backup_database_same_time = true;
1066
+ }
1067
+ } else {
1068
+ if ($next_scheduled_backup_database) {
1069
+ // Convert to GMT
1070
+ $next_scheduled_backup_database_gmt = gmdate('Y-m-d H:i:s', $next_scheduled_backup_database);
1071
+ // Convert to blog time zone
1072
+ $next_scheduled_backup_database = get_date_from_gmt($next_scheduled_backup_database_gmt, 'D, F j, Y H:i');
1073
+ // $next_scheduled_backup_database = date_i18n('D, F j, Y H:i', $next_scheduled_backup_database);
1074
+ } else {
1075
+ $next_scheduled_backup_database = __('Nothing currently scheduled', 'updraftplus');
1076
+ $database_not_scheduled = true;
1077
+ }
1078
+ }
1079
+
1080
+ $current_timegmt = time();
1081
+ $current_time = get_date_from_gmt( gmdate( 'Y-m-d H:i:s', $current_timegmt ), 'D, F j, Y H:i' );
1082
+
1083
+ $html = '<table style="border: 0px; padding: 0px; margin: 0 10px 0 0;">
1084
+ <tr>
1085
+ <td style="width: 124px; vertical-align:top; margin: 0px; padding: 0px;">' . __( 'Files', 'updraftplus' ) . ': </td><td style="color:blue; margin: 0px; padding: 0px;">' . $next_scheduled_backup . '</td>
1086
+ </tr><tr>
1087
+ <td style="width: 124px; vertical-align:top; margin: 0px; padding: 0px;">' . __( 'Database', 'updraftplus' ) . ': </td><td style="color:blue; margin: 0px; padding: 0px;">' . $next_scheduled_backup_database . '</td>
1088
+ </tr><tr>
1089
+ <td style="width: 124px; vertical-align:top; margin: 0px; padding: 0px;">' . __( 'Time now', 'updraftplus' ) . ': </td><td style="color:blue; margin: 0px; padding: 0px;">' . $current_time . '</td>
1090
+ </table>';
1091
+
1092
+ $updraft_dir = $updraftplus->backups_dir_location();
1093
+ $backup_disabled = ( $updraftplus->really_is_writable( $updraft_dir ) ) ? 0 : 1;
1094
+
1095
+ $out = array(
1096
+ 'n' => $html,
1097
+ 'updraft_backup_disabled' => $backup_disabled,
1098
+ 'nextsched_files_gmt' => $next_scheduled_backup_gmt,
1099
+ 'nextsched_database_gmt' => $next_scheduled_backup_database_gmt,
1100
+ 'nextsched_current_timegmt' => $current_timegmt,
1101
+ 'nextsched_current_timezone' => $current_time,
1102
+ );
1103
+
1104
+ if ( $next_scheduled_backup_gmt ) {
1105
+ $out['nextsched_files_timezone'] = $next_scheduled_backup;
1106
+ }
1107
+
1108
+ if ( $next_scheduled_backup_database_gmt ) {
1109
+ $out['nextsched_database_timezone'] = $next_scheduled_backup_database;
1110
+ }
1111
+
1112
+ return $out;
1113
+ }
1114
+
1115
+ private function deleteset() {
1116
+ global $updraftplus;
1117
+
1118
+ if (method_exists($updraftplus, 'get_backup_history')) {
1119
+ $backups = $updraftplus->get_backup_history();
1120
+ } else if (class_exists('UpdraftPlus_Backup_History')) {
1121
+ $backups = UpdraftPlus_Backup_History::get_history();
1122
+ }
1123
+ $timestamp = $_POST['backup_timestamp'];
1124
+ if ( ! isset( $backups[ $timestamp ] ) ) {
1125
+ $bh = $this->build_historystatus();
1126
+
1127
+ return array(
1128
+ 'result' => 'error',
1129
+ 'message' => __( 'Backup set not found', 'updraftplus' ),
1130
+ 'updraft_historystatus' => $bh['h'],
1131
+ 'updraft_count_backups' => $bh['c'],
1132
+ );
1133
+ }
1134
+
1135
+ // You need a nonce before you can set job data. And we certainly don't yet have one.
1136
+ $updraftplus->backup_time_nonce();
1137
+ // Set the job type before logging, as there can be different logging destinations
1138
+ $updraftplus->jobdata_set( 'job_type', 'delete' );
1139
+ $updraftplus->jobdata_set( 'job_time_ms', $updraftplus->job_time_ms );
1140
+
1141
+ if ( UpdraftPlus_Options::get_updraft_option( 'updraft_debug_mode' ) ) {
1142
+ $updraftplus->logfile_open( $updraftplus->nonce );
1143
+ set_error_handler( array( $updraftplus, 'php_error' ), E_ALL & ~E_STRICT );
1144
+ }
1145
+
1146
+ $updraft_dir = $updraftplus->backups_dir_location();
1147
+ $backupable_entities = $updraftplus->get_backupable_file_entities( true, true );
1148
+
1149
+ $nonce = isset( $backups[ $timestamp ]['nonce'] ) ? $backups[ $timestamp ]['nonce'] : '';
1150
+
1151
+ $delete_from_service = array();
1152
+
1153
+ if ( isset( $_POST['delete_remote'] ) && 1 == $_POST['delete_remote'] ) {
1154
+ // Locate backup set
1155
+ if ( isset( $backups[ $timestamp ]['service'] ) ) {
1156
+ $services = is_string( $backups[ $timestamp ]['service'] ) ? array( $backups[ $timestamp ]['service'] ) : $backups[ $timestamp ]['service'];
1157
+ if ( is_array( $services ) ) {
1158
+ foreach ( $services as $service ) {
1159
+ if ( $service != 'none' ) {
1160
+ $delete_from_service[] = $service;
1161
+ }
1162
+ }
1163
+ }
1164
+ }
1165
+ }
1166
+
1167
+ $files_to_delete = array();
1168
+ foreach ( $backupable_entities as $key => $ent ) {
1169
+ if ( isset( $backups[ $timestamp ][ $key ] ) ) {
1170
+ $files_to_delete[ $key ] = $backups[ $timestamp ][ $key ];
1171
+ }
1172
+ }
1173
+ // Delete DB
1174
+ if ( isset( $backups[ $timestamp ]['db'] ) ) {
1175
+ $files_to_delete['db'] = $backups[ $timestamp ]['db'];
1176
+ }
1177
+
1178
+ // Also delete the log
1179
+ if ( $nonce && ! UpdraftPlus_Options::get_updraft_option( 'updraft_debug_mode' ) ) {
1180
+ $files_to_delete['log'] = "log.$nonce.txt";
1181
+ }
1182
+
1183
+ unset( $backups[ $timestamp ] );
1184
+ UpdraftPlus_Options::update_updraft_option( 'updraft_backup_history', $backups );
1185
+
1186
+ $message = '';
1187
+
1188
+ $local_deleted = 0;
1189
+ $remote_deleted = 0;
1190
+ add_action( 'http_request_args', array( $updraftplus, 'modify_http_options' ) );
1191
+ foreach ( $files_to_delete as $key => $files ) {
1192
+ # Local deletion
1193
+ if ( is_string( $files ) ) {
1194
+ $files = array( $files );
1195
+ }
1196
+ foreach ( $files as $file ) {
1197
+ if ( is_file( $updraft_dir . '/' . $file ) ) {
1198
+ if ( @unlink( $updraft_dir . '/' . $file ) ) {
1199
+ $local_deleted ++;
1200
+ }
1201
+ }
1202
+ }
1203
+ if ( 'log' != $key && count( $delete_from_service ) > 0 ) {
1204
+ foreach ( $delete_from_service as $service ) {
1205
+ if ( 'email' == $service ) {
1206
+ continue;
1207
+ }
1208
+ if ( file_exists( UPDRAFTPLUS_DIR . "/methods/$service.php" ) ) {
1209
+ require_once( UPDRAFTPLUS_DIR . "/methods/$service.php" );
1210
+ }
1211
+ $objname = 'UpdraftPlus_BackupModule_' . $service;
1212
+ $deleted = - 1;
1213
+ if ( class_exists( $objname ) ) {
1214
+ # TODO: Re-use the object (i.e. prevent repeated connection setup/teardown)
1215
+ $remote_obj = new $objname;
1216
+ $deleted = $remote_obj->delete( $files );
1217
+ }
1218
+ if ( $deleted === - 1 ) {
1219
+ //echo __('Did not know how to delete from this cloud service.', 'updraftplus');
1220
+ } elseif ( $deleted !== false ) {
1221
+ $remote_deleted = $remote_deleted + count( $files );
1222
+ } else {
1223
+ // Do nothing
1224
+ }
1225
+ }
1226
+ }
1227
+ }
1228
+ remove_action( 'http_request_args', array( $updraftplus, 'modify_http_options' ) );
1229
+ $message .= __( 'The backup set has been removed.', 'updraftplus' ) . "\n";
1230
+ $message .= sprintf( __( 'Local archives deleted: %d', 'updraftplus' ), $local_deleted ) . "\n";
1231
+ $message .= sprintf( __( 'Remote archives deleted: %d', 'updraftplus' ), $remote_deleted ) . "\n";
1232
+
1233
+ $updraftplus->log( 'Local archives deleted: ' . $local_deleted );
1234
+ $updraftplus->log( 'Remote archives deleted: ' . $remote_deleted );
1235
+
1236
+ if ( UpdraftPlus_Options::get_updraft_option( 'updraft_debug_mode' ) ) {
1237
+ restore_error_handler();
1238
+ }
1239
+
1240
+ $bh = $this->build_historystatus();
1241
+
1242
+ return array(
1243
+ 'result' => 'success',
1244
+ 'message' => $message,
1245
+ 'updraft_historystatus' => $bh['h'],
1246
+ 'updraft_count_backups' => $bh['c'],
1247
+ );
1248
+ }
1249
+
1250
+ public function build_historystatus() {
1251
+ $backup_history = UpdraftPlus_Options::get_updraft_option( 'updraft_backup_history' );
1252
+ $backup_history = ( is_array( $backup_history ) ) ? $backup_history : array();
1253
+ $output = $this->existing_backup_table( $backup_history );
1254
+
1255
+ if ( ! empty( $messages ) && is_array( $messages ) ) {
1256
+ $noutput = '<div style="margin-left: 100px; margin-top: 10px;"><ul style="list-style: disc inside;">';
1257
+ foreach ( $messages as $msg ) {
1258
+ $noutput .= '<li>' . ( ( $msg['desc'] ) ? $msg['desc'] . ': ' : '' ) . '<em>' . $msg['message'] . '</em></li>';
1259
+ }
1260
+ $noutput .= '</ul></div>';
1261
+ $output = $noutput . $output;
1262
+ }
1263
+
1264
+ return array( 'h' => $output, 'c' => count( $backup_history ) );
1265
+ }
1266
+
1267
+ public function historystatus( $remotescan = null, $rescan = null ) {
1268
+ global $updraftplus;
1269
+
1270
+ $remotescan = ( $remotescan !== null ) ? $remotescan : $_POST['remotescan'];
1271
+ $rescan = ( $rescan !== null ) ? $rescan : $_POST['rescan'];
1272
+
1273
+ if ( $rescan ) {
1274
+ $messages = $this->rebuildBackupHistory( $remotescan );
1275
+ }
1276
+
1277
+ $backup_history = UpdraftPlus_Options::get_updraft_option( 'updraft_backup_history' );
1278
+ $backup_history = ( is_array( $backup_history ) ) ? $backup_history : array();
1279
+ $output = $this->existing_backup_table( $backup_history );
1280
+
1281
+ if ( ! empty( $messages ) && is_array( $messages ) ) {
1282
+ $noutput = '<div style="margin-left: 100px; margin-top: 10px;"><ul style="list-style: disc inside;">';
1283
+ foreach ( $messages as $msg ) {
1284
+ $noutput .= '<li>' . ( ( $msg['desc'] ) ? $msg['desc'] . ': ' : '' ) . '<em>' . $msg['message'] . '</em></li>';
1285
+ }
1286
+ $noutput .= '</ul></div>';
1287
+ $output = $noutput . $output;
1288
+ }
1289
+
1290
+ return array(
1291
+ 'n' => sprintf( __( 'Existing Backups', 'updraftplus' ) . ' (%d)', count( $backup_history ) ),
1292
+ 't' => $output,
1293
+ 'c' => count( $backup_history ),
1294
+ 'm' => $updraftplus->detect_safe_mode(),
1295
+ );
1296
+ }
1297
+
1298
+
1299
+ public function updraft_download_backup() {
1300
+
1301
+ @set_time_limit( 900 );
1302
+
1303
+ global $updraftplus;
1304
+
1305
+ if ( ! isset( $_REQUEST['timestamp'] ) || ! is_numeric( $_REQUEST['timestamp'] ) || ! isset( $_REQUEST['type'] ) ) {
1306
+ exit;
1307
+ }
1308
+
1309
+ $findex = ( isset( $_REQUEST['findex'] ) ) ? $_REQUEST['findex'] : 0;
1310
+ if ( empty( $findex ) ) {
1311
+ $findex = 0;
1312
+ }
1313
+
1314
+ $backupable_entities = $updraftplus->get_backupable_file_entities( true );
1315
+ $type_match = false;
1316
+ foreach ( $backupable_entities as $type => $info ) {
1317
+ if ( $_REQUEST['type'] == $type ) {
1318
+ $type_match = true;
1319
+ }
1320
+ }
1321
+
1322
+ if ( ! $type_match && 'db' != substr( $_REQUEST['type'], 0, 2 ) ) {
1323
+ exit;
1324
+ }
1325
+
1326
+ // Get the information on what is wanted
1327
+ $type = $_REQUEST['type'];
1328
+ $timestamp = $_REQUEST['timestamp'];
1329
+
1330
+ // You need a nonce before you can set job data. And we certainly don't yet have one.
1331
+ $updraftplus->backup_time_nonce( $timestamp );
1332
+
1333
+ $debug_mode = UpdraftPlus_Options::get_updraft_option( 'updraft_debug_mode' );
1334
+
1335
+ // Set the job type before logging, as there can be different logging destinations
1336
+ $updraftplus->jobdata_set( 'job_type', 'download' );
1337
+ $updraftplus->jobdata_set( 'job_time_ms', $updraftplus->job_time_ms );
1338
+
1339
+ // Retrieve the information from our backup history
1340
+ if (method_exists($updraftplus, 'get_backup_history')) {
1341
+ $backup_history = $updraftplus->get_backup_history();
1342
+ } else if (class_exists('UpdraftPlus_Backup_History')) {
1343
+ $backup_history = UpdraftPlus_Backup_History::get_history();
1344
+ }
1345
+
1346
+ // Base name
1347
+ $file = $backup_history[ $timestamp ][ $type ];
1348
+
1349
+ // Deal with multi-archive sets
1350
+ if ( is_array( $file ) ) {
1351
+ $file = $file[ $findex ];
1352
+ }
1353
+
1354
+ // Where it should end up being downloaded to
1355
+ $fullpath = $updraftplus->backups_dir_location() . '/' . $file;
1356
+
1357
+ if ( isset( $_POST['stage'] ) && '2' == $_POST['stage'] ) {
1358
+ $updraftplus->spool_file( $type, $fullpath );
1359
+
1360
+ return array();
1361
+ }
1362
+
1363
+ if ( isset( $_POST['stage'] ) && 'delete' == $_POST['stage'] ) {
1364
+ @unlink( $fullpath );
1365
+ $updraftplus->log( 'The file has been deleted' );
1366
+
1367
+ return 'deleted';
1368
+ }
1369
+
1370
+ // TODO: FIXME: Failed downloads may leave log files forever (though they are small)
1371
+ // Note that log() assumes that the data is in _POST, not _GET
1372
+ if ( $debug_mode ) {
1373
+ $updraftplus->logfile_open( $updraftplus->nonce );
1374
+ }
1375
+
1376
+ set_error_handler( array( $updraftplus, 'php_error' ), E_ALL & ~E_STRICT );
1377
+
1378
+ $updraftplus->log( "Requested to obtain file: timestamp=$timestamp, type=$type, index=$findex" );
1379
+
1380
+ $itext = ( empty( $findex ) ) ? '' : $findex;
1381
+ $known_size = isset( $backup_history[ $timestamp ][ $type . $itext . '-size' ] ) ? $backup_history[ $timestamp ][ $type . $itext . '-size' ] : 0;
1382
+
1383
+ $services = ( isset( $backup_history[ $timestamp ]['service'] ) ) ? $backup_history[ $timestamp ]['service'] : false;
1384
+ if ( is_string( $services ) ) {
1385
+ $services = array( $services );
1386
+ }
1387
+
1388
+ $updraftplus->jobdata_set( 'service', $services );
1389
+
1390
+ // Fetch it from the cloud, if we have not already got it
1391
+
1392
+ $needs_downloading = false;
1393
+
1394
+ if ( ! file_exists( $fullpath ) ) {
1395
+ //if the file doesn't exist and they're using one of the cloud options, fetch it down from the cloud.
1396
+ $needs_downloading = true;
1397
+ $updraftplus->log( 'File does not yet exist locally - needs downloading' );
1398
+ } elseif ( $known_size > 0 && filesize( $fullpath ) < $known_size ) {
1399
+ $updraftplus->log( 'The file was found locally (' . filesize( $fullpath ) . ") but did not match the size in the backup history ($known_size) - will resume downloading" );
1400
+ $needs_downloading = true;
1401
+ } elseif ( $known_size > 0 ) {
1402
+ $updraftplus->log( 'The file was found locally and matched the recorded size from the backup history (' . round( $known_size / 1024, 1 ) . ' Kb)' );
1403
+ } else {
1404
+ $updraftplus->log( 'No file size was found recorded in the backup history. We will assume the local one is complete.' );
1405
+ $known_size = filesize( $fullpath );
1406
+ }
1407
+
1408
+ // The AJAX responder that updates on progress wants to see this
1409
+ $updraftplus->jobdata_set( 'dlfile_' . $timestamp . '_' . $type . '_' . $findex, "downloading:$known_size:$fullpath" );
1410
+
1411
+ if ( $needs_downloading ) {
1412
+ $this->close_browser_connection();
1413
+ $is_downloaded = false;
1414
+ add_action( 'http_request_args', array( $updraftplus, 'modify_http_options' ) );
1415
+ foreach ( $services as $service ) {
1416
+ if ( $is_downloaded ) {
1417
+ continue;
1418
+ }
1419
+ $download = $this->download_file( $file, $service );
1420
+ if ( is_readable( $fullpath ) && $download !== false ) {
1421
+ clearstatcache();
1422
+ $updraftplus->log( 'Remote fetch was successful (file size: ' . round( filesize( $fullpath ) / 1024, 1 ) . ' Kb)' );
1423
+ $is_downloaded = true;
1424
+ } else {
1425
+ clearstatcache();
1426
+ if ( 0 === @filesize( $fullpath ) ) {
1427
+ @unlink( $fullpath );
1428
+ }
1429
+ $updraftplus->log( 'Remote fetch failed' );
1430
+ }
1431
+ }
1432
+ remove_action( 'http_request_args', array( $updraftplus, 'modify_http_options' ) );
1433
+ }
1434
+
1435
+ // Now, spool the thing to the browser
1436
+ if ( is_file( $fullpath ) && is_readable( $fullpath ) ) {
1437
+
1438
+ // That message is then picked up by the AJAX listener
1439
+ $updraftplus->jobdata_set( 'dlfile_' . $timestamp . '_' . $type . '_' . $findex, 'downloaded:' . filesize( $fullpath ) . ":$fullpath" );
1440
+
1441
+ } else {
1442
+ $updraftplus->jobdata_set( 'dlfile_' . $timestamp . '_' . $type . '_' . $findex, 'failed' );
1443
+ $updraftplus->jobdata_set( 'dlerrors_' . $timestamp . '_' . $type . '_' . $findex, $updraftplus->errors );
1444
+ $updraftplus->log( 'Remote fetch failed. File ' . $fullpath . ' did not exist or was unreadable. If you delete local backups then remote retrieval may have failed.' );
1445
+ }
1446
+
1447
+ restore_error_handler();
1448
+
1449
+ @fclose( $updraftplus->logfile_handle );
1450
+ if ( ! $debug_mode ) {
1451
+ @unlink( $updraftplus->logfile_name );
1452
+ }
1453
+
1454
+ return array( 'result' => 'OK' );
1455
+
1456
+ }
1457
+
1458
+ # Pass only a single service, as a string, into this function
1459
+ private function download_file( $file, $service ) {
1460
+
1461
+ global $updraftplus;
1462
+
1463
+ @set_time_limit( 900 );
1464
+
1465
+ $updraftplus->log( "Requested file from remote service: $service: $file" );
1466
+
1467
+ $method_include = UPDRAFTPLUS_DIR . '/methods/' . $service . '.php';
1468
+ if ( file_exists( $method_include ) ) {
1469
+ require_once( $method_include );
1470
+ }
1471
+
1472
+ $objname = "UpdraftPlus_BackupModule_${service}";
1473
+ if ( method_exists( $objname, 'download' ) ) {
1474
+ $remote_obj = new $objname;
1475
+
1476
+ return $remote_obj->download( $file );
1477
+ } else {
1478
+ $updraftplus->log( "Automatic backup restoration is not available with the method: $service." );
1479
+ $updraftplus->log( "$file: " . sprintf( __( "The backup archive for this file could not be found. The remote storage method in use (%s) does not allow us to retrieve files. To perform any restoration using UpdraftPlus, you will need to obtain a copy of this file and place it inside UpdraftPlus's working folder", 'updraftplus' ), $service ) . ' (' . $this->prune_updraft_dir_prefix( $updraftplus->backups_dir_location() ) . ')', 'error' );
1480
+
1481
+ return false;
1482
+ }
1483
+
1484
+ }
1485
+
1486
+ // This options filter removes ABSPATH off the front of updraft_dir, if it is given absolutely and contained within it
1487
+ public function prune_updraft_dir_prefix( $updraft_dir ) {
1488
+ if ( '/' == substr( $updraft_dir, 0, 1 ) || '\\' === substr( $updraft_dir, 0, 1 ) || preg_match( '/^[a-zA-Z]:/', $updraft_dir ) ) {
1489
+ $wcd = trailingslashit( WP_CONTENT_DIR );
1490
+ if ( strpos( $updraft_dir, $wcd ) === 0 ) {
1491
+ $updraft_dir = substr( $updraft_dir, strlen( $wcd ) );
1492
+ }
1493
+ }
1494
+
1495
+ return $updraft_dir;
1496
+ }
1497
+
1498
+
1499
+ public function restore_alldownloaded() {
1500
+ global $updraftplus;
1501
+
1502
+ if (method_exists($updraftplus, 'get_backup_history')) {
1503
+ $backups = $updraftplus->get_backup_history();
1504
+ } else if (class_exists('UpdraftPlus_Backup_History')) {
1505
+ $backups = UpdraftPlus_Backup_History::get_history();
1506
+ }
1507
+
1508
+ $updraft_dir = $updraftplus->backups_dir_location();
1509
+
1510
+ $timestamp = (int) $_POST['timestamp'];
1511
+ if ( ! isset( $backups[ $timestamp ] ) ) {
1512
+ return array( 'm' => '', 'w' => '', 'e' => __( 'No such backup set exists', 'updraftplus' ) );
1513
+
1514
+ }
1515
+
1516
+ $mess = array();
1517
+ parse_str( $_POST['restoreopts'], $res );
1518
+ if ( isset( $res['updraft_restore'] ) ) {
1519
+ set_error_handler( array( $this, 'get_php_errors' ), E_ALL & ~E_STRICT );
1520
+
1521
+ $elements = array_flip( $res['updraft_restore'] );
1522
+
1523
+ $warn = array();
1524
+ $err = array();
1525
+
1526
+ @set_time_limit( 900 );
1527
+ $max_execution_time = (int) @ini_get( 'max_execution_time' );
1528
+
1529
+ if ( $max_execution_time > 0 && $max_execution_time < 61 ) {
1530
+ $warn[] = sprintf( __( 'The PHP setup on this webserver allows only %s seconds for PHP to run, and does not allow this limit to be raised. If you have a lot of data to import, and if the restore operation times out, then you will need to ask your web hosting company for ways to raise this limit (or attempt the restoration piece-by-piece).', 'updraftplus' ), $max_execution_time );
1531
+ }
1532
+
1533
+ if ( isset( $backups[ $timestamp ]['native'] ) && false === $backups[ $timestamp ]['native'] ) {
1534
+ $warn[] = __( 'This backup set was not known by UpdraftPlus to be created by the current WordPress installation, but was found in remote storage.', 'updraftplus' ) . ' ' . __( 'You should make sure that this really is a backup set intended for use on this website, before you restore (rather than a backup set of an unrelated website that was using the same storage location).', 'updraftplus' );
1535
+ }
1536
+
1537
+ if ( isset( $elements['db'] ) ) {
1538
+ // Analyse the header of the database file + display results
1539
+ list ( $mess2, $warn2, $err2, $info ) = $this->analyse_db_file( $timestamp, $res );
1540
+ $mess = array_merge( $mess, $mess2 );
1541
+ $warn = array_merge( $warn, $warn2 );
1542
+ $err = array_merge( $err, $err2 );
1543
+ foreach ( $backups[ $timestamp ] as $bid => $bval ) {
1544
+ if ( 'db' !== $bid && 'db' === substr( $bid, 0, 2 ) && '-size' !== substr( $bid, - 5, 5 ) ) {
1545
+ $warn[] = __( 'Only the WordPress database can be restored; you will need to deal with the external database manually.', 'updraftplus' );
1546
+ break;
1547
+ }
1548
+ }
1549
+ }
1550
+
1551
+ $backupable_entities = $updraftplus->get_backupable_file_entities( true, true );
1552
+ $backupable_plus_db = $backupable_entities;
1553
+ $backupable_plus_db['db'] = array(
1554
+ 'path' => 'path-unused',
1555
+ 'description' => __( 'Database', 'updraftplus' ),
1556
+ );
1557
+
1558
+ if ( ! empty( $backups[ $timestamp ]['meta_foreign'] ) ) {
1559
+ $foreign_known = apply_filters( 'updraftplus_accept_archivename', array() );
1560
+ if ( ! is_array( $foreign_known ) || empty( $foreign_known[ $backups[ $timestamp ]['meta_foreign'] ] ) ) {
1561
+ $err[] = sprintf( __( 'Backup created by unknown source (%s) - cannot be restored.', 'updraftplus' ), $backups[ $timestamp ]['meta_foreign'] );
1562
+ } else {
1563
+ # For some reason, on PHP 5.5 passing by reference in a single array stopped working with apply_filters_ref_array (though not with do_action_ref_array).
1564
+ $backupable_plus_db = apply_filters_ref_array( 'updraftplus_importforeign_backupable_plus_db', array(
1565
+ $backupable_plus_db,
1566
+ array( $foreign_known[ $backups[ $timestamp ]['meta_foreign'] ], &$mess, &$warn, &$err ),
1567
+ ) );
1568
+ }
1569
+ }
1570
+
1571
+ foreach ( $backupable_plus_db as $type => $info ) {
1572
+ if ( ! isset( $elements[ $type ] ) ) {
1573
+ continue;
1574
+ }
1575
+ $whatwegot = $backups[ $timestamp ][ $type ];
1576
+ if ( is_string( $whatwegot ) ) {
1577
+ $whatwegot = array( $whatwegot );
1578
+ }
1579
+ $expected_index = 0;
1580
+ $missing = '';
1581
+ ksort( $whatwegot );
1582
+ $outof = false;
1583
+ foreach ( $whatwegot as $index => $file ) {
1584
+ if ( preg_match( '/\d+of(\d+)\.zip/', $file, $omatch ) ) {
1585
+ $outof = max( $matches[1], 1 );
1586
+ }
1587
+ if ( $index !== $expected_index ) {
1588
+ $missing .= ( '' === $missing ) ? ( 1 + $expected_index ) : ',' . ( 1 + $expected_index );
1589
+ }
1590
+ if ( ! file_exists( $updraft_dir . '/' . $file ) ) {
1591
+ $err[] = sprintf( __( 'File not found (you need to upload it): %s', 'updraftplus' ), $updraft_dir . '/' . $file );
1592
+ } elseif ( 0 === filesize( $updraft_dir . '/' . $file ) ) {
1593
+ $err[] = sprintf( __( 'File was found, but is zero-sized (you need to re-upload it): %s', 'updraftplus' ), $file );
1594
+ } else {
1595
+ $itext = ( 0 === $index ) ? '' : $index;
1596
+ if ( ! empty( $backups[ $timestamp ][ $type . $itext . '-size' ] ) && filesize( $updraft_dir . '/' . $file ) !== $backups[ $timestamp ][ $type . $itext . '-size' ] ) {
1597
+ if ( empty( $warn['doublecompressfixed'] ) ) {
1598
+ $warn[] = sprintf( __( 'File (%s) was found, but has a different size (%s) from what was expected (%s) - it may be corrupt.', 'updraftplus' ), $file, filesize( $updraft_dir . '/' . $file ), $backups[ $timestamp ][ $type . $itext . '-size' ] );
1599
+ }
1600
+ }
1601
+ do_action_ref_array( "updraftplus_checkzip_$type", array(
1602
+ $updraft_dir . '/' . $file,
1603
+ &$mess,
1604
+ &$warn,
1605
+ &$err,
1606
+ ) );
1607
+ }
1608
+ $expected_index ++;
1609
+ }
1610
+ do_action_ref_array( "updraftplus_checkzip_end_$type", array( &$mess, &$warn, &$err ) );
1611
+ # Detect missing archives where they are missing from the end of the set
1612
+ if ( $outof > 0 && $expected_index < $outof ) {
1613
+ for ( $j = $expected_index; $j < $outof; $j ++ ) {
1614
+ $missing .= ( '' === $missing ) ? ( 1 + $j ) : ',' . ( 1 + $j );
1615
+ }
1616
+ }
1617
+ if ( '' !== $missing ) {
1618
+ $warn[] = sprintf( __( 'This multi-archive backup set appears to have the following archives missing: %s', 'updraftplus' ), $missing . ' (' . $info['description'] . ')' );
1619
+ }
1620
+ }
1621
+
1622
+ if ( 0 === count( $err ) && 0 === count( $warn ) ) {
1623
+ $mess_first = __( 'The backup archive files have been successfully processed. Now press Restore again to proceed.', 'updraftplus' );
1624
+ } elseif ( 0 === count( $err ) ) {
1625
+ $mess_first = __( 'The backup archive files have been processed, but with some warnings. If all is well, then now press Restore again to proceed. Otherwise, cancel and correct any problems first.', 'updraftplus' );
1626
+ } else {
1627
+ $mess_first = __( 'The backup archive files have been processed, but with some errors. You will need to cancel and correct any problems before retrying.', 'updraftplus' );
1628
+ }
1629
+
1630
+ if ( count( $this->logged ) > 0 ) {
1631
+ foreach ( $this->logged as $lwarn ) {
1632
+ $warn[] = $lwarn;
1633
+ }
1634
+ }
1635
+ restore_error_handler();
1636
+
1637
+ return array(
1638
+ 'm' => '<p>' . $mess_first . '</p>' . implode( '<br>', $mess ),
1639
+ 'w' => implode( '<br>', $warn ),
1640
+ 'e' => implode( '<br>', $err ),
1641
+ );
1642
+ }
1643
+ }
1644
+
1645
+ public function restoreBackup() {
1646
+
1647
+ global $updraftplus_admin, $updraftplus;
1648
+ if ( empty( $updraftplus_admin ) ) {
1649
+ require_once( UPDRAFTPLUS_DIR . '/admin.php' );
1650
+ }
1651
+ ob_start();
1652
+ $backup_success = $this->restore_backup( $_REQUEST['backup_timestamp'] );
1653
+ if ( empty( $updraftplus->errors ) && true === $backup_success ) {
1654
+ // If we restored the database, then that will have out-of-date information which may confuse the user - so automatically re-scan for them.
1655
+ $this->rebuildBackupHistory();
1656
+ echo '<p><strong>';
1657
+ $updraftplus->log_e( 'Restore successful!' );
1658
+ echo '</strong></p>';
1659
+ $updraftplus->log( 'Restore successful' );
1660
+ $s_val = 1;
1661
+ if ( ! empty( $this->entities_to_restore ) && is_array( $this->entities_to_restore ) ) {
1662
+ foreach ( $this->entities_to_restore as $k => $v ) {
1663
+ if ( 'db' !== $v ) {
1664
+ $s_val = 2;
1665
+ }
1666
+ }
1667
+ }
1668
+ $pval = ( $updraftplus->have_addons ) ? 1 : 0;
1669
+ //echo '<strong>'.__('Actions','updraftplus').':</strong> <a href="'.UpdraftPlus_Options::admin_page_url().'?page=updraftplus&updraft_restore_success='.$s_val.'&pval='.$pval.'">'.__('Return to UpdraftPlus Configuration','updraftplus').'</a>';
1670
+
1671
+ } elseif ( is_wp_error( $backup_success ) ) {
1672
+ echo '<p>';
1673
+ $updraftplus->log_e( 'Restore failed...' );
1674
+ echo '</p>';
1675
+ $updraftplus->log_wp_error( $backup_success );
1676
+ $updraftplus->log( 'Restore failed' );
1677
+ $updraftplus->list_errors();
1678
+ //echo '<strong>'.__('Actions','updraftplus').':</strong> <a href="'.UpdraftPlus_Options::admin_page_url().'?page=updraftplus">'.__('Return to UpdraftPlus Configuration','updraftplus').'</a>';
1679
+
1680
+ } elseif ( false === $backup_success ) {
1681
+ # This means, "not yet - but stay on the page because we may be able to do it later, e.g. if the user types in the requested information"
1682
+
1683
+ }
1684
+
1685
+ $output = ob_get_clean();
1686
+
1687
+ return array( 'o' => $output );
1688
+
1689
+ }
1690
+
1691
+ // Return values: false = 'not yet' (not necessarily terminal); WP_Error = terminal failure; true = success
1692
+ private function restore_backup( $timestamp ) {
1693
+
1694
+ @set_time_limit( 900 );
1695
+
1696
+ global $wp_filesystem, $updraftplus;
1697
+ $backup_history = UpdraftPlus_Options::get_updraft_option( 'updraft_backup_history' );
1698
+ if ( ! is_array( $backup_history[ $timestamp ] ) ) {
1699
+ echo wp_kses_post( '<p>' . esc_html__( 'This backup does not exist in the backup history - restoration aborted. Timestamp:', 'updraftplus' ) . " $timestamp</p><br/>" );
1700
+
1701
+ return new WP_Error( 'does_not_exist', __( 'Backup does not exist in the backup history', 'updraftplus' ) );
1702
+ }
1703
+
1704
+ // request_filesystem_credentials passes on fields just via hidden name/value pairs.
1705
+ // Build array of parameters to be passed via this
1706
+ $extra_fields = array();
1707
+ if ( isset( $_POST['updraft_restore'] ) && is_array( $_POST['updraft_restore'] ) ) {
1708
+ foreach ( $_POST['updraft_restore'] as $entity ) {
1709
+ $_POST[ 'updraft_restore_' . $entity ] = 1;
1710
+ $extra_fields[] = 'updraft_restore_' . $entity;
1711
+ }
1712
+ }
1713
+ // Now make sure that updraft_restorer_ option fields get passed along to request_filesystem_credentials
1714
+ foreach ( $_POST as $key => $value ) {
1715
+ if ( 0 === strpos( $key, 'updraft_restorer_' ) ) {
1716
+ $extra_fields[] = $key;
1717
+ }
1718
+ }
1719
+
1720
+ $credentials = request_filesystem_credentials( UpdraftPlus_Options::admin_page() . "?page=updraftplus&action=updraft_restore&backup_timestamp=$timestamp", '', false, false, $extra_fields );
1721
+ WP_Filesystem( $credentials );
1722
+ if ( $wp_filesystem->errors->get_error_code() ) {
1723
+ echo '<p><em><a href="http://updraftplus.com/faqs/asked-ftp-details-upon-restorationmigration-updates/">' . esc_html__( 'Why am I seeing this?', 'updraftplus' ) . '</a></em></p>';
1724
+ foreach ( $wp_filesystem->errors->get_error_messages() as $message ) {
1725
+ show_message( $message );
1726
+ }
1727
+ exit;
1728
+ }
1729
+
1730
+ # Set up logging
1731
+ $updraftplus->backup_time_nonce();
1732
+ $updraftplus->jobdata_set( 'job_type', 'restore' );
1733
+ $updraftplus->jobdata_set( 'job_time_ms', $updraftplus->job_time_ms );
1734
+ $updraftplus->logfile_open( $updraftplus->nonce );
1735
+
1736
+ # Provide download link for the log file
1737
+
1738
+ #echo '<p><a target="_new" href="?action=downloadlog&page=updraftplus&updraftplus_backup_nonce='.htmlspecialchars($updraftplus->nonce).'">'.__('Follow this link to download the log file for this restoration.', 'updraftplus').'</a></p>';
1739
+
1740
+ # TODO: Automatic purging of old log files
1741
+ # TODO: Provide option to auto-email the log file
1742
+
1743
+ //if we make it this far then WP_Filesystem has been instantiated and is functional (tested with ftpext, what about suPHP and other situations where direct may work?)
1744
+ echo '<h1>' . esc_html__( 'UpdraftPlus Restoration: Progress', 'updraftplus' ) . '</h1><div id="updraft-restore-progress">';
1745
+ $this->show_admin_warning( '<a href="#" onclick="event.preventDefault(); mainwp_updraft_popuplog(\'' . htmlspecialchars( $updraftplus->nonce ) . '\', this);" >' . __( 'Follow this link to download the log file for this restoration (needed for any support requests).', 'updraftplus' ) . '</a>' );
1746
+
1747
+ $updraft_dir = trailingslashit( $updraftplus->backups_dir_location() );
1748
+ $foreign_known = apply_filters( 'updraftplus_accept_archivename', array() );
1749
+
1750
+ $service = ( isset( $backup_history[ $timestamp ]['service'] ) ) ? $backup_history[ $timestamp ]['service'] : false;
1751
+ if ( ! is_array( $service ) ) {
1752
+ $service = array( $service );
1753
+ }
1754
+
1755
+ // Now, need to turn any updraft_restore_<entity> fields (that came from a potential WP_Filesystem form) back into parts of the _POST array (which we want to use)
1756
+ if ( empty( $_POST['updraft_restore'] ) || ( ! is_array( $_POST['updraft_restore'] ) ) ) {
1757
+ $_POST['updraft_restore'] = array();
1758
+ }
1759
+
1760
+ $backup_set = $backup_history[ $timestamp ];
1761
+ $entities_to_restore = array();
1762
+ foreach ( $_POST['updraft_restore'] as $entity ) {
1763
+ if ( empty( $backup_set['meta_foreign'] ) ) {
1764
+ $entities_to_restore[ $entity ] = $entity;
1765
+ } else {
1766
+ if ( 'db' === $entity && ! empty( $foreign_known[ $backup_set['meta_foreign'] ] ) && ! empty( $foreign_known[ $backup_set['meta_foreign'] ]['separatedb'] ) ) {
1767
+ $entities_to_restore[ $entity ] = 'db';
1768
+ } else {
1769
+ $entities_to_restore[ $entity ] = 'wpcore';
1770
+ }
1771
+ }
1772
+ }
1773
+
1774
+ foreach ( $_POST as $key => $value ) {
1775
+ if ( 0 === strpos( $key, 'updraft_restore_' ) ) {
1776
+ $nkey = substr( $key, 16 );
1777
+ if ( ! isset( $entities_to_restore[ $nkey ] ) ) {
1778
+ $_POST['updraft_restore'][] = $nkey;
1779
+ if ( empty( $backup_set['meta_foreign'] ) ) {
1780
+ $entities_to_restore[ $nkey ] = $nkey;
1781
+ } else {
1782
+ if ( 'db' === $entity && ! empty( $foreign_known[ $backup_set['meta_foreign'] ]['separatedb'] ) ) {
1783
+ $entities_to_restore[ $nkey ] = 'db';
1784
+ } else {
1785
+ $entities_to_restore[ $nkey ] = 'wpcore';
1786
+ }
1787
+ }
1788
+ }
1789
+ }
1790
+ }
1791
+
1792
+ if ( 0 === count( $_POST['updraft_restore'] ) ) {
1793
+ echo esc_html( '<p>' . __( 'ABORT: Could not find the information on which entities to restore.', 'updraftplus' ) . '</p>' );
1794
+ echo esc_html( '<p>' . __( 'If making a request for support, please include this information:', 'updraftplus' ) . ' ' . count( $_POST ) . ' : ' . htmlspecialchars( serialize( $_POST ) ) . '</p>' );
1795
+
1796
+ return new WP_Error( 'missing_info', 'Backup information not found' );
1797
+ }
1798
+
1799
+ $updraftplus->log( 'Restore job started. Entities to restore: ' . implode( ', ', array_flip( $entities_to_restore ) ) );
1800
+
1801
+ $this->entities_to_restore = $entities_to_restore;
1802
+
1803
+ set_error_handler( array( $updraftplus, 'php_error' ), E_ALL & ~E_STRICT );
1804
+
1805
+ /*
1806
+ $_POST['updraft_restore'] is typically something like: array( 0=>'db', 1=>'plugins', 2=>'themes'), etc.
1807
+ i.e. array ( 'db', 'plugins', themes')
1808
+ */
1809
+
1810
+ $backupable_entities = $updraftplus->get_backupable_file_entities( true, true );
1811
+
1812
+ uksort( $backup_set, array( $this, 'sort_restoration_entities' ) );
1813
+
1814
+ // We use a single object for each entity, because we want to store information about the backup set
1815
+ require_once( UPDRAFTPLUS_DIR . '/restorer.php' );
1816
+
1817
+ global $updraftplus_restorer;
1818
+ $updraftplus_restorer = new Updraft_Restorer( new Updraft_Restorer_Skin, $backup_set );
1819
+
1820
+ $second_loop = array();
1821
+
1822
+ echo wp_kses_post( '<h2>' . esc_html__( 'Final checks', 'updraftplus' ) . '</h2>' );
1823
+
1824
+ if ( empty( $backup_set['meta_foreign'] ) ) {
1825
+ $entities_to_download = $entities_to_restore;
1826
+ } else {
1827
+ if ( ! empty( $foreign_known[ $backup_set['meta_foreign'] ]['separatedb'] ) ) {
1828
+ $entities_to_download = array();
1829
+ if ( in_array( 'db', $entities_to_restore ) ) {
1830
+ $entities_to_download['db'] = 1;
1831
+ }
1832
+ if ( count( $entities_to_restore ) > 1 || ! in_array( 'db', $entities_to_restore ) ) {
1833
+ $entities_to_download['wpcore'] = 1;
1834
+ }
1835
+ } else {
1836
+ $entities_to_download = array( 'wpcore' => 1 );
1837
+ }
1838
+ }
1839
+
1840
+ // First loop: make sure that files are present + readable; and populate array for second loop
1841
+ foreach ( $backup_set as $type => $files ) {
1842
+ // All restorable entities must be given explicitly, as we can store other arbitrary data in the history array
1843
+ if ( ! isset( $backupable_entities[ $type ] ) && 'db' !== $type ) {
1844
+ continue;
1845
+ }
1846
+ if ( isset( $backupable_entities[ $type ]['restorable'] ) && false === $backupable_entities[ $type ]['restorable'] ) {
1847
+ continue;
1848
+ }
1849
+
1850
+ if ( ! isset( $entities_to_download[ $type ] ) ) {
1851
+ continue;
1852
+ }
1853
+ if ( 'wpcore' === $type && is_multisite() && 0 === $updraftplus_restorer->ud_backup_is_multisite ) {
1854
+ echo wp_kses_post( "<p>$type: <strong>" );
1855
+ esc_html_e( 'Skipping restoration of WordPress core when importing a single site into a multisite installation. If you had anything necessary in your WordPress directory then you will need to re-add it manually from the zip file.', 'updraftplus' );
1856
+ #TODO
1857
+ #$updraftplus->log_e('Skipping restoration of WordPress core when importing a single site into a multisite installation. If you had anything necessary in your WordPress directory then you will need to re-add it manually from the zip file.');
1858
+ echo '</strong></p>';
1859
+ continue;
1860
+ }
1861
+
1862
+ if ( is_string( $files ) ) {
1863
+ $files = array( $files );
1864
+ }
1865
+
1866
+ foreach ( $files as $ind => $file ) {
1867
+ $fullpath = $updraft_dir . $file;
1868
+ echo sprintf( esc_html__( 'Looking for %s archive: file name: %s', 'updraftplus' ), esc_html( $type ), esc_html( htmlspecialchars( $file ) ) ) . '<br>';
1869
+
1870
+ add_action( 'http_request_args', array( $updraftplus, 'modify_http_options' ) );
1871
+ foreach ( $service as $serv ) {
1872
+ if ( ! is_readable( $fullpath ) ) {
1873
+ $sd = ( empty( $updraftplus->backup_methods[ $serv ] ) ) ? $serv : $updraftplus->backup_methods[ $serv ];
1874
+ echo esc_html__( 'File is not locally present - needs retrieving from remote storage', 'updraftplus' ) . esc_html( " ($sd)" );
1875
+ $this->download_file( $file, $serv );
1876
+ echo ': ';
1877
+ if ( ! is_readable( $fullpath ) ) {
1878
+ esc_html_e( 'Error', 'updraftplus' );
1879
+ } else {
1880
+ esc_html_e( 'OK', 'updraftplus' );
1881
+ }
1882
+ echo '<br>';
1883
+ }
1884
+ }
1885
+ remove_action( 'http_request_args', array( $updraftplus, 'modify_http_options' ) );
1886
+
1887
+ $index = ( 0 === $ind ) ? '' : $ind;
1888
+ // If a file size is stored in the backup data, then verify correctness of the local file
1889
+ if ( isset( $backup_history[ $timestamp ][ $type . $index . '-size' ] ) ) {
1890
+ $fs = $backup_history[ $timestamp ][ $type . $index . '-size' ];
1891
+ echo esc_html__( 'Archive is expected to be size:', 'updraftplus' ) . ' ' . esc_html( round( $fs / 1024, 1 ) ) . ' Kb: ';
1892
+ $as = @filesize( $fullpath );
1893
+ if ( $as === $fs ) {
1894
+ echo esc_html__( 'OK', 'updraftplus' ) . '<br>';
1895
+ } else {
1896
+ echo '<strong>' . esc_html__( 'Error:', 'updraftplus' ) . '</strong> ' . esc_html__( 'file is size:', 'updraftplus' ) . ' ' . esc_html( round( $as / 1024 ) ) . esc_html( " ($fs, $as)" ) . '<br>';
1897
+ }
1898
+ } else {
1899
+ echo esc_html__( 'The backup records do not contain information about the proper size of this file.', 'updraftplus' ) . '<br>';
1900
+ }
1901
+ if ( ! is_readable( $fullpath ) ) {
1902
+ echo esc_html__( 'Could not find one of the files for restoration', 'updraftplus' ) . esc_html( " ($file)" ) . '<br>';
1903
+ $updraftplus->log( "$file: " . __( 'Could not find one of the files for restoration', 'updraftplus' ), 'error' );
1904
+ echo '</div>';
1905
+ restore_error_handler();
1906
+
1907
+ return false;
1908
+ }
1909
+ }
1910
+
1911
+ if ( empty( $updraftplus_restorer->ud_foreign ) ) {
1912
+ $types = array( $type );
1913
+ } else {
1914
+ if ( 'db' !== $type || empty( $foreign_known[ $updraftplus_restorer->ud_foreign ]['separatedb'] ) ) {
1915
+ $types = array( 'wpcore' );
1916
+ } else {
1917
+ $types = array( 'db' );
1918
+ }
1919
+ }
1920
+
1921
+ foreach ( $types as $check_type ) {
1922
+ $info = ( isset( $backupable_entities[ $check_type ] ) ) ? $backupable_entities[ $check_type ] : array();
1923
+ $val = $updraftplus_restorer->pre_restore_backup( $files, $check_type, $info );
1924
+ if ( is_wp_error( $val ) ) {
1925
+ $updraftplus->log_wp_error( $val );
1926
+ foreach ( $val->get_error_messages() as $msg ) {
1927
+ echo '<strong>' . esc_html__( 'Error:', 'updraftplus' ) . '</strong> ' . esc_html( htmlspecialchars( $msg ) ) . '<br>';
1928
+ }
1929
+ foreach ( $val->get_error_codes() as $code ) {
1930
+ if ( 'already_exists' === $code ) {
1931
+ $this->print_delete_old_dirs_form();
1932
+ }
1933
+ }
1934
+ echo '</div>'; //close the updraft_restore_progress div even if we error
1935
+ restore_error_handler();
1936
+
1937
+ return $val;
1938
+ } elseif ( false === $val ) {
1939
+ echo '</div>'; //close the updraft_restore_progress div even if we error
1940
+ restore_error_handler();
1941
+
1942
+ return false;
1943
+ }
1944
+ }
1945
+
1946
+ foreach ( $entities_to_restore as $entity => $via ) {
1947
+ if ( $via === $type ) {
1948
+ $second_loop[ $entity ] = $files;
1949
+ }
1950
+ }
1951
+ }
1952
+
1953
+ $updraftplus_restorer->delete = ( UpdraftPlus_Options::get_updraft_option( 'updraft_delete_local' ) ) ? true : false;
1954
+ if ( 'none' === $service || 'email' === $service || empty( $service ) || ( is_array( $service ) && 1 === count( $service ) && ( in_array( 'none', $service ) || in_array( '', $service ) || in_array( 'email', $service ) ) ) || ! empty( $updraftplus_restorer->ud_foreign ) ) {
1955
+ if ( $updraftplus_restorer->delete ) {
1956
+ $updraftplus->log_e( 'Will not delete any archives after unpacking them, because there was no cloud storage for this backup' );
1957
+ }
1958
+ $updraftplus_restorer->delete = false;
1959
+ }
1960
+
1961
+ if ( ! empty( $updraftplus_restorer->ud_foreign ) ) {
1962
+ $updraftplus->log( 'Foreign backup; created by: ' . $updraftplus_restorer->ud_foreign );
1963
+ }
1964
+
1965
+ // Second loop: now actually do the restoration
1966
+ uksort( $second_loop, array( $this, 'sort_restoration_entities' ) );
1967
+ foreach ( $second_loop as $type => $files ) {
1968
+ # Types: uploads, themes, plugins, others, db
1969
+ $info = ( isset( $backupable_entities[ $type ] ) ) ? $backupable_entities[ $type ] : array();
1970
+
1971
+ echo ( 'db' === $type ) ? '<h2>' . esc_html__( 'Database', 'updraftplus' ) . '</h2>' : '<h2>' . esc_html( $info['description'] ) . '</h2>';
1972
+ $updraftplus->log( 'Entity: ' . $type );
1973
+
1974
+ if ( is_string( $files ) ) {
1975
+ $files = array( $files );
1976
+ }
1977
+ foreach ( $files as $fkey => $file ) {
1978
+ $last_one = ( 1 === count( $second_loop ) && 1 === count( $files ) );
1979
+
1980
+ $val = $updraftplus_restorer->restore_backup( $file, $type, $info, $last_one );
1981
+
1982
+ if ( is_wp_error( $val ) ) {
1983
+ $updraftplus->log_e( $val );
1984
+ foreach ( $val->get_error_messages() as $msg ) {
1985
+ echo '<strong>' . esc_html__( 'Error message', 'updraftplus' ) . ':</strong> ' . esc_html( htmlspecialchars( $msg ) ) . '<br>';
1986
+ }
1987
+ $codes = $val->get_error_codes();
1988
+ if ( is_array( $codes ) ) {
1989
+ foreach ( $codes as $code ) {
1990
+ $data = $val->get_error_data( $code );
1991
+ if ( ! empty( $data ) ) {
1992
+ $pdata = ( is_string( $data ) ) ? $data : serialize( $data );
1993
+ echo '<strong>' . esc_html__( 'Error data:', 'updraftplus' ) . '</strong> ' . esc_html( htmlspecialchars( $pdata ) ) . '<br>';
1994
+ if ( false !== strpos( $pdata, 'PCLZIP_ERR_BAD_FORMAT (-10)' ) ) {
1995
+ echo '<a href="http://updraftplus.com/faqs/error-message-pclzip_err_bad_format-10-invalid-archive-structure-mean/"><strong>' . esc_html__( 'Please consult this FAQ for help on what to do about it.', 'updraftplus' ) . '</strong></a><br>';
1996
+ }
1997
+ }
1998
+ }
1999
+ }
2000
+ echo '</div>'; //close the updraft_restore_progress div even if we error
2001
+ restore_error_handler();
2002
+
2003
+ return $val;
2004
+ } elseif ( false === $val ) {
2005
+ echo '</div>'; //close the updraft_restore_progress div even if we error
2006
+ restore_error_handler();
2007
+
2008
+ return false;
2009
+ }
2010
+ unset( $files[ $fkey ] );
2011
+ }
2012
+ unset( $second_loop[ $type ] );
2013
+ }
2014
+
2015
+ foreach ( array( 'template', 'stylesheet', 'template_root', 'stylesheet_root' ) as $opt ) {
2016
+ add_filter( 'pre_option_' . $opt, array( $this, 'option_filter_' . $opt ) );
2017
+ }
2018
+
2019
+ # Clear any cached pages after the restore
2020
+ $updraftplus_restorer->clear_cache();
2021
+
2022
+ if ( ! function_exists( 'validate_current_theme' ) ) {
2023
+ require_once( ABSPATH . WPINC . '/themes' );
2024
+ }
2025
+
2026
+ # Have seen a case where the current theme in the DB began with a capital, but not on disk - and this breaks migrating from Windows to a case-sensitive system
2027
+ $template = get_option( 'template' );
2028
+ echo esc_html( $template );
2029
+ if ( ! empty( $template ) && WP_DEFAULT_THEME !== $template && strtolower( $template ) !== $template ) {
2030
+
2031
+ $theme_root = get_theme_root( $template );
2032
+ $theme_root2 = get_theme_root( strtolower( $template ) );
2033
+
2034
+ if ( ! file_exists( "$theme_root/$template/style.css" ) && file_exists( "$theme_root/" . strtolower( $template ) . '/style.css' ) ) {
2035
+ $updraftplus->log_e( 'Theme directory (%s) not found, but lower-case version exists; updating database option accordingly', $template );
2036
+ update_option( 'template', strtolower( $template ) );
2037
+ }
2038
+ }
2039
+
2040
+ if ( ! validate_current_theme() ) {
2041
+ global $updraftplus;
2042
+ echo '<strong>';
2043
+ $updraftplus->log_e( 'The current theme was not found; to prevent this stopping the site from loading, your theme has been reverted to the default theme' );
2044
+ echo '</strong>';
2045
+ }
2046
+ #foreach (array('template', 'stylesheet', 'template_root', 'stylesheet_root') as $opt) {
2047
+ # remove_filter('pre_option_'.$opt, array($this, 'option_filter_'.$opt));
2048
+ #}
2049
+
2050
+ echo '</div>'; //close the updraft_restore_progress div
2051
+
2052
+ restore_error_handler();
2053
+
2054
+ return true;
2055
+ }
2056
+
2057
+
2058
+ public function option_filter_template( $val ) {
2059
+ global $updraftplus;
2060
+
2061
+ return $updraftplus->option_filter_get( 'template' );
2062
+ }
2063
+
2064
+ public function option_filter_stylesheet( $val ) {
2065
+ global $updraftplus;
2066
+
2067
+ return $updraftplus->option_filter_get( 'stylesheet' );
2068
+ }
2069
+
2070
+ public function option_filter_template_root( $val ) {
2071
+ global $updraftplus;
2072
+
2073
+ return $updraftplus->option_filter_get( 'template_root' );
2074
+ }
2075
+
2076
+ public function option_filter_stylesheet_root( $val ) {
2077
+ global $updraftplus;
2078
+
2079
+ return $updraftplus->option_filter_get( 'stylesheet_root' );
2080
+ }
2081
+
2082
+
2083
+ private function print_delete_old_dirs_form() {
2084
+ echo '<a href="#" class="button-primary" onclick="event.preventDefault(); mainwp_updraft_delete_old_dirs();">' . esc_html__( 'Delete Old Directories', 'updraftplus' ) . '</a>';
2085
+ }
2086
+
2087
+ private function delete_old_dirs_go( $show_return = true ) {
2088
+ ob_start();
2089
+
2090
+ echo ( $show_return ) ? '<h1>UpdraftPlus - ' . esc_html__( 'Remove old directories', 'updraftplus' ) . '</h1>' : '<h2>' . esc_html__( 'Remove old directories', 'updraftplus' ) . '</h2>';
2091
+ $deleted = 0;
2092
+ if ( $this->delete_old_dirs() ) {
2093
+ echo '<p>' . esc_html__( 'Old directories successfully removed.', 'updraftplus' ) . '</p>';
2094
+ echo '<p>' . esc_html__( 'Now press Restore again to proceed.', 'updraftplus' ) . '</p><br/>';
2095
+ $deleted = 1;
2096
+ } else {
2097
+ echo '<p>', esc_html__( 'Old directory removal failed for some reason. You may want to do this manually.', 'updraftplus' ) . '</p><br/>';
2098
+ }
2099
+ //if ($show_return) echo '<b>'.__('Actions','updraftplus').':</b> <a href="'.UpdraftPlus_Options::admin_page_url().'?page=updraftplus">'.__('Return to UpdraftPlus Configuration','updraftplus').'</a>';
2100
+
2101
+ $output = ob_get_clean();
2102
+
2103
+ return array( 'o' => $output, 'd' => $deleted );
2104
+ }
2105
+
2106
+ //deletes the -old directories that are created when a backup is restored.
2107
+ private function delete_old_dirs() {
2108
+ global $wp_filesystem, $updraftplus;
2109
+ $credentials = request_filesystem_credentials( wp_nonce_url( UpdraftPlus_Options::admin_page_url() . '?page=updraftplus&action=updraft_delete_old_dirs', 'updraftplus-credentialtest-nonce' ) );
2110
+ WP_Filesystem( $credentials );
2111
+ if ( $wp_filesystem->errors->get_error_code() ) {
2112
+ foreach ( $wp_filesystem->errors->get_error_messages() as $message ) {
2113
+ show_message( $message );
2114
+ }
2115
+ exit;
2116
+ }
2117
+ // From WP_CONTENT_DIR - which contains 'themes'
2118
+ $ret = $this->delete_old_dirs_dir( $wp_filesystem->wp_content_dir() );
2119
+
2120
+ $updraft_dir = $updraftplus->backups_dir_location();
2121
+ if ( $updraft_dir ) {
2122
+ $ret4 = ( $updraft_dir ) ? $this->delete_old_dirs_dir( $updraft_dir, false ) : true;
2123
+ } else {
2124
+ $ret4 = true;
2125
+ }
2126
+
2127
+ // $ret2 = $this->delete_old_dirs_dir($wp_filesystem->abspath());
2128
+ $plugs = untrailingslashit( $wp_filesystem->wp_plugins_dir() );
2129
+ if ( $wp_filesystem->is_dir( $plugs . '-old' ) ) {
2130
+ print '<strong>' . esc_html__( 'Delete', 'updraftplus' ) . ': </strong>plugins-old: ';
2131
+ if ( ! $wp_filesystem->delete( $plugs . '-old', true ) ) {
2132
+ $ret3 = false;
2133
+ print '<strong>' . esc_html__( 'Failed', 'updraftplus' ) . '</strong><br>';
2134
+ } else {
2135
+ $ret3 = true;
2136
+ print '<strong>' . esc_html__( 'OK', 'updraftplus' ) . '</strong><br>';
2137
+ }
2138
+ } else {
2139
+ $ret3 = true;
2140
+ }
2141
+
2142
+ return $ret && $ret3 && $ret4;
2143
+ }
2144
+
2145
+ private function delete_old_dirs_dir( $dir, $wpfs = true ) {
2146
+
2147
+ $dir = trailingslashit( $dir );
2148
+
2149
+ global $wp_filesystem, $updraftplus;
2150
+
2151
+ if ( $wpfs ) {
2152
+ $list = $wp_filesystem->dirlist( $dir );
2153
+ } else {
2154
+ $list = scandir( $dir );
2155
+ }
2156
+ if ( ! is_array( $list ) ) {
2157
+ return false;
2158
+ }
2159
+
2160
+ $ret = true;
2161
+ foreach ( $list as $item ) {
2162
+ $name = ( is_array( $item ) ) ? $item['name'] : $item;
2163
+ if ( '-old' == substr( $name, - 4, 4 ) ) {
2164
+ //recursively delete
2165
+ print '<strong>' . esc_html__( 'Delete', 'updraftplus' ) . ': </strong>' . htmlspecialchars( $name ) . ': ';
2166
+
2167
+ if ( $wpfs ) {
2168
+ if ( ! $wp_filesystem->delete( $dir . $name, true ) ) {
2169
+ $ret = false;
2170
+ echo '<strong>' . esc_html__( 'Failed', 'updraftplus' ) . '</strong><br>';
2171
+ } else {
2172
+ echo '<strong>' . esc_html__( 'OK', 'updraftplus' ) . '</strong><br>';
2173
+ }
2174
+ } else {
2175
+ if ( $updraftplus->remove_local_directory( $dir . $name ) ) {
2176
+ echo '<strong>' . esc_html__( 'OK', 'updraftplus' ) . '</strong><br>';
2177
+ } else {
2178
+ $ret = false;
2179
+ echo '<strong>' . esc_html__( 'Failed', 'updraftplus' ) . '</strong><br>';
2180
+ }
2181
+ }
2182
+ }
2183
+ }
2184
+
2185
+ return $ret;
2186
+ }
2187
+
2188
+
2189
+ public function show_admin_warning( $message, $class = 'updated' ) {
2190
+ echo '<div class="updraftmessage ' . $class . '">' . "<p>$message</p></div>";
2191
+ }
2192
+
2193
+ private function analyse_db_file( $timestamp, $res, $db_file = false, $header_only = false ) {
2194
+
2195
+ $mess = array();
2196
+ $warn = array();
2197
+ $err = array();
2198
+ $info = array();
2199
+
2200
+ global $updraftplus, $wp_version;
2201
+ include( ABSPATH . WPINC . '/version.php' );
2202
+
2203
+ $updraft_dir = $updraftplus->backups_dir_location();
2204
+
2205
+ if ( false === $db_file ) {
2206
+ # This attempts to raise the maximum packet size. This can't be done within the session, only globally. Therefore, it has to be done before the session starts; in our case, during the pre-analysis.
2207
+ $updraftplus->get_max_packet_size();
2208
+
2209
+ if (method_exists($updraftplus, 'get_backup_history')) {
2210
+ $backup = $updraftplus->get_backup_history($timestamp);
2211
+ } else if (class_exists('UpdraftPlus_Backup_History')) {
2212
+ $backup = UpdraftPlus_Backup_History::get_history($timestamp);
2213
+ }
2214
+
2215
+ if ( ! isset( $backup['nonce'] ) || ! isset( $backup['db'] ) ) {
2216
+ return array( $mess, $warn, $err, $info );
2217
+ }
2218
+
2219
+ $db_file = ( is_string( $backup['db'] ) ) ? $updraft_dir . '/' . $backup['db'] : $updraft_dir . '/' . $backup['db'][0];
2220
+ }
2221
+
2222
+ if ( ! is_readable( $db_file ) ) {
2223
+ return array( $mess, $warn, $err, $info );
2224
+ }
2225
+
2226
+ // Encrypted - decrypt it
2227
+ if ( $updraftplus->is_db_encrypted( $db_file ) ) {
2228
+
2229
+ $encryption = empty( $res['updraft_encryptionphrase'] ) ? UpdraftPlus_Options::get_updraft_option( 'updraft_encryptionphrase' ) : $res['updraft_encryptionphrase'];
2230
+
2231
+ if ( ! $encryption ) {
2232
+ if ( class_exists( 'UpdraftPlus_Addon_MoreDatabase' ) ) {
2233
+ $err[] = sprintf( __( 'Error: %s', 'updraftplus' ), __( 'Decryption failed. The database file is encrypted, but you have no encryption key entered.', 'updraftplus' ) );
2234
+ } else {
2235
+ $err[] = sprintf( __( 'Error: %s', 'updraftplus' ), __( 'Decryption failed. The database file is encrypted.', 'updraftplus' ) );
2236
+ }
2237
+
2238
+ return array( $mess, $warn, $err, $info );
2239
+ }
2240
+
2241
+ $ciphertext = $updraftplus->decrypt( $db_file, $encryption );
2242
+
2243
+ if ( $ciphertext ) {
2244
+ $new_db_file = $updraft_dir . '/' . basename( $db_file, '.crypt' );
2245
+ if ( ! file_put_contents( $new_db_file, $ciphertext ) ) {
2246
+ $err[] = __( 'Failed to write out the decrypted database to the filesystem.', 'updraftplus' );
2247
+
2248
+ return array( $mess, $warn, $err, $info );
2249
+ }
2250
+ $db_file = $new_db_file;
2251
+ } else {
2252
+ $err[] = __( 'Decryption failed. The most likely cause is that you used the wrong key.', 'updraftplus' );
2253
+
2254
+ return array( $mess, $warn, $err, $info );
2255
+ }
2256
+ }
2257
+
2258
+ # Even the empty schema when gzipped comes to 1565 bytes; a blank WP 3.6 install at 5158. But we go low, in case someone wants to share single tables.
2259
+ if ( filesize( $db_file ) < 1000 ) {
2260
+ $err[] = sprintf( __( 'The database is too small to be a valid WordPress database (size: %s Kb).', 'updraftplus' ), round( filesize( $db_file ) / 1024, 1 ) );
2261
+
2262
+ return array( $mess, $warn, $err, $info );
2263
+ }
2264
+
2265
+ $is_plain = ( '.gz' === substr( $db_file, - 3, 3 ) ) ? false : true;
2266
+
2267
+ $dbhandle = ( $is_plain ) ? fopen( $db_file, 'r' ) : $this->gzopen_for_read( $db_file, $warn, $err );
2268
+ if ( ! is_resource( $dbhandle ) ) {
2269
+ $err[] = __( 'Failed to open database file.', 'updraftplus' );
2270
+
2271
+ return array( $mess, $warn, $err, $info );
2272
+ }
2273
+
2274
+ # Analyse the file, print the results.
2275
+
2276
+ $line = 0;
2277
+ $old_siteurl = '';
2278
+ $old_home = '';
2279
+ $old_table_prefix = '';
2280
+ $old_siteinfo = array();
2281
+ $gathering_siteinfo = true;
2282
+ $old_wp_version = '';
2283
+ $old_php_version = '';
2284
+
2285
+ $tables_found = array();
2286
+
2287
+ // TODO: If the backup is the right size/checksum, then we could restore the $line <= 100 in the 'while' condition and not bother scanning the whole thing? Or better: sort the core tables to be first so that this usually terminates early
2288
+
2289
+ $wanted_tables = array(
2290
+ 'terms',
2291
+ 'term_taxonomy',
2292
+ 'term_relationships',
2293
+ 'commentmeta',
2294
+ 'comments',
2295
+ 'links',
2296
+ 'options',
2297
+ 'postmeta',
2298
+ 'posts',
2299
+ 'users',
2300
+ 'usermeta',
2301
+ );
2302
+
2303
+ $migration_warning = false;
2304
+
2305
+ # Don't set too high - we want a timely response returned to the browser
2306
+ @set_time_limit( 90 );
2307
+
2308
+ while ( ( ( $is_plain && ! feof( $dbhandle ) ) || ( ! $is_plain && ! gzeof( $dbhandle ) ) ) && ( $line < 100 || ( ! $header_only && count( $wanted_tables ) > 0 ) ) ) {
2309
+ $line ++;
2310
+ // Up to 1Mb
2311
+ $buffer = ( $is_plain ) ? rtrim( fgets( $dbhandle, 1048576 ) ) : rtrim( gzgets( $dbhandle, 1048576 ) );
2312
+ // Comments are what we are interested in
2313
+ if ( '#' === substr( $buffer, 0, 1 ) ) {
2314
+ if ( '' === $old_siteurl && preg_match( '/^\# Backup of: (http(.*))$/', $buffer, $matches ) ) {
2315
+ $old_siteurl = untrailingslashit( $matches[1] );
2316
+ $mess[] = __( 'Backup of:', 'updraftplus' ) . ' ' . htmlspecialchars( $old_siteurl ) . ( ( ! empty( $old_wp_version ) ) ? ' ' . sprintf( __( '(version: %s)', 'updraftplus' ), $old_wp_version ) : '' );
2317
+ // Check for should-be migration
2318
+ if ( ! $migration_warning && untrailingslashit( site_url() ) !== $old_siteurl ) {
2319
+ $migration_warning = true;
2320
+ $powarn = apply_filters( 'updraftplus_dbscan_urlchange', sprintf( __( 'Warning: %s', 'updraftplus' ), '<a href="http://updraftplus.com/shop/migrator/">' . __( 'This backup set is from a different site - this is not a restoration, but a migration. You need the Migrator add-on in order to make this work.', 'updraftplus' ) . '</a>' ), $old_siteurl, $res );
2321
+ if ( ! empty( $powarn ) ) {
2322
+ $warn[] = $powarn;
2323
+ }
2324
+ }
2325
+ } elseif ( '' === $old_home && preg_match( '/^\# Home URL: (http(.*))$/', $buffer, $matches ) ) {
2326
+ $old_home = untrailingslashit( $matches[1] );
2327
+ // Check for should-be migration
2328
+ if ( ! $migration_warning && home_url() !== $old_home ) {
2329
+ $migration_warning = true;
2330
+ $powarn = apply_filters( 'updraftplus_dbscan_urlchange', sprintf( __( 'Warning: %s', 'updraftplus' ), '<a href="http://updraftplus.com/shop/migrator/">' . __( 'This backup set is from a different site - this is not a restoration, but a migration. You need the Migrator add-on in order to make this work.', 'updraftplus' ) . '</a>' ), $old_home, $res );
2331
+ if ( ! empty( $powarn ) ) {
2332
+ $warn[] = $powarn;
2333
+ }
2334
+ }
2335
+ } elseif ( '' === $old_wp_version && preg_match( '/^\# WordPress Version: ([0-9]+(\.[0-9]+)+)(-[-a-z0-9]+,)?(.*)$/', $buffer, $matches ) ) {
2336
+ $old_wp_version = $matches[1];
2337
+ if ( ! empty( $matches[3] ) ) {
2338
+ $old_wp_version .= substr( $matches[3], 0, strlen( $matches[3] ) - 1 );
2339
+ }
2340
+ if ( version_compare( $old_wp_version, $wp_version, '>' ) ) {
2341
+ //$mess[] = sprintf(__('%s version: %s', 'updraftplus'), 'WordPress', $old_wp_version);
2342
+ $warn[] = sprintf( __( 'You are importing from a newer version of WordPress (%s) into an older one (%s). There are no guarantees that WordPress can handle this.', 'updraftplus' ), $old_wp_version, $wp_version );
2343
+ }
2344
+ if ( preg_match( '/running on PHP ([0-9]+\.[0-9]+)(\s|\.)/', $matches[4], $nmatches ) && preg_match( '/^([0-9]+\.[0-9]+)(\s|\.)/', PHP_VERSION, $cmatches ) ) {
2345
+ $old_php_version = $nmatches[1];
2346
+ $current_php_version = $cmatches[1];
2347
+ if ( version_compare( $old_php_version, $current_php_version, '>' ) ) {
2348
+ //$mess[] = sprintf(__('%s version: %s', 'updraftplus'), 'WordPress', $old_wp_version);
2349
+ $warn[] = sprintf( __( 'The site in this backup was running on a webserver with version %s of %s. ', 'updraftplus' ), $old_php_version, 'PHP' ) . ' ' . sprintf( __( 'This is significantly newer than the server which you are now restoring onto (version %s).', 'updraftplus' ), PHP_VERSION ) . ' ' . sprintf( __( 'You should only proceed if you cannot update the current server and are confident (or willing to risk) that your plugins/themes/etc. are compatible with the older %s version.', 'updraftplus' ), 'PHP' ) . ' ' . sprintf( __( 'Any support requests to do with %s should be raised with your web hosting company.', 'updraftplus' ), 'PHP' );
2350
+ }
2351
+ }
2352
+ } elseif ( '' === $old_table_prefix && ( preg_match( '/^\# Table prefix: (\S+)$/', $buffer, $matches ) || preg_match( '/^-- Table prefix: (\S+)$/i', $buffer, $matches ) ) ) {
2353
+ $old_table_prefix = $matches[1];
2354
+ // echo '<strong>'.__('Old table prefix:', 'updraftplus').'</strong> '.htmlspecialchars($old_table_prefix).'<br>';
2355
+ } elseif ( empty( $info['label'] ) && preg_match( '/^\# Label: (.*)$/', $buffer, $matches ) ) {
2356
+ $info['label'] = $matches[1];
2357
+ $mess[] = __( 'Backup label:', 'updraftplus' ) . ' ' . htmlspecialchars( $info['label'] );
2358
+ } elseif ( $gathering_siteinfo && preg_match( '/^\# Site info: (\S+)$/', $buffer, $matches ) ) {
2359
+ if ( 'end' === $matches[1] ) {
2360
+ $gathering_siteinfo = false;
2361
+ // Sanity checks
2362
+ if ( isset( $old_siteinfo['multisite'] ) && ! $old_siteinfo['multisite'] && is_multisite() ) {
2363
+ // Just need to check that you're crazy
2364
+ if ( ! defined( 'UPDRAFTPLUS_EXPERIMENTAL_IMPORTINTOMULTISITE' ) || true !== UPDRAFTPLUS_EXPERIMENTAL_IMPORTINTOMULTISITE ) {
2365
+ $err[] = sprintf( __( 'Error: %s', 'updraftplus' ), __( 'You are running on WordPress multisite - but your backup is not of a multisite site.', 'updraftplus' ) );
2366
+
2367
+ return array( $mess, $warn, $err, $info );
2368
+ }
2369
+ // Got the needed code?
2370
+ if ( ! class_exists( 'UpdraftPlusAddOn_MultiSite' ) || ! class_exists( 'UpdraftPlus_Addons_Migrator' ) ) {
2371
+ $err[] = sprintf( __( 'Error: %s', 'updraftplus' ), __( 'To import an ordinary WordPress site into a multisite installation requires both the multisite and migrator add-ons.', 'updraftplus' ) );
2372
+
2373
+ return array( $mess, $warn, $err, $info );
2374
+ }
2375
+ } elseif ( isset( $old_siteinfo['multisite'] ) && $old_siteinfo['multisite'] && ! is_multisite() ) {
2376
+ $warn[] = __( 'Warning:', 'updraftplus' ) . ' ' . __( 'Your backup is of a WordPress multisite install; but this site is not. Only the first site of the network will be accessible.', 'updraftplus' ) . ' <a href="http://codex.wordpress.org/Create_A_Network">' . __( 'If you want to restore a multisite backup, you should first set up your WordPress installation as a multisite.', 'updraftplus' ) . '</a>';
2377
+ }
2378
+ } elseif ( preg_match( '/^([^=]+)=(.*)$/', $matches[1], $kvmatches ) ) {
2379
+ $key = $kvmatches[1];
2380
+ $val = $kvmatches[2];
2381
+ if ( 'multisite' === $key && $val ) {
2382
+ $mess[] = '<strong>' . __( 'Site information:', 'updraftplus' ) . '</strong> is a WordPress Network';
2383
+ }
2384
+ $old_siteinfo[ $key ] = $val;
2385
+ }
2386
+ }
2387
+ } elseif ( preg_match( '/^\s*create table \`?([^\`\(]*)\`?\s*\(/i', $buffer, $matches ) ) {
2388
+ $table = $matches[1];
2389
+ $tables_found[] = $table;
2390
+ if ( $old_table_prefix ) {
2391
+ // Remove prefix
2392
+ $table = $updraftplus->str_replace_once( $old_table_prefix, '', $table );
2393
+ if ( in_array( $table, $wanted_tables ) ) {
2394
+ $wanted_tables = array_diff( $wanted_tables, array( $table ) );
2395
+ }
2396
+ }
2397
+ }
2398
+ }
2399
+
2400
+ if ( $is_plain ) {
2401
+ @fclose( $dbhandle );
2402
+ } else {
2403
+ @gzclose( $dbhandle );
2404
+ }
2405
+
2406
+ $missing_tables = array();
2407
+ if ( $old_table_prefix ) {
2408
+ if ( ! $header_only ) {
2409
+ foreach ( $wanted_tables as $table ) {
2410
+ if ( ! in_array( $old_table_prefix . $table, $tables_found ) ) {
2411
+ $missing_tables[] = $table;
2412
+ }
2413
+ }
2414
+ if ( count( $missing_tables ) > 0 ) {
2415
+ $warn[] = sprintf( __( 'This database backup is missing core WordPress tables: %s', 'updraftplus' ), implode( ', ', $missing_tables ) );
2416
+ }
2417
+ }
2418
+ } else {
2419
+ if ( empty( $backup['meta_foreign'] ) ) {
2420
+ $warn[] = __( 'UpdraftPlus was unable to find the table prefix when scanning the database backup.', 'updraftplus' );
2421
+ }
2422
+ }
2423
+
2424
+ return array( $mess, $warn, $err, $info );
2425
+
2426
+ }
2427
+
2428
+
2429
+ private function gzopen_for_read( $file, &$warn, &$err ) {
2430
+ if ( ! function_exists( 'gzopen' ) || ! function_exists( 'gzread' ) ) {
2431
+ $missing = '';
2432
+ if ( ! function_exists( 'gzopen' ) ) {
2433
+ $missing .= 'gzopen';
2434
+ }
2435
+ if ( ! function_exists( 'gzread' ) ) {
2436
+ $missing .= ( $missing ) ? ', gzread' : 'gzread';
2437
+ }
2438
+ $err[] = sprintf( __( "Your web server's PHP installation has these functions disabled: %s.", 'updraftplus' ), $missing ) . ' ' . sprintf( __( 'Your hosting company must enable these functions before %s can work.', 'updraftplus' ), __( 'restoration', 'updraftplus' ) );
2439
+
2440
+ return false;
2441
+ }
2442
+ if ( false === ( $dbhandle = gzopen( $file, 'r' ) ) ) {
2443
+ return false;
2444
+ }
2445
+
2446
+ if ( ! function_exists( 'gzseek' ) ) {
2447
+ return $dbhandle;
2448
+ }
2449
+
2450
+ if ( false === ( $bytes = gzread( $dbhandle, 3 ) ) ) {
2451
+ return false;
2452
+ }
2453
+ # Double-gzipped?
2454
+ if ( 'H4sI' !== base64_encode( $bytes ) ) {
2455
+ if ( 0 === gzseek( $dbhandle, 0 ) ) {
2456
+ return $dbhandle;
2457
+ } else {
2458
+ @gzclose( $dbhandle );
2459
+
2460
+ return gzopen( $file, 'r' );
2461
+ }
2462
+ }
2463
+ # Yes, it's double-gzipped
2464
+
2465
+ $what_to_return = false;
2466
+ $mess = __( 'The database file appears to have been compressed twice - probably the website you downloaded it from had a mis-configured webserver.', 'updraftplus' );
2467
+ $messkey = 'doublecompress';
2468
+ $err_msg = '';
2469
+
2470
+ if ( false === ( $fnew = fopen( $file . '.tmp', 'w' ) ) || ! is_resource( $fnew ) ) {
2471
+
2472
+ @gzclose( $dbhandle );
2473
+ $err_msg = __( 'The attempt to undo the double-compression failed.', 'updraftplus' );
2474
+
2475
+ } else {
2476
+
2477
+ @fwrite( $fnew, $bytes );
2478
+ $emptimes = 0;
2479
+ while ( ! gzeof( $dbhandle ) ) {
2480
+ $bytes = @gzread( $dbhandle, 131072 );
2481
+ if ( empty( $bytes ) ) {
2482
+ global $updraftplus;
2483
+ $emptimes ++;
2484
+ $updraftplus->log( "Got empty gzread ($emptimes times)" );
2485
+ if ( $emptimes > 2 ) {
2486
+ break;
2487
+ }
2488
+ } else {
2489
+ @fwrite( $fnew, $bytes );
2490
+ }
2491
+ }
2492
+
2493
+ gzclose( $dbhandle );
2494
+ fclose( $fnew );
2495
+ # On some systems (all Windows?) you can't rename a gz file whilst it's gzopened
2496
+ if ( ! rename( $file . '.tmp', $file ) ) {
2497
+ $err_msg = __( 'The attempt to undo the double-compression failed.', 'updraftplus' );
2498
+ } else {
2499
+ $mess .= ' ' . __( 'The attempt to undo the double-compression succeeded.', 'updraftplus' );
2500
+ $messkey = 'doublecompressfixed';
2501
+ $what_to_return = gzopen( $file, 'r' );
2502
+ }
2503
+ }
2504
+
2505
+ $warn[ $messkey ] = $mess;
2506
+ if ( ! empty( $err_msg ) ) {
2507
+ $err[] = $err_msg;
2508
+ }
2509
+
2510
+ return $what_to_return;
2511
+ }
2512
+
2513
+
2514
+ private function existing_backup_table( $backup_history = false ) {
2515
+
2516
+ global $updraftplus;
2517
+
2518
+ if ( false === $backup_history ) {
2519
+ $backup_history = UpdraftPlus_Options::get_updraft_option( 'updraft_backup_history' );
2520
+ }
2521
+ if ( ! is_array( $backup_history ) ) {
2522
+ $backup_history = array();
2523
+ }
2524
+ if ( empty( $backup_history ) ) {
2525
+ return '<p><em>' . __( 'You have not yet made any backups.', 'updraftplus' ) . '</em></p>';
2526
+ }
2527
+
2528
+ $updraft_dir = $updraftplus->backups_dir_location();
2529
+ $backupable_entities = $updraftplus->get_backupable_file_entities( true, true );
2530
+
2531
+ $accept = apply_filters( 'updraftplus_accept_archivename', array() );
2532
+ if ( ! is_array( $accept ) ) {
2533
+ $accept = array();
2534
+ }
2535
+
2536
+ $ret = '<table style="margin-top: 20px; margin-left: 20px;">';
2537
+ $nonce_field = wp_nonce_field( 'updraftplus_download', '_wpnonce', true, false );
2538
+
2539
+ //".__('Actions', 'updraftplus')."
2540
+ $ret .= '<thead>
2541
+ <tr style="margin-bottom: 4px;">
2542
+ <th style="padding:0px 10px 6px; width: 172px;">' . __( 'Backup date', 'updraftplus' ) . '</th>
2543
+ <th style="padding:0px 16px 6px; width: 426px;">' . __( 'Backup data (click to download)', 'updraftplus' ) . '</th>
2544
+ <th style="padding:0px 0px 6px 1px; width: 272px;">' . __( 'Actions', 'updraftplus' ) . '</th>
2545
+ </tr>
2546
+ <tr style="height:2px; padding:1px; margin:0px;">
2547
+ <td colspan="4" style="margin:0; padding:0"><div style="height: 2px; background-color:#888888;">&nbsp;</div></td>
2548
+ </tr>
2549
+ </thead>
2550
+ <tbody>';
2551
+ // $ret .= "<thead>
2552
+ // </thead>
2553
+ // <tbody>";
2554
+
2555
+ krsort( $backup_history );
2556
+ foreach ( $backup_history as $key => $backup ) {
2557
+
2558
+ # https://core.trac.wordpress.org/ticket/25331 explains why the following line is wrong
2559
+ # $pretty_date = date_i18n('Y-m-d G:i',$key);
2560
+ // Convert to blog time zone
2561
+ // $pretty_date = get_date_from_gmt(gmdate('Y-m-d H:i:s', (int)$key), 'Y-m-d G:i');
2562
+ $pretty_date = get_date_from_gmt( gmdate( 'Y-m-d H:i:s', (int) $key ), 'M d, Y G:i' );
2563
+
2564
+ $esc_pretty_date = esc_attr( $pretty_date );
2565
+ $entities = '';
2566
+
2567
+ $non = $backup['nonce'];
2568
+ $rawbackup = "<h2>$esc_pretty_date ($key)</h2><pre><p>" . esc_attr( print_r( $backup, true ) );
2569
+ if ( ! empty( $non ) ) {
2570
+ $jd = $updraftplus->jobdata_getarray( $non );
2571
+ if ( ! empty( $jd ) && is_array( $jd ) ) {
2572
+ $rawbackup .= '</p><p>' . esc_attr( print_r( $jd, true ) );
2573
+ }
2574
+ }
2575
+ $rawbackup .= '</p></pre>';
2576
+
2577
+ $jobdata = $updraftplus->jobdata_getarray( $non );
2578
+
2579
+ $delete_button = $this->delete_button( $key, $non, $backup );
2580
+
2581
+ $date_label = $this->date_label( $pretty_date, $key, $backup, $jobdata, $non );
2582
+
2583
+ $ret .= <<<ENDHERE
2584
+ <tr id="updraft_existing_backups_row_$key">
2585
+
2586
+ <td style="max-width: 140px;" class="updraft_existingbackup_date" data-rawbackup="$rawbackup">
2587
+ $date_label
2588
+ </td>
2589
+ ENDHERE;
2590
+
2591
+ $ret .= '<td>';
2592
+ if ( empty( $backup['meta_foreign'] ) || ! empty( $accept[ $backup['meta_foreign'] ]['separatedb'] ) ) {
2593
+
2594
+ if ( isset( $backup['db'] ) ) {
2595
+ $entities .= '/db=0/';
2596
+
2597
+ // Set a flag according to whether or not $backup['db'] ends in .crypt, then pick this up in the display of the decrypt field.
2598
+ $db = is_array( $backup['db'] ) ? $backup['db'][0] : $backup['db'];
2599
+ if ( $updraftplus->is_db_encrypted( $db ) ) {
2600
+ $entities .= '/dbcrypted=1/';
2601
+ }
2602
+
2603
+ $ret .= $this->download_db_button( 'db', $key, $esc_pretty_date, $nonce_field, $backup, $accept );
2604
+ } else {
2605
+ // $ret .= sprintf(_x('(No %s)','Message shown when no such object is available','updraftplus'), __('database', 'updraftplus'));
2606
+ }
2607
+
2608
+ # External databases
2609
+ foreach ( $backup as $bkey => $binfo ) {
2610
+ if ( 'db' === $bkey || 'db' !== substr( $bkey, 0, 2 ) || '-size' === substr( $bkey, - 5, 5 ) ) {
2611
+ continue;
2612
+ }
2613
+ $ret .= $this->download_db_button( $bkey, $key, $esc_pretty_date, $nonce_field, $backup );
2614
+ }
2615
+ } else {
2616
+ # Foreign without separate db
2617
+ $entities = '/db=0/meta_foreign=1/';
2618
+ }
2619
+
2620
+ if ( ! empty( $backup['meta_foreign'] ) && ! empty( $accept[ $backup['meta_foreign'] ] ) && ! empty( $accept[ $backup['meta_foreign'] ]['separatedb'] ) ) {
2621
+ $entities .= '/meta_foreign=2/';
2622
+ }
2623
+
2624
+ $download_buttons = $this->download_buttons( $backup, $key, $accept, $entities, $esc_pretty_date, $nonce_field );
2625
+
2626
+ $ret .= $download_buttons;
2627
+
2628
+ // $ret .="</td>";
2629
+
2630
+ // No logs expected for foreign backups
2631
+ if ( empty( $backup['meta_foreign'] ) ) {
2632
+ // $ret .= '<td>';
2633
+ // $ret .= $this->log_button($backup);
2634
+ // $ret .= "</td>";
2635
+ }
2636
+
2637
+ $ret .= '</td>';
2638
+
2639
+ $ret .= '<td style="padding: 1px; margin:0px;">';
2640
+ $ret .= $this->restore_button( $backup, $key, $pretty_date, $entities );
2641
+ $ret .= $delete_button;
2642
+ if ( empty( $backup['meta_foreign'] ) ) {
2643
+ $ret .= $this->log_button( $backup );
2644
+ }
2645
+ $ret .= '</td>';
2646
+
2647
+ $ret .= '</tr>';
2648
+
2649
+ $ret .= '<tr style="height:2px; padding:1px; margin:0px;"><td colspan="4" style="margin:0; padding:0"><div style="height: 2px; background-color:#aaaaaa;">&nbsp;</div></td></tr>';
2650
+
2651
+ }
2652
+
2653
+ $ret .= '</tbody></table>';
2654
+
2655
+ return $ret;
2656
+ }
2657
+
2658
+ private function restore_button( $backup, $key, $pretty_date, $entities ) {
2659
+ $ret = <<<ENDHERE
2660
+ <div style="float:left; clear:none; margin-right: 6px;">
2661
+ <form method="post" action="">
2662
+ <input type="hidden" name="backup_timestamp" value="$key">
2663
+ <input type="hidden" name="action" value="mainwp_updraft_restore" />
2664
+ ENDHERE;
2665
+ if ( $entities ) {
2666
+ $show_data = $pretty_date;
2667
+ if ( isset( $backup['native'] ) && false === $backup['native'] ) {
2668
+ $show_data .= ' ' . __( '(backup set imported from remote storage)', 'updraftplus' );
2669
+ }
2670
+ # jQuery('#updraft_restore_label_wpcore').html('".esc_js($wpcore_restore_descrip)."');
2671
+ $ret .= '<button title="' . __( 'After pressing this button, you will be given the option to choose which components you wish to restore', 'updraftplus' ) . '" type="button" class="button-primary" onclick="' . "mainwp_updraft_restore_setoptions('$entities', this);
2672
+ jQuery('#updraft_restore_timestamp').val('$key'); jQuery('.updraft_restore_date').html('$show_data'); ";
2673
+ $ret .= "mwp_updraft_restore_stage = 1; jQuery('#mwp-updraft-restore-modal').dialog('open'); jQuery('#mwp-updraft-restore-modal-stage1').show();jQuery('#mwp-updraft-restore-modal-stage2').hide(); jQuery('#mwp-updraft-restore-modal-stage2a').html(''); mainwp_updraft_activejobs_update(true);\">" . __( 'Restore', 'updraftplus' ) . '</button>';
2674
+ }
2675
+ $ret .= "</form></div>\n";
2676
+
2677
+ return $ret;
2678
+ }
2679
+
2680
+
2681
+ private function delete_button( $key, $nonce, $backup ) {
2682
+ $sval = ( ( isset( $backup['service'] ) && 'email' !== $backup['service'] && 'none' !== $backup['service'] ) ) ? '1' : '0';
2683
+
2684
+ return '<a style="float:left;margin-right:6px" class="mainwp-button-red button-primary button" href="#" onclick="event.preventDefault();' . "mainwp_updraft_delete('$key', '$nonce', $sval,this);" . '" title="' . esc_attr( __( 'Delete this backup set', 'updraftplus' ) ) . '">' . __( 'Delete', 'updraftplus' ) . '</a>';
2685
+ }
2686
+
2687
+ private function date_label( $pretty_date, $key, $backup, $jobdata, $nonce ) {
2688
+ $ret = apply_filters( 'updraftplus_showbackup_date', $pretty_date, $backup, $jobdata, (int) $key, false );
2689
+ if ( is_array( $jobdata ) && ! empty( $jobdata['resume_interval'] ) && ( empty( $jobdata['jobstatus'] ) || 'finished' !== $jobdata['jobstatus'] ) ) {
2690
+ $ret .= apply_filters( 'updraftplus_msg_unfinishedbackup', '<br><span title="' . esc_attr( __( 'If you are seeing more backups than you expect, then it is probably because the deletion of old backup sets does not happen until a fresh backup completes.', 'updraftplus' ) ) . '">' . __( '(Not finished)', 'updraftplus' ) . '</span>', $jobdata, $nonce );
2691
+ }
2692
+
2693
+ return $ret;
2694
+ }
2695
+
2696
+ private function download_db_button( $bkey, $key, $esc_pretty_date, $nonce_field, $backup, $accept = array() ) {
2697
+
2698
+ if ( ! empty( $backup['meta_foreign'] ) && isset( $accept[ $backup['meta_foreign'] ] ) ) {
2699
+ $desc_source = $accept[ $backup['meta_foreign'] ]['desc'];
2700
+ } else {
2701
+ $desc_source = __( 'unknown source', 'updraftplus' );
2702
+ }
2703
+
2704
+ $ret = '';
2705
+
2706
+ if ( 'db' === $bkey ) {
2707
+ $dbt = empty( $backup['meta_foreign'] ) ? esc_attr( __( 'Database', 'updraftplus' ) ) : esc_attr( sprintf( __( 'Database (created by %s)', 'updraftplus' ), $desc_source ) );
2708
+ } else {
2709
+ $dbt = __( 'External database', 'updraftplus' ) . ' (' . substr( $bkey, 2 ) . ')';
2710
+ }
2711
+
2712
+ $ret .= <<<ENDHERE
2713
+ <div style="float:left; clear: none;">
2714
+ <form id="uddownloadform_${bkey}_${key}_0" action="admin-ajax.php" onsubmit="return mainwp_updraft_downloader('uddlstatus_', $key, '$bkey', '#mwp_ud_downloadstatus', '0', '$esc_pretty_date', true, this)" method="post">
2715
+ $nonce_field
2716
+ <input type="hidden" name="action" value="mainwp_updraft_download_backup" />
2717
+ <input type="hidden" name="type" value="$bkey" />
2718
+ <input type="hidden" name="timestamp" value="$key" />
2719
+ <input type="submit" class="mwp-updraft-backupentitybutton button" value="$dbt" />
2720
+ </form>
2721
+ </div>
2722
+ ENDHERE;
2723
+
2724
+ return $ret;
2725
+ }
2726
+
2727
+ // Go through each of the file entities
2728
+ private function download_buttons( $backup, $key, $accept, &$entities, $esc_pretty_date, $nonce_field ) {
2729
+ global $updraftplus;
2730
+ $ret = '';
2731
+ $backupable_entities = $updraftplus->get_backupable_file_entities( true, true );
2732
+
2733
+ $first_entity = true;
2734
+
2735
+ foreach ( $backupable_entities as $type => $info ) {
2736
+ if ( ! empty( $backup['meta_foreign'] ) && 'wpcore' !== $type ) {
2737
+ continue;
2738
+ }
2739
+
2740
+ $ide = '';
2741
+ if ( 'wpcore' === $type ) {
2742
+ $wpcore_restore_descrip = $info['description'];
2743
+ }
2744
+ if ( empty( $backup['meta_foreign'] ) ) {
2745
+ $sdescrip = preg_replace( '/ \(.*\)$/', '', $info['description'] );
2746
+ if ( strlen( $sdescrip ) > 20 && isset( $info['shortdescription'] ) ) {
2747
+ $sdescrip = $info['shortdescription'];
2748
+ }
2749
+ } else {
2750
+ $info['description'] = 'WordPress';
2751
+
2752
+ if ( isset( $accept[ $backup['meta_foreign'] ] ) ) {
2753
+ $desc_source = $accept[ $backup['meta_foreign'] ]['desc'];
2754
+ $ide .= sprintf( __( 'Backup created by: %s.', 'updraftplus' ), $accept[ $backup['meta_foreign'] ]['desc'] ) . ' ';
2755
+ } else {
2756
+ $desc_source = __( 'unknown source', 'updraftplus' );
2757
+ $ide .= __( 'Backup created by unknown source (%s) - cannot be restored.', 'updraftplus' ) . ' ';
2758
+ }
2759
+
2760
+ $sdescrip = ( empty( $accept[ $backup['meta_foreign'] ]['separatedb'] ) ) ? sprintf( __( 'Files and database WordPress backup (created by %s)', 'updraftplus' ), $desc_source ) : sprintf( __( 'Files backup (created by %s)', 'updraftplus' ), $desc_source );
2761
+ if ( 'wpcore' === $type ) {
2762
+ $wpcore_restore_descrip = $sdescrip;
2763
+ }
2764
+ }
2765
+ if ( isset( $backup[ $type ] ) ) {
2766
+ if ( ! is_array( $backup[ $type ] ) ) {
2767
+ $backup[ $type ] = array( $backup[ $type ] );
2768
+ }
2769
+ $howmanyinset = count( $backup[ $type ] );
2770
+ $expected_index = 0;
2771
+ $index_missing = false;
2772
+ $set_contents = '';
2773
+ $entities .= "/$type=";
2774
+ $whatfiles = $backup[ $type ];
2775
+ ksort( $whatfiles );
2776
+ foreach ( $whatfiles as $findex => $bfile ) {
2777
+ $set_contents .= ( '' === $set_contents ) ? $findex : ",$findex";
2778
+ if ( $findex !== $expected_index ) {
2779
+ $index_missing = true;
2780
+ }
2781
+ $expected_index ++;
2782
+ }
2783
+ $entities .= $set_contents . '/';
2784
+ if ( ! empty( $backup['meta_foreign'] ) ) {
2785
+ $entities .= '/plugins=0//themes=0//uploads=0//others=0/';
2786
+ }
2787
+ $first_printed = true;
2788
+ foreach ( $whatfiles as $findex => $bfile ) {
2789
+ $ide .= __( 'Press here to download', 'updraftplus' ) . ' ' . strtolower( $info['description'] );
2790
+ $pdescrip = ( $findex > 0 ) ? $sdescrip . ' (' . ( $findex + 1 ) . ')' : $sdescrip;
2791
+ if ( ! $first_printed ) {
2792
+ $ret .= '<div style="display:none;">';
2793
+ }
2794
+ if ( count( $backup[ $type ] ) > 0 ) {
2795
+ $ide .= ' ' . sprintf( __( '(%d archive(s) in set).', 'updraftplus' ), $howmanyinset );
2796
+ }
2797
+ if ( $index_missing ) {
2798
+ $ide .= ' ' . __( 'You appear to be missing one or more archives from this multi-archive set.', 'updraftplus' );
2799
+ }
2800
+
2801
+ if ( $first_entity ) {
2802
+ $first_entity = false;
2803
+ }
2804
+
2805
+ $ret .= $this->download_button( $type, $key, $findex, $info, $nonce_field, $ide, $pdescrip, $esc_pretty_date, $set_contents );
2806
+
2807
+ if ( ! $first_printed ) {
2808
+ $ret .= '</div>';
2809
+ } else {
2810
+ $first_printed = false;
2811
+ }
2812
+ }
2813
+ }
2814
+ }
2815
+
2816
+ return $ret;
2817
+ }
2818
+
2819
+
2820
+ private function download_button( $type, $key, $findex, $info, $nonce_field, $ide, $pdescrip, $esc_pretty_date, $set_contents ) {
2821
+ $ret = <<<ENDHERE
2822
+ <div style="float: left; clear: none;">
2823
+ <form id="uddownloadform_${type}_${key}_${findex}" action="admin-ajax.php" onsubmit="return mainwp_updraft_downloader('uddlstatus_', '$key', '$type', '#mwp_ud_downloadstatus', '$set_contents', '$esc_pretty_date', true, this)" method="post">
2824
+ $nonce_field
2825
+ <input type="hidden" name="action" value="mainwp_updraft_download_backup" />
2826
+ <input type="hidden" name="type" value="$type" />
2827
+ <input type="hidden" name="timestamp" value="$key" />
2828
+ <input type="hidden" name="findex" value="$findex" />
2829
+ <input type="submit" class="mwp-updraft-backupentitybutton button" title="$ide" value="$pdescrip" />
2830
+ </form>
2831
+ </div>
2832
+ ENDHERE;
2833
+
2834
+ return $ret;
2835
+ }
2836
+
2837
+ private function log_button( $backup ) {
2838
+ global $updraftplus;
2839
+ $updraft_dir = $updraftplus->backups_dir_location();
2840
+ $ret = '';
2841
+ if ( isset( $backup['nonce'] ) && preg_match( '/^[0-9a-f]{12}$/', $backup['nonce'] ) && is_readable( $updraft_dir . '/log.' . $backup['nonce'] . '.txt' ) ) {
2842
+ $nval = $backup['nonce'];
2843
+ $lt = esc_attr( __( 'View Log', 'updraftplus' ) );
2844
+ $url = UpdraftPlus_Options::admin_page();
2845
+ $ret .= <<<ENDHERE
2846
+ <div style="float:left; clear:none;" class="mwp-updraft-viewlogdiv">
2847
+ <form action="$url" method="get">
2848
+ <input type="hidden" name="action" value="downloadlog" />
2849
+ <input type="hidden" name="page" value="updraftplus" />
2850
+ <input type="hidden" name="updraftplus_backup_nonce" value="$nval" />
2851
+ <input type="submit" value="$lt" class="updraft-log-link button" onclick="event.preventDefault(); mainwp_updraft_popuplog('$nval', this);" />
2852
+ </form>
2853
+ </div>
2854
+ ENDHERE;
2855
+
2856
+ return $ret;
2857
+ }
2858
+ }
2859
+
2860
+ private function rebuildBackupHistory( $remotescan = false ) {
2861
+ global $updraftplus_admin, $updraftplus;
2862
+ $messages = null;
2863
+ if ( method_exists( $updraftplus, 'rebuild_backup_history' ) ) {
2864
+ $messages = $updraftplus->rebuild_backup_history( $remotescan );
2865
+ } else if ( method_exists( $updraftplus_admin, 'rebuild_backup_history' ) ) {
2866
+ $messages = $updraftplus_admin->rebuild_backup_history( $remotescan );
2867
+ }
2868
+
2869
+ return $messages;
2870
+ }
2871
+
2872
+ private function forceScheduledResumption() {
2873
+ global $updraftplus;
2874
+ // Casting $resumption to int is absolutely necessary, as the WP cron system uses a hashed serialisation of the parameters for identifying jobs. Different type => different hash => does not match
2875
+ $resumption = (int) $_REQUEST['resumption'];
2876
+ $job_id = $_REQUEST['job_id'];
2877
+ $get_cron = $this->get_cron( $job_id );
2878
+ if ( ! is_array( $get_cron ) ) {
2879
+ return array( 'r' => false );
2880
+ } else {
2881
+ $updraftplus->log( "Forcing resumption: job id=$job_id, resumption=$resumption" );
2882
+ $time = $get_cron[0];
2883
+ wp_clear_scheduled_hook( 'updraft_backup_resume', array( $resumption, $job_id ) );
2884
+ $this->close_browser_connection( array( 'r' => true ) );
2885
+ $updraftplus->jobdata_set_from_array( $get_cron[1] );
2886
+ $updraftplus->backup_resume( $resumption, $job_id );
2887
+ }
2888
+
2889
+ return array();
2890
+ }
2891
+
2892
+
2893
+ function diskspaceused() {
2894
+ global $updraftplus;
2895
+ $out = array();
2896
+ if ( 'updraft' === $_POST['entity'] ) {
2897
+ $out['diskspaceused'] = $this->recursive_directory_size( $updraftplus->backups_dir_location() );
2898
+ } else {
2899
+ $backupable_entities = $updraftplus->get_backupable_file_entities( true, false );
2900
+ if ( ! empty( $backupable_entities[ $_POST['entity'] ] ) ) {
2901
+ # Might be an array
2902
+ $basedir = $backupable_entities[ $_POST['entity'] ];
2903
+ $dirs = apply_filters( 'updraftplus_dirlist_' . $_POST['entity'], $basedir );
2904
+ $out['diskspaceused'] = $this->recursive_directory_size( $dirs, $updraftplus->get_exclude( $_POST['entity'] ), $basedir );
2905
+ } else {
2906
+ $out['error'] = 'Error';
2907
+ }
2908
+ }
2909
+
2910
+ return $out;
2911
+ }
2912
+
2913
+
2914
+ # If $basedirs is passed as an array, then $directorieses must be too
2915
+ private function recursive_directory_size( $directorieses, $exclude = array(), $basedirs = '' ) {
2916
+
2917
+ $size = 0;
2918
+
2919
+ if ( is_string( $directorieses ) ) {
2920
+ $basedirs = $directorieses;
2921
+ $directorieses = array( $directorieses );
2922
+ }
2923
+
2924
+ if ( is_string( $basedirs ) ) {
2925
+ $basedirs = array( $basedirs );
2926
+ }
2927
+
2928
+ foreach ( $directorieses as $ind => $directories ) {
2929
+ if ( ! is_array( $directories ) ) {
2930
+ $directories = array( $directories );
2931
+ }
2932
+
2933
+ $basedir = empty( $basedirs[ $ind ] ) ? $basedirs[0] : $basedirs[ $ind ];
2934
+
2935
+ foreach ( $directories as $dir ) {
2936
+ if ( is_file( $dir ) ) {
2937
+ $size += @filesize( $dir );
2938
+ } else {
2939
+ $suffix = ( '' !== $basedir ) ? ( ( 0 === strpos( $dir, $basedir . '/' ) ) ? substr( $dir, 1 + strlen( $basedir ) ) : '' ) : '';
2940
+ $size += $this->recursive_directory_size_raw( $basedir, $exclude, $suffix );
2941
+ }
2942
+ }
2943
+ }
2944
+
2945
+ if ( $size > 1073741824 ) {
2946
+ return round( $size / 1073741824, 1 ) . ' Gb';
2947
+ } elseif ( $size > 1048576 ) {
2948
+ return round( $size / 1048576, 1 ) . ' Mb';
2949
+ } elseif ( $size > 1024 ) {
2950
+ return round( $size / 1024, 1 ) . ' Kb';
2951
+ } else {
2952
+ return round( $size, 1 ) . ' b';
2953
+ }
2954
+
2955
+ }
2956
+
2957
+ private function recursive_directory_size_raw( $prefix_directory, &$exclude = array(), $suffix_directory = '' ) {
2958
+
2959
+ $directory = $prefix_directory . ( '' === $suffix_directory ? '' : '/' . $suffix_directory );
2960
+ $size = 0;
2961
+ if ( '/' === substr( $directory, - 1 ) ) {
2962
+ $directory = substr( $directory, 0, - 1 );
2963
+ }
2964
+
2965
+ if ( ! file_exists( $directory ) || ! is_dir( $directory ) || ! is_readable( $directory ) ) {
2966
+ return - 1;
2967
+ }
2968
+ if ( file_exists( $directory . '/.donotbackup' ) ) {
2969
+ return 0;
2970
+ }
2971
+
2972
+ if ( $handle = opendir( $directory ) ) {
2973
+ while ( ( $file = readdir( $handle ) ) !== false ) {
2974
+ if ( '.' !== $file && '..' !== $file ) {
2975
+ $spath = ( '' === $suffix_directory ) ? $file : $suffix_directory . '/' . $file;
2976
+ if ( false !== ( $fkey = array_search( $spath, $exclude ) ) ) {
2977
+ unset( $exclude[ $fkey ] );
2978
+ continue;
2979
+ }
2980
+ $path = $directory . '/' . $file;
2981
+ if ( is_file( $path ) ) {
2982
+ $size += filesize( $path );
2983
+ } elseif ( is_dir( $path ) ) {
2984
+ $handlesize = $this->recursive_directory_size_raw( $prefix_directory, $exclude, $suffix_directory . ( '' === $suffix_directory ? '' : '/' ) . $file );
2985
+ if ( $handlesize >= 0 ) {
2986
+ $size += $handlesize;
2987
+ }# else { return -1; }
2988
+ }
2989
+ }
2990
+ }
2991
+ closedir( $handle );
2992
+ }
2993
+
2994
+ return $size;
2995
+
2996
+ }
2997
+
2998
+
2999
+ private function get_cron( $job_id = false ) {
3000
+
3001
+ $cron = get_option( 'cron' );
3002
+ if ( ! is_array( $cron ) ) {
3003
+ $cron = array();
3004
+ }
3005
+ if ( false === $job_id ) {
3006
+ return $cron;
3007
+ }
3008
+
3009
+ foreach ( $cron as $time => $job ) {
3010
+ if ( isset( $job['updraft_backup_resume'] ) ) {
3011
+ foreach ( $job['updraft_backup_resume'] as $hook => $info ) {
3012
+ if ( isset( $info['args'][1] ) && $job_id === $info['args'][1] ) {
3013
+ global $updraftplus;
3014
+ $jobdata = $updraftplus->jobdata_getarray( $job_id );
3015
+
3016
+ return ( ! is_array( $jobdata ) ) ? false : array( $time, $jobdata );
3017
+ }
3018
+ }
3019
+ }
3020
+ }
3021
+ }
3022
+
3023
+
3024
+ // A value for $this_job_only also causes something to always be returned (to allow detection of the job having started on the front-end)
3025
+ private function print_active_jobs( $this_job_only = false ) {
3026
+ $cron = $this->get_cron();
3027
+ // $found_jobs = 0;
3028
+ $ret = '';
3029
+
3030
+ foreach ( $cron as $time => $job ) {
3031
+ if ( isset( $job['updraft_backup_resume'] ) ) {
3032
+ foreach ( $job['updraft_backup_resume'] as $hook => $info ) {
3033
+ if ( isset( $info['args'][1] ) ) {
3034
+ // $found_jobs++;
3035
+ $job_id = $info['args'][1];
3036
+ if ( false === $this_job_only || $job_id === $this_job_only ) {
3037
+ $ret .= $this->print_active_job( $job_id, false, $time, $info['args'][0] );
3038
+ }
3039
+ }
3040
+ }
3041
+ }
3042
+ }
3043
+
3044
+ // A value for $this_job_only implies that output is required
3045
+ if ( false !== $this_job_only && ! $ret ) {
3046
+ $ret = $this->print_active_job( $this_job_only );
3047
+ if ( '' === $ret ) {
3048
+ // The presence of the exact ID matters to the front-end - indicates that the backup job has at least begun
3049
+ $ret = '<div style="min-width: 480px; min-height: 48px; text-align:center;margin-top: 4px; clear:left; float:left; padding: 8px; border: 1px solid;" id="updraft-jobid-' . $this_job_only . '" class="updraft_finished"><em>' . __( 'The backup apparently succeeded and is now complete', 'updraftplus' ) . '</em></div>';
3050
+ }
3051
+ }
3052
+
3053
+ // if (0 == $found_jobs) $ret .= '<p><em>'.__('(None)', 'updraftplus').'</em></p>';
3054
+ return $ret;
3055
+ }
3056
+
3057
+ private function print_active_job( $job_id, $is_oneshot = false, $time = false, $next_resumption = false ) {
3058
+
3059
+ $ret = '';
3060
+
3061
+ global $updraftplus;
3062
+ $jobdata = $updraftplus->jobdata_getarray( $job_id );
3063
+
3064
+ if ( false === apply_filters( 'updraftplus_print_active_job_continue', true, $is_oneshot, $next_resumption, $jobdata ) ) {
3065
+ return '';
3066
+ }
3067
+
3068
+ #if (!is_array($jobdata)) $jobdata = array();
3069
+ if ( ! isset( $jobdata['backup_time'] ) ) {
3070
+ return '';
3071
+ }
3072
+
3073
+ $backupable_entities = $updraftplus->get_backupable_file_entities( true, true );
3074
+
3075
+ $began_at = ( isset( $jobdata['backup_time'] ) ) ? get_date_from_gmt( gmdate( 'Y-m-d H:i:s', (int) $jobdata['backup_time'] ), 'D, F j, Y H:i' ) : '?';
3076
+
3077
+ $jobstatus = empty( $jobdata['jobstatus'] ) ? 'unknown' : $jobdata['jobstatus'];
3078
+ $stage = 0;
3079
+ switch ( $jobstatus ) {
3080
+ # Stage 0
3081
+ case 'begun':
3082
+ $curstage = __( 'Backup begun', 'updraftplus' );
3083
+ break;
3084
+ # Stage 1
3085
+ case 'filescreating':
3086
+ $stage = 1;
3087
+ $curstage = __( 'Creating file backup zips', 'updraftplus' );
3088
+ if ( ! empty( $jobdata['filecreating_substatus'] ) && isset( $backupable_entities[ $jobdata['filecreating_substatus']['e'] ]['description'] ) ) {
3089
+
3090
+ $sdescrip = preg_replace( '/ \(.*\)$/', '', $backupable_entities[ $jobdata['filecreating_substatus']['e'] ]['description'] );
3091
+ if ( strlen( $sdescrip ) > 20 && isset( $jobdata['filecreating_substatus']['e'] ) && is_array( $jobdata['filecreating_substatus']['e'] ) && isset( $backupable_entities[ $jobdata['filecreating_substatus']['e'] ]['shortdescription'] ) ) {
3092
+ $sdescrip = $backupable_entities[ $jobdata['filecreating_substatus']['e'] ]['shortdescription'];
3093
+ }
3094
+ $curstage .= ' (' . $sdescrip . ')';
3095
+ if ( isset( $jobdata['filecreating_substatus']['i'] ) && isset( $jobdata['filecreating_substatus']['t'] ) ) {
3096
+ $stage = min( 2, 1 + ( $jobdata['filecreating_substatus']['i'] / max( $jobdata['filecreating_substatus']['t'], 1 ) ) );
3097
+ }
3098
+ }
3099
+ break;
3100
+ case 'filescreated':
3101
+ $stage = 2;
3102
+ $curstage = __( 'Created file backup zips', 'updraftplus' );
3103
+ break;
3104
+
3105
+ # Stage 4
3106
+ case 'clouduploading':
3107
+ $stage = 4;
3108
+ $curstage = __( 'Uploading files to remote storage', 'updraftplus' );
3109
+ if ( isset( $jobdata['uploading_substatus']['t'] ) && isset( $jobdata['uploading_substatus']['i'] ) ) {
3110
+ $t = max( (int) $jobdata['uploading_substatus']['t'], 1 );
3111
+ $i = min( $jobdata['uploading_substatus']['i'] / $t, 1 );
3112
+ $p = min( $jobdata['uploading_substatus']['p'], 1 );
3113
+ $pd = $i + $p / $t;
3114
+ $stage = 4 + $pd;
3115
+ $curstage .= ' ' . sprintf( __( '(%s%%, file %s of %s)', 'updraftplus' ), floor( 100 * $pd ), $jobdata['uploading_substatus']['i'] + 1, $t );
3116
+ }
3117
+ break;
3118
+ case 'pruning':
3119
+ $stage = 5;
3120
+ $curstage = __( 'Pruning old backup sets', 'updraftplus' );
3121
+ break;
3122
+ case 'resumingforerrors':
3123
+ $stage = - 1;
3124
+ $curstage = __( 'Waiting until scheduled time to retry because of errors', 'updraftplus' );
3125
+ break;
3126
+ # Stage 6
3127
+ case 'finished':
3128
+ $stage = 6;
3129
+ $curstage = __( 'Backup finished', 'updraftplus' );
3130
+ break;
3131
+ default:
3132
+
3133
+ # Database creation and encryption occupies the space from 2 to 4. Databases are created then encrypted, then the next databae is created/encrypted, etc.
3134
+ if ( 'dbcreated' === substr( $jobstatus, 0, 9 ) ) {
3135
+ $jobstatus = 'dbcreated';
3136
+ $whichdb = substr( $jobstatus, 9 );
3137
+ if ( ! is_numeric( $whichdb ) ) {
3138
+ $whichdb = 0;
3139
+ }
3140
+ $howmanydbs = max( ( empty( $jobdata['backup_database'] ) || ! is_array( $jobdata['backup_database'] ) ) ? 1 : count( $jobdata['backup_database'] ), 1 );
3141
+ $perdbspace = 2 / $howmanydbs;
3142
+
3143
+ $stage = min( 4, 2 + ( $whichdb + 2 ) * $perdbspace );
3144
+
3145
+ $curstage = __( 'Created database backup', 'updraftplus' );
3146
+
3147
+ } elseif ( 'dbcreating' === substr( $jobstatus, 0, 10 ) ) {
3148
+ $whichdb = substr( $jobstatus, 10 );
3149
+ if ( ! is_numeric( $whichdb ) ) {
3150
+ $whichdb = 0;
3151
+ }
3152
+ $howmanydbs = ( empty( $jobdata['backup_database'] ) || ! is_array( $jobdata['backup_database'] ) ) ? 1 : count( $jobdata['backup_database'] );
3153
+ $perdbspace = 2 / $howmanydbs;
3154
+ $jobstatus = 'dbcreating';
3155
+
3156
+ $stage = min( 4, 2 + $whichdb * $perdbspace );
3157
+
3158
+ $curstage = __( 'Creating database backup', 'updraftplus' );
3159
+ if ( ! empty( $jobdata['dbcreating_substatus']['t'] ) ) {
3160
+ $curstage .= ' (' . sprintf( __( 'table: %s', 'updraftplus' ), $jobdata['dbcreating_substatus']['t'] ) . ')';
3161
+ if ( ! empty( $jobdata['dbcreating_substatus']['i'] ) && ! empty( $jobdata['dbcreating_substatus']['a'] ) ) {
3162
+ $substage = max( 0.001, ( $jobdata['dbcreating_substatus']['i'] / max( $jobdata['dbcreating_substatus']['a'], 1 ) ) );
3163
+ $stage += $substage * $perdbspace * 0.5;
3164
+ }
3165
+ }
3166
+ } elseif ( 'dbencrypting' === substr( $jobstatus, 0, 12 ) ) {
3167
+ $whichdb = substr( $jobstatus, 12 );
3168
+ if ( ! is_numeric( $whichdb ) ) {
3169
+ $whichdb = 0;
3170
+ }
3171
+ $howmanydbs = ( empty( $jobdata['backup_database'] ) || ! is_array( $jobdata['backup_database'] ) ) ? 1 : count( $jobdata['backup_database'] );
3172
+ $perdbspace = 2 / $howmanydbs;
3173
+ $stage = min( 4, 2 + $whichdb * $perdbspace + $perdbspace * 0.5 );
3174
+ $jobstatus = 'dbencrypting';
3175
+ $curstage = __( 'Encrypting database', 'updraftplus' );
3176
+ } elseif ( 'dbencrypted' === substr( $jobstatus, 0, 11 ) ) {
3177
+ $whichdb = substr( $jobstatus, 11 );
3178
+ if ( ! is_numeric( $whichdb ) ) {
3179
+ $whichdb = 0;
3180
+ }
3181
+ $howmanydbs = ( empty( $jobdata['backup_database'] ) || ! is_array( $jobdata['backup_database'] ) ) ? 1 : count( $jobdata['backup_database'] );
3182
+ $jobstatus = 'dbencrypted';
3183
+ $perdbspace = 2 / $howmanydbs;
3184
+ $stage = min( 4, 2 + $whichdb * $perdbspace + $perdbspace );
3185
+ $curstage = __( 'Encrypted database', 'updraftplus' );
3186
+ } else {
3187
+ $curstage = __( 'Unknown', 'updraftplus' );
3188
+ }
3189
+ }
3190
+
3191
+ $runs_started = ( empty( $jobdata['runs_started'] ) ) ? array() : $jobdata['runs_started'];
3192
+ $time_passed = ( empty( $jobdata['run_times'] ) ) ? array() : $jobdata['run_times'];
3193
+ $last_checkin_ago = - 1;
3194
+ if ( is_array( $time_passed ) ) {
3195
+ foreach ( $time_passed as $run => $passed ) {
3196
+ if ( isset( $runs_started[ $run ] ) ) {
3197
+ $time_ago = microtime( true ) - ( $runs_started[ $run ] + $time_passed[ $run ] );
3198
+ if ( $time_ago < $last_checkin_ago || -1 === $last_checkin_ago ) {
3199
+ $last_checkin_ago = $time_ago;
3200
+ }
3201
+ }
3202
+ }
3203
+ }
3204
+
3205
+ $next_res_after = (int) $time - time();
3206
+ $next_res_txt = ( $is_oneshot ) ? '' : ' - ' . sprintf( __( 'next resumption: %d (after %ss)', 'updraftplus' ), $next_resumption, $next_res_after ) . ' ';
3207
+ $last_activity_txt = ( $last_checkin_ago >= 0 ) ? ' - ' . sprintf( __( 'last activity: %ss ago', 'updraftplus' ), floor( $last_checkin_ago ) ) . ' ' : '';
3208
+
3209
+ if ( ( $last_checkin_ago < 50 && $next_res_after > 30 ) || $is_oneshot ) {
3210
+ $show_inline_info = $last_activity_txt;
3211
+ $title_info = $next_res_txt;
3212
+ } else {
3213
+ $show_inline_info = $next_res_txt;
3214
+ $title_info = $last_activity_txt;
3215
+ }
3216
+
3217
+ // Existence of the 'updraft-jobid-(id)' id is checked for in other places, so do not modify this
3218
+ $ret .= '<div style="min-width: 480px; margin-top: 4px; clear:left; float:left; padding: 8px; border: 1px solid;" id="updraft-jobid-' . $job_id . '"><span class="updraft_jobtimings" data-jobid="' . $job_id . '" data-lastactivity="' . (int) $last_checkin_ago . '" data-nextresumption="' . $next_resumption . '" data-nextresumptionafter="' . $next_res_after . '" style="font-weight:bold;" title="' . esc_attr( sprintf( __( 'Job ID: %s', 'updraftplus' ), $job_id ) ) . $title_info . '">' . $began_at . '</span> ';
3219
+
3220
+ $ret .= $show_inline_info;
3221
+ $ret .= '- <a href="#" class="updraft-log-link" onclick="event.preventDefault(); mainwp_updraft_popuplog(\'' . $job_id . '\', this);">' . __( 'show log', 'updraftplus' ) . '</a>';
3222
+
3223
+ if ( ! $is_oneshot ) {
3224
+ $ret .= ' - <a title="' . esc_attr( __( 'Note: the progress bar below is based on stages, NOT time. Do not stop the backup simply because it seems to have remained in the same place for a while - that is normal.', 'updraftplus' ) ) . '" href="javascript:mainwp_updraft_activejobs_delete(\'' . $job_id . '\')">' . __( 'delete schedule', 'updraftplus' ) . '</a>';
3225
+ }
3226
+
3227
+ if ( ! empty( $jobdata['warnings'] ) && is_array( $jobdata['warnings'] ) ) {
3228
+ $ret .= '<ul style="list-style: disc inside;">';
3229
+ foreach ( $jobdata['warnings'] as $warning ) {
3230
+ $ret .= '<li>' . sprintf( __( 'Warning: %s', 'updraftplus' ), make_clickable( htmlspecialchars( $warning ) ) ) . '</li>';
3231
+ }
3232
+ $ret .= '</ul>';
3233
+ }
3234
+
3235
+ $ret .= '<div style="border-radius: 4px; margin-top: 8px; z-index:0; padding-top: 4px;border: 1px solid #aaa; width: 100%; height: 22px; position: relative; text-align: center; font-style: italic;">';
3236
+ $ret .= htmlspecialchars( $curstage );
3237
+ $ret .= '<div style="z-index:-1; position: absolute; left: 0px; top: 0px; text-align: center; background-color: #f6a828; height: 100%; width:' . ( ( $stage > 0 ) ? ( ceil( ( 100 / 6 ) * $stage ) ) : '0' ) . '%"></div>';
3238
+ $ret .= '</div></div>';
3239
+
3240
+ $ret .= '</div>';
3241
+
3242
+ return $ret;
3243
+
3244
+ }
3245
+
3246
+ private function fetch_updraft_log() {
3247
+ $backup_nonce = $_POST['backup_nonce'];
3248
+
3249
+ return $this->fetch_log( $backup_nonce );
3250
+ }
3251
+
3252
+ private function activejobs_delete() {
3253
+ $jobid = $_POST['jobid'];
3254
+ if ( empty( $jobid ) ) {
3255
+ return array( 'error' => 'Error: empty job id.' );
3256
+ }
3257
+
3258
+ $cron = get_option( 'cron' );
3259
+ $found_it = 0;
3260
+ foreach ( $cron as $time => $job ) {
3261
+ if ( isset( $job['updraft_backup_resume'] ) ) {
3262
+ foreach ( $job['updraft_backup_resume'] as $hook => $info ) {
3263
+ if ( isset( $info['args'][1] ) && $info['args'][1] === $jobid ) {
3264
+ $args = $cron[ $time ]['updraft_backup_resume'][ $hook ]['args'];
3265
+ wp_unschedule_event( $time, 'updraft_backup_resume', $args );
3266
+ if ( ! $found_it ) {
3267
+ return array( 'ok' => 'Y', 'm' => __( 'Job deleted', 'updraftplus' ) );
3268
+ }
3269
+ $found_it = 1;
3270
+ }
3271
+ }
3272
+ }
3273
+ }
3274
+
3275
+ if ( ! $found_it ) {
3276
+ return array(
3277
+ 'ok' => 'N',
3278
+ 'm' => __( 'Could not find that job - perhaps it has already finished?', 'updraftplus' ),
3279
+ );
3280
+ }
3281
+
3282
+ return array();
3283
+ }
3284
+
3285
+ public function fetch_log( $backup_nonce, $log_pointer = 0 ) {
3286
+ global $updraftplus;
3287
+
3288
+ if ( empty( $backup_nonce ) ) {
3289
+ list( $mod_time, $log_file, $nonce ) = $updraftplus->last_modified_log();
3290
+ } else {
3291
+ $nonce = $backup_nonce;
3292
+ }
3293
+
3294
+ if ( ! preg_match( '/^[0-9a-f]+$/', $nonce ) ) {
3295
+ return array( 'error' => 'Security check' );
3296
+ }
3297
+
3298
+ $log_content = '';
3299
+ $new_pointer = $log_pointer;
3300
+
3301
+ if ( ! empty( $nonce ) ) {
3302
+ $updraft_dir = $updraftplus->backups_dir_location();
3303
+
3304
+ $potential_log_file = $updraft_dir . '/log.' . $nonce . '.txt';
3305
+
3306
+ if ( is_readable( $potential_log_file ) ) {
3307
+
3308
+ $templog_array = array();
3309
+ $log_file = fopen( $potential_log_file, 'r' );
3310
+ if ( $log_pointer > 0 ) {
3311
+ fseek( $log_file, $log_pointer );
3312
+ }
3313
+
3314
+ while ( ( $buffer = fgets( $log_file, 4096 ) ) !== false ) {
3315
+ $templog_array[] = $buffer;
3316
+ }
3317
+ if ( ! feof( $log_file ) ) {
3318
+ $templog_array[] = __( 'Error: unexpected file read fail', 'updraftplus' );
3319
+ }
3320
+
3321
+ $new_pointer = ftell( $log_file );
3322
+ $log_content = implode( '', $templog_array );
3323
+
3324
+ } else {
3325
+ $log_content .= __( 'The log file could not be read.', 'updraftplus' );
3326
+ }
3327
+ } else {
3328
+ $log_content .= __( 'The log file could not be read.', 'updraftplus' );
3329
+ }
3330
+
3331
+ $ret_array = array(
3332
+ 'html' => $log_content,
3333
+ 'nonce' => $nonce,
3334
+ 'pointer' => $new_pointer,
3335
+ );
3336
+
3337
+ return $ret_array;
3338
+ }
3339
+
3340
+ private function download_status( $timestamp, $type, $findex ) {
3341
+ global $updraftplus;
3342
+ $response = array( 'm' => $updraftplus->jobdata_get( 'dlmessage_' . $timestamp . '_' . $type . '_' . $findex ) . '<br>' );
3343
+ if ( $file = $updraftplus->jobdata_get( 'dlfile_' . $timestamp . '_' . $type . '_' . $findex ) ) {
3344
+ if ( 'failed' === $file ) {
3345
+ $response['e'] = __( 'Download failed', 'updraftplus' ) . '<br>';
3346
+ $errs = $updraftplus->jobdata_get( 'dlerrors_' . $timestamp . '_' . $type . '_' . $findex );
3347
+ if ( is_array( $errs ) && ! empty( $errs ) ) {
3348
+ $response['e'] .= '<ul style="list-style: disc inside;">';
3349
+ foreach ( $errs as $err ) {
3350
+ if ( is_array( $err ) ) {
3351
+ $response['e'] .= '<li>' . htmlspecialchars( $err['message'] ) . '</li>';
3352
+ } else {
3353
+ $response['e'] .= '<li>' . htmlspecialchars( $err ) . '</li>';
3354
+ }
3355
+ }
3356
+ $response['e'] .= '</ul>';
3357
+ }
3358
+ } elseif ( preg_match( '/^downloaded:(\d+):(.*)$/', $file, $matches ) && file_exists( $matches[2] ) ) {
3359
+ $response['p'] = 100;
3360
+ $response['f'] = $matches[2];
3361
+ $response['s'] = (int) $matches[1];
3362
+ $response['t'] = (int) $matches[1];
3363
+ $response['m'] = __( 'File ready.', 'updraftplus' );
3364
+ } elseif ( preg_match( '/^downloading:(\d+):(.*)$/', $file, $matches ) && file_exists( $matches[2] ) ) {
3365
+ // Convert to bytes
3366
+ $response['f'] = $matches[2];
3367
+ $total_size = (int) max( $matches[1], 1 );
3368
+ $cur_size = filesize( $matches[2] );
3369
+ $response['s'] = $cur_size;
3370
+ $file_age = time() - filemtime( $matches[2] );
3371
+ if ( $file_age > 20 ) {
3372
+ $response['a'] = time() - filemtime( $matches[2] );
3373
+ }
3374
+ $response['t'] = $total_size;
3375
+ $response['m'] .= __( 'Download in progress', 'updraftplus' ) . ' (' . round( $cur_size / 1024 ) . ' / ' . round( ( $total_size / 1024 ) ) . ' Kb)';
3376
+ $response['p'] = round( 100 * $cur_size / $total_size );
3377
+ } else {
3378
+ $response['m'] .= __( 'No local copy present.', 'updraftplus' );
3379
+ $response['p'] = 0;
3380
+ $response['s'] = 0;
3381
+ $response['t'] = 1;
3382
+ }
3383
+ }
3384
+
3385
+ return $response;
3386
+ }
3387
+
3388
+ private function close_browser_connection( $txt = '' ) {
3389
+ $txt = '<mainwp>' . base64_encode( serialize( $txt ) ) . '</mainwp>';
3390
+ // Close browser connection so that it can resume AJAX polling
3391
+ header( 'Content-Length: ' . ( ( ! empty( $txt ) ) ? strlen( $txt ) : '0' ) );
3392
+ header( 'Connection: close' );
3393
+ header( 'Content-Encoding: none' );
3394
+ if ( session_id() ) {
3395
+ session_write_close();
3396
+ }
3397
+ echo $txt;
3398
+ // These two added - 19-Feb-15 - started being required on local dev machine, for unknown reason (probably some plugin that started an output buffer).
3399
+ if ( ob_get_level() ) {
3400
+ ob_end_flush();
3401
+ }
3402
+ flush();
3403
+ }
3404
+
3405
+ public function updraftplus_init() {
3406
+ if ( get_option( 'mainwp_updraftplus_ext_enabled' ) !== 'Y' ) {
3407
+ return;
3408
+ }
3409
+
3410
+ if ( get_option( 'mainwp_updraftplus_hide_plugin' ) === 'hide' ) {
3411
+ add_filter( 'all_plugins', array( $this, 'all_plugins' ) );
3412
+ add_action( 'admin_menu', array( $this, 'remove_menu' ) );
3413
+ add_filter( 'site_transient_update_plugins', array( &$this, 'remove_update_nag' ) );
3414
+ add_action( 'wp_before_admin_bar_render', array( $this, 'wp_before_admin_bar_render' ), 99 );
3415
+ add_action( 'admin_init', array( $this, 'remove_notices' ) );
3416
+ }
3417
+ }
3418
+
3419
+ function remove_notices() {
3420
+ $remove_hooks['all_admin_notices'] = array(
3421
+ // 'UpdraftPlus_Admin' => array(
3422
+ // 'show_admin_notice_upgradead' => 10,
3423
+ // 'show_admin_warning_googledrive' => 10,
3424
+ // 'show_admin_warning_dropbox' => 10,
3425
+ // 'show_admin_warning_bitcasa' => 10,
3426
+ // 'show_admin_warning_copycom' => 10,
3427
+ // 'show_admin_warning_onedrive' => 10,
3428
+ // 'show_admin_warning_updraftvault' => 10,
3429
+ // 'show_admin_warning_diskspace' => 10,
3430
+ // 'show_admin_warning_disabledcron' => 10,
3431
+ // 'show_admin_nosettings_warning' => 10,
3432
+ // 'show_admin_warning_execution_time' => 10,
3433
+ // 'show_admin_warning_litespeed' => 10,
3434
+ // ),
3435
+ 'UpdraftPlus' => array(
3436
+ 'show_admin_warning_unreadablelog' => 10,
3437
+ 'show_admin_warning_nolog' => 10,
3438
+ 'show_admin_warning_unreadablefile' => 10,
3439
+ ),
3440
+ 'UpdraftPlus_BackupModule_dropbox' => array(
3441
+ 'show_authed_admin_warning' => 10,
3442
+ ),
3443
+ 'UpdraftPlus_BackupModule_googledrive' => array(
3444
+ 'show_authed_admin_success' => 10,
3445
+ ),
3446
+ // 'UpdraftPlus_Options' => array(
3447
+ // 'show_admin_warning_multisite' => 10
3448
+ // )
3449
+ );
3450
+
3451
+ foreach ( $remove_hooks as $hook_name => $hooks ) {
3452
+ foreach ( $hooks as $class_name => $methods ) {
3453
+ foreach ( $methods as $method => $priority ) {
3454
+ MainWP_Helper::remove_filters_for_anonymous_class( $hook_name, $class_name, $method, $priority );
3455
+ }
3456
+ }
3457
+ }
3458
+ }
3459
+
3460
+ function wp_before_admin_bar_render() {
3461
+ global $wp_admin_bar;
3462
+
3463
+ $nodes = $wp_admin_bar->get_nodes();
3464
+ if ( is_array( $nodes ) ) {
3465
+ foreach ( $nodes as $node ) {
3466
+ if ( is_array( $nodes ) ) {
3467
+ foreach ( $nodes as $node ) {
3468
+ if ( 'updraft_admin_node' === $node->parent || ( $node->id = 'updraft_admin_node' ) ) {
3469
+ $wp_admin_bar->remove_node( $node->id );
3470
+ }
3471
+ }
3472
+ }
3473
+ }
3474
+ }
3475
+ }
3476
+
3477
+ function remove_update_nag( $value ) {
3478
+ if ( isset( $_POST['mainwpsignature'] ) ) {
3479
+ return $value;
3480
+ }
3481
+ if ( isset( $value->response['updraftplus/updraftplus.php'] ) ) {
3482
+ unset( $value->response['updraftplus/updraftplus.php'] );
3483
+ }
3484
+
3485
+ return $value;
3486
+ }
3487
+
3488
+ public function syncData() {
3489
+ if ( ! self::isActivatedUpdraftplus() ) {
3490
+ return '';
3491
+ }
3492
+
3493
+ return $this->get_updraft_data();
3494
+ }
3495
+
3496
+ public function all_plugins( $plugins ) {
3497
+ foreach ( $plugins as $key => $value ) {
3498
+ $plugin_slug = basename( $key, '.php' );
3499
+ if ( 'updraftplus' === $plugin_slug ) {
3500
+ unset( $plugins[ $key ] );
3501
+ }
3502
+ }
3503
+
3504
+ return $plugins;
3505
+ }
3506
+
3507
+ public function remove_menu() {
3508
+ global $submenu;
3509
+ if ( isset( $submenu['options-general.php'] ) ) {
3510
+ foreach ( $submenu['options-general.php'] as $index => $item ) {
3511
+ if ( 'updraftplus' === $item[2] ) {
3512
+ unset( $submenu['options-general.php'][ $index ] );
3513
+ break;
3514
+ }
3515
+ }
3516
+ }
3517
+
3518
+ $pos = stripos( $_SERVER['REQUEST_URI'], 'options-general.php?page=updraftplus' );
3519
+ if ( false !== $pos ) {
3520
+ wp_redirect( get_option( 'siteurl' ) . '/wp-admin/index.php' );
3521
+ exit();
3522
+ }
3523
+ }
3524
+ }
3525
+
class/class-mainwp-child-vulnerability-checker.php ADDED
@@ -0,0 +1,220 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class MainWP_Child_Vulnerability_Checker {
4
+
5
+ public static $instance = null;
6
+
7
+ static function Instance() {
8
+ if ( null === MainWP_Child_Vulnerability_Checker::$instance ) {
9
+ MainWP_Child_Vulnerability_Checker::$instance = new MainWP_Child_Vulnerability_Checker();
10
+ }
11
+ return MainWP_Child_Vulnerability_Checker::$instance;
12
+ }
13
+
14
+ public function __construct() {
15
+
16
+ }
17
+
18
+ public function action() {
19
+ $information = array();
20
+ if ( isset( $_POST['mwp_action'] ) ) {
21
+ switch ( $_POST['mwp_action'] ) {
22
+ case 'vulner_recheck':
23
+ $information = $this->vulner_recheck();
24
+ break;
25
+ }
26
+ }
27
+ MainWP_Helper::write( $information );
28
+ }
29
+
30
+ function vulner_recheck(){
31
+ $result = array();
32
+ $force = (isset($_POST['force']) && !empty($_POST['force'])) ? true : false;
33
+ $result['plugin'] = $this->check_plugins($force);
34
+ $result['wp'] = $this->check_wp($force);
35
+ $result['theme'] = $this->check_themes($force);
36
+ $information = array( 'result' => $result, 'ok' => 1);
37
+ return $information;
38
+ }
39
+
40
+ function check_plugins($force = false){
41
+ $result = array();
42
+ $active_plugins = get_option('active_plugins');
43
+
44
+ if( !empty($active_plugins) ){
45
+ foreach($active_plugins as $plug){
46
+
47
+ $plugin_file = WP_CONTENT_DIR . '/plugins/' . $plug;
48
+ $plugin_info = get_plugin_data($plugin_file);
49
+ $plugin_version = isset($plugin_info['Version']) ? $plugin_info['Version'] : '';
50
+ $string = explode('/',$plug);
51
+ $plug_vuln = get_transient('mainwp_vulnche_trans_plug_'.$string[0]);
52
+ if(false === $plug_vuln || $force) {
53
+ $plug_vuln = $this->vulnche_get_content('https://wpvulndb.com/api/v2/plugins/' . $string[0]);
54
+ set_transient('mainwp_vulnche_trans_plug_'.$string[0],$plug_vuln, 1 * DAY_IN_SECONDS);
55
+ }
56
+ if ($plug_vuln) {
57
+ $plug_vuln = json_decode($plug_vuln, true);
58
+ $plug_vuln_filter = $plug_vuln;
59
+
60
+ foreach ($plug_vuln as $slug => $pl_data) {
61
+ if (isset($pl_data['vulnerabilities']) && count($pl_data['vulnerabilities']) > 0) {
62
+ $plug_vulner_data = array();
63
+ foreach($pl_data['vulnerabilities'] as $vuln_data) {
64
+ if ( isset($vuln_data['fixed_in']) && version_compare( $plugin_version, $vuln_data['fixed_in'] ) >= 0 ) {
65
+ continue;
66
+ }
67
+ $plug_vulner_data[] = $vuln_data;
68
+ }
69
+
70
+ if(count($plug_vulner_data) == 0) {
71
+ unset($plug_vuln_filter[$slug]);
72
+ } else {
73
+ $plug_vuln_filter[$slug]['vulnerabilities'] = $plug_vulner_data;
74
+ $plug_vuln_filter[$slug]['detected_version'] = $plugin_version;
75
+ $plug_vuln_filter[$slug]['plugin_slug'] = $plug;
76
+ }
77
+
78
+ } else {
79
+ unset($plug_vuln_filter[$slug]);
80
+ }
81
+
82
+ }
83
+
84
+ if (count($plug_vuln_filter) == 0) {
85
+ continue;
86
+ }
87
+ $plug_vuln = json_encode($plug_vuln_filter);
88
+
89
+ } else {
90
+ continue;
91
+ }
92
+ $result[$plug] = $plug_vuln;
93
+ }
94
+ }
95
+ return $result;
96
+ }
97
+
98
+ function check_wp($force = false){
99
+ $wp_vuln = get_transient('mainwp_vulnche_trans_wp_json');
100
+ $wp_version = str_replace('.', '', get_bloginfo('version'));
101
+ if(false === $wp_vuln || $force) {
102
+ $wp_vuln = $this->vulnche_get_content('https://wpvulndb.com/api/v2/wordpresses/' . $wp_version);
103
+ set_transient('mainwp_vulnche_trans_wp_json', $wp_vuln, 1 * DAY_IN_SECONDS);
104
+ }
105
+ return $wp_vuln;
106
+ }
107
+
108
+ function check_themes($force = false){
109
+
110
+ require_once( ABSPATH . 'wp-admin/includes/misc.php' );
111
+ require_once( ABSPATH . 'wp-admin/includes/theme.php' );
112
+
113
+ if ( current_user_can( 'switch_themes' ) ) {
114
+ $themes = wp_prepare_themes_for_js();
115
+ } else {
116
+ $themes = wp_prepare_themes_for_js( array( wp_get_theme() ) );
117
+ }
118
+ wp_reset_vars( array( 'theme', 'search' ) );
119
+ $result = array();
120
+ if(!empty($themes)){
121
+ foreach($themes as $th){
122
+ if(empty($th['parent'])) {
123
+ $th_vuln = get_transient('mainwp_vulnche_trans_theme_' . $th['id']);
124
+ if (false === $th_vuln || $force) {
125
+ $th_vuln = $this->vulnche_get_content('https://wpvulndb.com/api/v2/themes/' . $th['id']);
126
+ set_transient('mainwp_vulnche_trans_theme_' . $th['id'], $th_vuln, 1 * DAY_IN_SECONDS);
127
+ }
128
+
129
+ if ($th_vuln) {
130
+ $th_vuln = json_decode($th_vuln, true);
131
+ $th_vuln_filter = $th_vuln;
132
+ foreach ($th_vuln as $slug => $th_data) {
133
+ if (isset($th_data['vulnerabilities']) && count($th_data['vulnerabilities']) > 0) {
134
+
135
+ $th_vulner_data = array();
136
+ foreach($th_data['vulnerabilities'] as $vuln_data) {
137
+ if (empty($vuln_data))
138
+ continue;
139
+
140
+ if ( isset($vuln_data['fixed_in']) && version_compare( $th['version'], $vuln_data['fixed_in'] ) >= 0 ) {
141
+ continue;
142
+ }
143
+
144
+ $th_vulner_data[] = $vuln_data;
145
+ }
146
+
147
+ if(count($th_vulner_data) == 0) {
148
+ unset($th_vuln_filter[$slug]);
149
+ } else {
150
+ $th_vuln_filter[$slug]['vulnerabilities'] = $th_vulner_data;
151
+ }
152
+ } else {
153
+ unset($th_vuln_filter[$slug]);
154
+ }
155
+ }
156
+
157
+ if (count($th_vuln_filter) == 0) {
158
+ continue;
159
+ }
160
+
161
+ $th_vuln = json_encode($th_vuln_filter);
162
+ } else {
163
+ continue;
164
+ }
165
+
166
+ $result[$th['id']]['vulner_data'] = $th_vuln;
167
+ $result[$th['id']]['name'] = $th['name'];
168
+ $result[$th['id']]['author'] = $th['author'];
169
+ $result[$th['id']]['detected_version'] = $th['version'];
170
+ }
171
+ }
172
+ }
173
+ return $result;
174
+ }
175
+
176
+
177
+ function vulnche_get_content ($url) {
178
+
179
+ $ch = curl_init();
180
+
181
+ curl_setopt($ch, CURLOPT_URL, $url);
182
+ curl_setopt($ch, CURLOPT_HEADER, 0);
183
+ curl_setopt($ch, CURLOPT_USERAGENT, $this->get_random_user_agent());
184
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER,true);
185
+
186
+ $output = curl_exec($ch);
187
+ $info = curl_getinfo($ch, CURLINFO_HTTP_CODE);
188
+
189
+ curl_close($ch);
190
+ if ($output === false || $info != 200) {
191
+ $output = null;
192
+ }
193
+ return $output;
194
+ }
195
+
196
+
197
+ function get_random_user_agent ( ) {
198
+
199
+ $someUA = array (
200
+ "Mozilla/5.0 (Windows; U; Windows NT 6.0; fr; rv:1.9.1b1) Gecko/20081007 Firefox/3.1b1",
201
+ "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.0.1) Gecko/2008070208 Firefox/3.0.0",
202
+ "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/525.19 (KHTML, like Gecko) Chrome/0.4.154.18 Safari/525.19",
203
+ "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/525.13 (KHTML, like Gecko) Chrome/0.2.149.27 Safari/525.13",
204
+ "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30)",
205
+ "Mozilla/4.0 (compatible; MSIE 7.0b; Windows NT 5.1; .NET CLR 1.1.4322; .NET CLR 2.0.40607)",
206
+ "Mozilla/4.0 (compatible; MSIE 7.0b; Windows NT 5.1; .NET CLR 1.1.4322)",
207
+ "Mozilla/4.0 (compatible; MSIE 7.0b; Windows NT 5.1; .NET CLR 1.0.3705; Media Center PC 3.1; Alexa Toolbar; .NET CLR 1.1.4322; .NET CLR 2.0.50727)",
208
+ "Mozilla/45.0 (compatible; MSIE 6.0; Windows NT 5.1)",
209
+ "Mozilla/4.08 (compatible; MSIE 6.0; Windows NT 5.1)",
210
+ "Mozilla/4.01 (compatible; MSIE 6.0; Windows NT 5.1)"
211
+ );
212
+
213
+ srand((double)microtime()*1000000);
214
+
215
+ return $someUA[rand(0,count($someUA)-1)];
216
+ }
217
+
218
+
219
+ }
220
+
class/class-mainwp-child-woocommerce-status.php ADDED
@@ -0,0 +1,452 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class MainWP_Child_WooCommerce_Status {
4
+ public static $instance = null;
5
+
6
+ static function Instance() {
7
+ if ( null === MainWP_Child_WooCommerce_Status::$instance ) {
8
+ MainWP_Child_WooCommerce_Status::$instance = new MainWP_Child_WooCommerce_Status();
9
+ }
10
+
11
+ return MainWP_Child_WooCommerce_Status::$instance;
12
+ }
13
+
14
+ public function __construct() {
15
+ add_action( 'mainwp_child_deactivation', array( $this, 'child_deactivation' ) );
16
+
17
+ }
18
+
19
+ public function child_deactivation() {
20
+
21
+ }
22
+
23
+ public function action() {
24
+ $information = array();
25
+ if ( ! class_exists( 'WooCommerce' ) || !defined('WC_VERSION')) {
26
+ $information['error'] = 'NO_WOOCOMMERCE';
27
+ MainWP_Helper::write( $information );
28
+ }
29
+
30
+ $is_ver220 = $this->is_version_220();
31
+ if ( isset( $_POST['mwp_action'] ) ) {
32
+ switch ( $_POST['mwp_action'] ) {
33
+ case 'sync_data':
34
+ $information = ! $is_ver220 ? $this->sync_data() : $this->sync_data_two();
35
+ break;
36
+ case 'report_data':
37
+ $information = ! $is_ver220 ? $this->report_data() : $this->report_data_two();
38
+ break;
39
+ case 'update_wc_db':
40
+ $information = $this->update_wc_db();
41
+ break;
42
+ }
43
+ }
44
+ MainWP_Helper::write( $information );
45
+ }
46
+
47
+ function is_version_220() {
48
+ return version_compare( WC()->version, '2.2.0', '>=' );
49
+ }
50
+
51
+ function sync_data() {
52
+ global $wpdb;
53
+ $file = WP_PLUGIN_DIR . '/woocommerce/includes/admin/reports/class-wc-admin-report.php';
54
+ if ( file_exists( $file ) ) {
55
+ include_once( $file );
56
+ } else {
57
+ return false;
58
+ }
59
+
60
+ $reports = new WC_Admin_Report();
61
+
62
+ // Get sales
63
+ $sales = $wpdb->get_var( $wpdb->prepare( "SELECT SUM( postmeta.meta_value ) FROM {$wpdb->posts} as posts
64
+ LEFT JOIN {$wpdb->term_relationships} AS rel ON posts.ID=rel.object_ID
65
+ LEFT JOIN {$wpdb->term_taxonomy} AS tax USING( term_taxonomy_id )
66
+ LEFT JOIN {$wpdb->terms} AS term USING( term_id )
67
+ LEFT JOIN {$wpdb->postmeta} AS postmeta ON posts.ID = postmeta.post_id
68
+ WHERE posts.post_type = 'shop_order'
69
+ AND posts.post_status = 'publish'
70
+ AND tax.taxonomy = 'shop_order_status'
71
+ AND term.slug IN ( '" . implode( "','", apply_filters( 'woocommerce_reports_order_statuses', array(
72
+ 'completed',
73
+ 'processing',
74
+ 'on-hold',
75
+ ) ) ) . "' )
76
+ AND postmeta.meta_key = '_order_total'
77
+ AND posts.post_date >= %s
78
+ AND posts.post_date <= %s
79
+ ", date( 'Y-m-01', $start_date ), date( 'Y-m-d H:i:s', $end_date ) ) );
80
+
81
+
82
+
83
+ // Get top seller
84
+ $top_seller = $wpdb->get_row( $wpdb->prepare( "SELECT SUM( order_item_meta.meta_value ) as qty, order_item_meta_2.meta_value as product_id
85
+ FROM {$wpdb->posts} as posts
86
+ LEFT JOIN {$wpdb->term_relationships} AS rel ON posts.ID=rel.object_ID
87
+ LEFT JOIN {$wpdb->term_taxonomy} AS tax USING( term_taxonomy_id )
88
+ LEFT JOIN {$wpdb->terms} AS term USING( term_id )
89
+ LEFT JOIN {$wpdb->prefix}woocommerce_order_items AS order_items ON posts.ID = order_id
90
+ LEFT JOIN {$wpdb->prefix}woocommerce_order_itemmeta AS order_item_meta ON order_items.order_item_id = order_item_meta.order_item_id
91
+ LEFT JOIN {$wpdb->prefix}woocommerce_order_itemmeta AS order_item_meta_2 ON order_items.order_item_id = order_item_meta_2.order_item_id
92
+ WHERE posts.post_type = 'shop_order'
93
+ AND posts.post_status = 'publish'
94
+ AND tax.taxonomy = 'shop_order_status'
95
+ AND term.slug IN ( '" . implode( "','", apply_filters( 'woocommerce_reports_order_statuses', array(
96
+ 'completed',
97
+ 'processing',
98
+ 'on-hold',
99
+ ) ) ) . "' )
100
+ AND order_item_meta.meta_key = '_qty'
101
+ AND order_item_meta_2.meta_key = '_product_id'
102
+ AND posts.post_date >= %s
103
+ AND posts.post_date <= %s
104
+ GROUP BY product_id
105
+ ORDER BY qty DESC
106
+ LIMIT 1
107
+ ", date( 'Y-m-01', $start_date ), date( 'Y-m-d H:i:s', $end_date )) );
108
+
109
+ if ( ! empty( $top_seller ) ) {
110
+ $top_seller->name = get_the_title( $top_seller->product_id );
111
+ }
112
+
113
+ // Counts
114
+ $on_hold_count = get_term_by( 'slug', 'on-hold', 'shop_order_status' )->count;
115
+ $processing_count = get_term_by( 'slug', 'processing', 'shop_order_status' )->count;
116
+
117
+ // Get products using a query - this is too advanced for get_posts :(
118
+ $stock = absint( max( get_option( 'woocommerce_notify_low_stock_amount' ), 1 ) );
119
+ $nostock = absint( max( get_option( 'woocommerce_notify_no_stock_amount' ), 0 ) );
120
+
121
+ $query_from = "FROM {$wpdb->posts} as posts
122
+ INNER JOIN {$wpdb->postmeta} AS postmeta ON posts.ID = postmeta.post_id
123
+ INNER JOIN {$wpdb->postmeta} AS postmeta2 ON posts.ID = postmeta2.post_id
124
+ WHERE 1=1
125
+ AND posts.post_type IN ('product', 'product_variation')
126
+ AND posts.post_status = 'publish'
127
+ AND (
128
+ postmeta.meta_key = '_stock' AND CAST(postmeta.meta_value AS SIGNED) <= '{$stock}' AND CAST(postmeta.meta_value AS SIGNED) > '{$nostock}' AND postmeta.meta_value != ''
129
+ )
130
+ AND (
131
+ ( postmeta2.meta_key = '_manage_stock' AND postmeta2.meta_value = 'yes' ) OR ( posts.post_type = 'product_variation' )
132
+ )
133
+ ";
134
+
135
+ $lowinstock_count = absint( $wpdb->get_var( "SELECT COUNT( DISTINCT posts.ID ) {$query_from};" ) );
136
+
137
+ $query_from = "FROM {$wpdb->posts} as posts
138
+ INNER JOIN {$wpdb->postmeta} AS postmeta ON posts.ID = postmeta.post_id
139
+ INNER JOIN {$wpdb->postmeta} AS postmeta2 ON posts.ID = postmeta2.post_id
140
+ WHERE 1=1
141
+ AND posts.post_type IN ('product', 'product_variation')
142
+ AND posts.post_status = 'publish'
143
+ AND (
144
+ postmeta.meta_key = '_stock' AND CAST(postmeta.meta_value AS SIGNED) <= '{$nostock}' AND postmeta.meta_value != ''
145
+ )
146
+ AND (
147
+ ( postmeta2.meta_key = '_manage_stock' AND postmeta2.meta_value = 'yes' ) OR ( posts.post_type = 'product_variation' )
148
+ )
149
+ ";
150
+
151
+ $outofstock_count = absint( $wpdb->get_var( "SELECT COUNT( DISTINCT posts.ID ) {$query_from};" ) );
152
+
153
+ $data = array(
154
+ 'sales' => $sales,
155
+ 'formated_sales' => wc_price( $sales ),
156
+ 'top_seller' => $top_seller,
157
+ 'onhold' => $on_hold_count,
158
+ 'awaiting' => $processing_count,
159
+ 'stock' => $stock,
160
+ 'nostock' => $nostock,
161
+ 'lowstock' => $lowinstock_count,
162
+ 'outstock' => $outofstock_count,
163
+ );
164
+ $information['data'] = $data;
165
+
166
+ return $information;
167
+ }
168
+
169
+ function report_data() {
170
+ global $wpdb;
171
+ $file = WP_PLUGIN_DIR . '/woocommerce/includes/admin/reports/class-wc-admin-report.php';
172
+ if ( file_exists( $file ) ) {
173
+ include_once( $file );
174
+ } else {
175
+ return false;
176
+ }
177
+
178
+ $reports = new WC_Admin_Report();
179
+ $start_date = $_POST['start_date'];
180
+ $end_date = $_POST['end_date'];
181
+ // Get sales
182
+ $sales = $wpdb->get_var( "SELECT SUM( postmeta.meta_value ) FROM {$wpdb->posts} as posts
183
+ LEFT JOIN {$wpdb->term_relationships} AS rel ON posts.ID=rel.object_ID
184
+ LEFT JOIN {$wpdb->term_taxonomy} AS tax USING( term_taxonomy_id )
185
+ LEFT JOIN {$wpdb->terms} AS term USING( term_id )
186
+ LEFT JOIN {$wpdb->postmeta} AS postmeta ON posts.ID = postmeta.post_id
187
+ WHERE posts.post_type = 'shop_order'
188
+ AND posts.post_status = 'publish'
189
+ AND tax.taxonomy = 'shop_order_status'
190
+ AND term.slug IN ( '" . implode( "','", apply_filters( 'woocommerce_reports_order_statuses', array(
191
+ 'completed',
192
+ 'processing',
193
+ 'on-hold',
194
+ ) ) ) . "' )
195
+ AND postmeta.meta_key = '_order_total'
196
+ AND posts.post_date >= '" . date( 'Y-m-01', $start_date ) . "'
197
+ AND posts.post_date <= '" . date( 'Y-m-d H:i:s', $end_date ) . "'
198
+ " );
199
+
200
+ // Get top seller
201
+ $top_seller = $wpdb->get_row( "SELECT SUM( order_item_meta.meta_value ) as qty, order_item_meta_2.meta_value as product_id
202
+ FROM {$wpdb->posts} as posts
203
+ LEFT JOIN {$wpdb->term_relationships} AS rel ON posts.ID=rel.object_ID
204
+ LEFT JOIN {$wpdb->term_taxonomy} AS tax USING( term_taxonomy_id )
205
+ LEFT JOIN {$wpdb->terms} AS term USING( term_id )
206
+ LEFT JOIN {$wpdb->prefix}woocommerce_order_items AS order_items ON posts.ID = order_id
207
+ LEFT JOIN {$wpdb->prefix}woocommerce_order_itemmeta AS order_item_meta ON order_items.order_item_id = order_item_meta.order_item_id
208
+ LEFT JOIN {$wpdb->prefix}woocommerce_order_itemmeta AS order_item_meta_2 ON order_items.order_item_id = order_item_meta_2.order_item_id
209
+ WHERE posts.post_type = 'shop_order'
210
+ AND posts.post_status = 'publish'
211
+ AND tax.taxonomy = 'shop_order_status'
212
+ AND term.slug IN ( '" . implode( "','", apply_filters( 'woocommerce_reports_order_statuses', array(
213
+ 'completed',
214
+ 'processing',
215
+ 'on-hold',
216
+ ) ) ) . "' )
217
+ AND order_item_meta.meta_key = '_qty'
218
+ AND order_item_meta_2.meta_key = '_product_id'
219
+ AND posts.post_date >= '" . date( 'Y-m-01', $start_date ) . "'
220
+ AND posts.post_date <= '" . date( 'Y-m-d H:i:s', $end_date ) . "'
221
+ GROUP BY product_id
222
+ ORDER BY qty DESC
223
+ LIMIT 1
224
+ " );
225
+
226
+ if ( ! empty( $top_seller ) ) {
227
+ $top_seller->name = get_the_title( $top_seller->product_id );
228
+ }
229
+
230
+ // Counts
231
+ $on_hold_count = get_term_by( 'slug', 'on-hold', 'shop_order_status' )->count;
232
+ $processing_count = get_term_by( 'slug', 'processing', 'shop_order_status' )->count;
233
+
234
+ // Get products using a query - this is too advanced for get_posts :(
235
+ $stock = absint( max( get_option( 'woocommerce_notify_low_stock_amount' ), 1 ) );
236
+ $nostock = absint( max( get_option( 'woocommerce_notify_no_stock_amount' ), 0 ) );
237
+
238
+ $query_from = "FROM {$wpdb->posts} as posts
239
+ INNER JOIN {$wpdb->postmeta} AS postmeta ON posts.ID = postmeta.post_id
240
+ INNER JOIN {$wpdb->postmeta} AS postmeta2 ON posts.ID = postmeta2.post_id
241
+ WHERE 1=1
242
+ AND posts.post_type IN ('product', 'product_variation')
243
+ AND posts.post_status = 'publish'
244
+ AND (
245
+ postmeta.meta_key = '_stock' AND CAST(postmeta.meta_value AS SIGNED) <= '{$stock}' AND CAST(postmeta.meta_value AS SIGNED) > '{$nostock}' AND postmeta.meta_value != ''
246
+ )
247
+ AND (
248
+ ( postmeta2.meta_key = '_manage_stock' AND postmeta2.meta_value = 'yes' ) OR ( posts.post_type = 'product_variation' )
249
+ )
250
+ ";
251
+
252
+ $lowinstock_count = absint( $wpdb->get_var( "SELECT COUNT( DISTINCT posts.ID ) {$query_from};" ) );
253
+
254
+ $query_from = "FROM {$wpdb->posts} as posts
255
+ INNER JOIN {$wpdb->postmeta} AS postmeta ON posts.ID = postmeta.post_id
256
+ INNER JOIN {$wpdb->postmeta} AS postmeta2 ON posts.ID = postmeta2.post_id
257
+ WHERE 1=1
258
+ AND posts.post_type IN ('product', 'product_variation')
259
+ AND posts.post_status = 'publish'
260
+ AND (
261
+ postmeta.meta_key = '_stock' AND CAST(postmeta.meta_value AS SIGNED) <= '{$nostock}' AND postmeta.meta_value != ''
262
+ )
263
+ AND (
264
+ ( postmeta2.meta_key = '_manage_stock' AND postmeta2.meta_value = 'yes' ) OR ( posts.post_type = 'product_variation' )
265
+ )
266
+ ";
267
+
268
+ $outofstock_count = absint( $wpdb->get_var( "SELECT COUNT( DISTINCT posts.ID ) {$query_from};" ) );
269
+
270
+ $data = array(
271
+ 'sales' => $sales,
272
+ 'formated_sales' => wc_price( $sales ),
273
+ 'top_seller' => $top_seller,
274
+ 'onhold' => $on_hold_count,
275
+ 'awaiting' => $processing_count,
276
+ 'stock' => $stock,
277
+ 'nostock' => $nostock,
278
+ 'lowstock' => $lowinstock_count,
279
+ 'outstock' => $outofstock_count,
280
+ );
281
+ $information['data'] = $data;
282
+
283
+ return $information;
284
+ }
285
+
286
+ function sync_data_two() {
287
+ // sync data at current time
288
+ $start_date = current_time( 'timestamp' );
289
+ $end_date = current_time( 'timestamp' );
290
+
291
+ return $this->get_woocom_data( $start_date, $end_date );
292
+ }
293
+
294
+ function report_data_two() {
295
+ $start_date = $_POST['start_date'];
296
+ $end_date = $_POST['end_date'];
297
+
298
+ return $this->get_woocom_data( $start_date, $end_date );
299
+ }
300
+
301
+ function check_db_update() {
302
+ if ( version_compare( get_option( 'woocommerce_db_version' ), WC_VERSION, '<' ) ) {
303
+ return true;
304
+ }
305
+ return false;
306
+ }
307
+
308
+ function get_woocom_data( $start_date, $end_date ) {
309
+ global $wpdb;
310
+ $file = WP_PLUGIN_DIR . '/woocommerce/includes/admin/reports/class-wc-admin-report.php';
311
+ if ( file_exists( $file ) ) {
312
+ include_once( $file );
313
+ } else {
314
+ return false;
315
+ }
316
+ $reports = new WC_Admin_Report();
317
+ // Sales
318
+ $query = array();
319
+ $query['fields'] = "SELECT SUM( postmeta.meta_value ) FROM {$wpdb->posts} as posts";
320
+ $query['join'] = "INNER JOIN {$wpdb->postmeta} AS postmeta ON posts.ID = postmeta.post_id ";
321
+ $query['where'] = "WHERE posts.post_type IN ( '" . implode( "','", wc_get_order_types( 'reports' ) ) . "' ) ";
322
+ $query['where'] .= "AND posts.post_status IN ( 'wc-" . implode( "','wc-", apply_filters( 'woocommerce_reports_order_statuses', array(
323
+ 'completed',
324
+ 'processing',
325
+ 'on-hold',
326
+ ) ) ) . "' ) ";
327
+ $query['where'] .= "AND postmeta.meta_key = '_order_total' ";
328
+ $query['where'] .= "AND posts.post_date >= '" . date( 'Y-m-01', $start_date ) . "' ";
329
+ $query['where'] .= "AND posts.post_date <= '" . date( 'Y-m-d H:i:s', $end_date ) . "' ";
330
+
331
+ $sales = $wpdb->get_var( implode( ' ', apply_filters( 'woocommerce_dashboard_status_widget_sales_query', $query ) ) );
332
+
333
+ // Get top seller
334
+ $query = array();
335
+ $query['fields'] = "SELECT SUM( order_item_meta.meta_value ) as qty, order_item_meta_2.meta_value as product_id
336
+ FROM {$wpdb->posts} as posts";
337
+ $query['join'] = "INNER JOIN {$wpdb->prefix}woocommerce_order_items AS order_items ON posts.ID = order_id ";
338
+ $query['join'] .= "INNER JOIN {$wpdb->prefix}woocommerce_order_itemmeta AS order_item_meta ON order_items.order_item_id = order_item_meta.order_item_id ";
339
+ $query['join'] .= "INNER JOIN {$wpdb->prefix}woocommerce_order_itemmeta AS order_item_meta_2 ON order_items.order_item_id = order_item_meta_2.order_item_id ";
340
+ $query['where'] = "WHERE posts.post_type IN ( '" . implode( "','", wc_get_order_types( 'order-count' ) ) . "' ) ";
341
+ $query['where'] .= "AND posts.post_status IN ( 'wc-" . implode( "','wc-", apply_filters( 'woocommerce_reports_order_statuses', array(
342
+ 'completed',
343
+ 'processing',
344
+ 'on-hold',
345
+ ) ) ) . "' ) ";
346
+ $query['where'] .= "AND order_item_meta.meta_key = '_qty' ";
347
+ $query['where'] .= "AND order_item_meta_2.meta_key = '_product_id' ";
348
+ $query['where'] .= "AND posts.post_date >= %s ";
349
+ $query['where'] .= "AND posts.post_date <= %s ";
350
+ $query['groupby'] = 'GROUP BY product_id';
351
+ $query['orderby'] = 'ORDER BY qty DESC';
352
+ $query['limits'] = 'LIMIT 1';
353
+
354
+ $top_seller = $wpdb->get_row( $wpdb->prepare( implode( ' ', $query ), date( 'Y-m-01', $start_date ), date( 'Y-m-d H:i:s', $end_date ) ) );
355
+
356
+
357
+ if ( ! empty( $top_seller ) ) {
358
+ $top_seller->name = get_the_title( $top_seller->product_id );
359
+ }
360
+
361
+ // Counts
362
+ $on_hold_count = 0;
363
+ $processing_count = 0;
364
+
365
+ foreach ( wc_get_order_types( 'order-count' ) as $type ) {
366
+ $counts = (array) wp_count_posts( $type );
367
+ $on_hold_count += isset( $counts['wc-on-hold'] ) ? $counts['wc-on-hold'] : 0;
368
+ $processing_count += isset( $counts['wc-processing'] ) ? $counts['wc-processing'] : 0;
369
+ }
370
+
371
+ // Get products using a query - this is too advanced for get_posts :(
372
+ $stock = absint( max( get_option( 'woocommerce_notify_low_stock_amount' ), 1 ) );
373
+ $nostock = absint( max( get_option( 'woocommerce_notify_no_stock_amount' ), 0 ) );
374
+
375
+ $query_from = "FROM {$wpdb->posts} as posts
376
+ INNER JOIN {$wpdb->postmeta} AS postmeta ON posts.ID = postmeta.post_id
377
+ INNER JOIN {$wpdb->postmeta} AS postmeta2 ON posts.ID = postmeta2.post_id
378
+ WHERE 1=1
379
+ AND posts.post_type IN ('product', 'product_variation')
380
+ AND posts.post_status = 'publish'
381
+ AND (
382
+ postmeta.meta_key = '_stock' AND CAST(postmeta.meta_value AS SIGNED) <= '{$stock}' AND CAST(postmeta.meta_value AS SIGNED) > '{$nostock}' AND postmeta.meta_value != ''
383
+ )
384
+ AND (
385
+ ( postmeta2.meta_key = '_manage_stock' AND postmeta2.meta_value = 'yes' ) OR ( posts.post_type = 'product_variation' )
386
+ )
387
+ ";
388
+
389
+ $lowinstock_count = absint( $wpdb->get_var( "SELECT COUNT( DISTINCT posts.ID ) {$query_from};" ) );
390
+
391
+ $query_from = "FROM {$wpdb->posts} as posts
392
+ INNER JOIN {$wpdb->postmeta} AS postmeta ON posts.ID = postmeta.post_id
393
+ INNER JOIN {$wpdb->postmeta} AS postmeta2 ON posts.ID = postmeta2.post_id
394
+ WHERE 1=1
395
+ AND posts.post_type IN ('product', 'product_variation')
396
+ AND posts.post_status = 'publish'
397
+ AND (
398
+ postmeta.meta_key = '_stock' AND CAST(postmeta.meta_value AS SIGNED) <= '{$nostock}' AND postmeta.meta_value != ''
399
+ )
400
+ AND (
401
+ ( postmeta2.meta_key = '_manage_stock' AND postmeta2.meta_value = 'yes' ) OR ( posts.post_type = 'product_variation' )
402
+ )
403
+ ";
404
+
405
+ $outofstock_count = absint( $wpdb->get_var( "SELECT COUNT( DISTINCT posts.ID ) {$query_from};" ) );
406
+
407
+ $data = array(
408
+ 'sales' => $sales,
409
+ 'formated_sales' => wc_price( $sales ),
410
+ 'top_seller' => $top_seller,
411
+ 'onhold' => $on_hold_count,
412
+ 'awaiting' => $processing_count,
413
+ 'stock' => $stock,
414
+ 'nostock' => $nostock,
415
+ 'lowstock' => $lowinstock_count,
416
+ 'outstock' => $outofstock_count
417
+ );
418
+ $information['data'] = $data;
419
+ $information['need_db_update'] = $this->check_db_update();
420
+ return $information;
421
+ }
422
+
423
+ private static function update_wc_db() {
424
+ include_once( WC()->plugin_path() . '/includes/class-wc-background-updater.php' );
425
+ $background_updater = new WC_Background_Updater();
426
+
427
+ $current_db_version = get_option( 'woocommerce_db_version' );
428
+ $logger = wc_get_logger();
429
+ $update_queued = false;
430
+
431
+ foreach ( WC_Install::get_db_update_callbacks() as $version => $update_callbacks ) {
432
+ if ( version_compare( $current_db_version, $version, '<' ) ) {
433
+ foreach ( $update_callbacks as $update_callback ) {
434
+ $logger->info(
435
+ sprintf( 'Queuing %s - %s', $version, $update_callback ),
436
+ array( 'source' => 'wc_db_updates' )
437
+ );
438
+ $background_updater->push_to_queue( $update_callback );
439
+ $update_queued = true;
440
+ }
441
+ }
442
+ }
443
+
444
+ if ( $update_queued ) {
445
+ $background_updater->save()->dispatch();
446
+ }
447
+
448
+ return array('result' => 'success');
449
+ }
450
+
451
+ }
452
+
class/class-mainwp-child-wordfence.php ADDED
@@ -0,0 +1,2788 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class MainWP_Child_Wordfence {
4
+ public static $instance = null;
5
+ public $is_wordfence_installed = false;
6
+ public $plugin_translate = 'mainwp-child';
7
+
8
+ const OPTIONS_TYPE_GLOBAL = 'global';
9
+ const OPTIONS_TYPE_FIREWALL = 'firewall';
10
+ const OPTIONS_TYPE_BLOCKING = 'blocking';
11
+ const OPTIONS_TYPE_SCANNER = 'scanner';
12
+ const OPTIONS_TYPE_TWO_FACTOR = 'twofactor';
13
+ const OPTIONS_TYPE_LIVE_TRAFFIC = 'livetraffic';
14
+ const OPTIONS_TYPE_COMMENT_SPAM = 'commentspam';
15
+ const OPTIONS_TYPE_DIAGNOSTICS = 'diagnostics';
16
+ const OPTIONS_TYPE_ALL = 'alloptions';
17
+
18
+ public static $options_filter = array(
19
+ 'alertEmails',
20
+ 'alertOn_adminLogin',
21
+ 'alertOn_firstAdminLoginOnly',
22
+ 'alertOn_block',
23
+ 'alertOn_critical',
24
+ 'alertOn_loginLockout',
25
+ 'alertOn_lostPasswdForm',
26
+ 'alertOn_nonAdminLogin',
27
+ 'alertOn_firstNonAdminLoginOnly',
28
+ 'alertOn_wordfenceDeactivated',
29
+ 'alertOn_update',
30
+ 'alertOn_warnings',
31
+ 'alert_maxHourly',
32
+ 'autoUpdate',
33
+ 'firewallEnabled',
34
+ 'howGetIPs',
35
+ 'liveTrafficEnabled',
36
+ 'loginSec_blockAdminReg',
37
+ 'loginSec_countFailMins',
38
+ 'loginSec_disableAuthorScan',
39
+ 'notification_updatesNeeded',
40
+ "notification_securityAlerts",
41
+ "notification_promotions",
42
+ "notification_blogHighlights",
43
+ "notification_productUpdates",
44
+ "notification_scanStatus",
45
+ 'loginSec_lockInvalidUsers',
46
+ 'loginSec_lockoutMins',
47
+ 'loginSec_maskLoginErrors',
48
+ 'loginSec_maxFailures',
49
+ 'loginSec_maxForgotPasswd',
50
+ 'loginSec_strongPasswds',
51
+ 'loginSec_userBlacklist',
52
+ 'loginSecurityEnabled',
53
+ 'other_scanOutside',
54
+ 'scan_exclude',
55
+ 'scan_maxIssues',
56
+ 'scan_maxDuration',
57
+ 'scansEnabled_checkReadableConfig',
58
+ 'scansEnabled_suspectedFiles',
59
+ 'scansEnabled_comments',
60
+ 'scansEnabled_core',
61
+ 'scansEnabled_diskSpace',
62
+ 'scansEnabled_dns',
63
+ 'scansEnabled_fileContents',
64
+ 'scansEnabled_fileContentsGSB',
65
+ 'scan_include_extra',
66
+ //'scansEnabled_heartbleed',
67
+ 'scansEnabled_checkHowGetIPs',
68
+ 'scansEnabled_highSense',
69
+ 'lowResourceScansEnabled',
70
+ 'scansEnabled_malware',
71
+ 'scansEnabled_oldVersions',
72
+ "scansEnabled_suspiciousAdminUsers",
73
+ 'scansEnabled_passwds',
74
+ 'scansEnabled_plugins',
75
+ 'scansEnabled_coreUnknown',
76
+ 'scansEnabled_posts',
77
+ 'scansEnabled_scanImages',
78
+ 'scansEnabled_themes',
79
+ 'scheduledScansEnabled',
80
+ 'securityLevel',
81
+ //'scheduleScan' // NOTE: filtered, not save
82
+ 'blockFakeBots',
83
+ 'neverBlockBG',
84
+ 'maxGlobalRequests',
85
+ 'maxGlobalRequests_action',
86
+ 'maxRequestsCrawlers',
87
+ 'maxRequestsCrawlers_action',
88
+ 'max404Crawlers',
89
+ 'max404Crawlers_action',
90
+ 'maxRequestsHumans',
91
+ 'maxRequestsHumans_action',
92
+ 'max404Humans',
93
+ 'max404Humans_action',
94
+ 'maxScanHits',
95
+ 'maxScanHits_action',
96
+ 'blockedTime',
97
+ 'liveTraf_ignorePublishers',
98
+ 'liveTraf_displayExpandedRecords',
99
+ 'liveTraf_ignoreUsers',
100
+ 'liveTraf_ignoreIPs',
101
+ 'liveTraf_ignoreUA',
102
+ 'liveTraf_maxRows',
103
+ 'displayTopLevelLiveTraffic',
104
+ 'whitelisted',
105
+ 'bannedURLs',
106
+ 'other_hideWPVersion',
107
+ 'other_noAnonMemberComments',
108
+ 'other_scanComments',
109
+ 'other_pwStrengthOnUpdate',
110
+ 'other_WFNet',
111
+ 'maxMem',
112
+ 'maxExecutionTime',
113
+ 'actUpdateInterval',
114
+ 'debugOn',
115
+ 'deleteTablesOnDeact',
116
+ 'disableCookies',
117
+ 'startScansRemotely',
118
+ //'disableConfigCaching',
119
+ //'addCacheComment', // removed
120
+ 'disableCodeExecutionUploads',
121
+ //'isPaid',
122
+ "advancedCommentScanning",
123
+ "scansEnabled_checkGSB",
124
+ "checkSpamIP",
125
+ "spamvertizeCheck",
126
+ //'scansEnabled_public',
127
+ 'email_summary_enabled',
128
+ 'email_summary_dashboard_widget_enabled',
129
+ 'ssl_verify',
130
+ 'email_summary_interval',
131
+ 'email_summary_excluded_directories',
132
+ 'allowed404s',
133
+ 'wafAlertWhitelist',
134
+ 'wafAlertOnAttacks',
135
+ //'ajaxWatcherDisabled_front', // do not update those values when save settings
136
+ //'ajaxWatcherDisabled_admin' // those values saved in the ['changes'] in the saveOptions function
137
+ 'howGetIPs_trusted_proxies',
138
+ 'other_bypassLitespeedNoabort',
139
+ 'disableWAFIPBlocking',
140
+ 'other_blockBadPOST',
141
+ 'displayTopLevelBlocking',
142
+ 'betaThreatDefenseFeed',
143
+ 'scanType',
144
+ 'wafStatus',
145
+ 'learningModeGracePeriodEnabled',
146
+ 'learningModeGracePeriod'
147
+ );
148
+
149
+ // for separated saving this values
150
+ public static $diagnosticParams = array(
151
+ //'addCacheComment',
152
+ 'debugOn',
153
+ 'startScansRemotely',
154
+ 'ssl_verify',
155
+ //'disableConfigCaching',
156
+ 'betaThreatDefenseFeed',
157
+ );
158
+
159
+ public static $firewall_options_filter = array(
160
+ 'wafStatus',
161
+ 'learningModeGracePeriodEnabled',
162
+ 'learningModeGracePeriod'
163
+ );
164
+
165
+
166
+ static function Instance() {
167
+ if ( null === MainWP_Child_Wordfence::$instance ) {
168
+ MainWP_Child_Wordfence::$instance = new MainWP_Child_Wordfence();
169
+ }
170
+
171
+ return MainWP_Child_Wordfence::$instance;
172
+ }
173
+
174
+
175
+ public function __construct() {
176
+ add_action( 'mainwp_child_deactivation', array( $this, 'deactivation' ) );
177
+
178
+ require_once( ABSPATH . 'wp-admin/includes/plugin.php' );
179
+
180
+ if ( is_plugin_active( 'wordfence/wordfence.php' ) && file_exists( plugin_dir_path( __FILE__ ) . '../../wordfence/wordfence.php' ) ) {
181
+ require_once( plugin_dir_path( __FILE__ ) . '../../wordfence/wordfence.php' );
182
+ $this->is_wordfence_installed = true;
183
+ }
184
+
185
+ if ( $this->is_wordfence_installed ) {
186
+ add_action( 'wp_ajax_mainwp_wordfence_download_htaccess', array( $this, 'downloadHtaccess' ) );
187
+ }
188
+
189
+ }
190
+
191
+ public function deactivation() {
192
+ if ( $sched = wp_next_scheduled( 'mainwp_child_wordfence_cron_scan' ) ) {
193
+ wp_unschedule_event( $sched, 'mainwp_child_wordfence_cron_scan' );
194
+ }
195
+ }
196
+
197
+
198
+ public function action() {
199
+ $information = array();
200
+ if ( ! $this->is_wordfence_installed ) {
201
+ MainWP_Helper::write( array( 'error' => __( 'Please install the Wordfence plugin on the child site.', $this->plugin_translate ) ) );
202
+ return;
203
+ }
204
+
205
+ if ( ! class_exists( 'wordfence' ) || ! class_exists( 'wfScanEngine' ) ) {
206
+ $information['error'] = 'NO_WORDFENCE';
207
+ MainWP_Helper::write( $information );
208
+ }
209
+ if ( isset( $_POST['mwp_action'] ) ) {
210
+ MainWP_Helper::update_option('mainwp_wordfence_ext_enabled', "Y", 'yes');
211
+ switch ( $_POST['mwp_action'] ) {
212
+ case 'start_scan':
213
+ $information = $this->start_scan();
214
+ break;
215
+ case 'kill_scan':
216
+ $information = $this->kill_scan();
217
+ break;
218
+ case 'requestScan':
219
+ $information = $this->requestScan();
220
+ break;
221
+ case 'killScan':
222
+ $information = $this->killScan();
223
+ break;
224
+ case 'set_showhide':
225
+ $information = $this->set_showhide();
226
+ break;
227
+ case 'get_log':
228
+ $information = $this->get_log();
229
+ break;
230
+ case 'update_log':
231
+ $information = $this->update_log();
232
+ break;
233
+ case 'get_summary':
234
+ $information = $this->get_summary();
235
+ break;
236
+ case 'load_issues':
237
+ $information = $this->load_issues();
238
+ break;
239
+ case 'loadIssues':
240
+ $information = $this->ajax_loadIssues_callback();
241
+ break;
242
+ case 'load_wafData':
243
+ $information = $this->load_wafData();
244
+ break;
245
+ case 'update_all_issues':
246
+ $information = $this->update_all_issues();
247
+ break;
248
+ case 'update_issues_status':
249
+ $information = $this->update_issues_status();
250
+ break;
251
+ case 'updateIssueStatus':
252
+ $information = $this->updateIssueStatus();
253
+ break;
254
+ case 'delete_issues':
255
+ $information = $this->delete_issues();
256
+ break;
257
+ case 'bulk_operation':
258
+ $information = $this->bulk_operation();
259
+ break;
260
+ case 'bulkOperation': // new
261
+ $information = $this->bulkOperation();
262
+ break;
263
+ case 'delete_file':
264
+ $information = $this->delete_file();
265
+ break;
266
+ case 'restore_file':
267
+ $information = $this->restore_file();
268
+ break;
269
+ case 'save_setting': // to compatible
270
+ $information = $this->save_setting();
271
+ break;
272
+ case 'save_settings_new':
273
+ $information = $this->save_settings_new();
274
+ break;
275
+ case 'saveOptions':
276
+ $information = $this->saveOptions();
277
+ break;
278
+ case 'recentTraffic':
279
+ $information = $this->recentTraffic();
280
+ break;
281
+ case 'ticker':
282
+ $information = $this->ticker();
283
+ break;
284
+ case 'reverse_lookup':
285
+ $information = $this->reverse_lookup();
286
+ break;
287
+ case 'block_ip': // old block ip
288
+ $information = $this->ajax_blockIP_callback();
289
+ break;
290
+ case 'whois':
291
+ $information = $this->whois();
292
+ break;
293
+ case 'createBlock': // new version blockIP, blockIPUARange
294
+ $information = $this->ajax_createBlock_callback();
295
+ break;
296
+ case 'getBlocks':
297
+ $information = $this->ajax_getBlocks_callback();
298
+ break;
299
+ case 'deleteBlocks':
300
+ $information = $this->ajax_deleteBlocks_callback();
301
+ break;
302
+ case 'makePermanentBlocks':
303
+ $information = $this->ajax_makePermanentBlocks_callback();
304
+ break;
305
+ case 'unblock_ip':
306
+ $information = $this->unblock_ip();
307
+ break;
308
+ case 'load_static_panel':
309
+ $information = $this->load_static_panel();
310
+ break;
311
+ case 'downgrade_license':
312
+ $information = $this->downgrade_license();
313
+ break;
314
+ case "import_settings":
315
+ $information = $this->import_settings();
316
+ break;
317
+ case "export_settings":
318
+ $information = $this->export_settings();
319
+ break;
320
+ case "save_cache_config":
321
+ $information = $this->saveCacheConfig();
322
+ break;
323
+ case "check_falcon_htaccess":
324
+ $information = $this->checkFalconHtaccess();
325
+ break;
326
+ case "checkHtaccess":
327
+ $information = $this->checkHtaccess();
328
+ break;
329
+ case "save_cache_options":
330
+ $information = $this->saveCacheOptions();
331
+ break;
332
+ case "clear_page_cache":
333
+ $information = $this->clearPageCache();
334
+ break;
335
+ case "get_cache_stats":
336
+ $information = $this->getCacheStats();
337
+ break;
338
+ case "add_cache_exclusion":
339
+ $information = $this->addCacheExclusion();
340
+ break;
341
+ case "load_cache_exclusions":
342
+ $information = $this->loadCacheExclusions();
343
+ break;
344
+ case "remove_cache_exclusion":
345
+ $information = $this->removeCacheExclusion();
346
+ break;
347
+ case 'get_diagnostics':
348
+ $information = $this->getDiagnostics();
349
+ break;
350
+ case 'update_waf_rules':
351
+ $information = $this->updateWAFRules();
352
+ break;
353
+ case 'update_waf_rules_new':
354
+ $information = $this->updateWAFRules_New();
355
+ break;
356
+ case 'save_debugging_config':
357
+ $information = $this->save_debugging_config();
358
+ break;
359
+ case 'load_live_traffic':
360
+ $information = $this->loadLiveTraffic();
361
+ break;
362
+ case 'white_list_waf':
363
+ $information = $this->whitelistWAFParamKey();
364
+ break;
365
+ case 'hide_file_htaccess':
366
+ $information = $this->hideFileHtaccess();
367
+ break;
368
+ case 'fix_fpd':
369
+ $information = $this->fixFPD();
370
+ break;
371
+ case 'disable_directory_listing':
372
+ $information = $this->disableDirectoryListing();
373
+ break;
374
+ case 'delete_database_option':
375
+ $information = $this->deleteDatabaseOption();
376
+ break;
377
+ case 'misconfigured_howget_ips_choice':
378
+ $information = $this->misconfiguredHowGetIPsChoice();
379
+ break;
380
+ case 'delete_admin_user':
381
+ $information = $this->deleteAdminUser();
382
+ break;
383
+ case 'revoke_admin_user':
384
+ $information = $this->revokeAdminUser();
385
+ break;
386
+ case 'clear_all_blocked':
387
+ $information = $this->clearAllBlocked();
388
+ break;
389
+ case 'permanently_block_all_ips':
390
+ $information = $this->permanentlyBlockAllIPs();
391
+ break;
392
+ case 'unlockout_ip':
393
+ $information = $this->unlockOutIP();
394
+ break;
395
+ case 'unblock_range':
396
+ $information = $this->unblockRange();
397
+ break;
398
+ case 'block_ip_ua_range':
399
+ $information = $this->blockIPUARange();
400
+ break;
401
+ case 'load_block_ranges':
402
+ $information = $this->loadBlockRanges();
403
+ break;
404
+ case 'save_waf_config':
405
+ $information = $this->saveWAFConfig();
406
+ break;
407
+ case 'whitelist_bulk_delete':
408
+ $information = $this->whitelistBulkDelete();
409
+ break;
410
+ case 'whitelist_bulk_enable':
411
+ $information = $this->whitelistBulkEnable();
412
+ break;
413
+ case 'whitelist_bulk_disable':
414
+ $information = $this->whitelistBulkDisable();
415
+ break;
416
+ case 'update_config':
417
+ $information = $this->updateConfig();
418
+ break;
419
+ case 'save_country_blocking':
420
+ $information = $this->saveCountryBlocking();
421
+ break;
422
+ }
423
+ }
424
+ MainWP_Helper::write( $information );
425
+ }
426
+
427
+
428
+ public static function getSectionSettings($section) {
429
+ $general_opts = array(
430
+ 'scheduleScan',
431
+ 'apiKey',
432
+ 'autoUpdate',
433
+ 'alertEmails',
434
+ 'howGetIPs',
435
+ 'howGetIPs_trusted_proxies',
436
+ 'other_hideWPVersion',
437
+ 'disableCodeExecutionUploads',
438
+ 'disableCookies',
439
+ 'actUpdateInterval',
440
+ 'disableCookies',
441
+ 'deleteTablesOnDeact',
442
+ 'notification_updatesNeeded',
443
+ 'notification_securityAlerts', // paid
444
+ 'notification_promotions', // paid
445
+ 'notification_blogHighlights', // paid
446
+ 'notification_productUpdates', // paid
447
+ 'notification_scanStatus',
448
+ 'alertOn_update',
449
+ 'alertOn_wordfenceDeactivated',
450
+ 'alertOn_critical',
451
+ 'alertOn_warnings',
452
+ 'alertOn_block',
453
+ 'alertOn_loginLockout',
454
+ 'alertOn_lostPasswdForm',
455
+ 'alertOn_adminLogin',
456
+ 'alertOn_firstAdminLoginOnly',
457
+ 'alertOn_nonAdminLogin',
458
+ 'alertOn_firstNonAdminLoginOnly',
459
+ 'wafAlertOnAttacks',
460
+ 'alert_maxHourly',
461
+ 'email_summary_enabled',
462
+ 'email_summary_interval',
463
+ 'email_summary_excluded_directories',
464
+ 'email_summary_dashboard_widget_enabled',
465
+ 'other_noAnonMemberComments',
466
+ 'other_scanComments',
467
+ 'advancedCommentScanning' // paid
468
+ );
469
+
470
+ $traffic_opts = array(
471
+ 'liveTrafficEnabled',
472
+ 'liveTraf_ignorePublishers',
473
+ 'liveTraf_displayExpandedRecords',
474
+ 'liveTraf_ignoreUsers',
475
+ 'liveTraf_ignoreIPs',
476
+ 'liveTraf_ignoreUA',
477
+ 'liveTraf_maxRows',
478
+ 'displayTopLevelLiveTraffic'
479
+ );
480
+
481
+ $firewall_opts = array(
482
+ 'disableWAFIPBlocking',
483
+ 'whitelisted',
484
+ 'bannedURLs',
485
+ 'wafAlertWhitelist',
486
+ 'firewallEnabled',
487
+ 'blockFakeBots',
488
+ 'neverBlockBG',
489
+ 'maxGlobalRequests',
490
+ 'maxGlobalRequests_action',
491
+ 'maxRequestsCrawlers',
492
+ 'maxRequestsCrawlers_action',
493
+ 'max404Crawlers',
494
+ 'max404Crawlers_action',
495
+ 'maxRequestsHumans',
496
+ 'maxRequestsHumans_action',
497
+ 'max404Humans',
498
+ 'max404Humans_action',
499
+ 'maxScanHits',
500
+ 'maxScanHits_action',
501
+ 'blockedTime',
502
+ 'allowed404s',
503
+ 'loginSecurityEnabled',
504
+ 'loginSec_maxFailures',
505
+ 'loginSec_maxForgotPasswd',
506
+ 'loginSec_countFailMins',
507
+ 'loginSec_lockoutMins',
508
+ 'loginSec_lockInvalidUsers',
509
+ 'loginSec_userBlacklist',
510
+ 'loginSec_strongPasswds',
511
+ 'loginSec_maskLoginErrors',
512
+ 'loginSec_blockAdminReg',
513
+ 'loginSec_disableAuthorScan',
514
+ 'other_blockBadPOST',
515
+ 'other_pwStrengthOnUpdate',
516
+ 'other_WFNet',
517
+ 'wafStatus',
518
+ 'learningModeGracePeriodEnabled',
519
+ 'learningModeGracePeriod'
520
+ );
521
+
522
+ $scan_opts = array(
523
+ 'scansEnabled_checkGSB', //paid
524
+ 'spamvertizeCheck', //paid
525
+ 'checkSpamIP', // paid
526
+ 'scansEnabled_checkHowGetIPs',
527
+ 'scansEnabled_checkReadableConfig',
528
+ 'scansEnabled_suspectedFiles',
529
+ 'scansEnabled_core',
530
+ 'scansEnabled_themes',
531
+ 'scansEnabled_plugins',
532
+ 'scansEnabled_coreUnknown',
533
+ 'scansEnabled_malware',
534
+ 'scansEnabled_fileContents',
535
+ 'scansEnabled_fileContentsGSB',
536
+ 'scansEnabled_posts',
537
+ 'scansEnabled_comments',
538
+ 'scansEnabled_suspiciousOptions',
539
+ 'scansEnabled_oldVersions',
540
+ 'scansEnabled_suspiciousAdminUsers',
541
+ 'scansEnabled_passwds',
542
+ 'scansEnabled_diskSpace',
543
+ 'scansEnabled_dns',
544
+ 'other_scanOutside',
545
+ 'scansEnabled_scanImages',
546
+ 'scansEnabled_highSense',
547
+ 'scheduledScansEnabled',
548
+ 'lowResourceScansEnabled',
549
+ 'scan_maxIssues',
550
+ 'scan_maxDuration',
551
+ 'maxMem',
552
+ 'maxExecutionTime',
553
+ 'scan_exclude',
554
+ 'scan_include_extra',
555
+ 'scanType'
556
+ );
557
+ $diagnostics_opts = array(
558
+ 'debugOn',
559
+ 'startScansRemotely',
560
+ 'ssl_verify',
561
+ 'betaThreatDefenseFeed'
562
+ );
563
+
564
+ $blocking_opts = array(
565
+ 'displayTopLevelBlocking',
566
+ );
567
+
568
+ $options = array();
569
+
570
+ switch($section) {
571
+ case self::OPTIONS_TYPE_GLOBAL:
572
+ $options = $general_opts;
573
+ break;
574
+ case self::OPTIONS_TYPE_LIVE_TRAFFIC:
575
+ $options = $traffic_opts;
576
+ break;
577
+ case self::OPTIONS_TYPE_FIREWALL:
578
+ $options = $firewall_opts;
579
+ break;
580
+ case self::OPTIONS_TYPE_SCANNER:
581
+ $options = $scan_opts;
582
+ break;
583
+ case self::OPTIONS_TYPE_DIAGNOSTICS:
584
+ $options = $diagnostics_opts;
585
+ break;
586
+ case self::OPTIONS_TYPE_BLOCKING:
587
+ $options = $blocking_opts;
588
+ break;
589
+ case self::OPTIONS_TYPE_ALL:
590
+ $options = array_merge($general_opts, $traffic_opts, $firewall_opts, $scan_opts, $diagnostics_opts, $blocking_opts);
591
+ break;
592
+ }
593
+ return $options;
594
+ }
595
+
596
+
597
+ private function start_scan() {
598
+ $information = wordfence::ajax_scan_callback();
599
+ if ( is_array($information) && isset($information['ok']) )
600
+ $information['result'] = 'SUCCESS';
601
+
602
+ return $information;
603
+ }
604
+
605
+ private function kill_scan() {
606
+ wordfence::status(1, 'info', "Scan kill request received.");
607
+ wordfence::status(10, 'info', "SUM_KILLED:A request was received to kill the previous scan.");
608
+ wfUtils::clearScanLock(); //Clear the lock now because there may not be a scan running to pick up the kill request and clear the lock
609
+ wfScanEngine::requestKill();
610
+ return array(
611
+ 'ok' => 1,
612
+ );
613
+ }
614
+
615
+ private function requestScan() {
616
+ return wordfence::ajax_scan_callback();
617
+ }
618
+
619
+ private function killScan() {
620
+ return wordfence::ajax_killScan_callback();
621
+ }
622
+
623
+ function set_showhide() {
624
+ $hide = isset( $_POST['showhide'] ) && ( $_POST['showhide'] === 'hide' ) ? 'hide' : '';
625
+ MainWP_Helper::update_option( 'mainwp_wordfence_hide_plugin', $hide, 'yes' );
626
+ $information['result'] = 'SUCCESS';
627
+
628
+ return $information;
629
+ }
630
+
631
+ public function wordfence_init() {
632
+ if ( get_option( 'mainwp_wordfence_ext_enabled' ) !== 'Y' ) return;
633
+ if ( ! $this->is_wordfence_installed ) return;
634
+
635
+ add_action( 'mainwp_child_site_stats', array( $this, 'do_site_stats' ) );
636
+ if ( get_option( 'mainwp_wordfence_hide_plugin' ) === 'hide' ) {
637
+ add_filter( 'all_plugins', array( $this, 'all_plugins' ) );
638
+ add_action( 'admin_menu', array( $this, 'remove_menu' ) );
639
+ add_action( 'admin_init', array( $this, 'admin_init' ) );
640
+ }
641
+ $this->init_cron();
642
+ }
643
+
644
+ function do_site_stats() {
645
+ do_action( 'mainwp_child_reports_log', 'wordfence' );
646
+ }
647
+
648
+ public function do_reports_log($ext = '') {
649
+ if ( $ext !== 'wordfence' ) return;
650
+ if ( ! $this->is_wordfence_installed ) return;
651
+
652
+ global $wpdb;
653
+
654
+ $lastcheck = get_option('mainwp_wordfence_lastcheck_scan');
655
+ if ($lastcheck == false) {
656
+ $lastcheck = time() - 3600 * 24 * 10; // check 10 days ago
657
+ }
658
+
659
+ $status_table = $wpdb->base_prefix . 'wfStatus';
660
+ // to fix prepare sql empty
661
+ $sql = sprintf( "SELECT * FROM {$status_table} WHERE ctime >= %d AND level = 1 AND type = 'info' AND msg LIKE ", $lastcheck );
662
+ $sql .= " 'Scan Complete. %';";
663
+ $rows = MainWP_Child_DB::_query( $sql, $wpdb->dbh );
664
+
665
+ if ( $rows ) {
666
+ while ( $row = MainWP_Child_DB::fetch_array( $rows ) ) {
667
+ $message = "Wordfence scan completed";
668
+ $scan_time = $row['ctime'];
669
+
670
+ $sql = sprintf( "SELECT * FROM {$status_table} WHERE ctime > %d AND ctime < %d AND level = 10 AND type = 'info' AND msg LIKE ", $scan_time, $scan_time + 100 ); // to get nearest SUM_FINAL msg
671
+ $sql .= " 'SUM_FINAL:Scan complete.%';";
672
+ $sum_rows = MainWP_Child_DB::_query( $sql, $wpdb->dbh );
673
+ $result = '';
674
+ if ($sum_rows) {
675
+ $sum_row = MainWP_Child_DB::fetch_array( $sum_rows );
676
+ if (is_array($sum_row) && isset($sum_row['msg'])) {
677
+ if ( false !== strpos( $sum_row['msg'], 'Congratulations, no problems found' ) ) {
678
+ $result = 'No issues detected';
679
+ } else {
680
+ $result = 'Issues Detected';
681
+ }
682
+ }
683
+ }
684
+ $details = $row['msg'];
685
+ do_action( 'mainwp_reports_wordfence_scan', $message, $scan_time, $details, $result );
686
+ }
687
+ }
688
+
689
+ update_option( 'mainwp_wordfence_lastcheck_scan', time() );
690
+ }
691
+
692
+ public function admin_init() {
693
+ remove_meta_box( 'wordfence_activity_report_widget', 'dashboard', 'normal' );
694
+ }
695
+
696
+ public function init_cron() {
697
+ $sched = wp_next_scheduled( 'mainwp_child_wordfence_cron_scan' );
698
+ $sch = get_option( 'mainwp_child_wordfence_cron_time' );
699
+ if ( 'twicedaily' === $sch ||
700
+ 'daily' === $sch ||
701
+ 'weekly' === $sch ||
702
+ 'monthly' === $sch
703
+ ) {
704
+ add_action( 'mainwp_child_wordfence_cron_scan', array( $this, 'wfc_cron_scan' ) );
705
+ if ( false === $sched ) {
706
+ $sched = wp_schedule_event( time(), $sch, 'mainwp_child_wordfence_cron_scan' );
707
+ }
708
+ } else {
709
+ if ( false !== $sched ) {
710
+ wp_unschedule_event( $sched, 'mainwp_child_wordfence_cron_scan' );
711
+ }
712
+ }
713
+ }
714
+
715
+ public function wfc_cron_scan() {
716
+ if ( ! class_exists( 'wordfence' ) || ! class_exists( 'wfScanEngine' ) ) {
717
+ return;
718
+ }
719
+ $this->start_scan();
720
+ }
721
+
722
+ public function all_plugins( $plugins ) {
723
+ foreach ( $plugins as $key => $value ) {
724
+ $plugin_slug = basename( $key, '.php' );
725
+ if ( 'wordfence' === $plugin_slug ) {
726
+ unset( $plugins[ $key ] );
727
+ }
728
+ }
729
+
730
+ return $plugins;
731
+ }
732
+
733
+ public function remove_menu() {
734
+ remove_menu_page( 'Wordfence' );
735
+ }
736
+
737
+ public function get_log() {
738
+ $information = array();
739
+ $wfLog = wordfence::getLog();
740
+ if ( $wfLog ) {
741
+ $information['events'] = $wfLog->getStatusEvents( 0 );
742
+
743
+ if (method_exists($wfLog, 'getSummaryEvents')) {
744
+ $information['summary'] = $wfLog->getSummaryEvents();
745
+ } else {
746
+ $information['summary'] = '';
747
+ }
748
+ }
749
+ $information['debugOn'] = wfConfig::get( 'debugOn', false );
750
+ $information['timeOffset'] = 3600 * get_option( 'gmt_offset' );
751
+
752
+ return $information;
753
+ }
754
+
755
+ public function update_log() {
756
+ return wordfence::ajax_activityLogUpdate_callback();
757
+ }
758
+
759
+ public function load_issues() {
760
+ $offset = isset($_POST['offset']) ? intval($_POST['offset']) : 0;
761
+ $limit = isset($_POST['limit']) ? intval($_POST['limit']) : WORDFENCE_SCAN_ISSUES_PER_PAGE;
762
+
763
+ $i = new wfIssues();
764
+ $iss = $i->getIssues($offset, $limit);
765
+ $counts = $i->getIssueCounts();
766
+
767
+ return array(
768
+ 'issuesLists' => $iss,
769
+ 'issueCounts' => $counts,
770
+ 'lastScanCompleted' => wfConfig::get( 'lastScanCompleted' ),
771
+ 'apiKey' => wfConfig::get( 'apiKey' ),
772
+ 'isPaid' => wfConfig::get('isPaid'),
773
+ 'lastscan_timestamp' => $this->get_lastscan(),
774
+ 'isNginx' => wfUtils::isNginx() ? 1 : 0,
775
+ 'todayAttBlocked' => $this->count_attacks_blocked(1),
776
+ 'weekAttBlocked' => $this->count_attacks_blocked(7),
777
+ 'monthAttBlocked' => $this->count_attacks_blocked(30),
778
+ 'wafData' => $this->_getWAFData()
779
+ );
780
+ }
781
+
782
+ public static function ajax_loadIssues_callback(){
783
+ $offset = isset($_POST['offset']) ? intval($_POST['offset']) : 0;
784
+ $limit = isset($_POST['limit']) ? intval($_POST['limit']) : WORDFENCE_SCAN_ISSUES_PER_PAGE;
785
+
786
+ $i = new wfIssues();
787
+ $iss = $i->getIssues($offset, $limit);
788
+ $counts = $i->getIssueCounts();
789
+ return array(
790
+ 'issuesLists' => $iss,
791
+ 'issueCounts' => $counts,
792
+ 'lastScanCompleted' => wfConfig::get('lastScanCompleted')
793
+ );
794
+ }
795
+
796
+ public function load_wafData() {
797
+
798
+ $return = array(
799
+ 'wafData' => $this->_getWAFData(),
800
+ 'ip' => wfUtils::getIP(),
801
+ 'ajaxWatcherDisabled_front' => (bool)wfConfig::get('ajaxWatcherDisabled_front'),
802
+ 'ajaxWatcherDisabled_admin' => (bool)wfConfig::get('ajaxWatcherDisabled_admin')
803
+ );
804
+
805
+ if (class_exists('wfFirewall')) {
806
+ $firewall = new wfFirewall();
807
+ $return['isSubDirectoryInstallation'] = $firewall->isSubDirectoryInstallation();
808
+ }
809
+ return $return;
810
+ }
811
+
812
+ public function count_attacks_blocked($maxAgeDays) {
813
+ global $wpdb;
814
+ $interval = 'FLOOR(UNIX_TIMESTAMP(DATE_SUB(NOW(), interval ' . $maxAgeDays . ' day)) / 86400)';
815
+ return $wpdb->get_var(<<<SQL
816
+ SELECT SUM(blockCount) as blockCount
817
+ FROM {$wpdb->prefix}wfBlockedIPLog
818
+ WHERE unixday >= {$interval}
819
+ SQL
820
+ );
821
+ }
822
+
823
+
824
+ function get_lastscan() {
825
+ global $wpdb;
826
+ $wfdb = new wfDB();
827
+ $p = $wpdb->base_prefix;
828
+ $ctime = $wfdb->querySingle("SELECT MAX(ctime) FROM $p"."wfStatus WHERE msg LIKE '%SUM_PREP:Preparing a new scan.%'");
829
+ return $ctime;
830
+ }
831
+
832
+ function update_all_issues() {
833
+ $op = $_POST['op'];
834
+ $i = new wfIssues();
835
+ if ( 'deleteIgnored' === $op ) {
836
+ $i->deleteIgnored();
837
+ } else if ( 'deleteNew' === $op ) {
838
+ $i->deleteNew();
839
+ } else if ( 'ignoreAllNew' === $op ) {
840
+ $i->ignoreAllNew();
841
+ } else {
842
+ return array( 'errorMsg' => 'An invalid operation was called.' );
843
+ }
844
+
845
+ return array( 'ok' => 1 );
846
+ }
847
+
848
+ function updateIssueStatus() {
849
+ $wfIssues = new wfIssues();
850
+ $status = $_POST['status'];
851
+ $issueID = $_POST['id'];
852
+ if(! preg_match('/^(?:new|delete|ignoreP|ignoreC)$/', $status)){
853
+ return array('errorMsg' => "An invalid status was specified when trying to update that issue.");
854
+ }
855
+ $wfIssues->updateIssue($issueID, $status);
856
+ wfScanEngine::refreshScanNotification($wfIssues);
857
+
858
+ $counts = $wfIssues->getIssueCounts();
859
+ return array(
860
+ 'ok' => 1,
861
+ 'issueCounts' => $counts,
862
+ );
863
+ }
864
+
865
+ function update_issues_status() {
866
+ $wfIssues = new wfIssues();
867
+ $status = $_POST['status'];
868
+ $issueID = $_POST['id'];
869
+ if ( ! preg_match( '/^(?:new|delete|ignoreP|ignoreC)$/', $status ) ) {
870
+ return array( 'errorMsg' => 'An invalid status was specified when trying to update that issue.' );
871
+ }
872
+ $wfIssues->updateIssue( $issueID, $status );
873
+
874
+ return array( 'ok' => 1 );
875
+ }
876
+
877
+ function delete_issues() {
878
+ $wfIssues = new wfIssues();
879
+ $issueID = $_POST['id'];
880
+ $wfIssues->deleteIssue( $issueID );
881
+
882
+ return array( 'ok' => 1 );
883
+ }
884
+
885
+ function bulk_operation() {
886
+ $op = $_POST['op'];
887
+ if ( 'del' === $op || 'repair' === $op ) {
888
+ $ids = $_POST['ids'];
889
+ $filesWorkedOn = 0;
890
+ $errors = array();
891
+ $issues = new wfIssues();
892
+ foreach ( $ids as $id ) {
893
+ $issue = $issues->getIssueByID( $id );
894
+ if ( ! $issue ) {
895
+ $errors[] = "Could not delete one of the files because we could not find the issue. Perhaps it's been resolved?";
896
+ continue;
897
+ }
898
+ $file = $issue['data']['file'];
899
+ $localFile = ABSPATH . '/' . preg_replace( '/^[\.\/]+/', '', $file );
900
+ $localFile = realpath( $localFile );
901
+ if ( strpos( $localFile, ABSPATH ) !== 0 ) {
902
+ $errors[] = 'An invalid file was requested: ' . htmlentities( $file );
903
+ continue;
904
+ }
905
+ if ( 'del' === $op ) {
906
+ if ( @unlink( $localFile ) ) {
907
+ $issues->updateIssue( $id, 'delete' );
908
+ $filesWorkedOn ++;
909
+ } else {
910
+ $err = error_get_last();
911
+ $errors[] = 'Could not delete file ' . htmlentities( $file ) . '. Error was: ' . htmlentities( $err['message'] );
912
+ }
913
+ } else if ( 'repair' === $op ) {
914
+ $dat = $issue['data'];
915
+ $result = wordfence::getWPFileContent( $dat['file'], $dat['cType'], $dat['cName'], $dat['cVersion'] );
916
+ if ( $result['cerrorMsg'] ) {
917
+ $errors[] = $result['cerrorMsg'];
918
+ continue;
919
+ } else if ( ! $result['fileContent'] ) {
920
+ $errors[] = 'We could not get the original file of ' . htmlentities( $file ) . ' to do a repair.';
921
+ continue;
922
+ }
923
+
924
+ if ( preg_match( '/\.\./', $file ) ) {
925
+ $errors[] = 'An invalid file ' . htmlentities( $file ) . ' was specified for repair.';
926
+ continue;
927
+ }
928
+ $fh = fopen( $localFile, 'w' );
929
+ if ( ! $fh ) {
930
+ $err = error_get_last();
931
+ if ( preg_match( '/Permission denied/i', $err['message'] ) ) {
932
+ $errMsg = "You don't have permission to repair " . htmlentities( $file ) . '. You need to either fix the file manually using FTP or change the file permissions and ownership so that your web server has write access to repair the file.';
933
+ } else {
934
+ $errMsg = 'We could not write to ' . htmlentities( $file ) . '. The error was: ' . $err['message'];
935
+ }
936
+ $errors[] = $errMsg;
937
+ continue;
938
+ }
939
+ flock( $fh, LOCK_EX );
940
+ $bytes = fwrite( $fh, $result['fileContent'] );
941
+ flock( $fh, LOCK_UN );
942
+ fclose( $fh );
943
+ if ( $bytes < 1 ) {
944
+ $errors[] = 'We could not write to ' . htmlentities( $file ) . ". ($bytes bytes written) You may not have permission to modify files on your WordPress server.";
945
+ continue;
946
+ }
947
+ $filesWorkedOn ++;
948
+ $issues->updateIssue( $id, 'delete' );
949
+ }
950
+ }
951
+ $headMsg = '';
952
+ $bodyMsg = '';
953
+ $verb = 'del' === $op ? 'Deleted' : 'Repaired';
954
+ $verb2 = 'del' === $op ? 'delete' : 'repair';
955
+ if ( $filesWorkedOn > 0 && count( $errors ) > 0 ) {
956
+ $headMsg = "$verb some files with errors";
957
+ $bodyMsg = "$verb $filesWorkedOn files but we encountered the following errors with other files: " . implode( '<br />', $errors );
958
+ } else if ( $filesWorkedOn > 0 ) {
959
+ $headMsg = "$verb $filesWorkedOn files successfully";
960
+ $bodyMsg = "$verb $filesWorkedOn files successfully. No errors were encountered.";
961
+ } else if ( count( $errors ) > 0 ) {
962
+ $headMsg = "Could not $verb2 files";
963
+ $bodyMsg = "We could not $verb2 any of the files you selected. We encountered the following errors: " . implode( '<br />', $errors );
964
+ } else {
965
+ $headMsg = 'Nothing done';
966
+ $bodyMsg = "We didn't $verb2 anything and no errors were found.";
967
+ }
968
+
969
+ return array( 'ok' => 1, 'bulkHeading' => $headMsg, 'bulkBody' => $bodyMsg );
970
+ } else {
971
+ return array( 'errorMsg' => 'Invalid bulk operation selected' );
972
+ }
973
+ }
974
+
975
+ function bulkOperation() {
976
+ return wordfence::ajax_bulkOperation_callback();
977
+ }
978
+
979
+ function delete_file() {
980
+ $issueID = $_POST['issueID'];
981
+ $wfIssues = new wfIssues();
982
+ $issue = $wfIssues->getIssueByID( $issueID );
983
+ if ( ! $issue ) {
984
+ return array( 'errorMsg' => 'Could not delete file because we could not find that issue.' );
985
+ }
986
+ if ( ! $issue['data']['file'] ) {
987
+ return array( 'errorMsg' => 'Could not delete file because that issue does not appear to be a file related issue.' );
988
+ }
989
+ $file = $issue['data']['file'];
990
+ $localFile = ABSPATH . '/' . preg_replace( '/^[\.\/]+/', '', $file );
991
+ $localFile = realpath( $localFile );
992
+ if ( strpos( $localFile, ABSPATH ) !== 0 ) {
993
+ return array( 'errorMsg' => 'An invalid file was requested for deletion.' );
994
+ }
995
+ if ( @unlink( $localFile ) ) {
996
+ $wfIssues->updateIssue( $issueID, 'delete' );
997
+
998
+ return array(
999
+ 'ok' => 1,
1000
+ 'localFile' => $localFile,
1001
+ 'file' => $file,
1002
+ );
1003
+ } else {
1004
+ $err = error_get_last();
1005
+
1006
+ return array( 'errorMsg' => 'Could not delete file ' . htmlentities( $file ) . '. The error was: ' . htmlentities( $err['message'] ) );
1007
+ }
1008
+ }
1009
+
1010
+ function restore_file() {
1011
+ $issueID = $_POST['issueID'];
1012
+ $wfIssues = new wfIssues();
1013
+ $issue = $wfIssues->getIssueByID( $issueID );
1014
+ if ( ! $issue ) {
1015
+ return array( 'cerrorMsg' => 'We could not find that issue in our database.' );
1016
+ }
1017
+ $dat = $issue['data'];
1018
+ $result = wordfence::getWPFileContent( $dat['file'], $dat['cType'], ( isset( $dat['cName'] ) ? $dat['cName'] : '' ), ( isset( $dat['cVersion'] ) ? $dat['cVersion'] : '' ) );
1019
+ $file = $dat['file'];
1020
+ if ( isset( $result['cerrorMsg'] ) && $result['cerrorMsg'] ) {
1021
+ return $result;
1022
+ } else if ( ! $result['fileContent'] ) {
1023
+ return array( 'cerrorMsg' => 'We could not get the original file to do a repair.' );
1024
+ }
1025
+
1026
+ if ( preg_match( '/\.\./', $file ) ) {
1027
+ return array( 'cerrorMsg' => 'An invalid file was specified for repair.' );
1028
+ }
1029
+ $localFile = ABSPATH . '/' . preg_replace( '/^[\.\/]+/', '', $file );
1030
+ $fh = fopen( $localFile, 'w' );
1031
+ if ( ! $fh ) {
1032
+ $err = error_get_last();
1033
+ if ( preg_match( '/Permission denied/i', $err['message'] ) ) {
1034
+ $errMsg = "You don't have permission to repair that file. You need to either fix the file manually using FTP or change the file permissions and ownership so that your web server has write access to repair the file.";
1035
+ } else {
1036
+ $errMsg = 'We could not write to that file. The error was: ' . $err['message'];
1037
+ }
1038
+
1039
+ return array( 'cerrorMsg' => $errMsg );
1040
+ }
1041
+ flock( $fh, LOCK_EX );
1042
+ $bytes = fwrite( $fh, $result['fileContent'] );
1043
+ flock( $fh, LOCK_UN );
1044
+ fclose( $fh );
1045
+ if ( $bytes < 1 ) {
1046
+ return array( 'cerrorMsg' => "We could not write to that file. ($bytes bytes written) You may not have permission to modify files on your WordPress server." );
1047
+ }
1048
+ $wfIssues->updateIssue( $issueID, 'delete' );
1049
+
1050
+ return array(
1051
+ 'ok' => 1,
1052
+ 'file' => $localFile,
1053
+ );
1054
+ }
1055
+
1056
+ function simple_crypt($key, $data, $action = 'encrypt'){
1057
+ $res = '';
1058
+ if($action == 'encrypt'){
1059
+ $string = base64_encode( serialize($data) );
1060
+ } else {
1061
+ $string = $data;
1062
+ }
1063
+ for( $i = 0; $i < strlen($string); $i++){
1064
+ $c = ord(substr($string, $i));
1065
+ if($action == 'encrypt'){
1066
+ $c += ord(substr($key, (($i + 1) % strlen($key))));
1067
+ $res .= chr($c & 0xFF);
1068
+ }else{
1069
+ $c -= ord(substr($key, (($i + 1) % strlen($key))));
1070
+ $res .= chr(abs($c) & 0xFF);
1071
+ }
1072
+ }
1073
+
1074
+ if($action !== 'encrypt'){
1075
+ $res = unserialize( base64_decode($res) );
1076
+ }
1077
+ return $res;
1078
+ }
1079
+
1080
+ function save_settings_new()
1081
+ {
1082
+ if (isset($_POST['encrypted']))
1083
+ $settings = $this->simple_crypt( 'thisisakey', $_POST['settings'], 'decrypt' ); // to fix pass through sec rules of Dreamhost
1084
+ else {
1085
+ $settings = maybe_unserialize( base64_decode( $_POST['settings'] ) );
1086
+ }
1087
+
1088
+ $section = isset($_POST['savingSection']) ? $_POST['savingSection'] : '';
1089
+ $saving_opts = self::getSectionSettings($section);
1090
+
1091
+ $result = array();
1092
+
1093
+ if ( is_array( $settings ) && count( $settings ) > 0 && count($saving_opts) > 0 ) {
1094
+
1095
+ $reload = '';
1096
+ $opts = $settings;
1097
+
1098
+ // if saving then validate data
1099
+ if (isset($saving_opts['liveTraf_ignoreUsers'])) {
1100
+ $validUsers = array();
1101
+ $invalidUsers = array();
1102
+ foreach ( explode( ',', $opts['liveTraf_ignoreUsers'] ) as $val ) {
1103
+ $val = trim( $val );
1104
+ if ( strlen( $val ) > 0 ) {
1105
+ if ( get_user_by( 'login', $val ) ) {
1106
+ $validUsers[] = $val;
1107
+ } else {
1108
+ $invalidUsers[] = $val;
1109
+ }
1110
+ }
1111
+ }
1112
+
1113
+ if ( count( $invalidUsers ) > 0 ) {
1114
+ // return array('errorMsg' => "The following users you selected to ignore in live traffic reports are not valid on this system: " . htmlentities(implode(', ', $invalidUsers)) );
1115
+ $result['invalid_users'] = htmlentities( implode( ', ', $invalidUsers ) );
1116
+ }
1117
+
1118
+ if ( count( $validUsers ) > 0 ) {
1119
+ $opts['liveTraf_ignoreUsers'] = implode( ',', $validUsers );
1120
+ } else {
1121
+ $opts['liveTraf_ignoreUsers'] = '';
1122
+ }
1123
+ }
1124
+
1125
+ // if saving then validate data
1126
+ if (isset($saving_opts['other_WFNet'])) {
1127
+ if ( ! $opts['other_WFNet'] ) {
1128
+ $wfdb = new wfDB();
1129
+ global $wpdb;
1130
+ $p = $wpdb->base_prefix;
1131
+ $wfdb->queryWrite( "delete from $p" . 'wfBlocks where wfsn=1 and permanent=0' );
1132
+ }
1133
+ }
1134
+
1135
+ $regenerateHtaccess = false;
1136
+ // if saving then validate data
1137
+ if (isset($saving_opts['bannedURLs'])) {
1138
+ if ( wfConfig::get( 'bannedURLs', false ) !== $opts['bannedURLs'] ) {
1139
+ $regenerateHtaccess = true;
1140
+ }
1141
+ }
1142
+
1143
+ // save the settings
1144
+ foreach ( $opts as $key => $val ) {
1145
+ // check saving section fields
1146
+ if ( in_array( $key, $saving_opts ) ) {
1147
+ if ( 'apiKey' == $key ) { //Don't save API key yet
1148
+ continue;
1149
+ }
1150
+
1151
+ if (in_array( $key, self::$firewall_options_filter ) ) {
1152
+ wfWAF::getInstance()->getStorageEngine()->setConfig($key, $val);
1153
+ } else {
1154
+ wfConfig::set( $key, $val ); // save it
1155
+ }
1156
+ }
1157
+ }
1158
+
1159
+ if ( $regenerateHtaccess && ( wfConfig::get('cacheType') == 'falcon' ) ) {
1160
+ wfCache::addHtaccessCode('add');
1161
+ }
1162
+
1163
+ // if saving then validate data
1164
+ if (isset($saving_opts['autoUpdate'])) {
1165
+ if ( '1' === $opts['autoUpdate'] ) {
1166
+ wfConfig::enableAutoUpdate();
1167
+ } else if ( '0' === $opts['autoUpdate'] ) {
1168
+ wfConfig::disableAutoUpdate();
1169
+ }
1170
+ }
1171
+
1172
+ // if saving then validate data
1173
+ if (isset($saving_opts['disableCodeExecutionUploads'])) {
1174
+ if (isset($opts['disableCodeExecutionUploads'])) {
1175
+ try {
1176
+ if ( $opts['disableCodeExecutionUploads'] ) {
1177
+ wfConfig::disableCodeExecutionForUploads();
1178
+ } else {
1179
+ wfConfig::removeCodeExecutionProtectionForUploads();
1180
+ }
1181
+ } catch ( wfConfigException $e ) {
1182
+ return array( 'error' => $e->getMessage() );
1183
+ }
1184
+ }
1185
+ }
1186
+
1187
+ // if saving then validate data
1188
+ if (isset($saving_opts['email_summary_enabled'])) {
1189
+ if (isset($opts['email_summary_enabled'])) {
1190
+ if ( ! empty( $opts['email_summary_enabled'] ) ) {
1191
+ wfConfig::set( 'email_summary_enabled', 1 );
1192
+ wfConfig::set( 'email_summary_interval', $opts['email_summary_interval'] );
1193
+ wfConfig::set( 'email_summary_excluded_directories', $opts['email_summary_excluded_directories'] );
1194
+ wfActivityReport::scheduleCronJob();
1195
+ } else {
1196
+ wfConfig::set( 'email_summary_enabled', 0 );
1197
+ wfActivityReport::disableCronJob();
1198
+ }
1199
+ }
1200
+ }
1201
+
1202
+ // if saving then validate data
1203
+ if (isset($saving_opts['scheduleScan'])) {
1204
+ $sch = isset( $opts['scheduleScan'] ) ? $opts['scheduleScan'] : '';
1205
+ if ( get_option( 'mainwp_child_wordfence_cron_time' ) !== $sch ) {
1206
+ update_option( 'mainwp_child_wordfence_cron_time', $sch );
1207
+ $sched = wp_next_scheduled( 'mainwp_child_wordfence_cron_scan' );
1208
+ if ( false !== $sched ) {
1209
+ wp_unschedule_event( $sched, 'mainwp_child_wordfence_cron_scan' );
1210
+ }
1211
+ }
1212
+ }
1213
+
1214
+ // Finished saving settings
1215
+ /////////////////////
1216
+
1217
+
1218
+ $result['cacheType'] = wfConfig::get( 'cacheType' );
1219
+ $result['paidKeyMsg'] = false;
1220
+
1221
+ // if saving then validate data
1222
+ if (isset($saving_opts['apiKey'])) {
1223
+ $apiKey = trim( $_POST['apiKey'] );
1224
+ if ( ! $apiKey ) { //Empty API key (after trim above), then try to get one.
1225
+ $api = new wfAPI( '', wfUtils::getWPVersion() );
1226
+ try {
1227
+ $keyData = $api->call( 'get_anon_api_key' );
1228
+ if ( $keyData['ok'] && $keyData['apiKey'] ) {
1229
+ wfConfig::set( 'apiKey', $keyData['apiKey'] );
1230
+ wfConfig::set( 'isPaid', 0 );
1231
+ $result['apiKey'] = $keyData['apiKey'];
1232
+ $result['isPaid'] = 0;
1233
+ $reload = 'reload';
1234
+ } else {
1235
+ throw new Exception( "We could not understand the Wordfence server's response because it did not contain an 'ok' and 'apiKey' element." );
1236
+ }
1237
+ } catch ( Exception $e ) {
1238
+ $result['error'] = 'Your options have been saved, but we encountered a problem. You left your API key blank, so we tried to get you a free API key from the Wordfence servers. However we encountered a problem fetching the free key: ' . htmlentities( $e->getMessage() );
1239
+
1240
+ return $result;
1241
+ }
1242
+ } else if ( wfConfig::get( 'apiKey' ) !== $apiKey ) {
1243
+ $api = new wfAPI( $apiKey, wfUtils::getWPVersion() );
1244
+ try {
1245
+ $res = $api->call( 'check_api_key', array(), array() );
1246
+ if ( $res['ok'] && isset( $res['isPaid'] ) ) {
1247
+ wfConfig::set( 'apiKey', $apiKey );
1248
+ wfConfig::set( 'isPaid', $res['isPaid'] ); //res['isPaid'] is boolean coming back as JSON and turned back into PHP struct. Assuming JSON to PHP handles bools.
1249
+ $result['apiKey'] = $apiKey;
1250
+ $result['isPaid'] = $res['isPaid'];
1251
+ if ( $res['isPaid'] ) {
1252
+ $result['paidKeyMsg'] = true;
1253
+ }
1254
+ $reload = 'reload';
1255
+ } else {
1256
+ throw new Exception( 'We could not understand the Wordfence API server reply when updating your API key.' );
1257
+ }
1258
+ } catch ( Exception $e ) {
1259
+ $result['error'] = 'Your options have been saved. However we noticed you changed your API key and we tried to verify it with the Wordfence servers and received an error: ' . htmlentities( $e->getMessage() );
1260
+
1261
+ return $result;
1262
+ }
1263
+ } else {
1264
+ try {
1265
+ $api = new wfAPI( $apiKey, wfUtils::getWPVersion() );
1266
+ $res = $api->call( 'ping_api_key', array(), array() );
1267
+ } catch ( Exception $e ) {
1268
+ $result['error'] = 'Your options have been saved. However we noticed you do not change your API key and we tried to verify it with the Wordfence servers and received an error: ' . htmlentities( $e->getMessage() );
1269
+
1270
+ return $result;
1271
+ }
1272
+ }
1273
+ }
1274
+
1275
+ $result['ok'] = 1;
1276
+ $result['reload'] = $reload;
1277
+
1278
+ return $result;
1279
+ } else {
1280
+ $result['error'] = 'Empty settings';
1281
+ }
1282
+
1283
+ return $result;
1284
+ }
1285
+
1286
+
1287
+ public static function recentTraffic(){
1288
+ return wordfence::ajax_recentTraffic_callback();
1289
+ }
1290
+
1291
+ function save_setting() {
1292
+ if (isset($_POST['encrypted']))
1293
+ $settings = $this->simple_crypt( 'thisisakey', $_POST['settings'], 'decrypt' ); // to fix pass through sec rules of Dreamhost
1294
+ else {
1295
+ $settings = maybe_unserialize( base64_decode( $_POST['settings'] ) );
1296
+ }
1297
+
1298
+ if ( is_array( $settings ) && count( $settings ) > 0 ) {
1299
+ $result = array();
1300
+ $reload = '';
1301
+ $opts = $settings;
1302
+ $validUsers = array();
1303
+ $invalidUsers = array();
1304
+ foreach ( explode( ',', $opts['liveTraf_ignoreUsers'] ) as $val ) {
1305
+ $val = trim( $val );
1306
+ if ( strlen( $val ) > 0 ) {
1307
+ if ( get_user_by( 'login', $val ) ) {
1308
+ $validUsers[] = $val;
1309
+ } else {
1310
+ $invalidUsers[] = $val;
1311
+ }
1312
+ }
1313
+ }
1314
+
1315
+ if ( count( $invalidUsers ) > 0 ) {
1316
+ // return array('errorMsg' => "The following users you selected to ignore in live traffic reports are not valid on this system: " . htmlentities(implode(', ', $invalidUsers)) );
1317
+ $result['invalid_users'] = htmlentities( implode( ', ', $invalidUsers ) );
1318
+ }
1319
+
1320
+ if ( count( $validUsers ) > 0 ) {
1321
+ $opts['liveTraf_ignoreUsers'] = implode( ',', $validUsers );
1322
+ } else {
1323
+ $opts['liveTraf_ignoreUsers'] = '';
1324
+ }
1325
+
1326
+ if ( ! $opts['other_WFNet'] ) {
1327
+ $wfdb = new wfDB();
1328
+ global $wpdb;
1329
+ $p = $wpdb->base_prefix;
1330
+ $wfdb->queryWrite( "delete from $p" . 'wfBlocks where wfsn=1 and permanent=0' );
1331
+ }
1332
+
1333
+ $regenerateHtaccess = false;
1334
+ if ( wfConfig::get( 'bannedURLs', false ) !== $opts['bannedURLs'] ) {
1335
+ $regenerateHtaccess = true;
1336
+ }
1337
+
1338
+ foreach ( $opts as $key => $val ) {
1339
+ if ( in_array( $key, self::$options_filter ) ) {
1340
+ if ( 'apiKey' !== $key ) { //Don't save API key yet
1341
+ wfConfig::set( $key, $val );
1342
+ }
1343
+ }
1344
+ }
1345
+
1346
+ if ( $regenerateHtaccess && ( wfConfig::get('cacheType') == 'falcon' ) ) {
1347
+ wfCache::addHtaccessCode('add');
1348
+ }
1349
+
1350
+ if ( '1' === $opts['autoUpdate'] ) {
1351
+ wfConfig::enableAutoUpdate();
1352
+ } else if ( '0' === $opts['autoUpdate'] ) {
1353
+ wfConfig::disableAutoUpdate();
1354
+ }
1355
+
1356
+ if (isset($opts['disableCodeExecutionUploads'])) {
1357
+ try {
1358
+ if ( $opts['disableCodeExecutionUploads'] ) {
1359
+ wfConfig::disableCodeExecutionForUploads();
1360
+ } else {
1361
+ wfConfig::removeCodeExecutionProtectionForUploads();
1362
+ }
1363
+ } catch ( wfConfigException $e ) {
1364
+ return array( 'error' => $e->getMessage() );
1365
+ }
1366
+ }
1367
+
1368
+ if (isset($opts['email_summary_enabled'])) {
1369
+ if ( ! empty( $opts['email_summary_enabled'] ) ) {
1370
+ wfConfig::set( 'email_summary_enabled', 1 );
1371
+ wfConfig::set( 'email_summary_interval', $opts['email_summary_interval'] );
1372
+ wfConfig::set( 'email_summary_excluded_directories', $opts['email_summary_excluded_directories'] );
1373
+ wfActivityReport::scheduleCronJob();
1374
+ } else {
1375
+ wfConfig::set( 'email_summary_enabled', 0 );
1376
+ wfActivityReport::disableCronJob();
1377
+ }
1378
+ }
1379
+
1380
+ $sch = isset( $opts['scheduleScan'] ) ? $opts['scheduleScan'] : '';
1381
+ if ( get_option( 'mainwp_child_wordfence_cron_time' ) !== $sch ) {
1382
+ update_option( 'mainwp_child_wordfence_cron_time', $sch );
1383
+ $sched = wp_next_scheduled( 'mainwp_child_wordfence_cron_scan' );
1384
+ if ( false !== $sched ) {
1385
+ wp_unschedule_event( $sched, 'mainwp_child_wordfence_cron_scan' );
1386
+ }
1387
+ }
1388
+
1389
+ $result['cacheType'] = wfConfig::get( 'cacheType' );
1390
+ $result['paidKeyMsg'] = false;
1391
+ $apiKey = trim( $_POST['apiKey'] );
1392
+ if ( ! $apiKey ) { //Empty API key (after trim above), then try to get one.
1393
+ $api = new wfAPI( '', wfUtils::getWPVersion() );
1394
+ try {
1395
+ $keyData = $api->call( 'get_anon_api_key' );
1396
+ if ( $keyData['ok'] && $keyData['apiKey'] ) {
1397
+ wfConfig::set( 'apiKey', $keyData['apiKey'] );
1398
+ wfConfig::set( 'isPaid', 0 );
1399
+ $result['apiKey'] = $keyData['apiKey'];
1400
+ $result['isPaid'] = 0;
1401
+ $reload = 'reload';
1402
+ } else {
1403
+ throw new Exception( "We could not understand the Wordfence server's response because it did not contain an 'ok' and 'apiKey' element." );
1404
+ }
1405
+ } catch ( Exception $e ) {
1406
+ $result['error'] = 'Your options have been saved, but we encountered a problem. You left your API key blank, so we tried to get you a free API key from the Wordfence servers. However we encountered a problem fetching the free key: ' . htmlentities( $e->getMessage() );
1407
+
1408
+ return $result;
1409
+ }
1410
+ } else if ( wfConfig::get( 'apiKey' ) !== $apiKey ) {
1411
+ $api = new wfAPI( $apiKey, wfUtils::getWPVersion() );
1412
+ try {
1413
+ $res = $api->call( 'check_api_key', array(), array() );
1414
+ if ( $res['ok'] && isset( $res['isPaid'] ) ) {
1415
+ wfConfig::set( 'apiKey', $apiKey );
1416
+ wfConfig::set( 'isPaid', $res['isPaid'] ); //res['isPaid'] is boolean coming back as JSON and turned back into PHP struct. Assuming JSON to PHP handles bools.
1417
+ $result['apiKey'] = $apiKey;
1418
+ $result['isPaid'] = $res['isPaid'];
1419
+ if ( $res['isPaid'] ) {
1420
+ $result['paidKeyMsg'] = true;
1421
+ }
1422
+ $reload = 'reload';
1423
+ } else {
1424
+ throw new Exception( 'We could not understand the Wordfence API server reply when updating your API key.' );
1425
+ }
1426
+ } catch ( Exception $e ) {
1427
+ $result['error'] = 'Your options have been saved. However we noticed you changed your API key and we tried to verify it with the Wordfence servers and received an error: ' . htmlentities( $e->getMessage() );
1428
+
1429
+ return $result;
1430
+ }
1431
+ } else {
1432
+ try {
1433
+ $api = new wfAPI( $apiKey, wfUtils::getWPVersion() );
1434
+ $res = $api->call( 'ping_api_key', array(), array() );
1435
+ } catch ( Exception $e ) {
1436
+ $result['error'] = 'Your options have been saved. However we noticed you do not change your API key and we tried to verify it with the Wordfence servers and received an error: ' . htmlentities( $e->getMessage() );
1437
+
1438
+ return $result;
1439
+ }
1440
+ }
1441
+ $result['ok'] = 1;
1442
+ $result['reload'] = $reload;
1443
+
1444
+ return $result;
1445
+ }
1446
+ }
1447
+
1448
+ public function export_settings(){
1449
+ /** @var wpdb $wpdb */
1450
+ global $wpdb;
1451
+
1452
+ $keys = wfConfig::getExportableOptionsKeys();
1453
+ $export = array();
1454
+ foreach($keys as $key){
1455
+ $export[$key] = wfConfig::get($key, '');
1456
+ }
1457
+ $export['scanScheduleJSON'] = json_encode(wfConfig::get_ser('scanSched', array()));
1458
+ $export['schedMode'] = wfConfig::get('schedMode', '');
1459
+
1460
+ // Any user supplied blocked IPs.
1461
+ $export['_blockedIPs'] = $wpdb->get_results('SELECT *, HEX(IP) as IP FROM ' . $wpdb->base_prefix . 'wfBlocks WHERE wfsn = 0 AND permanent = 1');
1462
+
1463
+ // Any advanced blocking stuff too.
1464
+ $export['_advancedBlocking'] = $wpdb->get_results('SELECT * FROM ' . $wpdb->base_prefix . 'wfBlocksAdv');
1465
+
1466
+ try {
1467
+ $api = new wfAPI(wfConfig::get('apiKey'), wfUtils::getWPVersion());
1468
+ $res = $api->call('export_options', array(), $export);
1469
+ if($res['ok'] && $res['token']){
1470
+ return array(
1471
+ 'ok' => 1,
1472
+ 'token' => $res['token'],
1473
+ );
1474
+ } else {
1475
+ throw new Exception("Invalid response: " . var_export($res, true));
1476
+ }
1477
+ } catch(Exception $e){
1478
+ return array('errorExport' => "An error occurred: " . $e->getMessage());
1479
+ }
1480
+ }
1481
+
1482
+ public function import_settings(){
1483
+ $token = $_POST['token'];
1484
+ try {
1485
+ $totalSet = wordfence::importSettings($token);
1486
+ return array(
1487
+ 'ok' => 1,
1488
+ 'totalSet' => $totalSet,
1489
+ 'settings' => $this->get_settings()
1490
+ );
1491
+ } catch(Exception $e){
1492
+ return array('errorImport' => "An error occurred: " . $e->getMessage());
1493
+ }
1494
+ }
1495
+
1496
+ function get_settings() {
1497
+ $keys = wfConfig::getExportableOptionsKeys();
1498
+ $settings = array();
1499
+ foreach($keys as $key){
1500
+ $settings[$key] = wfConfig::get($key, '');
1501
+ }
1502
+ $settings['apiKey'] = wfConfig::get('apiKey'); //get more apiKey
1503
+ $settings['isPaid'] = wfConfig::get('isPaid');
1504
+ return $settings;
1505
+ }
1506
+
1507
+ function ticker() {
1508
+ $wfdb = new wfDB();
1509
+ global $wpdb;
1510
+ $p = $wpdb->base_prefix;
1511
+
1512
+ $serverTime = $wfdb->querySingle( 'select unix_timestamp()' );
1513
+
1514
+ $jsonData = array(
1515
+ 'serverTime' => $serverTime,
1516
+ 'serverMicrotime' => microtime(true),
1517
+ 'msg' => $wfdb->querySingle( "select msg from $p" . 'wfStatus where level < 3 order by ctime desc limit 1' ),
1518
+ );
1519
+
1520
+ $events = array();
1521
+ $alsoGet = $_POST['alsoGet'];
1522
+ if ( preg_match( '/^logList_(404|hit|human|ruser|crawler|gCrawler|loginLogout)$/', $alsoGet, $m ) ) {
1523
+ $type = $m[1];
1524
+ $newestEventTime = $_POST['otherParams'];
1525
+ $listType = 'hits';
1526
+ if ( 'loginLogout' === $type ) {
1527
+ $listType = 'logins';
1528
+ }
1529
+ $events = wordfence::getLog()->getHits( $listType, $type, $newestEventTime );
1530
+ } else if ( 'perfStats' === $alsoGet ) {
1531
+ $newestEventTime = $_POST['otherParams'];
1532
+ $events = wordfence::getLog()->getPerfStats( $newestEventTime );
1533
+ } else if ($alsoGet == 'liveTraffic') {
1534
+ if (get_site_option('wordfence_syncAttackDataAttempts') > 10) {
1535
+ wordfence::syncAttackData(false);
1536
+ }
1537
+ $results = wordfence::ajax_loadLiveTraffic_callback();
1538
+ $events = $results['data'];
1539
+ if (isset($results['sql'])) {
1540
+ $jsonData['sql'] = $results['sql'];
1541
+ }
1542
+ }
1543
+ $jsonData['events'] = $events;
1544
+ $jsonData['alsoGet'] = $alsoGet; //send it back so we don't load data if panel has changed
1545
+ $jsonData['cacheType'] = wfConfig::get( 'cacheType' );
1546
+ return $jsonData;
1547
+ }
1548
+
1549
+ public static function loadLiveTraffic() {
1550
+ $wfdb = new wfDB();
1551
+ $serverTime = $wfdb->querySingle( 'select unix_timestamp()' );
1552
+ $return = wordfence::ajax_loadLiveTraffic_callback();
1553
+ $return['serverTime'] = $serverTime;
1554
+ $return['serverMicrotime'] = microtime(true);
1555
+ return $return;
1556
+ }
1557
+
1558
+ function whitelistWAFParamKey() {
1559
+ $return = wordfence::ajax_whitelistWAFParamKey_callback();
1560
+ return $return;
1561
+ }
1562
+
1563
+ function hideFileHtaccess() {
1564
+ $return = wordfence::ajax_hideFileHtaccess_callback();
1565
+ return $return;
1566
+ }
1567
+
1568
+ public static function fixFPD(){
1569
+ $return = wordfence::ajax_fixFPD_callback();
1570
+ return $return;
1571
+ }
1572
+
1573
+ public static function disableDirectoryListing() {
1574
+ $return = wordfence::ajax_disableDirectoryListing_callback();
1575
+ return $return;
1576
+ }
1577
+
1578
+ public static function deleteDatabaseOption() {
1579
+ $return = wordfence::ajax_deleteDatabaseOption_callback();
1580
+ return $return;
1581
+ }
1582
+
1583
+ public static function misconfiguredHowGetIPsChoice() {
1584
+ $return = wordfence::ajax_misconfiguredHowGetIPsChoice_callback();
1585
+ return $return;
1586
+ }
1587
+
1588
+ public static function deleteAdminUser() {
1589
+ $return = wordfence::ajax_deleteAdminUser_callback();
1590
+ return $return;
1591
+ }
1592
+
1593
+ public static function revokeAdminUser() {
1594
+ $return = wordfence::ajax_revokeAdminUser_callback();
1595
+ return $return;
1596
+ }
1597
+
1598
+ public static function clearAllBlocked() {
1599
+ $return = wordfence::ajax_clearAllBlocked_callback();
1600
+ return $return;
1601
+ }
1602
+
1603
+ public static function permanentlyBlockAllIPs() {
1604
+ $return = wordfence::ajax_permanentlyBlockAllIPs_callback();
1605
+ return $return;
1606
+ }
1607
+
1608
+ public static function unlockOutIP() {
1609
+ $return = wordfence::ajax_unlockOutIP_callback();
1610
+ return $return;
1611
+ }
1612
+
1613
+ public static function unblockRange() {
1614
+ $return = wordfence::ajax_unblockRange_callback();
1615
+ return $return;
1616
+ }
1617
+
1618
+ public static function blockIPUARange() {
1619
+ $return = wordfence::ajax_blockIPUARange_callback();
1620
+ return $return;
1621
+ }
1622
+
1623
+ public static function loadBlockRanges() {
1624
+ $return = wordfence::ajax_loadBlockRanges_callback();
1625
+ return $return;
1626
+ }
1627
+
1628
+ public static function saveWAFConfig() {
1629
+ $return = wordfence::ajax_saveWAFConfig_callback();
1630
+ if (is_array($return) && isset($return['data'])) {
1631
+ $return['learningModeGracePeriod'] = wfWAF::getInstance()->getStorageEngine()->getConfig('learningModeGracePeriod');
1632
+ }
1633
+ return $return;
1634
+ }
1635
+
1636
+ public static function whitelistBulkDelete() {
1637
+ $return = wordfence::ajax_whitelistBulkDelete_callback();
1638
+ return $return;
1639
+ }
1640
+
1641
+ public static function whitelistBulkEnable() {
1642
+ $return = wordfence::ajax_whitelistBulkEnable_callback();
1643
+ return $return;
1644
+ }
1645
+
1646
+ public static function whitelistBulkDisable() {
1647
+ $return = wordfence::ajax_whitelistBulkDisable_callback();
1648
+ return $return;
1649
+ }
1650
+ public static function updateConfig() {
1651
+ $return = wordfence::ajax_updateConfig_callback();
1652
+ return $return;
1653
+ }
1654
+
1655
+ // credit of Wordfence
1656
+ private static function _getWAFData($updated = null) {
1657
+ // custom
1658
+ if(!class_exists('wfWAF'))
1659
+ return false;
1660
+ // end if custom
1661
+
1662
+ $data['learningMode'] = wfWAF::getInstance()->isInLearningMode();
1663
+ $data['rules'] = wfWAF::getInstance()->getRules();
1664
+ /** @var wfWAFRule $rule */
1665
+ foreach ($data['rules'] as $ruleID => $rule) {
1666
+ $data['rules'][$ruleID] = $rule->toArray();
1667
+ }
1668
+
1669
+ $whitelistedURLParams = wfWAF::getInstance()->getStorageEngine()->getConfig('whitelistedURLParams', array());
1670
+ $data['whitelistedURLParams'] = array();
1671
+ foreach ($whitelistedURLParams as $urlParamKey => $rules) {
1672
+ list($path, $paramKey) = explode('|', $urlParamKey);
1673
+ $whitelistData = null;
1674
+ foreach ($rules as $ruleID => $whitelistedData) {
1675
+ if ($whitelistData === null) {
1676
+ $whitelistData = $whitelistedData;
1677
+ continue;
1678
+ }
1679
+ if ($ruleID === 'all') {
1680
+ $whitelistData = $whitelistedData;
1681
+ break;
1682
+ }
1683
+ }
1684
+
1685
+ if (is_array($whitelistData) && array_key_exists('userID', $whitelistData) && function_exists('get_user_by')) {
1686
+ $user = get_user_by('id', $whitelistData['userID']);
1687
+ if ($user) {
1688
+ $whitelistData['username'] = $user->user_login;
1689
+ }
1690
+ }
1691
+
1692
+ $data['whitelistedURLParams'][] = array(
1693
+ 'path' => $path,
1694
+ 'paramKey' => $paramKey,
1695
+ 'ruleID' => array_keys($rules),
1696
+ 'data' => $whitelistData,
1697
+ );
1698
+ }
1699
+
1700
+ $data['disabledRules'] = (array) wfWAF::getInstance()->getStorageEngine()->getConfig('disabledRules');
1701
+ if ($lastUpdated = wfWAF::getInstance()->getStorageEngine()->getConfig('rulesLastUpdated')) {
1702
+ $data['rulesLastUpdated'] = $lastUpdated;
1703
+ }
1704
+ $data['isPaid'] = (bool) wfConfig::get('isPaid', 0);
1705
+
1706
+ if ($updated !== null) {
1707
+ $data['updated'] = (bool) $updated;
1708
+ }
1709
+ return $data;
1710
+ }
1711
+
1712
+
1713
+ function reverse_lookup() {
1714
+ $ips = explode( ',', $_POST['ips'] );
1715
+ $res = array();
1716
+ foreach ( $ips as $ip ) {
1717
+ $res[ $ip ] = wfUtils::reverseLookup( $ip );
1718
+ }
1719
+
1720
+ return array( 'ok' => 1, 'ips' => $res );
1721
+ }
1722
+
1723
+
1724
+ public function saveOptions(){
1725
+ if (!empty($_POST['changes']) && ($changes = json_decode(stripslashes($_POST['changes']), true)) !== false) {
1726
+ try {
1727
+ if (is_array($changes) && isset($changes['whitelistedURLParams']) && isset($changes['whitelistedURLParams']['add'])) {
1728
+ $user = wp_get_current_user();
1729
+ foreach($changes['whitelistedURLParams']['add'] as $key => &$value) :
1730
+ if (isset($value['data'])) {
1731
+
1732
+ if(isset($value['data']['userID'])) {
1733
+ $value['data']['userID'] = $user->ID;
1734
+ }
1735
+ if(isset($value['data']['username'])) {
1736
+ $value['data']['username'] = $user->user_login;
1737
+ }
1738
+ }
1739
+ endforeach;
1740
+ }
1741
+
1742
+ $errors = wfConfig::validate($changes);
1743
+
1744
+ if ($errors !== true) {
1745
+ if (count($errors) == 1) {
1746
+ return array(
1747
+ 'error' => sprintf(__('An error occurred while saving the configuration: %s', 'wordfence'), $errors[0]['error']),
1748
+ );
1749
+ }
1750
+ else if (count($errors) > 1) {
1751
+ $compoundMessage = array();
1752
+ foreach ($errors as $e) {
1753
+ $compoundMessage[] = $e['error'];
1754
+ }
1755
+ return array(
1756
+ 'error' => sprintf(__('Errors occurred while saving the configuration: %s', 'wordfence'), implode(', ', $compoundMessage)),
1757
+ );
1758
+ }
1759
+
1760
+ return array(
1761
+ 'error' => __('Errors occurred while saving the configuration.', 'wordfence'),
1762
+ );
1763
+ }
1764
+
1765
+ wfConfig::save($changes);
1766
+ return array('success' => true);
1767
+ }
1768
+ catch (wfWAFStorageFileException $e) {
1769
+ return array(
1770
+ 'error' => __('An error occurred while saving the configuration.', 'wordfence'),
1771
+ );
1772
+ }
1773
+ catch (Exception $e) {
1774
+ return array(
1775
+ 'error' => $e->getMessage(),
1776
+ );
1777
+ }
1778
+ }
1779
+
1780
+ return array(
1781
+ 'error' => __('No configuration changes were provided to save.', 'wordfence'),
1782
+ );
1783
+ }
1784
+
1785
+ public function ajax_getBlocks_callback(){
1786
+ $information = wordfence::ajax_getBlocks_callback();
1787
+ return $information;
1788
+ }
1789
+ // credit of Wordfence
1790
+ public function ajax_createBlock_callback()
1791
+ {
1792
+ return wordfence::ajax_createBlock_callback();
1793
+ }
1794
+
1795
+ public static function ajax_deleteBlocks_callback() {
1796
+ $information = wordfence::ajax_deleteBlocks_callback();
1797
+ return $information;
1798
+ }
1799
+
1800
+ public static function ajax_makePermanentBlocks_callback() {
1801
+ $information = wordfence::ajax_makePermanentBlocks_callback();
1802
+ return $information;
1803
+ }
1804
+
1805
+ public function ajax_blockIP_callback(){
1806
+ return wordfence::ajax_blockIP_callback();
1807
+ }
1808
+
1809
+ // credit of Wordfence
1810
+ public function whois(){
1811
+ return wordfence::ajax_whois_callback();
1812
+ }
1813
+
1814
+ function unblock_ip() {
1815
+ if ( isset( $_POST['IP'] ) ) {
1816
+ $IP = $_POST['IP'];
1817
+ wfBlock::unblockIP( $IP );
1818
+ return array( 'ok' => 1 );
1819
+ }
1820
+ }
1821
+
1822
+ public static function saveCountryBlocking(){
1823
+ if(! wfConfig::get('isPaid')){
1824
+ return array('error' => "Sorry but this feature is only available for paid customers.");
1825
+ }
1826
+ $settings = $_POST['settings'];
1827
+ wfConfig::set('cbl_action', $settings['blockAction']);
1828
+ wfConfig::set('cbl_countries', $settings['codes']);
1829
+ wfConfig::set('cbl_redirURL', $settings['redirURL']);
1830
+ wfConfig::set('cbl_loggedInBlocked', $settings['loggedInBlocked']);
1831
+ wfConfig::set('cbl_loginFormBlocked', $settings['loginFormBlocked']);
1832
+ wfConfig::set('cbl_restOfSiteBlocked', $settings['restOfSiteBlocked']);
1833
+ wfConfig::set('cbl_bypassRedirURL', $settings['bypassRedirURL']);
1834
+ wfConfig::set('cbl_bypassRedirDest', $settings['bypassRedirDest']);
1835
+ wfConfig::set('cbl_bypassViewURL', $settings['bypassViewURL']);
1836
+ return array('ok' => 1);
1837
+ }
1838
+
1839
+ public function load_static_panel() {
1840
+ $mode = $_POST['mode'];
1841
+ $wfLog = wordfence::getLog();
1842
+ if ( 'topScanners' === $mode || 'topLeechers' === $mode ) {
1843
+ $results = $wfLog->getLeechers( $mode );
1844
+ } else if ( 'blockedIPs' === $mode ) {
1845
+ $results = $wfLog->getBlockedIPs();
1846
+ } else if ( 'lockedOutIPs' === $mode ) {
1847
+ $results = $wfLog->getLockedOutIPs();
1848
+ } else if ( 'throttledIPs' === $mode ) {
1849
+ $results = $wfLog->getThrottledIPs();
1850
+ }
1851
+
1852
+ return array( 'ok' => 1, 'results' => $results );
1853
+ }
1854
+
1855
+ public function downgrade_license() {
1856
+ $api = new wfAPI( '', wfUtils::getWPVersion() );
1857
+ $return = array();
1858
+ try {
1859
+ $keyData = $api->call( 'get_anon_api_key' );
1860
+ if ( $keyData['ok'] && $keyData['apiKey'] ) {
1861
+ wfConfig::set( 'apiKey', $keyData['apiKey'] );
1862
+ wfConfig::set( 'isPaid', 0 );
1863
+ $return['apiKey'] = $keyData['apiKey'];
1864
+ $return['isPaid'] = 0;
1865
+ //When downgrading we must disable all two factor authentication because it can lock an admin out if we don't.
1866
+ wfConfig::set_ser( 'twoFactorUsers', array() );
1867
+ } else {
1868
+ throw new Exception( 'Could not understand the response we received from the Wordfence servers when applying for a free API key.' );
1869
+ }
1870
+ } catch ( Exception $e ) {
1871
+ $return['errorMsg'] = 'Could not fetch free API key from Wordfence: ' . htmlentities( $e->getMessage() );
1872
+
1873
+ return $return;
1874
+ }
1875
+ $return['ok'] = 1;
1876
+
1877
+ return $return;
1878
+ }
1879
+
1880
+ public static function saveCacheConfig(){
1881
+ $noEditHtaccess = '1';
1882
+ if (isset($_POST['needToCheckFalconHtaccess']) && !empty($_POST['needToCheckFalconHtaccess'])) {
1883
+ $checkHtaccess = self::checkFalconHtaccess();
1884
+ if (isset($checkHtaccess['ok']))
1885
+ $noEditHtaccess = '0';
1886
+ } else if (isset($_POST['noEditHtaccess'])) {
1887
+ $noEditHtaccess = $_POST['noEditHtaccess'];
1888
+ }
1889
+
1890
+ $cacheType = $_POST['cacheType'];
1891
+ if($cacheType == 'falcon' || $cacheType == 'php'){
1892
+ $plugins = get_plugins();
1893
+ $badPlugins = array();
1894
+ foreach($plugins as $pluginFile => $data){
1895
+ if(is_plugin_active($pluginFile)){
1896
+ if($pluginFile == 'w3-total-cache/w3-total-cache.php'){
1897
+ $badPlugins[] = "W3 Total Cache";
1898
+ } else if($pluginFile == 'quick-cache/quick-cache.php'){
1899
+ $badPlugins[] = "Quick Cache";
1900
+ } else if($pluginFile == "wp-super-cache/wp-cache.php"){
1901
+ $badPlugins[] = "WP Super Cache";
1902
+ } else if($pluginFile == "wp-fast-cache/wp-fast-cache.php"){
1903
+ $badPlugins[] = "WP Fast Cache";
1904
+ } else if($pluginFile == "wp-fastest-cache/wpFastestCache.php"){
1905
+ $badPlugins[] = "WP Fastest Cache";
1906
+ }
1907
+ }
1908
+ }
1909
+ if(count($badPlugins) > 0){
1910
+ return array('errorMsg' => "You can not enable caching in Wordfence with other caching plugins enabled. This may cause conflicts. You need to disable other caching plugins first. Wordfence caching is very fast and does not require other caching plugins to be active. The plugins you have that conflict are: " . implode(', ', $badPlugins) . ". Disable these plugins, then return to this page and enable Wordfence caching.");
1911
+ }
1912
+ $siteURL = site_url();
1913
+ if(preg_match('/^https?:\/\/[^\/]+\/[^\/]+\/[^\/]+\/.+/i', $siteURL)){
1914
+ return array('errorMsg' => "Wordfence caching currently does not support sites that are installed in a subdirectory and have a home page that is more than 2 directory levels deep. e.g. we don't support sites who's home page is http://example.com/levelOne/levelTwo/levelThree");
1915
+ }
1916
+ }
1917
+ if($cacheType == 'falcon'){
1918
+ if(! get_option('permalink_structure', '')){
1919
+ return array('errorMsg' => "You need to enable Permalinks for your site to use Falcon Engine. You can enable Permalinks in WordPress by going to the Settings - Permalinks menu and enabling it there. Permalinks change your site URL structure from something that looks like /p=123 to pretty URLs like /my-new-post-today/ that are generally more search engine friendly.");
1920
+ }
1921
+ }
1922
+ $warnHtaccess = false;
1923
+ if($cacheType == 'disable' || $cacheType == 'php'){
1924
+ $removeError = wfCache::addHtaccessCode('remove');
1925
+ $removeError2 = wfCache::updateBlockedIPs('remove');
1926
+ if($removeError || $removeError2){
1927
+ $warnHtaccess = true;
1928
+ }
1929
+ }
1930
+ if($cacheType == 'php' || $cacheType == 'falcon'){
1931
+ $err = wfCache::cacheDirectoryTest();
1932
+ if($err){
1933
+ return array('ok' => 1, 'heading' => "Could not write to cache directory", 'body' => "To enable caching, Wordfence needs to be able to create and write to the /wp-content/wfcache/ directory. We did some tests that indicate this is not possible. You need to manually create the /wp-content/wfcache/ directory and make it writable by Wordfence. The error we encountered was during our tests was: $err");
1934
+ }
1935
+ }
1936
+
1937
+ //Mainly we clear the cache here so that any footer cache diagnostic comments are rebuilt. We could just leave it intact unless caching is being disabled.
1938
+ if($cacheType != wfConfig::get('cacheType', false)){
1939
+ wfCache::scheduleCacheClear();
1940
+ }
1941
+ $htMsg = "";
1942
+ if($warnHtaccess){
1943
+ $htMsg = " <strong style='color: #F00;'>Warning: We could not remove the caching code from your .htaccess file. you need to remove this manually yourself.</strong> ";
1944
+ }
1945
+ if($cacheType == 'disable'){
1946
+ wfConfig::set('cacheType', false);
1947
+ return array('ok' => 1, 'heading' => "Caching successfully disabled.", 'body' => "{$htMsg}Caching has been disabled on your system.<br /><br /><center><input type='button' name='wfReload' value='Click here now to refresh this page' onclick='window.location.reload(true);' /></center>");
1948
+ } else if($cacheType == 'php'){
1949
+ wfConfig::set('cacheType', 'php');
1950
+ return array('ok' => 1, 'heading' => "Wordfence Basic Caching Enabled", 'body' => "{$htMsg}Wordfence basic caching has been enabled on your system.<br /><br /><center><input type='button' name='wfReload' value='Click here now to refresh this page' onclick='window.location.reload(true);' /></center>");
1951
+ } else if($cacheType == 'falcon'){
1952
+ if($noEditHtaccess != '1'){
1953
+ $err = wfCache::addHtaccessCode('add');
1954
+ if($err){
1955
+ return array('ok' => 1, 'heading' => "Wordfence could not edit .htaccess", 'body' => "Wordfence could not edit your .htaccess code. The error was: " . $err);
1956
+ }
1957
+ }
1958
+ wfConfig::set('cacheType', 'falcon');
1959
+ wfCache::scheduleUpdateBlockedIPs(); //Runs every 5 mins until we change cachetype
1960
+ return array('ok' => 1, 'heading' => "Wordfence Falcon Engine Activated!", 'body' => "Wordfence Falcon Engine has been activated on your system. You will see this icon appear on the Wordfence admin pages as long as Falcon is active indicating your site is running in high performance mode:<div class='wfFalconImage'></div><center><input type='button' name='wfReload' value='Click here now to refresh this page' onclick='window.location.reload(true);' /></center>");
1961
+ }
1962
+ return array('errorMsg' => "An error occurred.");
1963
+ }
1964
+
1965
+ public static function checkFalconHtaccess(){
1966
+ if(wfUtils::isNginx()){
1967
+ return array('nginx' => 1);
1968
+ }
1969
+ $file = wfCache::getHtaccessPath();
1970
+ if(! $file){
1971
+ return array('err' => "We could not find your .htaccess file to modify it.", 'code' => wfCache::getHtaccessCode() );
1972
+ }
1973
+ $fh = @fopen($file, 'r+');
1974
+ if(! $fh){
1975
+ $err = error_get_last();
1976
+ return array('err' => "We found your .htaccess file but could not open it for writing: " . $err['message'], 'code' => wfCache::getHtaccessCode() );
1977
+ }
1978
+ $download_url = admin_url( 'admin-ajax.php' ) . '?action=mainwp_wordfence_download_htaccess&_wpnonce=' . MainWP_Helper::create_nonce_without_session( 'mainwp_download_htaccess' );
1979
+ return array( 'ok' => 1 , 'download_url' => $download_url );
1980
+ }
1981
+
1982
+ public static function checkHtaccess(){
1983
+ if(wfUtils::isNginx()){
1984
+ return array('nginx' => 1);
1985
+ }
1986
+ $file = wfCache::getHtaccessPath();
1987
+ if(! $file){
1988
+ return array('err' => "We could not find your .htaccess file to modify it.");
1989
+ }
1990
+ $fh = @fopen($file, 'r+');
1991
+ if(! $fh){
1992
+ $err = error_get_last();
1993
+ return array('err' => "We found your .htaccess file but could not open it for writing: " . $err['message']);
1994
+ }
1995
+ return array('ok' => 1);
1996
+ }
1997
+
1998
+ public static function downloadHtaccess() {
1999
+ if ( ! isset( $_GET['_wpnonce'] ) || empty( $_GET['_wpnonce'] ) ) {
2000
+ die( '-1' );
2001
+ }
2002
+
2003
+ if ( ! MainWP_Helper::verify_nonce_without_session( $_GET['_wpnonce'], 'mainwp_download_htaccess' ) ) {
2004
+ die( '-2' );
2005
+ }
2006
+
2007
+ $url = site_url();
2008
+ $url = preg_replace('/^https?:\/\//i', '', $url);
2009
+ $url = preg_replace('/[^a-zA-Z0-9\.]+/', '_', $url);
2010
+ $url = preg_replace('/^_+/', '', $url);
2011
+ $url = preg_replace('/_+$/', '', $url);
2012
+ header('Content-Type: application/octet-stream');
2013
+ header('Content-Disposition: attachment; filename="htaccess_Backup_for_' . $url . '.txt"');
2014
+ $file = wfCache::getHtaccessPath();
2015
+ readfile($file);
2016
+ die();
2017
+ }
2018
+
2019
+ public static function saveCacheOptions(){
2020
+ $changed = false;
2021
+ if($_POST['allowHTTPSCaching'] != wfConfig::get('allowHTTPSCaching', false)){
2022
+ $changed = true;
2023
+ }
2024
+ wfConfig::set('allowHTTPSCaching', $_POST['allowHTTPSCaching'] == '1' ? 1 : 0);
2025
+ //wfConfig::set('addCacheComment', $_POST['addCacheComment'] == 1 ? '1' : 0);
2026
+ wfConfig::set('clearCacheSched', $_POST['clearCacheSched'] == 1 ? '1' : 0);
2027
+ if($changed && wfConfig::get('cacheType', false) == 'falcon'){
2028
+ $err = wfCache::addHtaccessCode('add');
2029
+ if($err){
2030
+ return array('updateErr' => "Wordfence could not edit your .htaccess file. The error was: " . $err, 'code' => wfCache::getHtaccessCode() );
2031
+ }
2032
+ }
2033
+ wfCache::scheduleCacheClear();
2034
+ return array('ok' => 1);
2035
+ }
2036
+
2037
+ public static function clearPageCache(){
2038
+ $stats = wfCache::clearPageCache();
2039
+ if($stats['error']){
2040
+ $body = "A total of " . $stats['totalErrors'] . " errors occurred while trying to clear your cache. The last error was: " . $stats['error'];
2041
+ return array('ok' => 1, 'heading' => 'Error occurred while clearing cache', 'body' => $body );
2042
+ }
2043
+ $body = "A total of " . $stats['filesDeleted'] . ' files were deleted and ' . $stats['dirsDeleted'] . ' directories were removed. We cleared a total of ' . $stats['totalData'] . 'KB of data in the cache.';
2044
+ if($stats['totalErrors'] > 0){
2045
+ $body .= ' A total of ' . $stats['totalErrors'] . ' errors were encountered. This probably means that we could not remove some of the files or directories in the cache. Please use your CPanel or file manager to remove the rest of the files in the directory: ' . WP_CONTENT_DIR . '/wfcache/';
2046
+ }
2047
+ return array('ok' => 1, 'heading' => 'Page Cache Cleared', 'body' => $body );
2048
+ }
2049
+
2050
+ public static function getCacheStats(){
2051
+ $s = wfCache::getCacheStats();
2052
+ if($s['files'] == 0){
2053
+ return array('ok' => 1, 'heading' => 'Cache Stats', 'body' => "The cache is currently empty. It may be disabled or it may have been recently cleared.");
2054
+ }
2055
+ $body = 'Total files in cache: ' . $s['files'] .
2056
+ '<br />Total directories in cache: ' . $s['dirs'] .
2057
+ '<br />Total data: ' . $s['data'] . 'KB';
2058
+ if($s['compressedFiles'] > 0){
2059
+ $body .= '<br />Files: ' . $s['uncompressedFiles'] .
2060
+ '<br />Data: ' . $s['uncompressedKBytes'] . 'KB' .
2061
+ '<br />Compressed files: ' . $s['compressedFiles'] .
2062
+ '<br />Compressed data: ' . $s['compressedKBytes'] . 'KB';
2063
+ }
2064
+ if($s['largestFile'] > 0){
2065
+ $body .= '<br />Largest file: ' . $s['largestFile'] . 'KB';
2066
+ }
2067
+ if($s['oldestFile'] !== false){
2068
+ $body .= '<br />Oldest file in cache created ';
2069
+ if(time() - $s['oldestFile'] < 300){
2070
+ $body .= (time() - $s['oldestFile']) . ' seconds ago';
2071
+ } else {
2072
+ $body .= human_time_diff($s['oldestFile']) . ' ago.';
2073
+ }
2074
+ }
2075
+ if($s['newestFile'] !== false){
2076
+ $body .= '<br />Newest file in cache created ';
2077
+ if(time() - $s['newestFile'] < 300){
2078
+ $body .= (time() - $s['newestFile']) . ' seconds ago';
2079
+ } else {
2080
+ $body .= human_time_diff($s['newestFile']) . ' ago.';
2081
+ }
2082
+ }
2083
+
2084
+ return array('ok' => 1, 'heading' => 'Cache Stats', 'body' => $body);
2085
+ }
2086
+
2087
+ public static function addCacheExclusion(){
2088
+ $ex = wfConfig::get('cacheExclusions', false);
2089
+ if($ex){
2090
+ $ex = unserialize($ex);
2091
+ } else {
2092
+ $ex = array();
2093
+ }
2094
+ if (isset($_POST['cacheExclusions'])) {
2095
+ $ex = $_POST['cacheExclusions'];
2096
+ } else {
2097
+ $ex[] = array(
2098
+ 'pt' => $_POST['patternType'],
2099
+ 'p' => $_POST['pattern'],
2100
+ 'id' => $_POST['id'],
2101
+ );
2102
+ }
2103
+ wfConfig::set('cacheExclusions', serialize($ex));
2104
+ wfCache::scheduleCacheClear();
2105
+ if(wfConfig::get('cacheType', false) == 'falcon' && preg_match('/^(?:uac|uaeq|cc)$/', $_POST['patternType'])){
2106
+ if(wfCache::addHtaccessCode('add')){ //rewrites htaccess rules
2107
+ return array('errorMsg' => "We added the rule you requested but could not modify your .htaccess file. Please delete this rule, check the permissions on your .htaccess file and then try again.", 'ex' => $ex);
2108
+ }
2109
+ }
2110
+ return array('ok' => 1, 'ex' => $ex);
2111
+ }
2112
+
2113
+ public static function loadCacheExclusions(){
2114
+ $ex = wfConfig::get('cacheExclusions', false);
2115
+ if(! $ex){
2116
+ return array('ex' => false);
2117
+ }
2118
+ $ex = unserialize($ex);
2119
+ return array('ok' => 1, 'ex' => $ex);
2120
+ }
2121
+
2122
+ public static function removeCacheExclusion(){
2123
+ $id = $_POST['id'];
2124
+ $ex = wfConfig::get('cacheExclusions', false);
2125
+ if(! $ex){
2126
+ return array('ok' => 1);
2127
+ }
2128
+ $ex = unserialize($ex);
2129
+ $rewriteHtaccess = false;
2130
+ $removed = false;
2131
+ for($i = 0; $i < sizeof($ex); $i++){
2132
+ if((string)$ex[$i]['id'] == (string)$id){
2133
+ if(wfConfig::get('cacheType', false) == 'falcon' && preg_match('/^(?:uac|uaeq|cc)$/', $ex[$i]['pt'])){
2134
+ $rewriteHtaccess = true;
2135
+ }
2136
+ array_splice($ex, $i, 1);
2137
+ //Dont break in case of dups
2138
+ $removed = true;
2139
+ }
2140
+ }
2141
+ $return = array('ex' => $ex);
2142
+ if (!$removed) {
2143
+ $return['error'] = "Not found the cache exclusion.";
2144
+ return $return;
2145
+ }
2146
+
2147
+ wfConfig::set('cacheExclusions', serialize($ex));
2148
+ if($rewriteHtaccess && wfCache::addHtaccessCode('add')){ //rewrites htaccess rules
2149
+ $return['errorMsg'] = "We removed that rule but could not rewrite your .htaccess file. You're going to have to manually remove this rule from your .htaccess file. Please reload this page now.";
2150
+ return $return;
2151
+ }
2152
+
2153
+ $return['ok'] = 1;
2154
+ return $return;
2155
+ }
2156
+
2157
+ public function getDiagnostics() {
2158
+
2159
+ $diagnostic = new wfDiagnostic;
2160
+ $plugins = get_plugins();
2161
+ $activePlugins = array_flip(get_option('active_plugins'));
2162
+ $activeNetworkPlugins = is_multisite() ? array_flip(wp_get_active_network_plugins()) : array();
2163
+ $muPlugins = get_mu_plugins();
2164
+ $themes = wp_get_themes();
2165
+ $currentTheme = wp_get_theme();
2166
+ $cols = 3;
2167
+
2168
+ $w = new wfConfig();
2169
+
2170
+ $inEmail = false;
2171
+ ob_start();
2172
+
2173
+ ?>
2174
+ <div id="wf-diagnostics">
2175
+
2176
+ <form id="wfConfigForm" style="overflow-x: auto;">
2177
+ <?php foreach ($diagnostic->getResults() as $title => $tests):
2178
+ $key = sanitize_key('wf-diagnostics-' . $title);
2179
+ $hasFailingTest = false;
2180
+ foreach ($tests['results'] as $result) {
2181
+ if (!$result['test']) {
2182
+ $hasFailingTest = true;
2183
+ break;
2184
+ }
2185
+ }
2186
+
2187
+ if ($inEmail): ?>
2188
+ <table>
2189
+ <thead>
2190
+ <tr>
2191
+ <th colspan="<?php echo $cols ?>"><?php echo esc_html(__($title, 'wordfence')) ?></th>
2192
+ </tr>
2193
+ </thead>
2194
+ <tbody>
2195
+ <?php foreach ($tests['results'] as $result): ?>
2196
+ <tr>
2197
+ <td style="width: 75%;"
2198
+ colspan="<?php echo $cols - 1 ?>"><?php echo wp_kses($result['label'], array(
2199
+ 'code' => array(),
2200
+ 'strong' => array(),
2201
+ 'em' => array(),
2202
+ 'a' => array('href' => true),
2203
+ )) ?></td>
2204
+ <td>
2205
+ <?php if ($result['test']): ?>
2206
+ <div class="wf-result-success"><?php echo esc_html($result['message']) ?></div>
2207
+ <?php else: ?>
2208
+ <div class="wf-result-error"><?php echo esc_html($result['message']) ?></div>
2209
+ <?php endif ?>
2210
+ </td>
2211
+ </tr>
2212
+ <?php endforeach ?>
2213
+ </tbody>
2214
+ </table>
2215
+ <?php else: ?>
2216
+ <div class="wf-block<?php echo (wfPersistenceController::shared()->isActive($key) ? ' wf-active' : '') .
2217
+ ($hasFailingTest ? ' wf-diagnostic-fail' : '') ?>" data-persistence-key="<?php echo esc_attr($key) ?>">
2218
+ <div class="wf-block-header">
2219
+ <div class="wf-block-header-content">
2220
+ <div class="wf-block-title">
2221
+ <strong><?php echo esc_html(__($title, 'wordfence')) ?></strong>
2222
+ <span class="wf-text-small"><?php echo esc_html(__($tests['description'], 'wordfence')) ?></span>
2223
+ </div>
2224
+ <div class="wf-block-header-action">
2225
+ <div class="wf-block-header-action-disclosure"></div>
2226
+ </div>
2227
+ </div>
2228
+ </div>
2229
+ <div class="wf-block-content wf-clearfix">
2230
+ <ul class="wf-block-list">
2231
+ <?php foreach ($tests['results'] as $result): ?>
2232
+ <li>
2233
+ <div style="width: 75%;"
2234
+ colspan="<?php echo $cols - 1 ?>"><?php echo wp_kses($result['label'], array(
2235
+ 'code' => array(),
2236
+ 'strong' => array(),
2237
+ 'em' => array(),
2238
+ 'a' => array('href' => true),
2239
+ )) ?></div>
2240
+ <?php if ($result['test']): ?>
2241
+ <div class="wf-result-success"><?php echo esc_html($result['message']) ?></div>
2242
+ <?php else: ?>
2243
+ <div class="wf-result-error"><?php echo esc_html($result['message']) ?></div>
2244
+ <?php endif ?>
2245
+ </li>
2246
+ <?php endforeach ?>
2247
+ </ul>
2248
+ </div>
2249
+ </div>
2250
+ <?php endif ?>
2251
+
2252
+ <?php endforeach ?>
2253
+ <?php
2254
+ $howGet = wfConfig::get('howGetIPs', false);
2255
+ list($currentIP, $currentServerVarForIP) = wfUtils::getIPAndServerVariable();
2256
+ $howGetHasErrors = false;
2257
+ foreach (array(
2258
+ 'REMOTE_ADDR' => 'REMOTE_ADDR',
2259
+ 'HTTP_CF_CONNECTING_IP' => 'CF-Connecting-IP',
2260
+ 'HTTP_X_REAL_IP' => 'X-Real-IP',
2261
+ 'HTTP_X_FORWARDED_FOR' => 'X-Forwarded-For',
2262
+ ) as $variable => $label) {
2263
+ if (!($currentServerVarForIP && $currentServerVarForIP === $variable) && $howGet === $variable) {
2264
+ $howGetHasErrors = true;
2265
+ break;
2266
+ }
2267
+ }
2268
+ ?>
2269
+ <div class="wf-block<?php echo ($howGetHasErrors ? ' wf-diagnostic-fail' : '') . (wfPersistenceController::shared()->isActive('wf-diagnostics-client-ip') ? ' wf-active' : '') ?>" data-persistence-key="<?php echo esc_attr('wf-diagnostics-client-ip') ?>">
2270
+ <div class="wf-block-header">
2271
+ <div class="wf-block-header-content">
2272
+ <div class="wf-block-title">
2273
+ <strong><?php _e('IP Detection', 'wordfence') ?></strong>
2274
+ <span class="wf-text-small"><?php _e('Methods of detecting a visitor\'s IP address.', 'wordfence') ?></span>
2275
+ </div>
2276
+ <div class="wf-block-header-action">
2277
+ <div class="wf-block-header-action-disclosure"></div>
2278
+ </div>
2279
+ </div>
2280
+ </div>
2281
+ <div class="wf-block-content wf-clearfix wf-padding-no-left wf-padding-no-right">
2282
+
2283
+ <table class="wf-striped-table"<?php echo !empty($inEmail) ? ' border=1' : '' ?>>
2284
+ <tbody class="thead">
2285
+ <tr>
2286
+ <th>IPs</th>
2287
+ <th>Value</th>
2288
+ <th>Used</th>
2289
+ </tr>
2290
+ </tbody>
2291
+ <tbody>
2292
+ <?php
2293
+ $howGet = wfConfig::get('howGetIPs', false);
2294
+ list($currentIP, $currentServerVarForIP) = wfUtils::getIPAndServerVariable();
2295
+ foreach (array(
2296
+ 'REMOTE_ADDR' => 'REMOTE_ADDR',
2297
+ 'HTTP_CF_CONNECTING_IP' => 'CF-Connecting-IP',
2298
+ 'HTTP_X_REAL_IP' => 'X-Real-IP',
2299
+ 'HTTP_X_FORWARDED_FOR' => 'X-Forwarded-For',
2300
+ ) as $variable => $label): ?>
2301
+ <tr>
2302
+ <td><?php echo $label ?></td>
2303
+ <td><?php
2304
+ if (!array_key_exists($variable, $_SERVER)) {
2305
+ echo '(not set)';
2306
+ } else {
2307
+ if (strpos($_SERVER[$variable], ',') !== false) {
2308
+ $trustedProxies = explode("\n", wfConfig::get('howGetIPs_trusted_proxies', ''));
2309
+ $items = preg_replace('/[\s,]/', '', explode(',', $_SERVER[$variable]));
2310
+ $items = array_reverse($items);
2311
+ $output = '';
2312
+ $markedSelectedAddress = false;
2313
+ foreach ($items as $index => $i) {
2314
+ foreach ($trustedProxies as $proxy) {
2315
+ if (!empty($proxy)) {
2316
+ if (wfUtils::subnetContainsIP($proxy, $i) && $index < count($items) - 1) {
2317
+ $output = esc_html($i) . ', ' . $output;
2318
+ continue 2;
2319
+ }
2320
+ }
2321
+ }
2322
+
2323
+ if (!$markedSelectedAddress) {
2324
+ $output = '<strong>' . esc_html($i) . '</strong>, ' . $output;
2325
+ $markedSelectedAddress = true;
2326
+ } else {
2327
+ $output = esc_html($i) . ', ' . $output;
2328
+ }
2329
+ }
2330
+
2331
+ echo substr($output, 0, -2);
2332
+ } else {
2333
+ echo esc_html($_SERVER[$variable]);
2334
+ }
2335
+ }
2336
+ ?></td>
2337
+ <?php if ($currentServerVarForIP && $currentServerVarForIP === $variable): ?>
2338
+ <td class="wf-result-success">In use</td>
2339
+ <?php elseif ($howGet === $variable): ?>
2340
+ <td class="wf-result-error">Configured, but not valid</td>
2341
+ <?php else: ?>
2342
+ <td></td>
2343
+ <?php endif ?>
2344
+ </tr>
2345
+ <?php endforeach ?>
2346
+ </tbody>
2347
+ </table>
2348
+
2349
+ </div>
2350
+ </div>
2351
+
2352
+ <div class="wf-block<?php echo(wfPersistenceController::shared()->isActive('wf-diagnostics-wordpress-constants') ? ' wf-active' : '') ?>" data-persistence-key="<?php echo esc_attr('wf-diagnostics-wordpress-constants') ?>">
2353
+ <div class="wf-block-header">
2354
+ <div class="wf-block-header-content">
2355
+ <div class="wf-block-title">
2356
+ <strong><?php _e('WordPress Settings', 'wordfence') ?></strong>
2357
+ <span class="wf-text-small"><?php _e('WordPress version and internal settings/constants.', 'wordfence') ?></span>
2358
+ </div>
2359
+ <div class="wf-block-header-action">
2360
+ <div class="wf-block-header-action-disclosure"></div>
2361
+ </div>
2362
+ </div>
2363
+ </div>
2364
+ <div class="wf-block-content wf-clearfix wf-padding-no-left wf-padding-no-right">
2365
+ <table class="wf-striped-table"<?php echo !empty($inEmail) ? ' border=1' : '' ?>>
2366
+ <tbody>
2367
+ <?php
2368
+ require(ABSPATH . 'wp-includes/version.php');
2369
+ $postRevisions = (defined('WP_POST_REVISIONS') ? WP_POST_REVISIONS : true);
2370
+ $wordPressValues = array(
2371
+ 'WordPress Version' => array('description' => '', 'value' => $wp_version),
2372
+ 'WP_DEBUG' => array('description' => 'WordPress debug mode', 'value' => (defined('WP_DEBUG') && WP_DEBUG ? 'On' : 'Off')),
2373
+ 'WP_DEBUG_LOG' => array('description' => 'WordPress error logging override', 'value' => defined('WP_DEBUG_LOG') ? (WP_DEBUG_LOG ? 'Enabled' : 'Disabled') : '(not set)'),
2374
+ 'WP_DEBUG_DISPLAY' => array('description' => 'WordPress error display override', 'value' => defined('WP_DEBUG_DISPLAY') ? (WP_DEBUG_LOG ? 'Enabled' : 'Disabled') : '(not set)'),
2375
+ 'SCRIPT_DEBUG' => array('description' => 'WordPress script debug mode', 'value' => (defined('SCRIPT_DEBUG') && SCRIPT_DEBUG ? 'On' : 'Off')),
2376
+ 'SAVEQUERIES' => array('description' => 'WordPress query debug mode', 'value' => (defined('SAVEQUERIES') && SAVEQUERIES ? 'On' : 'Off')),
2377
+ 'DB_CHARSET' => 'Database character set',
2378
+ 'DB_COLLATE' => 'Database collation',
2379
+ 'WP_SITEURL' => 'Explicitly set site URL',
2380
+ 'WP_HOME' => 'Explicitly set blog URL',
2381
+ 'WP_CONTENT_DIR' => array('description' => '"wp-content" folder is in default location', 'value' => (realpath(WP_CONTENT_DIR) === realpath(ABSPATH . 'wp-content') ? 'Yes' : 'No')),
2382
+ 'WP_CONTENT_URL' => 'URL to the "wp-content" folder',
2383
+ 'WP_PLUGIN_DIR' => array('description' => '"plugins" folder is in default location', 'value' => (realpath(WP_PLUGIN_DIR) === realpath(ABSPATH . 'wp-content/plugins') ? 'Yes' : 'No')),
2384
+ 'WP_LANG_DIR' => array('description' => '"languages" folder is in default location', 'value' => (realpath(WP_LANG_DIR) === realpath(ABSPATH . 'wp-content/languages') ? 'Yes' : 'No')),
2385
+ 'WPLANG' => 'Language choice',
2386
+ 'UPLOADS' => 'Custom upload folder location',
2387
+ 'TEMPLATEPATH' => array('description' => 'Theme template folder override', 'value' => (defined('TEMPLATEPATH') && realpath(get_template_directory()) !== realpath(TEMPLATEPATH) ? 'Overridden' : '(not set)')),
2388
+ 'STYLESHEETPATH' => array('description' => 'Theme stylesheet folder override', 'value' => (defined('STYLESHEETPATH') && realpath(get_stylesheet_directory()) !== realpath(STYLESHEETPATH) ? 'Overridden' : '(not set)')),
2389
+ 'AUTOSAVE_INTERVAL' => 'Post editing automatic saving interval',
2390
+ 'WP_POST_REVISIONS' => array('description' => 'Post revisions saved by WordPress', 'value' => is_numeric($postRevisions) ? $postRevisions : ($postRevisions ? 'Unlimited' : 'None')),
2391
+ 'COOKIE_DOMAIN' => 'WordPress cookie domain',
2392
+ 'COOKIEPATH' => 'WordPress cookie path',
2393
+ 'SITECOOKIEPATH' => 'WordPress site cookie path',
2394
+ 'ADMIN_COOKIE_PATH' => 'WordPress admin cookie path',
2395
+ 'PLUGINS_COOKIE_PATH' => 'WordPress plugins cookie path',
2396
+ 'WP_ALLOW_MULTISITE' => array('description' => 'Multisite/network ability enabled', 'value' => (defined('WP_ALLOW_MULTISITE') && WP_ALLOW_MULTISITE ? 'Yes' : 'No')),
2397
+ 'NOBLOGREDIRECT' => 'URL redirected to if the visitor tries to access a nonexistent blog',
2398
+ 'CONCATENATE_SCRIPTS' => array('description' => 'Concatenate JavaScript files', 'value' => (defined('CONCATENATE_SCRIPTS') && CONCATENATE_SCRIPTS ? 'Yes' : 'No')),
2399
+ 'WP_MEMORY_LIMIT' => 'WordPress memory limit',
2400
+ 'WP_MAX_MEMORY_LIMIT' => 'Administrative memory limit',
2401
+ 'WP_CACHE' => array('description' => 'Built-in caching', 'value' => (defined('WP_CACHE') && WP_CACHE ? 'Enabled' : 'Disabled')),
2402
+ 'CUSTOM_USER_TABLE' => array('description' => 'Custom "users" table', 'value' => (defined('CUSTOM_USER_TABLE') ? 'Set' : '(not set)')),
2403
+ 'CUSTOM_USER_META_TABLE' => array('description' => 'Custom "usermeta" table', 'value' => (defined('CUSTOM_USER_META_TABLE') ? 'Set' : '(not set)')),
2404
+ 'FS_CHMOD_DIR' => array('description' => 'Overridden permissions for a new folder', 'value' => defined('FS_CHMOD_DIR') ? decoct(FS_CHMOD_DIR) : '(not set)'),
2405
+ 'FS_CHMOD_FILE' => array('description' => 'Overridden permissions for a new file', 'value' => defined('FS_CHMOD_FILE') ? decoct(FS_CHMOD_FILE) : '(not set)'),
2406
+ 'ALTERNATE_WP_CRON' => array('description' => 'Alternate WP cron', 'value' => (defined('ALTERNATE_WP_CRON') && ALTERNATE_WP_CRON ? 'Enabled' : 'Disabled')),
2407
+ 'DISABLE_WP_CRON' => array('description' => 'WP cron status', 'value' => (defined('DISABLE_WP_CRON') && DISABLE_WP_CRON ? 'Disabled' : 'Enabled')),
2408
+ 'WP_CRON_LOCK_TIMEOUT' => 'Cron running frequency lock',
2409
+ 'EMPTY_TRASH_DAYS' => array('description' => 'Interval the trash is automatically emptied at in days', 'value' => (EMPTY_TRASH_DAYS > 0 ? EMPTY_TRASH_DAYS : 'Never')),
2410
+ 'WP_ALLOW_REPAIR' => array('description' => 'Automatic database repair', 'value' => (defined('WP_ALLOW_REPAIR') && WP_ALLOW_REPAIR ? 'Enabled' : 'Disabled')),
2411
+ 'DO_NOT_UPGRADE_GLOBAL_TABLES' => array('description' => 'Do not upgrade global tables', 'value' => (defined('DO_NOT_UPGRADE_GLOBAL_TABLES') && DO_NOT_UPGRADE_GLOBAL_TABLES ? 'Yes' : 'No')),
2412
+ 'DISALLOW_FILE_EDIT' => array('description' => 'Disallow plugin/theme editing', 'value' => (defined('DISALLOW_FILE_EDIT') && DISALLOW_FILE_EDIT ? 'Yes' : 'No')),
2413
+ 'DISALLOW_FILE_MODS' => array('description' => 'Disallow plugin/theme update and installation', 'value' => (defined('DISALLOW_FILE_MODS') && DISALLOW_FILE_MODS ? 'Yes' : 'No')),
2414
+ 'IMAGE_EDIT_OVERWRITE' => array('description' => 'Overwrite image edits when restoring the original', 'value' => (defined('IMAGE_EDIT_OVERWRITE') && IMAGE_EDIT_OVERWRITE ? 'Yes' : 'No')),
2415
+ 'FORCE_SSL_ADMIN' => array('description' => 'Force SSL for administrative logins', 'value' => (defined('FORCE_SSL_ADMIN') && FORCE_SSL_ADMIN ? 'Yes' : 'No')),
2416
+ 'WP_HTTP_BLOCK_EXTERNAL' => array('description' => 'Block external URL requests', 'value' => (defined('WP_HTTP_BLOCK_EXTERNAL') && WP_HTTP_BLOCK_EXTERNAL ? 'Yes' : 'No')),
2417
+ 'WP_ACCESSIBLE_HOSTS' => 'Whitelisted hosts',
2418
+ 'WP_AUTO_UPDATE_CORE' => array('description' => 'Automatic WP Core updates', 'value' => defined('WP_AUTO_UPDATE_CORE') ? (is_bool(WP_AUTO_UPDATE_CORE) ? (WP_AUTO_UPDATE_CORE ? 'Everything' : 'None') : WP_AUTO_UPDATE_CORE) : 'Default'),
2419
+ 'WP_PROXY_HOST' => array('description' => 'Hostname for a proxy server', 'value' => defined('WP_PROXY_HOST') ? WP_PROXY_HOST : '(not set)'),
2420
+ 'WP_PROXY_PORT' => array('description' => 'Port for a proxy server', 'value' => defined('WP_PROXY_PORT') ? WP_PROXY_PORT : '(not set)'),
2421
+ );
2422
+
2423
+ foreach ($wordPressValues as $settingName => $settingData):
2424
+ $escapedName = esc_html($settingName);
2425
+ $escapedDescription = '';
2426
+ $escapedValue = '(not set)';
2427
+ if (is_array($settingData)) {
2428
+ $escapedDescription = esc_html($settingData['description']);
2429
+ if (isset($settingData['value'])) {
2430
+ $escapedValue = esc_html($settingData['value']);
2431
+ }
2432
+ } else {
2433
+ $escapedDescription = esc_html($settingData);
2434
+ if (defined($settingName)) {
2435
+ $escapedValue = esc_html(constant($settingName));
2436
+ }
2437
+ }
2438
+ ?>
2439
+ <tr>
2440
+ <td><strong><?php echo $escapedName ?></strong></td>
2441
+ <td><?php echo $escapedDescription ?></td>
2442
+ <td><?php echo $escapedValue ?></td>
2443
+ </tr>
2444
+ <?php endforeach ?>
2445
+ </tbody>
2446
+ </table>
2447
+ </div>
2448
+ </div>
2449
+
2450
+ <div class="wf-block<?php echo(wfPersistenceController::shared()->isActive('wf-diagnostics-wordpress-plugins') ? ' wf-active' : '') ?>" data-persistence-key="<?php echo esc_attr('wf-diagnostics-wordpress-plugins') ?>">
2451
+ <div class="wf-block-header">
2452
+ <div class="wf-block-header-content">
2453
+ <div class="wf-block-title">
2454
+ <strong><?php _e('WordPress Plugins', 'wordfence') ?></strong>
2455
+ <span class="wf-text-small"><?php _e('Status of installed plugins.', 'wordfence') ?></span>
2456
+ </div>
2457
+ <div class="wf-block-header-action">
2458
+ <div class="wf-block-header-action-disclosure"></div>
2459
+ </div>
2460
+ </div>
2461
+ </div>
2462
+ <div class="wf-block-content wf-clearfix wf-padding-no-left wf-padding-no-right">
2463
+ <table class="wf-striped-table"<?php echo !empty($inEmail) ? ' border=1' : '' ?>>
2464
+ <tbody>
2465
+ <?php foreach ($plugins as $plugin => $pluginData): ?>
2466
+ <tr>
2467
+ <td colspan="<?php echo $cols - 1 ?>">
2468
+ <strong><?php echo esc_html($pluginData['Name']) ?></strong>
2469
+ <?php if (!empty($pluginData['Version'])): ?>
2470
+ - Version <?php echo esc_html($pluginData['Version']) ?>
2471
+ <?php endif ?>
2472
+ </td>
2473
+ <?php if (array_key_exists(trailingslashit(WP_PLUGIN_DIR) . $plugin, $activeNetworkPlugins)): ?>
2474
+ <td class="wf-result-success">Network Activated</td>
2475
+ <?php elseif (array_key_exists($plugin, $activePlugins)): ?>
2476
+ <td class="wf-result-success">Active</td>
2477
+ <?php else: ?>
2478
+ <td class="wf-result-inactive">Inactive</td>
2479
+ <?php endif ?>
2480
+ </tr>
2481
+ <?php endforeach ?>
2482
+ </tbody>
2483
+ </table>
2484
+ </div>
2485
+ </div>
2486
+ <div class="wf-block<?php echo(wfPersistenceController::shared()->isActive('wf-diagnostics-mu-wordpress-plugins') ? ' wf-active' : '') ?>" data-persistence-key="<?php echo esc_attr('wf-diagnostics-mu-wordpress-plugins') ?>">
2487
+ <div class="wf-block-header">
2488
+ <div class="wf-block-header-content">
2489
+ <div class="wf-block-title">
2490
+ <strong><?php _e('Must-Use WordPress Plugins', 'wordfence') ?></strong>
2491
+ <span class="wf-text-small"><?php _e('WordPress "mu-plugins" that are always active, incluing those provided by hosts.', 'wordfence') ?></span>
2492
+ </div>
2493
+ <div class="wf-block-header-action">
2494
+ <div class="wf-block-header-action-disclosure"></div>
2495
+ </div>
2496
+ </div>
2497
+ </div>
2498
+ <div class="wf-block-content wf-clearfix wf-padding-no-left wf-padding-no-right">
2499
+ <table class="wf-striped-table"<?php echo !empty($inEmail) ? ' border=1' : '' ?>>
2500
+ <?php if (!empty($muPlugins)): ?>
2501
+ <tbody>
2502
+ <?php foreach ($muPlugins as $plugin => $pluginData): ?>
2503
+ <tr>
2504
+ <td colspan="<?php echo $cols - 1 ?>">
2505
+ <strong><?php echo esc_html($pluginData['Name']) ?></strong>
2506
+ <?php if (!empty($pluginData['Version'])): ?>
2507
+ - Version <?php echo esc_html($pluginData['Version']) ?>
2508
+ <?php endif ?>
2509
+ </td>
2510
+ <td class="wf-result-success">Active</td>
2511
+ </tr>
2512
+ <?php endforeach ?>
2513
+ </tbody>
2514
+ <?php else: ?>
2515
+ <tbody>
2516
+ <tr>
2517
+ <td colspan="<?php echo $cols ?>">No MU-Plugins</td>
2518
+ </tr>
2519
+ </tbody>
2520
+
2521
+ <?php endif ?>
2522
+ </table>
2523
+ </div>
2524
+ </div>
2525
+ <div class="wf-block<?php echo(wfPersistenceController::shared()->isActive('wf-diagnostics-wordpress-themes') ? ' wf-active' : '') ?>" data-persistence-key="<?php echo esc_attr('wf-diagnostics-wordpress-themes') ?>">
2526
+ <div class="wf-block-header">
2527
+ <div class="wf-block-header-content">
2528
+ <div class="wf-block-title">
2529
+ <strong><?php _e('Themes', 'wordfence') ?></strong>
2530
+ <span class="wf-text-small"><?php _e('Status of installed themes.', 'wordfence') ?></span>
2531
+ </div>
2532
+ <div class="wf-block-header-action">
2533
+ <div class="wf-block-header-action-disclosure"></div>
2534
+ </div>
2535
+ </div>
2536
+ </div>
2537
+ <div class="wf-block-content wf-clearfix wf-padding-no-left wf-padding-no-right">
2538
+ <table class="wf-striped-table"<?php echo !empty($inEmail) ? ' border=1' : '' ?>>
2539
+ <?php if (!empty($themes)): ?>
2540
+ <tbody>
2541
+ <?php foreach ($themes as $theme => $themeData): ?>
2542
+ <tr>
2543
+ <td colspan="<?php echo $cols - 1 ?>">
2544
+ <strong><?php echo esc_html($themeData['Name']) ?></strong>
2545
+ Version <?php echo esc_html($themeData['Version']) ?></td>
2546
+ <?php if ($currentTheme instanceof WP_Theme && $theme === $currentTheme->get_stylesheet()): ?>
2547
+ <td class="wf-result-success">Active</td>
2548
+ <?php else: ?>
2549
+ <td class="wf-result-inactive">Inactive</td>
2550
+ <?php endif ?>
2551
+ </tr>
2552
+ <?php endforeach ?>
2553
+ </tbody>
2554
+ <?php else: ?>
2555
+ <tbody>
2556
+ <tr>
2557
+ <td colspan="<?php echo $cols ?>">No Themes</td>
2558
+ </tr>
2559
+ </tbody>
2560
+
2561
+ <?php endif ?>
2562
+ </table>
2563
+ </div>
2564
+ </div>
2565
+ <div class="wf-block<?php echo(wfPersistenceController::shared()->isActive('wf-diagnostics-wordpress-cron-jobs') ? ' wf-active' : '') ?>" data-persistence-key="<?php echo esc_attr('wf-diagnostics-wordpress-cron-jobs') ?>">
2566
+ <div class="wf-block-header">
2567
+ <div class="wf-block-header-content">
2568
+ <div class="wf-block-title">
2569
+ <strong><?php _e('Cron Jobs', 'wordfence') ?></strong>
2570
+ <span class="wf-text-small"><?php _e('List of WordPress cron jobs scheduled by WordPress, plugins, or themes.', 'wordfence') ?></span>
2571
+ </div>
2572
+ <div class="wf-block-header-action">
2573
+ <div class="wf-block-header-action-disclosure"></div>
2574
+ </div>
2575
+ </div>
2576
+ </div>
2577
+ <div class="wf-block-content wf-clearfix wf-padding-no-left wf-padding-no-right">
2578
+ <table class="wf-striped-table"<?php echo !empty($inEmail) ? ' border=1' : '' ?>>
2579
+ <tbody>
2580
+ <?php
2581
+ $cron = _get_cron_array();
2582
+
2583
+ foreach ($cron as $timestamp => $values) {
2584
+ if (is_array($values)) {
2585
+ foreach ($values as $cron_job => $v) {
2586
+ if (is_numeric($timestamp)) {
2587
+ ?>
2588
+ <tr>
2589
+ <td colspan="<?php echo $cols - 1 ?>"><?php echo esc_html(date('r', $timestamp)) ?></td>
2590
+ <td><?php echo esc_html($cron_job) ?></td>
2591
+ </tr>
2592
+ <?php
2593
+ }
2594
+ }
2595
+ }
2596
+ }
2597
+ ?>
2598
+ </tbody>
2599
+ </table>
2600
+ </div>
2601
+ </div>
2602
+
2603
+ <?php
2604
+ global $wpdb;
2605
+ $wfdb = new wfDB();
2606
+ //This must be done this way because MySQL with InnoDB tables does a full regeneration of all metadata if we don't. That takes a long time with a large table count.
2607
+ $tables = $wfdb->querySelect('SELECT SQL_CALC_FOUND_ROWS TABLE_NAME FROM information_schema.TABLES WHERE TABLE_SCHEMA=DATABASE() ORDER BY TABLE_NAME ASC LIMIT 250');
2608
+ $total = $wfdb->querySingle('SELECT FOUND_ROWS()');
2609
+ foreach ($tables as &$t) {
2610
+ $t = "'" . esc_sql($t['TABLE_NAME']) . "'";
2611
+ }
2612
+ unset($t);
2613
+ $q = $wfdb->querySelect("SHOW TABLE STATUS WHERE Name IN (" . implode(',', $tables) . ')');
2614
+ if ($q):
2615
+ $databaseCols = count($q[0]);
2616
+ ?>
2617
+ <div class="wf-block<?php echo(wfPersistenceController::shared()->isActive('wf-diagnostics-database-tables') ? ' wf-active' : '') ?>" data-persistence-key="<?php echo esc_attr('wf-diagnostics-database-tables') ?>">
2618
+ <div class="wf-block-header">
2619
+ <div class="wf-block-header-content">
2620
+ <div class="wf-block-title">
2621
+ <strong><?php _e('Database Tables', 'wordfence') ?></strong>
2622
+ <span class="wf-text-small"><?php _e('Database table names, sizes, timestamps, and other metadata.', 'wordfence') ?></span>
2623
+ </div>
2624
+ <div class="wf-block-header-action">
2625
+ <div class="wf-block-header-action-disclosure"></div>
2626
+ </div>
2627
+ </div>
2628
+ </div>
2629
+ <div class="wf-block-content wf-clearfix wf-padding-no-left wf-padding-no-right">
2630
+ <div style="max-width: 100%; overflow: auto; padding: 1px;">
2631
+ <table class="wf-striped-table"<?php echo !empty($inEmail) ? ' border=1' : '' ?>>
2632
+ <tbody class="thead thead-subhead" style="font-size: 85%">
2633
+ <?php
2634
+ $val = wfUtils::array_first($q);
2635
+ ?>
2636
+ <tr>
2637
+ <?php foreach ($val as $tkey => $tval): ?>
2638
+ <th><?php echo esc_html($tkey) ?></th>
2639
+ <?php endforeach; ?>
2640
+ </tr>
2641
+ </tbody>
2642
+ <tbody style="font-size: 85%">
2643
+ <?php
2644
+ $count = 0;
2645
+ foreach ($q as $val) {
2646
+ ?>
2647
+ <tr>
2648
+ <?php foreach ($val as $tkey => $tval): ?>
2649
+ <td><?php echo esc_html($tval) ?></td>
2650
+ <?php endforeach; ?>
2651
+ </tr>
2652
+ <?php
2653
+ $count++;
2654
+ if ($count >= 250) {
2655
+ ?>
2656
+ <tr>
2657
+ <td colspan="<?php echo $databaseCols; ?>">and <?php echo $total - $count; ?> more</td>
2658
+ </tr>
2659
+ <?php
2660
+ break;
2661
+ }
2662
+ }
2663
+ ?>
2664
+ </tbody>
2665
+
2666
+ </table>
2667
+ </div>
2668
+
2669
+ </div>
2670
+ </div>
2671
+ <?php endif ?>
2672
+ <div class="wf-block<?php echo(wfPersistenceController::shared()->isActive('wf-diagnostics-log-files') ? ' wf-active' : '') ?>" data-persistence-key="<?php echo esc_attr('wf-diagnostics-log-files') ?>">
2673
+ <div class="wf-block-header">
2674
+ <div class="wf-block-header-content">
2675
+ <div class="wf-block-title">
2676
+ <strong><?php _e('Log Files', 'wordfence') ?></strong>
2677
+ <span class="wf-text-small"><?php _e('PHP error logs generated by your site, if enabled by your host.', 'wordfence') ?></span>
2678
+ </div>
2679
+ <div class="wf-block-header-action">
2680
+ <div class="wf-block-header-action-disclosure"></div>
2681
+ </div>
2682
+ </div>
2683
+ </div>
2684
+ <div class="wf-block-content wf-clearfix wf-padding-no-left wf-padding-no-right">
2685
+ <div style="max-width: 100%; overflow: auto; padding: 1px;">
2686
+ <table class="wf-striped-table"<?php echo !empty($inEmail) ? ' border=1' : '' ?>>
2687
+ <tbody class="thead thead-subhead" style="font-size: 85%">
2688
+ <tr>
2689
+ <th>File</th>
2690
+ <th>Download</th>
2691
+ </tr>
2692
+ </tbody>
2693
+ <tbody style="font-size: 85%">
2694
+ <?php
2695
+ $errorLogs = wfErrorLogHandler::getErrorLogs();
2696
+ if (count($errorLogs) < 1): ?>
2697
+ <tr>
2698
+ <td colspan="2"><em>No log files found.</em></td>
2699
+ </tr>
2700
+ <?php else:
2701
+ foreach ($errorLogs as $log => $readable): ?>
2702
+ <tr>
2703
+ <td style="width: 100%"><?php echo esc_html($log) . ' (' . wfUtils::formatBytes(filesize($log)) . ')'; ?></td>
2704
+ <td style="white-space: nowrap; text-align: right;"><?php echo($readable ? '<a href="#" data-logfile="' . esc_html($log) . '" class="downloadLogFile" target="_blank" rel="noopener noreferrer">Download</a>' : '<em>Requires downloading from the server directly</em>'); ?></td>
2705
+ </tr>
2706
+ <?php endforeach;
2707
+ endif; ?>
2708
+ </tbody>
2709
+
2710
+ </table>
2711
+ </div>
2712
+ </div>
2713
+ </div>
2714
+ </form>
2715
+ </div>
2716
+ <script type="application/javascript">
2717
+ jQuery( document ).ready(function ($) {
2718
+ $('.wf-block-header-action-disclosure').each(function() {
2719
+ $(this).closest('.wf-block-header').css('cursor', 'pointer');
2720
+
2721
+ $(this).closest('.wf-block-header').on('click', function(e) {
2722
+ // Let links in the header work.
2723
+ if (e.target && e.target.nodeName === 'A' && e.target.href) {
2724
+ return;
2725
+ }
2726
+ e.preventDefault();
2727
+ e.stopPropagation();
2728
+
2729
+ if ($(this).closest('.wf-block').hasClass('wf-disabled')) {
2730
+ return;
2731
+ }
2732
+
2733
+ var isActive = $(this).closest('.wf-block').hasClass('wf-active');
2734
+ if (isActive) {
2735
+ //$(this).closest('.wf-block').removeClass('wf-active');
2736
+ $(this).closest('.wf-block').find('.wf-block-content').slideUp({
2737
+ always: function() {
2738
+ $(this).closest('.wf-block').removeClass('wf-active');
2739
+ }
2740
+ });
2741
+ }
2742
+ else {
2743
+ //$(this).closest('.wf-block').addClass('wf-active');
2744
+ $(this).closest('.wf-block').find('.wf-block-content').slideDown({
2745
+ always: function() {
2746
+ $(this).closest('.wf-block').addClass('wf-active');
2747
+ }
2748
+ });
2749
+ }
2750
+ });
2751
+ });
2752
+ });
2753
+ </script>
2754
+
2755
+
2756
+ <?php
2757
+ $html = ob_get_clean();
2758
+ return array('ok' => 1, 'html' => $html);
2759
+
2760
+ }
2761
+
2762
+ public static function updateWAFRules() {
2763
+ $event = new wfWAFCronFetchRulesEvent(time() - 2);
2764
+ $event->setWaf(wfWAF::getInstance());
2765
+ $event->fire();
2766
+ $isPaid = (bool) wfConfig::get('isPaid', 0);
2767
+ //return self::_getWAFData();
2768
+ return array('ok' => 1, 'isPaid' => $isPaid );
2769
+ }
2770
+
2771
+ public static function updateWAFRules_New() {
2772
+ $event = new wfWAFCronFetchRulesEvent(time() - 2);
2773
+ $event->setWaf(wfWAF::getInstance());
2774
+ $success = $event->fire();
2775
+
2776
+ return self::_getWAFData($success);
2777
+ }
2778
+
2779
+ public static function save_debugging_config() {
2780
+ $settings = $_POST['settings'];
2781
+ foreach (self::$diagnosticParams as $param) {
2782
+ if (isset($settings[$param])) {
2783
+ wfConfig::set( $param, $settings[$param] );
2784
+ }
2785
+ }
2786
+ return array('ok' => 1 );
2787
+ }
2788
+ }
class/class-mainwp-child-wp-rocket.php ADDED
@@ -0,0 +1,342 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class MainWP_Child_WP_Rocket {
4
+ public static $instance = null;
5
+
6
+ public static function Instance() {
7
+ if ( null === MainWP_Child_WP_Rocket::$instance ) {
8
+ MainWP_Child_WP_Rocket::$instance = new MainWP_Child_WP_Rocket();
9
+ }
10
+
11
+ return MainWP_Child_WP_Rocket::$instance;
12
+ }
13
+
14
+ public function __construct() {
15
+
16
+ }
17
+
18
+ public function init() {
19
+ if ( get_option( 'mainwp_wprocket_ext_enabled' ) !== 'Y' ) {
20
+ return;
21
+ }
22
+
23
+ if ( get_option( 'mainwp_wprocket_hide_plugin' ) === 'hide' ) {
24
+ add_filter( 'all_plugins', array( $this, 'all_plugins' ) );
25
+ add_action( 'admin_menu', array( $this, 'remove_menu' ) );
26
+ add_filter( 'site_transient_update_plugins', array( &$this, 'remove_update_nag' ) );
27
+ add_action( 'wp_before_admin_bar_render', array( $this, 'wp_before_admin_bar_render' ), 99 );
28
+ add_action( 'admin_init', array( $this, 'remove_notices' ) );
29
+ }
30
+ }
31
+
32
+ function remove_notices() {
33
+ $remove_hooks['admin_notices'] = array(
34
+ 'rocket_bad_deactivations' => 10,
35
+ 'rocket_warning_plugin_modification' => 10,
36
+ 'rocket_plugins_to_deactivate' => 10,
37
+ 'rocket_warning_using_permalinks' => 10,
38
+ 'rocket_warning_wp_config_permissions' => 10,
39
+ 'rocket_warning_advanced_cache_permissions' => 10,
40
+ 'rocket_warning_advanced_cache_not_ours' => 10,
41
+ 'rocket_warning_htaccess_permissions' => 10,
42
+ 'rocket_warning_config_dir_permissions' => 10,
43
+ 'rocket_warning_cache_dir_permissions' => 10,
44
+ 'rocket_warning_minify_cache_dir_permissions' => 10,
45
+ 'rocket_thank_you_license' => 10,
46
+ 'rocket_need_api_key' => 10,
47
+ );
48
+ foreach ( $remove_hooks as $hook_name => $hooks ) {
49
+ foreach ( $hooks as $method => $priority ) {
50
+ MainWP_Helper::remove_filters_with_method_name( $hook_name, $method, $priority );
51
+ }
52
+ }
53
+ }
54
+
55
+
56
+ public function wp_before_admin_bar_render() {
57
+ global $wp_admin_bar;
58
+ $nodes = $wp_admin_bar->get_nodes();
59
+ if ( is_array( $nodes ) ) {
60
+ foreach ( $nodes as $node ) {
61
+ if ( 'wp-rocket' === $node->parent || ( $node->id = 'wp-rocket' ) ) {
62
+ $wp_admin_bar->remove_node( $node->id );
63
+ }
64
+ }
65
+ }
66
+ }
67
+
68
+ function remove_update_nag( $value ) {
69
+ if ( isset( $_POST['mainwpsignature'] ) ) {
70
+ return $value;
71
+ }
72
+ if ( isset( $value->response['wp-rocket/wp-rocket.php'] ) ) {
73
+ unset( $value->response['wp-rocket/wp-rocket.php'] );
74
+ }
75
+
76
+ return $value;
77
+ }
78
+
79
+ public static function isActivated() {
80
+ if ( ! defined( 'WP_ROCKET_VERSION' ) || ! defined( 'WP_ROCKET_SLUG' ) ) {
81
+ return false;
82
+ }
83
+
84
+ return true;
85
+ }
86
+
87
+ public function remove_menu() {
88
+ global $submenu;
89
+ if ( isset( $submenu['options-general.php'] ) ) {
90
+ foreach ( $submenu['options-general.php'] as $index => $item ) {
91
+ if ( 'wprocket' === $item[2] ) {
92
+ unset( $submenu['options-general.php'][ $index ] );
93
+ break;
94
+ }
95
+ }
96
+ }
97
+ $pos = stripos( $_SERVER['REQUEST_URI'], 'options-general.php?page=wprocket' );
98
+ if ( false !== $pos ) {
99
+ wp_redirect( get_option( 'siteurl' ) . '/wp-admin/index.php' );
100
+ exit();
101
+ }
102
+ }
103
+
104
+ public function all_plugins( $plugins ) {
105
+ foreach ( $plugins as $key => $value ) {
106
+ $plugin_slug = basename( $key, '.php' );
107
+ if ( 'wp-rocket' === $plugin_slug ) {
108
+ unset( $plugins[ $key ] );
109
+ }
110
+ }
111
+
112
+ return $plugins;
113
+ }
114
+
115
+ public function action() {
116
+ $information = array();
117
+ if ( ! self::isActivated() ) {
118
+ $information['error'] = 'NO_WPROCKET';
119
+ MainWP_Helper::write( $information );
120
+ }
121
+ if ( isset( $_POST['mwp_action'] ) ) {
122
+ MainWP_Helper::update_option( 'mainwp_wprocket_ext_enabled', 'Y' );
123
+ switch ( $_POST['mwp_action'] ) {
124
+ case 'set_showhide':
125
+ $information = $this->set_showhide();
126
+ break;
127
+ case 'purge_cloudflare':
128
+ $information = $this->purge_cloudflare();
129
+ break;
130
+ case 'purge_all':
131
+ $information = $this->purge_cache_all();
132
+ break;
133
+ case 'preload_cache':
134
+ $information = $this->preload_cache();
135
+ break;
136
+ case 'save_settings':
137
+ $information = $this->save_settings();
138
+ break;
139
+ case "load_existing_settings":
140
+ $information = $this->load_existing_settings();
141
+ break;
142
+ case 'optimize_database':
143
+ $information = $this->optimize_database();
144
+ break;
145
+ case 'get_optimize_info':
146
+ $information = $this->get_optimize_info();
147
+ break;
148
+ case 'purge_opcache':
149
+ $information = $this->do_admin_post_rocket_purge_opcache();
150
+ break;
151
+ }
152
+ }
153
+ MainWP_Helper::write( $information );
154
+ }
155
+
156
+ function set_showhide() {
157
+ $hide = isset( $_POST['showhide'] ) && ( $_POST['showhide'] === 'hide' ) ? 'hide' : '';
158
+ MainWP_Helper::update_option( 'mainwp_wprocket_hide_plugin', $hide );
159
+ $information['result'] = 'SUCCESS';
160
+
161
+ return $information;
162
+ }
163
+
164
+ function do_admin_post_rocket_purge_opcache() {
165
+ if ( function_exists( 'opcache_reset' ) ) {
166
+ @opcache_reset();
167
+ } else {
168
+ return array('error' => 'The host do not support the function reset opcache.');
169
+ }
170
+ return array('result' => 'SUCCESS');
171
+ }
172
+
173
+ function purge_cloudflare() {
174
+ if ( function_exists( 'rocket_purge_cloudflare' ) ) {
175
+ // Purge CloudFlare
176
+ rocket_purge_cloudflare();
177
+
178
+ return array( 'result' => 'SUCCESS' );
179
+ } else {
180
+ return array( 'error' => 'function_not_exist' );
181
+ }
182
+ }
183
+
184
+ function purge_cache_all() {
185
+ if ( function_exists( 'rocket_clean_domain' ) || function_exists( 'rocket_clean_minify' ) || function_exists( 'create_rocket_uniqid' ) ) {
186
+ // Remove all cache files
187
+ rocket_clean_domain();
188
+
189
+ // Remove all minify cache files
190
+ rocket_clean_minify();
191
+
192
+ // Generate a new random key for minify cache file
193
+ $options = get_option( WP_ROCKET_SLUG );
194
+ $options['minify_css_key'] = create_rocket_uniqid();
195
+ $options['minify_js_key'] = create_rocket_uniqid();
196
+ remove_all_filters( 'update_option_' . WP_ROCKET_SLUG );
197
+ update_option( WP_ROCKET_SLUG, $options );
198
+ //rocket_dismiss_box( 'rocket_warning_plugin_modification' );
199
+
200
+ return array( 'result' => 'SUCCESS' );
201
+ } else {
202
+ return array( 'error' => 'function_not_exist' );
203
+ }
204
+ }
205
+
206
+ function preload_cache() {
207
+ if ( function_exists( 'run_rocket_bot' ) ) {
208
+ run_rocket_bot( 'cache-preload', '' );
209
+
210
+ return array( 'result' => 'SUCCESS' );
211
+ } else {
212
+ return array( 'error' => 'function_not_exist' );
213
+ }
214
+ }
215
+
216
+ function save_settings() {
217
+ $options = maybe_unserialize( base64_decode( $_POST['settings'] ) );
218
+ if ( ! is_array( $options ) || empty( $options ) ) {
219
+ return array( 'error' => 'INVALID_OPTIONS' );
220
+ }
221
+
222
+ $old_values = get_option( WP_ROCKET_SLUG );
223
+
224
+ $defaults_fields = $this->get_rocket_default_options();
225
+ foreach ( $old_values as $field => $value ) {
226
+ if ( ! isset( $defaults_fields[ $field ] ) ) { // keep other options
227
+ $options[ $field ] = $value;
228
+ }
229
+ }
230
+ if (isset($_POST['do_database_optimization']) && !empty($_POST['do_database_optimization'])) {
231
+ $_POST['wp_rocket_settings']['submit_optimize'] = 1; // simulate POST
232
+ }
233
+
234
+ update_option( WP_ROCKET_SLUG, $options );
235
+
236
+ return array( 'result' => 'SUCCESS' );
237
+ }
238
+
239
+ function optimize_database() {
240
+ $return = array();
241
+ if (function_exists('do_rocket_database_optimization')) {
242
+ do_rocket_database_optimization();
243
+ $return['result'] = 'SUCCESS';
244
+ }
245
+ return $return;
246
+ }
247
+
248
+ function get_optimize_info() {
249
+
250
+ if (function_exists('rocket_database_count_cleanup_items')) {
251
+ $information['optimize_info'] = array(
252
+ 'total_revisions' => rocket_database_count_cleanup_items( 'revisions' ),
253
+ 'total_auto_draft' => rocket_database_count_cleanup_items( 'auto_drafts' ),
254
+ 'total_trashed_posts' => rocket_database_count_cleanup_items( 'trashed_posts' ),
255
+ 'total_spam_comments' => rocket_database_count_cleanup_items( 'spam_comments' ),
256
+ 'total_trashed_comments' => rocket_database_count_cleanup_items( 'trashed_comments' ),
257
+ 'total_expired_transients' => rocket_database_count_cleanup_items( 'expired_transients' ),
258
+ 'total_all_transients' => rocket_database_count_cleanup_items( 'all_transients' ),
259
+ 'total_optimize_tables' => rocket_database_count_cleanup_items( 'optimize_tables' )
260
+ );
261
+ $information['result'] = 'SUCCESS';
262
+ }
263
+ return $information;
264
+ }
265
+
266
+ function load_existing_settings() {
267
+ $options = get_option( WP_ROCKET_SLUG );
268
+ return array('result' => 'SUCCESS', 'options' => $options);
269
+ }
270
+
271
+ function get_rocket_default_options() {
272
+ return array(
273
+ 'cache_mobile' => 1,
274
+ 'do_caching_mobile_files' => 0,
275
+ 'cache_logged_user' => 0,
276
+ 'cache_ssl' => 0,
277
+ 'emoji' => 0,
278
+ 'embeds' => 1,
279
+ 'varnish_auto_purge' => 0,
280
+ 'manual_preload' => 0,
281
+ 'automatic_preload' => 0,
282
+ 'sitemap_preload' => 0,
283
+ 'sitemap_preload_url_crawl' => 500000,
284
+ 'sitemaps' => array(),
285
+ 'database_revisions' => 0,
286
+ 'database_auto_drafts' => 0,
287
+ 'database_trashed_posts' => 0,
288
+ 'database_spam_comments' => 0,
289
+ 'database_trashed_comments' => 0,
290
+ 'database_expired_transients' => 0,
291
+ 'database_all_transients' => 0,
292
+ 'database_optimize_tables' => 0,
293
+ 'schedule_automatic_cleanup' => 0,
294
+ 'automatic_cleanup_frequency' => '',
295
+ 'cache_reject_uri' => array(),
296
+ 'cache_reject_cookies' => array(),
297
+ 'cache_reject_ua' => array(),
298
+ 'cache_query_strings' => array(),
299
+ 'cache_purge_pages' => array(),
300
+ 'purge_cron_interval' => 10,
301
+ 'purge_cron_unit' => 'HOUR_IN_SECONDS',
302
+ 'exclude_css' => array(),
303
+ 'exclude_js' => array(),
304
+ 'defer_all_js' => 0,
305
+ 'critical_css' => '',
306
+ 'deferred_js_files' => array(),
307
+ 'lazyload' => 0,
308
+ 'lazyload_iframes' => 0,
309
+ 'minify_css' => 0,
310
+ // 'minify_css_key' => $minify_css_key,
311
+ 'minify_concatenate_css' => 0,
312
+ 'minify_css_combine_all' => 0,
313
+ 'minify_css_legacy' => 0,
314
+ 'minify_js' => 0,
315
+ // 'minify_js_key' => $minify_js_key,
316
+ 'minify_js_in_footer' => array(),
317
+ 'minify_concatenate_js' => 0,
318
+ 'minify_js_combine_all' => 0,
319
+ //'minify_js_legacy' => 0,
320
+ 'minify_google_fonts' => 0,
321
+ 'minify_html' => 0,
322
+ 'remove_query_strings' => 0,
323
+ 'dns_prefetch' => 0,
324
+ 'cdn' => 0,
325
+ 'cdn_cnames' => array(),
326
+ 'cdn_zone' => array(),
327
+ 'cdn_ssl' => 0,
328
+ 'cdn_reject_files' => array(),
329
+ 'do_cloudflare' => 0,
330
+ 'cloudflare_email' => '',
331
+ 'cloudflare_api_key' => '',
332
+ 'cloudflare_domain' => '',
333
+ //'cloudflare_zone_id' => '',
334
+ 'cloudflare_devmode' => 0,
335
+ 'cloudflare_protocol_rewrite' => 0,
336
+ 'cloudflare_auto_settings' => 0,
337
+ 'cloudflare_old_settings' => 0,
338
+ 'do_beta' => 0,
339
+ );
340
+ }
341
+ }
342
+
class/class-mainwp-child.php ADDED
@@ -0,0 +1,5481 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if ( defined( 'MAINWP_DEBUG' ) && MAINWP_DEBUG === TRUE ) {
3
+ @error_reporting( E_ALL );
4
+ @ini_set( 'display_errors', TRUE );
5
+ @ini_set( 'display_startup_errors', TRUE );
6
+ } else {
7
+ @ini_set( 'display_errors', FALSE );
8
+ @error_reporting( 0 );
9
+ }
10
+
11
+ define( 'MAINWP_CHILD_NR_OF_COMMENTS', 50 );
12
+ define( 'MAINWP_CHILD_NR_OF_PAGES', 50 );
13
+
14
+ include_once( ABSPATH . '/wp-admin/includes/file.php' );
15
+ include_once( ABSPATH . '/wp-admin/includes/plugin.php' );
16
+
17
+
18
+ if ( isset( $_GET['skeleton_keyuse_nonce_key'] ) && isset( $_GET['skeleton_keyuse_nonce_hmac'] ) ) {
19
+ $skeleton_keyuse_nonce_key = intval( $_GET['skeleton_keyuse_nonce_key'] );
20
+ $skeleton_keyuse_nonce_hmac = $_GET['skeleton_keyuse_nonce_hmac'];
21
+ $skeleton_keycurrent_time = intval( time() );
22
+
23
+ if ( $skeleton_keycurrent_time >= $skeleton_keyuse_nonce_key && $skeleton_keycurrent_time <= ( $skeleton_keyuse_nonce_key + 30 ) ) {
24
+
25
+ if ( strcmp( $skeleton_keyuse_nonce_hmac, hash_hmac( 'sha256', $skeleton_keyuse_nonce_key, NONCE_KEY ) ) === 0 ) {
26
+
27
+ if ( ! function_exists( 'wp_verify_nonce' ) ) :
28
+
29
+ /**
30
+ * Verify that correct nonce was used with time limit.
31
+ *
32
+ * The user is given an amount of time to use the token, so therefore, since the
33
+ * UID and $action remain the same, the independent variable is the time.
34
+ *
35
+ * @since 2.0.3
36
+ *
37
+ * @param string $nonce Nonce that was used in the form to verify
38
+ * @param string|int $action Should give context to what is taking place and be the same when nonce was created.
39
+ *
40
+ * @return false|int False if the nonce is invalid, 1 if the nonce is valid and generated between
41
+ * 0-12 hours ago, 2 if the nonce is valid and generated between 12-24 hours ago.
42
+ */
43
+ function wp_verify_nonce( $nonce, $action = - 1 ) {
44
+ $nonce = (string) $nonce;
45
+ $user = wp_get_current_user();
46
+ $uid = (int) $user->ID;
47
+ if ( ! $uid ) {
48
+ /**
49
+ * Filter whether the user who generated the nonce is logged out.
50
+ *
51
+ * @since 3.5.0
52
+ *
53
+ * @param int $uid ID of the nonce-owning user.
54
+ * @param string $action The nonce action.
55
+ */
56
+ $uid = apply_filters( 'nonce_user_logged_out', $uid, $action );
57
+ }
58
+
59
+ if ( empty( $nonce ) ) {
60
+ die( '<mainwp>' . base64_encode( json_encode( array( 'error' => 'You dont send nonce: ' . $action ) ) ) . '</mainwp>' );
61
+ }
62
+
63
+ $token = wp_get_session_token();
64
+ $i = wp_nonce_tick();
65
+
66
+ // Nonce generated 0-12 hours ago
67
+ $expected = substr( wp_hash( $i . '|' . $action . '|' . $uid . '|' . $token, 'nonce' ), - 12, 10 );
68
+ if ( hash_equals( $expected, $nonce ) ) {
69
+ return 1;
70
+ }
71
+
72
+ // Nonce generated 12-24 hours ago
73
+ $expected = substr( wp_hash( ( $i - 1 ) . '|' . $action . '|' . $uid . '|' . $token, 'nonce' ), - 12, 10 );
74
+ if ( hash_equals( $expected, $nonce ) ) {
75
+ return 2;
76
+ }
77
+
78
+ // Invalid nonce
79
+ die( '<mainwp>' . base64_encode( json_encode( array( 'error' => 'Invalid nonce! Try to use: ' . $action ) ) ) . '</mainwp>' );
80
+ }
81
+ endif;
82
+ }
83
+ }
84
+ }
85
+
86
+ class MainWP_Child {
87
+ public static $version = '3.4.6';
88
+ private $update_version = '1.3';
89
+
90
+ private $callableFunctions = array(
91
+ 'stats' => 'getSiteStats',
92
+ 'upgrade' => 'upgradeWP',
93
+ 'newpost' => 'newPost',
94
+ 'deactivate' => 'deactivate',
95
+ 'newuser' => 'newUser',
96
+ 'newadminpassword' => 'newAdminPassword',
97
+ 'installplugintheme' => 'installPluginTheme',
98
+ 'upgradeplugintheme' => 'upgradePluginTheme',
99
+ 'upgradetranslation' => 'upgradeTranslation',
100
+ 'backup' => 'backup',
101
+ 'backup_checkpid' => 'backup_checkpid',
102
+ 'cloneinfo' => 'cloneinfo',
103
+ 'security' => 'getSecurityStats',
104
+ 'securityFix' => 'doSecurityFix',
105
+ 'securityUnFix' => 'doSecurityUnFix',
106
+ 'post_action' => 'post_action',
107
+ 'get_all_posts' => 'get_all_posts',
108
+ 'comment_action' => 'comment_action',
109
+ 'comment_bulk_action' => 'comment_bulk_action',
110
+ 'get_all_comments' => 'get_all_comments',
111
+ 'get_all_themes' => 'get_all_themes',
112
+ 'theme_action' => 'theme_action',
113
+ 'get_all_plugins' => 'get_all_plugins',
114
+ 'plugin_action' => 'plugin_action',
115
+ 'get_all_pages' => 'get_all_pages',
116
+ 'get_all_users' => 'get_all_users',
117
+ 'user_action' => 'user_action',
118
+ 'search_users' => 'search_users',
119
+ 'get_terms' => 'get_terms',
120
+ 'set_terms' => 'set_terms',
121
+ 'insert_comment' => 'insert_comment',
122
+ 'get_post_meta' => 'get_post_meta',
123
+ 'get_total_ezine_post' => 'get_total_ezine_post',
124
+ 'get_next_time_to_post' => 'get_next_time_to_post',
125
+ 'cancel_scheduled_post' => 'cancel_scheduled_post',
126
+ 'serverInformation' => 'serverInformation',
127
+ 'maintenance_site' => 'maintenance_site',
128
+ 'keyword_links_action' => 'keyword_links_action',
129
+ 'branding_child_plugin' => 'branding_child_plugin',
130
+ 'code_snippet' => 'code_snippet',
131
+ 'uploader_action' => 'uploader_action',
132
+ 'wordpress_seo' => 'wordpress_seo',
133
+ 'client_report' => 'client_report',
134
+ 'createBackupPoll' => 'backupPoll',
135
+ 'page_speed' => 'page_speed',
136
+ 'woo_com_status' => 'woo_com_status',
137
+ 'heatmaps' => 'heatmaps',
138
+ 'links_checker' => 'links_checker',
139
+ 'wordfence' => 'wordfence',
140
+ 'delete_backup' => 'delete_backup',
141
+ 'update_values' => 'update_values',
142
+ 'ithemes' => 'ithemes',
143
+ 'updraftplus' => 'updraftplus',
144
+ 'backup_wp' => 'backup_wp',
145
+ 'backwpup' => 'backwpup',
146
+ 'wp_rocket' => 'wp_rocket',
147
+ 'settings_tools' => 'settings_tools',
148
+ 'skeleton_key' => 'skeleton_key',
149
+ 'custom_post_type' => 'custom_post_type',
150
+ 'backup_buddy' => 'backup_buddy',
151
+ 'get_site_icon' => 'get_site_icon',
152
+ 'vulner_checker' => 'vulner_checker',
153
+ 'wp_staging' => 'wp_staging'
154
+ );
155
+
156
+ private $FTP_ERROR = 'Failed! Please, add FTP details for automatic updates.';
157
+
158
+ private $callableFunctionsNoAuth = array(
159
+ 'stats' => 'getSiteStatsNoAuth',
160
+ );
161
+
162
+ private $posts_where_suffix;
163
+ private $comments_and_clauses;
164
+ private $plugin_slug;
165
+ private $plugin_dir;
166
+ private $slug;
167
+ private $maxHistory = 5;
168
+
169
+ private $filterFunction = null;
170
+ public static $brandingTitle = null;
171
+ private $branding_robust = 'MainWP';
172
+
173
+ public static $subPages;
174
+ public static $subPagesLoaded = false;
175
+
176
+ public function __construct( $plugin_file ) {
177
+ $this->update();
178
+ $this->load_all_options();
179
+ $this->filterFunction = create_function( '$a', 'if ($a == null) { return false; } if (is_object($a) && property_exists($a, "last_checked") && !property_exists($a, "checked")) return false; return $a;' );
180
+ $this->plugin_dir = dirname( $plugin_file );
181
+ $this->plugin_slug = plugin_basename( $plugin_file );
182
+ list ( $t1, $t2 ) = explode( '/', $this->plugin_slug );
183
+ $this->slug = str_replace( '.php', '', $t2 );
184
+
185
+ $this->posts_where_suffix = '';
186
+ $this->comments_and_clauses = '';
187
+ add_action( 'template_redirect', array( $this, 'template_redirect' ) );
188
+ add_action( 'init', array( &$this, 'check_login' ), 1 );
189
+ add_action( 'init', array( &$this, 'parse_init' ), 33 );
190
+ add_action( 'admin_menu', array( &$this, 'admin_menu' ) );
191
+ add_action( 'admin_init', array( &$this, 'admin_init' ) );
192
+ add_action( 'admin_head', array( &$this, 'admin_head' ) );
193
+ add_action( 'init', array( &$this, 'localization' ), 33 );
194
+ add_action( 'pre_current_active_plugins', array( &$this, 'pre_current_active_plugins' ) );
195
+
196
+ if ( is_admin() ) {
197
+ MainWP_Helper::update_option( 'mainwp_child_plugin_version', self::$version, 'yes' );
198
+ }
199
+
200
+ $this->checkOtherAuth();
201
+
202
+ MainWP_Clone::get()->init();
203
+ MainWP_Child_Server_Information::init();
204
+ MainWP_Client_Report::init();
205
+ MainWP_Child_Plugins_Check::Instance();
206
+ MainWP_Child_Themes_Check::Instance();
207
+
208
+ $this->run_saved_snippets();
209
+
210
+ if ( ! get_option( 'mainwp_child_pubkey' ) ) {
211
+ MainWP_Helper::update_option( 'mainwp_child_branding_disconnected', 'yes', 'yes' );
212
+ }
213
+
214
+ $cancelled_branding = ( get_option( 'mainwp_child_branding_disconnected' ) === 'yes' ) && ! get_option( 'mainwp_branding_preserve_branding' );
215
+ if ( ! $cancelled_branding ) {
216
+ $branding_header = get_option( 'mainwp_branding_plugin_header' );
217
+ if ( is_array( $branding_header ) && isset( $branding_header['name'] ) && ! empty( $branding_header['name'] ) ) {
218
+ $this->branding_robust = stripslashes( $branding_header['name'] );
219
+ }
220
+ }
221
+ add_action( 'admin_notices', array( &$this, 'admin_notice' ) );
222
+ add_filter( 'plugin_row_meta', array( &$this, 'plugin_row_meta' ), 10, 2 );
223
+
224
+ //WP-Cron
225
+ if ( defined( 'DOING_CRON' ) && DOING_CRON ) {
226
+ if ( isset($_GET[ 'mainwp_child_run' ]) && ! empty( $_GET[ 'mainwp_child_run' ] ) ) {
227
+ add_action( 'init', array( $this, 'cron_active' ), PHP_INT_MAX );
228
+ }
229
+ }
230
+
231
+ }
232
+
233
+
234
+
235
+ function load_all_options() {
236
+ global $wpdb;
237
+
238
+ if ( !defined( 'WP_INSTALLING' ) || !is_multisite() )
239
+ $alloptions = wp_cache_get( 'alloptions', 'options' );
240
+ else
241
+ $alloptions = false;
242
+
243
+ if ( !defined( 'WP_INSTALLING' ) || !is_multisite() )
244
+ $notoptions = wp_cache_get( 'notoptions', 'options' );
245
+ else
246
+ $notoptions = false;
247
+
248
+ if ( !isset($alloptions['mainwp_db_version']) ) {
249
+ $suppress = $wpdb->suppress_errors();
250
+ $options = array(
251
+ 'mainwp_child_auth',
252
+ 'mainwp_branding_plugin_header',
253
+ 'mainwp_child_reports_db',
254
+ 'mainwp_child_fix_htaccess',
255
+ 'mainwp_child_pluginDir',
256
+ 'mainwp_updraftplus_hide_plugin',
257
+ 'mainwp_backwpup_ext_enabled',
258
+ 'mainwpKeywordLinks',
259
+ 'mainwp_child_server',
260
+ 'mainwp_kwl_options',
261
+ 'mainwp_kwl_keyword_links',
262
+ 'mainwp_keyword_links_htaccess_set',
263
+ 'mainwp_pagespeed_hide_plugin',
264
+ 'mainwp_kwl_enable_statistic',
265
+ 'mainwp_child_clone_permalink',
266
+ 'mainwp_child_restore_permalink',
267
+ 'mainwp_ext_snippets_enabled',
268
+ 'mainwp_child_pubkey',
269
+ 'mainwp_child_nossl',
270
+ 'mainwp_security',
271
+ 'mainwp_backupwordpress_ext_enabled',
272
+ 'mainwp_wprocket_ext_enabled',
273
+ 'mainwp_wordfence_ext_enabled',
274
+ 'mainwp_branding_button_contact_label',
275
+ 'mainwp_branding_extra_settings',
276
+ 'mainwp_branding_child_hide',
277
+ 'mainwp_branding_ext_enabled',
278
+ 'mainwp_creport_ext_branding_enabled',
279
+ 'mainwp_pagespeed_ext_enabled',
280
+ 'mainwp_linkschecker_ext_enabled',
281
+ 'mainwp_ithemes_ext_enabled',
282
+ );
283
+ $query = "SELECT option_name, option_value FROM $wpdb->options WHERE option_name in (";
284
+ foreach ($options as $option) {
285
+ $query .= "'" . $option . "', ";
286
+ }
287
+ $query = substr($query, 0, strlen($query) - 2);
288
+ $query .= ")";
289
+
290
+ $alloptions_db = $wpdb->get_results( $query );
291
+ $wpdb->suppress_errors($suppress);
292
+ if ( !is_array( $alloptions ) ) $alloptions = array();
293
+ if ( is_array( $alloptions_db ) ) {
294
+ foreach ( (array) $alloptions_db as $o ) {
295
+ $alloptions[ $o->option_name ] = $o->option_value;
296
+ unset($options[array_search($o->option_name, $options)]);
297
+ }
298
+ foreach ($options as $option ) {
299
+ $notoptions[ $option ] = true;
300
+ }
301
+ if ( ! defined( 'WP_INSTALLING' ) || ! is_multisite() ) {
302
+ wp_cache_set( 'alloptions', $alloptions, 'options' );
303
+ wp_cache_set( 'notoptions', $notoptions, 'options' );
304
+ }
305
+ }
306
+ }
307
+
308
+ return $alloptions;
309
+ }
310
+
311
+
312
+ function update() {
313
+ $update_version = get_option( 'mainwp_child_update_version' );
314
+
315
+ if ( $update_version === $this->update_version ) {
316
+ return;
317
+ }
318
+
319
+ if ( false === $update_version ) {
320
+ $options = array(
321
+ 'mainwp_child_legacy',
322
+ 'mainwp_child_auth',
323
+ 'mainwp_branding_ext_enabled',
324
+ 'mainwp_child_uniqueId',
325
+ 'mainwp_child_htaccess_set',
326
+ 'mainwp_child_fix_htaccess',
327
+ 'mainwp_child_pubkey',
328
+ 'mainwp_child_server',
329
+ 'mainwp_child_nonce',
330
+ 'mainwp_child_nossl',
331
+ 'mainwp_child_nossl_key',
332
+ 'mainwp_child_remove_wp_version',
333
+ 'mainwp_child_remove_rsd',
334
+ 'mainwp_child_remove_wlw',
335
+ 'mainwp_child_remove_core_updates',
336
+ 'mainwp_child_remove_plugin_updates',
337
+ 'mainwp_child_remove_theme_updates',
338
+ 'mainwp_child_remove_php_reporting',
339
+ 'mainwp_child_remove_scripts_version',
340
+ 'mainwp_child_remove_styles_version',
341
+ 'mainwp_child_remove_readme',
342
+ 'heatMapEnabled',
343
+ 'mainwp_child_clone_sites',
344
+ 'mainwp_child_pluginDir',
345
+ 'mainwp_premium_updates',
346
+ 'mainwp_child_activated_once',
347
+ 'mainwp_maintenance_opt_alert_404',
348
+ 'mainwp_maintenance_opt_alert_404_email',
349
+ 'mainwp_ext_code_snippets',
350
+ 'mainwp_ext_snippets_enabled',
351
+ 'mainwp_temp_clone_plugins',
352
+ 'mainwp_temp_clone_themes',
353
+ 'mainwp_child_click_data',
354
+ 'mainwp_child_clone_from_server_last_folder',
355
+ 'mainwp_child_clone_permalink',
356
+ 'mainwp_child_restore_permalink',
357
+ 'mainwp_keyword_links_htaccess_set',
358
+ 'mainwp_kwl_options',
359
+ 'mainwp_kwl_keyword_links',
360
+ 'mainwp_kwl_click_statistic_data',
361
+ 'mainwp_kwl_statistic_data_',
362
+ 'mainwp_kwl_enable_statistic',
363
+ 'mainwpKeywordLinks',
364
+ 'mainwp_branding_ext_enabled',
365
+ 'mainwp_branding_plugin_header',
366
+ 'mainwp_branding_support_email',
367
+ 'mainwp_branding_support_message',
368
+ 'mainwp_branding_remove_restore',
369
+ 'mainwp_branding_remove_setting',
370
+ 'mainwp_branding_remove_wp_tools',
371
+ 'mainwp_branding_remove_wp_setting',
372
+ 'mainwp_branding_remove_permalink',
373
+ 'mainwp_branding_button_contact_label',
374
+ 'mainwp_branding_send_email_message',
375
+ 'mainwp_branding_message_return_sender',
376
+ 'mainwp_branding_submit_button_title',
377
+ 'mainwp_branding_disable_wp_branding',
378
+ 'mainwp_branding_extra_settings',
379
+ 'mainwp_branding_child_hide',
380
+ 'mainwp_branding_show_support',
381
+ 'mainwp_branding_disable_change',
382
+ );
383
+ foreach ( $options as $option ) {
384
+ MainWP_Helper::fix_option( $option );
385
+ }
386
+ } else if ( ( false === $update_version ) || ( '1.0' === $update_version ) || ( '1.1' === $update_version ) ) {
387
+ $options = array(
388
+ 'mainwp_child_pubkey',
389
+ 'mainwp_child_branding_disconnected',
390
+ 'mainwp_branding_plugin_header',
391
+ 'mainwp_child_update_version',
392
+ 'mainwp_child_auth',
393
+ 'mainwp_child_clone_permalink',
394
+ 'mainwp_child_restore_permalink',
395
+ 'mainwp_ext_snippets_enabled',
396
+ 'mainwp_child_fix_htaccess',
397
+ 'mainwp_child_pluginDir',
398
+ 'mainwp_child_htaccess_set',
399
+ 'heatMapEnabled',
400
+ 'heatMapsIndividualOverrideSetting',
401
+ 'heatMapExtensionLoaded',
402
+ 'heatMapsIndividualDisable',
403
+ 'mainwp_child_nossl',
404
+ 'mainwp_updraftplus_ext_enabled',
405
+ 'mainwpKeywordLinks',
406
+ 'mainwp_keyword_links_htaccess_set',
407
+ 'mainwp_branding_button_contact_label',
408
+ 'mainwp_branding_extra_settings',
409
+ 'mainwp_branding_ext_enabled',
410
+ 'mainwp_creport_ext_branding_enabled',
411
+ 'mainwp_pagespeed_ext_enabled',
412
+ 'mainwp_linkschecker_ext_enabled',
413
+ 'mainwp_wordfence_ext_enabled',
414
+ 'mainwp_ithemes_ext_enabled',
415
+ 'mainwp_maintenance_opt_alert_404',
416
+ );
417
+ foreach ( $options as $option ) {
418
+ MainWP_Helper::fix_option( $option, 'yes' );
419
+ }
420
+
421
+ if ( ! is_array( get_option( 'mainwp_security' ) ) ) {
422
+ $securityOptions = array(
423
+ 'wp_version' => 'mainwp_child_remove_wp_version',
424
+ 'rsd' => 'mainwp_child_remove_rsd',
425
+ 'wlw' => 'mainwp_child_remove_wlw',
426
+ 'core_updates' => 'mainwp_child_remove_core_updates',
427
+ 'plugin_updates' => 'mainwp_child_remove_plugin_updates',
428
+ 'theme_updates' => 'mainwp_child_remove_theme_updates',
429
+ 'php_reporting' => 'mainwp_child_remove_php_reporting',
430
+ 'scripts_version' => 'mainwp_child_remove_scripts_version',
431
+ 'styles_version' => 'mainwp_child_remove_styles_version',
432
+ 'readme' => 'mainwp_child_remove_readme',
433
+ );
434
+
435
+ $security = array();
436
+ foreach ( $securityOptions as $option => $old ) {
437
+ $value = get_option( $old );
438
+ $security[ $option ] = ( 'T' === $value );
439
+ }
440
+ MainWP_Helper::update_option( 'mainwp_security', $security, 'yes' );
441
+ }
442
+ } else if ($update_version == '1.2') {
443
+ MainWP_Child_Plugins_Check::Instance()->cleanup_deactivation(false);
444
+ MainWP_Child_Themes_Check::Instance()->cleanup_deactivation(false);
445
+ }
446
+
447
+ MainWP_Helper::update_option( 'mainwp_child_update_version', $this->update_version, 'yes' );
448
+ }
449
+
450
+ function cron_active() {
451
+ if ( ! defined( 'DOING_CRON' ) || ! DOING_CRON ) {
452
+ return;
453
+ }
454
+ if ( empty( $_GET[ 'mainwp_child_run' ] ) || 'test' !== $_GET[ 'mainwp_child_run' ] ) {
455
+ return;
456
+ }
457
+ @session_write_close();
458
+ @header( 'Content-Type: text/html; charset=' . get_bloginfo( 'charset' ), TRUE );
459
+ @header( 'X-Robots-Tag: noindex, nofollow', TRUE );
460
+ @header( 'X-MainWP-Child-Version: ' . MainWP_Child::$version, TRUE );
461
+ nocache_headers();
462
+ if ( $_GET[ 'mainwp_child_run' ] == 'test' ) {
463
+ die( 'MainWP Test' );
464
+ }
465
+ die( '' );
466
+ }
467
+
468
+ public function admin_notice() {
469
+ //Admin Notice...
470
+ if ( is_plugin_active( 'mainwp-child/mainwp-child.php' ) ) {
471
+ if ( ! get_option( 'mainwp_child_pubkey' ) && MainWP_Helper::isAdmin() && is_admin() ) {
472
+ $child_name = ( $this->branding_robust === 'MainWP' ) ? 'MainWP Child' : $this->branding_robust;
473
+ $msg = '<div class="wrap"><div class="postbox" style="margin-top: 4em;"><p style="background: #a00; color: #fff; font-size: 22px; font-weight: bold; margin: 0; padding: .3em;">';
474
+ $msg .= __( 'Attention!', 'mainwp-child' );
475
+ $msg .= '</p><div style="padding-left: 1em; padding-right: 1em;"><p style="font-size: 16px;">';
476
+ $msg .= __( 'Please add this site to your ', 'mainwp-child' ) . $this->branding_robust . __( ' Dashboard <b>NOW</b> or deactivate the ', 'mainwp-child' ) . $child_name . __( ' plugin until you are ready to connect this site to your Dashboard in order to avoid unexpected security issues.','mainwp-child' );
477
+ $msg .= '</p>';
478
+ $msg .= '<p style="font-size: 16px;">';
479
+ $msg .= __( 'If you are not sure how to add this site to your Dashboard, <a href="https://mainwp.com/help/docs/set-up-the-mainwp-plugin/add-site-to-your-dashboard/" target="_blank">please review these instructions</a>.', 'mainwp-child' );
480
+ $msg .= '</p>';
481
+ if ( ! MainWP_Child_Branding::is_branding() ) {
482
+ $msg .= '<p>';
483
+ $msg .= __( 'You can also turn on the unique security ID option in <a href="admin.php?page=mainwp_child_tab">', 'mainwp-child' ) . $this->branding_robust . __( ' settings</a> if you would like extra security and additional time to add this site to your Dashboard. <br/>Find out more in this help document <a href="https://mainwp.com/help/docs/set-up-the-mainwp-plugin/set-unique-security-id/" target="_blank">How do I use the child unique security ID?</a>', 'mainwp-child' );
484
+ $msg .= '</p>';
485
+ }
486
+ $msg .= '</div></div></div>';
487
+ echo wp_kses_post( $msg );
488
+ }
489
+ }
490
+
491
+ MainWP_Child_Server_Information::showWarnings();
492
+ }
493
+
494
+ public function localization() {
495
+ load_plugin_textdomain( 'mainwp-child', false, dirname( dirname( plugin_basename( __FILE__ ) ) ) . '/languages/' );
496
+ }
497
+
498
+ public function pre_current_active_plugins() {
499
+ $plugin_updates = get_plugin_updates();
500
+ $fix_update_plugins = array();
501
+ if ( is_array( $plugin_updates ) ) {
502
+ foreach ( $plugin_updates as $slug => $plugin_update ) {
503
+ if ( in_array( $slug, array( 'ithemes-security-pro/ithemes-security-pro.php', 'monarch/monarch.php', 'cornerstone/cornerstone.php', 'updraftplus/updraftplus.php', 'wp-all-import-pro/wp-all-import-pro.php') ) ) {
504
+ $fix_update_plugins[ $slug ] = $plugin_update;
505
+ }
506
+ }
507
+ }
508
+ set_site_transient( 'tofix_update_plugins', $fix_update_plugins);
509
+ }
510
+
511
+ function checkOtherAuth() {
512
+ $auths = get_option( 'mainwp_child_auth' );
513
+
514
+ if ( ! $auths ) {
515
+ $auths = array();
516
+ }
517
+
518
+ if ( ! isset( $auths['last'] ) || $auths['last'] < mktime( 0, 0, 0, date( 'm' ), date( 'd' ), date( 'Y' ) ) ) {
519
+ //Generate code for today..
520
+ for ( $i = 0; $i < $this->maxHistory; $i ++ ) {
521
+ if ( ! isset( $auths[ $i + 1 ] ) ) {
522
+ continue;
523
+ }
524
+
525
+ $auths[ $i ] = $auths[ $i + 1 ];
526
+ }
527
+ $newI = $this->maxHistory + 1;
528
+ while ( isset( $auths[ $newI ] ) ) {
529
+ unset( $auths[ $newI ++ ] );
530
+ }
531
+ $auths[ $this->maxHistory ] = md5( MainWP_Helper::randString( 14 ) );
532
+ $auths['last'] = time();
533
+ MainWP_Helper::update_option( 'mainwp_child_auth', $auths, 'yes' );
534
+ }
535
+ }
536
+
537
+ function isValidAuth( $key ) {
538
+ $auths = get_option( 'mainwp_child_auth' );
539
+ if ( ! $auths ) {
540
+ return false;
541
+ }
542
+ for ( $i = 0; $i <= $this->maxHistory; $i ++ ) {
543
+ if ( isset( $auths[ $i ] ) && ( $auths[ $i ] === $key ) ) {
544
+ return true;
545
+ }
546
+ }
547
+
548
+ return false;
549
+ }
550
+
551
+ function template_redirect() {
552
+ $this->maintenance_alert_404();
553
+ }
554
+
555
+
556
+ public function plugin_row_meta( $plugin_meta, $plugin_file ) {
557
+ if ( $this->plugin_slug !== $plugin_file ) {
558
+ return $plugin_meta;
559
+ }
560
+
561
+ return apply_filters( 'mainwp_child_plugin_row_meta', $plugin_meta, $plugin_file, $this->plugin_slug );
562
+ }
563
+
564
+ function admin_menu() {
565
+ $cancelled_branding = ( get_option( 'mainwp_child_branding_disconnected' ) === 'yes' ) && ! get_option( 'mainwp_branding_preserve_branding' );
566
+
567
+ if ( get_option( 'mainwp_branding_remove_wp_tools' ) && ! $cancelled_branding ) {
568
+ remove_menu_page( 'tools.php' );
569
+ $pos = stripos( $_SERVER['REQUEST_URI'], 'tools.php' ) ||
570
+ stripos( $_SERVER['REQUEST_URI'], 'import.php' ) ||
571
+ stripos( $_SERVER['REQUEST_URI'], 'export.php' );
572
+ if ( false !== $pos ) {
573
+ wp_redirect( get_option( 'siteurl' ) . '/wp-admin/index.php' );
574
+ }
575
+ }
576
+ // if preserve branding do not remove menus
577
+ if ( get_option( 'mainwp_branding_remove_wp_setting' ) && ! $cancelled_branding ) {
578
+ remove_menu_page( 'options-general.php' );
579
+ $pos = stripos( $_SERVER['REQUEST_URI'], 'options-general.php' ) ||
580
+ stripos( $_SERVER['REQUEST_URI'], 'options-writing.php' ) ||
581
+ stripos( $_SERVER['REQUEST_URI'], 'options-reading.php' ) ||
582
+ stripos( $_SERVER['REQUEST_URI'], 'options-discussion.php' ) ||
583
+ stripos( $_SERVER['REQUEST_URI'], 'options-media.php' ) ||
584
+ stripos( $_SERVER['REQUEST_URI'], 'options-permalink.php' );
585
+ if ( false !== $pos ) {
586
+ wp_redirect( get_option( 'siteurl' ) . '/wp-admin/index.php' );
587
+ exit();
588
+ }
589
+ }
590
+
591
+ if ( get_option( 'mainwp_branding_remove_permalink' ) && ! $cancelled_branding ) {
592
+ remove_submenu_page( 'options-general.php', 'options-permalink.php' );
593
+ $pos = stripos( $_SERVER['REQUEST_URI'], 'options-permalink.php' );
594
+ if ( false !== $pos ) {
595
+ wp_redirect( get_option( 'siteurl' ) . '/wp-admin/index.php' );
596
+ exit();
597
+ }
598
+ }
599
+
600
+ $remove_all_child_menu = false;
601
+ if ( get_option( 'mainwp_branding_remove_setting' ) && get_option( 'mainwp_branding_remove_restore' ) && get_option( 'mainwp_branding_remove_server_info' ) ) {
602
+ $remove_all_child_menu = true;
603
+ }
604
+
605
+ // if preserve branding do not hide menus
606
+ if ( ( ! $remove_all_child_menu && get_option( 'mainwp_branding_child_hide' ) !== 'T' ) || $cancelled_branding ) {
607
+ $branding_header = get_option( 'mainwp_branding_plugin_header' );
608
+ if ( ( is_array( $branding_header ) && ! empty( $branding_header['name'] ) ) && ! $cancelled_branding ) {
609
+ self::$brandingTitle = $child_menu_title = stripslashes( $branding_header['name'] );
610
+ $child_page_title = $child_menu_title . ' Settings';
611
+ } else {
612
+ $child_menu_title = 'MainWP Child';
613
+ $child_page_title = 'MainWPSettings';
614
+ }
615
+
616
+ $settingsPage = add_submenu_page( 'options-general.php', $child_menu_title, $child_menu_title, 'manage_options', 'mainwp_child_tab', array( &$this, 'render_pages' ) );
617
+
618
+ add_action( 'admin_print_scripts-' . $settingsPage, array( 'MainWP_Clone', 'print_scripts' ) );
619
+ $subpageargs = array(
620
+ 'child_slug' => 'options-general.php', // to backwards compatible
621
+ 'branding' => (self::$brandingTitle === null) ? 'MainWP' : self::$brandingTitle,
622
+ 'parent_menu' => $settingsPage
623
+ );
624
+ do_action( 'mainwp-child-subpages', $subpageargs ); // to compatible
625
+
626
+ $sub_pages = array();
627
+ $all_subpages = apply_filters( 'mainwp-child-init-subpages', array() );
628
+
629
+ if ( !is_array( $all_subpages ) )
630
+ $all_subpages = array();
631
+
632
+ if ( !self::$subPagesLoaded ) {
633
+ foreach( $all_subpages as $page ) {
634
+ $slug = isset( $page['slug'] ) ? $page['slug'] : '';
635
+ if ( empty( $slug ) )
636
+ continue;
637
+ $subpage = array();
638
+ $subpage['slug'] = $slug;
639
+ $subpage['title'] = $page['title'];
640
+ $subpage['page'] = 'mainwp-' . str_replace( ' ', '-', strtolower( str_replace( '-', ' ', $slug ) ) );
641
+ if ( isset( $page['callback'] ) ) {
642
+ $subpage['callback'] = $page['callback'];
643
+ $created_page = add_submenu_page( 'options-general.php', $subpage['title'], '<div class="mainwp-hidden">' . $subpage['title'] . '</div>', 'manage_options', $subpage['page'], $subpage['callback'] );
644
+ if ( isset( $page['load_callback'] ) ) {
645
+ $subpage['load_callback'] = $page['load_callback'];
646
+ add_action( 'load-' . $created_page, $subpage['load_callback'] );
647
+ }
648
+ }
649
+ $sub_pages[] = $subpage;
650
+ }
651
+ self::$subPages = $sub_pages;
652
+ self::$subPagesLoaded = true;
653
+ MainWP_Helper::update_option( 'mainwp_child_subpages', self::$subPages );
654
+ }
655
+ add_action( 'mainwp-child-pageheader', array( __CLASS__, 'render_header' ) );
656
+ add_action( 'mainwp-child-pagefooter', array( __CLASS__, 'render_footer' ) );
657
+
658
+ global $submenu;
659
+ if ( isset( $submenu['options-general.php'] ) ) {
660
+ foreach ( $submenu['options-general.php'] as $index => $item ) {
661
+ if ( 'mainwp-reports-page' === $item[2] || 'mainwp-reports-settings' === $item[2]) {
662
+ unset( $submenu['options-general.php'][ $index ] );
663
+ }
664
+ }
665
+ }
666
+ }
667
+ }
668
+
669
+ function render_pages($shownPage) {
670
+ $shownPage = '';
671
+ if ( isset($_GET['tab']) ) {
672
+ $shownPage = $_GET['tab'];
673
+ }
674
+
675
+ $hide_settings = get_option( 'mainwp_branding_remove_setting' ) ? true : false;
676
+ $hide_restore = get_option( 'mainwp_branding_remove_restore' ) ? true : false;
677
+ $hide_server_info = get_option( 'mainwp_branding_remove_server_info' ) ? true : false;
678
+ $hide_connection_detail = get_option( 'mainwp_branding_remove_connection_detail' ) ? true : false;
679
+ $hide_style = 'style="display:none"';
680
+
681
+ if ($shownPage == '') {
682
+ if (!$hide_settings ) {
683
+ $shownPage = 'settings';
684
+ } else if (!$hide_restore) {
685
+ $shownPage = 'restore-clone';
686
+ } else if (!$hide_server_info) {
687
+ $shownPage = 'server-info';
688
+ } else if (!$hide_connection_detail) {
689
+ $shownPage = 'connection-detail';
690
+ }
691
+ }
692
+
693
+ self::render_header($shownPage, false);
694
+ ?>
695
+ <?php if (!$hide_settings ) { ?>
696
+ <div class="mainwp-child-setting-tab settings" <?php echo ('settings' !== $shownPage) ? $hide_style : '' ; ?>>
697
+ <?php $this->settings(); ?>
698
+ </div>
699
+ <?php } ?>
700
+
701
+ <?php if ( !$hide_restore ) { ?>
702
+ <div class="mainwp-child-setting-tab restore-clone" <?php echo ( 'restore-clone' !== $shownPage ) ? $hide_style : ''; ?>>
703
+ <?php
704
+ if ( '' === session_id() ) {
705
+ @session_start();
706
+ }
707
+
708
+ if ( isset( $_SESSION['file'] ) ) {
709
+ MainWP_Clone::renderRestore();
710
+ } else {
711
+ $sitesToClone = get_option( 'mainwp_child_clone_sites' );
712
+ if ( 0 !== (int) $sitesToClone ) {
713
+ MainWP_Clone::render();
714
+ } else {
715
+ MainWP_Clone::renderNormalRestore();
716
+ }
717
+ }
718
+ ?>
719
+ </div>
720
+ <?php } ?>
721
+
722
+ <?php if ( !$hide_server_info ) { ?>
723
+ <div class="mainwp-child-setting-tab server-info" <?php echo ('server-info' !== $shownPage) ? $hide_style : '' ; ?>>
724
+ <?php MainWP_Child_Server_Information::renderPage(); ?>
725
+ </div>
726
+ <?php } ?>
727
+
728
+ <?php if ( !$hide_connection_detail ) { ?>
729
+ <div class="mainwp-child-setting-tab connection-detail" <?php echo ('connection-detail' !== $shownPage) ? $hide_style : '' ; ?>>
730
+ <?php MainWP_Child_Server_Information::renderConnectionDetails(); ?>
731
+ </div>
732
+ <?php } ?>
733
+
734
+
735
+
736
+ <?php
737
+ self::render_footer();
738
+ }
739
+
740
+ public static function render_header($shownPage, $subpage = true) {
741
+ if ( isset($_GET['tab']) ) {
742
+ $shownPage = $_GET['tab'];
743
+ }
744
+
745
+ if (empty($shownPage))
746
+ $shownPage = 'settings';
747
+
748
+ $hide_settings = get_option( 'mainwp_branding_remove_setting' ) ? true : false;
749
+ $hide_restore = get_option( 'mainwp_branding_remove_restore' ) ? true : false;
750
+ $hide_server_info = get_option( 'mainwp_branding_remove_server_info' ) ? true : false;
751
+ $hide_connection_detail = get_option( 'mainwp_branding_remove_connection_detail' ) ? true : false;
752
+ $sitesToClone = get_option( 'mainwp_child_clone_sites' );
753
+
754
+ ?>
755
+ <style type="text/css">
756
+ .mainwp-tabs
757
+ {
758
+ margin-top: 2em;
759
+ border-bottom: 1px solid #e5e5e5;
760
+ }
761
+
762
+ #mainwp-tabs {
763
+ clear: both ;
764
+ }
765
+ #mainwp-tabs .nav-tab-active {
766
+ background: #fafafa ;
767
+ border-top: 1px solid #7fb100 !important;
768
+ border-left: 1px solid #e5e5e5;
769
+ border-right: 1px solid #e5e5e5;
770
+ border-bottom: 1px solid #fafafa !important ;
771
+ color: #7fb100;
772
+ }
773
+
774
+ #mainwp-tabs .nav-tab {
775
+ border-top: 1px solid #e5e5e5;
776
+ border-left: 1px solid #e5e5e5;
777
+ border-right: 1px solid #e5e5e5;
778
+ border-bottom: 1px solid #e5e5e5;
779
+ padding: 10px 16px;
780
+ font-size: 14px;
781
+ text-transform: uppercase;
782
+ }
783
+
784
+ #mainwp_wrap-inside {
785
+ min-height: 80vh;
786
+ height: 100% ;
787
+ margin-top: 0em ;
788
+ padding: 10px ;
789
+ background: #fafafa ;
790
+ border-top: none ;
791
+ border-bottom: 1px solid #e5e5e5;
792
+ border-left: 1px solid #e5e5e5;
793
+ border-right: 1px solid #e5e5e5;
794
+ box-shadow: 0 1px 1px rgba(0,0,0,.04);
795
+ position: relative;
796
+ }
797
+
798
+ #mainwp_wrap-inside h2.hndle {
799
+ font-size: 14px;
800
+ padding: 8px 12px;
801
+ margin: 0;
802
+ line-height: 1.4;
803
+ }
804
+
805
+ .mainwp-hidden {
806
+ display: none;
807
+ }
808
+ </style>
809
+
810
+ <div class="wrap">
811
+ <h2><i class="fa fa-file"></i> <?php echo ( self::$brandingTitle === null ? 'MainWP Child' : self::$brandingTitle ); ?></h2>
812
+ <div style="clear: both;"></div><br/>
813
+ <div class="mainwp-tabs" id="mainwp-tabs">
814
+ <?php if ( !$hide_settings ) { ?>
815
+ <a class="nav-tab pos-nav-tab <?php if ( $shownPage === 'settings' ) { echo 'nav-tab-active'; } ?>" tab-slug="settings" href="<?php echo $subpage ? 'options-general.php?page=mainwp_child_tab&tab=settings' : '#'; ?>" style="margin-left: 0 !important;"><?php _e( 'Settings','mainwp-child' ); ?></a>
816
+ <?php } ?>
817
+ <?php if ( !$hide_restore ) { ?>
818
+ <a class="nav-tab pos-nav-tab <?php if ( $shownPage === 'restore-clone' ) { echo 'nav-tab-active'; } ?>" tab-slug="restore-clone" href="<?php echo $subpage ? 'options-general.php?page=mainwp_child_tab&tab=restore-clone' : '#'; ?>"><?php echo ( 0 !== (int) $sitesToClone ) ? __( 'Restore / Clone','mainwp-child' ) : __( 'Restore','mainwp-child' ); ?></a>
819
+ <?php } ?>
820
+ <?php if (!$hide_server_info ) { ?>
821
+ <a class="nav-tab pos-nav-tab <?php if ( $shownPage === 'server-info' ) { echo 'nav-tab-active'; } ?>" tab-slug="server-info" href="<?php echo $subpage ? 'options-general.php?page=mainwp_child_tab&tab=server-info' : '#'; ?>"><?php _e( 'Server information','mainwp-child' ); ?></a>
822
+ <?php } ?>
823
+ <?php if (!$hide_connection_detail ) { ?>
824
+ <a class="nav-tab pos-nav-tab <?php if ( $shownPage === 'connection-detail' ) { echo 'nav-tab-active'; } ?>" tab-slug="connection-detail" href="<?php echo $subpage ? 'options-general.php?page=mainwp_child_tab&tab=connection-detail' : '#'; ?>"><?php _e( 'Connection Details','mainwp-child' ); ?></a>
825
+ <?php } ?>
826
+ <?php
827
+ if ( isset( self::$subPages ) && is_array( self::$subPages ) ) {
828
+ foreach ( self::$subPages as $subPage ) {
829
+ ?>
830
+ <a class="nav-tab pos-nav-tab <?php if ( $shownPage == $subPage['slug'] ) { echo 'nav-tab-active'; } ?>" tab-slug="<?php echo $subPage['slug']; ?>" href="options-general.php?page=<?php echo $subPage['page']; ?>"><?php echo $subPage['title']; ?></a>
831
+ <?php
832
+ }
833
+ }
834
+ ?>
835
+ <div style="clear:both;"></div>
836
+ </div>
837
+ <div style="clear:both;"></div>
838
+ <script type="text/javascript">
839
+ jQuery( document ).ready( function () {
840
+ $hideMenu = jQuery('#menu-settings li a .mainwp-hidden');
841
+ $hideMenu.each(function(){jQuery(this).closest('li').hide();})
842
+
843
+ var $tabs = jQuery( '.mainwp-tabs' );
844
+ $tabs.on('click', 'a', function () {
845
+ if (jQuery(this).attr('href') !=='#' )
846
+ return true;
847
+ jQuery('.mainwp-tabs > a').removeClass('nav-tab-active');
848
+ jQuery(this).addClass('nav-tab-active');
849
+ jQuery('.mainwp-child-setting-tab').hide();
850
+ var _tab = jQuery(this).attr('tab-slug');
851
+ jQuery('.mainwp-child-setting-tab.' + _tab ).show();
852
+ return false;
853
+ });
854
+ })
855
+ </script>
856
+
857
+ <div id="mainwp_wrap-inside">
858
+
859
+ <?php
860
+ }
861
+
862
+ public static function render_footer() {
863
+ ?>
864
+ </div>
865
+ </div>
866
+ <?php
867
+ }
868
+
869
+ function admin_init() {
870
+ MainWP_Child_Branding::admin_init();
871
+ if ( MainWP_Helper::isAdmin() && is_admin() ) {
872
+ MainWP_Clone::get()->init_ajax();
873
+ }
874
+ }
875
+
876
+ function admin_head() {
877
+ if (isset($_GET['page']) && $_GET['page'] == 'mainwp_child_tab') {
878
+ ?>
879
+ <style type="text/css">
880
+ .mainwp-postbox-actions-top {
881
+ padding: 10px;
882
+ clear: both;
883
+ border-bottom: 1px solid #ddd;
884
+ background: #f5f5f5;
885
+ }
886
+ h3.mainwp_box_title {
887
+ font-family: "Open Sans",sans-serif;
888
+ font-size: 14px;
889
+ font-weight: 600;
890
+ line-height: 1.4;
891
+ margin: 0;
892
+ padding: 8px 12px;
893
+ border-bottom: 1px solid #eee;
894
+ }
895
+ .mainwp-child-setting-tab.connection-detail .postbox .inside{
896
+ margin: 0;
897
+ padding: 0;
898
+ }
899
+ </style>
900
+ <?php
901
+ }
902
+ }
903
+ function settings() {
904
+ if ( isset( $_POST['submit'] ) && isset( $_POST['nonce'] ) && wp_verify_nonce( $_POST['nonce'], 'child-settings' ) ) {
905
+ if ( isset( $_POST['requireUniqueSecurityId'] ) ) {
906
+ MainWP_Helper::update_option( 'mainwp_child_uniqueId', MainWP_Helper::randString( 8 ) );
907
+ } else {
908
+ MainWP_Helper::update_option( 'mainwp_child_uniqueId', '' );
909
+ }
910
+ }
911
+
912
+ ?>
913
+ <div class="postbox">
914
+ <h2 class="hndle"><span><?php esc_html_e( 'Connection settings', 'mainwp-child' ); ?></span></h2>
915
+ <div class="inside">
916
+ <form method="post" action="options-general.php?page=mainwp_child_tab">
917
+ <div class="howto"><?php esc_html_e( 'The unique security ID adds additional protection between the child plugin and your Dashboard. The unique security ID will need to match when being added to the Dashboard. This is additional security and should not be needed in most situations.', 'mainwp-child' ); ?></div>
918
+ <div style="margin: 1em 0 4em 0;">
919
+ <input name="requireUniqueSecurityId"
920
+ type="checkbox"
921
+ id="requireUniqueSecurityId" <?php if ( '' != get_option( 'mainwp_child_uniqueId' ) ) { echo 'checked'; } ?> />
922
+ <label for="requireUniqueSecurityId"
923
+ style="font-size: 15px;"><?php esc_html_e( 'Require unique security ID', 'mainwp-child' ); ?></label>
924
+ </div>
925
+ <div>
926
+ <?php if ( '' != get_option( 'mainwp_child_uniqueId' ) ) {
927
+ echo '<span style="border: 1px dashed #e5e5e5; background: #fafafa; font-size: 24px; padding: 1em 2em;">' . esc_html__( 'Your unique security ID is:', 'mainwp-child' ) . ' <span style="font-weight: bold; color: #7fb100;">' . esc_html( get_option( 'mainwp_child_uniqueId' ) ) . '</span></span>';
928
+ } ?>
929
+ </div>
930
+ <p class="submit" style="margin-top: 4em;">
931
+ <input type="submit"
932
+ name="submit"
933
+ id="submit"
934
+ class="button button-primary button-hero"
935
+ value="<?php esc_html_e( 'Save changes', 'mainwp-child' ); ?>">
936
+ </p>
937
+ <input type="hidden" name="nonce" value="<?php echo wp_create_nonce( 'child-settings' );?>">
938
+ </form>
939
+ </div>
940
+ </div>
941
+
942
+ <?php
943
+ //self::render_footer('setting');
944
+ }
945
+
946
+ function mod_rewrite_rules( $pRules ) {
947
+
948
+ $home_root = parse_url( home_url() );
949
+ if ( isset( $home_root['path'] ) ) {
950
+ $home_root = trailingslashit( $home_root['path'] );
951
+ } else {
952
+ $home_root = '/';
953
+ }
954
+
955
+ $rules = "<IfModule mod_rewrite.c>\n";
956
+ $rules .= "RewriteEngine On\n";
957
+ $rules .= "RewriteBase $home_root\n";
958
+
959
+ //add in the rules that don't redirect to WP's index.php (and thus shouldn't be handled by WP at all)
960
+ foreach ( $pRules as $match => $query ) {
961
+ // Apache 1.3 does not support the reluctant (non-greedy) modifier.
962
+ $match = str_replace( '.+?', '.+', $match );
963
+
964
+ $rules .= 'RewriteRule ^' . $match . ' ' . $home_root . $query . " [QSA,L]\n";
965
+ }
966
+
967
+ $rules .= "</IfModule>\n";
968
+
969
+ return $rules;
970
+ }
971
+
972
+ function update_htaccess( $hard = false ) {
973
+ if ( !$hard && defined( 'DOING_CRON' ) && DOING_CRON ) {
974
+ return;
975
+ }
976
+
977
+ if ( 'hidden' === ( get_option( 'mainwp_child_pluginDir' ) ) && ( $hard || 'yes' !== ( get_option( 'mainwp_child_htaccess_set' ) ) ) ) {
978
+ include_once( ABSPATH . '/wp-admin/includes/misc.php' );
979
+
980
+ $snPluginDir = basename( $this->plugin_dir );
981
+
982
+ $rules = null;
983
+ if ( ( '1' !== get_option( 'heatMapsIndividualOverrideSetting' ) && '0' !== get_option( 'heatMapEnabled' ) ) ||
984
+ ( '1' === get_option( 'heatMapsIndividualOverrideSetting' ) && '1' !== get_option( 'heatMapsIndividualDisable' ) ) ||
985
+ get_option( 'mainwp_kwl_enable_statistic' )
986
+ ) {
987
+ //Heatmap enabled
988
+ //Make the plugin invisible, except heatmap
989
+ $rules = $this->mod_rewrite_rules( array( 'wp-content/plugins/' . $snPluginDir . '/([^js\/]*)$' => 'wp-content/plugins/THIS_PLUGIN_DOES_NOT_EXIST' ) );
990
+ } else {
991
+ //Make the plugin invisible
992
+ $rules = $this->mod_rewrite_rules( array( 'wp-content/plugins/' . $snPluginDir . '/(.*)$' => 'wp-content/plugins/THIS_PLUGIN_DOES_NOT_EXIST' ) );
993
+ }
994
+
995
+ $home_path = ABSPATH;
996
+ $htaccess_file = $home_path . '.htaccess';
997
+ if ( function_exists( 'save_mod_rewrite_rules' ) ) {
998
+ $rules = explode( "\n", $rules );
999
+
1000
+ // $ch = @fopen($htaccess_file,'w');
1001
+ // if (@flock($ch, LOCK_EX))
1002
+ // {
1003
+ insert_with_markers( $htaccess_file, 'MainWP', $rules );
1004
+ // }
1005
+ // @flock($ch, LOCK_UN);
1006
+ // @fclose($ch);
1007
+
1008
+ }
1009
+ MainWP_Helper::update_option( 'mainwp_child_htaccess_set', 'yes', 'yes' );
1010
+ } else if ( $hard ) {
1011
+ include_once( ABSPATH . '/wp-admin/includes/misc.php' );
1012
+
1013
+ $home_path = ABSPATH;
1014
+ $htaccess_file = $home_path . '.htaccess';
1015
+ if ( function_exists( 'save_mod_rewrite_rules' ) ) {
1016
+ $rules = explode( "\n", '' );
1017
+
1018
+ // $ch = @fopen($htaccess_file,'w');
1019
+ // if (@flock($ch, LOCK_EX))
1020
+ // {
1021
+ insert_with_markers( $htaccess_file, 'MainWP', $rules );
1022
+ // }
1023
+ // @flock($ch, LOCK_UN);
1024
+ // @fclose($ch);
1025
+
1026
+ }
1027
+ }
1028
+ }
1029
+
1030
+ function check_login() {
1031
+ $file = '';
1032
+ if ( isset( $_REQUEST['f'] ) ) {
1033
+ $file = $_REQUEST['f'];
1034
+ } else if ( isset( $_REQUEST['file'] ) ) {
1035
+ $file = $_REQUEST['file'];
1036
+ } else if ( isset( $_REQUEST['fdl'] ) ) {
1037
+ $file = $_REQUEST['fdl'];
1038
+ }
1039
+
1040
+ $auth = $this->auth( isset( $_POST['mainwpsignature'] ) ? rawurldecode( $_POST['mainwpsignature'] ) : '', isset( $_POST['function'] ) ? $_POST['function'] : rawurldecode( ( isset( $_REQUEST['where'] ) ? $_REQUEST['where'] : $file ) ), isset( $_POST['nonce'] ) ? $_POST['nonce'] : '', isset( $_POST['nossl'] ) ? $_POST['nossl'] : 0 );
1041
+
1042
+ if ( ! $auth && isset( $_POST['mainwpsignature'] ) ) {
1043
+ MainWP_Helper::error( __( 'Authentication failed! Please deactivate and re-activate the MainWP Child plugin on this site.', 'mainwp-child' ) );
1044
+ }
1045
+
1046
+ if ( ! $auth && isset( $_POST['function'] ) && isset( $this->callableFunctions[ $_POST['function'] ] ) && ! isset( $this->callableFunctionsNoAuth[ $_POST['function'] ] ) ) {
1047
+ MainWP_Helper::error( __( 'Authentication failed! Please deactivate and re-activate the MainWP Child plugin on this site.', 'mainwp-child' ) );
1048
+ }
1049
+
1050
+ if ( $auth ) {
1051
+ //disable duo auth for mainwp
1052
+ remove_action('init', 'duo_verify_auth', 10);
1053
+
1054
+ //Check if the user exists & is an administrator
1055
+ if ( isset( $_POST['function'] ) && isset( $_POST['user'] ) ) {
1056
+ $user = get_user_by( 'login', $_POST['user'] );
1057
+ if ( ! $user ) {
1058
+ MainWP_Helper::error( __( 'That administrator username was not found on this child site. Please verify that it is an existing administrator.', 'mainwp-child' ) );
1059
+ }
1060
+
1061
+ if ( 10 != $user->wp_user_level && ( ! isset( $user->user_level ) || 10 != $user->user_level ) && ! $user->has_cap( 'level_10' ) ) {
1062
+ MainWP_Helper::error( __( 'That user is not an administrator. Please use an administrator user to establish the connection.', 'mainwp-child' ) );
1063
+ }
1064
+
1065
+ $this->login( $_REQUEST['user'] );
1066
+ }
1067
+
1068
+ if ( isset( $_POST['function'] ) && 'visitPermalink' === $_POST['function'] ) {
1069
+ if ( $this->login( $_POST['user'], true ) ) {
1070
+ return;
1071
+ } else {
1072
+ exit();
1073
+ }
1074
+ }
1075
+
1076
+ //Redirect to the admin part if needed
1077
+ if ( isset( $_POST['admin'] ) && '1' === $_POST['admin'] ) {
1078
+ wp_redirect( get_option( 'siteurl' ) . '/wp-admin/' );
1079
+ die();
1080
+ }
1081
+ }
1082
+ }
1083
+
1084
+ function parse_init() {
1085
+ if ( isset( $_REQUEST['cloneFunc'] ) ) {
1086
+ if ( ! isset( $_REQUEST['key'] ) ) {
1087
+ return;
1088
+ }
1089
+ if ( ! isset( $_REQUEST['f'] ) || ( '' === $_REQUEST['f'] ) ) {
1090
+ return;
1091
+ }
1092
+ if ( ! $this->isValidAuth( $_REQUEST['key'] ) ) {
1093
+ return;
1094
+ }
1095
+
1096
+ if ( 'dl' === $_REQUEST['cloneFunc'] ) {
1097
+ $this->uploadFile( $_REQUEST['f'] );
1098
+ exit;
1099
+ } else if ( 'deleteCloneBackup' === $_POST['cloneFunc'] ) {
1100
+ $dirs = MainWP_Helper::getMainWPDir( 'backup' );
1101
+ $backupdir = $dirs[0];
1102
+ $result = glob( $backupdir . $_POST['f'] );
1103
+ if ( 0 === count( $result ) ) {
1104
+ return;
1105
+ }
1106
+
1107
+ @unlink( $result[0] );
1108
+ MainWP_Helper::write( array( 'result' => 'ok' ) );
1109
+ } else if ( 'createCloneBackupPoll' === $_POST['cloneFunc'] ) {
1110
+ $dirs = MainWP_Helper::getMainWPDir( 'backup' );
1111
+ $backupdir = $dirs[0];
1112
+ $result = glob( $backupdir . 'backup-' . $_POST['f'] . '-*' );
1113
+ $archiveFile = false;
1114
+ foreach ( $result as $file ) {
1115
+ if ( MainWP_Helper::isArchive( $file, 'backup-' . $_POST['f'] . '-' ) ) {
1116
+ $archiveFile = $file;
1117
+ break;
1118
+ }
1119
+ }
1120
+ if ( false === $archiveFile ) {
1121
+ return;
1122
+ }
1123
+
1124
+ MainWP_Helper::write( array( 'size' => filesize( $archiveFile ) ) );
1125
+ } else if ( 'createCloneBackup' === $_POST['cloneFunc'] ) {
1126
+ MainWP_Helper::endSession();
1127
+
1128
+ $files = glob( WP_CONTENT_DIR . '/dbBackup*.sql' );
1129
+ foreach ( $files as $file ) {
1130
+ @unlink( $file );
1131
+ }
1132
+ if ( file_exists( ABSPATH . 'clone/config.txt' ) ) {
1133
+ @unlink( ABSPATH . 'clone/config.txt' );
1134
+ }
1135
+ if ( MainWP_Helper::is_dir_empty( ABSPATH . 'clone' ) ) {
1136
+ @rmdir( ABSPATH . 'clone' );
1137
+ }
1138
+
1139
+ $wpversion = $_POST['wpversion'];
1140
+ global $wp_version;
1141
+ $includeCoreFiles = ( $wpversion !== $wp_version );
1142
+ $excludes = ( isset( $_POST['exclude'] ) ? explode( ',', $_POST['exclude'] ) : array() );
1143
+ $excludes[] = str_replace( ABSPATH, '', WP_CONTENT_DIR ) . '/uploads/mainwp';
1144
+ $uploadDir = MainWP_Helper::getMainWPDir();
1145
+ $uploadDir = $uploadDir[0];
1146
+ $excludes[] = str_replace( ABSPATH, '', $uploadDir );
1147
+ $excludes[] = str_replace( ABSPATH, '', WP_CONTENT_DIR ) . '/object-cache.php';
1148
+ if ( version_compare(phpversion(), '5.3.0') >= 0 || ! ini_get( 'safe_mode' ) ) {
1149
+ @set_time_limit( 6000 );
1150
+ }
1151
+
1152
+ $newExcludes = array();
1153
+ foreach ( $excludes as $exclude ) {
1154
+ $newExcludes[] = rtrim( $exclude, '/' );
1155
+ }
1156
+
1157
+ $method = ( ! isset( $_POST['zipmethod'] ) ? 'tar.gz' : $_POST['zipmethod'] );
1158
+ if ( 'tar.gz' === $method && ! function_exists( 'gzopen' ) ) {
1159
+ $method = 'zip';
1160
+ }
1161
+
1162
+ $res = MainWP_Backup::get()->createFullBackup( $newExcludes, ( isset( $_POST['f'] ) ? $_POST['f'] : $_POST['file'] ), true, $includeCoreFiles, 0, false, false, false, false, $method );
1163
+ if ( ! $res ) {
1164
+ $information['backup'] = false;
1165
+ } else {
1166
+ $information['backup'] = $res['file'];
1167
+ $information['size'] = $res['filesize'];
1168
+ }
1169
+
1170
+ //todo: RS: Remove this when the .18 is out
1171
+ $plugins = array();
1172
+ $dir = WP_CONTENT_DIR . '/plugins/';
1173
+ $fh = @opendir( $dir );
1174
+ while ( $entry = @readdir( $fh ) ) {
1175
+ if ( ! is_dir( $dir . $entry ) ) {
1176
+ continue;
1177
+ }
1178
+ if ( ( '.' === $entry ) || ( '..' === $entry ) ) {
1179
+ continue;
1180
+ }
1181
+ $plugins[] = $entry;
1182
+ }
1183
+ @closedir( $fh );
1184
+ $information['plugins'] = $plugins;
1185
+
1186
+ $themes = array();
1187
+ $dir = WP_CONTENT_DIR . '/themes/';
1188
+ $fh = @opendir( $dir );
1189
+ while ( $entry = @readdir( $fh ) ) {
1190
+ if ( ! is_dir( $dir . $entry ) ) {
1191
+ continue;
1192
+ }
1193
+ if ( ( '.' === $entry ) || ( '..' === $entry ) ) {
1194
+ continue;
1195
+ }
1196
+ $themes[] = $entry;
1197
+ }
1198
+ @closedir( $fh );
1199
+ $information['themes'] = $themes;
1200
+
1201
+ MainWP_Helper::write( $information );
1202
+ }
1203
+ }
1204
+
1205
+ global $wp_rewrite;
1206
+ $snPluginDir = basename( $this->plugin_dir );
1207
+ if ( isset( $wp_rewrite->non_wp_rules[ 'wp-content/plugins/' . $snPluginDir . '/([^js\/]*)$' ] ) ) {
1208
+ unset( $wp_rewrite->non_wp_rules[ 'wp-content/plugins/' . $snPluginDir . '/([^js\/]*)$' ] );
1209
+ }
1210
+
1211
+ if ( isset( $wp_rewrite->non_wp_rules[ 'wp-content/plugins/' . $snPluginDir . '/(.*)$' ] ) ) {
1212
+ unset( $wp_rewrite->non_wp_rules[ 'wp-content/plugins/' . $snPluginDir . '/(.*)$' ] );
1213
+ }
1214
+
1215
+ if ( get_option( 'mainwp_child_fix_htaccess' ) === false ) {
1216
+ include_once( ABSPATH . '/wp-admin/includes/misc.php' );
1217
+
1218
+ $wp_rewrite->flush_rules();
1219
+ MainWP_Helper::update_option( 'mainwp_child_fix_htaccess', 'yes', 'yes' );
1220
+ }
1221
+
1222
+ $this->update_htaccess();
1223
+
1224
+ global $current_user; //wp variable
1225
+ //Login the user
1226
+ if ( isset( $_REQUEST['login_required'] ) && ( '1' === $_REQUEST['login_required'] ) && isset( $_REQUEST['user'] ) ) {
1227
+ $username = rawurldecode( $_REQUEST['user'] );
1228
+ if ( is_user_logged_in() ) {
1229
+ global $current_user;
1230
+ if ( 10 !== $current_user->wp_user_level && ( ! isset( $current_user->user_level ) || 10 !== $current_user->user_level ) && ! current_user_can( 'level_10' ) ) {
1231
+ do_action( 'wp_logout' );
1232
+ }
1233
+ }
1234
+
1235
+ $signature = rawurldecode( isset( $_REQUEST['mainwpsignature'] ) ? $_REQUEST['mainwpsignature'] : '' );
1236
+ $file = '';
1237
+ if ( isset( $_REQUEST['f'] ) ) {
1238
+ $file = $_REQUEST['f'];
1239
+ } else if ( isset( $_REQUEST['file'] ) ) {
1240
+ $file = $_REQUEST['file'];
1241
+ } else if ( isset( $_REQUEST['fdl'] ) ) {
1242
+ $file = $_REQUEST['fdl'];
1243
+ }
1244
+
1245
+ $auth = $this->auth( $signature, rawurldecode( ( isset( $_REQUEST['where'] ) ? $_REQUEST['where'] : $file ) ), isset( $_REQUEST['nonce'] ) ? $_REQUEST['nonce'] : '', isset( $_REQUEST['nossl'] ) ? $_REQUEST['nossl'] : 0 );
1246
+ if ( ! $auth ) {
1247
+ return;
1248
+ }
1249
+
1250
+ if ( ! is_user_logged_in() || $username !== $current_user->user_login ) {
1251
+ if ( ! $this->login( $username ) ) {
1252
+ return;
1253
+ }
1254
+
1255
+ global $current_user;
1256
+ if ( 10 !== $current_user->wp_user_level && ( ! isset( $current_user->user_level ) || 10 !== $current_user->user_level ) && ! current_user_can( 'level_10' ) ) {
1257
+ do_action( 'wp_logout' );
1258
+
1259
+ return;
1260
+ }
1261
+ }
1262
+
1263
+ if ( isset( $_REQUEST['fdl'] ) ) {
1264
+ if ( stristr( $_REQUEST['fdl'], '..' ) ) {
1265
+ return;
1266
+ }
1267
+
1268
+ $this->uploadFile( $_REQUEST['fdl'], isset( $_REQUEST['foffset'] ) ? $_REQUEST['foffset'] : 0 );
1269
+ exit;
1270
+ }
1271
+
1272
+ $where = isset( $_REQUEST['where'] ) ? $_REQUEST['where'] : '';
1273
+ if ( isset( $_POST['f'] ) || isset( $_POST['file'] ) ) {
1274
+ $file = '';
1275
+ if ( isset( $_POST['f'] ) ) {
1276
+ $file = $_POST['f'];
1277
+ } else if ( isset( $_POST['file'] ) ) {
1278
+ $file = $_POST['file'];
1279
+ }
1280
+
1281
+ $where = 'admin.php?page=mainwp_child_tab&tab=restore-clone';
1282
+ if ( '' === session_id() ) {
1283
+ session_start();
1284
+ }
1285
+ $_SESSION['file'] = $file;
1286
+ $_SESSION['size'] = $_POST['size'];
1287
+ }
1288
+
1289
+ $open_location = isset( $_REQUEST['open_location'] ) ? $_REQUEST['open_location'] : '';
1290
+ if ( ! empty( $open_location ) ) {
1291
+ $open_location = base64_decode( $open_location );
1292
+ $_vars = MainWP_Helper::parse_query( $open_location );
1293
+ $_path = parse_url( $open_location, PHP_URL_PATH );
1294
+ if ( isset( $_vars['_mwpNoneName'] ) && isset( $_vars['_mwpNoneValue'] ) ) {
1295
+ $_vars[ $_vars['_mwpNoneName'] ] = wp_create_nonce( $_vars['_mwpNoneValue'] );
1296
+ unset( $_vars['_mwpNoneName'] );
1297
+ unset( $_vars['_mwpNoneValue'] );
1298
+ $open_url = '';
1299
+ foreach ( $_vars as $key => $value ) {
1300
+ $open_url .= $key . '=' . $value . '&';
1301
+ }
1302
+ $open_url = rtrim( $open_url, '&' );
1303
+ $open_location = '/wp-admin/' . $_path . '?' . $open_url;
1304
+ } else {
1305
+ if ( strpos( $open_location, 'nonce=child_temp_nonce' ) !== false ) {
1306
+ $open_location = str_replace( 'nonce=child_temp_nonce', 'nonce=' . wp_create_nonce( 'wp-ajax' ), $open_location );
1307
+ }
1308
+ }
1309
+ wp_redirect( site_url() . $open_location );
1310
+ exit();
1311
+ }
1312
+
1313
+ add_filter( 'the_content', array( MainWP_Keyword_Links::Instance(), 'filter_content' ), 100, 2 );
1314
+ wp_redirect( admin_url( $where ) );
1315
+ exit();
1316
+ }
1317
+
1318
+ remove_action( 'admin_init', 'send_frame_options_header' );
1319
+ remove_action( 'login_init', 'send_frame_options_header' );
1320
+
1321
+ // Call Heatmap
1322
+ if ( 'yes' === get_option( 'heatMapExtensionLoaded' ) ) {
1323
+ if ( ( '1' !== get_option( 'heatMapsIndividualOverrideSetting' ) && '0' !== get_option( 'heatMapEnabled' ) ) ||
1324
+ ( '1' !== get_option( 'heatMapsIndividualOverrideSetting' ) && '1' !== get_option( 'heatMapsIndividualDisable' ) )
1325
+ ) {
1326
+ new MainWP_Heatmap_Tracker();
1327
+ }
1328
+ }
1329
+
1330
+ /**
1331
+ * Security
1332
+ */
1333
+ MainWP_Security::fixAll();
1334
+ MainWP_Debug::process($this);
1335
+
1336
+ //Register does not require auth, so we register here..
1337
+ if ( isset( $_POST['function'] ) && 'register' === $_POST['function'] ) {
1338
+ define( 'DOING_CRON', true );
1339
+ MainWP_Child::fix_for_custom_themes();
1340
+ $this->registerSite();
1341
+ }
1342
+
1343
+ $auth = $this->auth( isset( $_POST['mainwpsignature'] ) ? $_POST['mainwpsignature'] : '', isset( $_POST['function'] ) ? $_POST['function'] : '', isset( $_POST['nonce'] ) ? $_POST['nonce'] : '', isset( $_POST['nossl'] ) ? $_POST['nossl'] : 0 );
1344
+
1345
+ if ( ! $auth && isset( $_POST['mainwpsignature'] ) ) {
1346
+ MainWP_Helper::error( __( 'Authentication failed! Please deactivate and re-activate the MainWP Child plugin on this site.', 'mainwp-child' ) );
1347
+ }
1348
+
1349
+ if ( ! $auth && isset( $_POST['function'] ) && isset( $this->callableFunctions[ $_POST['function'] ] ) && ! isset( $this->callableFunctionsNoAuth[ $_POST['function'] ] ) ) {
1350
+ MainWP_Helper::error( __( 'Authentication failed! Please deactivate and re-activate the MainWP Child plugin on this site.', 'mainwp-child' ) );
1351
+ }
1352
+
1353
+ if ( $auth ) {
1354
+ //Check if the user exists & is an administrator
1355
+ if ( isset( $_POST['function'] ) && isset( $_POST['user'] ) ) {
1356
+ $user = get_user_by( 'login', $_POST['user'] );
1357
+ if ( ! $user ) {
1358
+ MainWP_Helper::error( __( 'That administrator username was not found on this child site. Please verify that it is an existing administrator.', 'mainwp-child' ) );
1359
+ }
1360
+
1361
+ if ( 10 != $user->wp_user_level && ( ! isset( $user->user_level ) || 10 != $user->user_level ) && ! $user->has_cap( 'level_10' ) ) {
1362
+ MainWP_Helper::error( __( 'That user is not an administrator. Please use an administrator user to establish the connection.', 'mainwp-child' ) );
1363
+ }
1364
+
1365
+ $this->login( $_REQUEST['user'] );
1366
+ }
1367
+
1368
+ if ( isset( $_POST['function'] ) && 'visitPermalink' === $_POST['function'] ) {
1369
+ if ( $this->login( $_POST['user'], true ) ) {
1370
+ return;
1371
+ } else {
1372
+ exit();
1373
+ }
1374
+ }
1375
+
1376
+ //Redirect to the admin part if needed
1377
+ if ( isset( $_POST['admin'] ) && '1' === $_POST['admin'] ) {
1378
+ wp_redirect( get_option( 'siteurl' ) . '/wp-admin/' );
1379
+ die();
1380
+ }
1381
+ }
1382
+
1383
+ new MainWP_Child_iThemes_Security();
1384
+ new MainWP_Child_Updraft_Plus_Backups();
1385
+
1386
+ MainWP_Child_Updraft_Plus_Backups::Instance()->updraftplus_init();
1387
+ if ( version_compare( phpversion(), '5.3', '>=' ) ) {
1388
+ MainWP_Child_Back_Up_Wordpress::Instance()->init();
1389
+ }
1390
+
1391
+ MainWP_Child_WP_Rocket::Instance()->init();
1392
+
1393
+ MainWP_Child_Back_WP_Up::Instance()->init();
1394
+
1395
+ new MainWP_Child_Back_Up_Buddy();
1396
+ MainWP_Child_Wordfence::Instance()->wordfence_init();
1397
+ MainWP_Child_Staging::Instance()->init();
1398
+
1399
+ global $_wp_submenu_nopriv;
1400
+ if ($_wp_submenu_nopriv === null)
1401
+ $_wp_submenu_nopriv = array(); // fix warning
1402
+ //
1403
+ //Call the function required
1404
+ if ( $auth && isset( $_POST['function'] ) && isset( $this->callableFunctions[ $_POST['function'] ] ) ) {
1405
+ define( 'DOING_CRON', true );
1406
+ // ob_start();
1407
+ // require_once( ABSPATH . 'wp-admin/admin.php' );
1408
+ // ob_end_clean();
1409
+ MainWP_Child::fix_for_custom_themes();
1410
+ call_user_func( array( $this, $this->callableFunctions[ $_POST['function'] ] ) );
1411
+ } else if ( isset( $_POST['function'] ) && isset( $this->callableFunctionsNoAuth[ $_POST['function'] ] ) ) {
1412
+ define( 'DOING_CRON', true );
1413
+ MainWP_Child::fix_for_custom_themes();
1414
+ call_user_func( array( $this, $this->callableFunctionsNoAuth[ $_POST['function'] ] ) );
1415
+ } else if (isset( $_POST['function'] ) && isset( $_POST['mainwpsignature'] ) && !isset($this->callableFunctions[ $_POST['function'] ]) && !isset( $this->callableFunctionsNoAuth[ $_POST['function'] ]) ) {
1416
+ MainWP_Helper::error( __( 'Required version has not been detected. Please, make sure that you are using the latest version of the MainWP Child plugin on your site.', 'mainwp-child' ) );
1417
+ }
1418
+
1419
+ if ( 1 === (int) get_option( 'mainwpKeywordLinks' ) ) {
1420
+ new MainWP_Keyword_Links();
1421
+ if ( ! is_admin() ) {
1422
+ add_filter( 'the_content', array( MainWP_Keyword_Links::Instance(), 'filter_content' ), 100 );
1423
+ }
1424
+ MainWP_Keyword_Links::Instance()->update_htaccess(); // if needed
1425
+ MainWP_Keyword_Links::Instance()->redirect_cloak();
1426
+ } else if ( 'yes' === get_option( 'mainwp_keyword_links_htaccess_set' ) ) {
1427
+ MainWP_Keyword_Links::clear_htaccess(); // force clear
1428
+ }
1429
+
1430
+ // Branding extension
1431
+ MainWP_Child_Branding::Instance()->branding_init();
1432
+ MainWP_Client_Report::Instance()->creport_init();
1433
+ MainWP_Child_Pagespeed::Instance()->init();
1434
+ MainWP_Child_Links_Checker::Instance()->init();
1435
+ MainWP_Child_Wordfence::Instance()->wordfence_init();
1436
+ MainWP_Child_iThemes_Security::Instance()->ithemes_init();
1437
+ }
1438
+
1439
+ function default_option_active_plugins( $default ) {
1440
+ if ( ! is_array( $default ) ) {
1441
+ $default = array();
1442
+ }
1443
+ if ( ! in_array( 'managewp/init.php', $default ) ) {
1444
+ $default[] = 'managewp/init.php';
1445
+ }
1446
+
1447
+ return $default;
1448
+ }
1449
+
1450
+ function auth( $signature, $func, $nonce, $pNossl ) {
1451
+ if ( ! isset( $signature ) || ! isset( $func ) || ( ! get_option( 'mainwp_child_pubkey' ) && ! get_option( 'mainwp_child_nossl_key' ) ) ) {
1452
+ $auth = false;
1453
+ } else {
1454
+ $nossl = get_option( 'mainwp_child_nossl' );
1455
+ $serverNoSsl = ( isset( $pNossl ) && 1 === (int) $pNossl );
1456
+
1457
+ if ( ( 1 === (int) $nossl ) || $serverNoSsl ) {
1458
+ $auth = hash_equals( md5( $func . $nonce . get_option( 'mainwp_child_nossl_key' ) ), base64_decode( $signature ) );
1459
+ } else {
1460
+ $auth = openssl_verify( $func . $nonce, base64_decode( $signature ), base64_decode( get_option( 'mainwp_child_pubkey' ) ) );
1461
+ if ($auth !== 1) {
1462
+ $auth = false;
1463
+ }
1464
+ }
1465
+ }
1466
+
1467
+ return $auth;
1468
+ }
1469
+
1470
+ //Login..
1471
+ function login( $username, $doAction = false ) {
1472
+ global $current_user;
1473
+
1474
+ //Logout if required
1475
+ if ( isset( $current_user->user_login ) ) {
1476
+ if ( $current_user->user_login === $username ) {
1477
+ wp_set_auth_cookie( $current_user->ID );
1478
+ return true;
1479
+ }
1480
+
1481
+ do_action( 'wp_logout' );
1482
+ }
1483
+
1484
+ $user = get_user_by( 'login', $username );
1485
+ if ( $user ) { //If user exists, login
1486
+ // wp_set_current_user($user->ID, $user->user_login);
1487
+ // wp_set_auth_cookie($user->ID);
1488
+
1489
+ wp_set_current_user( $user->ID );
1490
+ wp_set_auth_cookie( $user->ID );
1491
+ if ( $doAction ) {
1492
+ do_action( 'wp_login', $user->user_login );
1493
+ }
1494
+
1495
+ return ( is_user_logged_in() && $current_user->user_login === $username );
1496
+ }
1497
+
1498
+ return false;
1499
+ }
1500
+
1501
+ function noSSLFilterFunction( $r, $url ) {
1502
+ $r['sslverify'] = false;
1503
+
1504
+ return $r;
1505
+ }
1506
+
1507
+ public function http_request_reject_unsafe_urls( $r, $url ) {
1508
+ $r['reject_unsafe_urls'] = false;
1509
+ if ( isset($_POST['wpadmin_user']) && !empty($_POST['wpadmin_user']) && isset($_POST['wpadmin_passwd']) && !empty($_POST['wpadmin_passwd']) ) {
1510
+ $auth = base64_encode( $_POST['wpadmin_user'] . ':' . $_POST['wpadmin_passwd'] );
1511
+ $r['headers']['Authorization'] = "Basic $auth";
1512
+ }
1513
+ return $r;
1514
+ }
1515
+
1516
+ /**
1517
+ * Functions to support core functionality
1518
+ */
1519
+ function installPluginTheme() {
1520
+ $wp_filesystem = $this->getWPFilesystem();
1521
+
1522
+ if ( ! isset( $_POST['type'] ) || ! isset( $_POST['url'] ) || ( 'plugin' !== $_POST['type'] && 'theme' !== $_POST['type'] ) || '' === $_POST['url'] ) {
1523
+ MainWP_Helper::error( __( 'Invalid request!', 'mainwp-child' ) );
1524
+ }
1525
+ // if (file_exists(ABSPATH . '/wp-admin/includes/deprecated.php')) include_once(ABSPATH . '/wp-admin/includes/deprecated.php');
1526
+ if ( file_exists( ABSPATH . '/wp-admin/includes/screen.php' ) ) {
1527
+ include_once( ABSPATH . '/wp-admin/includes/screen.php' );
1528
+ }
1529
+ include_once( ABSPATH . '/wp-admin/includes/template.php' );
1530
+ include_once( ABSPATH . '/wp-admin/includes/misc.php' );
1531
+ include_once( ABSPATH . '/wp-admin/includes/class-wp-upgrader.php' );
1532
+ include_once( ABSPATH . '/wp-admin/includes/plugin.php' );
1533
+
1534
+ $urlgot = json_decode( stripslashes( $_POST['url'] ) );
1535
+
1536
+ $urls = array();
1537
+ if ( ! is_array( $urlgot ) ) {
1538
+ $urls[] = $urlgot;
1539
+ } else {
1540
+ $urls = $urlgot;
1541
+ }
1542
+
1543
+ $result = array();
1544
+ foreach ( $urls as $url ) {
1545
+ $installer = new WP_Upgrader();
1546
+ $ssl_verify = true;
1547
+ //@see wp-admin/includes/class-wp-upgrader.php
1548
+ if ( isset( $_POST['sslVerify'] ) && '0' === $_POST['sslVerify'] ) {
1549
+ add_filter( 'http_request_args', array( &$this, 'noSSLFilterFunction' ), 99, 2 );
1550
+ $ssl_verify = false;
1551
+ }
1552
+ add_filter( 'http_request_args', array( &$this, 'http_request_reject_unsafe_urls' ), 99, 2 );
1553
+
1554
+ $result = $installer->run( array(
1555
+ 'package' => $url,
1556
+ 'destination' => ( 'plugin' === $_POST['type'] ? WP_PLUGIN_DIR
1557
+ : WP_CONTENT_DIR . '/themes' ),
1558
+ 'clear_destination' => ( isset( $_POST['overwrite'] ) && $_POST['overwrite'] ),
1559
+ //overwrite files?
1560
+ 'clear_working' => true,
1561
+ 'hook_extra' => array(),
1562
+ ) );
1563
+
1564
+ if ( is_wp_error( $result ) ) {
1565
+ if ( true == $ssl_verify && strpos( $url, 'https://' ) === 0) {
1566
+ // retry
1567
+ add_filter( 'http_request_args', array( &$this, 'noSSLFilterFunction' ), 99, 2 );
1568
+ $ssl_verify = false;
1569
+ $result = $installer->run( array(
1570
+ 'package' => $url,
1571
+ 'destination' => ( 'plugin' === $_POST['type'] ? WP_PLUGIN_DIR
1572
+ : WP_CONTENT_DIR . '/themes' ),
1573
+ 'clear_destination' => ( isset( $_POST['overwrite'] ) && $_POST['overwrite'] ),
1574
+ //overwrite files?
1575
+ 'clear_working' => true,
1576
+ 'hook_extra' => array(),
1577
+ ) );
1578
+ }
1579
+
1580
+ if ( is_wp_error( $result ) ) {
1581
+ $err_code = $result->get_error_code();
1582
+ if ( $result->get_error_data() && is_string( $result->get_error_data() ) ) {
1583
+ $error = $result->get_error_data();
1584
+ MainWP_Helper::error( $error, $err_code );
1585
+ } else {
1586
+ MainWP_Helper::error( implode( ', ', $error ), $err_code );
1587
+ }
1588
+ }
1589
+ }
1590
+
1591
+ remove_filter( 'http_request_args', array( &$this, 'http_request_reject_unsafe_urls' ), 99, 2 );
1592
+ if ( false == $ssl_verify ) {
1593
+ remove_filter( 'http_request_args', array( &$this, 'noSSLFilterFunction' ), 99 );
1594
+ }
1595
+
1596
+ $args = array( 'success' => 1, 'action' => 'install' );
1597
+ if ( 'plugin' === $_POST['type'] ) {
1598
+ $path = $result['destination'];
1599
+ $fileName = '';
1600
+ $rslt = null;
1601
+ wp_cache_set( 'plugins', array(), 'plugins' );
1602
+ foreach ( $result['source_files'] as $srcFile ) {
1603
+ if ( is_dir( $path . $srcFile ) ) {
1604
+ continue;
1605
+ }
1606
+ $thePlugin = get_plugin_data( $path . $srcFile );
1607
+ if ( null !== $thePlugin && '' !== $thePlugin && '' !== $thePlugin['Name'] ) {
1608
+ $args['type'] = 'plugin';
1609
+ $args['Name'] = $thePlugin['Name'];
1610
+ $args['Version'] = $thePlugin['Version'];
1611
+ $args['slug'] = $result['destination_name'] . '/' . $srcFile;
1612
+ $fileName = $srcFile;
1613
+ break;
1614
+ }
1615
+ }
1616
+
1617
+ if ( ! empty( $fileName ) ) {
1618
+ do_action( 'mainwp_child_installPluginTheme', $args );
1619
+ if ( isset( $_POST['activatePlugin'] ) && 'yes' === $_POST['activatePlugin'] ) {
1620
+ // to fix activate issue
1621
+ if ('quotes-collection/quotes-collection.php' == $args['slug']) {
1622
+ activate_plugin( $path . $fileName, '', false, true );
1623
+ } else {
1624
+ activate_plugin( $path . $fileName, '' /* false, true */ );
1625
+ }
1626
+ do_action( 'activate_plugin', $args['slug'], null );
1627
+ }
1628
+ }
1629
+ } else {
1630
+ $args['type'] = 'theme';
1631
+ $args['slug'] = $result['destination_name'];
1632
+ do_action( 'mainwp_child_installPluginTheme', $args );
1633
+ }
1634
+
1635
+ // if ($_POST['type'] == 'plugin' && isset($_POST['activatePlugin']) && $_POST['activatePlugin'] == 'yes')
1636
+ // {
1637
+ // $path = $result['destination'];
1638
+ // $rslt = null;
1639
+ // wp_cache_set('plugins', array(), 'plugins');
1640
+ // foreach ($result['source_files'] as $srcFile)
1641
+ // {
1642
+ // if (is_dir($path . $srcFile)) continue;
1643
+ //
1644
+ // $thePlugin = get_plugin_data($path . $srcFile);
1645
+ // if ($thePlugin != null && $thePlugin != '' && $thePlugin['Name'] != '')
1646
+ // {
1647
+ // activate_plugin($path . $srcFile, '', false, true);
1648
+ //
1649
+ // }
1650
+ // }
1651
+ // }
1652
+ }
1653
+ $information['installation'] = 'SUCCESS';
1654
+ $information['destination_name'] = $result['destination_name'];
1655
+ MainWP_Helper::write( $information );
1656
+ }
1657
+
1658
+ //This will upgrade WP
1659
+ function upgradeWP() {
1660
+ global $wp_version;
1661
+ $wp_filesystem = $this->getWPFilesystem();
1662
+
1663
+ $information = array();
1664
+
1665
+ include_once( ABSPATH . '/wp-admin/includes/update.php' );
1666
+ include_once( ABSPATH . '/wp-admin/includes/class-wp-upgrader.php' );
1667
+ // if (file_exists(ABSPATH . '/wp-admin/includes/deprecated.php')) include_once(ABSPATH . '/wp-admin/includes/deprecated.php');
1668
+ if ( file_exists( ABSPATH . '/wp-admin/includes/screen.php' ) ) {
1669
+ include_once( ABSPATH . '/wp-admin/includes/screen.php' );
1670
+ }
1671
+ if ( file_exists( ABSPATH . '/wp-admin/includes/template.php' ) ) {
1672
+ include_once( ABSPATH . '/wp-admin/includes/template.php' );
1673
+ }
1674
+ include_once( ABSPATH . '/wp-admin/includes/file.php' );
1675
+ include_once( ABSPATH . '/wp-admin/includes/misc.php' );
1676
+
1677
+ if ( null !== $this->filterFunction ) {
1678
+ add_filter( 'pre_site_transient_update_core', $this->filterFunction, 99 );
1679
+ }
1680
+ if ( null !== $this->filterFunction ) {
1681
+ add_filter( 'pre_transient_update_core', $this->filterFunction, 99 );
1682
+ }
1683
+
1684
+ //Check for new versions
1685
+ @wp_version_check();
1686
+
1687
+ $core_updates = get_core_updates();
1688
+ if ( is_array($core_updates) && count( $core_updates ) > 0 ) {
1689
+ foreach ( $core_updates as $core_update ) {
1690
+ if ( 'latest' === $core_update->response ) {
1691
+ $information['upgrade'] = 'SUCCESS';
1692
+ } else if ( 'upgrade' === $core_update->response && $core_update->locale === get_locale() && version_compare( $wp_version, $core_update->current, '<=' ) ) {
1693
+ //Upgrade!
1694
+ $upgrade = false;
1695
+ if ( class_exists( 'Core_Upgrader' ) ) {
1696
+ $core = new Core_Upgrader();
1697
+ $upgrade = $core->upgrade( $core_update );
1698
+ }
1699
+ //If this does not work - add code from /wp-admin/includes/class-wp-upgrader.php in the newer versions
1700
+ //So users can upgrade older versions too.
1701
+ //3rd option: 'wp_update_core'
1702
+
1703
+ if ( ! is_wp_error( $upgrade ) ) {
1704
+ $information['upgrade'] = 'SUCCESS';
1705
+ } else {
1706
+ $information['upgrade'] = 'WPERROR';
1707
+ }
1708
+ break;
1709
+ }
1710
+ }
1711
+
1712
+ if ( ! isset( $information['upgrade'] ) ) {
1713
+ foreach ( $core_updates as $core_update ) {
1714
+ if ( 'upgrade' === $core_update->response && version_compare( $wp_version, $core_update->current, '<=' ) ) {
1715
+ //Upgrade!
1716
+ $upgrade = false;
1717
+ if ( class_exists( 'Core_Upgrader' ) ) {
1718
+ $core = new Core_Upgrader();
1719
+ $upgrade = $core->upgrade( $core_update );
1720
+ }
1721
+ //If this does not work - add code from /wp-admin/includes/class-wp-upgrader.php in the newer versions
1722
+ //So users can upgrade older versions too.
1723
+ //3rd option: 'wp_update_core'
1724
+
1725
+ if ( ! is_wp_error( $upgrade ) ) {
1726
+ $information['upgrade'] = 'SUCCESS';
1727
+ } else {
1728
+ $information['upgrade'] = 'WPERROR';
1729
+ }
1730
+ break;
1731
+ }
1732
+ }
1733
+ }
1734
+ } else {
1735
+ $information['upgrade'] = 'NORESPONSE';
1736
+ }
1737
+ if ( null !== $this->filterFunction ) {
1738
+ remove_filter( 'pre_site_transient_update_core', $this->filterFunction, 99 );
1739
+ }
1740
+ if ( null !== $this->filterFunction ) {
1741
+ remove_filter( 'pre_transient_update_core', $this->filterFunction, 99 );
1742
+ }
1743
+
1744
+ MainWP_Helper::write( $information );
1745
+ }
1746
+
1747
+ function upgradeTranslation() {
1748
+ //Prevent disable/re-enable at upgrade
1749
+ define( 'DOING_CRON', true );
1750
+
1751
+ MainWP_Helper::getWPFilesystem();
1752
+ include_once( ABSPATH . '/wp-admin/includes/class-wp-upgrader.php' );
1753
+ if ( file_exists( ABSPATH . '/wp-admin/includes/screen.php' ) ) {
1754
+ include_once( ABSPATH . '/wp-admin/includes/screen.php' );
1755
+ }
1756
+ if ( file_exists( ABSPATH . '/wp-admin/includes/template.php' ) ) {
1757
+ include_once( ABSPATH . '/wp-admin/includes/template.php' );
1758
+ }
1759
+ if ( file_exists( ABSPATH . '/wp-admin/includes/misc.php' ) ) {
1760
+ include_once( ABSPATH . '/wp-admin/includes/misc.php' );
1761
+ }
1762
+ include_once( ABSPATH . '/wp-admin/includes/file.php' );
1763
+
1764
+ include_once( ABSPATH . 'wp-admin/includes/class-wp-upgrader.php' );
1765
+
1766
+ $upgrader = new Language_Pack_Upgrader( new Language_Pack_Upgrader_Skin( compact( 'url', 'nonce', 'title', 'context' ) ) );
1767
+ $translations = explode( ',', urldecode( $_POST['list'] ) );
1768
+ $all_language_updates = wp_get_translation_updates();
1769
+
1770
+ $language_updates = array();
1771
+ foreach ( $all_language_updates as $current_language_update ) {
1772
+ if ( in_array( $current_language_update->slug, $translations ) ) {
1773
+ $language_updates[] = $current_language_update;
1774
+ }
1775
+ }
1776
+
1777
+ $result = count( $language_updates ) == 0 ? false : $upgrader->bulk_upgrade( $language_updates );
1778
+ if ( ! empty( $result ) ) {
1779
+ for ( $i = 0; $i < count( $result ); $i++ ) {
1780
+ if ( empty( $result[$i] ) || is_wp_error( $result[$i] ) ) {
1781
+ $information['upgrades'][ $language_updates[$i]->slug ] = false;
1782
+ } else {
1783
+ $information['upgrades'][ $language_updates[$i]->slug ] = true;
1784
+ }
1785
+ }
1786
+ } else {
1787
+ MainWP_Helper::error( __( 'Invalid request!', 'mainwp-child' ) );
1788
+ }
1789
+
1790
+ $information['sync'] = $this->getSiteStats( array(), false );
1791
+ MainWP_Helper::write( $information );
1792
+ }
1793
+
1794
+ /**
1795
+ * Expects $_POST['type'] == plugin/theme
1796
+ * $_POST['list'] == 'theme1,theme2' or 'plugin1,plugin2'
1797
+ */
1798
+ function upgradePluginTheme() {
1799
+ //Prevent disable/re-enable at upgrade
1800
+ if (!defined( 'DOING_CRON') )
1801
+ define( 'DOING_CRON', true );
1802
+
1803
+ MainWP_Helper::getWPFilesystem();
1804
+
1805
+ include_once( ABSPATH . '/wp-admin/includes/class-wp-upgrader.php' );
1806
+ // if (file_exists(ABSPATH . '/wp-admin/includes/deprecated.php')) include_once(ABSPATH . '/wp-admin/includes/deprecated.php');
1807
+ if ( file_exists( ABSPATH . '/wp-admin/includes/screen.php' ) ) {
1808
+ include_once( ABSPATH . '/wp-admin/includes/screen.php' );
1809
+ }
1810
+ if ( file_exists( ABSPATH . '/wp-admin/includes/template.php' ) ) {
1811
+ include_once( ABSPATH . '/wp-admin/includes/template.php' );
1812
+ }
1813
+ if ( file_exists( ABSPATH . '/wp-admin/includes/misc.php' ) ) {
1814
+ include_once( ABSPATH . '/wp-admin/includes/misc.php' );
1815
+ }
1816
+ include_once( ABSPATH . '/wp-admin/includes/file.php' );
1817
+ include_once( ABSPATH . '/wp-admin/includes/plugin.php' );
1818
+ $information = array();
1819
+ $information['upgrades'] = array();
1820
+ $mwp_premium_updates_todo = array();
1821
+ $mwp_premium_updates_todo_slugs = array();
1822
+ if ( isset( $_POST['type'] ) && 'plugin' === $_POST['type'] ) {
1823
+ include_once( ABSPATH . '/wp-admin/includes/update.php' );
1824
+ if ( null !== $this->filterFunction ) {
1825
+ // ET_Automatic_Updates
1826
+ add_filter( 'pre_site_transient_update_plugins', $this->filterFunction, 99 );
1827
+ }
1828
+
1829
+ $plugins = explode( ',', urldecode( $_POST['list'] ) );
1830
+
1831
+ // To fix: backupbuddy update
1832
+ if ( in_array( 'backupbuddy/backupbuddy.php', $plugins ) ) {
1833
+ if ( isset( $GLOBALS['ithemes_updater_path'] ) ) {
1834
+ if ( ! class_exists( 'Ithemes_Updater_Settings' ) ) {
1835
+ require( $GLOBALS['ithemes_updater_path'] . '/settings.php' );
1836
+ }
1837
+ if ( class_exists( 'Ithemes_Updater_Settings' ) ) {
1838
+ $ithemes_updater = new Ithemes_Updater_Settings();
1839
+ $ithemes_updater->update();
1840
+ }
1841
+ }
1842
+ }
1843
+ ////
1844
+
1845
+ // to fix: smart-manager-for-wp-e-commerce update
1846
+ if (in_array('smart-manager-for-wp-e-commerce/smart-manager.php', $plugins)) {
1847
+ if (file_exists(plugin_dir_path( __FILE__ ) . '../../smart-manager-for-wp-e-commerce/pro/upgrade.php') && file_exists(plugin_dir_path( __FILE__ ) . '../../smart-manager-for-wp-e-commerce/smart-manager.php')) {
1848
+ include_once plugin_dir_path( __FILE__ ) . '../../smart-manager-for-wp-e-commerce/smart-manager.php';
1849
+ include_once (plugin_dir_path( __FILE__ ) . '../../smart-manager-for-wp-e-commerce/pro/upgrade.php');
1850
+ }
1851
+ }
1852
+ ////
1853
+
1854
+ global $wp_current_filter;
1855
+ $wp_current_filter[] = 'load-plugins.php';
1856
+ @wp_update_plugins();
1857
+ $information['plugin_updates'] = get_plugin_updates();
1858
+
1859
+ $plugins = explode( ',', urldecode( $_POST['list'] ) );
1860
+ $premiumPlugins = array();
1861
+ $premiumUpdates = get_option( 'mainwp_premium_updates' );
1862
+ if ( is_array( $premiumUpdates ) ) {
1863
+ $newPlugins = array();
1864
+ foreach ( $plugins as $plugin ) {
1865
+ if ( in_array( $plugin, $premiumUpdates ) ) {
1866
+ $premiumPlugins[] = $plugin;
1867
+ } else {
1868
+ $newPlugins[] = $plugin;
1869
+ }
1870
+ }
1871
+ $plugins = $newPlugins;
1872
+ }
1873
+
1874
+ if ( count( $plugins ) > 0 ) {
1875
+ //@see wp-admin/update.php
1876
+ $failed = true;
1877
+ $upgrader = new Plugin_Upgrader( new Bulk_Plugin_Upgrader_Skin( compact( 'nonce', 'url' ) ) );
1878
+ $result = $upgrader->bulk_upgrade( $plugins );
1879
+
1880
+ if ( ! empty( $result ) ) {
1881
+ foreach ( $result as $plugin => $info ) {
1882
+ if ( empty( $info ) ) {
1883
+ $information['upgrades'][ $plugin ] = false;
1884
+ } else {
1885
+ $information['upgrades'][ $plugin ] = true;
1886
+ // to fix logging update
1887
+ if (isset($information['plugin_updates']) && isset($information['plugin_updates'][$plugin])) {
1888
+ $plugin_info = $information['plugin_updates'][$plugin];
1889
+ $args = array();
1890
+ $args['type'] = 'plugin';
1891
+ $args['name'] = $plugin_info->Name;
1892
+ $args['version'] = $plugin_info->update->new_version;
1893
+ $args['old_version'] = $plugin_info->Version;
1894
+ $args['action'] = 'update';
1895
+ do_action( 'mainwp_child_upgradePluginTheme', $args );
1896
+ }
1897
+ }
1898
+ }
1899
+ $failed = false;
1900
+ }
1901
+
1902
+ if ($failed) {
1903
+ MainWP_Helper::error( __( 'Invalid request!', 'mainwp-child' ) );
1904
+ }
1905
+ }
1906
+ if ( count( $premiumPlugins ) > 0 ) {
1907
+ $mwp_premium_updates = apply_filters( 'mwp_premium_perform_update', array() );
1908
+ if ( is_array( $mwp_premium_updates ) && is_array( $premiumPlugins ) ) {
1909
+ foreach ( $premiumPlugins as $premiumPlugin ) {
1910
+ foreach ( $mwp_premium_updates as $key => $update ) {
1911
+ $slug = ( isset( $update['slug'] ) ? $update['slug'] : $update['Name'] );
1912
+ if ( 0 === strcmp( $slug, $premiumPlugin ) ) {
1913
+ $mwp_premium_updates_todo[ $key ] = $update;
1914
+ $mwp_premium_updates_todo_slugs[] = $premiumPlugin;
1915
+ }
1916
+ }
1917
+ }
1918
+ }
1919
+ unset( $mwp_premium_updates );
1920
+ $premiumUpgrader = new Plugin_Upgrader( new Bulk_Plugin_Upgrader_Skin( compact( 'nonce', 'url' ) ) );
1921
+ }
1922
+
1923
+ if ( count( $plugins ) <= 0 && count( $premiumPlugins ) <= 0 ) {
1924
+ MainWP_Helper::error( __( 'Invalid request!', 'mainwp-child' ) );
1925
+ }
1926
+
1927
+ if ( null !== $this->filterFunction ) {
1928
+ remove_filter( 'pre_site_transient_update_plugins', $this->filterFunction, 99 );
1929
+ }
1930
+ } else if ( isset( $_POST['type'] ) && 'theme' === $_POST['type'] ) {
1931
+
1932
+ $last_update = get_site_transient( 'update_themes' );
1933
+
1934
+ include_once( ABSPATH . '/wp-admin/includes/update.php' );
1935
+ if ( null !== $this->filterFunction ) {
1936
+ add_filter( 'pre_site_transient_update_themes', $this->filterFunction, 99 );
1937
+ }
1938
+
1939
+ // $last_update = get_site_transient( 'update_themes' );
1940
+ // $originalLastChecked = !empty( $last_update ) && property_exists( $last_update, 'last_checked' ) ? $last_update->last_checked : 0;
1941
+
1942
+ @wp_update_themes();
1943
+ include_once( ABSPATH . '/wp-admin/includes/theme.php' );
1944
+ $information['theme_updates'] = $this->upgrade_get_theme_updates();
1945
+ $themes = explode( ',', $_POST['list'] );
1946
+ $premiumThemes = array();
1947
+ $premiumUpdates = get_option( 'mainwp_premium_updates' );
1948
+ if ( is_array( $premiumUpdates ) ) {
1949
+ $newThemes = array();
1950
+ foreach ( $themes as $theme ) {
1951
+ if ( in_array( $theme, $premiumUpdates ) ) {
1952
+ $premiumThemes[] = $theme;
1953
+ } else {
1954
+ $newThemes[] = $theme;
1955
+ }
1956
+ }
1957
+ $themes = $newThemes;
1958
+ }
1959
+
1960
+ if ( count( $themes ) > 0 ) {
1961
+ // To fix: optimizePressTheme update
1962
+ $addFilterToFixUpdate_optimizePressTheme = false;
1963
+ if ( in_array( 'optimizePressTheme', $themes ) ) {
1964
+ $addFilterToFixUpdate_optimizePressTheme = true;
1965
+ add_filter( 'site_transient_update_themes', array( $this, 'hookFixOptimizePressThemeUpdate' ), 99 );
1966
+ }
1967
+
1968
+ //@see wp-admin/update.php
1969
+ if ( null !== $this->filterFunction ) {
1970
+ remove_filter( 'pre_site_transient_update_plugins', $this->filterFunction, 99 );
1971
+ }
1972
+
1973
+ $last_update2 = get_site_transient( 'update_themes' );
1974
+ set_site_transient( 'update_themes', $last_update );
1975
+ // if ( !empty( $last_update ) && property_exists( $last_update, 'last_checked' ) ) {
1976
+ // $last_update->last_checked = $originalLastChecked;
1977
+ // set_site_transient( 'update_themes', $last_update );
1978
+ // }
1979
+
1980
+ // @wp_update_themes();
1981
+ $failed = true;
1982
+ $upgrader = new Theme_Upgrader( new Bulk_Theme_Upgrader_Skin( compact( 'nonce', 'url' ) ) );
1983
+ $result = $upgrader->bulk_upgrade( $themes );
1984
+ if ( ! empty( $result ) ) {
1985
+ foreach ( $result as $theme => $info ) {
1986
+ if ( empty( $info ) ) {
1987
+ $information['upgrades'][ $theme ] = false;
1988
+ } else {
1989
+ $information['upgrades'][ $theme ] = true;
1990
+ // to fix logging update
1991
+ if (isset($information['theme_updates']) && isset($information['theme_updates'][$theme])) {
1992
+ $theme_info = $information['theme_updates'][$theme];
1993
+ $args = array();
1994
+ $args['type'] = 'theme';
1995
+ $args['slug'] = $theme;
1996
+ $args['name'] = $theme_info['Name'];
1997
+ $args['version'] = $theme_info['update']['new_version'];
1998
+ $args['old_version'] = $theme_info['Version'];
1999
+ $args['action'] = 'update';
2000
+ do_action( 'mainwp_child_upgradePluginTheme', $args );
2001
+ }
2002
+
2003
+ }
2004
+ }
2005
+ $failed = false;
2006
+ }
2007
+
2008
+ if ($failed) {
2009
+ MainWP_Helper::error( __( 'Invalid request!', 'mainwp-child' ) );
2010
+ }
2011
+
2012
+ if ( null !== $this->filterFunction ) {
2013
+ add_filter( 'pre_site_transient_update_themes', $this->filterFunction, 99 );
2014
+ }
2015
+
2016
+ set_site_transient( 'update_themes', $last_update2 );
2017
+
2018
+ if ( $addFilterToFixUpdate_optimizePressTheme ) {
2019
+ remove_filter( 'site_transient_update_themes', array(
2020
+ $this,
2021
+ 'hookFixOptimizePressThemeUpdate',
2022
+ ), 99 );
2023
+ }
2024
+
2025
+ }
2026
+
2027
+ // $last_update = get_site_transient( 'update_themes' );
2028
+ // if ( !empty( $last_update ) && property_exists( $last_update, 'last_checked' ) ) {
2029
+ // $last_update->last_checked = $originalLastChecked;
2030
+ // set_site_transient( 'update_themes', $last_update );
2031
+ // }
2032
+
2033
+ // @wp_update_themes();
2034
+
2035
+ if ( count( $premiumThemes ) > 0 ) {
2036
+ $mwp_premium_updates = apply_filters( 'mwp_premium_perform_update', array() );
2037
+ $mwp_premium_updates_todo = array();
2038
+ $mwp_premium_updates_todo_slugs = array();
2039
+ if ( is_array( $premiumThemes ) && is_array( $mwp_premium_updates ) ) {
2040
+ foreach ( $premiumThemes as $premiumTheme ) {
2041
+ foreach ( $mwp_premium_updates as $key => $update ) {
2042
+ $slug = ( isset( $update['slug'] ) ? $update['slug'] : $update['Name'] );
2043
+ if ( 0 === strcmp( $slug, $premiumTheme ) ) {
2044
+ $mwp_premium_updates_todo[ $key ] = $update;
2045
+ $mwp_premium_updates_todo_slugs[] = $slug;
2046
+ }
2047
+ }
2048
+ }
2049
+ }
2050
+ unset( $mwp_premium_updates );
2051
+
2052
+ $premiumUpgrader = new Theme_Upgrader( new Bulk_Theme_Upgrader_Skin( compact( 'nonce', 'url' ) ) );
2053
+ }
2054
+ if ( count( $themes ) <= 0 && count( $premiumThemes ) <= 0 ) {
2055
+ MainWP_Helper::error( __( 'Invalid request!', 'mainwp-child' ) );
2056
+ }
2057
+
2058
+ if ( null !== $this->filterFunction ) {
2059
+ remove_filter( 'pre_site_transient_update_themes', $this->filterFunction, 99 );
2060
+ }
2061
+ } else {
2062
+ MainWP_Helper::error( __( 'Invalid request!', 'mainwp-child' ) );
2063
+ }
2064
+
2065
+ if ( count( $mwp_premium_updates_todo ) > 0 ) {
2066
+ //Upgrade via WP
2067
+ //@see wp-admin/update.php
2068
+ $result = $premiumUpgrader->bulk_upgrade( $mwp_premium_updates_todo_slugs );
2069
+ if ( ! empty( $result ) ) {
2070
+ foreach ( $result as $plugin => $info ) {
2071
+ if ( ! empty( $info ) ) {
2072
+ $information['upgrades'][ $plugin ] = true;
2073
+
2074
+ foreach ( $mwp_premium_updates_todo as $key => $update ) {
2075
+ $slug = ( isset( $update['slug'] ) ? $update['slug'] : $update['Name'] );
2076
+ if ( 0 === strcmp( $slug, $plugin ) ) {
2077
+ //unset($mwp_premium_updates_todo[$key]);
2078
+ }
2079
+ }
2080
+ }
2081
+ }
2082
+ }
2083
+
2084
+ //Upgrade via callback
2085
+ foreach ( $mwp_premium_updates_todo as $update ) {
2086
+ $slug = ( isset( $update['slug'] ) ? $update['slug'] : $update['Name'] );
2087
+
2088
+ if ( isset( $update['url'] ) ) {
2089
+ $installer = new WP_Upgrader();
2090
+ //@see wp-admin/includes/class-wp-upgrader.php
2091
+ $result = $installer->run( array(
2092
+ 'package' => $update['url'],
2093
+ 'destination' => ( 'plugin' === $update['type'] ? WP_PLUGIN_DIR : WP_CONTENT_DIR . '/themes' ),
2094
+ 'clear_destination' => true,
2095
+ 'clear_working' => true,
2096
+ 'hook_extra' => array(),
2097
+ ) );
2098
+ $information['upgrades'][ $slug ] = ( ! is_wp_error( $result ) && ! empty( $result ) );
2099
+ } else if ( isset( $update['callback'] ) ) {
2100
+ if ( is_array( $update['callback'] ) && isset( $update['callback'][0] ) && isset( $update['callback'][1] ) ) {
2101
+ $update_result = @call_user_func( array(
2102
+ $update['callback'][0],
2103
+ $update['callback'][1],
2104
+ ) );
2105
+ $information['upgrades'][ $slug ] = $update_result && true;
2106
+ } else if ( is_string( $update['callback'] ) ) {
2107
+ $update_result = @call_user_func( $update['callback'] );
2108
+ $information['upgrades'][ $slug ] = $update_result && true;
2109
+ } else {
2110
+ $information['upgrades'][ $slug ] = false;
2111
+ }
2112
+ } else {
2113
+ $information['upgrades'][ $slug ] = false;
2114
+ }
2115
+ }
2116
+ }
2117
+ $information['sync'] = $this->getSiteStats( array(), false );
2118
+ MainWP_Helper::write( $information );
2119
+ }
2120
+
2121
+ function hookFixOptimizePressThemeUpdate( $transient ) {
2122
+ if ( ! defined( 'OP_FUNC' ) ) {
2123
+ return $transient;
2124
+ }
2125
+
2126
+ $theme_slug = 'optimizePressTheme';
2127
+
2128
+ if ( ! function_exists( 'op_sl_update' ) ) {
2129
+ require_once OP_FUNC . 'options.php';
2130
+ require_once OP_FUNC . 'sl_api.php';
2131
+ }
2132
+ $apiResponse = op_sl_update( 'theme' );
2133
+
2134
+ if ( is_wp_error( $apiResponse ) ) {
2135
+ return $transient;
2136
+ }
2137
+
2138
+ $obj = new stdClass();
2139
+ $obj->slug = $theme_slug;
2140
+ $obj->new_version = $apiResponse->new_version;
2141
+ $obj->url = $apiResponse->url;
2142
+ $obj->package = $apiResponse->s3_package;
2143
+ $obj->sections = array(
2144
+ 'description' => $apiResponse->section->description,
2145
+ 'changelog' => $apiResponse->section->changelog,
2146
+ );
2147
+
2148
+ $transient->response[ $theme_slug ] = (array) $obj;
2149
+
2150
+ return $transient;
2151
+ }
2152
+
2153
+ //This will register the current wp - thus generating the public key etc..
2154
+ function registerSite() {
2155
+ global $current_user;
2156
+
2157
+ $information = array();
2158
+ //Check if the user is valid & login
2159
+ if ( ! isset( $_POST['user'] ) || ! isset( $_POST['pubkey'] ) ) {
2160
+ MainWP_Helper::error( __( 'Invalid request!', 'mainwp-child' ) );
2161
+ }
2162
+
2163
+ MainWP_Helper::update_option( 'mainwp_child_branding_disconnected', 'yes', 'yes' );
2164
+
2165
+ //Already added - can't readd. Deactivate plugin..
2166
+ if ( get_option( 'mainwp_child_pubkey' ) ) {
2167
+ MainWP_Helper::error( __( 'Public key already set. Please reset the MainWP Child plugin on the child site and try again.', 'mainwp-child' ) );
2168
+ }
2169
+
2170
+ if ( '' != get_option( 'mainwp_child_uniqueId' ) ) {
2171
+ if ( ! isset( $_POST['uniqueId'] ) || ( '' === $_POST['uniqueId'] ) ) {
2172
+ MainWP_Helper::error( __( 'This child site is set to require a unique security ID. Please enter it before the connection can be established.', 'mainwp-child' ) );
2173
+ } else if ( get_option( 'mainwp_child_uniqueId' ) !== $_POST['uniqueId'] ) {
2174
+ MainWP_Helper::error( __( 'The unique security ID mismatch! Please correct it before the connection can be established.', 'mainwp-child' ) );
2175
+ }
2176
+ }
2177
+
2178
+ //Check SSL Requirement
2179
+ if ( !MainWP_Helper::isSSLEnabled() && ( !defined( 'MAINWP_ALLOW_NOSSL_CONNECT' ) || !MAINWP_ALLOW_NOSSL_CONNECT ) ) {
2180
+ MainWP_Helper::error( __( 'SSL is required on the child site to set up a secure connection.', 'mainwp-child' ) );
2181
+ }
2182
+
2183
+ //Login
2184
+ if ( isset( $_POST['user'] ) ) {
2185
+ if ( ! $this->login( $_POST['user'] ) ) {
2186
+ $hint = "<br/>" . __('Hint: Check if the administrator user exists on the child site, if not, you need to use an existing administrator.', 'mainwp-child');
2187
+ MainWP_Helper::error(__('That administrator username was not found on this child site. Please verify that it is an existing administrator.' . $hint,'mainwp-child'));
2188
+ }
2189
+
2190
+ if ( 10 !== $current_user->wp_user_level && ( ! isset( $current_user->user_level ) || 10 !== $current_user->user_level ) && ! $current_user->has_cap( 'level_10' ) ) {
2191
+ MainWP_Helper::error( __( 'That user is not an administrator. Please use an administrator user to establish the connection.', 'mainwp-child' ) );
2192
+ }
2193
+ }
2194
+
2195
+ MainWP_Helper::update_option( 'mainwp_child_pubkey', base64_encode( $_POST['pubkey'] ), 'yes' ); //Save the public key
2196
+ MainWP_Helper::update_option( 'mainwp_child_server', $_POST['server'] ); //Save the public key
2197
+ MainWP_Helper::update_option( 'mainwp_child_nonce', 0 ); //Save the nonce
2198
+
2199
+ MainWP_Helper::update_option( 'mainwp_child_nossl', ( '-1' === $_POST['pubkey'] || ! MainWP_Helper::isSSLEnabled() ? 1 : 0 ), 'yes' );
2200
+ $information['nossl'] = ( '-1' === $_POST['pubkey'] || ! MainWP_Helper::isSSLEnabled() ? 1 : 0 );
2201
+ $nossl_key = uniqid( '', true );
2202
+ MainWP_Helper::update_option( 'mainwp_child_nossl_key', $nossl_key, 'yes' );
2203
+ $information['nosslkey'] = $nossl_key;
2204
+ MainWP_Helper::update_option( 'mainwp_child_branding_disconnected', '', 'yes' );
2205
+
2206
+ $information['register'] = 'OK';
2207
+ $information['uniqueId'] = get_option( 'mainwp_child_uniqueId', '' );
2208
+ $information['user'] = $_POST['user'];
2209
+
2210
+ $this->getSiteStats( $information );
2211
+ }
2212
+
2213
+ function newPost() {
2214
+ //Read form data
2215
+ $new_post = maybe_unserialize( base64_decode( $_POST['new_post'] ) );
2216
+ $post_custom = maybe_unserialize( base64_decode( $_POST['post_custom'] ) );
2217
+ $post_category = rawurldecode( isset( $_POST['post_category'] ) ? base64_decode( $_POST['post_category'] ) : null );
2218
+ $post_tags = rawurldecode( isset( $new_post['post_tags'] ) ? $new_post['post_tags'] : null );
2219
+ $post_featured_image = base64_decode( $_POST['post_featured_image'] );
2220
+ $upload_dir = maybe_unserialize( base64_decode( $_POST['mainwp_upload_dir'] ) );
2221
+
2222
+ if ( isset( $_POST['_ezin_post_category'] ) ) {
2223
+ $new_post['_ezin_post_category'] = maybe_unserialize( base64_decode( $_POST['_ezin_post_category'] ) );
2224
+ }
2225
+
2226
+ $others = array();
2227
+ if ( isset( $_POST['featured_image_data'] ) && !empty($_POST['featured_image_data'])) {
2228
+ $others['featured_image_data'] = unserialize(base64_decode( $_POST['featured_image_data'] ));
2229
+ }
2230
+
2231
+ $res = MainWP_Helper::createPost( $new_post, $post_custom, $post_category, $post_featured_image, $upload_dir, $post_tags, $others );
2232
+
2233
+ if (is_array($res) && isset($res['error'])) {
2234
+ MainWP_Helper::error( $res['error'] );
2235
+ }
2236
+
2237
+ $created = $res['success'];
2238
+ if ( true !== $created ) {
2239
+ MainWP_Helper::error( 'Undefined error' );
2240
+ }
2241
+
2242
+ $information['added'] = true;
2243
+ $information['added_id'] = $res['added_id'];
2244
+ $information['link'] = $res['link'];
2245
+
2246
+ do_action('mainwp_child_after_newpost', $res);
2247
+
2248
+ MainWP_Helper::write( $information );
2249
+ }
2250
+
2251
+ function post_action() {
2252
+ //Read form data
2253
+ $action = $_POST['action'];
2254
+ $postId = $_POST['id'];
2255
+ $my_post = array();
2256
+
2257
+ if ( 'publish' === $action ) {
2258
+ // to fix error post slug
2259
+ //wp_publish_post( $postId );
2260
+ wp_update_post(array('ID' => $postId, 'post_status' => 'publish' ));
2261
+ } else if ( 'update' === $action ) {
2262
+ $postData = $_POST['post_data'];
2263
+ $my_post = is_array( $postData ) ? $postData : array();
2264
+ wp_update_post( $my_post );
2265
+ } else if ( 'unpublish' === $action ) {
2266
+ $my_post['ID'] = $postId;
2267
+ $my_post['post_status'] = 'draft';
2268
+ wp_update_post( $my_post );
2269
+ } else if ( 'trash' === $action ) {
2270
+ add_action( 'trash_post', array( 'MainWP_Child_Links_Checker', 'hook_post_deleted' ) );
2271
+ wp_trash_post( $postId );
2272
+ } else if ( 'delete' === $action ) {
2273
+ add_action( 'delete_post', array( 'MainWP_Child_Links_Checker', 'hook_post_deleted' ) );
2274
+ wp_delete_post( $postId, true );
2275
+ } else if ( 'restore' === $action ) {
2276
+ wp_untrash_post( $postId );
2277
+ } else if ( 'update_meta' === $action ) {
2278
+ $values = maybe_unserialize( base64_decode( $_POST['values'] ) );
2279
+ $meta_key = $values['meta_key'];
2280
+ $meta_value = $values['meta_value'];
2281
+ $check_prev = $values['check_prev'];
2282
+
2283
+ foreach ( $meta_key as $i => $key ) {
2284
+ if ( 1 === intval( $check_prev[ $i ] ) ) {
2285
+ update_post_meta( $postId, $key, get_post_meta( $postId, $key, true ) ? get_post_meta( $postId, $key, true ) : $meta_value[ $i ] );
2286
+ } else {
2287
+ update_post_meta( $postId, $key, $meta_value[ $i ] );
2288
+ }
2289
+ }
2290
+ } else if ( 'get_edit' === $action ) {
2291
+ $postId = $_POST['id'];
2292
+ $post_type = $_POST['post_type'];
2293
+ if ( $post_type == 'post' ) {
2294
+ $my_post = $this->get_post_edit( $postId );
2295
+ } else {
2296
+ $my_post = $this->get_page_edit( $postId );
2297
+ }
2298
+ } else {
2299
+ $information['status'] = 'FAIL';
2300
+ }
2301
+
2302
+ if ( ! isset( $information['status'] ) ) {
2303
+ $information['status'] = 'SUCCESS';
2304
+ }
2305
+ $information['my_post'] = $my_post;
2306
+ MainWP_Helper::write( $information );
2307
+ }
2308
+
2309
+ function get_post_edit($id) {
2310
+ $post = get_post( $id );
2311
+ if ( $post ) {
2312
+ $categoryObjects = get_the_category( $post->ID );
2313
+ $categories = '';
2314
+ foreach ( $categoryObjects as $cat ) {
2315
+ if ( '' !== $categories ) {
2316
+ $categories .= ', ';
2317
+ }
2318
+ $categories .= $cat->name;
2319
+ }
2320
+ $post_category = $categories;
2321
+
2322
+ $tagObjects = get_the_tags( $post->ID );
2323
+ $tags = '';
2324
+ if ( is_array( $tagObjects ) ) {
2325
+ foreach ( $tagObjects as $tag ) {
2326
+ if ( '' !== $tags ) {
2327
+ $tags .= ', ';
2328
+ }
2329
+ $tags .= $tag->name;
2330
+ }
2331
+ }
2332
+ $post_tags = $tags;
2333
+
2334
+ $post_custom = get_post_custom( $id );
2335
+
2336
+ $galleries = get_post_gallery( $id, false );
2337
+ $post_gallery_images = array();
2338
+
2339
+ if ( is_array($galleries) && isset($galleries['ids']) ) {
2340
+ $attached_images = explode( ',', $galleries['ids'] );
2341
+ foreach( $attached_images as $attachment_id ) {
2342
+ $attachment = get_post( $attachment_id );
2343
+ if ( $attachment ) {
2344
+ $post_gallery_images[] = array(
2345
+ 'id' => $attachment_id,
2346
+ 'alt' => get_post_meta( $attachment->ID, '_wp_attachment_image_alt', true ),
2347
+ 'caption' => $attachment->post_excerpt,
2348
+ 'description' => $attachment->post_content,
2349
+ 'src' => $attachment->guid,
2350
+ 'title' => $attachment->post_title
2351
+ );
2352
+ }
2353
+ }
2354
+ }
2355
+
2356
+ include_once( ABSPATH . 'wp-includes' . DIRECTORY_SEPARATOR . 'post-thumbnail-template.php' );
2357
+ $post_featured_image = get_post_thumbnail_id( $id );
2358
+ $child_upload_dir = wp_upload_dir();
2359
+ $new_post = array(
2360
+ 'edit_id' => $id,
2361
+ 'is_sticky' => is_sticky( $id ) ? 1 : 0,
2362
+ 'post_title' => $post->post_title,
2363
+ 'post_content' => $post->post_content,
2364
+ 'post_status' => $post->post_status,
2365
+ 'post_date' => $post->post_date,
2366
+ 'post_date_gmt' => $post->post_date_gmt,
2367
+ 'post_tags' => $post_tags,
2368
+ 'post_name' => $post->post_name,
2369
+ 'post_excerpt' => $post->post_excerpt,
2370
+ 'comment_status' => $post->comment_status,
2371
+ 'ping_status' => $post->ping_status
2372
+ );
2373
+
2374
+ if ( $post_featured_image != null ) { //Featured image is set, retrieve URL
2375
+ $img = wp_get_attachment_image_src( $post_featured_image, 'full' );
2376
+ $post_featured_image = $img[0];
2377
+ }
2378
+
2379
+ require_once ABSPATH . 'wp-admin/includes/post.php';
2380
+ wp_set_post_lock($id);
2381
+
2382
+ $post_data = array(
2383
+ 'new_post' => base64_encode( serialize( $new_post ) ),
2384
+ 'post_custom' => base64_encode( serialize( $post_custom ) ),
2385
+ 'post_category' => base64_encode( $post_category ),
2386
+ 'post_featured_image' => base64_encode( $post_featured_image ),
2387
+ 'post_gallery_images' => base64_encode( serialize( $post_gallery_images ) ),
2388
+ 'child_upload_dir' => base64_encode( serialize( $child_upload_dir ) ),
2389
+ );
2390
+ return $post_data;
2391
+
2392
+ }
2393
+ return false;
2394
+ }
2395
+
2396
+ function get_page_edit($id) {
2397
+ $post = get_post( $id );
2398
+ if ( $post ) {
2399
+ $post_custom = get_post_custom( $id );
2400
+ //post_slug = base64_decode( get_post_meta( $id, '_slug', true ) );
2401
+ include_once( ABSPATH . 'wp-includes' . DIRECTORY_SEPARATOR . 'post-thumbnail-template.php' );
2402
+ $post_featured_image = get_post_thumbnail_id( $id );
2403
+ $child_upload_dir = wp_upload_dir();
2404
+
2405
+ $new_post = array(
2406
+ 'edit_id' => $id,
2407
+ 'post_title' => $post->post_title,
2408
+ 'post_content' => $post->post_content,
2409
+ 'post_status' => $post->post_status,
2410
+ 'post_date' => $post->post_date,
2411
+ 'post_date_gmt' => $post->post_date_gmt,
2412
+ 'post_type' => 'page',
2413
+ 'post_name' => $post->post_name,
2414
+ 'post_excerpt' => $post->post_excerpt,
2415
+ 'comment_status' => $post->comment_status,
2416
+ 'ping_status' => $post->ping_status
2417
+ );
2418
+
2419
+
2420
+ if ( $post_featured_image != null ) { //Featured image is set, retrieve URL
2421
+ $img = wp_get_attachment_image_src( $post_featured_image, 'full' );
2422
+ $post_featured_image = $img[0];
2423
+ }
2424
+
2425
+ $galleries = get_post_gallery( $id, false );
2426
+ $post_gallery_images = array();
2427
+
2428
+ if ( is_array($galleries) && isset($galleries['ids']) ) {
2429
+ $attached_images = explode( ',', $galleries['ids'] );
2430
+ foreach( $attached_images as $attachment_id ) {
2431
+ $attachment = get_post( $attachment_id );
2432
+ if ( $attachment ) {
2433
+ $post_gallery_images[] = array(
2434
+ 'id' => $attachment_id,
2435
+ 'alt' => get_post_meta( $attachment->ID, '_wp_attachment_image_alt', true ),
2436
+ 'caption' => $attachment->post_excerpt,
2437
+ 'description' => $attachment->post_content,
2438
+ 'src' => $attachment->guid,
2439
+ 'title' => $attachment->post_title
2440
+ );
2441
+ }
2442
+ }
2443
+ }
2444
+
2445
+ require_once ABSPATH . 'wp-admin/includes/post.php';
2446
+ wp_set_post_lock($id);
2447
+
2448
+ $post_data = array(
2449
+ 'new_post' => base64_encode( serialize( $new_post ) ),
2450
+ 'post_custom' => base64_encode( serialize( $post_custom ) ),
2451
+ 'post_featured_image' => base64_encode( $post_featured_image ),
2452
+ 'post_gallery_images' => base64_encode( serialize( $post_gallery_images ) ),
2453
+ 'child_upload_dir' => base64_encode( serialize( $child_upload_dir ) ),
2454
+ );
2455
+ return $post_data;
2456
+ }
2457
+ return false;
2458
+ }
2459
+
2460
+
2461
+ function user_action() {
2462
+ //Read form data
2463
+ $action = $_POST['action'];
2464
+ $extra = $_POST['extra'];
2465
+ $userId = $_POST['id'];
2466
+ $user_pass = $_POST['user_pass'];
2467
+ $failed = false;
2468
+
2469
+ global $current_user;
2470
+ $reassign = ( isset( $current_user ) && isset( $current_user->ID ) ) ? $current_user->ID : 0;
2471
+ include_once( ABSPATH . '/wp-admin/includes/user.php' );
2472
+
2473
+ if ( 'delete' === $action ) {
2474
+ wp_delete_user( $userId, $reassign );
2475
+ } else if ( 'changeRole' === $action ) {
2476
+ $my_user = array();
2477
+ $my_user['ID'] = $userId;
2478
+ $my_user['role'] = $extra;
2479
+ wp_update_user( $my_user );
2480
+ } else if ( 'update_password' === $action ) {
2481
+ $my_user = array();
2482
+ $my_user['ID'] = $userId;
2483
+ $my_user['user_pass'] = $user_pass;
2484
+ wp_update_user( $my_user );
2485
+ } else if ( 'edit' === $action ) {
2486
+ $user_data = $this->get_user_to_edit($userId);
2487
+ if (!empty($user_data)) {
2488
+ $information['user_data'] = $user_data;
2489
+ } else {
2490
+ $failed = true;
2491
+ }
2492
+ } else if ( 'update_user' === $action ) {
2493
+ $my_user = $_POST['extra'];
2494
+ if (is_array($my_user)) {
2495
+ foreach($my_user as $idx => $val) {
2496
+ if ($val === 'donotupdate' || (empty($val) && $idx !== 'role')) {
2497
+ unset($my_user[$idx]);
2498
+ }
2499
+ }
2500
+ $result = $this->edit_user( $userId, $my_user );
2501
+ if (is_array($result) && isset($result['error'])) {
2502
+ $information['error'] = $result['error'];
2503
+ }
2504
+ } else {
2505
+ $failed = true;
2506
+ }
2507
+ } else {
2508
+ $failed = true;
2509
+ }
2510
+
2511
+ if ($failed)
2512
+ $information['status'] = 'FAIL';
2513
+
2514
+ if ( ! isset( $information['status'] ) && !isset($information['error']) ) {
2515
+ $information['status'] = 'SUCCESS';
2516
+ if ('update_user' === $action && isset($_POST['optimize']) && !empty($_POST['optimize'])) {
2517
+ $information['users'] = $this->get_all_users_int(500); // to fix
2518
+ }
2519
+
2520
+ }
2521
+ MainWP_Helper::write( $information );
2522
+ }
2523
+
2524
+ function edit_user( $user_id, $data) {
2525
+ $wp_roles = wp_roles();
2526
+ $user = new stdClass;
2527
+
2528
+ $update = true;
2529
+
2530
+ if ( $user_id ) {
2531
+ $user->ID = (int) $user_id;
2532
+ $userdata = get_userdata( $user_id );
2533
+ $user->user_login = wp_slash( $userdata->user_login );
2534
+ } else {
2535
+ return array('error' => 'ERROR: Empty user id.');
2536
+ }
2537
+
2538
+ $pass1 = $pass2 = '';
2539
+ if ( isset( $data['pass1'] ) )
2540
+ $pass1 = $data['pass1'];
2541
+ if ( isset( $data['pass2'] ) )
2542
+ $pass2 = $data['pass2'];
2543
+
2544
+ if ( isset( $data['role'] ) && current_user_can( 'edit_users' ) ) {
2545
+ $new_role = sanitize_text_field( $data['role'] );
2546
+ $potential_role = isset($wp_roles->role_objects[$new_role]) ? $wp_roles->role_objects[$new_role] : false;
2547
+ // Don't let anyone with 'edit_users' (admins) edit their own role to something without it.
2548
+ // Multisite super admins can freely edit their blog roles -- they possess all caps.
2549
+ if ( ( is_multisite() && current_user_can( 'manage_sites' ) ) || $user_id != get_current_user_id() || ($potential_role && $potential_role->has_cap( 'edit_users' ) ) )
2550
+ $user->role = $new_role;
2551
+
2552
+ // If the new role isn't editable by the logged-in user die with error
2553
+ $editable_roles = get_editable_roles();
2554
+ if ( ! empty( $new_role ) && empty( $editable_roles[$new_role] ) )
2555
+ return array('error' => 'You can&#8217;t give users that role.');
2556
+ }
2557
+
2558
+ $email = '';
2559
+ if ( isset( $data['email'] ) )
2560
+ $email = trim( $data['email'] );
2561
+
2562
+ if ( !empty( $email ) )
2563
+ $user->user_email = sanitize_text_field( wp_unslash( $email ) );
2564
+ else
2565
+ $user->user_email = $userdata->user_email;
2566
+
2567
+ if ( isset( $data['url'] ) ) {
2568
+ if ( empty ( $data['url'] ) || $data['url'] == 'http://' ) {
2569
+ $user->user_url = '';
2570
+ } else {
2571
+ $user->user_url = esc_url_raw( $data['url'] );
2572
+ $protocols = implode( '|', array_map( 'preg_quote', wp_allowed_protocols() ) );
2573
+ $user->user_url = preg_match('/^(' . $protocols . '):/is', $user->user_url) ? $user->user_url : 'http://'.$user->user_url;
2574
+ }
2575
+ }
2576
+
2577
+ if ( isset( $data['first_name'] ) )
2578
+ $user->first_name = sanitize_text_field( $data['first_name'] );
2579
+ if ( isset( $data['last_name'] ) )
2580
+ $user->last_name = sanitize_text_field( $data['last_name'] );
2581
+ if ( isset( $data['nickname'] ) && !empty($data['nickname']))
2582
+ $user->nickname = sanitize_text_field( $data['nickname'] );
2583
+ if ( isset( $data['display_name'] ) )
2584
+ $user->display_name = sanitize_text_field( $data['display_name'] );
2585
+ if ( isset( $data['description'] ) )
2586
+ $user->description = trim( $data['description'] );
2587
+
2588
+ $errors = new WP_Error();
2589
+
2590
+ /* checking that username has been typed */
2591
+ if ( $user->user_login == '' )
2592
+ $errors->add( 'user_login', __( '<strong>ERROR</strong>: Please enter a username.' ) );
2593
+
2594
+ do_action_ref_array( 'check_passwords', array( $user->user_login, &$pass1, &$pass2 ) );
2595
+
2596
+ if (!empty($pass1) || !empty($pass2)) {
2597
+ // Check for blank password when adding a user.
2598
+ if ( ! $update && empty( $pass1 ) ) {
2599
+ $errors->add( 'pass', __( '<strong>ERROR</strong>: Please enter a password.' ), array( 'form-field' => 'pass1' ) );
2600
+ }
2601
+
2602
+ // Check for "\" in password.
2603
+ if ( false !== strpos( wp_unslash( $pass1 ), "\\" ) ) {
2604
+ $errors->add( 'pass', __( '<strong>ERROR</strong>: Passwords may not contain the character "\\".' ), array( 'form-field' => 'pass1' ) );
2605
+ }
2606
+
2607
+ // Checking the password has been typed twice the same.
2608
+ if ( ( $update || ! empty( $pass1 ) ) && $pass1 != $pass2 ) {
2609
+ $errors->add( 'pass', __( '<strong>ERROR</strong>: Please enter the same password in both password fields.' ), array( 'form-field' => 'pass1' ) );
2610
+ }
2611
+
2612
+ if ( !empty( $pass1 ) )
2613
+ $user->user_pass = $pass1;
2614
+ } else {
2615
+ $user->user_pass = $userdata->user_pass;
2616
+ }
2617
+
2618
+ /** This filter is documented in wp-includes/user.php */
2619
+ $illegal_logins = (array) apply_filters( 'illegal_user_logins', array() );
2620
+
2621
+ if ( in_array( strtolower( $user->user_login ), array_map( 'strtolower', $illegal_logins ) ) ) {
2622
+ $errors->add( 'invalid_username', __( '<strong>ERROR</strong>: Sorry, that username is not allowed.' ) );
2623
+ }
2624
+
2625
+ /* checking email address */
2626
+ if ( empty( $user->user_email ) ) {
2627
+ $errors->add( 'empty_email', __( '<strong>ERROR</strong>: Please enter an email address.' ), array( 'form-field' => 'email' ) );
2628
+ } elseif ( !is_email( $user->user_email ) ) {
2629
+ $errors->add( 'invalid_email', __( '<strong>ERROR</strong>: The email address isn&#8217;t correct.' ), array( 'form-field' => 'email' ) );
2630
+ } elseif ( ( $owner_id = email_exists($user->user_email) ) && ( !$update || ( $owner_id != $user->ID ) ) ) {
2631
+ $errors->add( 'email_exists', __('<strong>ERROR</strong>: This email is already registered, please choose another one.'), array( 'form-field' => 'email' ) );
2632
+ }
2633
+
2634
+ do_action_ref_array( 'user_profile_update_errors', array( &$errors, $update, &$user ) );
2635
+
2636
+ if ( $errors->get_error_codes() ) {
2637
+ $error_str = '';
2638
+ foreach ( $errors->get_error_messages() as $message ) {
2639
+ if ( is_string( $message ) )
2640
+ $error_str .= ' ' . esc_html( strip_tags( $message ) );
2641
+
2642
+ }
2643
+ return array( 'error' => $error_str );
2644
+ }
2645
+
2646
+ $user_id = wp_update_user( $user );
2647
+
2648
+ return $user_id;
2649
+ }
2650
+
2651
+ function get_user_to_edit( $user_id ) {
2652
+ require_once(ABSPATH . 'wp-admin/includes/user.php');
2653
+ $profileuser = get_user_to_edit($user_id);
2654
+
2655
+ $edit_data = array();
2656
+ if (is_object($profileuser)) {
2657
+ $user_roles = array_intersect( array_values( $profileuser->roles ), array_keys( get_editable_roles() ) );
2658
+ $user_role = reset( $user_roles );
2659
+ $edit_data['role'] = $user_role;
2660
+ $edit_data['first_name'] = $profileuser->first_name;
2661
+ $edit_data['last_name'] = $profileuser->last_name;
2662
+ $edit_data['nickname'] = $profileuser->nickname;
2663
+
2664
+ $public_display = array();
2665
+ $public_display['display_nickname'] = $profileuser->nickname;
2666
+ $public_display['display_username'] = $profileuser->user_login;
2667
+
2668
+ if ( !empty($profileuser->first_name) )
2669
+ $public_display['display_firstname'] = $profileuser->first_name;
2670
+
2671
+ if ( !empty($profileuser->last_name) )
2672
+ $public_display['display_lastname'] = $profileuser->last_name;
2673
+
2674
+ if ( !empty($profileuser->first_name) && !empty($profileuser->last_name) ) {
2675
+ $public_display['display_firstlast'] = $profileuser->first_name . ' ' . $profileuser->last_name;
2676
+ $public_display['display_lastfirst'] = $profileuser->last_name . ' ' . $profileuser->first_name;
2677
+ }
2678
+
2679
+ if ( !in_array( $profileuser->display_name, $public_display ) ) // Only add this if it isn't duplicated elsewhere
2680
+ $public_display = array( 'display_displayname' => $profileuser->display_name ) + $public_display;
2681
+
2682
+ $public_display = array_map( 'trim', $public_display );
2683
+ $public_display = array_unique( $public_display );
2684
+
2685
+ $edit_data['public_display'] = $public_display;
2686
+ $edit_data['display_name'] = $profileuser->display_name;
2687
+ $edit_data['user_email'] = $profileuser->user_email;
2688
+ $edit_data['user_url'] = $profileuser->user_url;
2689
+ foreach ( wp_get_user_contact_methods( $profileuser ) as $name => $desc ) {
2690
+ $edit_data['contact_methods'][$name] = $profileuser->$name;
2691
+ }
2692
+ $edit_data['description'] = $profileuser->description;
2693
+ }
2694
+ return $edit_data;
2695
+ }
2696
+
2697
+ //todo: backwards compatible: wp_set_comment_status ?
2698
+ function comment_action() {
2699
+ //Read form data
2700
+ $action = $_POST['action'];
2701
+ $commentId = $_POST['id'];
2702
+
2703
+ if ( 'approve' === $action ) {
2704
+ wp_set_comment_status( $commentId, 'approve' );
2705
+ } else if ( 'unapprove' === $action ) {
2706
+ wp_set_comment_status( $commentId, 'hold' );
2707
+ } else if ( 'spam' === $action ) {
2708
+ wp_spam_comment( $commentId );
2709
+ } else if ( 'unspam' === $action ) {
2710
+ wp_unspam_comment( $commentId );
2711
+ } else if ( 'trash' === $action ) {
2712
+ add_action( 'trashed_comment', array( 'MainWP_Child_Links_Checker', 'hook_trashed_comment' ), 10, 1 );
2713
+ wp_trash_comment( $commentId );
2714
+ } else if ( 'restore' === $action ) {
2715
+ wp_untrash_comment( $commentId );
2716
+ } else if ( 'delete' === $action ) {
2717
+ wp_delete_comment( $commentId, true );
2718
+ } else {
2719
+ $information['status'] = 'FAIL';
2720
+ }
2721
+
2722
+ if ( ! isset( $information['status'] ) ) {
2723
+ $information['status'] = 'SUCCESS';
2724
+ }
2725
+ MainWP_Helper::write( $information );
2726
+ }
2727
+
2728
+ //todo: backwards compatible: wp_set_comment_status ?
2729
+ function comment_bulk_action() {
2730
+ //Read form data
2731
+ $action = $_POST['action'];
2732
+ $commentIds = explode( ',', $_POST['ids'] );
2733
+ $information['success'] = 0;
2734
+ foreach ( $commentIds as $commentId ) {
2735
+ if ( $commentId ) {
2736
+ $information['success'] ++;
2737
+ if ( 'approve' === $action ) {
2738
+ wp_set_comment_status( $commentId, 'approve' );
2739
+ } else if ( 'unapprove' === $action ) {
2740
+ wp_set_comment_status( $commentId, 'hold' );
2741
+ } else if ( 'spam' === $action ) {
2742
+ wp_spam_comment( $commentId );
2743
+ } else if ( 'unspam' === $action ) {
2744
+ wp_unspam_comment( $commentId );
2745
+ } else if ( 'trash' === $action ) {
2746
+ wp_trash_comment( $commentId );
2747
+ } else if ( 'restore' === $action ) {
2748
+ wp_untrash_comment( $commentId );
2749
+ } else if ( 'delete' === $action ) {
2750
+ wp_delete_comment( $commentId, true );
2751
+ } else {
2752
+ $information['success']--;
2753
+ }
2754
+ }
2755
+ }
2756
+ MainWP_Helper::write( $information );
2757
+ }
2758
+
2759
+
2760
+ function newAdminPassword() {
2761
+ //Read form data
2762
+ $new_password = maybe_unserialize( base64_decode( $_POST['new_password'] ) );
2763
+ $user = get_user_by( 'login', $_POST['user'] );
2764
+ require_once( ABSPATH . WPINC . '/registration.php' );
2765
+
2766
+ $id = wp_update_user( array( 'ID' => $user->ID, 'user_pass' => $new_password['user_pass'] ) );
2767
+ if ( $id !== $user->ID ) {
2768
+ if ( is_wp_error( $id ) ) {
2769
+ MainWP_Helper::error( $id->get_error_message() );
2770
+ } else {
2771
+ MainWP_Helper::error( __( 'Administrator password could not be changed.', 'mainwp-child' ) );
2772
+ }
2773
+ }
2774
+
2775
+ $information['added'] = true;
2776
+ MainWP_Helper::write( $information );
2777
+ }
2778
+
2779
+ function newUser() {
2780
+ //Read form data
2781
+ $new_user = maybe_unserialize( base64_decode( $_POST['new_user'] ) );
2782
+ $send_password = $_POST['send_password'];
2783
+
2784
+ $new_user_id = wp_insert_user( $new_user );
2785
+
2786
+ if ( is_wp_error( $new_user_id ) ) {
2787
+ MainWP_Helper::error( $new_user_id->get_error_message() );
2788
+ }
2789
+ if ( 0 === $new_user_id ) {
2790
+ MainWP_Helper::error( __( 'Undefined error!', 'mainwp-child' ) );
2791
+ }
2792
+
2793
+ if ( $send_password ) {
2794
+ $user = new WP_User( $new_user_id );
2795
+
2796
+ $user_login = stripslashes( $user->user_login );
2797
+ $user_email = stripslashes( $user->user_email );
2798
+
2799
+ // The blogname option is escaped with esc_html on the way into the database in sanitize_option
2800
+ // we want to reverse this for the plain text arena of emails.
2801
+ $blogname = wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES );
2802
+
2803
+ $message = sprintf( __( 'Username: %s' ), $user_login ) . "\r\n";
2804
+ $message .= sprintf( __( 'Password: %s' ), $new_user['user_pass'] ) . "\r\n";
2805
+ $message .= wp_login_url() . "\r\n";
2806
+
2807
+ wp_mail( $user_email, sprintf( __( '[%s] Your username and password' ), $blogname ), $message );
2808
+ }
2809
+ $information['added'] = true;
2810
+ MainWP_Helper::write( $information );
2811
+ }
2812
+
2813
+ function cloneinfo() {
2814
+ global $table_prefix;
2815
+ $information['dbCharset'] = DB_CHARSET;
2816
+ $information['dbCollate'] = DB_COLLATE;
2817
+ $information['table_prefix'] = $table_prefix;
2818
+ $information['site_url'] = get_option( 'site_url' );
2819
+ $information['home'] = get_option( 'home' );
2820
+
2821
+ MainWP_Helper::write( $information );
2822
+ }
2823
+
2824
+ function backupPoll() {
2825
+ $fileNameUID = ( isset( $_POST['fileNameUID'] ) ? $_POST['fileNameUID'] : '' );
2826
+ $fileName = ( isset( $_POST['fileName'] ) ? $_POST['fileName'] : '' );
2827
+
2828
+ if ( 'full' === $_POST['type'] ) {
2829
+ if ( '' !== $fileName ) {
2830
+ $backupFile = $fileName;
2831
+ } else {
2832
+ $backupFile = 'backup-' . $fileNameUID . '-';
2833
+ }
2834
+
2835
+ $dirs = MainWP_Helper::getMainWPDir( 'backup' );
2836
+ $backupdir = $dirs[0];
2837
+ $result = glob( $backupdir . $backupFile . '*' );
2838
+ $archiveFile = false;
2839
+ foreach ( $result as $file ) {
2840
+ if ( MainWP_Helper::isArchive( $file, $backupFile, '(.*)' ) ) {
2841
+ $archiveFile = $file;
2842
+ break;
2843
+ }
2844
+ }
2845
+ if ( false === $archiveFile ) {
2846
+ MainWP_Helper::write( array() );
2847
+ }
2848
+
2849
+ MainWP_Helper::write( array( 'size' => filesize( $archiveFile ) ) );
2850
+ } else {
2851
+ $backupFile = 'dbBackup-' . $fileNameUID . '-*.sql';
2852
+
2853
+ $dirs = MainWP_Helper::getMainWPDir( 'backup' );
2854
+ $backupdir = $dirs[0];
2855
+ $result = glob( $backupdir . $backupFile . '*' );
2856
+ if ( 0 === count( $result ) ) {
2857
+ MainWP_Helper::write( array() );
2858
+ }
2859
+
2860
+ $size = 0;
2861
+ foreach ( $result as $f ) {
2862
+ $size += filesize($f);
2863
+ }
2864
+ MainWP_Helper::write( array( 'size' => $size ) );
2865
+ exit();
2866
+ }
2867
+ }
2868
+
2869
+ function backup_checkpid() {
2870
+ $pid = $_POST['pid'];
2871
+
2872
+ $dirs = MainWP_Helper::getMainWPDir( 'backup' );
2873
+ $backupdir = $dirs[0];
2874
+
2875
+ $information = array();
2876
+
2877
+ /** @var $wp_filesystem WP_Filesystem_Base */
2878
+ global $wp_filesystem;
2879
+
2880
+ MainWP_Helper::getWPFilesystem();
2881
+
2882
+ $pidFile = trailingslashit( $backupdir ) . 'backup-' . $pid . '.pid';
2883
+ $doneFile = trailingslashit( $backupdir ) . 'backup-' . $pid . '.done';
2884
+ if ( $wp_filesystem->is_file( $pidFile ) ) {
2885
+ $time = $wp_filesystem->mtime( $pidFile );
2886
+
2887
+ $minutes = date( 'i', time() );
2888
+ $seconds = date( 's', time() );
2889
+
2890
+ $file_minutes = date( 'i', $time );
2891
+ $file_seconds = date( 's', $time );
2892
+
2893
+ $minuteDiff = $minutes - $file_minutes;
2894
+ if ( 59 === $minuteDiff ) {
2895
+ $minuteDiff = 1;
2896
+ }
2897
+ $secondsdiff = ( $minuteDiff * 60 ) + $seconds - $file_seconds;
2898
+
2899
+ $file = $wp_filesystem->get_contents( $pidFile );
2900
+ $information['file'] = basename( $file );
2901
+ if ( $secondsdiff < 80 ) {
2902
+ $information['status'] = 'busy';
2903
+ } else {
2904
+ $information['status'] = 'stalled';
2905
+ }
2906
+ } else if ( $wp_filesystem->is_file( $doneFile ) ) {
2907
+ $file = $wp_filesystem->get_contents( $doneFile );
2908
+ $information['status'] = 'done';
2909
+ $information['file'] = basename( $file );
2910
+ $information['size'] = @filesize( $file );
2911
+ } else {
2912
+ $information['status'] = 'invalid';
2913
+ }
2914
+
2915
+ MainWP_Helper::write( $information );
2916
+ }
2917
+
2918
+ function backup( $pWrite = true ) {
2919
+ $timeout = 20 * 60 * 60; //20minutes
2920
+ @set_time_limit( $timeout );
2921
+ @ini_set( 'max_execution_time', $timeout );
2922
+ MainWP_Helper::endSession();
2923
+
2924
+ //Cleanup pid files!
2925
+ $dirs = MainWP_Helper::getMainWPDir( 'backup' );
2926
+ $backupdir = trailingslashit( $dirs[0] );
2927
+
2928
+ /** @var $wp_filesystem WP_Filesystem_Base */
2929
+ global $wp_filesystem;
2930
+
2931
+ MainWP_Helper::getWPFilesystem();
2932
+
2933
+ $files = glob( $backupdir . '*' );
2934
+ //Find old files (changes > 3 hr)
2935
+ foreach ( $files as $file ) {
2936
+ if ( MainWP_Helper::endsWith( $file, '/index.php' ) | MainWP_Helper::endsWith( $file, '/.htaccess' ) ) {
2937
+ continue;
2938
+ }
2939
+
2940
+ if ( ( time() - filemtime( $file ) ) > ( 60 * 60 * 3 ) ) {
2941
+ @unlink( $file );
2942
+ }
2943
+ }
2944
+
2945
+ $fileName = ( isset( $_POST['fileUID'] ) ? $_POST['fileUID'] : '' );
2946
+ if ( 'full' === $_POST['type'] ) {
2947
+ $excludes = ( isset( $_POST['exclude'] ) ? explode( ',', $_POST['exclude'] ) : array() );
2948
+ $excludes[] = str_replace( ABSPATH, '', WP_CONTENT_DIR ) . '/uploads/mainwp';
2949
+ $uploadDir = MainWP_Helper::getMainWPDir();
2950
+ $uploadDir = $uploadDir[0];
2951
+ $excludes[] = str_replace( ABSPATH, '', $uploadDir );
2952
+ $excludes[] = str_replace( ABSPATH, '', WP_CONTENT_DIR ) . '/object-cache.php';
2953
+
2954
+ if ( function_exists( 'posix_uname' ) ) {
2955
+ $uname = @posix_uname();
2956
+ if ( is_array( $uname ) && isset( $uname['nodename'] ) ) {
2957
+ if ( stristr( $uname['nodename'], 'hostgator' ) ) {
2958
+ if ( ! isset( $_POST['file_descriptors'] ) || '0' == $_POST['file_descriptors'] || $_POST['file_descriptors'] > 1000 ) {
2959
+ $_POST['file_descriptors'] = 1000;
2960
+ }
2961
+ $_POST['file_descriptors_auto'] = 0;
2962
+ $_POST['loadFilesBeforeZip'] = false;
2963
+ }
2964
+ }
2965
+ }
2966
+
2967
+ $file_descriptors = ( isset( $_POST['file_descriptors'] ) ? $_POST['file_descriptors'] : 0 );
2968
+ $file_descriptors_auto = ( isset( $_POST['file_descriptors_auto'] ) ? $_POST['file_descriptors_auto'] : 0 );
2969
+ if ( 1 === (int) $file_descriptors_auto ) {
2970
+ if ( function_exists( 'posix_getrlimit' ) ) {
2971
+ $result = @posix_getrlimit();
2972
+ if ( isset( $result['soft openfiles'] ) ) {
2973
+ $file_descriptors = $result['soft openfiles'];
2974
+ }
2975
+ }
2976
+ }
2977
+
2978
+ $loadFilesBeforeZip = ( isset( $_POST['loadFilesBeforeZip'] ) ? $_POST['loadFilesBeforeZip'] : true );
2979
+
2980
+ $newExcludes = array();
2981
+ foreach ( $excludes as $exclude ) {
2982
+ $newExcludes[] = rtrim( $exclude, '/' );
2983
+ }
2984
+
2985
+ $excludebackup = ( isset( $_POST['excludebackup'] ) && '1' == $_POST['excludebackup'] );
2986
+ $excludecache = ( isset( $_POST['excludecache'] ) && '1' == $_POST['excludecache'] );
2987
+ $excludezip = ( isset( $_POST['excludezip'] ) && '1' == $_POST['excludezip'] );
2988
+ $excludenonwp = ( isset( $_POST['excludenonwp'] ) && '1' == $_POST['excludenonwp'] );
2989
+
2990
+ if ( $excludebackup ) {
2991
+ //Backup buddy
2992
+ $newExcludes[] = str_replace( ABSPATH, '', WP_CONTENT_DIR ) . '/uploads/backupbuddy_backups';
2993
+ $newExcludes[] = str_replace( ABSPATH, '', WP_CONTENT_DIR ) . '/uploads/backupbuddy_temp';
2994
+ $newExcludes[] = str_replace( ABSPATH, '', WP_CONTENT_DIR ) . '/uploads/pb_backupbuddy';
2995
+
2996
+ //ManageWP
2997
+ $newExcludes[] = str_replace( ABSPATH, '', WP_CONTENT_DIR ) . '/managewp';
2998
+
2999
+ //InfiniteWP
3000
+ $newExcludes[] = str_replace( ABSPATH, '', WP_CONTENT_DIR ) . '/infinitewp';
3001
+
3002
+ //WordPress Backup to Dropbox
3003
+ $newExcludes[] = str_replace( ABSPATH, '', WP_CONTENT_DIR ) . '/backups';
3004
+
3005
+ //BackUpWordpress
3006
+ $newExcludes[] = str_replace( ABSPATH, '', WP_CONTENT_DIR ) . '/backups';
3007
+
3008
+ //BackWPUp
3009
+ $newExcludes[] = str_replace( ABSPATH, '', WP_CONTENT_DIR ) . '/uploads/backwpup*';
3010
+
3011
+ //WP Complete Backup
3012
+ $newExcludes[] = str_replace( ABSPATH, '', WP_CONTENT_DIR ) . '/plugins/wp-complete-backup/storage';
3013
+
3014
+ //WordPress EZ Backup
3015
+ //This one may be hard to do since they add random text at the end for example, feel free to skip if you need to
3016
+ ///backup_randomkyfkj where kyfkj is random
3017
+
3018
+ //Online Backup for WordPress
3019
+ $newExcludes[] = str_replace( ABSPATH, '', WP_CONTENT_DIR ) . '/backups';
3020
+
3021
+ //XCloner
3022
+ $newExcludes[] = '/administrator/backups';
3023
+ }
3024
+
3025
+ if ( $excludecache ) {
3026
+ //W3 Total Cache
3027
+ $newExcludes[] = str_replace( ABSPATH, '', WP_CONTENT_DIR ) . '/w3tc-cache';
3028
+ $newExcludes[] = str_replace( ABSPATH, '', WP_CONTENT_DIR ) . '/w3tc';
3029
+ $newExcludes[] = str_replace( ABSPATH, '', WP_CONTENT_DIR ) . '/cache/config';
3030
+ $newExcludes[] = str_replace( ABSPATH, '', WP_CONTENT_DIR ) . '/cache/minify';
3031
+ $newExcludes[] = str_replace( ABSPATH, '', WP_CONTENT_DIR ) . '/cache/page_enhanced';
3032
+ $newExcludes[] = str_replace( ABSPATH, '', WP_CONTENT_DIR ) . '/cache/tmp';
3033
+
3034
+ //WP Super Cache
3035
+ $newExcludes[] = str_replace( ABSPATH, '', WP_CONTENT_DIR ) . '/cache/supercache';
3036
+
3037
+ //Quick Cache
3038
+ $newExcludes[] = str_replace( ABSPATH, '', WP_CONTENT_DIR ) . '/cache/quick-cache';
3039
+
3040
+ //Hyper Cache
3041
+ $newExcludes[] = str_replace( ABSPATH, '', WP_CONTENT_DIR ) . '/hyper-cache/cache';
3042
+
3043
+ //WP Fastest Cache
3044
+ $newExcludes[] = str_replace( ABSPATH, '', WP_CONTENT_DIR ) . '/cache/all';
3045
+
3046
+ //WP-Rocket
3047
+ $newExcludes[] = str_replace( ABSPATH, '', WP_CONTENT_DIR ) . '/cache/wp-rocket';
3048
+ }
3049
+
3050
+ $file = false;
3051
+ if ( isset( $_POST['f'] ) ) {
3052
+ $file = $_POST['f'];
3053
+ } else if ( isset( $_POST['file'] ) ) {
3054
+ $file = $_POST['file'];
3055
+ }
3056
+
3057
+ $ext = 'zip';
3058
+ if ( isset( $_POST['ext'] ) ) {
3059
+ $ext = $_POST['ext'];
3060
+ }
3061
+
3062
+ $pid = false;
3063
+ if ( isset( $_POST['pid'] ) ) {
3064
+ $pid = $_POST['pid'];
3065
+ }
3066
+
3067
+ $append = ( isset( $_POST['append'] ) && ( '1' == $_POST['append'] ) );
3068
+
3069
+ $res = MainWP_Backup::get()->createFullBackup( $newExcludes, $fileName, true, true, $file_descriptors, $file, $excludezip, $excludenonwp, $loadFilesBeforeZip, $ext, $pid, $append );
3070
+ if ( ! $res ) {
3071
+ $information['full'] = false;
3072
+ } else {
3073
+ $information['full'] = $res['file'];
3074
+ $information['size'] = $res['filesize'];
3075
+ }
3076
+ $information['db'] = false;
3077
+ } else if ( 'db' == $_POST['type'] ) {
3078
+ $ext = 'zip';
3079
+ if ( isset( $_POST['ext'] ) ) {
3080
+ $ext = $_POST['ext'];
3081
+ }
3082
+
3083
+ $res = $this->backupDB( $fileName, $ext );
3084
+ if ( ! $res ) {
3085
+ $information['db'] = false;
3086
+ } else {
3087
+ $information['db'] = $res['file'];
3088
+ $information['size'] = $res['filesize'];
3089
+ }
3090
+ $information['full'] = false;
3091
+ } else {
3092
+ $information['full'] = false;
3093
+ $information['db'] = false;
3094
+ }
3095
+
3096
+ if ( $pWrite ) {
3097
+ MainWP_Helper::write( $information );
3098
+ }
3099
+
3100
+ return $information;
3101
+ }
3102
+
3103
+ protected function backupDB( $fileName = '', $ext = 'zip' ) {
3104
+ $dirs = MainWP_Helper::getMainWPDir( 'backup' );
3105
+ $dir = $dirs[0];
3106
+ $timestamp = time();
3107
+
3108
+ if ( '' !== $fileName ) {
3109
+ $fileName .= '-';
3110
+ }
3111
+
3112
+ $filepath_prefix = $dir . 'dbBackup-' . $fileName . $timestamp;
3113
+
3114
+ if ( $dh = opendir( $dir ) ) {
3115
+ while ( ( $file = readdir( $dh ) ) !== false ) {
3116
+ if ( '.' !== $file && '..' !== $file && ( preg_match( '/dbBackup-(.*).sql(\.zip|\.tar|\.tar\.gz|\.tar\.bz2|\.tmp)?$/', $file ) ) ) {
3117
+ @unlink( $dir . $file );
3118
+ }
3119
+ }
3120
+ closedir( $dh );
3121
+ }
3122
+
3123
+ $result = MainWP_Backup::get()->createBackupDB( $filepath_prefix, $ext );
3124
+
3125
+ MainWP_Helper::update_option( 'mainwp_child_last_db_backup_size', filesize( $result['filepath'] ) );
3126
+
3127
+ return ( ! $result ) ? false : array(
3128
+ 'timestamp' => $timestamp,
3129
+ 'file' => basename( $result['filepath'] ),
3130
+ 'filesize' => filesize( $result['filepath'] ),
3131
+ );
3132
+ }
3133
+
3134
+ function doSecurityFix() {
3135
+ $sync = false;
3136
+ if ( 'all' === $_POST['feature'] ) {
3137
+ //fix all
3138
+ $sync = true;
3139
+ }
3140
+
3141
+ $information = array();
3142
+ $security = get_option( 'mainwp_security' );
3143
+ if ( ! is_array( $security ) ) {
3144
+ $security = array();
3145
+ }
3146
+
3147
+ if ( 'all' === $_POST['feature'] || 'listing' === $_POST['feature'] ) {
3148
+ MainWP_Security::prevent_listing();
3149
+ $information['listing'] = ( ! MainWP_Security::prevent_listing_ok() ? 'N' : 'Y' );
3150
+ }
3151
+
3152
+ if ( 'all' === $_POST['feature'] || 'wp_version' === $_POST['feature'] ) {
3153
+ $security['wp_version'] = true;
3154
+ MainWP_Security::remove_wp_version( true );
3155
+ $information['wp_version'] = ( ! MainWP_Security::remove_wp_version_ok() ? 'N' : 'Y' );
3156
+ }
3157
+
3158
+ if ( 'all' === $_POST['feature'] || 'rsd' === $_POST['feature'] ) {
3159
+ $security['rsd'] = true;
3160
+ MainWP_Security::remove_rsd( true );
3161
+ $information['rsd'] = ( ! MainWP_Security::remove_rsd_ok() ? 'N' : 'Y' );
3162
+ }
3163
+
3164
+ if ( 'all' === $_POST['feature'] || 'wlw' === $_POST['feature'] ) {
3165
+ $security['wlw'] = true;
3166
+ MainWP_Security::remove_wlw( true );
3167
+ $information['wlw'] = ( ! MainWP_Security::remove_wlw_ok() ? 'N' : 'Y' );
3168
+ }
3169
+
3170
+ // if ($_POST['feature'] == 'all' || $_POST['feature'] == 'core_updates')
3171
+ // {
3172
+ // $security['core_updates'] = true;
3173
+ // MainWP_Security::remove_core_update(true);
3174
+ // $information['core_updates'] = (!MainWP_Security::remove_core_update_ok() ? 'N' : 'Y');
3175
+ // }
3176
+
3177
+ // if ($_POST['feature'] == 'all' || $_POST['feature'] == 'plugin_updates')
3178
+ // {
3179
+ // $security['plugin_updates'] = true;
3180
+ // MainWP_Security::remove_plugin_update(true);
3181
+ // $information['plugin_updates'] = (!MainWP_Security::remove_plugin_update_ok() ? 'N' : 'Y');
3182
+ // }
3183
+
3184
+ // if ($_POST['feature'] == 'all' || $_POST['feature'] == 'theme_updates')
3185
+ // {
3186
+ // $security['theme_updates'] = true;
3187
+ // MainWP_Security::remove_theme_update(true);
3188
+ // $information['theme_updates'] = (!MainWP_Security::remove_theme_update_ok() ? 'N' : 'Y');
3189
+ // }
3190
+
3191
+ // if ($_POST['feature'] == 'all' || $_POST['feature'] == 'file_perms')
3192
+ // {
3193
+ // MainWP_Security::fix_file_permissions();
3194
+ // $information['file_perms'] = (!MainWP_Security::fix_file_permissions_ok() ? 'N' : 'Y');
3195
+ // if ($information['file_perms'] == 'N')
3196
+ // {
3197
+ // $information['file_perms'] = 'Could not change all the file permissions';
3198
+ // }
3199
+ // }
3200
+
3201
+ if ( 'all' === $_POST['feature'] || 'db_reporting' === $_POST['feature'] ) {
3202
+ MainWP_Security::remove_database_reporting();
3203
+ $information['db_reporting'] = ( ! MainWP_Security::remove_database_reporting_ok() ? 'N' : 'Y' );
3204
+ }
3205
+
3206
+ if ( 'all' === $_POST['feature'] || 'php_reporting' === $_POST['feature'] ) {
3207
+ $security['php_reporting'] = true;
3208
+ MainWP_Security::remove_php_reporting( true );
3209
+ $information['php_reporting'] = ( ! MainWP_Security::remove_php_reporting_ok() ? 'N' : 'Y' );
3210
+ }
3211
+
3212
+ if ( 'all' === $_POST['feature'] || 'versions' === $_POST['feature'] ) {
3213
+ $security['scripts_version'] = true;
3214
+ $security['styles_version'] = true;
3215
+ $security['generator_version'] = true;
3216
+ MainWP_Security::remove_scripts_version( true );
3217
+ MainWP_Security::remove_styles_version( true );
3218
+ MainWP_Security::remove_generator_version( true );
3219
+ $information['versions'] = 'Y';
3220
+ }
3221
+
3222
+ if ( 'all' === $_POST['feature'] || 'admin' === $_POST['feature'] ) {
3223
+ $information['admin'] = ( ! MainWP_Security::admin_user_ok() ? 'N' : 'Y' );
3224
+ }
3225
+
3226
+ if ( 'all' === $_POST['feature'] || 'readme' === $_POST['feature'] ) {
3227
+ $security['readme'] = true;
3228
+ MainWP_Security::remove_readme( true );
3229
+ $information['readme'] = ( MainWP_Security::remove_readme_ok() ? 'Y' : 'N' );
3230
+ }
3231
+
3232
+ MainWP_Helper::update_option( 'mainwp_security', $security, 'yes' );
3233
+
3234
+ if ( $sync ) {
3235
+ $information['sync'] = $this->getSiteStats( array(), false );
3236
+ }
3237
+ MainWP_Helper::write( $information );
3238
+ }
3239
+
3240
+ function doSecurityUnFix() {
3241
+ $information = array();
3242
+
3243
+ $sync = false;
3244
+ if ( 'all' === $_POST['feature'] ) {
3245
+ $sync = true;
3246
+ }
3247
+
3248
+ $security = get_option( 'mainwp_security' );
3249
+
3250
+ if ( 'all' === $_POST['feature'] || 'wp_version' === $_POST['feature'] ) {
3251
+ $security['wp_version'] = false;
3252
+ $information['wp_version'] = 'N';
3253
+ }
3254
+
3255
+ if ( 'all' === $_POST['feature'] || 'rsd' === $_POST['feature'] ) {
3256
+ $security['rsd'] = false;
3257
+ $information['rsd'] = 'N';
3258
+ }
3259
+
3260
+ if ( 'all' === $_POST['feature'] || 'wlw' === $_POST['feature'] ) {
3261
+ $security['wlw'] = false;
3262
+ $information['wlw'] = 'N';
3263
+ }
3264
+
3265
+ if ( 'all' === $_POST['feature'] || 'php_reporting' === $_POST['feature'] ) {
3266
+ $security['php_reporting'] = false;
3267
+ $information['php_reporting'] = 'N';
3268
+ }
3269
+
3270
+ if ( 'all' === $_POST['feature'] || 'versions' === $_POST['feature'] ) {
3271
+ $security['scripts_version'] = false;
3272
+ $security['styles_version'] = false;
3273
+ $security['generator_version'] = false;
3274
+ $information['versions'] = 'N';
3275
+ }
3276
+
3277
+ if ( 'all' === $_POST['feature'] || 'readme' === $_POST['feature'] ) {
3278
+ $security['readme'] = false;
3279
+ $information['readme'] = MainWP_Security::remove_readme_ok();
3280
+ }
3281
+
3282
+ MainWP_Helper::update_option( 'mainwp_security', $security, 'yes' );
3283
+
3284
+ if ( $sync ) {
3285
+ $information['sync'] = $this->getSiteStats( array(), false );
3286
+ }
3287
+
3288
+ MainWP_Helper::write( $information );
3289
+ }
3290
+
3291
+ function getSecurityStats() {
3292
+ $information = array();
3293
+
3294
+ $information['listing'] = ( ! MainWP_Security::prevent_listing_ok() ? 'N' : 'Y' );
3295
+ $information['wp_version'] = ( ! MainWP_Security::remove_wp_version_ok() ? 'N' : 'Y' );
3296
+ $information['rsd'] = ( ! MainWP_Security::remove_rsd_ok() ? 'N' : 'Y' );
3297
+ $information['wlw'] = ( ! MainWP_Security::remove_wlw_ok() ? 'N' : 'Y' );
3298
+ // $information['core_updates'] = (!MainWP_Security::remove_core_update_ok() ? 'N' : 'Y');
3299
+ // $information['plugin_updates'] = (!MainWP_Security::remove_plugin_update_ok() ? 'N' : 'Y');
3300
+ // $information['theme_updates'] = (!MainWP_Security::remove_theme_update_ok() ? 'N' : 'Y');
3301
+ // $information['file_perms'] = (!MainWP_Security::fix_file_permissions_ok() ? 'N' : 'Y');
3302
+ $information['db_reporting'] = ( ! MainWP_Security::remove_database_reporting_ok() ? 'N' : 'Y' );
3303
+ $information['php_reporting'] = ( ! MainWP_Security::remove_php_reporting_ok() ? 'N' : 'Y' );
3304
+ $information['versions'] = ( ! MainWP_Security::remove_scripts_version_ok() || ! MainWP_Security::remove_styles_version_ok() || ! MainWP_Security::remove_generator_version_ok()
3305
+ ? 'N' : 'Y' );
3306
+ $information['admin'] = ( MainWP_Security::admin_user_ok() ? 'Y' : 'N' );
3307
+ $information['readme'] = ( MainWP_Security::remove_readme_ok() ? 'Y' : 'N' );
3308
+
3309
+ MainWP_Helper::write( $information );
3310
+ }
3311
+
3312
+ function updateExternalSettings() {
3313
+ $update_htaccess = false;
3314
+
3315
+ if ( isset( $_POST['heatMap'] ) ) {
3316
+ if ( '1' === $_POST['heatMap'] ) {
3317
+ if ( '1' !== get_option( 'heatMapEnabled' ) ) {
3318
+ $update_htaccess = true;
3319
+ }
3320
+ MainWP_Helper::update_option( 'heatMapEnabled', '1', 'yes' );
3321
+ MainWP_Helper::update_option( 'heatMapExtensionLoaded', 'yes', 'yes' );
3322
+ } else {
3323
+ if ( '0' !== get_option( 'heatMapEnabled' ) ) {
3324
+ $update_htaccess = true;
3325
+ }
3326
+ MainWP_Helper::update_option( 'heatMapEnabled', '0', 'yes' );
3327
+ MainWP_Helper::update_option( 'heatMapExtensionLoaded', '', 'yes' );
3328
+ }
3329
+ }
3330
+
3331
+ if ( isset( $_POST['cloneSites'] ) ) {
3332
+ if ( '0' !== $_POST['cloneSites'] ) {
3333
+ $arr = @json_decode( urldecode( $_POST['cloneSites'] ), 1 );
3334
+ MainWP_Helper::update_option( 'mainwp_child_clone_sites', ( ! is_array( $arr ) ? array() : $arr ) );
3335
+ } else {
3336
+ MainWP_Helper::update_option( 'mainwp_child_clone_sites', '0' );
3337
+ }
3338
+ }
3339
+
3340
+ if ( isset( $_POST['pluginDir'] ) ) {
3341
+ if ( get_option( 'mainwp_child_pluginDir' ) !== $_POST['pluginDir'] ) {
3342
+ MainWP_Helper::update_option( 'mainwp_child_pluginDir', $_POST['pluginDir'], 'yes' );
3343
+ $update_htaccess = true;
3344
+ }
3345
+ } else if ( false !== get_option( 'mainwp_child_pluginDir' ) ) {
3346
+ MainWP_Helper::update_option( 'mainwp_child_pluginDir', false, 'yes' );
3347
+ $update_htaccess = true;
3348
+ }
3349
+
3350
+ if ( $update_htaccess ) {
3351
+ $this->update_htaccess( true );
3352
+ }
3353
+ }
3354
+
3355
+ //Show stats
3356
+ function getSiteStats( $information = array(), $exit = true ) {
3357
+ global $wp_version;
3358
+
3359
+ if ( $exit ) {
3360
+ $this->updateExternalSettings();
3361
+ }
3362
+
3363
+ MainWP_Helper::update_option( 'mainwp_child_branding_disconnected', '', 'yes' );
3364
+ if ( isset( $_POST['server'] ) ) {
3365
+ MainWP_Helper::update_option( 'mainwp_child_server', $_POST['server'] );
3366
+ }
3367
+
3368
+ if ( isset( $_POST['numberdaysOutdatePluginTheme'] ) && ! empty( $_POST['numberdaysOutdatePluginTheme'] ) ) {
3369
+ $days_outdate = get_option( 'mainwp_child_plugintheme_days_outdate', 365 );
3370
+ if ( $days_outdate !== $_POST['numberdaysOutdatePluginTheme'] ) {
3371
+ $days_outdate = $_POST['numberdaysOutdatePluginTheme'];
3372
+ MainWP_Helper::update_option( 'mainwp_child_plugintheme_days_outdate', $days_outdate );
3373
+ MainWP_Child_Plugins_Check::Instance()->cleanup_deactivation( false );
3374
+ MainWP_Child_Themes_Check::Instance()->cleanup_deactivation( false );
3375
+ }
3376
+ }
3377
+
3378
+ $information['version'] = self::$version;
3379
+ $information['wpversion'] = $wp_version;
3380
+ $information['siteurl'] = get_option( 'siteurl' );
3381
+ $information['wpe'] = function_exists( 'is_wpe' ) ? 1 : 0;
3382
+
3383
+ $information['site_info'] = array(
3384
+ 'wpversion' => $wp_version,
3385
+ 'phpversion' => phpversion(),
3386
+ 'child_version' => self::$version,
3387
+ 'memory_limit' => MainWP_Child_Server_Information::getPHPMemoryLimit(),
3388
+ 'mysql_version' => MainWP_Child_Server_Information::getMySQLVersion(),
3389
+ 'ip' => $_SERVER['SERVER_ADDR']
3390
+ );
3391
+
3392
+ //Try to switch to SSL if SSL is enabled in between!
3393
+ $pubkey = get_option( 'mainwp_child_pubkey' );
3394
+ $nossl = get_option( 'mainwp_child_nossl' );
3395
+ if ( 1 == $nossl ) {
3396
+ if ( isset($pubkey) && MainWP_Helper::isSSLEnabled() ) {
3397
+ MainWP_Helper::update_option( 'mainwp_child_nossl', 0, 'yes' );
3398
+ $nossl = 0;
3399
+ }
3400
+ }
3401
+ $information['nossl'] = ( 1 == $nossl ? 1 : 0 );
3402
+
3403
+ include_once( ABSPATH . '/wp-admin/includes/update.php' );
3404
+
3405
+ $timeout = 3 * 60 * 60; // 3minutes
3406
+ @set_time_limit( $timeout );
3407
+ @ini_set( 'max_execution_time', $timeout );
3408
+
3409
+ //Check for new versions
3410
+ if ( null !== $this->filterFunction ) {
3411
+ add_filter( 'pre_site_transient_update_core', $this->filterFunction, 99 );
3412
+ }
3413
+ if ( null !== $this->filterFunction ) {
3414
+ add_filter( 'pre_transient_update_core', $this->filterFunction, 99 );
3415
+ }
3416
+ @wp_version_check();
3417
+ $core_updates = get_core_updates();
3418
+ if ( is_array($core_updates) && count( $core_updates ) > 0 ) {
3419
+ foreach ( $core_updates as $core_update ) {
3420
+ if ( 'latest' === $core_update->response ) {
3421
+ break;
3422
+ }
3423
+ if ( 'upgrade' === $core_update->response && version_compare( $wp_version, $core_update->current, '<=' ) ) {
3424
+ $information['wp_updates'] = $core_update->current;
3425
+ }
3426
+ }
3427
+ }
3428
+ if ( ! isset( $information['wp_updates'] ) ) {
3429
+ $information['wp_updates'] = null;
3430
+ }
3431
+ if ( null !== $this->filterFunction ) {
3432
+ remove_filter( 'pre_site_transient_update_core', $this->filterFunction, 99 );
3433
+ }
3434
+ if ( null !== $this->filterFunction ) {
3435
+ remove_filter( 'pre_transient_update_core', $this->filterFunction, 99 );
3436
+ }
3437
+
3438
+ add_filter( 'default_option_active_plugins', array( &$this, 'default_option_active_plugins' ) );
3439
+ add_filter( 'option_active_plugins', array( &$this, 'default_option_active_plugins' ) );
3440
+
3441
+ //First check for new premium updates
3442
+ $update_check = apply_filters( 'mwp_premium_update_check', array() );
3443
+ if ( ! empty( $update_check ) ) {
3444
+ foreach ( $update_check as $updateFeedback ) {
3445
+ if ( is_array( $updateFeedback['callback'] ) && isset( $updateFeedback['callback'][0] ) && isset( $updateFeedback['callback'][1] ) ) {
3446
+ @call_user_func( array( $updateFeedback['callback'][0], $updateFeedback['callback'][1] ) );
3447
+ } else if ( is_string( $updateFeedback['callback'] ) ) {
3448
+ @call_user_func( $updateFeedback['callback'] );
3449
+ }
3450
+ }
3451
+ }
3452
+
3453
+ $informationPremiumUpdates = apply_filters( 'mwp_premium_update_notification', array() );
3454
+ $premiumPlugins = array();
3455
+ $premiumThemes = array();
3456
+ if ( is_array( $informationPremiumUpdates ) ) {
3457
+ $premiumUpdates = array();
3458
+ $information['premium_updates'] = array();
3459
+ $informationPremiumUpdatesLength = count( $informationPremiumUpdates );
3460
+ for ( $i = 0; $i < $informationPremiumUpdatesLength; $i ++ ) {
3461
+ if ( ! isset( $informationPremiumUpdates[ $i ]['new_version'] ) ) {
3462
+ continue;
3463
+ }
3464
+ $slug = ( isset( $informationPremiumUpdates[ $i ]['slug'] ) ? $informationPremiumUpdates[ $i ]['slug'] : $informationPremiumUpdates[ $i ]['Name'] );
3465
+
3466
+ if ( 'plugin' === $informationPremiumUpdates[ $i ]['type'] ) {
3467
+ $premiumPlugins[] = $slug;
3468
+ } else if ( 'theme' === $informationPremiumUpdates[ $i ]['type'] ) {
3469
+ $premiumThemes[] = $slug;
3470
+ }
3471
+
3472
+ $new_version = $informationPremiumUpdates[ $i ]['new_version'];
3473
+
3474
+ unset( $informationPremiumUpdates[ $i ]['old_version'] );
3475
+ unset( $informationPremiumUpdates[ $i ]['new_version'] );
3476
+
3477
+ $information['premium_updates'][ $slug ] = $informationPremiumUpdates[ $i ];
3478
+ $information['premium_updates'][ $slug ]['update'] = (object) array(
3479
+ 'new_version' => $new_version,
3480
+ 'premium' => true,
3481
+ 'slug' => $slug,
3482
+ );
3483
+ if ( ! in_array( $slug, $premiumUpdates ) ) {
3484
+ $premiumUpdates[] = $slug;
3485
+ }
3486
+ }
3487
+ MainWP_Helper::update_option( 'mainwp_premium_updates', $premiumUpdates );
3488
+ }
3489
+
3490
+ remove_filter( 'default_option_active_plugins', array( &$this, 'default_option_active_plugins' ) );
3491
+ remove_filter( 'option_active_plugins', array( &$this, 'default_option_active_plugins' ) );
3492
+
3493
+ if ( null !== $this->filterFunction ) {
3494
+ add_filter( 'pre_site_transient_update_plugins', $this->filterFunction, 99 );
3495
+ }
3496
+
3497
+ global $wp_current_filter;
3498
+ $wp_current_filter[] = 'load-plugins.php';
3499
+
3500
+ @wp_update_plugins();
3501
+ include_once( ABSPATH . '/wp-admin/includes/plugin.php' );
3502
+ $plugin_updates = get_plugin_updates();
3503
+ if ( is_array( $plugin_updates ) ) {
3504
+ $information['plugin_updates'] = array();
3505
+
3506
+ foreach ( $plugin_updates as $slug => $plugin_update ) {
3507
+ if ( in_array( $plugin_update->Name, $premiumPlugins ) ) {
3508
+ continue;
3509
+ }
3510
+
3511
+ $information['plugin_updates'][ $slug ] = $plugin_update;
3512
+ }
3513
+
3514
+ // to fix bug
3515
+ $fix_update_plugins = get_site_transient( 'tofix_update_plugins' );
3516
+ if ( is_array( $fix_update_plugins ) && ( count( $fix_update_plugins ) > 0 ) ) {
3517
+ foreach( $fix_update_plugins as $slug => $plugin_update ) {
3518
+ if ( !isset( $information['plugin_updates'][ $slug ] ) ) {
3519
+ $information['plugin_updates'][ $slug ] = $plugin_update;
3520
+ }
3521
+ }
3522
+ }
3523
+ // end fix
3524
+ }
3525
+
3526
+ if ( null !== $this->filterFunction ) {
3527
+ remove_filter( 'pre_site_transient_update_plugins', $this->filterFunction, 99 );
3528
+ }
3529
+ if ( null !== $this->filterFunction ) {
3530
+ add_filter( 'pre_site_transient_update_themes', $this->filterFunction, 99 );
3531
+ }
3532
+ @wp_update_themes();
3533
+ include_once( ABSPATH . '/wp-admin/includes/theme.php' );
3534
+ $theme_updates = $this->upgrade_get_theme_updates();
3535
+ if ( is_array( $theme_updates ) ) {
3536
+ $information['theme_updates'] = array();
3537
+
3538
+ foreach ( $theme_updates as $slug => $theme_update ) {
3539
+ $name = ( is_array( $theme_update ) ? $theme_update['Name'] : $theme_update->Name );
3540
+ if ( in_array( $name, $premiumThemes ) ) {
3541
+ continue;
3542
+ }
3543
+
3544
+ $information['theme_updates'][ $slug ] = $theme_update;
3545
+ }
3546
+ }
3547
+ if ( null !== $this->filterFunction ) {
3548
+ remove_filter( 'pre_site_transient_update_themes', $this->filterFunction, 99 );
3549
+ }
3550
+
3551
+ $translation_updates = wp_get_translation_updates();
3552
+ if ( !empty( $translation_updates ) ) {
3553
+ $information['translation_updates'] = array();
3554
+ foreach ($translation_updates as $translation_update)
3555
+ {
3556
+ $new_translation_update = array('type' => $translation_update->type,
3557
+ 'slug' => $translation_update->slug,
3558
+ 'language' => $translation_update->language,
3559
+ 'version' => $translation_update->version);
3560
+ if ( 'plugin' === $translation_update->type ) {
3561
+ $all_plugins = get_plugins();
3562
+ foreach ( $all_plugins as $file => $plugin ) {
3563
+ if ( stristr( $file, $translation_update->slug ) ) {
3564
+ $new_translation_update['name'] = $plugin['Name'];
3565
+ break;
3566
+ }
3567
+ }
3568
+ } else if ( 'theme' === $translation_update->type ) {
3569
+ $theme = wp_get_theme($translation_update->slug);
3570
+ $new_translation_update['name'] = $theme->name;
3571
+ } else if ( ( 'core' === $translation_update->type ) && ( 'default' === $translation_update->slug ) ) {
3572
+ $new_translation_update['name'] = 'Wordpress core';
3573
+ }
3574
+ $information['translation_updates'][] = $new_translation_update;
3575
+ }
3576
+ }
3577
+
3578
+ $information['recent_comments'] = $this->get_recent_comments( array( 'approve', 'hold' ), 5 );
3579
+ $information['recent_posts'] = $this->get_recent_posts( array( 'publish', 'draft', 'pending', 'trash', 'future' ), 5 );
3580
+ $information['recent_pages'] = $this->get_recent_posts( array(
3581
+ 'publish',
3582
+ 'draft',
3583
+ 'pending',
3584
+ 'trash',
3585
+ 'future'
3586
+ ), 5, 'page' );
3587
+
3588
+ $securityIssuess = 0;
3589
+ if ( ! MainWP_Security::prevent_listing_ok() ) {
3590
+ $securityIssuess ++;
3591
+ }
3592
+ if ( ! MainWP_Security::remove_wp_version_ok() ) {
3593
+ $securityIssuess ++;
3594
+ }
3595
+ if ( ! MainWP_Security::remove_rsd_ok() ) {
3596
+ $securityIssuess ++;
3597
+ }
3598
+ if ( ! MainWP_Security::remove_wlw_ok() ) {
3599
+ $securityIssuess ++;
3600
+ }
3601
+ // if (!MainWP_Security::remove_core_update_ok()) $securityIssuess++;
3602
+ // if (!MainWP_Security::remove_plugin_update_ok()) $securityIssuess++;
3603
+ // if (!MainWP_Security::remove_theme_update_ok()) $securityIssuess++;
3604
+ // if (!MainWP_Security::fix_file_permissions_ok()) $securityIssuess++;
3605
+ if ( ! MainWP_Security::remove_database_reporting_ok() ) {
3606
+ $securityIssuess ++;
3607
+ }
3608
+ if ( ! MainWP_Security::remove_php_reporting_ok() ) {
3609
+ $securityIssuess ++;
3610
+ }
3611
+ if ( ! MainWP_Security::remove_scripts_version_ok() || ! MainWP_Security::remove_styles_version_ok() || ! MainWP_Security::remove_generator_version_ok() ) {
3612
+ $securityIssuess ++;
3613
+ }
3614
+ if ( ! MainWP_Security::admin_user_ok() ) {
3615
+ $securityIssuess ++;
3616
+ }
3617
+ if ( ! MainWP_Security::remove_readme_ok() ) {
3618
+ $securityIssuess ++;
3619
+ }
3620
+
3621
+ $information['securityIssues'] = $securityIssuess;
3622
+
3623
+ //Directory listings!
3624
+ $information['directories'] = $this->scanDir( ABSPATH, 3 );
3625
+ $cats = get_categories( array( 'hide_empty' => 0, 'hierarchical' => true, 'number' => 300 ) );
3626
+ $categories = array();
3627
+ foreach ( $cats as $cat ) {
3628
+ $categories[] = $cat->name;
3629
+ }
3630
+ $information['categories'] = $categories;
3631
+ $get_file_size = apply_filters('mainwp-child-get-total-size', true);
3632
+ if ($get_file_size) {
3633
+ $information['totalsize'] = $this->getTotalFileSize();
3634
+ }
3635
+ $information['dbsize'] = MainWP_Child_DB::get_size();
3636
+
3637
+ $auths = get_option( 'mainwp_child_auth' );
3638
+ $information['extauth'] = ( $auths && isset( $auths[ $this->maxHistory ] ) ? $auths[ $this->maxHistory ] : null );
3639
+
3640
+ $plugins = $this->get_all_plugins_int( false );
3641
+ $themes = $this->get_all_themes_int( false );
3642
+ $information['plugins'] = $plugins;
3643
+ $information['themes'] = $themes;
3644
+
3645
+ if ( isset( $_POST['optimize'] ) && ( '1' === $_POST['optimize'] ) ) {
3646
+ $information['users'] = $this->get_all_users_int(500); // to fix
3647
+ }
3648
+
3649
+ if ( isset( $_POST['othersData'] ) ) {
3650
+ $othersData = json_decode( stripslashes( $_POST['othersData'] ), true );
3651
+ if ( ! is_array( $othersData ) ) {
3652
+ $othersData = array();
3653
+ }
3654
+
3655
+ $information = apply_filters( 'mainwp-site-sync-others-data', $information, $othersData );
3656
+
3657
+ if ( version_compare( phpversion(), '5.3', '>=' ) ) {
3658
+ if ( isset( $othersData['syncBackUpWordPress'] ) && $othersData['syncBackUpWordPress'] ) {
3659
+ if ( MainWP_Child_Back_Up_Wordpress::isActivated() ) {
3660
+ $information['syncBackUpWordPress'] = MainWP_Child_Back_Up_Wordpress::Instance()->syncData();
3661
+ }
3662
+ }
3663
+ }
3664
+
3665
+
3666
+ if ( isset( $othersData['syncWPStaging'] ) && !empty( $othersData['syncWPStaging'] ) ) {
3667
+ if ( MainWP_Child_Staging::Instance()->is_plugin_installed ) {
3668
+ $information['syncWPStaging'] = MainWP_Child_Staging::Instance()->get_sync_data();
3669
+ }
3670
+ }
3671
+
3672
+
3673
+ if ( isset( $othersData['syncBackupBuddy'] ) && !empty( $othersData['syncBackupBuddy'] ) ) {
3674
+ if ( MainWP_Child_Back_Up_Buddy::Instance()->is_backupbuddy_installed ) {
3675
+ $information['syncBackupBuddy'] = MainWP_Child_Back_Up_Buddy::Instance()->get_sync_data();
3676
+ }
3677
+ }
3678
+
3679
+ if ( isset( $othersData['syncWPRocketData'] ) && ( 'yes' === $othersData['syncWPRocketData'] ) ) {
3680
+ $data = array();
3681
+ if ( MainWP_Child_WP_Rocket::isActivated() ) {
3682
+ $boxes = get_user_meta( $GLOBALS['current_user']->ID, 'rocket_boxes', true );
3683
+ $data['rocket_boxes'] = $boxes;
3684
+ }
3685
+ $information['syncWPRocketData'] = $data;
3686
+ }
3687
+
3688
+ if ( isset( $othersData['syncPageSpeedData'] ) && !empty( $othersData['syncPageSpeedData'] ) ) {
3689
+ if ( MainWP_Child_Pagespeed::Instance()->is_plugin_installed ) {
3690
+ $information['syncPageSpeedData'] = MainWP_Child_Pagespeed::Instance()->sync_data();
3691
+ }
3692
+ }
3693
+
3694
+ if ( isset( $othersData['syncBrokenLinksCheckerData'] ) && !empty( $othersData['syncBrokenLinksCheckerData'] ) ) {
3695
+ if ( MainWP_Child_Links_Checker::Instance()->is_plugin_installed ) {
3696
+ $information['syncBrokenLinksCheckerData'] = MainWP_Child_Links_Checker::Instance()->sync_data();
3697
+ }
3698
+ }
3699
+
3700
+ if ( isset( $othersData['syncClientReportData'] ) && !empty( $othersData['syncClientReportData'] ) ) {
3701
+ $creport_sync_data = array();
3702
+ if ( ( $firsttime = get_option( 'mainwp_creport_first_time_activated' ) ) !== false ) {
3703
+ $creport_sync_data['firsttime_activated'] = $firsttime;
3704
+ }
3705
+ if ( !empty( $creport_sync_data ) ) {
3706
+ $information['syncClientReportData'] = $creport_sync_data;
3707
+ }
3708
+ }
3709
+
3710
+ }
3711
+
3712
+ if (isset($_POST['primaryBackup']) && !empty($_POST['primaryBackup'])) {
3713
+ $primary_bk = $_POST['primaryBackup'];
3714
+ $information['primaryLasttimeBackup'] = MainWP_Helper::get_lasttime_backup($primary_bk);
3715
+ }
3716
+
3717
+ $last_post = wp_get_recent_posts( array( 'numberposts' => absint( '1' ) ) );
3718
+ if ( isset( $last_post[0] ) ) {
3719
+ $last_post = $last_post[0];
3720
+ }
3721
+ if ( isset( $last_post ) && isset( $last_post['post_modified_gmt'] ) ) {
3722
+ $information['last_post_gmt'] = strtotime( $last_post['post_modified_gmt'] );
3723
+ }
3724
+ $information['mainwpdir'] = ( MainWP_Helper::validateMainWPDir() ? 1 : - 1 );
3725
+ $information['uniqueId'] = get_option( 'mainwp_child_uniqueId', '' );
3726
+ $information['plugins_outdate_info'] = MainWP_Child_Plugins_Check::Instance()->get_plugins_outdate_info();
3727
+ $information['themes_outdate_info'] = MainWP_Child_Themes_Check::Instance()->get_themes_outdate_info();
3728
+
3729
+ do_action('mainwp_child_site_stats');
3730
+
3731
+ if ( $exit ) {
3732
+ MainWP_Helper::write( $information );
3733
+ }
3734
+
3735
+ return $information;
3736
+ }
3737
+
3738
+ function get_site_icon() {
3739
+ $information = array();
3740
+ $url = $this->get_favicon( true );
3741
+ if ( !empty( $url ) )
3742
+ $information['faviIconUrl'] = $url;
3743
+ MainWP_Helper::write( $information );
3744
+ }
3745
+
3746
+ function get_favicon( $parse_page = false ) {
3747
+
3748
+ $favi_url = '';
3749
+ $favi = ''; // to compatible
3750
+
3751
+ $site_url = get_option( 'siteurl' );
3752
+ if ( substr( $site_url, - 1 ) != '/' ) {
3753
+ $site_url .= '/';
3754
+ }
3755
+
3756
+ if ( function_exists( 'get_site_icon_url' ) && has_site_icon() ) {
3757
+ $favi = $favi_url = get_site_icon_url();
3758
+ }
3759
+
3760
+ if ( empty( $favi ) ) {
3761
+ if ( file_exists( ABSPATH . 'favicon.ico' ) ) {
3762
+ $favi = 'favicon.ico';
3763
+ } else if ( file_exists( ABSPATH . 'favicon.png' ) ) {
3764
+ $favi = 'favicon.png';
3765
+ }
3766
+
3767
+ if ( !empty( $favi ) ) {
3768
+ $favi_url = $site_url . $favi;
3769
+ }
3770
+ }
3771
+
3772
+ if ($parse_page) {
3773
+ // try to parse page
3774
+ if (empty($favi_url)) {
3775
+ $request = wp_remote_get( $site_url, array( 'timeout' => 50 ) );
3776
+ $favi = '';
3777
+ if ( is_array( $request ) && isset( $request['body'] ) ) {
3778
+ // to fix bug
3779
+ $preg_str1 = '/(<link\s+(?:[^\>]*)(?:rel="shortcut\s+icon"\s*)(?:[^>]*)?href="([^"]+)"(?:[^>]*)?>)/is';
3780
+ $preg_str2 = '/(<link\s+(?:[^\>]*)(?:rel="(?:shortcut\s+)?icon"\s*)(?:[^>]*)?href="([^"]+)"(?:[^>]*)?>)/is';
3781
+
3782
+ if ( preg_match( $preg_str1, $request['body'], $matches ) ) {
3783
+ $favi = $matches[2];
3784
+ } else if ( preg_match( $preg_str2, $request['body'], $matches ) ) {
3785
+ $favi = $matches[2];
3786
+ }
3787
+ }
3788
+
3789
+ if ( !empty( $favi ) ){
3790
+ if ( false === strpos( $favi, 'http' ) ) {
3791
+ $favi_url = $site_url . $favi;
3792
+ } else {
3793
+ $favi_url = $favi;
3794
+ }
3795
+ }
3796
+ }
3797
+
3798
+ if ( !empty( $favi_url ) ) {
3799
+ return $favi_url;
3800
+ } else {
3801
+ return false;
3802
+ }
3803
+ } else {
3804
+ return $favi_url;
3805
+ }
3806
+ }
3807
+
3808
+ function scanDir( $pDir, $pLvl ) {
3809
+ $output = array();
3810
+ if ( file_exists( $pDir ) && is_dir( $pDir ) ) {
3811
+ if ( 'logs' === basename( $pDir ) ) {
3812
+ return empty( $output ) ? null : $output;
3813
+ }
3814
+ if ( 0 === $pLvl ) {
3815
+ return empty( $output ) ? null : $output;
3816
+ }
3817
+
3818
+ if ( $files = $this->intScanDir( $pDir ) ) {
3819
+ foreach ( $files as $file ) {
3820
+ if ( ( '.' === $file ) || ( '..' === $file ) ) {
3821
+ continue;
3822
+ }
3823
+ $newDir = $pDir . $file . DIRECTORY_SEPARATOR;
3824
+ if ( @is_dir( $newDir ) ) {
3825
+ $output[ $file ] = $this->scanDir( $newDir, $pLvl - 1, false );
3826
+ }
3827
+ }
3828
+
3829
+ unset( $files );
3830
+ $files = null;
3831
+ }
3832
+ }
3833
+
3834
+ return empty( $output ) ? null : $output;
3835
+ }
3836
+
3837
+ function intScanDir( $dir ) {
3838
+ if ( @is_dir( $dir ) && ( $dh = @opendir( $dir ) ) ) {
3839
+ $cnt = 0;
3840
+ $out = array();
3841
+ while ( ( $file = @readdir( $dh ) ) !== false ) {
3842
+ $newDir = $dir . $file . DIRECTORY_SEPARATOR;
3843
+ if ( ! @is_dir( $newDir ) ) {
3844
+ continue;
3845
+ }
3846
+
3847
+ $out[] = $file;
3848
+ if ( $cnt ++ > 10 ) {
3849
+ return $out;
3850
+ }
3851
+ }
3852
+ @closedir( $dh );
3853
+
3854
+ return $out;
3855
+ }
3856
+
3857
+ return false;
3858
+ }
3859
+
3860
+ function upgrade_get_theme_updates() {
3861
+ $themeUpdates = get_theme_updates();
3862
+ $newThemeUpdates = array();
3863
+ if ( is_array( $themeUpdates ) ) {
3864
+ foreach ( $themeUpdates as $slug => $themeUpdate ) {
3865
+ $newThemeUpdate = array();
3866
+ $newThemeUpdate['update'] = $themeUpdate->update;
3867
+ $newThemeUpdate['Name'] = MainWP_Helper::search( $themeUpdate, 'Name' );
3868
+ $newThemeUpdate['Version'] = MainWP_Helper::search( $themeUpdate, 'Version' );
3869
+ $newThemeUpdates[ $slug ] = $newThemeUpdate;
3870
+ }
3871
+ }
3872
+
3873
+ return $newThemeUpdates;
3874
+ }
3875
+
3876
+ function get_recent_posts( $pAllowedStatuses, $pCount, $type = 'post', $extra = null ) {
3877
+ $allPosts = array();
3878
+ if ( null !== $pAllowedStatuses ) {
3879
+ foreach ( $pAllowedStatuses as $status ) {
3880
+ $this->get_recent_posts_int( $status, $pCount, $type, $allPosts, $extra );
3881
+ }
3882
+ } else {
3883
+ $this->get_recent_posts_int( 'any', $pCount, $type, $allPosts, $extra );
3884
+ }
3885
+
3886
+ return $allPosts;
3887
+ }
3888
+
3889
+ function get_recent_posts_int( $status, $pCount, $type = 'post', &$allPosts, $extra = null ) {
3890
+ $args = array(
3891
+ 'post_status' => $status,
3892
+ 'suppress_filters' => false,
3893
+ 'post_type' => $type,
3894
+ );
3895
+
3896
+ $tokens = array();
3897
+ if ( is_array( $extra ) && isset( $extra['tokens'] ) ) {
3898
+ $tokens = $extra['tokens'];
3899
+ if ( 1 == $extra['extract_post_type'] ) {
3900
+ $args['post_type'] = 'post';
3901
+ } else if ( 2 == $extra['extract_post_type'] ) {
3902
+ $args['post_type'] = 'page';
3903
+ } else if ( 3 == $extra['extract_post_type'] ) {
3904
+ $args['post_type'] = array( 'post', 'page' );
3905
+ }
3906
+ }
3907
+ $tokens = array_flip( $tokens );
3908
+
3909
+ if ( 0 !== $pCount ) {
3910
+ $args['numberposts'] = $pCount;
3911
+ }
3912
+
3913
+ $wp_seo_enabled = false;
3914
+ if ( isset( $_POST['WPSEOEnabled'] ) && $_POST['WPSEOEnabled']) {
3915
+ if (is_plugin_active('wordpress-seo/wp-seo.php') && class_exists('WPSEO_Link_Column_Count') && class_exists('WPSEO_Meta')) {
3916
+ $wp_seo_enabled = true;
3917
+ }
3918
+ }
3919
+
3920
+ $posts = get_posts( $args );
3921
+ if ( is_array( $posts ) ) {
3922
+ if ($wp_seo_enabled) {
3923
+ $post_ids = array();
3924
+ foreach ( $posts as $post ) {
3925
+ $post_ids[] = $post->ID;
3926
+ }
3927
+ $link_count = new WPSEO_Link_Column_Count();
3928
+ $link_count->set( $post_ids );
3929
+ }
3930
+ foreach ( $posts as $post ) {
3931
+ $outPost = array();
3932
+ $outPost['id'] = $post->ID;
3933
+ $outPost['post_type'] = $post->post_type;
3934
+ $outPost['status'] = $post->post_status;
3935
+ $outPost['title'] = $post->post_title;
3936
+ //$outPost['content'] = $post->post_content; // to fix overload memory
3937
+ $outPost['comment_count'] = $post->comment_count;
3938
+ // to support extract urls extension
3939
+ if ( isset( $extra['where_post_date'] ) && !empty( $extra['where_post_date'] ) ) {
3940
+ $outPost['dts'] = strtotime( $post->post_date_gmt );
3941
+ } else {
3942
+ $outPost['dts'] = strtotime( $post->post_modified_gmt );
3943
+ }
3944
+
3945
+ if ($post->post_status == 'future') {
3946
+ $outPost['dts'] = strtotime( $post->post_date_gmt );
3947
+ }
3948
+
3949
+ $usr = get_user_by( 'id', $post->post_author );
3950
+ $outPost['author'] = ! empty( $usr ) ? $usr->user_nicename : 'removed';
3951
+ $categoryObjects = get_the_category( $post->ID );
3952
+ $categories = '';
3953
+ foreach ( $categoryObjects as $cat ) {
3954
+ if ( '' !== $categories ) {
3955
+ $categories .= ', ';
3956
+ }
3957
+ $categories .= $cat->name;
3958
+ }
3959
+ $outPost['categories'] = $categories;
3960
+
3961
+ $tagObjects = get_the_tags( $post->ID );
3962
+ $tags = '';
3963
+ if ( is_array( $tagObjects ) ) {
3964
+ foreach ( $tagObjects as $tag ) {
3965
+ if ( '' !== $tags ) {
3966
+ $tags .= ', ';
3967
+ }
3968
+ $tags .= $tag->name;
3969
+ }
3970
+ }
3971
+ $outPost['tags'] = $tags;
3972
+
3973
+ if ( is_array( $tokens ) ) {
3974
+ if ( isset( $tokens['[post.url]'] ) ) {
3975
+ $outPost['[post.url]'] = get_permalink( $post->ID );
3976
+ }
3977
+ if ( isset( $tokens['[post.website.url]'] ) ) {
3978
+ $outPost['[post.website.url]'] = get_site_url();
3979
+ }
3980
+ if ( isset( $tokens['[post.website.name]'] ) ) {
3981
+ $outPost['[post.website.name]'] = get_bloginfo( 'name' );
3982
+ }
3983
+ }
3984
+
3985
+ if ($wp_seo_enabled) {
3986
+ $post_id = $post->ID;
3987
+ $outPost['seo_data'] = array(
3988
+ 'count_seo_links' => $link_count->get( $post_id, 'internal_link_count' ),
3989
+ 'count_seo_linked' => $link_count->get( $post_id, 'incoming_link_count' ),
3990
+ 'seo_score' => MainWP_Wordpress_SEO::Instance()->parse_column_score($post_id),
3991
+ 'readability_score' => MainWP_Wordpress_SEO::Instance()->parse_column_score_readability($post_id),
3992
+ );
3993
+ }
3994
+
3995
+ $allPosts[] = $outPost;
3996
+ }
3997
+ }
3998
+ }
3999
+
4000
+ function posts_where( $where ) {
4001
+ if ( $this->posts_where_suffix ) {
4002
+ $where .= ' ' . $this->posts_where_suffix;
4003
+ }
4004
+
4005
+ return $where;
4006
+ }
4007
+
4008
+ function get_all_posts() {
4009
+ $post_type = (isset($_POST['post_type']) ? $_POST['post_type'] : 'post');
4010
+ $this->get_all_posts_by_type( $post_type );
4011
+ }
4012
+
4013
+ function get_terms() {
4014
+ $taxonomy = base64_decode( $_POST['taxonomy'] );
4015
+ $rslt = get_terms( taxonomy_exists( $taxonomy ) ? $taxonomy : 'category', 'hide_empty=0' );
4016
+ MainWP_Helper::write( $rslt );
4017
+ }
4018
+
4019
+ function set_terms() {
4020
+ $id = base64_decode( $_POST['id'] );
4021
+ $terms = base64_decode( $_POST['terms'] );
4022
+ $taxonomy = base64_decode( $_POST['taxonomy'] );
4023
+
4024
+ if ( '' !== trim( $terms ) ) {
4025
+ $terms = explode( ',', $terms );
4026
+ if ( count( $terms ) > 0 ) {
4027
+ wp_set_object_terms( $id, array_map( 'intval', $terms ), taxonomy_exists( $taxonomy ) ? $taxonomy : 'category' );
4028
+ }
4029
+ }
4030
+ }
4031
+
4032
+ function insert_comment() {
4033
+ $postId = $_POST['id'];
4034
+ $comments = maybe_unserialize( base64_decode( $_POST['comments'] ) );
4035
+ $ids = array();
4036
+ foreach ( $comments as $comment ) {
4037
+ $ids[] = wp_insert_comment( array(
4038
+ 'comment_post_ID' => $postId,
4039
+ 'comment_author' => $comment['author'],
4040
+ 'comment_content' => $comment['content'],
4041
+ 'comment_date' => $comment['date'],
4042
+ ) );
4043
+ }
4044
+ MainWP_Helper::write( $ids );
4045
+ }
4046
+
4047
+ function get_post_meta() {
4048
+ /** @var $wpdb wpdb */
4049
+ global $wpdb;
4050
+ $postId = $_POST['id'];
4051
+ $keys = base64_decode( unserialize( $_POST['keys'] ) );
4052
+ $meta_value = $_POST['value'];
4053
+
4054
+ $where = '';
4055
+ if ( ! empty( $postId ) ) {
4056
+ $where .= " AND `post_id` = $postId ";
4057
+ }
4058
+ if ( ! empty( $keys ) ) {
4059
+ $str_keys = '\'' . implode( '\',\'', $keys ) . '\'';
4060
+ $where .= " AND `meta_key` IN = $str_keys ";
4061
+ }
4062
+ if ( ! empty( $meta_value ) ) {
4063
+ $where .= " AND `meta_value` = $meta_value ";
4064
+ }
4065
+
4066
+ $results = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM %s WHERE 1 = 1 $where ", $wpdb->postmeta ) );
4067
+ MainWP_Helper::write( $results );
4068
+ }
4069
+
4070
+ function get_total_ezine_post() {
4071
+ /** @var $wpdb wpdb */
4072
+ global $wpdb;
4073
+ $start_date = base64_decode( $_POST['start_date'] );
4074
+ $end_date = base64_decode( $_POST['end_date'] );
4075
+ $keyword_meta = base64_decode( $_POST['keyword_meta'] );
4076
+ $where = ' WHERE ';
4077
+ if ( ! empty( $start_date ) && ! empty( $end_date ) ) {
4078
+ $where .= " p.post_date>='$start_date' AND p.post_date<='$end_date' AND ";
4079
+ } else if ( ! empty( $start_date ) && empty( $end_date ) ) {
4080
+ $where .= " p.post_date='$start_date' AND ";
4081
+ }
4082
+ $where .= " ( p.post_status='publish' OR p.post_status='future' OR p.post_status='draft' )
4083
+ AND (pm.meta_key='_ezine_keyword' AND pm.meta_value='$keyword_meta')";
4084
+ $total = $wpdb->get_var( "SELECT COUNT(*)
4085
+ FROM $wpdb->posts p JOIN $wpdb->postmeta pm ON p.ID=pm.post_id
4086
+ $where " );
4087
+ MainWP_Helper::write( $total );
4088
+ }
4089
+
4090
+ function cancel_scheduled_post() {
4091
+ global $wpdb;
4092
+ $postId = $_POST['post_id'];
4093
+ $cancel_all = $_POST['cancel_all'];
4094
+ $result = false;
4095
+ $information = array();
4096
+ if ( $postId > 0 ) {
4097
+ if ( 'yes' === get_post_meta( $postId, '_is_auto_generate_content', true ) ) {
4098
+ $post = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $wpdb->posts
4099
+ WHERE ID = %d
4100
+ AND post_status = 'future'", $postId ) );
4101
+ if ( $post ) {
4102
+ $result = wp_trash_post( $postId );
4103
+ } else {
4104
+ $result = true;
4105
+ }
4106
+ }
4107
+ if ( ! $result ) {
4108
+ $information['status'] = 'SUCCESS';
4109
+ }
4110
+ } else if ( $cancel_all ) {
4111
+ $post_type = $_POST['post_type'];
4112
+ $where = " WHERE p.post_status='future' AND p.post_type = %s AND pm.meta_key = '_is_auto_generate_content' AND pm.meta_value = 'yes' ";
4113
+ $posts = $wpdb->get_results( $wpdb->prepare( "SELECT p.ID FROM $wpdb->posts p JOIN $wpdb->postmeta pm ON p.ID=pm.post_id $where ", $post_type) );
4114
+ $count = 0;
4115
+ if ( is_array( $posts ) ) {
4116
+ foreach ( $posts as $post ) {
4117
+ if ( $post ) {
4118
+ if ( false !== wp_trash_post( $post->ID ) ) {
4119
+ $count ++;
4120
+
4121
+ }
4122
+ }
4123
+ }
4124
+ } else {
4125
+ $posts = array();
4126
+ }
4127
+
4128
+ $information['status'] = 'SUCCESS';
4129
+ $information['count'] = $count;
4130
+ }
4131
+
4132
+ MainWP_Helper::write( $information );
4133
+ }
4134
+
4135
+ function get_next_time_to_post() {
4136
+ $post_type = $_POST['post_type'];
4137
+ if ( 'post' !== $post_type && 'page' !== $post_type ) {
4138
+ MainWP_Helper::write( array( 'error' => 'Data error.' ) );
4139
+
4140
+ return;
4141
+ }
4142
+ $information = array();
4143
+ try {
4144
+ global $wpdb;
4145
+ $ct = current_time( 'mysql' );
4146
+ $next_post = $wpdb->get_row( $wpdb->prepare( '
4147
+ SELECT *
4148
+ FROM ' . $wpdb->posts . ' p JOIN ' . $wpdb->postmeta . " pm ON p.ID=pm.post_id
4149
+ WHERE
4150
+ pm.meta_key='_is_auto_generate_content' AND
4151
+ pm.meta_value='yes' AND
4152
+ p.post_status='future' AND
4153
+ p.post_type= %s AND
4154
+ p.post_date > NOW()
4155
+ ORDER BY p.post_date
4156
+ LIMIT 1", $post_type) );
4157
+
4158
+ if ( ! $next_post ) {
4159
+ $information['error'] = __( 'No scheduled posts.', 'mainwp-child' );
4160
+ } else {
4161
+ $timestamp = strtotime( $next_post->post_date );
4162
+ $timestamp_gmt = $timestamp - get_option( 'gmt_offset' ) * 60 * 60;
4163
+ $information['next_post_date_timestamp_gmt'] = $timestamp_gmt;
4164
+ $information['next_post_id'] = $next_post->ID;
4165
+ }
4166
+
4167
+ MainWP_Helper::write( $information );
4168
+ } catch ( Exception $e ) {
4169
+ $information['error'] = $e->getMessage();
4170
+ MainWP_Helper::write( $information );
4171
+ }
4172
+ }
4173
+
4174
+ function get_all_pages() {
4175
+ $this->get_all_posts_by_type( 'page' );
4176
+ }
4177
+
4178
+ function get_all_pages_int() {
4179
+ $rslt = $this->get_recent_posts( null, - 1, 'page' );
4180
+
4181
+ return $rslt;
4182
+ }
4183
+
4184
+ function get_all_posts_by_type( $type ) {
4185
+ global $wpdb;
4186
+
4187
+ add_filter( 'posts_where', array( &$this, 'posts_where' ) );
4188
+ $where_post_date = isset($_POST['where_post_date']) && !empty($_POST['where_post_date']) ? true : false;
4189
+ if ( isset( $_POST['postId'] ) ) {
4190
+ $this->posts_where_suffix .= " AND $wpdb->posts.ID = " . $_POST['postId'];
4191
+ } else if ( isset( $_POST['userId'] ) ) {
4192
+ $this->posts_where_suffix .= " AND $wpdb->posts.post_author = " . $_POST['userId'];
4193
+ } else {
4194
+ if ( isset( $_POST['keyword'] ) ) {
4195
+ $search_on = isset($_POST['search_on']) ? $_POST['search_on'] : '';
4196
+ if ($search_on == 'title') {
4197
+ $this->posts_where_suffix .= " AND ( $wpdb->posts.post_title LIKE '%" . $_POST['keyword'] . "%' )";
4198
+ } else if ($search_on == 'content') {
4199
+ $this->posts_where_suffix .= " AND ($wpdb->posts.post_content LIKE '%" . $_POST['keyword'] . "%' )";
4200
+ } else {
4201
+ $this->posts_where_suffix .= " AND ($wpdb->posts.post_content LIKE '%" . $_POST['keyword'] . "%' OR $wpdb->posts.post_title LIKE '%" . $_POST['keyword'] . "%' )";
4202
+ }
4203
+ }
4204
+ if ( isset( $_POST['dtsstart'] ) && '' !== $_POST['dtsstart'] ) {
4205
+ if ($where_post_date) {
4206
+ $this->posts_where_suffix .= " AND $wpdb->posts.post_date > '" . $_POST['dtsstart'] . "'";
4207
+ } else {
4208
+ $this->posts_where_suffix .= " AND $wpdb->posts.post_modified > '" . $_POST['dtsstart'] . "'";
4209
+ }
4210
+ }
4211
+ if ( isset( $_POST['dtsstop'] ) && '' !== $_POST['dtsstop'] ) {
4212
+ if ($where_post_date) {
4213
+ $this->posts_where_suffix .= " AND $wpdb->posts.post_date < '" . $_POST['dtsstop'] . "'";
4214
+ } else {
4215
+ $this->posts_where_suffix .= " AND $wpdb->posts.post_modified < '" . $_POST['dtsstop'] . "'";
4216
+ }
4217
+ }
4218
+
4219
+ if ( isset( $_POST['exclude_page_type'] ) && $_POST['exclude_page_type'] ) {
4220
+ $this->posts_where_suffix .= " AND $wpdb->posts.post_type NOT IN ('page')";
4221
+ }
4222
+ }
4223
+
4224
+ $maxPages = MAINWP_CHILD_NR_OF_PAGES;
4225
+ if ( isset( $_POST['maxRecords'] ) ) {
4226
+ $maxPages = $_POST['maxRecords'];
4227
+ }
4228
+ if ( 0 === $maxPages ) {
4229
+ $maxPages = 99999;
4230
+ }
4231
+
4232
+ $extra = array();
4233
+ if ( isset( $_POST['extract_tokens'] ) ) {
4234
+ $extra['tokens'] = maybe_unserialize( base64_decode( $_POST['extract_tokens'] ) );
4235
+ $extra['extract_post_type'] = $_POST['extract_post_type'];
4236
+ }
4237
+
4238
+ $extra['where_post_date'] = $where_post_date;
4239
+ $rslt = $this->get_recent_posts( explode( ',', $_POST['status'] ), $maxPages, $type, $extra );
4240
+ $this->posts_where_suffix = '';
4241
+
4242
+ MainWP_Helper::write( $rslt );
4243
+ }
4244
+
4245
+ function comments_clauses( $clauses ) {
4246
+ if ( $this->comments_and_clauses ) {
4247
+ $clauses['where'] .= ' ' . $this->comments_and_clauses;
4248
+ }
4249
+
4250
+ return $clauses;
4251
+ }
4252
+
4253
+ function get_all_comments() {
4254
+ global $wpdb;
4255
+
4256
+ add_filter( 'comments_clauses', array( &$this, 'comments_clauses' ) );
4257
+
4258
+ if ( isset( $_POST['postId'] ) ) {
4259
+ $this->comments_and_clauses .= " AND $wpdb->comments.comment_post_ID = " . $_POST['postId'];
4260
+ } else {
4261
+ if ( isset( $_POST['keyword'] ) ) {
4262
+ $this->comments_and_clauses .= " AND $wpdb->comments.comment_content LIKE '%" . $_POST['keyword'] . "%'";
4263
+ }
4264
+ if ( isset( $_POST['dtsstart'] ) && '' !== $_POST['dtsstart'] ) {
4265
+ $this->comments_and_clauses .= " AND $wpdb->comments.comment_date > '" . $_POST['dtsstart'] . "'";
4266
+ }
4267
+ if ( isset( $_POST['dtsstop'] ) && '' !== $_POST['dtsstop'] ) {
4268
+ $this->comments_and_clauses .= " AND $wpdb->comments.comment_date < '" . $_POST['dtsstop'] . "'";
4269
+ }
4270
+ }
4271
+
4272
+ $maxComments = MAINWP_CHILD_NR_OF_COMMENTS;
4273
+ if ( isset( $_POST['maxRecords'] ) ) {
4274
+ $maxComments = $_POST['maxRecords'];
4275
+ }
4276
+
4277
+ if ( 0 === $maxComments ) {
4278
+ $maxComments = 99999;
4279
+ }
4280
+
4281
+ $rslt = $this->get_recent_comments( explode( ',', $_POST['status'] ), $maxComments );
4282
+ $this->comments_and_clauses = '';
4283
+
4284
+ MainWP_Helper::write( $rslt );
4285
+ }
4286
+
4287
+ function get_recent_comments( $pAllowedStatuses, $pCount ) {
4288
+ if ( ! function_exists( 'get_comment_author_url' ) ) {
4289
+ include_once( WPINC . '/comment-template.php' );
4290
+ }
4291
+ $allComments = array();
4292
+
4293
+ foreach ( $pAllowedStatuses as $status ) {
4294
+ $params = array( 'status' => $status );
4295
+ if ( 0 !== $pCount ) {
4296
+ $params['number'] = $pCount;
4297
+ }
4298
+ $comments = get_comments( $params );
4299
+ if ( is_array( $comments ) ) {
4300
+ foreach ( $comments as $comment ) {
4301
+ $post = get_post( $comment->comment_post_ID );
4302
+ $outComment = array();
4303
+ $outComment['id'] = $comment->comment_ID;
4304
+ $outComment['status'] = wp_get_comment_status( $comment->comment_ID );
4305
+ $outComment['author'] = $comment->comment_author;
4306
+ $outComment['author_url'] = get_comment_author_url( $comment->comment_ID );
4307
+ $outComment['author_ip'] = get_comment_author_IP( $comment->comment_ID );
4308
+ $outComment['author_email'] = $email = apply_filters( 'comment_email', $comment->comment_author_email );
4309
+ if ( ( ! empty( $outComment['author_email'] ) ) && ( '@' !== $outComment['author_email'] ) ) {
4310
+ $outComment['author_email'] = '<a href="mailto:' . $outComment['author_email'] . '">' . $outComment['author_email'] . '</a>';
4311
+ }
4312
+ $outComment['postId'] = $comment->comment_post_ID;
4313
+ $outComment['postName'] = $post->post_title;
4314
+ $outComment['comment_count'] = $post->comment_count;
4315
+ $outComment['content'] = $comment->comment_content;
4316
+ $outComment['dts'] = strtotime( $comment->comment_date_gmt );
4317
+ $allComments[] = $outComment;
4318
+ }
4319
+ }
4320
+ }
4321
+
4322
+ return $allComments;
4323
+ }
4324
+
4325
+ function theme_action() {
4326
+ //Read form data
4327
+ $action = $_POST['action'];
4328
+ $theme = $_POST['theme'];
4329
+
4330
+ if ( 'activate' === $action ) {
4331
+ include_once( ABSPATH . '/wp-admin/includes/theme.php' );
4332
+ $theTheme = get_theme( $theme );
4333
+ if ( null !== $theTheme && '' !== $theTheme ) {
4334
+ switch_theme( $theTheme['Template'], $theTheme['Stylesheet'] );
4335
+ }
4336
+ } else if ( 'delete' === $action ) {
4337
+ include_once( ABSPATH . '/wp-admin/includes/theme.php' );
4338
+ // if (file_exists(ABSPATH . '/wp-admin/includes/deprecated.php')) include_once(ABSPATH . '/wp-admin/includes/deprecated.php');
4339
+ if ( file_exists( ABSPATH . '/wp-admin/includes/screen.php' ) ) {
4340
+ include_once( ABSPATH . '/wp-admin/includes/screen.php' );
4341
+ }
4342
+ include_once( ABSPATH . '/wp-admin/includes/file.php' );
4343
+ include_once( ABSPATH . '/wp-admin/includes/template.php' );
4344
+ include_once( ABSPATH . '/wp-admin/includes/misc.php' );
4345
+ include_once( ABSPATH . '/wp-admin/includes/class-wp-upgrader.php' );
4346
+ include_once( ABSPATH . '/wp-admin/includes/class-wp-filesystem-base.php' );
4347
+ include_once( ABSPATH . '/wp-admin/includes/class-wp-filesystem-direct.php' );
4348
+
4349
+ $wp_filesystem = $this->getWPFilesystem();
4350
+ if ( empty( $wp_filesystem ) ) {
4351
+ $wp_filesystem = new WP_Filesystem_Direct( null );
4352
+ }
4353
+ $themeUpgrader = new Theme_Upgrader();
4354
+
4355
+ $theme_name = wp_get_theme()->get( 'Name' );
4356
+ $themes = explode( '||', $theme );
4357
+
4358
+ if (count($themes) == 1) {
4359
+ $themeToDelete = current($themes);
4360
+ if ( $themeToDelete == $theme_name ) {
4361
+ $information['error'] = 'IsActivatedTheme';
4362
+ MainWP_Helper::write( $information );
4363
+ return;
4364
+ }
4365
+ }
4366
+
4367
+ foreach ( $themes as $idx => $themeToDelete ) {
4368
+ if ( $themeToDelete !== $theme_name ) {
4369
+ $theTheme = get_theme( $themeToDelete );
4370
+ if ( null !== $theTheme && '' !== $theTheme ) {
4371
+ $tmp['theme'] = $theTheme['Template'];
4372
+ if ( true === $themeUpgrader->delete_old_theme( null, null, null, $tmp ) ) {
4373
+ $args = array( 'action' => 'delete', 'Name' => $theTheme['Name'] );
4374
+ do_action( 'mainwp_child_theme_action', $args );
4375
+ }
4376
+ }
4377
+ }
4378
+ }
4379
+ } else {
4380
+ $information['status'] = 'FAIL';
4381
+ }
4382
+
4383
+ if ( ! isset( $information['status'] ) ) {
4384
+ $information['status'] = 'SUCCESS';
4385
+ }
4386
+ $information['sync'] = $this->getSiteStats( array(), false );
4387
+ MainWP_Helper::write( $information );
4388
+ }
4389
+
4390
+ function get_all_themes() {
4391
+ $keyword = $_POST['keyword'];
4392
+ $status = $_POST['status'];
4393
+ $filter = isset( $_POST['filter'] ) ? $_POST['filter'] : true;
4394
+ $rslt = $this->get_all_themes_int( $filter, $keyword, $status );
4395
+
4396
+ MainWP_Helper::write( $rslt );
4397
+ }
4398
+
4399
+ function get_all_themes_int( $filter, $keyword = '', $status = '' ) {
4400
+ $rslt = array();
4401
+ $themes = wp_get_themes();
4402
+
4403
+ if ( is_array( $themes ) ) {
4404
+ $theme_name = wp_get_theme()->get( 'Name' );
4405
+
4406
+ /** @var $theme WP_Theme */
4407
+ foreach ( $themes as $theme ) {
4408
+ $out = array();
4409
+ $out['name'] = $theme->get( 'Name' );
4410
+ $out['title'] = $theme->display( 'Name', true, false );
4411
+ $out['description'] = $theme->display( 'Description', true, false );
4412
+ $out['version'] = $theme->display( 'Version', true, false );
4413
+ $out['active'] = ( $theme->get( 'Name' ) === $theme_name ) ? 1 : 0;
4414
+ $out['slug'] = $theme->get_stylesheet();
4415
+ if ( ! $filter ) {
4416
+ if ( '' == $keyword || stristr( $out['title'], $keyword ) ) {
4417
+ $rslt[] = $out;
4418
+ }
4419
+ } else if ( $out['active'] === ( ( 'active' === $status ) ? 1 : 0 ) ) {
4420
+ if ( '' == $keyword || stristr( $out['title'], $keyword ) ) {
4421
+ $rslt[] = $out;
4422
+ }
4423
+ }
4424
+ }
4425
+ }
4426
+
4427
+ return $rslt;
4428
+ }
4429
+
4430
+ function plugin_action() {
4431
+ //Read form data
4432
+ $action = $_POST['action'];
4433
+ $plugins = explode( '||', $_POST['plugin'] );
4434
+
4435
+ if ( 'activate' === $action ) {
4436
+ include_once( ABSPATH . '/wp-admin/includes/plugin.php' );
4437
+
4438
+ foreach ( $plugins as $idx => $plugin ) {
4439
+ if ( $plugin !== $this->plugin_slug ) {
4440
+ $thePlugin = get_plugin_data( $plugin );
4441
+ if ( null !== $thePlugin && '' !== $thePlugin ) {
4442
+ // to fix activate issue
4443
+ if ('quotes-collection/quotes-collection.php' == $plugin) {
4444
+ activate_plugin( $plugin, '', false, true );
4445
+ do_action( 'activate_plugin', $plugin, null );
4446
+ } else {
4447
+ activate_plugin( $plugin );
4448
+ }
4449
+ }
4450
+ }
4451
+ }
4452
+ } else if ( 'deactivate' === $action ) {
4453
+ include_once( ABSPATH . '/wp-admin/includes/plugin.php' );
4454
+
4455
+ foreach ( $plugins as $idx => $plugin ) {
4456
+ if ( $plugin !== $this->plugin_slug ) {
4457
+ $thePlugin = get_plugin_data( $plugin );
4458
+ if ( null !== $thePlugin && '' !== $thePlugin ) {
4459
+ deactivate_plugins( $plugin );
4460
+ }
4461
+ }
4462
+ }
4463
+ } else if ( 'delete' === $action ) {
4464
+ include_once( ABSPATH . '/wp-admin/includes/plugin.php' );
4465
+ // if (file_exists(ABSPATH . '/wp-admin/includes/deprecated.php')) include_once(ABSPATH . '/wp-admin/includes/deprecated.php');
4466
+ if ( file_exists( ABSPATH . '/wp-admin/includes/screen.php' ) ) {
4467
+ include_once( ABSPATH . '/wp-admin/includes/screen.php' );
4468
+ }
4469
+ include_once( ABSPATH . '/wp-admin/includes/file.php' );
4470
+ include_once( ABSPATH . '/wp-admin/includes/template.php' );
4471
+ include_once( ABSPATH . '/wp-admin/includes/misc.php' );
4472
+ include_once( ABSPATH . '/wp-admin/includes/class-wp-upgrader.php' );
4473
+ include_once( ABSPATH . '/wp-admin/includes/class-wp-filesystem-base.php' );
4474
+ include_once( ABSPATH . '/wp-admin/includes/class-wp-filesystem-direct.php' );
4475
+
4476
+ $wp_filesystem = $this->getWPFilesystem();
4477
+ if ( null === $wp_filesystem ) {
4478
+ $wp_filesystem = new WP_Filesystem_Direct( null );
4479
+ }
4480
+ $pluginUpgrader = new Plugin_Upgrader();
4481
+
4482
+ $all_plugins = get_plugins();
4483
+ foreach ( $plugins as $idx => $plugin ) {
4484
+ if ( $plugin !== $this->plugin_slug ) {
4485
+ if ( isset( $all_plugins[ $plugin ] ) ) {
4486
+ if (is_plugin_active($plugin)) {
4487
+ $thePlugin = get_plugin_data( $plugin );
4488
+ if ( null !== $thePlugin && '' !== $thePlugin ) {
4489
+ deactivate_plugins( $plugin );
4490
+ }
4491
+ }
4492
+ $tmp['plugin'] = $plugin;
4493
+ if ( true === $pluginUpgrader->delete_old_plugin( null, null, null, $tmp ) ) {
4494
+ $args = array( 'action' => 'delete', 'Name' => $all_plugins[ $plugin ]['Name'] );
4495
+ do_action( 'mainwp_child_plugin_action', $args );
4496
+ }
4497
+ }
4498
+ }
4499
+ }
4500
+ } else {
4501
+ $information['status'] = 'FAIL';
4502
+ }
4503
+
4504
+ if ( ! isset( $information['status'] ) ) {
4505
+ $information['status'] = 'SUCCESS';
4506
+ }
4507
+ $information['sync'] = $this->getSiteStats( array(), false );
4508
+ MainWP_Helper::write( $information );
4509
+ }
4510
+
4511
+ function get_all_plugins() {
4512
+ $keyword = $_POST['keyword'];
4513
+ $status = $_POST['status'];
4514
+ $filter = isset( $_POST['filter'] ) ? $_POST['filter'] : true;
4515
+ $rslt = $this->get_all_plugins_int( $filter, $keyword, $status );
4516
+
4517
+ MainWP_Helper::write( $rslt );
4518
+ }
4519
+
4520
+ function get_all_plugins_int( $filter, $keyword = '', $status = '' ) {
4521
+ if ( ! function_exists( 'get_plugins' ) ) {
4522
+ include_once( ABSPATH . 'wp-admin/includes/plugin.php' );
4523
+ }
4524
+ $rslt = array();
4525
+ $plugins = get_plugins();
4526
+ if ( is_array( $plugins ) ) {
4527
+ $active_plugins = get_option( 'active_plugins' );
4528
+
4529
+ foreach ( $plugins as $pluginslug => $plugin ) {
4530
+ $out = array();
4531
+ $out['mainwp'] = ($pluginslug == $this->plugin_slug ? 'T' : 'F');
4532
+ $out['name'] = $plugin['Name'];
4533
+ $out['slug'] = $pluginslug;
4534
+ $out['description'] = $plugin['Description'];
4535
+ $out['version'] = $plugin['Version'];
4536
+ $out['active'] = is_plugin_active($pluginslug) ? 1 : 0; // ( is_array( $active_plugins ) && in_array( $pluginslug, $active_plugins ) ) ? 1 : 0; // to fix for multisites
4537
+ if ( ! $filter ) {
4538
+ if ( '' == $keyword || stristr( $out['name'], $keyword ) ) {
4539
+ $rslt[] = $out;
4540
+ }
4541
+ } else if ( $out['active'] == ( ( $status == 'active' ) ? 1 : 0 ) ) {
4542
+ if ( '' == $keyword || stristr( $out['name'], $keyword ) ) {
4543
+ $rslt[] = $out;
4544
+ }
4545
+ }
4546
+ }
4547
+ }
4548
+
4549
+ $muplugins = get_mu_plugins();
4550
+ if ( is_array( $muplugins ) ) {
4551
+ foreach ( $muplugins as $pluginslug => $plugin ) {
4552
+ $out = array();
4553
+ $out['mainwp'] = ($pluginslug == $this->plugin_slug ? 'T' : 'F');
4554
+ $out['name'] = $plugin['Name'];
4555
+ $out['slug'] = $pluginslug;
4556
+ $out['description'] = $plugin['Description'];
4557
+ $out['version'] = $plugin['Version'];
4558
+ $out['active'] = 1;
4559
+ $out['mu'] = 1;
4560
+ if ( ! $filter ) {
4561
+ if ( '' == $keyword || stristr( $out['name'], $keyword ) ) {
4562
+ $rslt[] = $out;
4563
+ }
4564
+ } else if ( $out['active'] == ( ( $status == 'active' ) ? 1 : 0 ) ) {
4565
+ if ( '' == $keyword || stristr( $out['name'], $keyword ) ) {
4566
+ $rslt[] = $out;
4567
+ }
4568
+ }
4569
+ }
4570
+ }
4571
+
4572
+ return $rslt;
4573
+ }
4574
+
4575
+ function get_all_users($return = false) {
4576
+ $roles = explode( ',', $_POST['role'] );
4577
+ $allusers = array();
4578
+ if ( is_array( $roles ) ) {
4579
+ foreach ( $roles as $role ) {
4580
+ $new_users = get_users( 'role=' . $role );
4581
+ // $allusers[$role] = array();
4582
+ foreach ( $new_users as $new_user ) {
4583
+ $usr = array();
4584
+ $usr['id'] = $new_user->ID;
4585
+ $usr['login'] = $new_user->user_login;
4586
+ $usr['nicename'] = $new_user->user_nicename;
4587
+ $usr['email'] = $new_user->user_email;
4588
+ $usr['registered'] = $new_user->user_registered;
4589
+ $usr['status'] = $new_user->user_status;
4590
+ $usr['display_name'] = $new_user->display_name;
4591
+ $usr['role'] = $role;
4592
+ $usr['post_count'] = count_user_posts( $new_user->ID );
4593
+ $usr['avatar'] = get_avatar( $new_user->ID, 32 );
4594
+ $allusers[] = $usr;
4595
+ }
4596
+ }
4597
+ }
4598
+ if ($return)
4599
+ return $allusers;
4600
+ MainWP_Helper::write( $allusers );
4601
+ }
4602
+
4603
+ function get_all_users_int($number = false) {
4604
+ $allusers = array();
4605
+
4606
+ $params = array();
4607
+ if ($number)
4608
+ $params['number'] = $number;
4609
+
4610
+ $new_users = get_users($params);
4611
+ if ( is_array( $new_users ) ) {
4612
+ foreach ( $new_users as $new_user ) {
4613
+ $usr = array();
4614
+ $usr['id'] = $new_user->ID;
4615
+ $usr['login'] = $new_user->user_login;
4616
+ $usr['nicename'] = $new_user->user_nicename;
4617
+ $usr['email'] = $new_user->user_email;
4618
+ $usr['registered'] = $new_user->user_registered;
4619
+ $usr['status'] = $new_user->user_status;
4620
+ $usr['display_name'] = $new_user->display_name;
4621
+ $userdata = get_userdata( $new_user->ID );
4622
+ $user_roles = $userdata->roles;
4623
+ $user_role = array_shift( $user_roles );
4624
+ $usr['role'] = $user_role;
4625
+ $usr['post_count'] = count_user_posts( $new_user->ID );
4626
+ $allusers[] = $usr;
4627
+ }
4628
+ }
4629
+
4630
+ return $allusers;
4631
+ }
4632
+
4633
+ function search_users() {
4634
+
4635
+ $search_user_role = array();
4636
+ $check_users_role = false;
4637
+
4638
+ if (isset($_POST['role']) && !empty($_POST['role'])) {
4639
+ $check_users_role = true;
4640
+ $all_users_role = $this->get_all_users(true);
4641
+ foreach($all_users_role as $user) {
4642
+ $search_user_role[] = $user['id'];
4643
+ }
4644
+ unset($all_users_role);
4645
+ }
4646
+
4647
+ $columns = explode( ',', $_POST['search_columns'] );
4648
+ $allusers = array();
4649
+ $exclude = array();
4650
+
4651
+ foreach ( $columns as $col ) {
4652
+ if ( empty( $col ) ) {
4653
+ continue;
4654
+ }
4655
+
4656
+ $user_query = new WP_User_Query( array(
4657
+ 'search' => $_POST['search'],
4658
+ 'fields' => 'all_with_meta',
4659
+ 'search_columns' => array( $col ),
4660
+ 'query_orderby' => array( $col ),
4661
+ 'exclude' => $exclude,
4662
+ ) );
4663
+ if ( ! empty( $user_query->results ) ) {
4664
+ foreach ( $user_query->results as $new_user ) {
4665
+ if ($check_users_role) {
4666
+ if (!in_array($new_user->ID, $search_user_role )){
4667
+ continue;
4668
+ }
4669
+ }
4670
+ $exclude[] = $new_user->ID;
4671
+ $usr = array();
4672
+ $usr['id'] = $new_user->ID;
4673
+ $usr['login'] = $new_user->user_login;
4674
+ $usr['nicename'] = $new_user->user_nicename;
4675
+ $usr['email'] = $new_user->user_email;
4676
+ $usr['registered'] = $new_user->user_registered;
4677
+ $usr['status'] = $new_user->user_status;
4678
+ $usr['display_name'] = $new_user->display_name;
4679
+ $userdata = get_userdata( $new_user->ID );
4680
+ $user_roles = $userdata->roles;
4681
+ $user_role = array_shift( $user_roles );
4682
+ $usr['role'] = $user_role;
4683
+ $usr['post_count'] = count_user_posts( $new_user->ID );
4684
+ $usr['avatar'] = get_avatar( $new_user->ID, 32 );
4685
+ $allusers[] = $usr;
4686
+ }
4687
+ }
4688
+ }
4689
+
4690
+ MainWP_Helper::write( $allusers );
4691
+ }
4692
+
4693
+ //Show stats without login - only allowed while no account is added yet
4694
+ function getSiteStatsNoAuth( $information = array() ) {
4695
+ if ( get_option( 'mainwp_child_pubkey' ) ) {
4696
+ $hint = '<br/>' . __('Hint: Go to the child site, deactivate and reactivate the MainWP Child plugin and try again.', 'mainwp-child');
4697
+ MainWP_Helper::error(__('This site already contains a link. Please deactivate and reactivate the MainWP plugin.','mainwp-child') . $hint);
4698
+ }
4699
+
4700
+ global $wp_version;
4701
+ $information['version'] = self::$version;
4702
+ $information['wpversion'] = $wp_version;
4703
+ $information['wpe'] = function_exists( 'is_wpe' ) ? 1 : 0;
4704
+ MainWP_Helper::write( $information );
4705
+ }
4706
+
4707
+ //Deactivating the plugin
4708
+ function deactivate() {
4709
+ include_once( ABSPATH . 'wp-admin/includes/plugin.php' );
4710
+ deactivate_plugins( $this->plugin_slug, true );
4711
+ $information = array();
4712
+ if ( is_plugin_active( $this->plugin_slug ) ) {
4713
+ MainWP_Helper::error( 'Plugin still active' );
4714
+ }
4715
+ $information['deactivated'] = true;
4716
+ MainWP_Helper::write( $information );
4717
+ }
4718
+
4719
+ function activation() {
4720
+ $to_delete = array(
4721
+ 'mainwp_child_pubkey',
4722
+ 'mainwp_child_nonce',
4723
+ 'mainwp_child_nossl',
4724
+ 'mainwp_child_nossl_key',
4725
+ );
4726
+ foreach ( $to_delete as $delete ) {
4727
+ if ( get_option( $delete ) ) {
4728
+ delete_option( $delete );
4729
+ }
4730
+ }
4731
+
4732
+ MainWP_Helper::update_option( 'mainwp_child_activated_once', true );
4733
+
4734
+ // delete bad data if existed
4735
+ $to_delete = array( 'mainwp_ext_snippets_enabled', 'mainwp_ext_code_snippets' );
4736
+ foreach ( $to_delete as $delete ) {
4737
+ delete_option( $delete );
4738
+ }
4739
+ }
4740
+
4741
+ function deactivation() {
4742
+ $to_delete = array(
4743
+ 'mainwp_child_pubkey',
4744
+ 'mainwp_child_nonce',
4745
+ 'mainwp_child_nossl',
4746
+ 'mainwp_child_nossl_key',
4747
+ 'mainwp_security',
4748
+ 'mainwp_child_server',
4749
+ );
4750
+ $to_delete[] = 'mainwp_ext_snippets_enabled';
4751
+ $to_delete[] = 'mainwp_ext_code_snippets';
4752
+
4753
+ foreach ( $to_delete as $delete ) {
4754
+ if ( get_option( $delete ) ) {
4755
+ delete_option( $delete );
4756
+ wp_cache_delete( $delete, 'options' );
4757
+ }
4758
+ }
4759
+ do_action( 'mainwp_child_deactivation' );
4760
+ }
4761
+
4762
+ function getWPFilesystem() {
4763
+ global $wp_filesystem;
4764
+
4765
+ if ( empty( $wp_filesystem ) ) {
4766
+ ob_start();
4767
+ // if (file_exists(ABSPATH . '/wp-admin/includes/deprecated.php')) include_once(ABSPATH . '/wp-admin/includes/deprecated.php');
4768
+ if ( file_exists( ABSPATH . '/wp-admin/includes/screen.php' ) ) {
4769
+ include_once( ABSPATH . '/wp-admin/includes/screen.php' );
4770
+ }
4771
+ if ( file_exists( ABSPATH . '/wp-admin/includes/template.php' ) ) {
4772
+ include_once( ABSPATH . '/wp-admin/includes/template.php' );
4773
+ }
4774
+ $creds = request_filesystem_credentials( 'test', '', false, false, $extra_fields = null );
4775
+ ob_end_clean();
4776
+ if ( empty( $creds ) ) {
4777
+ define( 'FS_METHOD', 'direct' );
4778
+ }
4779
+ WP_Filesystem( $creds );
4780
+ }
4781
+
4782
+ if ( empty( $wp_filesystem ) ) {
4783
+ MainWP_Helper::error( $this->FTP_ERROR );
4784
+ } else if ( is_wp_error( $wp_filesystem->errors ) ) {
4785
+ $errorCodes = $wp_filesystem->errors->get_error_codes();
4786
+ if ( ! empty( $errorCodes ) ) {
4787
+ MainWP_Helper::error( __( 'WordPress Filesystem error: ', 'mainwp-child' ) . $wp_filesystem->errors->get_error_message() );
4788
+ }
4789
+ }
4790
+
4791
+ return $wp_filesystem;
4792
+ }
4793
+
4794
+ function getTotalFileSize( $directory = WP_CONTENT_DIR ) {
4795
+ try {
4796
+ // function continueFileSize( $dir, $limit ) {
4797
+ // $dirs = array( $dir );
4798
+ // $cnt = 0;
4799
+ // while ( isset( $dirs[0] ) ) {
4800
+ // $path = array_shift( $dirs );
4801
+ // if ( stristr( $path, WP_CONTENT_DIR . '/uploads/mainwp' ) ) {
4802
+ // continue;
4803
+ // }
4804
+ // $uploadDir = MainWP_Helper::getMainWPDir();
4805
+ // $uploadDir = $uploadDir[0];
4806
+ // if ( stristr( $path, $uploadDir ) ) {
4807
+ // continue;
4808
+ // }
4809
+ // $res = @glob( $path . '/*' );
4810
+ // if ( is_array( $res ) ) {
4811
+ // foreach ( $res as $next ) {
4812
+ // if ( is_dir( $next ) ) {
4813
+ // $dirs[] = $next;
4814
+ // } else {
4815
+ // if ($cnt++ > $limit) return false;;
4816
+ // }
4817
+ // }
4818
+ // }
4819
+ // }
4820
+ // return true;
4821
+ // }
4822
+ //
4823
+ // if ( !continueFilesize( $directory, 20000 ) ) return 0;
4824
+
4825
+ if ( MainWP_Helper::function_exists( 'popen' ) ) {
4826
+ $uploadDir = MainWP_Helper::getMainWPDir();
4827
+ $uploadDir = $uploadDir[0];
4828
+ $popenHandle = @popen( 'du -s ' . $directory . ' --exclude "' . str_replace( ABSPATH, '', $uploadDir ) . '"', 'r' );
4829
+ if ( 'resource' === gettype( $popenHandle ) ) {
4830
+ $size = @fread( $popenHandle, 1024 );
4831
+ @pclose( $popenHandle );
4832
+ $size = substr( $size, 0, strpos( $size, "\t" ) );
4833
+ if ( $size && MainWP_Helper::ctype_digit( $size ) ) {
4834
+ return $size / 1024;
4835
+ }
4836
+ }
4837
+ }
4838
+
4839
+ if ( MainWP_Helper::function_exists( 'shell_exec' ) ) {
4840
+ $uploadDir = MainWP_Helper::getMainWPDir();
4841
+ $uploadDir = $uploadDir[0];
4842
+ $size = @shell_exec( 'du -s ' . $directory . ' --exclude "' . str_replace( ABSPATH, '', $uploadDir ) . '"' );
4843
+ if ( null !== $size ) {
4844
+ $size = substr( $size, 0, strpos( $size, "\t" ) );
4845
+ if ( $size && MainWP_Helper::ctype_digit( $size ) ) {
4846
+ return $size / 1024;
4847
+ }
4848
+ }
4849
+ }
4850
+ if ( class_exists( 'COM' ) ) {
4851
+ $obj = new COM( 'scripting.filesystemobject' );
4852
+
4853
+ if ( is_object( $obj ) ) {
4854
+ $ref = $obj->getfolder( $directory );
4855
+
4856
+ $size = $ref->size;
4857
+
4858
+ $obj = null;
4859
+ if ( MainWP_Helper::ctype_digit( $size ) ) {
4860
+ return $size / 1024;
4861
+ }
4862
+ }
4863
+ }
4864
+ // to fix for window host, performance not good?
4865
+ if ( class_exists( 'RecursiveIteratorIterator' ) ) {
4866
+ $size = 0;
4867
+ foreach(new RecursiveIteratorIterator(new RecursiveDirectoryIterator($directory)) as $file){
4868
+ $size+=$file->getSize();
4869
+ }
4870
+ if ( $size && MainWP_Helper::ctype_digit( $size ) ) {
4871
+ return $size / 1024 / 1024;
4872
+ }
4873
+ }
4874
+
4875
+ // function dirsize( $dir ) {
4876
+ // $dirs = array( $dir );
4877
+ // $size = 0;
4878
+ // while ( isset( $dirs[0] ) ) {
4879
+ // $path = array_shift( $dirs );
4880
+ // if ( stristr( $path, WP_CONTENT_DIR . '/uploads/mainwp' ) ) {
4881
+ // continue;
4882
+ // }
4883
+ // $uploadDir = MainWP_Helper::getMainWPDir();
4884
+ // $uploadDir = $uploadDir[0];
4885
+ // if ( stristr( $path, $uploadDir ) ) {
4886
+ // continue;
4887
+ // }
4888
+ // $res = @glob( $path . '/*' );
4889
+ // if ( is_array( $res ) ) {
4890
+ // foreach ( $res as $next ) {
4891
+ // if ( is_dir( $next ) ) {
4892
+ // $dirs[] = $next;
4893
+ // } else {
4894
+ // $fs = filesize( $next );
4895
+ // $size += $fs;
4896
+ // }
4897
+ // }
4898
+ // }
4899
+ // }
4900
+ //
4901
+ // return $size / 1024 / 1024;
4902
+ // }
4903
+ //
4904
+ // return dirsize( $directory );
4905
+ return 0;
4906
+ } catch ( Exception $e ) {
4907
+ return 0;
4908
+ }
4909
+ }
4910
+
4911
+ function serverInformation() {
4912
+ @ob_start();
4913
+ MainWP_Child_Server_Information::render();
4914
+ $output['information'] = @ob_get_contents();
4915
+ @ob_end_clean();
4916
+ @ob_start();
4917
+ MainWP_Child_Server_Information::renderCron();
4918
+ $output['cron'] = @ob_get_contents();
4919
+ @ob_end_clean();
4920
+ @ob_start();
4921
+ MainWP_Child_Server_Information::renderErrorLogPage();
4922
+ $output['error'] = @ob_get_contents();
4923
+ @ob_end_clean();
4924
+ @ob_start();
4925
+ MainWP_Child_Server_Information::renderWPConfig();
4926
+ $output['wpconfig'] = @ob_get_contents();
4927
+ @ob_end_clean();
4928
+ @ob_start();
4929
+ MainWP_Child_Server_Information::renderhtaccess();
4930
+ $output['htaccess'] = @ob_get_contents();
4931
+ @ob_end_clean();
4932
+
4933
+ MainWP_Helper::write( $output );
4934
+ }
4935
+
4936
+ function maintenance_site() {
4937
+ global $wpdb;
4938
+ $information = array();
4939
+ if ( isset( $_POST['action'] ) ) {
4940
+ if ( 'save_settings' === $_POST['action'] ) {
4941
+
4942
+ if ( isset( $_POST['enable_alert'] ) && '1' === $_POST['enable_alert'] ) {
4943
+ MainWP_Helper::update_option( 'mainwp_maintenance_opt_alert_404', 1, 'yes' );
4944
+ } else {
4945
+ delete_option( 'mainwp_maintenance_opt_alert_404' );
4946
+ }
4947
+
4948
+ if ( isset( $_POST['email'] ) && ! empty( $_POST['email'] ) ) {
4949
+ MainWP_Helper::update_option( 'mainwp_maintenance_opt_alert_404_email', $_POST['email'], 'yes' );
4950
+ } else {
4951
+ delete_option( 'mainwp_maintenance_opt_alert_404_email' );
4952
+ }
4953
+ $information['result'] = 'SUCCESS';
4954
+ MainWP_Helper::write( $information );
4955
+
4956
+ return;
4957
+ } else if ( 'clear_settings' === $_POST['action'] ) {
4958
+ delete_option( 'mainwp_maintenance_opt_alert_404' );
4959
+ delete_option( 'mainwp_maintenance_opt_alert_404_email' );
4960
+ $information['result'] = 'SUCCESS';
4961
+ MainWP_Helper::write( $information );
4962
+ }
4963
+ MainWP_Helper::write( $information );
4964
+ }
4965
+
4966
+ $maint_options = $_POST['options'];
4967
+ $max_revisions = isset( $_POST['revisions'] ) ? intval( $_POST['revisions'] ) : 0;
4968
+
4969
+ if ( ! is_array( $maint_options ) ) {
4970
+ $information['status'] = 'FAIL';
4971
+ $maint_options = array();
4972
+ }
4973
+
4974
+ $performed_what = array();
4975
+ if ( empty( $max_revisions ) ) {
4976
+ $sql_clean = "DELETE FROM $wpdb->posts WHERE post_type = 'revision'";
4977
+ $wpdb->query( $sql_clean );
4978
+ $performed_what[] = 'Posts revisions deleted';
4979
+ } else {
4980
+ $results = MainWP_Helper::getRevisions( $max_revisions );
4981
+ $count_deleted = MainWP_Helper::deleteRevisions( $results, $max_revisions );
4982
+ $performed_what[] = 'Posts revisions deleted';
4983
+ }
4984
+
4985
+ if ( in_array( 'autodraft', $maint_options ) ) {
4986
+ $sql_clean = "DELETE FROM $wpdb->posts WHERE post_status = 'auto-draft'";
4987
+ $wpdb->query( $sql_clean );
4988
+ $performed_what[] = 'Auto draft posts deleted';
4989
+ }
4990
+
4991
+ if ( in_array( 'trashpost', $maint_options ) ) {
4992
+ $sql_clean = "DELETE FROM $wpdb->posts WHERE post_status = 'trash'";
4993
+ $wpdb->query( $sql_clean );
4994
+ $performed_what[] = 'Trash posts deleted';
4995
+ }
4996
+
4997
+ if ( in_array( 'spam', $maint_options ) ) {
4998
+ $sql_clean = "DELETE FROM $wpdb->comments WHERE comment_approved = 'spam'";
4999
+ $wpdb->query( $sql_clean );
5000
+ $performed_what[] = 'Spam comments deleted';
5001
+ }
5002
+
5003
+ if ( in_array( 'pending', $maint_options ) ) {
5004
+ $sql_clean = "DELETE FROM $wpdb->comments WHERE comment_approved = '0'";
5005
+ $wpdb->query( $sql_clean );
5006
+ $performed_what[] = 'Pending comments deleted';
5007
+ }
5008
+
5009
+ if ( in_array( 'trashcomment', $maint_options ) ) {
5010
+ $sql_clean = "DELETE FROM $wpdb->comments WHERE comment_approved = 'trash'";
5011
+ $wpdb->query( $sql_clean );
5012
+ $performed_what[] = 'Trash comments deleted';
5013
+ }
5014
+
5015
+ if ( in_array( 'tags', $maint_options ) ) {
5016
+ $post_tags = get_terms( 'post_tag', array( 'hide_empty' => false ) );
5017
+ if ( is_array( $post_tags ) ) {
5018
+ foreach ( $post_tags as $tag ) {
5019
+ if ( 0 === $tag->count ) {
5020
+ wp_delete_term( $tag->term_id, 'post_tag' );
5021
+ }
5022
+ }
5023
+ }
5024
+ $performed_what[] = 'Tags with 0 posts associated deleted';
5025
+ }
5026
+
5027
+ if ( in_array( 'categories', $maint_options ) ) {
5028
+ $post_cats = get_terms( 'category', array( 'hide_empty' => false ) );
5029
+ if ( is_array( $post_cats ) ) {
5030
+ foreach ( $post_cats as $cat ) {
5031
+ if ( 0 === $cat->count ) {
5032
+ wp_delete_term( $cat->term_id, 'category' );
5033
+ }
5034
+ }
5035
+ }
5036
+ $performed_what[] = 'Categories with 0 posts associated deleted';
5037
+ }
5038
+
5039
+ if ( in_array( 'optimize', $maint_options ) ) {
5040
+ $this->maintenance_optimize();
5041
+ $performed_what[] = 'Database optimized';
5042
+ }
5043
+ if ( ! isset( $information['status'] ) ) {
5044
+ $information['status'] = 'SUCCESS';
5045
+ }
5046
+
5047
+ if ( !empty( $performed_what ) && has_action( 'mainwp_reports_maintenance' ) ) {
5048
+ $details = implode( ', ', $performed_what );
5049
+ $log_time = time();
5050
+ $message = $result = "Maintenance Performed";
5051
+ do_action( 'mainwp_reports_maintenance', $message, $log_time, $details, $result);
5052
+ }
5053
+
5054
+ MainWP_Helper::write( $information );
5055
+ }
5056
+
5057
+ function maintenance_optimize() {
5058
+ global $wpdb, $table_prefix;
5059
+ $sql = 'SHOW TABLE STATUS FROM `' . DB_NAME . '`';
5060
+ $result = @MainWP_Child_DB::_query( $sql, $wpdb->dbh );
5061
+ if ( @MainWP_Child_DB::num_rows( $result ) && @MainWP_Child_DB::is_result( $result ) ) {
5062
+ while ( $row = MainWP_Child_DB::fetch_array( $result ) ) {
5063
+ if ( strpos( $row['Name'], $table_prefix ) !== false ) {
5064
+ $sql = 'OPTIMIZE TABLE ' . $row['Name'];
5065
+ MainWP_Child_DB::_query( $sql, $wpdb->dbh );
5066
+ }
5067
+ }
5068
+ }
5069
+ }
5070
+
5071
+ function maintenance_alert_404() {
5072
+ if ( ! is_404() ) {
5073
+ return;
5074
+ }
5075
+
5076
+ if ( 1 !== (int) get_option( 'mainwp_maintenance_opt_alert_404' ) ) {
5077
+ return;
5078
+ }
5079
+
5080
+ $email = get_option( 'mainwp_maintenance_opt_alert_404_email' );
5081
+
5082
+ if ( empty( $email ) || ! preg_match( '/^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$/is', $email ) ) {
5083
+ return;
5084
+ }
5085
+
5086
+ // set status
5087
+ header( 'HTTP/1.1 404 Not Found' );
5088
+ header( 'Status: 404 Not Found' );
5089
+
5090
+ // site info
5091
+ $blog = get_bloginfo( 'name' );
5092
+ $site = get_bloginfo( 'url' ) . '/';
5093
+ $from_email = get_bloginfo( 'admin_email' );
5094
+
5095
+ // referrer
5096
+ if ( isset( $_SERVER['HTTP_REFERER'] ) ) {
5097
+ $referer = MainWP_Helper::clean( $_SERVER['HTTP_REFERER'] );
5098
+ } else {
5099
+ $referer = 'undefined';
5100
+ }
5101
+ $protocol = isset( $_SERVER['HTTPS'] ) && strcasecmp( $_SERVER['HTTPS'], 'off' ) ? 'https://' : 'http://';
5102
+ // request URI
5103
+ if ( isset( $_SERVER['REQUEST_URI'] ) && isset( $_SERVER['HTTP_HOST'] ) ) {
5104
+ $request = MainWP_Helper::clean( $protocol . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] );
5105
+ } else {
5106
+ $request = 'undefined';
5107
+ }
5108
+ // query string
5109
+ if ( isset( $_SERVER['QUERY_STRING'] ) ) {
5110
+ $string = MainWP_Helper::clean( $_SERVER['QUERY_STRING'] );
5111
+ } else {
5112
+ $string = 'undefined';
5113
+ }
5114
+ // IP address
5115
+ if ( isset( $_SERVER['REMOTE_ADDR'] ) ) {
5116
+ $address = MainWP_Helper::clean( $_SERVER['REMOTE_ADDR'] );
5117
+ } else {
5118
+ $address = 'undefined';
5119
+ }
5120
+ // user agent
5121
+ if ( isset( $_SERVER['HTTP_USER_AGENT'] ) ) {
5122
+ $agent = MainWP_Helper::clean( $_SERVER['HTTP_USER_AGENT'] );
5123
+ } else {
5124
+ $agent = 'undefined';
5125
+ }
5126
+ // identity
5127
+ if ( isset( $_SERVER['REMOTE_IDENT'] ) ) {
5128
+ $remote = MainWP_Helper::clean( $_SERVER['REMOTE_IDENT'] );
5129
+ } else {
5130
+ $remote = 'undefined';
5131
+ }
5132
+ // log time
5133
+ $time = MainWP_Helper::clean( date( 'F jS Y, h:ia', time() ) );
5134
+
5135
+ $mail = '<div>' . 'TIME: ' . $time . '</div>' .
5136
+ '<div>' . '*404: ' . $request . '</div>' .
5137
+ '<div>' . 'SITE: ' . $site . '</div>' .
5138
+ '<div>' . 'REFERRER: ' . $referer . '</div>' .
5139
+ '<div>' . 'QUERY STRING: ' . $string . '</div>' .
5140
+ '<div>' . 'REMOTE ADDRESS: ' . $address . '</div>' .
5141
+ '<div>' . 'REMOTE IDENTITY: ' . $remote . '</div>' .
5142
+ '<div>' . 'USER AGENT: ' . $agent . '</div>';
5143
+ $mail = '<div>404 alert</div>
5144
+ <div></div>' . $mail;
5145
+ wp_mail( $email, 'MainWP - 404 Alert: ' . $blog, MainWP_Helper::formatEmail( $email, $mail ), array(
5146
+ 'From: "' . $from_email . '" <' . $from_email . '>',
5147
+ 'content-type: text/html',
5148
+ ) );
5149
+
5150
+ }
5151
+
5152
+ public function keyword_links_action() {
5153
+ MainWP_Keyword_Links::Instance()->action();
5154
+ }
5155
+
5156
+ public function branding_child_plugin() {
5157
+ MainWP_Child_Branding::Instance()->action();
5158
+ }
5159
+
5160
+ public function code_snippet() {
5161
+ $action = $_POST['action'];
5162
+ $information = array( 'status' => 'FAIL' );
5163
+ if ( 'run_snippet' === $action || 'save_snippet' === $action ) {
5164
+ if ( ! isset( $_POST['code'] ) ) {
5165
+ MainWP_Helper::write( $information );
5166
+ }
5167
+ }
5168
+ $code = stripslashes( $_POST['code'] );
5169
+ if ( 'run_snippet' === $action ) {
5170
+ $information = MainWP_Tools::execute_snippet( $code );
5171
+ } else if ( 'save_snippet' === $action ) {
5172
+ $type = $_POST['type'];
5173
+ $slug = $_POST['slug'];
5174
+ $snippets = get_option( 'mainwp_ext_code_snippets' );
5175
+
5176
+ if ( ! is_array( $snippets ) ) {
5177
+ $snippets = array();
5178
+ }
5179
+
5180
+ if ( 'C' === $type ) {// save into wp-config file
5181
+ if ( false !== $this->snippetUpdateWPConfig( 'save', $slug, $code ) ) {
5182
+ $information['status'] = 'SUCCESS';
5183
+ }
5184
+ } else {
5185
+ $snippets[ $slug ] = $code;
5186
+ if ( MainWP_Helper::update_option( 'mainwp_ext_code_snippets', $snippets ) ) {
5187
+ $information['status'] = 'SUCCESS';
5188
+ }
5189
+ }
5190
+ MainWP_Helper::update_option( 'mainwp_ext_snippets_enabled', true, 'yes' );
5191
+ } else if ( 'delete_snippet' === $action ) {
5192
+ $type = $_POST['type'];
5193
+ $slug = $_POST['slug'];
5194
+ $snippets = get_option( 'mainwp_ext_code_snippets' );
5195
+
5196
+ if ( ! is_array( $snippets ) ) {
5197
+ $snippets = array();
5198
+ }
5199
+ if ( 'C' === $type ) {// delete in wp-config file
5200
+ if ( false !== $this->snippetUpdateWPConfig( 'delete', $slug ) ) {
5201
+ $information['status'] = 'SUCCESS';
5202
+ }
5203
+ } else {
5204
+ if ( isset( $snippets[ $slug ] ) ) {
5205
+ unset( $snippets[ $slug ] );
5206
+ if ( MainWP_Helper::update_option( 'mainwp_ext_code_snippets', $snippets ) ) {
5207
+ $information['status'] = 'SUCCESS';
5208
+ }
5209
+ } else {
5210
+ $information['status'] = 'SUCCESS';
5211
+ }
5212
+ }
5213
+ }
5214
+ MainWP_Helper::write( $information );
5215
+ }
5216
+
5217
+ public function snippetUpdateWPConfig( $action, $slug, $code = '' ) {
5218
+ $wpConfig = file_get_contents( ABSPATH . 'wp-config.php' );
5219
+ if ( 'delete' === $action ) {
5220
+ $wpConfig = preg_replace( '/' . PHP_EOL . '{1,2}\/\*\*\*snippet_' . $slug . '\*\*\*\/(.*)\/\*\*\*end_' . $slug . '\*\*\*\/' . PHP_EOL . '/is', '', $wpConfig );
5221
+ } else if ( 'save' === $action ) {
5222
+ $wpConfig = preg_replace( '/(\$table_prefix *= *[\'"][^\'|^"]*[\'"] *;)/is', '${1}' . PHP_EOL . PHP_EOL . '/***snippet_' . $slug . '***/' . PHP_EOL . $code . PHP_EOL . '/***end_' . $slug . '***/' . PHP_EOL, $wpConfig );
5223
+ }
5224
+ file_put_contents( ABSPATH . 'wp-config.php', $wpConfig );
5225
+ }
5226
+
5227
+ function run_saved_snippets() {
5228
+ $action = null;
5229
+ if ( isset( $_POST['action'] ) ) {
5230
+ $action = $_POST['action'];
5231
+ }
5232
+
5233
+ if ( 'run_snippet' === $action || 'save_snippet' === $action || 'delete_snippet' === $action ) {
5234
+ return;
5235
+ } // do not run saved snippets if in do action snippet
5236
+
5237
+ if ( get_option( 'mainwp_ext_snippets_enabled' ) ) {
5238
+ $snippets = get_option( 'mainwp_ext_code_snippets' );
5239
+ if ( is_array( $snippets ) && count( $snippets ) > 0 ) {
5240
+ foreach ( $snippets as $code ) {
5241
+ MainWP_Tools::execute_snippet( $code );
5242
+ }
5243
+ }
5244
+ }
5245
+ }
5246
+
5247
+
5248
+ function uploader_action() {
5249
+ $file_url = base64_decode( $_POST['url'] );
5250
+ $path = $_POST['path'];
5251
+ $filename = $_POST['filename'];
5252
+ $information = array();
5253
+
5254
+ if ( empty( $file_url ) || empty( $path ) ) {
5255
+ MainWP_Helper::write( $information );
5256
+
5257
+ return;
5258
+ }
5259
+
5260
+ if ( strpos( $path, 'wp-content' ) === 0 ) {
5261
+ $path = basename( WP_CONTENT_DIR ) . substr( $path, 10 );
5262
+ } else if ( strpos( $path, 'wp-includes' ) === 0 ) {
5263
+ $path = WPINC . substr( $path, 11 );
5264
+ }
5265
+
5266
+ if ( '/' === $path ) {
5267
+ $dir = ABSPATH;
5268
+ } else {
5269
+ $path = str_replace( ' ', '-', $path );
5270
+ $path = str_replace( '.', '-', $path );
5271
+ $dir = ABSPATH . $path;
5272
+ }
5273
+
5274
+ if ( ! file_exists( $dir ) ) {
5275
+ if ( false === @mkdir( $dir, 0777, true ) ) {
5276
+ $information['error'] = 'ERRORCREATEDIR';
5277
+ MainWP_Helper::write( $information );
5278
+
5279
+ return;
5280
+ }
5281
+ }
5282
+
5283
+ try {
5284
+ $upload = MainWP_Helper::uploadFile( $file_url, $dir, $filename );
5285
+ if ( null !== $upload ) {
5286
+ $information['success'] = true;
5287
+ }
5288
+ } catch ( Exception $e ) {
5289
+ $information['error'] = $e->getMessage();
5290
+ }
5291
+ MainWP_Helper::write( $information );
5292
+ }
5293
+
5294
+ function wordpress_seo() {
5295
+ MainWP_Wordpress_SEO::Instance()->action();
5296
+ }
5297
+
5298
+ function client_report() {
5299
+ MainWP_Client_Report::Instance()->action();
5300
+ }
5301
+
5302
+ function page_speed() {
5303
+ MainWP_Child_Pagespeed::Instance()->action();
5304
+ }
5305
+
5306
+ function woo_com_status() {
5307
+ MainWP_Child_WooCommerce_Status::Instance()->action();
5308
+ }
5309
+
5310
+ function heatmaps() {
5311
+ $need_update = true;
5312
+ if ( isset( $_POST['heatMapsOverride'] ) ) {
5313
+ $override = $_POST['heatMapsOverride'] ? '1' : '0';
5314
+ $disable = $_POST['heatMapsDisable'] ? '1' : '0';
5315
+ if ( get_option( 'heatMapsIndividualOverrideSetting' ) === $override && get_option( 'heatMapsIndividualDisable' ) === $disable ) {
5316
+ $need_update = false;
5317
+ }
5318
+ if ( $need_update ) {
5319
+ MainWP_Helper::update_option( 'heatMapsIndividualOverrideSetting', $override, 'yes' );
5320
+ MainWP_Helper::update_option( 'heatMapsIndividualDisable', $disable, 'yes' );
5321
+ $this->update_htaccess( true );
5322
+ }
5323
+ MainWP_Helper::write( array( 'result' => 'success' ) );
5324
+ }
5325
+ MainWP_Helper::write( array( 'result' => 'fail' ) );
5326
+ }
5327
+
5328
+ function links_checker() {
5329
+ MainWP_Child_Links_Checker::Instance()->action();
5330
+ }
5331
+
5332
+ function wordfence() {
5333
+ MainWP_Child_Wordfence::Instance()->action();
5334
+ }
5335
+
5336
+ function ithemes() {
5337
+ MainWP_Child_iThemes_Security::Instance()->action();
5338
+ }
5339
+
5340
+
5341
+ function updraftplus() {
5342
+ MainWP_Child_Updraft_Plus_Backups::Instance()->action();
5343
+ }
5344
+
5345
+ function backup_wp() {
5346
+ if ( ! version_compare( phpversion(), '5.3', '>=' ) ) {
5347
+ $error = sprintf( __( 'PHP Version %s is unsupported.', 'mainwp-child' ), phpversion() );
5348
+ MainWP_Helper::write( array( 'error' => $error ) );
5349
+ }
5350
+ MainWP_Child_Back_Up_Wordpress::Instance()->action();
5351
+ }
5352
+
5353
+ function wp_rocket() {
5354
+ MainWP_Child_WP_Rocket::Instance()->action();
5355
+ }
5356
+
5357
+ function backwpup() {
5358
+ MainWP_Child_Back_WP_Up::Instance()->action();
5359
+ }
5360
+
5361
+
5362
+ function delete_backup() {
5363
+ $dirs = MainWP_Helper::getMainWPDir( 'backup' );
5364
+ $backupdir = $dirs[0];
5365
+
5366
+ $file = $_REQUEST['del'];
5367
+
5368
+ if ( @file_exists( $backupdir . $file ) ) {
5369
+ @unlink( $backupdir . $file );
5370
+ }
5371
+
5372
+ MainWP_Helper::write( array( 'result' => 'ok' ) );
5373
+ }
5374
+
5375
+ function update_values() {
5376
+ $uniId = isset( $_POST['uniqueId'] ) ? $_POST['uniqueId'] : '';
5377
+ MainWP_Helper::update_option( 'mainwp_child_uniqueId', $uniId );
5378
+ MainWP_Helper::write( array( 'result' => 'ok' ) );
5379
+ }
5380
+
5381
+ function uploadFile( $file, $offset = 0 ) {
5382
+ $dirs = MainWP_Helper::getMainWPDir( 'backup' );
5383
+ $backupdir = $dirs[0];
5384
+
5385
+ header( 'Content-Description: File Transfer' );
5386
+
5387
+ header( 'Content-Description: File Transfer' );
5388
+ if ( MainWP_Helper::endsWith( $file, '.tar.gz' ) ) {
5389
+ header( 'Content-Type: application/x-gzip' );
5390
+ header( "Content-Encoding: gzip" );
5391
+ } else {
5392
+ header( 'Content-Type: application/octet-stream' );
5393
+ }
5394
+ header( 'Content-Disposition: attachment; filename="' . basename( $file ) . '"' );
5395
+ header( 'Expires: 0' );
5396
+ header( 'Cache-Control: must-revalidate' );
5397
+ header( 'Pragma: public' );
5398
+ header( 'Content-Length: ' . filesize( $backupdir . $file ) );
5399
+ while ( @ob_end_flush() ) {
5400
+ ;
5401
+ }
5402
+ $this->readfile_chunked( $backupdir . $file, $offset );
5403
+ }
5404
+
5405
+ function readfile_chunked( $filename, $offset ) {
5406
+ $chunksize = 1024; // how many bytes per chunk
5407
+ $handle = @fopen( $filename, 'rb' );
5408
+ if ( false === $handle ) {
5409
+ return false;
5410
+ }
5411
+
5412
+ @fseek( $handle, $offset );
5413
+
5414
+ while ( ! @feof( $handle ) ) {
5415
+ $buffer = @fread( $handle, $chunksize );
5416
+ echo $buffer;
5417
+ @ob_flush();
5418
+ @flush();
5419
+ $buffer = null;
5420
+ }
5421
+
5422
+ return @fclose( $handle );
5423
+ }
5424
+
5425
+ function settings_tools() {
5426
+ if ( isset( $_POST['action'] ) ) {
5427
+ switch ( $_POST['action'] ) {
5428
+ case 'force_destroy_sessions';
5429
+ if ( 0 === get_current_user_id() ) {
5430
+ MainWP_Helper::write( array( 'error' => __( 'Cannot get user_id', 'mainwp-child' ) ) );
5431
+ }
5432
+
5433
+ wp_destroy_all_sessions();
5434
+
5435
+ $sessions = wp_get_all_sessions();
5436
+
5437
+ if ( empty( $sessions ) ) {
5438
+ MainWP_Helper::write( array( 'success' => 1 ) );
5439
+ } else {
5440
+ MainWP_Helper::write( array( 'error' => __( 'Cannot destroy sessions', 'mainwp-child' ) ) );
5441
+ }
5442
+ break;
5443
+
5444
+ default:
5445
+ MainWP_Helper::write( array( 'error' => __( 'Invalid action', 'mainwp-child' ) ) );
5446
+ }
5447
+ } else {
5448
+ MainWP_Helper::write( array( 'error' => __( 'Missing action', 'mainwp-child' ) ) );
5449
+ }
5450
+ }
5451
+
5452
+ function skeleton_key() {
5453
+ MainWP_Child_Skeleton_Key::Instance()->action();
5454
+ }
5455
+
5456
+ function custom_post_type() {
5457
+ MainWP_Custom_Post_Type::Instance()->action();
5458
+ }
5459
+
5460
+ function backup_buddy() {
5461
+ MainWP_Child_Back_Up_Buddy::Instance()->action();
5462
+ }
5463
+
5464
+ function vulner_checker() {
5465
+ MainWP_Child_Vulnerability_Checker::Instance()->action();
5466
+ }
5467
+
5468
+ function wp_staging() {
5469
+ MainWP_Child_Staging::Instance()->action();
5470
+ }
5471
+
5472
+ static function fix_for_custom_themes() {
5473
+ if ( file_exists( ABSPATH . '/wp-admin/includes/screen.php' ) ) {
5474
+ include_once( ABSPATH . '/wp-admin/includes/screen.php' );
5475
+ }
5476
+
5477
+ if ( function_exists( 'et_register_updates_component' ) ) {
5478
+ et_register_updates_component();
5479
+ }
5480
+ }
5481
+ }
class/class-mainwp-client-report.php ADDED
@@ -0,0 +1,789 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class MainWP_Client_Report {
4
+ public static $instance = null;
5
+
6
+ static function Instance() {
7
+ if ( null === MainWP_Client_Report::$instance ) {
8
+ MainWP_Client_Report::$instance = new MainWP_Client_Report();
9
+ }
10
+
11
+ return MainWP_Client_Report::$instance;
12
+ }
13
+
14
+ public static function init() {
15
+ add_filter( 'wp_stream_connectors', array( 'MainWP_Client_Report', 'init_stream_connectors' ), 10, 1 );
16
+ add_filter( 'mainwp_client_reports_connectors', array( 'MainWP_Client_Report', 'init_report_connectors' ), 10, 1 );
17
+ add_action( 'mainwp_child_log', array( 'MainWP_Client_Report', 'do_reports_log' ) );
18
+ }
19
+
20
+ public static function init_stream_connectors( $classes ) {
21
+ $connectors = array(
22
+ 'Backups',
23
+ 'Sucuri',
24
+ );
25
+
26
+ foreach ( $connectors as $connector ) {
27
+ $class_name = "MainWP_Child_Reports_Connector_$connector";
28
+ if ( ! class_exists( $class_name ) ) {
29
+ continue;
30
+ }
31
+ $class = new $class_name();
32
+ if ( ! method_exists( $class, 'is_dependency_satisfied' ) ) {
33
+ continue;
34
+ }
35
+ if ( $class->is_dependency_satisfied() ) {
36
+ $classes[] = $class;
37
+ }
38
+ }
39
+
40
+ return $classes;
41
+ }
42
+
43
+ public static function init_report_connectors( $classes ) {
44
+ $connectors = array(
45
+ 'Backups',
46
+ 'Sucuri'
47
+ );
48
+
49
+ foreach ( $connectors as $connector ) {
50
+ $class = "MainWP_Child_Reports_Connector_$connector";
51
+ if ( ! class_exists( $class ) ) {
52
+ continue;
53
+ }
54
+ $classes[] = $class;
55
+ }
56
+
57
+ return $classes;
58
+ }
59
+
60
+ public static function do_reports_log( $ext = '' ) {
61
+ switch( $ext ) {
62
+ case 'backupbuddy':
63
+ MainWP_Child_Back_Up_Buddy::Instance()->do_reports_log( $ext );
64
+ break;
65
+ case 'backupwordpress':
66
+ MainWP_Child_Back_Up_Wordpress::Instance()->do_reports_log( $ext );
67
+ break;
68
+ case 'backwpup':
69
+ MainWP_Child_Back_WP_Up::Instance()->do_reports_log( $ext );
70
+ break;
71
+ case 'wordfence':
72
+ MainWP_Child_Wordfence::Instance()->do_reports_log( $ext );
73
+ break;
74
+ // case 'wptimecapsule':
75
+ // MainWP_Child_WP_Time_Capsule::Instance()->do_reports_log( $ext );
76
+ // break;
77
+ }
78
+ }
79
+
80
+ public function action() {
81
+
82
+ $information = array();
83
+
84
+ if ( !function_exists( 'mainwp_wp_stream_query' ) || !class_exists( 'MainWP_WP_Stream' ) ) {
85
+ $information['error'] = 'NO_CREPORT';
86
+ MainWP_Helper::write( $information );
87
+ }
88
+
89
+ if ( isset( $_POST['mwp_action'] ) ) {
90
+ switch ( $_POST['mwp_action'] ) {
91
+ case 'save_sucuri_stream':
92
+ $information = $this->save_sucuri_stream();
93
+ break;
94
+ case 'save_backup_stream':
95
+ $information = $this->save_backup_stream();
96
+ break;
97
+ case 'get_stream':
98
+ $information = $this->get_stream();
99
+ break;
100
+ case 'set_showhide':
101
+ $information = $this->set_showhide();
102
+ break;
103
+ }
104
+ }
105
+ MainWP_Helper::write( $information );
106
+ }
107
+
108
+ public function save_sucuri_stream() {
109
+ $scan_data = isset($_POST['scan_data']) ? $_POST['scan_data'] : '';
110
+ do_action( 'mainwp_sucuri_scan', $_POST['result'], $_POST['scan_status'], $scan_data );
111
+
112
+ return true;
113
+ }
114
+
115
+ public function save_backup_stream() {
116
+ do_action( 'mainwp_backup', $_POST['destination'], $_POST['message'], $_POST['size'], $_POST['status'], $_POST['type'] );
117
+
118
+ return true;
119
+ }
120
+
121
+ public function get_stream() {
122
+ // Filters
123
+ $allowed_params = array(
124
+ 'connector',
125
+ 'context',
126
+ 'action',
127
+ 'author',
128
+ 'author_role',
129
+ 'object_id',
130
+ 'search',
131
+ 'date',
132
+ 'date_from',
133
+ 'date_to',
134
+ 'record__in',
135
+ 'blog_id',
136
+ 'ip',
137
+ );
138
+
139
+ $sections = isset( $_POST['sections'] ) ? maybe_unserialize( base64_decode( $_POST['sections'] ) ) : array();
140
+ if ( ! is_array( $sections ) ) {
141
+ $sections = array();
142
+ }
143
+ //return $sections;
144
+
145
+ $other_tokens = isset( $_POST['other_tokens'] ) ? maybe_unserialize( base64_decode( $_POST['other_tokens'] ) ) : array();
146
+ if ( ! is_array( $other_tokens ) ) {
147
+ $other_tokens = array();
148
+ }
149
+ //return $other_tokens;
150
+
151
+ unset( $_POST['sections'] );
152
+ unset( $_POST['other_tokens'] );
153
+
154
+ $args = array();
155
+ foreach ( $allowed_params as $param ) {
156
+ $paramval = mainwp_wp_stream_filter_input( INPUT_POST, $param );
157
+ if ( $paramval || '0' === $paramval ) {
158
+ $args[ $param ] = $paramval;
159
+ }
160
+ }
161
+
162
+ foreach ( $args as $arg => $val ) {
163
+ if ( ! in_array( $arg, $allowed_params ) ) {
164
+ unset( $args[ $arg ] );
165
+ }
166
+ }
167
+
168
+ // to fix bug
169
+ $exclude_connector_posts = true;
170
+ if ( isset( $sections['body'] ) && isset( $sections['body']['section_token'] ) && is_array($sections['body']['section_token']) ) {
171
+ foreach ($sections['body']['section_token'] as $sec) {
172
+ if (strpos($sec, "[section.posts") !== false) {
173
+ $exclude_connector_posts = false;
174
+ break;
175
+ }
176
+ }
177
+ }
178
+ if ($exclude_connector_posts) {
179
+ if ( isset( $sections['header'] ) && isset( $sections['header']['section_token'] ) && is_array($sections['header']['section_token']) ) {
180
+ foreach ($sections['header']['section_token'] as $sec) {
181
+ if (strpos($sec, "[section.posts") !== false) {
182
+ $exclude_connector_posts = false;
183
+ break;
184
+ }
185
+ }
186
+ }
187
+ }
188
+ if ($exclude_connector_posts) {
189
+ if ( isset( $sections['footer'] ) && isset( $sections['footer']['section_token'] ) && is_array($sections['footer']['section_token']) ) {
190
+ foreach ($sections['footer']['section_token'] as $sec) {
191
+ if (strpos($sec, "[section.posts") !== false) {
192
+ $exclude_connector_posts = false;
193
+ break;
194
+ }
195
+ }
196
+ }
197
+ }
198
+ if ($exclude_connector_posts) {
199
+ if ( isset( $other_tokens['body'] ) && is_array( $other_tokens['body'] ) ) {
200
+ foreach ( $other_tokens['body'] as $sec ) {
201
+ if ( strpos( $sec, "[post." ) !== false ) {
202
+ $exclude_connector_posts = false;
203
+ break;
204
+ }
205
+ }
206
+ }
207
+ }
208
+ if ($exclude_connector_posts) {
209
+ if ( isset( $other_tokens['header'] ) && is_array($other_tokens['header']) ) {
210
+ foreach ($other_tokens['header'] as $sec) {
211
+ if (strpos($sec, "[post.") !== false) {
212
+ $exclude_connector_posts = false;
213
+ break;
214
+ }
215
+ }
216
+ }
217
+ }
218
+ if ($exclude_connector_posts) {
219
+ if ( isset( $other_tokens['footer'] ) && is_array($other_tokens['footer']) ) {
220
+ foreach ($other_tokens['footer'] as $sec) {
221
+ if (strpos($sec, "[post.") !== false) {
222
+ $exclude_connector_posts = false;
223
+ break;
224
+ }
225
+ }
226
+ }
227
+ }
228
+ if ($exclude_connector_posts)
229
+ $args['connector__not_in'] = array('posts');
230
+ ///// end fix /////
231
+
232
+ $args['action__not_in'] = array( 'login' );
233
+
234
+ $args['fields'] = 'with-meta';
235
+ if ( isset( $args['date_from'] ) ) {
236
+ $args['date_from'] = date( 'Y-m-d H:i:s', $args['date_from'] );
237
+ }
238
+
239
+ if ( isset( $args['date_to'] ) ) {
240
+ $args['date_to'] = date( 'Y-m-d H:i:s', $args['date_to'] );
241
+ }
242
+
243
+ if ( MainWP_Child_Branding::is_branding() ) {
244
+ $args['hide_child_reports'] = 1;
245
+ }
246
+
247
+ $args['records_per_page'] = 9999;
248
+
249
+ $records = mainwp_wp_stream_query( $args );
250
+
251
+ if ( ! is_array( $records ) ) {
252
+ $records = array();
253
+ }
254
+
255
+ //return $records;
256
+ //$other_tokens_data = $this->get_other_tokens_data($records, $other_tokens);
257
+
258
+ // to fix invalid data
259
+ $skip_records = array();
260
+ if ( isset( $other_tokens['header'] ) && is_array( $other_tokens['header'] ) ) {
261
+ $other_tokens_data['header'] = $this->get_other_tokens_data( $records, $other_tokens['header'], $skip_records);
262
+ }
263
+
264
+ if ( isset( $other_tokens['body'] ) && is_array( $other_tokens['body'] ) ) {
265
+ $other_tokens_data['body'] = $this->get_other_tokens_data( $records, $other_tokens['body'], $skip_records );
266
+ }
267
+
268
+ if ( isset( $other_tokens['footer'] ) && is_array( $other_tokens['footer'] ) ) {
269
+ $other_tokens_data['footer'] = $this->get_other_tokens_data( $records, $other_tokens['footer'], $skip_records );
270
+ }
271
+
272
+ $sections_data = array();
273
+
274
+ if ( isset( $sections['header'] ) && is_array( $sections['header'] ) && ! empty( $sections['header'] ) ) {
275
+ foreach ( $sections['header']['section_token'] as $index => $sec ) {
276
+ $tokens = $sections['header']['section_content_tokens'][ $index ];
277
+ $sections_data['header'][ $index ] = $this->get_section_loop_data( $records, $tokens, $sec, $skip_records );
278
+ }
279
+ }
280
+ if ( isset( $sections['body'] ) && is_array( $sections['body'] ) && ! empty( $sections['body'] ) ) {
281
+ foreach ( $sections['body']['section_token'] as $index => $sec ) {
282
+ $tokens = $sections['body']['section_content_tokens'][ $index ];
283
+ $sections_data['body'][ $index ] = $this->get_section_loop_data( $records, $tokens, $sec, $skip_records );
284
+ }
285
+ }
286
+ if ( isset( $sections['footer'] ) && is_array( $sections['footer'] ) && ! empty( $sections['footer'] ) ) {
287
+ foreach ( $sections['footer']['section_token'] as $index => $sec ) {
288
+ $tokens = $sections['footer']['section_content_tokens'][ $index ];
289
+ $sections_data['footer'][ $index ] = $this->get_section_loop_data( $records, $tokens, $sec, $skip_records );
290
+ }
291
+ }
292
+
293
+ $information = array(
294
+ 'other_tokens_data' => $other_tokens_data,
295
+ 'sections_data' => $sections_data,
296
+ );
297
+
298
+ return $information;
299
+ }
300
+
301
+ function get_other_tokens_data( $records, $tokens, &$skip_records ) {
302
+
303
+ $convert_context_name = array(
304
+ 'comment' => 'comments',
305
+ 'plugin' => 'plugins',
306
+ 'profile' => 'profiles',
307
+ 'session' => 'sessions',
308
+ 'setting' => 'settings',
309
+ 'setting' => 'settings',
310
+ 'theme' => 'themes',
311
+ 'posts' => 'post',
312
+ 'pages' => 'page',
313
+ 'user' => 'users',
314
+ 'widget' => 'widgets',
315
+ 'menu' => 'menus',
316
+ 'backups' => 'mainwp_backups',
317
+ 'backup' => 'mainwp_backups',
318
+ 'sucuri' => 'mainwp_sucuri',
319
+ );
320
+
321
+ $convert_action_name = array(
322
+ 'restored' => 'untrashed',
323
+ 'spam' => 'spammed',
324
+ 'backups' => 'mainwp_backup',
325
+ 'backup' => 'mainwp_backup',
326
+ );
327
+
328
+ $allowed_data = array(
329
+ 'count'
330
+ );
331
+
332
+ $token_values = array();
333
+
334
+ if ( ! is_array( $tokens ) ) {
335
+ $tokens = array();
336
+ }
337
+
338
+ foreach ( $tokens as $token ) {
339
+ $str_tmp = str_replace( array( '[', ']' ), '', $token );
340
+ $array_tmp = explode( '.', $str_tmp );
341
+
342
+ if ( is_array( $array_tmp ) ) {
343
+ $context = $action = $data = '';
344
+ if ( 2 === count( $array_tmp ) ) {
345
+ list( $context, $data ) = $array_tmp;
346
+ } else if ( 3 === count( $array_tmp ) ) {
347
+ list( $context, $action, $data ) = $array_tmp;
348
+ }
349
+
350
+ $context = isset( $convert_context_name[ $context ] ) ? $convert_context_name[ $context ] : $context;
351
+ if ( isset( $convert_action_name[ $action ] ) ) {
352
+ $action = $convert_action_name[ $action ];
353
+ }
354
+ switch ( $data ) {
355
+ case 'count':
356
+ $count = 0;
357
+ foreach ( $records as $record ) {
358
+ if ( 'themes' === $context && 'edited' === $action ) {
359
+ if ( $record->action !== 'updated' || $record->connector !== 'editor' ) {
360
+ continue;
361
+ }
362
+ } else if ( 'users' === $context && 'updated' === $action ) {
363
+ if ( $record->context !== 'profiles' || $record->connector !== 'users' ) {
364
+ continue;
365
+ }
366
+ } else if ( 'mainwp_backups' === $context ) {
367
+ if ( $record->context !== 'mainwp_backups' && $record->context !== 'backwpup_backups' && $record->context !== 'updraftplus_backups' && $record->context !== 'backupwordpress_backups' && $record->context !== 'backupbuddy_backups' ) {
368
+ continue;
369
+ }
370
+ } else if ( 'mainwp_sucuri' === $context ) {
371
+ if ( $record->context !== 'mainwp_sucuri' ) {
372
+ continue;
373
+ }
374
+ } else if ( 'wordfence' === $context ) {
375
+ if ( $record->context !== 'wordfence_scans' ) {
376
+ continue;
377
+ }
378
+ } else if ( 'maintenance' === $context ) {
379
+ if ( $record->context !== 'mainwp_maintenances' ) {
380
+ continue;
381
+ }
382
+ } else {
383
+ if ( $action !== $record->action ) {
384
+ continue;
385
+ }
386
+
387
+ if ( 'comments' === $context && 'comments' !== $record->connector ) {
388
+ continue;
389
+ } else if ( 'media' === $context && 'media' !== $record->connector ) {
390
+ continue;
391
+ } else if ( 'widgets' === $context && 'widgets' !== $record->connector ) {
392
+ continue;
393
+ } else if ( 'menus' === $context && 'menus' !== $record->connector ) {
394
+ continue;
395
+ }
396
+
397
+ if ( 'comments' !== $context && 'media' !== $context &&
398
+ 'widgets' !== $context && 'menus' !== $context &&
399
+ $record->context !== $context
400
+ ) {
401
+ continue;
402
+ }
403
+
404
+ if ( 'updated' === $action && ( 'post' === $context || 'page' === $context ) ) {
405
+ $new_status = $this->get_stream_meta_data( $record, 'new_status' );
406
+ if ( 'draft' === $new_status ) { // avoid auto save post
407
+ continue;
408
+ }
409
+ } else if ( 'updated' === $action && ('themes' === $context || 'plugins' === $context)) {
410
+ $name = $this->get_stream_meta_data( $record, 'name' );
411
+ if ( empty($name) ) { // to fix empty value
412
+ if (!in_array($record->ID, $skip_records))
413
+ $skip_records[] = $record->ID;
414
+ continue;
415
+ } else {
416
+ $old_version = $this->get_stream_meta_data( $record, 'old_version' );
417
+ $version = $this->get_stream_meta_data( $record, 'version' );
418
+ if (version_compare($version, $old_version, '<=')) { // to fix
419
+ if (!in_array($record->ID, $skip_records))
420
+ $skip_records[] = $record->ID;
421
+ continue;
422
+ }
423
+ }
424
+ }
425
+
426
+ }
427
+
428
+ $count ++;
429
+ }
430
+ $token_values[ $token ] = $count;
431
+ break;
432
+ }
433
+ }
434
+ }
435
+
436
+ return $token_values;
437
+ }
438
+
439
+ function get_section_loop_data( $records, $tokens, $section, $skip_records = array() ) {
440
+
441
+ $convert_context_name = array(
442
+ 'comment' => 'comments',
443
+ 'plugin' => 'plugins',
444
+ 'profile' => 'profiles',
445
+ 'session' => 'sessions',
446
+ 'setting' => 'settings',
447
+ 'theme' => 'themes',
448
+ 'posts' => 'post',
449
+ 'pages' => 'page',
450
+ 'widget' => 'widgets',
451
+ 'menu' => 'menus',
452
+ 'backups' => 'mainwp_backups',
453
+ 'backup' => 'mainwp_backups',
454
+ 'sucuri' => 'mainwp_sucuri',
455
+ );
456
+
457
+ $convert_action_name = array(
458
+ 'restored' => 'untrashed',
459
+ 'spam' => 'spammed',
460
+ 'backup' => 'mainwp_backup',
461
+ );
462
+
463
+ $some_allowed_data = array(
464
+ 'ID',
465
+ 'name',
466
+ 'title',
467
+ 'oldversion',
468
+ 'currentversion',
469
+ 'date',
470
+ 'time',
471
+ 'count',
472
+ 'author',
473
+ 'old.version',
474
+ 'current.version',
475
+ );
476
+
477
+ $context = $action = '';
478
+ $str_tmp = str_replace( array( '[', ']' ), '', $section );
479
+ $array_tmp = explode( '.', $str_tmp );
480
+ if ( is_array( $array_tmp ) ) {
481
+ if ( 2 === count( $array_tmp ) ) {
482
+ list( $str1, $context ) = $array_tmp;
483
+ } else if ( 3 === count( $array_tmp ) ) {
484
+ list( $str1, $context, $action ) = $array_tmp;
485
+ }
486
+ }
487
+
488
+ $context = isset( $convert_context_name[ $context ] ) ? $convert_context_name[ $context ] : $context;
489
+ $action = isset( $convert_action_name[ $action ] ) ? $convert_action_name[ $action ] : $action;
490
+
491
+ $loops = array();
492
+ $loop_count = 0;
493
+
494
+ foreach ( $records as $record ) {
495
+ if (in_array($record->ID, $skip_records)) {
496
+ continue;
497
+ }
498
+
499
+ $theme_edited = $users_updated = $plugin_edited = false;
500
+
501
+ if ( $plugin_edited ) {
502
+ // ok next
503
+ } else if ( 'themes' === $context && 'edited' === $action ) {
504
+ if ( $record->action !== 'updated' || $record->connector !== 'editor' ) {
505
+ continue;
506
+ } else {
507
+ $theme_edited = true;
508
+ }
509
+ } else if ( 'users' === $context && 'updated' === $action ) {
510
+ if ( $record->context !== 'profiles' || $record->connector !== 'users' ) {
511
+ continue;
512
+ } else {
513
+ $users_updated = true;
514
+ }
515
+ } else if ( 'mainwp_backups' === $context ) {
516
+ if ( $record->context !== 'mainwp_backups' && $record->context !== 'backwpup_backups' && $record->context !== 'updraftplus_backups' && $record->context !== 'backupwordpress_backups' && $record->context !== 'backupbuddy_backups' && $record->context !== 'wptimecapsule_backups') {
517
+ continue;
518
+ }
519
+ } else if ( 'mainwp_sucuri' === $context ) {
520
+ if ( $record->context !== 'mainwp_sucuri' ) {
521
+ continue;
522
+ }
523
+ } else if ( 'wordfence' === $context ) {
524
+ if ( $record->context !== 'wordfence_scans' ) {
525
+ continue;
526
+ }
527
+ } else if ( 'maintenance' === $context ) {
528
+ if ( $record->context !== 'mainwp_maintenances' ) {
529
+ continue;
530
+ }
531
+ } else {
532
+ if ( $action !== $record->action ) {
533
+ continue;
534
+ }
535
+
536
+ if ( 'comments' === $context && 'comments' !== $record->connector ) {
537
+ continue;
538
+ } else if ( 'media' === $context && 'media' !== $record->connector ) {
539
+ continue;
540
+ } else if ( 'widgets' === $context && 'widgets' !== $record->connector ) {
541
+ continue;
542
+ } else if ( 'menus' === $context && 'menus' !== $record->connector ) {
543
+ continue;
544
+ }
545
+ // else if ($context === "themes" && $record->connector !== "themes")
546
+ // continue;
547
+
548
+ if ( 'comments' !== $context && 'media' !== $context &&
549
+ 'widgets' !== $context && 'menus' !== $context &&
550
+ $record->context !== $context
551
+ ) {
552
+ continue;
553
+ }
554
+
555
+ if ( 'updated' === $action && ( 'post' === $context || 'page' === $context ) ) {
556
+ $new_status = $this->get_stream_meta_data( $record, 'new_status' );
557
+ if ( 'draft' === $new_status ) { // avoid auto save post
558
+ continue;
559
+ }
560
+ }
561
+ }
562
+
563
+ $token_values = array();
564
+
565
+ foreach ( $tokens as $token ) {
566
+ $data = '';
567
+ $token_name = str_replace( array( '[', ']' ), '', $token );
568
+ $array_tmp = explode( '.', $token_name );
569
+
570
+ if ( 'user.name' === $token_name ) {
571
+ $data = 'display_name';
572
+ } else {
573
+ if ( 1 === count( $array_tmp ) ) {
574
+ list( $data ) = $array_tmp;
575
+ } else if ( 2 === count( $array_tmp ) ) {
576
+ list( $str1, $data ) = $array_tmp;
577
+ } else if ( 3 === count( $array_tmp ) ) {
578
+ list( $str1, $str2, $data ) = $array_tmp;
579
+ }
580
+
581
+ if ( 'version' === $data ) {
582
+ if ( 'old' === $str2 ) {
583
+ $data = 'old_version';
584
+ } else if ( 'current' === $str2 && 'wordpress' === $str1 ) {
585
+ $data = 'new_version';
586
+ }
587
+ }
588
+ }
589
+
590
+ if ( 'role' === $data ) {
591
+ $data = 'roles';
592
+ }
593
+
594
+ switch ( $data ) {
595
+ case 'ID':
596
+ $token_values[ $token ] = $record->ID;
597
+ break;
598
+ case 'date':
599
+ $token_values[ $token ] = MainWP_Helper::formatDate( MainWP_Helper::getTimestamp( strtotime( $record->created ) ) );
600
+ break;
601
+ case 'time':
602
+ $token_values[ $token ] = MainWP_Helper::formatTime( MainWP_Helper::getTimestamp( strtotime( $record->created ) ) );
603
+ break;
604
+ case 'area':
605
+ $data = 'sidebar_name';
606
+ $token_values[ $token ] = $this->get_stream_meta_data( $record, $data );
607
+ break;
608
+ case 'name':
609
+ case 'version':
610
+ case 'old_version':
611
+ case 'new_version':
612
+ case 'display_name':
613
+ case 'roles':
614
+ if ( 'name' === $data ) {
615
+ if ( $theme_edited ) {
616
+ $data = 'theme_name';
617
+ } else if ( $plugin_edited ) {
618
+ $data = 'plugin_name';
619
+ } else if ( $users_updated ) {
620
+ $data = 'display_name';
621
+ }
622
+ }
623
+
624
+ if ( 'roles' === $data && $users_updated ) {
625
+ $user_info = get_userdata( $record->object_id );
626
+ if ( ! ( is_object( $user_info ) && $user_info instanceof WP_User ) ) {
627
+ $roles = '';
628
+ } else {
629
+ $roles = implode( ', ', $user_info->roles );
630
+ }
631
+ $token_values[ $token ] = $roles;
632
+ } else {
633
+ $token_values[ $token ] = $this->get_stream_meta_data( $record, $data );
634
+ }
635
+ break;
636
+ case 'title':
637
+ if ( 'comments' === $context ) {
638
+ $token_values[ $token ] = $record->summary;
639
+ } else {
640
+ if ( 'page' === $context || 'post' === $context ) {
641
+ $data = 'post_title';
642
+ } else if ( 'menus' === $record->connector ) {
643
+ $data = 'name';
644
+ }
645
+ $token_values[ $token ] = $this->get_stream_meta_data( $record, $data );
646
+ }
647
+ break;
648
+ case 'author':
649
+ $data = 'author_meta';
650
+ $value = $this->get_stream_meta_data( $record, $data );
651
+ if ( empty( $value ) && 'comments' === $context ) {
652
+ $value = __( 'Guest', 'mainwp-child-reports' );
653
+ }
654
+ $token_values[ $token ] = $value;
655
+ break;
656
+ case 'status': // sucuri cases
657
+ case 'webtrust':
658
+ if ( 'mainwp_sucuri' === $context ) {
659
+
660
+ $scan_data = $this->get_stream_meta_data( $record, 'scan_data' );
661
+ if (!empty($scan_data)) {
662
+ $scan_data = maybe_unserialize( base64_decode( $scan_data ) );
663
+ if ( is_array( $scan_data ) ) {
664
+
665
+ $blacklisted = $scan_data['blacklisted'];
666
+ $malware_exists = $scan_data['malware_exists'];
667
+
668
+ $status = array();
669
+ if ( $blacklisted ) {
670
+ $status[] = __( 'Site Blacklisted', 'mainwp-child' ); }
671
+ if ( $malware_exists ) {
672
+ $status[] = __( 'Site With Warnings', 'mainwp-child' ); }
673
+
674
+ if ($data == 'status') {
675
+ $token_values[$token] = count( $status ) > 0 ? implode( ', ', $status ) : __( 'Verified Clear', 'mainwp-child' );
676
+ } else if ($data == 'webtrust') {
677
+ $token_values[$token] = $blacklisted ? __( 'Site Blacklisted', 'mainwp-child' ) : __( 'Trusted', 'mainwp-child' );
678
+ }
679
+ }
680
+
681
+ } else {
682
+ $token_values[ $token ] = $this->get_stream_meta_data( $record, $data );
683
+ }
684
+ } else {
685
+ $token_values[ $token ] = $value;
686
+ }
687
+ break;
688
+ case 'details':
689
+ case 'result':
690
+ if ( 'wordfence' === $context || 'maintenance' === $context ) {
691
+ $token_values[ $token ] = $this->get_stream_meta_data( $record, $data );
692
+ }
693
+ break;
694
+ case 'destination': // backup cases
695
+ case 'type':
696
+ if ( 'mainwp_backups' === $context ) {
697
+ $token_values[ $token ] = $this->get_stream_meta_data( $record, $data );
698
+ } else {
699
+ $token_values[ $token ] = $token;
700
+ }
701
+ break;
702
+ default:
703
+ $token_values[ $token ] = 'N/A';
704
+ break;
705
+ }
706
+ } // foreach $tokens
707
+
708
+ if ( ! empty( $token_values ) ) {
709
+ $loops[ $loop_count ] = $token_values;
710
+ $loop_count ++;
711
+ }
712
+ } // foreach $records
713
+ return $loops;
714
+ }
715
+
716
+ function get_stream_meta_data( $record, $data ) {
717
+
718
+ if ( empty( $record ) ) {
719
+ return '';
720
+ }
721
+
722
+ $meta_key = $data;
723
+
724
+ $value = '';
725
+
726
+ if ( isset( $record->meta ) ) {
727
+ $meta = $record->meta;
728
+ if ( isset( $meta[ $meta_key ] ) ) {
729
+ $value = $meta[ $meta_key ];
730
+ $value = current( $value );
731
+ if ( 'author_meta' === $meta_key || 'user_meta' === $meta_key ) {
732
+ $value = maybe_unserialize( $value );
733
+ $value = $value['display_name'];
734
+ }
735
+ }
736
+ }
737
+
738
+ return $value;
739
+ }
740
+
741
+ function set_showhide() {
742
+ MainWP_Helper::update_option( 'mainwp_creport_ext_branding_enabled', 'Y', 'yes' );
743
+ $hide = isset( $_POST['showhide'] ) && ( 'hide' === $_POST['showhide'] ) ? 'hide' : '';
744
+ MainWP_Helper::update_option( 'mainwp_creport_branding_stream_hide', $hide, 'yes' );
745
+ $information['result'] = 'SUCCESS';
746
+
747
+ return $information;
748
+ }
749
+
750
+ public function creport_init() {
751
+ if ( get_option( 'mainwp_creport_ext_branding_enabled' ) !== 'Y' ) {
752
+ return;
753
+ }
754
+
755
+ if ( get_option( 'mainwp_creport_branding_stream_hide' ) === 'hide' ) {
756
+ add_filter( 'all_plugins', array( $this, 'creport_branding_plugin' ) );
757
+ add_action( 'admin_menu', array( $this, 'creport_remove_menu' ) );
758
+ add_filter( 'site_transient_update_plugins', array( &$this, 'remove_update_nag' ) );
759
+ }
760
+ }
761
+
762
+ function remove_update_nag( $value ) {
763
+ if ( isset( $_POST['mainwpsignature'] ) ) {
764
+ return $value;
765
+ }
766
+ if ( isset( $value->response['mainwp-child-reports/mainwp-child-reports.php'] ) ) {
767
+ unset( $value->response['mainwp-child-reports/mainwp-child-reports.php'] );
768
+ }
769
+
770
+ return $value;
771
+ }
772
+
773
+
774
+ public function creport_branding_plugin( $plugins ) {
775
+ foreach ( $plugins as $key => $value ) {
776
+ $plugin_slug = basename( $key, '.php' );
777
+ if ( 'mainwp-child-reports' === $plugin_slug ) {
778
+ unset( $plugins[ $key ] );
779
+ }
780
+ }
781
+
782
+ return $plugins;
783
+ }
784
+
785
+ public function creport_remove_menu() {
786
+ remove_menu_page( 'mainwp_wp_stream' );
787
+ }
788
+ }
789
+
class/class-mainwp-clone-install.php ADDED
@@ -0,0 +1,697 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class MainWP_Clone_Install {
4
+ protected $file;
5
+ public $config;
6
+ /** @var $archiver Tar_Archiver */
7
+ protected $archiver;
8
+
9
+ /**
10
+ * Class constructor
11
+ *
12
+ * @param string $file The zip backup file path
13
+ */
14
+ public function __construct( $file ) {
15
+ require_once( ABSPATH . 'wp-admin/includes/class-pclzip.php' );
16
+
17
+ $this->file = $file;
18
+ if ( '.zip' === substr( $this->file, - 4 ) ) {
19
+ $this->archiver = null;
20
+ } else if ( '.tar.gz' === substr( $this->file, - 7 ) ) {
21
+ $this->archiver = new Tar_Archiver( null, 'tar.gz' );
22
+ } else if ( '.tar.bz2' === substr( $this->file, - 8 ) ) {
23
+ $this->archiver = new Tar_Archiver( null, 'tar.bz2' );
24
+ } else if ( '.tar' === substr( $this->file, - 4 ) ) {
25
+ $this->archiver = new Tar_Archiver( null, 'tar' );
26
+ }
27
+ }
28
+
29
+ /**
30
+ * Check for default PHP zip support
31
+ *
32
+ * @return bool
33
+ */
34
+ public function checkZipSupport() {
35
+ return class_exists( 'ZipArchive' );
36
+ }
37
+
38
+ /**
39
+ * Check if we could run zip on console
40
+ *
41
+ * @return bool
42
+ */
43
+ public function checkZipConsole() {
44
+ //todo: implement
45
+ // return function_exists('system');
46
+ return false;
47
+ }
48
+
49
+ public function checkWPZip() {
50
+ return function_exists( 'unzip_file' );
51
+ }
52
+
53
+
54
+ public function removeConfigFile() {
55
+ if ( ! $this->file || ! file_exists( $this->file ) ) {
56
+ return false;
57
+ }
58
+
59
+ if ( null !== $this->archiver ) {
60
+
61
+ } else if ( $this->checkZipConsole() ) {
62
+ //todo: implement
63
+ } else if ( $this->checkZipSupport() ) {
64
+ $zip = new ZipArchive();
65
+ $zipRes = $zip->open( $this->file );
66
+ if ( $zipRes ) {
67
+ $zip->deleteName( 'wp-config.php' );
68
+ $zip->deleteName( 'clone' );
69
+ $zip->close();
70
+
71
+ return true;
72
+ }
73
+
74
+ return false;
75
+ } else {
76
+ //use pclzip
77
+ $zip = new PclZip( $this->file );
78
+ $list = $zip->delete( PCLZIP_OPT_BY_NAME, 'wp-config.php' );
79
+ $list2 = $zip->delete( PCLZIP_OPT_BY_NAME, 'clone' );
80
+ if ( 0 === $list ) {
81
+ return false;
82
+ }
83
+
84
+ return true;
85
+ }
86
+
87
+ return false;
88
+ }
89
+
90
+ public function testDownload() {
91
+ if ( ! $this->file_exists( 'wp-content/' ) ) {
92
+ throw new Exception( __( 'This is not a full backup.', 'mainwp-child' ) );
93
+ }
94
+ if ( ! $this->file_exists( 'wp-admin/' ) ) {
95
+ throw new Exception( __( 'This is not a full backup.', 'mainwp-child' ) );
96
+ }
97
+ if ( ! $this->file_exists( 'wp-content/dbBackup.sql' ) ) {
98
+ throw new Exception( __( 'Database backup is missing.', 'mainwp-child' ) );
99
+ }
100
+ }
101
+
102
+ private function file_exists( $file ) {
103
+ if ( 'extracted' === $this->file ) {
104
+ return file_get_contents( '../clone/config.txt' );
105
+ }
106
+
107
+ if ( ! $this->file || ! file_exists( $this->file ) ) {
108
+ return false;
109
+ }
110
+
111
+ if ( null !== $this->archiver ) {
112
+ if ( ! $this->archiver->isOpen() ) {
113
+ $this->archiver->read( $this->file );
114
+ }
115
+
116
+ return $this->archiver->file_exists( $file );
117
+ } else if ( $this->checkZipConsole() ) {
118
+ //todo: implement
119
+ } else if ( $this->checkZipSupport() ) {
120
+ $zip = new ZipArchive();
121
+ $zipRes = $zip->open( $this->file );
122
+ if ( $zipRes ) {
123
+ $content = $zip->locateName( $file );
124
+ $zip->close();
125
+
126
+ return false !== $content;
127
+ }
128
+
129
+ return false;
130
+ } else {
131
+ return true;
132
+ }
133
+
134
+ return false;
135
+ }
136
+
137
+ public function readConfigurationFile() {
138
+ $configContents = $this->getConfigContents();
139
+ if ( false === $configContents ) {
140
+ throw new Exception( __( 'Cant read configuration file from the backup.', 'mainwp-child' ) );
141
+ }
142
+ $this->config = maybe_unserialize( base64_decode( $configContents ) );
143
+
144
+ if ( isset( $this->config['plugins'] ) ) {
145
+ MainWP_Helper::update_option( 'mainwp_temp_clone_plugins', $this->config['plugins'] );
146
+ }
147
+ if ( isset( $this->config['themes'] ) ) {
148
+ MainWP_Helper::update_option( 'mainwp_temp_clone_themes', $this->config['themes'] );
149
+ }
150
+ }
151
+
152
+ public function setConfig( $key, $val ) {
153
+ $this->config[ $key ] = $val;
154
+ }
155
+
156
+ public function testDatabase() {
157
+ $link = @MainWP_Child_DB::connect( $this->config['dbHost'], $this->config['dbUser'], $this->config['dbPass'] );
158
+ if ( ! $link ) {
159
+ throw new Exception( __( 'Invalid database host or user/password.', 'mainwp-child' ) );
160
+ }
161
+
162
+ $db_selected = @MainWP_Child_DB::select_db( $this->config['dbName'], $link );
163
+ if ( ! $db_selected ) {
164
+ throw new Exception( __( 'Invalid database name.', 'mainwp-child' ) );
165
+ }
166
+ }
167
+
168
+ public function clean() {
169
+ $files = glob( WP_CONTENT_DIR . '/dbBackup*.sql' );
170
+ foreach ( $files as $file ) {
171
+ @unlink( $file );
172
+ }
173
+ if ( file_exists( ABSPATH . 'clone/config.txt' ) ) {
174
+ @unlink( ABSPATH . 'clone/config.txt' );
175
+ }
176
+ if ( MainWP_Helper::is_dir_empty( ABSPATH . 'clone' ) ) {
177
+ @rmdir( ABSPATH . 'clone' );
178
+ }
179
+
180
+ try {
181
+ $dirs = MainWP_Helper::getMainWPDir( 'backup', false );
182
+ $backupdir = $dirs[0];
183
+
184
+ $files = glob( $backupdir . '*' );
185
+ foreach ( $files as $file ) {
186
+ if ( MainWP_Helper::isArchive( $file ) ) {
187
+ @unlink( $file );
188
+ }
189
+ }
190
+ } catch ( Exception $e ) {
191
+
192
+ }
193
+ }
194
+
195
+ public function updateWPConfig() {
196
+ $wpConfig = file_get_contents( ABSPATH . 'wp-config.php' );
197
+ $wpConfig = $this->replaceVar( 'table_prefix', $this->config['prefix'], $wpConfig );
198
+ if ( isset( $this->config['lang'] ) ) {
199
+ $wpConfig = $this->replaceDefine( 'WPLANG', $this->config['lang'], $wpConfig );
200
+ }
201
+ file_put_contents( ABSPATH . 'wp-config.php', $wpConfig );
202
+ }
203
+
204
+ public function update_option( $name, $value ) {
205
+ /** @var $wpdb wpdb */
206
+ global $wpdb;
207
+
208
+ $var = $wpdb->get_var( $wpdb->prepare( 'SELECT option_value FROM ' . $this->config['prefix'] . 'options WHERE option_name = %s', $name) );
209
+ if ( null === $var ) {
210
+ $wpdb->query( $wpdb->prepare( 'INSERT INTO ' . $this->config['prefix'] . 'options (`option_name`, `option_value`) VALUES (%s, "' . MainWP_Child_DB::real_escape_string( maybe_serialize( $value ) ) . '")', $name) );
211
+ } else {
212
+ $wpdb->query( $wpdb->prepare( 'UPDATE ' . $this->config['prefix'] . 'options SET option_value = "' . MainWP_Child_DB::real_escape_string( maybe_serialize( $value ) ) . '" WHERE option_name = %s', $name) );
213
+ }
214
+ }
215
+
216
+ public function install() {
217
+ /** @var $wpdb wpdb */
218
+ global $wpdb;
219
+
220
+ $table_prefix = $this->config['prefix'];
221
+ $home = get_option( 'home' );
222
+ $site_url = get_option( 'siteurl' );
223
+ // Install database
224
+ define( 'WP_INSTALLING', true );
225
+ define( 'WP_DEBUG', false );
226
+ $query = '';
227
+ $tableName = '';
228
+ $wpdb->query( 'SET foreign_key_checks = 0' );
229
+
230
+ $files = glob( WP_CONTENT_DIR . '/dbBackup*.sql' );
231
+ foreach ( $files as $file ) {
232
+ $handle = @fopen( $file, 'r' );
233
+
234
+ $lastRun = 0;
235
+ if ( $handle ) {
236
+ $readline = '';
237
+ while ( ( $line = fgets( $handle, 81920 ) ) !== false ) {
238
+ if ( time() - $lastRun > 20 ) {
239
+ @set_time_limit( 0 ); //reset timer..
240
+ $lastRun = time();
241
+ }
242
+
243
+ $readline .= $line;
244
+ if ( ! stristr( $line, ";\n" ) && ! feof( $handle ) ) {
245
+ continue;
246
+ }
247
+
248
+ $splitLine = explode( ";\n", $readline );
249
+ $splitLineLength = count( $splitLine );
250
+ for ( $i = 0; $i < $splitLineLength - 1; $i ++ ) {
251
+ $wpdb->query( $splitLine[ $i ] );
252
+ }
253
+
254
+ $readline = $splitLine[ count( $splitLine ) - 1 ];
255
+ }
256
+
257
+ if ( trim( $readline ) != '' ) {
258
+ $wpdb->query( $readline );
259
+ }
260
+
261
+ if ( ! feof( $handle ) ) {
262
+ throw new Exception( __( 'Error: unexpected end of file for database.', 'mainwp-child' ) );
263
+ }
264
+ fclose( $handle );
265
+ }
266
+ }
267
+
268
+ $tables = array();
269
+ $tables_db = $wpdb->get_results( 'SHOW TABLES FROM `' . DB_NAME . '`', ARRAY_N );
270
+
271
+ foreach ( $tables_db as $curr_table ) {
272
+ // fix for more table prefix in one database
273
+ if ( ( strpos( $curr_table[0], $wpdb->prefix ) !== false ) || ( strpos( $curr_table[0], $table_prefix ) !== false ) ) {
274
+ $tables[] = $curr_table[0];
275
+ }
276
+ }
277
+ // Replace importance data first so if other replace failed, the website still work
278
+ $wpdb->query( $wpdb->prepare( 'UPDATE ' . $table_prefix . 'options SET option_value = %s WHERE option_name = "siteurl"', $site_url ) );
279
+ $wpdb->query( $wpdb->prepare( 'UPDATE ' . $table_prefix . 'options SET option_value = %s WHERE option_name = "home"', $home ) );
280
+ // Replace others
281
+ $this->icit_srdb_replacer( $wpdb->dbh, $this->config['home'], $home, $tables );
282
+ $this->icit_srdb_replacer( $wpdb->dbh, $this->config['siteurl'], $site_url, $tables );
283
+
284
+ $wpdb->query( 'SET foreign_key_checks = 1' );
285
+
286
+ return true;
287
+ }
288
+
289
+ protected function recalculateSerializedLengths( $pObject ) {
290
+ return preg_replace_callback( '|s:(\d+):"(.*?)";|', array(
291
+ $this,
292
+ 'recalculateSerializedLengths_callback',
293
+ ), $pObject );
294
+ }
295
+
296
+ protected function recalculateSerializedLengths_callback( $matches ) {
297
+ return 's:' . strlen( $matches[2] ) . ':"' . $matches[2] . '";';
298
+ }
299
+
300
+ /**
301
+ * Check value to find if it was serialized.
302
+ *
303
+ * If $data is not an string, then returned value will always be false.
304
+ * Serialized data is always a string.
305
+ *
306
+ * @since 2.0.5
307
+ *
308
+ * @param mixed $data Value to check to see if was serialized.
309
+ *
310
+ * @return bool False if not serialized and true if it was.
311
+ */
312
+ function is_serialized( $data ) {
313
+ // if it isn't a string, it isn't serialized
314
+ if ( ! is_string( $data ) ) {
315
+ return false;
316
+ }
317
+ $data = trim( $data );
318
+ if ( 'N;' === $data ) {
319
+ return true;
320
+ }
321
+ $length = strlen( $data );
322
+ if ( $length < 4 ) {
323
+ return false;
324
+ }
325
+ if ( ':' !== $data[1] ) {
326
+ return false;
327
+ }
328
+ $lastc = $data[ $length - 1 ];
329
+ if ( ';' !== $lastc && '}' !== $lastc ) {
330
+ return false;
331
+ }
332
+ $token = $data[0];
333
+ switch ( $token ) {
334
+ case 's' :
335
+ if ( '"' !== $data[ $length - 2 ] ) {
336
+ return false;
337
+ }
338
+ case 'a' :
339
+ case 'O' :
340
+ return (bool) preg_match( "/^{$token}:[0-9]+:/s", $data );
341
+ case 'b' :
342
+ case 'i' :
343
+ case 'd' :
344
+ return (bool) preg_match( "/^{$token}:[0-9.E-]+;\$/", $data );
345
+ }
346
+
347
+ return false;
348
+ }
349
+
350
+ public function cleanUp() {
351
+ // Clean up!
352
+ $files = glob( '../dbBackup*.sql' );
353
+ foreach ( $files as $file ) {
354
+ @unlink( $file );
355
+ }
356
+ }
357
+
358
+ public function getConfigContents() {
359
+ if ( 'extracted' === $this->file ) {
360
+ return file_get_contents( '../clone/config.txt' );
361
+ }
362
+
363
+ if ( ! $this->file || ! file_exists( $this->file ) ) {
364
+ return false;
365
+ }
366
+
367
+ if ( null !== $this->archiver ) {
368
+ if ( ! $this->archiver->isOpen() ) {
369
+ $this->archiver->read( $this->file );
370
+ }
371
+ $content = $this->archiver->getFromName( 'clone/config.txt' );
372
+
373
+ return $content;
374
+ } else {
375
+ if ( $this->checkZipConsole() ) {
376
+ //todo: implement
377
+ } else if ( $this->checkZipSupport() ) {
378
+ $zip = new ZipArchive();
379
+ $zipRes = $zip->open( $this->file );
380
+ if ( $zipRes ) {
381
+ $content = $zip->getFromName( 'clone/config.txt' );
382
+ // $zip->deleteName('clone/config.txt');
383
+ // $zip->deleteName('clone/');
384
+ $zip->close();
385
+
386
+ return $content;
387
+ }
388
+
389
+ return false;
390
+ } else {
391
+ //use pclzip
392
+ $zip = new PclZip( $this->file );
393
+ $content = $zip->extract( PCLZIP_OPT_BY_NAME, 'clone/config.txt',
394
+ PCLZIP_OPT_EXTRACT_AS_STRING );
395
+ if ( ! is_array( $content ) || ! isset( $content[0]['content'] ) ) {
396
+ return false;
397
+ }
398
+
399
+ return $content[0]['content'];
400
+ }
401
+ }
402
+
403
+ return false;
404
+ }
405
+
406
+ /**
407
+ * Extract backup
408
+ *
409
+ * @return bool
410
+ */
411
+ public function extractBackup() {
412
+ if ( ! $this->file || ! file_exists( $this->file ) ) {
413
+ return false;
414
+ }
415
+
416
+ if ( null !== $this->archiver ) {
417
+ if ( ! $this->archiver->isOpen() ) {
418
+ $this->archiver->read( $this->file );
419
+ }
420
+
421
+ return $this->archiver->extractTo( ABSPATH );
422
+ } else if ( ( filesize( $this->file ) >= 50000000 ) && $this->checkWPZip() ) {
423
+ return $this->extractWPZipBackup();
424
+ } else if ( $this->checkZipConsole() ) {
425
+ return $this->extractZipConsoleBackup();
426
+ } else if ( $this->checkZipSupport() ) {
427
+ return $this->extractZipBackup();
428
+ } else if ( ( filesize( $this->file ) < 50000000 ) && $this->checkWPZip() ) {
429
+ return $this->extractWPZipBackup();
430
+ } else {
431
+ return $this->extractZipPclBackup();
432
+ }
433
+ }
434
+
435
+ /**
436
+ * Extract backup using default PHP zip library
437
+ *
438
+ * @return bool
439
+ */
440
+ public function extractZipBackup() {
441
+ $zip = new ZipArchive();
442
+ $zipRes = $zip->open( $this->file );
443
+ if ( $zipRes ) {
444
+ @$zip->extractTo( ABSPATH );
445
+ $zip->close();
446
+
447
+ return true;
448
+ }
449
+
450
+ return false;
451
+ }
452
+
453
+ public function extractWPZipBackup() {
454
+ MainWP_Helper::getWPFilesystem();
455
+ global $wp_filesystem;
456
+
457
+ $tmpdir = ABSPATH;
458
+ if ( ( 'ftpext' === $wp_filesystem->method ) && defined( 'FTP_BASE' ) ) {
459
+ $ftpBase = FTP_BASE;
460
+ $ftpBase = trailingslashit( $ftpBase );
461
+ $tmpdir = str_replace( ABSPATH, $ftpBase, $tmpdir );
462
+ }
463
+
464
+ unzip_file( $this->file, $tmpdir );
465
+
466
+ return true;
467
+ }
468
+
469
+ public function extractZipPclBackup() {
470
+ $zip = new PclZip( $this->file );
471
+ if ( 0 === $zip->extract( PCLZIP_OPT_PATH, ABSPATH, PCLZIP_OPT_REPLACE_NEWER ) ) {
472
+ return false;
473
+ }
474
+ if ( $zip->error_code !== PCLZIP_ERR_NO_ERROR ) {
475
+ throw new Exception( $zip->errorInfo( true ) );
476
+ }
477
+
478
+ return true;
479
+ }
480
+
481
+ /**
482
+ * Extract backup using zip on console
483
+ *
484
+ * @return bool
485
+ */
486
+ public function extractZipConsoleBackup() {
487
+ //todo implement
488
+ //system('zip');
489
+ return false;
490
+ }
491
+
492
+ /**
493
+ * Replace define statement to work with wp-config.php
494
+ *
495
+ * @param string $constant The constant name
496
+ * @param string $value The new value
497
+ * @param string $content The PHP file content
498
+ *
499
+ * @return string Replaced define statement with new value
500
+ */
501
+ protected function replaceDefine( $constant, $value, $content ) {
502
+ return preg_replace( '/(define *\( *[\'"]' . $constant . '[\'"] *, *[\'"])(.*?)([\'"] *\))/is', '${1}' . $value . '${3}', $content );
503
+ }
504
+
505
+ /**
506
+ * Replace variable value to work with wp-config.php
507
+ *
508
+ * @param string $varname The variable name
509
+ * @param string $value The new value
510
+ * @param string $content The PHP file content
511
+ *
512
+ * @return string Replaced variable value with new value
513
+ */
514
+ protected function replaceVar( $varname, $value, $content ) {
515
+ return preg_replace( '/(\$' . $varname . ' *= *[\'"])(.*?)([\'"] *;)/is', '${1}' . $value . '${3}', $content );
516
+ }
517
+
518
+ function recurse_chmod( $mypath, $arg ) {
519
+ $d = opendir( $mypath );
520
+ while ( ( $file = readdir( $d ) ) !== false ) {
521
+ if ( '.' !== $file && '..' !== $file ) {
522
+ $typepath = $mypath . '/' . $file;
523
+ if ( 'dir' === filetype( $typepath ) ) {
524
+ recurse_chmod( $typepath, $arg );
525
+ }
526
+ chmod( $typepath, $arg );
527
+ }
528
+ }
529
+ }
530
+
531
+
532
+ /**
533
+ * The main loop triggered in step 5. Up here to keep it out of the way of the
534
+ * HTML. This walks every table in the db that was selected in step 3 and then
535
+ * walks every row and column replacing all occurences of a string with another.
536
+ * We split large tables into 50,000 row blocks when dealing with them to save
537
+ * on memmory consumption.
538
+ *
539
+ * @param mysql $connection The db connection object
540
+ * @param string $search What we want to replace
541
+ * @param string $replace What we want to replace it with.
542
+ * @param array $tables The tables we want to look at.
543
+ *
544
+ * @return array Collection of information gathered during the run.
545
+ */
546
+ function icit_srdb_replacer( $connection, $search = '', $replace = '', $tables = array() ) {
547
+ global $guid, $exclude_cols;
548
+
549
+ $report = array(
550
+ 'tables' => 0,
551
+ 'rows' => 0,
552
+ 'change' => 0,
553
+ 'updates' => 0,
554
+ 'start' => microtime(),
555
+ 'end' => microtime(),
556
+ 'errors' => array(),
557
+ );
558
+ if ( is_array( $tables ) && ! empty( $tables ) ) {
559
+ foreach ( $tables as $table ) {
560
+ $report['tables'] ++;
561
+
562
+ $columns = array();
563
+
564
+ // Get a list of columns in this table
565
+ $fields = MainWP_Child_DB::_query( 'DESCRIBE ' . $table, $connection );
566
+ while ( $column = MainWP_Child_DB::fetch_array( $fields ) ) {
567
+ $columns[ $column['Field'] ] = 'PRI' === $column['Key'] ? true : false;
568
+ }
569
+
570
+ // Count the number of rows we have in the table if large we'll split into blocks, This is a mod from Simon Wheatley
571
+ $row_count = MainWP_Child_DB::_query( 'SELECT COUNT(*) as count FROM ' . $table, $connection ); // to fix bug
572
+ $rows_result = MainWP_Child_DB::fetch_array( $row_count );
573
+ $row_count = $rows_result['count'];
574
+ if ( 0 === $row_count ) {
575
+ continue;
576
+ }
577
+
578
+ $page_size = 50000;
579
+ $pages = ceil( $row_count / $page_size );
580
+ for ( $page = 0; $page < $pages; $page ++ ) {
581
+ $current_row = 0;
582
+ $start = $page * $page_size;
583
+ $end = $start + $page_size;
584
+ // Grab the content of the table
585
+ $data = MainWP_Child_DB::_query( sprintf( 'SELECT * FROM %s LIMIT %d, %d', $table, $start, $end ), $connection );
586
+ if ( ! $data ) {
587
+ $report['errors'][] = MainWP_Child_DB::error();
588
+ }
589
+
590
+ while ( $row = MainWP_Child_DB::fetch_array( $data ) ) {
591
+
592
+ $report['rows'] ++; // Increment the row counter
593
+ $current_row ++;
594
+
595
+ $update_sql = array();
596
+ $where_sql = array();
597
+ $upd = false;
598
+
599
+ foreach ( $columns as $column => $primary_key ) {
600
+ if ( 1 === $guid && in_array( $column, $exclude_cols ) ) {
601
+ continue;
602
+ }
603
+
604
+ $edited_data = $data_to_fix = $row[ $column ];
605
+ // Run a search replace on the data that'll respect the serialisation.
606
+ $edited_data = $this->recursive_unserialize_replace( $search, $replace, $data_to_fix );
607
+ // Something was changed
608
+ if ( $edited_data !== $data_to_fix ) {
609
+ $report['change'] ++;
610
+ $update_sql[] = $column . ' = "' . MainWP_Child_DB::real_escape_string( $edited_data ) . '"';
611
+ $upd = true;
612
+ }
613
+
614
+ if ( $primary_key ) {
615
+ $where_sql[] = $column . ' = "' . MainWP_Child_DB::real_escape_string( $data_to_fix ) . '"';
616
+ }
617
+ }
618
+
619
+ if ( $upd && ! empty( $where_sql ) ) {
620
+ $sql = 'UPDATE ' . $table . ' SET ' . implode( ', ', $update_sql ) . ' WHERE ' . implode( ' AND ', array_filter( $where_sql ) );
621
+ $result = MainWP_Child_DB::_query( $sql, $connection );
622
+ if ( ! $result ) {
623
+ $report['errors'][] = MainWP_Child_DB::error();
624
+ } else {
625
+ $report['updates'] ++;
626
+ }
627
+ } elseif ( $upd ) {
628
+ $report['errors'][] = sprintf( '"%s" has no primary key, manual change needed on row %s.', $table, $current_row );
629
+ }
630
+ }
631
+ }
632
+ }
633
+ }
634
+ $report['end'] = microtime();
635
+
636
+ return $report;
637
+ }
638
+
639
+ /**
640
+ * Take a serialised array and unserialise it replacing elements as needed and
641
+ * unserialising any subordinate arrays and performing the replace on those too.
642
+ *
643
+ * @param string $from String we're looking to replace.
644
+ * @param string $to What we want it to be replaced with
645
+ * @param array $data Used to pass any subordinate arrays back to in.
646
+ * @param bool $serialised Does the array passed via $data need serialising.
647
+ *
648
+ * @return array The original array with all elements replaced as needed.
649
+ */
650
+
651
+ /* Fixed serialize issue */
652
+ function recursive_unserialize_replace( $from = '', $to = '', $data = '', $serialised = false ) {
653
+
654
+ // some unseriliased data cannot be re-serialised eg. SimpleXMLElements
655
+ try {
656
+
657
+ if ( is_string( $data ) && is_serialized( $data ) && !is_serialized_string( $data ) && ( $unserialized = @unserialize( $data ) ) !== false ) {
658
+ $data = $this->recursive_unserialize_replace( $from, $to, $unserialized, true );
659
+ } elseif ( is_array( $data ) ) {
660
+ $_tmp = array();
661
+ foreach ( $data as $key => $value ) {
662
+ $_tmp[ $key ] = $this->recursive_unserialize_replace( $from, $to, $value, false );
663
+ }
664
+
665
+ $data = $_tmp;
666
+ unset( $_tmp );
667
+ } elseif ( is_object( $data ) ) {
668
+ $_tmp = $data;
669
+ $props = get_object_vars( $data );
670
+ foreach ( $props as $key => $value ) {
671
+ $_tmp->{$key} = $this->recursive_unserialize_replace( $from, $to, $value, false );
672
+ }
673
+
674
+ $data = $_tmp;
675
+ unset( $_tmp );
676
+ } elseif (is_serialized_string($data) && is_serialized($data)) {
677
+ // TODO: apply solution like phpmyadmin project have!
678
+ if ( ($data = @unserialize( $data )) !== false ) {
679
+ $data = str_replace( $from, $to, $data );
680
+ $data = serialize( $data );
681
+ }
682
+ } else {
683
+ if ( is_string( $data ) ) {
684
+ $data = str_replace( $from, $to, $data );
685
+ }
686
+ }
687
+
688
+ if ( $serialised ) {
689
+ return serialize( $data );
690
+ }
691
+ } catch ( Exception $error ) {
692
+
693
+ }
694
+
695
+ return $data;
696
+ }
697
+ }
class/class-mainwp-clone.php ADDED
@@ -0,0 +1,1617 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class MainWP_Clone {
4
+ protected static $instance = null;
5
+ protected $security_nonces;
6
+
7
+ public static function get() {
8
+ if ( null === self::$instance ) {
9
+ self::$instance = new MainWP_Clone();
10
+ }
11
+
12
+ return self::$instance;
13
+ }
14
+
15
+ function addSecurityNonce( $action ) {
16
+ if ( ! is_array( $this->security_nonces ) ) {
17
+ $this->security_nonces = array();
18
+ }
19
+
20
+ if ( ! function_exists( 'wp_create_nonce' ) ) {
21
+ include_once( ABSPATH . WPINC . '/pluggable.php' );
22
+ }
23
+ $this->security_nonces[ $action ] = wp_create_nonce( $action );
24
+ }
25
+
26
+ function getSecurityNonces() {
27
+ return $this->security_nonces;
28
+ }
29
+
30
+ function addAction( $action, $callback ) {
31
+ add_action( 'wp_ajax_' . $action, $callback );
32
+ $this->addSecurityNonce( $action );
33
+ }
34
+
35
+ function secure_request( $action = '', $query_arg = 'security' ) {
36
+ if ( ! MainWP_Helper::isAdmin() ) {
37
+ die( 0 );
38
+ }
39
+ if ( $action == '' ) {
40
+ return;
41
+ }
42
+
43
+ if ( ! $this->check_security( $action, $query_arg ) ) {
44
+ die( json_encode( array( 'error' => __( 'Invalid request!', 'mainwp-child' ) ) ) );
45
+ }
46
+
47
+ if ( isset( $_POST['dts'] ) ) {
48
+ $ajaxPosts = get_option( 'mainwp_ajaxposts' );
49
+ if ( ! is_array( $ajaxPosts ) ) {
50
+ $ajaxPosts = array();
51
+ }
52
+
53
+ //If already processed, just quit!
54
+ if ( isset( $ajaxPosts[ $action ] ) && ( $ajaxPosts[ $action ] == $_POST['dts'] ) ) {
55
+ die( json_encode( array( 'error' => __( 'Double request!', 'mainwp-child' ) ) ) );
56
+ }
57
+
58
+ $ajaxPosts[ $action ] = $_POST['dts'];
59
+ MainWP_Helper::update_option( 'mainwp_ajaxposts', $ajaxPosts );
60
+ }
61
+ }
62
+
63
+ function check_security( $action = - 1, $query_arg = 'security' ) {
64
+ if ( $action == - 1 ) {
65
+ return false;
66
+ }
67
+
68
+ $adminurl = strtolower( admin_url() );
69
+ $referer = strtolower( wp_get_referer() );
70
+ $result = isset( $_REQUEST[ $query_arg ] ) ? wp_verify_nonce( $_REQUEST[ $query_arg ], $action ) : false;
71
+ if ( ! $result && ! ( - 1 == $action && strpos( $referer, $adminurl ) === 0 ) ) {
72
+ return false;
73
+ }
74
+
75
+ return true;
76
+ }
77
+
78
+ public function init() {
79
+ add_action( 'check_admin_referer', array( 'MainWP_Clone', 'permalinkChanged' ) );
80
+ if ( get_option( 'mainwp_child_clone_permalink' ) || get_option( 'mainwp_child_restore_permalink' ) ) {
81
+ add_action( 'admin_notices', array( 'MainWP_Clone', 'permalinkAdminNotice' ) );
82
+ }
83
+ }
84
+
85
+ public static function print_scripts() {
86
+ wp_enqueue_script( 'jquery-ui-tooltip' );
87
+ wp_enqueue_script( 'jquery-ui-autocomplete' );
88
+ wp_enqueue_script( 'jquery-ui-progressbar' );
89
+ wp_enqueue_script( 'jquery-ui-dialog' );
90
+
91
+ global $wp_scripts;
92
+ $ui = $wp_scripts->query( 'jquery-ui-core' );
93
+ $version = $ui->ver;
94
+ if ( MainWP_Helper::startsWith( $version, '1.10' ) ) {
95
+ wp_enqueue_style( 'jquery-ui-style', plugins_url( '/css/1.10.4/jquery-ui.min.css', dirname( __FILE__ ) ) );
96
+ } else {
97
+ wp_enqueue_style( 'jquery-ui-style', plugins_url( '/css/1.11.1/jquery-ui.min.css', dirname( __FILE__ ) ) );
98
+ }
99
+ }
100
+
101
+ public static function upload_mimes( $mime_types = array() ) {
102
+ if ( ! isset( $mime_types['tar.bz2'] ) ) {
103
+ $mime_types['tar.bz2'] = 'application/x-tar';
104
+ }
105
+
106
+ return $mime_types;
107
+ }
108
+
109
+ public static function render() {
110
+ $uploadError = false;
111
+ $uploadFile = false;
112
+ if ( isset( $_REQUEST['upload'] ) && wp_verify_nonce( $_POST['_nonce'], 'cloneRestore' ) ) {
113
+ if ( isset( $_FILES['file'] ) ) {
114
+ if ( ! function_exists( 'wp_handle_upload' ) ) {
115
+ require_once( ABSPATH . 'wp-admin/includes/file.php' );
116
+ }
117
+ $uploadedfile = $_FILES['file'];
118
+ $upload_overrides = array( 'test_form' => false );
119
+ add_filter( 'upload_mimes', array( 'MainWP_Clone', 'upload_mimes' ) );
120
+ $movefile = wp_handle_upload( $uploadedfile, $upload_overrides );
121
+ if ( $movefile ) {
122
+ $uploadFile = str_replace( ABSPATH, '', $movefile['file'] );
123
+ } else {
124
+ $uploadError = __( 'File could not be uploaded.', 'mainwp-child' );
125
+ }
126
+ } else {
127
+ $uploadError = __( 'File is empty. Please upload something more substantial. This error could also be caused by uploads being disabled in your php.ini or by post_max_size being defined as smaller than upload_max_filesize in php.ini.', 'mainwp-child' );
128
+ }
129
+ }
130
+
131
+ $sitesToClone = get_option( 'mainwp_child_clone_sites' );
132
+ $uploadSizeInBytes = min( MainWP_Helper::return_bytes( ini_get( 'upload_max_filesize' ) ), MainWP_Helper::return_bytes( ini_get( 'post_max_size' ) ) );
133
+ $uploadSize = MainWP_Helper::human_filesize( $uploadSizeInBytes );
134
+ self::renderStyle();
135
+
136
+ if ( '0' === $sitesToClone ) {
137
+ echo '<div class="mainwp-child_info-box-red"><strong>' . esc_html__( 'Cloning is currently off - To turn on return to your main dashboard and turn cloning on on the Clone page.', 'mainwp-child' ) . '</strong></div>';
138
+
139
+ return;
140
+ }
141
+ $error = false;
142
+ MainWP_Helper::getWPFilesystem();
143
+ global $wp_filesystem;
144
+ if ( ( ! empty( $wp_filesystem ) && ! $wp_filesystem->is_writable( WP_CONTENT_DIR ) ) || ( empty( $wp_filesystem ) && ! is_writable( WP_CONTENT_DIR ) ) ) {
145
+ echo '<div class="mainwp-child_info-box-red"><strong>' . esc_html__( 'Your content directory is not writable. Please set 0755 permission to ', 'mainwp-child' ) . esc_html( basename( WP_CONTENT_DIR ) ) . '. (' . esc_html( WP_CONTENT_DIR ) . ')</strong></div>';
146
+ $error = true;
147
+ }
148
+ ?>
149
+ <div class="mainwp-child_info-box-green"
150
+ style="display: none;"><?php esc_html_e( 'Cloning process completed successfully! You will now need to click ', 'mainwp-child' ); ?>
151
+ <a href="<?php echo esc_url( admin_url( 'options-permalink.php' ) ); ?>"><?php esc_html_e( 'here', 'mainwp-child' ); ?></a><?php esc_html_e( ' to re-login to the admin and re-save permalinks.', 'mainwp-child' ); ?>
152
+ </div>
153
+
154
+ <?php
155
+ if ( $uploadFile ) {
156
+ esc_html_e( 'Upload successful.', 'mainwp-child' ); ?> <a href="#" id="mainwp-child_uploadclonebutton"
157
+ class="button-primary"
158
+ file="<?php echo esc_attr( $uploadFile ); ?>"><?php esc_html_e( 'Clone/Restore website', 'mainwp-child' ); ?></a><?php
159
+ } else {
160
+ if ( $uploadError ) {
161
+ ?>
162
+ <div class="mainwp-child_info-box-red"><?php echo esc_html( $uploadError ); ?></div><?php
163
+ }
164
+
165
+ if ( empty( $sitesToClone ) ) {
166
+ echo '<div class="mainwp-child_info-box-yellow"><strong>' . esc_html__( 'Cloning is currently on but no sites have been allowed, to allow sites return to your main dashboard and turn cloning on on the Clone page.', 'mainwp-child' ) . '</strong></div>';
167
+ } else {
168
+ ?>
169
+ <form method="post" action="">
170
+ <div class="mainwp-child_select_sites_box">
171
+ <div class="postbox">
172
+
173
+ <div class="mainwp-child_displayby"><?php esc_html_e( 'Display by:', 'mainwp-child' ); ?> <a
174
+ class="mainwp-child_action left mainwp-child_action_down" href="#"
175
+ id="mainwp-child_displayby_sitename"><?php esc_html_e( 'Site Name', 'mainwp-child' ); ?></a><a
176
+ class="mainwp-child_action right" href="#"
177
+ id="mainwp-child_displayby_url"><?php esc_html_e( 'URL', 'mainwp-child' ); ?></a></div>
178
+ <h2 class="hndle"><?php esc_html_e( 'Select Source for clone', 'mainwp-child' ); ?></h2>
179
+ <div class="inside">
180
+ <div id="mainwp-child_clonesite_select_site">
181
+ <?php
182
+ foreach ( $sitesToClone as $siteId => $siteToClone ) {
183
+ ?>
184
+ <div class="clonesite_select_site_item" id="<?php echo esc_attr( $siteId ); ?>"
185
+ rand="<?php echo esc_attr( MainWP_Helper::randString( 5 ) ); ?>">
186
+ <div class="mainwp-child_size_label"
187
+ size="<?php echo esc_attr( $siteToClone['size'] ); ?>"><?php echo esc_html( $siteToClone['size'] ); ?>
188
+ MB
189
+ </div>
190
+ <div
191
+ class="mainwp-child_name_label"><?php echo esc_html( $siteToClone['name'] ); ?></div>
192
+ <div
193
+ class="mainwp-child_url_label"><?php echo esc_html( MainWP_Helper::getNiceURL( $siteToClone['url'] ) ); ?></div>
194
+ </div>
195
+ <?php
196
+ }
197
+ ?>
198
+ </div>
199
+ <p><?php _e("The site selected above will replace this site's files and database", 'mainwp-child'); ?></p>
200
+ </div>
201
+ <div class="mainwp-child_clonebutton_container"><?php if ( ! $error ) { ?>
202
+ <a href="#"
203
+ id="mainwp-child_clonebutton"
204
+ class="button-primary"><?php esc_html_e( 'Clone website', 'mainwp-child' ); ?></a><?php } ?>
205
+ </div>
206
+ <div style="clear:both"></div>
207
+ </div>
208
+ </div>
209
+ </form>
210
+ <br/>
211
+ <?php
212
+ }
213
+ $sitesToClone = get_option( 'mainwp_child_clone_sites' );
214
+ ?>
215
+ <div class="postbox">
216
+ <h2 class="hndle"><strong><?php esc_html_e( 'Option 1:', 'mainwp-child' ); ?></strong> <?php esc_html_e( 'Restore/Clone from backup', 'mainwp-child' ); ?></h2>
217
+ <div class="inside">
218
+ <p><?php esc_html_e( 'Upload backup in .zip format (Maximum filesize for your server settings: ', 'mainwp-child' ); ?><?php echo esc_html( $uploadSize ); ?>)</p>
219
+ <em><?php esc_html_e( 'If you have a FULL backup created by the default MainWP Backup system you may restore it by uploading here. Backups created by 3rd party plugins will not work.', 'mainwp-child' ); ?>
220
+ <br/>
221
+ <?php esc_html_e( 'A database only backup will not work.', 'mainwp-child' ); ?></em>
222
+ <br/>
223
+ <br/>
224
+ <form
225
+ action="<?php echo esc_attr( admin_url( 'options-general.php?page=mainwp_child_tab&tab=restore-clone&upload=yes' ) ); ?>"
226
+ method="post"
227
+ enctype="multipart/form-data">
228
+ <input type="file" name="file" id="file"/>
229
+ <input type="submit"
230
+ name="submit"
231
+ id="filesubmit"
232
+ class="button button-primary"
233
+ disabled="disabled"
234
+ value="<?php esc_attr_e( 'Clone/Restore Website', 'mainwp-child' ); ?>"/>
235
+ <input type="hidden" name="_nonce" value="<?php echo wp_create_nonce( 'cloneRestore' ); ?>" />
236
+ </form>
237
+ </div>
238
+ </div>
239
+ <?php
240
+ }
241
+
242
+ self::renderCloneFromServer();
243
+
244
+ self::renderJavaScript();
245
+ }
246
+
247
+ public static function renderNormalRestore() {
248
+ $uploadError = false;
249
+ $uploadFile = false;
250
+ if ( isset( $_REQUEST['upload'] ) && wp_verify_nonce( $_POST['_nonce'], 'cloneRestore' ) ) {
251
+ if ( isset( $_FILES['file'] ) ) {
252
+ if ( ! function_exists( 'wp_handle_upload' ) ) {
253
+ require_once( ABSPATH . 'wp-admin/includes/file.php' );
254
+ }
255
+ $uploadedfile = $_FILES['file'];
256
+ $upload_overrides = array( 'test_form' => false );
257
+ $movefile = wp_handle_upload( $uploadedfile, $upload_overrides );
258
+ if ( $movefile ) {
259
+ $uploadFile = str_replace( ABSPATH, '', $movefile['file'] );
260
+ } else {
261
+ $uploadError = __( 'File could not be uploaded.', 'mainwp-child' );
262
+ }
263
+ } else {
264
+ $uploadError = __( 'File is empty. Please upload something more substantial. This error could also be caused by uploads being disabled in your php.ini or by post_max_size being defined as smaller than upload_max_filesize in php.ini.', 'mainwp-child' );
265
+ }
266
+ }
267
+
268
+ $uploadSizeInBytes = min( MainWP_Helper::return_bytes( ini_get( 'upload_max_filesize' ) ), MainWP_Helper::return_bytes( ini_get( 'post_max_size' ) ) );
269
+ $uploadSize = MainWP_Helper::human_filesize( $uploadSizeInBytes );
270
+ self::renderStyle();
271
+
272
+ ?>
273
+ <div class="postbox">
274
+ <h2 class="hndle"><span><strong><?php esc_html_e( 'Option 1:', 'mainwp-child' ); ?></strong> <?php esc_html_e( 'Restore', 'mainwp-child' ); ?></span></h2>
275
+ <div class="inside">
276
+
277
+ <?php
278
+ MainWP_Helper::getWPFilesystem();
279
+ global $wp_filesystem;
280
+ if ( ( ! empty( $wp_filesystem ) && ! $wp_filesystem->is_writable( WP_CONTENT_DIR ) ) || ( empty( $wp_filesystem ) && ! is_writable( WP_CONTENT_DIR ) ) ) {
281
+ echo '<div class="mainwp-child_info-box-red"><strong>' . esc_html__( 'Your content directory is not writable. Please set 0755 permission to ', 'mainwp-child' ) . esc_html( basename( WP_CONTENT_DIR ) ) . '. (' . esc_html( WP_CONTENT_DIR ) . ')</strong></div>';
282
+ $error = true;
283
+ }
284
+ ?>
285
+ <div class="mainwp-child_info-box-green" style="display: none;"><?php esc_html_e( 'Restore process completed successfully! You will now need to click ', 'mainwp-child' ); ?>
286
+ <a href="<?php echo esc_attr( admin_url( 'options-permalink.php' ) ); ?>"><?php esc_html_e( 'here', 'mainwp-child' ); ?></a><?php esc_html_e( ' to re-login to the admin and re-save permalinks.', 'mainwp-child' ); ?>
287
+ </div>
288
+ <?php
289
+ if ( $uploadFile ) {
290
+ esc_html_e( 'Upload successful.', 'mainwp-child' ); ?> <a href="#"
291
+ id="mainwp-child_uploadclonebutton"
292
+ class="button-primary"
293
+ file="<?php echo esc_attr( $uploadFile ); ?>"><?php esc_html_e( 'Restore Website', 'mainwp-child' ); ?></a><?php
294
+ } else {
295
+ if ( $uploadError ) {
296
+ ?>
297
+ <div class="mainwp-child_info-box-red"><?php echo esc_html( $uploadError ); ?></div>
298
+ <?php
299
+ }
300
+ ?>
301
+ <p><?php esc_html_e( 'Upload backup in .zip format (Maximum filesize for your server settings: ', 'mainwp-child' ); ?><?php echo esc_html( $uploadSize ); ?>)</p>
302
+ <?php
303
+ $branding_msg = '';
304
+ if ( MainWP_Child_Branding::is_branding() ) {
305
+ $branding_title = MainWP_Child_Branding::get_branding();
306
+ $branding_msg = 'If you have a FULL backup created by basic ' . esc_html( stripslashes( $branding_title ) ) . ' Backup system you may restore it by uploading here. Backups created by 3rd party plugins will not work.';
307
+ }
308
+ ?>
309
+ <em>
310
+ <?php
311
+ if ($branding_msg != '') {
312
+ echo $branding_msg ;
313
+ } else {
314
+ esc_html_e( 'If you have a FULL backup created by basic MainWP Backup system you may restore it by uploading here. Backups created by 3rd party plugins will not work.', 'mainwp-child' );
315
+ }
316
+ ?>
317
+ <br/>
318
+ <?php esc_html_e( 'A database only backup will not work.', 'mainwp-child' ); ?></em><br/><br/>
319
+ <form action="<?php echo esc_attr( admin_url( 'options-general.php?page=mainwp_child_tab&tab=restore-clone&upload=yes' ) ); ?>"
320
+ method="post"
321
+ enctype="multipart/form-data">
322
+ <input type="file" name="file" id="file"/>
323
+ <input type="submit"
324
+ name="submit"
325
+ class="button button-primary"
326
+ id="filesubmit"
327
+ disabled="disabled"
328
+ value="<?php esc_html_e( 'Restore Website', 'mainwp-child' ); ?>"/>
329
+ <input type="hidden" name="_nonce" value="<?php echo wp_create_nonce( 'cloneRestore' ); ?>" />
330
+ </form>
331
+ <?php } ?>
332
+ </div>
333
+ </div>
334
+ <?php
335
+
336
+ self::renderCloneFromServer();
337
+ self::renderJavaScript();
338
+ }
339
+
340
+ /*
341
+ Plugin Name: Add From Server
342
+ Version: 3.2.0.3
343
+ Plugin URI: http://dd32.id.au/wordpress-plugins/add-from-server/
344
+ Description: Plugin to allow the Media Manager to add files from the webservers filesystem. <strong>Note:</strong> All files are copied to the uploads directory.
345
+ Author: Dion Hulse
346
+ Author URI: http://dd32.id.au/
347
+ */
348
+
349
+ public static function renderCloneFromServer() {
350
+
351
+ $page = $_REQUEST['page'];
352
+
353
+ $sitesToClone = get_option( 'mainwp_child_clone_sites' );
354
+ $url = admin_url( 'options-general.php?page=mainwp_child_tab&tab=restore-clone#title_03' );
355
+
356
+ $dirs = MainWP_Helper::getMainWPDir( 'backup', false );
357
+ $current_dir = $backup_dir = $dirs[0];
358
+
359
+ if ( isset( $_REQUEST['dir'] ) ) {
360
+ $current_dir = stripslashes( urldecode( $_REQUEST['dir'] ) );
361
+ $current_dir = '/' . ltrim( $current_dir, '/' );
362
+ if ( ! is_readable( $current_dir ) && get_option( 'mainwp_child_clone_from_server_last_folder' ) ) {
363
+ $current_dir = get_option( 'mainwp_child_clone_from_server_last_folder' ) . $current_dir;
364
+ }
365
+ }
366
+
367
+ if ( ! is_readable( $current_dir ) ) {
368
+ $current_dir = WP_CONTENT_DIR;
369
+ }
370
+
371
+ $current_dir = str_replace( '\\', '/', $current_dir );
372
+
373
+ if ( strlen( $current_dir ) > 1 ) {
374
+ $current_dir = untrailingslashit( $current_dir );
375
+ }
376
+ echo '<div class="postbox">';
377
+ echo '<h2 id="title_03" class="hndle"><span><strong>' . esc_html__( 'Option 2:', 'mainwp-child' ) . '</strong> ' . esc_html__( 'Restore/Clone From Server', 'mainwp-child' ) . '</span></h2>';
378
+ echo '<div class="inside">';
379
+ echo '<em>' . esc_html__( 'If you have uploaded a FULL backup to your server (via FTP or other means) you can use this section to locate the zip file and select it. A database only backup will not work.', 'mainwp-child' ) . '</em>';
380
+
381
+ if ( ! is_readable( $current_dir ) ) {
382
+ echo '<div class="mainwp-child_info-box-yellow"><strong>' . esc_html__( 'Root directory is not readable. Please contact with site administrator to correct.', 'mainwp-child' ) . '</strong></div>';
383
+
384
+ return;
385
+ }
386
+ MainWP_Helper::update_option( 'mainwp_child_clone_from_server_last_folder', rtrim( $current_dir, '/' ) );
387
+
388
+ $parts = explode( '/', ltrim( $current_dir, '/' ) );
389
+ $dirparts = '';
390
+ for ( $i = count( $parts ) - 1; $i >= 0; $i -- ) {
391
+ $part = $parts[ $i ];
392
+ $adir = implode( '/', array_slice( $parts, 0, $i + 1 ) );
393
+ if ( strlen( $adir ) > 1 ) {
394
+ $adir = ltrim( $adir, '/' );
395
+ }
396
+ $durl = esc_url( add_query_arg( array( 'dir' => rawurlencode( $adir ) ), $url ) );
397
+ $dirparts = '<a href="' . $durl . '">' . $part . DIRECTORY_SEPARATOR . '</a>' . $dirparts;
398
+ }
399
+
400
+ echo '<div style="padding: 8px 12px; background-color: #e5e5e5; margin-top: 1em;">' . __( '<strong>Current Directory:</strong> <span>' . $dirparts . '</span>', 'mainwp-child' ) . '</div>';
401
+ $quick_dirs = array();
402
+ $quick_dirs[] = array( __( 'Site Root', 'mainwp-child' ), ABSPATH );
403
+ $quick_dirs[] = array( __( 'Backup', 'mainwp-child' ), $backup_dir );
404
+ if ( ( $uploads = wp_upload_dir() ) && false === $uploads['error'] ) {
405
+ $quick_dirs[] = array( __( 'Uploads Folder', 'mainwp-child' ), $uploads['path'] );
406
+ }
407
+ $quick_dirs[] = array( __( 'Content Folder', 'mainwp-child' ), WP_CONTENT_DIR );
408
+
409
+ $quick_links = array();
410
+ foreach ( $quick_dirs as $dir ) {
411
+ list( $text, $adir ) = $dir;
412
+ $adir = str_replace( '\\', '/', strtolower( $adir ) );
413
+ if ( strlen( $adir ) > 1 ) {
414
+ $adir = ltrim( $adir, '/' );
415
+ }
416
+ $durl = esc_url( add_query_arg( array( 'dir' => rawurlencode( $adir ) ), $url ) );
417
+ $quick_links[] = "<a href='$durl'>$text</a>";
418
+ }
419
+
420
+ if ( ! empty( $quick_links ) ) {
421
+ echo '<div style="padding: 8px 12px; border-bottom: 1px solid #e5e5e5; margin-bottom: 1em;"><strong>' . esc_html__( 'Quick Jump:', 'mainwp-child' ) . '</strong> ' . __( implode( ' | ', $quick_links ) ) . '</div>';
422
+ }
423
+
424
+ $dir_files = scandir( $current_dir );
425
+ $directories = array();
426
+ $files = array();
427
+ $rejected_files = array();
428
+ foreach ( (array) $dir_files as $file ) {
429
+ if ( in_array( $file, array( '.', '..' ) ) ) {
430
+ continue;
431
+ }
432
+ if ( is_dir( $current_dir . '/' . $file ) ) {
433
+ $directories[] = $file;
434
+ } else {
435
+ if ( ! MainWP_Helper::isArchive( $file ) ) {
436
+ $rejected_files[] = $file;
437
+ } else {
438
+ $files[] = $file;
439
+ }
440
+ }
441
+ }
442
+
443
+ sort( $directories );
444
+ sort( $files );
445
+ $parent = dirname( $current_dir );
446
+ ?>
447
+
448
+ <form method="post" action="">
449
+ <div class="mainwp-child_select_sites_box" id="mainwp_child_select_files_from_server_box">
450
+ <div class="postbox">
451
+ <h2 class="hndle"><?php esc_html_e( 'Select File', 'mainwp-child' ); ?></h2>
452
+
453
+ <div class="inside">
454
+ <div id="mainwp-child_clonesite_select_site">
455
+ <div class="clonesite_select_site_item">
456
+ <div class="mainwp-child_name_label">
457
+ <a href="<?php echo esc_url( add_query_arg( array( 'dir' => rawurlencode( $parent ) ), $url ) ); ?>"
458
+ title="<?php echo esc_attr( dirname( $current_dir ) ) ?>"><?php esc_html_e( 'Parent Folder', 'mainwp-child' ) ?></a>
459
+ </div>
460
+ </div>
461
+
462
+ <?php
463
+ foreach ( (array) $directories as $file ) {
464
+ $filename = ltrim( $file, '/' );
465
+ $folder_url = esc_url( add_query_arg( array( 'dir' => rawurlencode( $filename ) ), $url ) );
466
+ ?>
467
+ <div class="clonesite_select_site_item">
468
+ <div class="mainwp-child_name_label">
469
+ <a href="<?php echo esc_attr( $folder_url ) ?>"><?php echo esc_html( rtrim( $filename, '/' ) . DIRECTORY_SEPARATOR ); ?></a>
470
+ </div>
471
+ </div>
472
+ <?php
473
+ }
474
+
475
+ foreach ( $files as $file ) {
476
+ ?>
477
+ <div class="clonesite_select_site_item">
478
+ <div class="mainwp-child_name_label">
479
+ <span><?php echo esc_html( $file ) ?></span>
480
+ </div>
481
+ </div>
482
+ <?php
483
+ }
484
+
485
+ foreach ( $rejected_files as $file ) {
486
+ ?>
487
+ <div class="mainwp_rejected_files">
488
+ <div class="mainwp-child_name_label">
489
+ <span><?php echo esc_html( $file ) ?></span>
490
+ </div>
491
+ </div>
492
+ <?php
493
+ }
494
+
495
+ ?>
496
+ </div>
497
+ </div>
498
+ <div class="mainwp-child_clonebutton_container"><a href="#"
499
+ id="mainwp-child_clonebutton_from_server"
500
+ class="button-primary button"><?php esc_html_e( 'Clone/Restore Website', 'mainwp-child' ); ?></a>
501
+ </div>
502
+ <div style="clear:both"></div>
503
+ </div>
504
+ </div>
505
+ </form>
506
+ <input type="hidden" id="clonesite_from_server_current_dir" value="<?php echo esc_attr( $current_dir ); ?>"/>
507
+ </div>
508
+ </div>
509
+ <?php
510
+ }
511
+
512
+ public static function renderJavaScript() {
513
+ $uploadSizeInBytes = min( MainWP_Helper::return_bytes( ini_get( 'upload_max_filesize' ) ), MainWP_Helper::return_bytes( ini_get( 'post_max_size' ) ) );
514
+ $uploadSize = MainWP_Helper::human_filesize( $uploadSizeInBytes );
515
+ ?>
516
+ <div id="mainwp-child_clone_status" title="Restore process"></div>
517
+ <script language="javascript">
518
+ var child_security_nonces = [];
519
+ <?php
520
+ $security_nonces = MainWP_Clone::get()->getSecurityNonces();
521
+ foreach ($security_nonces as $k => $v)
522
+ {
523
+ echo 'child_security_nonces['."'" .$k . "'". '] = ' . "'" . $v . "';\n";
524
+ }
525
+ ?>
526
+
527
+ mainwpchild_secure_data = function(data, includeDts)
528
+ {
529
+ if (data['action'] == undefined) return data;
530
+
531
+ data['security'] = child_security_nonces[data['action']];
532
+ if (includeDts) data['dts'] = Math.round(new Date().getTime() / 1000);
533
+ return data;
534
+ };
535
+
536
+ jQuery( document ).on( 'change', '#file', function () {
537
+ var maxSize = <?php echo esc_js( $uploadSizeInBytes ); ?>;
538
+ var humanSize = '<?php echo esc_js( $uploadSize ); ?>';
539
+
540
+ if ( this.files[0].size > maxSize ) {
541
+ jQuery( '#filesubmit' ).attr( 'disabled', 'disabled' );
542
+ alert( 'The selected file is bigger than your maximum allowed filesize. (Maximum: ' + humanSize + ')' );
543
+ }
544
+ else {
545
+ jQuery( '#filesubmit' ).removeAttr( 'disabled' );
546
+ }
547
+ } );
548
+ jQuery( document ).on( 'click', '#mainwp-child_displayby_sitename', function () {
549
+ jQuery( '#mainwp-child_displayby_url' ).removeClass( 'mainwp-child_action_down' );
550
+ jQuery( this ).addClass( 'mainwp-child_action_down' );
551
+ jQuery( '.mainwp-child_url_label' ).hide();
552
+ jQuery( '.mainwp-child_name_label' ).show();
553
+ return false;
554
+ } );
555
+ jQuery( document ).on( 'click', '#mainwp-child_displayby_url', function () {
556
+ jQuery( '#mainwp-child_displayby_sitename' ).removeClass( 'mainwp-child_action_down' );
557
+ jQuery( this ).addClass( 'mainwp-child_action_down' );
558
+ jQuery( '.mainwp-child_name_label' ).hide();
559
+ jQuery( '.mainwp-child_url_label' ).show();
560
+ return false;
561
+ } );
562
+ jQuery( document ).on( 'click', '.clonesite_select_site_item', function () {
563
+ jQuery( '.clonesite_select_site_item' ).removeClass( 'selected' );
564
+ jQuery( this ).addClass( 'selected' );
565
+ } );
566
+
567
+ var pollingCreation = undefined;
568
+ var backupCreationFinished = false;
569
+
570
+ var pollingDownloading = undefined;
571
+ var backupDownloadFinished = false;
572
+
573
+ handleCloneError = function ( resp ) {
574
+ updateClonePopup( resp.error, true, 'red' );
575
+ };
576
+
577
+ updateClonePopup = function ( pText, pShowDate, pColor ) {
578
+ if ( pShowDate == undefined ) pShowDate = true;
579
+
580
+ var theDiv = jQuery( '#mainwp-child_clone_status' );
581
+ theDiv.append( '<br /><span style="color: ' + pColor + ';">' + (pShowDate ? cloneDateToHMS( new Date() ) + ' ' : '') + pText + '</span>' );
582
+ theDiv.animate( {scrollTop: theDiv.height() * 2}, 100 );
583
+ };
584
+
585
+ cloneDateToHMS = function ( date ) {
586
+ var h = date.getHours();
587
+ var m = date.getMinutes();
588
+ var s = date.getSeconds();
589
+ return '' + (h <= 9 ? '0' + h : h) + ':' + (m <= 9 ? '0' + m : m) + ':' + (s <= 9 ? '0' + s : s);
590
+ };
591
+
592
+ var translations = [];
593
+ translations['large_site'] = "<?php esc_html_e( 'This is a large site (%dMB), the restore process will more than likely fail.', 'mainwp-child' ); ?>";
594
+ translations['continue_anyway'] = "<?php esc_html_e( 'Continue Anyway?', 'mainwp-child' ); ?>";
595
+ translations['creating_backup'] = "<?php esc_html_e( 'Creating backup on %s expected size: %dMB (estimated time: %d seconds)', 'mainwp-child' ); ?>";
596
+ translations['backup_created'] = "<?php esc_html_e( 'Backup created on %s total size to download: %dMB', 'mainwp-child' ); ?>";
597
+ translations['downloading_backup'] = "<?php esc_html_e( 'Downloading backup', 'mainwp-child' ); ?>";
598
+ translations['backup_downloaded'] = "<?php esc_html_e( 'Backup downloaded', 'mainwp-child' ); ?>";
599
+ translations['extracting_backup'] = "<?php esc_html_e( 'Extracting backup and updating your database, this might take a while. Please be patient.', 'mainwp-child' ); ?>";
600
+ translations['clone_complete'] = "<?php esc_html_e( 'Cloning process completed successfully!', 'mainwp-child' ); ?>";
601
+
602
+ cloneInitiateBackupCreation = function ( siteId, siteName, size, rand, continueAnyway ) {
603
+ if ( (continueAnyway == undefined) && (size > 256) ) {
604
+ updateClonePopup( mwp_sprintf( translations['large_site'], size ) + ' <a href="#" class="button continueCloneButton" onClick="cloneInitiateBackupCreation(' + "'" + siteId + "'" + ', ' + "'" + siteName + "'" + ', ' + size + ', ' + "'" + rand + "'" + ', true); return false;">' + translations['continue_anyway'] + '</a>' );
605
+ return;
606
+ }
607
+ else {
608
+ jQuery( '.continueCloneButton' ).hide();
609
+ }
610
+
611
+ size = size / 2.4; //Guessing how large the zip will be
612
+
613
+ //5 mb every 10 seconds
614
+ updateClonePopup( mwp_sprintf( translations['creating_backup'], siteName, size.toFixed( 2 ), (size / 5 * 3).toFixed( 2 ) ) );
615
+
616
+ updateClonePopup( '<div id="mainwp-child-clone-create-progress" style="margin-top: 1em !important;"></div>', false );
617
+ jQuery( '#mainwp-child-clone-create-progress' ).progressbar( {value: 0, max: (size * 1024)} );
618
+
619
+ var data = mainwpchild_secure_data({
620
+ action: 'mainwp-child_clone_backupcreate',
621
+ siteId: siteId,
622
+ rand: rand
623
+ });
624
+
625
+ jQuery.post( ajaxurl, data, function ( pSiteId, pSiteName ) {
626
+ return function ( resp ) {
627
+ backupCreationFinished = true;
628
+ clearTimeout( pollingCreation );
629
+
630
+ var progressBar = jQuery( '#mainwp-child-clone-create-progress' );
631
+ progressBar.progressbar( 'value', parseFloat( progressBar.progressbar( 'option', 'max' ) ) );
632
+
633
+ if ( resp.error ) {
634
+ handleCloneError( resp );
635
+ return;
636
+ }
637
+ updateClonePopup( mwp_sprintf( translations['backup_created'], pSiteName, (resp.size / 1024).toFixed( 2 ) ) );
638
+ //update view;
639
+ cloneInitiateBackupDownload( pSiteId, resp.url, resp.size );
640
+ }
641
+ }( siteId, siteName ), 'json' );
642
+
643
+ //Poll for filesize 'till it's complete
644
+ pollingCreation = setTimeout( function () {
645
+ cloneBackupCreationPolling( siteId, rand );
646
+ }, 1000 );
647
+ };
648
+
649
+ cloneBackupCreationPolling = function ( siteId, rand ) {
650
+ if ( backupCreationFinished ) return;
651
+
652
+ var data = mainwpchild_secure_data({
653
+ action: 'mainwp-child_clone_backupcreatepoll',
654
+ siteId: siteId,
655
+ rand: rand
656
+ });
657
+
658
+ jQuery.post( ajaxurl, data, function ( pSiteId, pRand ) {
659
+ return function ( resp ) {
660
+ if ( backupCreationFinished ) return;
661
+ if ( resp.size ) {
662
+ var progressBar = jQuery( '#mainwp-child-clone-create-progress' );
663
+ if ( progressBar.progressbar( 'option', 'value' ) < progressBar.progressbar( 'option', 'max' ) ) {
664
+ progressBar.progressbar( 'value', resp.size );
665
+ }
666
+
667
+ //Also update estimated time?? ETA??
668
+ }
669
+ pollingCreation = setTimeout( function () {
670
+ cloneBackupCreationPolling( pSiteId, pRand );
671
+ }, 1000 );
672
+ }
673
+ }( siteId, rand ), 'json' );
674
+ };
675
+
676
+ cloneInitiateBackupDownload = function ( pSiteId, pFile, pSize ) {
677
+ updateClonePopup( translations['downloading_backup'] );
678
+
679
+ updateClonePopup( '<div id="mainwp-child-clone-download-progress" style="margin-top: 1em !important;"></div>', false );
680
+ jQuery( '#mainwp-child-clone-download-progress' ).progressbar( {value: 0, max: pSize} );
681
+
682
+ var data = mainwpchild_secure_data({
683
+ action: 'mainwp-child_clone_backupdownload',
684
+ file: pFile
685
+ });
686
+
687
+ if ( pSiteId != undefined ) data['siteId'] = pSiteId;
688
+
689
+ jQuery.post( ajaxurl, data, function ( siteId ) {
690
+ return function ( resp ) {
691
+ backupDownloadFinished = true;
692
+ clearTimeout( pollingDownloading );
693
+
694
+ var progressBar = jQuery( '#mainwp-child-clone-download-progress' );
695
+ progressBar.progressbar( 'value', parseFloat( progressBar.progressbar( 'option', 'max' ) ) );
696
+
697
+ if ( resp.error ) {
698
+ handleCloneError( resp );
699
+ return;
700
+ }
701
+ updateClonePopup( translations['backup_downloaded'] );
702
+
703
+ //update view
704
+ cloneInitiateExtractBackup();
705
+ }
706
+ }( pSiteId ), 'json' );
707
+
708
+ //Poll for filesize 'till it's complete
709
+ pollingDownloading = setTimeout( function () {
710
+ cloneBackupDownloadPolling( pSiteId, pFile );
711
+ }, 1000 );
712
+ };
713
+
714
+ cloneBackupDownloadPolling = function ( siteId, pFile ) {
715
+ if ( backupDownloadFinished ) return;
716
+
717
+ var data = ({
718
+ action: 'mainwp-child_clone_backupdownloadpoll',
719
+ siteId: siteId,
720
+ file: pFile
721
+ });
722
+
723
+ jQuery.post( ajaxurl, data, function ( pSiteId ) {
724
+ return function ( resp ) {
725
+ if ( backupDownloadFinished ) return;
726
+ if ( resp.size ) {
727
+ var progressBar = jQuery( '#mainwp-child-clone-download-progress' );
728
+ if ( progressBar.progressbar( 'option', 'value' ) < progressBar.progressbar( 'option', 'max' ) ) {
729
+ progressBar.progressbar( 'value', resp.size );
730
+ }
731
+ }
732
+
733
+ pollingDownloading = setTimeout( function () {
734
+ cloneBackupDownloadPolling( pSiteId );
735
+ }, 1000 );
736
+ }
737
+ }( siteId ), 'json' );
738
+ };
739
+
740
+ cloneInitiateExtractBackup = function ( file ) {
741
+ if ( file == undefined ) file = '';
742
+
743
+ updateClonePopup( translations['extracting_backup'] );
744
+ //Extract & install SQL
745
+ var data = mainwpchild_secure_data({
746
+ action: 'mainwp-child_clone_backupextract',
747
+ f: file
748
+ });
749
+
750
+ jQuery.ajax( {
751
+ type: "POST",
752
+ url: ajaxurl,
753
+ data: data,
754
+ success: function ( resp ) {
755
+ if ( resp.error ) {
756
+ handleCloneError( resp );
757
+ return;
758
+ }
759
+
760
+ updateClonePopup( translations['clone_complete'] );
761
+
762
+ setTimeout( function () {
763
+ jQuery( '#mainwp-child_clone_status' ).dialog( 'close' );
764
+