fieldFactory = new FieldFactory(); } /** * Defines possible cron fields and their matching priority * * @var Array * @access protected */ protected $fieldTypes = Array (self::MONTH, self::DAY, self::WEEKDAY, self::HOUR, self::MINUTE); protected $commonSettings = Array ( '* * * * *' => 'la_opt_CronEveryMinute', '*/5 * * * *' => 'la_opt_CronEveryFiveMinutes', '0,30 * * * *' => 'la_opt_CronTwiceAnHour', '0 * * * *' => 'la_opt_CronOnceAnHour', '0 0,12 * * *' => 'la_opt_CronTwiceADay', '0 0 * * *' => 'la_opt_CronOnceADay', '0 0 * * 0' => 'la_opt_CronOnceAWeek', '0 0 1,15 * *' => 'la_opt_CronTwiceAMonth', '0 0 1 * *' => 'la_opt_CronOnceAMonth', '0 0 1 1 *' => 'la_opt_CronOnceAYear', ); protected $minuteSettings = Array ( '*' => 'la_opt_CronEveryMinute', '*/2' => 'la_opt_CronEveryOtherMinute', '*/5' => 'la_opt_CronEveryFiveMinutes', '*/10' => 'la_opt_CronEveryTenMinutes', '*/15' => 'la_opt_CronEveryFifteenMinutes', '0,30' => 'la_opt_CronEveryThirtyMinutes', '--' => 'la_opt_CronMinutes', // minutes added dynamically later ); protected $hourSettings = Array ( '*' => 'la_opt_CronEveryHour', '*/2' => 'la_opt_CronEveryOtherHour', '*/3' => 'la_opt_CronEveryThreeHours', '*/4' => 'la_opt_CronEveryFourHours', '*/6' => 'la_opt_CronEverySixHours', '0,12' => 'la_opt_CronEveryTwelveHours', '--' => 'la_opt_CronHours', // hours added dynamically later ); protected $daySettings = Array ( '*' => 'la_opt_CronEveryDay', '*/2' => 'la_opt_CronEveryOtherDay', '1,15' => 'la_opt_CronTwiceAMonth', '--' => 'la_opt_CronDays', // days added dynamically later ); protected $monthSettings = Array ( '*' => 'la_opt_CronEveryMonth', '*/2' => 'la_opt_CronEveryOtherMonth', '*/4' => 'la_opt_CronEveryThreeMonths', '1,7' => 'la_opt_CronEverySixMonths', '--' => 'la_opt_CronMonths', '1' => 'la_opt_January', '2' => 'la_opt_February', '3' => 'la_opt_March', '4' => 'la_opt_April', '5' => 'la_opt_May', '6' => 'la_opt_June', '7' => 'la_opt_July', '8' => 'la_opt_August', '9' => 'la_opt_September', '10' => 'la_opt_October', '11' => 'la_opt_November', '12' => 'la_opt_December', ); protected $weekdaySettings = Array ( '*' => 'la_opt_CronEveryWeekday', '1-5' => 'la_opt_CronMondayThroughFriday', '0,6' => 'la_opt_CronSaturdayAndSunday', '1,3,5' => 'la_opt_CronMondayWednesdayAndFriday', '2,4' => 'la_opt_CronTuesdayAndThursday', '--' => 'la_opt_CronWeekdays', '0' => 'la_opt_Sunday', '1' => 'la_opt_Monday', '2' => 'la_opt_Tuesday', '3' => 'la_opt_Wednesday', '4' => 'la_opt_Thursday', '5' => 'la_opt_Friday', '6' => 'la_opt_Saturday', ); /** * Returns possible field options by type * * @param int $field_type * @return Array */ public function getOptions($field_type) { $mapping = Array ( self::COMMON => $this->commonSettings, self::MINUTE => $this->minuteSettings, self::HOUR => $this->hourSettings, self::DAY => $this->daySettings, self::MONTH => $this->monthSettings, self::WEEKDAY => $this->weekdaySettings, ); /** @var Array $ret */ $ret = $mapping[$field_type]; foreach ($ret as $option_key => $option_title) { $option_title = substr($option_title, 0, 1) == '+' ? substr($option_title, 1) : $this->Application->Phrase($option_title); $ret[$option_key] = $option_title; if ( "$option_key" !== '--' ) { $ret[$option_key] .= ' (' . $option_key . ')'; } } if ( $field_type == self::MINUTE ) { for ($i = 0; $i <= 59; $i++) { $ret[$i] = ':' . str_pad($i, 2, '0', STR_PAD_LEFT) . ' (' . $i . ')'; } } elseif ( $field_type == self::HOUR ) { /** @var LanguagesItem $language */ $language = $this->Application->recallObject('lang.current'); $short_time_format = str_replace(':s', '', $language->GetDBField('TimeFormat')); for ($i = 0; $i <= 23; $i++) { $ret[$i] = adodb_date($short_time_format, adodb_mktime($i, 0, 0)) . ' (' . $i . ')'; } } elseif ( $field_type == self::DAY ) { /** @var kMultiLanguageHelper $ml_helper */ $ml_helper = $this->Application->recallObject('kMultiLanguageHelper'); $forms = Array ( 'phrase1' => 'la_NumberSuffixSt', 'phrase2' => 'la_NumberSuffixNd', 'phrase3' => 'la_NumberSuffixRd', 'phrase4' => 'la_NumberSuffixTh', 'phrase5' => 'la_NumberSuffixTh' ); for ($i = 1; $i <= 31; $i++) { $ret[$i] = $i . $ml_helper->getPluralPhrase($i, $forms) . ' (' . $i . ')'; } } return $ret; } /** * Returns field name by type * * @param int $field_type * @param string $field_prefix * @return string * @access protected */ protected function _getFieldNameByType($field_type, $field_prefix) { $field_mapping = Array ( self::MINUTE => 'Minute', self::HOUR => 'Hour', self::DAY => 'Day', self::MONTH => 'Month', self::WEEKDAY => 'Weekday', ); return $field_prefix . $field_mapping[$field_type]; } /** * Get an instance of a field object for a cron expression field type. * * @param integer $field_type Field type. * * @return FieldInterface */ protected function getField($field_type) { $field_mapping = array( self::MINUTE => 0, self::HOUR => 1, self::DAY => 2, self::MONTH => 3, self::WEEKDAY => 4, ); return $this->fieldFactory->getField($field_mapping[$field_type]); } /** * Creates virtual fields for given unit * * @param string $prefix * @param string $field_prefix * @return void * @access public */ public function initUnit($prefix, $field_prefix = '') { $virtual_fields = $this->Application->getUnitOption($prefix, 'VirtualFields', Array ()); $virtual_fields[$field_prefix . 'CommonHints'] = Array ( 'type' => 'string', 'formatter' => 'kOptionsFormatter', 'options' => $this->getOptions(self::COMMON), 'default' => '' ); foreach ($this->fieldTypes as $field_type) { $field_name = $this->_getFieldNameByType($field_type, $field_prefix); $virtual_fields[$field_name] = Array ('type' => 'string', 'max_len' => 30, 'default' => '*'); $virtual_fields[$field_name . 'Hints'] = Array ( 'type' => 'string', 'formatter' => 'kOptionsFormatter', 'options' => $this->getOptions($field_type), 'default' => '' ); } $this->Application->setUnitOption($prefix, 'VirtualFields', $virtual_fields); } /** * Loads schedule values from database into virtual fields * * @param kDBItem $object * @param string $field_prefix */ public function load(kDBItem $object, $field_prefix = '') { $combined_value = explode(' ', $object->GetDBField($field_prefix)); foreach ($this->fieldTypes as $field_type) { $field_name = $this->_getFieldNameByType($field_type, $field_prefix); $object->SetDBField($field_name, $combined_value[$field_type - 1]); } } /** * Validates schedule values and saves them to database * * @param kDBItem $object * @param string $field_prefix * @return bool * @access public */ public function validateAndSave(kDBItem $object, $field_prefix = '') { $validated = true; $combined_value = Array (); foreach ($this->fieldTypes as $field_type) { $field_name = $this->_getFieldNameByType($field_type, $field_prefix); $value = preg_replace('/\s+/s', '', mb_strtoupper($object->GetDBField($field_name))); if ( $this->getField($field_type)->validate($value) ) { $object->SetDBField($field_name, $value); } else { $validated = false; $object->SetError($field_name, 'invalid_format'); } $combined_value[$field_type] = $value; } ksort($combined_value); $object->SetDBField($field_prefix, implode(' ', $combined_value)); return $validated; } /** * Returns next (after given one or now) timestamp matching given cron expression * * @param string $expression * @param int $date * @param bool $inverse * @param bool $allow_current_date * @return int * @access public * @throws RuntimeException */ public function getMatch($expression, $date = NULL, $inverse = false, $allow_current_date = false) { if ( !isset($date) ) { $date = TIMENOW; } $cron = CronExpression::factory($expression); $date_formatted = date('Y-m-d H:i:s', $date); if ( $inverse ) { return $cron->getPreviousRunDate($date_formatted, 0, $allow_current_date)->format('U'); } return $cron->getNextRunDate($date_formatted, 0, $allow_current_date)->format('U'); } }