Page Menu
Home
In-Portal Phabricator
Search
Configure Global Search
Log In
Files
F773171
D438.id1106.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Sun, Feb 2, 3:56 AM
Size
15 KB
Mime Type
text/x-diff
Expires
Mon, Feb 3, 3:56 AM (14 h, 52 m)
Engine
blob
Format
Raw Data
Handle
556426
Attached To
D438: INP-1834 - Connect "mtdowling/cron-expression" library
D438.id1106.diff
View Options
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
Log In to Comment