You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

149 lines
3.8 KiB

  1. <?php
  2. namespace Cron;
  3. /**
  4. * Abstract CRON expression field
  5. */
  6. abstract class AbstractField implements FieldInterface
  7. {
  8. /**
  9. * Check to see if a field is satisfied by a value
  10. *
  11. * @param string $dateValue Date value to check
  12. * @param string $value Value to test
  13. *
  14. * @return bool
  15. */
  16. public function isSatisfied($dateValue, $value)
  17. {
  18. if ($this->isIncrementsOfRanges($value)) {
  19. return $this->isInIncrementsOfRanges($dateValue, $value);
  20. } elseif ($this->isRange($value)) {
  21. return $this->isInRange($dateValue, $value);
  22. }
  23. return $value == '*' || $dateValue == $value;
  24. }
  25. /**
  26. * Check if a value is a range
  27. *
  28. * @param string $value Value to test
  29. *
  30. * @return bool
  31. */
  32. public function isRange($value)
  33. {
  34. return strpos($value, '-') !== false;
  35. }
  36. /**
  37. * Check if a value is an increments of ranges
  38. *
  39. * @param string $value Value to test
  40. *
  41. * @return bool
  42. */
  43. public function isIncrementsOfRanges($value)
  44. {
  45. return strpos($value, '/') !== false;
  46. }
  47. /**
  48. * Test if a value is within a range
  49. *
  50. * @param string $dateValue Set date value
  51. * @param string $value Value to test
  52. *
  53. * @return bool
  54. */
  55. public function isInRange($dateValue, $value)
  56. {
  57. $parts = array_map('trim', explode('-', $value, 2));
  58. return $dateValue >= $parts[0] && $dateValue <= $parts[1];
  59. }
  60. /**
  61. * Test if a value is within an increments of ranges (offset[-to]/step size)
  62. *
  63. * @param string $dateValue Set date value
  64. * @param string $value Value to test
  65. *
  66. * @return bool
  67. */
  68. public function isInIncrementsOfRanges($dateValue, $value)
  69. {
  70. $parts = array_map('trim', explode('/', $value, 2));
  71. $stepSize = isset($parts[1]) ? (int) $parts[1] : 0;
  72. if ($stepSize === 0) {
  73. return false;
  74. }
  75. if (($parts[0] == '*' || $parts[0] === '0')) {
  76. return (int) $dateValue % $stepSize == 0;
  77. }
  78. $range = explode('-', $parts[0], 2);
  79. $offset = $range[0];
  80. $to = isset($range[1]) ? $range[1] : $dateValue;
  81. // Ensure that the date value is within the range
  82. if ($dateValue < $offset || $dateValue > $to) {
  83. return false;
  84. }
  85. if ($dateValue > $offset && 0 === $stepSize) {
  86. return false;
  87. }
  88. for ($i = $offset; $i <= $to; $i+= $stepSize) {
  89. if ($i == $dateValue) {
  90. return true;
  91. }
  92. }
  93. return false;
  94. }
  95. /**
  96. * Returns a range of values for the given cron expression
  97. *
  98. * @param string $expression The expression to evaluate
  99. * @param int $max Maximum offset for range
  100. *
  101. * @return array
  102. */
  103. public function getRangeForExpression($expression, $max)
  104. {
  105. $values = array();
  106. if ($this->isRange($expression) || $this->isIncrementsOfRanges($expression)) {
  107. if (!$this->isIncrementsOfRanges($expression)) {
  108. list ($offset, $to) = explode('-', $expression);
  109. $stepSize = 1;
  110. }
  111. else {
  112. $range = array_map('trim', explode('/', $expression, 2));
  113. $stepSize = isset($range[1]) ? $range[1] : 0;
  114. $range = $range[0];
  115. $range = explode('-', $range, 2);
  116. $offset = $range[0];
  117. $to = isset($range[1]) ? $range[1] : $max;
  118. }
  119. $offset = $offset == '*' ? 0 : $offset;
  120. for ($i = $offset; $i <= $to; $i += $stepSize) {
  121. $values[] = $i;
  122. }
  123. sort($values);
  124. }
  125. else {
  126. $values = array($expression);
  127. }
  128. return $values;
  129. }
  130. }