19declare(strict_types=1);
56 private readonly \ILIAS\DI\RBACServices
$rbac;
59 private readonly \ILIAS\HTTP\GlobalHttpState
$http;
69 $this->
lng = $DIC->language();
70 $this->
ctrl = $DIC->ctrl();
72 $this->tpl =
$DIC->ui()->mainTemplate();
73 $this->ui_factory =
$DIC->ui()->factory();
74 $this->ui_renderer =
$DIC->ui()->renderer();
75 $this->ui_service =
$DIC->uiService();
76 $this->
rbac = $DIC->rbac();
77 $this->
error = $DIC[
'ilErr'];
78 $this->http_wrapper =
$DIC->http()->wrapper();
79 $this->
http = $DIC->http();
81 $this->actor =
$DIC->user();
82 $this->cron_repository =
$DIC->cron()->repository();
83 $this->cron_manager =
$DIC->cron()->manager();
85 $this->
lng->loadLanguageModule(
'cron');
86 $this->
lng->loadLanguageModule(
'cmps');
94 $retrieval = $this->http_wrapper->query();
95 if (strtoupper($this->
http->request()->getMethod()) ===
'POST') {
96 $retrieval = $this->http_wrapper->post();
100 $this->
refinery->kindlyTo()->listOf($this->refinery->kindlyTo()->string()),
101 $this->refinery->always([])
104 $ids = $retrieval->retrieve(
109 if (count($ids) === 1 && $ids[0] ===
'ALL_OBJECTS') {
111 $this->cron_repository->findAll(),
116 $filter = $tableFilterMediator->filter(
117 $this->
ctrl->getFormAction(
126 $tableFilterMediator->filteredJobs(
137 return implode(
'_', array_merge(self::TABLE_ACTION_NAMESPACE, [self::TABLE_ACTION_PARAM_NAME]));
145 \
ILIAS\Cron\Job\JobCollection $filtered_jobs,
149 $problematic_jobs = $filtered_jobs->
filter(static function (
JobEntity $entity): bool {
152 if (count($problematic_jobs) > 0) {
153 $problematic_jobs_info = $this->ui_factory->messageBox()->info(
154 $this->
lng->txt(
'cron_jobs_with_required_intervention')
158 return $this->ui_factory->link()->
standard(
165 OrderedJobEntities::ORDER_BY_NAME
173 [$problematic_jobs_info],
177 array_unshift(
$components, $problematic_jobs_info);
186 return implode(
'_', array_merge(self::TABLE_ACTION_NAMESPACE, [self::TABLE_ACTION_IDENTIFIER_NAME]));
195 \
ILIAS\Refinery\Transformation $trafo,
196 bool $force_retrieval =
false,
202 if ($force_retrieval || $this->http_wrapper->query()->has($key)) {
203 return $this->http_wrapper->query()->retrieve($key, $trafo);
205 }
catch (OutOfBoundsException
$e) {
210 if ($force_retrieval || $this->http_wrapper->post()->has($key)) {
211 return $this->http_wrapper->post()->retrieve($key, $trafo);
213 }
catch (OutOfBoundsException
$e) {
217 if ($force_retrieval && $exc) {
221 return $default ??
null;
227 $this->
error->raiseError($this->
lng->txt(
'no_permission'), $this->error->WARNING);
230 $class = $this->
ctrl->getNextClass($this) ??
'';
232 switch (strtolower($class)) {
233 case strtolower(ilPropertyFormGUI::class):
234 $job_id = $this->getRequestValue($this->getJobIdParameterName(), $this->
refinery->kindlyTo()->string());
236 $form = $this->initLegacyEditForm($job);
237 $this->
ctrl->forwardCommand($form);
241 $cmd = $this->
ctrl->getCmd(
'render');
247 $action = $this->http_wrapper->query()->retrieve(
248 $this->getTableActionParameterName(),
250 $this->refinery->kindlyTo()->string(),
251 $this->refinery->always(
'')
255 'run' => $this->run(),
256 'activate' => $this->activate(),
257 'deactivate' => $this->deactivate(),
258 'reset' => $this->reset(),
259 'edit' => $this->edit(),
260 default => $this->render()
266 $tstamp = $this->
lng->txt(
'cronjob_last_start_unknown');
267 if ($this->
settings->get(
'last_cronjob_start_ts')) {
270 $this->
settings->get(
'last_cronjob_start_ts'),
276 $message = $this->ui_factory->messageBox()->info($this->
lng->txt(
'cronjob_last_start') .
': ' . $tstamp);
278 $cronJobs = $this->cron_repository->findAll();
286 $filter = $tableFilterMediator->filter(
287 $this->
ctrl->getFormAction(
295 $filtered_jobs = $tableFilterMediator->filteredJobs(
301 'handleTableActions',
302 self::TABLE_ACTION_NAMESPACE,
303 self::TABLE_ACTION_PARAM_NAME,
304 self::TABLE_ACTION_IDENTIFIER_NAME,
306 $this->
http->request(),
310 $this->cron_repository,
314 $this->tpl->setContent(
315 $this->ui_renderer->render(
316 $this->addProblematicItemsInfo(
319 [
$message, $filter, $tbl->getComponent()]
328 $this->
error->raiseError($this->
lng->txt(
'no_permission'), $this->error->WARNING);
331 if ($form ===
null) {
332 $job_ids = $this->retrieveTableActionJobIds();
333 if (count($job_ids) !== 1) {
334 $this->
ctrl->redirect($this,
'render');
337 $job_id = current($job_ids);
338 $job = $this->cron_repository->getJobInstanceById($job_id);
339 if ($job && $job->usesLegacyForms()) {
340 $this->
ctrl->setParameter($this, $this->getJobIdParameterName(), $job->getId());
341 $this->
ctrl->redirect($this,
'editLegacy');
344 $form = $this->initEditForm($job);
347 $this->tpl->setContent($this->ui_renderer->render($form));
353 $this->
error->raiseError($this->
lng->txt(
'no_permission'), $this->error->WARNING);
356 if ($a_form ===
null) {
357 $job_ids = $this->retrieveTableActionJobIds();
358 if (count($job_ids) !== 1) {
359 $this->
ctrl->redirect($this,
'render');
362 $job_id = current($job_ids);
363 $job = $this->cron_repository->getJobInstanceById($job_id);
364 $a_form = $this->initLegacyEditForm($job);
367 $this->tpl->setContent($a_form->getHTML());
372 return match ($schedule_type) {
373 JobScheduleType::DAILY => $this->
lng->txt(
'cron_schedule_daily'),
374 JobScheduleType::WEEKLY => $this->
lng->txt(
'cron_schedule_weekly'),
375 JobScheduleType::MONTHLY => $this->
lng->txt(
'cron_schedule_monthly'),
376 JobScheduleType::QUARTERLY => $this->
lng->txt(
'cron_schedule_quarterly'),
378 JobScheduleType::IN_MINUTES => sprintf($this->
lng->txt(
'cron_schedule_in_minutes'),
'x'),
379 JobScheduleType::IN_HOURS => sprintf($this->
lng->txt(
'cron_schedule_in_hours'),
'x'),
380 JobScheduleType::IN_DAYS => sprintf($this->
lng->txt(
'cron_schedule_in_days'),
'x'),
386 return match ($schedule_type) {
387 JobScheduleType::IN_MINUTES =>
'smini',
388 JobScheduleType::IN_HOURS =>
'shri',
389 JobScheduleType::IN_DAYS =>
'sdyi',
390 default =>
throw new InvalidArgumentException(
392 'The passed argument %s is invalid!',
393 var_export($schedule_type,
true)
401 return in_array($schedule_type, [
402 JobScheduleType::IN_MINUTES,
403 JobScheduleType::IN_HOURS,
404 JobScheduleType::IN_DAYS
410 if (!($job instanceof
CronJob)) {
411 $this->
ctrl->redirect($this,
'render');
414 $this->
ctrl->setParameter($this, $this->getJobIdParameterName(), $job->
getId());
416 $jobs_data = $this->cron_repository->getCronJobData($job->
getId());
417 $job_data = $jobs_data[0];
419 $section_inputs = [];
421 $schedule_type_groups = [];
427 $schedule_type_inputs = [];
429 $schedule_value_input = $this->ui_factory
433 $this->
lng->txt(
'cron_schedule_value')
434 )->withAdditionalTransformation(
436 $this->refinery->int()->isGreaterThanOrEqual(1)
438 )->withRequired(
true);
440 if (is_numeric($job_data[
'schedule_type']) &&
441 JobScheduleType::tryFrom((
int) $job_data[
'schedule_type']) === $schedule_type) {
442 $schedule_value_input = $schedule_value_input->withValue(
443 $job_data[
'schedule_value'] ===
null ?
null : (
int) $job_data[
'schedule_value']
447 $schedule_type_inputs = [
448 $this->getScheduleValueFormElementName($schedule_type) => $schedule_value_input
452 $schedule_type_groups[self::FORM_PARAM_SCHEDULE_PREFIX . $schedule_type->value] = $this->ui_factory
456 $schedule_type_inputs,
457 $this->getScheduleTypeFormElementName($schedule_type)
459 ->withDedicatedName(self::FORM_PARAM_SCHEDULE_PREFIX . $schedule_type->value);
464 $section_inputs[
'schedule'] = $this->ui_factory
468 $schedule_type_groups,
469 $this->
lng->txt(
'cron_schedule_type')
473 $job_data[
'schedule_type'] ===
null ?
474 self::FORM_PARAM_SCHEDULE_PREFIX . $default_schedule_type :
475 self::FORM_PARAM_SCHEDULE_PREFIX . $job_data[
'schedule_type']
479 $main_section = $this->ui_factory->input()->field()->section(
481 $this->
lng->txt(
'cron_action_edit') .
': "' . $job->
getTitle() .
'"'
485 self::FORM_PARAM_MAIN_SECTION => $main_section
492 self::FORM_PARAM_JOB_INPUT =>
502 return $this->ui_factory
506 ->standard($this->
ctrl->getFormAction($this,
'update'),
$inputs)
507 ->withDedicatedName(
'cron_form');
513 #[\Deprecated('Will be removed without any alternative, KS/UI forms will be expected', since: '13.0')]
516 if (!($job instanceof
CronJob)) {
517 $this->
ctrl->redirect($this,
'render');
520 $this->
ctrl->setParameter($this, $this->getJobIdParameterName(), $job->
getId());
522 $jobs_data = $this->cron_repository->getCronJobData($job->
getId());
523 $job_data = $jobs_data[0];
526 $form->setFormAction($this->
ctrl->getFormAction($this,
'updateLegacy'));
527 $form->setTitle($this->
lng->txt(
'cron_action_edit') .
': "' . $job->
getTitle() .
'"');
531 $type->setRequired(
true);
532 $type->setValue($job_data[
'schedule_type'] ===
null ?
null : (
string) $job_data[
'schedule_type']);
540 $this->getScheduleTypeFormElementName($schedule_type),
541 (
string) $schedule_type->value
543 $type->addOption($option);
547 $this->
lng->txt(
'cron_schedule_value'),
548 $this->getScheduleValueFormElementName($schedule_type)
550 $scheduleValue->allowDecimals(
false);
551 $scheduleValue->setRequired(
true);
552 $scheduleValue->setSize(5);
553 if (is_numeric($job_data[
'schedule_type']) &&
554 JobScheduleType::tryFrom((
int) $job_data[
'schedule_type']) === $schedule_type) {
555 $scheduleValue->setValue(
556 $job_data[
'schedule_value'] ===
null ?
null : (
string) $job_data[
'schedule_value']
559 $option->addSubItem($scheduleValue);
563 $form->addItem($type);
570 $form->addCommandButton(
'updateLegacy', $this->
lng->txt(
'save'));
571 $form->addCommandButton(
'render', $this->
lng->txt(
'cancel'));
579 $this->
error->raiseError($this->
lng->txt(
'no_permission'), $this->error->WARNING);
582 $job_id = $this->getRequestValue($this->getJobIdParameterName(), $this->
refinery->kindlyTo()->string());
584 $this->
ctrl->redirect($this,
'render');
587 $job = $this->cron_repository->getJobInstanceById($job_id);
588 $form = $this->initEditForm($job);
592 if ($this->
http->request()->getMethod() ===
'POST') {
593 $form = $form->withRequest($this->
http->request());
594 $form_data = $form->getData();
595 $form_valid = $form_data !==
null;
604 if ($job->hasFlexibleSchedule()) {
605 $schedule_group = $form_data[self::FORM_PARAM_MAIN_SECTION][self::FORM_PARAM_GROUP_SCHEDULE];
608 (
int) ltrim($schedule_group[0], self::FORM_PARAM_SCHEDULE_PREFIX)
611 $value = match (
true) {
612 $this->hasScheduleValue($type) => (
int) $schedule_group[1][$this->getScheduleValueFormElementName(
618 $this->cron_repository->updateJobSchedule($job, $type, $value);
621 if ($job->hasCustomSettings()) {
622 $job->saveCustomConfiguration($form_data[self::FORM_PARAM_JOB_INPUT]);
625 $this->tpl->setOnScreenMessage(
'success', $this->
lng->txt(
'cron_action_edit_success'),
true);
626 $this->
ctrl->redirect($this,
'render');
635 #[\Deprecated('Will be removed without any alternative, KS/UI forms will be expected', since: '12.0')]
639 $this->
error->raiseError($this->
lng->txt(
'no_permission'), $this->error->WARNING);
642 $job_id = $this->getRequestValue($this->getJobIdParameterName(), $this->
refinery->kindlyTo()->string());
644 $this->
ctrl->redirect($this,
'render');
647 $job = $this->cron_repository->getJobInstanceById($job_id);
649 $form = $this->initLegacyEditForm($job);
650 if ($job instanceof
CronJob && $form->checkInput()) {
652 if ($job->hasCustomSettings() && !$job->saveCustomSettings($form)) {
656 if (
$valid && $job->hasFlexibleSchedule()) {
658 $value = match (
true) {
659 $this->hasScheduleValue($type) => (
int) $form->getInput(
660 $this->getScheduleValueFormElementName($type)
665 $this->cron_repository->updateJobSchedule($job, $type, $value);
669 $this->tpl->setOnScreenMessage(
'success', $this->
lng->txt(
'cron_action_edit_success'),
true);
670 $this->
ctrl->redirect($this,
'render');
674 $form->setValuesByPost();
675 $this->editLegacy($form);
678 public function run(): void
680 $this->confirm(
'run');
686 $this->
error->raiseError($this->
lng->txt(
'no_permission'), $this->error->WARNING);
689 $job_ids = $this->retrieveTableActionJobIds();
690 if (count($job_ids) !== 1) {
691 $this->
ctrl->redirect($this,
'render');
694 $job_id = current($job_ids);
695 if ($this->cron_manager->runJobManual($job_id, $this->actor)) {
696 $this->tpl->setOnScreenMessage(
'success', $this->
lng->txt(
'cron_action_run_success'),
true);
698 $this->tpl->setOnScreenMessage(
'failure', $this->
lng->txt(
'cron_action_run_fail'),
true);
701 $this->
ctrl->redirect($this,
'render');
706 $this->confirm(
'activate');
712 $this->
error->raiseError($this->
lng->txt(
'no_permission'), $this->error->WARNING);
715 $jobs = $this->getMultiActionData();
717 foreach ($jobs as $job) {
718 if ($this->cron_manager->isJobInactive($job->getId())) {
719 $this->cron_manager->resetJob($job, $this->actor);
723 $this->tpl->setOnScreenMessage(
'success', $this->
lng->txt(
'cron_action_activate_success'),
true);
725 $this->tpl->setOnScreenMessage(
'info', $this->
lng->txt(
'no_checkbox'),
true);
728 $this->
ctrl->redirect($this,
'render');
733 $this->confirm(
'deactivate');
739 $this->
error->raiseError($this->
lng->txt(
'no_permission'), $this->error->WARNING);
742 $jobs = $this->getMultiActionData();
744 foreach ($jobs as $job) {
745 if ($this->cron_manager->isJobActive($job->getId())) {
746 $this->cron_manager->deactivateJob($job, $this->actor,
true);
750 $this->tpl->setOnScreenMessage(
'success', $this->
lng->txt(
'cron_action_deactivate_success'),
true);
752 $this->tpl->setOnScreenMessage(
'info', $this->
lng->txt(
'no_checkbox'),
true);
755 $this->
ctrl->redirect($this,
'render');
760 $this->confirm(
'reset');
766 $this->
error->raiseError($this->
lng->txt(
'no_permission'), $this->error->WARNING);
769 $jobs = $this->getMultiActionData();
771 foreach ($jobs as $job) {
772 $this->cron_manager->resetJob($job, $this->actor);
774 $this->tpl->setOnScreenMessage(
'success', $this->
lng->txt(
'cron_action_reset_success'),
true);
776 $this->tpl->setOnScreenMessage(
'info', $this->
lng->txt(
'no_checkbox'),
true);
779 $this->
ctrl->redirect($this,
'render');
791 $job_ids = $this->retrieveTableActionJobIds();
792 }
catch (\
ILIAS\Refinery\ConstraintViolationException|OutOfBoundsException) {
795 foreach ($job_ids as $job_id) {
796 $job = $this->cron_repository->getJobInstanceById($job_id);
798 $res[$job_id] = $job;
805 protected function confirm(
string $a_action): void
808 $this->
error->raiseError($this->
lng->txt(
'no_permission'), $this->error->WARNING);
811 $jobs = $this->getMultiActionData();
813 $this->tpl->setOnScreenMessage(
'info', $this->
lng->txt(
'no_checkbox'),
true);
814 $this->
ctrl->redirect($this,
'render');
817 if ($a_action ===
'run') {
818 $jobs = array_filter($jobs,
static function (
CronJob $job):
bool {
823 $this->tpl->setOnScreenMessage(
'failure', $this->
lng->txt(
'cron_no_executable_job_selected'),
true);
824 $this->
ctrl->redirect($this,
'render');
830 if (count($jobs) === 1) {
831 $jobKeys = array_keys($jobs);
832 $job_id = array_pop($jobKeys);
833 $job = array_pop($jobs);
834 $title = $job->getTitle();
836 $title = preg_replace(
'[^A-Za-z0-9_\-]',
'', $job->getId());
839 $cgui->setHeaderText(
841 $this->
lng->txt(
'cron_action_' . $a_action .
'_sure'),
846 $cgui->addHiddenItem($this->getJobIdParameterName() .
'[]', $job_id);
848 $cgui->setHeaderText($this->
lng->txt(
'cron_action_' . $a_action .
'_sure_multi'));
850 foreach ($jobs as $job_id => $job) {
851 $cgui->addItem($this->getJobIdParameterName() .
'[]', $job_id, $job->getTitle());
855 $cgui->setFormAction($this->
ctrl->getFormAction($this,
'confirmed' . ucfirst($a_action)));
856 $cgui->setCancel($this->
lng->txt(
'cancel'),
'render');
857 $cgui->setConfirm($this->
lng->txt(
'cron_action_' . $a_action),
'confirmed' . ucfirst($a_action));
859 $this->tpl->setContent($cgui->getHTML());
869 $data = $this->cron_repository->getCronJobData();
870 foreach (
$data as $item) {
871 $job = $this->cron_repository->getJobInstance(
877 $job->addToExternalSettingsForm($a_form_id, $fields, (
bool) $item[
'job_status']);
881 if ($fields !== []) {
890 return $form_elements;
getCustomConfigurationInput(\ILIAS\UI\Factory $ui_factory, \ILIAS\Refinery\Factory $factory, \ilLanguage $lng)
getAllScheduleTypes()
Get all available schedule types.
getScheduleTypesWithValues()
getValidScheduleTypes()
Returns a collection of all valid schedule types for a specific job.
addCustomSettingsToForm(\ilPropertyFormGUI $a_form)
Builds a Color from either hex- or rgb values.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
@ilCtrl_Calls ilCronManagerGUI: ilPropertyFormGUI @ilCtrl_isCalledBy ilCronManagerGUI: ilAdministrati...
readonly JobManager $cron_manager
retrieveTableActionJobIds()
getScheduleValueFormElementName(JobScheduleType $schedule_type)
readonly ILIAS DI RBACServices $rbac
const string FORM_PARAM_SCHEDULE_PREFIX
const FORM_PARAM_MAIN_SECTION
addProblematicItemsInfo(\ILIAS\Cron\Job\JobCollection $filtered_jobs, \ILIAS\UI\Component\MessageBox\MessageBox $message, array $components)
readonly ilSetting $settings
readonly ILIAS HTTP GlobalHttpState $http
const string TABLE_ACTION_IDENTIFIER_NAME
readonly JobRepository $cron_repository
readonly ilErrorHandling $error
getRequestValue(string $key, \ILIAS\Refinery\Transformation $trafo, bool $force_retrieval=false, $default=null)
readonly ilUIService $ui_service
initLegacyEditForm(?CronJob $job)
readonly ilGlobalTemplateInterface $tpl
hasScheduleValue(JobScheduleType $schedule_type)
edit(?ILIAS\UI\Component\Input\Container\Form\Form $form=null)
readonly Factory $ui_factory
addToExternalSettingsForm(int $a_form_id)
editLegacy(?ilPropertyFormGUI $a_form=null)
getScheduleTypeFormElementName(JobScheduleType $schedule_type)
const string TABLE_ACTION_PARAM_NAME
readonly WrapperFactory $http_wrapper
const FORM_PARAM_GROUP_SCHEDULE
readonly ilCtrlInterface $ctrl
readonly ilObjUser $actor
readonly Renderer $ui_renderer
const array TABLE_ACTION_NAMESPACE
readonly ILIAS Refinery Factory $refinery
confirm(string $a_action)
const FORM_PARAM_JOB_INPUT
initEditForm(?CronJob $job)
getTableActionParameterName()
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
Error Handling & global info handling.
This class represents an option in a radio group.
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...
This is how the factory for UI elements looks.
An entity that renders components to a string output.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static http()
Fetches the global http state from ILIAS.
__construct(Container $dic, ilPlugin $plugin)
@inheritDoc
filter(string $filter_id, $class_path, string $cmd, bool $activated=true, bool $expanded=true)
Interface Observer \BackgroundTasks Contains several chained tasks and infos about them.