ILIAS  trunk Revision v12.0_alpha-1227-g7ff6d300864
class.ilObjCronGUI.php
Go to the documentation of this file.
1<?php
2
19declare(strict_types=1);
20
31use ILIAS\Data\Factory as DataFactory;
32
38final class ilObjCronGUI extends ilObjectGUI
39{
40 private const array TABLE_ACTION_NAMESPACE = ['cron', 'jobs'];
41 private const string TABLE_ACTION_PARAM_NAME = 'table_action';
42 private const string TABLE_ACTION_IDENTIFIER_NAME = 'jid';
43 private const string FORM_PARAM_SCHEDULE_PREFIX = 'schedule_';
44 public const string VIEW = 'view';
45 public const FORM_PARAM_MAIN_SECTION = 'main';
46 public const FORM_PARAM_JOB_INPUT = 'additional_job_input';
47 public const FORM_PARAM_GROUP_SCHEDULE = 'schedule';
48
49 private readonly ilUIService $ui_service;
51 private readonly \ILIAS\DI\RBACServices $rbac;
52 private readonly WrapperFactory $http_wrapper;
53 private readonly JobManager $cron_manager;
54 private readonly DataFactory $data_factory;
55
56 public function __construct()
57 {
58 global $DIC;
59 parent::__construct(...func_get_args());
60
61 $this->ui_service = $DIC->uiService();
62 $this->rbac = $DIC->rbac();
63 $this->http_wrapper = $DIC->http()->wrapper();
64 $this->cron_repository = $DIC->cron()->repository();
65 $this->cron_manager = $DIC->cron()->manager();
66 $this->data_factory = new DataFactory();
67
68 $this->lng->loadLanguageModule('cron');
69 $this->lng->loadLanguageModule('cmps');
70 }
71
72 public static function create(): self
73 {
74 return new self(null, current(ilObject::_getAllReferences(current(
76 )['id'])), true, false);
77 }
78
82 private function retrieveTableActionJobIds(): array
83 {
84 $retrieval = $this->http_wrapper->query();
85 if (strtoupper($this->http->request()->getMethod()) === 'POST') {
86 $retrieval = $this->http_wrapper->post();
87 }
88
89 $trafo = $this->refinery->byTrying([
90 $this->refinery->kindlyTo()->listOf($this->refinery->kindlyTo()->string()),
91 $this->refinery->always([])
92 ]);
93
94 $ids = $retrieval->retrieve(
95 $this->getJobIdParameterName(),
96 $trafo
97 );
98
99 if (count($ids) === 1 && $ids[0] === 'ALL_OBJECTS') {
100 $tableFilterMediator = new JobTableFilterMediator(
101 $this->cron_repository->findAll(),
102 $this->ui_factory,
103 $this->ui_service,
104 $this->lng
105 );
106 $filter = $tableFilterMediator->filter(
107 $this->ctrl->getFormAction(
108 $this,
109 self::VIEW,
110 '',
111 true
112 )
113 );
114 $ids = array_map(
115 static fn(JobEntity $entity): string => $entity->getEffectiveJobId(),
116 $tableFilterMediator->filteredJobs(
117 $filter
118 )->toArray()
119 );
120 }
121
122 return $ids;
123 }
124
125 private function getTableActionParameterName(): string
126 {
127 return implode('_', array_merge(self::TABLE_ACTION_NAMESPACE, [self::TABLE_ACTION_PARAM_NAME]));
128 }
129
134 private function addProblematicItemsInfo(
135 \ILIAS\Cron\Job\JobCollection $filtered_jobs,
136 \ILIAS\UI\Component\MessageBox\MessageBox $message,
137 array $components
138 ): array {
139 $problematic_jobs = $filtered_jobs->filter(static function (JobEntity $entity): bool {
140 return $entity->getJobResultStatus() === JobResult::STATUS_CRASHED;
141 });
142 if (count($problematic_jobs) > 0) {
143 $problematic_jobs_info = $this->ui_factory->messageBox()->info(
144 $this->lng->txt('cron_jobs_with_required_intervention')
145 )->withLinks(
146 array_map(
147 function (JobEntity $entity): \ILIAS\UI\Component\Link\Standard {
148 return $this->ui_factory->link()->standard(
149 $entity->getEffectiveTitle(),
150 '#job-' . $entity->getEffectiveJobId()
151 );
152 },
154 $problematic_jobs,
155 OrderedJobEntities::ORDER_BY_NAME
156 ))->toArray()
157 )
158 );
159
160 if (in_array($message, $components, true)) {
161 $components = array_merge(
162 array_slice($components, 0, array_search($message, $components, true) + 1),
163 [$problematic_jobs_info],
164 array_slice($components, array_search($message, $components, true) + 1)
165 );
166 } else {
167 array_unshift($components, $problematic_jobs_info);
168 }
169 }
170
171 return $components;
172 }
173
174 private function getJobIdParameterName(): string
175 {
176 return implode('_', array_merge(self::TABLE_ACTION_NAMESPACE, [self::TABLE_ACTION_IDENTIFIER_NAME]));
177 }
178
183 private function getRequestValue(
184 string $key,
185 \ILIAS\Refinery\Transformation $trafo,
186 bool $force_retrieval = false,
187 $default = null
188 ) {
189 $exc = null;
190
191 try {
192 if ($force_retrieval || $this->http_wrapper->query()->has($key)) {
193 return $this->http_wrapper->query()->retrieve($key, $trafo);
194 }
195 } catch (OutOfBoundsException $e) {
196 $exc = $e;
197 }
198
199 try {
200 if ($force_retrieval || $this->http_wrapper->post()->has($key)) {
201 return $this->http_wrapper->post()->retrieve($key, $trafo);
202 }
203 } catch (OutOfBoundsException $e) {
204 $exc = $e;
205 }
206
207 if ($force_retrieval && $exc) {
208 throw $exc;
209 }
210
211 return $default ?? null;
212 }
213
214 public function executeCommand(): void
215 {
216 if (!$this->rbac->system()->checkAccess('read', $this->ref_id)) {
217 $this->error->raiseError($this->lng->txt('no_permission'), $this->error->WARNING);
218 }
219
220 $this->prepareOutput();
221
222 $class = $this->ctrl->getNextClass($this) ?? '';
223
224 switch (strtolower($class)) {
225 case strtolower(ilPropertyFormGUI::class):
226 $this->tabs_gui->activateTab(self::VIEW);
227 $entity = $this->cron_repository->getEntityById(
229 $this->getRequestValue($this->getJobIdParameterName(), $this->refinery->kindlyTo()->string())
230 )
231 );
232 if ($entity === null) {
233 $this->ctrl->redirect($this, self::VIEW);
234 }
235
236 $form = $this->initLegacyEditForm($entity);
237 $this->ctrl->forwardCommand($form);
238 return;
239
240 case strtolower(ilPermissionGUI::class):
241 $this->ctrl->forwardCommand(new ilPermissionGUI($this));
242 return;
243 }
244
245 $this->tabs_gui->activateTab(self::VIEW);
246 $cmd = $this->ctrl->getCmd(self::VIEW);
247 $this->$cmd();
248 }
249
250 private function handleTableActions(): void
251 {
252 $action = $this->http_wrapper->query()->retrieve(
253 $this->getTableActionParameterName(),
254 $this->refinery->byTrying([
255 $this->refinery->kindlyTo()->string(),
256 $this->refinery->always('')
257 ])
258 );
259 match ($action) {
260 'run' => $this->run(),
261 'activate' => $this->activate(),
262 'deactivate' => $this->deactivate(),
263 'reset' => $this->reset(),
264 'edit' => $this->edit(),
265 default => $this->view()
266 };
267 }
268
269 protected function view(): void
270 {
271 $tstamp = $this->lng->txt('cronjob_last_start_unknown');
272 if ($this->settings->get('last_cronjob_start_ts')) {
274 new ilDateTime(
275 $this->settings->get('last_cronjob_start_ts'),
277 )
278 );
279 }
280
281 $message = $this->ui_factory->messageBox()->info($this->lng->txt('cronjob_last_start') . ': ' . $tstamp);
282
283 $cronJobs = $this->cron_repository->findAll();
284
285 $tableFilterMediator = new JobTableFilterMediator(
286 $cronJobs,
287 $this->ui_factory,
288 $this->ui_service,
289 $this->lng
290 );
291 $filter = $tableFilterMediator->filter(
292 $this->ctrl->getFormAction(
293 $this,
294 self::VIEW,
295 '',
296 true
297 )
298 );
299
300 $filtered_jobs = $tableFilterMediator->filteredJobs(
301 $filter
302 );
303
304 $tbl = new JobTable(
305 $this->data_factory->uri(ilUtil::_getHttpPath() . '/' . $this->ctrl->getLinkTarget($this, 'handleTableActions')),
306 self::TABLE_ACTION_NAMESPACE,
307 self::TABLE_ACTION_PARAM_NAME,
308 self::TABLE_ACTION_IDENTIFIER_NAME,
309 $this->ui_factory,
310 $this->http->request(),
311 $this->lng,
312 $filtered_jobs,
313 $this->cron_repository,
314 $this->rbac->system()->checkAccess('write', $this->ref_id)
315 );
316
317 $this->tpl->setContent(
318 $this->ui_renderer->render(
319 $this->addProblematicItemsInfo(
320 $filtered_jobs,
321 $message,
322 [$message, $filter, $tbl->getComponent()]
323 )
324 )
325 );
326 }
327
328 public function edit(?ILIAS\UI\Component\Input\Container\Form\Form $form = null): void
329 {
330 if (!$this->rbac->system()->checkAccess('write', $this->ref_id)) {
331 $this->error->raiseError($this->lng->txt('no_permission'), $this->error->WARNING);
332 }
333
334 if ($form === null) {
335 $job_ids = $this->retrieveTableActionJobIds();
336 if (count($job_ids) !== 1) {
337 $this->ctrl->redirect($this, self::VIEW);
338 }
339
340 $job_id = current($job_ids);
341 $entity = $this->cron_repository->getEntityById($job_id);
342 if ($entity === null) {
343 $this->ctrl->redirect($this, self::VIEW);
344 }
345
346 if ($entity->getJob()->usesLegacyForms()) {
347 $this->ctrl->setParameter($this, $this->getJobIdParameterName(), $entity->getEffectiveJobId());
348 $this->ctrl->redirect($this, 'editLegacy');
349 }
350
351 $form = $this->buildForm($entity);
352 }
353
354 $this->tpl->setContent($this->ui_renderer->render($form));
355 }
356
357 public function editLegacy(?ilPropertyFormGUI $a_form = null): void
358 {
359 if (!$this->rbac->system()->checkAccess('write', $this->ref_id)) {
360 $this->error->raiseError($this->lng->txt('no_permission'), $this->error->WARNING);
361 }
362
363 if ($a_form === null) {
364 $job_ids = $this->retrieveTableActionJobIds();
365 if (count($job_ids) !== 1) {
366 $this->ctrl->redirect($this, self::VIEW);
367 }
368
369 $job_id = current($job_ids);
370 $entity = $this->cron_repository->getEntityById($job_id);
371 if ($entity === null) {
372 $this->ctrl->redirect($this, self::VIEW);
373 }
374
375 $a_form = $this->initLegacyEditForm($entity);
376 }
377
378 $this->tpl->setContent($a_form->getHTML());
379 }
380
381 private function getScheduleTypeFormElementName(JobScheduleType $schedule_type): string
382 {
383 return match ($schedule_type) {
384 JobScheduleType::DAILY => $this->lng->txt('cron_schedule_daily'),
385 JobScheduleType::WEEKLY => $this->lng->txt('cron_schedule_weekly'),
386 JobScheduleType::MONTHLY => $this->lng->txt('cron_schedule_monthly'),
387 JobScheduleType::QUARTERLY => $this->lng->txt('cron_schedule_quarterly'),
388 JobScheduleType::YEARLY => $this->lng->txt('cron_schedule_yearly'),
389 JobScheduleType::IN_MINUTES => sprintf($this->lng->txt('cron_schedule_in_minutes'), 'x'),
390 JobScheduleType::IN_HOURS => sprintf($this->lng->txt('cron_schedule_in_hours'), 'x'),
391 JobScheduleType::IN_DAYS => sprintf($this->lng->txt('cron_schedule_in_days'), 'x'),
392 };
393 }
394
395 protected function getScheduleValueFormElementName(JobScheduleType $schedule_type): string
396 {
397 return match ($schedule_type) {
398 JobScheduleType::IN_MINUTES => 'smini',
399 JobScheduleType::IN_HOURS => 'shri',
400 JobScheduleType::IN_DAYS => 'sdyi',
401 default => throw new InvalidArgumentException(
402 sprintf(
403 'The passed argument %s is invalid!',
404 var_export($schedule_type, true)
405 )
406 ),
407 };
408 }
409
410 protected function hasScheduleValue(JobScheduleType $schedule_type): bool
411 {
412 return in_array($schedule_type, [
413 JobScheduleType::IN_MINUTES,
414 JobScheduleType::IN_HOURS,
415 JobScheduleType::IN_DAYS
416 ], true);
417 }
418
419 protected function buildForm(JobEntity $entity): ILIAS\UI\Component\Input\Container\Form\Form
420 {
421 $job = $entity->getJob();
422
423 $this->ctrl->setParameter($this, $this->getJobIdParameterName(), $entity->getEffectiveJobId());
424
425 $section_inputs = [];
426 if ($job->hasFlexibleSchedule()) {
427 $schedule_type_groups = [];
428 foreach ($job->getAllScheduleTypes() as $schedule_type) {
429 if (!in_array($schedule_type, $job->getValidScheduleTypes(), true)) {
430 continue;
431 }
432
433 $schedule_type_inputs = [];
434 if (in_array($schedule_type, $job->getScheduleTypesWithValues(), true)) {
435 $schedule_value_input = $this->ui_factory
436 ->input()
437 ->field()
438 ->numeric(
439 $this->lng->txt('cron_schedule_value')
440 )->withAdditionalTransformation(
441 $this->refinery->in()->series([
442 $this->refinery->int()->isGreaterThanOrEqual(1)
443 ])
444 )->withRequired(true);
445
446 if (is_numeric($entity->getRawScheduleType()) &&
447 JobScheduleType::tryFrom((int) $entity->getRawScheduleType()) === $schedule_type) {
448 $schedule_value_input = $schedule_value_input->withValue(
449 $entity->getRawScheduleValue() === null ? null : (int) $entity->getRawScheduleValue()
450 );
451 }
452
453 $schedule_type_inputs = [
454 $this->getScheduleValueFormElementName($schedule_type) => $schedule_value_input
455 ];
456 }
457
458 $schedule_type_groups[self::FORM_PARAM_SCHEDULE_PREFIX . $schedule_type->value] = $this->ui_factory
459 ->input()
460 ->field()
461 ->group(
462 $schedule_type_inputs,
463 $this->getScheduleTypeFormElementName($schedule_type)
464 )
465 ->withDedicatedName(self::FORM_PARAM_SCHEDULE_PREFIX . $schedule_type->value);
466 }
467
468 $default_schedule_type = current($job->getValidScheduleTypes())->value;
469
470 $section_inputs['schedule'] = $this->ui_factory
471 ->input()
472 ->field()
473 ->switchableGroup(
474 $schedule_type_groups,
475 $this->lng->txt('cron_schedule_type')
476 )
477 ->withRequired(true)
478 ->withValue(
479 $entity->getRawScheduleType() === null ?
480 self::FORM_PARAM_SCHEDULE_PREFIX . $default_schedule_type :
481 self::FORM_PARAM_SCHEDULE_PREFIX . $entity->getRawScheduleType()
482 );
483 }
484
485 $main_section = $this->ui_factory->input()->field()->section(
486 $section_inputs,
487 $this->lng->txt('cron_action_edit') . ': "' . $job->getTitle() . '"'
488 );
489
490 $inputs = [
491 self::FORM_PARAM_MAIN_SECTION => $main_section
492 ];
493
494 if ($job->hasCustomSettings()) {
495 $inputs = array_merge(
496 $inputs,
497 [
498 self::FORM_PARAM_JOB_INPUT =>
499 $job->getCustomConfigurationInput(
500 $this->ui_factory,
501 $this->refinery,
502 $this->lng
503 )
504 ]
505 );
506 }
507
508 return $this->ui_factory
509 ->input()
510 ->container()
511 ->form()
512 ->standard($this->ctrl->getFormAction($this, 'update'), $inputs)
513 ->withDedicatedName('cron_form');
514 }
515
519 #[\Deprecated('Will be removed without any alternative, KS/UI forms will be expected', since: '11.0')]
520 protected function initLegacyEditForm(JobEntity $entity): ilPropertyFormGUI
521 {
522 $job = $entity->getJob();
523
524 $this->ctrl->setParameter($this, $this->getJobIdParameterName(), $entity->getEffectiveJobId());
525
526 $form = new ilPropertyFormGUI();
527 $form->setFormAction($this->ctrl->getFormAction($this, 'updateLegacy'));
528 $form->setTitle($this->lng->txt('cron_action_edit') . ': "' . $job->getTitle() . '"');
529
530 if ($job->hasFlexibleSchedule()) {
531 $type = new ilRadioGroupInputGUI($this->lng->txt('cron_schedule_type'), 'type');
532 $type->setRequired(true);
533 $type->setValue(
534 $entity->getRawScheduleType() === null ? null : (string) $entity->getRawScheduleType()
535 );
536
537 foreach ($job->getAllScheduleTypes() as $schedule_type) {
538 if (!in_array($schedule_type, $job->getValidScheduleTypes(), true)) {
539 continue;
540 }
541
542 $option = new ilRadioOption(
543 $this->getScheduleTypeFormElementName($schedule_type),
544 (string) $schedule_type->value
545 );
546 $type->addOption($option);
547
548 if (in_array($schedule_type, $job->getScheduleTypesWithValues(), true)) {
549 $scheduleValue = new ilNumberInputGUI(
550 $this->lng->txt('cron_schedule_value'),
551 $this->getScheduleValueFormElementName($schedule_type)
552 );
553 $scheduleValue->allowDecimals(false);
554 $scheduleValue->setRequired(true);
555 $scheduleValue->setSize(5);
556 if (is_numeric($entity->getRawScheduleType()) &&
557 JobScheduleType::tryFrom((int) $entity->getRawScheduleType()) === $schedule_type) {
558 $scheduleValue->setValue(
559 $entity->getRawScheduleValue() === null ? null : (string) $entity->getRawScheduleValue()
560 );
561 }
562 $option->addSubItem($scheduleValue);
563 }
564 }
565
566 $form->addItem($type);
567 }
568
569 if ($job->hasCustomSettings()) {
570 $job->addCustomSettingsToForm($form);
571 }
572
573 $form->addCommandButton('updateLegacy', $this->lng->txt('save'));
574 $form->addCommandButton(self::VIEW, $this->lng->txt('cancel'));
575
576 return $form;
577 }
578
579 public function update(): void
580 {
581 if (!$this->rbac->system()->checkAccess('write', $this->ref_id)) {
582 $this->error->raiseError($this->lng->txt('no_permission'), $this->error->WARNING);
583 }
584
585 $job_id = $this->getRequestValue($this->getJobIdParameterName(), $this->refinery->kindlyTo()->string());
586 if (!$job_id) {
587 $this->ctrl->redirect($this, self::VIEW);
588 }
589
590 $entity = $this->cron_repository->getEntityById($job_id);
591 if ($entity === null) {
592 $this->ctrl->redirect($this, self::VIEW);
593 }
594
595 $form = $this->buildForm($entity);
596
597 $form_valid = false;
598 $form_data = null;
599 if ($this->http->request()->getMethod() === 'POST') {
600 $form = $form->withRequest($this->http->request());
601 $form_data = $form->getData();
602 $form_valid = $form_data !== null;
603 }
604
605 if (!$form_valid) {
606 $this->edit($form);
607 return;
608 }
609
610 $job = $entity->getJob();
611 if ($job->hasFlexibleSchedule()) {
612 $schedule_group = $form_data[self::FORM_PARAM_MAIN_SECTION][self::FORM_PARAM_GROUP_SCHEDULE];
613
614 $type = JobScheduleType::from(
615 (int) ltrim($schedule_group[0], self::FORM_PARAM_SCHEDULE_PREFIX)
616 );
617
618 $value = match (true) {
619 $this->hasScheduleValue($type) => (int) $schedule_group[1][$this->getScheduleValueFormElementName(
620 $type
621 )],
622 default => null,
623 };
624
625 $this->cron_repository->updateJobSchedule($job, $type, $value);
626 }
627
628 if ($job->hasCustomSettings()) {
629 $job->saveCustomConfiguration($form_data[self::FORM_PARAM_JOB_INPUT]);
630 }
631
632 $this->tpl->setOnScreenMessage('success', $this->lng->txt('cron_action_edit_success'), true);
633 $this->ctrl->redirect($this, self::VIEW);
634 }
635
639 #[\Deprecated('Will be removed without any alternative, KS/UI forms will be expected', since: '11.0')]
640 public function updateLegacy(): void
641 {
642 if (!$this->rbac->system()->checkAccess('write', $this->ref_id)) {
643 $this->error->raiseError($this->lng->txt('no_permission'), $this->error->WARNING);
644 }
645
646 $job_id = $this->getRequestValue($this->getJobIdParameterName(), $this->refinery->kindlyTo()->string());
647 if (!$job_id) {
648 $this->ctrl->redirect($this, self::VIEW);
649 }
650
651 $entity = $this->cron_repository->getEntityById($job_id);
652 if ($entity === null) {
653 $this->ctrl->redirect($this, self::VIEW);
654 }
655
656 $form = $this->initLegacyEditForm($entity);
657 $job = $entity->getJob();
658 if ($form->checkInput()) {
659 $valid = true;
660 if ($job->hasCustomSettings() && !$job->saveCustomSettings($form)) {
661 $valid = false;
662 }
663
664 if ($valid && $job->hasFlexibleSchedule()) {
665 $type = JobScheduleType::from((int) $form->getInput('type'));
666 $value = match (true) {
667 $this->hasScheduleValue($type) => (int) $form->getInput(
668 $this->getScheduleValueFormElementName($type)
669 ),
670 default => null,
671 };
672
673 $this->cron_repository->updateJobSchedule($job, $type, $value);
674 }
675
676 if ($valid) {
677 $this->tpl->setOnScreenMessage('success', $this->lng->txt('cron_action_edit_success'), true);
678 $this->ctrl->redirect($this, self::VIEW);
679 }
680 }
681
682 $form->setValuesByPost();
683 $this->editLegacy($form);
684 }
685
686 public function run(): void
687 {
688 $this->confirm('run');
689 }
690
691 public function confirmedRun(): void
692 {
693 if (!$this->rbac->system()->checkAccess('write', $this->ref_id)) {
694 $this->error->raiseError($this->lng->txt('no_permission'), $this->error->WARNING);
695 }
696
697 $job_ids = $this->retrieveTableActionJobIds();
698 if (count($job_ids) !== 1) {
699 $this->ctrl->redirect($this, self::VIEW);
700 }
701
702 $job_id = current($job_ids);
703 if ($this->cron_manager->runJobManual($job_id, $this->user)) {
704 $this->tpl->setOnScreenMessage('success', $this->lng->txt('cron_action_run_success'), true);
705 } else {
706 $this->tpl->setOnScreenMessage('failure', $this->lng->txt('cron_action_run_fail'), true);
707 }
708
709 $this->ctrl->redirect($this, self::VIEW);
710 }
711
712 public function activate(): void
713 {
714 $this->confirm('activate');
715 }
716
717 public function confirmedActivate(): void
718 {
719 if (!$this->rbac->system()->checkAccess('write', $this->ref_id)) {
720 $this->error->raiseError($this->lng->txt('no_permission'), $this->error->WARNING);
721 }
722
723 $jobs = $this->getMultiActionData();
724 if ($jobs !== []) {
725 foreach ($jobs as $job) {
726 if ($this->cron_manager->isJobInactive($job->getId())) {
727 $this->cron_manager->resetJob($job, $this->user);
728 }
729 }
730
731 $this->tpl->setOnScreenMessage('success', $this->lng->txt('cron_action_activate_success'), true);
732 } else {
733 $this->tpl->setOnScreenMessage('info', $this->lng->txt('no_checkbox'), true);
734 }
735
736 $this->ctrl->redirect($this, self::VIEW);
737 }
738
739 public function deactivate(): void
740 {
741 $this->confirm('deactivate');
742 }
743
744 public function confirmedDeactivate(): void
745 {
746 if (!$this->rbac->system()->checkAccess('write', $this->ref_id)) {
747 $this->error->raiseError($this->lng->txt('no_permission'), $this->error->WARNING);
748 }
749
750 $jobs = $this->getMultiActionData();
751 if ($jobs !== []) {
752 foreach ($jobs as $job) {
753 if ($this->cron_manager->isJobActive($job->getId())) {
754 $this->cron_manager->deactivateJob($job, $this->user, true);
755 }
756 }
757
758 $this->tpl->setOnScreenMessage('success', $this->lng->txt('cron_action_deactivate_success'), true);
759 } else {
760 $this->tpl->setOnScreenMessage('info', $this->lng->txt('no_checkbox'), true);
761 }
762
763 $this->ctrl->redirect($this, self::VIEW);
764 }
765
766 public function reset(): void
767 {
768 $this->confirm('reset');
769 }
770
771 public function confirmedReset(): void
772 {
773 if (!$this->rbac->system()->checkAccess('write', $this->ref_id)) {
774 $this->error->raiseError($this->lng->txt('no_permission'), $this->error->WARNING);
775 }
776
777 $jobs = $this->getMultiActionData();
778 if ($jobs !== []) {
779 foreach ($jobs as $job) {
780 $this->cron_manager->resetJob($job, $this->user);
781 }
782 $this->tpl->setOnScreenMessage('success', $this->lng->txt('cron_action_reset_success'), true);
783 } else {
784 $this->tpl->setOnScreenMessage('info', $this->lng->txt('no_checkbox'), true);
785 }
786
787 $this->ctrl->redirect($this, self::VIEW);
788 }
789
793 protected function getMultiActionData(): array
794 {
795 $res = [];
796
797 $job_ids = [];
798 try {
799 $job_ids = $this->retrieveTableActionJobIds();
800 } catch (\ILIAS\Refinery\ConstraintViolationException|OutOfBoundsException) {
801 }
802
803 foreach ($job_ids as $job_id) {
804 $job = $this->cron_repository->getJobInstanceById($job_id);
805 if ($job instanceof CronJob) {
806 $res[$job_id] = $job;
807 }
808 }
809
810 return $res;
811 }
812
813 protected function confirm(string $a_action): void
814 {
815 if (!$this->rbac->system()->checkAccess('write', $this->ref_id)) {
816 $this->error->raiseError($this->lng->txt('no_permission'), $this->error->WARNING);
817 }
818
819 $jobs = $this->getMultiActionData();
820 if ($jobs === []) {
821 $this->tpl->setOnScreenMessage('info', $this->lng->txt('no_checkbox'), true);
822 $this->ctrl->redirect($this, self::VIEW);
823 }
824
825 if ($a_action === 'run') {
826 $jobs = array_filter($jobs, static function (CronJob $job): bool {
827 return $job->isManuallyExecutable();
828 });
829
830 if ($jobs === []) {
831 $this->tpl->setOnScreenMessage('failure', $this->lng->txt('cron_no_executable_job_selected'), true);
832 $this->ctrl->redirect($this, self::VIEW);
833 }
834 }
835
836 $cgui = new ilConfirmationGUI();
837
838 if (count($jobs) === 1) {
839 $jobKeys = array_keys($jobs);
840 $job_id = array_pop($jobKeys);
841 $job = array_pop($jobs);
842 $title = $job->getTitle();
843 if (!$title) {
844 $title = preg_replace('[^A-Za-z0-9_\-]', '', $job->getId());
845 }
846
847 $cgui->setHeaderText(
848 sprintf(
849 $this->lng->txt('cron_action_' . $a_action . '_sure'),
850 $title
851 )
852 );
853
854 $cgui->addHiddenItem($this->getJobIdParameterName() . '[]', $job_id);
855 } else {
856 $cgui->setHeaderText($this->lng->txt('cron_action_' . $a_action . '_sure_multi'));
857
858 foreach ($jobs as $job_id => $job) {
859 $cgui->addItem($this->getJobIdParameterName() . '[]', $job_id, $job->getTitle());
860 }
861 }
862
863 $cgui->setFormAction($this->ctrl->getFormAction($this, 'confirmed' . ucfirst($a_action)));
864 $cgui->setCancel($this->lng->txt('cancel'), self::VIEW);
865 $cgui->setConfirm($this->lng->txt('cron_action_' . $a_action), 'confirmed' . ucfirst($a_action));
866
867 $this->tpl->setContent($cgui->getHTML());
868 }
869
873 public function addToExternalSettingsForm(int $a_form_id): array
874 {
875 $form_elements = [];
876 $fields = [];
877 $data = $this->cron_repository->getCronJobData();
878 foreach ($data as $item) {
879 $job = $this->cron_repository->getJobInstance(
880 $item['job_id'],
881 $item['component'],
882 $item['class']
883 );
884 if ($job !== null) {
885 $job->addToExternalSettingsForm($a_form_id, $fields, (bool) $item['job_status']);
886 }
887 }
888
889 if ($fields !== []) {
890 return [
891 'cron_jobs' => [
892 self::VIEW,
893 $fields
894 ]
895 ];
896 }
897
898 return [];
899 }
900}
$components
Builds data types.
Definition: Factory.php:36
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...
static formatDate(ilDateTime $date, bool $a_skip_day=false, bool $a_include_wd=false, bool $include_seconds=false, ?ilObjUser $user=null,)
@classDescription Date and time handling
This class represents a number property in a property form.
@ilCtrl_isCalledBy ilObjCronGUI: ilAdministrationGUI @ilCtrl_Calls ilObjCronGUI: ilPropertyFormGUI @i...
hasScheduleValue(JobScheduleType $schedule_type)
confirm(string $a_action)
editLegacy(?ilPropertyFormGUI $a_form=null)
readonly ilUIService $ui_service
const string TABLE_ACTION_PARAM_NAME
const string TABLE_ACTION_IDENTIFIER_NAME
addToExternalSettingsForm(int $a_form_id)
const string FORM_PARAM_SCHEDULE_PREFIX
const FORM_PARAM_GROUP_SCHEDULE
getRequestValue(string $key, \ILIAS\Refinery\Transformation $trafo, bool $force_retrieval=false, $default=null)
readonly JobManager $cron_manager
readonly JobRepository $cron_repository
readonly DataFactory $data_factory
readonly WrapperFactory $http_wrapper
addProblematicItemsInfo(\ILIAS\Cron\Job\JobCollection $filtered_jobs, \ILIAS\UI\Component\MessageBox\MessageBox $message, array $components)
const array TABLE_ACTION_NAMESPACE
edit(?ILIAS\UI\Component\Input\Container\Form\Form $form=null)
getScheduleTypeFormElementName(JobScheduleType $schedule_type)
readonly ILIAS DI RBACServices $rbac
const string VIEW
getScheduleValueFormElementName(JobScheduleType $schedule_type)
const FORM_PARAM_MAIN_SECTION
initLegacyEditForm(JobEntity $entity)
buildForm(JobEntity $entity)
Class ilObjectGUI Basic methods of all Output classes.
static _getAllReferences(int $id)
get all reference ids for object ID
static _getObjectsDataForType(string $type, bool $omit_trash=false)
get all objects of a certain type
This class represents a property form user interface.
This class represents a property in a property form.
This class represents an option in a radio group.
Filter service.
static _getHttpPath()
static stripSlashes(string $a_str, bool $a_strip_html=true, string $a_allow="")
return['delivery_method'=> 'php',]
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
$valid
$res
Definition: ltiservices.php:69
static http()
Fetches the global http state from ILIAS.
__construct(Container $dic, ilPlugin $plugin)
@inheritDoc
filter(string $filter_id, array $class_path, string $cmd, bool $activated=true, bool $expanded=true)
Interface Observer \BackgroundTasks Contains several chained tasks and infos about them.
global $DIC
Definition: shib_login.php:26