ILIAS  release_9 Revision v9.13-25-g2c18ec4c24f
class.ilCronManagerTableGUI.php
Go to the documentation of this file.
1 <?php
2 
19 declare(strict_types=1);
20 
22 
24 {
25  public function __construct(
26  ilCronManagerGUI $a_parent_obj,
27  private readonly ilCronJobRepository $cronRepository,
28  string $a_parent_cmd,
29  private readonly bool $mayWrite = false
30  ) {
31  $this->setId('crnmng'); // #14526 / #16391
32 
33  parent::__construct($a_parent_obj, $a_parent_cmd);
34 
35  if ($this->mayWrite) {
36  $this->addColumn("", "", '1px', true);
37  }
38  $this->addColumn($this->lng->txt('cron_job_id'), 'title');
39  $this->addColumn($this->lng->txt('cron_component'), 'component');
40  $this->addColumn($this->lng->txt('cron_schedule'), 'schedule');
41  $this->addColumn($this->lng->txt('cron_status'), 'status');
42  $this->addColumn($this->lng->txt('cron_status_info'), '');
43  $this->addColumn($this->lng->txt('cron_result'), 'result');
44  $this->addColumn($this->lng->txt('cron_result_info'), '');
45  $this->addColumn($this->lng->txt('cron_last_run'), 'last_run');
46  if ($this->mayWrite) {
47  $this->addColumn($this->lng->txt('actions'), '');
48  }
49 
50  $this->setTitle($this->lng->txt('cron_jobs'));
51  $this->setDefaultOrderField('title');
52 
53  if ($this->mayWrite) {
54  $this->setSelectAllCheckbox('mjid');
55  $this->addMultiCommand('activate', $this->lng->txt('cron_action_activate'));
56  $this->addMultiCommand('deactivate', $this->lng->txt('cron_action_deactivate'));
57  $this->addMultiCommand('reset', $this->lng->txt('cron_action_reset'));
58  }
59 
60  $this->setRowTemplate('tpl.cron_job_row.html', 'Services/Cron');
61  $this->setFormAction($this->ctrl->getFormAction($a_parent_obj, $a_parent_cmd));
62  }
63 
64  private function formatSchedule(ilCronJobEntity $entity, array $row): string
65  {
66  $schedule = match ($entity->getEffectiveScheduleType()) {
67  CronJobScheduleType::SCHEDULE_TYPE_DAILY => $this->lng->txt('cron_schedule_daily'),
68  CronJobScheduleType::SCHEDULE_TYPE_WEEKLY => $this->lng->txt('cron_schedule_weekly'),
69  CronJobScheduleType::SCHEDULE_TYPE_MONTHLY => $this->lng->txt('cron_schedule_monthly'),
70  CronJobScheduleType::SCHEDULE_TYPE_QUARTERLY => $this->lng->txt('cron_schedule_quarterly'),
71  CronJobScheduleType::SCHEDULE_TYPE_YEARLY => $this->lng->txt('cron_schedule_yearly'),
72  CronJobScheduleType::SCHEDULE_TYPE_IN_MINUTES => sprintf(
73  $this->lng->txt('cron_schedule_in_minutes'),
74  $entity->getEffectiveScheduleValue()
75  ),
76  CronJobScheduleType::SCHEDULE_TYPE_IN_HOURS => sprintf(
77  $this->lng->txt('cron_schedule_in_hours'),
78  $entity->getEffectiveScheduleValue()
79  ),
80  CronJobScheduleType::SCHEDULE_TYPE_IN_DAYS => sprintf(
81  $this->lng->txt('cron_schedule_in_days'),
82  $entity->getEffectiveScheduleValue()
83  )
84  };
85 
86  return $schedule;
87  }
88 
89  private function formatStatusInfo(ilCronJobEntity $entity): string
90  {
91  $status_info = [];
92  if ($entity->getJobStatusTimestamp()) {
93  $status_info[] = ilDatePresentation::formatDate(
95  );
96  }
97 
98  if ($entity->getJobStatusType()) {
99  $status_info[] = ilUserUtil::getNamePresentation($entity->getJobStatusUsrId());
100  } else {
101  $status_info[] = $this->lng->txt('cron_changed_by_crontab');
102  }
103 
104  return implode('<br />', $status_info);
105  }
106 
107  private function formatResult(ilCronJobEntity $entity): string
108  {
109  $result = '-';
110  if ($entity->getJobResultStatus()) {
111  switch ($entity->getJobResultStatus()) {
113  $result = $this->lng->txt('cron_result_status_invalid_configuration');
114  break;
115 
117  $result = $this->lng->txt('cron_result_status_no_action');
118  break;
119 
121  $result = $this->lng->txt('cron_result_status_ok');
122  break;
123 
125  $result = $this->lng->txt('cron_result_status_crashed');
126  break;
127 
129  $result = $this->lng->txt('cron_result_status_reset');
130  break;
131 
133  $result = $this->lng->txt('cron_result_status_fail');
134  break;
135  }
136  }
137 
138  return $result;
139  }
140 
141  private function formatResultInfo(ilCronJobEntity $entity): string
142  {
143  $result_info = [];
144  if ($entity->getJobResultDuration()) {
145  $result_info[] = ($entity->getJobResultDuration() / 1000) . ' sec';
146  }
147 
148  // #23391 / #11866
149  $resultCode = $entity->getJobResultCode();
150  if (in_array($resultCode, ilCronJobResult::getCoreCodes(), true)) {
151  $result_info[] = $this->lng->txt('cro_job_rc_' . $resultCode);
152  } elseif ($entity->getJobResultMessage()) {
153  $result_info[] = $entity->getJobResultMessage();
154  }
155 
156  if (defined('DEVMODE') && DEVMODE && $resultCode) {
157  $result_info[] = $resultCode;
158  }
159 
160  if ($entity->getJobResultType()) {
161  $result_info[] = ilUserUtil::getNamePresentation($entity->getJobResultUsrId());
162  } else {
163  $result_info[] = $this->lng->txt('cron_changed_by_crontab');
164  }
165 
166  return implode('<br />', $result_info);
167  }
168 
169  public function populate(ilCronJobCollection $collection): self
170  {
171  $this->setData(array_map(function (ilCronJobEntity $entity): array {
172  $row = [];
173 
174  $row['schedule'] = $this->formatSchedule($entity, $row);
175  $row['status'] = $this->lng->txt('cron_status_inactive');
176  if ($entity->getJobStatus()) {
177  $row['status'] = $this->lng->txt('cron_status_active');
178  }
179  $row['status_info'] = $this->formatStatusInfo($entity);
180  $row['result'] = $this->formatResult($entity);
181  $row['result_info'] = $this->formatResultInfo($entity);
182 
183  $row['last_run'] = null;
184  if ($entity->getRunningTimestamp()) {
185  $row['last_run'] = strtotime('+1year', $entity->getRunningTimestamp());
186  } elseif ($entity->getJobResultTimestamp()) {
187  $row['last_run'] = $entity->getJobResultTimestamp();
188  }
189 
190  $row['job_id'] = $entity->getJobId();
191  $row['component'] = $entity->getComponent();
192  if ($entity->isPlugin()) {
193  $row['job_id'] = 'pl__' . $row['component'] . '__' . $row['job_id'];
194  $row['component'] = $this->lng->txt('cmps_plugin') . '/' . $row['component'];
195  }
196 
197  $row['title'] = $entity->getEffectiveTitle();
198  $row['description'] = $entity->getJob()->getDescription();
199  $row['is_manually_executable'] = $entity->getJob()->isManuallyExecutable();
200  $row['has_settings'] = $entity->getJob()->hasCustomSettings();
201  $row['job_result_status'] = $entity->getJobResultStatus();
202  $row['job_status'] = $entity->getJobStatus();
203  $row['alive_ts'] = $entity->getAliveTimestamp();
204  $row['running_ts'] = $entity->getRunningTimestamp();
205 
206  if ($entity->getJob()->hasFlexibleSchedule()) {
207  $row['editable_schedule'] = true;
208  if ($entity->getScheduleType() === null) {
209  $this->cronRepository->updateJobSchedule(
210  $entity->getJob(),
211  $entity->getEffectiveScheduleType(),
212  $entity->getEffectiveScheduleValue()
213  );
214  }
215  } elseif ($entity->getScheduleType() !== null) {
216  $this->cronRepository->updateJobSchedule($entity->getJob(), null, null);
217  }
218 
219  return $row;
220  }, $collection->toArray()));
221 
222  return $this;
223  }
224 
225  protected function fillRow(array $a_set): void
226  {
227  if ($this->mayWrite) {
228  $this->tpl->setVariable('VAL_JID', $a_set['job_id']);
229  }
230  $this->tpl->setVariable('VAL_ID', $a_set['title']);
231 
232  if ($a_set['description']) {
233  $this->tpl->setVariable('VAL_DESC', $a_set['description']);
234  }
235 
236  $this->tpl->setVariable('VAL_COMPONENT', $a_set['component']);
237  $this->tpl->setVariable('VAL_SCHEDULE', $a_set['schedule']);
238  $this->tpl->setVariable('VAL_STATUS', $a_set['status']);
239  $this->tpl->setVariable('VAL_STATUS_INFO', $a_set['status_info']);
240  $this->tpl->setVariable('VAL_RESULT', $a_set['result']);
241  $this->tpl->setVariable('VAL_RESULT_INFO', $a_set['result_info']);
242  if ($a_set['last_run'] > time()) {
243  $a_set['last_run'] = $this->lng->txt('cron_running_since') . ' ' .
244  ilDatePresentation::formatDate(new ilDateTime($a_set['running_ts'], IL_CAL_UNIX));
245 
246  // job has pinged
247  if ($a_set['alive_ts'] !== $a_set['running_ts']) {
248  $a_set['last_run'] .= '<br />(Ping: ' .
249  ilDatePresentation::formatDate(new ilDateTime($a_set['alive_ts'], IL_CAL_UNIX)) . ')';
250  }
251  } elseif ($a_set['last_run']) {
252  $a_set['last_run'] = ilDatePresentation::formatDate(new ilDateTime($a_set['last_run'], IL_CAL_UNIX));
253  }
254  $this->tpl->setVariable('VAL_LAST_RUN', $a_set['last_run'] ?: '-');
255 
256  $actions = [];
257  if ($this->mayWrite && !$a_set['running_ts']) {
258  if ($a_set['job_result_status'] === ilCronJobResult::STATUS_CRASHED) {
259  $actions[] = 'reset';
260  } elseif (!$a_set['job_status']) {
261  $actions[] = 'activate';
262  } else {
263  if ($a_set['is_manually_executable']) {
264  $actions[] = 'run';
265  }
266  $actions[] = 'deactivate';
267  }
268 
269  if (
270  (isset($a_set['editable_schedule']) && $a_set['editable_schedule']) ||
271  (isset($a_set['has_settings']) && $a_set['has_settings'])
272  ) {
273  $actions[] = 'edit';
274  }
275 
276  $this->ctrl->setParameter($this->getParentObject(), 'jid', $a_set['job_id']);
277  foreach ($actions as $action) {
278  $this->tpl->setCurrentBlock('action_bl');
279  $this->tpl->setVariable(
280  'URL_ACTION',
281  $this->ctrl->getLinkTarget($this->getParentObject(), $action)
282  );
283  $this->tpl->setVariable('TXT_ACTION', $this->lng->txt('cron_action_' . $action));
284  $this->tpl->parseCurrentBlock();
285  }
286  $this->ctrl->setParameter($this->getParentObject(), 'jid', '');
287  }
288  }
289 }
setData(array $a_data)
formatResultInfo(ilCronJobEntity $entity)
formatSchedule(ilCronJobEntity $entity, array $row)
setFormAction(string $a_form_action, bool $a_multipart=false)
setSelectAllCheckbox(string $a_select_all_checkbox, bool $a_select_all_on_top=false)
static formatDate(ilDateTime $date, bool $a_skip_day=false, bool $a_include_wd=false, bool $include_seconds=false)
formatStatusInfo(ilCronJobEntity $entity)
const IL_CAL_UNIX
final const STATUS_INVALID_CONFIGURATION
setId(string $a_val)
__construct(VocabulariesInterface $vocabularies)
static getNamePresentation( $a_user_id, bool $a_user_image=false, bool $a_profile_link=false, string $a_profile_back_link='', bool $a_force_first_lastname=false, bool $a_omit_login=false, bool $a_sortable=true, bool $a_return_data_array=false, $a_ctrl_path='ilpublicuserprofilegui')
Default behaviour is:
setDefaultOrderField(string $a_defaultorderfield)
final const STATUS_NO_ACTION
setRowTemplate(string $a_template, string $a_template_dir="")
Set row template.
setTitle(string $a_title, string $a_icon="", string $a_icon_alt="")
formatResult(ilCronJobEntity $entity)
addColumn(string $a_text, string $a_sort_field="", string $a_width="", bool $a_is_checkbox_action_column=false, string $a_class="", string $a_tooltip="", bool $a_tooltip_with_html=false)
Class ilCronManagerGUI.
addMultiCommand(string $a_cmd, string $a_text)
__construct(ilCronManagerGUI $a_parent_obj, private readonly ilCronJobRepository $cronRepository, string $a_parent_cmd, private readonly bool $mayWrite=false)
populate(ilCronJobCollection $collection)