ILIAS  release_8 Revision v8.24
class.ilCronJob.php
Go to the documentation of this file.
1<?php
2
19declare(strict_types=1);
20
21abstract class ilCronJob
22{
24 public const SCHEDULE_TYPE_DAILY = 1;
26 public const SCHEDULE_TYPE_IN_MINUTES = 2;
28 public const SCHEDULE_TYPE_IN_HOURS = 3;
30 public const SCHEDULE_TYPE_IN_DAYS = 4;
32 public const SCHEDULE_TYPE_WEEKLY = 5;
34 public const SCHEDULE_TYPE_MONTHLY = 6;
36 public const SCHEDULE_TYPE_QUARTERLY = 7;
38 public const SCHEDULE_TYPE_YEARLY = 8;
39
40 protected ?int $schedule_type = null;
41 protected ?int $schedule_value = null;
42 protected ?Closure $date_time_provider = null;
43
44 private function checkWeeklySchedule(DateTimeImmutable $last_run, DateTimeImmutable $now): bool
45 {
46 $last_year = (int) $last_run->format('Y');
47 $now_year = (int) $now->format('Y');
48
49 if ($last_year > $now_year) {
50 // Should never happen, don't execute otherwise
51 return false;
52 }
53
54 $last_week = $last_run->format('W');
55 $now_week = $now->format('W');
56
57 if ($last_week !== $now_week) {
58 // Week differs, always execute the job
59 return true;
60 }
61
62 // For all following cases, the week number is always identical
63
64 $last_month = (int) $last_run->format('m');
65 $now_month = (int) $now->format('m');
66
67 $is_within_same_week_in_same_year = ($last_year . '-' . $last_week) === ($now_year . '-' . $now_week);
68 if ($is_within_same_week_in_same_year) {
69 // Same week in same year, only execute if the month differs (2022-52 is valid for January and December)
70 return $last_month !== $now_month && $now->diff($last_run)->d > 7;
71 }
72
73 if ($now_year - $last_year > 1) {
74 // Always execute if the difference of years is greater than 1
75 return true;
76 }
77
78 // Execute for week number 52 in 2022 (last run) and week number 52 in December of 2022 (now), but not for week number 52 in January of 2022 (now)
79 return $last_month === $now_month;
80 }
81
82 private function checkSchedule(?DateTimeImmutable $last_run, ?int $schedule_type, ?int $schedule_value): bool
83 {
84 if (null === $schedule_type) {
85 return false;
86 }
87
88 if (null === $last_run) {
89 return true;
90 }
91
92 if ($this->date_time_provider === null) {
93 $now = new DateTimeImmutable('@' . time(), new DateTimeZone(date_default_timezone_get()));
94 } else {
96 }
97
98 switch ($schedule_type) {
100 $last = $last_run->format('Y-m-d');
101 $ref = $now->format('Y-m-d');
102 return ($last !== $ref);
103
105 return $this->checkWeeklySchedule($last_run, $now);
106
108 $last = $last_run->format('Y-n');
109 $ref = $now->format('Y-n');
110 return ($last !== $ref);
111
113 $last = $last_run->format('Y') . '-' . ceil(((int) $last_run->format('n')) / 3);
114 $ref = $now->format('Y') . '-' . ceil(((int) $now->format('n')) / 3);
115 return ($last !== $ref);
116
118 $last = $last_run->format('Y');
119 $ref = $now->format('Y');
120 return ($last !== $ref);
121
123 $diff = floor(($now->getTimestamp() - $last_run->getTimestamp()) / 60);
124 return ($diff >= $schedule_value);
125
127 $diff = floor(($now->getTimestamp() - $last_run->getTimestamp()) / (60 * 60));
128 return ($diff >= $schedule_value);
129
131 $diff = floor(($now->getTimestamp() - $last_run->getTimestamp()) / (60 * 60 * 24));
132 return ($diff >= $schedule_value);
133 }
134
135 return false;
136 }
137
141 public function setDateTimeProvider(?Closure $date_time_provider): void
142 {
143 if ($date_time_provider !== null) {
144 $r = new ReflectionFunction($date_time_provider);
145 $return_type = $r->getReturnType();
146 if ($return_type !== null) {
147 $return_type = $return_type->getName();
148 }
149 $expected_type = DateTimeInterface::class;
150 if (!is_subclass_of($return_type, $expected_type)) {
151 throw new InvalidArgumentException(sprintf(
152 'The return type of the datetime provider must be of type %s',
153 $expected_type
154 ));
155 }
156
157 $r = new ReflectionFunction($date_time_provider);
158 $parameters = $r->getParameters();
159 if ($parameters !== []) {
160 throw new InvalidArgumentException(
161 'The datetime provider must not define any parameters',
162 );
163 }
164 }
165
166 $this->date_time_provider = $date_time_provider;
167 }
168
169 public function isDue(
170 ?DateTimeImmutable $last_run,
171 ?int $schedule_type,
172 ?int $schedule_value,
173 bool $is_manually_executed = false
174 ): bool {
175 if ($is_manually_executed) {
176 return true;
177 }
178
179 if (!$this->hasFlexibleSchedule()) {
180 $schedule_type = $this->getDefaultScheduleType();
181 $schedule_value = $this->getDefaultScheduleValue();
182 }
183
184 return $this->checkSchedule($last_run, $schedule_type, $schedule_value);
185 }
186
191 public function getScheduleType(): ?int
192 {
193 if ($this->schedule_type && $this->hasFlexibleSchedule()) {
194 return $this->schedule_type;
195 }
196
197 return null;
198 }
199
204 public function getScheduleValue(): ?int
205 {
206 if ($this->schedule_value && $this->hasFlexibleSchedule()) {
207 return $this->schedule_value;
208 }
209
210 return null;
211 }
212
218 public function setSchedule(?int $a_type, ?int $a_value): void
219 {
220 if (
221 $a_value &&
222 $this->hasFlexibleSchedule() &&
223 in_array($a_type, $this->getValidScheduleTypes(), true)
224 ) {
225 $this->schedule_type = $a_type;
226 $this->schedule_value = $a_value;
227 }
228 }
229
234 public function getAllScheduleTypes(): array
235 {
236 return [
237 self::SCHEDULE_TYPE_DAILY,
238 self::SCHEDULE_TYPE_WEEKLY,
239 self::SCHEDULE_TYPE_MONTHLY,
240 self::SCHEDULE_TYPE_QUARTERLY,
241 self::SCHEDULE_TYPE_YEARLY,
242 self::SCHEDULE_TYPE_IN_MINUTES,
243 self::SCHEDULE_TYPE_IN_HOURS,
244 self::SCHEDULE_TYPE_IN_DAYS,
245 ];
246 }
247
251 public function getScheduleTypesWithValues(): array
252 {
253 return [
254 self::SCHEDULE_TYPE_IN_MINUTES,
255 self::SCHEDULE_TYPE_IN_HOURS,
256 self::SCHEDULE_TYPE_IN_DAYS,
257 ];
258 }
259
264 public function getValidScheduleTypes(): array
265 {
266 return $this->getAllScheduleTypes();
267 }
268
269 public function isManuallyExecutable(): bool
270 {
271 return true;
272 }
273
274 public function hasCustomSettings(): bool
275 {
276 return false;
277 }
278
279 public function addCustomSettingsToForm(ilPropertyFormGUI $a_form): void
280 {
281 }
282
283 public function saveCustomSettings(ilPropertyFormGUI $a_form): bool
284 {
285 return true;
286 }
287
288 public function addToExternalSettingsForm(int $a_form_id, array &$a_fields, bool $a_is_active): void
289 {
290 }
291
300 public function activationWasToggled(ilDBInterface $db, ilSetting $setting, bool $a_currently_active): void
301 {
302 }
303
304 abstract public function getId(): string;
305
306 abstract public function getTitle(): string;
307
308 abstract public function getDescription(): string;
309
313 abstract public function hasAutoActivation(): bool;
314
315 abstract public function hasFlexibleSchedule(): bool;
316
317 abstract public function getDefaultScheduleType(): int;
318
319 abstract public function getDefaultScheduleValue(): ?int;
320
321 abstract public function run(): ilCronJobResult;
322}
getScheduleType()
Get current schedule type (if flexible)
const SCHEDULE_TYPE_IN_DAYS
@depracated This will be replaced with an ENUM in ILIAS 9
getDefaultScheduleType()
activationWasToggled(ilDBInterface $db, ilSetting $setting, bool $a_currently_active)
Important: This method is (also) called from the setup process, where the constructor of an ilCronJob...
getDescription()
setDateTimeProvider(?Closure $date_time_provider)
const SCHEDULE_TYPE_IN_HOURS
@depracated This will be replaced with an ENUM in ILIAS 9
getDefaultScheduleValue()
addCustomSettingsToForm(ilPropertyFormGUI $a_form)
saveCustomSettings(ilPropertyFormGUI $a_form)
isDue(?DateTimeImmutable $last_run, ?int $schedule_type, ?int $schedule_value, bool $is_manually_executed=false)
getScheduleTypesWithValues()
const SCHEDULE_TYPE_IN_MINUTES
@depracated This will be replaced with an ENUM in ILIAS 9
setSchedule(?int $a_type, ?int $a_value)
Update current schedule (if flexible)
getScheduleValue()
Get current schedule value (if flexible)
const SCHEDULE_TYPE_WEEKLY
@depracated This will be replaced with an ENUM in ILIAS 9
const SCHEDULE_TYPE_YEARLY
@depracated This will be replaced with an ENUM in ILIAS 9
checkWeeklySchedule(DateTimeImmutable $last_run, DateTimeImmutable $now)
hasAutoActivation()
Is to be activated on "installation", does only work for ILIAS core cron jobs.
const SCHEDULE_TYPE_DAILY
@depracated This will be replaced with an ENUM in ILIAS 9
Closure $date_time_provider
checkSchedule(?DateTimeImmutable $last_run, ?int $schedule_type, ?int $schedule_value)
hasFlexibleSchedule()
const SCHEDULE_TYPE_QUARTERLY
@depracated This will be replaced with an ENUM in ILIAS 9
const SCHEDULE_TYPE_MONTHLY
@depracated This will be replaced with an ENUM in ILIAS 9
getValidScheduleTypes()
Returns a collection of all valid schedule types for a specific job.
getAllScheduleTypes()
Get all available schedule types.
addToExternalSettingsForm(int $a_form_id, array &$a_fields, bool $a_is_active)
This class represents a property form user interface.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
if(!file_exists(getcwd() . '/ilias.ini.php'))
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
Definition: confirmReg.php:20
Interface ilDBInterface.