add_action( 'mainwp-child_clone_backupcreate', array( &$this, 'clone_backup_create' ) ); $this->add_action( 'mainwp-child_clone_backupcreatepoll', array( &$this, 'clone_backup_create_poll' ) ); $this->add_action( 'mainwp-child_clone_backupdownload', array( &$this, 'clone_backup_download' ) ); $this->add_action( 'mainwp-child_clone_backupdownloadpoll', array( &$this, 'clone_backup_download_poll' ) ); $this->add_action( 'mainwp-child_clone_backupextract', array( &$this, 'clone_backup_extract' ) ); } /** * Method add_security_nonce() * * Create security nonce for specific actions. * * @param string $action Contains the action that requires security nonce. */ public function add_security_nonce( $action ) { if ( ! is_array( $this->security_nonces ) ) { $this->security_nonces = array(); } if ( ! function_exists( 'wp_create_nonce' ) ) { include_once ABSPATH . WPINC . '/pluggable.php'; } $this->security_nonces[ $action ] = wp_create_nonce( $action ); } /** * Method get_security_nonces() * * Get security nonces from the security nonces array. * * @return array Security nonces. */ public function get_security_nonces() { return $this->security_nonces; } /** * Method add_action() * * Add actions to the 'wp_ajax_' hook and create security nonce. * * @param string $action Contains action to be added to the 'wp_ajax_' hook. * @param string $callback Contains a callback action. */ public function add_action( $action, $callback ) { add_action( 'wp_ajax_' . $action, $callback ); $this->add_security_nonce( $action ); } /** * Method secure_request() * * Build secure request for the clone process. * * @param string $action Contains the action that is being performed. * @param string $query_arg Contains the query argument. * * @return void * * @uses \MainWP\Child\MainWP_Helper::update_option() */ public function secure_request( $action = '', $query_arg = 'security' ) { if ( ! MainWP_Helper::is_admin() ) { die( 0 ); } if ( '' === $action ) { return; } if ( ! $this->check_security( $action, $query_arg ) ) { die( wp_json_encode( array( 'error' => esc_html__( 'Invalid request!', 'mainwp-child' ) ) ) ); } // phpcs:disable WordPress.Security.NonceVerification if ( isset( $_POST['dts'] ) ) { $ajaxPosts = get_option( 'mainwp_ajaxposts' ); if ( ! is_array( $ajaxPosts ) ) { $ajaxPosts = array(); } // If already processed, just quit! if ( isset( $ajaxPosts[ $action ] ) && ( $ajaxPosts[ $action ] === $_POST['dts'] ) ) { die( wp_json_encode( array( 'error' => esc_html__( 'Double request!', 'mainwp-child' ) ) ) ); } $ajaxPosts[ $action ] = isset( $_POST['dts'] ) ? sanitize_text_field( wp_unslash( $_POST['dts'] ) ) : ''; MainWP_Helper::update_option( 'mainwp_ajaxposts', $ajaxPosts ); } // phpcs:enable WordPress.Security.NonceVerification } /** * Method check_security() * * Check the clone request security. * * @param string $action Contains the action that is being performed. * @param string $query_arg Contains the query argument. * * @return bool true|false If secure, return true, if not, return false. */ public function check_security( $action = - 1, $query_arg = 'security' ) { if ( - 1 === (int) $action ) { return false; } $adminurl = strtolower( admin_url() ); $referer = strtolower( wp_get_referer() ); $result = isset( $_REQUEST[ $query_arg ] ) ? wp_verify_nonce( sanitize_text_field( wp_unslash( $_REQUEST[ $query_arg ] ) ), $action ) : false; if ( ! $result && ! ( - 1 === $action && 0 === strpos( $referer, $adminurl ) ) ) { return false; } return true; } /** * Method init() * * Initiate action hooks. * * @uses \MainWP\Child\MainWP_Clone_Page::get_class_name() */ public function init() { add_action( 'check_admin_referer', array( self::get_class_name(), 'permalink_changed' ) ); if ( get_option( 'mainwp_child_clone_permalink' ) || get_option( 'mainwp_child_restore_permalink' ) ) { add_action( 'admin_notices', array( MainWP_Clone_Page::get_class_name(), 'permalink_admin_notice' ) ); } } /** * Method upload_mimes() * * Add allowed mime types and file extensions. * * @param array $mime_types Mime types keyed by the file extension regex corresponding to those types. * * @return array Array containing allowed mime types. */ public static function upload_mimes( $mime_types = array() ) { if ( ! isset( $mime_types['tar.bz2'] ) ) { $mime_types['tar.bz2'] = 'application/x-tar'; } return $mime_types; } /** * Request clone. * * @return bool|void true|void. * * @uses \MainWP\Child\MainWP_Connect::is_valid_auth() * @uses \MainWP\Child\MainWP_Helper::get_mainwp_dir() * @uses \MainWP\Child\MainWP_Helper::write() */ public function request_clone_funct() { // phpcs:ignore -- Current complexity is the only way to achieve desired results, pull request solutions appreciated. // phpcs:disable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized if ( ! isset( $_REQUEST['key'] ) ) { return; } if ( ! isset( $_REQUEST['f'] ) || ( '' === $_REQUEST['f'] ) ) { return; } if ( ! isset( $_REQUEST['key'] ) || ! MainWP_Connect::instance()->is_valid_auth( wp_unslash( $_REQUEST['key'] ) ) ) { //phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized return; } $cloneFunc = isset( $_REQUEST['cloneFunc'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['cloneFunc'] ) ) : ''; if ( 'dl' === $cloneFunc ) { $f = isset( $_REQUEST['f'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['f'] ) ) : ''; if ( ! empty( $f ) ) { MainWP_Utility::instance()->upload_file_backup( sanitize_text_field( wp_unslash( $_REQUEST['f'] ) ) ); } exit; } elseif ( 'deleteCloneBackup' === $cloneFunc ) { $df = isset( $_POST['f'] ) ? sanitize_text_field( wp_unslash( $_POST['f'] ) ) : ''; if ( empty( $df ) || stristr( $df, '..' ) ) { return false; } $dirs = MainWP_Helper::get_mainwp_dir( 'backup' ); $backupdir = $dirs[0]; $result = glob( $backupdir . $df ); if ( 0 === count( $result ) ) { return; } wp_delete_file( $result[0] ); MainWP_Helper::write( array( 'result' => 'ok' ) ); } elseif ( 'createCloneBackupPoll' === $cloneFunc ) { $dirs = MainWP_Helper::get_mainwp_dir( 'backup' ); $backupdir = $dirs[0]; $f = isset( $_POST['f'] ) ? sanitize_text_field( wp_unslash( $_POST['f'] ) ) : ''; $archiveFile = false; if ( ! empty( $f ) ) { $result = glob( $backupdir . 'backup-' . $f . '-*' ); // NOSONAR . $found_files = array(); // to bad fix multi full backup files created with same rand value. foreach ( $result as $file ) { if ( self::is_archive( $file, 'backup-' . $f . '-' ) ) { $found_files[] = $file; } } if ( $found_files ) { $the_size = 0; $the_file = false; foreach ( $found_files as $_file ) { $file_size = filesize( $_file ); if ( $file_size > $the_size ) { $the_size = $file_size; $the_file = $_file; } } $archiveFile = $the_file; } } if ( false === $archiveFile ) { return; } $fsize = filesize( $archiveFile ); $check_info = ! empty( $_POST['cloneCheckInfo'] ) ? json_decode( wp_unslash( $_POST['cloneCheckInfo'] ), true ) : array(); if ( ! is_array( $check_info ) ) { $check_info = array(); } $poll_check = isset( $check_info['poll_check'] ) ? intval( $check_info['poll_check'] ) : 0; $size_check = isset( $check_info['size_check'] ) ? intval( $check_info['size_check'] ) : 0; if ( $poll_check > 5 && $size_check === $fsize ) { // smart check backup done. $backup_result = get_transient( 'clone-full-backup-' . wp_unslash( $_POST['f'] ) ); if ( ! empty( $backup_result ) && is_array( $backup_result ) ) { MainWP_Helper::write( array( 'size' => $fsize, 'backupFinishedResult' => array( 'url' => $backup_result['backup'], 'size' => round( $backup_result['size'] / 1024, 0 ), ), ) ); } } MainWP_Helper::write( array( 'size' => $fsize ) ); } elseif ( 'createCloneBackup' === $cloneFunc ) { $this->create_clone_backup(); } // phpcs:enable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized return true; } /** * Create backup of clone. * * @uses \MainWP\Child\MainWP_Backup::create_full_backup() * @uses \MainWP\Child\MainWP_Helper::end_session() * @uses \MainWP\Child\MainWP_Helper::is_dir_empty() * @uses \MainWP\Child\MainWP_Helper::get_mainwp_dir() * @uses \MainWP\Child\MainWP_Helper::write() */ private function create_clone_backup() { // phpcs:ignore -- Current complexity is the only way to achieve desired results, pull request solutions appreciated. MainWP_Helper::end_session(); $files = glob( WP_CONTENT_DIR . '/dbBackup*.sql.php' ); foreach ( $files as $file ) { wp_delete_file( $file ); } if ( file_exists( WP_CONTENT_DIR . '/dbBackup.sql' ) ) { wp_delete_file( WP_CONTENT_DIR . '/dbBackup.sql' ); } if ( file_exists( ABSPATH . 'clone/config.txt' ) ) { wp_delete_file( ABSPATH . 'clone/config.txt' ); } if ( MainWP_Helper::is_dir_empty( ABSPATH . 'clone' ) ) { MainWP_Helper::rmdir( ABSPATH . 'clone' ); } //phpcs:disable WordPress.Security.NonceVerification,WordPress.Security.NonceVerification.Missing,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized $wpversion = isset( $_POST['wpversion'] ) ? sanitize_text_field( wp_unslash( $_POST['wpversion'] ) ) : ''; $wp_ver = MainWP_Child_Server_Information_Base::get_wordpress_version(); $includeCoreFiles = ( $wpversion !== $wp_ver ); $excludes = ( isset( $_POST['exclude'] ) ? explode( ',', wp_unslash( $_POST['exclude'] ) ) : array() ); //phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized $excludes[] = str_replace( ABSPATH, '', WP_CONTENT_DIR ) . '/uploads/mainwp'; $uploadDir = MainWP_Helper::get_mainwp_dir(); $uploadDir = $uploadDir[0]; $excludes[] = str_replace( ABSPATH, '', $uploadDir ); $excludes[] = str_replace( ABSPATH, '', WP_CONTENT_DIR ) . '/object-cache.php'; if ( version_compare( phpversion(), '5.3.0' ) >= 0 || ! ini_get( 'safe_mode' ) ) { set_time_limit( 6000 ); } $newExcludes = array(); foreach ( $excludes as $exclude ) { $newExcludes[] = rtrim( $exclude, '/' ); } $method = ( ! isset( $_POST['zipmethod'] ) ? 'tar.gz' : sanitize_text_field( wp_unslash( $_POST['zipmethod'] ) ) ); if ( 'tar.gz' === $method && ! function_exists( 'gzopen' ) ) { $method = 'zip'; } $file = false; if ( isset( $_POST['f'] ) ) { $file = ! empty( $_POST['f'] ) ? sanitize_text_field( wp_unslash( $_POST['f'] ) ) : false; } elseif ( isset( $_POST['file'] ) ) { $file = ! empty( $_POST['file'] ) ? sanitize_text_field( wp_unslash( $_POST['file'] ) ) : false; } $res = MainWP_Backup::get()->create_full_backup( $newExcludes, $file, true, $includeCoreFiles, 0, false, false, false, false, $method ); if ( ! $res ) { $information['backup'] = false; } else { $information['backup'] = $res['file']; $information['size'] = $res['filesize']; } $plugins = array(); $dir = WP_CONTENT_DIR . '/plugins/'; $fh = opendir( $dir ); while ( $entry = readdir( $fh ) ) { if ( ! is_dir( $dir . $entry ) ) { continue; } if ( ( '.' === $entry ) || ( '..' === $entry ) ) { continue; } $plugins[] = $entry; } closedir( $fh ); $information['plugins'] = $plugins; $themes = array(); $dir = WP_CONTENT_DIR . '/themes/'; $fh = opendir( $dir ); while ( $entry = readdir( $fh ) ) { if ( ! is_dir( $dir . $entry ) ) { continue; } if ( ( '.' === $entry ) || ( '..' === $entry ) ) { continue; } $themes[] = $entry; } closedir( $fh ); $information['themes'] = $themes; update_option( '', $information ); set_transient( 'clone-full-backup-' . wp_unslash( $_POST['f'] ), $information, HOUR_IN_SECONDS ); // to support to fix issue timeout of create clone backup request. MainWP_Helper::write( $information ); //phpcs:enable WordPress.Security.NonceVerification,WordPress.Security.NonceVerification.Missing,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized } /** * Method clone_backup_create() * * Create backup of template site so it can be used to clone it. * * @throws \Exception Error message. * * @uses \MainWP\Child\MainWP_Helper::end_session() * @uses \MainWP\Child\MainWP_Helper::update_option() * @uses \MainWP\Child\MainWP_Utility::fetch_url() */ public function clone_backup_create() { // phpcs:disable WordPress.Security.NonceVerification try { $this->secure_request( 'mainwp-child_clone_backupcreate' ); if ( ! isset( $_POST['siteId'] ) ) { throw new \Exception( esc_html__( 'No site given', 'mainwp-child' ) ); } $siteId = isset( $_POST['siteId'] ) ? intval( wp_unslash( $_POST['siteId'] ) ) : false; $rand = isset( $_POST['rand'] ) ? sanitize_text_field( wp_unslash( $_POST['rand'] ) ) : ''; $sitesToClone = get_option( 'mainwp_child_clone_sites' ); if ( ! is_array( $sitesToClone ) || ! isset( $sitesToClone[ $siteId ] ) ) { throw new \Exception( esc_html__( 'Site not found', 'mainwp-child' ) ); } $siteToClone = $sitesToClone[ $siteId ]; $url = $siteToClone['url']; $key = $siteToClone['extauth']; $clone_admin = $siteToClone['connect_admin']; MainWP_Helper::end_session(); // Send request to the childsite! $timeout = 20 * 60 * 60; MainWP_Helper::set_limit( $timeout ); $method = ( function_exists( 'gzopen' ) ? 'tar.gz' : 'zip' ); $result = MainWP_Utility::fetch_url( $url, array( 'cloneFunc' => 'createCloneBackup', 'key' => $key, 'f' => $rand, 'wpversion' => MainWP_Child_Server_Information_Base::get_wordpress_version(), 'zipmethod' => $method, ) ); if ( ! $result['backup'] ) { throw new \Exception( esc_html__( 'Could not create backupfile on child', 'mainwp-child' ) ); } MainWP_Helper::update_option( 'mainwp_temp_clone_plugins', $result['plugins'] ); MainWP_Helper::update_option( 'mainwp_temp_clone_themes', $result['themes'] ); MainWP_Helper::update_option( 'mainwp_temp_clone_admin', $clone_admin ); $output = array( 'url' => $result['backup'], 'size' => round( $result['size'] / 1024, 0 ), ); } catch ( \Exception $e ) { $output = array( 'error' => $e->getMessage() ); } // phpcs:enable WordPress.Security.NonceVerification die( wp_json_encode( $output ) ); } /** * Method clone_backup_create_poll() * * Create backup poll of template site so it can be used to clone it. * * @throws \Exception Error message. * * @uses \MainWP\Child\MainWP_Helper::end_session() * @uses \MainWP\Child\MainWP_Utility::fetch_url() */ public function clone_backup_create_poll() { try { $this->secure_request( 'mainwp-child_clone_backupcreatepoll' ); // phpcs:disable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized if ( ! isset( $_POST['siteId'] ) ) { throw new \Exception( esc_html__( 'No site given', 'mainwp-child' ) ); } $siteId = isset( $_POST['siteId'] ) ? sanitize_text_field( wp_unslash( $_POST['siteId'] ) ) : ''; $rand = isset( $_POST['rand'] ) ? sanitize_text_field( wp_unslash( $_POST['rand'] ) ) : ''; $sitesToClone = get_option( 'mainwp_child_clone_sites' ); if ( ! is_array( $sitesToClone ) || ! isset( $sitesToClone[ $siteId ] ) ) { throw new \Exception( esc_html__( 'Site not found', 'mainwp-child' ) ); } $siteToClone = $sitesToClone[ $siteId ]; $url = $siteToClone['url']; $key = $siteToClone['extauth']; MainWP_Helper::end_session(); // Send request to the childsite! $result = MainWP_Utility::fetch_url( $url, array( 'cloneFunc' => 'createCloneBackupPoll', 'key' => $key, 'f' => $rand, 'cloneCheckInfo' => isset( $_POST['backupInfo'] ) && is_array( $_POST['backupInfo'] ) ? wp_json_encode( wp_unslash( $_POST['backupInfo'] ) ) : '', ) ); if ( ! isset( $result['size'] ) ) { throw new \Exception( esc_html__( 'Invalid response', 'mainwp-child' ) ); } $output = array( 'size' => round( $result['size'] / 1024, 0 ), 'size_byte' => $result['size'], ); if ( isset( $result['backupFinishedResult'] ) ) { $output['backupFinishedResult'] = $result['backupFinishedResult']; } // phpcs:enable WordPress.Security.NonceVerification,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized } catch ( \Exception $e ) { $output = array( 'error' => $e->getMessage() ); } die( wp_json_encode( $output ) ); } /** * Method clone_backup_download() * * Download backup file of template site so it can be used to clone it. * * @return mixed Response message. * @throws \Exception Error message. * * @uses \MainWP\Child\MainWP_Helper::end_session() * @uses \MainWP\Child\MainWP_Helper::get_mainwp_dir() * @uses \MainWP\Child\MainWP_Utility::fetch_url() */ public function clone_backup_download() { // phpcs:ignore -- Current complexity is the only way to achieve desired results, pull request solutions appreciated. try { $this->secure_request( 'mainwp-child_clone_backupdownload' ); // phpcs:disable WordPress.Security.NonceVerification if ( ! isset( $_POST['file'] ) ) { throw new \Exception( esc_html__( 'No download link given', 'mainwp-child' ) ); } $file = isset( $_POST['file'] ) ? sanitize_text_field( wp_unslash( $_POST['file'] ) ) : ''; if ( isset( $_POST['siteId'] ) ) { $siteId = isset( $_POST['siteId'] ) ? intval( wp_unslash( $_POST['siteId'] ) ) : false; $sitesToClone = get_option( 'mainwp_child_clone_sites' ); if ( ! is_array( $sitesToClone ) || ! isset( $sitesToClone[ $siteId ] ) ) { throw new \Exception( esc_html__( 'Site not found', 'mainwp-child' ) ); } $siteToClone = $sitesToClone[ $siteId ]; $url = $siteToClone['url']; $key = $siteToClone['extauth']; $url = trailingslashit( $url ) . '?cloneFunc=dl&key=' . rawurlencode( $key ) . '&f=' . $file; } else { $url = $file; } MainWP_Helper::end_session(); // Send request to the childsite! $split = explode( '=', $file ); $file = urldecode( $split[ count( $split ) - 1 ] ); $filename = 'download-' . basename( $file ); $dirs = MainWP_Helper::get_mainwp_dir( 'backup', false ); $backupdir = $dirs[0]; $dh = opendir( $backupdir ); if ( $dh ) { $fl = readdir( $dh ); while ( false !== $fl ) { if ( '.' !== $fl && '..' !== $fl && self::is_archive( $fl, 'download-' ) ) { wp_delete_file( $backupdir . $fl ); } $fl = readdir( $dh ); } closedir( $dh ); } $filename = $backupdir . $filename; $response = wp_remote_get( $url, array( 'timeout' => 300000, 'stream' => true, 'filename' => $filename, ) ); if ( is_wp_error( $response ) ) { wp_delete_file( $filename ); return $response; } if ( 200 !== (int) wp_remote_retrieve_response_code( $response ) ) { wp_delete_file( $filename ); return new \WP_Error( 'http_404', trim( wp_remote_retrieve_response_message( $response ) ) ); } $output = array( 'done' => $filename ); // Delete backup on child. try { if ( isset( $_POST['siteId'] ) ) { $siteId = isset( $_POST['siteId'] ) ? intval( wp_unslash( $_POST['siteId'] ) ) : false; $sitesToClone = get_option( 'mainwp_child_clone_sites' ); if ( is_array( $sitesToClone ) && isset( $sitesToClone[ $siteId ] ) ) { $siteToClone = $sitesToClone[ $siteId ]; MainWP_Utility::fetch_url( $siteToClone['url'], array( 'cloneFunc' => 'deleteCloneBackup', 'key' => $siteToClone['extauth'], 'f' => $file, ) ); } } } catch ( \Exception $e ) { throw $e; } } catch ( \Exception $e ) { $output = array( 'error' => $e->getMessage() ); } // phpcs:enable WordPress.Security.NonceVerification die( wp_json_encode( $output ) ); } /** * Method clone_backup_download_poll() * * Download backup file poll of template site so it can be used to clone it. * * @throws \Exception Error message. * * @uses \MainWP\Child\MainWP_Helper::end_session() * @uses \MainWP\Child\MainWP_Helper::get_mainwp_dir() */ public function clone_backup_download_poll() { try { $this->secure_request( 'mainwp-child_clone_backupdownloadpoll' ); MainWP_Helper::end_session(); $dirs = MainWP_Helper::get_mainwp_dir( 'backup', false ); $backupdir = $dirs[0]; $files = glob( $backupdir . 'download-*' ); $archiveFile = false; foreach ( $files as $file ) { if ( self::is_archive( $file, 'download-' ) ) { $archiveFile = $file; break; } } if ( false === $archiveFile ) { throw new \Exception( esc_html__( 'No download file found', 'mainwp-child' ) ); } $output = array( 'size' => filesize( $archiveFile ) / 1024 ); } catch ( \Exception $e ) { $output = array( 'error' => $e->getMessage() ); } die( wp_json_encode( $output ) ); } /** * Method clone_backup_extract() * * Extract the backup archive to clone the site. * * @uses \MainWP\Child\MainWP_Clone_Install() * @uses \MainWP\Child\MainWP_Helper::end_session() * @uses \MainWP\Child\MainWP_Helper::update_option() * @uses \MainWP\Child\MainWP_Helper::starts_with() */ public function clone_backup_extract() { try { $this->secure_request( 'mainwp-child_clone_backupextract' ); MainWP_Helper::end_session(); // phpcs:disable WordPress.Security.NonceVerification $file = false; if ( isset( $_POST['f'] ) ) { $file = ! empty( $_POST['f'] ) ? sanitize_text_field( wp_unslash( $_POST['f'] ) ) : false; } elseif ( isset( $_POST['file'] ) ) { $file = ! empty( $_POST['file'] ) ? sanitize_text_field( wp_unslash( $_POST['file'] ) ) : false; } // phpcs:enable WordPress.Security.NonceVerification $testFull = false; $file = $this->clone_backup_get_file( $file, $testFull ); $cloneInstall = new MainWP_Clone_Install( $file ); $cloneInstall->read_configuration_file(); $plugins = get_option( 'mainwp_temp_clone_plugins' ); $themes = get_option( 'mainwp_temp_clone_themes' ); if ( $testFull ) { $cloneInstall->test_download(); } $cloneInstall->remove_config_file(); $cloneInstall->extract_backup(); $cloneInstall->install( $file ); $cloneInstall->update_wp_config(); $cloneInstall->clean(); $output = $this->clone_backup_delete_files( $plugins, $themes ); } catch ( \Exception $e ) { $output = array( 'error' => $e->getMessage() ); } die( wp_json_encode( $output ) ); } /** * Method clone_backup_get_file() * * Get the backup file to download and clone. * * @param resource $file Backup file to be downloaded. * @param bool $testFull Return true if the file exists. * * @return resource Return the backup file. * @throws \Exception Error message. * * @uses \MainWP\Child\MainWP_Helper::get_mainwp_dir() */ private function clone_backup_get_file( $file, &$testFull ) { if ( empty( $file ) ) { $dirs = MainWP_Helper::get_mainwp_dir( 'backup', false ); $backupdir = $dirs[0]; $files = glob( $backupdir . 'download-*' ); $archiveFile = false; foreach ( $files as $file ) { if ( self::is_archive( $file, 'download-' ) ) { $archiveFile = $file; break; } } if ( false === $archiveFile ) { throw new \Exception( esc_html__( 'No download file found', 'mainwp-child' ) ); } $file = $archiveFile; } elseif ( file_exists( $file ) ) { $testFull = true; } else { $file = ABSPATH . $file; if ( ! file_exists( $file ) ) { throw new \Exception( esc_html__( 'Backup file not found', 'mainwp-child' ) ); } $testFull = true; } return $file; } /** * Method is_archive() * * Check if the file is archive file. * * @param string $file_name Contains the file name. * @param string $prefix Contains the prefix. * @param string $suffix Contains the sufix. * * @return bool true|false If the file is archive, return true, if not, return false. */ public static function is_archive( $file_name, $prefix = '', $suffix = '' ) { return preg_match( '/' . $prefix . '(.*).(zip|tar|tar.gz|tar.bz2)' . $suffix . '$/', $file_name ); // NOSONAR . } /** * Method clone_backup_delete_files() * * Delete unneeded files (plugins and themes). * * @param array $plugins Array containig plugins to be kept. * @param array $themes Array containig themes to be kept. * * @return array Array containing output feedback. * * @uses \MainWP\Child\MainWP_Helper::delete_dir() */ private function clone_backup_delete_files( $plugins, $themes ) { if ( false !== $plugins ) { $out = array(); if ( is_array( $plugins ) ) { $dir = WP_CONTENT_DIR . '/plugins/'; $fh = opendir( $dir ); while ( $entry = readdir( $fh ) ) { if ( ! is_dir( $dir . $entry ) ) { continue; } if ( ( '.' === $entry ) || ( '..' === $entry ) ) { continue; } if ( ! in_array( $entry, $plugins ) ) { MainWP_Helper::delete_dir( $dir . $entry ); } } closedir( $fh ); } delete_option( 'mainwp_temp_clone_plugins' ); } if ( false !== $themes ) { $out = array(); if ( is_array( $themes ) ) { $dir = WP_CONTENT_DIR . '/themes/'; $fh = opendir( $dir ); while ( $entry = readdir( $fh ) ) { if ( ! is_dir( $dir . $entry ) ) { continue; } if ( ( '.' === $entry ) || ( '..' === $entry ) ) { continue; } if ( ! in_array( $entry, $themes ) ) { MainWP_Helper::delete_dir( $dir . $entry ); } } closedir( $fh ); } delete_option( 'mainwp_temp_clone_themes' ); } $output = array( 'result' => 'ok' ); wp_logout(); wp_set_current_user( 0 ); return $output; } /** * Method permalink_changed() * * Check if the permalinks settings are re-saved. * * @param string $action Contains performed action. */ public static function permalink_changed( $action ) { if ( 'update-permalink' === $action ) { if ( isset( $_POST['permalink_structure'] ) || isset( $_POST['category_base'] ) || isset( $_POST['tag_base'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification delete_option( 'mainwp_child_clone_permalink' ); delete_option( 'mainwp_child_restore_permalink' ); } } } }