PluginProbe
MainWP Dashboard: Self-hosted WordPress Management for Agencies / 5.3
MainWP Dashboard: Self-hosted WordPress Management for Agencies v5.3
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 5.3, at class/class-mainwp-backup-handler.php

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