PluginProbe ʕ •ᴥ•ʔ
Backup Migration / 1.4.8
Backup Migration v1.4.8
2.1.6 2.1.5.2 trunk 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.3.5 1.3.6 1.3.7 1.3.8 1.3.9 1.4.0 1.4.1 1.4.2 1.4.3 1.4.4 1.4.5 1.4.6 1.4.6.1 1.4.7 1.4.8 1.4.9 1.4.9.1 2.0.0 2.1.0 2.1.1 2.1.2 2.1.3 2.1.4 2.1.5 2.1.5.1
backup-backup / includes / initializer.php
backup-backup / includes Last commit date
banner 1 year ago check 1 year ago cli 1 year ago cron 1 year ago dashboard 1 year ago database 1 year ago extracter 1 year ago htaccess 1 year ago progress 1 year ago scanner 1 year ago staging 1 year ago traits 1 year ago uploader 1 year ago zipper 1 year ago .htaccess 1 year ago activation.php 1 year ago ajax.php 1 year ago analyst.php 1 year ago backup-process.php 1 year ago class-backup-method-mananger.php 1 year ago cli-handler.php 1 year ago compatibility.php 1 year ago config.php 1 year ago constants.php 1 year ago initializer.php 1 year ago logger.php 1 year ago
initializer.php
1731 lines
1 <?php
2
3 // Namespace
4 namespace BMI\Plugin;
5
6 // Exit on direct access
7 if (!defined('ABSPATH')) {
8 exit;
9 }
10
11 // Require classes
12 require_once BMI_INCLUDES . '/logger.php';
13
14 // Alias for classes
15 use BMI\Plugin\BMI_Logger as Logger;
16 use BMI\Plugin\CRON\BMI_Crons as Crons;
17 use BMI\Plugin\Dashboard as Dashboard;
18 use BMI\Plugin\Scanner\BMI_BackupsScanner as Backups;
19 use BMI\Plugin\Heart\BMI_Backup_Heart as Bypasser;
20 use BMI\Plugin\Zipper\BMI_Zipper as Zipper;
21 use BMI\Plugin\Staging\BMI_Staging as Staging;
22
23 // Uninstallator
24 if (!function_exists('bmi_uninstall_handler')) {
25 function bmi_uninstall_handler() {
26 require_once BMI_ROOT_DIR . '/uninstall.php';
27 }
28 }
29
30 /**
31 * Backup Migration Main Class
32 */
33 class Backup_Migration_Plugin {
34 public function initialize() {
35
36 // Determine which BMI version is used
37 add_action('wp_head', function () {
38 echo '<meta name="bmi-version" content="' . BMI_VERSION . '" />';
39 });
40
41 if (!file_exists(BMI_BACKUPS)) @mkdir(BMI_BACKUPS, 0755, true);
42 if (!file_exists(BMI_STAGING)) @mkdir(BMI_STAGING, 0755, true);
43
44 // Handle PHP CLI functions
45 if (defined('BMI_USING_CLI_FUNCTIONALITY') && BMI_USING_CLI_FUNCTIONALITY === true) {
46
47 // Below all WordPress functions and directives can be accessed
48 if (defined('BMI_CLI_FUNCTION')) {
49
50 if (BMI_CLI_FUNCTION == 'bmi_restore' && defined('BMI_CLI_ARGUMENT')) {
51
52 $_SERVER['HTTP_X_REQUESTED_WITH'] = 'xmlhttprequest';
53 $_POST['f'] = 'restore-backup';
54 if (defined('BMI_CLI_ARGUMENT_2')) {
55 $_POST['remote'] = BMI_CLI_ARGUMENT_2;
56 } else $_POST['remote'] = false;
57 $_POST['file'] = BMI_CLI_ARGUMENT;
58
59 $this->ajax(true);
60
61 } elseif (BMI_CLI_FUNCTION == 'bmi_backup' || BMI_CLI_FUNCTION == 'bmi_backup_cron') {
62
63 if (BMI_CLI_FUNCTION == 'bmi_backup_cron') {
64 define('BMI_DOING_SCHEDULED_BACKUP', true);
65 define('BMI_DOING_SCHEDULED_BACKUP_VIA_CLI', true);
66 }
67
68 $_SERVER['HTTP_X_REQUESTED_WITH'] = 'xmlhttprequest';
69 $_POST['f'] = 'create-backup';
70
71 $this->ajax(true);
72
73 } elseif (BMI_CLI_FUNCTION == 'bmi_quick_migration') {
74
75 $_SERVER['HTTP_X_REQUESTED_WITH'] = 'xmlhttprequest';
76 $_POST['f'] = 'download-backup';
77 $_POST['url'] = BMI_CLI_ARGUMENT;
78
79 $this->ajax(true);
80
81 }
82
83 }
84
85 return;
86
87 }
88
89 if (defined('BMI_RESTORE_SECRET') && defined('BMI_POST_CONTINUE_RESTORE') && constant('BMI_POST_CONTINUE_RESTORE') === true) {
90
91 if (!isset($_POST['bmi_restore_secret'])) exit;
92
93 // Check the secret
94 $bmi_secret_storage = BMI_TMP . DIRECTORY_SEPARATOR . '.restore_secret';
95 if (file_exists($bmi_secret_storage)) {
96 $bmi_saved_secret = file_get_contents($bmi_secret_storage);
97 if ($bmi_saved_secret === $_POST['bmi_restore_secret']) {
98 $bmi_continue_module = true;
99 } else exit;
100 } else exit;
101
102 $_SERVER['HTTP_X_REQUESTED_WITH'] = 'xmlhttprequest';
103 $_POST['f'] = 'continue_restore_process';
104
105 $this->ajax(true);
106
107 return;
108
109 }
110
111 // Hooks
112 register_deactivation_hook(BMI_ROOT_FILE, [&$this, 'deactivation']);
113 register_uninstall_hook(BMI_ROOT_FILE, 'bmi_uninstall_handler');
114
115 // File downloading
116 add_action('wp_loaded', [&$this, 'handle_downloading']);
117
118 // Additional actions
119 if (isset($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] === 'GET') {
120 add_action('wp_loaded', [&$this, 'handle_after_actions'], 1000);
121 }
122 // Handle CRONs
123 add_action('bmi_do_backup_right_now', [&$this, 'handle_cron_backup']);
124 add_action('bmi_handle_cron_check', [&$this, 'handle_cron_check']);
125 add_action('wp_loaded', [&$this, 'handle_crons']);
126 add_action('wp_loaded', [&$this, 'include_offline']);
127 add_action('admin_notices', [&$this, 'incompatibility_notices']);
128
129 // Return if CRON time
130 if (function_exists('wp_doing_cron') && wp_doing_cron()) return;
131
132 // Check user permissions
133 $user = get_userdata(get_current_user_id());
134 if (!$user || !$user->roles) return;
135 if (!current_user_can('do_backups') && !in_array('administrator', (array) $user->roles)) return;
136
137 if (Dashboard\bmi_get_config('OTHER:PROMOTIONAL:DISPLAY') != 'true') {
138
139 // Include our cool banner
140 include_once BMI_INCLUDES . '/banner/misc.php';
141
142 // Review banner
143 if (!is_dir(WP_PLUGIN_DIR . '/backup-backup-pro')) {
144 if (!(class_exists('\Inisev\Subs\Inisev_Review') || class_exists('Inisev\Subs\Inisev_Review') || class_exists('Inisev_Review'))) {
145 require_once BMI_MODULES_DIR . 'review' . DIRECTORY_SEPARATOR . 'review.php';
146 }
147 $review_banner = new \Inisev\Subs\Inisev_Review(BMI_ROOT_FILE, BMI_ROOT_DIR, 'backup-backup', 'Backup & Migration', 'http://bit.ly/3vdk45L', 'backup-migration');
148 }
149
150 // GDrive banner
151 if (!is_dir(WP_PLUGIN_DIR . '/backup-backup-pro')) {
152 if (!(class_exists('\Inisev\Subs\BMI_Banners_GDrive') || class_exists('Inisev\Subs\BMI_Banners_GDrive') || class_exists('BMI_Banners_GDrive'))) {
153 require_once BMI_MODULES_DIR . 'gdrivebanner' . DIRECTORY_SEPARATOR . 'misc.php';
154 }
155 $gdirve_banner = new \Inisev\Subs\BMI_Banners_GDrive('Backup & Migration', 'backup-migration');
156 }
157
158 }
159
160 // POST Logic
161 if ($_SERVER['REQUEST_METHOD'] === 'POST') {
162
163 // Register AJAX Handler
164 add_action('wp_ajax_backup_migration', [&$this, 'ajax']);
165
166 // Stop GET Registration
167 // return; // Commented because of conflicts with USM Icons
168
169 }
170
171 // Actions
172 add_action('admin_init', [&$this, 'admin_init_hook']);
173 add_action('admin_menu', [&$this, 'submenu']);
174 add_action('admin_notices', [&$this, 'admin_notices']);
175
176
177 // Settings action
178 add_filter('plugin_action_links_' . plugin_basename(BMI_ROOT_FILE), [&$this, 'settings_action']);
179
180 // Ignore below actions if those true
181 if (function_exists('wp_doing_ajax') && wp_doing_ajax()) {
182 return;
183 }
184
185 // Styles & scripts
186 add_action('admin_enqueue_scripts', [&$this, 'enqueue_styles']);
187 add_action('admin_enqueue_scripts', [&$this, 'enqueue_scripts']);
188
189 }
190
191 public function incompatibility_notices() {
192
193 if (strpos(home_url(), 'instawp') === false && strpos(home_url(), 'playground.wordpress') === false) return;
194
195 $environment = 'sandbox';
196 if (strpos(home_url(), 'instawp') !== false) $environment = 'InstaWP';
197 if (strpos(home_url(), 'playground.wordpress') !== false) $environment = 'WordPress Playground';
198
199 $class = 'notice notice-warning';
200 $message = __('We noticed that you are using %s, our plugin may not work in this environment, please use %s environment instead.', 'backup-backup');
201
202 printf('<div class="%s"><p><b>Backup Migration:</b> %s</p></div>',
203 esc_attr($class),
204 sprintf(
205 esc_html($message),
206 '<i>' . $environment . '</i>',
207 '<a href="https://tastewp.com" target="_blank">TasteWP</a>'
208 )
209 );
210 }
211
212 public static function randomString($max = 16) {
213
214 $bank = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
215 $bank .= 'abcdefghijklmnopqrstuvwxyz';
216 $bank .= '0123456789';
217
218 $str = str_shuffle($bank);
219
220 while (is_numeric($str[0])) {
221 $str = str_shuffle($bank);
222 }
223
224 $str = substr($str, 0, $max);
225
226 return $str;
227
228 }
229
230 public static function isFunctionEnabled($func) {
231
232 $disabled = explode(',', ini_get('disable_functions'));
233 $isDisabled = in_array($func, $disabled);
234 if (!$isDisabled && function_exists($func)) return true;
235 else return false;
236
237 }
238
239 /**
240 * hotFixPatches - Function which fixes things for "old" users
241 *
242 * @return void
243 */
244 public function hotfix_patches() {
245
246 if (!is_admin()) return;
247
248 $current_patch = get_option('bmi_hotfixes', array());
249 if (!in_array('BMI_D20_M07_01', $current_patch)) {
250
251 $current_directory = Dashboard\bmi_get_config('STORAGE::LOCAL::PATH');
252 if (basename($current_directory) == 'backup-migration') {
253
254 require_once BMI_INCLUDES . '/ajax.php';
255 $handler_a = new BMI_Ajax(true);
256
257 $handler_a->post['directory'] = dirname($current_directory) . DIRECTORY_SEPARATOR . 'backup-migration-' . $this->randomString(10);
258 $handler_a->post['access'] = Dashboard\bmi_get_config('STORAGE::DIRECT::URL');
259
260 $res_a = $handler_a->saveStorageConfig();
261 if (isset($res_a['status']) && $res_a['status'] == 'success') {
262
263 $current_patch[] = 'BMI_D20_M07_01';
264
265 }
266
267 } else {
268
269 $current_patch[] = 'BMI_D20_M07_01';
270
271 }
272
273 }
274
275 if (!in_array('BMI_D17_M12_Y21_02', $current_patch)) {
276
277 $current_splitting_value = Dashboard\bmi_get_config('OTHER:RESTORE:SPLITTING');
278 $current_query_size = Dashboard\bmi_get_config('OTHER:DB:QUERIES');
279
280 $current_query_size = intval($current_query_size);
281 if ($current_splitting_value == 'true' || $current_splitting_value === true) {
282 $current_splitting_value = true;
283 } else {
284 $current_splitting_value = false;
285 }
286
287 if ($current_splitting_value === false || $current_query_size != 300) {
288
289 $b_db_restore_splitting = true;
290 $b_db_query_size = '2000';
291
292 $error_b = 0;
293 if (!Dashboard\bmi_set_config('OTHER:RESTORE:SPLITTING', $b_db_restore_splitting)) {
294 $error_b++;
295 }
296 if (!Dashboard\bmi_set_config('OTHER:DB:QUERIES', $b_db_query_size)) {
297 $error_b++;
298 }
299
300 if ($error_b <= 0) {
301
302 $current_patch[] = 'BMI_D17_M12_Y21_02';
303
304 }
305
306 } else {
307
308 $current_patch[] = 'BMI_D17_M12_Y21_02';
309
310 }
311
312 }
313
314 if (!in_array('BMI_D13_M08_Y23_01', $current_patch)) {
315
316 $current_direct_download_value = Dashboard\bmi_get_config('OTHER:DOWNLOAD:DIRECT');
317
318 if ($current_direct_download_value === false || $current_direct_download_value == 'false') {
319
320 $error_b = 0;
321 if (!Dashboard\bmi_set_config('OTHER:DOWNLOAD:DIRECT', true)) $error_b++;
322 if ($error_b <= 0) $current_patch[] = 'BMI_D13_M08_Y23_01';
323
324 } else $current_patch[] = 'BMI_D13_M08_Y23_01';
325
326 }
327
328 update_option('bmi_hotfixes', $current_patch);
329
330 }
331
332 public function ajax($cli = false) {
333 if (isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest') {
334 if ((isset($_POST['token']) && $_POST['token'] == 'bmi' && isset($_POST['f']) && is_admin()) || $cli) {
335 try {
336
337 if (gettype($cli) != 'boolean') $cli = false;
338
339 // Extend execution time
340 if ($this->isFunctionEnabled('headers_sent') && $this->isFunctionEnabled('session_status')) {
341 if (!headers_sent() && session_status() === PHP_SESSION_DISABLED) {
342 if ($this->isFunctionEnabled('ignore_user_abort')) @ignore_user_abort(true);
343 if ($this->isFunctionEnabled('set_time_limit')) @set_time_limit(16000);
344 if ($this->isFunctionEnabled('ini_set')) {
345 @ini_set('max_execution_time', '259200');
346 @ini_set('max_input_time', '259200');
347 }
348 }
349 }
350
351 // May cause issues with auto login
352 // if (strlen(session_id()) > 0) session_write_close();
353
354 if ($this->isFunctionEnabled('register_shutdown_function')) {
355 register_shutdown_function([$this, 'execution_shutdown']);
356 }
357
358 // Require AJAX Handler
359 require_once BMI_INCLUDES . '/ajax.php';
360 $handler = new BMI_Ajax($cli);
361
362 } catch (\Exception $e) {
363
364 Logger::error('POST error:');
365 Logger::error($e);
366 if ($_POST['f'] == 'create-backup') {
367 $progress = &$GLOBALS['bmi_backup_progress'];
368 $this->handleErrorDuringBackup($e->getMessage(), $e->getFile(), $e->getLine(), $progress);
369 }
370 if ($_POST['f'] == 'restore-backup') {
371 $progress = &$GLOBALS['bmi_migration_progress'];
372 $this->handleErrorDuringRestore($e->getMessage(), $e->getFile(), $e->getLine(), $progress);
373 }
374
375 $this->res(['status' => 'error', 'error' => $e]);
376 exit;
377
378 } catch (\Throwable $e) {
379
380 Logger::error('POST error:');
381 Logger::error($e);
382 if ($_POST['f'] == 'create-backup') {
383 $progress = &$GLOBALS['bmi_backup_progress'];
384 $this->handleErrorDuringBackup($e->getMessage(), $e->getFile(), $e->getLine(), $progress);
385 }
386 if ($_POST['f'] == 'restore-backup') {
387 $progress = &$GLOBALS['bmi_migration_progress'];
388 $this->handleErrorDuringRestore($e->getMessage(), $e->getFile(), $e->getLine(), $progress);
389 }
390
391 $this->res(['status' => 'error', 'error' => $e]);
392 exit;
393
394 }
395 }
396 }
397 }
398
399 public function execution_shutdown() {
400 $err = error_get_last();
401
402 if (defined('BMI_USING_CLI_FUNCTIONALITY') && BMI_USING_CLI_FUNCTIONALITY === true) {
403 $lock_cli = BMI_BACKUPS . '/.migration_lock_cli';
404 $lock_cli_end = BMI_BACKUPS . '/.migration_lock_ended';
405 $cli_failed_lock = BMI_BACKUPS . '/.backup_lock_cli_failed';
406 $lock_cli_end_backup = BMI_BACKUPS . '/.backup_lock_cli_end';
407
408 if (file_exists($lock_cli)) @unlink($lock_cli);
409 if (file_exists($lock_cli_end)) @touch($lock_cli_end);
410 if (file_exists($cli_failed_lock)) @touch($cli_failed_lock);
411 if (file_exists($lock_cli_end_backup)) @touch($lock_cli_end_backup);
412 }
413
414 if ($err != null) {
415
416 $msg = $err['message'];
417 $file = $err['file'];
418 $line = $err['line'];
419 $type = $err['type'];
420
421 if ($type != '1' && ($type != E_ERROR && $type != E_CORE_ERROR && $type != E_COMPILE_ERROR && $type != E_USER_ERROR && $type != E_RECOVERABLE_ERROR)) {
422 Logger::error(__('There was an error before request shutdown (but it was not logged to backup/restore log)', 'backup-backup'));
423 Logger::error(__('Error message: ', 'backup-backup') . $msg);
424 Logger::error(__('Error file/line: ', 'backup-backup') . $file . '|' . $line);
425 Logger::error(__('Error handler: ', 'backup-backup') . 'init#01' . '|' . $type);
426 return;
427 }
428
429 if (isset($GLOBALS['bmi_error_handled']) && $GLOBALS['bmi_error_handled']) return;
430 if ($_POST['f'] == 'create-backup') {
431 Logger::error(__('There was an error during backup', 'backup-backup'));
432 Logger::error(__('Error message: ', 'backup-backup') . $msg);
433 Logger::error(__('Error file/line: ', 'backup-backup') . $file . '|' . $line);
434 Logger::error(__('Error handler: ', 'backup-backup') . 'init#02' . '|' . $type);
435 $progress = &$GLOBALS['bmi_backup_progress'];
436 if ($progress) {
437 $progress->log(__('Error message: ', 'backup-backup') . $msg, 'error');
438 $progress->log(__('You can get more pieces of information in troubleshooting log file.', 'backup-backup'), 'error');
439 }
440 $this->handleErrorDuringBackup($msg, $file, $line, $progress);
441
442 $fullPath = BMI_TMP . DIRECTORY_SEPARATOR;
443 array_map('unlink', glob($fullPath . '*.tmp'));
444 array_map('unlink', glob($fullPath . '*.gz'));
445 }
446
447 if ($_POST['f'] == 'restore-backup') {
448 Logger::error(__('There was an error during restore process', 'backup-backup'));
449 Logger::error(__('Error message: ', 'backup-backup') . $msg);
450 Logger::error(__('Error file/line: ', 'backup-backup') . $file . '|' . $line);
451 Logger::error(__('Error handler: ', 'backup-backup') . 'init#03' . '|' . $type);
452 $progress = &$GLOBALS['bmi_migration_progress'];
453 if ($progress) {
454 $progress->log(__('Error message: ', 'backup-backup') . $msg, 'error');
455 $progress->log(__('You can get more pieces of information in troubleshooting log file.', 'backup-backup'), 'error');
456 }
457 $this->handleErrorDuringRestore($msg, $file, $line, $progress);
458 }
459
460 $this->res(['status' => 'error', 'error' => $err]);
461 exit;
462 }
463 }
464
465 public function handleErrorDuringBackup($msg, $file, $line, &$progress) {
466 $backup = $GLOBALS['bmi_current_backup_name'];
467
468 Logger::log('Due to fatal error backup handled correctly (closed and removed).');
469 if ($progress) {
470 $progress->log(__('Something bad happened on PHP side.', 'backup-backup'), 'error');
471 $progress->log(__('Unfortunately we had to remove the backup (if partly created).', 'backup-backup'), 'error');
472 $progress->log(__('Error message: ', 'backup-backup') . $msg, 'error');
473 $progress->log(__('Error file/line: ', 'backup-backup') . $file . '|' . $line, 'error');
474 if (strpos($msg, 'execution time') !== false) {
475 $progress->log(__('Probably we could not increase the execution time, please edit your php.ini manually', 'backup-backup'), 'error');
476 }
477 }
478
479 $backup_path = BMI_BACKUPS . DIRECTORY_SEPARATOR . $backup;
480 $partial_backup_path = glob( BMI_BACKUPS . DIRECTORY_SEPARATOR . $backup . '.??????');
481 if (is_array($partial_backup_path) && count($partial_backup_path) > 0) {
482 foreach ($partial_backup_path as $key => $value) {
483 @unlink($value);
484 }
485 }
486 if (file_exists($backup_path)) @unlink($backup_path);
487 if (file_exists(BMI_BACKUPS . DIRECTORY_SEPARATOR . '.running')) @unlink(BMI_BACKUPS . DIRECTORY_SEPARATOR . '.running');
488 if (file_exists(BMI_BACKUPS . DIRECTORY_SEPARATOR . '.abort')) @unlink(BMI_BACKUPS . DIRECTORY_SEPARATOR . '.abort');
489
490 if ($progress) {
491 $progress->log(__("Aborting backup...", 'backup-backup'), 'step');
492 $progress->log('#002', 'END-CODE');
493 $progress->end();
494 }
495 }
496
497 public function handleErrorDuringRestore($msg, $file, $line, &$progress) {
498 Logger::log('There was fatal error during restore.');
499 if ($progress) {
500 $progress->log(__('Something bad happened on PHP side.', 'backup-backup'), 'error');
501 $progress->log(__('Error message: ', 'backup-backup') . $msg, 'error');
502 $progress->log(__('Error file/line: ', 'backup-backup') . $file . '|' . $line, 'error');
503 }
504 if (file_exists(BMI_BACKUPS . DIRECTORY_SEPARATOR . '.migration_lock')) @unlink(BMI_BACKUPS . DIRECTORY_SEPARATOR . '.migration_lock');
505 if ($progress) {
506 $progress->log(__("Aborting & unlocking restore process...", 'backup-backup'), 'step');
507 $progress->end();
508 }
509
510 $lock = BMI_BACKUPS . '/.migration_lock';
511 if (file_exists($lock)) @unlink($lock);
512 }
513
514 public function submenu() {
515
516 // Menu icon
517 $icon_url = $this->get_asset('images', 'logo-min.png');
518
519 // Main menu slug
520 $parentSlug = 'backup-migration';
521
522 // Content
523 $content = [$this, 'settings_page'];
524
525 // Main menu hook
526 add_menu_page('Backup Migration', '<span id="bmi-menu">Backup Migration</span>', 'read', $parentSlug, $content, $icon_url, 98);
527
528 // Remove default submenu by menu
529 remove_submenu_page($parentSlug, $parentSlug);
530
531 }
532
533 public function settings_action($links) {
534 $text = __('Manage', 'backup-backup');
535 $links['bmi-settings-link'] = '<a href="' . admin_url('/admin.php?page=backup-migration') . '">' . $text . '</a>';
536
537 return $links;
538 }
539
540 public function include_offline() {
541
542 // Prevent if there is no offline action required (save resources)
543 if (get_option('bmip_last', false) !== '1') return;
544
545 if (defined('BMI_PRO_INC')) {
546
547 // Handle offline tasks
548 if (!class_exists('BMI_Pro_Offline')) {
549 if (file_exists(constant('BMI_PRO_INC') . 'offline.php')) {
550 require_once constant('BMI_PRO_INC') . 'offline.php';
551 new BMI_Pro_Offline();
552 }
553 }
554
555 }
556
557 }
558
559 public function settings_page() {
560
561 // Set email if does not exist
562 if (!Dashboard\bmi_get_config('OTHER:EMAIL')) {
563 Dashboard\bmi_set_config('OTHER:EMAIL', get_bloginfo('admin_email'));
564 }
565
566 // Require The HTML
567 require_once BMI_INCLUDES . '/dashboard/settings.php';
568 }
569
570 public function admin_init_hook() {
571 $this->hotfix_patches();
572 if (get_option('_bmi_redirect', false)) {
573 $this->fixLitespeed();
574 delete_option('_bmi_redirect');
575 wp_safe_redirect(admin_url('admin.php?page=backup-migration'));
576 }
577 }
578
579 public function admin_notices() {
580 if (get_current_screen()->id != 'toplevel_page_backup-migration' && get_option('bmi_display_email_issues', false)) {
581 ?>
582 <div class="notice notice-warning">
583 <p>
584 <?php _e('There was an error during automated backup, please', 'backup-backup'); ?>
585 <?php echo '<a href="' . admin_url('/admin.php?page=backup-migration') . '">' . __('check that.', 'backup-backup') . '</a>'; ?>
586 </p>
587 </div>
588 <?php
589 }
590 }
591
592 public function handle_crons() {
593 if (Dashboard\bmi_get_config('CRON:ENABLED') !== true) return;
594
595 $time = get_option('bmi_backup_check', 0);
596 if ((time() - $time) > 60) {
597 update_option('bmi_backup_check', time());
598
599 do_action('bmi_handle_cron_check');
600 }
601 }
602
603 public static function email_error($msg) {
604 Logger::log('Displaying some issues about email sending...');
605 update_option('bmi_display_email_issues', $msg);
606 }
607
608 public function backup_inproper_time($should_time) {
609 $plan_file = BMI_TMP . DIRECTORY_SEPARATOR . '.plan';
610 if (!file_exists($plan_file) || intval($should_time) < 1234567890) return;
611
612 Logger::log('Sending notification about backup being late');
613 $email = Dashboard\bmi_get_config('OTHER:EMAIL') != false ? Dashboard\bmi_get_config('OTHER:EMAIL') : get_bloginfo('admin_email');
614 $subject = Dashboard\bmi_get_config('OTHER:EMAIL:TITLE');
615 $message = __("Automatic backup was not on time because there was no traffic on the site.", 'backup-backup') . "\n";
616 $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);
617 $message .= ' ' . __("(server time)", 'backup-backup');
618
619 Logger::debug($message);
620 if (!self::send_notification_mail($email, $subject, $message)) {
621 $issue = __("Couldn't send mail to you, please check server configuration.", 'backup-backup') . '<br>';
622 $issue .= '<b>' . __("Message you missed because of this: ", 'backup-backup') . '</b>' . $message;
623 self::email_error($issue);
624 }
625 }
626
627 public function handle_cron_check() {
628
629 if (Dashboard\bmi_get_config('CRON:ENABLED') !== true) return;
630
631 $now = time();
632 if (file_exists(BMI_TMP . DIRECTORY_SEPARATOR . '.last')) {
633 $last = @file_get_contents(BMI_TMP . DIRECTORY_SEPARATOR . '.last');
634 $last_status = explode('.', $last)[0];
635 $last_time = intval(explode('.', $last)[1]);
636 } else {
637 $last_time = 0;
638 $last_status = 0;
639 }
640
641 if (file_exists(BMI_TMP . DIRECTORY_SEPARATOR . '.plan')) {
642 $plan = intval(@file_get_contents(BMI_TMP . DIRECTORY_SEPARATOR . '.plan'));
643 if ($last_time < $plan && ((time() - $plan) > 7200)) {
644 if ($last_status !== '0') {
645 $this->backup_inproper_time($plan);
646 if (!wp_next_scheduled('bmi_do_backup_right_now')) {
647 wp_schedule_single_event(time(), 'bmi_do_backup_right_now');
648 }
649 }
650 }
651 }
652
653 }
654
655 public function get_next_cron($curr = false) {
656 if ($curr === false) {
657 $curr = time();
658 }
659
660 $time = Crons::calculate_date([
661 'type' => Dashboard\bmi_get_config('CRON:TYPE'),
662 'week' => Dashboard\bmi_get_config('CRON:WEEK'),
663 'day' => Dashboard\bmi_get_config('CRON:DAY'),
664 'hour' => Dashboard\bmi_get_config('CRON:HOUR'),
665 'minute' => Dashboard\bmi_get_config('CRON:MINUTE')
666 ], $curr);
667
668 return $time;
669 }
670
671 public function handle_cron_error($e) {
672 Logger::error(__("Automatic backup failed at time: ", 'backup-backup') . date('Y-m-d, H:i:s'));
673 if (is_object($e) || is_array($e)) {
674 Logger::error('Error: ' . $e->getMessage());
675 } else {
676 Logger::error('Error: ' . $e);
677 }
678
679 $notis = Dashboard\bmi_get_config('OTHER:EMAIL:NOTIS');
680 if (in_array($notis, [true, 'true'])) {
681 $email = Dashboard\bmi_get_config('OTHER:EMAIL') != false ? Dashboard\bmi_get_config('OTHER:EMAIL') : get_bloginfo('admin_email');
682 $subject = Dashboard\bmi_get_config('OTHER:EMAIL:TITLE');
683 $message = __("There was an error during automatic backup, please check the logs.", 'backup-backup');
684 if (is_string($e)) {
685 $message .= "\nError: " . $e;
686 }
687
688 self::send_notification_mail($email, $subject, $message);
689 }
690
691 if (file_exists(BMI_BACKUPS . '/.cron')) {
692 @unlink(BMI_BACKUPS . '/.cron');
693 }
694 }
695
696 public static function send_notification_mail($email, $subject, $message, $force = false) {
697
698 $currentDate = date('Y-m-d');
699 if (get_option('bmi_last_email_notification', false) == $currentDate && $force === false) {
700 Logger::log(__("Disallowing to send mail as today we already sent one.", 'backup-backup'));
701 return;
702 }
703
704 update_option('bmi_last_email_notification', $currentDate);
705
706 $email_fail = __("Could not send the email notification about that fail", 'backup-backup');
707
708 try {
709
710 if (wp_mail($email, $subject, $message)) {
711 Logger::log(__("Sent email notification to: ", 'backup-backup') . $email);
712
713 return true;
714 } else {
715 Logger::error($email_fail);
716 self::email_error(__("Couldn't send notification via email, please check the email and your server settings.", 'backup-backup'));
717
718 return false;
719 }
720
721 } catch (\Exception $e) {
722 Logger::error($email_fail);
723 self::email_error(__("Couldn't send notification via email due to error, please check plugin logs for more details.", 'backup-backup'));
724
725 return false;
726 } catch (\Throwable $e) {
727 Logger::error($email_fail);
728 self::email_error(__("Couldn't send notification via email due to error, please check plugin logs for more details.", 'backup-backup'));
729
730 return false;
731 }
732 }
733
734 public static function handle_after_cron() {
735 require_once BMI_INCLUDES . DIRECTORY_SEPARATOR . 'scanner' . DIRECTORY_SEPARATOR . 'backups.php';
736 $backups = new Backups();
737 $availableBackups = $backups->getAvailableBackups();
738 $list = $availableBackups['local'];
739
740 $cron_list = [];
741 $cron_dates = [];
742 $sortedMD5s = [];
743 foreach ($list as $key => $value) {
744 if ($list[$key][6] == true) {
745 if ($list[$key][5] == 'unlocked') {
746 $cron_list[$list[$key][1]] = $list[$key][0];
747 $cron_dates[] = $list[$key][1];
748 $sortedMD5s[] = [$list[$key][1], $list[$key][7]];
749 }
750 }
751 }
752
753 usort($cron_dates, function ($a, $b) {
754 return (strtotime($a) < strtotime($b)) ? -1 : 1;
755 });
756
757 $cron_dates = array_slice($cron_dates, 0, -(intval(Dashboard\bmi_get_config('CRON:KEEP'))));
758 foreach ($cron_dates as $key => $value) {
759 $name = $cron_list[$cron_dates[$key]];
760 $name = explode('#%&', $name)[1];
761 Logger::log(__("Removing backup due to keep rules: ", 'backup-backup') . $name);
762 @unlink(BMI_BACKUPS . DIRECTORY_SEPARATOR . $name);
763 }
764
765 // Auto External Removal
766 $sortedMD5s = [];
767 $externalStorages = ['gdrive', 'dropbox', 'onedrive', 'FTP', 'sftp'];
768 foreach ($externalStorages as $storage) {
769 if (isset($availableBackups['external'][$storage])) {
770 $storageList = $availableBackups['external'][$storage];
771 foreach ($storageList as $md5 => $data) {
772 if ($storageList[$md5][6] == true && $storageList[$md5][5] == 'unlocked') {
773 $sortedMD5s[] = [$storageList[$md5][1], $md5];
774 }
775 }
776 }
777 }
778 $sortedMD5s = array_intersect_key($sortedMD5s, array_unique(array_map('serialize', $sortedMD5s)));
779
780 usort($sortedMD5s, function ($a, $b) {
781 return (strtotime($a[0]) < strtotime($b[0])) ? -1 : 1;
782 });
783
784 $sortedMD5s = array_slice($sortedMD5s, 0, -(intval(Dashboard\bmi_get_config('CRON:KEEP'))));
785 foreach ($sortedMD5s as $index => $data) {
786 $md5 = $data[1];
787
788 do_action('bmi_premium_remove_backup_file', $md5);
789 do_action('bmi_premium_remove_backup_json_file', $md5 . '.json');
790 }
791 }
792
793 public function set_last_cron($status, $time) {
794 $file = BMI_TMP . DIRECTORY_SEPARATOR . '.last';
795 file_put_contents($file, $status . '.' . $time);
796 }
797
798 public function readFileSensitive($file) {
799 if (!file_exists($file)) {
800 echo '';
801 return;
802 }
803
804 $file = new \SplFileObject($file);
805 $file->seek($file->getSize());
806 $total_lines = $file->key() + 1;
807
808 $current_directory = Dashboard\bmi_get_config('STORAGE::LOCAL::PATH');
809 $backups_path = $this->fixSlashes($current_directory . DIRECTORY_SEPARATOR . 'backups');
810 $scanned_directory_all = array_diff(scandir($backups_path), ['..', '.']);
811 $scanned_directory = array_values(preg_grep('/((.*).zip)/i', $scanned_directory_all));
812
813 for ($i = 0; $i < $total_lines; ++$i) {
814
815 $file->seek($i);
816 $line = $this->escapeSensitive($file->current(), $current_directory, $scanned_directory);
817
818 echo $line;
819 unset($line);
820
821 }
822
823 }
824
825 public function escapeSensitive($line, $current_directory, $scanned_directory) {
826
827 global $table_prefix;
828
829 $dir_name = basename($current_directory);
830
831 $line = preg_replace('/\:\ ((.*)\.zip)/', ': *****.zip', $line);
832 $line = preg_replace('/(\"filename\":(.*)\.zip)\"/', '"filename": "*****.zip"', $line);
833 $line = preg_replace('/\"http(.*)\"/', '"***site_url***"', $line);
834 $line = preg_replace('/\:\ http(.*)\n/', ": ***site_url***\n", $line);
835 $line = preg_replace('/\"\d{10}\"/', '"***secret_login***"', $line);
836 $line = str_replace(ABSPATH, '***ABSPATH***/', $line);
837 $line = str_replace($dir_name, '***backup_path***', $line);
838 $line = str_replace($table_prefix, '***_', $line);
839 $line = preg_replace('/^(.*?&sk=).*$/', '$1***', $line);
840
841 for ($i = 0; $i < sizeof($scanned_directory); ++$i) {
842
843 $backup_name = $scanned_directory[$i];
844 $line = str_replace($backup_name, '***some_backup***', $line);
845
846 }
847
848 return $line;
849
850 }
851
852 public function handle_cron_backup() {
853
854 $plan_file = BMI_TMP . DIRECTORY_SEPARATOR . '.plan';
855 $last_file = BMI_TMP . DIRECTORY_SEPARATOR . '.last';
856
857 // Abort if disabled
858 if (Dashboard\bmi_get_config('CRON:ENABLED') !== true) {
859
860
861 if (file_exists($plan_file)) @unlink($plan_file);
862 if (file_exists($last_file)) @unlink($last_file);
863
864 return;
865
866 }
867
868 if (!file_exists($plan_file)) return;
869
870 // Planned time
871 $plan = intval(@file_get_contents(BMI_TMP . DIRECTORY_SEPARATOR . '.plan'));
872
873 // Check difference
874 if ((time() - $plan) > 3600) {
875 Logger::log('Backup failed to run on proper time, but running now.');
876 Logger::log('Planned time: ' . date('Y-m-d H:i:s', $plan));
877 $this->backup_inproper_time($plan);
878 }
879
880 // Now
881 $now = time();
882 $this->set_last_cron('0', $now);
883
884 // Extend execution time
885 if ($this->isFunctionEnabled('headers_sent') && $this->isFunctionEnabled('session_status')) {
886 if (!headers_sent() && session_status() === PHP_SESSION_DISABLED) {
887 if ($this->isFunctionEnabled('ignore_user_abort')) @ignore_user_abort(true);
888 if ($this->isFunctionEnabled('set_time_limit')) @set_time_limit(16000);
889 if ($this->isFunctionEnabled('ini_set')) {
890 @ini_set('max_execution_time', '259200');
891 @ini_set('max_input_time', '259200');
892 }
893 }
894 }
895
896 if (strlen(session_id()) > 0) session_write_close();
897
898 Logger::log(__("Automatic backup called at time: ", 'backup-backup') . date('Y-m-d, H:i:s'));
899
900 try {
901 require_once BMI_INCLUDES . '/ajax.php';
902 $isBackup = (file_exists(BMI_BACKUPS . '/.running') && (time() - filemtime(BMI_BACKUPS . '/.running')) <= 65) ? true : false;
903 $isCron = (file_exists(BMI_BACKUPS . '/.cron') && (time() - filemtime(BMI_BACKUPS . '/.cron')) <= 65) ? true : false;
904 if ($isCron) {
905 return;
906 }
907
908 if ($isBackup) {
909 $this->handle_cron_error(__("Could not make the backup: Backup already running, please wait till it complete.", 'backup-backup'));
910 $this->set_last_cron('2', $now);
911 } else {
912 touch(BMI_BACKUPS . '/.cron');
913
914 if (!defined('BMI_DOING_SCHEDULED_BACKUP')) {
915 define('BMI_DOING_SCHEDULED_BACKUP', true);
916 }
917
918 $handler = new BMI_Ajax();
919 $handler->resetLatestLogs();
920 $backup = $handler->prepareAndMakeBackup(true);
921
922 if ($backup['status'] == 'success') {
923 if (isset($backup['filename'])) {
924 Logger::log(__("Automatic backup successed: ", 'backup-backup') . $backup['filename']);
925 } else {
926 Logger::log(__("Automatic backup successed", 'backup-backup'));
927 }
928 $this->set_last_cron('1', $now);
929 } elseif ($backup['status'] == 'background') {
930 Logger::log(__('Scheduled backup is running in background: ', 'backup-backup') . $backup['filename']);
931 $this->set_last_cron('1', $now);
932 } elseif ($backup['status'] == 'msg') {
933 $this->handle_cron_error($backup['why']);
934 $this->set_last_cron('3', $now);
935 } else {
936 $this->handle_cron_error(__("Could not make the backup due to internal server error.", 'backup-backup'));
937 $this->set_last_cron('4', $now);
938 }
939 }
940 } catch (\Exception $e) {
941 $this->handle_cron_error($e);
942 $this->set_last_cron('5', $now);
943 } catch (\Throwable $e) {
944 $this->handle_cron_error($e);
945 $this->set_last_cron('5', $now);
946 }
947
948 $this->handle_after_cron();
949
950 if (file_exists(BMI_BACKUPS . '/.cron')) {
951 @unlink(BMI_BACKUPS . '/.cron');
952 }
953 require_once BMI_INCLUDES . '/cron/handler.php';
954 $time = $this->get_next_cron();
955
956 wp_clear_scheduled_hook('bmi_do_backup_right_now');
957 wp_schedule_single_event($time, 'bmi_do_backup_right_now');
958
959 $file = BMI_TMP . DIRECTORY_SEPARATOR . '.plan';
960 file_put_contents($file, $time);
961 }
962
963 public function enqueue_scripts() {
964
965 // Global
966 if (in_array(get_current_screen()->id, ['toplevel_page_backup-migration', 'plugins'])) { ?>
967 <script type="text/javascript">
968 let stars = '<?php echo plugin_dir_url(BMI_ROOT_FILE); ?>' + 'admin/images/stars.gif';
969 let css_star = "background:url('" + stars + "')";
970 document.addEventListener("DOMContentLoaded", function(event) {
971 jQuery('[data-slug="backup-migration-pro"]').find('strong').html('<span>Backup Migration <b style="color: orange; ' + css_star + '">Pro</b></span>');
972 jQuery('[data-slug="backup-backup-pro"]').find('strong').html('<span>Backup Migration <b style="color: orange; ' + css_star + '">Pro</b></span>');
973 });
974 </script>
975 <?php }
976
977 // Only for BM Settings
978 if (!in_array(get_current_screen()->id, ['toplevel_page_backup-migration', 'update-core', 'plugins', 'plugin-install', 'themes','customize', 'plugins-network', 'plugin-install-network', 'themes-network'])) return;
979 wp_enqueue_script('backup-migration-script', $this->get_asset('js', 'backup-migration.min.js'), ['jquery'], BMI_VERSION, true);
980 wp_localize_script('backup-migration-script', 'bmiVariables', [
981 'nonce' => wp_create_nonce('backup-migration-ajax'),
982 'stgLoading' => __('Loading, please wait...', 'backup-backup'),
983 'stgStagingDefaultName' => __('staging', 'backup-backup'),
984 'urlCopies' => __('URL copied successfully', 'backup-backup'),
985 'isBeforeUpdateEnabled' => dashboard\bmi_get_config('OTHER:TRIGGER:BEFORE:UPDATES') ? 'true' : 'false',
986 'maxUploadSize' => $this->getMaxUploadSize()
987 ]);
988
989 }
990
991 public function phpSizeToB($phpSize) {
992
993 $sSuffix = strtoupper(substr($phpSize, -1));
994
995 if (!in_array($sSuffix, array('P','T','G','M','K'))) {
996 return (int) $phpSize;
997 }
998
999 $iValue = substr($phpSize, 0, -1);
1000 switch ($sSuffix) {
1001 case 'P': $iValue *= 1024;
1002 case 'T': $iValue *= 1024;
1003 case 'G': $iValue *= 1024;
1004 case 'M': $iValue *= 1024;
1005 case 'K': $iValue *= 1024;
1006 break;
1007 }
1008
1009 return (int) $iValue;
1010
1011 }
1012
1013 public function getMaxUploadSize() {
1014 $ten = (10 * 1024 * 1024);
1015 $max = min($this->phpSizeToB(ini_get('post_max_size')), $this->phpSizeToB(ini_get('upload_max_filesize')), $ten);
1016 return intval($max / 1024 / 1024);
1017 }
1018
1019 public function enqueue_styles() {
1020
1021 // Global styles
1022 wp_enqueue_style('backup-migration-style-icon', $this->get_asset('css', 'bmi-plugin-icon.min.css'), [], BMI_VERSION);
1023
1024 // Only for BM Settings and Update Core page
1025 if (!in_array(get_current_screen()->id, ['toplevel_page_backup-migration', 'update-core', 'plugins', 'plugin-install', 'themes','customize', 'plugins-network', 'plugin-install-network', 'themes-network'])) return;
1026
1027 // Enqueue the style
1028 wp_enqueue_style('backup-migration-style', $this->get_asset('css', 'bmi-plugin.min.css'), [], BMI_VERSION);
1029
1030 }
1031
1032 public function handle_after_actions() {
1033
1034 // Handle After Migration actions
1035 $afterMigrationLock = BMI_TMP . DIRECTORY_SEPARATOR . '.migrationFinished';
1036 if (file_exists($afterMigrationLock)) {
1037 if (strpos(site_url(), 'tastewp') !== false) {
1038
1039 if (function_exists('wp_load_alloptions')) {
1040 wp_load_alloptions(true);
1041 }
1042
1043 update_option('__tastewp_redirection_performed', true);
1044 update_option('auto_smart_tastewp_redirect_performed', 1);
1045 update_option('tastewp_auto_activated', true);
1046 update_option('__tastewp_sub_requested', true);
1047
1048 }
1049
1050 unlink($afterMigrationLock);
1051 }
1052
1053 }
1054
1055 public function handle_downloading() {
1056 global $wpdb;
1057 @error_reporting(0);
1058 $autologin_file = BMI_BACKUPS . '/.autologin';
1059 $ip = '127.0.0.1';
1060 if (isset($_SERVER['HTTP_CLIENT_IP'])) {
1061 $ip = $_SERVER['HTTP_CLIENT_IP'];
1062 } else {
1063 if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
1064 $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
1065 }
1066 if ($ip === false) {
1067 if (isset($_SERVER['REMOTE_ADDR'])) $ip = $_SERVER['REMOTE_ADDR'];
1068 }
1069 }
1070 $allowed = ['BMI_BACKUP', 'BMI_BACKUP_LOGS', 'PROGRESS_LOGS', 'AFTER_RESTORE', 'CURL_BACKUP'];
1071 $get_bmi = !empty($_GET['backup-migration']) ? sanitize_text_field($_GET['backup-migration']) : false;
1072 $get_bid = !empty($_GET['backup-id']) ? sanitize_text_field($_GET['backup-id']) : false;
1073 $get_pid = !empty($_GET['progress-id']) ? sanitize_text_field($_GET['progress-id']) : false;
1074 $get_is_uncensored = !empty($_GET['uncensored']) ? sanitize_text_field($_GET['uncensored']) : false;
1075 $crons_enabled = !empty($_GET['crons']) ? sanitize_text_field($_GET['crons']) : false;
1076 $secret_key = !empty($_GET['sk']) ? sanitize_text_field($_GET['sk']) : false;
1077
1078 if (isset($get_bmi) && in_array($get_bmi, $allowed)) {
1079 if (isset($get_bid) && strlen($get_bid) > 0 && isset($secret_key) && $secret_key === Dashboard\bmi_get_config('REQUEST:SECRET')) {
1080 $type = $get_bmi;
1081
1082 if ($type == 'AFTER_RESTORE' && isset($get_pid)) {
1083 if (file_exists($autologin_file)) {
1084 $autoLoginMD = file_get_contents($autologin_file);
1085 $autoLoginMD = explode('_', $autoLoginMD);
1086 $aID = intval($autoLoginMD[0]);
1087 $aID2 = intval($autoLoginMD[0]) - 1;
1088 $aID3 = intval($autoLoginMD[0]) + 1;
1089 $aID4 = intval($autoLoginMD[0]) + 2;
1090 $aID5 = intval($autoLoginMD[0]) + 3;
1091 $aID6 = intval($autoLoginMD[0]) + 4;
1092 $aIP = $autoLoginMD[1];
1093 $aIZ = $autoLoginMD[2];
1094
1095 // Allow 1 second delay
1096 $timeIsProper = false;
1097 if ($aID === intval($get_bid)) $timeIsProper = true;
1098 if ($aID2 === intval($get_bid)) $timeIsProper = true;
1099 if ($aID3 === intval($get_bid)) $timeIsProper = true;
1100 if ($aID4 === intval($get_bid)) $timeIsProper = true;
1101 if ($aID5 === intval($get_bid)) $timeIsProper = true;
1102 if ($aID6 === intval($get_bid)) $timeIsProper = true;
1103
1104 if ($timeIsProper && $aIP === $ip && trim($aIZ) === $get_pid) {
1105 $query = new \WP_User_Query(['role' => 'Administrator', 'count_total' => false, 'fields' => 'all']);
1106 $sqlres = $wpdb->get_results($query->request);
1107
1108 if (sizeof($sqlres) > 0 && isset($sqlres[0]->ID) && isset($sqlres[0]->user_login)) {
1109
1110 $user = $sqlres[0];
1111 $adminID = $sqlres[0]->ID;
1112 $adminLogin = $sqlres[0]->user_login;
1113
1114 remove_all_actions('wp_login', -1000);
1115 wp_load_alloptions(true);
1116 clean_user_cache(get_current_user_id());
1117 clean_user_cache($adminID);
1118 wp_clear_auth_cookie();
1119 wp_set_current_user($adminID, $adminLogin);
1120 wp_set_auth_cookie($adminID, 1, is_ssl());
1121 do_action('wp_login', $adminLogin, $user);
1122 update_user_caches($user);
1123
1124 }
1125 $cronsEnabledParam = $crons_enabled ? "&crons=true" : "";
1126
1127 $url = admin_url('admin.php?page=backup-migration' . $cronsEnabledParam);
1128 header('Location: ' . $url);
1129
1130 @unlink($autologin_file);
1131 exit;
1132 }
1133 }
1134
1135 } else if ($type == 'BMI_BACKUP') {
1136 if (Dashboard\bmi_get_config('STORAGE::DIRECT::URL') === 'true' || current_user_can('administrator')) {
1137
1138 $backupname = $get_bid;
1139 $file = $this->fixSlashes(BMI_BACKUPS . DIRECTORY_SEPARATOR . $backupname);
1140
1141 $outsideDir = false;
1142 if (!(file_exists($file) && $this->fixSlashes(dirname($file)) == $this->fixSlashes(BMI_BACKUPS))) {
1143 $outsideDir = true;
1144 }
1145
1146 if ($outsideDir || strpos(strtolower(mime_content_type($file)), 'zip') === false) {
1147 header('HTTP/1.0 423 Locked');
1148 _e("Incorrect usage of the query request.", 'backup-backup');
1149 exit;
1150 }
1151
1152 if (Dashboard\bmi_get_config('OTHER:DOWNLOAD:DIRECT') == 'true') {
1153 if (file_exists(BMI_BACKUPS . DIRECTORY_SEPARATOR . '.htaccess')) @unlink(BMI_BACKUPS . DIRECTORY_SEPARATOR . '.htaccess');
1154 if (file_exists(dirname(BMI_BACKUPS) . DIRECTORY_SEPARATOR . '.htaccess')) @unlink(dirname(BMI_BACKUPS) . DIRECTORY_SEPARATOR . '.htaccess');
1155 $wpcontent = trailingslashit(WP_CONTENT_DIR);
1156 $wpcs = strlen($wpcontent);
1157 $url = $this->fixSlashes(content_url(substr($file, $wpcs)), '/');
1158 $path = wp_redirect($url);
1159 exit;
1160 }
1161
1162 // Prevent parent directory downloading
1163 if (ob_get_contents()) ob_end_clean();
1164
1165 if ($this->isFunctionEnabled('ignore_user_abort')) @ignore_user_abort(true);
1166 if ($this->isFunctionEnabled('set_time_limit')) @set_time_limit(16000);
1167 if ($this->isFunctionEnabled('headers_sent') && $this->isFunctionEnabled('session_status')) {
1168 if (!headers_sent() && session_status() === PHP_SESSION_DISABLED) {
1169 if ($this->isFunctionEnabled('ini_set')) {
1170 @ini_set('max_execution_time', '259200');
1171 @ini_set('max_input_time', '259200');
1172 @ini_set('memory_limit', '-1');
1173 if (@ini_get('zlib.output_compression')) {
1174 @ini_set('zlib.output_compression', 'Off');
1175 }
1176 }
1177 }
1178 }
1179
1180 if (strlen(session_id()) > 0) session_write_close();
1181
1182 $fp = @fopen($file, 'rb');
1183
1184 // header('X-Sendfile: ' . $file);
1185 // header('X-Sendfile-Type: X-Accel-Redirect');
1186 // header('X-Accel-Redirect: ' . $file);
1187 // header('X-Accel-Buffering: yes');
1188 header('Expires: 0');
1189 header('Pragma: public');
1190 header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
1191 header('Content-Disposition: attachment; filename="' . $backupname . '"');
1192 header('Content-Type: application/octet-stream');
1193 header('Content-Transfer-Encoding: binary');
1194 header('Content-Length: ' . filesize($file));
1195 header('Content-Description: File Transfer');
1196 http_response_code(200);
1197
1198 if (ob_get_level()) ob_end_clean();
1199
1200 fpassthru($fp);
1201 fclose($fp);
1202 exit;
1203
1204 } else {
1205 if (ob_get_contents()) ob_end_clean();
1206 header('HTTP/1.0 423 Locked');
1207 if (ob_get_level()) ob_end_clean();
1208 echo __("Backup download is restricted (allowed for admins only).", 'backup-backup');
1209 exit;
1210 }
1211 } else if ($type == 'BMI_BACKUP_LOGS') {
1212
1213 // Only Admin can download backup logs
1214 if (!(current_user_can('administrator') || current_user_can('do_backups'))) return;
1215
1216 if (ob_get_contents()) ob_end_clean();
1217 $backupname = $get_bid;
1218 $file = $this->fixSlashes(BMI_BACKUPS . DIRECTORY_SEPARATOR . $backupname);
1219
1220 // Prevent parent directory downloading
1221 if (file_exists($file) && $this->fixSlashes(dirname($file)) == $this->fixSlashes(BMI_BACKUPS)) {
1222 require_once BMI_INCLUDES . '/zipper/zipping.php';
1223
1224 $zipper = new Zipper();
1225 $logs = $zipper->getZipFileContentPlain($file, 'bmi_logs_this_backup.log');
1226 header('Content-Type: text/plain');
1227
1228 if ($logs) {
1229 header('Content-Disposition: attachment; filename="' . substr($backupname, 0, -4) . '.log"');
1230 http_response_code(200);
1231 if (ob_get_level()) ob_end_clean();
1232
1233 $logs = explode('\n', $logs);
1234 $current_directory = Dashboard\bmi_get_config('STORAGE::LOCAL::PATH');
1235 $backups_path = $this->fixSlashes($current_directory . DIRECTORY_SEPARATOR . 'backups');
1236 $scanned_directory_all = array_diff(scandir($backups_path), ['..', '.']);
1237 $scanned_directory = array_values(preg_grep('/((.*).zip)/i', $scanned_directory_all));
1238
1239 for ($i = 0; $i < sizeof($logs); ++$i) {
1240
1241 $line = $logs[$i];
1242 echo $this->escapeSensitive($line, $current_directory, $scanned_directory) . "\n";
1243
1244 }
1245
1246 exit;
1247 } else {
1248 if (ob_get_level()) ob_end_clean();
1249 header('HTTP/1.0 404 Not found');
1250 echo __("There was an error during getting logs, this file is not right log file.", 'backup-backup');
1251 exit;
1252 }
1253 }
1254
1255 } else if ($type == 'PROGRESS_LOGS') {
1256 $allowed_progress = [
1257 'latest_full.log',
1258 'latest.log',
1259 'latest_progress.log',
1260 'latest_migration_full.log',
1261 'latest_migration.log',
1262 'latest_migration_progress.log',
1263 'latest_staging_full.log',
1264 'latest_staging.log',
1265 'latest_staging_progress.log',
1266 'complete_logs.log'
1267 ];
1268 if (isset($get_pid) && in_array($get_pid, $allowed_progress)) {
1269
1270 $restricted_progress = ['complete_logs.log'];
1271 if (in_array($get_pid, $restricted_progress)) {
1272
1273 // Only Admin can download backup logs
1274 if (!(current_user_can('administrator') || current_user_can('do_backups'))) return;
1275
1276 }
1277
1278 header('Content-Type: text/plain');
1279 header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
1280 http_response_code(200);
1281 if (ob_get_contents()) ob_end_clean();
1282 if ($get_pid == 'complete_logs.log') {
1283 $file = BMI_CONFIG_DIR . DIRECTORY_SEPARATOR . 'complete_logs.log';
1284 if (ob_get_level()) ob_end_clean();
1285 $this->readFileSensitive($file);
1286 exit;
1287 } else if ($get_pid == 'latest_full.log') {
1288 $progress = dirname(BMI_BACKUPS) . DIRECTORY_SEPARATOR . 'backups' . DIRECTORY_SEPARATOR . 'latest_progress.log';
1289 $logs = dirname(BMI_BACKUPS) . DIRECTORY_SEPARATOR . 'backups' . DIRECTORY_SEPARATOR . 'latest.log';
1290 if ((file_exists($progress) && file_exists($logs) && ((time() - filemtime($progress)) < (60 * 1))) || current_user_can('administrator')) {
1291 if (ob_get_level()) ob_end_clean();
1292 readfile($progress);
1293 echo "\n";
1294 if (isset($get_is_uncensored) && $get_is_uncensored && current_user_can('administrator')) readfile($logs);
1295 else $this->readFileSensitive($logs);
1296 exit;
1297 } else {
1298 if (file_exists($progress) && !(time() - filemtime($progress)) < (60 * 1)) {
1299 if (ob_get_level()) ob_end_clean();
1300 echo __("Due to security reasons access to this file is disabled at this moment.", 'backup-backup') . "\n";
1301 echo __("Human readable: file expired.", 'backup-backup');
1302 exit;
1303 } else {
1304 if (ob_get_level()) ob_end_clean();
1305 echo '';
1306 exit;
1307 }
1308 }
1309 } else if ($get_pid == 'latest_migration_full.log') {
1310 $progress = dirname(BMI_BACKUPS) . DIRECTORY_SEPARATOR . 'backups' . DIRECTORY_SEPARATOR . 'latest_migration_progress.log';
1311 $logs = dirname(BMI_BACKUPS) . DIRECTORY_SEPARATOR . 'backups' . DIRECTORY_SEPARATOR . 'latest_migration.log';
1312 if ((file_exists($progress) && file_exists($logs) && ((time() - filemtime($progress)) < (60 * 1))) || current_user_can('administrator')) {
1313 if (ob_get_level()) ob_end_clean();
1314 readfile($progress);
1315 echo "\n";
1316 if (isset($get_is_uncensored) && $get_is_uncensored && current_user_can('administrator')) readfile($logs);
1317 else $this->readFileSensitive($logs);
1318 exit;
1319 } else {
1320 if (file_exists($progress) && !(time() - filemtime($progress)) < (60 * 1)) {
1321 if (ob_get_level()) ob_end_clean();
1322 echo __("Due to security reasons access to this file is disabled at this moment.", 'backup-backup') . "\n";
1323 echo __("Human readable: file expired.", 'backup-backup');
1324 exit;
1325 } else {
1326 if (ob_get_level()) ob_end_clean();
1327 echo '';
1328 exit;
1329 }
1330 }
1331 } else if ($get_pid == 'latest_staging_full.log') {
1332 $progress = BMI_STAGING . DIRECTORY_SEPARATOR . 'latest_staging_progress.log';
1333 $logs = BMI_STAGING . DIRECTORY_SEPARATOR . 'latest_staging.log';
1334 if ((file_exists($progress) && file_exists($logs) && ((time() - filemtime($progress)) < (60 * 1))) || current_user_can('administrator')) {
1335 if (ob_get_level()) ob_end_clean();
1336 readfile($progress);
1337 echo "\n";
1338 $this->readFileSensitive($logs);
1339 exit;
1340 } else {
1341 if (file_exists($progress) && !(time() - filemtime($progress)) < (60 * 1)) {
1342 if (ob_get_level()) ob_end_clean();
1343 echo __("Due to security reasons access to this file is disabled at this moment.", 'backup-backup') . "\n";
1344 echo __("Human readable: file expired.", 'backup-backup');
1345 exit;
1346 } else {
1347 if (ob_get_level()) ob_end_clean();
1348 echo '';
1349 exit;
1350 }
1351 }
1352 } else {
1353 $file = dirname(BMI_BACKUPS) . DIRECTORY_SEPARATOR . 'backups' . DIRECTORY_SEPARATOR . $get_pid;
1354 if ($get_pid == 'latest_staging.log') $file = BMI_STAGING . DIRECTORY_SEPARATOR . $get_pid;
1355 if ($get_pid == 'latest_staging_progress.log') $file = BMI_STAGING . DIRECTORY_SEPARATOR . $get_pid;
1356 if (file_exists($file) && (((time() - filemtime($file)) < (60 * 1)) || current_user_can('administrator'))) {
1357 if (ob_get_level()) ob_end_clean();
1358
1359 if (isset($get_is_uncensored) && $get_is_uncensored && current_user_can('administrator')) readfile($file);
1360 else $this->readFileSensitive($file);
1361
1362 echo "\n";
1363 if ($get_pid == 'latest.log') $file = dirname(BMI_BACKUPS) . DIRECTORY_SEPARATOR . 'backups' . DIRECTORY_SEPARATOR . 'latest_progress.log';
1364 if ($get_pid == 'latest_migration.log') $file = dirname(BMI_BACKUPS) . DIRECTORY_SEPARATOR . 'backups' . DIRECTORY_SEPARATOR . 'latest_migration_progress.log';
1365 if ($get_pid == 'latest_staging.log') $file = BMI_STAGING . DIRECTORY_SEPARATOR . 'latest_staging_progress.log';
1366 echo __("[DOWNLOAD GENERATED] File downloaded on (server time): ", 'backup-backup') . date('Y-m-d H:i:s') . "\n";
1367 echo __("[DOWNLOAD GENERATED] Last update (seconds): ", 'backup-backup') . (time() - filemtime($file)) . __(" seconds ago ", 'backup-backup') . "\n";
1368 echo __("[DOWNLOAD GENERATED] Last update (date): ", 'backup-backup') . date('Y-m-d H:i:s', filemtime($file)) . " \n";
1369 exit;
1370 } else {
1371 if (file_exists($file) && !(time() - filemtime($file)) < (60 * 1)) {
1372 if (ob_get_level()) ob_end_clean();
1373 echo __("Due to security reasons access to this file is disabled at this moment.", 'backup-backup') . "\n";
1374 echo __("Human readable: file expired.", 'backup-backup');
1375 exit;
1376 } else {
1377 if (ob_get_level()) ob_end_clean();
1378 echo '';
1379 exit;
1380 }
1381 }
1382 }
1383 }
1384 } else if ($type == 'CURL_BACKUP') {
1385
1386 // We tried to use nonces here, but turns out that WordPress does not work well with generating nonces for cURL session.
1387 // We also tries to use cookiejar etc. but for researchers, this function is "verified" by process identy.
1388 // It's similarly safe as nonce, but it works in case we need, nonces gets rejected after second request.
1389 //
1390 // At the end, user who indeed would like to abuse this functionality, he can't do anything than helping the site owner.
1391 // Free browser will keep the process ongoing, user won't receive any details other than "success" - as long as the user know the process identy.
1392
1393 try {
1394
1395 // Load bypasser
1396 require_once BMI_INCLUDES . '/backup-process.php';
1397 $request = new Bypasser($get_bid, BMI_CONFIG_DIR, trailingslashit(WP_CONTENT_DIR), BMI_BACKUPS, trailingslashit(ABSPATH), plugin_dir_path(BMI_ROOT_FILE));
1398
1399 if (sizeof($request->remote_settings) === 0) return;
1400
1401 // Handle request
1402 $request->handle_batch();
1403 exit;
1404
1405 } catch (\Exception $e) {
1406
1407 error_log('There was an error with Backup Migration plugin: ' . $e->getMessage());
1408 Logger::error(__('Error handler: ', 'backup-backup') . 'ajax#01' . '|' . $e->getMessage());
1409 error_log(strval($e));
1410
1411 } catch (\Throwable $t) {
1412
1413 error_log('There was an error with Backup Migration plugin: ' . $t->getMessage());
1414 Logger::error(__('Error handler: ', 'backup-backup') . 'ajax#01' . '|' . $t->getMessage());
1415 error_log(strval($t));
1416
1417 }
1418
1419 }
1420 }
1421 }
1422 }
1423
1424 public function deactivation() {
1425 Logger::log(__("Plugin has been deactivated", 'backup-backup'));
1426 $this->revertLitespeed();
1427 }
1428
1429 public static function res($array) {
1430 $GLOBALS['BMI::RESPONSE::SENT'] = true;
1431 echo json_encode(Backup_Migration_Plugin::sanitize($array));
1432
1433 if (defined('BMI_USING_CLI_FUNCTIONALITY') && BMI_USING_CLI_FUNCTIONALITY === true) {
1434 Logger::log('CLI response:');
1435 Logger::log(json_encode(Backup_Migration_Plugin::sanitize($array)));
1436 }
1437
1438 exit;
1439 }
1440
1441 public static function getAvailableMemoryInBytes() {
1442
1443 $totalMemory = @ini_get('memory_limit');
1444 if ($totalMemory == -1) {
1445
1446 $totalMemory = 32 * 1024 * 1024;
1447
1448 } else {
1449
1450 if (strpos($totalMemory, 'M') !== false || strpos($totalMemory, 'm') !== false) {
1451 $totalMemory = intval($totalMemory) * 1024 * 1024;
1452 } else if (strpos($totalMemory, 'G') !== false || strpos($totalMemory, 'g') !== false) {
1453 $totalMemory = intval($totalMemory) * 1024 * 1024 * 1024;
1454 } else if (strpos($totalMemory, 'K') !== false || strpos($totalMemory, 'k') !== false) {
1455 $totalMemory = intval($totalMemory) * 1024;
1456 } else {
1457 $totalMemory = intval($totalMemory);
1458 }
1459
1460 }
1461
1462 $availableMemory = $totalMemory - memory_get_usage(true);
1463
1464 return $availableMemory;
1465
1466 }
1467
1468 public static function sanitize($data = []) {
1469 $array = [];
1470
1471 if (is_array($data) || is_object($data)) {
1472 foreach ($data as $key => $value) {
1473 $key = ((is_numeric($key))?intval($key):sanitize_text_field($key));
1474
1475 if (is_array($value) || is_object($value)) {
1476 $array[$key] = Backup_Migration_Plugin::sanitize($value);
1477 } else {
1478 $array[$key] = sanitize_text_field($value);
1479 }
1480 }
1481 } elseif (is_string($data)) {
1482 return sanitize_text_field($data);
1483 } elseif (is_bool($data)) {
1484 return $data;
1485 } elseif (is_null($data)) {
1486 return 'false';
1487 } else {
1488 Logger::log(__("Unknow AJAX Sanitize Type: ", 'backup-backup') . gettype($data));
1489 wp_die();
1490 }
1491
1492 return $array;
1493 }
1494
1495 public static function fixLitespeed() {
1496 $litepath = BMI_INCLUDES . DIRECTORY_SEPARATOR . 'htaccess' . DIRECTORY_SEPARATOR . '.litespeed';
1497 $htpath = ABSPATH . DIRECTORY_SEPARATOR . '.htaccess';
1498 if (!is_writable($htpath)) return ['status' => 'success'];
1499 if (file_exists($htpath)) {
1500 Backup_Migration_Plugin::revertLitespeed();
1501 $litespeed = @file_get_contents($litepath);
1502 $htaccess = @file_get_contents($htpath);
1503 $htaccess = explode("\n", $htaccess);
1504 $litespeed = explode("\n", $litespeed);
1505
1506 $hasAlready = false;
1507 for ($i = 0; $i < sizeof($htaccess); ++$i) {
1508 if (strpos($htaccess[$i], 'Backup Migration') !== false) {
1509 $hasAlready = true;
1510
1511 break;
1512 }
1513 }
1514
1515 if ($hasAlready) {
1516 return ['status' => 'success'];
1517 }
1518 $htaccess[] = '';
1519 for ($i = 0; $i < sizeof($litespeed); ++$i) {
1520 $htaccess[] = $litespeed[$i];
1521 }
1522
1523 file_put_contents($htpath, implode("\n", $htaccess));
1524 } else {
1525 copy($litepath, $htpath);
1526 }
1527
1528 return ['status' => 'success'];
1529 }
1530
1531 public static function revertLitespeed() {
1532 $htpath = ABSPATH . DIRECTORY_SEPARATOR . '.htaccess';
1533 $addline = true;
1534
1535 if (!is_writable($htpath)) return ['status' => 'success'];
1536 $htaccess = @file_get_contents($htpath);
1537 $htaccess = explode("\n", $htaccess);
1538 $htFilter = [];
1539
1540 for ($i = 0; $i < sizeof($htaccess); ++$i) {
1541 if (strpos($htaccess[$i], 'Backup Migration START')) {
1542 $addline = false;
1543
1544 continue;
1545 } elseif (strpos($htaccess[$i], 'Backup Migration END')) {
1546 $addline = true;
1547
1548 continue;
1549 } else {
1550 if ($addline == true) {
1551 $htFilter[] = $htaccess[$i];
1552 }
1553 }
1554 }
1555
1556 file_put_contents($htpath, trim(implode("\n", $htFilter)));
1557
1558 return ['status' => 'success'];
1559 }
1560
1561 public static function humanSize($bytes) {
1562 if (is_int($bytes)) {
1563 $label = ['B', 'KB', 'MB', 'GB', 'TB', 'PB'];
1564 for ($i = 0; $bytes >= 1024 && $i < (count($label) - 1); $bytes /= 1024, $i++);
1565
1566 return (round($bytes, 2) . " " . $label[$i]);
1567 } else return $bytes;
1568 }
1569
1570 public static function fixSlashes($str, $slash = false) {
1571 // Old version
1572 // $str = str_replace('\\\\', DIRECTORY_SEPARATOR, $str);
1573 // $str = str_replace('\\', DIRECTORY_SEPARATOR, $str);
1574 // $str = str_replace('\/', DIRECTORY_SEPARATOR, $str);
1575 // $str = str_replace('/', DIRECTORY_SEPARATOR, $str);
1576
1577 // if ($str[strlen($str) - 1] == DIRECTORY_SEPARATOR) {
1578 // $str = substr($str, 0, -1);
1579 // }
1580
1581 // Since 1.3.2
1582 $protocol = '';
1583 if ($slash == false) $slash = DIRECTORY_SEPARATOR;
1584 if (substr($str, 0, 7) == 'http://') $protocol = 'http://';
1585 else if (substr($str, 0, 8) == 'https://') $protocol = 'https://';
1586
1587 $str = substr($str, strlen($protocol));
1588 $str = preg_replace('/[\\\\\/]+/', $slash, $str);
1589 $str = untrailingslashit($str);
1590
1591 return $protocol . $str;
1592 }
1593
1594 public static function canShareLogsOrShouldAsk() {
1595
1596 return 'not-allowed';
1597
1598 // REMOVED CODE:
1599 // $isAllowed = get_option('BMI_LOGS_SHARING_IS_ALLOWED', 'unknown');
1600 // $isAllowedConfig = Dashboard\bmi_get_config('LOGS::SHARING');
1601 //
1602 // if ($isAllowed == 'unknown' || empty($isAllowedConfig)) return 'ask';
1603 // else if ($isAllowed === 'yes' && $isAllowedConfig === 'yes') {
1604 // return 'allowed';
1605 // } else if ($isAllowed === 'no' && $isAllowedConfig === 'no') {
1606 // return 'not-allowed';
1607 // } else return 'ask';
1608
1609 }
1610
1611 public static function getRecentSize() {
1612 $folderNames = [ 'BACKUP:DATABASE' => 'database',
1613 "BACKUP:FILES::PLUGINS" => 'plugins',
1614 "BACKUP:FILES::UPLOADS" => 'uploads',
1615 "BACKUP:FILES::THEMES" => 'themes',
1616 "BACKUP:FILES::OTHERS" => 'contents_others',
1617 "BACKUP:FILES::WP" => 'wordpress'
1618 ];
1619
1620 $size = 0;
1621 foreach ($folderNames as $setting => $fileName) {
1622 if (Dashboard\bmi_get_config($setting) === 'true') {
1623 $size += get_transient('bmi_latest_size_' . $fileName);
1624 }
1625
1626 }
1627 return $size;
1628 }
1629
1630 public static function merge_arrays(&$array1, &$array2) {
1631 for ($i = 0; $i < sizeof($array2); ++$i) {
1632 $array1[] = $array2[$i];
1633 }
1634 }
1635
1636 public static function getDefaultDisabledPaths() {
1637 require_once BMI_INCLUDES . '/staging/controller.php';
1638 $staging = new Staging('..ajax..');
1639 $stagingSites = $staging->getStagingSites(true);
1640 $stagingSitesPaths = [];
1641 // Get all directory names of staging sites
1642 foreach ($stagingSites as $index => $site) {
1643
1644 // Convert every directory to their location path
1645 $stagingSitesPaths[] = '***ABSPATH***/' . $site['name'];
1646
1647 }
1648
1649 $ignored_paths_default = [
1650 BMI_CONFIG_DIR,
1651 BMI_BACKUPS,
1652 BMI_ROOT_DIR,
1653 constant('BMI_PRO_ROOT_DIR'),
1654 "***ABSPATH***/wp-content/ai1wm-backups",
1655 "***ABSPATH***/wp-content/ai1wm-backups-old",
1656 "***ABSPATH***/wp-content/mwp-download",
1657 "***ABSPATH***/wp-content/uploads/wp-clone",
1658 "***ABSPATH***/wp-content/updraft",
1659 "***ABSPATH***/wp-content/backups-dup-pro",
1660 "***ABSPATH***/wp-content/wpvividbackups",
1661 "***ABSPATH***/wp-content/backup-guard",
1662 "***ABSPATH***/wp-content/backuply",
1663 "***ABSPATH***/wp-content/backups-dup-lite",
1664 "***ABSPATH***/wp-content/uploads/backupbuddy_backups",
1665 "***ABSPATH***/wp-content/uploads/wp-file-manager-pro",
1666 "***ABSPATH***/wp-content/uploads/wp-file-manager",
1667 "***ABSPATH***/wp-content/plugins/akeebabackupwp",
1668 "***ABSPATH***/wp-content/uploads/jetbackup",
1669 "***ABSPATH***/wp-content/uploads/backup-guard",
1670 "***ABSPATH***/wp-content/uploads/wp-migrate-db",
1671 "***ABSPATH***/wp-content/uploads/wpforms/.htaccess.cpmh3129",
1672 "***ABSPATH***/wp-content/uploads/gravity_forms/.htaccess.cpmh3129",
1673 "***ABSPATH***/.htaccess.cpmh3129",
1674 "***ABSPATH***/logs/traffic.html/.md5sums",
1675 "***ABSPATH***/wp-config.php",
1676 "***ABSPATH***/wp-content/backup-migration-config.php",
1677 ];
1678 $ignored_paths = array_merge($ignored_paths_default, $stagingSitesPaths);
1679 array_walk($ignored_paths, function(&$path){
1680 $path = self::fixSlashes(str_replace('***ABSPATH***', ABSPATH, $path));
1681 });
1682 return $ignored_paths;
1683 }
1684
1685 private function get_asset($base = '', $asset = '') {
1686 return BMI_ASSETS . '/' . $base . '/' . $asset;
1687 }
1688
1689 /**
1690 * Extend the execution time for the plugin
1691 *
1692 * @return void
1693 */
1694 public static function extend_execution_time() {
1695 if (self::isFunctionEnabled('headers_sent') && self::isFunctionEnabled('session_status')) {
1696 if (!headers_sent() && session_status() === PHP_SESSION_DISABLED) {
1697 if (self::isFunctionEnabled('ignore_user_abort')) @ignore_user_abort(true);
1698 if (self::isFunctionEnabled('set_time_limit')) @set_time_limit(16000);
1699 if (self::isFunctionEnabled('ini_set')) {
1700 @ini_set('max_execution_time', '259200');
1701 @ini_set('max_input_time', '259200');
1702 }
1703 }
1704 }
1705 }
1706
1707 public static function getRetryAfterIfAvailable($ch, $response)
1708 {
1709 $phpVersion = phpversion();
1710 $curlVersion = curl_version();
1711 // Available as of PHP 8.2.0 and cURL 7.66.0
1712 if (version_compare($phpVersion, '8.2.0', '>=') && version_compare($curlVersion['version'], '7.66.0', '>=')) {
1713 $retryAfter = curl_getinfo($ch, CURLINFO_RETRY_AFTER);
1714 if ($retryAfter !== false) {
1715 return $retryAfter;
1716 }
1717 }else {
1718 $header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
1719 $header = substr($response, 0, $header_size);
1720 $headers = explode("\r\n", $header);
1721 foreach ($headers as $h) {
1722 if (preg_match('/^Retry-After:\s+(\d+)/i', $h, $matches)) {
1723 return intval($matches[1]);
1724 }
1725 }
1726 }
1727 return false;
1728
1729 }
1730 }
1731