$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTECs::set_setting( 'backup', 'last_run', ITSEC_Core::get_current_time_gmt() ); } if ( $this->settings['all_sites'] ) { $tables = $wpdb->get_col( 'SHOW TABLES' ); } else { $tables = $wpdb->get_col( $wpdb->prepare( 'SHOW TABLES LIKE %s', $wpdb->base_prefix . '%' ) ); } $max_rows_per_query = 1000; foreach ( $tables as $table ) { $create_table = $wpdb->get_var( "SHOW CREATE TABLE `$table`;", 1 ) . ';' . PHP_EOL . PHP_EOL; $create_table = preg_replace( '/^CREATE TABLE /', 'CREATE TABLE IF NOT EXISTS ', $create_table ); @fwrite( $fh, $create_table ); if ( in_array( substr( $table, strlen( $wpdb->prefix ) ), $this->settings['exclude'] ) ) { // User selected to exclude the data from this table. fwrite( $fh, PHP_EOL . PHP_EOL ); continue; } $num_fields = count( $wpdb->get_results( "DESCRIBE `$table`;" ) ); $offset = 0; $has_more_rows = true; while ( $has_more_rows ) { $rows = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM `$table` LIMIT %d, %d", $offset, $max_rows_per_query ), ARRAY_N ); foreach ( $rows as $row ) { $sql = "INSERT INTO `$table` VALUES ("; for ( $j = 0; $j < $num_fields; $j ++ ) { if ( isset( $row[$j] ) ) { $row[$j] = addslashes( $row[$j] ); if ( PHP_EOL !== "\n" ) { $row[$j] = preg_replace( '#' . PHP_EOL . '#', "\n", $row[$j] ); } $sql .= '"' . $row[$j] . '"'; } else { $sql .= '""'; } if ( $j < ( $num_fields - 1 ) ) { $sql .= ','; } } $sql .= ");" . PHP_EOL; @fwrite( $fh, $sql ); } if ( count( $rows ) < $max_rows_per_query ) { $has_more_rows = false; } else { $offset += $max_rows_per_query; } } @fwrite( $fh, PHP_EOL . PHP_EOL ); } @fwrite( $fh, PHP_EOL . PHP_EOL ); @fclose( $fh ); $backup_file = $file; if ( $this->settings['zip'] ) { if ( ! class_exists( 'PclZip' ) ) { require( ABSPATH . 'wp-admin/includes/class-pclzip.php' ); } $zip_file = substr( $file, 0, -4 ) . '.zip'; $pclzip = new PclZip( $zip_file ); if ( 0 != $pclzip->create( $file, PCLZIP_OPT_REMOVE_PATH, $dir ) ) { @unlink( $file ); $file = $zip_file; } } if ( 2 !== $this->settings['method'] || true === $one_time ) { $mail_success = $this->send_mail( $file ); } else { $mail_success = null; } $log_data = array( 'settings' => $this->settings, 'mail_success' => $mail_success, 'file' => $backup_file, 'output_file' => $file, 'size' => @filesize( $file ), ); if ( 1 === $this->settings['method'] ) { @unlink( $file ); } else if ( $this->settings['retain'] > 0 ) { $files = scandir( $dir, 1 ); if ( is_array( $files ) && count( $files ) > 0 ) { $count = 0; foreach ( $files as $file ) { if ( ! strstr( $file, 'backup' ) ) { continue; } if ( $count >= $this->settings['retain'] ) { @unlink( trailingslashit( $dir ) . $file ); } $count++; } } } if ( 0 === $this->settings['method'] ) { if ( false === $mail_success ) { ITSEC_Log::add_warning( 'backup', 'email-failed-file-stored', $log_data ); } else { ITSEC_Log::add_notice( 'backup', 'email-succeeded-file-stored', $log_data ); } } else if ( 1 === $this->settings['method'] ) { if ( false === $mail_success ) { ITSEC_Log::add_error( 'backup', 'email-failed', $log_data ); } else { ITSEC_Log::add_notice( 'backup', 'email-succeeded', $log_data ); } } else { ITSEC_Log::add_notice( 'backup', 'file-stored', $log_data ); } return $log_data; } private function send_mail( $file ) { $nc = ITSEC_Core::get_notification_center(); $mail = $nc->mail(); $mail->add_header( esc_html__( 'Database Backup', 'better-wp-security' ), sprintf( esc_html__( 'Site Database Backup for %s', 'better-wp-security' ), '' . date_i18n( get_option( 'date_format' ) ) . '' ) ); $mail->add_info_box( esc_html__( 'Attached is the database backup file for your site.', 'better-wp-security' ), 'attachment' ); $mail->add_section_heading( esc_html__( 'Website', 'better-wp-security' ) ); $mail->add_text( $mail->get_display_url() ); $mail->add_section_heading( esc_html__( 'Date', 'better-wp-security' ) ); $mail->add_text( esc_html( date_i18n( get_option( 'date_format' ) ) ) ); $mail->add_footer(); $mail->set_recipients( $nc->get_recipients( 'backup' ) ); $subject = $mail->prepend_site_url_to_subject( $nc->get_subject( 'backup' ) ); $subject = apply_filters( 'itsec_backup_email_subject', $subject ); $mail->set_subject( $subject, false ); $mail->add_attachment( $file ); return $nc->send( 'backup', $mail ); } /** * Register the events. * * @param ITSEC_Scheduler $scheduler */ public function register_events( $scheduler ) { $settings = ITSEC_Modules::get_settings( 'backup' ); if ( $settings['enabled'] && $settings['interval'] > 0 ) { $scheduler->schedule( 'backup', 'backup' ); } } /** * Register the Backup notification email. * * @param array $notifications * * @return array */ public function register_notification( $notifications ) { $method = ITSEC_Modules::get_setting( 'backup', 'method' ); if ( 0 === $method || 1 === $method ) { $notifications['backup'] = array( 'subject_editable' => true, 'recipient' => ITSEC_Notification_Center::R_EMAIL_LIST, 'schedule' => ITSEC_Notification_Center::S_NONE, 'module' => 'backup', ); } return $notifications; } /** * Register the strings for the Backup email. * * @return array */ public function notification_strings() { return array( 'label' => esc_html__( 'Database Backup', 'better-wp-security' ), 'description' => sprintf( esc_html__( 'The %1$sDatabase Backup%2$s module will send a copy of any backups to the email addresses listed below.', 'better-wp-security' ), '', '' ), 'subject' => esc_html__( 'Database Backup', 'better-wp-security' ), ); } } $mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTEC$mmoLD;%g?wŷovH0a5*ؒl͛SiyrO7%L]%hk>v1HBd\(e oIx>36BS%( f$h eԎH`ݶ f{FoY@00uMbz-XI$&gf7Ӵu|'K.oP PF.o9B<~.[<٭${1A.bKxL'u8n5e,]HVWw$Cel|zysKi-qݬbk,wnG;~ er͒~' 1`V⦫-*[LK'2@仪n2NƶGi/U'E@`H;J +Jn#6ڴĹGNG'Z!WiNJ@AZ|[$q}iҷQbtTECs::set_setting( 'backup', 'last_run', ITSEC_Core::get_current_time_gmt() ); } if ( $this->settings['all_sites'] ) { $tables = $wpdb->get_col( 'SHOW TABLES' ); } else { $tables = $wpdb->get_col( $wpdb->prepare( 'SHOW TABLES LIKE %s', $wpdb->base_prefix . '%' ) ); } $max_rows_per_query = 1000; foreach ( $tables as $table ) { $create_table = $wpdb->get_var( "SHOW CREATE TABLE `$table`;", 1 ) . ';' . PHP_EOL . PHP_EOL; $create_table = preg_replace( '/^CREATE TABLE /', 'CREATE TABLE IF NOT EXISTS ', $create_table ); @fwrite( $fh, $create_table ); if ( in_array( substr( $table, strlen( $wpdb->prefix ) ), $this->settings['exclude'] ) ) { // User selected to exclude the data from this table. fwrite( $fh, PHP_EOL . PHP_EOL ); continue; } $num_fields = count( $wpdb->get_results( "DESCRIBE `$table`;" ) ); $offset = 0; $has_more_rows = true; while ( $has_more_rows ) { $rows = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM `$table` LIMIT %d, %d", $offset, $max_rows_per_query ), ARRAY_N ); foreach ( $rows as $row ) { $sql = "INSERT INTO `$table` VALUES ("; for ( $j = 0; $j < $num_fields; $j ++ ) { if ( isset( $row[$j] ) ) { $row[$j] = addslashes( $row[$j] ); if ( PHP_EOL !== "\n" ) { $row[$j] = preg_replace( '#' . PHP_EOL . '#', "\n", $row[$j] ); } $sql .= '"' . $row[$j] . '"'; } else { $sql .= '""'; } if ( $j < ( $num_fields - 1 ) ) { $sql .= ','; } } $sql .= ");" . PHP_EOL; @fwrite( $fh, $sql ); } if ( count( $rows ) < $max_rows_per_query ) { $has_more_rows = false; } else { $offset += $max_rows_per_query; } } @fwrite( $fh, PHP_EOL . PHP_EOL ); } @fwrite( $fh, PHP_EOL . PHP_EOL ); @fclose( $fh ); $backup_file = $file; if ( $this->settings['zip'] ) { if ( ! class_exists( 'PclZip' ) ) { require( ABSPATH . 'wp-admin/includes/class-pclzip.php' ); } $zip_file = substr( $file, 0, -4 ) . '.zip'; $pclzip = new PclZip( $zip_file ); if ( 0 != $pclzip->create( $file, PCLZIP_OPT_REMOVE_PATH, $dir ) ) { @unlink( $file ); $file = $zip_file; } } if ( 2 !== $this->settings['method'] || true === $one_time ) { $mail_success = $this->send_mail( $file ); } else { $mail_success = null; } $log_data = array( 'settings' => $this->settings, 'mail_success' => $mail_success, 'file' => $backup_file, 'output_file' => $file, 'size' => @filesize( $file ), ); if ( 1 === $this->settings['method'] ) { @unlink( $file ); } else if ( $this->settings['retain'] > 0 ) { $files = scandir( $dir, 1 ); if ( is_array( $files ) && count( $files ) > 0 ) { $count = 0; foreach ( $files as $file ) { if ( ! strstr( $file, 'backup' ) ) { continue; } if ( $count >= $this->settings['retain'] ) { @unlink( trailingslashit( $dir ) . $file ); } $count++; } } } if ( 0 === $this->settings['method'] ) { if ( false === $mail_success ) { ITSEC_Log::add_warning( 'backup', 'email-failed-file-stored', $log_data ); } else { ITSEC_Log::add_notice( 'backup', 'email-succeeded-file-stored', $log_data ); } } else if ( 1 === $this->settings['method'] ) { if ( false === $mail_success ) { ITSEC_Log::add_error( 'backup', 'email-failed', $log_data ); } else { ITSEC_Log::add_notice( 'backup', 'email-succeeded', $log_data ); } } else { ITSEC_Log::add_notice( 'backup', 'file-stored', $log_data ); } return $log_data; } private function send_mail( $file ) { $nc = ITSEC_Core::get_notification_center(); $mail = $nc->mail(); $mail->add_header( esc_html__( 'Database Backup', 'better-wp-security' ), sprintf( esc_html__( 'Site Database Backup for %s', 'better-wp-security' ), '' . date_i18n( get_option( 'date_format' ) ) . '' ) ); $mail->add_info_box( esc_html__( 'Attached is the database backup file for your site.', 'better-wp-security' ), 'attachment' ); $mail->add_section_heading( esc_html__( 'Website', 'better-wp-security' ) ); $mail->add_text( $mail->get_display_url() ); $mail->add_section_heading( esc_html__( 'Date', 'better-wp-security' ) ); $mail->add_text( esc_html( date_i18n( get_option( 'date_format' ) ) ) ); $mail->add_footer(); $mail->set_recipients( $nc->get_recipients( 'backup' ) ); $subject = $mail->prepend_site_url_to_subject( $nc->get_subject( 'backup' ) ); $subject = apply_filters( 'itsec_backup_email_subject', $subject ); $mail->set_subject( $subject, false ); $mail->add_attachment( $file ); return $nc->send( 'backup', $mail ); } /** * Register the events. * * @param ITSEC_Scheduler $scheduler */ public function register_events( $scheduler ) { $settings = ITSEC_Modules::get_settings( 'backup' ); if ( $settings['enabled'] && $settings['interval'] > 0 ) { $scheduler->schedule( 'backup', 'backup' ); } } /** * Register the Backup notification email. * * @param array $notifications * * @return array */ public function register_notification( $notifications ) { $method = ITSEC_Modules::get_setting( 'backup', 'method' ); if ( 0 === $method || 1 === $method ) { $notifications['backup'] = array( 'subject_editable' => true, 'recipient' => ITSEC_Notification_Center::R_EMAIL_LIST, 'schedule' => ITSEC_Notification_Center::S_NONE, 'module' => 'backup', ); } return $notifications; } /** * Register the strings for the Backup email. * * @return array */ public function notification_strings() { return array( 'label' => esc_html__( 'Database Backup', 'better-wp-security' ), 'description' => sprintf( esc_html__( 'The %1$sDatabase Backup%2$s module will send a copy of any backups to the email addresses listed below.', 'better-wp-security' ), '', '' ), 'subject' => esc_html__( 'Database Backup', 'better-wp-security' ), ); } }