ILIAS  release_5-3 Revision v5.3.23-19-g915713cf615
class.ilObjBookingPoolGUI.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (c) 1998-2010 ILIAS open source, Extended GPL, see docs/LICENSE */
3 
4 require_once "./Services/Object/classes/class.ilObjectGUI.php";
5 
18 {
22  protected $tabs;
23 
27  protected $nav_history;
28 
32  protected $help;
33 
38  public function __construct($a_data, $a_id, $a_call_by_reference, $a_prepare_output = true)
39  {
40  global $DIC;
41 
42  $this->tpl = $DIC["tpl"];
43  $this->tabs = $DIC->tabs();
44  $this->nav_history = $DIC["ilNavigationHistory"];
45  $this->help = $DIC["ilHelp"];
46  $this->ctrl = $DIC->ctrl();
47  $this->lng = $DIC->language();
48  $this->type = "book";
49  parent::__construct($a_data, $a_id, $a_call_by_reference, $a_prepare_output);
50  $this->lng->loadLanguageModule("book");
51 
52  if ((int) $_REQUEST['object_id'] > 0 && ilBookingObject::lookupPoolId((int) $_REQUEST['object_id']) != $this->object->getId()) {
53  throw new ilException("Booking Object ID does not match Booking Pool.");
54  }
55  }
56 
62  public function executeCommand()
63  {
64  $tpl = $this->tpl;
65  $ilTabs = $this->tabs;
66  $ilNavigationHistory = $this->nav_history;
68 
69  $next_class = $this->ctrl->getNextClass($this);
70  $cmd = $this->ctrl->getCmd();
71 
72  if (!$next_class && $cmd == 'render') {
73  if ($ilUser->getId() != ANONYMOUS_USER_ID) {
74  $this->ctrl->setCmdClass('ilBookingObjectGUI');
75  $next_class = $this->ctrl->getNextClass($this);
76  } else {
77  $this->ctrl->redirect($this, "infoscreen");
78  }
79  }
80 
81  if (substr($cmd, 0, 4) == 'book') {
82  $next_class = '';
83  }
84 
85  $ilNavigationHistory->addItem(
86  $this->ref_id,
87  "./goto.php?target=book_" . $this->ref_id,
88  "book"
89  );
90 
91  $this->prepareOutput();
92 
93  switch ($next_class) {
94  case 'ilpermissiongui':
95  $this->checkPermission('edit_permission');
96  $this->tabs_gui->setTabActive('perm_settings');
97  include_once("Services/AccessControl/classes/class.ilPermissionGUI.php");
98  $perm_gui = new ilPermissionGUI($this);
99  $ret =&$this->ctrl->forwardCommand($perm_gui);
100  break;
101 
102  case 'ilbookingobjectgui':
103  if (!$this->checkPermissionBool('read') && $this->checkPermissionBool('visible')) {
104  $this->ctrl->redirect($this, "infoScreen");
105  }
106  $this->checkPermission('read');
107  $this->tabs_gui->setTabActive('render');
108  include_once("Modules/BookingManager/classes/class.ilBookingObjectGUI.php");
109  $object_gui = new ilBookingObjectGUI($this);
110  $ret =&$this->ctrl->forwardCommand($object_gui);
111  break;
112 
113  case 'ilbookingschedulegui':
114  $this->checkPermission('write');
115  $this->tabs_gui->setTabActive('schedules');
116  include_once("Modules/BookingManager/classes/class.ilBookingScheduleGUI.php");
117  $schedule_gui = new ilBookingScheduleGUI($this);
118  $ret =&$this->ctrl->forwardCommand($schedule_gui);
119  break;
120 
121  case 'ilpublicuserprofilegui':
122  $this->checkPermission('read');
123  $ilTabs->clearTargets();
124  include_once("Services/User/classes/class.ilPublicUserProfileGUI.php");
125  $profile = new ilPublicUserProfileGUI((int) $_GET["user_id"]);
126  $profile->setBackUrl($this->ctrl->getLinkTarget($this, 'log'));
127  $ret = $this->ctrl->forwardCommand($profile);
128  $tpl->setContent($ret);
129  break;
130 
131  case 'ilinfoscreengui':
132  $this->checkPermission('visible');
133  $this->infoScreen();
134  break;
135 
136  case "ilcommonactiondispatchergui":
137  $this->checkPermission('read');
138  include_once("Services/Object/classes/class.ilCommonActionDispatcherGUI.php");
140  $this->ctrl->forwardCommand($gui);
141  break;
142 
143  case "ilobjectcopygui":
144  $this->checkPermission('copy');
145  include_once "./Services/Object/classes/class.ilObjectCopyGUI.php";
146  $cp = new ilObjectCopyGUI($this);
147  $cp->setType("book");
148  $this->ctrl->forwardCommand($cp);
149  break;
150 
151  case 'ilobjectmetadatagui':
152  $this->checkPermission('write');
153  $this->tabs_gui->setTabActive('meta_data');
154  include_once 'Services/Object/classes/class.ilObjectMetaDataGUI.php';
155  $md_gui = new ilObjectMetaDataGUI($this->object, 'bobj');
156  $this->ctrl->forwardCommand($md_gui);
157  break;
158 
159  default:
160  if (!in_array($cmd, ["create", "save", "infoScreen"])) {
161  $this->checkPermission('read');
162  }
163  $cmd = $this->ctrl->getCmd();
164  $cmd .= 'Object';
165  $this->$cmd();
166  break;
167  }
168 
169  $this->addHeaderAction();
170  return true;
171  }
172 
173  protected function initCreationForms($a_new_type)
174  {
175  $forms = parent::initCreationForms($a_new_type);
176  unset($forms[self::CFORM_IMPORT]);
177 
178  return $forms;
179  }
180 
181  protected function afterSave(ilObject $a_new_object)
182  {
183  $a_new_object->setOffline(true);
184  $a_new_object->update();
185 
186  // always send a message
187  ilUtil::sendSuccess($this->lng->txt("book_pool_added"), true);
188  $this->ctrl->setParameter($this, "ref_id", $a_new_object->getRefId());
189  $this->ctrl->redirect($this, "edit");
190  }
191 
192  public function editObject()
193  {
194  $this->showNoScheduleMessage();
195  return parent::editObject();
196  }
197 
204  public function showNoScheduleMessage()
205  {
206  // if we have no schedules yet - show info
207  include_once "Modules/BookingManager/classes/class.ilBookingSchedule.php";
208  if ($this->object->getScheduleType() != ilObjBookingPool::TYPE_NO_SCHEDULE &&
209  !sizeof(ilBookingSchedule::getList($this->object->getId()))) {
210  ilUtil::sendInfo($this->lng->txt("book_schedule_warning_edit"));
211  }
212  }
213 
214 
215  protected function initEditCustomForm(ilPropertyFormGUI $a_form)
216  {
217  $online = new ilCheckboxInputGUI($this->lng->txt("online"), "online");
218  $a_form->addItem($online);
219 
220  $type = new ilRadioGroupInputGUI($this->lng->txt("book_schedule_type"), "stype");
221  $type->setRequired(true);
222  $a_form->addItem($type);
223 
224  // #14478
225  include_once "Modules/BookingManager/classes/class.ilBookingObject.php";
226  if (sizeof(ilBookingObject::getList($this->object->getId()))) {
227  $type->setDisabled(true);
228  }
229 
230  $fixed = new ilRadioOption($this->lng->txt("book_schedule_type_fixed"), ilObjBookingPool::TYPE_FIX_SCHEDULE);
231  $fixed->setInfo($this->lng->txt("book_schedule_type_fixed_info"));
232  $type->addOption($fixed);
233 
234  $none = new ilRadioOption($this->lng->txt("book_schedule_type_none"), ilObjBookingPool::TYPE_NO_SCHEDULE);
235  $none->setInfo($this->lng->txt("book_schedule_type_none_info"));
236  $type->addOption($none);
237 
238  $limit = new ilNumberInputGUI($this->lng->txt("book_overall_limit"), "limit");
239  $limit->setSize(4);
240  $limit->setMinValue(1);
241  $limit->setInfo($this->lng->txt("book_overall_limit_info"));
242  $none->addSubItem($limit);
243 
244  $public = new ilCheckboxInputGUI($this->lng->txt("book_public_log"), "public");
245  $public->setInfo($this->lng->txt("book_public_log_info"));
246  $a_form->addItem($public);
247 
248  $period = new ilNumberInputGUI($this->lng->txt("book_reservation_filter_period"), "period");
249  $period->setInfo($this->lng->txt("book_reservation_filter_period_info"));
250  $period->setSuffix($this->lng->txt("days"));
251  $period->setSize(3);
252  $period->setMinValue(0);
253  $a_form->addItem($period);
254 
255  // additional features
256  $feat = new ilFormSectionHeaderGUI();
257  $feat->setTitle($this->lng->txt('obj_features'));
258  $a_form->addItem($feat);
259  }
260 
261  protected function getEditFormCustomValues(array &$a_values)
262  {
263  $a_values["online"] = !$this->object->isOffline();
264  $a_values["public"] = $this->object->hasPublicLog();
265  $a_values["stype"] = $this->object->getScheduleType();
266  $a_values["limit"] = $this->object->getOverallLimit();
267  $a_values["period"] = $this->object->getReservationFilterPeriod();
268  }
269 
270  protected function updateCustom(ilPropertyFormGUI $a_form)
271  {
272  $this->object->setOffline(!$a_form->getInput('online'));
273  $this->object->setPublicLog($a_form->getInput('public'));
274  $this->object->setScheduleType($a_form->getInput('stype'));
275  $this->object->setOverallLimit($a_form->getInput('limit') ? $a_form->getInput('limit') : null);
276  $this->object->setReservationFilterPeriod(strlen($a_form->getInput('period')) ? (int) $a_form->getInput('period') : null);
277 
278  include_once './Services/Container/classes/class.ilContainer.php';
279  include_once './Services/Object/classes/class.ilObjectServiceSettingsGUI.php';
281  $this->object->getId(),
282  $a_form,
284  );
285  }
286 
288  {
289  include_once './Services/Container/classes/class.ilContainer.php';
290  include_once './Services/Object/classes/class.ilObjectServiceSettingsGUI.php';
292  $this->object->getId(),
293  $a_form,
295  );
296  }
297 
301  public function setTabs()
302  {
303  $ilHelp = $this->help;
305 
306  if (in_array($this->ctrl->getCmd(), array("create", "save")) && !$this->ctrl->getNextClass()) {
307  return;
308  }
309 
310  $ilHelp->setScreenIdComponent("book");
311 
312  if ($this->checkPermissionBool('read')) {
313  if ($ilUser->getId() != ANONYMOUS_USER_ID) {
314  $this->tabs_gui->addTab(
315  "render",
316  $this->lng->txt("book_booking_types"),
317  $this->ctrl->getLinkTarget($this, "render")
318  );
319  }
320 
321  $this->tabs_gui->addTab(
322  "info",
323  $this->lng->txt("info_short"),
324  $this->ctrl->getLinkTarget($this, "infoscreen")
325  );
326 
327  if ($ilUser->getId() != ANONYMOUS_USER_ID || $this->object->hasPublicLog()) {
328  $this->tabs_gui->addTab(
329  "log",
330  $this->lng->txt("book_log"),
331  $this->ctrl->getLinkTarget($this, "log")
332  );
333  }
334  }
335 
336  if ($this->checkPermissionBool('write')) {
337  if ($this->object->getScheduleType() != ilObjBookingPool::TYPE_NO_SCHEDULE) {
338  $this->tabs_gui->addTab(
339  "schedules",
340  $this->lng->txt("book_schedules"),
341  $this->ctrl->getLinkTargetByClass("ilbookingschedulegui", "render")
342  );
343  }
344 
345  $this->tabs_gui->addTab(
346  "settings",
347  $this->lng->txt("settings"),
348  $this->ctrl->getLinkTarget($this, "edit")
349  );
350 
351  // meta data
352  include_once "Services/Object/classes/class.ilObjectMetaDataGUI.php";
353  $mdgui = new ilObjectMetaDataGUI($this->object, "bobj");
354  $mdtab = $mdgui->getTab();
355  if ($mdtab) {
356  $this->tabs_gui->addTarget(
357  "meta_data",
358  $mdtab,
359  "",
360  "ilobjectmetadatagui"
361  );
362  }
363  }
364 
365  if ($this->checkPermissionBool('edit_permission')) {
366  $this->tabs_gui->addTab(
367  "perm_settings",
368  $this->lng->txt("perm_settings"),
369  $this->ctrl->getLinkTargetByClass("ilpermissiongui", "perm")
370  );
371  }
372  }
373 
374  protected function setHelpId($a_id)
375  {
376  $ilHelp = $this->help;
377 
378  $object_subtype = ($this->object->getScheduleType() == ilObjBookingPool::TYPE_FIX_SCHEDULE)
379  ? '-schedule'
380  : '-nonschedule';
381 
382  $ilHelp->setScreenIdComponent('book');
383  $ilHelp->setScreenId('object' . $object_subtype);
384  $ilHelp->setSubScreenId($a_id);
385  }
386 
390  public function bookObject()
391  {
392  $tpl = $this->tpl;
393 
394  $this->tabs_gui->clearTargets();
395  $this->tabs_gui->setBackTarget($this->lng->txt('book_back_to_list'), $this->ctrl->getLinkTarget($this, 'render'));
396 
397  $this->setHelpId("book");
398 
399  include_once 'Modules/BookingManager/classes/class.ilBookingObject.php';
400  $obj = new ilBookingObject((int) $_GET['object_id']);
401 
402  $this->lng->loadLanguageModule("dateplaner");
403  $this->ctrl->setParameter($this, 'object_id', $obj->getId());
404 
405  if ($this->object->getScheduleType() == ilObjBookingPool::TYPE_FIX_SCHEDULE) {
406  include_once 'Modules/BookingManager/classes/class.ilBookingSchedule.php';
407  $schedule = new ilBookingSchedule($obj->getScheduleId());
408 
409  $tpl->setContent($this->renderSlots($schedule, array($obj->getId()), $obj->getTitle()));
410  } else {
411  include_once("./Services/Utilities/classes/class.ilConfirmationGUI.php");
412  $cgui = new ilConfirmationGUI();
413  $cgui->setHeaderText($this->lng->txt("book_confirm_booking_no_schedule"));
414 
415  $cgui->setFormAction($this->ctrl->getFormAction($this));
416  $cgui->setCancel($this->lng->txt("cancel"), "render");
417  $cgui->setConfirm($this->lng->txt("confirm"), "confirmedBooking");
418 
419  $cgui->addItem("object_id", $obj->getId(), $obj->getTitle());
420 
421  $tpl->setContent($cgui->getHTML());
422  }
423  }
424 
425  protected function renderSlots(ilBookingSchedule $schedule, array $object_ids, $title)
426  {
428 
429  // fix
430  if (!$schedule->getRaster()) {
431  $mytpl = new ilTemplate('tpl.booking_reservation_fix.html', true, true, 'Modules/BookingManager');
432 
433  $mytpl->setVariable('FORM_ACTION', $this->ctrl->getFormAction($this));
434  $mytpl->setVariable('TXT_TITLE', $this->lng->txt('book_reservation_title'));
435  $mytpl->setVariable('TXT_INFO', $this->lng->txt('book_reservation_fix_info'));
436  $mytpl->setVariable('TXT_OBJECT', $title);
437  $mytpl->setVariable('TXT_CMD_BOOK', $this->lng->txt('book_confirm_booking'));
438  $mytpl->setVariable('TXT_CMD_CANCEL', $this->lng->txt('cancel'));
439 
440  include_once 'Services/Calendar/classes/class.ilCalendarUserSettings.php';
441 
442  $user_settings = ilCalendarUserSettings::_getInstanceByUserId($ilUser->getId());
443 
444  $morning_aggr = $user_settings->getDayStart();
445  $evening_aggr = $user_settings->getDayEnd();
446  $hours = array();
447  for ($i = $morning_aggr;$i <= $evening_aggr;$i++) {
448  switch ($user_settings->getTimeFormat()) {
450  if ($morning_aggr > 0 && $i == $morning_aggr) {
451  $hours[$i] = sprintf('%02d:00', 0) . "-";
452  }
453  $hours[$i].= sprintf('%02d:00', $i);
454  if ($evening_aggr < 23 && $i == $evening_aggr) {
455  $hours[$i].= "-" . sprintf('%02d:00', 23);
456  }
457  break;
458 
460  if ($morning_aggr > 0 && $i == $morning_aggr) {
461  $hours[$i] = date('h a', mktime(0, 0, 0, 1, 1, 2000)) . "-";
462  }
463  $hours[$i].= date('h a', mktime($i, 0, 0, 1, 1, 2000));
464  if ($evening_aggr < 23 && $i == $evening_aggr) {
465  $hours[$i].= "-" . date('h a', mktime(23, 0, 0, 1, 1, 2000));
466  }
467  break;
468  }
469  }
470 
471  if (isset($_GET['seed'])) {
472  $find_first_open = false;
473  $seed = new ilDate($_GET['seed'], IL_CAL_DATE);
474  } else {
475  $find_first_open = true;
476  $seed = isset($_GET['sseed'])
477  ? new ilDate($_GET['sseed'], IL_CAL_DATE)
478  : new ilDate(time(), IL_CAL_UNIX);
479  }
480 
481  include_once 'Services/Calendar/classes/class.ilCalendarUtil.php';
482  include_once 'Modules/BookingManager/classes/class.ilBookingReservation.php';
483  $week_start = $user_settings->getWeekStart();
484 
485  if (!$find_first_open) {
486  $dates = array();
487  $this->buildDatesBySchedule($week_start, $hours, $schedule, $object_ids, $seed, $dates);
488  } else {
489  $dates = array();
490 
491  //loop for 1 week
492  $has_open_slot = $this->buildDatesBySchedule($week_start, $hours, $schedule, $object_ids, $seed, $dates);
493 
494  // find first open slot
495  if (!$has_open_slot) {
496  // 1 year is limit for search
497  $limit = clone($seed);
498  $limit->increment(ilDate::YEAR, 1);
499  $limit = $limit->get(IL_CAL_UNIX);
500 
501  while (!$has_open_slot && $seed->get(IL_CAL_UNIX) < $limit) {
502  $seed->increment(ilDate::WEEK, 1);
503 
504  $dates = array();
505  $has_open_slot = $this->buildDatesBySchedule($week_start, $hours, $schedule, $object_ids, $seed, $dates);
506  }
507  }
508  }
509 
510  include_once 'Services/Calendar/classes/class.ilCalendarHeaderNavigationGUI.php';
511  $navigation = new ilCalendarHeaderNavigationGUI($this, $seed, ilDateTime::WEEK, 'book');
512  $mytpl->setVariable('NAVIGATION', $navigation->getHTML());
513 
514  foreach (ilCalendarUtil::_buildWeekDayList($seed, $week_start)->get() as $date) {
515  $date_info = $date->get(IL_CAL_FKT_GETDATE, '', 'UTC');
516 
517  $mytpl->setCurrentBlock('weekdays');
518  $mytpl->setVariable('TXT_WEEKDAY', ilCalendarUtil:: _numericDayToString($date_info['wday']));
519  $mytpl->setVariable('TXT_DATE', $date_info['mday'] . ' ' . ilCalendarUtil:: _numericMonthToString($date_info['mon']));
520  $mytpl->parseCurrentBlock();
521  }
522 
523  include_once 'Services/Calendar/classes/class.ilCalendarAppointmentColors.php';
524  include_once 'Services/Calendar/classes/class.ilCalendarUtil.php';
525  $color = array();
527  for ($loop = 0; $loop < 7; $loop++) {
528  $col = $all[$loop];
530  $color[$loop+1] = 'border-bottom: 1px solid ' . $col . '; background-color: ' . $col . '; color: ' . $fnt;
531  }
532 
533  $counter = 0;
534  foreach ($dates as $hour => $days) {
535  $caption = $days;
536  $caption = array_shift($caption);
537 
538  for ($loop = 1; $loop < 8; $loop++) {
539  if (!isset($days[$loop])) {
540  $mytpl->setCurrentBlock('dates');
541  $mytpl->setVariable('DUMMY', '&nbsp;');
542  $mytpl->parseCurrentBlock();
543  } else {
544  if (isset($days[$loop]['captions'])) {
545  foreach ($days[$loop]['captions'] as $slot_id => $slot_caption) {
546  $mytpl->setCurrentBlock('choice');
547  $mytpl->setVariable('TXT_DATE', $slot_caption);
548  $mytpl->setVariable('VALUE_DATE', $slot_id);
549  $mytpl->setVariable('DATE_COLOR', $color[$loop]);
550  $mytpl->setVariable(
551  'TXT_AVAILABLE',
552  sprintf(
553  $this->lng->txt('book_reservation_available'),
554  $days[$loop]['available'][$slot_id]
555  )
556  );
557  $mytpl->parseCurrentBlock();
558  }
559 
560  $mytpl->setCurrentBlock('dates');
561  $mytpl->setVariable('DUMMY', '');
562  $mytpl->parseCurrentBlock();
563  } elseif (isset($days[$loop]['in_slot'])) {
564  $mytpl->setCurrentBlock('dates');
565  $mytpl->setVariable('DATE_COLOR', $color[$loop]);
566  $mytpl->parseCurrentBlock();
567  } else {
568  $mytpl->setCurrentBlock('dates');
569  $mytpl->setVariable('DUMMY', '&nbsp;');
570  $mytpl->parseCurrentBlock();
571  }
572  }
573  }
574 
575  $mytpl->setCurrentBlock('slots');
576  $mytpl->setVariable('TXT_HOUR', $caption);
577  if ($counter%2) {
578  $mytpl->setVariable('CSS_ROW', 'tblrow1');
579  } else {
580  $mytpl->setVariable('CSS_ROW', 'tblrow2');
581  }
582  $mytpl->parseCurrentBlock();
583 
584  $counter++;
585  }
586  }
587  // flexible
588  else {
589  // :TODO: inactive for now
590  }
591 
592  return $mytpl->get();
593  }
594 
595  protected function buildDatesBySchedule($week_start, array $hours, $schedule, array $object_ids, $seed, array &$dates)
596  {
598 
599  include_once 'Services/Calendar/classes/class.ilCalendarUserSettings.php';
600  $user_settings = ilCalendarUserSettings::_getInstanceByUserId($ilUser->getId());
601 
602  $map = array('mo', 'tu', 'we', 'th', 'fr', 'sa', 'su');
603  $definition = $schedule->getDefinition();
604 
605  $av_from = ($schedule->getAvailabilityFrom() && !$schedule->getAvailabilityFrom()->isNull())
606  ? $schedule->getAvailabilityFrom()->get(IL_CAL_DATE)
607  : null;
608  $av_to = ($schedule->getAvailabilityTo() && !$schedule->getAvailabilityTo()->isNull())
609  ? $schedule->getAvailabilityTo()->get(IL_CAL_DATE)
610  : null;
611 
612  $has_open_slot = false;
613  foreach (ilCalendarUtil::_buildWeekDayList($seed, $week_start)->get() as $date) {
614  $date_info = $date->get(IL_CAL_FKT_GETDATE, '', 'UTC');
615 
616  #24045 and #24936
617  if ($av_from || $av_to) {
618  $today = $date->get(IL_CAL_DATE);
619 
620  if ($av_from && $av_from > $today) {
621  continue;
622  }
623 
624  if ($av_to && $av_to < $today) {
625  continue;
626  }
627  }
628 
629  $slots = array();
630  if (isset($definition[$map[$date_info['isoday']-1]])) {
631  $slots = array();
632  foreach ($definition[$map[$date_info['isoday']-1]] as $slot) {
633  $slot = explode('-', $slot);
634  $slots[] = array('from'=>str_replace(':', '', $slot[0]),
635  'to'=>str_replace(':', '', $slot[1]));
636  }
637  }
638 
639  $last = array_pop(array_keys($hours));
640  $slot_captions = array();
641  foreach ($hours as $hour => $period) {
642  $dates[$hour][0] = $period;
643 
644  $period = explode("-", $period);
645 
646  // #13738
647  if ($user_settings->getTimeFormat() == ilCalendarSettings::TIME_FORMAT_12) {
648  $period[0] = date("H", strtotime($period[0]));
649  if (sizeof($period) == 2) {
650  $period[1] = date("H", strtotime($period[1]));
651  }
652  }
653 
654  if (sizeof($period) == 1) {
655  $period_from = (int) substr($period[0], 0, 2) . "00";
656  $period_to = (int) substr($period[0], 0, 2) . "59";
657  } else {
658  $period_from = (int) substr($period[0], 0, 2) . "00";
659  $period_to = (int) substr($period[1], 0, 2) . "59";
660  }
661 
662  $column = $date_info['isoday'];
663  if (!$week_start) {
664  if ($column < 7) {
665  $column++;
666  } else {
667  $column = 1;
668  }
669  }
670 
671  if (sizeof($slots)) {
672  $in = false;
673  foreach ($slots as $slot) {
674  $slot_from = mktime(substr($slot['from'], 0, 2), substr($slot['from'], 2, 2), 0, $date_info["mon"], $date_info["mday"], $date_info["year"]);
675  $slot_to = mktime(substr($slot['to'], 0, 2), substr($slot['to'], 2, 2), 0, $date_info["mon"], $date_info["mday"], $date_info["year"]);
676 
677  // always single object, we can sum up
678  $nr_available = (array) ilBookingReservation::getAvailableObject($object_ids, $slot_from, $slot_to-1, false, true);
679 
680  // any objects available?
681  if (!array_sum($nr_available)) {
682  continue;
683  }
684 
685  // check deadline
686  if ($schedule->getDeadline() >= 0) {
687  // 0-n hours before slots begins
688  if ($slot_from < (time()+$schedule->getDeadline()*60*60)) {
689  continue;
690  }
691  } else {
692  // running slots can be booked, only ended slots are invalid
693  if ($slot_to < time()) {
694  continue;
695  }
696  }
697 
698  // is slot active in current hour?
699  if ((int) $slot['from'] < $period_to && (int) $slot['to'] > $period_from) {
701  $from = array_pop(explode(' ', $from));
703  $to = array_pop(explode(' ', $to));
704 
705  // show caption (first hour) of slot
706  $id = $slot_from . '_' . $slot_to;
707  if (!in_array($id, $slot_captions)) {
708  $dates[$hour][$column]['captions'][$id] = $from . '-' . $to;
709  $dates[$hour][$column]['available'][$id] = array_sum($nr_available);
710  $slot_captions[] = $id;
711  }
712 
713  $in = true;
714  }
715  }
716  // (any) active slot
717  if ($in) {
718  $has_open_slot = true;
719  $dates[$hour][$column]['in_slot'] = $in;
720  }
721  }
722  }
723  }
724 
725  return $has_open_slot;
726  }
727 
731  public function confirmedBookingObject()
732  {
734 
735  include_once 'Modules/BookingManager/classes/class.ilBookingObject.php';
736  include_once 'Modules/BookingManager/classes/class.ilBookingReservation.php';
737 
738  $success = false;
739  $rsv_ids = array();
740 
741  if ($this->object->getScheduleType() == ilObjBookingPool::TYPE_NO_SCHEDULE) {
742  if ($_POST['object_id']) {
743  $object_id = $_POST['object_id'];
744  if ($object_id) {
746  !ilBookingReservation::getObjectReservationForUser($object_id, $ilUser->getId())) { // #18304
747  $rsv_ids[] = $this->processBooking($object_id);
748  $success = $object_id;
749  } else {
750  // #11852
751  ilUtil::sendFailure($this->lng->txt('book_reservation_failed_overbooked'), true);
752  $this->ctrl->redirect($this, 'render');
753  }
754  }
755  }
756  } else {
757  if (!isset($_POST['date'])) {
758  ilUtil::sendFailure($this->lng->txt('select_one'));
759  return $this->bookObject();
760  }
761 
762  // single object reservation(s)
763  if (isset($_GET['object_id'])) {
764  $confirm = array();
765 
766  $object_id = (int) $_GET['object_id'];
767  if ($object_id) {
768  $group_id = null;
770  // needed for recurrence
771  if (true) { // if($nr[$object_id] > 1 || sizeof($_POST['date']) > 1)
773  }
774  foreach ($_POST['date'] as $date) {
775  $fromto = explode('_', $date);
776  $fromto[1]--;
777 
778  $counter = ilBookingReservation::getAvailableObject(array($object_id), $fromto[0], $fromto[1], false, true);
779  $counter = $counter[$object_id];
780  if ($counter) {
781  // needed for recurrence
782  if (true) { // if($counter > 1)
783  $confirm[$object_id . "_" . $fromto[0] . "_" . ($fromto[1]+1)] = $counter;
784  } else {
785  $rsv_ids[] = $this->processBooking($object_id, $fromto[0], $fromto[1], $group_id);
786  $success = $object_id;
787  }
788  }
789  }
790  }
791 
792  if (sizeof($confirm)) {
793  return $this->confirmBookingNumbers($confirm, $group_id);
794  }
795  }
796  /*
797  // group object reservation(s)
798  else
799  {
800  $all_object_ids = array();
801  foreach(ilBookingObject::getList((int)$_GET['type_id']) as $item)
802  {
803  $all_object_ids[] = $item['booking_object_id'];
804  }
805 
806  $possible_objects = $counter = array();
807  sort($_POST['date']);
808  foreach($_POST['date'] as $date)
809  {
810  $fromto = explode('_', $date);
811  $fromto[1]--;
812  $possible_objects[$date] = ilBookingReservation::getAvailableObject($all_object_ids, $fromto[0], $fromto[1], false);
813  foreach($possible_objects[$date] as $obj_id)
814  {
815  $counter[$obj_id]++;
816  }
817  }
818 
819  if(max($counter))
820  {
821  // we prefer the objects which are available for most slots
822  arsort($counter);
823  $counter = array_keys($counter);
824 
825  // book each slot
826  foreach($possible_objects as $date => $available_ids)
827  {
828  $fromto = explode('_', $date);
829  $fromto[1]--;
830 
831  // find "best" object for slot
832  foreach($counter as $best_object_id)
833  {
834  if(in_array($best_object_id, $available_ids))
835  {
836  $object_id = $best_object_id;
837  break;
838  }
839  }
840  $this->processBooking($object_id, $fromto[0], $fromto[1]);
841  $success = true;
842  }
843  }
844  }
845  */
846  }
847 
848  if ($success) {
849  $this->handleBookingSuccess($success, $rsv_ids);
850  } else {
851  ilUtil::sendFailure($this->lng->txt('book_reservation_failed'), true);
852  $this->ctrl->redirect($this, 'book');
853  }
854  }
855 
856  protected function handleBookingSuccess($a_obj_id, array $a_rsv_ids = null)
857  {
858  ilUtil::sendSuccess($this->lng->txt('book_reservation_confirmed'), true);
859 
860  // show post booking information?
861  include_once 'Modules/BookingManager/classes/class.ilBookingObject.php';
862  $obj = new ilBookingObject($a_obj_id);
863  $pfile = $obj->getPostFile();
864  $ptext = $obj->getPostText();
865  if (trim($ptext) || $pfile) {
866  if (sizeof($a_rsv_ids)) {
867  $this->ctrl->setParameterByClass('ilbookingobjectgui', 'rsv_ids', implode(";", $a_rsv_ids));
868  }
869  $this->ctrl->setParameterByClass('ilbookingobjectgui', 'object_id', $obj->getId());
870  $this->ctrl->redirectByClass('ilbookingobjectgui', 'displayPostInfo');
871  } else {
872  $this->ctrl->redirect($this, 'render');
873  }
874  }
875 
876  protected function initBookingNumbersForm(array $a_objects_counter, $a_group_id, $a_reload = false)
877  {
878  include_once 'Services/Form/classes/class.ilPropertyFormGUI.php';
879  $form = new ilPropertyFormGUI();
880  $form->setFormAction($this->ctrl->getFormAction($this, "confirmedBooking"));
881  $form->setTitle($this->lng->txt("book_confirm_booking_schedule_number_of_objects"));
882  $form->setDescription($this->lng->txt("book_confirm_booking_schedule_number_of_objects_info"));
883 
884  include_once 'Modules/BookingManager/classes/class.ilBookingObject.php';
885  $section = false;
886  $min_date = null;
887  foreach ($a_objects_counter as $id => $counter) {
888  $id = explode("_", $id);
889  $book_id = $id[0] . "_" . $id[1] . "_" . $id[2] . "_" . $counter;
890 
891  $obj = new ilBookingObject($id[0]);
892 
893  if (!$section) {
895  $section->setTitle($obj->getTitle());
896  $form->addItem($section);
897 
898  $section = true;
899  }
900 
901  $period = /* $this->lng->txt("book_period").": ". */
903  new ilDateTime($id[1], IL_CAL_UNIX),
904  new ilDateTime($id[2], IL_CAL_UNIX)
905  );
906 
907  $nr_field = new ilNumberInputGUI($period, "conf_nr__" . $book_id);
908  $nr_field->setValue(1);
909  $nr_field->setSize(3);
910  $nr_field->setMaxValue($counter);
911  $nr_field->setMinValue($counter ? 1 : 0);
912  $nr_field->setRequired(true);
913  $form->addItem($nr_field);
914 
915  if (!$min_date || $id[1] < $min_date) {
916  $min_date = $id[1];
917  }
918  }
919 
920  // recurrence
921  $this->lng->loadLanguageModule("dateplaner");
922  $rec_mode = new ilSelectInputGUI($this->lng->txt("cal_recurrences"), "recm");
923  $rec_mode->setRequired(true);
924  $rec_mode->setOptions(array(
925  "-1" => $this->lng->txt("cal_no_recurrence"),
926  1 => $this->lng->txt("cal_weekly"),
927  2 => $this->lng->txt("r_14"),
928  4 => $this->lng->txt("r_4_weeks")
929  ));
930  $form->addItem($rec_mode);
931 
932  $rec_end = new ilDateTimeInputGUI($this->lng->txt("cal_repeat_until"), "rece");
933  $rec_end->setRequired(true);
934  $rec_mode->addSubItem($rec_end);
935 
936  if (!$a_reload) {
937  // show date only if active recurrence
938  $rec_mode->setHideSubForm(true, '>= 1');
939 
940  if ($min_date) {
941  $rec_end->setDate(new ilDateTime($min_date, IL_CAL_UNIX));
942  }
943  } else {
944  // recurrence may not be changed on reload
945  $rec_mode->setDisabled(true);
946  $rec_end->setDisabled(true);
947  }
948 
949  if ($a_group_id) {
950  $grp = new ilHiddenInputGUI("grp_id");
951  $grp->setValue($a_group_id);
952  $form->addItem($grp);
953  }
954 
955  $form->addCommandButton("confirmedBookingNumbers", $this->lng->txt("confirm"));
956  $form->addCommandButton("render", $this->lng->txt("cancel"));
957 
958  return $form;
959  }
960 
961  public function confirmBookingNumbers(array $a_objects_counter, $a_group_id, ilPropertyFormGUI $a_form = null)
962  {
963  $tpl = $this->tpl;
964 
965  $this->tabs_gui->clearTargets();
966  $this->tabs_gui->setBackTarget($this->lng->txt('book_back_to_list'), $this->ctrl->getLinkTarget($this, 'render'));
967 
968  if (!$a_form) {
969  $a_form = $this->initBookingNumbersForm($a_objects_counter, $a_group_id);
970  }
971 
972  $tpl->setContent($a_form->getHTML());
973  }
974 
975  protected function addDaysDate($a_date, $a_days)
976  {
977  $date = date_parse($a_date);
978  $stamp = mktime(0, 0, 1, $date["month"], $date["day"]+$a_days, $date["year"]);
979  return date("Y-m-d", $stamp);
980  }
981 
982  protected function addDaysStamp($a_stamp, $a_days)
983  {
984  $date = getDate($a_stamp);
985  return mktime(
986  $date["hours"],
987  $date["minutes"],
988  $date["seconds"],
989  $date["mon"],
990  $date["mday"]+$a_days,
991  $date["year"]
992  );
993  }
994 
996  {
997  include_once 'Modules/BookingManager/classes/class.ilBookingReservation.php';
998  include_once 'Modules/BookingManager/classes/class.ilBookingObject.php';
999 
1000  // convert post data to initial form config
1001  $counter = array();
1002  $current_first = $obj_id = null;
1003  foreach (array_keys($_POST) as $id) {
1004  if (substr($id, 0, 9) == "conf_nr__") {
1005  $id = explode("_", substr($id, 9));
1006  $counter[$id[0] . "_" . $id[1] . "_" . $id[2]] = (int) $id[3];
1007  if (!$current_first) {
1008  $current_first = date("Y-m-d", $id[1]);
1009  }
1010  }
1011  }
1012 
1013  // recurrence
1014 
1015  // checkInput() has not been called yet, so we have to improvise
1016  include_once 'Services/Calendar/classes/class.ilCalendarUtil.php';
1018 
1019  if ((int) $_POST["recm"] > 0 && $end && $current_first) {
1020  ksort($counter);
1021  $end = $end->get(IL_CAL_DATE);
1022  $cycle = (int) $_POST["recm"]*7;
1023  $cut = 0;
1024  $org = $counter;
1025  while ($cut < 1000 && $this->addDaysDate($current_first, $cycle) <= $end) {
1026  $cut++;
1027  $current_first = null;
1028  foreach ($org as $item_id => $max) {
1029  $parts = explode("_", $item_id);
1030  $obj_id = $parts[0];
1031 
1032  $from = $this->addDaysStamp($parts[1], $cycle*$cut);
1033  $to = $this->addDaysStamp($parts[2], $cycle*$cut);
1034 
1035  $new_item_id = $obj_id . "_" . $from . "_" . $to;
1036 
1037  // form reload because of validation errors
1038  if (!isset($counter[$new_item_id]) && date("Y-m-d", $to) <= $end) {
1039  // get max available for added dates
1040  $new_max = ilBookingReservation::getAvailableObject(array($obj_id), $from, $to-1, false, true);
1041  $new_max = (int) $new_max[$obj_id];
1042 
1043  $counter[$new_item_id] = $new_max;
1044 
1045  if (!$current_first) {
1046  $current_first = date("Y-m-d", $from);
1047  }
1048 
1049  // clone input
1050  $_POST["conf_nr__" . $new_item_id . "_" . $new_max] = $_POST["conf_nr__" . $item_id . "_" . $max];
1051  }
1052  }
1053  }
1054  }
1055 
1056  $group_id = $_POST["grp_id"];
1057 
1058  $form = $this->initBookingNumbersForm($counter, $group_id, true);
1059  if ($form->checkInput()) {
1060  $success = false;
1061  $rsv_ids = array();
1062  foreach ($counter as $id => $all_nr) {
1063  $book_nr = $form->getInput("conf_nr__" . $id . "_" . $all_nr);
1064  $parts = explode("_", $id);
1065  $obj_id = $parts[0];
1066  $from = $parts[1];
1067  $to = $parts[2]-1;
1068 
1069  // get currently available slots
1072  if ($counter) {
1073  // we can only book what is left
1074  $book_nr = min($book_nr, $counter);
1075  for ($loop = 0; $loop < $book_nr; $loop++) {
1076  $rsv_ids[] = $this->processBooking($obj_id, $from, $to, $group_id);
1077  $success = $obj_id;
1078  }
1079  }
1080  }
1081  if ($success) {
1082  $this->handleBookingSuccess($success, $rsv_ids);
1083  } else {
1084  ilUtil::sendFailure($this->lng->txt('book_reservation_failed'), true);
1085  $this->ctrl->redirect($this, 'render');
1086  }
1087  } else {
1088  // ilDateTimeInputGUI does NOT add hidden values on disabled!
1089 
1090  $rece_array = explode(".", $_POST['rece']);
1091 
1092  $rece_day = str_pad($rece_array[0], 2, "0", STR_PAD_LEFT);
1093  $rece_month = str_pad($rece_array[1], 2, "0", STR_PAD_LEFT);
1094  $rece_year = $rece_array[2];
1095 
1096  // ilDateTimeInputGUI will choke on POST array format
1097  $_POST["rece"] = null;
1098 
1099  $form->setValuesByPost();
1100 
1101  $rece_date = new ilDate($rece_year . "-" . $rece_month . "-" . $rece_day, IL_CAL_DATE);
1102 
1103  $form->getItemByPostVar("rece")->setDate($rece_date);
1104  $form->getItemByPostVar("recm")->setHideSubForm($_POST["recm"] < 1);
1105 
1106  $hidden_date = new ilHiddenInputGUI("rece");
1107  $hidden_date->setValue($rece_date);
1108  $form->addItem($hidden_date);
1109 
1110  return $this->confirmBookingNumbers($counter, $group_id, $form);
1111  }
1112  }
1113 
1123  public function processBooking($a_object_id, $a_from = null, $a_to = null, $a_group_id = null)
1124  {
1125  $ilUser = $this->user;
1126 
1127  // #11995
1128  $this->checkPermission('read');
1129 
1130  include_once 'Modules/BookingManager/classes/class.ilBookingReservation.php';
1131  $reservation = new ilBookingReservation();
1132  $reservation->setObjectId($a_object_id);
1133  $reservation->setUserId($ilUser->getID());
1134  $reservation->setFrom($a_from);
1135  $reservation->setTo($a_to);
1136  $reservation->setGroupId($a_group_id);
1137  $reservation->save();
1138 
1139  if ($a_from) {
1140  $this->lng->loadLanguageModule('dateplaner');
1141  include_once 'Services/Calendar/classes/class.ilCalendarUtil.php';
1142  include_once 'Services/Calendar/classes/class.ilCalendarCategory.php';
1143  $def_cat = ilCalendarUtil::initDefaultCalendarByType(ilCalendarCategory::TYPE_BOOK, $ilUser->getId(), $this->lng->txt('cal_ch_personal_book'), true);
1144 
1145  include_once 'Modules/BookingManager/classes/class.ilBookingObject.php';
1146  $object = new ilBookingObject($a_object_id);
1147 
1148  include_once 'Services/Calendar/classes/class.ilCalendarEntry.php';
1149  $entry = new ilCalendarEntry;
1150  $entry->setStart(new ilDateTime($a_from, IL_CAL_UNIX));
1151  $entry->setEnd(new ilDateTime($a_to, IL_CAL_UNIX));
1152  $entry->setTitle($this->lng->txt('book_cal_entry') . ' ' . $object->getTitle());
1153  $entry->setContextId($reservation->getId());
1154  $entry->save();
1155 
1156  include_once 'Services/Calendar/classes/class.ilCalendarCategoryAssignments.php';
1157  $assignment = new ilCalendarCategoryAssignments($entry->getEntryId());
1158  $assignment->addAssignment($def_cat->getCategoryId());
1159  }
1160 
1161  return $reservation->getId();
1162  }
1163 
1167  public function logObject()
1168  {
1169  $tpl = $this->tpl;
1170 
1171  $this->tabs_gui->setTabActive('log');
1172 
1173  $show_all = ($this->checkPermissionBool('write') || $this->object->hasPublicLog());
1174 
1175  $filter = null;
1176  if ($_GET["object_id"]) {
1177  $filter["object"] = (int) $_GET["object_id"];
1178  }
1179 
1180  include_once 'Modules/BookingManager/classes/class.ilBookingReservationsTableGUI.php';
1182  $this,
1183  'log',
1184  $this->ref_id,
1185  $this->object->getId(),
1186  $show_all,
1187  ($this->object->getScheduleType() != ilObjBookingPool::TYPE_NO_SCHEDULE),
1188  $filter
1189  );
1190  $tpl->setContent($table->getHTML());
1191  }
1192 
1193  public function logDetailsObject()
1194  {
1195  $tpl = $this->tpl;
1196 
1197  $this->tabs_gui->clearTargets();
1198  $this->tabs_gui->setBackTarget(
1199  $this->lng->txt("back"),
1200  $this->ctrl->getLinkTarget($this, "log")
1201  );
1202 
1203  $show_all = ($this->checkPermissionBool('write') || $this->object->hasPublicLog());
1204 
1205  $filter = null;
1206  if ($_GET["object_id"]) {
1207  $filter["object"] = (int) $_GET["object_id"];
1208  }
1209 
1210  include_once 'Modules/BookingManager/classes/class.ilBookingReservationsTableGUI.php';
1212  $this,
1213  'log',
1214  $this->ref_id,
1215  $this->object->getId(),
1216  $show_all,
1217  ($this->object->getScheduleType() != ilObjBookingPool::TYPE_NO_SCHEDULE),
1218  $filter,
1219  $_GET["reservation_id"]
1220  );
1221  $tpl->setContent($table->getHTML());
1222  }
1223 
1227  public function changeStatusObject()
1228  {
1229  $this->tabs_gui->setTabActive('log');
1230 
1231  if (!$_POST['reservation_id']) {
1232  ilUtil::sendFailure($this->lng->txt('select_one'));
1233  return $this->logObject();
1234  }
1235 
1236  if ($this->checkPermissionBool('write')) {
1237  include_once 'Modules/BookingManager/classes/class.ilBookingReservation.php';
1238  ilBookingReservation::changeStatus($_POST['reservation_id'], (int) $_POST['tstatus']);
1239  }
1240 
1241  ilUtil::sendSuccess($this->lng->txt('settings_saved'), true);
1242  return $this->ctrl->redirect($this, 'log');
1243  }
1244 
1248  public function applyLogFilterObject()
1249  {
1250  $show_all = ($this->checkPermissionBool('write') || $this->object->hasPublicLog());
1251 
1252  include_once 'Modules/BookingManager/classes/class.ilBookingReservationsTableGUI.php';
1254  $this,
1255  'log',
1256  $this->ref_id,
1257  $this->object->getId(),
1258  $show_all,
1259  ($this->object->getScheduleType() != ilObjBookingPool::TYPE_NO_SCHEDULE)
1260  );
1261  $table->resetOffset();
1262  $table->writeFilterToSession();
1263  $this->logObject();
1264  }
1265 
1269  public function resetLogFilterObject()
1270  {
1271  $show_all = ($this->checkPermissionBool('write') || $this->object->hasPublicLog());
1272 
1273  include_once 'Modules/BookingManager/classes/class.ilBookingReservationsTableGUI.php';
1275  $this,
1276  'log',
1277  $this->ref_id,
1278  $this->object->getId(),
1279  $show_all,
1280  ($this->object->getScheduleType() != ilObjBookingPool::TYPE_NO_SCHEDULE)
1281  );
1282  $table->resetOffset();
1283  $table->resetFilter();
1284  $this->logObject();
1285  }
1286 
1287  public static function _goto($a_target)
1288  {
1289  global $DIC;
1290 
1291  $ilAccess = $DIC->access();
1292  $lng = $DIC->language();
1293 
1294  if ($ilAccess->checkAccess("read", "", $a_target)) {
1295  ilObjectGUI::_gotoRepositoryNode($a_target, "render");
1296  } elseif ($ilAccess->checkAccess("read", "", ROOT_FOLDER_ID)) {
1297  ilUtil::sendFailure(sprintf(
1298  $lng->txt("msg_no_perm_read_item"),
1300  ), true);
1302  }
1303  }
1304 
1310  public function infoScreenObject()
1311  {
1312  $this->ctrl->setCmd("showSummary");
1313  $this->ctrl->setCmdClass("ilinfoscreengui");
1314  $this->infoScreen();
1315  }
1316 
1317  public function infoScreen()
1318  {
1319  $ilCtrl = $this->ctrl;
1320 
1321  $this->tabs_gui->setTabActive('info');
1322 
1323  $this->checkPermission("visible");
1324 
1325  include_once("./Services/InfoScreen/classes/class.ilInfoScreenGUI.php");
1326  $info = new ilInfoScreenGUI($this);
1327 
1328  $info->enablePrivateNotes();
1329 
1330  if ($this->checkPermissionBool("read")) {
1331  $info->enableNews();
1332  }
1333 
1334  // no news editing for files, just notifications
1335  $info->enableNewsEditing(false);
1336  if ($this->checkPermissionBool("write")) {
1337  $news_set = new ilSetting("news");
1338  $enable_internal_rss = $news_set->get("enable_rss_for_internal");
1339 
1340  if ($enable_internal_rss) {
1341  $info->setBlockProperty("news", "settings", true);
1342  $info->setBlockProperty("news", "public_notifications_option", true);
1343  }
1344  }
1345 
1346  // forward the command
1347  if ($ilCtrl->getNextClass() == "ilinfoscreengui") {
1348  $ilCtrl->forwardCommand($info);
1349  } else {
1350  return $ilCtrl->getHTML($info);
1351  }
1352  }
1353 
1354  protected function getLogReservationIds()
1355  {
1356  if ($_POST["mrsv"]) {
1357  return $_POST["mrsv"];
1358  } elseif ($_GET["reservation_id"]) {
1359  return array($_GET["reservation_id"]);
1360  }
1361  }
1362 
1363  public function rsvConfirmCancelObject()
1364  {
1365  $ilCtrl = $this->ctrl;
1366  $lng = $this->lng;
1367  $tpl = $this->tpl;
1368  $ilUser = $this->user;
1369 
1370  $ids = $this->getLogReservationIds();
1371  if (!is_array($ids) || !sizeof($ids)) {
1372  $this->ctrl->redirect($this, 'log');
1373  }
1374 
1375  include_once 'Modules/BookingManager/classes/class.ilBookingObject.php';
1376  include_once 'Modules/BookingManager/classes/class.ilBookingReservation.php';
1377 
1378  $max = array();
1379  foreach ($ids as $idx => $id) {
1380  if (!is_numeric($id)) {
1381  list($obj_id, $user_id, $from, $to) = explode("_", $id);
1382 
1383  $valid_ids = array();
1384  foreach (ilBookingObject::getList($this->object->getId()) as $item) {
1385  $valid_ids[$item["booking_object_id"]] = $item["title"];
1386  }
1387 
1388  if (($this->checkPermissionBool("write") || $user_id == $ilUser->getId()) &&
1389  $from > time() &&
1390  in_array($obj_id, array_keys($valid_ids))) {
1391  $rsv_ids = ilBookingReservation::getCancelDetails($obj_id, $user_id, $from, $to);
1392  if (!sizeof($rsv_ids)) {
1393  unset($ids[$idx]);
1394  }
1395  if (sizeof($rsv_ids) > 1) {
1396  $max[$id] = sizeof($rsv_ids);
1397  $ids[$idx] = $rsv_ids;
1398  } else {
1399  // only 1 in group? treat as normal reservation
1400  $ids[$idx] = array_shift($rsv_ids);
1401  }
1402  } else {
1403  unset($ids[$idx]);
1404  }
1405  }
1406  }
1407 
1408  if (!is_array($ids) || !sizeof($ids)) {
1409  $this->ctrl->redirect($this, 'log');
1410  }
1411 
1412  // show form instead
1413  if (sizeof($max) && max($max) > 1) {
1414  return $this->rsvConfirmCancelAggregationObject($ids);
1415  }
1416 
1417  $this->tabs_gui->clearTargets();
1418  $this->tabs_gui->setBackTarget(
1419  $lng->txt("back"),
1420  $ilCtrl->getLinkTarget($this, "log")
1421  );
1422 
1423  $this->setHelpId("cancel_booking");
1424 
1425  include_once 'Services/Utilities/classes/class.ilConfirmationGUI.php';
1426  $conf = new ilConfirmationGUI();
1427  $conf->setFormAction($ilCtrl->getFormAction($this, 'rsvCancel'));
1428  $conf->setHeaderText($lng->txt('book_confirm_cancel'));
1429  $conf->setConfirm($lng->txt('book_set_cancel'), 'rsvCancel');
1430  $conf->setCancel($lng->txt('cancel'), 'log');
1431 
1432  foreach ($ids as $id) {
1433  $rsv = new ilBookingReservation($id);
1434  $obj = new ilBookingObject($rsv->getObjectId());
1435 
1436  $details = $obj->getTitle();
1437  if ($this->object->getScheduleType() != ilObjBookingPool::TYPE_NO_SCHEDULE) {
1438  $details .= ", " . ilDatePresentation::formatPeriod(
1439  new ilDateTime($rsv->getFrom(), IL_CAL_UNIX),
1440  new ilDateTime($rsv->getTo()+1, IL_CAL_UNIX)
1441  );
1442  }
1443 
1444  $conf->addItem('rsv_id[]', $id, $details);
1445  }
1446 
1447  $tpl->setContent($conf->getHTML());
1448  }
1449 
1450  public function rsvConfirmCancelAggregationForm($a_ids)
1451  {
1452  include_once 'Services/Form/classes/class.ilPropertyFormGUI.php';
1453  $form = new ilPropertyFormGUI();
1454  $form->setFormAction($this->ctrl->getFormAction($this, "rsvCancel"));
1455  $form->setTitle($this->lng->txt("book_confirm_cancel_aggregation"));
1456 
1457  include_once 'Modules/BookingManager/classes/class.ilBookingObject.php';
1458  include_once 'Modules/BookingManager/classes/class.ilBookingReservation.php';
1459 
1461 
1462  foreach ($a_ids as $idx => $ids) {
1463  if (is_array($ids)) {
1464  $first = $ids;
1465  $first = array_shift($first);
1466  } else {
1467  $first = $ids;
1468  }
1469 
1470  $rsv = new ilBookingReservation($first);
1471  $obj = new ilBookingObject($rsv->getObjectId());
1472 
1473  $caption = $obj->getTitle() . ", " . ilDatePresentation::formatPeriod(
1474  new ilDateTime($rsv->getFrom(), IL_CAL_UNIX),
1475  new ilDateTime($rsv->getTo()+1, IL_CAL_UNIX)
1476  );
1477 
1478  // #17869
1479  if (is_array($ids)) {
1480  $caption .= " (" . sizeof($ids) . ")";
1481  }
1482 
1483  $item = new ilNumberInputGUI($caption, "rsv_id_" . $idx);
1484  $item->setRequired(true);
1485  $item->setMinValue(0);
1486  $item->setSize(4);
1487  $form->addItem($item);
1488 
1489  if (is_array($ids)) {
1490  $item->setMaxValue(sizeof($ids));
1491 
1492  foreach ($ids as $id) {
1493  $hidden = new ilHiddenInputGUI("rsv_aggr[" . $idx . "][]");
1494  $hidden->setValue($id);
1495  $form->addItem($hidden);
1496  }
1497  } else {
1498  $item->setMaxValue(1);
1499 
1500  $hidden = new ilHiddenInputGUI("rsv_aggr[" . $idx . "]");
1501  $hidden->setValue($ids);
1502  $form->addItem($hidden);
1503  }
1504 
1505  if ($_POST["rsv_id_" . $idx]) {
1506  $item->setValue((int) $_POST["rsv_id_" . $idx]);
1507  }
1508  }
1509 
1510  $form->addCommandButton("rsvCancel", $this->lng->txt("confirm"));
1511  $form->addCommandButton("log", $this->lng->txt("cancel"));
1512 
1513  return $form;
1514  }
1515 
1516  public function rsvConfirmCancelAggregationObject(array $a_ids = null)
1517  {
1518  $tpl = $this->tpl;
1519  $ilCtrl = $this->ctrl;
1520  $lng = $this->lng;
1521 
1522  $this->tabs_gui->clearTargets();
1523  $this->tabs_gui->setBackTarget(
1524  $lng->txt("back"),
1525  $ilCtrl->getLinkTarget($this, "log")
1526  );
1527 
1528  $this->setHelpId("cancel_booking");
1529 
1530  // #13511
1531  ilUtil::sendQuestion($lng->txt("book_confirm_cancel"));
1532 
1533  $form = $this->rsvConfirmCancelAggregationForm($a_ids);
1534 
1535  $tpl->setContent($form->getHTML());
1536  }
1537 
1538  public function rsvCancelObject()
1539  {
1540  $ilUser = $this->user;
1541  $tpl = $this->tpl;
1542  $lng = $this->lng;
1543  $ilCtrl = $this->ctrl;
1544 
1545  $ids = $_POST["rsv_id"];
1546 
1547  // parse aggregation form
1548  if ($_POST["rsv_aggr"]) {
1549  $form = $this->rsvConfirmCancelAggregationForm($_POST["rsv_aggr"]);
1550  if (!$form->checkInput()) {
1551  $this->tabs_gui->clearTargets();
1552  $this->tabs_gui->setBackTarget(
1553  $lng->txt("back"),
1554  $ilCtrl->getLinkTarget($this, "log")
1555  );
1556 
1557  return $tpl->setContent($form->getHTML());
1558  }
1559 
1560  $ids = array();
1561  foreach ($_POST["rsv_aggr"] as $idx => $aggr_ids) {
1562  $max = (int) $_POST["rsv_id_" . $idx];
1563  if ($max) {
1564  if (!is_array($aggr_ids)) {
1565  $ids[] = $aggr_ids;
1566  } else {
1567  $aggr_ids = array_slice($aggr_ids, 0, $max);
1568  $ids = array_merge($ids, $aggr_ids);
1569  }
1570  }
1571  }
1572  }
1573 
1574  if ($ids) {
1575  include_once 'Modules/BookingManager/classes/class.ilBookingReservation.php';
1576  foreach ($ids as $id) {
1577  $obj = new ilBookingReservation($id);
1578 
1579  if (!$this->checkPermissionBool("write") && $obj->getUserId() != $ilUser->getId()) {
1580  ilUtil::sendFailure($this->lng->txt('permission_denied'), true);
1581  $this->ctrl->redirect($this, 'log');
1582  }
1583 
1584  $obj->setStatus(ilBookingReservation::STATUS_CANCELLED);
1585  $obj->update();
1586 
1587  if ($this->object->getScheduleType() != ilObjBookingPool::TYPE_NO_SCHEDULE) {
1588  // remove user calendar entry (#11086)
1589  $cal_entry_id = $obj->getCalendarEntry();
1590  if ($cal_entry_id) {
1591  include_once 'Services/Calendar/classes/class.ilCalendarEntry.php';
1592  $entry = new ilCalendarEntry($cal_entry_id);
1593  $entry->delete();
1594  }
1595  }
1596  }
1597  }
1598 
1599  ilUtil::sendSuccess($this->lng->txt('settings_saved'));
1600  $this->logObject();
1601  }
1602 
1603  public function rsvInUseObject()
1604  {
1605  $this->checkPermission("write");
1606 
1607  $ids = $this->getLogReservationIds();
1608  if ($ids) {
1609  include_once 'Modules/BookingManager/classes/class.ilBookingReservation.php';
1610  foreach ($ids as $id) {
1611  $obj = new ilBookingReservation($id);
1612  $obj->setStatus(ilBookingReservation::STATUS_IN_USE);
1613  $obj->update();
1614  }
1615  }
1616 
1617  ilUtil::sendSuccess($this->lng->txt('settings_saved'));
1618  $this->logObject();
1619  }
1620 
1621  public function rsvNotInUseObject()
1622  {
1623  $this->checkPermission("write");
1624 
1625  $ids = $this->getLogReservationIds();
1626  if ($ids) {
1627  include_once 'Modules/BookingManager/classes/class.ilBookingReservation.php';
1628  foreach ($ids as $id) {
1629  $obj = new ilBookingReservation($id);
1630  $obj->setStatus(null);
1631  $obj->update();
1632  }
1633  }
1634 
1635  ilUtil::sendSuccess($this->lng->txt('settings_saved'));
1636  $this->logObject();
1637  }
1638 
1639  public function showProfileObject()
1640  {
1641  $tpl = $this->tpl;
1642  $ilCtrl = $this->ctrl;
1643 
1644  $this->tabs_gui->clearTargets();
1645 
1646  $user_id = (int) $_GET['user_id'];
1647 
1648  include_once 'Services/User/classes/class.ilPublicUserProfileGUI.php';
1649  $profile = new ilPublicUserProfileGUI($user_id);
1650  $profile->setBackUrl($this->ctrl->getLinkTarget($this, 'log'));
1651  $tpl->setContent($ilCtrl->getHTML($profile));
1652  }
1653 
1654  public function addLocatorItems()
1655  {
1656  $ilLocator = $this->locator;
1657 
1658  if (is_object($this->object)) {
1659  $ilLocator->addItem($this->object->getTitle(), $this->ctrl->getLinkTarget($this, "render"), "", $_GET["ref_id"]);
1660  }
1661  }
1662 }
static sendSuccess($a_info="", $a_keep=false)
Send Success Message to Screen.
applyLogFilterObject()
Apply filter from reservations table gui.
Class ilObjBookingPoolGUI.
This class represents an option in a radio group.
a bookable ressource
Class ilObjectMetaDataGUI.
Model for a calendar entry.
renderSlots(ilBookingSchedule $schedule, array $object_ids, $title)
static _getColorsByType($a_type)
get selectable colors
Class ilInfoScreenGUI.
getEditFormCustomValues(array &$a_values)
static getList($a_pool_id, $a_title=null)
Get list of booking objects for given type.
This class represents a selection list property in a property form.
static _numericDayToString($a_day, $a_long=true)
get
This class represents a property form user interface.
static isObjectAvailableNoSchedule($a_obj_id)
GUI class for the workflow of copying objects.
$type
global $DIC
Definition: saml.php:7
bookObject()
First step in booking process.
$_GET["client_id"]
handleBookingSuccess($a_obj_id, array $a_rsv_ids=null)
static getNewGroupId()
Get next group id.
This class represents a section header in a property form.
static _getInstanceByUserId($a_user_id)
get singleton instance
buildDatesBySchedule($week_start, array $hours, $schedule, array $object_ids, $seed, array &$dates)
static formatDate(ilDateTime $date, $a_skip_day=false, $a_include_wd=false)
Format a date public.
schedule for booking ressource
getRaster()
Get booking raster.
$end
Definition: saml1-acs.php:18
if(!array_key_exists('StateId', $_REQUEST)) $id
static _gotoRepositoryRoot($a_raise_error=false)
Goto repository root.
This class represents a checkbox property in a property form.
static setUseRelativeDates($a_status)
set use relative dates
static _lookupTitle($a_id)
lookup object title
$from
addItem($a_item)
Add Item (Property, SectionHeader).
static _buildWeekDayList($a_day, $a_weekstart)
build week day list
updateCustom(ilPropertyFormGUI $a_form)
const IL_CAL_UNIX
initBookingNumbersForm(array $a_objects_counter, $a_group_id, $a_reload=false)
setInfo($a_info)
Set Info.
static _numericMonthToString($a_month, $a_long=true)
numeric month to string
__construct($a_data, $a_id, $a_call_by_reference, $a_prepare_output=true)
Constructor.
This class represents a date/time property in a property form.
global $ilCtrl
Definition: ilias.php:18
setInfo($a_info)
Set Information Text.
static sendInfo($a_info="", $a_keep=false)
Send Info Message to Screen.
$counter
$section
Definition: Utf8Test.php:83
static getNrOfItemsForObjects(array $a_obj_ids)
Get nr of available items.
This class represents a hidden form property in a property form.
prepareOutput($a_show_subobjects=true)
prepare output
GUI class for public user profile presentation.
getTitle()
Get object title.
This class represents a property in a property form.
static getObjectReservationForUser($a_object_id, $a_user_id, $a_multi=false)
$success
Definition: Utf8Test.php:86
Class ilBookingObjectGUI.
$column
Definition: 39dropdown.php:62
Class for single dates.
if(isset($_POST['submit'])) $form
static _gotoRepositoryNode($a_ref_id, $a_cmd="frameset")
Goto repository root.
This class represents a number property in a property form.
Class ilObjectGUI Basic methods of all Output classes.
static _lookupObjId($a_id)
date( 'd-M-Y', $objPHPExcel->getProperties() ->getCreated())
special template class to simplify handling of ITX/PEAR
processBooking($a_object_id, $a_from=null, $a_to=null, $a_group_id=null)
Book object for date.
Date and time handling
$ilUser
Definition: imgupload.php:18
confirmedBookingObject()
Book object - either of type or specific - for given dates.
static calculateFontColor($a_html_color_code)
Calculate best font color from html hex color code.
initEditCustomForm(ilPropertyFormGUI $a_form)
static sendQuestion($a_info="", $a_keep=false)
Send Question to Screen.
getInput($a_post_var, $ensureValidation=true)
Returns the value of a HTTP-POST variable, identified by the passed id.
static updateServiceSettingsForm($a_obj_id, ilPropertyFormGUI $form, $services)
Update service settings.
rsvConfirmCancelAggregationObject(array $a_ids=null)
Create styles array
The data for the language used.
static getAvailableObject(array $a_ids, $a_from, $a_to, $a_return_single=true, $a_return_counter=false)
Check if any of given objects are bookable.
static sendFailure($a_info="", $a_keep=false)
Send Failure Message to Screen.
static lookupPoolId($object_id)
Lookup pool id.
if(php_sapi_name() !='cli') $in
Definition: Utf8Test.php:37
const IL_CAL_FKT_GETDATE
afterSave(ilObject $a_new_object)
setSize($a_size)
Set Size.
const IL_CAL_DATE
static formatPeriod(ilDateTime $start, ilDateTime $end, $a_skip_starting_day=false)
Format a period of two date Shows: 14.
setStart($a_start)
public
Create new PHPExcel object
obj_idprivate
Class ilBookingScheduleGUI.
logObject()
List reservations.
$ret
Definition: parser.php:6
static initServiceSettingsForm($a_obj_id, ilPropertyFormGUI $form, $services)
Init service settings form.
static initDefaultCalendarByType($a_type_id, $a_usr_id, $a_title, $a_create=false)
Init the default calendar for given type and user.
addExternalEditFormCustom(ilPropertyFormGUI $a_form)
$i
Definition: disco.tpl.php:19
getRefId()
get reference id public
resetLogFilterObject()
Reset filter in reservations table gui.
checkPermission($a_perm, $a_cmd="", $a_type="", $a_ref_id=null)
Check permission and redirect on error.
New PermissionGUI (extends from old ilPermission2GUI) RBAC related output.
confirmBookingNumbers(array $a_objects_counter, $a_group_id, ilPropertyFormGUI $a_form=null)
static getCancelDetails($a_obj_id, $a_user_id, $a_from, $a_to)
Get reservation ids from aggregated id for cancellation.
Add data(end) time
Method that wraps PHPs time in order to allow simulations with the workflow.
if(empty($password)) $table
Definition: pwgen.php:24
update()
update object in db
static changeStatus(array $a_ids, $a_status)
List all reservations.
$info
Definition: index.php:5
addHeaderAction()
Add header action menu.
infoScreenObject()
this one is called from the info button in the repository not very nice to set cmdClass/Cmd manually...
static getList($a_pool_id)
Get list of booking objects for given pool.
checkPermissionBool($a_perm, $a_cmd="", $a_type="", $a_ref_id=null)
Check permission.
showNoScheduleMessage()
Show no schedule message.
$_POST["username"]
changeStatusObject()
Change status of given reservations.
setRequired($a_required)
Set Required.
static parseIncomingDate($a_value, $a_add_time=null)
Try to parse incoming value to date object.
static getInstanceFromAjaxCall()
(Re-)Build instance from ajax call
Confirmation screen class.