Created
May 14, 2020 15:42
-
-
Save cuongdcdev/fdbd09b33941c1b2e1e522fba64d0d22 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| use Base32\Base32; | |
| /** | |
| * Class for options | |
| */ | |
| final class BackWPup_Option { | |
| /** | |
| * | |
| * add filter for Site option defaults | |
| * | |
| */ | |
| public static function default_site_options() { | |
| //global | |
| add_site_option( 'backwpup_version', '0.0.0' ); | |
| //job default | |
| add_site_option( 'backwpup_jobs', array() ); | |
| //general | |
| add_site_option( 'backwpup_cfg_showadminbar', false ); | |
| add_site_option( 'backwpup_cfg_showfoldersize', false ); | |
| add_site_option( 'backwpup_cfg_protectfolders', true ); | |
| add_site_option('backwpup_cfg_phone_home_client', true); | |
| //job | |
| add_site_option( 'backwpup_cfg_jobmaxexecutiontime', 30 ); | |
| add_site_option( 'backwpup_cfg_jobstepretry', 3 ); | |
| add_site_option( 'backwpup_cfg_jobrunauthkey', BackWPup::get_generated_hash( 8 ) ); | |
| add_site_option( 'backwpup_cfg_loglevel', 'normal_translated' ); | |
| add_site_option( 'backwpup_cfg_jobwaittimems', 0 ); | |
| add_site_option( 'backwpup_cfg_jobdooutput', 0 ); | |
| add_site_option( 'backwpup_cfg_windows', 0 ); | |
| //Logs | |
| add_site_option( 'backwpup_cfg_maxlogs', 30 ); | |
| add_site_option( 'backwpup_cfg_gzlogs', 0 ); | |
| $upload_dir = wp_upload_dir( null, false, true ); | |
| $logs_dir = trailingslashit( str_replace( '\\', | |
| '/', | |
| $upload_dir['basedir'] ) ) . 'backwpup-' . BackWPup::get_plugin_data( 'hash' ) . '-logs/'; | |
| $content_path = trailingslashit( str_replace( '\\', '/', WP_CONTENT_DIR ) ); | |
| $logs_dir = str_replace( $content_path, '', $logs_dir ); | |
| add_site_option( 'backwpup_cfg_logfolder', $logs_dir ); | |
| //Network Auth | |
| add_site_option( 'backwpup_cfg_httpauthuser', '' ); | |
| add_site_option( 'backwpup_cfg_httpauthpassword', '' ); | |
| } | |
| /** | |
| * | |
| * Update a BackWPup option | |
| * | |
| * @param int $jobid the job id | |
| * @param string $option Option key | |
| * @param mixed $value the value to store | |
| * | |
| * @return bool if option save or not | |
| */ | |
| public static function update( $jobid, $option, $value ) { | |
| $jobid = (int) $jobid; | |
| $option = sanitize_key( trim( $option ) ); | |
| if ( empty( $jobid ) || empty( $option ) ) { | |
| return false; | |
| } | |
| //Update option | |
| $jobs_options = self::jobs_options( false ); | |
| $jobs_options[ $jobid ][ $option ] = $value; | |
| return self::update_jobs_options( $jobs_options ); | |
| } | |
| /** | |
| * | |
| * Load BackWPup Options | |
| * | |
| * @param bool $use_cache | |
| * | |
| * @return array of options | |
| */ | |
| private static function jobs_options( $use_cache = true ) { | |
| global $current_site; | |
| //remove from cache | |
| if ( ! $use_cache ) { | |
| if ( is_multisite() ) { | |
| $network_id = $current_site->id; | |
| $cache_key = "$network_id:backwpup_jobs"; | |
| wp_cache_delete( $cache_key, 'site-options' ); | |
| } else { | |
| wp_cache_delete( 'backwpup_jobs', 'options' ); | |
| $alloptions = wp_cache_get( 'alloptions', 'options' ); | |
| if ( isset( $alloptions['backwpup_jobs'] ) ) { | |
| unset( $alloptions['backwpup_jobs'] ); | |
| wp_cache_set( 'alloptions', $alloptions, 'options' ); | |
| } | |
| } | |
| } | |
| return get_site_option( 'backwpup_jobs', array() ); | |
| } | |
| /** | |
| * | |
| * Update BackWPup Options | |
| * | |
| * @param array $options The options array to save | |
| * | |
| * @return bool updated or not | |
| */ | |
| private static function update_jobs_options( $options ) { | |
| return update_site_option( 'backwpup_jobs', $options ); | |
| } | |
| /** | |
| * | |
| * Get a BackWPup Option | |
| * | |
| * @param int $jobid Option the job id | |
| * @param string $option Option key | |
| * @param mixed $default returned if no value, if null the the default BackWPup option will get | |
| * @param bool $use_cache USe the cache | |
| * | |
| * @return bool|mixed false if nothing can get else the option value | |
| */ | |
| public static function get( $jobid, $option, $default = null, $use_cache = true ) { | |
| $jobid = (int) $jobid; | |
| $option = sanitize_key( trim( $option ) ); | |
| if ( empty( $jobid ) || empty( $option ) ) { | |
| return false; | |
| } | |
| $jobs_options = self::jobs_options( $use_cache ); | |
| if ( isset( $jobs_options[ $jobid ] ) && isset( $jobs_options[ $jobid ]['archivename'] ) ) { | |
| $jobs_options[ $jobid ]['archivenamenohash'] = $jobs_options[ $jobid ]['archivename']; | |
| } | |
| if ( ! isset( $jobs_options[ $jobid ][ $option ] ) && $default !== null ) { | |
| return $default; | |
| } | |
| if ( ! isset( $jobs_options[ $jobid ][ $option ] ) ) { | |
| if ( $option === 'archivename' ) { | |
| return self::normalize_archive_name( self::defaults_job( $option ), $jobid ); | |
| } | |
| return self::defaults_job( $option ); | |
| } | |
| // Ensure archive name formatted properly | |
| if ( $option === 'archivename' ) { | |
| return self::normalize_archive_name( $jobs_options[ $jobid ][ $option ], $jobid, true ); | |
| } | |
| if ( $option === 'archivenamenohash' ) { | |
| return self::normalize_archive_name( $jobs_options[ $jobid ]['archivename'], $jobid, false ); | |
| } | |
| $option_value = $jobs_options[ $jobid ][ $option ]; | |
| switch ( $option ) { | |
| case 'archiveformat': | |
| if ( $option_value === '.tar.bz2' ) { | |
| $option_value = '.tar.gz'; | |
| } | |
| break; | |
| case 'pluginlistfilecompression': | |
| case 'wpexportfilecompression': | |
| if ( $option_value === '.bz2' ) { | |
| $option_value = '.gz'; | |
| } | |
| break; | |
| } | |
| return $option_value; | |
| } | |
| /** | |
| * | |
| * Get default option for BackWPup option | |
| * | |
| * @param string $key Option key | |
| * | |
| * @internal param int $id The job id | |
| * | |
| * @return bool|mixed | |
| */ | |
| public static function defaults_job( $key = '' ) { | |
| $key = sanitize_key( trim( $key ) ); | |
| //set defaults | |
| $default['type'] = array( 'DBDUMP', 'FILE', 'WPPLUGIN' ); | |
| $default['destinations'] = array(); | |
| $default['name'] = __( 'New Job', 'backwpup' ); | |
| $default['activetype'] = ''; | |
| $default['logfile'] = ''; | |
| $default['lastbackupdownloadurl'] = ''; | |
| $default['cronselect'] = 'basic'; | |
| $default['cron'] = '0 3 * * *'; | |
| $default['mailaddresslog'] = sanitize_email( get_bloginfo( 'admin_email' ) ); | |
| $default['mailaddresssenderlog'] = 'BackWPup ' . get_bloginfo( 'name' ) . ' <' . sanitize_email( get_bloginfo( 'admin_email' ) ) . '>'; | |
| $default['mailerroronly'] = true; | |
| $default['backuptype'] = 'archive'; | |
| $default['archiveformat'] = '.zip'; | |
| $default['archivename'] = '%Y-%m-%d_%H-%i-%s_%hash%'; | |
| $default['archivenamenohash'] = '%Y-%m-%d_%H-%i-%s_%hash%'; | |
| //defaults vor destinations | |
| foreach ( BackWPup::get_registered_destinations() as $dest_key => $dest ) { | |
| if ( ! empty( $dest['class'] ) ) { | |
| $dest_object = BackWPup::get_destination( $dest_key ); | |
| $default = array_merge( $default, $dest_object->option_defaults() ); | |
| } | |
| } | |
| //defaults vor job types | |
| foreach ( BackWPup::get_job_types() as $job_type ) { | |
| $default = array_merge( $default, $job_type->option_defaults() ); | |
| } | |
| //return all | |
| if ( empty( $key ) ) { | |
| return $default; | |
| } | |
| //return one default setting | |
| if ( isset( $default[ $key ] ) ) { | |
| return $default[ $key ]; | |
| } else { | |
| return false; | |
| } | |
| } | |
| /** | |
| * | |
| * BackWPup Job Options | |
| * | |
| * @param int $id The job id | |
| * @param bool $use_cache | |
| * | |
| * @return array of all job options | |
| */ | |
| public static function get_job( $id, $use_cache = true ) { | |
| if ( ! is_numeric( $id ) ) { | |
| return false; | |
| } | |
| $id = intval( $id ); | |
| $jobs_options = self::jobs_options( $use_cache ); | |
| if ( isset( $jobs_options[ $id ]['archivename'] ) ) { | |
| $jobs_options[ $id ]['archivename'] = self::normalize_archive_name( | |
| $jobs_options[ $id ]['archivename'], | |
| $id, | |
| true | |
| ); | |
| } | |
| $options = wp_parse_args( $jobs_options[ $id ], self::defaults_job() ); | |
| if ( isset( $options['archiveformat'] ) && $options['archiveformat'] === '.tar.bz2' ) { | |
| $options['archiveformat'] = '.tar.gz'; | |
| } | |
| if ( isset($options['pluginlistfilecompression'] ) && $options['pluginlistfilecompression'] === '.bz2' ) { | |
| $options['pluginlistfilecompression'] = '.gz'; | |
| } | |
| if ( isset($options['wpexportfilecompression'] ) && $options['wpexportfilecompression'] === '.bz2' ) { | |
| $options['wpexportfilecompression'] = '.gz'; | |
| } | |
| return $options; | |
| } | |
| /** | |
| * | |
| * Delete a BackWPup Option | |
| * | |
| * @param int $jobid the job id | |
| * @param string $option Option key | |
| * | |
| * @return bool deleted or not | |
| */ | |
| public static function delete( $jobid, $option ) { | |
| $jobid = (int) $jobid; | |
| $option = sanitize_key( trim( $option ) ); | |
| if ( empty( $jobid ) || empty( $option ) ) { | |
| return false; | |
| } | |
| //delete option | |
| $jobs_options = self::jobs_options( false ); | |
| unset( $jobs_options[ $jobid ][ $option ] ); | |
| return self::update_jobs_options( $jobs_options ); | |
| } | |
| /** | |
| * | |
| * Delete a BackWPup Job | |
| * | |
| * @param int $id The job id | |
| * | |
| * @return bool deleted or not | |
| */ | |
| public static function delete_job( $id ) { | |
| if ( ! is_numeric( $id ) ) { | |
| return false; | |
| } | |
| $id = intval( $id ); | |
| $jobs_options = self::jobs_options( false ); | |
| unset( $jobs_options[ $id ] ); | |
| return self::update_jobs_options( $jobs_options ); | |
| } | |
| /** | |
| * | |
| * get the id's of jobs | |
| * | |
| * @param string|null $key Option key or null for getting all id's | |
| * @param bool $value Value that the option must have to get the id | |
| * | |
| * @return array job id's | |
| */ | |
| public static function get_job_ids( $key = null, $value = false ) { | |
| $key = sanitize_key( trim( $key ) ); | |
| $jobs_options = self::jobs_options( false ); | |
| if ( empty( $jobs_options ) ) { | |
| return array(); | |
| } | |
| //get option job ids | |
| if ( empty( $key ) ) { | |
| return array_keys( $jobs_options ); | |
| } | |
| //get option ids for option with the defined value | |
| $new_option_job_ids = array(); | |
| foreach ( $jobs_options as $id => $option ) { | |
| if ( isset( $option[ $key ] ) && $value == $option[ $key ] ) { | |
| $new_option_job_ids[] = (int) $id; | |
| } | |
| } | |
| sort( $new_option_job_ids ); | |
| return $new_option_job_ids; | |
| } | |
| /** | |
| * Gets the next available job id. | |
| * | |
| * @return int | |
| */ | |
| public static function next_job_id() { | |
| $ids = self::get_job_ids(); | |
| sort( $ids ); | |
| return end( $ids ) + 1; | |
| } | |
| /** | |
| * Normalizes the archive name. | |
| * | |
| * The archive name should include the hash to identify this site, and the job id to identify this job. | |
| * | |
| * This allows backup files belonging to this job to be tracked. | |
| * | |
| * @param string $archive_name | |
| * @param int $jobid | |
| * | |
| * @return string The normalized archive name | |
| */ | |
| public static function normalize_archive_name( $archive_name, $jobid, $substitute_hash = true ) { | |
| $hash = BackWPup::get_plugin_data( 'hash' ); | |
| $generated_hash = self::get_generated_hash( $jobid ); | |
| // Does the string contain %hash%? | |
| if ( strpos( $archive_name, '%hash%' ) !== false ) { | |
| if ( $substitute_hash == true ) { | |
| return str_replace( '%hash%', $generated_hash, $archive_name ); | |
| } else { | |
| // Nothing needs to be done since we don't have to substitute it. | |
| return $archive_name; | |
| } | |
| } else { | |
| // %hash% not included, so check for old style archive name pre-3.4.3 | |
| // If name starts with 'backwpup', then we can try to parse | |
| if ( substr( $archive_name, 0, 8 ) == 'backwpup' ) { | |
| $parts = explode( '_', $archive_name ); | |
| // Decode hash part if hash not found (from 3.4.2) | |
| if ( strpos( $parts[1], $hash ) === false ) { | |
| $parts[1] = is_numeric($parts[1]) ? base_convert( $parts[1], 36, 16 ) : $parts[1] ; | |
| } | |
| // Search again | |
| if ( strpos( $parts[1], $hash ) !== false ) { | |
| $parts[1] = '%hash%'; | |
| } else { | |
| // Hash not included, so insert | |
| array_splice( $parts, 1, 0, '%hash%' ); | |
| } | |
| $archive_name = implode( '_', $parts ); | |
| if ( $substitute_hash == true ) { | |
| return str_replace( '%hash%', $generated_hash, $archive_name ); | |
| } else { | |
| return $archive_name; | |
| } | |
| } else { | |
| // But otherwise, just append the hash | |
| if ( $substitute_hash == true ) { | |
| return $archive_name . '_' . $generated_hash; | |
| } else { | |
| return $archive_name . '_%hash%'; | |
| } | |
| } | |
| } | |
| } | |
| /** | |
| * Generate a hash including random bytes and job ID | |
| * | |
| * @return string | |
| */ | |
| public static function get_generated_hash( $jobid ) { | |
| return Base32::encode( pack( 'H*', | |
| sprintf( '%02x%06s%02x', | |
| mt_rand( 0, 255 ), | |
| BackWPup::get_plugin_data( 'hash' ), | |
| mt_rand( 0, 255 ) ) ) ) . | |
| sprintf( '%02d', $jobid ); | |
| } | |
| /** | |
| * Return the decoded hash and the job ID. | |
| * | |
| * If the hash is not found in the given code, then false is returned. | |
| * | |
| * @param string $code The string to decode | |
| * | |
| * @return array|bool An array with hash and job ID, or false otherwise | |
| */ | |
| public static function decode_hash( $code ) { | |
| $hash = BackWPup::get_plugin_data( 'hash' ); | |
| // Try base 32 first | |
| $decoded = bin2hex( Base32::decode( substr( $code, 0, 8 ) ) ); | |
| if ( substr( $decoded, 2, 6 ) == $hash ) { | |
| return array( substr( $decoded, 2, 6 ), intval( substr( $code, - 2 ) ) ); | |
| } | |
| // Try base 36 | |
| $decoded = is_numeric($code) ? base_convert( $code, 36, 16 ) : $code ; //cuongdc | |
| if ( substr( $decoded, 2, 6 ) == $hash ) { | |
| return array( substr( $decoded, 2, 6 ), intval( substr( $decoded, - 2 ) ) ); | |
| } | |
| // Check style prior to 3.4.1 | |
| if ( substr( $code, 0, 6 ) == $hash ) { | |
| return array( substr( $code, 0, 6 ), intval( substr( $code, - 2 ) ) ); | |
| } | |
| // Tried everything, now return failure | |
| return false; | |
| } | |
| /** | |
| * Substitute date variables in archive name. | |
| * | |
| * @param string $archivename The name of the archive. | |
| * | |
| * @return string The archive name with substituted variables. | |
| */ | |
| public static function substitute_date_vars( $archivename ) { | |
| $current_time = current_time( 'timestamp' ); | |
| $datevars = array( | |
| '%d', | |
| '%j', | |
| '%m', | |
| '%n', | |
| '%Y', | |
| '%y', | |
| '%a', | |
| '%A', | |
| '%B', | |
| '%g', | |
| '%G', | |
| '%h', | |
| '%H', | |
| '%i', | |
| '%s', | |
| ); | |
| $datevalues = array( | |
| date( 'd', $current_time ), | |
| date( 'j', $current_time ), | |
| date( 'm', $current_time ), | |
| date( 'n', $current_time ), | |
| date( 'Y', $current_time ), | |
| date( 'y', $current_time ), | |
| date( 'a', $current_time ), | |
| date( 'A', $current_time ), | |
| date( 'B', $current_time ), | |
| date( 'g', $current_time ), | |
| date( 'G', $current_time ), | |
| date( 'h', $current_time ), | |
| date( 'H', $current_time ), | |
| date( 'i', $current_time ), | |
| date( 's', $current_time ), | |
| ); | |
| // Temporarily replace %hash% with [hash] | |
| $archivename = str_replace( '%hash%', '[hash]', $archivename ); | |
| $archivename = str_replace( $datevars, | |
| $datevalues, | |
| $archivename ); | |
| $archivename = str_replace( '[hash]', '%hash%', $archivename ); | |
| return BackWPup_Job::sanitize_file_name( $archivename ); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment