Page MenuHomeIn-Portal Phabricator

cron_helper.php
No OneTemporary

File Metadata

Created
Mon, Sep 29, 6:28 PM

cron_helper.php

<?php
/**
* @version $Id: cron_helper.php 16769 2023-11-16 09:45:43Z alex $
* @package In-Portal
* @copyright Copyright (C) 1997 - 2009 Intechnic. All rights reserved.
* @license GNU/GPL
* In-Portal is Open Source software.
* This means that this software may have been modified pursuant
* the GNU General Public License, and as distributed it includes
* or is derivative of works licensed under the GNU General Public License
* or other free or open source software licenses.
* See http://www.in-portal.org/license for copyright notices and details.
*/
use Cron\CronExpression;
use Cron\FieldFactory;
use Cron\FieldInterface;
defined('FULL_PATH') or die('restricted access!');
class kCronHelper extends kHelper {
const COMMON = 0;
const MINUTE = 1;
const HOUR = 2;
const DAY = 3;
const MONTH = 4;
const WEEKDAY = 5;
/**
* Field factory.
*
* @var FieldFactory
*/
protected $fieldFactory;
/**
* Creates an instance of kCronHelper class.
*/
public function __construct()
{
parent::__construct();
$this->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');
}
}

Event Timeline