ILIAS  trunk Revision v11.0_alpha-1713-gd8962da2f67
All Data Structures Namespaces Files Functions Variables Enumerations Enumerator Modules Pages
class.ilCalendarAppointmentGUI.php
Go to the documentation of this file.
1 <?php
2 
19 declare(strict_types=1);
20 
25 
32 {
35  protected bool $requested_rexl;
36 
37  protected ilDate $seed;
39  protected bool $default_fulltime = true;
40  protected ilCalendarEntry $app;
42  protected string $timezone;
43 
45  protected ilLanguage $lng;
47  protected ilObjUser $user;
48  protected ilTabsGUI $tabs;
49  protected ilSetting $settings;
50  protected ilHelpGUI $help;
52  private ilLogger $logger;
53  protected HTTPServices $http;
56 
60  public function __construct(ilDate $seed, ilDate $initialDate, int $a_appointment_id = 0)
61  {
62  global $DIC;
63 
64  $this->lng = $DIC->language();
65  $this->lng->loadLanguageModule('dateplaner');
66  $this->ctrl = $DIC->ctrl();
67  $this->tpl = $DIC->ui()->mainTemplate();
68  $this->logger = $DIC->logger()->cal();
69  $this->user = $DIC->user();
70  $this->settings = $DIC->settings();
71  $this->tabs = $DIC->tabs();
72  $this->help = $DIC->help();
73  $this->error = $DIC['ilErr'];
74 
75  $this->http = $DIC->http();
76  $this->refinery = $DIC->refinery();
77  $this->request = $DIC->http()->request();
78 
79  $this->initTimeZone();
80  $this->initSeed($seed);
81  $this->initInitialDate($initialDate);
82  $this->initAppointment($a_appointment_id);
83  $this->requested_rexl = (bool) $this->getRecurrenceExclusionFromQuery();
84  }
85 
86  protected function getAppointmentIdFromQuery(): int
87  {
88  if ($this->http->wrapper()->query()->has('app_id')) {
89  return $this->http->wrapper()->query()->retrieve(
90  'app_id',
91  $this->refinery->kindlyTo()->int()
92  );
93  }
94  return 0;
95  }
96 
97  protected function getRecurrenceExclusionFromQuery(): int
98  {
99  $val = 0;
100  if ($this->http->wrapper()->post()->has('rexl')) {
101  $val = $this->http->wrapper()->post()->retrieve(
102  'rexl',
103  $this->refinery->kindlyTo()->int()
104  );
105  }
106  if ($val === 0 && $this->http->wrapper()->query()->has('rexl')) {
107  $val = $this->http->wrapper()->query()->retrieve(
108  'rexl',
109  $this->refinery->kindlyTo()->int()
110  );
111  }
112  return $val;
113  }
114 
115  protected function getRecurrenceDateFromQuery(): int
116  {
117  if ($this->http->wrapper()->query()->has('dt')) {
118  return $this->http->wrapper()->query()->retrieve(
119  'dt',
120  $this->refinery->kindlyTo()->int()
121  );
122  }
123  return 0;
124  }
125 
126  public function executeCommand(): void
127  {
128  // Clear tabs and set back target
129  $this->tabs->clearTargets();
130  if ($this->http->wrapper()->query()->has('app_id')) {
131  $this->ctrl->saveParameter($this, 'app_id');
132  }
133  $this->tabs->setBackTarget(
134  $this->lng->txt('cal_back_to_cal'),
135  $this->ctrl->getLinkTarget($this, 'cancel')
136  );
137 
138  $next_class = $this->ctrl->getNextClass($this);
139  switch ($next_class) {
140  default:
141  $cmd = $this->ctrl->getCmd("add");
142  $this->$cmd();
143  break;
144  }
145  }
146 
147  public function getAppointment(): ilCalendarEntry
148  {
149  return $this->app;
150  }
151 
152  protected function cancel(): void
153  {
154  $this->ctrl->returnToParent($this);
155  }
156 
157  protected function initForm(string $a_mode, bool $a_edit_single_app = false): ilPropertyFormGUI
158  {
159  $this->form = new ilPropertyFormGUI();
161  switch ($a_mode) {
162  case 'create':
163  $this->ctrl->saveParameter($this, array('seed', 'idate'));
164  $this->form->setFormAction($this->ctrl->getFormAction($this));
165  $this->form->setTitle($this->lng->txt('cal_new_app'));
166  $this->form->addCommandButton('save', $this->lng->txt('cal_add_appointment'));
167  $this->form->addCommandButton('cancel', $this->lng->txt('cancel'));
168  break;
169  case 'edit':
170  $this->form->setTitle($this->lng->txt('cal_edit_appointment'));
171  $this->ctrl->saveParameter($this, array('seed', 'app_id', 'idate'));
172  $this->form->setFormAction($this->ctrl->getFormAction($this));
173  $this->form->addCommandButton('update', $this->lng->txt('save'));
174  $this->form->addCommandButton('cancel', $this->lng->txt('cancel'));
175  break;
176  }
177  // title
178  $title = new ilTextInputGUI($this->lng->txt('title'), 'title');
179  $title->setValue($this->app->getTitle());
180  $title->setRequired(true);
181  $title->setMaxLength(128);
182  $title->setSize(32);
183  $this->form->addItem($title);
184 
185  $category_id = 0;
186  if ($this->http->wrapper()->query()->has('category_id')) {
187  $category_id = $this->http->wrapper()->query()->retrieve(
188  'category_id',
189  $this->refinery->kindlyTo()->int()
190  );
191  }
192  $ref_id = 0;
193  if ($this->http->wrapper()->query()->has('ref_id')) {
194  $ref_id = $this->http->wrapper()->query()->retrieve(
195  'ref_id',
196  $this->refinery->kindlyTo()->int()
197  );
198  }
199  // calendar selection
200  $calendar = new ilSelectInputGUI($this->lng->txt('cal_category_selection'), 'calendar');
201 
202  $selected_calendar = 0;
203  if ($this->http->wrapper()->post()->has('calendar')) {
204  $selected_calendar = $this->http->wrapper()->post()->retrieve(
205  'calendar',
206  $this->refinery->kindlyTo()->int()
207  );
208  }
209  if ($selected_calendar > 0) {
210  $calendar->setValue($selected_calendar);
211  } elseif ($category_id) {
212  $calendar->setValue((int) $category_id);
213  $selected_calendar = (int) $category_id;
214  } elseif ($a_mode == 'edit') {
215  $ass = new ilCalendarCategoryAssignments($this->app->getEntryId());
216  $cat = $ass->getFirstAssignment();
217  $calendar->setValue($cat);
218  $selected_calendar = $cat;
219  } elseif ($ref_id) {
220  $obj_cal = ilObject::_lookupObjId($ref_id);
221  $calendar->setValue(ilCalendarCategories::_lookupCategoryIdByObjId($obj_cal));
222  $selected_calendar = ilCalendarCategories::_lookupCategoryIdByObjId($obj_cal);
223  $cats = ilCalendarCategories::_getInstance($this->user->getId());
224  $cats->readSingleCalendar($selected_calendar);
225  } else {
226  $cats = ilCalendarCategories::_getInstance($this->user->getId());
227  $categories = $cats->prepareCategoriesOfUserForSelection();
228  $selected_calendar = key($categories);
229  $calendar->setValue($selected_calendar);
230  }
231  $calendar->setRequired(true);
232  $cats = ilCalendarCategories::_getInstance($this->user->getId());
233  $calendar->setOptions($cats->prepareCategoriesOfUserForSelection());
234 
235  if (ilCalendarSettings::_getInstance()->isNotificationEnabled()) {
236  $notification_cals = $cats->getNotificationCalendars();
237  $notification_cals = count($notification_cals) ? implode(',', $notification_cals) : '';
238  $calendar->addCustomAttribute("onchange=\"ilToggleNotification([" . $notification_cals . "]);\"");
239  }
240  $this->form->addItem($calendar);
241 
242  $dur = new ilDateDurationInputGUI($this->lng->txt('cal_fullday'), 'event');
243  $dur->setRequired(true);
244  $dur->enableToggleFullTime(
245  $this->lng->txt('cal_fullday_title'),
246  $this->app->isFullday()
247  );
248  $dur->setShowTime(true);
249  $dur->setStart($this->app->getStart());
250  $dur->setEnd($this->app->getEnd());
251  $this->form->addItem($dur);
252 
253  // recurrence
254  if (!$a_edit_single_app) {
255  $rec = new ilRecurrenceInputGUI($this->lng->txt('cal_recurrences'), 'frequence');
256  $rec->setRecurrence($this->rec);
257  $this->form->addItem($rec);
258  }
259 
260  // location
261  $where = new ilTextInputGUI($this->lng->txt('cal_where'), 'location');
262  $where->setValue($this->app->getLocation());
263  $where->setMaxLength(128);
264  $where->setSize(32);
265  $this->form->addItem($where);
266 
267  $desc = new ilTextAreaInputGUI($this->lng->txt('description'), 'description');
268  $desc->setValue($this->app->getDescription());
269  $desc->setRows(5);
270  $this->form->addItem($desc);
271 
272  if (ilCalendarSettings::_getInstance()->isUserNotificationEnabled()) {
273  $ajax_url = $this->ctrl->getLinkTarget(
274  $this,
275  'doUserAutoComplete',
276  '',
277  true,
278  false
279  );
280 
281  $notu = new ilTextInputGUI(
282  $this->lng->txt('cal_user_notification'),
283  'notu'
284  );
285  $notu->setMulti(true, true);
286  $notu->setInfo($this->lng->txt('cal_user_notification_info'));
287  $notu->setDataSource($ajax_url);
288 
289  $values = [];
290  foreach ($this->notification->getRecipients() as $rcp) {
291  switch ($rcp['type']) {
293  $values[] = ilObjUser::_lookupLogin($rcp['usr_id']);
294  break;
295 
297  $values[] = $rcp['email'];
298  break;
299  }
300  }
301  $notu->setValue($values);
302  $this->form->addItem($notu);
303  }
304 
305  // Notifications
306  if (ilCalendarSettings::_getInstance()->isNotificationEnabled() and count($cats->getNotificationCalendars())) {
307  $selected_cal = new ilCalendarCategory($selected_calendar);
308  $disabled = true;
309  if ($selected_cal->getType() == ilCalendarCategory::TYPE_OBJ) {
310  if (ilObject::_lookupType($selected_cal->getObjId()) == 'crs' or ilObject::_lookupType($selected_cal->getObjId()) == 'grp') {
311  $disabled = false;
312  }
313  }
314 
315  $this->tpl->addJavaScript('assets/js/toggle_notification.js');
316  $not = new ilCheckboxInputGUI($this->lng->txt('cal_cg_notification'), 'not');
317  $not->setInfo($this->lng->txt('cal_notification_info'));
318  $not->setValue('1');
319  $not->setChecked($this->app->isNotificationEnabled());
320  $not->setDisabled($disabled);
321  $this->form->addItem($not);
322  }
323  return $this->form;
324  }
325 
326 
327  protected function doUserAutoComplete(): ?string
328  {
329  // hide anonymout request
330  if ($this->user->getId() == ANONYMOUS_USER_ID) {
331  return json_encode(new stdClass(), JSON_THROW_ON_ERROR);
332  }
333  if (!$this->http->wrapper()->query()->has('autoCompleteField')) {
334  $a_fields = [
335  'login',
336  'firstname',
337  'lastname',
338  'email'
339  ];
340  $result_field = 'login';
341  } else {
342  $auto_complete_field = $this->http->wrapper()->query()->retrieve(
343  'autoCompleteField',
344  $this->refinery->kindlyTo()->string()
345  );
346  $a_fields = [$auto_complete_field];
347  $result_field = $auto_complete_field;
348  }
349  $auto = new ilUserAutoComplete();
351 
352  if ($this->http->wrapper()->query()->has('fetchall')) {
353  $auto->setLimit(ilUserAutoComplete::MAX_ENTRIES);
354  }
355 
356  $auto->setMoreLinkAvailable(true);
357  $auto->setSearchFields($a_fields);
358  $auto->setResultField($result_field);
359  $auto->enableFieldSearchableCheck(true);
360  $query = '';
361  if ($this->http->wrapper()->post()->has('term')) {
362  $query = $this->http->wrapper()->post()->retrieve(
363  'term',
364  $this->refinery->kindlyTo()->string()
365  );
366  }
367  if ($query === '') {
368  if ($this->http->wrapper()->query()->has('term')) {
369  $query = $this->http->wrapper()->query()->retrieve(
370  'term',
371  $this->refinery->kindlyTo()->string()
372  );
373  }
374  }
375  echo $auto->getList($query);
376  exit;
377  }
378 
382  protected function add(?ilPropertyFormGUI $form = null): void
383  {
384  $this->help->setScreenIdComponent("cal");
385  $this->help->setScreenId("app");
386  $this->help->setSubScreenId("create");
387 
388  if (!$form instanceof ilPropertyFormGUI) {
389  $form = $this->initForm('create');
390  }
391  $this->tpl->setContent($form->getHTML());
392  }
393 
394  protected function save(): void
395  {
396  $form = $this->load('create');
397 
398  if ($this->app->validate() and $this->notification->validate()) {
399  if ((int) $form->getInput('calendar') === 0) {
400  $cat_id = $this->createDefaultCalendar();
401  } else {
402  $cat_id = (int) $form->getInput('calendar');
403  }
404 
405  $this->app->save();
406  $this->notification->setEntryId($this->app->getEntryId());
407  $this->notification->save();
408  $this->rec->setEntryId($this->app->getEntryId());
409  $this->saveRecurrenceSettings();
410 
411  $ass = new ilCalendarCategoryAssignments($this->app->getEntryId());
412  $ass->addAssignment($cat_id);
413 
414  // Send notifications
415  if (
416  ilCalendarSettings::_getInstance()->isNotificationEnabled() &&
417  (int) $form->getInput('not')
418  ) {
419  $this->distributeNotifications($cat_id, $this->app->getEntryId(), true);
420  }
421  if (ilCalendarSettings::_getInstance()->isUserNotificationEnabled()) {
423  }
424 
425  $this->tpl->setOnScreenMessage('success', $this->lng->txt('cal_created_appointment'), true);
426  $this->ctrl->returnToParent($this);
427  } else {
428  $this->form->setValuesByPost();
429  if ($this->error->getMessage() !== '') {
430  $this->tpl->setOnScreenMessage('failure', $this->error->getMessage());
431  } else {
432  $this->tpl->setOnScreenMessage('failure', $this->lng->txt('err_check_input'));
433  }
434  $this->add($this->form);
435  return;
436  }
437  $this->add();
438  }
439 
443  protected function distributeUserNotifications(): void
444  {
445  $notification = new ilCalendarMailNotification();
446  $notification->setAppointmentId($this->app->getEntryId());
447 
448  foreach ($this->notification->getRecipients() as $rcp) {
449  switch ($rcp['type']) {
451  $notification->setSender(ANONYMOUS_USER_ID);
452  $notification->setRecipients(array($rcp['usr_id']));
453  $notification->setType(ilCalendarMailNotification::TYPE_USER);
454  break;
455 
457  $notification->setSender(ANONYMOUS_USER_ID);
458  $notification->setRecipients(array($rcp['email']));
459  $notification->setType(ilCalendarMailNotification::TYPE_USER_ANONYMOUS);
460  break;
461  }
462  $notification->send();
463  }
464  }
465 
466  protected function distributeNotifications(int $a_cat_id, int $app_id, bool $a_new_appointment = true): void
467  {
468  $cat_info = ilCalendarCategories::_getInstance()->getCategoryInfo($a_cat_id);
469 
470  $notification = new ilCalendarMailNotification();
471  $notification->setAppointmentId($app_id);
472 
473  switch ($cat_info['type']) {
475 
476  switch ($cat_info['obj_type']) {
477  case 'crs':
478  $ref_ids = ilObject::_getAllReferences($cat_info['obj_id']);
479  $ref_id = current($ref_ids);
480  $notification->setRefId($ref_id);
481  $notification->setType(
482  $a_new_appointment ?
485  );
486  break;
487 
488  case 'grp':
489  $ref_ids = ilObject::_getAllReferences($cat_info['obj_id']);
490  $ref_id = current($ref_ids);
491  $notification->setRefId($ref_id);
492  $notification->setType(
493  $a_new_appointment ?
496  );
497  break;
498  }
499  break;
500  }
501  $notification->send();
502  }
503 
504  public function editResponsibleUsers(): void
505  {
506  $cat_id = ilCalendarCategoryAssignments::_lookupCategory($this->app->getEntryId());
507  $cat_info = ilCalendarCategories::_getInstance()->getCategoryInfo($cat_id);
508  $this->showResponsibleUsersList($cat_info['obj_id']);
509  }
510 
514  protected function askEdit(): void
515  {
516  // check for recurring entries
517  $rec = ilCalendarRecurrences::_getRecurrences($this->getAppointment()->getEntryId());
518  if (!$rec) {
519  $this->edit(true);
520  return;
521  }
522  // Show edit single/all appointments
523  $this->ctrl->saveParameter($this, array('seed', 'app_id', 'dt', 'idate'));
524 
525  $confirm = new ilConfirmationGUI();
526  $confirm->setHeaderText($this->lng->txt('cal_edit_single_or_all_info'));
527  $confirm->setFormAction($this->ctrl->getFormAction($this));
528  $confirm->setCancel($this->lng->txt('cancel'), 'cancel');
529  $confirm->addItem('appointments[]', (string) $this->app->getEntryId(), $this->app->getTitle());
530  $confirm->addButton($this->lng->txt('cal_edit_single'), 'editSingle');
531  $confirm->setConfirm($this->lng->txt('cal_edit_recurrences'), 'edit');
532 
533  $this->tpl->setContent($confirm->getHTML());
534  }
535 
539  protected function editSingle(): void
540  {
541  $this->ctrl->setParameter($this, 'rexl', "1");
542  $this->requested_rexl = true;
543  $this->edit(true);
544  }
545 
549  protected function edit(bool $a_edit_single_app = false, ?ilPropertyFormGUI $form = null): void
550  {
551  $this->help->setScreenIdComponent("cal");
552  $this->help->setScreenId("app");
553  $this->help->setSubScreenId("edit");
554 
555  $this->ctrl->saveParameter($this, array('seed', 'app_id', 'dt', 'idate'));
556  if ($this->requested_rexl) {
557  $this->ctrl->setParameter($this, 'rexl', 1);
558  // Calculate new appointment time
559  $duration = $this->getAppointment()->getEnd()->get(IL_CAL_UNIX) - $this->getAppointment()->getStart()->get(IL_CAL_UNIX);
560  $calc = new ilCalendarRecurrenceCalculator($this->getAppointment(), $this->rec);
561 
562  $current_date = new ilDateTime($this->getRecurrenceDateFromQuery(), IL_CAL_UNIX);
563 
564  $yesterday = clone $current_date;
565  $yesterday->increment(IL_CAL_DAY, -1);
566  $tomorrow = clone $current_date;
567  $tomorrow->increment(IL_CAL_DAY, 1);
568 
569  foreach ($calc->calculateDateList($current_date, $tomorrow, 1) as $date_entry) {
570  if (ilDateTime::_equals($current_date, $date_entry, IL_CAL_DAY)) {
571  $this->getAppointment()->setStart(new ilDateTime($date_entry->get(IL_CAL_UNIX), IL_CAL_UNIX));
572  $this->getAppointment()->setEnd(new ilDateTime(
573  $date_entry->get(IL_CAL_UNIX) + $duration,
575  ));
576  break;
577  }
578  }
579  // Finally reset recurrence
580  $this->rec = new ilCalendarRecurrence();
581  }
582 
583  $cat_id = ilCalendarCategoryAssignments::_lookupCategory($this->app->getEntryId());
584  $cats = ilCalendarCategories::_getInstance($this->user->getId());
585 
586  if (!$cats->isVisible($cat_id)) {
587  $this->error->raiseError($this->lng->txt('permission_denied'), $this->error->WARNING);
588  return;
589  }
590  if (!$cats->isEditable($cat_id) or $this->app->isAutoGenerated()) {
591  $this->showInfoScreen();
592  return;
593  }
594  if (!$form instanceof ilPropertyFormGUI) {
595  $form = $this->initForm('edit', $a_edit_single_app);
596  }
597  $this->tpl->setContent($form->getHTML());
598  }
599 
600  protected function showInfoScreen(): void
601  {
602  $info = new ilInfoScreenGUI($this);
603  $info->setFormAction($this->ctrl->getFormAction($this));
604  $info->addSection($this->lng->txt('cal_details'));
605 
606  // Appointment
607  $info->addProperty(
608  $this->lng->txt('appointment'),
610  $this->app->getStart(),
611  $this->app->getEnd()
612  )
613  );
614  $info->addProperty($this->lng->txt('title'), $this->app->getPresentationTitle());
615 
616  // Description
617  if (strlen($desc = $this->app->getDescription())) {
618  $info->addProperty($this->lng->txt('description'), $desc);
619  }
620 
621  // Location
622  if (strlen($loc = $this->app->getLocation())) {
623  $info->addProperty($this->lng->txt('cal_where'), $loc);
624  }
625 
626  $cat_id = ilCalendarCategoryAssignments::_lookupCategory($this->app->getEntryId());
627  $category = new ilCalendarCategory($cat_id);
628 
629  if ($category->getType() == ilCalendarCategory::TYPE_OBJ) {
630  $info->addSection($this->lng->txt('additional_info'));
631 
632  $cat_info = ilCalendarCategories::_getInstance()->getCategoryInfo($cat_id);
633  $refs = ilObject::_getAllReferences($cat_info['obj_id']);
634 
635  $href = ilLink::_getStaticLink(current($refs), ilObject::_lookupType($cat_info['obj_id']), true);
636  $info->addProperty(
637  $this->lng->txt('perma_link'),
638  '<a class="small" href="' . $href . '" target="_top">' . $href . '</a>'
639  );
640  }
641  $this->tpl->setContent($info->getHTML());
642  }
643 
644  protected function update(): void
645  {
646  $single_editing = $this->requested_rexl;
647  $form = $this->load('edit');
648 
649  if ($this->app->validate() and $this->notification->validate()) {
650  if (!(int) $form->getInput('calendar')) {
651  $cat_id = $this->createDefaultCalendar();
652  } else {
653  $cat_id = (int) $form->getInput('calendar');
654  }
655 
656  if ($single_editing) {
657  $original_id = $this->getAppointment()->getEntryId();
658  $this->getAppointment()->save();
659  $selected_ut = $this->getRecurrenceDateFromQuery();
660  if ($selected_ut > 0) {
661  $exclusion = new ilCalendarRecurrenceExclusion();
662  $exclusion->setEntryId($original_id);
663  $exclusion->setDate(new ilDate($selected_ut, IL_CAL_UNIX));
664  $this->logger->dump($this->getAppointment()->getEntryId());
665  $this->logger->dump(ilDatePresentation::formatDate(new ilDate($selected_ut, IL_CAL_UNIX)));
666  $exclusion->save();
667  }
668  $this->rec = new ilCalendarRecurrence();
669  $this->rec->setEntryId($this->getAppointment()->getEntryId());
670  } else {
671  $this->getAppointment()->update();
672  }
673  $this->notification->save();
674  $this->saveRecurrenceSettings();
675  $ass = new ilCalendarCategoryAssignments($this->app->getEntryId());
676  $ass->deleteAssignments();
677  $ass->addAssignment($cat_id);
678 
679  // Send notifications
680  $notification = (bool) $form->getInput('not');
681  if (
682  ilCalendarSettings::_getInstance()->isNotificationEnabled() &&
683  $notification
684  ) {
685  $this->distributeNotifications($cat_id, $this->app->getEntryId(), false);
686  }
687  if (ilCalendarSettings::_getInstance()->isUserNotificationEnabled()) {
689  }
690 
691  $this->tpl->setOnScreenMessage('success', $this->lng->txt('msg_obj_modified'), true);
692  $this->ctrl->returnToParent($this);
693  } else {
694  $this->form->setValuesByPost();
695  $this->tpl->setOnScreenMessage('failure', $this->error->getMessage());
696  }
697  $this->edit(false, $this->form);
698  }
699 
700  protected function askDelete(): void
701  {
702  $this->ctrl->saveParameter(
703  $this,
704  [
705  'seed',
706  'app_id',
707  'dt',
708  'idate'
709  ]
710  );
711 
712  $app_id = (int) ($this->request->getQueryParams()['app_id'] ?? 0);
713  if (!$app_id) {
714  $this->tpl->setOnScreenMessage('failure', $this->lng->txt('err_check_input'));
715  $this->ctrl->returnToParent($this);
716  }
717 
719  if (!count($recs)) {
720  $confirm = new ilConfirmationGUI();
721  $confirm->setFormAction($this->ctrl->getFormAction($this));
722  $confirm->setHeaderText($this->lng->txt('cal_delete_app_sure'));
723  $confirm->setCancel($this->lng->txt('cancel'), 'cancel');
724  $confirm->addItem('appointments[]', (string) $this->app->getEntryId(), $this->app->getTitle());
725  $confirm->setConfirm($this->lng->txt('delete'), 'delete');
726  $this->tpl->setContent($confirm->getHTML());
727  } else {
728  $table = new ilCalendarRecurrenceTableGUI(
729  $this->app,
730  $this,
731  'askDelete'
732  );
733  $table->init();
734  $table->parse();
735  $this->tpl->setContent($table->getHTML());
736  $this->tpl->setOnScreenMessage('question', $this->lng->txt('cal_delete_app_sure'));
737  $this->tpl->setOnScreenMessage('info', $this->lng->txt('cal_recurrence_confirm_deletion'));
738  }
739  }
740 
741  protected function delete(): void
742  {
743  $app_ids = (array) ($this->request->getParsedBody()['appointment_ids'] ?? []);
744  if (!$app_ids) {
745  $this->logger->dump($app_ids);
746  $app_ids = (array) ($this->request->getQueryParams()['app_id'] ?? []);
747  }
748  if (!$app_ids) {
749  $this->ctrl->returnToParent($this);
750  }
751  foreach ($app_ids as $app_id) {
752  $app_id = (int) $app_id;
753  $app = new ilCalendarEntry($app_id);
754  $app->delete();
757  }
758  $this->tpl->setOnScreenMessage('success', $this->lng->txt('cal_deleted_app'), true);
759  $this->ctrl->returnToParent($this);
760  }
761 
762  protected function deleteExclude(bool $a_return = true): void
763  {
764  $recurrence_ids = (array) ($this->request->getParsedBody()['recurrence_ids'] ?? []);
765  $app_id = (int) ($this->request->getQueryParams()['app_id'] ?? 0);
766  if (!count($recurrence_ids)) {
767  $this->tpl->setOnScreenMessage('failure', $this->lng->txt('select_one'), true);
768  $this->ctrl->redirect($this, 'askDelete');
769  }
770  if (!$app_id) {
771  $this->ctrl->returnToParent($this);
772  }
773  foreach ($recurrence_ids as $rdate) {
774  $exclusion = new ilCalendarRecurrenceExclusion();
775  $exclusion->setEntryId($app_id);
776  $exclusion->setDate(new ilDate($rdate, IL_CAL_UNIX));
777  $exclusion->save();
778  }
779  if ($a_return) {
780  $this->tpl->setOnScreenMessage('success', $this->lng->txt('cal_deleted_app'), true);
781  $this->ctrl->returnToParent($this);
782  }
783  }
784 
785  protected function initTimeZone(): void
786  {
787  $this->timezone = $this->user->getTimeZone();
788  }
789 
790  protected function initInitialDate(ilDate $initialDate): void
791  {
792  $hour = 0;
793  if ($this->http->wrapper()->query()->has('hour')) {
794  $hour = $this->http->wrapper()->query()->retrieve(
795  'hour',
796  $this->refinery->kindlyTo()->int()
797  );
798  }
799 
800  if (!$hour) {
801  $this->initialDate = clone $initialDate;
802  $this->default_fulltime = true;
803  } else {
804  if ($hour < 10) {
805  $time = '0' . $hour . ':00:00';
806  } else {
807  $time = (int) $hour . ':00:00';
808  }
809  $this->initialDate = new ilDateTime(
810  $initialDate->get(IL_CAL_DATE) . ' ' . $time,
813  );
814  $this->default_fulltime = false;
815  }
816  }
817 
818  protected function initSeed(ilDate $seed): void
819  {
820  $this->seed = clone $seed;
821  $this->default_fulltime = true;
822  }
823 
824  protected function initAppointment(int $a_app_id = 0): void
825  {
826  $this->app = new ilCalendarEntry($a_app_id);
827  $this->notification = new ilCalendarUserNotification($this->app->getEntryId());
828 
829  if (!$a_app_id) {
830  $start = clone $this->initialDate;
831  $this->app->setStart($start);
832 
833  $seed_end = clone $this->initialDate;
834  if ($this->default_fulltime) {
835  #$seed_end->increment(IL_CAL_DAY,1);
836  } else {
837  $seed_end->increment(IL_CAL_HOUR, 1);
838  }
839  $this->app->setEnd($seed_end);
840  $this->app->setFullday($this->default_fulltime);
841 
842  $this->rec = new ilCalendarRecurrence();
843  } else {
844  $this->rec = ilCalendarRecurrences::_getFirstRecurrence($this->app->getEntryId());
845  }
846  }
847 
848  protected function load($a_mode): ilPropertyFormGUI
849  {
850  // needed for date handling
851  $form = $this->initForm($a_mode);
852  $this->form->checkInput();
853 
854  $this->app->setTitle($form->getInput('title'));
855  $this->app->setLocation($form->getInput('location'));
856  $this->app->setDescription($form->getInput('description'));
857  $this->app->enableNotification((bool) $form->getInput('not'));
858 
859  $period = $this->form->getItemByPostVar('event');
860  $start = $period->getStart();
861  $end = $period->getEnd();
862 
863  $this->app->setFullday($start instanceof ilDate);
864  $this->app->setStart($start);
865  $this->app->setEnd($end);
866 
867  $this->loadNotificationRecipients($form);
868  $this->loadRecurrenceSettings($form);
869  return $form;
870  }
871 
872  protected function loadNotificationRecipients(ilPropertyFormGUI $form): void
873  {
874  $this->notification->setRecipients(array());
875  $map = [];
876  foreach ((array) $form->getInput('notu') as $rcp) {
877  $rcp = trim($rcp);
878  $usr_id = (int) ilObjUser::_loginExists($rcp);
879  if ($rcp === '') {
880  continue;
881  }
882  if (in_array($rcp, $map)) {
883  continue;
884  }
885  $map[] = $rcp;
886  if ($usr_id) {
887  $this->notification->addRecipient(
889  $usr_id
890  );
891  } else {
892  $this->notification->addRecipient(
894  0,
895  $rcp
896  );
897  }
898  }
899  }
900 
901  protected function loadRecurrenceSettings(ilPropertyFormGUI $form): void
902  {
903  if ($form->getItemByPostVar('frequence') instanceof ilRecurrenceInputGUI) {
904  $this->rec = $form->getItemByPostVar('frequence')->getRecurrence();
905  } else {
906  $this->rec = new ilCalendarRecurrence();
907  }
908  }
909 
910  protected function saveRecurrenceSettings(): void
911  {
912  switch ($this->rec->getFrequenceType()) {
913  case '':
915  // No recurrence => delete if there is an recurrence rule
916  if ($this->rec->getRecurrenceId()) {
917  $this->rec->delete();
918  }
919  break;
920 
921  default:
922  if ($this->rec->getRecurrenceId()) {
923  $this->rec->update();
924  } else {
925  $this->rec->save();
926  }
927  break;
928  }
929  }
930 
931  protected function createDefaultCalendar(): int
932  {
933  $cat = new ilCalendarCategory();
934  $cat->setColor(ilCalendarCategory::DEFAULT_COLOR);
935  $cat->setType(ilCalendarCategory::TYPE_USR);
936  $cat->setTitle($this->lng->txt('cal_default_calendar'));
937  $cat->setObjId($this->user->getId());
938 
939  // delete calendar cache
940  ilCalendarCache::getInstance()->deleteUserEntries($this->user->getId());
941 
942  return $cat->add();
943  }
944 
948  protected function confirmRegister(): void
949  {
950  $dstart = 0;
951  if ($this->http->wrapper()->query()->has('dstart')) {
952  $dstart = $this->http->wrapper()->query()->retrieve(
953  'dstart',
954  $this->refinery->kindlyTo()->int()
955  );
956  }
957  $dend = 0;
958  if ($this->http->wrapper()->query()->has('dend')) {
959  $dend = $this->http->wrapper()->query()->retrieve(
960  'dend',
961  $this->refinery->kindlyTo()->int()
962  );
963  }
964 
965  $app_id = $this->getAppointmentIdFromQuery();
966  $entry = new ilCalendarEntry($app_id);
968  new ilDateTime($dstart, IL_CAL_UNIX),
969  new ilDateTime($dend, IL_CAL_UNIX)
970  );
971 
972  $conf = new ilConfirmationGUI();
973  $this->ctrl->setParameter($this, 'dstart', $dstart);
974  $this->ctrl->setParameter($this, 'dend', $dend);
975 
976  $conf->setFormAction($this->ctrl->getFormAction($this));
977  $conf->setHeaderText($this->lng->txt('cal_confirm_reg_info'));
978  $conf->setConfirm($this->lng->txt('cal_reg_register'), 'register');
979  $conf->setCancel($this->lng->txt('cancel'), 'cancel');
980  $conf->addItem('app_id', (string) $entry->getEntryId(), $entry->getTitle() . ' (' . $start . ')');
981  $this->tpl->setContent($conf->getHTML());
982  }
983 
984  protected function register(): void
985  {
986  $dstart = 0;
987  if ($this->http->wrapper()->query()->has('dstart')) {
988  $dstart = $this->http->wrapper()->query()->retrieve(
989  'dstart',
990  $this->refinery->kindlyTo()->int()
991  );
992  }
993  $dend = 0;
994  if ($this->http->wrapper()->query()->has('dend')) {
995  $dend = $this->http->wrapper()->query()->retrieve(
996  'dend',
997  $this->refinery->kindlyTo()->int()
998  );
999  }
1000  $app_id = 0;
1001  if ($this->http->wrapper()->post()->has('app_id')) {
1002  $app_id = $this->http->wrapper()->post()->retrieve(
1003  'app_id',
1004  $this->refinery->kindlyTo()->int()
1005  );
1006  }
1007  $reg = new ilCalendarRegistration($app_id);
1008  $reg->register(
1009  $this->user->getId(),
1010  new ilDateTime($dstart, IL_CAL_UNIX),
1011  new ilDateTime((int) $dend, IL_CAL_UNIX)
1012  );
1013 
1014  $this->tpl->setOnScreenMessage('success', $this->lng->txt('cal_reg_registered'), true);
1015  $this->ctrl->returnToParent($this);
1016  }
1017 
1018  public function confirmUnregister(): void
1019  {
1020  $dstart = 0;
1021  if ($this->http->wrapper()->query()->has('dstart')) {
1022  $dstart = $this->http->wrapper()->query()->retrieve(
1023  'dstart',
1024  $this->refinery->kindlyTo()->int()
1025  );
1026  }
1027  $dend = 0;
1028  if ($this->http->wrapper()->query()->has('dend')) {
1029  $dend = $this->http->wrapper()->query()->retrieve(
1030  'dend',
1031  $this->refinery->kindlyTo()->int()
1032  );
1033  }
1034 
1035  $app_id = $this->getAppointmentIdFromQuery();
1036  $entry = new ilCalendarEntry($app_id);
1038  new ilDateTime($dstart, IL_CAL_UNIX),
1039  new ilDateTime($dend, IL_CAL_UNIX)
1040  );
1041 
1042  $this->ctrl->setParameter($this, 'dstart', (int) $dstart);
1043  $this->ctrl->setParameter($this, 'dend', (int) $dend);
1044 
1045  $conf = new ilConfirmationGUI();
1046  $conf->setFormAction($this->ctrl->getFormAction($this));
1047  $conf->setHeaderText($this->lng->txt('cal_confirm_unreg_info'));
1048  $conf->setConfirm($this->lng->txt('cal_reg_unregister'), 'unregister');
1049  $conf->setCancel($this->lng->txt('cancel'), 'cancel');
1050  $conf->addItem('app_id', (string) $entry->getEntryId(), $entry->getTitle() . ' (' . $start . ')');
1051 
1052  $this->tpl->setContent($conf->getHTML());
1053  }
1054 
1058  protected function unregister(): void
1059  {
1060  $dstart = 0;
1061  if ($this->http->wrapper()->query()->has('dstart')) {
1062  $dstart = $this->http->wrapper()->query()->retrieve(
1063  'dstart',
1064  $this->refinery->kindlyTo()->int()
1065  );
1066  }
1067  $dend = 0;
1068  if ($this->http->wrapper()->query()->has('dend')) {
1069  $dend = $this->http->wrapper()->query()->retrieve(
1070  'dend',
1071  $this->refinery->kindlyTo()->int()
1072  );
1073  }
1074  $app_id = 0;
1075  if ($this->http->wrapper()->post()->has('app_id')) {
1076  $app_id = $this->http->wrapper()->post()->retrieve(
1077  'app_id',
1078  $this->refinery->kindlyTo()->int()
1079  );
1080  }
1081  $reg = new ilCalendarRegistration($app_id);
1082  $reg->unregister(
1083  $this->user->getId(),
1084  new ilDateTime((int) $dstart, IL_CAL_UNIX),
1085  new ilDateTime((int) $dend, IL_CAL_UNIX)
1086  );
1087 
1088  $this->tpl->setOnScreenMessage('success', $this->lng->txt('cal_reg_unregistered'), true);
1089  $this->ctrl->returnToParent($this);
1090  }
1091 
1095  public function book(): void
1096  {
1097  $entry_id = $this->getAppointmentIdFromQuery();
1098  $this->ctrl->saveParameter($this, 'app_id');
1099 
1100  $entry = new ilCalendarEntry($entry_id);
1101  $booking = new \ilBookingEntry($entry->getContextId());
1102  $user = $booking->getObjId();
1103 
1104  $form = $this->initFormConfirmBooking();
1105  $form->getItemByPostVar('date')->setValue(ilDatePresentation::formatPeriod(
1106  $entry->getStart(),
1107  $entry->getEnd()
1108  ));
1109  $form->getItemByPostVar('title')->setValue($entry->getTitle() . " (" . ilObjUser::_lookupFullname($user) . ')');
1110 
1111  $this->tpl->setContent($form->getHTML());
1112  }
1113 
1115  {
1116  $form = new ilPropertyFormGUI();
1117  $form->setFormAction($this->ctrl->getFormAction($this));
1118  $form->addCommandButton('bookconfirmed', $this->lng->txt('cal_confirm_booking'));
1119  $form->addCommandButton('cancel', $this->lng->txt('cancel'));
1120 
1121  $date = new ilNonEditableValueGUI($this->lng->txt('appointment'), 'date');
1122  $form->addItem($date);
1123 
1124  $title = new ilNonEditableValueGUI($this->lng->txt('title'), 'title');
1125  $form->addItem($title);
1126 
1127  $message = new ilTextAreaInputGUI($this->lng->txt('cal_ch_booking_message_tbl'), 'comment');
1128  $message->setRows(5);
1129  $form->addItem($message);
1130 
1131  return $form;
1132  }
1133 
1137  public function bookconfirmed()
1138  {
1139  $entry = $this->getAppointmentIdFromQuery();
1140  $form = $this->initFormConfirmBooking();
1141  if ($form->checkInput()) {
1142  // check if appointment is bookable
1143  $cal_entry = new ilCalendarEntry($entry);
1144 
1145  $booking = new ilBookingEntry($cal_entry->getContextId());
1146 
1147  if (!$booking->isAppointmentBookableForUser($entry, $GLOBALS['DIC']['ilUser']->getId())) {
1148  $this->tpl->setOnScreenMessage('failure', $this->lng->txt('cal_booking_failed_info'), true);
1149  $this->ctrl->returnToParent($this);
1150  }
1151 
1152  ilConsultationHourUtils::bookAppointment($this->user->getId(), $entry, $form->getInput('comment'));
1153  }
1154  $this->tpl->setOnScreenMessage('success', $this->lng->txt('cal_booking_confirmed'), true);
1155  $this->ctrl->returnToParent($this);
1156  }
1157 
1158  protected function deleteBooking(): void
1159  {
1160  $this->cancelBooking(false);
1161  }
1162 
1167  public function cancelBooking(bool $send_mail = true): void
1168  {
1169  $entry = $this->getAppointmentIdFromQuery();
1170  $entry = new ilCalendarEntry($entry);
1171 
1172  $category = $this->calendarEntryToCategory($entry);
1173  if ($category->getType() == ilCalendarCategory::TYPE_CH) {
1174  $booking = new ilBookingEntry($entry->getContextId());
1175  if (!$booking->hasBooked($entry->getEntryId()) && !$booking->isOwner()) {
1176  $this->ctrl->returnToParent($this);
1177  return;
1178  }
1179  $entry_title = ' ' . $entry->getTitle() . " (" . ilObjUser::_lookupFullname($booking->getObjId()) . ')';
1180  } elseif ($category->getType() == ilCalendarCategory::TYPE_BOOK) {
1181  $entry_title = ' ' . $entry->getTitle();
1182  } else {
1183  $this->ctrl->returnToParent($this);
1184  return;
1185  }
1186  $title = ilDatePresentation::formatPeriod($entry->getStart(), $entry->getEnd());
1187  $conf = new ilConfirmationGUI();
1188  $conf->setFormAction($this->ctrl->getFormAction($this));
1189  $conf->setHeaderText(
1190  $send_mail ?
1191  $this->lng->txt('cal_cancel_booking_info') :
1192  $this->lng->txt('cal_delete_booking_info')
1193  );
1194  $conf->setConfirm(
1195  $send_mail ?
1196  $this->lng->txt('cal_cancel_booking') :
1197  $this->lng->txt('delete'),
1198  $send_mail ?
1199  'cancelConfirmed' :
1200  'deleteConfirmed'
1201  );
1202  $conf->setCancel($this->lng->txt('cancel'), 'cancel');
1203  $conf->addItem('app_id', (string) $entry->getEntryId(), $title . ' - ' . $entry_title);
1204  $this->tpl->setContent($conf->getHTML());
1205  }
1206 
1207  protected function deleteConfirmed(): void
1208  {
1209  $this->cancelConfirmed(false);
1210  }
1211 
1216  public function cancelConfirmed(bool $send_mail = true): void
1217  {
1218  $app_id = 0;
1219  if ($this->http->wrapper()->post()->has('app_id')) {
1220  $app_id = $this->http->wrapper()->post()->retrieve(
1221  'app_id',
1222  $this->refinery->kindlyTo()->int()
1223  );
1224  }
1225  $entry = new ilCalendarEntry($app_id);
1226  $category = $this->calendarEntryToCategory($entry);
1227  $booking = new ilBookingEntry($entry->getContextId());
1228  if ($category->getType() == ilCalendarCategory::TYPE_CH && $booking->isOwner()) {
1229  foreach ($booking->getCurrentBookings($entry->getEntryId()) as $bookuser) {
1231  $bookuser,
1232  (int) $app_id,
1233  $send_mail
1234  );
1235  }
1236  } elseif ($category->getType() == ilCalendarCategory::TYPE_CH) {
1237  // find cloned calendar entry in user calendar
1239  $this->user->getId(),
1240  $entry->getContextId(),
1241  $entry->getStart(),
1243  false
1244  );
1245 
1246  // Fix for wrong, old entries
1247  foreach ($apps as $own_app) {
1248  $ref_entry = new ilCalendarEntry($own_app);
1249  $ref_entry->delete();
1250  }
1251 
1252  $booking = new ilBookingEntry($entry->getContextId());
1253  $booking->cancelBooking($entry->getEntryId());
1254 
1255  // do NOT delete original entry
1256  } elseif ($category->getType() == ilCalendarCategory::TYPE_BOOK) {
1257  $booking = new ilBookingReservation($entry->getContextId());
1259  $booking->update();
1260 
1261  $entry->delete();
1262  }
1263 
1264  $this->tpl->setOnScreenMessage('success', $this->lng->txt('cal_cancel_booking_confirmed'), true);
1265  $this->ctrl->returnToParent($this);
1266  }
1267 
1272  {
1273  $assignment = new ilCalendarCategoryAssignments($entry->getEntryId());
1274  $assignment = $assignment->getFirstAssignment();
1275  return new ilCalendarCategory($assignment);
1276  }
1277 }
__construct(ilDate $seed, ilDate $initialDate, int $a_appointment_id=0)
loadRecurrenceSettings(ilPropertyFormGUI $form)
const IL_CAL_DATETIME
const ANONYMOUS_USER_ID
Definition: constants.php:27
This class represents a selection list property in a property form.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
ilCalendarUserNotification $notification
getItemByPostVar(string $a_post_var)
static _lookupFullname(int $a_user_id)
const IL_CAL_HOUR
static getAppointmentIds(int $a_user_id, ?int $a_context_id=null, ?ilDateTime $a_start=null, ?int $a_type=null, bool $a_check_owner=true)
This class represents an input GUI for recurring events/appointments (course events or calendar appoi...
Model of calendar entry recurrcences based on iCalendar-RFC-5545.
Distributes calendar mail notifications.
static _getAllReferences(int $id)
get all reference ids for object ID
Help GUI class.
static cancelBooking(int $a_usr_id, int $a_app_id, bool $a_send_notification=true)
Cancel a booking.
distributeNotifications(int $a_cat_id, int $app_id, bool $a_new_appointment=true)
static initDomEvent(?ilGlobalTemplateInterface $a_main_tpl=null)
Init YUI DomEvent used in Services/Calendar, Modules/Session, Modules/Test (Jan 2022) ...
get(int $a_format, string $a_format_str='', string $a_tz='')
increment(string $a_type, int $a_count=1)
loadNotificationRecipients(ilPropertyFormGUI $form)
Stores calendar categories.
initForm(string $a_mode, bool $a_edit_single_app=false)
add(?ilPropertyFormGUI $form=null)
add new appointment
static _getRecurrences(int $a_cal_id)
get all recurrences of an appointment
const IL_CAL_UNIX
unregister()
Unregister calendar, was confirmed.
$duration
askEdit()
Check edit single apppointment / edit all appointments for recurring appointments.
getInput(string $a_post_var, bool $ensureValidation=true)
Returns the input of an item, if item provides getInput method and as fallback the value of the HTTP-...
setRecurrence(int $a_type)
set type of recurrence public
notification()
description: > Example for rendring a notification glyph.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static _lookupObjId(int $ref_id)
static _lookupCategoryIdByObjId(int $a_obj_id)
lookup category by obj_id
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
const IL_CAL_DAY
cancelBooking(bool $send_mail=true)
Confirmation screen to cancel consultation appointment or ressource booking depends on calendar categ...
$ref_id
Definition: ltiauth.php:65
static http()
Fetches the global http state from ILIAS.
$GLOBALS["DIC"]
Definition: wac.php:53
static _deleteByAppointmentId(int $a_app_id)
Delete appointment assignment.
Calculates an ilDateList for a given calendar entry and recurrence rule.
edit(bool $a_edit_single_app=false, ?ilPropertyFormGUI $form=null)
edit appointment
setFormAction(string $a_formaction)
distributeUserNotifications()
Send mail to selected users.
calendarEntryToCategory(ilCalendarEntry $entry)
Get category object of given calendar entry.
static _loginExists(string $a_login, int $a_user_id=0)
check if a login name already exists You may exclude a user from the check by giving his user id as 2...
registration for calendar appointments
global $DIC
Definition: shib_login.php:22
setStatus(?int $a_status)
Set booking status.
static _getInstance($a_usr_id=0)
get singleton instance
addCommandButton(string $a_cmd, string $a_text, string $a_id="")
bookconfirmed()
Book consultation appointment, was confirmed.
form( $class_path, string $cmd, string $submit_caption="")
const IL_CAL_DATE
editSingle()
Edit one single appointment ^.
Administrate calendar appointments.
This class represents a text area property in a property form.
static formatDate(ilDateTime $date, bool $a_skip_day=false, bool $a_include_wd=false, bool $include_seconds=false, ?ilObjUser $user=null,)
static _equals(ilDateTime $start, ilDateTime $end, string $a_compare_field='', string $a_tz='')
Check if two date are equal.
$message
Definition: xapiexit.php:31
static bookAppointment(int $a_usr_id, int $a_app_id, string $comment='')
Book an appointment.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static _lookupType(int $id, bool $reference=false)
book()
Confirmation screen for booking of consultation appointment.
exit
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
cancelConfirmed(bool $send_mail=true)
Cancel consultation appointment or ressource booking, was confirmed This will delete the calendar ent...
confirmRegister()
Register to an appointment.
Class ilCalendarRecurrenceTableGUI.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static formatPeriod(ilDateTime $start, ilDateTime $end, bool $a_skip_starting_day=false, ?ilObjUser $user=null)
Format a period of two dates Shows: 14.
static _lookupLogin(int $a_user_id)