ILIAS  trunk Revision v11.0_alpha-3011-gc6b235a2e85
CronJob.php
Go to the documentation of this file.
1<?php
2
19declare(strict_types=1);
20
21namespace ILIAS\Cron;
22
25
26abstract class CronJob
27{
29 protected ?int $schedule_value = null;
30 protected ?\Closure $date_time_provider = null;
31
32 private function checkWeeklySchedule(\DateTimeImmutable $last_run, \DateTimeImmutable $now): bool
33 {
34 if ($last_run > $now) {
35 // Defensive check: last run is in the future → don't run again
36 return false;
37 }
38
39 // We are using ISO week/year to handle issues with week #52/#53 (see: https://mantis.ilias.de/view.php?id=36118 / https://en.wikipedia.org/wiki/ISO_8601#Week_dates)
40 return $last_run->format('o-W') !== $now->format('o-W');
41 }
42
43 private function checkSchedule(
44 ?\DateTimeImmutable $last_run,
47 ): bool {
48 if (null === $schedule_type) {
49 return false;
50 }
51
52 if (null === $last_run) {
53 return true;
54 }
55
56 if ($this->date_time_provider === null) {
57 $now = new \DateTimeImmutable('@' . time(), new \DateTimeZone(date_default_timezone_get()));
58 } else {
60 }
61
62 switch ($schedule_type) {
63 case JobScheduleType::DAILY:
64 $last = $last_run->format('Y-m-d');
65 $ref = $now->format('Y-m-d');
66 return ($last !== $ref);
67
68 case JobScheduleType::WEEKLY:
69 return $this->checkWeeklySchedule($last_run, $now);
70
71 case JobScheduleType::MONTHLY:
72 $last = $last_run->format('Y-n');
73 $ref = $now->format('Y-n');
74 return ($last !== $ref);
75
76 case JobScheduleType::QUARTERLY:
77 $last = $last_run->format('Y') . '-' . ceil(((int) $last_run->format('n')) / 3);
78 $ref = $now->format('Y') . '-' . ceil(((int) $now->format('n')) / 3);
79 return ($last !== $ref);
80
82 $last = $last_run->format('Y');
83 $ref = $now->format('Y');
84 return ($last !== $ref);
85
86 case JobScheduleType::IN_MINUTES:
87 $diff = floor(($now->getTimestamp() - $last_run->getTimestamp()) / 60);
88 return ($diff >= $schedule_value);
89
90 case JobScheduleType::IN_HOURS:
91 $diff = floor(($now->getTimestamp() - $last_run->getTimestamp()) / (60 * 60));
92 return ($diff >= $schedule_value);
93
94 case JobScheduleType::IN_DAYS:
95 $diff = floor(($now->getTimestamp() - $last_run->getTimestamp()) / (60 * 60 * 24));
96 return ($diff >= $schedule_value);
97 }
98
99 return false;
100 }
101
105 public function setDateTimeProvider(?\Closure $date_time_provider): void
106 {
107 if ($date_time_provider !== null) {
108 $r = new \ReflectionFunction($date_time_provider);
109 $return_type = $r->getReturnType();
110 if ($return_type instanceof \ReflectionNamedType) {
111 $return_type = $return_type->getName();
112 }
113 $expected_type = \DateTimeInterface::class;
114 if (!is_subclass_of($return_type, $expected_type)) {
115 throw new \InvalidArgumentException(
116 \sprintf(
117 'The return type of the datetime provider must be of type %s',
118 $expected_type
119 )
120 );
121 }
122
123 $r = new \ReflectionFunction($date_time_provider);
124 $parameters = $r->getParameters();
125 if ($parameters !== []) {
126 throw new \InvalidArgumentException(
127 'The datetime provider must not define any parameters',
128 );
129 }
130 }
131
132 $this->date_time_provider = $date_time_provider;
133 }
134
135 public function isDue(
136 ?\DateTimeImmutable $last_run,
137 ?JobScheduleType $schedule_type,
138 ?int $schedule_value,
139 bool $is_manually_executed = false
140 ): bool {
141 if ($is_manually_executed) {
142 return true;
143 }
144
145 if (!$this->hasFlexibleSchedule()) {
146 $schedule_type = $this->getDefaultScheduleType();
147 $schedule_value = $this->getDefaultScheduleValue();
148 }
149
150 return $this->checkSchedule($last_run, $schedule_type, $schedule_value);
151 }
152
157 {
158 if ($this->schedule_type && $this->hasFlexibleSchedule()) {
159 return $this->schedule_type;
160 }
161
162 return null;
163 }
164
168 public function getScheduleValue(): ?int
169 {
170 if ($this->schedule_value && $this->hasFlexibleSchedule()) {
171 return $this->schedule_value;
172 }
173
174 return null;
175 }
176
180 public function setSchedule(?JobScheduleType $a_type, ?int $a_value): void
181 {
182 if (
183 $a_value &&
184 $this->hasFlexibleSchedule() &&
185 \in_array($a_type, $this->getValidScheduleTypes(), true)
186 ) {
187 $this->schedule_type = $a_type;
188 $this->schedule_value = $a_value;
189 }
190 }
191
196 public function getAllScheduleTypes(): array
197 {
198 return JobScheduleType::cases();
199 }
200
204 public function getScheduleTypesWithValues(): array
205 {
206 return [
207 JobScheduleType::IN_MINUTES,
208 JobScheduleType::IN_HOURS,
209 JobScheduleType::IN_DAYS,
210 ];
211 }
212
217 public function getValidScheduleTypes(): array
218 {
219 return $this->getAllScheduleTypes();
220 }
221
222 public function isManuallyExecutable(): bool
223 {
224 return true;
225 }
226
227 public function hasCustomSettings(): bool
228 {
229 return false;
230 }
231
235 #[\Deprecated('Will be removed without any alternative, KS/UI forms will be expected', since: '13.0')]
236 public function usesLegacyForms(): bool
237 {
238 return true;
239 }
240
242 \ILIAS\UI\Factory $ui_factory,
243 \ILIAS\Refinery\Factory $factory,
245 ): \ILIAS\UI\Component\Input\Container\Form\FormInput {
246 throw new \RuntimeException('Not implemented');
247 }
248
252 #[\Deprecated('Will be removed without any alternative, KS/UI forms will be expected', since: '13.0')]
253 public function addCustomSettingsToForm(\ilPropertyFormGUI $a_form): void
254 {
255 }
256
262 public function saveCustomConfiguration(mixed $form_data): void
263 {
264 throw new \RuntimeException('Not implemented');
265 }
266
270 #[\Deprecated('Will be removed without any alternative, KS/UI forms will be expected', since: '13.0')]
271 public function saveCustomSettings(\ilPropertyFormGUI $a_form): bool
272 {
273 return true;
274 }
275
279 public function addToExternalSettingsForm(int $a_form_id, array &$a_fields, bool $a_is_active): void
280 {
281 }
282
287 public function activationWasToggled(\ilDBInterface $db, \ilSetting $setting, bool $a_currently_active): void
288 {
289 }
290
291 abstract public function getId(): string;
292
293 abstract public function getTitle(): string;
294
295 abstract public function getDescription(): string;
296
300 abstract public function hasAutoActivation(): bool;
301
302 abstract public function hasFlexibleSchedule(): bool;
303
304 abstract public function getDefaultScheduleType(): JobScheduleType;
305
306 abstract public function getDefaultScheduleValue(): ?int;
307
308 abstract public function run(): JobResult;
309}
getScheduleType()
Get current schedule type (if flexible)
Definition: CronJob.php:156
checkSchedule(?\DateTimeImmutable $last_run, ?JobScheduleType $schedule_type, ?int $schedule_value)
Definition: CronJob.php:43
isDue(?\DateTimeImmutable $last_run, ?JobScheduleType $schedule_type, ?int $schedule_value, bool $is_manually_executed=false)
Definition: CronJob.php:135
getCustomConfigurationInput(\ILIAS\UI\Factory $ui_factory, \ILIAS\Refinery\Factory $factory, \ilLanguage $lng)
Definition: CronJob.php:241
Closure $date_time_provider
Definition: CronJob.php:30
setDateTimeProvider(?\Closure $date_time_provider)
Definition: CronJob.php:105
saveCustomConfiguration(mixed $form_data)
Definition: CronJob.php:262
setSchedule(?JobScheduleType $a_type, ?int $a_value)
Update current schedule (if flexible)
Definition: CronJob.php:180
JobScheduleType $schedule_type
Definition: CronJob.php:28
getAllScheduleTypes()
Get all available schedule types.
Definition: CronJob.php:196
getScheduleTypesWithValues()
Definition: CronJob.php:204
getValidScheduleTypes()
Returns a collection of all valid schedule types for a specific job.
Definition: CronJob.php:217
addToExternalSettingsForm(int $a_form_id, array &$a_fields, bool $a_is_active)
Definition: CronJob.php:279
getScheduleValue()
Get current schedule value (if flexible)
Definition: CronJob.php:168
addCustomSettingsToForm(\ilPropertyFormGUI $a_form)
Definition: CronJob.php:253
saveCustomSettings(\ilPropertyFormGUI $a_form)
Definition: CronJob.php:271
checkWeeklySchedule(\DateTimeImmutable $last_run, \DateTimeImmutable $now)
Definition: CronJob.php:32
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...
Definition: CronJob.php:287
hasAutoActivation()
Is to be activated on "installation", does only work for ILIAS core cron jobs.
Builds a Color from either hex- or rgb values.
Definition: Factory.php:31
Definition: UI.php:24
language handling
This class represents a property form user interface.
ILIAS Setting Class.
Interface ilDBInterface.
Interface Observer \BackgroundTasks Contains several chained tasks and infos about them.
global $lng
Definition: privfeed.php:31
if(!file_exists('../ilias.ini.php'))