Refactor and streamline event code

Make controller smaller, remove unused code.
Move creation of demand object into its own factory.
Reduce npath complexity in repository and move parts into named methods.
This commit is contained in:
Daniel Siepmann 2021-01-12 14:34:13 +01:00
parent 17bd83eedf
commit f111884299
3 changed files with 150 additions and 175 deletions

View file

@ -2,32 +2,20 @@
namespace Wrm\Events\Controller;
use TYPO3\CMS\Core\Database\QueryGenerator;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Annotation as Extbase;
use TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface;
use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
use Wrm\Events\Domain\Model\Dto\EventDemand;
use Wrm\Events\Domain\Model\Dto\EventDemandFactory;
use Wrm\Events\Domain\Model\Event;
use Wrm\Events\Domain\Repository\EventRepository;
use Wrm\Events\Service\DataProcessingForModels;
/**
* EventController
*/
class EventController extends ActionController
{
/**
* @var eventRepository
* @var EventRepository
*/
protected $eventRepository = null;
/**
* @var QueryGenerator
*/
protected $queryGenerator;
protected $eventRepository;
/**
* @var DataProcessingForModels
@ -35,117 +23,54 @@ class EventController extends ActionController
protected $dataProcessing;
/**
* @var array
* @var EventDemandFactory
*/
protected $pluginSettings;
protected $demandFactory;
/**
* @param EventRepository $eventRepository
*/
public function injectEventRepository(EventRepository $eventRepository)
{
public function __construct(
EventRepository $eventRepository,
DataProcessingForModels $dataProcessing,
EventDemandFactory $demandFactory
) {
$this->eventRepository = $eventRepository;
}
/**
* @param DataProcessingForModels $dataProcessing
*/
public function injectDataProcessingForModels(DataProcessingForModels $dataProcessing)
{
$this->dataProcessing = $dataProcessing;
$this->demandFactory = $demandFactory;
}
/**
* Action initializer
*/
protected function initializeAction()
{
$this->dataProcessing->setConfigurationManager($this->configurationManager);
$this->pluginSettings = $this->configurationManager->getConfiguration(
ConfigurationManagerInterface::CONFIGURATION_TYPE_FRAMEWORK
);
}
/**
* Action list
*
* @return void
*/
public function listAction()
public function listAction(): void
{
$demand = $this->createDemandFromSettings();
$demand = $this->demandFactory->fromSettings($this->settings);
$events = $this->eventRepository->findByDemand($demand);
$this->view->assign('events', $events);
}
/**
* Action show
*
* @Extbase\IgnoreValidation("event")
*
* @param Event $event
* @return void
*/
public function showAction(Event $event)
public function showAction(Event $event): void
{
$this->view->assign('event', $event);
}
/**
* action teaser
*
* @return void
* @deprecated Use listAction instead and configure settings properly.
* Use Settings or something else to switch between list and teaser rendering.
*/
public function teaserAction()
public function teaserAction(): void
{
$events = $this->eventRepository->findByUids($this->settings['eventUids']);
$this->view->assign('events', $events);
$this->view->assignMultiple([
'events' => $this->eventRepository->findByUids($this->settings['eventUids']),
]);
}
/**
* @param string $search
*/
public function searchAction(): void
public function searchAction(string $search = ''): void
{
$search = '';
if ($this->request->hasArgument('search')) {
$search = $this->request->getArgument('search');
}
$this->view->assign('search', $search);
$this->view->assign('events', $this->eventRepository->findSearchWord($search));
}
/**
* @return EventDemand
*/
protected function createDemandFromSettings(): EventDemand
{
/** @var EventDemand $demand */
$demand = $this->objectManager->get(EventDemand::class);
$demand->setRegion((string)$this->settings['region']);
$demand->setCategories((string)$this->settings['categories']);
$categoryCombination = (int)$this->settings['categoryCombination'] === 1 ? 'or' : 'and';
$demand->setCategoryCombination($categoryCombination);
$demand->setIncludeSubCategories((bool)$this->settings['includeSubcategories']);
$demand->setSortBy((string)$this->settings['sortByEvent']);
$demand->setSortOrder((string)$this->settings['sortOrder']);
$demand->setHighlight((bool)$this->settings['highlight']);
$demand->setRecordUids(GeneralUtility::intExplode(',', $this->settings['selectedRecords'], true));
if (!empty($this->settings['limit'])) {
$demand->setLimit($this->settings['limit']);
}
return $demand;
}
}

View file

@ -0,0 +1,58 @@
<?php
namespace Wrm\Events\Domain\Model\Dto;
/*
* 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\Utility\GeneralUtility;
class EventDemandFactory
{
public function fromSettings(array $settings): EventDemand
{
/** @var EventDemand $demand */
$demand = GeneralUtility::makeInstance(EventDemand::class);
$demand->setRegion((string)$settings['region']);
$demand->setCategories((string)$settings['categories']);
$categoryCombination = 'and';
if ((int)$settings['categoryCombination'] === 1) {
$categoryCombination = 'or';
}
$demand->setCategoryCombination($categoryCombination);
$demand->setIncludeSubCategories((bool)$settings['includeSubcategories']);
$demand->setSortBy((string)$settings['sortByEvent']);
$demand->setSortOrder((string)$settings['sortOrder']);
$demand->setHighlight((bool)$settings['highlight']);
$demand->setRecordUids(GeneralUtility::intExplode(',', $settings['selectedRecords'], true));
if (!empty($settings['limit'])) {
$demand->setLimit($settings['limit']);
}
return $demand;
}
}

View file

@ -16,6 +16,7 @@ namespace Wrm\Events\Domain\Repository;
*/
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Persistence\Generic\Qom\ConstraintInterface;
use TYPO3\CMS\Extbase\Persistence\QueryInterface;
use TYPO3\CMS\Extbase\Persistence\QueryResultInterface;
use TYPO3\CMS\Extbase\Persistence\Repository;
@ -25,33 +26,16 @@ use Wrm\Events\Service\CategoryService;
class EventRepository extends Repository
{
/**
* Find all products based on selected uids
*
* @param string $uids
*
* @return array
*/
public function findByUids($uids)
public function findByUids(string $uids): QueryResultInterface
{
$uids = explode(',', $uids);
$query = $this->createQuery();
//$query->getQuerySettings()->setRespectStoragePage(false);
$query->matching(
$query->in('uid', $uids)
);
//return $this->orderByField($query->execute(), $uids);
$query->matching($query->in('uid', GeneralUtility::intExplode(',', $uids)));
return $query->execute();
}
/**
* @param EventDemand $demand
* @return QueryResultInterface
* @return QueryResultInterface|array
* @throws InvalidQueryException
*/
public function findByDemand(EventDemand $demand)
@ -66,82 +50,42 @@ class EventRepository extends Repository
}
/**
* @param EventDemand $demand
* @return QueryInterface
* @throws InvalidQueryException
*/
protected function createDemandQuery(EventDemand $demand): QueryInterface
{
$query = $this->createQuery();
$query = $this->setOrderings($query, $demand);
// sorting
$sortBy = $demand->getSortBy();
$sortingsToIgnore = ['singleSelection', 'default'];
if ($sortBy && in_array($sortBy, $sortingsToIgnore) === false) {
$order = strtolower($demand->getSortOrder()) === 'desc' ? QueryInterface::ORDER_DESCENDING : QueryInterface::ORDER_ASCENDING;
$query->setOrderings([$sortBy => $order]);
}
$constraints = [];
$categories = $demand->getCategories();
if ($categories) {
$categoryConstraints = $this->createCategoryConstraint($query, $categories, $demand->getIncludeSubCategories());
if ($demand->getCategoryCombination() === 'or') {
$constraints['categories'] = $query->logicalOr($categoryConstraints);
} else {
$constraints['categories'] = $query->logicalAnd($categoryConstraints);
}
}
if ($demand->getRecordUids() !== []) {
$constraints['recordUids'] = $query->in('uid', $demand->getRecordUids());
}
if ($demand->getRegion() !== '') {
$constraints['region'] = $query->equals('region', $demand->getRegion());
}
if ($demand->getHighlight()) {
$constraints['highlight'] = $query->equals('highlight', $demand->getHighlight());
$constraints = $this->getConstraints($query, $demand);
if (!empty($constraints)) {
$query->matching($query->logicalAnd($constraints));
}
if ($demand->getLimit() !== '') {
$query->setLimit((int) $demand->getLimit());
}
if (!empty($constraints)) {
$query->matching($query->logicalAnd($constraints));
}
return $query;
}
/**
* @param QueryInterface $query
* @param string $categories
* @param bool $includeSubCategories
* @return array
* @throws InvalidQueryException
*/
protected function createCategoryConstraint(QueryInterface $query, $categories, bool $includeSubCategories = false): array
private function setOrderings(QueryInterface $query, EventDemand $demand): QueryInterface
{
$constraints = [];
$sortBy = $demand->getSortBy();
$sortingsToIgnore = ['singleSelection', 'default'];
if ($includeSubCategories) {
$categoryService = GeneralUtility::makeInstance(CategoryService::class);
$allCategories = $categoryService->getChildrenCategories($categories);
if (!\is_array($allCategories)) {
$allCategories = GeneralUtility::intExplode(',', $allCategories, true);
}
} else {
$allCategories = GeneralUtility::intExplode(',', $categories, true);
if (!$sortBy || in_array($sortBy, $sortingsToIgnore)) {
return $query;
}
foreach ($allCategories as $category) {
$constraints[] = $query->contains('categories', $category);
$order = QueryInterface::ORDER_ASCENDING;
if (strtolower($demand->getSortOrder()) === 'desc') {
$order = QueryInterface::ORDER_DESCENDING;
}
return $constraints;
$query->setOrderings([$sortBy => $order]);
return $query;
}
private function sortByDemand(QueryInterface $query, EventDemand $demand): array
@ -159,12 +103,60 @@ class EventRepository extends Repository
return $result;
}
private function getConstraints(QueryInterface $query, EventDemand $demand): array
{
$constraints = [];
if ($demand->getCategories()) {
$constraints['categories'] = $this->createCategoryConstraint($query, $demand);
}
if ($demand->getRecordUids() !== []) {
$constraints['recordUids'] = $query->in('uid', $demand->getRecordUids());
}
if ($demand->getRegion() !== '') {
$constraints['region'] = $query->equals('region', $demand->getRegion());
}
if ($demand->getHighlight()) {
$constraints['highlight'] = $query->equals('highlight', $demand->getHighlight());
}
return $constraints;
}
/**
* @throws InvalidQueryException
*/
protected function createCategoryConstraint(QueryInterface $query, EventDemand $demand): ConstraintInterface
{
$constraints = [];
$allCategories = GeneralUtility::intExplode(',', $demand->getCategories(), true);
if ($demand->includeSubCategories()) {
$categoryService = GeneralUtility::makeInstance(CategoryService::class);
$allCategories = $categoryService->getChildrenCategories($demand->getCategories());
if (!\is_array($allCategories)) {
$allCategories = GeneralUtility::intExplode(',', $allCategories, true);
}
}
foreach ($allCategories as $category) {
$constraints[] = $query->contains('demand->getCategories()', $category);
}
if ($demand->getCategoryCombination() === 'or') {
return $query->logicalOr($constraints);
}
return $query->logicalAnd($constraints);
}
public function findSearchWord($search)
{
$query = $this->createQuery();
$query->matching(
$query->like('title', '%' . $search . '%')
);
$query->matching($query->like('title', '%' . $search . '%'));
$query->setOrderings(['title' => QueryInterface::ORDER_ASCENDING]);
$query->setLimit(20);
return $query->execute();