diff --git a/src/Controller/SurfSession/NewSurfSessionController.php b/src/Controller/SurfSession/NewSurfSessionController.php
index 1c5ca4b..e6caf8e 100644
--- a/src/Controller/SurfSession/NewSurfSessionController.php
+++ b/src/Controller/SurfSession/NewSurfSessionController.php
@@ -8,14 +8,17 @@
use App\Entity\SurfSession;
use App\Entity\User;
use App\Enum\User\UserRole;
-use App\Form\Model\SurfSession\SurfSessionWriteModel;
use App\Form\SurfSession\SurfSessionFormType;
use App\Repository\SurfSessionRepository;
+use App\Security\Voter\TripVoter;
+use App\Service\SurfSession\SurfSessionWriteModelFactory;
+use App\Service\Trip\TripReadModelProvider;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\ObjectMapper\ObjectMapperInterface;
use Symfony\Component\Routing\Attribute\Route;
+use Symfony\Component\Routing\Requirement\Requirement;
use Symfony\Component\Security\Http\Attribute\CurrentUser;
use Symfony\Component\Security\Http\Attribute\IsGranted;
@@ -25,6 +28,8 @@ public function __construct(
private readonly ObjectMapperInterface $objectMapper,
private readonly SurfSessionRepository $surfSessionRepository,
private readonly SurfSessionCacheInvalidator $surfSessionCacheInvalidator,
+ private readonly TripReadModelProvider $tripReadModelProvider,
+ private readonly SurfSessionWriteModelFactory $surfSessionWriteModelFactory,
) {}
#[Route(
@@ -32,10 +37,24 @@ public function __construct(
name: 'app.surf_session.new',
methods: [Request::METHOD_GET, Request::METHOD_POST],
)]
+ #[Route(
+ path: '/trip/{tripId}/sessions/new',
+ name: 'app.trip.surf_session.new',
+ requirements: ['tripId' => Requirement::POSITIVE_INT],
+ methods: [Request::METHOD_GET, Request::METHOD_POST],
+ )]
#[IsGranted(UserRole::USER)]
- public function __invoke(Request $request, #[CurrentUser()] User $currentUser): Response
+ public function __invoke(Request $request, #[CurrentUser()] User $currentUser, ?int $tripId = null): Response
{
- $surfSessionWriteModel = new SurfSessionWriteModel();
+ $trip = null;
+
+ if (null !== $tripId) {
+ $trip = $this->tripReadModelProvider->getById($tripId);
+
+ $this->denyAccessUnlessGranted(TripVoter::EDIT, $trip);
+ }
+
+ $surfSessionWriteModel = $this->surfSessionWriteModelFactory->create($trip);
$form = $this->createForm(SurfSessionFormType::class, $surfSessionWriteModel);
$form->handleRequest($request);
diff --git a/src/Controller/Trip/EditTripController.php b/src/Controller/Trip/EditTripController.php
index 64a56e6..56c39c5 100644
--- a/src/Controller/Trip/EditTripController.php
+++ b/src/Controller/Trip/EditTripController.php
@@ -4,7 +4,6 @@
namespace App\Controller\Trip;
-use App\Exception\TripNotFoundHttpException;
use App\Form\Model\Trip\TripWriteModel;
use App\Form\Trip\TripFormType;
use App\Security\Voter\TripVoter;
@@ -40,10 +39,6 @@ public function __invoke(Request $request, int $id, string $slug): Response
{
$trip = $this->tripReadModelProvider->getById($id);
- if (null === $trip) {
- throw new TripNotFoundHttpException($id);
- }
-
$this->denyAccessUnlessGranted(TripVoter::EDIT, $trip);
if ($trip->slug->value !== $slug) {
diff --git a/src/Controller/Trip/ShowTripController.php b/src/Controller/Trip/ShowTripController.php
index 47f0c39..6c76981 100644
--- a/src/Controller/Trip/ShowTripController.php
+++ b/src/Controller/Trip/ShowTripController.php
@@ -4,7 +4,6 @@
namespace App\Controller\Trip;
-use App\Exception\TripNotFoundHttpException;
use App\Service\Trip\TripReadModelProvider;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
@@ -33,10 +32,6 @@ public function __invoke(int $id, string $slug): Response
{
$trip = $this->tripReadModelProvider->getById($id);
- if (null === $trip) {
- throw new TripNotFoundHttpException($id);
- }
-
if ($trip->slug->value !== $slug) {
return $this->redirectToRoute(self::ROUTE, [
'id' => $trip->id,
diff --git a/src/Service/SurfSession/SurfSessionWriteModelFactory.php b/src/Service/SurfSession/SurfSessionWriteModelFactory.php
new file mode 100644
index 0000000..33ee169
--- /dev/null
+++ b/src/Service/SurfSession/SurfSessionWriteModelFactory.php
@@ -0,0 +1,50 @@
+resolveStartAt($trip);
+ $tripSelect = null;
+
+ if (null !== $trip) {
+ $tripSelect = new TripSelectReadModel(
+ id: $trip->id,
+ title: $trip->title->value,
+ location: $trip->location->value,
+ );
+ }
+
+ $surfSessionWriteModel->trip = $tripSelect;
+ $surfSessionWriteModel->spot = $tripSelect?->location;
+ $surfSessionWriteModel->startAt = $startAt;
+ $surfSessionWriteModel->endAt = $startAt->modify(sprintf('+%d hours', self::DEFAULT_SESSION_DURATION_HOURS));
+
+ return $surfSessionWriteModel;
+ }
+
+ private function resolveStartAt(?AbstractTripReadModel $trip = null): \DateTimeImmutable
+ {
+ $now = new \DateTimeImmutable();
+
+ $startAt = match (true) {
+ null === $trip => $now,
+ $now < $trip->startAt => $trip->startAt,
+ $now > $trip->endAt => $trip->endAt,
+ default => $now,
+ };
+
+ return $startAt->setTime(10, 0);
+ }
+}
diff --git a/src/Service/Trip/TripReadModelProvider.php b/src/Service/Trip/TripReadModelProvider.php
index d4381c3..628c0f4 100644
--- a/src/Service/Trip/TripReadModelProvider.php
+++ b/src/Service/Trip/TripReadModelProvider.php
@@ -5,6 +5,7 @@
namespace App\Service\Trip;
use App\Cache\Trip\TripCacheKeys;
+use App\Exception\TripNotFoundHttpException;
use App\ReadModel\Trip\TripShowReadModel;
use App\Repository\TripRepository;
use Symfony\Contracts\Cache\ItemInterface;
@@ -19,9 +20,9 @@ public function __construct(
private TagAwareCacheInterface $cache,
) {}
- public function getById(int $id): ?TripShowReadModel
+ public function getById(int $id): TripShowReadModel
{
- return $this->cache->get(
+ $trip = $this->cache->get(
TripCacheKeys::readModel($id),
function (ItemInterface $item) use ($id): ?TripShowReadModel {
$item->expiresAfter(new \DateInterval(self::CACHE_TTL));
@@ -29,5 +30,13 @@ function (ItemInterface $item) use ($id): ?TripShowReadModel {
return $this->tripRepository->findShowReadModelById($id);
},
);
+
+ if (null === $trip) {
+ $this->cache->delete(TripCacheKeys::readModel($id));
+
+ throw new TripNotFoundHttpException($id);
+ }
+
+ return $trip;
}
}
diff --git a/templates/trip/edit.html.twig b/templates/trip/edit.html.twig
index 0f2e658..16f807f 100644
--- a/templates/trip/edit.html.twig
+++ b/templates/trip/edit.html.twig
@@ -3,7 +3,16 @@
{% set title = 'trip.edit.label'|trans %}
{% block body %}
-