fix: apply the booking horizon to admins as well

This commit is contained in:
fromme committed 2026-09-18 10:54:01 +02:00
1 parent 2f5d1d14e4
commit 867bd413c8
4 files changed
+16 -19

No files matched your search

+2 -1
View File
@@ -13,7 +13,8 @@ namespace App\Config;
* nine). It governs single bookings and series alike, which is why it lives here rather than on
* BookingSeries.
*
* ROLE_ADMIN is exempt -- see BookingRequest::$unlimitedHorizon.
* It binds everybody: the booking modal always books for the person using it, so there is no
* on-behalf case an administrator would need it lifted for.
*/
final class BookingHorizon
{
+1 -5
View File
@@ -19,7 +19,6 @@ use App\Model\SeriesResult;
use App\Model\Spot;
use App\Repository\BookingRepository;
use App\Routing\DateParam;
use App\Security\Role;
use App\Service\BoardContextFactory;
use App\Service\BookingManager;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
@@ -73,13 +72,10 @@ final class CreateController extends AbstractController
$this->currentUser(),
);
$data = new BookingRequest($selected, $spot->suggested() ?? $boardTime);
// An admin books on behalf of people and cleans up after the fact, so the three-month
// horizon that keeps desks from being blocked half a year ahead does not bind them.
$data->unlimitedHorizon = $this->isGranted(Role::ADMIN);
$form = $this->createForm(BookingType::class, $data, [
'action' => $this->generateUrl('app_booking_new', ['id' => $resource->getId(), 'date' => $date] + $this->timeParameters($boardTime)),
'horizon' => $data->unlimitedHorizon ? null : BookingHorizon::latest(),
'horizon' => BookingHorizon::latest(),
]);
$form->handleRequest($request);
+4 -11
View File
@@ -20,13 +20,6 @@ final class BookingRequest
#[Assert\GreaterThanOrEqual('today', message: 'Für vergangene Tage kann nicht gebucht werden.')]
public ?\DateTimeImmutable $date = null;
/**
* Lifts the BookingHorizon cap for this request. Set by the controller for ROLE_ADMIN -- a DTO
* cannot reach the security container, and giving it one would make these rules untestable
* in isolation.
*/
public bool $unlimitedHorizon = false;
public bool $allDay = true;
public ?\DateTimeImmutable $startTime = null;
@@ -110,7 +103,7 @@ final class BookingRequest
return;
}
if (!$this->unlimitedHorizon && $this->until > BookingHorizon::latest()) {
if ($this->until > BookingHorizon::latest()) {
$context->buildViolation(\sprintf('Eine Wiederholung darf höchstens %d Monate in die Zukunft laufen.', BookingHorizon::MONTHS))
->atPath('until')
->addViolation();
@@ -119,12 +112,12 @@ final class BookingRequest
/**
* The booking horizon, measured from today rather than from the chosen day -- see BookingHorizon.
* Not an attribute constraint because it has to be liftable per role, which an attribute
* cannot express.
* Not an attribute constraint because the cap moves with today, which an attribute cannot
* express.
*/
private function validateHorizon(ExecutionContextInterface $context): void
{
if ($this->unlimitedHorizon || null === $this->date) {
if (null === $this->date) {
return;
}