ILIAS  release_6 Revision v6.24-5-g0c8bfefb3b8
class.ilBookingProcessGUI.php
Go to the documentation of this file.
1<?php
2
3/* Copyright (c) 1998-2019 ILIAS open source, Extended GPL, see docs/LICENSE */
4
12{
16 protected $pool;
17
22
28
33
37 protected $seed;
38
42 protected $help;
43
47 protected $context_obj_id;
48
52 public function __construct(
56 string $seed = "",
57 string $sseed = "",
58 int $context_obj_id = 0
59 ) {
60 global $DIC;
61
62 $this->ctrl = $DIC->ctrl();
63 $this->tpl = $DIC["tpl"];
64 $this->lng = $DIC->language();
65 $this->access = $DIC->access();
66 $this->tabs_gui = $DIC->tabs();
67 $this->user = $DIC->user();
68 $this->help = $help;
69
70 $this->context_obj_id = $context_obj_id;
71
72 $this->book_obj_id = $booking_object_id;
73
74 $this->pool = $pool;
75
76 $this->seed = $seed;
77 $this->sseed = $sseed;
78
79 $this->rsv_ids = explode(";", $_REQUEST["rsv_ids"]);
80
81
82 $this->user_id_assigner = $this->user->getId();
83 if ($_GET['bkusr']) {
84 $this->user_id_to_book = (int) $_GET['bkusr'];
85 } else {
86 $this->user_id_to_book = $this->user_id_assigner; // by default user books his own booking objects.
87 }
88 $this->ctrl->saveParameter($this, ["bkusr"]);
89 }
90
94 public function executeCommand()
95 {
96 $ctrl = $this->ctrl;
97
98 $next_class = $ctrl->getNextClass($this);
99 $cmd = $ctrl->getCmd("show");
100 switch ($next_class) {
101 default:
102 if (in_array($cmd, array("book", "back",
103 "assignParticipants",
104 "bookMultipleParticipants",
105 "saveMultipleBookings",
106 "confirmedBooking",
107 "confirmBookingNumbers",
108 "confirmedBookingNumbers",
109 "displayPostInfo",
110 "deliverPostFile"
111 ))) {
112 $this->$cmd();
113 }
114 }
115 }
116
120 protected function back() // ok
121 {
122 $this->ctrl->returnToParent($this);
123 }
124
128 protected function setHelpId(string $a_id)
129 {
130 $this->help->setHelpId($a_id);
131 }
132
138 protected function checkPermissionBool($a_perm)
139 {
140 $ilAccess = $this->access;
141
142 if (!$ilAccess->checkAccess($a_perm, "", $this->pool->getRefId())) {
143 return false;
144 }
145 return true;
146 }
147
153 protected function checkPermission($a_perm)
154 {
155 if (!$this->checkPermissionBool($a_perm)) {
156 ilUtil::sendFailure($this->lng->txt("no_permission"), true);
157 $this->back();
158 }
159 }
160
161 //
162 // Step 1
163 //
164
165
169 public function book() // ok
170 {
172
173 $this->tabs_gui->clearTargets();
174 $this->tabs_gui->setBackTarget($this->lng->txt('book_back_to_list'), $this->ctrl->getLinkTarget($this, 'back'));
175
176 $this->setHelpId("book");
177
178 $obj = new ilBookingObject($this->book_obj_id);
179
180 $this->lng->loadLanguageModule("dateplaner");
181 $this->ctrl->setParameter($this, 'object_id', $obj->getId());
182
183 if ($this->user_id_to_book != $this->user_id_assigner) {
184 $this->ctrl->setParameter($this, 'bkusr', $this->user_id_to_book);
185 }
186
187 if ($this->pool->getScheduleType() == ilObjBookingPool::TYPE_FIX_SCHEDULE) {
188 $schedule = new ilBookingSchedule($obj->getScheduleId());
189
190 $tpl->setContent($this->renderSlots($schedule, array($obj->getId()), $obj->getTitle()));
191 } else {
192 $cgui = new ilConfirmationGUI();
193 $cgui->setHeaderText($this->lng->txt("book_confirm_booking_no_schedule"));
194
195 $cgui->setFormAction($this->ctrl->getFormAction($this));
196 $cgui->setCancel($this->lng->txt("cancel"), "back");
197 $cgui->setConfirm($this->lng->txt("confirm"), "confirmedBooking");
198
199 $cgui->addItem("object_id", $obj->getId(), $obj->getTitle());
200
201 $tpl->setContent($cgui->getHTML());
202 }
203 }
204
211 protected function renderSlots(ilBookingSchedule $schedule, array $object_ids, string $title) // ok
212 {
213 $ilUser = $this->user;
214
215 // fix
216 if (!$schedule->getRaster()) {
217 $mytpl = new ilTemplate('tpl.booking_reservation_fix.html', true, true, 'Modules/BookingManager');
218
219 $mytpl->setVariable('FORM_ACTION', $this->ctrl->getFormAction($this));
220 $mytpl->setVariable('TXT_TITLE', $this->lng->txt('book_reservation_title'));
221 $mytpl->setVariable('TXT_INFO', $this->lng->txt('book_reservation_fix_info'));
222 $mytpl->setVariable('TXT_OBJECT', $title);
223 $mytpl->setVariable('TXT_CMD_BOOK', $this->lng->txt('book_confirm_booking'));
224 $mytpl->setVariable('TXT_CMD_CANCEL', $this->lng->txt('cancel'));
225
226 $user_settings = ilCalendarUserSettings::_getInstanceByUserId($ilUser->getId());
227
228 $morning_aggr = $user_settings->getDayStart();
229 $evening_aggr = $user_settings->getDayEnd();
230 $hours = array();
231 for ($i = $morning_aggr;$i <= $evening_aggr;$i++) {
232 switch ($user_settings->getTimeFormat()) {
234 if ($morning_aggr > 0 && $i == $morning_aggr) {
235 $hours[$i] = sprintf('%02d:00', 0) . "-";
236 }
237 $hours[$i] .= sprintf('%02d:00', $i);
238 if ($evening_aggr < 23 && $i == $evening_aggr) {
239 $hours[$i] .= "-" . sprintf('%02d:00', 23);
240 }
241 break;
242
244 if ($morning_aggr > 0 && $i == $morning_aggr) {
245 $hours[$i] = date('h a', mktime(0, 0, 0, 1, 1, 2000)) . "-";
246 }
247 $hours[$i] .= date('h a', mktime($i, 0, 0, 1, 1, 2000));
248 if ($evening_aggr < 23 && $i == $evening_aggr) {
249 $hours[$i] .= "-" . date('h a', mktime(23, 0, 0, 1, 1, 2000));
250 }
251 break;
252 }
253 }
254
255 if ($this->seed != "") {
256 $find_first_open = false;
257 $seed = new ilDate($this->seed, IL_CAL_DATE);
258 } else {
259 $find_first_open = true;
260 $seed = ($this->sseed != "")
261 ? new ilDate($this->sseed, IL_CAL_DATE)
262 : new ilDate(time(), IL_CAL_UNIX);
263 }
264
265 $week_start = $user_settings->getWeekStart();
266
267 if (!$find_first_open) {
268 $dates = array();
269 $this->buildDatesBySchedule($week_start, $hours, $schedule, $object_ids, $seed, $dates);
270 } else {
271 $dates = array();
272
273 //loop for 1 week
274 $has_open_slot = $this->buildDatesBySchedule($week_start, $hours, $schedule, $object_ids, $seed, $dates);
275
276 // find first open slot
277 if (!$has_open_slot) {
278 // 1 year is limit for search
279 $limit = clone($seed);
280 $limit->increment(ilDate::YEAR, 1);
281 $limit = $limit->get(IL_CAL_UNIX);
282
283 while (!$has_open_slot && $seed->get(IL_CAL_UNIX) < $limit) {
284 $seed->increment(ilDate::WEEK, 1);
285
286 $dates = array();
287 $has_open_slot = $this->buildDatesBySchedule($week_start, $hours, $schedule, $object_ids, $seed, $dates);
288 }
289 }
290 }
291
292 $navigation = new ilCalendarHeaderNavigationGUI($this, $seed, ilDateTime::WEEK, 'book');
293 $mytpl->setVariable('NAVIGATION', $navigation->getHTML());
294
296 foreach (ilCalendarUtil::_buildWeekDayList($seed, $week_start)->get() as $date) {
297 $date_info = $date->get(IL_CAL_FKT_GETDATE, '', 'UTC');
298
299 $mytpl->setCurrentBlock('weekdays');
300 $mytpl->setVariable('TXT_WEEKDAY', ilCalendarUtil:: _numericDayToString($date_info['wday']));
301 $mytpl->setVariable('TXT_DATE', $date_info['mday'] . ' ' . ilCalendarUtil:: _numericMonthToString($date_info['mon']));
302 $mytpl->parseCurrentBlock();
303 }
304
305 $color = array();
307 for ($loop = 0; $loop < 7; $loop++) {
308 $col = $all[$loop];
310 $color[$loop + 1] = 'border-bottom: 1px solid ' . $col . '; background-color: ' . $col . '; color: ' . $fnt;
311 }
312
313 $counter = 0;
314 foreach ($dates as $hour => $days) {
315 $caption = $days;
316 $caption = array_shift($caption);
317
318 for ($loop = 1; $loop < 8; $loop++) {
319 if (!isset($days[$loop])) {
320 $mytpl->setCurrentBlock('dates');
321 $mytpl->setVariable('DUMMY', '&nbsp;');
322 $mytpl->parseCurrentBlock();
323 } else {
324 if (isset($days[$loop]['captions'])) {
325 foreach ($days[$loop]['captions'] as $slot_id => $slot_caption) {
326 $mytpl->setCurrentBlock('choice');
327 $mytpl->setVariable('TXT_DATE', $slot_caption);
328 $mytpl->setVariable('VALUE_DATE', $slot_id);
329 $mytpl->setVariable('DATE_COLOR', $color[$loop]);
330 $mytpl->setVariable(
331 'TXT_AVAILABLE',
332 sprintf(
333 $this->lng->txt('book_reservation_available'),
334 $days[$loop]['available'][$slot_id]
335 )
336 );
337 $mytpl->parseCurrentBlock();
338 }
339
340 $mytpl->setCurrentBlock('dates');
341 $mytpl->setVariable('DUMMY', '');
342 $mytpl->parseCurrentBlock();
343 } elseif (isset($days[$loop]['in_slot'])) {
344 $mytpl->setCurrentBlock('dates');
345 $mytpl->setVariable('DATE_COLOR', $color[$loop]);
346 $mytpl->parseCurrentBlock();
347 } else {
348 $mytpl->setCurrentBlock('dates');
349 $mytpl->setVariable('DUMMY', '&nbsp;');
350 $mytpl->parseCurrentBlock();
351 }
352 }
353 }
354
355 $mytpl->setCurrentBlock('slots');
356 $mytpl->setVariable('TXT_HOUR', $caption);
357 if ($counter % 2) {
358 $mytpl->setVariable('CSS_ROW', 'tblrow1');
359 } else {
360 $mytpl->setVariable('CSS_ROW', 'tblrow2');
361 }
362 $mytpl->parseCurrentBlock();
363
364 $counter++;
365 }
366 }
367
368 return $mytpl->get();
369 }
370
380 protected function buildDatesBySchedule($week_start, array $hours, ilBookingSchedule $schedule, array $object_ids, $seed, array &$dates) // ok
381 {
382 $ilUser = $this->user;
383
384 $user_settings = ilCalendarUserSettings::_getInstanceByUserId($ilUser->getId());
385
386 $map = array('mo', 'tu', 'we', 'th', 'fr', 'sa', 'su');
387 $definition = $schedule->getDefinition();
388
389 $av_from = ($schedule->getAvailabilityFrom() && !$schedule->getAvailabilityFrom()->isNull())
390 ? $schedule->getAvailabilityFrom()->get(IL_CAL_DATE)
391 : null;
392 $av_to = ($schedule->getAvailabilityTo() && !$schedule->getAvailabilityTo()->isNull())
393 ? $schedule->getAvailabilityTo()->get(IL_CAL_DATE)
394 : null;
395
396 $has_open_slot = false;
398 foreach (ilCalendarUtil::_buildWeekDayList($seed, $week_start)->get() as $date) {
399 $date_info = $date->get(IL_CAL_FKT_GETDATE, '', 'UTC');
400
401 #24045 and #24936
402 if ($av_from || $av_to) {
403 $today = $date->get(IL_CAL_DATE);
404
405 if ($av_from && $av_from > $today) {
406 continue;
407 }
408
409 if ($av_to && $av_to < $today) {
410 continue;
411 }
412 }
413
414 $slots = array();
415 if (isset($definition[$map[$date_info['isoday'] - 1]])) {
416 $slots = array();
417 foreach ($definition[$map[$date_info['isoday'] - 1]] as $slot) {
418 $slot = explode('-', $slot);
419 $slots[] = array('from' => str_replace(':', '', $slot[0]),
420 'to' => str_replace(':', '', $slot[1]));
421 }
422 }
423
424 $last = array_pop(array_keys($hours));
425 $slot_captions = array();
426 foreach ($hours as $hour => $period) {
427 $dates[$hour][0] = $period;
428
429 $period = explode("-", $period);
430
431 // #13738
432 if ($user_settings->getTimeFormat() == ilCalendarSettings::TIME_FORMAT_12) {
433 $period[0] = date("H", strtotime($period[0]));
434 if (sizeof($period) == 2) {
435 $period[1] = date("H", strtotime($period[1]));
436 }
437 }
438
439 if (sizeof($period) == 1) {
440 $period_from = (int) substr($period[0], 0, 2) . "00";
441 $period_to = (int) substr($period[0], 0, 2) . "59";
442 } else {
443 $period_from = (int) substr($period[0], 0, 2) . "00";
444 $period_to = (int) substr($period[1], 0, 2) . "59";
445 }
446
447 $column = $date_info['isoday'];
448 if (!$week_start) {
449 if ($column < 7) {
450 $column++;
451 } else {
452 $column = 1;
453 }
454 }
455
456 if (sizeof($slots)) {
457 $in = false;
458 foreach ($slots as $slot) {
459 $slot_from = mktime(substr($slot['from'], 0, 2), substr($slot['from'], 2, 2), 0, $date_info["mon"], $date_info["mday"], $date_info["year"]);
460 $slot_to = mktime(substr($slot['to'], 0, 2), substr($slot['to'], 2, 2), 0, $date_info["mon"], $date_info["mday"], $date_info["year"]);
461
462 // always single object, we can sum up
463 $nr_available = (array) ilBookingReservation::getAvailableObject($object_ids, $slot_from, $slot_to - 1, false, true);
464
465 // any objects available?
466 if (!array_sum($nr_available)) {
467 continue;
468 }
469
470 // check deadline
471 if ($schedule->getDeadline() >= 0) {
472 // 0-n hours before slots begins
473 if ($slot_from < (time() + $schedule->getDeadline() * 60 * 60)) {
474 continue;
475 }
476 } else {
477 // running slots can be booked, only ended slots are invalid
478 if ($slot_to < time()) {
479 continue;
480 }
481 }
482
483 // is slot active in current hour?
484 if ((int) $slot['from'] < $period_to && (int) $slot['to'] > $period_from) {
485 $from = ilDatePresentation::formatDate(new ilDateTime($slot_from, IL_CAL_UNIX));
486 $from = array_pop(explode(' ', $from));
488 $to = array_pop(explode(' ', $to));
489
490 // show caption (first hour) of slot
491 $id = $slot_from . '_' . $slot_to;
492 if (!in_array($id, $slot_captions)) {
493 $dates[$hour][$column]['captions'][$id] = $from . '-' . $to;
494 $dates[$hour][$column]['available'][$id] = array_sum($nr_available);
495 $slot_captions[] = $id;
496 }
497
498 $in = true;
499 }
500 }
501 // (any) active slot
502 if ($in) {
503 $has_open_slot = true;
504 $dates[$hour][$column]['in_slot'] = $in;
505 }
506 }
507 }
508 }
509
510 return $has_open_slot;
511 }
512
513 //
514 // Step 1a)
515 //
516 // Assign multiple participants (starting from participants screen) (no, from object screen!)
517 //
518
519 //Table to assing participants to an object.
520 public function assignParticipants()
521 {
522 $this->tabs_gui->clearTargets();
523 $this->tabs_gui->setBackTarget($this->lng->txt('book_back_to_list'), $this->ctrl->getLinkTarget($this, 'back'));
524
525 $table = new ilBookingAssignParticipantsTableGUI($this, 'assignParticipants', $this->pool->getRefId(), $this->pool->getId(), $this->book_obj_id);
526
527 $this->tpl->setContent($table->getHTML());
528 }
529
533 public function bookMultipleParticipants()
534 {
535 if ($_POST["mass"]) {
536 $participants = $_POST["mass"];
537 } else {
538 $this->back();
539 }
540
541 $this->tabs_gui->clearTargets();
542 $this->tabs_gui->setBackTarget($this->lng->txt("back"), $this->ctrl->getLinkTarget($this, 'assignparticipants'));
543
544 $conf = new ilConfirmationGUI();
545 $conf->setFormAction($this->ctrl->getFormAction($this));
546
547 //add user list as items.
548 foreach ($participants as $id) {
550 $conf->addItem("participants[]", $id, $name);
551 }
552
553 $available = ilBookingReservation::numAvailableFromObjectNoSchedule($this->book_obj_id);
554 if (sizeof($participants) > $available) {
555 $obj = new ilBookingObject($this->book_obj_id);
556 $conf->setHeaderText(
557 sprintf(
558 $this->lng->txt('book_limit_objects_available'),
559 sizeof($participants),
560 $obj->getTitle(),
561 $available
562 )
563 );
564 } else {
565 $conf->setHeaderText($this->lng->txt('book_confirm_booking_no_schedule'));
566 $conf->addHiddenItem("object_id", $this->book_obj_id);
567 $conf->setConfirm($this->lng->txt("assign"), "saveMultipleBookings");
568 }
569
570 $conf->setCancel($this->lng->txt("cancel"), 'redirectToList');
571 $this->tpl->setContent($conf->getHTML());
572 }
573
574 public function redirectToList()
575 {
576 $this->ctrl->redirect($this, 'assignParticipants');
577 }
578
583 public function saveMultipleBookings()
584 {
585 if ($_POST["participants"] && $_POST['object_id']) {
586 $participants = $_POST["participants"];
587 $this->book_obj_id = $_POST['object_id'];
588 } else {
589 $this->back();
590 }
591 $rsv_ids = array();
592 foreach ($participants as $id) {
593 $this->user_id_to_book = $id;
594 $rsv_ids[] = $this->processBooking($this->book_obj_id);
595 }
596
597 if (sizeof($rsv_ids)) {
598 ilUtil::sendSuccess("booking_multiple_succesfully");
599 $this->back();
600 } else {
601 ilUtil::sendFailure($this->lng->txt('book_reservation_failed_overbooked'), true);
602 $this->back();
603 }
604 }
605
606
607 //
608 // Step 2: Confirmation
609 //
610
615 public function confirmedBooking() // ok
616 {
617 $success = false;
618 $rsv_ids = array();
619
620 if ($this->pool->getScheduleType() != ilObjBookingPool::TYPE_FIX_SCHEDULE) {
621 if ($this->book_obj_id > 0) {
622 $object_id = $this->book_obj_id;
623 if ($object_id) {
625 !ilBookingReservation::getObjectReservationForUser($object_id, $this->user_id_to_book)) { // #18304
626 $rsv_ids[] = $this->processBooking($object_id);
627 $success = $object_id;
628 } else {
629 // #11852
630 ilUtil::sendFailure($this->lng->txt('book_reservation_failed_overbooked'), true);
631 $this->ctrl->redirect($this, 'back');
632 }
633 }
634 }
635 } else {
636 if (!isset($_POST['date'])) {
637 ilUtil::sendFailure($this->lng->txt('select_one'));
638 $this->book();
639 return false;
640 }
641
642 // single object reservation(s)
643 if ($this->book_obj_id > 0) {
644 $confirm = array();
645
646 $object_id = $this->book_obj_id;
647 if ($object_id) {
648 $group_id = null;
649 $nr = ilBookingObject::getNrOfItemsForObjects(array($object_id));
650 // needed for recurrence
652 $repo = $f->getRepo();
653 $group_id = $repo->getNewGroupId();
654 foreach ($_POST['date'] as $date) {
655 $fromto = explode('_', $date);
656 $fromto[1]--;
657
658 $counter = ilBookingReservation::getAvailableObject(array($object_id), $fromto[0], $fromto[1], false, true);
659 $counter = $counter[$object_id];
660 if ($counter) {
661 // needed for recurrence
662 $confirm[$object_id . "_" . $fromto[0] . "_" . ($fromto[1] + 1)] = $counter;
663 }
664 }
665 }
666
667 if (sizeof($confirm)) {
668 $this->confirmBookingNumbers($confirm, $group_id);
669 return false;
670 }
671 }
672 }
673
674 if ($success) {
675 $this->saveParticipant();
676 $this->handleBookingSuccess($success, $rsv_ids);
677 } else {
678 ilUtil::sendFailure($this->lng->txt('book_reservation_failed'), true);
679 $this->ctrl->redirect($this, 'book');
680 }
681 return true;
682 }
683
687 protected function saveParticipant()
688 {
689 $participant = new ilBookingParticipant($this->user_id_to_book, $this->pool->getId());
690 }
691
701 public function processBooking($a_object_id, $a_from = null, $a_to = null, $a_group_id = null)
702 {
703 // #11995
704 $this->checkPermission('read');
705
706 $reservation = new ilBookingReservation();
707 $reservation->setObjectId($a_object_id);
708 $reservation->setUserId($this->user_id_to_book);
709 $reservation->setAssignerId($this->user_id_assigner);
710 $reservation->setFrom($a_from);
711 $reservation->setTo($a_to);
712 $reservation->setGroupId($a_group_id);
713 $reservation->setContextObjId($this->context_obj_id);
714 $reservation->save();
715
716 if ($a_from) {
717 $this->lng->loadLanguageModule('dateplaner');
718 $def_cat = ilCalendarUtil::initDefaultCalendarByType(ilCalendarCategory::TYPE_BOOK, $this->user_id_to_book, $this->lng->txt('cal_ch_personal_book'), true);
719
720 $object = new ilBookingObject($a_object_id);
721
722 $entry = new ilCalendarEntry;
723 $entry->setStart(new ilDateTime($a_from, IL_CAL_UNIX));
724 $entry->setEnd(new ilDateTime($a_to, IL_CAL_UNIX));
725 $entry->setTitle($this->lng->txt('book_cal_entry') . ' ' . $object->getTitle());
726 $entry->setContextId($reservation->getId());
727 $entry->save();
728
729 $assignment = new ilCalendarCategoryAssignments($entry->getEntryId());
730 $assignment->addAssignment($def_cat->getCategoryId());
731 }
732
733 return $reservation->getId();
734 }
735
736 //
737 // Confirm booking numbers
738 //
739
740 public function confirmBookingNumbers(array $a_objects_counter, $a_group_id, ilPropertyFormGUI $a_form = null)
741 {
743
744 $this->tabs_gui->clearTargets();
745 $this->tabs_gui->setBackTarget($this->lng->txt('book_back_to_list'), $this->ctrl->getLinkTarget($this, 'back'));
746
747 if (!$a_form) {
748 $a_form = $this->initBookingNumbersForm($a_objects_counter, $a_group_id);
749 }
750
751 $tpl->setContent($a_form->getHTML());
752 }
753
754
755 protected function initBookingNumbersForm(array $a_objects_counter, $a_group_id, $a_reload = false)
756 {
757 $form = new ilPropertyFormGUI();
758 $form->setFormAction($this->ctrl->getFormAction($this, "confirmedBooking"));
759 $form->setTitle($this->lng->txt("book_confirm_booking_schedule_number_of_objects"));
760 $form->setDescription($this->lng->txt("book_confirm_booking_schedule_number_of_objects_info"));
761
762 $section = false;
763 $min_date = null;
764 foreach ($a_objects_counter as $id => $counter) {
765 $id = explode("_", $id);
766 $book_id = $id[0] . "_" . $id[1] . "_" . $id[2] . "_" . $counter;
767
768 $obj = new ilBookingObject($id[0]);
769
770 if (!$section) {
772 $section->setTitle($obj->getTitle());
773 $form->addItem($section);
774
775 $section = true;
776 }
777
778 $period = /* $this->lng->txt("book_period").": ". */
780 new ilDateTime($id[1], IL_CAL_UNIX),
781 new ilDateTime($id[2], IL_CAL_UNIX)
782 );
783
784 $nr_field = new ilNumberInputGUI($period, "conf_nr__" . $book_id);
785 $nr_field->setValue(1);
786 $nr_field->setSize(3);
787 $nr_field->setMaxValue($counter);
788 $nr_field->setMinValue($counter ? 1 : 0);
789 $nr_field->setRequired(true);
790 $form->addItem($nr_field);
791
792 if (!$min_date || $id[1] < $min_date) {
793 $min_date = $id[1];
794 }
795 }
796
797 // recurrence
798 $this->lng->loadLanguageModule("dateplaner");
799 $rec_mode = new ilSelectInputGUI($this->lng->txt("cal_recurrences"), "recm");
800 $rec_mode->setRequired(true);
801 $rec_mode->setOptions(array(
802 "-1" => $this->lng->txt("cal_no_recurrence"),
803 1 => $this->lng->txt("cal_weekly"),
804 2 => $this->lng->txt("r_14"),
805 4 => $this->lng->txt("r_4_weeks")
806 ));
807 $form->addItem($rec_mode);
808
809 $rec_end = new ilDateTimeInputGUI($this->lng->txt("cal_repeat_until"), "rece");
810 $rec_end->setRequired(true);
811 $rec_mode->addSubItem($rec_end);
812
813 if (!$a_reload) {
814 // show date only if active recurrence
815 $rec_mode->setHideSubForm(true, '>= 1');
816
817 if ($min_date) {
818 $rec_end->setDate(new ilDateTime($min_date, IL_CAL_UNIX));
819 }
820 } else {
821 // recurrence may not be changed on reload
822 $rec_mode->setDisabled(true);
823 $rec_end->setDisabled(true);
824 }
825
826 if ($a_group_id) {
827 $grp = new ilHiddenInputGUI("grp_id");
828 $grp->setValue($a_group_id);
829 $form->addItem($grp);
830 }
831
832 if ($this->user_id_assigner != $this->user_id_to_book) {
833 $usr = new ilHiddenInputGUI("bkusr");
834 $usr->setValue($this->user_id_to_book);
835 $form->addItem($usr);
836 }
837
838 $form->addCommandButton("confirmedBookingNumbers", $this->lng->txt("confirm"));
839 $form->addCommandButton("back", $this->lng->txt("cancel"));
840
841 return $form;
842 }
843
844 public function confirmedBookingNumbers() // ok
845 {
846
847 //get the user who will get the booking.
848 if ($_POST['bkusr']) {
849 $this->user_id_to_book = (int) $_POST['bkusr'];
850 }
851
852 // convert post data to initial form config
853 $counter = array();
854 $current_first = $obj_id = null;
855 foreach (array_keys($_POST) as $id) {
856 if (substr($id, 0, 9) == "conf_nr__") {
857 $id = explode("_", substr($id, 9));
858 $counter[$id[0] . "_" . $id[1] . "_" . $id[2]] = (int) $id[3];
859 if (!$current_first) {
860 $current_first = date("Y-m-d", $id[1]);
861 }
862 }
863 }
864
865 // recurrence
866
867 // checkInput() has not been called yet, so we have to improvise
868 $end = ilCalendarUtil::parseIncomingDate($_POST["rece"], null);
869
870 if ((int) $_POST["recm"] > 0 && $end && $current_first) {
871 ksort($counter);
872 $end = $end->get(IL_CAL_DATE);
873 $cycle = (int) $_POST["recm"] * 7;
874 $cut = 0;
875 $org = $counter;
876 while ($cut < 1000 && $this->addDaysDate($current_first, $cycle) <= $end) {
877 $cut++;
878 $current_first = null;
879 foreach ($org as $item_id => $max) {
880 $parts = explode("_", $item_id);
881 $obj_id = $parts[0];
882
883 $from = $this->addDaysStamp($parts[1], $cycle * $cut);
884 $to = $this->addDaysStamp($parts[2], $cycle * $cut);
885
886 $new_item_id = $obj_id . "_" . $from . "_" . $to;
887
888 // form reload because of validation errors
889 if (!isset($counter[$new_item_id]) && date("Y-m-d", $to) <= $end) {
890 // get max available for added dates
891 $new_max = ilBookingReservation::getAvailableObject(array($obj_id), $from, $to - 1, false, true);
892 $new_max = (int) $new_max[$obj_id];
893
894 $counter[$new_item_id] = $new_max;
895
896 if (!$current_first) {
897 $current_first = date("Y-m-d", $from);
898 }
899
900 // clone input
901 $_POST["conf_nr__" . $new_item_id . "_" . $new_max] = $_POST["conf_nr__" . $item_id . "_" . $max];
902 }
903 }
904 }
905 }
906
907 $group_id = $_POST["grp_id"];
908
909 $form = $this->initBookingNumbersForm($counter, $group_id, true);
910 if ($form->checkInput()) {
911 $success = false;
912 $rsv_ids = array();
913 foreach ($counter as $id => $all_nr) {
914 $book_nr = $form->getInput("conf_nr__" . $id . "_" . $all_nr);
915 $parts = explode("_", $id);
916 $obj_id = $parts[0];
917 $from = $parts[1];
918 $to = $parts[2] - 1;
919
920 // get currently available slots
921 $counter = ilBookingReservation::getAvailableObject(array($obj_id), $from, $to, false, true);
922 $counter = $counter[$obj_id];
923 if ($counter) {
924 // we can only book what is left
925 $book_nr = min($book_nr, $counter);
926 for ($loop = 0; $loop < $book_nr; $loop++) {
927 $rsv_ids[] = $this->processBooking($obj_id, $from, $to, $group_id);
928 $success = $obj_id;
929 }
930 }
931 }
932 if ($success) {
933 $this->saveParticipant();
934 $this->handleBookingSuccess($success, $rsv_ids);
935 } else {
936 ilUtil::sendFailure($this->lng->txt('book_reservation_failed'), true);
937 $this->back();
938 }
939 } else {
940 // ilDateTimeInputGUI does NOT add hidden values on disabled!
941
942 $rece_array = explode(".", $_POST['rece']);
943
944 $rece_day = str_pad($rece_array[0], 2, "0", STR_PAD_LEFT);
945 $rece_month = str_pad($rece_array[1], 2, "0", STR_PAD_LEFT);
946 $rece_year = $rece_array[2];
947
948 // ilDateTimeInputGUI will choke on POST array format
949 $_POST["rece"] = null;
950
951 $form->setValuesByPost();
952
953 $rece_date = new ilDate($rece_year . "-" . $rece_month . "-" . $rece_day, IL_CAL_DATE);
954
955 $form->getItemByPostVar("rece")->setDate($rece_date);
956 $form->getItemByPostVar("recm")->setHideSubForm($_POST["recm"] < 1);
957
958 $hidden_date = new ilHiddenInputGUI("rece");
959 $hidden_date->setValue($rece_date);
960 $form->addItem($hidden_date);
961
962 $this->confirmBookingNumbers($counter, $group_id, $form);
963 }
964 }
965
966 protected function addDaysDate($a_date, $a_days)
967 {
968 $date = date_parse($a_date);
969 $stamp = mktime(0, 0, 1, $date["month"], $date["day"] + $a_days, $date["year"]);
970 return date("Y-m-d", $stamp);
971 }
972
973 protected function addDaysStamp($a_stamp, $a_days)
974 {
975 $date = getDate($a_stamp);
976 return mktime(
977 $date["hours"],
978 $date["minutes"],
979 $date["seconds"],
980 $date["mon"],
981 $date["mday"] + $a_days,
982 $date["year"]
983 );
984 }
985
986 //
987 // Step 3: Display post success info
988 //
989
990 protected function handleBookingSuccess($a_obj_id, array $a_rsv_ids = null)
991 {
992 ilUtil::sendSuccess($this->lng->txt('book_reservation_confirmed'), true);
993
994 // show post booking information?
995 $obj = new ilBookingObject($a_obj_id);
996 $pfile = $obj->getPostFile();
997 $ptext = $obj->getPostText();
998
999 if (trim($ptext) || $pfile) {
1000 if (sizeof($a_rsv_ids)) {
1001 $this->ctrl->setParameter($this, 'rsv_ids', implode(";", $a_rsv_ids));
1002 }
1003 $this->ctrl->redirect($this, 'displayPostInfo');
1004 } else {
1005 $this->back();
1006 }
1007 }
1008
1012 public function displayPostInfo()
1013 {
1014 $tpl = $this->tpl;
1015 $lng = $this->lng;
1016 $ilCtrl = $this->ctrl;
1017 $id = $this->book_obj_id;
1018 if (!$id) {
1019 return;
1020 }
1021
1022 // placeholder
1023
1024 $book_ids = ilBookingReservation::getObjectReservationForUser($id, $this->user_id_assigner, true);
1025 $tmp = array();
1026 foreach ($book_ids as $book_id) {
1027 if (in_array($book_id, $this->rsv_ids)) {
1028 $obj = new ilBookingReservation($book_id);
1029 $from = $obj->getFrom();
1030 $to = $obj->getTo();
1031 if ($from > time()) {
1032 $tmp[$from . "-" . $to]++;
1033 }
1034 }
1035 }
1036
1039
1040 $period = array();
1041 ksort($tmp);
1042 foreach ($tmp as $time => $counter) {
1043 $time = explode("-", $time);
1045 new ilDateTime($time[0], IL_CAL_UNIX),
1046 new ilDateTime($time[1], IL_CAL_UNIX)
1047 );
1048 if ($counter > 1) {
1049 $time .= " (" . $counter . ")";
1050 }
1051 $period[] = $time;
1052 }
1053 $book_id = array_shift($book_ids);
1054
1056
1057
1058 /*
1059 #23578 since Booking pool participants.
1060 $obj = new ilBookingReservation($book_id);
1061 if ($obj->getUserId() != $ilUser->getId())
1062 {
1063 return;
1064 }
1065 */
1066
1067 $obj = new ilBookingObject($id);
1068 $pfile = $obj->getPostFile();
1069 $ptext = $obj->getPostText();
1070
1071 $mytpl = new ilTemplate('tpl.booking_reservation_post.html', true, true, 'Modules/BookingManager/BookingProcess');
1072 $mytpl->setVariable("TITLE", $lng->txt('book_post_booking_information'));
1073
1074 if ($ptext) {
1075 // placeholder
1076 $ptext = str_replace("[OBJECT]", $obj->getTitle(), $ptext);
1077 $ptext = str_replace("[PERIOD]", implode("<br />", $period), $ptext);
1078
1079 $mytpl->setVariable("POST_TEXT", nl2br($ptext));
1080 }
1081
1082 if ($pfile) {
1083 $url = $ilCtrl->getLinkTarget($this, 'deliverPostFile');
1084
1085 $mytpl->setVariable("DOWNLOAD", $lng->txt('download'));
1086 $mytpl->setVariable("URL_FILE", $url);
1087 $mytpl->setVariable("TXT_FILE", $pfile);
1088 }
1089
1090 $mytpl->setVariable("TXT_SUBMIT", $lng->txt('ok'));
1091 $mytpl->setVariable("URL_SUBMIT", $ilCtrl->getLinkTarget($this, "back"));
1092
1093 $tpl->setContent($mytpl->get());
1094 }
1095
1099 public function deliverPostFile()
1100 {
1101 $id = $this->book_obj_id;
1102 if (!$id) {
1103 return;
1104 }
1105
1106 $book_id = ilBookingReservation::getObjectReservationForUser($id, $this->user_id_assigner);
1107 $obj = new ilBookingReservation($book_id);
1108 if ($obj->getUserId() != $this->user_id_assigner) {
1109 return;
1110 }
1111
1112 $obj = new ilBookingObject($id);
1113 $file = $obj->getPostFileFullPath();
1114 if ($file) {
1115 ilUtil::deliverFile($file, $obj->getPostFile());
1116 }
1117 }
1118}
user()
Definition: user.php:4
$success
Definition: Utf8Test.php:86
if(php_sapi_name() !='cli') $in
Definition: Utf8Test.php:37
$section
Definition: Utf8Test.php:83
$_GET["client_id"]
$_POST["username"]
An exception for terminatinating execution or to throw for unit testing.
const IL_CAL_FKT_GETDATE
const IL_CAL_DATE
const IL_CAL_UNIX
Help adapter for booking manager.
a bookable ressource
static getNrOfItemsForObjects(array $a_obj_ids)
Get nr of available items.
Class ilBookingParticipant.
Booking process ui class.
__construct(ilObjBookingPool $pool, int $booking_object_id, ilBookingHelpAdapter $help, string $seed="", string $sseed="", int $context_obj_id=0)
Constructor.
initBookingNumbersForm(array $a_objects_counter, $a_group_id, $a_reload=false)
saveMultipleBookings()
Save multiple users reservations for one booking pool object.
confirmedBooking()
Book object - either of type or specific - for given dates.
bookMultipleParticipants()
Create reservations for a bunch of booking pool participants.
processBooking($a_object_id, $a_from=null, $a_to=null, $a_group_id=null)
Book object for date.
displayPostInfo()
Display post booking informatins.
book()
First step in booking process.
confirmBookingNumbers(array $a_objects_counter, $a_group_id, ilPropertyFormGUI $a_form=null)
checkPermission($a_perm)
Check permission.
saveParticipant()
save booking participant.
deliverPostFile()
Deliver post booking file.
checkPermissionBool($a_perm)
Check permission.
handleBookingSuccess($a_obj_id, array $a_rsv_ids=null)
executeCommand()
Execute command.
static getObjectReservationForUser($a_object_id, $a_user_id, $a_multi=false)
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 numAvailableFromObjectNoSchedule($a_obj_id)
static isObjectAvailableNoSchedule($a_obj_id)
schedule for booking ressource
getRaster()
Get booking raster.
getAvailabilityTo()
Get availability end.
getAvailabilityFrom()
Get availability start.
getDefinition()
Get definition.
static _getColorsByType($a_type)
get selectable colors
Model for a calendar entry.
setStart($a_start)
@access public
static _getInstanceByUserId($a_user_id)
get singleton instance
static parseIncomingDate($a_value, $a_add_time=null)
Try to parse incoming value to date object.
static _numericDayToString($a_day, $a_long=true)
get
static _buildWeekDayList($a_day, $a_weekstart)
build week day list
static calculateFontColor($a_html_color_code)
Calculate best font color from html hex color code.
static _numericMonthToString($a_month, $a_long=true)
numeric month to string
static initDefaultCalendarByType($a_type_id, $a_usr_id, $a_title, $a_create=false)
Init the default calendar for given type and user.
Confirmation screen class.
static formatDate(ilDateTime $date, $a_skip_day=false, $a_include_wd=false, $include_seconds=false)
Format a date @access public.
static setUseRelativeDates($a_status)
set use relative dates
static useRelativeDates()
check if relative dates are used
static formatPeriod(ilDateTime $start, ilDateTime $end, $a_skip_starting_day=false)
Format a period of two date Shows: 14.
This class represents a date/time property in a property form.
@classDescription Date and time handling
Class for single dates.
This class represents a section header in a property form.
This class represents a hidden form property in a property form.
This class represents a number property in a property form.
Class ilObjBookingPool.
static _lookupFullname($a_user_id)
Lookup Full Name.
This class represents a property form user interface.
This class represents a selection list property in a property form.
special template class to simplify handling of ITX/PEAR
static sendFailure($a_info="", $a_keep=false)
Send Failure Message to Screen.
static deliverFile( $a_file, $a_filename, $a_mime='', $isInline=false, $removeAfterDelivery=false, $a_exit_after=true)
deliver file for download via browser.
help()
Definition: help.php:2
global $ilCtrl
Definition: ilias.php:18
if($format !==null) $name
Definition: metadata.php:230
$i
Definition: metadata.php:24
$url
$lng
if(isset($_FILES['img_file']['size']) && $_FILES['img_file']['size'] > 0) $tpl
$ilUser
Definition: imgupload.php:18
$DIC
Definition: xapitoken.php:46