File "initializer.php"
Full path: /home/bud/public_html/swamp/deprecated/wp-admin/wp-content/plugins/backup-backup/includes/initializer.php
File size: 46.71 KB
MIME-type: text/x-php
Charset: utf-8
<?php
// Namespace
namespace BMI\Plugin;
// Exit on direct access
if (!defined('ABSPATH')) {
exit;
}
// Require classes
require_once BMI_INCLUDES . '/logger.php';
// Alias for classes
use BMI\Plugin\BMI_Logger as Logger;
use BMI\Plugin\CRON\BMI_Crons as Crons;
use BMI\Plugin\Dashboard as Dashboard;
use BMI\Plugin\Scanner\BMI_BackupsScanner as Backups;
use BMI\Plugin\Zipper\BMI_Zipper as Zipper;
// Uninstallator
if (!function_exists('bmi_uninstall_handler')) {
function bmi_uninstall_handler() {
require_once BMI_ROOT_DIR . '/uninstall.php';
}
}
/**
* Backup Migration Main Class
*/
class Backup_Migration_Plugin {
public function initialize() {
// Determine which BMI version is used
add_action('wp_head', function () {
echo '<meta name="bmi-version" content="' . BMI_VERSION . '" />';
});
// Handle PHP CLI functions
if (defined('BMI_USING_CLI_FUNCTIONALITY') && BMI_USING_CLI_FUNCTIONALITY === true) {
// Below all WordPress functions and directives can be accessed
if (defined('BMI_CLI_FUNCTION')) {
if (BMI_CLI_FUNCTION == 'bmi_restore' && defined('BMI_CLI_ARGUMENT')) {
$_SERVER['HTTP_X_REQUESTED_WITH'] = 'xmlhttprequest';
$_POST['f'] = 'restore-backup';
if (defined('BMI_CLI_ARGUMENT_2')) {
$_POST['remote'] = BMI_CLI_ARGUMENT_2;
} else $_POST['remote'] = false;
$_POST['file'] = BMI_CLI_ARGUMENT;
$this->ajax(true);
} elseif (BMI_CLI_FUNCTION == 'bmi_backup') {
$_SERVER['HTTP_X_REQUESTED_WITH'] = 'xmlhttprequest';
$_POST['f'] = 'create-backup';
$this->ajax(true);
} elseif (BMI_CLI_FUNCTION == 'bmi_quick_migration') {
$_SERVER['HTTP_X_REQUESTED_WITH'] = 'xmlhttprequest';
$_POST['f'] = 'download-backup';
$this->ajax(true);
}
}
return;
}
if (defined('BMI_RESTORE_SECRET') && defined('BMI_POST_CONTINUE_RESTORE') && BMI_POST_CONTINUE_RESTORE === true) {
$_SERVER['HTTP_X_REQUESTED_WITH'] = 'xmlhttprequest';
$_POST['f'] = 'continue_restore_process';
$this->ajax(true);
return;
}
// Hooks
register_deactivation_hook(BMI_ROOT_FILE, [&$this, 'deactivation']);
register_uninstall_hook(BMI_ROOT_FILE, 'bmi_uninstall_handler');
// File downloading
add_action('init', [&$this, 'handle_downloading']);
// Handle CRONs
add_action('bmi_do_backup_right_now', [&$this, 'handle_cron_backup']);
add_action('bmi_handle_cron_check', [&$this, 'handle_cron_check']);
add_action('init', [&$this, 'handle_crons']);
// Return if CRON time
if (function_exists('wp_doing_cron') && wp_doing_cron()) return;
// Check user permissions
$user = get_userdata(get_current_user_id());
if (!$user || !$user->roles) return;
if (!current_user_can('do_backups') && !in_array('administrator', (array) $user->roles)) return;
// Include our cool banner
include_once BMI_INCLUDES . '/banner/misc.php';
// Review banner
if (!is_dir(WP_PLUGIN_DIR . '/backup-backup-pro')) {
if (!(class_exists('\Inisev\Subs\Inisev_Review') || class_exists('Inisev\Subs\Inisev_Review') || class_exists('Inisev_Review'))) {
require_once BMI_MODULES_DIR . 'review' . DIRECTORY_SEPARATOR . 'review.php';
}
$review_banner = new \Inisev\Subs\Inisev_Review(BMI_ROOT_FILE, BMI_ROOT_DIR, 'backup-backup', 'Backup & Migration', 'http://bit.ly/3vdk45L', 'backup-migration');
}
// Deactivation module
// $bmi_plugin_path = trailingslashit(basename(BMI_ROOT_DIR)) . basename(BMI_ROOT_FILE);
// if (isset($GLOBALS['IIEV_PLUGINS_DEACTIVATION'])) {
// if (is_array($GLOBALS['IIEV_PLUGINS_DEACTIVATION'])) $GLOBALS['IIEV_PLUGINS_DEACTIVATION'][] = $bmi_plugin_path;
// } else {
// if (!(class_exists('\Inisev\Subs\Inisev_Deactivation') || class_exists('Inisev\Subs\Inisev_Deactivation') || class_exists('Inisev_Deactivation'))) {
// require_once BMI_MODULES_DIR . 'deactivation' . DIRECTORY_SEPARATOR . 'deactivation.php';
// }
// $deactivation_module = new \Inisev\Subs\Inisev_Deactivation($bmi_plugin_path, BMI_ROOT_DIR, BMI_ROOT_FILE);
// }
// POST Logic
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// Register AJAX Handler
add_action('wp_ajax_backup_migration', [&$this, 'ajax']);
// Stop GET Registration
// return; // Commented because of conflicts with USM Icons
}
// Actions
add_action('admin_init', [&$this, 'admin_init_hook']);
add_action('admin_menu', [&$this, 'submenu']);
add_action('admin_notices', [&$this, 'admin_notices']);
// Settings action
add_filter('plugin_action_links_' . plugin_basename(BMI_ROOT_FILE), [&$this, 'settings_action']);
// Ignore below actions if those true
if (function_exists('wp_doing_ajax') && wp_doing_ajax()) {
return;
}
// Styles & scripts
add_action('admin_head', [&$this, 'enqueue_styles']);
add_action('admin_footer', [&$this, 'enqueue_scripts']);
}
public static function randomString($max = 16) {
$bank = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
$bank .= 'abcdefghijklmnopqrstuvwxyz';
$bank .= '0123456789';
$str = str_shuffle($bank);
while (is_numeric($str[0])) {
$str = str_shuffle($bank);
}
$str = substr($str, 0, $max);
return $str;
}
/**
* hotFixPatches - Function which fixes things for "old" users
*
* @return @void
*/
public function hotfix_patches() {
if (!is_admin()) return;
$current_patch = get_option('bmi_hotfixes', array());
if (!in_array('BMI_D20_M07_01', $current_patch)) {
$current_directory = Dashboard\bmi_get_config('STORAGE::LOCAL::PATH');
if (basename($current_directory) == 'backup-migration') {
require_once BMI_INCLUDES . '/ajax.php';
$handler_a = new BMI_Ajax();
$handler_a->post['directory'] = dirname($current_directory) . DIRECTORY_SEPARATOR . 'backup-migration-' . $this->randomString(10);
$handler_a->post['access'] = Dashboard\bmi_get_config('STORAGE::DIRECT::URL');
$res_a = $handler_a->saveStorageConfig();
if (isset($res_a['status']) && $res_a['status'] == 'success') {
$current_patch[] = 'BMI_D20_M07_01';
}
} else {
$current_patch[] = 'BMI_D20_M07_01';
}
}
if (!in_array('BMI_D17_M12_Y21_02', $current_patch)) {
$current_splitting_value = Dashboard\bmi_get_config('OTHER:RESTORE:SPLITTING');
$current_query_size = Dashboard\bmi_get_config('OTHER:DB:QUERIES');
$current_query_size = intval($current_query_size);
if ($current_splitting_value == 'true' || $current_splitting_value === true) {
$current_splitting_value = true;
} else {
$current_splitting_value = false;
}
if ($current_splitting_value === false || $current_query_size != 300) {
$b_db_restore_splitting = true;
$b_db_query_size = '300';
$error_b = 0;
if (!Dashboard\bmi_set_config('OTHER:RESTORE:SPLITTING', $b_db_restore_splitting)) {
$error_b++;
}
if (!Dashboard\bmi_set_config('OTHER:DB:QUERIES', $b_db_query_size)) {
$error_b++;
}
if ($error_b <= 0) {
$current_patch[] = 'BMI_D17_M12_Y21_02';
}
} else {
$current_patch[] = 'BMI_D17_M12_Y21_02';
}
}
update_option('bmi_hotfixes', $current_patch);
}
public function ajax($cli = false) {
if (isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest') {
if ((isset($_POST['token']) && $_POST['token'] == 'bmi' && isset($_POST['f']) && is_admin()) || $cli) {
try {
// Extend execution time
// $exectime = intval(ini_get('max_execution_time'));
// if ($exectime < 16000 && $exectime != 0) set_time_limit(16000);
if (!headers_sent()) {
@ignore_user_abort(true);
@set_time_limit(16000);
@ini_set('max_execution_time', '259200');
@ini_set('max_input_time', '259200');
@ini_set('session.gc_maxlifetime', '1200');
}
// May cause issues with auto login
// if (strlen(session_id()) > 0) session_write_close();
register_shutdown_function([$this, 'execution_shutdown']);
// Require AJAX Handler
require_once BMI_INCLUDES . '/ajax.php';
$handler = new BMI_Ajax();
} catch (\Exception $e) {
Logger::error('POST error:');
Logger::error($e);
if ($_POST['f'] == 'create-backup') {
$progress = &$GLOBALS['bmi_backup_progress'];
$this->handleErrorDuringBackup($e->getMessage(), $e->getFile(), $e->getLine(), $progress);
}
if ($_POST['f'] == 'restore-backup') {
$progress = &$GLOBALS['bmi_migration_progress'];
$this->handleErrorDuringRestore($e->getMessage(), $e->getFile(), $e->getLine(), $progress);
}
$this->res(['status' => 'error', 'error' => $e]);
exit;
} catch (\Throwable $e) {
Logger::error('POST error:');
Logger::error($e);
if ($_POST['f'] == 'create-backup') {
$progress = &$GLOBALS['bmi_backup_progress'];
$this->handleErrorDuringBackup($e->getMessage(), $e->getFile(), $e->getLine(), $progress);
}
if ($_POST['f'] == 'restore-backup') {
$progress = &$GLOBALS['bmi_migration_progress'];
$this->handleErrorDuringRestore($e->getMessage(), $e->getFile(), $e->getLine(), $progress);
}
$this->res(['status' => 'error', 'error' => $e]);
exit;
}
}
}
}
public function execution_shutdown() {
$err = error_get_last();
if (defined('BMI_USING_CLI_FUNCTIONALITY') && BMI_USING_CLI_FUNCTIONALITY === true) {
$lock_cli = BMI_BACKUPS . '/.migration_lock_cli';
$lock_cli_end = BMI_BACKUPS . '/.migration_lock_ended';
$lock_cli_end_backup = BMI_BACKUPS . '/.backup_lock_cli_end';
if (file_exists($lock_cli)) @unlink($lock_cli);
if (file_exists($lock_cli_end)) @touch($lock_cli_end);
if (file_exists($lock_cli_end_backup)) @touch($lock_cli_end_backup);
}
if ($err != null) {
Logger::error(__('Shuted down', 'backup-backup'));
Logger::error(print_r($err, true));
$msg = $err['message'];
$file = $err['file'];
$line = $err['line'];
$type = $err['type'];
if ($type != '1' && ($type != E_ERROR && $type != E_CORE_ERROR && $type != E_COMPILE_ERROR && $type != E_USER_ERROR && $type != E_RECOVERABLE_ERROR)) {
Logger::error(__('There was an error before request shutdown (but it was not logged to backup/restore log)', 'backup-backup'));
Logger::error(__('Error message: ', 'backup-backup') . $msg);
Logger::error(__('Error file/line: ', 'backup-backup') . $file . '|' . $line);
return;
}
if ($GLOBALS['bmi_error_handled']) return;
if ($_POST['f'] == 'create-backup') {
Logger::error(__('There was an error during backup', 'backup-backup'));
Logger::error(__('Error message: ', 'backup-backup') . $msg);
Logger::error(__('Error file/line: ', 'backup-backup') . $file . '|' . $line);
$progress = &$GLOBALS['bmi_backup_progress'];
if ($progress) {
$progress->log(__('Error message: ', 'backup-backup') . $msg, 'error');
$progress->log(__('You can get more pieces of information in troubleshooting log file.', 'backup-backup'), 'error');
}
$this->handleErrorDuringBackup($msg, $file, $line, $progress);
$fullPath = BMI_ROOT_DIR . '/tmp' . '/';
array_map('unlink', glob($fullPath . '*.tmp'));
array_map('unlink', glob($fullPath . '*.gz'));
}
if ($_POST['f'] == 'restore-backup') {
Logger::error(__('There was an error during restore process', 'backup-backup'));
Logger::error(__('Error message: ', 'backup-backup') . $msg);
Logger::error(__('Error file/line: ', 'backup-backup') . $file . '|' . $line);
$progress = &$GLOBALS['bmi_migration_progress'];
if ($progress) {
$progress->log(__('Error message: ', 'backup-backup') . $msg, 'error');
$progress->log(__('You can get more pieces of information in troubleshooting log file.', 'backup-backup'), 'error');
}
$this->handleErrorDuringRestore($msg, $file, $line, $progress);
}
$this->res(['status' => 'error', 'error' => $err]);
exit;
}
}
public function handleErrorDuringBackup($msg, $file, $line, &$progress) {
$backup = $GLOBALS['bmi_current_backup_name'];
Logger::log('Due to fatal error backup handled correctly (closed and removed).');
if ($progress) {
$progress->log(__('Something bad happened on PHP side.', 'backup-backup'), 'error');
$progress->log(__('Unfortunately we had to remove the backup (if partly created).', 'backup-backup'), 'error');
$progress->log(__('Error message: ', 'backup-backup') . $msg, 'error');
$progress->log(__('Error file/line: ', 'backup-backup') . $file . '|' . $line, 'error');
if (strpos($msg, 'execution time') !== false) {
$progress->log(__('Probably we could not increase the execution time, please edit your php.ini manually', 'backup-backup'), 'error');
}
}
$backup_path = BMI_BACKUPS . DIRECTORY_SEPARATOR . $backup;
if (file_exists($backup_path)) @unlink($backup_path);
if (file_exists(BMI_BACKUPS . DIRECTORY_SEPARATOR . '.running')) @unlink(BMI_BACKUPS . DIRECTORY_SEPARATOR . '.running');
if (file_exists(BMI_BACKUPS . DIRECTORY_SEPARATOR . '.abort')) @unlink(BMI_BACKUPS . DIRECTORY_SEPARATOR . '.abort');
if ($progress) {
$progress->log(__("Aborting backup...", 'backup-backup'), 'step');
$progress->end();
}
}
public function handleErrorDuringRestore($msg, $file, $line, &$progress) {
Logger::log('There was fatal error during restore.');
if ($progress) {
$progress->log(__('Something bad happened on PHP side.', 'backup-backup'), 'error');
$progress->log(__('Error message: ', 'backup-backup') . $msg, 'error');
$progress->log(__('Error file/line: ', 'backup-backup') . $file . '|' . $line, 'error');
}
if (file_exists(BMI_BACKUPS . DIRECTORY_SEPARATOR . '.migration_lock')) @unlink(BMI_BACKUPS . DIRECTORY_SEPARATOR . '.migration_lock');
if ($progress) {
$progress->log(__("Aborting & unlocking restore process...", 'backup-backup'), 'step');
$progress->end();
}
$lock = BMI_BACKUPS . '/.migration_lock';
if (file_exists($lock)) @unlink($lock);
}
public function submenu() {
// Menu icon
$icon_url = $this->get_asset('images', 'logo-min.png');
// Main menu slug
$parentSlug = 'backup-migration';
// Content
$content = [$this, 'settings_page'];
// Main menu hook
add_menu_page('Backup Migration', '<span id="bmi-menu">Backup Migration</span>', 'read', $parentSlug, $content, $icon_url, $position = 98);
// Remove default submenu by menu
remove_submenu_page($parentSlug, $parentSlug);
}
public function settings_action($links) {
$text = __('Manage', 'backup-backup');
$links['bmi-settings-link'] = '<a href="' . admin_url('/admin.php?page=backup-migration') . '">' . $text . '</a>';
return $links;
}
public function settings_page() {
// Set email if does not exist
if (!Dashboard\bmi_get_config('OTHER:EMAIL')) {
Dashboard\bmi_set_config('OTHER:EMAIL', get_bloginfo('admin_email'));
}
// Require The HTML
require_once BMI_INCLUDES . '/dashboard/settings.php';
}
public function admin_init_hook() {
$this->hotfix_patches();
if (get_option('_bmi_redirect', false)) {
$this->fixLitespeed();
delete_option('_bmi_redirect');
wp_safe_redirect(admin_url('admin.php?page=backup-migration'));
}
}
public function admin_notices() {
if (get_current_screen()->id != 'toplevel_page_backup-migration' && get_option('bmi_display_email_issues', false)) {
?>
<div class="notice notice-warning">
<p>
<?php _e('There was an error during automated backup, please', 'backup-backup'); ?>
<?php echo '<a href="' . admin_url('/admin.php?page=backup-migration') . '">' . __('check that.', 'backup-backup') . '</a>'; ?>
</p>
</div>
<?php
}
}
public function handle_crons() {
if (Dashboard\bmi_get_config('CRON:ENABLED') !== true) return;
$time = get_option('bmi_backup_check', 0);
if ((time() - $time) > 60) {
update_option('bmi_backup_check', time());
do_action('bmi_handle_cron_check');
}
}
public function email_error($msg) {
Logger::log('Displaying some issues about email sending...');
update_option('bmi_display_email_issues', $msg);
}
public function backup_inproper_time($should_time) {
Logger::log('Sending notification about backup being late');
$email = Dashboard\bmi_get_config('OTHER:EMAIL') != false ? Dashboard\bmi_get_config('OTHER:EMAIL') : get_bloginfo('admin_email');
$subject = Dashboard\bmi_get_config('OTHER:EMAIL:TITLE');
$message = __("Automatic backup was not on time because there was no traffic on the site.", 'backup-backup') . "\n";
$message .= __("Backup was made on: ", 'backup-backup') . date('Y-m-d H:i:s') . __(', but should be on: ', 'backup-backup') . date('Y-m-d H:i:s', $should_time);
$message .= ' ' . __("(server time)", 'backup-backup');
Logger::debug($message);
if (!$this->send_notification_mail($email, $subject, $message)) {
$issue = __("Couldn't send mail to you, please check server configuration.", 'backup-backup') . '<br>';
$issue .= '<b>' . __("Message you missed because of this: ", 'backup-backup') . '</b>' . $message;
$this->email_error($issue);
}
}
public function handle_cron_check() {
if (Dashboard\bmi_get_config('CRON:ENABLED') !== true) return;
$now = time();
if (file_exists(BMI_INCLUDES . '/htaccess/.last')) {
$last = @file_get_contents(BMI_INCLUDES . '/htaccess/.last');
$last_status = explode('.', $last)[0];
$last_time = intval(explode('.', $last)[1]);
} else {
$last_time = 0;
$last_status = 0;
}
if (file_exists(BMI_INCLUDES . '/htaccess/.plan')) {
$plan = intval(@file_get_contents(BMI_INCLUDES . '/htaccess/.plan'));
if ($last_time < $plan && ((time() - $plan) > 3600)) {
if ($last_status !== '0') {
$this->backup_inproper_time($plan);
if (!wp_next_scheduled('bmi_do_backup_right_now')) {
wp_schedule_single_event(time(), 'bmi_do_backup_right_now');
}
}
}
}
}
public function get_next_cron($curr = false) {
if ($curr === false) {
$curr = time();
}
$time = Crons::calculate_date([
'type' => Dashboard\bmi_get_config('CRON:TYPE'),
'week' => Dashboard\bmi_get_config('CRON:WEEK'),
'day' => Dashboard\bmi_get_config('CRON:DAY'),
'hour' => Dashboard\bmi_get_config('CRON:HOUR'),
'minute' => Dashboard\bmi_get_config('CRON:MINUTE')
], $curr);
return $time;
}
public function handle_cron_error($e) {
Logger::error(__("Automatic backup failed at time: ", 'backup-backup') . date('Y-m-d, H:i:s'));
if (is_object($e) || is_array($e)) {
Logger::error('Error: ' . $e->getMessage());
} else {
Logger::error('Error: ' . $e);
}
$notis = Dashboard\bmi_get_config('OTHER:EMAIL:NOTIS');
if (in_array($notis, [true, 'true'])) {
$email = Dashboard\bmi_get_config('OTHER:EMAIL') != false ? Dashboard\bmi_get_config('OTHER:EMAIL') : get_bloginfo('admin_email');
$subject = Dashboard\bmi_get_config('OTHER:EMAIL:TITLE');
$message = __("There was an error during automatic backup, please check the logs.", 'backup-backup');
if (is_string($e)) {
$message .= "\nError: " . $e;
}
$this->send_notification_mail($email, $subject, $message);
}
if (file_exists(BMI_BACKUPS . '/.cron')) {
@unlink(BMI_BACKUPS . '/.cron');
}
}
public function send_notification_mail($email, $subject, $message) {
$currentDate = date('Y-m-d');
if (get_option('bmi_last_email_notification', false) == $currentDate) {
Logger::log(__("Disallowing to send mail as today we already sent one.", 'backup-backup'));
return;
}
update_option('bmi_last_email_notification', $currentDate);
$email_fail = __("Could not send the email notification about that fail", 'backup-backup');
try {
if (wp_mail($email, $subject, $message)) {
Logger::log(__("Sent email notification to: ", 'backup-backup') . $email);
return true;
} else {
Logger::error($email_fail);
$this->email_error(__("Couldn't send notification via email, please check the email and your server settings.", 'backup-backup'));
return false;
}
} catch (\Exception $e) {
Logger::error($email_fail);
$this->email_error(__("Couldn't send notification via email due to error, please check plugin logs for more details.", 'backup-backup'));
return false;
} catch (\Throwable $e) {
Logger::error($email_fail);
$this->email_error(__("Couldn't send notification via email due to error, please check plugin logs for more details.", 'backup-backup'));
return false;
}
}
public function handle_after_cron() {
require_once BMI_INCLUDES . DIRECTORY_SEPARATOR . 'scanner' . DIRECTORY_SEPARATOR . 'backups.php';
$backups = new Backups();
$list = $backups->getAvailableBackups();
$cron_list = [];
$cron_dates = [];
foreach ($list as $key => $value) {
if ($list[$key][6] == true) {
if ($list[$key][5] == 'unlocked') {
$cron_list[$list[$key][1]] = $list[$key][0];
$cron_dates[] = $list[$key][1];
}
}
}
usort($cron_dates, function ($a, $b) {
return (strtotime($a) < strtotime($b)) ? -1 : 1;
});
$cron_dates = array_slice($cron_dates, 0, -(intval(Dashboard\bmi_get_config('CRON:KEEP'))));
foreach ($cron_dates as $key => $value) {
$name = $cron_list[$cron_dates[$key]];
Logger::log(__("Removing backup due to keep rules: ", 'backup-backup') . $name);
@unlink(BMI_BACKUPS . DIRECTORY_SEPARATOR . $name);
}
}
public function set_last_cron($status, $time) {
$file = BMI_INCLUDES . '/htaccess/.last';
file_put_contents($file, $status . '.' . $time);
}
public function readFileSensitive($file) {
$file = new \SplFileObject($file);
$file->seek($file->getSize());
$total_lines = $file->key() + 1;
$current_directory = Dashboard\bmi_get_config('STORAGE::LOCAL::PATH');
$backups_path = $this->fixSlashes($current_directory . DIRECTORY_SEPARATOR . 'backups');
$scanned_directory_all = array_diff(scandir($backups_path), ['..', '.']);
$scanned_directory = array_values(preg_grep('/((.*).zip)/i', $scanned_directory_all));
for ($i = 0; $i < $total_lines; ++$i) {
$file->seek($i);
$line = $this->escapeSensitive($file->current(), $current_directory, $scanned_directory);
echo $line;
unset($line);
}
}
public function escapeSensitive($line, $current_directory, $scanned_directory) {
$dir_name = basename($current_directory);
$line = preg_replace('/\:\ ((.*)\.zip)/', ': *****.zip', $line);
$line = preg_replace('/(\"filename\":(.*)\.zip)\"/', '"filename": "*****.zip"', $line);
$line = preg_replace('/\"http(.*)\"/', '"***site_url***"', $line);
$line = preg_replace('/\:\ http(.*)\n/', ": ***site_url***\n", $line);
$line = preg_replace('/\"\d{10}\"/', '"***secret_login***"', $line);
$line = str_replace(ABSPATH, '***ABSPATH***/', $line);
$line = str_replace($dir_name, '***backup_path***', $line);
for ($i = 0; $i < sizeof($scanned_directory); ++$i) {
$backup_name = $scanned_directory[$i];
$line = str_replace($backup_name, '***some_backup***', $line);
}
return $line;
}
public function handle_cron_backup() {
// Abort if disabled
if (Dashboard\bmi_get_config('CRON:ENABLED') !== true) {
$plan_file = BMI_INCLUDES . '/htaccess/.plan';
$last_file = BMI_INCLUDES . '/htaccess/.last';
if (file_exists($plan_file)) @unlink($plan_file);
if (file_exists($last_file)) @unlink($last_file);
return;
}
// Planned time
$plan = intval(@file_get_contents(BMI_INCLUDES . '/htaccess/.plan'));
// Check difference
if ((time() - $plan) > 3600) {
Logger::log('Backup failed to run on proper time, but running now.');
Logger::log('Planned time: ' . date('Y-m-d H:i:s', $plan));
$this->backup_inproper_time($plan);
}
// Now
$now = time();
$this->set_last_cron('0', $now);
// Extend execution time
@ignore_user_abort(true);
@set_time_limit(16000);
@ini_set('max_execution_time', '259200');
@ini_set('max_input_time', '259200');
@ini_set('session.gc_maxlifetime', '1200');
if (strlen(session_id()) > 0) session_write_close();
Logger::log(__("Automatic backup called at time: ", 'backup-backup') . date('Y-m-d, H:i:s'));
try {
require_once BMI_INCLUDES . '/ajax.php';
$isBackup = (file_exists(BMI_BACKUPS . '/.running') && (time() - filemtime(BMI_BACKUPS . '/.running')) <= 65) ? true : false;
$isCron = (file_exists(BMI_BACKUPS . '/.cron') && (time() - filemtime(BMI_BACKUPS . '/.cron')) <= 65) ? true : false;
if ($isCron) {
return;
}
if ($isBackup) {
$this->handle_cron_error(__("Could not make the backup: Backup already running, please wait till it complete.", 'backup-backup'));
$this->set_last_cron('2', $now);
} else {
touch(BMI_BACKUPS . '/.cron');
$handler = new BMI_Ajax();
$handler->resetLatestLogs();
$backup = $handler->prepareAndMakeBackup(true);
if ($backup['status'] == 'success') {
Logger::log(__("Automatic backup successed: ", 'backup-backup') . $backup['filename']);
$this->handle_after_cron();
$this->set_last_cron('1', $now);
} elseif ($backup['status'] == 'msg') {
$this->handle_cron_error($backup['why']);
$this->set_last_cron('3', $now);
} else {
$this->handle_cron_error(__("Could not make the backup due to internal server error.", 'backup-backup'));
$this->set_last_cron('4', $now);
}
}
} catch (\Exception $e) {
$this->handle_cron_error($e);
$this->set_last_cron('5', $now);
} catch (\Throwable $e) {
$this->handle_cron_error($e);
$this->set_last_cron('5', $now);
}
if (file_exists(BMI_BACKUPS . '/.cron')) {
@unlink(BMI_BACKUPS . '/.cron');
}
require_once BMI_INCLUDES . '/cron/handler.php';
$time = $this->get_next_cron();
wp_clear_scheduled_hook('bmi_do_backup_right_now');
wp_schedule_single_event($time, 'bmi_do_backup_right_now');
$file = BMI_INCLUDES . '/htaccess/.plan';
file_put_contents($file, $time);
}
public function enqueue_scripts() {
// Global
if (in_array(get_current_screen()->id, ['toplevel_page_backup-migration', 'plugins'])) { ?>
<script type="text/javascript">
let stars = '<?php echo plugin_dir_url(BMI_ROOT_FILE); ?>' + 'admin/images/stars.gif';
let css_star = "background:url('" + stars + "')";
jQuery('[data-slug="backup-migration-pro"]').find('strong').html('<span>Backup Migration <b style="color: orange; ' + css_star + '">Pro</b></span>');
jQuery('[data-slug="backup-backup-pro"]').find('strong').html('<span>Backup Migration <b style="color: orange; ' + css_star + '">Pro</b></span>');
</script>
<?php }
// Only for BM Settings
if (get_current_screen()->id != 'toplevel_page_backup-migration') {
return;
}
wp_enqueue_script('backup-migration-script', $this->get_asset('js', 'backup-migration.min.js'), ['jquery'], BMI_VERSION, true);
}
public function enqueue_styles() {
// Global styles
wp_enqueue_style('backup-migration-style-icon', $this->get_asset('css', 'bmi-plugin-icon.min.css'), [], BMI_VERSION);
// Only for BM Settings
if (get_current_screen()->id != 'toplevel_page_backup-migration') return;
// Enqueue the style
wp_enqueue_style('backup-migration-style', $this->get_asset('css', 'bmi-plugin.min.css'), [], BMI_VERSION);
}
public function handle_downloading() {
global $wpdb;
@error_reporting(0);
$autologin_file = BMI_BACKUPS . '/.autologin';
$ip = '127.0.0.1';
if (isset($_SERVER['HTTP_CLIENT_IP'])) {
$ip = $_SERVER['HTTP_CLIENT_IP'];
} else {
if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
}
if ($ip === false) {
if (isset($_SERVER['REMOTE_ADDR'])) $ip = $_SERVER['REMOTE_ADDR'];
}
}
$allowed = ['BMI_BACKUP', 'BMI_BACKUP_LOGS', 'PROGRESS_LOGS', 'AFTER_RESTORE'];
$get_bmi = !empty($_GET['backup-migration']) ? sanitize_text_field($_GET['backup-migration']) : false;
$get_bid = !empty($_GET['backup-id']) ? sanitize_text_field($_GET['backup-id']) : false;
$get_pid = !empty($_GET['progress-id']) ? sanitize_text_field($_GET['progress-id']) : false;
if (isset($get_bmi) && in_array($get_bmi, $allowed)) {
if (isset($get_bid) && strlen($get_bid) > 0) {
$type = $get_bmi;
if ($type == 'AFTER_RESTORE' && isset($get_pid)) {
if (file_exists($autologin_file)) {
$autoLoginMD = file_get_contents($autologin_file);
$autoLoginMD = explode('_', $autoLoginMD);
$aID = intval($autoLoginMD[0]);
$aID2 = intval($autoLoginMD[0]) - 1;
$aID3 = intval($autoLoginMD[0]) + 1;
$aID4 = intval($autoLoginMD[0]) + 2;
$aID5 = intval($autoLoginMD[0]) + 3;
$aID6 = intval($autoLoginMD[0]) + 4;
$aIP = $autoLoginMD[1];
$aIZ = $autoLoginMD[2];
// Allow 1 second delay
$timeIsProper = false;
if ($aID === intval($get_bid)) $timeIsProper = true;
if ($aID2 === intval($get_bid)) $timeIsProper = true;
if ($aID3 === intval($get_bid)) $timeIsProper = true;
if ($aID4 === intval($get_bid)) $timeIsProper = true;
if ($aID5 === intval($get_bid)) $timeIsProper = true;
if ($aID6 === intval($get_bid)) $timeIsProper = true;
if ($timeIsProper && $aIP === $ip && trim($aIZ) === $get_pid) {
$query = new \WP_User_Query(['role' => 'Administrator', 'count_total' => false]);
$sqlres = $wpdb->get_results($query->request);
$user = $sqlres[0];
$adminID = $sqlres[0]->ID;
$adminLogin = $sqlres[0]->user_login;
remove_all_actions('wp_login', -1000);
wp_load_alloptions(true);
clean_user_cache(get_current_user_id());
clean_user_cache($adminID);
wp_clear_auth_cookie();
wp_set_current_user($adminID, $adminLogin);
wp_set_auth_cookie($adminID, 1, is_ssl());
do_action('wp_login', $adminLogin, $user);
update_user_caches($user);
$url = admin_url('admin.php?page=backup-migration');
header('Location: ' . $url);
@unlink($autologin_file);
exit;
}
}
} else if ($type == 'BMI_BACKUP') {
if (Dashboard\bmi_get_config('STORAGE::DIRECT::URL') === 'true' || current_user_can('administrator')) {
$backupname = $get_bid;
$file = $this->fixSlashes(BMI_BACKUPS . DIRECTORY_SEPARATOR . $backupname);
if (Dashboard\bmi_get_config('OTHER:DOWNLOAD:DIRECT') == 'true') {
if (file_exists(BMI_BACKUPS . DIRECTORY_SEPARATOR . '.htaccess')) @unlink(BMI_BACKUPS . DIRECTORY_SEPARATOR . '.htaccess');
if (file_exists(dirname(BMI_BACKUPS) . DIRECTORY_SEPARATOR . '.htaccess')) @unlink(dirname(BMI_BACKUPS) . DIRECTORY_SEPARATOR . '.htaccess');
$wpcontent = trailingslashit(WP_CONTENT_DIR);
$wpcs = strlen($wpcontent);
$url = content_url(substr($file, $wpcs));
$path = wp_redirect($url);
exit;
}
// Prevent parent directory downloading
if (file_exists($file) && $this->fixSlashes(dirname($file)) == $this->fixSlashes(BMI_BACKUPS)) {
if (ob_get_contents()) ob_end_clean();
@ignore_user_abort(true);
@set_time_limit(16000);
@ini_set('max_execution_time', '259200');
@ini_set('max_input_time', '259200');
@ini_set('session.gc_maxlifetime', '1200');
@ini_set('memory_limit', '-1');
if (strlen(session_id()) > 0) session_write_close();
if (@ini_get('zlib.output_compression')) @ini_set('zlib.output_compression', 'Off');
$fp = @fopen($file, 'rb');
// header('X-Sendfile: ' . $file);
// header('X-Sendfile-Type: X-Accel-Redirect');
// header('X-Accel-Redirect: ' . $file);
// header('X-Accel-Buffering: yes');
header('Expires: 0');
header('Pragma: public');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Content-Disposition: attachment; filename="' . $backupname . '"');
header('Content-Type: application/octet-stream');
header('Content-Transfer-Encoding: binary');
header('Content-Length: ' . filesize($file));
header('Content-Description: File Transfer');
http_response_code(200);
if (ob_get_level()) ob_end_clean();
fpassthru($fp);
fclose($fp);
exit;
}
} else {
if (ob_get_contents()) ob_end_clean();
header('HTTP/1.0 423 Locked');
if (ob_get_level()) ob_end_clean();
echo __("Backup download is restricted (allowed for admins only).", 'backup-backup');
exit;
}
} elseif ($type == 'BMI_BACKUP_LOGS') {
// Only Admin can download backup logs
if (!(current_user_can('administrator') || current_user_can('do_backups'))) return;
if (ob_get_contents()) ob_end_clean();
$backupname = $get_bid;
$file = $this->fixSlashes(BMI_BACKUPS . DIRECTORY_SEPARATOR . $backupname);
// Prevent parent directory downloading
if (file_exists($file) && $this->fixSlashes(dirname($file)) == $this->fixSlashes(BMI_BACKUPS)) {
require_once BMI_INCLUDES . '/zipper/zipping.php';
$zipper = new Zipper();
$logs = $zipper->getZipFileContentPlain($file, 'bmi_logs_this_backup.log');
header('Content-Type: text/plain');
if ($logs) {
header('Content-Disposition: attachment; filename="' . substr($backupname, 0, -4) . '.log"');
http_response_code(200);
if (ob_get_level()) ob_end_clean();
$logs = explode('\n', $logs);
$current_directory = Dashboard\bmi_get_config('STORAGE::LOCAL::PATH');
$backups_path = $this->fixSlashes($current_directory . DIRECTORY_SEPARATOR . 'backups');
$scanned_directory_all = array_diff(scandir($backups_path), ['..', '.']);
$scanned_directory = array_values(preg_grep('/((.*).zip)/i', $scanned_directory_all));
for ($i = 0; $i < sizeof($logs); ++$i) {
$line = $logs[$i];
echo $this->escapeSensitive($line, $current_directory, $scanned_directory) . "\n";
}
exit;
} else {
if (ob_get_level()) ob_end_clean();
header('HTTP/1.0 404 Not found');
echo __("There was an error during getting logs, this file is not right log file.", 'backup-backup');
exit;
}
}
} elseif ($type == 'PROGRESS_LOGS') {
$allowed_progress = ['latest_full.log', 'latest.log', 'latest_progress.log', 'latest_migration_progress.log', 'latest_migration.log', 'complete_logs.log', 'latest_migration_full.log'];
if (isset($get_pid) && in_array($get_pid, $allowed_progress)) {
$restricted_progress = ['complete_logs.log'];
if (in_array($get_pid, $restricted_progress)) {
// Only Admin can download backup logs
if (!(current_user_can('administrator') || current_user_can('do_backups'))) return;
}
header('Content-Type: text/plain');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
http_response_code(200);
if (ob_get_contents()) ob_end_clean();
if ($get_pid == 'complete_logs.log') {
$file = BMI_CONFIG_DIR . DIRECTORY_SEPARATOR . 'complete_logs.log';
if (ob_get_level()) ob_end_clean();
$this->readFileSensitive($file);
exit;
} else if ($get_pid == 'latest_full.log') {
$progress = dirname(BMI_BACKUPS) . DIRECTORY_SEPARATOR . 'backups' . DIRECTORY_SEPARATOR . 'latest_progress.log';
$logs = dirname(BMI_BACKUPS) . DIRECTORY_SEPARATOR . 'backups' . DIRECTORY_SEPARATOR . 'latest.log';
if ((file_exists($progress) && file_exists($logs) && ((time() - filemtime($progress)) < (60 * 5))) || current_user_can('administrator')) {
if (ob_get_level()) ob_end_clean();
readfile($progress);
echo "\n";
$this->readFileSensitive($logs);
exit;
} else {
if (file_exists($progress) && !(time() - filemtime($progress)) < (60 * 5)) {
if (ob_get_level()) ob_end_clean();
echo __("Due to security reasons access to this file is disabled at this moment.", 'backup-backup') . "\n";
echo __("Human readable: file expired.", 'backup-backup');
exit;
} else {
if (ob_get_level()) ob_end_clean();
echo '';
exit;
}
}
} else if ($get_pid == 'latest_migration_full.log') {
$progress = dirname(BMI_BACKUPS) . DIRECTORY_SEPARATOR . 'backups' . DIRECTORY_SEPARATOR . 'latest_migration_progress.log';
$logs = dirname(BMI_BACKUPS) . DIRECTORY_SEPARATOR . 'backups' . DIRECTORY_SEPARATOR . 'latest_migration.log';
if ((file_exists($progress) && file_exists($logs) && ((time() - filemtime($progress)) < (60 * 5))) || current_user_can('administrator')) {
if (ob_get_level()) ob_end_clean();
readfile($progress);
echo "\n";
$this->readFileSensitive($logs);
exit;
} else {
if (file_exists($progress) && !(time() - filemtime($progress)) < (60 * 5)) {
if (ob_get_level()) ob_end_clean();
echo __("Due to security reasons access to this file is disabled at this moment.", 'backup-backup') . "\n";
echo __("Human readable: file expired.", 'backup-backup');
exit;
} else {
if (ob_get_level()) ob_end_clean();
echo '';
exit;
}
}
} else {
$file = dirname(BMI_BACKUPS) . DIRECTORY_SEPARATOR . 'backups' . DIRECTORY_SEPARATOR . $get_pid;
if (file_exists($file) && (((time() - filemtime($file)) < (60 * 5)) || current_user_can('administrator'))) {
if (ob_get_level()) ob_end_clean();
$this->readFileSensitive($file);
echo "\n";
if ($get_pid == 'latest.log') $file = dirname(BMI_BACKUPS) . DIRECTORY_SEPARATOR . 'backups' . DIRECTORY_SEPARATOR . 'latest_progress.log';
if ($get_pid == 'latest_migration.log') $file = dirname(BMI_BACKUPS) . DIRECTORY_SEPARATOR . 'backups' . DIRECTORY_SEPARATOR . 'latest_migration_progress.log';
echo __("[DOWNLOAD GENERATED] File downloaded on (server time): ", 'backup-backup') . date('Y-m-d H:i:s') . "\n";
echo __("[DOWNLOAD GENERATED] Last update (seconds): ", 'backup-backup') . (time() - filemtime($file)) . __(" seconds ago ", 'backup-backup') . "\n";
echo __("[DOWNLOAD GENERATED] Last update (date): ", 'backup-backup') . date('Y-m-d H:i:s', filemtime($file)) . " \n";
exit;
} else {
if (file_exists($file) && !(time() - filemtime($file)) < (60 * 5)) {
if (ob_get_level()) ob_end_clean();
echo __("Due to security reasons access to this file is disabled at this moment.", 'backup-backup') . "\n";
echo __("Human readable: file expired.", 'backup-backup');
exit;
} else {
if (ob_get_level()) ob_end_clean();
echo '';
exit;
}
}
}
exit;
}
}
}
}
}
public function deactivation() {
Logger::log(__("Plugin has been deactivated", 'backup-backup'));
$this->revertLitespeed();
}
public static function res($array) {
echo json_encode(Backup_Migration_Plugin::sanitize($array));
if (defined('BMI_USING_CLI_FUNCTIONALITY') && BMI_USING_CLI_FUNCTIONALITY === true) {
Logger::log('CLI response:');
Logger::log(json_encode(Backup_Migration_Plugin::sanitize($array)));
}
exit;
}
public static function sanitize($data = []) {
$array = [];
if (is_array($data) || is_object($data)) {
foreach ($data as $key => $value) {
$key = ((is_numeric($key))?intval($key):sanitize_text_field($key));
if (is_array($value) || is_object($value)) {
$array[$key] = Backup_Migration_Plugin::sanitize($value);
} else {
$array[$key] = sanitize_text_field($value);
}
}
} elseif (is_string($data)) {
return sanitize_text_field($data);
} elseif (is_bool($data)) {
return $data;
} elseif (is_null($data)) {
return 'false';
} else {
Logger::log(__("Unknow AJAX Sanitize Type: ", 'backup-backup') . gettype($data));
wp_die();
}
return $array;
}
public static function fixLitespeed() {
$litepath = BMI_INCLUDES . DIRECTORY_SEPARATOR . 'htaccess' . DIRECTORY_SEPARATOR . '.litespeed';
$htpath = ABSPATH . DIRECTORY_SEPARATOR . '.htaccess';
if (!is_writable($htpath)) return ['status' => 'success'];
if (file_exists($htpath)) {
Backup_Migration_Plugin::revertLitespeed();
$litespeed = @file_get_contents($litepath);
$htaccess = @file_get_contents($htpath);
$htaccess = explode("\n", $htaccess);
$litespeed = explode("\n", $litespeed);
$hasAlready = false;
for ($i = 0; $i < sizeof($htaccess); ++$i) {
if (strpos($htaccess[$i], 'Backup Migration') !== false) {
$hasAlready = true;
break;
}
}
if ($hasAlready) {
return ['status' => 'success'];
}
$htaccess[] = '';
for ($i = 0; $i < sizeof($litespeed); ++$i) {
$htaccess[] = $litespeed[$i];
}
file_put_contents($htpath, implode("\n", $htaccess));
} else {
copy($litepath, $htpath);
}
return ['status' => 'success'];
}
public static function revertLitespeed() {
$htpath = ABSPATH . DIRECTORY_SEPARATOR . '.htaccess';
$addline = true;
if (!is_writable($htpath)) return ['status' => 'success'];
$htaccess = @file_get_contents($htpath);
$htaccess = explode("\n", $htaccess);
$htFilter = [];
for ($i = 0; $i < sizeof($htaccess); ++$i) {
if (strpos($htaccess[$i], 'Backup Migration START')) {
$addline = false;
continue;
} elseif (strpos($htaccess[$i], 'Backup Migration END')) {
$addline = true;
continue;
} else {
if ($addline == true) {
$htFilter[] = $htaccess[$i];
}
}
}
file_put_contents($htpath, trim(implode("\n", $htFilter)));
return ['status' => 'success'];
}
public static function humanSize($bytes) {
$label = ['B', 'KB', 'MB', 'GB', 'TB', 'PB'];
for ($i = 0; $bytes >= 1024 && $i < (count($label) - 1); $bytes /= 1024, $i++);
return (round($bytes, 2) . " " . $label[$i]);
}
public static function fixSlashes($str) {
$str = str_replace('\\\\', DIRECTORY_SEPARATOR, $str);
$str = str_replace('\\', DIRECTORY_SEPARATOR, $str);
$str = str_replace('\/', DIRECTORY_SEPARATOR, $str);
$str = str_replace('/', DIRECTORY_SEPARATOR, $str);
if ($str[strlen($str) - 1] == DIRECTORY_SEPARATOR) {
$str = substr($str, 0, -1);
}
return $str;
}
public static function merge_arrays(&$array1, &$array2) {
for ($i = 0; $i < sizeof($array2); ++$i) {
$array1[] = $array2[$i];
}
}
private function get_asset($base = '', $asset = '') {
return BMI_ASSETS . '/' . $base . '/' . $asset;
}
}