Current Path : /var/www/spmeat/wp-content/plugins/duplicator-pro/classes/entities/ |
Current File : /var/www/spmeat/wp-content/plugins/duplicator-pro/classes/entities/class.schedule.entity.php |
<?php /** * Enity layer for schedules * * Standard: Missing * * @package DUP_PRO * @subpackage classes/entities * @copyright (c) 2017, Snapcreek LLC * @license https://opensource.org/licenses/GPL-3.0 GNU Public License * @since 3.0.0 * * @todo Finish Docs */ use Duplicator\Libs\Snap\SnapLog; use Duplicator\Libs\Snap\SnapString; use Duplicator\Libs\Snap\SnapUtil; defined('ABSPATH') || defined('DUPXABSPATH') || exit; require_once(DUPLICATOR_PRO_PLUGIN_PATH . '/classes/entities/class.json.entity.base.php'); require_once(DUPLICATOR_PRO_PLUGIN_PATH . '/classes/entities/class.package.template.entity.php'); require_once(DUPLICATOR_PRO_PLUGIN_PATH . '/classes/entities/class.system.global.entity.php'); require_once(DUPLICATOR_PRO_PLUGIN_PATH . '/vendor/cron-expression/src/includeCronLib.php'); if (!class_exists('DUP_PRO_Brand_Entity')) { require_once(DUPLICATOR_PRO_PLUGIN_PATH . '/classes/entities/class.brand.entity.php'); } abstract class DUP_PRO_Schedule_Repeat_Types { const Daily = 0; const Weekly = 1; const Monthly = 2; const Hourly = 3; } abstract class DUP_PRO_Schedule_Days { const Monday = 1; const Tuesday = 2; const Wednesday = 4; const Thursday = 8; const Friday = 16; const Saturday = 32; const Sunday = 64; } class DUP_PRO_Schedule_Entity extends DUP_PRO_JSON_Entity_Base { const CRON_PARSER_LIB_CSD_PARSER = 'csd-parser'; const CRON_PARSER_LIB_CRON_EXP = 'cron-exp'; public $name = ''; public $template_id = -1; public $start_ticks; public $repeat_type = DUP_PRO_Schedule_Repeat_Types::Weekly; public $active = true; public $next_run_time = -1; public $run_every = 1; public $weekly_days = 0; // for now just using a single day but they can be bit encoded here public $day_of_month = 1; public $cron_string = ''; public $last_run_time = -1; public $last_run_status = DUP_PRO_Package_Build_Outcome::FAILURE; public $times_run = 0; public $storage_ids; function __construct() { parent::__construct(); $this->verifiers['name'] = new DUP_PRO_Required_Verifier("Name must not be blank"); // $this->start_ticks = time(); $this->storage_ids = array(); array_push($this->storage_ids, DUP_PRO_Virtual_Storage_IDs::Default_Local); $this->name = DUP_PRO_U::__('New Schedule'); } public static function create_from_data($data) { $instance = new DUP_PRO_Schedule_Entity(); $instance->name = $data->name; $instance->template_id = $data->template_id; $instance->start_ticks = $data->start_ticks; $instance->repeat_type = $data->repeat_type; $instance->active = $data->active; $instance->cron_string = $data->cron_string; $instance->next_run_time = $instance->get_next_run_time(); $instance->run_every = $data->run_every; $instance->weekly_days = $data->weekly_days; // for now just using a single day but they can be bit encoded here $instance->day_of_month = $data->day_of_month; $instance->last_run_time = -1; $instance->last_run_status = DUP_PRO_Package_Build_Outcome::FAILURE; $instance->times_run = 0; $instance->storage_ids = $data->storage_ids; return $instance; } /** * If it should run, queue up a package then update the run time * * @return void */ public function process() { DUP_PRO_LOG::trace("process"); $now = time(); if ($this->next_run_time == -1) { return; } if ($this->active && ($this->next_run_time <= $now)) { $exception = null; try { $next_run_time_string = DUP_PRO_DATE::getLocalTimeFromGMTTicks($this->next_run_time); $now_string = DUP_PRO_DATE::getLocalTimeFromGMTTicks($this->next_run_time); DUP_PRO_LOG::trace("NEXT RUN IS NOW! $next_run_time_string <= $now_string so trying to queue package"); $this->insert_new_package(); $this->next_run_time = $this->get_next_run_time(); $this->save(); $next_run_time_string = DUP_PRO_DATE::getLocalTimeFromGMTTicks($this->next_run_time); DUP_PRO_LOG::trace("******PACKAGE JUST CREATED. UPDATED NEXT RUN TIME TO $next_run_time_string"); } catch (Exception $e) { $exception = $e; } catch (Error $e) { $exception = $e; } if (!is_null($exception)) { $msg = "Start schedule error " . $exception->getMessage() . "\n" . SnapLog::getTextException($exception); error_log($msg); \DUP_PRO_LOG::trace($msg); $system_global = DUP_PRO_System_Global_Entity::get_instance(); $system_global->schedule_failed = true; $system_global->save(); } } else { DUP_PRO_LOG::trace("active and runtime=$this->next_run_time >= $now"); } } public function copy_from_source_id($source_id) { /* @var $source_schedule DUP_PRO_Schedule_Entity */ $source_schedule = self::get_by_id($source_id); $this->active = $source_schedule->active; $this->cron_string = $source_schedule->cron_string; $this->day_of_month = $source_schedule->day_of_month; $this->last_run_status = $source_schedule->last_run_status; $this->name = sprintf(DUP_PRO_U::__('%1$s - Copy'), $source_schedule->name); //$this->last_run_time = $source_schedule->last_run_time; //$this->next_run_time = $source_schedule $this->repeat_type = $source_schedule->repeat_type; $this->run_every = $source_schedule->run_every; $this->start_ticks = $source_schedule->start_ticks; $this->storage_ids = $source_schedule->storage_ids; // Arrays are copied $this->template_id = $source_schedule->template_id; //$this->times_run; $this->weekly_days = $source_schedule->weekly_days; } public function insert_new_package($run_now = false) { global $wp_version; /** @var \wpdb $wpdb */ global $wpdb; /* @var $global DUP_PRO_Global_Entity */ $global = DUP_PRO_Global_Entity::get_instance(); DUP_PRO_LOG::trace("archive build mode before calling insert new package " . $global->archive_build_mode); DUP_PRO_LOG::trace("Inserting new package for schedule $this->name"); /* @var $schedule DUP_PRO_Schedule_Entity */ $template = DUP_PRO_Package_Template_Entity::get_by_id((int) $this->template_id); if ($template != null) { $package = new DUP_PRO_Package(); $package->template_name = $template->name; $dbversion = DUP_PRO_DB::getVersion(); $dbversion = is_null($dbversion) ? '- unknown -' : $dbversion; $dbcomments = DUP_PRO_DB::getVariable('version_comment'); $dbcomments = is_null($dbcomments) ? '- unknown -' : $dbcomments; //PACKAGE $package->Created = gmdate("Y-m-d H:i:s"); $package->Version = DUPLICATOR_PRO_VERSION; $package->VersionOS = defined('PHP_OS') ? PHP_OS : 'unknown'; $package->VersionWP = $wp_version; $package->VersionPHP = phpversion(); $package->VersionDB = $dbversion; $package->Name = $this->generate_package_name(); $package->Hash = $package->make_hash(); $package->NameHash = "{$package->Name}_{$package->Hash}"; $package->Notes = sprintf(DUP_PRO_U::esc_html__('Created by schedule %1$s'), $this->name); if ($run_now) { $package->Type = DUP_PRO_PackageType::RUN_NOW; } else { $package->Type = DUP_PRO_PackageType::SCHEDULED; } //BRAND $brand_data = DUP_PRO_Brand_Entity::get_by_id((int) $template->installer_opts_brand, true); $package->Brand = $brand_data->name; $package->Brand_ID = (int) $brand_data->id; //MULTISITE $package->Multisite->FilterSites = $template->filter_sites; //ARCHIVE if ($global->archive_build_mode == DUP_PRO_Archive_Build_Mode::DupArchive) { $package->Archive->Format = 'DAF'; } else { $package->Archive->Format = 'ZIP'; } $package->Archive->ExportOnlyDB = $template->archive_export_onlydb; $package->Archive->FilterOn = $template->archive_filter_on; $package->Archive->FilterDirs = $template->archive_filter_dirs; $package->Archive->FilterExts = $template->archive_filter_exts; $package->Archive->FilterFiles = $template->archive_filter_files; //INSTALLER $package->Installer->OptsDBHost = $template->installer_opts_db_host; $package->Installer->OptsDBName = $template->installer_opts_db_name; $package->Installer->OptsDBUser = $template->installer_opts_db_user; $package->Installer->OptsSecureOn = $template->installer_opts_secure_on; $package->Installer->OptsSecurePass = $template->installer_opts_secure_pass; $package->Installer->OptsSkipScan = $template->installer_opts_skip_scan; // CPANEL $package->Installer->OptsCPNLHost = $template->installer_opts_cpnl_host; $package->Installer->OptsCPNLUser = $template->installer_opts_cpnl_user; $package->Installer->OptsCPNLPass = $template->installer_opts_cpnl_pass; $package->Installer->OptsCPNLEnable = $template->installer_opts_cpnl_enable; $package->Installer->OptsCPNLConnect = false; //CPANEL DB //1 = Create New, 2 = Connect Remove $package->Installer->OptsCPNLDBAction = $template->installer_opts_cpnl_db_action; $package->Installer->OptsCPNLDBHost = $template->installer_opts_cpnl_db_host; $package->Installer->OptsCPNLDBName = $template->installer_opts_cpnl_db_name; $package->Installer->OptsCPNLDBUser = $template->installer_opts_cpnl_db_user; //DATABASE $package->Database->FilterOn = $template->database_filter_on; $package->Database->FilterTables = $template->database_filter_tables; $package->Database->Comments = esc_html($dbcomments); $package->Status = DUP_PRO_PackageStatus::PRE_PROCESS; $package->schedule_id = $this->id; $package->add_upload_infos($this->storage_ids); $package->build_progress->set_build_mode(); $packageObj = json_encode($package); /* @var $system_global DUP_PRO_System_Global_Entity */ $system_global = DUP_PRO_System_Global_Entity::get_instance(); $system_global->clear_recommended_fixes(); $system_global->package_check_ts = 0; $system_global->save(); error_log('NEW PACKAGE NAME ' . $package->Name); $results = $wpdb->insert( $wpdb->base_prefix . "duplicator_pro_packages", array( 'name' => $package->Name, 'hash' => $package->Hash, 'status' => DUP_PRO_PackageStatus::PRE_PROCESS, 'created' => current_time('mysql'/* , get_option('gmt_offset', 1) */), 'owner' => DUP_PRO_U::__('System'), 'package' => $packageObj ) ); if ($results === false) { //$error_result = $wpdb->print_error(); DUP_PRO_LOG::trace("Problem inserting package: {$wpdb->last_error}"); throw new Exception("Duplicator is unable to insert a package record into the database table from schedule {$this->name}. Error: " . $wpdb->last_error); } } else { DUP_PRO_LOG::traceError("No settings object exists for schedule {$this->name}!"); } DUP_PRO_LOG::trace("archive build mode after calling insert new package " . $global->archive_build_mode); } /** * * @return boolean|\DUP_PRO_Package_Template_Entity */ public function getTemplate() { if ($this->template_id > 0) { $template = DUP_PRO_Package_Template_Entity::get_by_id($this->template_id); } else { $template = null; } if (!$template instanceof DUP_PRO_Package_Template_Entity) { return false; } return $template; } public function recoveableHtmlInfo($isList = false) { if (($template = $this->getTemplate()) === false) { return false; } $schedule = $this; require DUPLICATOR_PRO_PLUGIN_PATH . '/views/tools/templates/widget/recoveable-template-info.php'; } private function generate_package_name() { $ticks = time(); $ticks += ((int) get_option('gmt_offset') * 3600); //Remove specail_chars from final result $sanitize_special_chars = array( ".", "-", "?", "[", "]", "/", "\\", "=", "<", ">", ":", ";", ",", "'", "\"", "&", "$", "#", "*", "(", ")", "|", "~", "`", "!", "{", "}", "%", "+", chr(0) ); $scheduleName = SnapUtil::sanitizeNSCharsNewlineTabs($this->name); $scheduleName = trim(str_replace($sanitize_special_chars, '', $scheduleName), '_'); error_log('SCHEDULE NAME ' . $scheduleName); $blogName = sanitize_title(SnapUtil::sanitizeNSCharsNewlineTabs(get_bloginfo('name', 'display'))); $blogName = trim(str_replace($sanitize_special_chars, '', $blogName), '_'); error_log('BLOG NAME NAME ' . $blogName); $name = date('Ymd_His', $ticks) . '_' . $scheduleName . '_' . $blogName; return substr($name, 0, 40); } public function save() { DUP_PRO_LOG::trace("saving schedule $this->id"); // If we are inactive clear out any packages associated with us parent::save(); } // Return the next run time in UTC public function get_next_run_time() { if ($this->active) { $now = time(); $now += (int) get_option('gmt_offset') * 3600; $now += 60; switch (DUP_PRO_Global_Entity::get_instance()->cron_parser_lib) { case self::CRON_PARSER_LIB_CRON_EXP: $date = new DateTime(); $date->setTimestamp($now); $cronEx = Duplicator\Extlibs\Cron\CronExpression::factory($this->cron_string); $next_run_time = $cronEx->getNextRunDate($date)->getTimestamp(); break; case self::CRON_PARSER_LIB_CSD_PARSER: default: // RSR making default since there is an odd bug where cron parse lib not set! // self::CRON_PARSER_LIB_CSD_PARSER: //OLD LIB (had a bug in it) require_once(DUPLICATOR_PRO_PLUGIN_PATH . '/lib/cron/csd_parser.php'); // RSR was having problems with this - I THINK its because it considers when you are in the same // minute as not really being the next but the same $parser = new csd_parser($this->cron_string, $now); $next_run_time = $parser->get(); break; } // Have to negate the offset and add. For instance for az time -7 we want the next run timt to be 7 ahead // in utc time $next_run_time -= ((int) get_option('gmt_offset') * 3600); return $next_run_time; } else { return -1; } } public function set_weekdays_from_request($request) { $weekday = $request['weekday']; if (in_array('mon', $weekday)) { $this->weekly_days |= DUP_PRO_Schedule_Days::Monday; } else { $this->weekly_days &= ~DUP_PRO_Schedule_Days::Monday; } if (in_array('tue', $weekday)) { $this->weekly_days |= DUP_PRO_Schedule_Days::Tuesday; } else { $this->weekly_days &= ~DUP_PRO_Schedule_Days::Tuesday; } if (in_array('wed', $weekday)) { $this->weekly_days |= DUP_PRO_Schedule_Days::Wednesday; } else { $this->weekly_days &= ~DUP_PRO_Schedule_Days::Wednesday; } if (in_array('thu', $weekday)) { $this->weekly_days |= DUP_PRO_Schedule_Days::Thursday; } else { $this->weekly_days &= ~DUP_PRO_Schedule_Days::Thursday; } if (in_array('fri', $weekday)) { $this->weekly_days |= DUP_PRO_Schedule_Days::Friday; } else { $this->weekly_days &= ~DUP_PRO_Schedule_Days::Friday; } if (in_array('sat', $weekday)) { $this->weekly_days |= DUP_PRO_Schedule_Days::Saturday; } else { $this->weekly_days &= ~DUP_PRO_Schedule_Days::Saturday; } if (in_array('sun', $weekday)) { $this->weekly_days |= DUP_PRO_Schedule_Days::Sunday; } else { $this->weekly_days &= ~DUP_PRO_Schedule_Days::Sunday; } } public function is_day_set($day_string) { $day_bit = 0; switch ($day_string) { case 'mon': $day_bit = DUP_PRO_Schedule_Days::Monday; break; case 'tue': $day_bit = DUP_PRO_Schedule_Days::Tuesday; break; case 'wed': $day_bit = DUP_PRO_Schedule_Days::Wednesday; break; case 'thu': $day_bit = DUP_PRO_Schedule_Days::Thursday; break; case 'fri': $day_bit = DUP_PRO_Schedule_Days::Friday; break; case 'sat': $day_bit = DUP_PRO_Schedule_Days::Saturday; break; case 'sun': $day_bit = DUP_PRO_Schedule_Days::Sunday; break; } $is_set = (($this->weekly_days & $day_bit) != 0); $isset_string = $is_set ? 'yes' : 'no'; //DUP_PRO_U::debug("is_day_set:daystring=$day_string daybit=$day_bit)"); // DUP_PRO_U::debug("is set = $isset_string"); return $is_set; } public static function get_all() { return self::get_by_type(get_class()); } public static function delete_by_id($list_id) { parent::delete_by_id_base($list_id); } /** * Get active schedule * * @return self[] */ public static function get_active() { $schedules = self::get_all(); $active_schedules = array(); foreach ($schedules as $schedule) { /* @var $schedule DUP_PRO_Schedule_Entity */ if ($schedule->active) { array_push($active_schedules, $schedule); } } return $active_schedules; } // [0] = hour; [1] = minute; public function get_start_time_piece($piece) { switch ($piece) { case 0: return (int) date('G', $this->start_ticks); break; case 1: return (int) date('i', $this->start_ticks); break; default: return -1; } } public function get_next_run_time_string() { if ($this->next_run_time == -1) { return DUP_PRO_U::__('Unscheduled'); } else { $local_run_time = $this->next_run_time + ((int) get_option('gmt_offset') * 3600); $date_portion = date(get_option('date_format', 'n/j/y') . ' G:i', $local_run_time); $repeat_portion = $this->get_repeat_text(); return "$date_portion - $repeat_portion"; } } public function get_last_ran_string() { if ($this->last_run_time == -1) { return DUP_PRO_U::__('Never Ran'); } else { $local_run_time = $this->last_run_time + ((int) get_option('gmt_offset') * 3600); $date_portion = date(get_option('date_format', 'n/j/y') . ' G:i', $local_run_time); $status_portion = (($this->last_run_status == DUP_PRO_Package_Build_Outcome::SUCCESS) ? DUP_PRO_U::__('Success') : DUP_PRO_U::__('Failed')); return "$date_portion - $status_portion"; } } public function set_start_date_time($start_time_string, $start_date_string = '2015/1/1') { $this->start_ticks = strtotime("$start_date_string $start_time_string"); DUP_PRO_LOG::trace("start ticks = $this->start_ticks for $start_time_string $start_date_string"); } /** * Get schedule entity by id * * @param int $id * * @return self */ public static function get_by_id($id) { //Schedule Run Now = -1 don't search for id if ($id != -1) { return self::get_by_id_and_type($id, get_class()); } else { return null; } } /** * Get schedules entity by template id * * @param int $id * * @return self[] */ public static function get_by_template_id($template_id) { $schedules = self::get_all(); $filtered_schedules = array(); foreach ($schedules as $schedule) { /* @var $schedule DUP_PRO_Schedule_Entity */ if ($schedule->template_id == $template_id) { array_push($filtered_schedules, $schedule); } } DUP_PRO_LOG::trace("get by template id $template_id schedules = " . count($filtered_schedules)); return $filtered_schedules; } public function get_repeat_text() { switch ($this->repeat_type) { case DUP_PRO_Schedule_Repeat_Types::Daily: return DUP_PRO_U::__('Daily'); break; case DUP_PRO_Schedule_Repeat_Types::Weekly: return DUP_PRO_U::__('Weekly'); break; case DUP_PRO_Schedule_Repeat_Types::Monthly: return DUP_PRO_U::__('Monthly'); break; case DUP_PRO_Schedule_Repeat_Types::Hourly: return DUP_PRO_U::__('Hourly'); break; default: return DUP_PRO_U::__('Unknown'); } } public function build_cron_string() { // Special cron string for debugging if name set to 'bobtest' if ($this->name == 'bobtest') { $this->cron_string = '*/5 * * * *'; } else { $start_hour = $this->get_start_time_piece(0); $start_min = $this->get_start_time_piece(1); if ($this->run_every == 1) { $run_every_string = '*'; } else { $run_every_string = "*/$this->run_every"; } // Generated cron patterns using http://www.cronmaker.com/ switch ($this->repeat_type) { case DUP_PRO_Schedule_Repeat_Types::Hourly: $this->cron_string = "$start_min $run_every_string * * *"; break; case DUP_PRO_Schedule_Repeat_Types::Daily: $this->cron_string = "$start_min $start_hour $run_every_string * *"; break; case DUP_PRO_Schedule_Repeat_Types::Weekly: $day_of_week_string = $this->get_day_of_week_string(); $this->cron_string = "$start_min $start_hour * * $day_of_week_string"; DUP_PRO_LOG::trace("day of week cron string: $this->cron_string"); break; case DUP_PRO_Schedule_Repeat_Types::Monthly: $this->cron_string = "$start_min $start_hour $this->day_of_month $run_every_string *"; break; } } DUP_PRO_LOG::trace("cron string = $this->cron_string"); } private function get_day_of_week_string() { $day_array = array(); DUP_PRO_LOG::trace("weekly days=$this->weekly_days"); if (($this->weekly_days & DUP_PRO_Schedule_Days::Monday) != 0) { array_push($day_array, '1'); } if (($this->weekly_days & DUP_PRO_Schedule_Days::Tuesday) != 0) { array_push($day_array, '2'); } if (($this->weekly_days & DUP_PRO_Schedule_Days::Wednesday) != 0) { array_push($day_array, '3'); } if (($this->weekly_days & DUP_PRO_Schedule_Days::Thursday) != 0) { array_push($day_array, '4'); } if (($this->weekly_days & DUP_PRO_Schedule_Days::Friday) != 0) { array_push($day_array, '5'); } if (($this->weekly_days & DUP_PRO_Schedule_Days::Saturday) != 0) { array_push($day_array, '6'); } if (($this->weekly_days & DUP_PRO_Schedule_Days::Sunday) != 0) { array_push($day_array, '0'); } return implode(',', $day_array); } }