Page MenuHomeIn-Portal Phabricator

D438.id1106.diff
No OneTemporary

File Metadata

Created
Sun, Feb 2, 3:56 AM

D438.id1106.diff

Index: composer.json
===================================================================
--- composer.json
+++ composer.json
@@ -1,10 +1,11 @@
{
"name": "In-Portal",
"require": {
- "php": ">=5.3.7",
+ "php": ">=5.4.7",
"paragonie/random_compat": "^2.0",
"symfony/polyfill-php55": "^1.19",
- "symfony/polyfill-php56": "^1.19"
+ "symfony/polyfill-php56": "^1.19",
+ "mtdowling/cron-expression": "dev-master"
},
"require-dev": {
"aik099/phpunit-mink": "^2.2",
@@ -13,9 +14,16 @@
"behat/mink": "^1.7"
},
+ "repositories": [
+ {
+ "type": "vcs",
+ "url": "https://github.com/in-portal/cron-expression",
+ "no-api": true
+ }
+ ],
"config": {
"platform": {
- "php": "5.3.7"
+ "php": "5.4.7"
}
}
}
Index: composer.lock
===================================================================
--- composer.lock
+++ composer.lock
@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
- "content-hash": "ef20f3d542075e2d792fba4a7d3379c2",
+ "content-hash": "7751b2c25e8d11c582553cae50818aed",
"packages": [
{
"name": "ircmaxell/password-compat",
@@ -49,6 +49,55 @@
"time": "2014-11-20T16:49:30+00:00"
},
{
+ "name": "mtdowling/cron-expression",
+ "version": "dev-master",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/in-portal/cron-expression",
+ "reference": "c4dda94f8f13f5447aa82e9b9528de1115448c74"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/in-portal/cron-expression/zipball/c4dda94f8f13f5447aa82e9b9528de1115448c74",
+ "reference": "c4dda94f8f13f5447aa82e9b9528de1115448c74",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.4.7"
+ },
+ "require-dev": {
+ "yoast/phpunit-polyfills": "^1.0"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Cron\\": "src/Cron/"
+ }
+ },
+ "autoload-dev": {
+ "psr-4": {
+ "Tests\\": "tests/Cron/"
+ }
+ },
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Michael Dowling",
+ "email": "mtdowling@gmail.com",
+ "homepage": "https://github.com/mtdowling"
+ }
+ ],
+ "description": "CRON for PHP: Calculate the next or previous run date and determine if a CRON expression is due",
+ "keywords": [
+ "cron",
+ "schedule"
+ ],
+ "abandoned": "dragonmantank/cron-expression",
+ "time": "2022-11-08T11:57:39+00:00"
+ },
+ {
"name": "paragonie/random_compat",
"version": "v2.0.19",
"source": {
@@ -1901,16 +1950,17 @@
"aliases": [],
"minimum-stability": "stable",
"stability-flags": {
+ "mtdowling/cron-expression": 20,
"aik099/coding-standard": 20
},
"prefer-stable": false,
"prefer-lowest": false,
"platform": {
- "php": ">=5.3.7"
+ "php": ">=5.4.7"
},
"platform-dev": [],
"platform-overrides": {
- "php": "5.3.7"
+ "php": "5.4.7"
},
"plugin-api-version": "1.1.0"
}
Index: core/units/helpers/cron_helper.php
===================================================================
--- core/units/helpers/cron_helper.php
+++ core/units/helpers/cron_helper.php
@@ -12,6 +12,10 @@
* 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 {
@@ -24,6 +28,23 @@
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
@@ -193,6 +214,26 @@
}
/**
+ * 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
@@ -252,13 +293,12 @@
{
$validated = true;
$combined_value = Array ();
- $cron_field = new kCronField();
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 ( $cron_field->validate($field_type, $value) ) {
+ if ( $this->getField($field_type)->validate($value) ) {
$object->SetDBField($field_name, $value);
}
else {
@@ -276,36 +316,6 @@
}
/**
- * Replaces aliases in the field
- *
- * @param int $field_type
- * @param string $value
- * @return string
- * @access public
- */
- public static function replaceAliases($field_type, $value)
- {
- $replacements = Array ();
- $value = mb_strtolower($value);
-
- if ( $field_type == self::MONTH ) {
- $replacements = Array (
- 'jan' => 1, 'feb' => 2, 'mar' => 3, 'apr' => 4, 'may' => 5, 'jun' => 6,
- 'jul' => 7, 'aug' => 8, 'sep' => 9, 'oct' => 10, 'nov' => 11, 'dec' => 12,
- );
- }
- elseif ( $field_type == self::WEEKDAY ) {
- $replacements = Array ('sun' => 0, 'mon' => 1, 'tue' => 2, 'wed' => 3, 'thu' => 4, 'fri' => 5, 'sat' => 6);
- }
-
- if ( $replacements ) {
- $value = str_replace(array_keys($replacements), array_values($replacements), $value);
- }
-
- return $value;
- }
-
- /**
* Returns next (after given one or now) timestamp matching given cron expression
*
* @param string $expression
@@ -322,359 +332,15 @@
$date = TIMENOW;
}
- $next_run = strtotime('-' . (int)adodb_date('s', $date) . ' seconds', $date);
- $expression_parts = explode(' ', $expression);
-
- $cron_field = new kCronField();
-
- // set a hard limit to bail on an impossible date
- for ($i = 0; $i < 1000; $i++) {
- foreach ($this->fieldTypes as $field_type) {
- $matched = false;
- $part = $expression_parts[$field_type - 1];
-
- // check if this is singular or a list
- if ( strpos($part, ',') === false ) {
- $matched = $cron_field->match($field_type, $next_run, $part);
- }
- else {
- $rules = explode(',', $part);
-
- foreach ($rules as $rule) {
- if ( $cron_field->match($field_type, $next_run, $rule) ) {
- $matched = true;
- break;
- }
- }
- }
-
- // if the field is not matched, then start over
- if ( !$matched ) {
- $next_run = $cron_field->increment($field_type, $next_run, $inverse);
- continue 2;
- }
- }
-
- // Skip this match if needed
- if ( (!$allow_current_date && $next_run == $date) ) {
- $next_run = $cron_field->increment(self::MINUTE, $next_run, $inverse);
- continue;
- }
-
- return $next_run;
- }
-
- throw new RuntimeException('Impossible CRON expression');
- }
-}
-
-
-class kCronField extends kBase {
-
- /**
- * Validates field value
- *
- * @param int $field_type
- * @param string $value
- * @param bool $asterisk_allowed
- * @return bool
- * @access public
- */
- public function validate($field_type, $value, $asterisk_allowed = true)
- {
- $rules = explode(',', kCronHelper::replaceAliases($field_type, $value));
-
- foreach ($rules as $rule) {
- if ( $this->_isIncrementRule($rule) ) {
- if ( !$this->_validateIncrementRule($field_type, $rule) ) {
- return false;
- }
- }
- elseif ( $this->_isRangeRule($rule) ) {
- if ( !$this->_validateRangeRule($field_type, $rule) ) {
- return false;
- }
- }
- elseif ( !$this->_validateNumberRule($field_type, $rule, $asterisk_allowed) ) {
- return false;
- }
- }
-
- return true;
- }
-
- /**
- * Determines if expression is range
- *
- * @param string $rule
- * @return bool
- * @access protected
- */
- protected function _isRangeRule($rule)
- {
- return strpos($rule, '-') !== false;
- }
-
- /**
- * Validates range rule
- *
- * @param int $field_type
- * @param string $rule
- * @return bool
- * @access protected
- */
- protected function _validateRangeRule($field_type, $rule)
- {
- $parts = explode('-', $rule);
-
- if ( count($parts) != 2 ) {
- return false;
- }
-
- $min_value = $parts[0];
- $max_value = $parts[1];
-
- if ( !$this->_validateNumberRule($field_type, $min_value) || !$this->_validateNumberRule($field_type, $max_value) || $min_value >= $max_value ) {
- return false;
- }
-
- return true;
- }
-
- /**
- * Determines if expression is increment
- *
- * @param string $rule
- * @return bool
- * @access protected
- */
- protected function _isIncrementRule($rule)
- {
- return strpos($rule, '/') !== false;
- }
-
- /**
- * Validates increment rule
- *
- * @param int $field_type
- * @param string $rule
- * @return bool
- * @access protected
- */
- protected function _validateIncrementRule($field_type, $rule)
- {
- $parts = explode('/', $rule);
-
- if ( count($parts) != 2 ) {
- return false;
- }
-
- $interval = $parts[0];
- $increment = $parts[1];
-
- if ( $this->_isRangeRule($interval) ) {
- if ( !$this->_validateRangeRule($field_type, $interval) ) {
- return false;
- }
- }
- elseif ( !$this->_validateNumberRule($field_type, $interval, true) ) {
- return false;
- }
-
- if ( !$this->_validateNumberRule($field_type, $increment) ) {
- return false;
- }
-
- return true;
- }
-
- /**
- * Validates, that number within range OR an asterisk is given
- *
- * @param int $field_type
- * @param string $rule
- * @param bool $asterisk_allowed
- * @return bool
- * @access protected
- */
- protected function _validateNumberRule($field_type, $rule, $asterisk_allowed = false)
- {
- if ( "$rule" === '*' ) {
- return $asterisk_allowed;
- }
-
- $int_rule = (int)$rule;
-
- if ( !is_numeric($rule) || "$int_rule" !== "$rule" ) {
- // not integer
- return false;
- }
-
- $range_mapping = Array (
- kCronHelper::MINUTE => Array ('from' => 0, 'to' => 59),
- kCronHelper::HOUR => Array ('from' => 0, 'to' => 23),
- kCronHelper::DAY => Array ('from' => 1, 'to' => 31),
- kCronHelper::MONTH => Array ('from' => 1, 'to' => 12),
- kCronHelper::WEEKDAY => Array ('from' => 0, 'to' => 7),
- );
-
- return $int_rule >= $range_mapping[$field_type]['from'] && $int_rule <= $range_mapping[$field_type]['to'];
- }
-
- /**
- * Tries to match given date to given expression
- *
- * @param int $field_type
- * @param int $date
- * @param string $rule
- * @return bool
- * @access public
- */
- public function match($field_type, $date, $rule)
- {
- $date_part = $this->_getDatePart($field_type, $date, $rule);
-
- if ( $this->_isIncrementRule($rule) ) {
- return $this->_isInIncrement($date_part, $rule);
- }
- elseif ( $this->_isRangeRule($rule) ) {
- return $this->_isInRange($date_part, $rule);
- }
-
- return $rule == '*' || $date_part == $rule;
- }
-
- /**
- * Returns only part, needed based on field type of date in timestamp
- *
- * @param int $field_type
- * @param int $date
- * @param string $rule
- * @return int
- * @access protected
- */
- protected function _getDatePart($field_type, $date, $rule)
- {
- $mapping = Array (
- kCronHelper::MINUTE => 'i',
- kCronHelper::HOUR => 'G',
- kCronHelper::DAY => 'j',
- kCronHelper::MONTH => 'n',
- kCronHelper::WEEKDAY => 'N',
- );
-
- if ( $field_type == kCronHelper::WEEKDAY ) {
- // Test to see which Sunday to use -- 0 == 7 == Sunday
- $mapping[$field_type] = in_array(7, str_split($rule)) ? 'N' : 'w';
- }
-
- return (int)adodb_date($mapping[$field_type], $date);
- }
-
- /**
- * Test if a value is within a range
- *
- * @param string $date_value Set date value
- * @param string $rule Value to test
- * @return bool
- * @access protected
- */
- protected function _isInRange($date_value, $rule)
- {
- $parts = array_map('trim', explode('-', $rule, 2));
-
- return $date_value >= $parts[0] && $date_value <= $parts[1];
- }
+ $cron = CronExpression::factory($expression);
- /**
- * Test if a value is within an increments of ranges (offset[-to]/step size)
- *
- * @param string $date_value Set date value
- * @param string $rule Value to test
- * @return bool
- * @access protected
- */
- protected function _isInIncrement($date_value, $rule)
- {
- $parts = array_map('trim', explode('/', $rule, 2));
- $stepSize = isset($parts[1]) ? $parts[1] : 0;
+ $date_formatted = date('Y-m-d H:i:s', $date);
- if ( $parts[0] == '*' || $parts[0] == 0 ) {
- return (int)$date_value % $stepSize == 0;
+ if ( $inverse ) {
+ return $cron->getPreviousRunDate($date_formatted, 0, $allow_current_date)->format('U');
}
- $range = explode('-', $parts[0], 2);
- $offset = $range[0];
- $to = isset($range[1]) ? $range[1] : $date_value;
-
- // Ensure that the date value is within the range
- if ( $date_value < $offset || $date_value > $to ) {
- return false;
- }
-
- for ($i = $offset; $i <= $to; $i += $stepSize) {
- if ( $i == $date_value ) {
- return true;
- }
- }
-
- return false;
+ return $cron->getNextRunDate($date_formatted, 0, $allow_current_date)->format('U');
}
- /**
- * Increments/decrements given date for 1 unit based on field type
- *
- * @param int $field_type
- * @param int $date
- * @param bool $inverse
- * @return int
- * @access public
- */
- public function increment($field_type, $date, $inverse = false)
- {
- $mapping = Array (
- kCronHelper::MINUTE => '1 minute',
- kCronHelper::HOUR => '1 hour',
- kCronHelper::DAY => '1 day',
- kCronHelper::MONTH => '1 month',
- kCronHelper::WEEKDAY => '1 day',
- );
-
- return $this->_resetTime($field_type, strtotime(($inverse ? '-' : '+') . $mapping[$field_type], $date), $inverse);
- }
-
- /**
- * Resets time based on field type
- *
- * @param int $field_type
- * @param int $date
- * @param bool $inverse
- * @return int
- * @access public
- */
- protected function _resetTime($field_type, $date, $inverse = false)
- {
- if ( $field_type == kCronHelper::MONTH || $field_type == kCronHelper::WEEKDAY || $field_type == kCronHelper::DAY ) {
- if ( $inverse ) {
- $date = strtotime(adodb_date('Y-m-d 23:59:59', $date));
- // set time 23:59:00
- }
- else {
- // set time 00:00:00
- $date = strtotime(adodb_date('Y-m-d 00:00:00', $date));
- }
- }
- elseif ( $field_type == kCronHelper::HOUR ) {
- if ( $inverse ) {
- // set time <current_hour>:59:00
- $date = strtotime(adodb_date('Y-m-d H:59:59', $date));
- }
- else {
- // set time <current_hour>:00:00
- $date = strtotime(adodb_date('Y-m-d H:00:00', $date));
- }
- }
-
- return $date;
- }
-}
\ No newline at end of file
+}

Event Timeline