PluginProbe
WP Database Backup – Unlimited Database & Files Backup by Backup for WP / 7.12
WP Database Backup – Unlimited Database & Files Backup by Backup for WP v7.12
7.13 7.12 trunk 1.1 2.1.1 5.9 6.0 6.1 6.10 6.11 6.12 6.12.1 6.2 6.3 6.4 6.5 6.5.1 6.6 6.7 6.8 6.9 7.0 7.0.1 7.1 7.10 All 34 releases
wp-database-backup / includes / features.php

features.php in WP Database Backup – Unlimited Database & Files Backup by Backup for WP 7.12, at includes/features.php

1,156 lines 37.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 if ( ! defined( 'ABSPATH' ) ) {
3 exit;
4 }
5
6 /**
7 * Log backup/restore messages when WP_DEBUG_LOG is enabled.
8 *
9 * @param string $message Log message.
10 */
11 function wpdbbkp_log( $message ) {
12 if ( defined( 'WP_DEBUG' ) && WP_DEBUG && defined( 'WP_DEBUG_LOG' ) && WP_DEBUG_LOG ) {
13 // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log -- Intentional backup operation logging.
14 error_log( $message );
15 }
16 }
17
18 // Anonimization code
19 add_filter('wpdbbkp_process_db_fields', 'bkpforwp_anonimize_database', 10, 3);
20 add_action('wp_ajax_wpdbbkp_check_extract_status', 'wpdbbkp_check_extract_status');
21 function wpdbbkp_check_extract_status(){
22 if ( ! isset( $_POST['wpdbbkp_admin_security_nonce'] ) || ! wp_verify_nonce( wp_unslash( $_POST['wpdbbkp_admin_security_nonce'] ), 'wpdbbkp_ajax_check_nonce' ) ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Nonce.
23 wp_send_json_success( esc_html__( 'Invalid nonce check.', 'wpdbbkp' ) );
24 return;
25 }
26 $get_progress = get_transient('wpdbbkp_track_progress');
27 if($get_progress==false){
28 wp_send_json_success(['success'=>1,'message'=>esc_html__('Starring Extraction Process', 'wpdbbkp')]);
29 }else{
30 if($get_progress=='Process Completed'){
31 delete_transient('wpdbbkp_track_progress');
32 }
33 wp_send_json_success(['success'=>1,'message'=>$get_progress]);
34 }
35 }
36
37 add_action('wp_ajax_wpdbbkp_upload_site_chunk', 'wpdbbkp_upload_site_chunk');
38 function wpdbbkp_upload_site_chunk() {
39 if ( ! isset( $_POST['wpdbbkp_admin_security_nonce'] ) || ! wp_verify_nonce( wp_unslash( $_POST['wpdbbkp_admin_security_nonce'] ), 'wpdbbkp_ajax_check_nonce' ) ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Nonce.
40 wp_send_json_success( esc_html__( 'Invalid nonce check.', 'wpdbbkp' ) );
41 return;
42 }
43 if ( ! isset( $_FILES['file'], $_POST['fileName'], $_POST['offset'] ) ) {
44 wp_send_json_error( esc_html__( 'Invalid request.', 'wpdbbkp' ) );
45 }
46
47 $upload_dir = WP_CONTENT_DIR . '/uploads/wpdbbkp/temp';
48 wp_mkdir_p( $upload_dir );
49
50 $file_name = sanitize_file_name( wp_unslash( $_POST['fileName'] ) );
51 $file_path = $upload_dir . '/' . $file_name;
52
53 $chunk_tmp = isset( $_FILES['file']['tmp_name'] ) ? $_FILES['file']['tmp_name'] : ''; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Validated with is_uploaded_file().
54
55 if ( empty( $chunk_tmp ) || ! is_uploaded_file( $chunk_tmp ) ) {
56 wp_send_json_error( esc_html__( 'Invalid upload.', 'wpdbbkp' ) );
57 }
58
59 // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents, WordPress.WP.AlternativeFunctions.file_system_operations_file_put_contents -- Appending validated upload chunk.
60 file_put_contents( $file_path, file_get_contents( $chunk_tmp ), FILE_APPEND );
61
62 wp_send_json_success(esc_html__('Chunk uploaded successfully.', 'wpdbbkp'));
63 }
64 add_action('wp_ajax_wpdbbkp_extract_uploaded_site', 'wpdbbkp_extract_uploaded_site');
65 function wpdbbkp_extract_uploaded_site() {
66
67 try {
68
69 if ( ! isset( $_POST['wpdbbkp_admin_security_nonce'] ) || ! wp_verify_nonce( wp_unslash( $_POST['wpdbbkp_admin_security_nonce'] ), 'wpdbbkp_ajax_check_nonce' ) ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Nonce.
70
71 wp_send_json_success( esc_html__( 'Invalid nonce check.', 'wpdbbkp' ) );
72
73 return;
74
75 }
76
77 // phpcs:ignore Squiz.PHP.DiscouragedFunctions.Discouraged -- Required for large backup extraction.
78 ini_set( 'max_execution_time', '0' );
79
80 // phpcs:ignore Squiz.PHP.DiscouragedFunctions.Discouraged -- Required for large backup extraction.
81 set_time_limit( 0 );
82
83 wpdbbkp_log( 'AJAX extraction started' );
84
85
86
87 if (!isset($_POST['fileName'])) {
88
89 throw new Exception("No file provided.");
90
91 }
92
93
94
95 $upload_dir = WP_CONTENT_DIR . '/uploads/wpdbbkp/temp';
96
97 $backup_file = $upload_dir . '/' . sanitize_file_name( wp_unslash( $_POST['fileName'] ) );
98
99
100
101 if (!file_exists($backup_file)) {
102
103 throw new Exception("Backup file not found.");
104
105 }
106
107
108
109 $extract_path = $upload_dir . '/extracted/';
110
111 $zip = new ZipArchive();
112
113 if ($zip->open($backup_file) !== TRUE) {
114
115 throw new Exception("Failed to open the ZIP archive.");
116
117 }
118
119
120
121 wp_mkdir_p( $extract_path );
122
123
124
125 wpdbbkp_log("ZIP contains " . $zip->numFiles . " files");
126
127
128
129
130
131 $root_folder = '';
132
133 for ($i = 0; $i < $zip->numFiles; $i++) {
134
135 $entry = $zip->getNameIndex($i);
136
137 if (preg_match('#^(.*?)/wp-content/#', $entry, $matches)) {
138
139 $root_folder = $matches[1] . '/';
140
141 break;
142
143 }
144
145 }
146
147 wpdbbkp_log("Detected root folder: $root_folder");
148
149
150
151
152
153 for ($i = 0; $i < $zip->numFiles; $i++) {
154
155 $entry = $zip->getNameIndex($i);
156
157 $normalized_entry = str_replace($root_folder, '', $entry);
158
159
160
161 if (preg_match('#^wp-content/plugins/#', $normalized_entry) ||
162
163 preg_match('#^wp-content/themes/#', $normalized_entry) ||
164
165 (pathinfo($normalized_entry, PATHINFO_EXTENSION) === 'sql' && substr_count($normalized_entry, '/') === 0)
166
167 ) {
168
169 if ($zip->extractTo($extract_path, $entry)) {
170
171 set_transient('wpdbbkp_track_progress', $entry, 3600);
172
173 wpdbbkp_log("Successfully extracted: $entry");
174
175
176
177 } else {
178
179 wpdbbkp_log("Extraction failed: $entry");
180
181 }
182
183 }
184
185 }
186
187
188
189 $zip->close();
190
191 set_transient('wpdbbkp_track_progress', 'Extraction of files completed. Now taking live plugins & themes', 3600);
192
193 $plugins_path = $extract_path . '/wp-content/plugins/';
194
195 $themes_path = $extract_path . '/wp-content/themes/';
196
197
198
199 // Move extracted files to wp-content
200
201 $ignore_plugins = ['wp-database-backup'];
202
203
204
205 if (file_exists($plugins_path)) {
206
207 wpdbbkp_move_extracted_files($plugins_path, WP_CONTENT_DIR . '/plugins/', $ignore_plugins);
208
209 } else {
210
211 wpdbbkp_log("Plugins directory not found in extracted folder.");
212
213 }
214
215
216
217 if (file_exists($themes_path)) {
218
219 wpdbbkp_move_extracted_files($themes_path, WP_CONTENT_DIR . '/themes/');
220
221 } else {
222
223 wpdbbkp_log("Themes directory not found in extracted folder OR extraction failed.");
224
225 }
226
227
228
229 // Process SQL file if found
230
231 $sql_file = wpdbbkp_find_sql_file($extract_path);
232
233 if ($sql_file) {
234
235 set_transient('wpdbbkp_track_progress', 'Migrating Database...', 3600);
236
237 $wp_config_prefix = wpdbbkp_get_wp_config_table_prefix();
238 wpdbbkp_log("Sql File .".$sql_file);
239 wpdbbkp_update_sql_table_prefix($sql_file);
240
241 wpdbbkp_restore_database($sql_file);
242
243 } else {
244
245 wpdbbkp_log("No SQL file found in extracted folder.");
246
247 }
248
249
250
251 wpdbbkp_log("Extraction completed successfully");
252
253 $wpdbbkp_folder = WP_CONTENT_DIR . '/uploads/wpdbbkp';
254 if (file_exists($wpdbbkp_folder)) {
255 wpdbbkp_delete_folder($wpdbbkp_folder);
256 wpdbbkp_log("Deleted wpdbbkp folder after successful migration.");
257 }
258 set_transient('wpdbbkp_track_progress', 'Process Completed', 3600);
259 wp_send_json_success(esc_html__('Plugins, Themes, Database & Table Prefix Updated!', 'wpdbbkp'));
260
261
262
263 } catch (Exception $e) {
264
265 wpdbbkp_log("Error: " . $e->getMessage());
266
267 wp_send_json_error($e->getMessage());
268
269 }
270
271 }
272
273 /**
274 * Initialize WP_Filesystem API.
275 *
276 * @return bool
277 */
278 function wpdbbkp_init_filesystem() {
279 global $wp_filesystem;
280 if ( ! empty( $wp_filesystem ) ) {
281 return true;
282 }
283 if ( ! function_exists( 'WP_Filesystem' ) ) {
284 require_once ABSPATH . 'wp-admin/includes/file.php';
285 }
286 return WP_Filesystem();
287 }
288
289 function wpdbbkp_delete_folder( $folder_path ) {
290 if ( ! is_dir( $folder_path ) ) {
291 return;
292 }
293
294 if ( ! wpdbbkp_init_filesystem() ) {
295 return;
296 }
297
298 global $wp_filesystem;
299
300 $files = array_diff( scandir( $folder_path ), array( '.', '..' ) );
301
302 foreach ( $files as $file ) {
303 $file_path = $folder_path . DIRECTORY_SEPARATOR . $file;
304 if ( is_dir( $file_path ) ) {
305 wpdbbkp_delete_folder( $file_path );
306 } else {
307 set_transient( 'wpdbbkp_track_progress', 'Cleaning : ' . $file_path, 3600 );
308 $wp_filesystem->delete( $file_path );
309 }
310 }
311
312 $wp_filesystem->rmdir( $folder_path );
313 }
314
315
316
317
318 function wpdbbkp_find_sql_file($directory) {
319
320 $files = scandir($directory);
321
322 foreach ($files as $file) {
323
324 if (pathinfo($file, PATHINFO_EXTENSION) === 'sql') {
325
326 return $directory . '/' . $file;
327
328 }
329
330 }
331
332 return false;
333
334 }
335
336
337
338 function wpdbbkp_get_wp_config_table_prefix() {
339
340 $config_file = ABSPATH . 'wp-config.php';
341 wpdbbkp_log("[ERROR] Config Path: $config_file");
342 if (!file_exists($config_file)) {
343
344 return 'wp_';
345
346 }
347
348 $config_contents = file_get_contents($config_file);
349
350 if (preg_match("/\$table_prefix\s*=\s*'([^']+)'/", $config_contents, $matches)) {
351
352 return $matches[1];
353
354 }
355
356 return 'wp_';
357
358 }
359 function wpdbbkp_update_sql_table_prefix($sql_file) {
360 if (!file_exists($sql_file)) {
361 die( esc_html( sprintf(
362 /* translators: %s: path to the SQL file */
363 __( 'ERROR: SQL file not found: %s', 'wpdbbkp' ),
364 $sql_file
365 ) ) );
366 }
367
368 $sql_content = file_get_contents($sql_file);
369
370 // Find wp-config.php
371 $wp_config_path = wpdbbkp_find_wp_config();
372 if (!$wp_config_path) {
373 die(esc_html__("❌ ERROR: wp-config.php not found!\n", 'wpdbbkp'));
374 }
375
376 // Extract table prefix from wp-config.php
377 $config_content = file_get_contents($wp_config_path);
378 if (preg_match("/\\\$table_prefix\s*=\s*['\"]([^'\"]+)['\"]\s*;/", $config_content, $matches)) {
379 $new_prefix = $matches[1];
380 echo esc_html( sprintf(
381 /* translators: %s: table prefix from wp-config.php */
382 __( 'SUCCESS: Extracted new prefix from wp-config.php: %s', 'wpdbbkp' ),
383 $new_prefix
384 ) ) . "\n";
385 } else {
386 die(esc_html__("❌ ERROR: Could not extract table prefix from wp-config.php!\n", 'wpdbbkp'));
387 }
388
389 // Detect old prefix from the SQL file
390 if (preg_match("/(CREATE TABLE|INSERT INTO|ALTER TABLE|UPDATE|DELETE FROM)\s+[`']?([a-zA-Z0-9]+?_)/i", $sql_content, $matches)) {
391 $old_prefix = $matches[2];
392 echo esc_html( sprintf(
393 /* translators: %s: table prefix found in the SQL file */
394 __( 'SUCCESS: Found old prefix in SQL file: %s', 'wpdbbkp' ),
395 $old_prefix
396 ) ) . "\n";
397 } else {
398 die(esc_html__("❌ ERROR: No table prefix found in the SQL file!\n", 'wpdbbkp'));
399 }
400
401 // Prevent replacing if old prefix is same as new prefix
402 if ($old_prefix === $new_prefix) {
403 die( esc_html( sprintf(
404 /* translators: %s: table prefix */
405 __( 'INFO: Old and new prefixes are the same (%s), no changes needed.', 'wpdbbkp' ),
406 $old_prefix
407 ) ) );
408 }
409
410 // Replace all occurrences of the old prefix with the new one
411 $sql_content = preg_replace("/\b" . preg_quote($old_prefix, '/') . "/i", $new_prefix, $sql_content);
412
413 // Write the updated content back to the SQL file
414 file_put_contents($sql_file, $sql_content);
415
416 echo esc_html( sprintf(
417 /* translators: 1: old table prefix, 2: new table prefix, 3: path to SQL file */
418 __( 'SUCCESS: Table prefix updated from %1$s to %2$s in %3$s!', 'wpdbbkp' ),
419 $old_prefix,
420 $new_prefix,
421 $sql_file
422 ) ) . "\n";
423 }
424
425 /**
426 * Finds the root wp-config.php file by checking parent directories.
427 */
428 function wpdbbkp_find_wp_config() {
429 $dir = __DIR__;
430
431 while ($dir !== dirname($dir)) { // Keep going up until the root
432 $config_path = $dir . '/wp-config.php';
433 if (file_exists($config_path)) {
434 return $config_path;
435 }
436 $dir = dirname($dir);
437 }
438
439 return false; // wp-config.php not found
440 }
441
442
443
444
445
446
447
448
449 function wpdbbkp_move_extracted_files( $source, $destination, $ignore = array() ) {
450 if ( ! file_exists( $source ) || ! wpdbbkp_init_filesystem() ) {
451 return;
452 }
453
454 global $wp_filesystem;
455
456 wp_mkdir_p( $destination );
457
458 $files = array_diff( scandir( $source ), array( '.', '..' ) );
459 foreach ( $files as $file ) {
460 $src_file = rtrim( $source, '/' ) . '/' . $file;
461 $dest_file = rtrim( $destination, '/' ) . '/' . $file;
462
463 if ( in_array( $file, $ignore, true ) ) {
464 continue;
465 }
466
467 set_transient( 'wpdbbkp_track_progress', 'Copying: ' . $dest_file, 3600 );
468
469 if ( is_dir( $src_file ) ) {
470 if ( $wp_filesystem->exists( $dest_file ) ) {
471 wpdbbkp_delete_directory( $dest_file );
472 }
473 $wp_filesystem->move( $src_file, $dest_file, true );
474 } else {
475 if ( $wp_filesystem->exists( $dest_file ) ) {
476 $wp_filesystem->delete( $dest_file );
477 }
478 $wp_filesystem->move( $src_file, $dest_file, true );
479 }
480 }
481 }
482
483 function wpdbbkp_delete_directory( $dir ) {
484 if ( ! wpdbbkp_init_filesystem() ) {
485 return false;
486 }
487
488 global $wp_filesystem;
489
490 if ( ! $wp_filesystem->exists( $dir ) ) {
491 return false;
492 }
493
494 if ( ! $wp_filesystem->is_dir( $dir ) ) {
495 return $wp_filesystem->delete( $dir );
496 }
497
498 $files = array_diff( scandir( $dir ), array( '.', '..' ) );
499 foreach ( $files as $file ) {
500 $file_path = $dir . DIRECTORY_SEPARATOR . $file;
501 if ( $wp_filesystem->is_dir( $file_path ) ) {
502 wpdbbkp_delete_directory( $file_path );
503 } else {
504 $wp_filesystem->delete( $file_path );
505 }
506 }
507
508 return $wp_filesystem->rmdir( $dir );
509 }
510
511
512 function wpdbbkp_restore_database($sql_file) {
513
514 global $wpdb;
515
516 $new_site_url = get_site_url();
517
518
519
520 if (!file_exists($sql_file)) {
521
522 wpdbbkp_log("[ERROR] SQL file not found: $sql_file");
523
524 return false;
525
526 }
527
528
529
530 $sql_content = file_get_contents($sql_file);
531
532 if (!$sql_content) {
533
534 wpdbbkp_log("[ERROR] Failed to read SQL file: $sql_file");
535
536 return false;
537
538 }
539
540
541
542 // phpcs:disable WordPress.DB.DirectDatabaseQuery -- Direct $wpdb access required for SQL backup restore.
543 // Fetch old site URL from wp_options before updating
544
545 $old_site_url = $wpdb->get_var("SELECT option_value FROM {$wpdb->options} WHERE option_name = 'siteurl'");
546
547
548
549 if (!$old_site_url) {
550
551 wpdbbkp_log("[ERROR] Failed to fetch old site URL.");
552
553 return false;
554
555 }
556
557
558
559 wpdbbkp_log("[INFO] Old Site URL detected: $old_site_url");
560
561
562
563 // Split SQL statements properly
564
565 $queries = preg_split('/;\s*\n/', $sql_content, -1, PREG_SPLIT_NO_EMPTY);
566
567
568
569 // Tables to exclude (e.g., Users and Usermeta for security reasons)
570
571 $excluded_tables = ['users','usermeta','options'];
572
573
574
575 $wpdb->query('SET foreign_key_checks = 0'); // Disable FK checks
576
577 $wpdb->query('START TRANSACTION'); // Start transaction
578
579
580
581 try {
582
583 foreach ($queries as $query) {
584
585 $query = trim($query);
586
587 if (empty($query)) continue;
588
589 $query = str_replace('options','option_tmp',$query);
590
591 // Check for CREATE TABLE and extract table name
592
593 if (preg_match('/CREATE TABLE `([^`]*)`/', $query, $matches)) {
594
595 $table_name = $matches[1];
596
597
598
599 // Skip excluded tables
600
601 foreach ($excluded_tables as $excluded) {
602
603 if (strpos($table_name, $excluded) !== false) {
604
605 wpdbbkp_log("[SKIPPED] Table excluded: $table_name");
606
607 continue 2;
608
609 }
610
611 }
612
613
614
615 // Drop existing table before restoring
616
617 $wpdb->query( 'DROP TABLE IF EXISTS `' . esc_sql( $table_name ) . '`' );
618
619 wpdbbkp_log("[DROPPED] Table: $table_name");
620
621 }
622
623
624
625 // Skip execution of queries for excluded tables
626
627 foreach ($excluded_tables as $excluded) {
628
629 if (strpos($query, $excluded) !== false) {
630
631 wpdbbkp_log("[SKIPPED] Query contains excluded table reference.");
632
633 continue 2;
634
635 }
636
637 }
638
639
640
641 // Execute the query (dynamic SQL from backup; prepare cannot cover arbitrary statements).
642
643 // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter -- Restoring statements from trusted backup file.
644 $result = $wpdb->query( $query );
645
646 if ($result === false) {
647
648 throw new Exception("[ERROR] Failed to execute query: " . $wpdb->last_error);
649
650 }
651
652 }
653
654
655
656
657
658
659
660 // **Find and replace old URLs in all tables**
661
662 $tables = $wpdb->get_results("SHOW TABLES", ARRAY_N);
663
664 foreach ($tables as $table) {
665
666 $table_name = esc_sql( $table[0] );
667
668
669
670 // Skip excluded tables
671
672 foreach ($excluded_tables as $excluded) {
673
674 if (strpos($table_name, $excluded) !== false) {
675
676 wpdbbkp_log("[SKIPPED] URL Replacement in: $table_name");
677
678 continue 2;
679
680 }
681
682 }
683
684
685
686 // Get all columns for the table
687
688 // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- Table name escaped with esc_sql().
689 $columns = $wpdb->get_results( "SHOW COLUMNS FROM `{$table_name}`", ARRAY_A );
690
691 foreach ($columns as $column) {
692
693 $column_name = esc_sql( $column['Field'] );
694
695
696
697 // Update all occurrences of old URL in text-based columns.
698 $wpdb->query(
699 $wpdb->prepare(
700 "UPDATE `{$table_name}` SET `{$column_name}` = REPLACE(`{$column_name}`, %s, %s) WHERE `{$column_name}` LIKE %s", // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- Table and column identifiers escaped with esc_sql().
701 $old_site_url,
702 $new_site_url,
703 '%' . $wpdb->esc_like( $old_site_url ) . '%'
704 )
705 );
706
707 }
708
709 }
710
711
712
713 $blogname = $wpdb->get_var("SELECT option_value FROM {$wpdb->prefix}option_tmp WHERE option_name = 'blogname'");
714
715 if ($blogname) {
716
717 $wpdb->query(
718
719 $wpdb->prepare(
720
721 "UPDATE {$wpdb->prefix}options SET option_value = %s WHERE option_name = 'blogname'",
722
723 $blogname
724
725 )
726
727 );
728
729 wpdbbkp_log("[SUCCESS] Updated wp_options with blogname from option_tmp");
730
731 }
732 $active_plugins = $wpdb->get_var("SELECT option_value FROM {$wpdb->prefix}option_tmp WHERE option_name = 'active_plugins'");
733
734 if ($active_plugins) {
735
736 $wpdb->query(
737
738 $wpdb->prepare(
739
740 "UPDATE {$wpdb->prefix}options SET option_value = %s WHERE option_name = 'active_plugins'",
741
742 $active_plugins
743
744 )
745
746 );
747
748 wpdbbkp_log("[SUCCESS] Updated wp_options with active_plugins from option_tmp");
749
750 }
751
752 $wpdb->query('COMMIT'); // Commit transaction
753
754 wpdbbkp_log("[SUCCESS] Database restoration and URL replacement completed from: $sql_file");
755
756 return true;
757
758
759
760 } catch (Exception $e) {
761
762 $wpdb->query('ROLLBACK'); // Rollback in case of an error
763
764 wpdbbkp_log($e->getMessage());
765
766 return false;
767
768 } finally {
769
770 $wpdb->query('SET foreign_key_checks = 1'); // Re-enable FK checks
771
772 }
773
774 // phpcs:enable WordPress.DB.DirectDatabaseQuery
775
776 }
777 function bkpforwp_anonimize_database($value, $table, $column)
778 {
779 $enable_anonymization = get_option('bkpforwp_enable_anonymization', false);
780 $anonymization_type = get_option('bkpforwp_anonymization_type', false);
781 $enable_backup_encryption = get_option('bkpforwp_enable_backup_encryption', false);
782 $anonymization_pass = get_option('bkpforwp_anonymization_pass', '');
783
784
785 if (isset($enable_anonymization) && $enable_anonymization == 1) {
786 global $wpdb;
787 $bkpforwp_process_table = array($wpdb->prefix . 'options', $wpdb->prefix . 'users', $wpdb->prefix . 'usermeta', $wpdb->prefix . 'wc_customer_lookup', $wpdb->prefix . 'edd_customers', $wpdb->prefix . 'edd_customermeta');
788 $bkpforwp_process_cols = array('mailserver_pass', 'mailserver_login', 'user_email', 'email', 'user_url', 'nickname', 'name', 'twitter', 'facebook', 'instagram', 'phone', 'mobile', 'address', 'city', 'zip', 'pincode', 'user_login', 'postcode', 'state', 'user_ip', 'ip_address');
789
790 //Masking Logic
791 if (isset($anonymization_type) && $anonymization_type == 'masked_data') {
792 if (in_array($table, $bkpforwp_process_table)) {
793 $check_str = implode(',', $bkpforwp_process_cols);
794 if (stripos($check_str, $column) !== false) {
795 return str_replace($value, str_repeat('*', strlen($value)), $value);
796 }
797 }
798 }
799 //FakeData Logic
800
801 if (isset($anonymization_type) && $anonymization_type == 'fake_data') {
802 if (function_exists('wp_privacy_anonymize_data')) {
803 $bkpforwp_process_email = implode(',', array('email', 'user_email'));
804 $bkpforwp_process_url = implode(',', array('url', 'user_url', 'twitter', 'facebook', 'instagram'));
805 $bkpforwp_process_ip = implode(',', array('user_ip', 'ip_address'));
806 $bkpforwp_process_text = implode(',', array('nickname', 'name', 'address', 'phone', 'mobile', 'city', 'zip', 'pincode', 'user_login', 'postcode', 'state'));
807
808 if (in_array($table, $bkpforwp_process_table)) {
809
810 //For email
811 if (stripos($bkpforwp_process_email, $column) !== false) {
812 return str_replace($value, wp_privacy_anonymize_data('email', $value), $value);
813 }
814
815 if (stripos($bkpforwp_process_url, $column) !== false) {
816 return str_replace($value, wp_privacy_anonymize_data('url', $value), $value);
817 }
818
819 if (stripos($bkpforwp_process_ip, $column) !== false) {
820 return str_replace($value, wp_privacy_anonymize_data('ip', $value), $value);
821 }
822
823 if (stripos($bkpforwp_process_text, $column) !== false) {
824 return str_replace($value, wp_privacy_anonymize_data('text', $value), $value);
825 }
826
827 }
828
829 return $value;
830
831 } else {
832 if (in_array($table, $bkpforwp_process_table)) {
833 $check_str = implode(',', $bkpforwp_process_cols);
834 if (stripos($check_str, $column) !== false) {
835 return str_replace($value, str_repeat('*', strlen($value)), $value);
836 }
837 }
838 }
839
840 }
841
842 if (isset($anonymization_type) && $anonymization_type == 'encrypted_data' && !empty($anonymization_pass)) {
843 require_once 'class-symmetric-encryption.php';
844
845 if (in_array($table, $bkpforwp_process_table)) {
846 $check_str = implode(',', $bkpforwp_process_cols);
847 if (stripos($check_str, $column) !== false) {
848 $enc_pass = $anonymization_pass;
849 $encryption = new WPDBBackupSymmetricEncryption();
850 return str_replace($value, '<==>' . $encryption->encrypt($value, $enc_pass, $enc_pass) . '<==>', $value);
851 }
852
853 }
854
855 }
856
857 }
858 return $value;
859 }
860
861 add_filter('wpdbbkp_sql_query_restore', 'bkpforwp_sql_query_restore', 1);
862 function bkpforwp_sql_query_restore($sql_query)
863 {
864 $anonymization_type = get_option('bkpforwp_anonymization_type', false);
865 $anonymization_pass = get_option('bkpforwp_anonymization_pass', '');
866 if (isset($anonymization_type) && $anonymization_type == 'encrypted_data' && !empty($anonymization_pass)) {
867
868 $pattern = '/<==>(.*?)<==>/i';
869 return preg_replace_callback($pattern, 'bkpforwp_sql_restore_replace', $sql_query);
870 }
871 return $sql_query;
872 }
873
874 function bkpforwp_sql_restore_replace($matches)
875 {
876 $anonymization_pass = get_option('bkpforwp_anonymization_pass', '');
877 $enc_pass = isset($anonymization_pass) ? $anonymization_pass : false;
878 if ($enc_pass) {
879 require_once 'class-symmetric-encryption.php';
880 $encryption = new WPDBBackupSymmetricEncryption();
881 return $encryption->decrypt($matches[0], $enc_pass, $enc_pass);
882 }
883 return $matches[0];
884 }
885
886 add_action('wpdbbkp_database_backup_options', 'bkpforwp_database_backup_options');
887 function bkpforwp_database_backup_options()
888 {
889 $settings = get_option('wp_db_backup_options');
890 $autobackup_days = isset($settings['autobackup_days']) ? implode(',', $settings['autobackup_days']) : ',';
891 $autobackup_time = isset($settings['autobackup_time']) ? $settings['autobackup_time'] : '';
892 $autobackup_date = isset($settings['autobackup_date']) ? $settings['autobackup_date'] : '';
893 ?>
894
895
896 <div class="row form-group autobackup_frequency_pro" style="display:none"><label
897 class="col-sm-12 autobackup_daily_pro">We will automatically backup at 00:00 AM daily. <b><a
898 href="javascript:modify_backup_frequency();">Change Back Frequency Timings</a></b></label></div>
899 <div class="row form-group autobackup_frequency_pro" style="display:none"><label
900 class="col-sm-12 autobackup_weekly_pro">We will automatically backup every Sunday on weekly basis. <b><a
901 href="javascript:modify_backup_frequency();">Change Back Frequency Timings</a></b></label></div>
902 <div class="row form-group autobackup_frequency_pro" style="display:none"><label
903 class="col-sm-12 autobackup_monthly_pro">We will automatically backup on 1st on Monday on monthly basis. <b><a
904 href="javascript:modify_backup_frequency();">Change Back Frequency Timings</a></b></label></div>
905
906
907 <div class="row form-group autobackup_days database_autobackup" style="display:none">
908 <label class="col-sm-3" for="autobackup_days"><?php esc_html_e('Database Backup Days', 'wpdbbkp'); ?></label>
909 <div class="col-sm-9">
910 <select id="autobackup_days" class="form-control bkpforwp_multiselect"
911 name="wp_db_backup_options[autobackup_days][]" multiple>
912 <option value="Mon" <?php if (strpos($autobackup_days, 'Mon') !== false) {
913 echo 'selected';
914 } ?>>
915 <?php esc_html_e('Monday', 'wpdbbkp'); ?></option>
916 <option value="Tue" <?php if (strpos($autobackup_days, 'Tue') !== false) {
917 echo 'selected';
918 } ?>>
919 <?php esc_html_e('Tuesday', 'wpdbbkp'); ?></option>
920 <option value="Wed" <?php if (strpos($autobackup_days, 'Wed') !== false) {
921 echo 'selected';
922 } ?>>
923 <?php esc_html_e('Wednesday', 'wpdbbkp'); ?></option>
924 <option value="Thu" <?php if (strpos($autobackup_days, 'Thu') !== false) {
925 echo 'selected';
926 } ?>>
927 <?php esc_html_e('Thursday', 'wpdbbkp'); ?></option>
928 <option value="Fri" <?php if (strpos($autobackup_days, 'Fri') !== false) {
929 echo 'selected';
930 } ?>>
931 <?php esc_html_e('Friday', 'wpdbbkp'); ?></option>
932 <option value="Sat" <?php if (strpos($autobackup_days, 'Sat') !== false) {
933 echo 'selected';
934 } ?>>
935 <?php esc_html_e('Saturday', 'wpdbbkp'); ?></option>
936 <option value="Sun" <?php if (strpos($autobackup_days, 'Sun') !== false) {
937 echo 'selected';
938 } ?>>
939 <?php esc_html_e('Sunday', 'wpdbbkp'); ?></option>
940 </select>
941 </div>
942 </div>
943 <div class="row form-group autobackup_date database_autobackup" style="display:none">
944 <label class="col-sm-3" for="autobackup_date"><?php esc_html_e('Database Backup Date', 'wpdbbkp'); ?></label>
945 <div class="col-sm-9">
946 <input type="date" id="autobackup_date" value="<?php echo esc_attr($autobackup_date); ?>"
947 class="form-control bkpforwp_multiselect" name="wp_db_backup_options[autobackup_date]">
948 </div>
949 </div>
950 <div class="row form-group autobackup_time database_autobackup" style="display:none">
951 <label class="col-sm-3" for="autobackup_time"><?php esc_html_e('Database Backup Time', 'wpdbbkp'); ?></label>
952 <div class="col-sm-9">
953 <input type="time" id="autobackup_time" value="<?php echo esc_attr($autobackup_time); ?>"
954 class="form-control bkpforwp_multiselect" name="wp_db_backup_options[autobackup_time]">
955 </div>
956 </div>
957
958 <?php
959 }
960
961 add_action('wpdbbkp_full_backup_options', 'bkpforwp_full_backup_options');
962 function bkpforwp_full_backup_options()
963 {
964
965 $settings = get_option('wp_db_backup_options');
966 $autobackup_days = isset($settings['autobackup_full_days']) ? implode(',', $settings['autobackup_full_days']) : ',';
967 $autobackup_time = isset($settings['autobackup_full_time']) ? $settings['autobackup_full_time'] : '';
968 $autobackup_date = isset($settings['autobackup_full_date']) ? $settings['autobackup_full_date'] : '';
969 $autobackup_date = isset($settings['autobackup_full_date']) ? $settings['autobackup_full_date'] : '';
970 $senable_exact_backup_time = get_option('bkpforwp_enable_exact_backup_time', false);
971 if ($senable_exact_backup_time) {
972 ?>
973 <div class="row form-group autobackup_full_days full_autobackup" style="display:none">
974 <label class="col-sm-3" for="autobackup_full_days"><?php esc_html_e('Full Backup Days', 'wpdbbkp'); ?></label>
975 <div class="col-sm-9">
976 <select id="autobackup_full_days" class="form-control bkpforwp_multiselect"
977 name="wp_db_backup_options[autobackup_full_days][]" multiple>
978 <option value="Mon" <?php if (strpos($autobackup_days, 'Mon') !== false) {
979 echo 'selected';
980 } ?>>
981 <?php esc_html_e('Monday', 'wpdbbkp'); ?></option>
982 <option value="Tue" <?php if (strpos($autobackup_days, 'Tue') !== false) {
983 echo 'selected';
984 } ?>>
985 <?php esc_html_e('Tuesday', 'wpdbbkp'); ?></option>
986 <option value="Wed" <?php if (strpos($autobackup_days, 'Wed') !== false) {
987 echo 'selected';
988 } ?>>
989 <?php esc_html_e('Wednesday', 'wpdbbkp'); ?></option>
990 <option value="Thu" <?php if (strpos($autobackup_days, 'Thu') !== false) {
991 echo 'selected';
992 } ?>>
993 <?php esc_html_e('Thursday', 'wpdbbkp'); ?></option>
994 <option value="Fri" <?php if (strpos($autobackup_days, 'Fri') !== false) {
995 echo 'selected';
996 } ?>>
997 <?php esc_html_e('Friday', 'wpdbbkp'); ?></option>
998 <option value="Sat" <?php if (strpos($autobackup_days, 'Sat') !== false) {
999 echo 'selected';
1000 } ?>>
1001 <?php esc_html_e('Saturday', 'wpdbbkp'); ?></option>
1002 <option value="Sun" <?php if (strpos($autobackup_days, 'Sun') !== false) {
1003 echo 'selected';
1004 } ?>>
1005 <?php esc_html_e('Sunday', 'wpdbbkp'); ?></option>
1006 </select>
1007 </div>
1008 </div>
1009 <div class="row form-group autobackup_full_date full_autobackup" style="display:none">
1010 <label class="col-sm-3" for="autobackup_full_date"><?php esc_html_e('Full Backup Date', 'wpdbbkp'); ?></label>
1011 <div class="col-sm-9">
1012 <input type="date" id="autobackup_full_date" value="<?php echo esc_attr($autobackup_date); ?>" class="form-control"
1013 name="wp_db_backup_options[autobackup_full_date]">
1014 </div>
1015 </div>
1016 <div class="row form-group autobackup_full_time full_autobackup" style="display:none">
1017 <label class="col-sm-3" for="autobackup_full_time"><?php esc_html_e('Full Backup Time', 'wpdbbkp'); ?></label>
1018 <div class="col-sm-9">
1019 <input type="time" id="autobackup_full_time" value="<?php echo esc_attr($autobackup_time); ?>" class="form-control"
1020 name="wp_db_backup_options[autobackup_full_time]">
1021 </div>
1022 </div>
1023 <?php
1024 }
1025 }
1026
1027 add_filter('wpdbbkp_fullback_cron_condition', 'bkpforwp_fullback_cron_condition');
1028 function bkpforwp_fullback_cron_condition($value)
1029 {
1030 $options_settings = get_option('wp_db_backup_options', false);
1031
1032 $senable_exact_backup_time = get_option('bkpforwp_enable_exact_backup_time', false);
1033 if (!$senable_exact_backup_time) {
1034 return $value;
1035 }
1036 if (wp_doing_cron() && $options_settings && isset($options_settings['enable_autobackups']) && $options_settings['enable_autobackups'] == 1 && isset($options_settings['full_autobackup_frequency'])) {
1037 if ($options_settings['full_autobackup_frequency'] == 'daily' && isset($options_settings['autobackup_full_time']) && $options_settings['autobackup_full_time']) {
1038 if ($options_settings['autobackup_full_time'] < gmdate("H:i") || $options_settings['autobackup_full_time'] > gmdate("H:i", strtotime('+30 minutes', gmdate("H:i")))) {
1039 $value = false;
1040 }
1041 }
1042 if ($options_settings['full_autobackup_frequency'] == 'weekly' && isset($options_settings['autobackup_full_time']) && $options_settings['autobackup_full_time'] && isset($options_settings['autobackup_full_days'])) {
1043 $current_day = gmdate('M');
1044 $current_time = gmdate('H:i');
1045 $allowed_days = $options_settings['autobackup_full_days'];
1046 if (!in_array($current_day, $allowed_days) || ($options_settings['autobackup_full_time'] < $current_time) || $options_settings['autobackup_full_time'] > gmdate("H:i", strtotime('+30 minutes', $current_time))) {
1047 $value = false;
1048 }
1049 }
1050 if ($options_settings['full_autobackup_frequency'] == 'monthly' && isset($options_settings['autobackup_full_time']) && $options_settings['autobackup_full_time'] && isset($options_settings['autobackup_full_date'])) {
1051 $current_date = gmdate('d');
1052 $current_time = gmdate('H:i');
1053 $allowed_date = gmdate('d', strtotime($options_settings['autobackup_full_date']));
1054 if (($allowed_date != $current_date) || ($options_settings['autobackup_full_time'] < $current_time || $options_settings['autobackup_full_time'] > gmdate("H:i", strtotime('+30 minutes', $current_time)))) {
1055 $value = false;
1056 }
1057 }
1058 }
1059 return $value;
1060 }
1061
1062 add_filter('wpdbbkp_dbback_cron_condition', 'bkpforwp_dbback_cron_condition');
1063 function bkpforwp_dbback_cron_condition($value)
1064 {
1065 $options_settings = get_option('wp_db_backup_options', false);
1066 if (wp_doing_cron() && $options_settings && isset($options_settings['enable_autobackups']) && $options_settings['enable_autobackups'] == 1 && isset($options_settings['autobackup_frequency'])) {
1067 if ($options_settings['autobackup_frequency'] == 'daily' && isset($options_settings['autobackup_time'])) {
1068 if ($options_settings['autobackup_time'] < gmdate("H:i") || $options_settings['autobackup_time'] > gmdate("H:i", strtotime('+30 minutes', gmdate("H:i")))) {
1069 $value = false;
1070 }
1071 }
1072 if ($options_settings['autobackup_frequency'] == 'weekly' && isset($options_settings['autobackup_time']) && isset($options_settings['autobackup_days'])) {
1073 $current_day = gmdate('M');
1074 $current_time = gmdate('H:i');
1075 $allowed_days = $options_settings['autobackup_days'];
1076 if (!in_array($current_day, $allowed_days) || ($options_settings['autobackup_time'] < $current_time || $options_settings['autobackup_time'] > gmdate("H:i", strtotime('+30 minutes', $current_time)))) {
1077 $value = false;
1078 }
1079 }
1080 if ($options_settings['autobackup_frequency'] == 'monthly' && isset($options_settings['autobackup_time']) && isset($options_settings['autobackup_date'])) {
1081 $current_date = gmdate('d');
1082 $current_time = gmdate('H:i');
1083 $allowed_date = gmdate('d', strtotime($options_settings['autobackup_date']));
1084 if (($allowed_date != $current_date) || ($options_settings['autobackup_time'] < $current_time || $options_settings['autobackup_time'] > gmdate("H:i", strtotime('+30 minutes', $current_time)))) {
1085 $value = false;
1086 }
1087 }
1088 }
1089 return $value;
1090 }
1091
1092 add_filter('wpdbbkp_dbback_cron_frequency', 'bkpforwp_dbback_cron_frequency');
1093
1094 function bkpforwp_dbback_cron_frequency($value)
1095 {
1096 if (wp_doing_cron()) {
1097 $options = get_option('wp_db_backup_options');
1098 if (isset($options['autobackup_full_time']) && !empty($options['autobackup_full_time'])) {
1099 $value = 'thirty_minutes';
1100 }
1101 }
1102 return $value;
1103 }
1104
1105 /**
1106 * Function to force the new .htaccess file to fix the backup folder protection
1107 */
1108 function wpdbbkp_fix_htaccess_on_update()
1109 {
1110 static $wpdbbkp_htaccess_fix = false;
1111
1112 if (!$wpdbbkp_htaccess_fix && version_compare(WPDB_VERSION, '7.4', '>=')) {
1113 $wpdbbkp_htaccess_fix = true;
1114 $option_name = 'wpdbbkp_htaccess_fix';
1115 if (get_option($option_name, false)) {
1116 return; // Exit if already fixed
1117 }
1118
1119 // Initialize WP Filesystem
1120 global $wp_filesystem;
1121
1122 if (!function_exists('WP_Filesystem')) {
1123 require_once ABSPATH . 'wp-admin/includes/file.php';
1124 }
1125
1126 if (!WP_Filesystem()) {
1127 return;
1128 }
1129 // Define the .htaccess content
1130 $htaccess_content = "
1131 # Disable public access to this folder
1132 <IfModule mod_authz_core.c>
1133 Require all denied
1134 </IfModule>
1135
1136 <IfModule !mod_authz_core.c>
1137 Deny from all
1138 </IfModule>
1139 ";
1140
1141 $path_info = wp_upload_dir();
1142 $backup_folder = $path_info['basedir'] . '/' . WPDB_BACKUPS_DIR . '/';
1143 $htaccess_file = trailingslashit($backup_folder) . '.htaccess';
1144
1145 if ($wp_filesystem->exists($htaccess_file)) {
1146 $wp_filesystem->delete($htaccess_file);
1147 }
1148
1149 if (!$wp_filesystem->put_contents($htaccess_file, $htaccess_content, FS_CHMOD_FILE)) {
1150 return;
1151 }
1152 update_option($option_name, time(), false);
1153 }
1154 }
1155
1156 add_action('admin_init', 'wpdbbkp_fix_htaccess_on_update');