PluginProbe
MainWP Dashboard: Self-hosted WordPress Management for Agencies / 6.0.11
MainWP Dashboard: Self-hosted WordPress Management for Agencies v6.0.11
6.2 6.1.8 6.1.7 6.1.6 6.1.5 6.1.4 6.1.3 6.1.2 6.1.1 6.1 6.0.12 6.0.11 4.6.0.1 5.0 5.0.1 5.0.2 5.0.3 5.0.3.1 5.0.3.2 5.1 5.1.1 5.2 5.2.1 5.2.2 5.3 All 153 releases
mainwp / class / class-mainwp-backup-handler.php

class-mainwp-backup-handler.php in MainWP Dashboard: Self-hosted WordPress Management for Agencies 6.0.11, at class/class-mainwp-backup-handler.php

1,232 lines 53.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * MainWP Backup Handler.
4 *
5 * @package MainWP/Dashboard
6 */
7
8 namespace MainWP\Dashboard;
9
10 // Exit if accessed directly.
11 if ( ! defined( 'ABSPATH' ) ) {
12 exit;
13 }
14
15 /**
16 * Class MainWP_Backup_Handler
17 *
18 * @package MainWP\Dashboard
19 */
20 class MainWP_Backup_Handler { // phpcs:ignore Generic.Classes.OpeningBraceSameLine.ContentAfterBrace -- NOSONAR.
21
22 /**
23 * Method get_class_name()
24 *
25 * Get Class Name.
26 *
27 * @return string __CLASS__
28 */
29 public static function get_class_name() {
30 return __CLASS__;
31 }
32
33 /**
34 * Method backup_site()
35 *
36 * Backup Child Site.
37 *
38 * @param mixed $siteid Child Site ID.
39 * @param mixed $pTask Task to perform.
40 * @param mixed $subfolder Sub folder to place backup.
41 *
42 * @gobal object $wp_filesystem WordPress filesystem instance.
43 *
44 * @return mixed $backup_result
45 * @throws MainWP_Exception Error message.
46 *
47 * @uses \MainWP\Dashboard\MainWP_Connect::fetch_url_authed()
48 * @uses \MainWP\Dashboard\MainWP_Connect::download_to_file()
49 * @uses \MainWP\Dashboard\MainWP_Connect::get_get_data_authed()
50 * @uses \MainWP\Dashboard\MainWP_DB_Backup::get_backup_task_progress()
51 * @uses \MainWP\Dashboard\MainWP_DB_Backup::add_backup_task_progress()
52 * @uses \MainWP\Dashboard\MainWP_DB_Backup::update_backup_task_progress()
53 * @uses \MainWP\Dashboard\MainWP_DB::get_website_by_id()
54 * @uses \MainWP\Dashboard\MainWP_Exception
55 * @uses \MainWP\Dashboard\MainWP_Logger::debug_for_website()
56 * @uses \MainWP\Dashboard\MainWP_Logger::warning_for_website()
57 * @uses \MainWP\Dashboard\MainWP_System::is_single_user()
58 * @uses \MainWP\Dashboard\MainWP_System_Utility::get_wp_file_system()
59 * @uses \MainWP\Dashboard\MainWP_System_Utility::get_mainwp_specific_dir()
60 * @uses \MainWP\Dashboard\MainWP_Utility::sanitize()
61 * @uses \MainWP\Dashboard\MainWP_Utility::date()
62 * @uses \MainWP\Dashboard\MainWP_Utility::remove_preslash_spaces()
63 * @uses \MainWP\Dashboard\static::normalize_filename()
64 * @uses \MainWP\Dashboard\MainWP_Utility::value_to_string()
65 * @uses \MainWP\Dashboard\static::get_real_extension()
66 */
67 public static function backup_site( $siteid, $pTask, $subfolder ) {
68 // phpcs: ignore -- Current complexity is the only way to achieve desired results, pull request solutions appreciated.
69 if ( ! get_option( 'mainwp_enableLegacyBackupFeature' ) ) {
70 return false;
71 }
72
73 $userid = $pTask->userid;
74 $type = $pTask->type;
75 $exclude = $pTask->exclude;
76 $taskId = $pTask->id;
77 $excludebackup = $pTask->excludebackup;
78 $excludecache = $pTask->excludecache;
79 $excludenonwp = $pTask->excludenonwp;
80 $excludezip = $pTask->excludezip;
81 $pFilename = $pTask->filename;
82
83 if ( '' === trim( $pFilename ) ) {
84 $pFilename = null;
85 }
86
87 $backup_result = array();
88
89 // Creating a backup.
90 $website = MainWP_DB::instance()->get_website_by_id( $siteid );
91 $subfolder = str_replace( '%sitename%', MainWP_Utility::sanitize( $website->name ), $subfolder );
92 $subfolder = str_replace( '%url%', MainWP_Utility::sanitize( MainWP_Utility::get_nice_url( $website->url ) ), $subfolder );
93 $subfolder = str_replace( '%type%', $type, $subfolder );
94 $subfolder = str_replace( '%date%', MainWP_Utility::date( 'Ymd' ), $subfolder );
95 $subfolder = str_replace( '%task%', '', $subfolder );
96 $subfolder = str_replace( '%', '', $subfolder );
97 $subfolder = MainWP_Utility::remove_preslash_spaces( $subfolder );
98 $subfolder = static::normalize_filename( $subfolder );
99
100 if ( ! MainWP_System::instance()->is_single_user() && ( $userid !== $website->userid ) ) {
101 throw new MainWP_Exception( 'Undefined error.' );
102 }
103
104 $websiteCleanUrl = $website->url;
105 if ( '/' === substr( $websiteCleanUrl, - 1 ) ) {
106 $websiteCleanUrl = substr( $websiteCleanUrl, 0, - 1 );
107 }
108 $websiteCleanUrl = str_replace(
109 array( 'http://', 'https://', '/' ),
110 array( '', '', '-' ),
111 $websiteCleanUrl
112 );
113
114 if ( 'db' === $type ) {
115 $ext = '.sql.' . static::get_current_archive_extension( $website, $pTask );
116 } else {
117 $ext = '.' . static::get_current_archive_extension( $website, $pTask );
118 }
119
120 $file = str_replace(
121 array(
122 '%sitename%',
123 '%url%',
124 '%date%',
125 '%time%',
126 '%type%',
127 ),
128 array(
129 MainWP_Utility::sanitize( $website->name ),
130 $websiteCleanUrl,
131 MainWP_Utility::date( 'm-d-Y' ),
132 MainWP_Utility::date( 'G\hi\ms\s' ),
133 $type,
134 ),
135 $pFilename
136 );
137 $file = str_replace( '%', '', $file );
138 $file = static::normalize_filename( $file );
139
140 if ( ! empty( $file ) ) {
141 $file .= $ext;
142 }
143
144 if ( 'zip' === $pTask->archiveFormat ) {
145 $loadFilesBeforeZip = (int) $pTask->loadFilesBeforeZip;
146 } elseif ( '' === $pTask->archiveFormat || 'site' === $pTask->archiveFormat ) {
147 $loadFilesBeforeZip = (int) $website->loadFilesBeforeZip;
148 } else {
149 $loadFilesBeforeZip = 1;
150 }
151
152 if ( 1 === $loadFilesBeforeZip ) {
153 $loadFilesBeforeZip = get_option( 'mainwp_options_loadFilesBeforeZip' );
154 $loadFilesBeforeZip = ( 1 === (int) $loadFilesBeforeZip || false === $loadFilesBeforeZip );
155 } else {
156 $loadFilesBeforeZip = ( 2 === $loadFilesBeforeZip );
157 }
158
159 if ( ( 'zip' === $pTask->archiveFormat ) && ( 1 === (int) $pTask->maximumFileDescriptorsOverride ) ) {
160 $maximumFileDescriptorsAuto = ( 1 === (int) $pTask->maximumFileDescriptorsAuto );
161 $maximumFileDescriptors = $pTask->maximumFileDescriptors;
162 } elseif ( ( '' === $pTask->archiveFormat || 'site' === $pTask->archiveFormat ) && ( 1 === (int) $website->maximumFileDescriptorsOverride ) ) {
163 $maximumFileDescriptorsAuto = ( 1 === (int) $website->maximumFileDescriptorsAuto );
164 $maximumFileDescriptors = $website->maximumFileDescriptors;
165 } else {
166 $maximumFileDescriptorsAuto = get_option( 'mainwp_maximumFileDescriptorsAuto' );
167 $maximumFileDescriptors = get_option( 'mainwp_maximumFileDescriptors' );
168 $maximumFileDescriptors = ( false === $maximumFileDescriptors ? 150 : $maximumFileDescriptors );
169 }
170
171 $information = false;
172 $backupTaskProgress = MainWP_DB_Backup::instance()->get_backup_task_progress( $taskId, $website->id );
173 if ( empty( $backupTaskProgress ) || ( $backupTaskProgress->dtsFetched < $pTask->last_run ) ) {
174 $start = microtime( true );
175 try {
176 $pid = time();
177
178 if ( empty( $backupTaskProgress ) ) {
179 MainWP_DB_Backup::instance()->add_backup_task_progress( $taskId, $website->id, array() );
180 }
181
182 MainWP_DB_Backup::instance()->update_backup_task_progress(
183 $taskId,
184 $website->id,
185 array(
186 'dtsFetched' => time(),
187 'fetchResult' => wp_json_encode( array() ),
188 'downloadedDB' => '',
189 'downloadedDBComplete' => 0,
190 'downloadedFULL' => '',
191 'downloadedFULLComplete' => 0,
192 'removedFiles' => 0,
193 'attempts' => 0,
194 'last_error' => '',
195 'pid' => $pid,
196 )
197 );
198
199 $params = array(
200 'type' => $type,
201 'exclude' => $exclude,
202 'excludebackup' => $excludebackup,
203 'excludecache' => $excludecache,
204 'excludenonwp' => $excludenonwp,
205 'excludezip' => $excludezip,
206 'ext' => static::get_current_archive_extension( $website, $pTask ),
207 'file_descriptors_auto' => $maximumFileDescriptorsAuto,
208 'file_descriptors' => $maximumFileDescriptors,
209 'loadFilesBeforeZip' => $loadFilesBeforeZip,
210 'pid' => $pid,
211 'f' => $file,
212 );
213
214 MainWP_Logger::instance()->debug_for_website( $website, 'backup', 'Requesting backup: ' . MainWP_Utility::value_to_string( $params, 1 ) );
215
216 $information = MainWP_Connect::fetch_url_authed( $website, 'backup', $params, false, false, false );
217 } catch ( MainWP_Exception $e ) {
218 MainWP_Logger::instance()->warning_for_website( $website, 'backup', 'ERROR: ' . $e->getMessage() . ' (' . $e->get_message_extra() . ')' );
219 $stop = microtime( true );
220 // Bigger then 30 seconds means a timeout.
221 if ( 30 < ( $stop - $start ) ) {
222 MainWP_DB_Backup::instance()->update_backup_task_progress(
223 $taskId,
224 $website->id,
225 array(
226 'last_error' => wp_json_encode(
227 array(
228 'message' => $e->getMessage(),
229 'extra' => $e->get_message_extra(),
230 )
231 ),
232 )
233 );
234
235 return false;
236 }
237
238 throw $e;
239 }
240
241 if ( isset( $information['error'] ) && stristr( $information['error'], 'Another backup process is running' ) ) {
242 return false;
243 }
244
245 $backupTaskProgress = MainWP_DB_Backup::instance()->update_backup_task_progress( $taskId, $website->id, array( 'fetchResult' => wp_json_encode( $information ) ) );
246 } elseif ( empty( $backupTaskProgress->fetchResult ) ) {
247 try {
248 $temp = MainWP_Connect::fetch_url_authed( $website, 'backup_checkpid', array( 'pid' => $backupTaskProgress->pid ) );
249 } catch ( \Exception $e ) {
250 // ok!
251 }
252
253 if ( ! empty( $temp ) ) {
254 if ( 'stalled' === $temp['status'] ) {
255 if ( 5 > $backupTaskProgress->attempts ) {
256 $backupTaskProgress = MainWP_DB_Backup::instance()->update_backup_task_progress( $taskId, $website->id, array( 'attempts' => $backupTaskProgress->attempts ++ ) );
257
258 try {
259 $information = MainWP_Connect::fetch_url_authed(
260 $website,
261 'backup',
262 array(
263 'type' => $type,
264 'exclude' => $exclude,
265 'excludebackup' => $excludebackup,
266 'excludecache' => $excludecache,
267 'excludenonwp' => $excludenonwp,
268 'excludezip' => $excludezip,
269 'ext' => static::get_current_archive_extension( $website, $pTask ),
270 'file_descriptors_auto' => $maximumFileDescriptorsAuto,
271 'file_descriptors' => $maximumFileDescriptors,
272 'loadFilesBeforeZip' => $loadFilesBeforeZip,
273 'pid' => $backupTaskProgress->pid,
274 'append' => '1',
275 'f' => $temp['file'],
276 ),
277 false,
278 false,
279 false
280 );
281
282 if ( isset( $information['error'] ) && stristr( $information['error'], 'Another backup process is running' ) ) {
283 MainWP_DB_Backup::instance()->update_backup_task_progress( $taskId, $website->id, array( 'attempts' => ( $backupTaskProgress->attempts - 1 ) ) );
284
285 return false;
286 }
287 } catch ( MainWP_Exception $e ) {
288 return false;
289 }
290
291 $backupTaskProgress = MainWP_DB_Backup::instance()->update_backup_task_progress( $taskId, $website->id, array( 'fetchResult' => wp_json_encode( $information ) ) );
292 } else {
293 throw new MainWP_Exception( 'Backup failed after 5 retries.' );
294 }
295 } elseif ( 'invalid' === $temp['status'] ) {
296 $error = json_decode( $backupTaskProgress->last_error );
297
298 if ( ! is_array( $error ) ) {
299 throw new MainWP_Exception( 'Backup failed.' );
300 } else {
301 throw new MainWP_Exception( $error['message'], $error['extra'] ); //phpcs:ignore WordPress.Security.EscapeOutput.ExceptionNotEscaped
302 }
303 } elseif ( 'busy' === $temp['status'] ) {
304 return false;
305 } elseif ( 'done' === $temp['status'] ) {
306 if ( 'full' === $type ) {
307 $information['full'] = $temp['file'];
308 $information['db'] = false;
309 } else {
310 $information['full'] = false;
311 $information['db'] = $temp['file'];
312 }
313
314 $information['size'] = $temp['size'];
315
316 $backupTaskProgress = MainWP_DB_Backup::instance()->update_backup_task_progress( $taskId, $website->id, array( 'fetchResult' => wp_json_encode( $information ) ) );
317 }
318 } elseif ( 5 > $backupTaskProgress->attempts ) {
319 $backupTaskProgress = MainWP_DB_Backup::instance()->update_backup_task_progress( $taskId, $website->id, array( 'attempts' => $backupTaskProgress->attempts ++ ) );
320 } else {
321 throw new MainWP_Exception( 'Backup failed after 5 retries.' );
322 }
323 }
324
325 if ( false === $information ) {
326 $information = $backupTaskProgress->fetchResult;
327 }
328
329 if ( isset( $information['error'] ) ) {
330 throw new MainWP_Exception( esc_html( $information['error'] ) );
331 } elseif ( 'db' === $type && ! $information['db'] ) {
332 throw new MainWP_Exception( 'Database backup failed.' );
333 } elseif ( 'full' === $type && ! $information['full'] ) {
334 throw new MainWP_Exception( 'Full backup failed.' );
335 } elseif ( isset( $information['db'] ) ) {
336 $hasWPFileSystem = MainWP_System_Utility::get_wp_file_system();
337
338 /**
339 * WordPress filesystem instance.
340 *
341 * @global object
342 */
343 global $wp_filesystem;
344
345 $dir = MainWP_System_Utility::get_mainwp_specific_dir( $website->id );
346
347 $wp_filesystem->mkdir( $dir, 0777 );
348
349 if ( ! $wp_filesystem->exists( $dir . 'index.php' ) ) {
350 $wp_filesystem->touch( $dir . 'index.php' );
351 }
352
353 // Clean old backups from our system.
354 $maxBackups = get_option( 'mainwp_backupsOnServer' );
355 if ( false === $maxBackups ) {
356 $maxBackups = 1;
357 }
358
359 if ( 1 !== $backupTaskProgress->removedFiles ) {
360 $dbBackups = array();
361 $fullBackups = array();
362 if ( $wp_filesystem->exists( $dir ) ) {
363 $dh = opendir( $dir );
364 if ( $dh ) {
365 while ( false !== ( $file = readdir( $dh ) ) ) {
366 if ( '.' !== $file && '..' !== $file ) {
367 $theFile = $dir . $file;
368 if ( $information['db'] && static::is_sql_file( $file ) ) {
369 $dbBackups[ filemtime( $theFile ) . $file ] = $theFile;
370 }
371
372 if ( $information['full'] && static::is_archive( $file ) && ! static::is_sql_archive( $file ) ) {
373 $fullBackups[ filemtime( $theFile ) . $file ] = $theFile;
374 }
375 }
376 }
377 closedir( $dh );
378 }
379 }
380 krsort( $dbBackups );
381 krsort( $fullBackups );
382
383 $cnt = 0;
384 foreach ( $dbBackups as $key => $dbBackup ) {
385 ++$cnt;
386 if ( $cnt >= $maxBackups ) {
387 $wp_filesystem->delete( $dbBackup );
388 }
389 }
390
391 $cnt = 0;
392 foreach ( $fullBackups as $key => $fullBackup ) {
393 ++$cnt;
394 if ( $cnt >= $maxBackups ) {
395 $wp_filesystem->delete( $fullBackup );
396 }
397 }
398 $backupTaskProgress = MainWP_DB_Backup::instance()->update_backup_task_progress( $taskId, $website->id, array( 'removedFiles' => 1 ) );
399 }
400
401 $localBackupFile = null;
402
403 $fm_date = MainWP_Utility::sanitize_file_name( MainWP_Utility::date( get_option( 'date_format' ) ) );
404 $fm_time = MainWP_Utility::sanitize_file_name( MainWP_Utility::date( get_option( 'time_format' ) ) );
405
406 $what = null;
407 $regexBackupFile = null;
408
409 if ( $information['db'] ) {
410 $what = 'db';
411 $regexBackupFile = 'db-' . $websiteCleanUrl . '-(.*)-(.*).sql(\.zip|\.tar|\.tar\.gz|\.tar\.bz2)?';
412 if ( '' === $backupTaskProgress->downloadedDB ) {
413 $localBackupFile = $dir . 'db-' . $websiteCleanUrl . '-' . $fm_date . '-' . $fm_time;
414
415 if ( null !== $pFilename ) {
416 $filename = str_replace(
417 array(
418 '%sitename%',
419 '%url%',
420 '%date%',
421 '%time%',
422 '%type%',
423 ),
424 array(
425 MainWP_Utility::sanitize( $website->name ),
426 $websiteCleanUrl,
427 $fm_date,
428 $fm_time,
429 $what,
430 ),
431 $pFilename
432 );
433 $filename = str_replace( '%', '', $filename );
434 $localBackupFile = $dir . $filename;
435 }
436 $localBackupFile .= static::get_real_extension( $information['db'] );
437
438 $localBackupFile = static::normalize_filename( $localBackupFile );
439
440 $backupTaskProgress = MainWP_DB_Backup::instance()->update_backup_task_progress( $taskId, $website->id, array( 'downloadedDB' => $localBackupFile ) );
441 } else {
442 $localBackupFile = $backupTaskProgress->downloadedDB;
443 }
444
445 if ( 0 === (int) $backupTaskProgress->downloadedDBComplete ) {
446 MainWP_Connect::download_to_file( MainWP_Connect::get_get_data_authed( $website, $information['db'], 'fdl' ), $localBackupFile, $information['size'], $website->http_user, $website->http_pass );
447 $backupTaskProgress = MainWP_DB_Backup::instance()->update_backup_task_progress( $taskId, $website->id, array( 'downloadedDBComplete' => 1 ) );
448 }
449 }
450
451 if ( $information['full'] ) {
452 $realExt = static::get_real_extension( $information['full'] );
453 $what = 'full';
454 $regexBackupFile = 'full-' . $websiteCleanUrl . '-(.*)-(.*).(zip|tar|tar.gz|tar.bz2)';
455 if ( '' === $backupTaskProgress->downloadedFULL ) {
456 $localBackupFile = $dir . 'full-' . $websiteCleanUrl . '-' . $fm_date . '-' . $fm_time . $realExt;
457
458 if ( null !== $pFilename ) {
459 $filename = str_replace(
460 array(
461 '%sitename%',
462 '%url%',
463 '%date%',
464 '%time%',
465 '%type%',
466 ),
467 array(
468 MainWP_Utility::sanitize( $website->name ),
469 $websiteCleanUrl,
470 $fm_date,
471 $fm_time,
472 $what,
473 ),
474 $pFilename
475 );
476 $filename = str_replace( '%', '', $filename );
477 $localBackupFile = $dir . $filename . $realExt;
478 }
479
480 $localBackupFile = static::normalize_filename( $localBackupFile );
481
482 $backupTaskProgress = MainWP_DB_Backup::instance()->update_backup_task_progress( $taskId, $website->id, array( 'downloadedFULL' => $localBackupFile ) );
483 } else {
484 $localBackupFile = $backupTaskProgress->downloadedFULL;
485 }
486
487 if ( 0 === (int) $backupTaskProgress->downloadedFULLComplete ) {
488 if ( file_exists( $localBackupFile ) ) {
489 $time = filemtime( $localBackupFile );
490
491 $minutes = gmdate( 'i', time() );
492 $seconds = gmdate( 's', time() );
493
494 $file_minutes = gmdate( 'i', $time );
495 $file_seconds = gmdate( 's', $time );
496
497 $minuteDiff = $minutes - $file_minutes;
498 if ( 59 === $minuteDiff ) {
499 $minuteDiff = 1;
500 }
501 $secondsdiff = ( $minuteDiff * 60 ) + $seconds - $file_seconds;
502
503 if ( 60 > $secondsdiff ) {
504 // still downloading.
505 return false;
506 }
507 }
508
509 MainWP_Connect::download_to_file( MainWP_Connect::get_get_data_authed( $website, $information['full'], 'fdl' ), $localBackupFile, $information['size'], $website->http_user, $website->http_pass );
510 MainWP_Connect::fetch_url_authed( $website, 'delete_backup', array( 'del' => $information['full'] ) );
511 $backupTaskProgress = MainWP_DB_Backup::instance()->update_backup_task_progress( $taskId, $website->id, array( 'downloadedFULLComplete' => 1 ) );
512 }
513 }
514
515 $unique = $pTask->last_run;
516
517 do_action( 'mainwp_postprocess_backup_site', $localBackupFile, $what, $subfolder, $regexBackupFile, $website, $taskId, $unique );
518 $extra_result = apply_filters( 'mainwp_postprocess_backup_sites_feedback', array(), $unique );
519 if ( is_array( $extra_result ) ) {
520 foreach ( $extra_result as $key => $value ) {
521 $backup_result[ $key ] = $value;
522 }
523 }
524 } else {
525 throw new MainWP_Exception( 'Database backup failed due to an undefined error.' );
526 }
527
528 return $backup_result;
529 }
530
531 /**
532 * Method backup_download_file()
533 *
534 * Download backup file.
535 *
536 * @param mixed $pSiteId Child Site ID.
537 * @param mixed $pType full|db Type of backup.
538 * @param mixed $pUrl Backup location.
539 * @param mixed $pFile Backup File.
540 *
541 * @return bool true|false
542 * @throws MainWP_Exception Error message.
543 *
544 * @uses \MainWP\Dashboard\MainWP_Connect::get_get_data_authed()
545 * @uses \MainWP\Dashboard\MainWP_DB::get_website_by_id()
546 * @uses \MainWP\Dashboard\MainWP_Connect::download_to_file()
547 * @uses \MainWP\Dashboard\MainWP_Utility::end_session()
548 */
549 public static function backup_download_file( $pSiteId, $pType, $pUrl, $pFile ) {
550 $hasWPFileSystem = MainWP_System_Utility::get_wp_file_system();
551
552 /**
553 * WordPress filesystem instance.
554 *
555 * @global object
556 */
557 global $wp_filesystem;
558
559 $dir = dirname( $pFile ) . '/';
560 $wp_filesystem->mkdir( $dir, 0777 );
561 if ( ! $wp_filesystem->exists( $dir . 'index.php' ) ) {
562 $wp_filesystem->touch( $dir . 'index.php' );
563 }
564 // Clean old backups from our system.
565 $maxBackups = get_option( 'mainwp_backupsOnServer' );
566 if ( false === $maxBackups ) {
567 $maxBackups = 1;
568 }
569
570 $dbBackups = array();
571 $fullBackups = array();
572
573 if ( file_exists( $dir ) ) {
574 $dh = opendir( $dir );
575 if ( $dh ) {
576 while ( false !== ( $file = readdir( $dh ) ) ) {
577 if ( '.' !== $file && '..' !== $file ) {
578 $theFile = $dir . $file;
579 if ( 'db' === $pType && static::is_sql_file( $file ) ) {
580 $dbBackups[ filemtime( $theFile ) . $file ] = $theFile;
581 }
582
583 if ( 'full' === $pType && static::is_archive( $file ) && ! static::is_sql_archive( $file ) ) {
584 $fullBackups[ filemtime( $theFile ) . $file ] = $theFile;
585 }
586 }
587 }
588 closedir( $dh );
589 }
590 }
591 krsort( $dbBackups );
592 krsort( $fullBackups );
593
594 $cnt = 0;
595 foreach ( $dbBackups as $key => $dbBackup ) {
596 ++$cnt;
597 if ( $cnt >= $maxBackups ) {
598 $wp_filesystem->delete( $dbBackup );
599 }
600 }
601
602 $cnt = 0;
603 foreach ( $fullBackups as $key => $fullBackup ) {
604 ++$cnt;
605 if ( $cnt >= $maxBackups ) {
606 $wp_filesystem->delete( $fullBackup );
607 }
608 }
609
610 $website = MainWP_DB::instance()->get_website_by_id( $pSiteId );
611 MainWP_Utility::end_session();
612
613 if ( 'db' === $pType ) {
614 MainWP_Connect::download_to_file( MainWP_Connect::get_get_data_authed( $website, $pUrl, 'fdl' ), $pFile, false, $website->http_user, $website->http_pass );
615 }
616
617 if ( 'full' === $pType ) {
618 MainWP_Connect::download_to_file( MainWP_Connect::get_get_data_authed( $website, $pUrl, 'fdl' ), $pFile, false, $website->http_user, $website->http_pass );
619 }
620
621 return true;
622 }
623
624 /**
625 * Method backup_delete_file().
626 *
627 * Delete backup file.
628 *
629 * @param mixed $pSiteId Child Site ID.
630 * @param mixed $pFile File to delete.
631 *
632 * @return bool true
633 *
634 * @uses \MainWP\Dashboard\MainWP_Connect::fetch_url_authed()
635 * @uses \MainWP\Dashboard\MainWP_DB::get_website_by_id()
636 */
637 public static function backup_delete_file( $pSiteId, $pFile ) {
638 $website = MainWP_DB::instance()->get_website_by_id( $pSiteId );
639 MainWP_Connect::fetch_url_authed( $website, 'delete_backup', array( 'del' => $pFile ) );
640 return true;
641 }
642
643 /**
644 * Method backup_check_pid()
645 *
646 * Check backup pid.
647 *
648 * @param mixed $pSiteId Child Site id.
649 * @param mixed $pid Backup pid.
650 * @param mixed $type full|db Type of backup.
651 * @param mixed $subfolder Sub folder for backup.
652 * @param mixed $pFilename Backups filename.
653 *
654 * @return array $status, $result.
655 * @throws \MainWP_Exception Error message.
656 *
657 * @uses \MainWP\Dashboard\MainWP_System_Utility::get_mainwp_specific_dir()
658 * @uses \MainWP\Dashboard\MainWP_DB::get_website_by_id()
659 * @uses \MainWP\Dashboard\MainWP_Utility::end_session()
660 * @uses \MainWP\Dashboard\MainWP_Utility::sanitize()
661 * @uses \MainWP\Dashboard\MainWP_Utility::get_nice_url()
662 * @uses \MainWP\Dashboard\MainWP_Utility::date()
663 * @uses \MainWP\Dashboard\MainWP_Utility::remove_preslash_spaces()
664 * @uses \MainWP\Dashboard\static::normalize_filename()
665 * @uses \MainWP\Dashboard\MainWP_Utility::sanitize_file_name()
666 * @uses \MainWP\Dashboard\static::get_real_extension()
667 */
668 public static function backup_check_pid( $pSiteId, $pid, $type, $subfolder, $pFilename ) {
669 $website = MainWP_DB::instance()->get_website_by_id( $pSiteId );
670
671 MainWP_Utility::end_session();
672 $information = MainWP_Connect::fetch_url_authed( $website, 'backup_checkpid', array( 'pid' => $pid ) );
673
674 $status = $information['status'];
675
676 $result = isset( $information['file'] ) ? array( 'file' => $information['file'] ) : array();
677 if ( 'done' === $status ) {
678 $result['file'] = $information['file'];
679 $result['size'] = $information['size'];
680
681 $subfolder = str_replace( '%sitename%', MainWP_Utility::sanitize( $website->name ), $subfolder );
682 $subfolder = str_replace( '%url%', MainWP_Utility::sanitize( MainWP_Utility::get_nice_url( $website->url ) ), $subfolder );
683 $subfolder = str_replace( '%type%', $type, $subfolder );
684 $subfolder = str_replace( '%date%', MainWP_Utility::date( 'Ymd' ), $subfolder );
685 $subfolder = str_replace( '%task%', '', $subfolder );
686 $subfolder = str_replace( '%', '', $subfolder );
687 $subfolder = MainWP_Utility::remove_preslash_spaces( $subfolder );
688 $subfolder = static::normalize_filename( $subfolder );
689
690 $result['subfolder'] = $subfolder;
691
692 $websiteCleanUrl = $website->url;
693 if ( '/' === substr( $websiteCleanUrl, - 1 ) ) {
694 $websiteCleanUrl = substr( $websiteCleanUrl, 0, - 1 );
695 }
696 $websiteCleanUrl = str_replace(
697 array( 'http://', 'https://', '/' ),
698 array(
699 '',
700 '',
701 '-',
702 ),
703 $websiteCleanUrl
704 );
705
706 $dir = MainWP_System_Utility::get_mainwp_specific_dir( $pSiteId );
707
708 $fm_date = MainWP_Utility::sanitize_file_name( MainWP_Utility::date( get_option( 'date_format' ) ) );
709 $fm_time = MainWP_Utility::sanitize_file_name( MainWP_Utility::date( get_option( 'time_format' ) ) );
710
711 if ( 'db' === $type ) {
712 $localBackupFile = $dir . 'db-' . $websiteCleanUrl . '-' . $fm_date . '-' . $fm_time . static::get_real_extension( $information['file'] );
713 $localRegexFile = 'db-' . $websiteCleanUrl . '-(.*)-(.*).sql(\.zip|\.tar|\.tar\.gz|\.tar\.bz2)?';
714 } else {
715 $localBackupFile = $dir . 'full-' . $websiteCleanUrl . '-' . $fm_date . '-' . $fm_time . static::get_real_extension( $information['file'] );
716 $localRegexFile = 'full-' . $websiteCleanUrl . '-(.*)-(.*).(zip|tar|tar.gz|tar.bz2)';
717 }
718
719 if ( null !== $pFilename ) {
720 $filename = str_replace(
721 array(
722 '%sitename%',
723 '%url%',
724 '%date%',
725 '%time%',
726 '%type%',
727 ),
728 array(
729 MainWP_Utility::sanitize( $website->name ),
730 $websiteCleanUrl,
731 $fm_date,
732 $fm_time,
733 $type,
734 ),
735 $pFilename
736 );
737 $filename = str_replace( '%', '', $filename );
738 $localBackupFile = $dir . $filename;
739 $localBackupFile = static::normalize_filename( $localBackupFile );
740
741 if ( 'db' === $type ) {
742 $localBackupFile .= static::get_real_extension( $information['file'] );
743 } else {
744 $localBackupFile .= static::get_real_extension( $information['file'] );
745 }
746 }
747
748 $result['local'] = $localBackupFile;
749 $result['regexfile'] = $localRegexFile;
750 }
751
752 return array(
753 'status' => $status,
754 'result' => $result,
755 );
756 }
757
758 /**
759 * Method backup()
760 *
761 * Backup Child Site.
762 *
763 * @param mixed $pSiteId Child Site ID.
764 * @param mixed $pType full|db Typ of backup.
765 * @param mixed $pSubfolder Sub folder to store backup.
766 * @param mixed $pExclude Exclusion list.
767 * @param mixed $excludebackup Exclude backup files.
768 * @param mixed $excludecache Exclude cache files.
769 * @param mixed $excludenonwp Exclude no WP Files.
770 * @param mixed $excludezip Exclude Zip files.
771 * @param null $pFilename Name of backup file.
772 * @param string $pFileNameUID File name unique ID.
773 * @param bool $pArchiveFormat Archive format.
774 * @param bool $pMaximumFileDescriptorsOverride Override maximum file descriptors.
775 * @param bool $pMaximumFileDescriptorsAuto Auto maximum file descriptors.
776 * @param bool $pMaximumFileDescriptors Maximum file descriptors.
777 * @param bool $pLoadFilesBeforeZip Load files before zip.
778 * @param bool $pid Backup pid.
779 * @param bool $append Append to backup.
780 *
781 * @return mixed $backup_result
782 * @throws MainWP_Exception Error message.
783 *
784 * @uses \MainWP\Dashboard\MainWP_Connect::fetch_url_authed()
785 * @uses \MainWP\Dashboard\MainWP_Exception
786 * @uses \MainWP\Dashboard\MainWP_DB::get_website_by_id()
787 * @uses \MainWP\Dashboard\MainWP_Logger::debug_for_website()
788 * @uses \MainWP\Dashboard\MainWP_System_Utility::can_edit_website()
789 * @uses \MainWP\Dashboard\MainWP_System_Utility::get_mainwp_specific_dir()
790 * @uses \MainWP\Dashboard\MainWP_Utility::sanitize()
791 * @uses \MainWP\Dashboard\MainWP_Utility::date()
792 * @uses \MainWP\Dashboard\MainWP_Utility::remove_preslash_spaces()
793 * @uses \MainWP\Dashboard\static::normalize_filename()
794 * @uses \MainWP\Dashboard\MainWP_Utility::sanitize_file_name()
795 * @uses \MainWP\Dashboard\MainWP_Utility::end_session()
796 * @uses \MainWP\Dashboard\MainWP_Utility::value_to_string()
797 * @uses \MainWP\Dashboard\static::get_real_extension()
798 */
799 public static function backup(
800 $pSiteId,
801 $pType,
802 $pSubfolder,
803 $pExclude,
804 $excludebackup,
805 $excludecache,
806 $excludenonwp,
807 $excludezip,
808 $pFilename = null,
809 $pFileNameUID = '',
810 $pArchiveFormat = false,
811 $pMaximumFileDescriptorsOverride = false,
812 $pMaximumFileDescriptorsAuto = false,
813 $pMaximumFileDescriptors = false,
814 $pLoadFilesBeforeZip = false,
815 $pid = false,
816 $append = false
817 ) {
818
819 if ( ! get_option( 'mainwp_enableLegacyBackupFeature' ) ) {
820 return false;
821 }
822
823 if ( '' === trim( $pFilename ) ) {
824 $pFilename = null;
825 }
826
827 $backup_result = array();
828
829 $website = MainWP_DB::instance()->get_website_by_id( $pSiteId );
830 $subfolder = str_replace( '%sitename%', MainWP_Utility::sanitize( $website->name ), $pSubfolder );
831 $subfolder = str_replace( '%url%', MainWP_Utility::sanitize( MainWP_Utility::get_nice_url( $website->url ) ), $subfolder );
832 $subfolder = str_replace( '%type%', $pType, $subfolder );
833 $subfolder = str_replace( '%date%', MainWP_Utility::date( 'Ymd' ), $subfolder );
834 $subfolder = str_replace( '%task%', '', $subfolder );
835 $subfolder = str_replace( '%', '', $subfolder );
836 $subfolder = MainWP_Utility::remove_preslash_spaces( $subfolder );
837 $subfolder = static::normalize_filename( $subfolder );
838
839 if ( MainWP_System_Utility::is_suspended_site( $website ) ) {
840 throw new MainWP_Exception( 'Suspended site.', '', 'SUSPENDED_SITE' );
841 }
842
843 if ( ! MainWP_System_Utility::can_edit_website( $website ) ) {
844 throw new MainWP_Exception( 'You are not allowed to backup this site' );
845 }
846
847 $websiteCleanUrl = $website->url;
848 if ( '/' === substr( $websiteCleanUrl, - 1 ) ) {
849 $websiteCleanUrl = substr( $websiteCleanUrl, 0, - 1 );
850 }
851 $websiteCleanUrl = str_replace(
852 array( 'http://', 'https://', '/' ),
853 array( '', '', '-' ),
854 $websiteCleanUrl
855 );
856
857 if ( false === $pMaximumFileDescriptorsOverride ) {
858 if ( 1 === (int) $website->maximumFileDescriptorsOverride ) {
859 $maximumFileDescriptorsAuto = ( 1 === (int) $website->maximumFileDescriptorsAuto );
860 $maximumFileDescriptors = $website->maximumFileDescriptors;
861 } else {
862 $maximumFileDescriptorsAuto = get_option( 'mainwp_maximumFileDescriptorsAuto' );
863 $maximumFileDescriptors = get_option( 'mainwp_maximumFileDescriptors' );
864 $maximumFileDescriptors = ( false === $maximumFileDescriptors ? 150 : $maximumFileDescriptors );
865 }
866 } elseif ( ( 'global' !== $pArchiveFormat ) && ( 1 === (int) $pMaximumFileDescriptorsOverride ) ) {
867 $maximumFileDescriptorsAuto = ( 1 === $pMaximumFileDescriptorsAuto );
868 $maximumFileDescriptors = $pMaximumFileDescriptors;
869 } else {
870 $maximumFileDescriptorsAuto = get_option( 'mainwp_maximumFileDescriptorsAuto' );
871 $maximumFileDescriptors = get_option( 'mainwp_maximumFileDescriptors' );
872 $maximumFileDescriptors = ( false === $maximumFileDescriptors ? 150 : $maximumFileDescriptors );
873 }
874
875 $file = str_replace(
876 array(
877 '%sitename%',
878 '%url%',
879 '%date%',
880 '%time%',
881 '%type%',
882 ),
883 array(
884 MainWP_Utility::sanitize( $website->name ),
885 $websiteCleanUrl,
886 MainWP_Utility::date( 'm-d-Y' ),
887 MainWP_Utility::date( 'G\hi\ms\s' ),
888 $pType,
889 ),
890 $pFilename
891 );
892 $file = str_replace( '%', '', $file );
893 $file = static::normalize_filename( $file );
894
895 // Normal flow: check site settings & fallback to global.
896 if ( false === $pLoadFilesBeforeZip ) {
897 $loadFilesBeforeZip = $website->loadFilesBeforeZip;
898 if ( 1 === $loadFilesBeforeZip ) {
899 $loadFilesBeforeZip = get_option( 'mainwp_options_loadFilesBeforeZip' );
900 $loadFilesBeforeZip = ( 1 === $loadFilesBeforeZip || false === $loadFilesBeforeZip );
901 } else {
902 $loadFilesBeforeZip = ( 2 === $loadFilesBeforeZip );
903 }
904 } elseif ( 'global' === $pArchiveFormat || 1 === $pLoadFilesBeforeZip ) { // Overridden flow: only fallback to global.
905 $loadFilesBeforeZip = get_option( 'mainwp_options_loadFilesBeforeZip' );
906 $loadFilesBeforeZip = ( 1 === $loadFilesBeforeZip || false === $loadFilesBeforeZip );
907 } else {
908 $loadFilesBeforeZip = ( 2 === $pLoadFilesBeforeZip );
909 }
910
911 // Normal flow: check site settings & fallback to global.
912 if ( false === $pArchiveFormat ) {
913 $archiveFormat = static::get_current_archive_extension( $website );
914 } elseif ( 'global' === $pArchiveFormat ) {
915 $archiveFormat = static::get_current_archive_extension();
916 } else {
917 $archiveFormat = $pArchiveFormat;
918 }
919
920 MainWP_Utility::end_session();
921
922 $params = array(
923 'type' => $pType,
924 'exclude' => $pExclude,
925 'excludebackup' => $excludebackup,
926 'excludecache' => $excludecache,
927 'excludenonwp' => $excludenonwp,
928 'excludezip' => $excludezip,
929 'ext' => $archiveFormat,
930 'file_descriptors_auto' => $maximumFileDescriptorsAuto,
931 'file_descriptors' => $maximumFileDescriptors,
932 'loadFilesBeforeZip' => $loadFilesBeforeZip,
933 'f' => $file,
934 'fileUID' => $pFileNameUID,
935 'pid' => $pid,
936 'append' => ( $append ? 1 : 0 ),
937 );
938
939 MainWP_Logger::instance()->debug_for_website( $website, 'backup', 'Requesting backup: ' . MainWP_Utility::value_to_string( $params, 1 ) );
940
941 $information = MainWP_Connect::fetch_url_authed( $website, 'backup', $params, false, false, false );
942 do_action( 'mainwp_managesite_backup', $website, array( 'type' => $pType ), $information );
943
944 if ( isset( $information['error'] ) ) {
945 throw new MainWP_Exception( esc_html( $information['error'] ) ); //phpcs:ignore WordPress.Security.EscapeOutput.ExceptionNotEscaped
946 } elseif ( 'db' === $pType && ! $information['db'] ) {
947 throw new MainWP_Exception( 'Database backup failed.' );
948 } elseif ( 'full' === $pType && ! $information['full'] ) {
949 throw new MainWP_Exception( 'Full backup failed.' );
950 } elseif ( isset( $information['db'] ) || isset( $information['full'] ) ) {
951 if ( ! empty( $information['db'] ) ) {
952 $backup_result['url'] = $information['db'];
953 $backup_result['type'] = 'db';
954 } elseif ( ! empty( $information['full'] ) ) {
955 $backup_result['url'] = $information['full'];
956 $backup_result['type'] = 'full';
957 }
958
959 if ( isset( $information['size'] ) ) {
960 $backup_result['size'] = $information['size'];
961 }
962 $backup_result['subfolder'] = $subfolder;
963
964 $dir = MainWP_System_Utility::get_mainwp_specific_dir( $pSiteId );
965
966 $fm_date = MainWP_Utility::sanitize_file_name( MainWP_Utility::date( get_option( 'date_format' ) ) );
967 $fm_time = MainWP_Utility::sanitize_file_name( MainWP_Utility::date( get_option( 'time_format' ) ) );
968
969 if ( 'db' === $pType ) {
970 $localBackupFile = $dir . 'db-' . $websiteCleanUrl . '-' . $fm_date . '-' . $fm_time . static::get_real_extension( $information['db'] );
971 $localRegexFile = 'db-' . $websiteCleanUrl . '-(.*)-(.*).sql(\.zip|\.tar|\.tar\.gz|\.tar\.bz2)?';
972 } else {
973 $localBackupFile = $dir . 'full-' . $websiteCleanUrl . '-' . $fm_date . '-' . $fm_time . static::get_real_extension( $information['full'] );
974 $localRegexFile = 'full-' . $websiteCleanUrl . '-(.*)-(.*).(zip|tar|tar.gz|tar.bz2)';
975 }
976
977 if ( null !== $pFilename ) {
978 $filename = str_replace(
979 array(
980 '%sitename%',
981 '%url%',
982 '%date%',
983 '%time%',
984 '%type%',
985 ),
986 array(
987 MainWP_Utility::sanitize( $website->name ),
988 $websiteCleanUrl,
989 $fm_date,
990 $fm_time,
991 $pType,
992 ),
993 $pFilename
994 );
995 $filename = str_replace( '%', '', $filename );
996 $localBackupFile = $dir . $filename;
997 $localBackupFile = static::normalize_filename( $localBackupFile );
998
999 if ( 'db' === $pType ) {
1000 $localBackupFile .= static::get_real_extension( $information['db'] );
1001 } else {
1002 $localBackupFile .= static::get_real_extension( $information['full'] );
1003 }
1004 }
1005
1006 $backup_result['local'] = $localBackupFile;
1007 $backup_result['regexfile'] = $localRegexFile;
1008
1009 return $backup_result;
1010 } else {
1011 throw new MainWP_Exception( 'Database backup failed due to an undefined error' );
1012 }
1013 }
1014
1015 /**
1016 * Method normalize_filename()
1017 *
1018 * Normalize filename.
1019 *
1020 * @param mixed $s Filename to normalize.
1021 *
1022 * @return string $s Normalised filename.
1023 */
1024 public static function normalize_filename( $s ) {
1025 $s = preg_replace( '@\x{00c4}@u', 'A', $s );
1026 $s = preg_replace( '@\x{00d6}@u', 'O', $s );
1027 $s = preg_replace( '@\x{00dc}@u', 'U', $s );
1028 $s = preg_replace( '@\x{00cb}@u', 'E', $s );
1029 $s = preg_replace( '@\x{00e4}@u', 'a', $s );
1030 $s = preg_replace( '@\x{00f6}@u', 'o', $s );
1031 $s = preg_replace( '@\x{00fc}@u', 'u', $s );
1032 $s = preg_replace( '@\x{00eb}@u', 'e', $s );
1033 $s = preg_replace( '@\x{00f1}@u', 'n', $s );
1034 $s = preg_replace( '@\x{00ff}@u', 'y', $s );
1035 return $s;
1036 }
1037
1038 /**
1039 * Method is_archive()
1040 *
1041 * Check if Archive.
1042 *
1043 * @param mixed $pFileName File to check.
1044 * @param string $pPrefix File prefix.
1045 * @param string $pSuffix File suffix.
1046 *
1047 * @return mixed Files that are archives.
1048 */
1049 public static function is_archive( $pFileName, $pPrefix = '', $pSuffix = '' ) {
1050 return preg_match( '/' . $pPrefix . '(.*).(zip|tar|tar.gz|tar.bz2)' . $pSuffix . '$/', $pFileName );
1051 }
1052
1053 /**
1054 * Method is_sql_file()
1055 *
1056 * Check if file is SQL.
1057 *
1058 * @param mixed $pFileName File to check.
1059 *
1060 * @return mixed SQL Files.
1061 */
1062 public static function is_sql_file( $pFileName ) {
1063 return preg_match( '/(.*).sql$/', $pFileName ) || static::is_sql_archive( $pFileName );
1064 }
1065
1066 /**
1067 * Method is_sql_archive()
1068 *
1069 * Check if is SQL Archive.
1070 *
1071 * @param mixed $pFileName File to check.
1072 *
1073 * @return mixed SQL archive.
1074 */
1075 public static function is_sql_archive( $pFileName ) {
1076 return preg_match( '/(.*).sql.(zip|tar|tar.gz|tar.bz2)$/', $pFileName );
1077 }
1078
1079 /**
1080 * Method get_current_archive_extension()
1081 *
1082 * Get extension of current Archive.
1083 *
1084 * @param bool $website true|false.
1085 * @param bool|string $task true|false|global|site.
1086 *
1087 * @return mixed $archiveFormat Format of Archive.
1088 *
1089 * @uses \MainWP\Dashboard\MainWP_DB_Backup::get_website_backup_settings()
1090 */
1091 public static function get_current_archive_extension( $website = false, $task = false ) {
1092 $useSite = true;
1093 if ( false !== $task ) {
1094 if ( 'global' === $task->archiveFormat ) {
1095 $useGlobal = true;
1096 $useSite = false;
1097 } elseif ( '' === $task->archiveFormat || 'site' === $task->archiveFormat ) {
1098 $useGlobal = false;
1099 $useSite = true;
1100 } else {
1101 $archiveFormat = $task->archiveFormat;
1102 $useGlobal = false;
1103 $useSite = false;
1104 }
1105 }
1106
1107 if ( $useSite ) {
1108 if ( false === $website ) {
1109 $useGlobal = true;
1110 } else {
1111 $backupSettings = MainWP_DB_Backup::instance()->get_website_backup_settings( $website->id );
1112 $archiveFormat = $backupSettings->archiveFormat;
1113 $useGlobal = ( 'global' === $archiveFormat );
1114 }
1115 }
1116
1117 if ( $useGlobal ) {
1118 $archiveFormat = get_option( 'mainwp_archiveFormat' );
1119 if ( false === $archiveFormat ) {
1120 $archiveFormat = 'tar.gz';
1121 }
1122 }
1123
1124 return $archiveFormat;
1125 }
1126
1127 /**
1128 * Method get_real_extension()
1129 *
1130 * Get full file extension.
1131 *
1132 * @param mixed $path Path to file.
1133 *
1134 * @return mixed $check|pathinfo()
1135 */
1136 public static function get_real_extension( $path ) {
1137 $checks = array( '.sql.zip', '.sql.tar', '.sql.tar.gz', '.sql.tar.bz2', '.tar.gz', '.tar.bz2' );
1138 foreach ( $checks as $check ) {
1139 if ( MainWP_Utility::ends_with( $path, $check ) ) {
1140 return $check;
1141 }
1142 }
1143
1144 return '.' . pathinfo( $path, PATHINFO_EXTENSION );
1145 }
1146
1147
1148 /**
1149 * Method handle_settings_post()
1150 *
1151 * Update Child Site Settings.
1152 *
1153 * @return bool true|false
1154 *
1155 * @uses \MainWP\Dashboard\MainWP_System_Utility::is_admin()
1156 * @uses \MainWP\Dashboard\MainWP_Utility::update_option()
1157 */
1158 public static function handle_settings_post() {
1159 if ( MainWP_System_Utility::is_admin() ) {
1160 if ( isset( $_POST['submit'] ) && isset( $_POST['wp_nonce'] ) && wp_verify_nonce( sanitize_key( $_POST['wp_nonce'] ), 'Settings' ) ) {
1161 if ( isset( $_POST['mainwp_options_backupOnServer'] ) && 0 < $_POST['mainwp_options_backupOnServer'] ) {
1162 MainWP_Utility::update_option( 'mainwp_backupsOnServer', ( isset( $_POST['mainwp_options_backupOnServer'] ) ? intval( $_POST['mainwp_options_backupOnServer'] ) : 1 ) );
1163 }
1164 if ( isset( $_POST['mainwp_options_maximumFileDescriptors'] ) && - 1 < $_POST['mainwp_options_maximumFileDescriptors'] ) {
1165 MainWP_Utility::update_option( 'mainwp_maximumFileDescriptors', ( isset( $_POST['mainwp_options_maximumFileDescriptors'] ) ? intval( $_POST['mainwp_options_maximumFileDescriptors'] ) : 1 ) );
1166 }
1167 MainWP_Utility::update_option( 'mainwp_maximumFileDescriptorsAuto', ( ! isset( $_POST['mainwp_maximumFileDescriptorsAuto'] ) ? 0 : 1 ) );
1168 if ( ! empty( $_POST['mainwp_options_backupOnExternalSources'] ) && 0 <= $_POST['mainwp_options_backupOnExternalSources'] ) {
1169 MainWP_Utility::update_option( 'mainwp_backupOnExternalSources', ( isset( $_POST['mainwp_options_backupOnExternalSources'] ) ? intval( $_POST['mainwp_options_backupOnExternalSources'] ) : 1 ) );
1170 }
1171 MainWP_Utility::update_option( 'mainwp_archiveFormat', ( isset( $_POST['mainwp_archiveFormat'] ) ? sanitize_text_field( wp_unslash( $_POST['mainwp_archiveFormat'] ) ) : '' ) );
1172
1173 $old_primaryBackup = get_option( 'mainwp_primaryBackup' );
1174 $old_enableLegacyBackup = get_option( 'mainwp_enableLegacyBackupFeature' );
1175 $updated_enableLegacyBackup = false;
1176
1177 if ( isset( $_POST['mainwp_primaryBackup'] ) ) {
1178 if ( ! empty( $_POST['mainwp_primaryBackup'] ) ) { // not default backup method.
1179 MainWP_Utility::update_option( 'mainwp_notificationOnBackupFail', 0 );
1180 MainWP_Utility::update_option( 'mainwp_notificationOnBackupStart', 0 );
1181 MainWP_Utility::update_option( 'mainwp_chunkedBackupTasks', 0 );
1182 if ( empty( $old_primaryBackup ) ) {
1183 MainWP_Utility::update_option( 'mainwp_enableLegacyBackupFeature', 0 );
1184 $updated_enableLegacyBackup = true;
1185 }
1186 }
1187 MainWP_Utility::update_option( 'mainwp_primaryBackup', sanitize_text_field( wp_unslash( $_POST['mainwp_primaryBackup'] ) ) );
1188 }
1189
1190 if ( ! isset( $_POST['mainwp_primaryBackup'] ) || empty( $_POST['mainwp_primaryBackup'] ) ) {
1191 MainWP_Utility::update_option( 'mainwp_options_loadFilesBeforeZip', ( ! isset( $_POST['mainwp_options_loadFilesBeforeZip'] ) ? 0 : 1 ) );
1192 MainWP_Utility::update_option( 'mainwp_notificationOnBackupFail', ( ! isset( $_POST['mainwp_options_notificationOnBackupFail'] ) ? 0 : 1 ) );
1193 MainWP_Utility::update_option( 'mainwp_notificationOnBackupStart', ( ! isset( $_POST['mainwp_options_notificationOnBackupStart'] ) ? 0 : 1 ) );
1194 MainWP_Utility::update_option( 'mainwp_chunkedBackupTasks', ( ! isset( $_POST['mainwp_options_chunkedBackupTasks'] ) ? 0 : 1 ) );
1195 }
1196
1197 $enableLegacyBackup = ( isset( $_POST['mainwp_options_enableLegacyBackupFeature'] ) && ! empty( $_POST['mainwp_options_enableLegacyBackupFeature'] ) ) ? 1 : 0;
1198 if ( $enableLegacyBackup && empty( $old_enableLegacyBackup ) ) {
1199 MainWP_Utility::update_option( 'mainwp_primaryBackup', '' );
1200 }
1201
1202 if ( ! $updated_enableLegacyBackup ) {
1203 MainWP_Utility::update_option( 'mainwp_enableLegacyBackupFeature', $enableLegacyBackup );
1204 }
1205 return true;
1206 }
1207 }
1208 return false;
1209 }
1210
1211 /**
1212 * Method backup_get_file_size()
1213 *
1214 * Get file size.
1215 *
1216 * @param mixed $pFile Backup file.
1217 *
1218 * @return false|int
1219 *
1220 * @uses \MainWP\Dashboard\MainWP_System_Utility::get_mainwp_specific_dir()
1221 */
1222 public static function backup_get_file_size( $pFile ) {
1223 $dir = MainWP_System_Utility::get_mainwp_specific_dir();
1224
1225 if ( stristr( $pFile, $dir ) && file_exists( $pFile ) ) {
1226 return filesize( $pFile );
1227 }
1228
1229 return 0;
1230 }
1231 }
1232