ILIAS  release_8 Revision v8.24
class.ilCronManagerGUI.php
Go to the documentation of this file.
1<?php
2
19declare(strict_types=1);
20
24
33{
42 private \ILIAS\DI\RBACServices $rbac;
45 private \ILIAS\Refinery\Factory $refinery;
48
49 public function __construct()
50 {
52 global $DIC;
53
54 $this->lng = $DIC->language();
55 $this->ctrl = $DIC->ctrl();
56 $this->settings = $DIC->settings();
57 $this->tpl = $DIC->ui()->mainTemplate();
58 $this->uiFactory = $DIC->ui()->factory();
59 $this->uiRenderer = $DIC->ui()->renderer();
60 $this->uiService = $DIC->uiService();
61 $this->rbac = $DIC->rbac();
62 $this->error = $DIC['ilErr'];
63 $this->httpRequest = $DIC->http()->wrapper();
64 $this->refinery = $DIC->refinery();
65 $this->actor = $DIC->user();
66 $this->cronRepository = $DIC->cron()->repository();
67 $this->cronManager = $DIC->cron()->manager();
68
69 $this->lng->loadLanguageModule('cron');
70 $this->lng->loadLanguageModule('cmps');
71 }
72
80 protected function getRequestValue(
81 string $key,
82 \ILIAS\Refinery\Transformation $trafo,
83 bool $forceRetrieval = false,
84 $default = null
85 ) {
86 $exc = null;
87
88 try {
89 if ($forceRetrieval || $this->httpRequest->query()->has($key)) {
90 return $this->httpRequest->query()->retrieve($key, $trafo);
91 }
92 } catch (OutOfBoundsException $e) {
93 $exc = $e;
94 }
95
96 try {
97 if ($forceRetrieval || $this->httpRequest->post()->has($key)) {
98 return $this->httpRequest->post()->retrieve($key, $trafo);
99 }
100 } catch (OutOfBoundsException $e) {
101 $exc = $e;
102 }
103
104 if ($forceRetrieval && $exc) {
105 throw $exc;
106 }
107
108 return $default ?? null;
109 }
110
111 public function executeCommand(): void
112 {
113 if (!$this->rbac->system()->checkAccess('visible,read', SYSTEM_FOLDER_ID)) {
114 $this->error->raiseError($this->lng->txt('no_permission'), $this->error->WARNING);
115 }
116
117 $class = $this->ctrl->getNextClass($this);
118
120 switch (strtolower($class)) {
121 case strtolower(ilPropertyFormGUI::class):
122 $job_id = $this->getRequestValue('jid', $this->refinery->kindlyTo()->string());
123 $form = $this->initEditForm(ilUtil::stripSlashes($job_id));
124 $this->ctrl->forwardCommand($form);
125 break;
126 }
127
128 $cmd = $this->ctrl->getCmd('render');
129 $this->$cmd();
130 }
131
132 protected function render(): void
133 {
134 $tstamp = $this->lng->txt('cronjob_last_start_unknown');
135 if ($this->settings->get('last_cronjob_start_ts')) {
137 new ilDateTime(
138 $this->settings->get('last_cronjob_start_ts'),
140 )
141 );
142 }
143
144 $message = $this->uiFactory->messageBox()->info($this->lng->txt('cronjob_last_start') . ': ' . $tstamp);
145
146 $cronJobs = $this->cronRepository->findAll();
147
148 $tableFilterMediator = new ilCronManagerTableFilterMediator(
149 $cronJobs,
150 $this->uiFactory,
151 $this->uiService,
152 $this->lng
153 );
154 $filter = $tableFilterMediator->filter($this->ctrl->getFormAction(
155 $this,
156 'render',
157 '',
158 true
159 ));
160
161 $tbl = new ilCronManagerTableGUI(
162 $this,
163 $this->cronRepository,
164 'render',
165 $this->rbac->system()->checkAccess('write', SYSTEM_FOLDER_ID)
166 );
167 $this->tpl->setContent(implode('', [
168 $this->uiRenderer->render([$message, $filter]),
169 $tbl->populate(
170 $tableFilterMediator->filteredJobs(
171 $filter
172 )
173 )->getHTML()
174 ]));
175 }
176
177 public function edit(ilPropertyFormGUI $a_form = null): void
178 {
179 if (!$this->rbac->system()->checkAccess('write', SYSTEM_FOLDER_ID)) {
180 $this->error->raiseError($this->lng->txt('no_permission'), $this->error->WARNING);
181 }
182
183 $job_id = $this->getRequestValue('jid', $this->refinery->kindlyTo()->string());
184 if (!$job_id) {
185 $this->ctrl->redirect($this, 'render');
186 }
187
188 if ($a_form === null) {
189 $a_form = $this->initEditForm($job_id);
190 }
191
192 $this->tpl->setContent($a_form->getHTML());
193 }
194
195 protected function getScheduleTypeFormElementName(int $scheduleTypeId): string
196 {
197 switch ($scheduleTypeId) {
199 return $this->lng->txt('cron_schedule_daily');
200
202 return $this->lng->txt('cron_schedule_weekly');
203
205 return $this->lng->txt('cron_schedule_monthly');
206
208 return $this->lng->txt('cron_schedule_quarterly');
209
211 return $this->lng->txt('cron_schedule_yearly');
212
214 return sprintf($this->lng->txt('cron_schedule_in_minutes'), 'x');
215
217 return sprintf($this->lng->txt('cron_schedule_in_hours'), 'x');
218
220 return sprintf($this->lng->txt('cron_schedule_in_days'), 'x');
221 }
222
223 throw new InvalidArgumentException(sprintf(
224 'The passed argument %s is invalid!',
225 var_export($scheduleTypeId, true)
226 ));
227 }
228
229 protected function getScheduleValueFormElementName(int $scheduleTypeId): string
230 {
231 switch ($scheduleTypeId) {
233 return 'smini';
234
236 return 'shri';
237
239 return 'sdyi';
240 }
241
242 throw new InvalidArgumentException(sprintf(
243 'The passed argument %s is invalid!',
244 var_export($scheduleTypeId, true)
245 ));
246 }
247
248 protected function hasScheduleValue(int $scheduleTypeId): bool
249 {
250 return in_array($scheduleTypeId, [
254 ], true);
255 }
256
257 protected function initEditForm(string $a_job_id): ilPropertyFormGUI
258 {
259 $job = $this->cronRepository->getJobInstanceById($a_job_id);
260 if (!($job instanceof ilCronJob)) {
261 $this->ctrl->redirect($this, 'render');
262 }
263
264 $this->ctrl->setParameter($this, 'jid', $a_job_id);
265
266 $jobs_data = $this->cronRepository->getCronJobData($job->getId());
267 $job_data = $jobs_data[0];
268
269 $form = new ilPropertyFormGUI();
270 $form->setFormAction($this->ctrl->getFormAction($this, 'update'));
271 $form->setTitle($this->lng->txt('cron_action_edit') . ': "' . $job->getTitle() . '"');
272
273 if ($job->hasFlexibleSchedule()) {
274 $type = new ilRadioGroupInputGUI($this->lng->txt('cron_schedule_type'), 'type');
275 $type->setRequired(true);
276 $type->setValue((string) $job_data['schedule_type']);
277
278 foreach ($job->getAllScheduleTypes() as $typeId) {
279 if (!in_array($typeId, $job->getValidScheduleTypes(), true)) {
280 continue;
281 }
282
283 $option = new ilRadioOption(
284 $this->getScheduleTypeFormElementName($typeId),
285 (string) $typeId
286 );
287 $type->addOption($option);
288
289 if (in_array($typeId, $job->getScheduleTypesWithValues(), true)) {
290 $scheduleValue = new ilNumberInputGUI(
291 $this->lng->txt('cron_schedule_value'),
292 $this->getScheduleValueFormElementName($typeId)
293 );
294 $scheduleValue->allowDecimals(false);
295 $scheduleValue->setRequired(true);
296 $scheduleValue->setSize(5);
297 if ((int) $job_data['schedule_type'] === $typeId) {
298 $scheduleValue->setValue($job_data['schedule_value'] === null ? null : (string) $job_data['schedule_value']);
299 }
300 $option->addSubItem($scheduleValue);
301 }
302 }
303
304 $form->addItem($type);
305 }
306
307 if ($job->hasCustomSettings()) {
308 $job->addCustomSettingsToForm($form);
309 }
310
311 $form->addCommandButton('update', $this->lng->txt('save'));
312 $form->addCommandButton('render', $this->lng->txt('cancel'));
313
314 return $form;
315 }
316
317 public function update(): void
318 {
319 if (!$this->rbac->system()->checkAccess('write', SYSTEM_FOLDER_ID)) {
320 $this->error->raiseError($this->lng->txt('no_permission'), $this->error->WARNING);
321 }
322
323 $job_id = $this->getRequestValue('jid', $this->refinery->kindlyTo()->string());
324 if (!$job_id) {
325 $this->ctrl->redirect($this, 'render');
326 }
327
328 $form = $this->initEditForm($job_id);
329 if ($form->checkInput()) {
330 $job = $this->cronRepository->getJobInstanceById($job_id);
331 if ($job instanceof ilCronJob) {
332 $valid = true;
333 if ($job->hasCustomSettings() && !$job->saveCustomSettings($form)) {
334 $valid = false;
335 }
336
337 if ($valid && $job->hasFlexibleSchedule()) {
338 $type = (int) $form->getInput('type');
339 switch (true) {
340 case $this->hasScheduleValue($type):
341 $value = (int) $form->getInput($this->getScheduleValueFormElementName($type));
342 break;
343
344 default:
345 $value = null;
346 break;
347 }
348
349 $this->cronRepository->updateJobSchedule($job, $type, $value);
350 }
351
352 if ($valid) {
353 $this->tpl->setOnScreenMessage('success', $this->lng->txt('cron_action_edit_success'), true);
354 $this->ctrl->redirect($this, 'render');
355 }
356 }
357 }
358
359 $form->setValuesByPost();
360 $this->edit($form);
361 }
362
363 public function run(): void
364 {
365 $this->confirm('run');
366 }
367
368 public function confirmedRun(): void
369 {
370 if (!$this->rbac->system()->checkAccess('write', SYSTEM_FOLDER_ID)) {
371 $this->error->raiseError($this->lng->txt('no_permission'), $this->error->WARNING);
372 }
373
374 $job_id = $this->getRequestValue('jid', $this->refinery->kindlyTo()->string());
375 if ($job_id) {
376 if ($this->cronManager->runJobManual($job_id, $this->actor)) {
377 $this->tpl->setOnScreenMessage('success', $this->lng->txt('cron_action_run_success'), true);
378 } else {
379 $this->tpl->setOnScreenMessage('failure', $this->lng->txt('cron_action_run_fail'), true);
380 }
381 }
382
383 $this->ctrl->redirect($this, 'render');
384 }
385
386 public function activate(): void
387 {
388 $this->confirm('activate');
389 }
390
391 public function confirmedActivate(): void
392 {
393 if (!$this->rbac->system()->checkAccess('write', SYSTEM_FOLDER_ID)) {
394 $this->error->raiseError($this->lng->txt('no_permission'), $this->error->WARNING);
395 }
396
397 $jobs = $this->getMultiActionData();
398 if ($jobs !== []) {
399 foreach ($jobs as $job) {
400 if ($this->cronManager->isJobInactive($job->getId())) {
401 $this->cronManager->resetJob($job, $this->actor);
402 }
403 }
404
405 $this->tpl->setOnScreenMessage('success', $this->lng->txt('cron_action_activate_success'), true);
406 } else {
407 $this->tpl->setOnScreenMessage('info', $this->lng->txt('no_checkbox'), true);
408 }
409
410 $this->ctrl->redirect($this, 'render');
411 }
412
413 public function deactivate(): void
414 {
415 $this->confirm('deactivate');
416 }
417
418 public function confirmedDeactivate(): void
419 {
420 if (!$this->rbac->system()->checkAccess('write', SYSTEM_FOLDER_ID)) {
421 $this->error->raiseError($this->lng->txt('no_permission'), $this->error->WARNING);
422 }
423
424 $jobs = $this->getMultiActionData();
425 if ($jobs !== []) {
426 foreach ($jobs as $job) {
427 if ($this->cronManager->isJobActive($job->getId())) {
428 $this->cronManager->deactivateJob($job, $this->actor, true);
429 }
430 }
431
432 $this->tpl->setOnScreenMessage('success', $this->lng->txt('cron_action_deactivate_success'), true);
433 } else {
434 $this->tpl->setOnScreenMessage('info', $this->lng->txt('no_checkbox'), true);
435 }
436
437 $this->ctrl->redirect($this, 'render');
438 }
439
440 public function reset(): void
441 {
442 $this->confirm('reset');
443 }
444
445 public function confirmedReset(): void
446 {
447 if (!$this->rbac->system()->checkAccess('write', SYSTEM_FOLDER_ID)) {
448 $this->error->raiseError($this->lng->txt('no_permission'), $this->error->WARNING);
449 }
450
451 $jobs = $this->getMultiActionData();
452 if ($jobs !== []) {
453 foreach ($jobs as $job) {
454 $this->cronManager->resetJob($job, $this->actor);
455 }
456 $this->tpl->setOnScreenMessage('success', $this->lng->txt('cron_action_reset_success'), true);
457 } else {
458 $this->tpl->setOnScreenMessage('info', $this->lng->txt('no_checkbox'), true);
459 }
460
461 $this->ctrl->redirect($this, 'render');
462 }
463
467 protected function getMultiActionData(): array
468 {
469 $res = [];
470
471 $job_ids = [];
472 try {
473 try {
474 $job_ids = [$this->getRequestValue('jid', $this->refinery->kindlyTo()->string(), true)];
475 } catch (\ILIAS\Refinery\ConstraintViolationException | OutOfBoundsException $e) {
476 $job_ids = $this->getRequestValue('mjid', $this->refinery->kindlyTo()->listOf(
477 $this->refinery->kindlyTo()->string()
478 ), false, []);
479 }
480 } catch (\ILIAS\Refinery\ConstraintViolationException | OutOfBoundsException $e) {
481 }
482
483 foreach ($job_ids as $job_id) {
484 $job = $this->cronRepository->getJobInstanceById($job_id);
485 if ($job instanceof ilCronJob) {
486 $res[$job_id] = $job;
487 }
488 }
489
490 return $res;
491 }
492
493 protected function confirm(string $a_action): void
494 {
495 if (!$this->rbac->system()->checkAccess('write', SYSTEM_FOLDER_ID)) {
496 $this->error->raiseError($this->lng->txt('no_permission'), $this->error->WARNING);
497 }
498
499 $jobs = $this->getMultiActionData();
500 if ($jobs === []) {
501 $this->tpl->setOnScreenMessage('info', $this->lng->txt('no_checkbox'), true);
502 $this->ctrl->redirect($this, 'render');
503 }
504
505 if ('run' === $a_action) {
506 $jobs = array_filter($jobs, static function (ilCronJob $job): bool {
507 return $job->isManuallyExecutable();
508 });
509
510 if ($jobs === []) {
511 $this->tpl->setOnScreenMessage('failure', $this->lng->txt('cron_no_executable_job_selected'), true);
512 $this->ctrl->redirect($this, 'render');
513 }
514 }
515
516 $cgui = new ilConfirmationGUI();
517
518 if (1 === count($jobs)) {
519 $jobKeys = array_keys($jobs);
520 $job_id = array_pop($jobKeys);
521 $job = array_pop($jobs);
522 $title = $job->getTitle();
523 if (!$title) {
524 $title = preg_replace('[^A-Za-z0-9_\-]', '', $job->getId());
525 }
526
527 $cgui->setHeaderText(sprintf(
528 $this->lng->txt('cron_action_' . $a_action . '_sure'),
529 $title
530 ));
531
532 $this->ctrl->setParameter($this, 'jid', $job_id);
533 } else {
534 $cgui->setHeaderText($this->lng->txt('cron_action_' . $a_action . '_sure_multi'));
535
536 foreach ($jobs as $job_id => $job) {
537 $cgui->addItem('mjid[]', $job_id, $job->getTitle());
538 }
539 }
540
541 $cgui->setFormAction($this->ctrl->getFormAction($this, 'confirmed' . ucfirst($a_action)));
542 $cgui->setCancel($this->lng->txt('cancel'), 'render');
543 $cgui->setConfirm($this->lng->txt('cron_action_' . $a_action), 'confirmed' . ucfirst($a_action));
544
545 $this->tpl->setContent($cgui->getHTML());
546 }
547
548 public function addToExternalSettingsForm(int $a_form_id): array
549 {
550 $form_elements = [];
551 $fields = [];
552 $data = $this->cronRepository->getCronJobData();
553 foreach ($data as $item) {
554 $job = $this->cronRepository->getJobInstance(
555 $item['job_id'],
556 $item['component'],
557 $item['class']
558 );
559 if (!is_null($job)) {
560 $job->addToExternalSettingsForm($a_form_id, $fields, (bool) $item['job_status']);
561 }
562 }
563
564 if ($fields !== []) {
565 $form_elements = [
566 'cron_jobs' => [
567 'jumpToCronJobs',
568 $fields
569 ]
570 ];
571 }
572
573 return $form_elements;
574 }
575}
const IL_CAL_UNIX
error(string $a_errmsg)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
const SCHEDULE_TYPE_IN_DAYS
@depracated This will be replaced with an ENUM in ILIAS 9
const SCHEDULE_TYPE_IN_HOURS
@depracated This will be replaced with an ENUM in ILIAS 9
const SCHEDULE_TYPE_IN_MINUTES
@depracated This will be replaced with an ENUM in ILIAS 9
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
const SCHEDULE_TYPE_DAILY
@depracated This will be replaced with an ENUM in ILIAS 9
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
Class ilCronManagerGUI.
getRequestValue(string $key, \ILIAS\Refinery\Transformation $trafo, bool $forceRetrieval=false, $default=null)
getScheduleTypeFormElementName(int $scheduleTypeId)
ILIAS DI RBACServices $rbac
edit(ilPropertyFormGUI $a_form=null)
ilGlobalTemplateInterface $tpl
addToExternalSettingsForm(int $a_form_id)
getScheduleValueFormElementName(int $scheduleTypeId)
ILIAS Refinery Factory $refinery
WrapperFactory $httpRequest
hasScheduleValue(int $scheduleTypeId)
initEditForm(string $a_job_id)
ilCronJobRepository $cronRepository
confirm(string $a_action)
static formatDate(ilDateTime $date, bool $a_skip_day=false, bool $a_include_wd=false, bool $include_seconds=false)
@classDescription Date and time handling
Error Handling & global info handling uses PEAR error class.
language handling
This class represents a number property in a property form.
User class.
This class represents a property form user interface.
This class represents a property in a property form.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
Filter service.
static stripSlashes(string $a_str, bool $a_strip_html=true, string $a_allow="")
const SYSTEM_FOLDER_ID
Definition: constants.php:35
$valid
global $DIC
Definition: feed.php:28
This is how the factory for UI elements looks.
Definition: Factory.php:38
An entity that renders components to a string output.
Definition: Renderer.php:31
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
$typeId
Definition: ltiregstart.php:36
$res
Definition: ltiservices.php:69
__construct(Container $dic, ilPlugin $plugin)
@inheritDoc
string $key
Consumer key/client ID value.
Definition: System.php:193
Class ChatMainBarProvider \MainMenu\Provider.
$type
$message
Definition: xapiexit.php:32