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