diff --git a/components/ILIAS/BookingManager/BookingProcess/class.ProcessUtilGUI.php b/components/ILIAS/BookingManager/BookingProcess/class.ProcessUtilGUI.php
index 1ddab4e7782f..3f24055f45a6 100755
--- a/components/ILIAS/BookingManager/BookingProcess/class.ProcessUtilGUI.php
+++ b/components/ILIAS/BookingManager/BookingProcess/class.ProcessUtilGUI.php
@@ -76,6 +76,11 @@ public function back(): void
return;
}
+ if ($retCmd === 'render') {
+ $this->redirectToRender();
+ return;
+ }
+
if ($retCmd !== "") {
$this->ctrl->redirectByClass(get_class($this->parent_gui), $retCmd);
} else {
@@ -184,107 +189,205 @@ public function displayPostInfo(
int $user_id,
string $file_deliver_cmd
): void {
- $this->log->debug("displayPostInfo");
- $main_tpl = $this->gui->mainTemplate();
- $ctrl = $this->gui->ctrl();
- $lng = $this->domain->lng();
- $id = $book_obj_id;
- $request = $this->gui->standardRequest();
+ $this->log->debug('displayPostInfo');
+ $booking_ids = $this->request->getReservationIdsFromString();
- if (!$id) {
+ $objects_with_periods = $this->resolveObjectsWithPeriodsForPostInfo(
+ $book_obj_id,
+ $user_id,
+ $booking_ids
+ );
+
+ if ($objects_with_periods === []) {
+ $this->ctrl->redirect($this->parent_gui, 'back');
return;
}
- $rsv_ids = $request->getReservationIdsFromString();
-
- $tmp = [];
- if ($rsv_ids === [] && $request->getReservationId() !== '') {
- $reservationIdParts = explode('_', $request->getReservationId());
+ $booking_objects = [];
+ $booking_info_filenames = [];
- $user_id = (int) ($reservationIdParts[1] ?? 0);
- $from = (int) ($reservationIdParts[2] ?? 0);
+ $objects_with_info = [];
+ foreach ($objects_with_periods as $object_id => $periods) {
+ $booking_objects[$object_id] = new \ilBookingObject($object_id);
+ $booking_info_filenames[$object_id] = trim($this->objects_manager->getBookingInfoFilename($object_id));
- if ($from > time()) {
- $to = (int) ($reservationIdParts[3] ?? 0);
- $tmp["$from-" . ($to + 1)] = 1;
+ if (
+ trim($booking_objects[$object_id]->getPostText()) === ''
+ && $booking_info_filenames[$object_id] === ''
+ ) {
+ continue;
}
- $rsv_ids = [0];
+
+ $objects_with_info[$object_id] = $periods;
}
- // placeholder
+ if ($objects_with_info === []) {
+ $this->ctrl->redirect($this->parent_gui, 'back');
+ return;
+ }
- $book_ids = \ilBookingReservation::getObjectReservationForUser($id, $user_id);
- foreach ($book_ids as $book_id) {
- if (in_array($book_id, $rsv_ids) || count($rsv_ids) === 0) {
- $obj = new \ilBookingReservation($book_id);
- $from = $obj->getFrom();
- $to = $obj->getTo();
- if ($from > time()) {
- $tmp[$from . "-" . $to + 1] = $tmp[$from . "-" . $to + 1] ?? 0;
- $tmp[$from . "-" . $to + 1]++;
- }
+ $template = new \ilTemplate(
+ 'tpl.booking_reservation_post.html',
+ true,
+ true,
+ 'components/ILIAS/BookingManager/BookingProcess'
+ );
+ $multiple_objects = count($objects_with_info) > 1;
+ $submit_url = $this->ctrl->getLinkTarget($this->parent_gui, 'back');
+
+ foreach ($objects_with_info as $object_id => $periods) {
+ $booking_object = $booking_objects[$object_id];
+ $post_text = trim($booking_object->getPostText());
+
+ $template->setCurrentBlock('info_block');
+ $title = $multiple_objects
+ ? sprintf($this->lng->txt('book_post_booking_information_for'), $booking_object->getTitle())
+ : $this->lng->txt('book_post_booking_information');
+ $template->setVariable('TITLE', $title);
+
+ if ($post_text !== '') {
+ $post_text = str_replace(
+ ['[OBJECT]', '[PERIOD]'],
+ [$booking_object->getTitle(), implode('
', $periods)],
+ $post_text
+ );
+ $template->setVariable('POST_TEXT', nl2br($post_text));
+ }
+
+ if ($booking_info_filenames[$object_id] === '') {
+ $template->parseCurrentBlock();
+ continue;
}
+
+ $this->ctrl->setParameter($this->parent_gui, 'object_id', $object_id);
+ $url = $this->ctrl->getLinkTarget($this->parent_gui, $file_deliver_cmd);
+ $this->ctrl->clearParameterByClass($this->parent_gui::class, 'object_id');
+
+ $template->setCurrentBlock('download');
+ $template->setVariable('DOWNLOAD', $this->lng->txt('download'));
+ $template->setVariable('URL_FILE', $url);
+ $template->setVariable('TXT_FILE', $booking_info_filenames[$object_id]);
+ $template->parseCurrentBlock();
+ $template->setCurrentBlock('info_block');
+
+ $template->parseCurrentBlock();
}
- $olddt = \ilDatePresentation::useRelativeDates();
- \ilDatePresentation::setUseRelativeDates(false);
+ $template->setCurrentBlock('submit');
+ $template->setVariable('TXT_SUBMIT', $this->lng->txt('ok'));
+ $template->setVariable('URL_SUBMIT', $submit_url);
+ $template->parseCurrentBlock();
- $period = array();
- ksort($tmp);
- foreach ($tmp as $time => $counter) {
- $time = explode("-", $time);
- $time = \ilDatePresentation::formatPeriod(
- new \ilDateTime($time[0], IL_CAL_UNIX),
- new \ilDateTime($time[1], IL_CAL_UNIX)
- );
- if ($counter > 1) {
- $time .= " (" . $counter . ")";
+ $this->tpl->setContent($template->get());
+ }
+
+ /**
+ * @return array
+ */
+ protected function resolveObjectsWithPeriodsForPostInfo(
+ int $book_obj_id,
+ int $user_id,
+ array $booking_ids
+ ): array {
+ if ($booking_ids !== []) {
+ return $this->resolvePeriodsFromReservationIds($booking_ids);
+ }
+
+ if ($book_obj_id <= 0) {
+ return [];
+ }
+
+ $period_slots = [];
+ if ($this->request->getReservationId() !== '') {
+ $reservation_id_parts = explode('_', $this->request->getReservationId());
+ $user_id = (int) ($reservation_id_parts[1] ?? 0);
+ $from = (int) ($reservation_id_parts[2] ?? 0);
+
+ if ($from > time()) {
+ $to = (int) ($reservation_id_parts[3] ?? 0);
+ $period_slots["$from-$to"] = 1;
}
- $period[] = $time;
+ $booking_ids = [0];
}
- $book_id = array_shift($book_ids);
- \ilDatePresentation::setUseRelativeDates($olddt);
+ $book_ids = \ilBookingReservation::getObjectReservationForUser($book_obj_id, $user_id);
+ foreach ($book_ids as $book_id) {
+ if (!in_array($book_id, $booking_ids, true) && $booking_ids !== []) {
+ continue;
+ }
- /*
- #23578 since Booking pool participants.
- $obj = new ilBookingReservation($book_id);
- if ($obj->getUserId() != $ilUser->getId())
- {
- return;
+ $reservation = new \ilBookingReservation($book_id);
+ $from = $reservation->getFrom();
+ $to = $reservation->getTo();
+ if ($from > time()) {
+ $key = "$from-$to";
+ $period_slots[$key] = ($period_slots[$key] ?? 0) + 1;
+ }
}
- */
- $obj = new \ilBookingObject($id);
- $pfile = $this->objects_manager->getBookingInfoFilename($id);
- $ptext = $obj->getPostText();
+ return $period_slots === []
+ ? []
+ : [$book_obj_id => $this->formatPeriodSlots($period_slots)];
+ }
- $mytpl = new \ilTemplate('tpl.booking_reservation_post.html', true, true, 'components/ILIAS/BookingManager/BookingProcess');
- $mytpl->setVariable("TITLE", $lng->txt('book_post_booking_information'));
+ /**
+ * @param string[] $booking_ids
+ * @return array
+ */
+ protected function resolvePeriodsFromReservationIds(array $booking_ids): array
+ {
+ $period_slots_by_object = [];
- if ($ptext) {
- // placeholder
- $ptext = str_replace(
- ["[OBJECT]", "[PERIOD]"],
- [$obj->getTitle(), implode("
", $period)],
- $ptext
- );
+ foreach ($booking_ids as $booking_id) {
+ $booking_id = (int) $booking_id;
+ if ($booking_id <= 0) {
+ continue;
+ }
- $mytpl->setVariable("POST_TEXT", nl2br($ptext));
+ $reservation = new \ilBookingReservation($booking_id);
+ $object_id = $reservation->getObjectId();
+ $key = "{$reservation->getFrom()}-{$reservation->getTo()}";
+ $period_slots_by_object[$object_id][$key] = ($period_slots_by_object[$object_id][$key] ?? 0) + 1;
}
- if ($pfile) {
- $url = $ctrl->getLinkTarget($this->parent_gui, $file_deliver_cmd);
+ $objects_with_periods = [];
+ foreach ($period_slots_by_object as $object_id => $period_slots) {
+ $objects_with_periods[$object_id] = $this->formatPeriodSlots($period_slots);
+ }
+
+ ksort($objects_with_periods);
+
+ return $objects_with_periods;
+ }
+
+ /**
+ * @param array $period_slots
+ * @return string[]
+ */
+ protected function formatPeriodSlots(array $period_slots): array
+ {
+ $olddt = \ilDatePresentation::useRelativeDates();
+ \ilDatePresentation::setUseRelativeDates(false);
+
+ $period = [];
+ ksort($period_slots);
+ foreach ($period_slots as $time => $counter) {
+ $time_parts = explode('-', $time);
+ $formatted = \ilDatePresentation::formatPeriod(
+ new \ilDateTime((int) $time_parts[0], IL_CAL_UNIX),
+ new \ilDateTime((int) $time_parts[1], IL_CAL_UNIX)
+ );
- $mytpl->setVariable("DOWNLOAD", $lng->txt('download'));
- $mytpl->setVariable("URL_FILE", $url);
- $mytpl->setVariable("TXT_FILE", $pfile);
+ if ($counter > 1) {
+ $formatted .= " ($counter)";
+ }
+
+ $period[] = $formatted;
}
- $mytpl->setVariable("TXT_SUBMIT", $lng->txt('ok'));
- $mytpl->setVariable("URL_SUBMIT", $ctrl->getLinkTarget($this->parent_gui, "back"));
+ \ilDatePresentation::setUseRelativeDates($olddt);
- $main_tpl->setContent($mytpl->get());
+ return $period;
}
/**
diff --git a/components/ILIAS/BookingManager/BookingProcess/templates/default/tpl.booking_reservation_post.html b/components/ILIAS/BookingManager/BookingProcess/templates/default/tpl.booking_reservation_post.html
index 53621b1bdba5..c54fee6730f1 100755
--- a/components/ILIAS/BookingManager/BookingProcess/templates/default/tpl.booking_reservation_post.html
+++ b/components/ILIAS/BookingManager/BookingProcess/templates/default/tpl.booking_reservation_post.html
@@ -1,3 +1,4 @@
+
-
-
\ No newline at end of file
+
+
+
+
+
diff --git a/components/ILIAS/BookingManager/src/BookableItem/Table/Action/BookableItemTableBookAction.php b/components/ILIAS/BookingManager/src/BookableItem/Table/Action/BookableItemTableBookAction.php
index c0ae73b87720..ca6a4468b19d 100644
--- a/components/ILIAS/BookingManager/src/BookableItem/Table/Action/BookableItemTableBookAction.php
+++ b/components/ILIAS/BookingManager/src/BookableItem/Table/Action/BookableItemTableBookAction.php
@@ -21,6 +21,8 @@
namespace ILIAS\BookingManager\BookableItem\Table\Action;
use ilBookingObjectGUI;
+use ilBookingProcessWithScheduleGUI;
+use ilBookingProcessWithoutScheduleGUI;
use ilBookingReservation;
use ilCtrlInterface;
use ilDatePresentation;
@@ -43,8 +45,6 @@
use ilBookingObject;
use ILIAS\BookingManager\BookingProcess\BookingProcessManager;
use ilObjUser;
-use DateTimeZone;
-use DateTime;
class BookableItemTableBookAction implements TableAction
{
@@ -290,6 +290,7 @@ public function onSubmit(
$booked_total = 0;
$unavailable = [];
+ $booking_ids = [];
foreach ($data as $object_id => $section) {
$message = $section['message'] ?? '';
@@ -318,6 +319,9 @@ public function onSubmit(
if ($booked !== []) {
$booked_total += count($booked);
+ foreach ($booked as $booking_id) {
+ $booking_ids[] = $booking_id;
+ }
continue;
}
@@ -347,6 +351,15 @@ public function onSubmit(
$this->lng->txt('book_reservation_confirmed'),
true
);
+
+ $booking_process_gui_class = $this->pool->getScheduleType() === ilObjBookingPool::TYPE_FIX_SCHEDULE
+ ? ilBookingProcessWithScheduleGUI::class
+ : ilBookingProcessWithoutScheduleGUI::class;
+
+ $this->ctrl->setParameterByClass($booking_process_gui_class, 'rsv_ids', implode(';', array_unique($booking_ids)));
+ $this->ctrl->setParameterByClass($booking_process_gui_class, 'returnCmd', 'render');
+ $this->ctrl->redirectByClass($booking_process_gui_class, 'displayPostInfo');
+ return null;
}
$this->ctrl->redirectByClass(ilBookingObjectGUI::class, 'render');
diff --git a/components/ILIAS/BookingManager/src/Booking/Table/Action/BookingTableActionsFactory.php b/components/ILIAS/BookingManager/src/Booking/Table/Action/BookingTableActionsFactory.php
index 44502a36de95..c3ba8b9cf3f6 100644
--- a/components/ILIAS/BookingManager/src/Booking/Table/Action/BookingTableActionsFactory.php
+++ b/components/ILIAS/BookingManager/src/Booking/Table/Action/BookingTableActionsFactory.php
@@ -23,6 +23,7 @@
use ilCtrlInterface;
use ilGlobalTemplateInterface;
use ILIAS\BookingManager\Access\AccessManager;
+use ILIAS\BookingManager\Bookings\Table\Action\BookingsTableBookingInformationAction;
use ILIAS\BookingManager\Bookings\Table\Action\BookingsTableCancelAction;
use ILIAS\BookingManager\Bookings\Table\Action\BookingsTableDeleteAction;
use ILIAS\BookingManager\Bookings\Table\Action\BookingsTableMailAction;
@@ -44,6 +45,8 @@ class BookingTableActionsFactory implements TableActionsFactory
public const string ACTION_MAIL = 'mail';
+ public const string ACTION_BOOKING_INFORMATION = 'booking_information';
+
public function __construct(
protected readonly ilCtrlInterface $ctrl,
protected readonly ilLanguage $lng,
@@ -73,6 +76,7 @@ public function getTableActions(): TableActions
self::ACTION_CANCEL => $this->getCancelAction(),
self::ACTION_DELETE => $this->getDeleteAction(),
self::ACTION_MAIL => $this->getMailAction(),
+ self::ACTION_BOOKING_INFORMATION => $this->getBookingInformationAction(),
]
);
}
@@ -124,4 +128,16 @@ protected function getMailAction(): BookingsTableMailAction
$this->bookings
);
}
+
+ protected function getBookingInformationAction(): BookingsTableBookingInformationAction
+ {
+ return new BookingsTableBookingInformationAction(
+ $this->ui_factory,
+ $this->lng,
+ $this->http,
+ $this->tpl,
+ $this->ctrl,
+ $this->bookings
+ );
+ }
}
diff --git a/components/ILIAS/BookingManager/src/Booking/Table/Action/BookingsTableBookingInformationAction.php b/components/ILIAS/BookingManager/src/Booking/Table/Action/BookingsTableBookingInformationAction.php
new file mode 100644
index 000000000000..793cbecddfc0
--- /dev/null
+++ b/components/ILIAS/BookingManager/src/Booking/Table/Action/BookingsTableBookingInformationAction.php
@@ -0,0 +1,130 @@
+ui_factory->table()->action()->standard(
+ $this->lng->txt($this->getActionLabel()),
+ $url_builder
+ ->withParameter($action_token, $this->getActionId())
+ ->withParameter($action_type_token, 'booking_information'),
+ $row_id_token
+ );
+ }
+
+ public function onExecute(
+ URLBuilder $url_builder,
+ URLBuilderToken $row_id_token,
+ URLBuilderToken $action_token,
+ URLBuilderToken $action_type_token
+ ): mixed {
+ $row_parameters = $this->http->resolveRowParameters($row_id_token->getName());
+ if ($row_parameters === HttpService::ALL_OBJECTS) {
+ $selected_ids = null;
+ } elseif (is_string($row_parameters)) {
+ $selected_ids = [$row_parameters];
+ } else {
+ $selected_ids = $row_parameters;
+ }
+
+ $reservation_ids = $this->resolveRecords($selected_ids);
+
+ if ($reservation_ids === []) {
+ $this->tpl->setOnScreenMessage(
+ ilGlobalTemplateInterface::MESSAGE_TYPE_FAILURE,
+ $this->lng->txt('no_valid_selection'),
+ true
+ );
+ return null;
+ }
+
+ $this->ctrl->setParameterByClass(
+ ilBookingReservationsGUI::class,
+ 'rsv_ids',
+ implode(';', $reservation_ids)
+ );
+ $this->ctrl->redirectByClass(ilBookingReservationsGUI::class, 'displayPostInfo');
+ return null;
+ }
+
+ /**
+ * @return int[]
+ */
+ protected function resolveRecords(?array $selected_ids = null): array
+ {
+ return array_map(
+ 'intval',
+ $selected_ids ?? array_keys($this->bookings)
+ );
+ }
+}
diff --git a/lang/ilias_de.lang b/lang/ilias_de.lang
index 6dc03d2d7716..57098c560267 100644
--- a/lang/ilias_de.lang
+++ b/lang/ilias_de.lang
@@ -2656,6 +2656,7 @@ book#:#book_pool_added#:#Ein Buchungspool wurde angelegt.
book#:#book_pool_selection#:#Auswahl Buchungspool
book#:#book_post_booking_file#:#Datei
book#:#book_post_booking_information#:#Informationen zur Buchung
+book#:#book_post_booking_information_for#:#Informationen zur Buchung von "%s"
book#:#book_post_booking_text#:#Text
book#:#book_post_booking_text_info#:#Die Platzhalter können genutzt werden, um Buchungsdetails zum Infotext hinzuzufügen.
Der Platzhalter [OBJECT] wird durch das jeweilige Angebot ersetzt.
Der Platzhalter [PERIOD] wird durch den gewählten Buchungszeitraum ersetzt.
book#:#book_pref_book_cron#:#Buchung mit Präferenzen
diff --git a/lang/ilias_en.lang b/lang/ilias_en.lang
index b7a53e9a03ee..8fae3ba0770e 100644
--- a/lang/ilias_en.lang
+++ b/lang/ilias_en.lang
@@ -2657,6 +2657,7 @@ book#:#book_pool_added#:#Booking pool successfully created.
book#:#book_pool_selection#:#Booking Pool Selection
book#:#book_post_booking_file#:#File
book#:#book_post_booking_information#:#Booking Information
+book#:#book_post_booking_information_for#:#Booking Information for "%s"
book#:#book_post_booking_text#:#Text
book#:#book_post_booking_text_info#:#Use placeholders to include booking-specific information.
[OBJECT] will be replaced by the respective Bookable Item.
[PERIOD] will be replaced by the respective schedule.
book#:#book_pref_book_cron#:#Booking with Preferences