ILIAS  release_8 Revision v8.23
class.ilObjEmployeeTalkSeriesGUI.php
Go to the documentation of this file.
1 <?php
2 
3 declare(strict_types=1);
4 
27 
45 {
46  private \ILIAS\DI\Container $container;
48  private int $userId = -1;
49 
50  public function __construct()
51  {
52  $this->container = $GLOBALS["DIC"];
53 
54  $refId = $this->container
55  ->http()
56  ->wrapper()
57  ->query()
58  ->retrieve("ref_id", $this->container->refinery()->kindlyTo()->int());
59 
60  parent::__construct([], $refId, true, false);
61  $this->container->language()->loadLanguageModule('mst');
62  $this->container->language()->loadLanguageModule('trac');
63  $this->container->language()->loadLanguageModule('etal');
64  $this->container->language()->loadLanguageModule('dateplaner');
65 
66  $this->type = ilObjEmployeeTalkSeries::TYPE;
67 
68  $this->setReturnLocation("save", strtolower(ilEmployeeTalkMyStaffListGUI::class));
69  $wrapper = $this->container->http()->wrapper()->query();
70 
71  if ($wrapper->has('usr_id')) {
72  $this->userId = $wrapper->retrieve('usr_id', $this->container->refinery()->kindlyTo()->int());
73  }
74 
75  $this->omitLocator();
76  }
77 
78  private function checkAccessOrFail(): void
79  {
80  $talkAccess = new ilObjEmployeeTalkAccess();
81  if (!$talkAccess->canCreate()) {
82  $this->tpl->setOnScreenMessage('failure', $this->lng->txt("permission_denied"), true);
83  $this->ctrl->redirectByClass(ilDashboardGUI::class, "");
84  }
85  }
86 
87  public function executeCommand(): void
88  {
89  $this->checkAccessOrFail();
90 
91  // determine next class in the call structure
92  $next_class = $this->container->ctrl()->getNextClass($this);
93 
94  switch ($next_class) {
95  case strtolower(ilRepositorySearchGUI::class):
96  $repo = new ilRepositorySearchGUI();
97  $repo->addUserAccessFilterCallable(function ($user_ids) {
113  return array_filter(
114  $user_ids,
115  function (int $id) use ($access) {
116  return $access->canCreate(new ilObjUser($id));
117  }
118  );
119  });
120  $this->container->ctrl()->forwardCommand($repo);
121  break;
122  default:
123  parent::executeCommand();
124  }
125  }
126 
131  protected function setTitleAndDescription(): void
132  {
133  $this->tpl->resetHeaderBlock();
134  }
135 
146  protected function checkPermissionBool(string $a_perm, string $a_cmd = "", string $a_type = "", ?int $a_ref_id = null): bool
147  {
148  if ($a_perm === 'create') {
149  return true;
150  }
151  return false;
152  }
153 
154  public function confirmedDeleteObject(): void
155  {
156  if ($this->post_wrapper->has("mref_id")) {
157  $mref_id = $this->post_wrapper->retrieve(
158  "mref_id",
159  $this->refinery->kindlyTo()->listOf($this->refinery->kindlyTo()->int())
160  );
161  $saved_post = array_unique(array_merge(ilSession::get('saved_post'), $mref_id));
162  ilSession::set('saved_post', $saved_post);
163  }
164 
165  $ru = new ilRepositoryTrashGUI($this);
166  $ru->deleteObjects($this->requested_ref_id, ilSession::get("saved_post"));
167  ilSession::clear("saved_post");
168 
169  $this->ctrl->redirectByClass(strtolower(ilEmployeeTalkMyStaffListGUI::class), ControlFlowCommand::DEFAULT, "", false);
170  }
171 
172  public function cancelDeleteObject(): void
173  {
174  ilSession::clear("saved_post");
175 
176  $this->ctrl->redirectByClass(strtolower(ilEmployeeTalkMyStaffListGUI::class), ControlFlowCommand::DEFAULT, "", false);
177  }
178 
179  public function cancelObject(): void
180  {
181  $this->ctrl->redirectByClass(strtolower(ilEmployeeTalkMyStaffListGUI::class), ControlFlowCommand::DEFAULT, "", false);
182  }
183 
189  protected function afterSave(ilObject $a_new_object): void
190  {
194  $newObject = $a_new_object;
195 
196  // Create clones of the first one
197  $event = $this->loadRecurrenceSettings();
198  $this->copyTemplateValues($newObject);
199  $this->createRecurringTalks($newObject, $event);
200 
201  $this->tpl->setOnScreenMessage('success', $this->lng->txt("object_added"), true);
202  $this->ctrl->redirectByClass(strtolower(ilEmployeeTalkMyStaffListGUI::class), ControlFlowCommand::DEFAULT, "", false);
203  }
204 
205  public function saveObject(): void
206  {
207  $this->ctrl->setParameter($this, "new_type", $this->requested_new_type);
208 
209  $form = $this->initCreateForm($this->requested_new_type);
210  if ($form->checkInput()) {
211  $userName = (string) $form->getInput('etal_employee');
212  $userId = (int) ilObjUser::_lookupId($userName);
213  $talkAccess = new ilObjEmployeeTalkAccess();
214  if (
215  !ilObjUser::_loginExists($userName) ||
216  !$talkAccess->canCreate(new ilObjUser($userId))
217  ) {
218  $form->getItemByPostVar('etal_employee')
219  ->setAlert($this->lng->txt('etal_invalid_user'));
220  $this->tpl->setOnScreenMessage(
221  'failure',
222  $this->lng->txt('form_input_not_valid')
223  );
224  $form->setValuesByPost();
225  $this->tpl->setContent($form->getHTML());
226  return;
227  }
228 
229  $this->ctrl->setParameter($this, "new_type", "");
230 
231  $class_name = "ilObj" . $this->obj_definition->getClassName($this->requested_new_type);
232  $newObj = new $class_name();
233  $newObj->setType($this->requested_new_type);
234  $newObj->setTitle($form->getInput("title"));
235  $newObj->setDescription($form->getInput("desc"));
236  $newObj->create();
237 
238  $this->putObjectInTree($newObj);
239 
240  $this->afterSave($newObj);
241  }
242 
243  $form->setValuesByPost();
244  $this->tpl->setContent($form->getHTML());
245  }
246 
247  protected function initCreateForm(string $new_type): ilPropertyFormGUI
248  {
249  $form = new ilPropertyFormGUI();
250  $form->setTarget("_top");
251  $form->setFormAction($this->ctrl->getFormAction($this, "save") . '&template=' . $this->getTemplateRefId());
252  $form->setTitle($this->lng->txt($new_type . "_new"));
253 
254  // title
255  $ti = new ilTextInputGUI($this->lng->txt("title"), "title");
256  $ti->setSize(min(40, ilObject::TITLE_LENGTH));
257  $ti->setMaxLength(ilObject::TITLE_LENGTH);
258  $ti->setRequired(true);
259  $form->addItem($ti);
260 
261  // description
262  $ta = new ilTextAreaInputGUI($this->lng->txt("description"), "desc");
263  $ta->setCols(40);
264  $ta->setRows(2);
265  $form->addItem($ta);
266 
267  // Start & End Date
268  $dur = new ilDateDurationInputGUI($this->lng->txt('cal_fullday'), 'etal_event');
269  $dur->setRequired(true);
270  $dur->enableToggleFullTime(
271  $this->lng->txt('cal_fullday_title'),
272  false
273  );
274  $dur->setShowTime(true);
275  $form->addItem($dur);
276 
277  // Recurrence
278  $cal = new ilRecurrenceInputGUI("Calender", "frequence");
279  $event = new ilCalendarRecurrence();
280  //$event->setRecurrence(ilEventRecurrence::REC_EXCLUSION);
281  //$event->setFrequenceType(ilEventRecurrence::FREQ_DAILY);
282  $cal->allowUnlimitedRecurrences(false);
283  $cal->setRecurrence($event);
284  $form->addItem($cal);
285 
286  //Location
287  $location = new ilTextInputGUI("Location", "etal_location");
288  $location->setMaxLength(200);
289  $form->addItem($location);
290 
291  //Employee
292  $login = new ilTextInputGUI($this->lng->txt("employee"), "etal_employee");
293  $login->setRequired(true);
294  $login->setDataSource($this->ctrl->getLinkTargetByClass([
295  strtolower(self::class),
296  strtolower(ilRepositorySearchGUI::class)
297  ], 'doUserAutoComplete', '', true));
298 
299  if ($this->userId !== -1) {
300  $user = new ilObjUser($this->userId);
301  $login->setValue($user->getLogin());
302  }
303 
304  $form->addItem($login);
305 
306  $form = $this->initDidacticTemplate($form);
307 
308  $form->addCommandButton("save", $this->lng->txt($new_type . "_add"));
309  $form->addCommandButton("cancel", $this->lng->txt("cancel"));
310 
311  $this->form = $form;
312 
313  return $form;
314  }
315 
316  protected function initCreationForms($new_type): array
317  {
318  return [
319  self::CFORM_NEW => $this->initCreateForm($new_type)
320  ];
321  }
322 
323  public function viewObject(): void
324  {
325  self::_goto((string) $this->ref_id);
326  }
327 
328  public function getTabs(): void
329  {
330  }
331 
332  public function getAdminTabs(): void
333  {
334  }
335 
339  private function sendNotification(array $talks): void
340  {
341  if (count($talks) === 0) {
342  return;
343  }
344 
345  $firstTalk = $talks[0];
346  $talk_title = $firstTalk->getTitle();
347  $superior = new ilObjUser($firstTalk->getOwner());
348  $employee = new ilObjUser($firstTalk->getData()->getEmployee());
349  $superiorName = $superior->getFullname();
350 
351  $dates = array_map(
352  fn (ilObjEmployeeTalk $t) => $t->getData()->getStartDate(),
353  $talks
354  );
355  usort($dates, function (ilDateTime $a, ilDateTime $b) {
356  $a = $a->getUnixTime();
357  $b = $b->getUnixTime();
358  if ($a === $b) {
359  return 0;
360  }
361  return $a < $b ? -1 : 1;
362  });
363 
364  $add_time = $firstTalk->getData()->isAllDay() ? 0 : 1;
365  $format = ilCalendarUtil::getUserDateFormat($add_time, true);
366  $timezone = $employee->getTimeZone();
367  $dates = array_map(function (ilDateTime $d) use ($add_time, $format, $timezone) {
368  return $d->get(IL_CAL_FKT_DATE, $format, $timezone);
369  }, $dates);
370 
372  $firstTalk->getRefId(),
373  $talk_title,
374  $firstTalk->getDescription(),
375  $firstTalk->getData()->getLocation(),
376  'notification_talks_subject',
377  'notification_talks_created',
378  $superiorName,
379  $dates
380  );
381 
382  $vCalSender = new EmployeeTalkEmailNotificationService(
383  $message,
384  $talk_title,
385  $employee,
386  $superior,
387  VCalendarFactory::getInstanceFromTalks($firstTalk->getParent())
388  );
389 
390  $vCalSender->send();
391  }
392 
400  {
401  $rec = new ilCalendarRecurrence();
402 
403  switch ($this->form->getInput('frequence')) {
405  $rec->setFrequenceType($this->form->getInput('frequence'));
406  $rec->setInterval((int) $this->form->getInput('count_DAILY'));
407  break;
408 
410  $rec->setFrequenceType($this->form->getInput('frequence'));
411  $rec->setInterval((int) $this->form->getInput('count_WEEKLY'));
412  if (is_array($this->form->getInput('byday_WEEKLY'))) {
413  $rec->setBYDAY(ilUtil::stripSlashes(implode(',', $this->form->getInput('byday_WEEKLY'))));
414  }
415  break;
416 
418  $rec->setFrequenceType($this->form->getInput('frequence'));
419  $rec->setInterval((int) $this->form->getInput('count_MONTHLY'));
420  switch ((int) $this->form->getInput('subtype_MONTHLY')) {
421  case 0:
422  // nothing to do;
423  break;
424 
425  case 1:
426  switch ((int) $this->form->getInput('monthly_byday_day')) {
427  case 8:
428  // Weekday
429  $rec->setBYSETPOS($this->form->getInput('monthly_byday_num'));
430  $rec->setBYDAY('MO,TU,WE,TH,FR');
431  break;
432 
433  case 9:
434  // Day of month
435  $rec->setBYMONTHDAY($this->form->getInput('monthly_byday_num'));
436  break;
437 
438  default:
439  $rec->setBYDAY(($this->form->getInput('monthly_byday_num') . $this->form->getInput('monthly_byday_day')));
440  break;
441  }
442  break;
443 
444  case 2:
445  $rec->setBYMONTHDAY($this->form->getInput('monthly_bymonthday'));
446  break;
447  }
448  break;
449 
451  $rec->setFrequenceType($this->form->getInput('frequence'));
452  $rec->setInterval((int) $this->form->getInput('count_YEARLY'));
453  switch ((int) $this->form->getInput('subtype_YEARLY')) {
454  case 0:
455  // nothing to do;
456  break;
457 
458  case 1:
459  $rec->setBYMONTH($this->form->getInput('yearly_bymonth_byday'));
460  $rec->setBYDAY(($this->form->getInput('yearly_byday_num') . $this->form->getInput('yearly_byday')));
461  break;
462 
463  case 2:
464  $rec->setBYMONTH($this->form->getInput('yearly_bymonth_by_monthday'));
465  $rec->setBYMONTHDAY($this->form->getInput('yearly_bymonthday'));
466  break;
467  }
468  break;
469  }
470 
471  // UNTIL
472  switch ((int) $this->form->getInput('until_type')) {
473  case 1:
474  $rec->setFrequenceUntilDate(null);
475  // nothing to do
476  break;
477 
478  case 2:
479  $rec->setFrequenceUntilDate(null);
480  $rec->setFrequenceUntilCount((int) $this->form->getInput('count'));
481  break;
482 
483  case 3:
484  $frequence = $this->form->getItemByPostVar('frequence');
485  $end = $frequence->getRecurrence()->getFrequenceUntilDate();
486  $rec->setFrequenceUntilCount(0);
487  $rec->setFrequenceUntilDate($end);
488  break;
489  }
490 
491  return $rec;
492  }
493 
494 
495 
496  private function loadEtalkData(): EmployeeTalk
497  {
498  $location = $this->form->getInput('etal_location');
499  $employee = $this->form->getInput('etal_employee');
500  ['fullday' => $tgl] = $this->form->getInput('etal_event');
501 
505  $dateTimeInput = $this->form->getItemByPostVar('etal_event');
506  ['start' => $start, 'end' => $end] = $dateTimeInput->getValue();
507  if (intval($tgl)) {
508  $start_date = new ilDate($start, IL_CAL_UNIX);
509  $end_date = new ilDate($end, IL_CAL_UNIX);
510  } else {
511  $start_date = new ilDateTime($start, IL_CAL_UNIX, ilTimeZone::UTC);
512  $end_date = new ilDateTime($end, IL_CAL_UNIX, ilTimeZone::UTC);
513  }
514 
515  return new EmployeeTalk(
516  -1,
517  $start_date,
518  $end_date,
519  boolval(intval($tgl)),
520  '',
521  $location ?? '',
522  ilObjUser::getUserIdByLogin($employee),
523  false,
524  false,
526  );
527  }
528 
535  {
536  $template = new ilObjTalkTemplate($this->getTemplateRefId(), true);
537  $talk->setDescription($template->getTitle());
538  $talk->update();
539 
540  // assign talk series type to adv md records of the template
542  $template->getType(),
543  $template->getId(),
544  'etal',
545  false
546  ) as $rec) {
547  if (!$rec->isAssignedObjectType($talk->getType(), 'etal')) {
548  $rec->appendAssignedObjectType(
549  $talk->getType(),
550  'etal',
551  true
552  );
553  $rec->update();
554  }
555  }
556 
558  $talk->getId(),
559  'etal',
560  ilAdvancedMDRecord::getObjRecSelection($template->getId(), 'etal')
561  );
562 
564  0,
565  $template->getId(),
566  $talk->getId(),
568  );
569  }
570 
578  private function createRecurringTalks(ilObjEmployeeTalkSeries $talk, ilCalendarRecurrence $recurrence): bool
579  {
580  $data = $this->loadEtalkData();
581 
582  $firstAppointment = new EmployeeTalkPeriod(
583  $data->getStartDate(),
584  $data->getEndDate(),
585  $data->isAllDay()
586  );
587  $calc = new ilCalendarRecurrenceCalculator($firstAppointment, $recurrence);
588 
589  $periodStart = clone $data->getStartDate();
590 
591  $periodEnd = clone $data->getStartDate();
592  $periodEnd->increment(IL_CAL_YEAR, 5);
593  $dateIterator = $calc->calculateDateList($periodStart, $periodEnd);
594 
595  $periodDiff = $data->getEndDate()->get(IL_CAL_UNIX) -
596  $data->getStartDate()->get(IL_CAL_UNIX);
597 
598  $talkSession = new ilObjEmployeeTalk();
599  $talkSession->setTitle($this->form->getInput('title'));
600  $talkSession->setDescription($this->form->getInput('desc'));
601  $talkSession->setType(ilObjEmployeeTalk::TYPE);
602  $talkSession->create();
603 
604  $talkSession->createReference();
605  $talkSession->putInTree($talk->getRefId());
606 
607  $data->setObjectId($talkSession->getId());
608  $talkSession->setData($data);
609  $talkSession->update();
610  $talks = [];
611  $talks[] = $talkSession;
612 
613  if (!$recurrence->getFrequenceType()) {
614  $this->sendNotification($talks);
615  return true;
616  }
617 
618  // Remove start date
619  $dateIterator->removeByDAY($periodStart);
620  $dateIterator->rewind();
621 
625  foreach ($dateIterator as $date) {
626  $cloneObject = $talkSession->cloneObject($talk->getRefId());
627  $cloneData = $cloneObject->getData();
628 
629  $cloneData->setStartDate($date);
630  $endDate = $date->get(IL_CAL_UNIX) + $periodDiff;
631  if ($cloneData->isAllDay()) {
632  $cloneData->setEndDate(new ilDate($endDate, IL_CAL_UNIX));
633  } else {
634  $cloneData->setEndDate(new ilDateTime($endDate, IL_CAL_UNIX, ilTimeZone::UTC));
635  }
636  $cloneObject->setData($cloneData);
637  $cloneObject->update();
638  $talks[] = $cloneObject;
639  }
640 
641  $this->sendNotification($talks);
642 
643  return true;
644  }
645 
646  public static function _goto(string $refId): void
647  {
648  global $DIC;
649 
650  $children = $DIC->repositoryTree()->getChildIds((int) $refId);
651 
652  /*
653  * If the series contains talks, redirect to first talk,
654  * if not (which should only happen if someone messes with
655  * the URL) redirect to dashboard.
656  */
657  if (empty($children)) {
658  $DIC->ui()->mainTemplate()->setOnScreenMessage(
659  'failure',
660  $DIC->language()->txt("permission_denied"),
661  true
662  );
663  $DIC->ctrl()->redirectByClass(ilDashboardGUI::class, "");
664  }
665  ilObjEmployeeTalkGUI::_goto((string) $children[0]);
666  }
667 
668  private function getTemplateRefId(): int
669  {
670  $refId = 0;
671  if ($this->container->http()->wrapper()->query()->has('template')) {
672  $refId = $this->container->http()->wrapper()->query()->retrieve(
673  'template',
674  $this->container->refinery()->kindlyTo()->int()
675  );
676  }
677  if (
680  ) {
681  $this->tpl->setOnScreenMessage('failure', $this->lng->txt('etal_create_invalid_template_ref'), true);
682  $this->ctrl->redirectByClass([
683  strtolower(ilDashboardGUI::class),
684  strtolower(ilMyStaffGUI::class),
685  strtolower(ilEmployeeTalkMyStaffListGUI::class)
686  ], ControlFlowCommand::INDEX);
687  }
688 
689  return $refId;
690  }
691 }
get(int $a_format, string $a_format_str='', string $a_tz='')
get formatted date
static get(string $a_var)
omitLocator(bool $omit=true)
getItemByPostVar(string $a_post_var)
const TITLE_LENGTH
$location
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
Definition: buildRTE.php:22
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static stripSlashes(string $a_str, bool $a_strip_html=true, string $a_allow="")
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
setTarget(string $a_target)
static saveObjRecSelection(int $a_obj_id, string $a_sub_type="", array $a_records=null, bool $a_delete_before=true)
Save repository object record selection.
static _lookupId($a_user_str)
$refId
Definition: xapitoken.php:58
static _getSelectedRecordsByObject(string $a_obj_type, int $a_id, string $a_sub_type="", bool $is_ref_id=true)
const IL_CAL_UNIX
static getUserDateFormat(int $a_add_time=0, bool $a_for_parsing=false)
Parse current user setting into date/time format.
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-...
static lookupOfflineStatus(int $obj_id)
Lookup offline status using objectDataCache.
getFrequenceType()
Get Frequence type of recurrence.
global $DIC
Definition: feed.php:28
static getUserIdByLogin(string $a_login)
setDescription(string $desc)
static getObjRecSelection(int $a_obj_id, string $a_sub_type="")
Get repository object record selection.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
checkPermissionBool(string $a_perm, string $a_cmd="", string $a_type="", ?int $a_ref_id=null)
Talk Series does not use RBAC and therefore does not require the usual permission checks...
static _exists(int $id, bool $reference=false, ?string $type=null)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
setFormAction(string $a_formaction)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
initDidacticTemplate(ilPropertyFormGUI $form)
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...
loadRecurrenceSettings()
load recurrence settings
const IL_CAL_FKT_DATE
if(!defined('PATH_SEPARATOR')) $GLOBALS['_PEAR_default_error_mode']
Definition: PEAR.php:64
Repository GUI Utilities.
static _lookupObjectId(int $ref_id)
$format
Definition: metadata.php:235
afterSave(ilObject $new_object)
Post (successful) object creation hook.
setRequired(bool $a_required)
form( $class_path, string $cmd)
addCommandButton(string $a_cmd, string $a_text, string $a_id="")
putObjectInTree(ilObject $obj, int $parent_node_id=null)
Add object to tree at given position.
static _cloneValues(int $copy_id, int $a_source_id, int $a_target_id, ?string $a_sub_type=null, ?int $a_source_sub_id=null, ?int $a_target_sub_id=null)
Clone Advanced Meta Data.
__construct(Container $dic, ilPlugin $plugin)
This class represents a text area property in a property form.
setReturnLocation(string $cmd, string $location)
set specific return location for command
ilAccessHandler $access
$a
thx to https://mlocati.github.io/php-cs-fixer-configurator for the examples
Class ilContainerGUI This is a base GUI class for all container objects in ILIAS: root folder...
$message
Definition: xapiexit.php:32
setTitleAndDescription()
This GUI is only called when creating a talk (series).
static clear(string $a_var)
static set(string $a_var, $a_val)
Set a value.
copyTemplateValues(ilObjEmployeeTalkSeries $talk)
Copy the template values, into the talk series object.
for($i=6; $i< 13; $i++) for($i=1; $i< 13; $i++) $d
Definition: date.php:296
const IL_CAL_YEAR