diff --git a/Classes/Controller/DateController.php b/Classes/Controller/DateController.php
index d92ad06..5b8e137 100644
--- a/Classes/Controller/DateController.php
+++ b/Classes/Controller/DateController.php
@@ -6,6 +6,7 @@ use TYPO3\CMS\Core\EventDispatcher\EventDispatcher;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Annotation as Extbase;
use TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface;
+use TYPO3\CMS\Extbase\Service\ExtensionService;
use Wrm\Events\Domain\Model\Date;
use Wrm\Events\Domain\Model\Dto\DateDemand;
use Wrm\Events\Domain\Model\Dto\DateDemandFactory;
@@ -42,11 +43,6 @@ class DateController extends AbstractController
*/
protected $categoryRepository;
- /**
- * @var EventDispatcher
- */
- protected $eventDispatcher;
-
/**
* @var Factory
*/
@@ -57,22 +53,34 @@ class DateController extends AbstractController
*/
protected $dataProcessing;
+ /**
+ * @var EventDispatcher
+ */
+ protected $eventDispatcher;
+
+ /**
+ * @var ExtensionService
+ */
+ protected $extensionService;
+
public function __construct(
DateDemandFactory $demandFactory,
- RegionRepository $regionRepository,
DateRepository $dateRepository,
+ RegionRepository $regionRepository,
CategoryRepository $categoryRepository,
+ Factory $paginationFactory,
DataProcessingForModels $dataProcessing,
EventDispatcher $eventDispatcher,
- Factory $paginationFactory
+ ExtensionService $extensionService
) {
$this->demandFactory = $demandFactory;
- $this->regionRepository = $regionRepository;
$this->dateRepository = $dateRepository;
+ $this->regionRepository = $regionRepository;
$this->categoryRepository = $categoryRepository;
+ $this->paginationFactory = $paginationFactory;
$this->dataProcessing = $dataProcessing;
$this->eventDispatcher = $eventDispatcher;
- $this->paginationFactory = $paginationFactory;
+ $this->extensionService = $extensionService;
}
protected function initializeAction(): void
@@ -82,6 +90,8 @@ class DateController extends AbstractController
$this->demandFactory->setContentObjectRenderer($contentObject);
}
$this->dataProcessing->setConfigurationManager($this->configurationManager);
+
+ $this->handlePostRequest();
}
/**
@@ -95,14 +105,6 @@ class DateController extends AbstractController
$demand = $this->demandFactory->fromSettings($this->settings);
if ($search !== []) {
$demand = DateDemand::createFromRequestValues($search, $this->settings);
- } elseif (
- ($this->request->hasArgument('searchword') && $this->request->getArgument('searchword') != '')
- || ($this->request->hasArgument('region') && $this->request->getArgument('region') != '')
- || ($this->request->hasArgument('start') && $this->request->getArgument('start') != '')
- || ($this->request->hasArgument('end') && $this->request->getArgument('end') != '')
- || ($this->request->hasArgument('events_search') && $this->request->getArgument('events_search') != [])
- ) {
- $demand = $this->createDemandFromSearch();
}
$dates = $this->dateRepository->findByDemand($demand);
@@ -128,24 +130,6 @@ class DateController extends AbstractController
*/
public function searchAction(array $search = []): void
{
- $arguments = GeneralUtility::_GET('tx_events_datelist') ?? $search;
- if (is_array($arguments) === false) {
- $arguments = [];
- }
- if (isset($arguments['events_search']) && is_array($arguments['events_search'])) {
- $arguments += $arguments['events_search'];
- unset($arguments['events_search']);
- }
-
- // For legacy systems.
- $this->view->assignMultiple([
- 'searchword' => $arguments['searchword'] ?? '',
- 'selRegion' => $arguments['region'] ?? '',
- 'start' => $arguments['start'] ?? '',
- 'end' => $arguments['end'] ?? '',
- 'considerDate' => $arguments['considerDate'] ?? '',
- ]);
-
$demand = $this->demandFactory->fromSettings($this->settings);
if ($search !== []) {
$demand = DateDemand::createFromRequestValues($search, $this->settings);
@@ -178,17 +162,27 @@ class DateController extends AbstractController
$this->view->assign('date', $date);
}
- protected function createDemandFromSearch(): DateDemand
+ /**
+ * Convert POST to proper GET.
+ *
+ * @see: https://en.wikipedia.org/wiki/Post/Redirect/Get
+ */
+ private function handlePostRequest(): void
{
- $arguments = $this->request->getArguments();
- if (isset($arguments['events_search'])) {
- $arguments += $arguments['events_search'];
- unset($arguments['events_search']);
+ if (
+ $this->request->getMethod() === 'POST'
+ && $this->request->hasArgument('search')
+ && is_array($this->request->getArgument('search'))
+ ) {
+ $namespace = $this->extensionService->getPluginNamespace(null, null);
+ $this->redirectToUri($this->configurationManager->getContentObject()->typoLink_URL([
+ 'parameter' => 't3://page?uid=current',
+ 'additionalParams' => '&' . http_build_query([
+ $namespace => [
+ 'search' => array_filter($this->request->getArgument('search'))
+ ],
+ ]),
+ ]));
}
-
- return DateDemand::createFromRequestValues(
- $arguments,
- $this->settings
- );
}
}
diff --git a/Classes/Domain/Model/Dto/DateDemand.php b/Classes/Domain/Model/Dto/DateDemand.php
index fee8d34..bc81290 100644
--- a/Classes/Domain/Model/Dto/DateDemand.php
+++ b/Classes/Domain/Model/Dto/DateDemand.php
@@ -331,13 +331,18 @@ class DateDemand
return $this->startObject;
}
- public function getStart(): ?int
+ /**
+ * Returns necessary format for forms.
+ *
+ * @internal Only for Extbase/Fluid.
+ */
+ public function getStart(): string
{
if ($this->getStartObject() === null) {
- return null;
+ return '';
}
- return (int) $this->getStartObject()->format('U');
+ return $this->getStartObject()->format('Y-m-d');
}
public function setStart(?int $start): void
@@ -362,13 +367,18 @@ class DateDemand
return $this->getStartObject()->format('Y-m-d') === $this->getEndObject()->format('Y-m-d');
}
- public function getEnd(): ?int
+ /**
+ * Returns necessary format for forms.
+ *
+ * @internal Only for Extbase/Fluid.
+ */
+ public function getEnd(): string
{
if ($this->getEndObject() === null) {
- return null;
+ return '';
}
- return (int) $this->getEndObject()->format('U');
+ return $this->getEndObject()->format('Y-m-d');
}
public function setEnd(?int $end): void
@@ -387,15 +397,15 @@ class DateDemand
public function shouldShowFromNow(): bool
{
- return $this->getStart() === null
- && $this->getEnd() === null
+ return $this->getStartObject() === null
+ && $this->getEndObject() === null
&& $this->useMidnight === false;
}
public function shouldShowFromMidnight(): bool
{
- return $this->getStart() === null
- && $this->getEnd() === null
+ return $this->getStartObject() === null
+ && $this->getEndObject() === null
&& $this->useMidnight === true;
}
diff --git a/Classes/Domain/Repository/DateRepository.php b/Classes/Domain/Repository/DateRepository.php
index 99b30da..e8a3ee4 100644
--- a/Classes/Domain/Repository/DateRepository.php
+++ b/Classes/Domain/Repository/DateRepository.php
@@ -77,20 +77,20 @@ class DateRepository extends Repository
$constraints['userCategories'] = $query->in('event.categories.uid', $demand->getUserCategories());
}
- if ($demand->getStart() !== null) {
- $constraints['starts'] = $query->greaterThanOrEqual('start', $demand->getStart());
+ if ($demand->getStartObject() !== null) {
+ $constraints['starts'] = $query->greaterThanOrEqual('start', $demand->getStartObject());
}
- if ($demand->getEnd() != null) {
+ if ($demand->getEndObject() != null) {
// Dates might have end of 0 if only start exists.
// This is respected to take start as end date.
$constraints['ends'] = $query->logicalOr([
$query->logicalAnd([
- $query->lessThanOrEqual('end', $demand->getEnd()),
+ $query->lessThanOrEqual('end', $demand->getEndObject()),
$query->greaterThan('end', 0)
]),
$query->logicalAnd([
$query->equals('end', 0),
- $query->lessThanOrEqual('start', $demand->getEnd())
+ $query->lessThanOrEqual('start', $demand->getEndObject())
]),
]);
}
diff --git a/Configuration/TypoScript/setup.typoscript b/Configuration/TypoScript/setup.typoscript
index 71c4f8c..f679496 100644
--- a/Configuration/TypoScript/setup.typoscript
+++ b/Configuration/TypoScript/setup.typoscript
@@ -23,14 +23,10 @@ plugin.tx_events {
recursive = 1
}
features {
- #skipDefaultArguments = 1
- # if set to 1, the enable fields are ignored in BE context
- ignoreAllEnableFieldsInBe = 0
- # Should be on by default, but can be disabled if all action in the plugin are uncached
- requireCHashArgumentForActionArguments = 0
+ skipDefaultArguments = 1
}
mvc {
- #callDefaultActionIfActionCantBeResolved = 1
+ callDefaultActionIfActionCantBeResolved = 1
}
settings {
@@ -74,4 +70,7 @@ plugin.tx_events {
}
}
+plugin.tx_events_datelist.view.pluginNamespace = events_search
+plugin.tx_events_datesearch.view.pluginNamespace = events_search
+
module.tx_events < plugin.tx_events
diff --git a/Documentation/Changelog/3.0.0.rst b/Documentation/Changelog/3.0.0.rst
new file mode 100644
index 0000000..3f6fdde
--- /dev/null
+++ b/Documentation/Changelog/3.0.0.rst
@@ -0,0 +1,64 @@
+3.0.0
+=====
+
+Breaking
+--------
+
+Namespace changes
+^^^^^^^^^^^^^^^^^
+
+A new namespace was defined for plugins which is "events_search".
+The search parameters are now collected below namespace "search" instead of
+"events_search" leading to ``events_search[search][parametername]=value`` instead of
+``tx_events_signature[events_search][parametername]=value``.
+
+The form now is submitted as post and redirects to a proper URL with GET.
+
+The code was bloated and made it hard to fix bugs.
+
+Necessary steps:
+
+- Check usage of old namespace within templates and other sources.
+
+- Check usage of old nesting of parameters.
+
+API Changes
+^^^^^^^^^^^
+
+The methods of ``DateDemand`` have changed, ``getStart()`` and ``getEnd()`` return a
+string value necessary or Fluid forms.
+Those are not considered public API. Use ``getStartObject()`` and ``getEndObject()``
+instead.
+
+Features
+--------
+
+Nothing
+
+Fixes
+-----
+
+* Keep filter during pagination
+
+ Search requests are POST by default.
+ We apply PRG (=Post Redirect Get) on them to create proper GET requests.
+ Those can be used to generate the URLs for pagination.
+
+ We follow Extbase, and do not explicitly ask for arguments from foreign namespaces.
+ Instead we configure a pluginNamespace that's shared between plugins.
+ This is all necessary as we still ship pre defined plugins.
+ This should belong into integration of each project.
+
+ See: https://en.wikipedia.org/wiki/Post/Redirect/Get
+
+ Relates: #10175
+
+Tasks
+-----
+
+Nothing
+
+Deprecation
+-----------
+
+Nothing
diff --git a/Resources/Private/Language/de.locallang.xlf b/Resources/Private/Language/de.locallang.xlf
index dd71334..d0f4150 100644
--- a/Resources/Private/Language/de.locallang.xlf
+++ b/Resources/Private/Language/de.locallang.xlf
@@ -17,7 +17,7 @@
- Date bis
+ Datum bis
diff --git a/Resources/Private/Partials/Pagination.html b/Resources/Private/Partials/Pagination.html
index 657450b..e0060f9 100644
--- a/Resources/Private/Partials/Pagination.html
+++ b/Resources/Private/Partials/Pagination.html
@@ -8,13 +8,13 @@
«
-
+
«
@@ -25,7 +25,7 @@
1
@@ -54,7 +54,7 @@
{page}
@@ -62,7 +62,7 @@
1
@@ -83,7 +83,7 @@
{pagination.lastPageNumber}
@@ -94,7 +94,7 @@
»
diff --git a/Resources/Private/Templates/Date/Search.html b/Resources/Private/Templates/Date/Search.html
index 96f482d..c3945fd 100644
--- a/Resources/Private/Templates/Date/Search.html
+++ b/Resources/Private/Templates/Date/Search.html
@@ -3,14 +3,14 @@
-
+
@@ -44,7 +34,7 @@
@@ -52,7 +42,7 @@
diff --git a/Tests/Unit/Domain/Model/Dto/DateDemandTest.php b/Tests/Unit/Domain/Model/Dto/DateDemandTest.php
index a4aefd5..8682488 100644
--- a/Tests/Unit/Domain/Model/Dto/DateDemandTest.php
+++ b/Tests/Unit/Domain/Model/Dto/DateDemandTest.php
@@ -201,7 +201,7 @@ class DateDemandTest extends TestCase
$result->getStartObject()->format('Y-m-d')
);
self::assertSame(
- 1657576800,
+ '2022-07-12',
$result->getStart()
);
}
@@ -228,7 +228,7 @@ class DateDemandTest extends TestCase
$result->getEndObject()->format('Y-m-d')
);
self::assertSame(
- 1657663140,
+ '2022-07-12',
$result->getEnd()
);
}
diff --git a/ext_emconf.php b/ext_emconf.php
index f32f6a4..c18a1dd 100644
--- a/ext_emconf.php
+++ b/ext_emconf.php
@@ -9,7 +9,7 @@ $EM_CONF['events'] = [
'state' => 'alpha',
'createDirs' => '',
'clearCacheOnLoad' => 0,
- 'version' => '2.6.3',
+ 'version' => '3.0.0',
'constraints' => [
'depends' => [
'typo3' => '10.4.00-11.5.99',
diff --git a/ext_localconf.php b/ext_localconf.php
index bd81f08..3c53350 100644
--- a/ext_localconf.php
+++ b/ext_localconf.php
@@ -37,6 +37,8 @@ call_user_func(function () {
$GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations']['events_category'] = [];
}
+ $GLOBALS['TYPO3_CONF_VARS']['FE']['cacheHash']['excludedParameters'][] = '^events_search';
+
$iconRegistry = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Core\Imaging\IconRegistry::class);
$iconRegistry->registerIcon(
'events-plugin',
diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon
index 30bf9ac..1df3fc1 100644
--- a/phpstan-baseline.neon
+++ b/phpstan-baseline.neon
@@ -1,5 +1,9 @@
parameters:
ignoreErrors:
+ -
+ message: "#^Cannot call method typoLink_URL\\(\\) on TYPO3\\\\CMS\\\\Frontend\\\\ContentObject\\\\ContentObjectRenderer\\|null\\.$#"
+ count: 1
+ path: Classes/Controller/DateController.php
-
message: "#^Parameter \\#1 \\$categories of method Wrm\\\\Events\\\\Domain\\\\Model\\\\Event\\:\\:setCategories\\(\\) expects TYPO3\\\\CMS\\\\Extbase\\\\Persistence\\\\ObjectStorage\\, TYPO3\\\\CMS\\\\Extbase\\\\Persistence\\\\ObjectStorage\\ given\\.$#"
count: 1