PluginProbe
MainWP Dashboard: Self-hosted WordPress Management for Agencies / trunk
MainWP Dashboard: Self-hosted WordPress Management for Agencies vtrunk
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-db-backup.php

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

585 lines 20.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * MainWP Database Controller
4 *
5 * This file handles all interactions with the DB.
6 *
7 * @package MainWP/Dashboard
8 */
9
10 namespace MainWP\Dashboard;
11
12 // Exit if accessed directly.
13 if ( ! defined( 'ABSPATH' ) ) {
14 exit;
15 }
16
17 /**
18 * Class MainWP_DB_Backup
19 *
20 * @package MainWP\Dashboard
21 */
22 class MainWP_DB_Backup extends MainWP_DB { // phpcs:ignore Generic.Classes.OpeningBraceSameLine.ContentAfterBrace -- NOSONAR.
23 // phpcs:disable WordPress.DB.RestrictedFunctions, WordPress.DB.PreparedSQL.NotPrepared -- unprepared SQL ok, accessing the database directly to custom database functions.
24
25 /**
26 * Instance variable class.
27 *
28 * @static
29 * @var (self|null) $instance Instance of MainWP_DB_Backup or null.
30 */
31 private static $instance = null;
32
33 /**
34 * Method instance()
35 *
36 * Create public static instance.
37 *
38 * @static
39 * @return MainWP_DB
40 */
41 public static function instance() {
42 if ( null === static::$instance ) {
43 static::$instance = new self();
44 }
45 return static::$instance;
46 }
47
48 /**
49 * Method get_website_backup_settings()
50 *
51 * Get Child Site backup settings.
52 *
53 * @param mixed $websiteid Child Site ID.
54 *
55 * @return object|null Database query result for Child Site backup settings or null on failure
56 *
57 * @uses \MainWP\Dashboard\MainWP_Utility::ctype_digit()
58 */
59 public function get_website_backup_settings( $websiteid ) {
60 if ( ! MainWP_Utility::ctype_digit( $websiteid ) ) {
61 return null;
62 }
63
64 return $this->get_row_result( $this->wpdb->prepare( 'SELECT * FROM ' . $this->table_name( 'wp_settings_backup' ) . ' WHERE wpid = %d ', $websiteid ) );
65 }
66
67 /**
68 * Method update_backup_task_progress()
69 *
70 * Update backup tasuk progress.
71 *
72 * @param mixed $task_id Task ID.
73 * @param mixed $wp_id Child Site ID.
74 * @param mixed $values Values to update.
75 *
76 * @return mixed get_backup_task_progres().
77 */
78 public function update_backup_task_progress( $task_id, $wp_id, $values ) {
79 $this->wpdb->update(
80 $this->table_name( 'wp_backup_progress' ),
81 $values,
82 array(
83 'task_id' => $task_id,
84 'wp_id' => $wp_id,
85 )
86 );
87
88 return $this->get_backup_task_progress( $task_id, $wp_id );
89 }
90
91 /**
92 * Method add_backup_task_progress()
93 *
94 * Add backup task progress.
95 *
96 * @param mixed $task_id Task ID.
97 * @param mixed $wp_id Child Site ID.
98 * @param mixed $information Task info to add.
99 *
100 * @return (array|null) $this->get_backup_task_progress() or null on failure
101 */
102 public function add_backup_task_progress( $task_id, $wp_id, $information ) {
103 $values = array(
104 'task_id' => $task_id,
105 'wp_id' => $wp_id,
106 'dtsFetched' => time(),
107 'fetchResult' => wp_json_encode( $information ),
108 'removedFiles' => 0,
109 'downloadedDB' => '',
110 'downloadedFULL' => '',
111 );
112
113 if ( $this->wpdb->insert( $this->table_name( 'wp_backup_progress' ), $values ) ) {
114 return $this->get_backup_task_progress( $task_id, $wp_id );
115 }
116
117 return null;
118 }
119
120 /**
121 * Method get_backup_task_progress()
122 *
123 * Get backup task progress.
124 *
125 * @param mixed $task_id Task ID.
126 * @param mixed $wp_id Child Site ID.
127 *
128 * @return (array|null) Backup Progress or null on failer.
129 */
130 public function get_backup_task_progress( $task_id, $wp_id ) {
131 $progress = $this->wpdb->get_row( $this->wpdb->prepare( 'SELECT * FROM ' . esc_sql( $this->table_name( 'wp_backup_progress' ) ) . ' WHERE task_id= %d AND wp_id = %d ', $task_id, $wp_id ) );
132
133 if ( $progress && '' !== $progress->fetchResult ) {
134 $progress->fetchResult = json_decode( $progress->fetchResult, true );
135 }
136
137 return $progress;
138 }
139
140 /**
141 * Method backup_full_task_running()
142 *
143 * Check if full backup task is running.
144 *
145 * @param mixed $wp_id Child Site ID.
146 *
147 * @return boolean true|false.
148 */
149 public function backup_full_task_running( $wp_id ) { // phpcs:ignore -- NOSONAR - complex.
150
151 if ( ! get_option( 'mainwp_enableLegacyBackupFeature' ) ) {
152 return false;
153 }
154
155 $progresses = $this->wpdb->get_results( $this->wpdb->prepare( 'SELECT * FROM ' . esc_sql( $this->table_name( 'wp_backup_progress' ) ) . ' WHERE wp_id = %d AND dtsFetched > %d ', $wp_id, time() - ( 30 * 60 ) ) );
156 if ( is_array( $progresses ) ) {
157 foreach ( $progresses as $progress ) {
158 if ( empty( $progress->downloadedDBComplete ) && empty( $progress->downloadedFULLComplete ) ) {
159 $task = $this->get_backup_task_by_id( $progress->task_id );
160 if ( $task && ( 'full' === $task->type ) && ! $task->paused ) {
161 return true;
162 }
163 }
164 }
165 }
166 return false;
167 }
168
169 /**
170 * Method remove_backup_task()
171 *
172 * Remove backup task.
173 *
174 * @param mixed $id Task ID.
175 *
176 * @return void
177 */
178 public function remove_backup_task( $id ) {
179 $this->wpdb->query( $this->wpdb->prepare( 'DELETE FROM ' . esc_sql( $this->table_name( 'wp_backup' ) ) . ' WHERE id = %d', $id ) );
180 }
181
182 /**
183 * Method get_backup_task_by_id()
184 *
185 * Get backup task by id.
186 *
187 * @param mixed $id Task ID.
188 *
189 * @return (object|null) Database query result for Backup Task or null on failure
190 */
191 public function get_backup_task_by_id( $id ) {
192 return $this->wpdb->get_row( $this->wpdb->prepare( 'SELECT * FROM ' . esc_sql( $this->table_name( 'wp_backup' ) ) . ' WHERE id= %d ', $id ) );
193 }
194
195 /**
196 * Method get_backup_tasks_for_user()
197 *
198 * Get backup tasks for current user.
199 *
200 * @param string $orderBy Task order.
201 *
202 * @return object|null Database query result for backup tasks for current user or null on failer.
203 *
204 * @uses \MainWP\Dashboard\MainWP_System::is_single_user()
205 */
206 public function get_backup_tasks_for_user( $orderBy = 'name' ) {
207 if ( MainWP_System::instance()->is_single_user() ) {
208 return $this->get_backup_tasks( null, $orderBy );
209 }
210
211 /**
212 * Current user global.
213 *
214 * @global string
215 */
216 global $current_user;
217
218 return $this->get_backup_tasks( $current_user->ID, $orderBy );
219 }
220
221 /**
222 * Method get_backup_tasks()
223 *
224 * Get backup tasks for current user.
225 *
226 * @param null $userid Current user ID.
227 * @param string $orderBy Task order.
228 *
229 * @return (object|null) Database query result for backup tasks for current user or null on failer.
230 */
231 public function get_backup_tasks( $userid = null, $orderBy = null ) {
232 return $this->wpdb->get_results( 'SELECT * FROM ' . esc_sql( $this->table_name( 'wp_backup' ) ) . ' WHERE ' . ( null === $userid ? '' : 'userid= ' . absint( $userid ) . ' AND ' ) . ' template = 0 ' . ( null !== $orderBy ? 'ORDER BY ' . esc_sql( $orderBy ) : '' ), OBJECT );
233 }
234
235 /**
236 * Method add_backup_task()
237 *
238 * Add backup task.
239 *
240 * @param mixed $userid Current user ID.
241 * @param mixed $name Name of backup.
242 * @param mixed $schedule Backup schedual.
243 * @param mixed $type Type of backup, full|db.
244 * @param mixed $exclude Files or directories to exclude.
245 * @param mixed $sites Child Sites to backup.
246 * @param mixed $groups Groups to backup.
247 * @param mixed $subfolder Folder the backups are going into.
248 * @param mixed $filename Filename of the backups.
249 * @param mixed $template Backup template.
250 * @param mixed $excludebackup Backup files to exclude.
251 * @param mixed $excludecache Cache files to exclude.
252 * @param mixed $excludenonwp Non-wp files to exclude.
253 * @param mixed $excludezip Archives to exclude.
254 * @param mixed $archiveFormat Format to store backups in.
255 * @param mixed $maximumFileDescriptorsOverride Overide maximum file descriptors.
256 * @param mixed $maximumFileDescriptorsAuto Auto maximum file discriptors.
257 * @param mixed $maximumFileDescriptors Maximum file descriptors.
258 * @param mixed $loadFilesBeforeZip Load files before Zip.
259 *
260 * @return int|false The number of rows added, or false on error.
261 *
262 * @uses \MainWP\Dashboard\MainWP_Utility::ctype_digit()
263 * @uses \MainWP\Dashboard\MainWP_Utility::remove_preslash_spaces()
264 */
265 public function add_backup_task(
266 $userid,
267 $name,
268 $schedule,
269 $type,
270 $exclude,
271 $sites,
272 $groups,
273 $subfolder,
274 $filename,
275 $template,
276 $excludebackup,
277 $excludecache,
278 $excludenonwp,
279 $excludezip,
280 $archiveFormat,
281 $maximumFileDescriptorsOverride,
282 $maximumFileDescriptorsAuto,
283 $maximumFileDescriptors,
284 $loadFilesBeforeZip
285 ) {
286
287 // to fix null value.
288 if ( empty( $exclude ) ) {
289 $exclude = '';
290 }
291
292 if ( MainWP_Utility::ctype_digit( $userid ) ) {
293 $values = array(
294 'userid' => $userid,
295 'name' => $name,
296 'schedule' => $schedule,
297 'type' => $type,
298 'exclude' => $exclude,
299 'sites' => $sites,
300 'groups' => $groups,
301 'last' => 0,
302 'last_run' => 0,
303 'last_run_manually' => 0,
304 'completed_sites' => '',
305 'completed' => 0,
306 'backup_errors' => '',
307 'subfolder' => MainWP_Utility::remove_preslash_spaces( $subfolder ),
308 'filename' => $filename,
309 'paused' => 0,
310 'template' => $template,
311 'excludebackup' => $excludebackup,
312 'excludecache' => $excludecache,
313 'excludenonwp' => $excludenonwp,
314 'excludezip' => $excludezip,
315 'archiveFormat' => $archiveFormat,
316 'loadFilesBeforeZip' => $loadFilesBeforeZip,
317 'maximumFileDescriptorsOverride' => $maximumFileDescriptorsOverride,
318 'maximumFileDescriptorsAuto' => $maximumFileDescriptorsAuto,
319 'maximumFileDescriptors' => $maximumFileDescriptors,
320 );
321
322 if ( $this->wpdb->insert( $this->table_name( 'wp_backup' ), $values ) ) {
323 return $this->get_backup_task_by_id( $this->wpdb->insert_id );
324 }
325 }
326
327 return false;
328 }
329
330 /**
331 * Method update_backup_task()
332 *
333 * Update backup task.
334 *
335 * @param mixed $id task id.
336 * @param mixed $userid Current user ID.
337 * @param mixed $name Name of backup.
338 * @param mixed $schedule Backup schedual.
339 * @param mixed $type Type of backup, full|db.
340 * @param mixed $exclude Files or directories to exclude.
341 * @param mixed $sites Child Sites to backup.
342 * @param mixed $groups Groups to backup.
343 * @param mixed $subfolder Folder the backups are going into.
344 * @param mixed $filename Filename of the backups.
345 * @param mixed $excludebackup Backup files to exclude.
346 * @param mixed $excludecache Cache files to exclude.
347 * @param mixed $excludenonwp Non-wp files to exclude.
348 * @param mixed $excludezip Archives to exclude.
349 * @param mixed $archiveFormat Format to store backups in.
350 * @param mixed $maximumFileDescriptorsOverride Overide maximum file descriptors.
351 * @param mixed $maximumFileDescriptorsAuto Auto maximum file discriptors.
352 * @param mixed $maximumFileDescriptors Maximum file descriptors.
353 * @param mixed $loadFilesBeforeZip Load files before Zip.
354 *
355 * @return int|false The number of rows updated, or false on error.
356 *
357 * @uses \MainWP\Dashboard\MainWP_Utility::ctype_digit()
358 * @uses \MainWP\Dashboard\MainWP_Utility::remove_preslash_spaces()
359 */
360 public function update_backup_task(
361 $id,
362 $userid,
363 $name,
364 $schedule,
365 $type,
366 $exclude,
367 $sites,
368 $groups,
369 $subfolder,
370 $filename,
371 $excludebackup,
372 $excludecache,
373 $excludenonwp,
374 $excludezip,
375 $archiveFormat,
376 $maximumFileDescriptorsOverride,
377 $maximumFileDescriptorsAuto,
378 $maximumFileDescriptors,
379 $loadFilesBeforeZip
380 ) {
381
382 if ( MainWP_Utility::ctype_digit( $userid ) && MainWP_Utility::ctype_digit( $id ) ) {
383 return $this->wpdb->update(
384 $this->table_name( 'wp_backup' ),
385 array(
386 'userid' => $userid,
387 'name' => $name,
388 'schedule' => $schedule,
389 'type' => $type,
390 'exclude' => $exclude,
391 'sites' => $sites,
392 'groups' => $groups,
393 'subfolder' => MainWP_Utility::remove_preslash_spaces( $subfolder ),
394 'filename' => $filename,
395 'excludebackup' => $excludebackup,
396 'excludecache' => $excludecache,
397 'excludenonwp' => $excludenonwp,
398 'excludezip' => $excludezip,
399 'archiveFormat' => $archiveFormat,
400 'loadFilesBeforeZip' => $loadFilesBeforeZip,
401 'maximumFileDescriptorsOverride' => $maximumFileDescriptorsOverride,
402 'maximumFileDescriptorsAuto' => $maximumFileDescriptorsAuto,
403 'maximumFileDescriptors' => $maximumFileDescriptors,
404 ),
405 array( 'id' => $id )
406 );
407 }
408
409 return false;
410 }
411
412 /**
413 * Method update_backup_task_with_values()
414 *
415 * Update backup task with values.
416 *
417 * @param mixed $id Task ID.
418 * @param mixed $values values to update.
419 *
420 * @return (int|false) The number of rows updated, or false on error.
421 */
422 public function update_backup_task_with_values( $id, $values ) {
423 if ( ! is_array( $values ) ) {
424 return false;
425 }
426
427 return $this->wpdb->update( $this->table_name( 'wp_backup' ), $values, array( 'id' => $id ) );
428 }
429
430 /**
431 * Method update_backup_run()
432 *
433 * Update backup run.
434 *
435 * @param mixed $id Task ID.
436 *
437 * @return int|false The number of rows updated, or false on error.
438 *
439 * @uses \MainWP\Dashboard\MainWP_Utility::ctype_digit()
440 */
441 public function update_backup_run( $id ) {
442 if ( MainWP_Utility::ctype_digit( $id ) ) {
443 return $this->wpdb->update(
444 $this->table_name( 'wp_backup' ),
445 array(
446 'last_run' => time(),
447 'last' => time(),
448 'completed_sites' => wp_json_encode( array() ),
449 ),
450 array( 'id' => $id )
451 );
452 }
453
454 return false;
455 }
456
457 /**
458 * Method update_backup_run_manually()
459 *
460 * Update backup run manually.
461 *
462 * @param mixed $id Task ID.
463 *
464 * @return int|false The number of rows updated, or false on error.
465 *
466 * @uses \MainWP\Dashboard\MainWP_Utility::ctype_digit()
467 */
468 public function update_backup_run_manually( $id ) {
469 if ( MainWP_Utility::ctype_digit( $id ) ) {
470 return $this->wpdb->update( $this->table_name( 'wp_backup' ), array( 'last_run_manually' => time() ), array( 'id' => $id ) );
471 }
472
473 return false;
474 }
475
476 /**
477 * Method update_backup_completed()
478 *
479 * Update backup completed()
480 *
481 * @param mixed $id Task ID.
482 *
483 * @return int|false The number of rows updated, or false on error.
484 *
485 * @uses \MainWP\Dashboard\MainWP_Utility::ctype_digit()
486 */
487 public function update_backup_completed( $id ) {
488 if ( MainWP_Utility::ctype_digit( $id ) ) {
489 return $this->wpdb->update( $this->table_name( 'wp_backup' ), array( 'completed' => time() ), array( 'id' => $id ) );
490 }
491
492 return false;
493 }
494
495 /**
496 * Method update_backup_errors()
497 *
498 * Update backup errors.
499 *
500 * @param mixed $id Task ID.
501 * @param mixed $errors Backup errors.
502 *
503 * @return int|false The number of rows updated, or false on error.
504 *
505 * @uses \MainWP\Dashboard\MainWP_Utility::ctype_digit()
506 */
507 public function update_backup_errors( $id, $errors ) {
508 if ( MainWP_Utility::ctype_digit( $id ) ) {
509 if ( '' === $errors ) {
510 return $this->wpdb->update( $this->table_name( 'wp_backup' ), array( 'backup_errors' => '' ), array( 'id' => $id ) );
511 } else {
512 $task = $this->get_backup_task_by_id( $id );
513
514 return $this->wpdb->update( $this->table_name( 'wp_backup' ), array( 'backup_errors' => $task->backup_errors . $errors ), array( 'id' => $id ) );
515 }
516 }
517
518 return false;
519 }
520
521 /**
522 * Method update_completed_sites()
523 *
524 * Update completed sites.
525 *
526 * @param mixed $id Task ID.
527 * @param mixed $completedSites Completed sites.
528 *
529 * @return int|false The number of rows updated, or false on error.
530 *
531 * @uses \MainWP\Dashboard\MainWP_Utility::ctype_digit()
532 */
533 public function update_completed_sites( $id, $completedSites ) {
534 if ( MainWP_Utility::ctype_digit( $id ) ) {
535 return $this->wpdb->update( $this->table_name( 'wp_backup' ), array( 'completed_sites' => wp_json_encode( $completedSites ) ), array( 'id' => $id ) );
536 }
537
538 return false;
539 }
540
541 /**
542 * Method get_backup_tasks_to_complete()
543 *
544 * Get backup tasks to complete.
545 *
546 * @return object Backup tasks.
547 */
548 public function get_backup_tasks_to_complete() {
549 return $this->wpdb->get_results( 'SELECT * FROM ' . esc_sql( $this->table_name( 'wp_backup' ) ) . ' WHERE paused = 0 AND completed < last_run', OBJECT );
550 }
551
552 /**
553 * Method get backup tasks daily.
554 *
555 * Get daily backup tasks.
556 *
557 * @return object Backup tasks.
558 */
559 public function get_backup_tasks_todo_daily() {
560 return $this->wpdb->get_results( 'SELECT * FROM ' . esc_sql( $this->table_name( 'wp_backup' ) ) . ' WHERE paused = 0 AND schedule="daily" AND ' . absint( time() ) . ' - last_run >= ' . ( 60 * 60 * 24 ), OBJECT );
561 }
562
563 /**
564 * Method get backup tasks weekly.
565 *
566 * Get weekly backup tasks.
567 *
568 * @return object Backup tasks.
569 */
570 public function get_backup_tasks_todo_weekly() {
571 return $this->wpdb->get_results( 'SELECT * FROM ' . esc_sql( $this->table_name( 'wp_backup' ) ) . ' WHERE paused = 0 AND schedule="weekly" AND ' . absint( time() ) . ' - last_run >= ' . ( 60 * 60 * 24 * 7 ), OBJECT );
572 }
573
574 /**
575 * Method get backup tasks monthly.
576 *
577 * Get monthly backup tasks.
578 *
579 * @return object Backup tasks.
580 */
581 public function get_backup_tasks_todo_monthly() {
582 return $this->wpdb->get_results( 'SELECT * FROM ' . esc_sql( $this->table_name( 'wp_backup' ) ) . ' WHERE paused = 0 AND schedule="monthly" AND ' . absint( time() ) . ' - last_run >= ' . ( 60 * 60 * 24 * 30 ), OBJECT );
583 }
584 }
585