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