getName();
$payload = $data[$name] ?? null;
if ($def->isRequired() && is_null($payload)) {
$result->addError($name, 'required', 'Reservation payload is required');
return false;
}
if (!is_array($payload) || !array_key_exists('timetable_reservations', $payload)) {
$result->addError($name, 'invalid', 'Reservation payload must be an object with timetable_reservations');
return false;
}
$timetable_id = intval($payload['timetable_id'] ?? null);
$timetable = (new RsvTimetableService())->get($timetable_id);
if (!$timetable) {
$result->addError($name, 'invalid', 'Invalid timetable ID');
return false;
}
$reservation = new RsvReservation(
0,
$submit_id,
false,
array_map(fn($t) => new RsvTimetableReservation(
0,
$timetable_id,
new DateTime($t),
$this->end_from_start(new DateTime($t), $timetable->block_size)
), $payload['timetable_reservations'])
);
try {
$reservation_id = (new RsvReservationService())->create($reservation);
} catch (\Throwable $e) {
// The slot may have been taken since the user selected it.
Logger::error($e);
$result->addError($name, 'creation_failed', 'Could not create the reservation. The slot may no longer be available.');
return false;
}
$result->setValue($name . '_reservation_id', $reservation_id);
$price_per_block = (float) $def->getAttr('price_per_block', 0);
$result->setValue($name . '_price', $price_per_block * count($payload['timetable_reservations']));
return true;
}
/** Delete the reservation created by submit(). */
public function rollback(RsvFormElementDefinition $def, int $submit_id, array $data, RsvFormSubmitResult $result): void {
$reservation_id = $result->getValue($def->getName() . '_reservation_id');
if ($reservation_id) {
(new RsvReservationService())->delete((int) $reservation_id);
}
}
}