From 9743948cb5385a61d53e16945efecd7ee8ef7e1d Mon Sep 17 00:00:00 2001
From: Daniel Siepmann <daniel.siepmann@codappix.com>
Date: Wed, 27 Nov 2024 08:41:44 +0100
Subject: [PATCH] Trigger 404 for date show action without date

---
 Classes/Controller/AbstractController.php          |  5 +++++
 Classes/Controller/DateController.php              |  6 +++++-
 Documentation/Changelog/5.0.0.rst                  |  5 +++++
 Tests/Functional/Frontend/DatesTest.php            | 13 +++++++++++++
 .../Returns404IfNoDateIsGiven.php                  | 14 ++++++++++++++
 5 files changed, 42 insertions(+), 1 deletion(-)
 create mode 100644 Tests/Functional/Frontend/DatesTestFixtures/Returns404IfNoDateIsGiven.php

diff --git a/Classes/Controller/AbstractController.php b/Classes/Controller/AbstractController.php
index cfe7ac9..e0f9403 100644
--- a/Classes/Controller/AbstractController.php
+++ b/Classes/Controller/AbstractController.php
@@ -70,6 +70,11 @@ abstract class AbstractController extends ActionController
         }
     }
 
+    /**
+     * Will throw exception to trigger 404.
+     *
+     * @return never
+     */
     protected function trigger404(string $message): void
     {
         throw new PropagateResponseException(
diff --git a/Classes/Controller/DateController.php b/Classes/Controller/DateController.php
index 37c6fce..7b6deda 100644
--- a/Classes/Controller/DateController.php
+++ b/Classes/Controller/DateController.php
@@ -105,8 +105,12 @@ final class DateController extends AbstractController
     }
 
     #[Extbase\IgnoreValidation(['value' => 'date'])]
-    public function showAction(Date $date): ResponseInterface
+    public function showAction(?Date $date = null): ResponseInterface
     {
+        if ($date === null) {
+            $this->trigger404('No date given.');
+        }
+
         try {
             $date->getEvent();
         } catch (Throwable) {
diff --git a/Documentation/Changelog/5.0.0.rst b/Documentation/Changelog/5.0.0.rst
index 1ba126b..e59a331 100644
--- a/Documentation/Changelog/5.0.0.rst
+++ b/Documentation/Changelog/5.0.0.rst
@@ -33,6 +33,11 @@ Features
   The field no longer has a limitation.
   The field is now stored as `text` instead of `varchar`.
 
+* Deliver 404 on date show action without a given date.
+
+  This previously triggered an TYPO3 Exception.
+  We now handle the situation and trigger a TYPO3 404.
+
 Fixes
 -----
 
diff --git a/Tests/Functional/Frontend/DatesTest.php b/Tests/Functional/Frontend/DatesTest.php
index ccaedee..4f43410 100644
--- a/Tests/Functional/Frontend/DatesTest.php
+++ b/Tests/Functional/Frontend/DatesTest.php
@@ -137,6 +137,19 @@ final class DatesTest extends AbstractFrontendTestCase
         self::assertStringContainsString('Event 9', $html);
     }
 
+    #[Test]
+    public function returns404IfNoDateIsGiven(): void
+    {
+        $this->importPHPDataSet(__DIR__ . '/DatesTestFixtures/Returns404IfNoDateIsGiven.php');
+
+        $request = new InternalRequest('https://example.com/');
+        $request = $request->withPageId(1);
+
+        $response = $this->executeFrontendSubRequest($request);
+
+        self::assertSame(404, $response->getStatusCode());
+    }
+
     #[Test]
     public function returns404IfEventIsHidden(): void
     {
diff --git a/Tests/Functional/Frontend/DatesTestFixtures/Returns404IfNoDateIsGiven.php b/Tests/Functional/Frontend/DatesTestFixtures/Returns404IfNoDateIsGiven.php
new file mode 100644
index 0000000..b066de5
--- /dev/null
+++ b/Tests/Functional/Frontend/DatesTestFixtures/Returns404IfNoDateIsGiven.php
@@ -0,0 +1,14 @@
+<?php
+
+declare(strict_types=1);
+
+return  [
+    'tt_content' => [
+        0 => [
+            'uid' => '1',
+            'pid' => '1',
+            'CType' => 'events_dateshowtest',
+            'header' => 'Singleview',
+        ],
+    ],
+];