Current Path : /home/ncdcgo/public_html/wp-content/plugins backup/duplicator-pro/ctrls/ |
Current File : /home/ncdcgo/public_html/wp-content/plugins backup/duplicator-pro/ctrls/class.web.services.php |
<?php /** * @package Duplicator * @copyright (c) 2022, Snap Creek LLC */ use Duplicator\Ajax\AbstractAjaxService; use Duplicator\Ajax\AjaxWrapper; use Duplicator\Ajax\ServicesDashboard; use Duplicator\Ajax\ServicesImport; use Duplicator\Ajax\ServicesNotifications; use Duplicator\Ajax\ServicesRecovery; use Duplicator\Ajax\ServicesSchedule; use Duplicator\Ajax\ServicesSettings; use Duplicator\Ajax\ServicesStorage; use Duplicator\Core\CapMng; use Duplicator\Core\MigrationMng; use Duplicator\Libs\Snap\SnapIO; use Duplicator\Libs\Snap\SnapJson; use Duplicator\Libs\Snap\SnapURL; use Duplicator\Libs\Snap\SnapUtil; use Duplicator\Models\BrandEntity; use Duplicator\Models\Storages\AbstractStorageEntity; use Duplicator\Models\Storages\StoragesUtil; use Duplicator\Models\SystemGlobalEntity; use Duplicator\Utils\ExpireOptions; use Duplicator\Utils\Settings\MigrateSettings; use Duplicator\Utils\ZipArchiveExtended; use Duplicator\Views\AdminNotices; use VendorDuplicator\Amk\JsonSerialize\JsonSerialize; /** * WEB Service Execution Status */ abstract class DUP_PRO_Web_Service_Execution_Status { const Pass = 1; const Warn = 2; const Fail = 3; const Incomplete = 4; // Still more to go const ScheduleRunning = 5; } /** * DUPLICATOR_PRO_WEB_SERVICES */ class DUP_PRO_Web_Services extends AbstractAjaxService { /** * Init ajax hooks * * @return void */ public function init() { $importServices = new ServicesImport(); $importServices->init(); $recoveryService = new ServicesRecovery(); $recoveryService->init(); $scheduleService = new ServicesSchedule(); $scheduleService->init(); $storageService = new ServicesStorage(); $storageService->init(); $dashboardService = new ServicesDashboard(); $dashboardService->init(); $settingsService = new ServicesSettings(); $settingsService->init(); $notificationsService = new ServicesNotifications(); $notificationsService->init(); $this->addAjaxCall('wp_ajax_duplicator_pro_package_scan', 'duplicator_pro_package_scan'); $this->addAjaxCall('wp_ajax_duplicator_pro_package_delete', 'duplicator_pro_package_delete'); $this->addAjaxCall('wp_ajax_duplicator_pro_reset_packages', 'duplicator_pro_reset_packages'); $this->addAjaxCall('wp_ajax_duplicator_pro_get_trace_log', 'get_trace_log'); $this->addAjaxCall('wp_ajax_duplicator_pro_delete_trace_log', 'delete_trace_log'); $this->addAjaxCall('wp_ajax_duplicator_pro_get_package_statii', 'get_package_statii'); $this->addAjaxCall('wp_ajax_duplicator_pro_get_package_status', 'duplicator_pro_get_package_status'); $this->addAjaxCall('wp_ajax_duplicator_pro_get_package_log', 'get_package_log'); $this->addAjaxCall('wp_ajax_duplicator_pro_get_package_delete', 'duplicator_pro_get_package_delete'); $this->addAjaxCall('wp_ajax_duplicator_pro_is_pack_running', 'is_pack_running'); $this->addAjaxCall('wp_ajax_duplicator_pro_process_worker', 'process_worker'); $this->addAjaxCall('wp_ajax_nopriv_duplicator_pro_process_worker', 'process_worker'); $this->addAjaxCall('wp_ajax_duplicator_pro_manual_transfer_storage', 'manual_transfer_storage'); /* Screen-Specific Web Methods */ $this->addAjaxCall('wp_ajax_duplicator_pro_packages_details_transfer_get_package_vm', 'packages_details_transfer_get_package_vm'); /* Granular Web Methods */ $this->addAjaxCall('wp_ajax_duplicator_pro_package_stop_build', 'package_stop_build'); $this->addAjaxCall('wp_ajax_duplicator_pro_export_settings', 'export_settings'); $this->addAjaxCall('wp_ajax_duplicator_pro_brand_delete', 'duplicator_pro_brand_delete'); /* Quick Fix */ $this->addAjaxCall('wp_ajax_duplicator_pro_quick_fix', 'duplicator_pro_quick_fix'); /* Dir scan utils */ $this->addAjaxCall('wp_ajax_duplicator_pro_get_folder_children', 'duplicator_pro_get_folder_children'); $this->addAjaxCall('wp_ajax_duplicator_pro_restore_backup_prepare', 'duplicator_pro_restore_backup_prepare'); $this->addAjaxCall('wp_ajax_duplicator_pro_admin_notice_to_dismiss', 'admin_notice_to_dismiss'); $this->addAjaxCall('wp_ajax_duplicator_pro_download_package_file', 'download_package_file'); $this->addAjaxCall('wp_ajax_nopriv_duplicator_pro_download_package_file', 'download_package_file'); } /** * Restore backup prepare callback * * @return string */ public function duplicator_pro_restore_backup_prepare_callback() { $packageId = filter_input(INPUT_POST, 'packageId', FILTER_VALIDATE_INT); if (!$packageId) { throw new Exception('Invalid package ID in request.'); } $result = array(); if (($package = DUP_PRO_Package::get_by_id($packageId)) === false) { throw new Exception(esc_html__('Invalid package ID', 'duplicator-pro')); } $updDirs = wp_upload_dir(); $result = DUPLICATOR_PRO_SSDIR_URL . '/' . $package->Installer->getInstallerName() . '?dup_folder=dupinst_' . $package->Hash; $installerParams = array( 'inst_mode' => array('value' => 2 ), // mode restore backup 'url_old' => array('formStatus' => "st_skip"), 'url_new' => array( 'value' => DUP_PRO_Archive::getOriginalUrls('home'), 'formStatus' => "st_infoonly", ), 'path_old' => array('formStatus' => "st_skip"), 'path_new' => array( 'value' => duplicator_pro_get_home_path(), 'formStatus' => "st_infoonly", ), 'dbaction' => array( 'value' => 'empty', 'formStatus' => "st_infoonly", ), 'dbhost' => array( 'value' => DB_HOST, 'formStatus' => "st_infoonly", ), 'dbname' => array( 'value' => DB_NAME, 'formStatus' => "st_infoonly", ), 'dbuser' => array( 'value' => DB_USER, 'formStatus' => "st_infoonly", ), 'dbpass' => array( 'value' => DB_PASSWORD, 'formStatus' => "st_infoonly", ), 'dbtest_ok' => array('value' => true), 'siteurl_old' => array('formStatus' => "st_skip"), 'siteurl' => array( 'value' => 'site_url', 'formStatus' => "st_skip", ), 'path_cont_old' => array('formStatus' => "st_skip"), 'path_cont_new' => array( 'value' => WP_CONTENT_DIR, 'formStatus' => "st_skip", ), 'path_upl_old' => array('formStatus' => "st_skip"), 'path_upl_new' => array( 'value' => $updDirs['basedir'], 'formStatus' => "st_skip", ), 'url_cont_old' => array('formStatus' => "st_skip"), 'url_cont_new' => array( 'value' => content_url(), 'formStatus' => "st_skip", ), 'url_upl_old' => array('formStatus' => "st_skip"), 'url_upl_new' => array( 'value' => $updDirs['baseurl'], 'formStatus' => "st_skip", ), 'exe_safe_mode' => array('formStatus' => "st_skip"), 'remove-redundant' => array('formStatus' => "st_skip"), 'blogname' => array('formStatus' => "st_infoonly"), 'replace_mode' => array('formStatus' => "st_skip"), 'empty_schedule_storage' => array( 'value' => false, 'formStatus' => "st_skip", ), 'wp_config' => array( 'value' => 'original', 'formStatus' => "st_infoonly", ), 'ht_config' => array( 'value' => 'original', 'formStatus' => "st_infoonly", ), 'other_config' => array( 'value' => 'original', 'formStatus' => "st_infoonly", ), 'zip_filetime' => array( 'value' => 'original', 'formStatus' => "st_infoonly", ), 'mode_chunking' => array( 'value' => 3, 'formStatus' => "st_infoonly", ), ); $localParamsFile = DUPLICATOR_PRO_SSDIR_PATH . '/' . DUPLICATOR_PRO_LOCAL_OVERWRITE_PARAMS . '_' . $package->get_package_hash() . '.json'; file_put_contents($localParamsFile, SnapJson::jsonEncodePPrint($installerParams)); return $result; } /** * Hook ajax restore backup prepare * * @return void */ public function duplicator_pro_restore_backup_prepare() { AjaxWrapper::json( array( __CLASS__, 'duplicator_pro_restore_backup_prepare_callback', ), 'duplicator_pro_restore_backup_prepare', $_POST['nonce'], CapMng::CAP_BACKUP_RESTORE ); } /** * Hook ajax process worker * * @return never */ public function process_worker() { DUP_PRO_Handler::init_error_handler(); DUP_PRO_U::checkAjax(); header("HTTP/1.1 200 OK"); /* $nonce = sanitize_text_field($_REQUEST['nonce']); if (!wp_verify_nonce($nonce, 'duplicator_pro_process_worker')) { DUP_PRO_Log::trace('Security issue'); die('Security issue'); } */ DUP_PRO_Log::trace("Process worker request"); DUP_PRO_Package_Runner::process(); DUP_PRO_Log::trace("Exiting process worker request"); echo 'ok'; exit(); } /** * Hook ajax manual transfer storage * * @return never */ public function manual_transfer_storage() { DUP_PRO_Handler::init_error_handler(); check_ajax_referer('duplicator_pro_manual_transfer_storage', 'nonce'); $json = array( 'success' => false, 'message' => '', ); $isValid = true; $inputData = filter_input_array(INPUT_POST, array( 'package_id' => array( 'filter' => FILTER_VALIDATE_INT, 'flags' => FILTER_REQUIRE_SCALAR, 'options' => array('default' => false), ), 'storage_ids' => array( 'filter' => FILTER_VALIDATE_INT, 'flags' => FILTER_REQUIRE_ARRAY, 'options' => array('default' => false), ), )); $package_id = $inputData['package_id']; $storage_ids = $inputData['storage_ids']; $json['data'] = $inputData; if (!$package_id || !$storage_ids) { $isValid = false; } try { if (!CapMng::can(CapMng::CAP_STORAGE, false) && !CapMng::can(CapMng::CAP_CREATE, false)) { throw new Exception('Security issue.'); } if (!$isValid) { throw new Exception(__("Invalid request.", 'duplicator-pro')); } if (DUP_PRO_Package::isPackageRunning()) { $msg = sprintf(__('Trying to queue a transfer for package %d but a package is already active!', 'duplicator-pro'), $package_id); throw new Exception($msg); } $package = DUP_PRO_Package::get_by_id($package_id); DUP_PRO_Log::open($package->NameHash); if (!$package) { throw new Exception(sprintf(esc_html__('Could not find package ID %d!', 'duplicator-pro'), $package_id)); } if (empty($storage_ids)) { throw new Exception("Please select a storage."); } $info = "\n"; $info .= "********************************************************************************\n"; $info .= "********************************************************************************\n"; $info .= "PACKAGE MANUAL TRANSFER REQUESTED: " . @date("Y-m-d H:i:s") . "\n"; $info .= "********************************************************************************\n"; $info .= "********************************************************************************\n\n"; DUP_PRO_Log::infoTrace($info); foreach ($storage_ids as $storage_id) { if (($storage = AbstractStorageEntity::getById($storage_id)) === false) { throw new Exception(sprintf(__('Could not find storage ID %d!', 'duplicator-pro'), $storage_id)); } DUP_PRO_Log::infoTrace( 'Storage adding to the package "' . $package->Name . ' [Package Id: ' . $package_id . ']":: Storage Id: "' . $storage_id . '" Storage Name: "' . esc_html($storage->getName()) . '" Storage Type: "' . esc_html($storage->getStypeName()) . '"' ); $upload_info = new DUP_PRO_Package_Upload_Info($storage_id); array_push($package->upload_infos, $upload_info); } $package->set_status(DUP_PRO_PackageStatus::STORAGE_PROCESSING); $package->timer_start = DUP_PRO_U::getMicrotime(); $json['success'] = true; $package->update(); } catch (Exception $ex) { $json['message'] = $ex->getMessage(); DUP_PRO_Log::trace($ex->getMessage()); } DUP_PRO_Log::close(); die(SnapJson::jsonEncode($json)); } /** * DUPLICATOR_PRO_PACKAGE_SCAN * * @example to test: /wp-admin/admin-ajax.php?action=duplicator_pro_package_scan * * @return never */ public function duplicator_pro_package_scan() { DUP_PRO_Handler::init_error_handler(); try { CapMng::can(CapMng::CAP_CREATE); $global = DUP_PRO_Global_Entity::getInstance(); // Should be used $_REQUEST sometimes it gets in _GET and sometimes in _POST check_ajax_referer('duplicator_pro_package_scan', 'nonce'); header('Content-Type: application/json'); @ob_flush(); $json = array(); $errLevel = error_reporting(); // Keep the locking file opening and closing just to avoid adding even more complexity $locking_file = true; if ($global->lock_mode == DUP_PRO_Thread_Lock_Mode::Flock) { $locking_file = fopen(DUPLICATOR_PRO_LOCKING_FILE_FILENAME, 'c+'); } if ($locking_file != false) { if ($global->lock_mode == DUP_PRO_Thread_Lock_Mode::Flock) { $acquired_lock = (flock($locking_file, LOCK_EX | LOCK_NB) != false); if ($acquired_lock) { DUP_PRO_Log::trace("File lock acquired " . DUPLICATOR_PRO_LOCKING_FILE_FILENAME); } else { DUP_PRO_Log::trace("File lock denied " . DUPLICATOR_PRO_LOCKING_FILE_FILENAME); } } else { $acquired_lock = DUP_PRO_U::getSqlLock(); } if ($acquired_lock) { @set_time_limit(0); error_reporting(E_ERROR); StoragesUtil::getDefaultStorage()->initStorageDirectory(true); $package = DUP_PRO_Package::get_temporary_package(); $package->ID = null; $report = $package->create_scan_report(); //After scanner runs save FilterInfo (unreadable, warnings, globals etc) $package->set_temporary_package(); //delif($package->Archive->ScanStatus == DUP_PRO_Archive::ScanStatusComplete){ $report['Status'] = DUP_PRO_Web_Service_Execution_Status::Pass; // The package has now been corrupted with directories and scans so cant reuse it after this point DUP_PRO_Package::set_temporary_package_member('ScanFile', $package->ScanFile); DUP_PRO_Package::tmp_cleanup(); DUP_PRO_Package::set_temporary_package_member('Status', DUP_PRO_PackageStatus::AFTER_SCAN); //del} if ($global->lock_mode == DUP_PRO_Thread_Lock_Mode::Flock) { if (!flock($locking_file, LOCK_UN)) { DUP_PRO_Log::trace("File lock can't release " . $locking_file); } else { DUP_PRO_Log::trace("File lock released " . $locking_file); } fclose($locking_file); } else { DUP_PRO_U::releaseSqlLock(); } } else { // File is already locked indicating schedule is running $report['Status'] = DUP_PRO_Web_Service_Execution_Status::ScheduleRunning; DUP_PRO_Log::trace("Already locked when attempting manual build - schedule running"); } } else { // Problem opening the locking file report this is a critical error $report['Status'] = DUP_PRO_Web_Service_Execution_Status::Fail; DUP_PRO_Log::trace("Problem opening locking file so auto switching to SQL lock mode"); $global->lock_mode = DUP_PRO_Thread_Lock_Mode::SQL_Lock; $global->save(); } } catch (Exception $ex) { $data = array( 'Status' => 3, 'Message' => sprintf(__("Exception occurred. Exception message: %s", 'duplicator-pro'), $ex->getMessage()), 'File' => $ex->getFile(), 'Line' => $ex->getLine(), 'Trace' => $ex->getTrace(), ); die(json_encode($data)); } catch (Error $ex) { $data = array( 'Status' => 3, 'Message' => sprintf( esc_html__("Fatal Error occurred. Error message: %1\$s<br>\nTrace: %2\$s", 'duplicator-pro'), $ex->getMessage(), $ex->getTraceAsString() ), 'File' => $ex->getFile(), 'Line' => $ex->getLine(), 'Trace' => $ex->getTrace(), ); die(json_encode($data)); } try { if (($json = JsonSerialize::serialize($report, JSON_PRETTY_PRINT | JsonSerialize::JSON_SKIP_CLASS_NAME)) === false) { throw new Exception('Problem encoding json'); } } catch (Exception $ex) { $data = array( 'Status' => 3, 'Message' => sprintf(esc_html__("Fatal Error occurred. Error message: %s", 'duplicator-pro'), $ex->getMessage()), 'File' => $ex->getFile(), 'Line' => $ex->getLine(), 'Trace' => $ex->getTrace(), ); die(json_encode($data)); } error_reporting($errLevel); die($json); } /** * Return scan error message * * @return string */ public static function getScanErrorMessage() { ob_start(); ?> <br><b><?php esc_html_e('Please Retry:', 'duplicator-pro'); ?></b><br/> <?php esc_html_e('Unable to perform a full scan and read JSON file, please try the following actions.', 'duplicator-pro'); ?><br/> <?php esc_html_e('1. Go back and create a root path directory filter to validate the site is scan-able.', 'duplicator-pro'); ?><br/> <?php esc_html_e('2. Continue to add/remove filters to isolate which path is causing issues.', 'duplicator-pro'); ?><br/> <?php esc_html_e('3. This message will go away once the correct filters are applied.', 'duplicator-pro'); ?><br/><br/> <b><?php esc_html_e('Common Issues:', 'duplicator-pro'); ?></b><br/> <?php esc_html_e( '- On some budget hosts scanning over 30k files can lead to timeout/gateway issues. Consider scanning only your main WordPress site and avoid trying to backup other external directories.', 'duplicator-pro' ); ?><br/> <?php esc_html_e( '- Symbolic link recursion can cause timeouts. Ask your server admin if any are present in the scan path. If they are add the full path as a filter and try running the scan again.', 'duplicator-pro' ); ?><br/><br/> <b><?php esc_html_e('Details:', 'duplicator-pro'); ?></b><br/> <?php esc_html_e('JSON Service:', 'duplicator-pro'); ?> /wp-admin/admin-ajax.php?action=duplicator_pro_package_scan<br/> <?php esc_html_e('Scan Path:', 'duplicator-pro'); ?> [<?php echo duplicator_pro_get_home_path(); ?>]<br/><br/> <b><?php esc_html_e('More Information:', 'duplicator-pro'); ?></b><br/> <?php printf( __( 'Please see the online FAQ titled %1$s"How to resolve scanner warnings/errors and timeout issues?"%2$s', 'duplicator-pro' ), '<a href="' . DUPLICATOR_PRO_DUPLICATOR_DOCS_URL . 'how-to-resolve-scanner-warnings-errors-and-timeout-issues" target="_blank">', '</a>' ); return (string) ob_get_clean(); } /** * DUPLICATOR_PRO_QUICK_FIX * Set default quick fix values automaticaly to help user * * @return never */ public function duplicator_pro_quick_fix() { DUP_PRO_Handler::init_error_handler(); check_ajax_referer('duplicator_pro_quick_fix', 'nonce'); $json = array( 'success' => false, 'message' => '', ); $isValid = true; $inputData = filter_input_array(INPUT_POST, array( 'id' => array( 'filter' => FILTER_SANITIZE_SPECIAL_CHARS, 'flags' => FILTER_REQUIRE_SCALAR, 'options' => array('default' => false), ), 'setup' => array( 'filter' => FILTER_SANITIZE_SPECIAL_CHARS, 'flags' => FILTER_REQUIRE_ARRAY, 'options' => array('default' => false), ), )); $setup = $inputData['setup']; $id = $inputData['id']; if (!$id || empty($setup)) { $isValid = false; } //END OF VALIDATION try { CapMng::can(CapMng::CAP_BASIC); if (!$isValid) { throw new Exception(__("Invalid request.", 'duplicator-pro')); } $data = array(); $isSpecial = isset($setup['special']) && is_array($setup['special']) && count($setup['special']) > 0; /* **************** * GENERAL SETUP * **************** */ if (isset($setup['global']) && is_array($setup['global'])) { $global = DUP_PRO_Global_Entity::getInstance(); foreach ($setup['global'] as $object => $value) { $value = DUP_PRO_U::valType($value); if (isset($global->$object)) { // Get current setup $current = $global->$object; // If setup is not the same - fix this if ($current !== $value) { // Set new value $global->$object = $value; // Check value $data[$object] = $global->$object; } } } $global->save(); } /* **************** * SPECIAL SETUP * **************** */ if ($isSpecial) { $special = $setup['special']; $stuck5percent = isset($special['stuck_5percent_pending_fix']) && $special['stuck_5percent_pending_fix'] == 1; $basicAuth = isset($special['set_basic_auth']) && $special['set_basic_auth'] == 1; $removeInstallerFiles = isset($special['remove_installer_files']) && $special['remove_installer_files'] == 1; /** * SPECIAL FIX: Package build stuck at 5% or Pending? * */ if ($stuck5percent) { $data = array_merge($data, $this->special_quick_fix_stuck_5_percent()); } /** * SPECIAL FIX: Set basic auth username & password * */ if ($basicAuth) { $data = array_merge($data, $this->special_quick_fix_basic_auth()); } /** * SPECIAL FIX: Remove installer files * */ if ($removeInstallerFiles) { $data = array_merge($data, $this->special_quick_fix_remove_installer_files()); } } // Save new property $find = count($data); if ($find > 0) { $system_global = SystemGlobalEntity::getInstance(); if (strlen($id) > 0) { $system_global->removeFixById($id); $json['id'] = $id; } $json['success'] = true; $json['setup'] = $data; $json['fixed'] = $find; $json['recommended_fixes'] = count($system_global->recommended_fixes); } } catch (Exception $ex) { $json['message'] = $ex->getMessage(); DUP_PRO_Log::trace("Error while implementing quick fix: " . $ex->getMessage()); } die(SnapJson::jsonEncode($json)); } /** * Quick fix for removing installer files * * @return array{removed_installer_files:bool} $data */ private function special_quick_fix_remove_installer_files() { $data = array(); $fileRemoved = MigrationMng::cleanMigrationFiles(); $removeError = false; if (count($fileRemoved) > 0) { $data['removed_installer_files'] = true; } else { throw new Exception(esc_html__("Unable to remove installer files.", 'duplicator-pro')); } return $data; } /** * Quick fix for stuck at 5% or pending * * @return array<string, mixed> $data */ private function special_quick_fix_stuck_5_percent() { $global = DUP_PRO_Global_Entity::getInstance(); $data = array(); $kickoff = true; $custom = false; if ($global->ajax_protocol === 'custom') { $custom = true; } // Do things if SSL is active if (SnapURL::isCurrentUrlSSL()) { if ($custom) { // Set default admin ajax $custom_ajax_url = admin_url('admin-ajax.php', 'https'); if ($global->custom_ajax_url != $custom_ajax_url) { $global->custom_ajax_url = $custom_ajax_url; $data['custom_ajax_url'] = $global->custom_ajax_url; $kickoff = false; } } else { // Set HTTPS protocol if ($global->ajax_protocol === 'http') { $global->ajax_protocol = 'https'; $data['ajax_protocol'] = $global->ajax_protocol; $kickoff = false; } } } else { // SSL is OFF and we must handle that if ($custom) { // Set default admin ajax $custom_ajax_url = admin_url('admin-ajax.php', 'http'); if ($global->custom_ajax_url != $custom_ajax_url) { $global->custom_ajax_url = $custom_ajax_url; $data['custom_ajax_url'] = $global->custom_ajax_url; $kickoff = false; } } else { // Set HTTP protocol if ($global->ajax_protocol === 'https') { $global->ajax_protocol = 'http'; $data['ajax_protocol'] = $global->ajax_protocol; $kickoff = false; } } } // Set KickOff true if all setups are gone if ($kickoff) { if ($global->clientside_kickoff !== true) { $global->clientside_kickoff = true; $data['clientside_kickoff'] = $global->clientside_kickoff; } } $global->save(); return $data; } /** * Quick fix for basic auth * * @return array{basic_auth_enabled:bool,basic_auth_user:string,basic_auth_password:string} */ private function special_quick_fix_basic_auth() { $global = DUP_PRO_Global_Entity::getInstance(); $sglobal = DUP_PRO_Secure_Global_Entity::getInstance(); $username = isset($_SERVER['PHP_AUTH_USER']) ? $_SERVER['PHP_AUTH_USER'] : false; $password = isset($_SERVER['PHP_AUTH_PW']) ? $_SERVER['PHP_AUTH_PW'] : false; if ($username === false || $password === false) { throw new Exception(esc_html__("Username or password were not set.", 'duplicator-pro')); } $data = array(); $global->basic_auth_enabled = true; $data['basic_auth_enabled'] = true; $global->basic_auth_user = $username; $data['basic_auth_user'] = $username; $sglobal->basic_auth_password = $password; $data['basic_auth_password'] = "**Secure Info**"; $global->save(); $sglobal->save(); return $data; } /** * Hook ajax wp_ajax_duplicator_pro_brand_delete * * @return never */ public function duplicator_pro_brand_delete() { DUP_PRO_Handler::init_error_handler(); check_ajax_referer('duplicator_pro_brand_delete', 'nonce'); $json = array( 'success' => false, 'message' => '', ); $isValid = true; $inputData = filter_input_array(INPUT_POST, array( 'brand_ids' => array( 'filter' => FILTER_VALIDATE_INT, 'flags' => FILTER_REQUIRE_ARRAY, 'options' => array('default' => false), ), )); $brandIDs = $inputData['brand_ids']; $delCount = 0; if (empty($brandIDs) || in_array(false, $brandIDs)) { $isValid = false; } try { CapMng::can(CapMng::CAP_CREATE); if (!$isValid) { throw new Exception(__('Invalid Request.', 'duplicator-pro')); } foreach ($brandIDs as $id) { $brand = BrandEntity::deleteById($id); if ($brand) { $delCount++; } } $json['success'] = true; $json['ids'] = $brandIDs; $json['removed'] = $delCount; } catch (Exception $e) { $json['message'] = $e->getMessage(); } die(SnapJson::jsonEncode($json)); } /** * Hook ajax wp_ajax_duplicator_pro_package_delete * Deletes the files and database record entries * * @return never */ public function duplicator_pro_package_delete() { DUP_PRO_Handler::init_error_handler(); check_ajax_referer('duplicator_pro_package_delete', 'nonce'); $json = array( 'error' => '', 'ids' => '', 'removed' => 0, ); $isValid = true; $deletedCount = 0; $inputData = filter_input_array(INPUT_POST, array( 'package_ids' => array( 'filter' => FILTER_VALIDATE_INT, 'flags' => FILTER_REQUIRE_ARRAY, 'options' => array('default' => false), ), )); $packageIDList = $inputData['package_ids']; if (empty($packageIDList) || in_array(false, $packageIDList)) { $isValid = false; } //END OF VALIDATION try { CapMng::can(CapMng::CAP_CREATE); if (!$isValid) { throw new Exception(__("Invalid request.", 'duplicator-pro')); } DUP_PRO_Log::traceObject("Starting deletion of packages by ids: ", $packageIDList); foreach ($packageIDList as $id) { if ($package = DUP_PRO_Package::get_by_id($id)) { if ($package->delete()) { $deletedCount++; } } else { $json['error'] = "Invalid package ID."; break; } } } catch (Exception $ex) { $json['error'] = $ex->getMessage(); } $json['ids'] = $packageIDList; $json['removed'] = $deletedCount; die(SnapJson::jsonEncode($json)); } /** * Hook ajax wp_ajax_duplicator_pro_reset_packages * * @return never */ public function duplicator_pro_reset_packages() { ob_start(); try { DUP_PRO_Handler::init_error_handler(); $error = false; $result = array( 'data' => array('status' => null), 'html' => '', 'message' => '', ); $nonce = sanitize_text_field($_POST['nonce']); if (!wp_verify_nonce($nonce, 'duplicator_pro_reset_packages')) { DUP_PRO_Log::trace('Security issue'); throw new Exception('Security issue'); } CapMng::can(CapMng::CAP_SETTINGS); // first last package id $ids = DUP_PRO_Package::get_ids_by_status( array(array('op' => '<', 'status' => DUP_PRO_PackageStatus::COMPLETE)), 0, 0, '`id` DESC' ); foreach ($ids as $id) { // A smooth deletion is not performed because it is a forced reset. DUP_PRO_Package::force_delete($id); } } catch (Exception $e) { $error = true; $result['message'] = $e->getMessage(); } $result['html'] = ob_get_clean(); if ($error) { wp_send_json_error($result); } else { wp_send_json_success($result); } } /** * Hook ajax wp_ajax_duplicator_pro_get_trace_log * * @return never */ public function get_trace_log() { /** * don't init DUP_PRO_Handler::init_error_handler() in get trace */ check_ajax_referer('duplicator_pro_get_trace_log', 'nonce'); DUP_PRO_Log::trace("enter"); $file_path = DUP_PRO_Log::getTraceFilepath(); $backup_path = DUP_PRO_Log::getBackupTraceFilepath(); $zip_path = DUPLICATOR_PRO_SSDIR_PATH . "/" . DUP_PRO_Constants::ZIPPED_LOG_FILENAME; try { CapMng::can(CapMng::CAP_CREATE); if (file_exists($zip_path)) { SnapIO::unlink($zip_path); } $zipArchive = new ZipArchiveExtended($zip_path); if ($zipArchive->open() == false) { throw new Exception('Can\'t open ZIP archive'); } if ($zipArchive->addFile($file_path, basename($file_path)) == false) { throw new Exception('Can\'t add ZIP file '); } if (file_exists($backup_path) && $zipArchive->addFile($backup_path, basename($backup_path)) == false) { throw new Exception('Can\'t add ZIP file '); } $zipArchive->close(); if (($fp = fopen($zip_path, 'rb')) === false) { throw new Exception('Can\'t open ZIP archive'); } $zip_filename = basename($zip_path); header("Pragma: public"); header("Expires: 0"); header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); header("Cache-Control: private", false); header("Content-Transfer-Encoding: binary"); header("Content-Type: application/octet-stream"); header("Content-Disposition: attachment; filename=\"$zip_filename\";"); // required or large files wont work if (ob_get_length()) { ob_end_clean(); } DUP_PRO_Log::trace("streaming $zip_path"); fpassthru($fp); fclose($fp); @unlink($zip_path); } catch (Exception $e) { header("Content-Type: text/plain"); header("Content-Disposition: attachment; filename=\"error.txt\";"); $message = 'Create Log Zip error message: ' . $e->getMessage(); DUP_PRO_Log::trace($message); echo esc_html($message); } die(); } /** * Hook ajax wp_ajax_duplicator_pro_delete_trace_log * * @return never */ public function delete_trace_log() { /** * don't init DUP_PRO_Handler::init_error_handler() in get trace */ check_ajax_referer('duplicator_pro_delete_trace_log', 'nonce'); CapMng::can(CapMng::CAP_CREATE); $res = DUP_PRO_Log::deleteTraceLog(); if ($res) { wp_send_json_success(); } else { wp_send_json_error(); } } /** * Hook ajax wp_ajax_duplicator_pro_export_settings * * @return never */ public function export_settings() { DUP_PRO_Handler::init_error_handler(); check_ajax_referer('duplicator_pro_import_export_settings', 'nonce'); try { DUP_PRO_Log::trace("Export settings start"); CapMng::can(CapMng::CAP_SETTINGS); $message = ''; if (($filePath = MigrateSettings::export($message)) === false) { throw new Exception($message); } DUP_PRO_U::getDownloadAttachment($filePath, 'application/octet-stream'); } catch (Exception $ex) { // RSR TODO: set the error message to this $this->message = 'Error processing with export:' . $e->getMessage(); header("Content-Type: text/plain"); header("Content-Disposition: attachment; filename=\"error.txt\";"); $message = $ex->getMessage(); DUP_PRO_Log::trace($message); echo esc_html($message); } die(); } /** * Hook ajax wp_ajax_duplicator_pro_package_stop_build * * @return never */ public function package_stop_build() { DUP_PRO_Handler::init_error_handler(); check_ajax_referer('duplicator_pro_package_stop_build', 'nonce'); CapMng::can(CapMng::CAP_CREATE); $json = array( 'success' => false, 'message' => '', ); $isValid = true; $inputData = filter_input_array(INPUT_POST, array( 'package_id' => array( 'filter' => FILTER_VALIDATE_INT, 'flags' => FILTER_REQUIRE_SCALAR, 'options' => array('default' => false), ), )); $package_id = $inputData['package_id']; if (!$package_id) { $isValid = false; } try { if (!$isValid) { throw new Exception('Invalid request.'); } DUP_PRO_Log::trace("Web service stop build of $package_id"); $package = DUP_PRO_Package::get_by_id($package_id); if ($package == null) { DUP_PRO_Log::trace("could not find package so attempting hard delete. Old files may end up sticking around although chances are there isnt much if we couldnt nicely cancel it."); $result = DUP_PRO_Package::force_delete($package_id); if ($result) { $json['message'] = 'Hard delete success'; $json['success'] = true; } else { throw new Exception('Hard delete failure'); } } else { DUP_PRO_Log::trace("set $package->ID for cancel"); $package->set_for_cancel(); $json['success'] = true; } } catch (Exception $ex) { DUP_PRO_Log::trace($ex->getMessage()); $json['message'] = $ex->getMessage(); } die(SnapJson::jsonEncode($json)); } /** * Hook ajax handler for packages_details_transfer_get_package_vm * Retrieve view model for the Packages/Details/Transfer screen * active_package_id: true/false * percent_text: Percent through the current transfer * text: Text to display * transfer_logs: array of transfer request vms (start, stop, status, message) * * @return never */ public function packages_details_transfer_get_package_vm() { DUP_PRO_Handler::init_error_handler(); check_ajax_referer('duplicator_pro_packages_details_transfer_get_package_vm', 'nonce'); $json = array( 'success' => false, 'message' => '', ); $isValid = true; $inputData = filter_input_array(INPUT_POST, array( 'package_id' => array( 'filter' => FILTER_VALIDATE_INT, 'flags' => FILTER_REQUIRE_SCALAR, 'options' => array('default' => false), ), )); $package_id = $inputData['package_id']; if (!$package_id) { $isValid = false; } try { if (!CapMng::can(CapMng::CAP_STORAGE, false) && !CapMng::can(CapMng::CAP_CREATE, false)) { throw new Exception('Security issue.'); } if (!$isValid) { throw new Exception(__("Invalid request.", 'duplicator-pro')); } $package = DUP_PRO_Package::get_by_id($package_id); if (!$package) { $msg = sprintf(__('Could not get package by ID %s', 'duplicator-pro'), $package_id); throw new Exception($msg); } $vm = new stdClass(); /* -- First populate the transfer log information -- */ // If this is the package being requested include the transfer details $vm->transfer_logs = array(); $active_upload_info = null; $storages = AbstractStorageEntity::getAll(); foreach ($package->upload_infos as &$upload_info) { if ($upload_info->getStorageId() === StoragesUtil::getDefaultStorageId()) { continue; } $status = $upload_info->get_status(); $status_text = $upload_info->get_status_text(); $transfer_log = new stdClass(); if ($upload_info->get_started_timestamp() == null) { $transfer_log->started = __('N/A', 'duplicator-pro'); } else { $transfer_log->started = DUP_PRO_DATE::getLocalTimeFromGMTTicks($upload_info->get_started_timestamp()); } if ($upload_info->get_stopped_timestamp() == null) { $transfer_log->stopped = __('N/A', 'duplicator-pro'); } else { $transfer_log->stopped = DUP_PRO_DATE::getLocalTimeFromGMTTicks($upload_info->get_stopped_timestamp()); } $transfer_log->status_text = $status_text; $transfer_log->message = $upload_info->get_status_message(); $transfer_log->storage_type_text = __('Unknown', 'duplicator-pro'); foreach ($storages as $storage) { if ($storage->getId() == $upload_info->getStorageId()) { $transfer_log->storage_type_text = $storage->getStypeName(); // break; } } array_unshift($vm->transfer_logs, $transfer_log); if ($status == DUP_PRO_Upload_Status::Running) { if ($active_upload_info != null) { DUP_PRO_Log::trace("More than one upload info is running at the same time for package {$package->ID}"); } $active_upload_info = &$upload_info; } } /* -- Now populate the activa package information -- */ $active_package = DUP_PRO_Package::get_next_active_package(); if ($active_package == null) { // No active package $vm->active_package_id = -1; $vm->text = __('No package is building.', 'duplicator-pro'); } else { $vm->active_package_id = $active_package->ID; if ($active_package->ID == $package_id) { //$vm->is_transferring = (($package->Status >= DUP_PRO_PackageStatus::COPIEDPACKAGE) && ($package->Status < DUP_PRO_PackageStatus::COMPLETE)); if ($active_upload_info != null) { $vm->percent_text = "{$active_upload_info->progress}%"; $vm->text = $active_upload_info->get_status_message(); } else { // We see this condition at the beginning and end of the transfer so throw up a generic message $vm->percent_text = ""; $vm->text = __("Synchronizing with server...", 'duplicator-pro'); } } else { $vm->text = __("Another package is presently running.", 'duplicator-pro'); } if ($active_package->is_cancel_pending()) { // If it's getting cancelled override the normal text $vm->text = __("Cancellation pending...", 'duplicator-pro'); } } $json['success'] = true; $json['vm'] = $vm; } catch (Exception $ex) { $json['message'] = $ex->getMessage(); DUP_PRO_Log::trace($ex->getMessage()); } die(SnapJson::jsonEncode($json)); } /** * Get the package status * * @param DUP_PRO_Package $package The package to get the status for * * @return int|float */ private static function get_adjusted_package_status(DUP_PRO_Package $package) { $estimated_progress = ($package->build_progress->current_build_mode == DUP_PRO_Archive_Build_Mode::Shell_Exec) || ($package->ziparchive_mode == DUP_PRO_ZipArchive_Mode::SingleThread); if (($package->Status == DUP_PRO_PackageStatus::ARCSTART) && $estimated_progress) { // Amount of time passing before we give them a 1% $time_per_percent = 11; $thread_age = time() - $package->build_progress->thread_start_time; $total_percentage_delta = DUP_PRO_PackageStatus::ARCDONE - DUP_PRO_PackageStatus::ARCSTART; if ($thread_age > ($total_percentage_delta * $time_per_percent)) { // It's maxed out so just give them the done condition for the rest of the time return DUP_PRO_PackageStatus::ARCDONE; } else { $percentage_delta = (int) ($thread_age / $time_per_percent); return DUP_PRO_PackageStatus::ARCSTART + $percentage_delta; } } else { return $package->Status; } } /** * Hook ajax wp_ajax_duplicator_pro_is_pack_running * * @return never */ public function is_pack_running() { DUP_PRO_Handler::init_error_handler(); check_ajax_referer('duplicator_pro_is_pack_running', 'nonce'); ob_start(); try { CapMng::can(CapMng::CAP_BASIC); $error = false; $result = array( 'running' => false, 'data' => array( 'run_ids' => array(), 'cancel_ids' => array(), 'error_ids' => array(), 'complete_ids' => array(), ), 'html' => '', 'message' => '', ); $nonce = sanitize_text_field($_POST['nonce']); if (!wp_verify_nonce($nonce, 'duplicator_pro_is_pack_running')) { DUP_PRO_Log::trace('Security issue'); throw new Exception('Security issue'); } $tmpPackages = DUP_PRO_Package::get_row_by_status(array( array( 'op' => '>=', 'status' => DUP_PRO_PackageStatus::COMPLETE, ), )); foreach ($tmpPackages as $cPack) { $result['data']['complete_ids'][] = $cPack->id; } $tmpPackages = DUP_PRO_Package::get_row_by_status(array( 'relation' => 'AND', array( 'op' => '>=', 'status' => DUP_PRO_PackageStatus::PRE_PROCESS, ), array( 'op' => '<', 'status' => DUP_PRO_PackageStatus::COMPLETE, ) )); foreach ($tmpPackages as $cPack) { $result['data']['run_ids'][] = $cPack->id; } $tmpPackages = DUP_PRO_Package::get_row_by_status(array( array( 'op' => '=', 'status' => DUP_PRO_PackageStatus::PENDING_CANCEL, ), )); foreach ($tmpPackages as $cPack) { $result['data']['run_ids'][] = $cPack->id; } $tmpPackages = DUP_PRO_Package::get_row_by_status(array( 'relation' => 'OR', array( 'op' => '=', 'status' => DUP_PRO_PackageStatus::BUILD_CANCELLED, ), array( 'op' => '=', 'status' => DUP_PRO_PackageStatus::STORAGE_CANCELLED, ) )); foreach ($tmpPackages as $cPack) { $result['data']['cac_ids'][] = $cPack->id; } $tmpPackages = DUP_PRO_Package::get_row_by_status(array( 'relation' => 'AND', array( 'op' => '<', 'status' => DUP_PRO_PackageStatus::PRE_PROCESS, ), array( 'op' => '!=', 'status' => DUP_PRO_PackageStatus::BUILD_CANCELLED, ), array( 'op' => '!=', 'status' => DUP_PRO_PackageStatus::STORAGE_CANCELLED, ), array( 'op' => '!=', 'status' => DUP_PRO_PackageStatus::PENDING_CANCEL, ) )); foreach ($tmpPackages as $cPack) { $result['data']['err_ids'][] = $cPack->id; } $result['running'] = count($result['data']['run_ids']) > 0; } catch (Exception $e) { $error = true; $result['message'] = $e->getMessage(); } $result['html'] = ob_get_clean(); if ($error) { wp_send_json_error($result); } else { wp_send_json_success($result); } } /** * Hook ajax wp_ajax_duplicator_pro_get_package_statii * * @return never */ public function get_package_statii() { DUP_PRO_Handler::init_error_handler(); check_ajax_referer('duplicator_pro_get_package_statii', 'nonce'); CapMng::can(CapMng::CAP_BASIC); $limit = SnapUtil::sanitizeIntInput(SnapUtil::INPUT_REQUEST, 'limit', 0); $offset = SnapUtil::sanitizeIntInput(SnapUtil::INPUT_REQUEST, 'offset', 0); $resultData = []; DUP_PRO_Package::by_status_callback( function (DUP_PRO_Package $package) use (&$resultData) { $package_status = new stdClass(); $package_status->ID = $package->ID; $package_status->status = self::get_adjusted_package_status($package); $package_status->status_progress = $package->get_status_progress(); $package_status->size = $package->get_display_size(); $package_status->status_progress_text = ''; if ($package_status->status < DUP_PRO_PackageStatus::COMPLETE) { $active_storage = $package->get_active_storage(); if ($active_storage !== false) { $package_status->status_progress_text = $active_storage->getActionText(); } else { $package_status->status_progress_text = ''; } } $resultData[] = $package_status; }, [], $limit, $offset, '`id` DESC' ); die(SnapJson::jsonEncode($resultData)); } /** * Hook ajax wp_ajax_duplicator_pro_get_folder_children * * @return never */ public function duplicator_pro_get_folder_children() { DUP_PRO_Handler::init_error_handler(); check_ajax_referer('duplicator_pro_get_folder_children', 'nonce'); $json = array(); $isValid = true; $inputData = filter_input_array(INPUT_GET, array( 'folder' => array( 'filter' => FILTER_SANITIZE_SPECIAL_CHARS, 'flags' => FILTER_REQUIRE_SCALAR, 'options' => array('default' => false), ), 'exclude' => array( 'filter' => FILTER_SANITIZE_SPECIAL_CHARS, 'flags' => FILTER_REQUIRE_ARRAY, 'options' => array( 'default' => array(), ), ), )); $folder = $inputData['folder']; $exclude = $inputData['exclude']; if ($folder === false) { $isValid = false; } ob_start(); try { CapMng::can(CapMng::CAP_BASIC); if (!$isValid) { throw new Exception(__('Invalid request.', 'duplicator-pro')); } if (is_dir($folder)) { try { $Package = DUP_PRO_Package::get_temporary_package(); } catch (Exception $e) { $Package = null; } $treeObj = new DUP_PRO_Tree_files($folder, true, $exclude); $treeObj->uasort(array('DUP_PRO_Archive', 'sortTreeByFolderWarningName')); if (!is_null($Package)) { $treeObj->treeTraverseCallback(array($Package->Archive, 'checkTreeNodesFolder')); } $jsTreeData = DUP_PRO_Archive::getJsTreeStructure($treeObj, '', false); $json = $jsTreeData['children']; } } catch (Exception $e) { DUP_PRO_Log::trace($e->getMessage()); $json['message'] = $e->getMessage(); } ob_clean(); wp_send_json($json); } /** * AJjax callback for admin_notice_to_dismiss * * @return boolean */ public static function admin_notice_to_dismiss_callback() { $noticeToDismiss = filter_input(INPUT_POST, 'notice', FILTER_SANITIZE_SPECIAL_CHARS); $systemGlobal = SystemGlobalEntity::getInstance(); switch ($noticeToDismiss) { case AdminNotices::OPTION_KEY_ACTIVATE_PLUGINS_AFTER_INSTALL: case AdminNotices::OPTION_KEY_MIGRATION_SUCCESS_NOTICE: $ret = delete_option($noticeToDismiss); break; case AdminNotices::OPTION_KEY_S3_CONTENTS_FETCH_FAIL_NOTICE: $ret = update_option(AdminNotices::OPTION_KEY_S3_CONTENTS_FETCH_FAIL_NOTICE, false); break; case AdminNotices::QUICK_FIX_NOTICE: $systemGlobal->clearFixes(); $ret = $systemGlobal->save(); break; case AdminNotices::FAILED_SCHEDULE_NOTICE: $systemGlobal->schedule_failed = false; $ret = $systemGlobal->save(); break; default: throw new Exception('Notice invalid'); } return $ret; } /** * Hook ajax wp_ajax_duplicator_pro_admin_notice_to_dismiss * * @return never */ public static function admin_notice_to_dismiss() { AjaxWrapper::json( array( __CLASS__, 'admin_notice_to_dismiss_callback', ), 'duplicator_pro_admin_notice_to_dismiss', $_POST['nonce'], CapMng::CAP_BASIC ); } /** * Hook ajax wp_ajax_duplicator_pro_download_package_file * * @return never */ public function download_package_file() { DUP_PRO_Handler::init_error_handler(); $inputData = filter_input_array(INPUT_GET, array( 'fileType' => array( 'filter' => FILTER_VALIDATE_INT, 'flags' => FILTER_REQUIRE_SCALAR, 'options' => array('default' => false), ), 'hash' => array( 'filter' => FILTER_SANITIZE_SPECIAL_CHARS, 'flags' => FILTER_REQUIRE_SCALAR, 'options' => array('default' => false), ), 'token' => array( 'filter' => FILTER_SANITIZE_SPECIAL_CHARS, 'flags' => FILTER_REQUIRE_SCALAR, 'options' => array('default' => false), ), )); try { if ( $inputData['token'] === false || $inputData['hash'] === false || $inputData["fileType"] === false || md5(\Duplicator\Utils\Crypt\CryptBlowfish::encrypt($inputData['hash'])) !== $inputData['token'] || ($package = DUP_PRO_Package::get_by_hash($inputData['hash'])) == false ) { throw new Exception(__("Invalid request.", 'duplicator-pro')); } switch ($inputData['fileType']) { case DUP_PRO_Package_File_Type::Installer: $filePath = $package->getLocalPackageFilePath(DUP_PRO_Package_File_Type::Installer); $fileName = $package->Installer->getDownloadName(); break; case DUP_PRO_Package_File_Type::Archive: $filePath = $package->getLocalPackageFilePath(DUP_PRO_Package_File_Type::Archive); $fileName = basename($filePath); break; case DUP_PRO_Package_File_Type::Log: $filePath = $package->getLocalPackageFilePath(DUP_PRO_Package_File_Type::Log); $fileName = basename($filePath); break; default: throw new Exception(__("File type not supported.", 'duplicator-pro')); } if ($filePath == false) { throw new Exception(__("File don\'t exists", 'duplicator-pro')); } \Duplicator\Libs\Snap\SnapIO::serveFileForDownload($filePath, $fileName, DUPLICATOR_PRO_BUFFER_DOWNLOAD_SIZE); } catch (Exception $ex) { wp_die($ex->getMessage()); } die(); } }