From 80b6494e93ae6255bb9f63d2e2c992032627e0d6 Mon Sep 17 00:00:00 2001 From: Michael Kessler <michael.kessler@sgalinski.de> Date: Wed, 30 Mar 2022 12:22:54 +0200 Subject: [PATCH] [FEATURE] Enable filtering by all filters --- Classes/Controller/OverviewController.php | 175 ++++++++++++++++-- Configuration/FlexForms/Overview.xml | 37 ++-- .../Private/Language/de.locallang_db.xlf | 12 +- Resources/Private/Language/locallang_db.xlf | 7 +- 4 files changed, 202 insertions(+), 29 deletions(-) diff --git a/Classes/Controller/OverviewController.php b/Classes/Controller/OverviewController.php index 1194824..89c861d 100644 --- a/Classes/Controller/OverviewController.php +++ b/Classes/Controller/OverviewController.php @@ -35,13 +35,13 @@ use SGalinski\SgNews\Domain\Repository\TagRepository; use SGalinski\SgNews\Service\ConfigurationService; use SGalinski\SgNews\Service\HeaderMetaDataService; use TYPO3\CMS\Core\Http\ImmediateResponseException; +use TYPO3\CMS\Core\Utility\ExtensionManagementUtility; use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Extbase\Persistence\Generic\Query; use TYPO3\CMS\Extbase\Persistence\Generic\QueryResult; use TYPO3\CMS\Extbase\Persistence\QueryInterface; use TYPO3\CMS\Frontend\Controller\ErrorController; use TYPO3\CMS\Frontend\Page\PageAccessFailureReasons; -use TYPO3\CMS\Core\Utility\ExtensionManagementUtility; /** * Controller that handles the overview page of categories and their news @@ -108,17 +108,170 @@ class OverviewController extends AbstractController { * @throws \TYPO3\CMS\Extbase\Configuration\Exception\InvalidConfigurationTypeException */ public function overviewAction(array $newsFilter = [], int $currentPageBrowserPage = 0) { - switch ((int) $this->settings['groupBy']) { - case 1: - $this->overviewWithCategories([], [], $newsFilter, $currentPageBrowserPage); - break; - case 2: - $this->overviewWithTags([], [], $newsFilter, $currentPageBrowserPage); - break; - default: - $this->forward('overviewWithoutCategories', NULL, NULL, $this->request->getArguments()); - break; + if ((bool) $this->settings['enableFilter'] === TRUE) { + $this->overviewWithAllFilters([], [], $newsFilter, $currentPageBrowserPage); + } else { + switch ((int) $this->settings['groupBy']) { + case 1: + $this->overviewWithCategories([], [], $newsFilter, $currentPageBrowserPage); + break; + case 2: + $this->overviewWithTags([], [], $newsFilter, $currentPageBrowserPage); + break; + default: + $this->forward('overviewWithoutCategories', NULL, NULL, $this->request->getArguments()); + break; + } + } + } + + /** + * Renders the news overview by all filters + * + * @param array $newsByFilters + * @param array $allNews + * @param array $newsFilter + * @param int $currentPageBrowserPage + * @return void + * @throws \InvalidArgumentException + * @throws \TYPO3\CMS\Extbase\Persistence\Exception\InvalidQueryException + * @throws \TYPO3\CMS\Extbase\Configuration\Exception\InvalidConfigurationTypeException + * @throws ImmediateResponseException + * @throws \TYPO3\CMS\Core\Error\Http\PageNotFoundException + */ + protected function overviewWithAllFilters( + array $newsByFilters = [], array $allNews = [], array $newsFilter = [], int $currentPageBrowserPage = 0 + ) { + // Setup settings + $startTime = (int) $this->settings['starttime']; + $endTime = (int) $this->settings['endtime']; + $newsLimit = (int) $this->settings['newsLimit']; + $offset = $this->calculatePaginationOffset($currentPageBrowserPage, $newsLimit); + $configurationService = GeneralUtility::makeInstance(ConfigurationService::class); + $sortBy = $configurationService->getConfiguration('sortBy', $this->settings); + $sortDirection = $configurationService->getConfiguration('sortDirection', $this->settings); + $this->tagRepository->setDefaultOrderings(['sorting' => QueryInterface::ORDER_ASCENDING]); + $this->categoryRepository->setDefaultOrderings(['sorting' => QueryInterface::ORDER_ASCENDING]); + + // Get tag pid + $tagPid = (int) $this->settings['tagPid']; + if (!$tagPid) { + $tagPid = $GLOBALS['TSFE']->id; + } + + if ($this->settings['onlyNewsWithinThisPageSection']) { + $categories = $this->categoryRepository->findCategoriesInRootLine($GLOBALS['TSFE']->id); + $tags = $this->tagRepository->findTagsInRootLine($tagPid); + } else { + $tags = $this->tagRepository->findAll()->toArray(); + $categories = $this->categoryRepository->findAll()->toArray(); + } + + // Get category restrictions + $categoryRestrictions = GeneralUtility::intExplode(',', $this->settings['categoryRestrictions'], TRUE); + if (count($categoryRestrictions) > 0) { + foreach ($categories as $key => $category) { + $categoryId = $category->getUid(); + + // older version compatibility with selection of categories in translations and so on + $categoryIdTranslated = $categoryId; + if ($category->_getProperty('_languageUid') > 0) { + $originalLangCategory = $this->categoryRepository->findOriginalLanguageById($categoryId); + if ($originalLangCategory) { + $categoryIdTranslated = $originalLangCategory->getUid(); + } + } + + if (!in_array($categoryId, $categoryRestrictions, TRUE) && + !in_array($categoryIdTranslated, $categoryRestrictions, TRUE) + ) { + unset($categories[$key]); + } + } + } else { + return; + } + + // Get tag restrictions + $tagRestrictions = GeneralUtility::intExplode(',', $this->settings['tagRestrictions'], TRUE); + if (count($tagRestrictions) > 0) { + foreach ($tags as $key => $tag) { + if (!in_array($tag->getUid(), $tagRestrictions, TRUE)) { + unset($tags[$key]); + } + } + } else { + return; + } + + // Get category ids or use the one in the filter + $categoryIds = []; + if ($newsFilter['category']) { + $categoryIds = [(int) $newsFilter['category']]; + } else { + foreach ($categories as $category) { + $categoryIds[] = $category->getUid(); + } + } + + // Get tag ids or use the one in the filter + $tagIds = []; + if ($newsFilter['tag']) { + $tagIds = [(int) $newsFilter['tag']]; + } else { + foreach ($tags as $tag) { + $tagIds[] = $tag->getUid(); + } + } + + // Get all news by category and tag ids + $news = $this->newsRepository->findAllSortedNewsByCategories( + $categoryIds, $newsLimitPerTag, $offset, $sortBy, $tagIds, $startTime, $endTime, $sortDirection + ); + + // Process news result query into meta data + $newsMetaData = []; + foreach ($news as $newsEntry) { + /** @var News $newsEntry */ + $categoryId = $newsEntry->getPid(); + if (!isset($categoriesById[$categoryId])) { + $categoriesById[$categoryId] = $this->categoryRepository->findByUid($categoryId); + } + $category = $categoriesById[$categoryId]; + if (!$category) { + // Category isn't visible. + continue; + } + $newsMetaData[] = $this->getMetaDataForNews($newsEntry, $category); } + + $this->highlightBestFitNews([], $tagIds); + + // Check to achieve less Ajax calls. + $newsCount = $this->newsRepository->newsCountByCategories([], $tagIds, $startTime, $endTime); + $numberOfPages = (int) ($newsLimitPerTag <= 0 ? 0 : ceil($newsCount / $newsLimitPerTag)); + if ($numberOfPages !== 0 && $currentPageBrowserPage >= $numberOfPages) { + /** @var ErrorController $errorController */ + $errorController = GeneralUtility::makeInstance(ErrorController::class); + $response = $errorController->pageNotFoundAction( + $GLOBALS['TYPO3_REQUEST'], + 'The requested page does not exist', + ['code' => PageAccessFailureReasons::PAGE_NOT_FOUND] + ); + throw new ImmediateResponseException($response); + } + + // remember selection of the filter values, if any + $selectedTag = $this->tagRepository->findByUid((int) $newsFilter['tag']); + $selectedCategory = $this->categoryRepository->findByUid((int) $newsFilter['category']); + $this->view->assign('selectedCategory', $selectedCategory); + $this->view->assign('selectedTag', $selectedTag); + $this->view->assign('tags', $tags); + $this->view->assign('categories', $categories); + $this->view->assign('numberOfPages', $numberOfPages); + $this->view->assign('newsItems', $newsByTag); + $this->view->assign('groupBy', $this->settings['groupBy']); + $this->view->assign('allNews', $newsMetaData); } /** diff --git a/Configuration/FlexForms/Overview.xml b/Configuration/FlexForms/Overview.xml index 23ce498..6ce2261 100644 --- a/Configuration/FlexForms/Overview.xml +++ b/Configuration/FlexForms/Overview.xml @@ -13,6 +13,7 @@ <settings.groupBy> <TCEforms> <label>LLL:EXT:sg_news/Resources/Private/Language/locallang_db.xlf:plugin.overview.flexForm.groupBy</label> + <description>LLL:EXT:sg_news/Resources/Private/Language/locallang_db.xlf:plugin.overview.flexForm.groupBy.description</description> <onChange>reload</onChange> <config> <type>select</type> @@ -36,11 +37,28 @@ </TCEforms> </settings.groupBy> + <settings.enableFilter> + <TCEforms> + <label>LLL:EXT:sg_news/Resources/Private/Language/locallang_db.xlf:plugin.overview.flexForm.enableFilter</label> + <description>LLL:EXT:sg_news/Resources/Private/Language/locallang_db.xlf:plugin.overview.flexForm.enableFilter.description</description> + <onChange>reload</onChange> + <config> + <type>check</type> + <default>0</default> + </config> + </TCEforms> + </settings.enableFilter> + <settings.categoryRestrictions> <TCEforms> <label>LLL:EXT:sg_news/Resources/Private/Language/locallang_db.xlf:plugin.overview.flexForm.categoryRestrictions</label> <description>LLL:EXT:sg_news/Resources/Private/Language/locallang_db.xlf:plugin.overview.flexForm.categoryRestrictions.description</description> - <displayCond>FIELD:settings.groupBy:=:1</displayCond> + <displayCond> + <or> + <value1>FIELD:settings.groupBy:=:1</value1> + <value2>FIELD:settings.enableFilter:=:1</value2> + </or> + </displayCond> <config> <type>select</type> <renderType>selectMultipleSideBySide</renderType> @@ -57,7 +75,12 @@ <TCEforms> <label>LLL:EXT:sg_news/Resources/Private/Language/locallang_db.xlf:plugin.flexForm.tags</label> <description>LLL:EXT:sg_news/Resources/Private/Language/locallang_db.xlf:plugin.overview.flexForm.tags.description</description> - <displayCond>FIELD:settings.groupBy:=:2</displayCond> + <displayCond> + <or> + <value1>FIELD:settings.groupBy:=:2</value1> + <value2>FIELD:settings.enableFilter:=:1</value2> + </or> + </displayCond> <config> <type>select</type> <renderType>selectTree</renderType> @@ -77,16 +100,6 @@ </TCEforms> </settings.tagRestrictions> - <settings.enableFilter> - <TCEforms> - <label>LLL:EXT:sg_news/Resources/Private/Language/locallang_db.xlf:plugin.overview.flexForm.enableFilter</label> - <description>LLL:EXT:sg_news/Resources/Private/Language/locallang_db.xlf:plugin.overview.flexForm.enableFilter.description</description> - <config> - <type>check</type> - <default>0</default> - </config> - </TCEforms> - </settings.enableFilter> <settings.categoryLabel> <TCEforms> <label>LLL:EXT:sg_news/Resources/Private/Language/locallang_db.xlf:plugin.overview.flexForm.categoryLabel</label> diff --git a/Resources/Private/Language/de.locallang_db.xlf b/Resources/Private/Language/de.locallang_db.xlf index 22069fc..249b0d9 100644 --- a/Resources/Private/Language/de.locallang_db.xlf +++ b/Resources/Private/Language/de.locallang_db.xlf @@ -232,16 +232,20 @@ If none are selected, all categories will be available in the frontend.]]></sour Wenn keine ausgewählt werden, sind alle Kategorien im Frontend verfügbar.]]></target> </trans-unit> <trans-unit id="plugin.overview.flexForm.enableFilter" approved="yes"> - <source><![CDATA[Enable filtering by all criteria.]]></source> - <target><![CDATA[Ermögliche das Filtern mit allen Krierien.]]></target> + <source><![CDATA[Show all filters]]></source> + <target><![CDATA[Zeige alle Filter an]]></target> </trans-unit> <trans-unit id="plugin.overview.flexForm.enableFilter.description" approved="yes"> <source><![CDATA[Filters will be rendered as select boxes and tabs will be hidden.]]></source> <target><![CDATA[Filter werden als Dropdown-Box angezeigt und die Tabs ausgeblendet.]]></target> </trans-unit> <trans-unit id="plugin.overview.flexForm.groupBy" approved="yes"> - <source><![CDATA[Group news pages in tabs by]]></source> - <target><![CDATA[News-Seiten nach folgendem Kriterium in Tabs gruppieren]]></target> + <source><![CDATA[Group news pages by]]></source> + <target><![CDATA[News-Seiten nach folgendem Kriterium gruppieren]]></target> + </trans-unit> + <trans-unit id="plugin.overview.flexForm.groupBy.description" approved="yes"> + <source><![CDATA[News pages will be grouped in tabs.]]></source> + <target><![CDATA[News-Seiten werden in Tabs gruppiert.]]></target> </trans-unit> <trans-unit id="plugin.overview.flexForm.groupBy.I.0" approved="yes"> <source><![CDATA[No grouping]]></source> diff --git a/Resources/Private/Language/locallang_db.xlf b/Resources/Private/Language/locallang_db.xlf index a24ed7c..a1abc3a 100644 --- a/Resources/Private/Language/locallang_db.xlf +++ b/Resources/Private/Language/locallang_db.xlf @@ -176,13 +176,16 @@ If none are selected, all categories will be available in the frontend.]]></source> </trans-unit> <trans-unit id="plugin.overview.flexForm.enableFilter"> - <source><![CDATA[Enable filtering by all criteria.]]></source> + <source><![CDATA[Show all filters]]></source> </trans-unit> <trans-unit id="plugin.overview.flexForm.enableFilter.description"> <source><![CDATA[Filters will be rendered as select boxes and tabs will be hidden.]]></source> </trans-unit> <trans-unit id="plugin.overview.flexForm.groupBy"> - <source><![CDATA[Group news pages in tabs by]]></source> + <source><![CDATA[Group news pages by]]></source> + </trans-unit> + <trans-unit id="plugin.overview.flexForm.groupBy.description"> + <source><![CDATA[News pages will be grouped in tabs.]]></source> </trans-unit> <trans-unit id="plugin.overview.flexForm.groupBy.I.0"> <source><![CDATA[No grouping]]></source> -- GitLab