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; 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\Annotation as Extbase;
use TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface;
use TYPO3\CMS\Extbase\Mvc\Controller\ActionController; use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
use Wrm\Events\Domain\Model\Dto\EventDemand; use Wrm\Events\Domain\Model\Dto\EventDemand;
use Wrm\Events\Domain\Model\Dto\EventDemandFactory;
use Wrm\Events\Domain\Model\Event; use Wrm\Events\Domain\Model\Event;
use Wrm\Events\Domain\Repository\EventRepository; use Wrm\Events\Domain\Repository\EventRepository;
use Wrm\Events\Service\DataProcessingForModels; use Wrm\Events\Service\DataProcessingForModels;
/**
* EventController
*/
class EventController extends ActionController class EventController extends ActionController
{ {
/** /**
* @var eventRepository * @var EventRepository
*/ */
protected $eventRepository = null; protected $eventRepository;
/**
* @var QueryGenerator
*/
protected $queryGenerator;
/** /**
* @var DataProcessingForModels * @var DataProcessingForModels
@ -35,117 +23,54 @@ class EventController extends ActionController
protected $dataProcessing; protected $dataProcessing;
/** /**
* @var array * @var EventDemandFactory
*/ */
protected $pluginSettings; protected $demandFactory;
/** public function __construct(
* @param EventRepository $eventRepository EventRepository $eventRepository,
*/ DataProcessingForModels $dataProcessing,
public function injectEventRepository(EventRepository $eventRepository) EventDemandFactory $demandFactory
{ ) {
$this->eventRepository = $eventRepository; $this->eventRepository = $eventRepository;
}
/**
* @param DataProcessingForModels $dataProcessing
*/
public function injectDataProcessingForModels(DataProcessingForModels $dataProcessing)
{
$this->dataProcessing = $dataProcessing; $this->dataProcessing = $dataProcessing;
$this->demandFactory = $demandFactory;
} }
/**
* Action initializer
*/
protected function initializeAction() protected function initializeAction()
{ {
$this->dataProcessing->setConfigurationManager($this->configurationManager); $this->dataProcessing->setConfigurationManager($this->configurationManager);
$this->pluginSettings = $this->configurationManager->getConfiguration(
ConfigurationManagerInterface::CONFIGURATION_TYPE_FRAMEWORK
);
} }
/** public function listAction(): void
* Action list
*
* @return void
*/
public function listAction()
{ {
$demand = $this->demandFactory->fromSettings($this->settings);
$demand = $this->createDemandFromSettings();
$events = $this->eventRepository->findByDemand($demand); $events = $this->eventRepository->findByDemand($demand);
$this->view->assign('events', $events); $this->view->assign('events', $events);
} }
/** /**
* Action show
*
* @Extbase\IgnoreValidation("event") * @Extbase\IgnoreValidation("event")
*
* @param Event $event
* @return void
*/ */
public function showAction(Event $event) public function showAction(Event $event): void
{ {
$this->view->assign('event', $event); $this->view->assign('event', $event);
} }
/** /**
* action teaser * @deprecated Use listAction instead and configure settings properly.
* * Use Settings or something else to switch between list and teaser rendering.
* @return void
*/ */
public function teaserAction() public function teaserAction(): void
{ {
$events = $this->eventRepository->findByUids($this->settings['eventUids']); $this->view->assignMultiple([
$this->view->assign('events', $events); 'events' => $this->eventRepository->findByUids($this->settings['eventUids']),
]);
} }
/** public function searchAction(string $search = ''): void
* @param string $search
*/
public function searchAction(): void
{ {
$search = '';
if ($this->request->hasArgument('search')) {
$search = $this->request->getArgument('search');
}
$this->view->assign('search', $search); $this->view->assign('search', $search);
$this->view->assign('events', $this->eventRepository->findSearchWord($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\Core\Utility\GeneralUtility;
use TYPO3\CMS\Extbase\Persistence\Generic\Qom\ConstraintInterface;
use TYPO3\CMS\Extbase\Persistence\QueryInterface; use TYPO3\CMS\Extbase\Persistence\QueryInterface;
use TYPO3\CMS\Extbase\Persistence\QueryResultInterface; use TYPO3\CMS\Extbase\Persistence\QueryResultInterface;
use TYPO3\CMS\Extbase\Persistence\Repository; use TYPO3\CMS\Extbase\Persistence\Repository;
@ -25,33 +26,16 @@ use Wrm\Events\Service\CategoryService;
class EventRepository extends Repository class EventRepository extends Repository
{ {
public function findByUids(string $uids): QueryResultInterface
/**
* Find all products based on selected uids
*
* @param string $uids
*
* @return array
*/
public function findByUids($uids)
{ {
$uids = explode(',', $uids);
$query = $this->createQuery(); $query = $this->createQuery();
//$query->getQuerySettings()->setRespectStoragePage(false); $query->matching($query->in('uid', GeneralUtility::intExplode(',', $uids)));
$query->matching(
$query->in('uid', $uids)
);
//return $this->orderByField($query->execute(), $uids);
return $query->execute(); return $query->execute();
} }
/** /**
* @param EventDemand $demand * @return QueryResultInterface|array
* @return QueryResultInterface
* @throws InvalidQueryException * @throws InvalidQueryException
*/ */
public function findByDemand(EventDemand $demand) public function findByDemand(EventDemand $demand)
@ -66,82 +50,42 @@ class EventRepository extends Repository
} }
/** /**
* @param EventDemand $demand
* @return QueryInterface
* @throws InvalidQueryException * @throws InvalidQueryException
*/ */
protected function createDemandQuery(EventDemand $demand): QueryInterface protected function createDemandQuery(EventDemand $demand): QueryInterface
{ {
$query = $this->createQuery(); $query = $this->createQuery();
$query = $this->setOrderings($query, $demand);
// sorting $constraints = $this->getConstraints($query, $demand);
$sortBy = $demand->getSortBy(); if (!empty($constraints)) {
$sortingsToIgnore = ['singleSelection', 'default']; $query->matching($query->logicalAnd($constraints));
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());
} }
if ($demand->getLimit() !== '') { if ($demand->getLimit() !== '') {
$query->setLimit((int) $demand->getLimit()); $query->setLimit((int) $demand->getLimit());
} }
if (!empty($constraints)) {
$query->matching($query->logicalAnd($constraints));
}
return $query; return $query;
} }
/** private function setOrderings(QueryInterface $query, EventDemand $demand): QueryInterface
* @param QueryInterface $query
* @param string $categories
* @param bool $includeSubCategories
* @return array
* @throws InvalidQueryException
*/
protected function createCategoryConstraint(QueryInterface $query, $categories, bool $includeSubCategories = false): array
{ {
$constraints = []; $sortBy = $demand->getSortBy();
$sortingsToIgnore = ['singleSelection', 'default'];
if ($includeSubCategories) { if (!$sortBy || in_array($sortBy, $sortingsToIgnore)) {
$categoryService = GeneralUtility::makeInstance(CategoryService::class); return $query;
$allCategories = $categoryService->getChildrenCategories($categories);
if (!\is_array($allCategories)) {
$allCategories = GeneralUtility::intExplode(',', $allCategories, true);
}
} else {
$allCategories = GeneralUtility::intExplode(',', $categories, true);
} }
foreach ($allCategories as $category) { $order = QueryInterface::ORDER_ASCENDING;
$constraints[] = $query->contains('categories', $category); 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 private function sortByDemand(QueryInterface $query, EventDemand $demand): array
@ -159,12 +103,60 @@ class EventRepository extends Repository
return $result; 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) public function findSearchWord($search)
{ {
$query = $this->createQuery(); $query = $this->createQuery();
$query->matching( $query->matching($query->like('title', '%' . $search . '%'));
$query->like('title', '%' . $search . '%')
);
$query->setOrderings(['title' => QueryInterface::ORDER_ASCENDING]); $query->setOrderings(['title' => QueryInterface::ORDER_ASCENDING]);
$query->setLimit(20); $query->setLimit(20);
return $query->execute(); return $query->execute();