Merge branch 'feature/category-filter' into 'master'

Add categories filter

See merge request typo3/events!7
This commit is contained in:
Dirk Koritnik 2021-08-12 09:56:43 +00:00
commit a5cef0ac8f
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 Wrm\Events\Domain\Model\Dto\DateDemand;
use Wrm\Events\Domain\Repository\CategoryRepository;
use Wrm\Events\Domain\Repository\DateRepository;
use Wrm\Events\Domain\Repository\RegionRepository;
use TYPO3\CMS\Core\Database\QueryGenerator;
@ -25,6 +26,11 @@ class DateController extends ActionController
*/
protected $regionRepository;
/**
* @var CategoryRepository
*/
protected $categoryRepository;
/**
* @var QueryGenerator
*/
@ -38,13 +44,16 @@ class DateController extends ActionController
/*
* @param RegionRepository $regionRepository
* @param DateRepository $dateRepository
* @param CategoryRepository $categoryRepository
*/
public function __construct(
RegionRepository $regionRepository,
DateRepository $dateRepository
DateRepository $dateRepository,
CategoryRepository $categoryRepository
) {
$this->regionRepository = $regionRepository;
$this->dateRepository = $dateRepository;
$this->categoryRepository = $categoryRepository;
}
/**
@ -64,18 +73,18 @@ class DateController extends ActionController
*/
public function listAction()
{
if (($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') != ''))
{
if (
($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);
} else {
$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()
{
$arguments = GeneralUtility::_GET('tx_events_datelist');
$searchword = $arguments['searchword'];
$selRegion = $arguments['region'];
$start = $arguments['start'];
$end = $arguments['end'];
$considerDate = $arguments['considerDate'];
$arguments = GeneralUtility::_GET('tx_events_datelist') ?? [];
if (isset($arguments['events_search'])) {
$arguments += $arguments['events_search'];
unset($arguments['events_search']);
}
$regions = $this->regionRepository->findAll();
$this->view->assign('regions', $regions);
$this->view->assign('searchword', $searchword);
$this->view->assign('selRegion', $selRegion);
$this->view->assign('start', $start);
$this->view->assign('end', $end);
$this->view->assign('considerDate', $considerDate);
$this->view->assignMultiple([
'searchword' => $arguments['searchword'] ?? '',
'selRegion' => $arguments['region'] ?? '',
'start' => $arguments['start'] ?? '',
'end' => $arguments['end'] ?? '',
'considerDate' => $arguments['considerDate'] ?? '',
'demand' => DateDemand::createFromRequestValues($arguments, $this->settings),
'regions' => $this->regionRepository->findAll(),
'categories' => $this->categoryRepository->findAllCurrentlyAssigned(),
]);
}
/**
@ -150,35 +160,15 @@ class DateController extends ActionController
*/
protected function createDemandFromSearch(): DateDemand
{
$demand = $this->objectManager->get(DateDemand::class);
if ($this->request->hasArgument('region') && $this->request->getArgument('region') != '')
$demand->setRegion((string)$this->request->getArgument('region'));
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']);
$arguments = $this->request->getArguments() ?? [];
if (isset($arguments['events_search'])) {
$arguments += $arguments['events_search'];
unset($arguments['events_search']);
}
return $demand;
return DateDemand::createFromRequestValues(
$arguments,
$this->settings
);
}
}

View file

@ -21,6 +21,11 @@ class DateDemand {
*/
protected $categories = '';
/**
* @var array
*/
protected $userCategories = [];
/**
* @var bool
*/
@ -75,6 +80,44 @@ class DateDemand {
*/
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
*/
@ -115,6 +158,11 @@ class DateDemand {
return $this->categories;
}
public function getUserCategories(): array
{
return $this->userCategories;
}
/**
* @param string $categories
*/
@ -182,7 +230,7 @@ class DateDemand {
/**
* @param bool $highlight
*/
public function setHighlight(string $highlight): void
public function setHighlight(bool $highlight): void
{
$this->highlight = $highlight;
}
@ -299,5 +347,4 @@ class DateDemand {
{
$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);
}
if ($demand->getUserCategories() !== []) {
$constraints['userCategories'] = $query->in('event.categories.uid', $demand->getUserCategories());
}
if ($demand->getStart() !== '' && $demand->getEnd() != '') {
$constraints['daterange'] = $query->logicalAnd(
[

View file

@ -3,7 +3,7 @@
<f:section name="content">
<div class="row">
<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="col">
<div class="form-group">
@ -65,6 +65,18 @@
</f:for>
</div>
</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">
<f:form.submit value="{f:translate(key: 'LLL:EXT:events/Resources/Private/Language/locallang.xlf:tx_events.searchform.search')}" class="btn btn-primary" />
</div>