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