Add categories filter

Relates: #9171
This commit is contained in:
Daniel Siepmann 2021-07-13 15:50:14 +02:00
parent 049e121183
commit 52f1fe8dc1
5 changed files with 195 additions and 56 deletions

View file

@ -3,6 +3,7 @@ namespace Wrm\Events\Controller;
use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Core\Utility\GeneralUtility;
use Wrm\Events\Domain\Model\Dto\DateDemand; use Wrm\Events\Domain\Model\Dto\DateDemand;
use Wrm\Events\Domain\Repository\CategoryRepository;
use Wrm\Events\Domain\Repository\DateRepository; use Wrm\Events\Domain\Repository\DateRepository;
use Wrm\Events\Domain\Repository\RegionRepository; use Wrm\Events\Domain\Repository\RegionRepository;
use TYPO3\CMS\Core\Database\QueryGenerator; use TYPO3\CMS\Core\Database\QueryGenerator;
@ -25,6 +26,11 @@ class DateController extends ActionController
*/ */
protected $regionRepository; protected $regionRepository;
/**
* @var CategoryRepository
*/
protected $categoryRepository;
/** /**
* @var QueryGenerator * @var QueryGenerator
*/ */
@ -38,13 +44,16 @@ class DateController extends ActionController
/* /*
* @param RegionRepository $regionRepository * @param RegionRepository $regionRepository
* @param DateRepository $dateRepository * @param DateRepository $dateRepository
* @param CategoryRepository $categoryRepository
*/ */
public function __construct( public function __construct(
RegionRepository $regionRepository, RegionRepository $regionRepository,
DateRepository $dateRepository DateRepository $dateRepository,
CategoryRepository $categoryRepository
) { ) {
$this->regionRepository = $regionRepository; $this->regionRepository = $regionRepository;
$this->dateRepository = $dateRepository; $this->dateRepository = $dateRepository;
$this->categoryRepository = $categoryRepository;
} }
/** /**
@ -64,18 +73,18 @@ class DateController extends ActionController
*/ */
public function listAction() public function listAction()
{ {
if (($this->request->hasArgument('searchword') && $this->request->getArgument('searchword') != '') || if (
($this->request->hasArgument('region') && $this->request->getArgument('region') != '') || ($this->request->hasArgument('searchword') && $this->request->getArgument('searchword') != '')
($this->request->hasArgument('start') && $this->request->getArgument('start') != '') || || ($this->request->hasArgument('region') && $this->request->getArgument('region') != '')
($this->request->hasArgument('end') && $this->request->getArgument('end') != '')) || ($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(); $demand = $this->createDemandFromSearch();
$dates = $this->dateRepository->findByDemand($demand);
} else { } else {
$demand = $this->createDemandFromSettings(); $demand = $this->createDemandFromSettings();
$dates = $this->dateRepository->findByDemand($demand);
} }
$this->view->assign('dates', $dates); $this->view->assign('dates', $this->dateRepository->findByDemand($demand));
} }
/** /**
@ -83,21 +92,22 @@ class DateController extends ActionController
*/ */
public function searchAction() public function searchAction()
{ {
$arguments = GeneralUtility::_GET('tx_events_datelist'); $arguments = GeneralUtility::_GET('tx_events_datelist') ?? [];
$searchword = $arguments['searchword']; if (isset($arguments['events_search'])) {
$selRegion = $arguments['region']; $arguments += $arguments['events_search'];
$start = $arguments['start']; unset($arguments['events_search']);
$end = $arguments['end']; }
$considerDate = $arguments['considerDate'];
$regions = $this->regionRepository->findAll(); $this->view->assignMultiple([
$this->view->assign('regions', $regions); 'searchword' => $arguments['searchword'] ?? '',
'selRegion' => $arguments['region'] ?? '',
$this->view->assign('searchword', $searchword); 'start' => $arguments['start'] ?? '',
$this->view->assign('selRegion', $selRegion); 'end' => $arguments['end'] ?? '',
$this->view->assign('start', $start); 'considerDate' => $arguments['considerDate'] ?? '',
$this->view->assign('end', $end); 'demand' => DateDemand::createFromRequestValues($arguments, $this->settings),
$this->view->assign('considerDate', $considerDate); 'regions' => $this->regionRepository->findAll(),
'categories' => $this->categoryRepository->findAllCurrentlyAssigned(),
]);
} }
/** /**
@ -150,35 +160,15 @@ class DateController extends ActionController
*/ */
protected function createDemandFromSearch(): DateDemand protected function createDemandFromSearch(): DateDemand
{ {
$demand = $this->objectManager->get(DateDemand::class); $arguments = $this->request->getArguments() ?? [];
if (isset($arguments['events_search'])) {
if ($this->request->hasArgument('region') && $this->request->getArgument('region') != '') $arguments += $arguments['events_search'];
$demand->setRegion((string)$this->request->getArgument('region')); unset($arguments['events_search']);
if ($this->request->hasArgument('highlight') && $this->request->hasArgument('highlight') != '')
$demand->setHighlight((int)$this->settings['highlight']);
if ($this->request->hasArgument('searchword') && $this->request->getArgument('searchword') != '')
$demand->setSearchword((string)$this->request->getArgument('searchword'));
$demand->setSynonyms($this->settings['synonyms'] ?? []);
if ($this->request->hasArgument('start') && $this->request->getArgument('start') != '')
$demand->setStart(strtotime($this->request->getArgument('start') . ' 00:00'));
if ($this->request->hasArgument('end') && $this->request->getArgument('end') != '')
$demand->setEnd(strtotime($this->request->getArgument('end') . ' 23:59'));
if ($this->request->hasArgument('considerDate') && $this->request->getArgument('considerDate') != '')
$demand->setConsiderDate(strtotime($this->request->getArgument('considerDate')));
$demand->setSortBy((string)$this->settings['sortByDate']);
$demand->setSortOrder((string)$this->settings['sortOrder']);
if (!empty($this->settings['limit'])) {
$demand->setLimit($this->settings['limit']);
} }
return $demand; return DateDemand::createFromRequestValues(
$arguments,
$this->settings
);
} }
} }

View file

@ -21,6 +21,11 @@ class DateDemand {
*/ */
protected $categories = ''; protected $categories = '';
/**
* @var array
*/
protected $userCategories = [];
/** /**
* @var bool * @var bool
*/ */
@ -75,6 +80,44 @@ class DateDemand {
*/ */
protected $considerDate = 0; protected $considerDate = 0;
public static function createFromRequestValues(
array $submittedValues,
array $settings
): self {
$instance = new self();
$instance->setSearchword($submittedValues['searchword'] ?? '');
$instance->setSynonyms($settings['synonyms'] ?? []);
$instance->setRegion($submittedValues['region'] ?? '');
if ($submittedValues['highlight'] ?? false) {
$instance->setHighlight($settings['highlight'] ?? false);
}
if (isset($submittedValues['start']) && $submittedValues['start'] !== '') {
$instance->setStart(strtotime($submittedValues['start'] . ' 00:00'));
}
if (isset($submittedValues['end']) && $submittedValues['end'] !== '') {
$instance->setEnd(strtotime($submittedValues['end'] . ' 23:59'));
}
if (isset($submittedValues['considerDate']) && $submittedValues['considerDate'] !== '') {
$instance->setConsiderDate(strtotime($submittedValues['considerDate']));
}
if (is_array($submittedValues['userCategories'])) {
$instance->userCategories = array_map('intval', $submittedValues['userCategories']);
}
$instance->setSortBy($settings['sortByDate'] ?? '');
$instance->setSortOrder($settings['sortOrder'] ?? '');
if (!empty($settings['limit'])) {
$instance->setLimit($settings['limit']);
}
return $instance;
}
/** /**
* @return string * @return string
*/ */
@ -115,6 +158,11 @@ class DateDemand {
return $this->categories; return $this->categories;
} }
public function getUserCategories(): array
{
return $this->userCategories;
}
/** /**
* @param string $categories * @param string $categories
*/ */
@ -182,7 +230,7 @@ class DateDemand {
/** /**
* @param bool $highlight * @param bool $highlight
*/ */
public function setHighlight(string $highlight): void public function setHighlight(bool $highlight): void
{ {
$this->highlight = $highlight; $this->highlight = $highlight;
} }
@ -299,5 +347,4 @@ class DateDemand {
{ {
$this->considerDate = $considerDate; $this->considerDate = $considerDate;
} }
} }

View file

@ -0,0 +1,86 @@
<?php
declare(strict_types=1);
namespace Wrm\Events\Domain\Repository;
/*
* Copyright (C) 2021 Daniel Siepmann <coding@daniel-siepmann.de>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\Database\Query\QueryBuilder;
use TYPO3\CMS\Extbase\Domain\Model\Category;
use TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper;
use TYPO3\CMS\Extbase\Persistence\Repository;
class CategoryRepository
{
/**
* @var ConnectionPool
*/
protected $connectionPool;
/**
* @var DataMapper
*/
protected $dataMapper;
public function injectConnectionPool(ConnectionPool $connectionPool)
{
$this->connectionPool = $connectionPool;
}
public function injectDataMapper(DataMapper $dataMapper)
{
$this->dataMapper = $dataMapper;
}
public function findAllCurrentlyAssigned()
{
$qb = $this->connectionPool->getQueryBuilderForTable('tx_events_domain_model_event');
$qb->select('category.*');
$qb->from('tx_events_domain_model_event', 'event');
$qb->leftJoin(
'event',
'sys_category_record_mm',
'mm',
'event.uid = mm.uid_foreign'
. ' AND mm.tablenames = ' . $qb->createNamedParameter('tx_events_domain_model_event')
. ' AND mm.fieldname = ' . $qb->createNamedParameter('categories')
);
$qb->leftJoin(
'mm',
'sys_category',
'category',
'category.uid = mm.uid_local'
. ' AND mm.tablenames = ' . $qb->createNamedParameter('tx_events_domain_model_event')
. ' AND mm.fieldname = ' . $qb->createNamedParameter('categories')
);
$qb->orderBy('category.title', 'asc');
$qb->groupBy('category.uid');
return $this->dataMapper->map(
Category::class,
$qb->execute()->fetchAll()
);
}
}

View file

@ -74,6 +74,10 @@ class DateRepository extends \TYPO3\CMS\Extbase\Persistence\Repository
$constraints['searchword'] = $this->getSearchwordConstraint($query, $demand); $constraints['searchword'] = $this->getSearchwordConstraint($query, $demand);
} }
if ($demand->getUserCategories() !== []) {
$constraints['userCategories'] = $query->in('event.categories.uid', $demand->getUserCategories());
}
if ($demand->getStart() !== '' && $demand->getEnd() != '') { if ($demand->getStart() !== '' && $demand->getEnd() != '') {
$constraints['daterange'] = $query->logicalAnd( $constraints['daterange'] = $query->logicalAnd(
[ [

View file

@ -3,7 +3,7 @@
<f:section name="content"> <f:section name="content">
<div class="row"> <div class="row">
<div class="col-12 mb-5"> <div class="col-12 mb-5">
<f:form action="list" controller="Date" pluginName="DateList" method="get" id="events_search" name="events_search"> <f:form action="list" controller="Date" pluginName="DateList" method="get" id="events_search" name="events_search" object="{demand}">
<div class="row"> <div class="row">
<div class="col"> <div class="col">
<div class="form-group"> <div class="form-group">
@ -65,6 +65,18 @@
</f:for> </f:for>
</div> </div>
</f:if> </f:if>
<f:if condition="{categories}">
<div class="row">
<f:for each="{categories}" as="category">
<div class="col-3">
<div class="form-check">
<f:form.checkbox class="form-check-input" property="userCategories" value="{category.uid}" id="check_{category.uid}"/>
<label class="form-check-label" for="check_{category.uid}">{category.title} {category.amountOfEvents}</label>
</div>
</div>
</f:for>
</div>
</f:if>
<div class="form-group mt-3"> <div class="form-group mt-3">
<f:form.submit value="{f:translate(key: 'LLL:EXT:events/Resources/Private/Language/locallang.xlf:tx_events.searchform.search')}" class="btn btn-primary" /> <f:form.submit value="{f:translate(key: 'LLL:EXT:events/Resources/Private/Language/locallang.xlf:tx_events.searchform.search')}" class="btn btn-primary" />
</div> </div>