[BUGFIX] Add icon rendering for custom permissions options
[Packages/TYPO3.CMS.git] / typo3 / sysext / scheduler / Classes / Execution.php
1 <?php
2 namespace TYPO3\CMS\Scheduler;
3
4 /*
5 * This file is part of the TYPO3 CMS project.
6 *
7 * It is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License, either version 2
9 * of the License, or any later version.
10 *
11 * For the full copyright and license information, please read the
12 * LICENSE.txt file that was distributed with this source code.
13 *
14 * The TYPO3 project - inspiring people to share!
15 */
16
17 /**
18 * This class manages the logic of a particular execution of a task
19 */
20 class Execution
21 {
22 /**
23 * Start date of a task (timestamp)
24 *
25 * @var int
26 */
27 protected $start;
28
29 /**
30 * End date of a task (timestamp)
31 *
32 * @var int
33 */
34 protected $end;
35
36 /**
37 * Interval between executions (in seconds)
38 *
39 * @var int
40 */
41 protected $interval;
42
43 /**
44 * Flag for concurrent executions: TRUE if allowed, FALSE otherwise (default)
45 *
46 * @var bool
47 */
48 protected $multiple = false;
49
50 /**
51 * The cron command string of this task,
52 *
53 * @var string
54 */
55 protected $cronCmd;
56
57 /**
58 * This flag is used to mark a new single execution
59 * See explanations in method setIsNewSingleExecution()
60 *
61 * @var bool
62 * @see \TYPO3\CMS\Scheduler\Execution::setIsNewSingleExecution()
63 */
64 protected $isNewSingleExecution = false;
65
66 /**********************************
67 * Setters and getters
68 **********************************/
69 /**
70 * This method is used to set the start date
71 *
72 * @param int $start Start date (timestamp)
73 * @return void
74 */
75 public function setStart($start)
76 {
77 $this->start = $start;
78 }
79
80 /**
81 * This method is used to get the start date
82 *
83 * @return int Start date (timestamp)
84 */
85 public function getStart()
86 {
87 return $this->start;
88 }
89
90 /**
91 * This method is used to set the end date
92 *
93 * @param int $end End date (timestamp)
94 * @return void
95 */
96 public function setEnd($end)
97 {
98 $this->end = $end;
99 }
100
101 /**
102 * This method is used to get the end date
103 *
104 * @return int End date (timestamp)
105 */
106 public function getEnd()
107 {
108 return $this->end;
109 }
110
111 /**
112 * This method is used to set the interval
113 *
114 * @param int $interval Interval (in seconds)
115 * @return void
116 */
117 public function setInterval($interval)
118 {
119 $this->interval = $interval;
120 }
121
122 /**
123 * This method is used to get the interval
124 *
125 * @return int Interval (in seconds)
126 */
127 public function getInterval()
128 {
129 return $this->interval;
130 }
131
132 /**
133 * This method is used to set the multiple execution flag
134 *
135 * @param bool $multiple TRUE if concurrent executions are allowed, FALSE otherwise
136 * @return void
137 */
138 public function setMultiple($multiple)
139 {
140 $this->multiple = $multiple;
141 }
142
143 /**
144 * This method is used to get the multiple execution flag
145 *
146 * @return bool TRUE if concurrent executions are allowed, FALSE otherwise
147 */
148 public function getMultiple()
149 {
150 return $this->multiple;
151 }
152
153 /**
154 * Set the value of the cron command
155 *
156 * @param string $cmd Cron command, using cron-like syntax
157 * @return void
158 */
159 public function setCronCmd($cmd)
160 {
161 $this->cronCmd = $cmd;
162 }
163
164 /**
165 * Get the value of the cron command
166 *
167 * @return string Cron command, using cron-like syntax
168 */
169 public function getCronCmd()
170 {
171 return $this->cronCmd;
172 }
173
174 /**
175 * Set whether this is a newly created single execution.
176 * This is necessary for the following reason: if a new single-running task
177 * is created and its start date is in the past (even for only a few seconds),
178 * the next run time calculation (which happens upon saving) will disable
179 * that task, because it was meant to run only once and is in the past.
180 * Setting this flag to TRUE preserves this task for a single run.
181 * Upon next execution, this flag is set to FALSE.
182 *
183 * @param bool $isNewSingleExecution Is newly created single execution?
184 * @return void
185 * @see \TYPO3\CMS\Scheduler\Execution::getNextExecution()
186 */
187 public function setIsNewSingleExecution($isNewSingleExecution)
188 {
189 $this->isNewSingleExecution = $isNewSingleExecution;
190 }
191
192 /**
193 * Get whether this is a newly created single execution
194 *
195 * @return bool Is newly created single execution?
196 */
197 public function getIsNewSingleExecution()
198 {
199 return $this->isNewSingleExecution;
200 }
201
202 /**********************************
203 * Execution calculations and logic
204 **********************************/
205 /**
206 * This method gets or calculates the next execution date
207 *
208 * @return int Timestamp of the next execution
209 * @throws \OutOfBoundsException
210 */
211 public function getNextExecution()
212 {
213 if ($this->getIsNewSingleExecution()) {
214 $this->setIsNewSingleExecution(false);
215 return $this->start;
216 }
217 if (!$this->isEnded()) {
218 // If the schedule has not yet run out, find out the next date
219 if (!$this->isStarted()) {
220 // If the schedule hasn't started yet, next date is start date
221 $date = $this->start;
222 } else {
223 // If the schedule has already started, calculate next date
224 if ($this->cronCmd) {
225 // If it uses cron-like syntax, calculate next date
226 $date = $this->getNextCronExecution();
227 } elseif ($this->interval == 0) {
228 // If not and there's no interval either, it's a singe execution: use start date
229 $date = $this->start;
230 } else {
231 // Otherwise calculate date based on interval
232 $now = time();
233 $date = $now + $this->interval - ($now - $this->start) % $this->interval;
234 }
235 // If date is in the future, throw an exception
236 if (!empty($this->end) && $date > $this->end) {
237 throw new \OutOfBoundsException('Next execution date is past end date.', 1250715528);
238 }
239 }
240 } else {
241 // The event has ended, throw an exception
242 throw new \OutOfBoundsException('Task is past end date.', 1250715544);
243 }
244 return $date;
245 }
246
247 /**
248 * Calculates the next execution from a cron command
249 *
250 * @return int Next execution (timestamp)
251 */
252 public function getNextCronExecution()
253 {
254 /** @var $cronCmd \TYPO3\CMS\Scheduler\CronCommand\CronCommand */
255 $cronCmd = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Scheduler\CronCommand\CronCommand::class, $this->getCronCmd());
256 $cronCmd->calculateNextValue();
257 return $cronCmd->getTimestamp();
258 }
259
260 /**
261 * Checks if the schedule for a task is started or not
262 *
263 * @return bool TRUE if the schedule is already active, FALSE otherwise
264 */
265 public function isStarted()
266 {
267 return $this->start < time();
268 }
269
270 /**
271 * Checks if the schedule for a task is passed or not
272 *
273 * @return bool TRUE if the schedule is not active anymore, FALSE otherwise
274 */
275 public function isEnded()
276 {
277 if (empty($this->end)) {
278 // If no end is defined, the schedule never ends
279 $result = false;
280 } else {
281 // Otherwise check if end is in the past
282 $result = $this->end < time();
283 }
284 return $result;
285 }
286 }