diff --git a/Classes/EventListener/NewsListActionEventListener.php b/Classes/EventListener/NewsListActionEventListener.php
index 808c25a..cd53f4b 100644
--- a/Classes/EventListener/NewsListActionEventListener.php
+++ b/Classes/EventListener/NewsListActionEventListener.php
@@ -4,18 +4,24 @@
namespace GeorgRinger\NewsFilter\EventListener;
-use GeorgRinger\News\Domain\Model\Dto\NewsDemand;
+use Doctrine\DBAL\DBALException;
use GeorgRinger\News\Domain\Repository\CategoryRepository;
use GeorgRinger\News\Domain\Repository\TagRepository;
use GeorgRinger\News\Event\NewsListActionEvent;
use GeorgRinger\News\Utility\Page;
use GeorgRinger\NewsFilter\Domain\Model\Dto\Search;
use TYPO3\CMS\Core\Context\Context;
+use TYPO3\CMS\Core\Context\Exception\AspectNotFoundException;
use TYPO3\CMS\Core\Database\Connection;
use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\Utility\GeneralUtility;
+use TYPO3\CMS\Extbase\Property\Exception;
use TYPO3\CMS\Extbase\Property\PropertyMapper;
+use TYPO3\CMS\Extbase\Service\CacheService;
+/**
+ * NewsListActionEventListener
+ */
class NewsListActionEventListener
{
/** @var CategoryRepository */
@@ -27,26 +33,51 @@ class NewsListActionEventListener
/** @var PropertyMapper */
protected $propertyMapper;
+ /** @var CacheService */
+ protected $cacheService;
+
public function __construct(
CategoryRepository $categoryRepository,
TagRepository $tagRepository,
- PropertyMapper $propertyMapper
+ PropertyMapper $propertyMapper,
+ CacheService $cacheService
) {
$this->categoryRepository = $categoryRepository;
$this->tagRepository = $tagRepository;
$this->propertyMapper = $propertyMapper;
+ $this->cacheService = $cacheService;
}
- public function __invoke(NewsListActionEvent $event)
+ /**
+ * @throws Exception
+ * @throws AspectNotFoundException
+ */
+ public function __invoke(NewsListActionEvent $event): void
{
$data = $event->getAssignedValues();
$settings = $data['settings'];
if ($settings['enableFilter'] ?? false) {
- $search = GeneralUtility::makeInstance(Search::class);
+ $search = $settings['keepFilterOnReload'] ?
+ $this->getSearchFromSession($event) :
+ GeneralUtility::makeInstance(Search::class);
+
+ // set a new search if a new search was submitted
$vars = GeneralUtility::_POST('tx_news_pi1');
- if (isset($vars['search']) && is_array($vars['search'])) {
+ $hasPostData = isset($vars['search']) && is_array($vars['search']);
+ if ($hasPostData) {
+
+ if ($settings['keepFilterOnReload']) {
+ $this->saveSearchInSession($event, $vars['search']);
+
+ // clear teh cache for the current page when a
+ // new filter is saved to the session in order
+ // to get the new filter after reloading the page
+ $currentPage = $GLOBALS['TSFE']->id;
+ $this->cacheService->clearPageCache([$currentPage]);
+ }
+
/** @var Search $search */
$search = $this->propertyMapper->convert($vars['search'], Search::class);
}
@@ -72,6 +103,13 @@ public function __invoke(NewsListActionEvent $event)
$event->setAssignedValues($data);
}
+ /**
+ * @param string $tableName
+ * @param string $pidList
+ * @return array
+ * @throws \Doctrine\DBAL\Driver\Exception
+ * @throws DBALException
+ */
protected function getAllRecordsByPid(string $tableName, string $pidList): array
{
$list = [];
@@ -86,8 +124,8 @@ protected function getAllRecordsByPid(string $tableName, string $pidList): array
$queryBuilder->createNamedParameter(explode(',', $pidList), Connection::PARAM_INT_ARRAY)
)
)
- ->execute()
- ->fetchAll();
+ ->executeQuery()
+ ->fetchAllAssociative();
foreach ($rows as $row) {
$list[] = $row['uid'];
@@ -96,61 +134,39 @@ protected function getAllRecordsByPid(string $tableName, string $pidList): array
}
/**
- * Create the demand object which define which records will get shown
+ * Load filter from session or create a new empty search
*
- * @param array $settings
- * @param string $class optional class which must be an instance of \GeorgRinger\News\Domain\Model\Dto\NewsDemand
- * @return NewsDemand
+ * @param NewsListActionEvent $event
+ * @return Search
+ * @throws Exception
*/
- protected function createDemandObjectFromSettings(
- $settings,
- $class = 'GeorgRinger\\News\\Domain\\Model\\Dto\\NewsDemand'
- ) {
- $class = isset($settings['demandClass']) && !empty($settings['demandClass']) ? $settings['demandClass'] : $class;
-
- /* @var $demand \GeorgRinger\News\Domain\Model\Dto\NewsDemand */
- $demand = GeneralUtility::makeInstance($class, $settings);
- if (!$demand instanceof NewsDemand) {
- throw new \UnexpectedValueException(
- sprintf(
- 'The demand object must be an instance of \GeorgRinger\\News\\Domain\\Model\\Dto\\NewsDemand, but %s given!',
- $class
- ),
- 1423157953
- );
- }
-
- $demand->setCategories(GeneralUtility::trimExplode(',', $settings['categories'], true));
- $demand->setCategoryConjunction($settings['categoryConjunction']);
- $demand->setIncludeSubCategories((bool)$settings['includeSubCategories']);
- $demand->setTags($settings['tags']);
-
- $demand->setTopNewsRestriction((int)$settings['topNewsRestriction']);
- $demand->setTimeRestriction($settings['timeRestriction']);
- $demand->setTimeRestrictionHigh($settings['timeRestrictionHigh']);
- $demand->setArchiveRestriction($settings['archiveRestriction']);
- $demand->setExcludeAlreadyDisplayedNews((bool)$settings['excludeAlreadyDisplayedNews']);
- $demand->setHideIdList((string)($settings['hideIdList'] ?? ''));
-
- if ($settings['orderBy']) {
- $demand->setOrder($settings['orderBy'] . ' ' . $settings['orderDirection']);
+ protected function getSearchFromSession(NewsListActionEvent $event): Search
+ {
+ $request = $event->getRequest();
+ $frontendUser = $request->getAttribute('frontend.user');
+ $sessionFilter = $frontendUser->getKey('ses', 'tx_news_filter');
+ if ($sessionFilter) {
+ $sessionFilter = unserialize($sessionFilter);
+ $search = $this->propertyMapper->convert($sessionFilter, Search::class);
+ } else {
+ $search = GeneralUtility::makeInstance(Search::class);
}
- $demand->setOrderByAllowed($settings['orderByAllowed']);
-
- $demand->setTopNewsFirst((bool)$settings['topNewsFirst']);
- $demand->setLimit((int)$settings['limit']);
- $demand->setOffset((int)$settings['offset']);
-
- $demand->setSearchFields($settings['search']['fields']);
- $demand->setDateField($settings['dateField']);
- $demand->setMonth((int)$settings['month']);
- $demand->setYear((int)$settings['year']);
+ return $search;
+ }
- $demand->setStoragePage(Page::extendPidListByChildren(
- $settings['startingpoint'],
- $settings['recursive']
- ));
- return $demand;
+ /**
+ * serialize and save search in session
+ *
+ * @param NewsListActionEvent $event
+ * @param array $search
+ * @return void
+ */
+ protected function saveSearchInSession(NewsListActionEvent $event, array $search): void
+ {
+ $request = $event->getRequest();
+ $frontendUser = $request->getAttribute('frontend.user');
+ $sessionData = serialize($search);
+ $frontendUser->setKey('ses', 'tx_news_filter', $sessionData);
}
}
diff --git a/Classes/Hooks/EnrichDemandObject.php b/Classes/Hooks/EnrichDemandObject.php
index 874b32f..85fe12a 100644
--- a/Classes/Hooks/EnrichDemandObject.php
+++ b/Classes/Hooks/EnrichDemandObject.php
@@ -4,21 +4,34 @@
namespace GeorgRinger\NewsFilter\Hooks;
+use GeorgRinger\News\Event\NewsListActionEvent;
use GeorgRinger\NewsFilter\Domain\Model\Dto\Demand;
use GeorgRinger\NewsFilter\Domain\Model\Dto\Search;
use TYPO3\CMS\Core\Utility\GeneralUtility;
+use TYPO3\CMS\Extbase\Property\Exception;
use TYPO3\CMS\Extbase\Property\PropertyMapper;
+/**
+ * EnrichDemandObject
+ */
class EnrichDemandObject
{
/** @var PropertyMapper */
protected $propertyMapper;
+ /**
+ * @param PropertyMapper $propertyMapper
+ */
public function __construct(PropertyMapper $propertyMapper)
{
$this->propertyMapper = $propertyMapper;
}
+ /**
+ * @param array $params
+ * @return void
+ * @throws Exception
+ */
public function run(array &$params): void
{
$demand = $params['demand'];
@@ -28,18 +41,63 @@ public function run(array &$params): void
$settings = $params['settings'];
if ($settings['enableFilter'] ?? false) {
+
$vars = GeneralUtility::_POST('tx_news_pi1');
- if (isset($vars['search']) && is_array($vars['search'])) {
+ $hasPostData = isset($vars['search']) && is_array($vars['search']);
+ if ($hasPostData) {
+ // set the demand based on POST data
+
/** @var Search $search */
$search = $this->propertyMapper->convert($vars['search'], Search::class);
- $search->setFields($settings['search']['fields']);
- $search->setSplitSubjectWords((bool)$settings['search']['splitSearchWord']);
- $demand->setSearch($search);
- $demand->setFilteredCategories($search->getFilteredCategories());
- $demand->setFilteredTags($search->getFilteredTags());
- $demand->setFromDate($search->getFromDate());
- $demand->setToDate($search->getToDate());
+ $this->setSearchDemand($settings, $search, $demand);
+ } else {
+ // set the demand based on session data
+ if ($settings['keepFilterOnReload']) {
+ $search = $this->getSearchFromSession();
+ $this->setSearchDemand($settings, $search, $demand);
+ }
}
}
}
+
+ /**
+ * Load filter from session or create a new empty search
+ *
+ * @param NewsListActionEvent $event
+ * @return Search
+ * @throws Exception
+ */
+ protected function getSearchFromSession(): Search
+ {
+ $request = $GLOBALS['TYPO3_REQUEST'];
+ $frontendUser = $request->getAttribute('frontend.user');
+ $sessionFilter = $frontendUser->getKey('ses', 'tx_news_filter');
+ if ($sessionFilter) {
+ $sessionFilter = unserialize($sessionFilter);
+ $search = $this->propertyMapper->convert($sessionFilter, Search::class);
+ } else {
+ $search = GeneralUtility::makeInstance(Search::class);
+ }
+
+ return $search;
+ }
+
+ /**
+ * @param array $settings
+ * @param Search $search
+ * @param Demand $demand
+ * @return Demand
+ */
+ protected function setSearchDemand(array $settings, Search $search, Demand $demand): Demand
+ {
+ $search->setFields($settings['search']['fields']);
+ $search->setSplitSubjectWords((bool)$settings['search']['splitSearchWord']);
+ $demand->setSearch($search);
+ $demand->setFilteredCategories($search->getFilteredCategories());
+ $demand->setFilteredTags($search->getFilteredTags());
+ $demand->setFromDate($search->getFromDate());
+ $demand->setToDate($search->getToDate());
+
+ return $demand;
+ }
}
diff --git a/Configuration/FlexForms/flexform_newsfilter.xml b/Configuration/FlexForms/flexform_newsfilter.xml
index f78c96b..d1fe7c8 100644
--- a/Configuration/FlexForms/flexform_newsfilter.xml
+++ b/Configuration/FlexForms/flexform_newsfilter.xml
@@ -44,6 +44,17 @@
+
+
+
+
+
+
+ check
+ 0
+
+
+
diff --git a/Configuration/FlexForms/flexform_newsfilter12.xml b/Configuration/FlexForms/flexform_newsfilter12.xml
index 4704605..3c56b1a 100644
--- a/Configuration/FlexForms/flexform_newsfilter12.xml
+++ b/Configuration/FlexForms/flexform_newsfilter12.xml
@@ -36,6 +36,17 @@
0
+
+
+
+
+
+
+ check
+ 0
+
+
+
diff --git a/Resources/Private/Language/locallang_ff.xlf b/Resources/Private/Language/locallang_ff.xlf
index 8924d3b..370985e 100644
--- a/Resources/Private/Language/locallang_ff.xlf
+++ b/Resources/Private/Language/locallang_ff.xlf
@@ -3,9 +3,12 @@
-
- Enable filter
-
+
+ Enable filter
+
+
+ Keep filter on reload
+