Commit 89035ae7 authored by Tino Goratsch's avatar Tino Goratsch

refactored the search module to register the available module via a compiler pass

parent e2aab40e
<?php
/**
* Copyright (c) 2016 by the ACP3 Developers.
* See the LICENCE file at the top-level module directory for licencing details.
*/
namespace ACP3\Modules\ACP3\Articles\Event\Listener;
use ACP3\Modules\ACP3\Search\Event\AvailableModulesEvent;
/**
* Class OnAvailableModulesListener
* @package ACP3\Modules\ACP3\Articles\Event\Listener
*/
class OnAvailableModulesListener
{
/**
* @param \ACP3\Modules\ACP3\Search\Event\AvailableModulesEvent $availableModules
*/
public function onAvailableModules(AvailableModulesEvent $availableModules)
{
$availableModules->addAvailableModule('articles');
}
}
......@@ -9,22 +9,6 @@ services:
tags:
- { name: core.eventListener, event: articles.model.articles.after_delete, method: execute }
articles.events.on_available_modules_listener:
class: ACP3\Modules\ACP3\Articles\Event\Listener\OnAvailableModulesListener
tags:
- { name: core.eventListener, event: search.events.availableModules, method: onAvailableModules }
articles.events.on_display_search_results_listener:
class: ACP3\Modules\ACP3\Articles\Event\Listener\OnDisplaySearchResultsListener
arguments:
- '@core.acl'
- '@core.date'
- '@core.lang'
- '@core.router'
- '@articles.model.articlerepository'
tags:
- { name: core.eventListener, event: search.events.displaySearchResults, method: onDisplaySearchResults }
articles.events.update_article_cache_on_model_save_after_listener:
class: ACP3\Modules\ACP3\Articles\Event\Listener\UpdateArticleCacheOnModelSaveAfterListener
arguments:
......
services:
articles.search.search_availability:
class: ACP3\Modules\ACP3\Articles\Search\SearchAvailability
arguments:
- '@core.acl'
- '@core.date'
- '@core.router'
- '@articles.model.articlerepository'
tags:
- { name: search.available_module }
......@@ -4,6 +4,7 @@ imports:
- { resource: components/events.yml }
- { resource: components/installer.yml }
- { resource: components/models.yml }
- { resource: components/search.yml }
- { resource: components/validation.yml }
services:
......
......@@ -4,20 +4,17 @@
* See the LICENCE file at the top-level module directory for licencing details.
*/
namespace ACP3\Modules\ACP3\Articles\Event\Listener;
namespace ACP3\Modules\ACP3\Articles\Search;
use ACP3\Core\ACL;
use ACP3\Core\Date;
use ACP3\Core\I18n\Translator;
use ACP3\Core\Router\RouterInterface;
use ACP3\Modules\ACP3\Articles\Installer\Schema;
use ACP3\Modules\ACP3\Articles\Model\Repository\ArticleRepository;
use ACP3\Modules\ACP3\Search\Event\SearchResultsEvent;
use ACP3\Modules\ACP3\Search\Utility\SearchAvailabilityInterface;
/**
* Class OnDisplaySearchResultsListener
* @package ACP3\Modules\ACP3\Articles\Event\Listener
*/
class OnDisplaySearchResultsListener
class SearchAvailability implements SearchAvailabilityInterface
{
/**
* @var \ACP3\Core\ACL
......@@ -27,10 +24,6 @@ class OnDisplaySearchResultsListener
* @var \ACP3\Core\Date
*/
private $date;
/**
* @var \ACP3\Core\I18n\Translator
*/
private $translator;
/**
* @var \ACP3\Core\Router\RouterInterface
*/
......@@ -41,42 +34,47 @@ class OnDisplaySearchResultsListener
private $articleRepository;
/**
* OnDisplaySearchResultsListener constructor.
*
* @param \ACP3\Core\ACL $acl
* @param \ACP3\Core\Date $date
* @param \ACP3\Core\I18n\Translator $translator
* @param \ACP3\Core\Router\RouterInterface $router
* @param \ACP3\Modules\ACP3\Articles\Model\Repository\ArticleRepository $articleRepository
* SearchAvailability constructor.
* @param ACL $acl
* @param Date $date
* @param RouterInterface $router
* @param ArticleRepository $articleRepository
*/
public function __construct(
ACL $acl,
Date $date,
Translator $translator,
RouterInterface $router,
ArticleRepository $articleRepository
) {
$this->acl = $acl;
$this->date = $date;
$this->translator = $translator;
$this->router = $router;
$this->articleRepository = $articleRepository;
}
/**
* @param \ACP3\Modules\ACP3\Search\Event\SearchResultsEvent $displaySearchResults
* @return string
*/
public function getModuleName()
{
return Schema::MODULE_NAME;
}
/**
* @param string $searchTerm
* @param string $areas
* @param string $sortDirection
* @return array
*/
public function onDisplaySearchResults(SearchResultsEvent $displaySearchResults)
public function fetchSearchResults($searchTerm, $areas, $sortDirection)
{
if (in_array('articles', $displaySearchResults->getModules())
&& $this->acl->hasPermission('frontend/articles') === true
) {
$fields = $this->mapSearchAreasToFields($displaySearchResults->getAreas());
if ($this->acl->hasPermission('frontend/articles') === true) {
$fields = $this->mapSearchAreasToFields($areas);
$results = $this->articleRepository->getAllSearchResults(
$fields,
$displaySearchResults->getSearchTerm(),
$displaySearchResults->getSortDirection(),
$searchTerm,
$sortDirection,
$this->date->getCurrentDateTime()
);
$cResults = count($results);
......@@ -91,12 +89,11 @@ class OnDisplaySearchResultsListener
);
}
$displaySearchResults->addSearchResultsByModule(
$this->translator->t('articles', 'articles'),
$searchResults
);
return $searchResults;
}
}
return [];
}
/**
......
<?php
namespace ACP3\Modules\ACP3\Files\Event\Listener;
use ACP3\Modules\ACP3\Search\Event\AvailableModulesEvent;
/**
* Class OnAvailableModulesListener
* @package ACP3\Modules\ACP3\Files\Event\Listener
*/
class OnAvailableModulesListener
{
/**
* @param \ACP3\Modules\ACP3\Search\Event\AvailableModulesEvent $availableModules
*/
public function onAvailableModules(AvailableModulesEvent $availableModules)
{
$availableModules->addAvailableModule('files');
}
}
......@@ -120,7 +120,7 @@ class FilesRepository extends Core\Model\Repository\AbstractRepository
{
$period = ' AND ' . $this->getPublicationPeriod();
return $this->db->fetchAll(
'SELECT id, title, `text` FROM ' . $this->getTableName() . ' WHERE MATCH (' . $fields . ') AGAINST (' . $this->db->getConnection()->quote($searchTerm) . ' IN BOOLEAN MODE)' . $period . ' ORDER BY `start` ' . $sortDirection . ', `end` ' . $sortDirection . ', id ' . $sortDirection,
'SELECT id, title, `text` FROM ' . $this->getTableName() . ' WHERE MATCH(' . $fields . ') AGAINST (' . $this->db->getConnection()->quote($searchTerm) . ' IN BOOLEAN MODE)' . $period . ' ORDER BY `start` ' . $sortDirection . ', `end` ' . $sortDirection . ', id ' . $sortDirection,
['time' => $time]
);
}
......
......@@ -22,22 +22,6 @@ services:
tags:
- { name: core.eventListener, event: feeds.events.displayFeed.files, method: onDisplayFeed }
files.event.on_available_modules_listener:
class: ACP3\Modules\ACP3\Files\Event\Listener\OnAvailableModulesListener
tags:
- { name: core.eventListener, event: search.events.availableModules, method: onAvailableModules }
files.event.on_display_search_results_listener:
class: ACP3\Modules\ACP3\Files\Event\Listener\OnDisplaySearchResultsListener
arguments:
- '@core.acl'
- '@core.date'
- '@core.lang'
- '@core.router'
- '@files.model.filesrepository'
tags:
- { name: core.eventListener, event: search.events.displaySearchResults, method: onDisplaySearchResults }
files.event.update_file_cache_on_model_after_save_listener:
class: ACP3\Modules\ACP3\Files\Event\Listener\UpdateFileCacheOnModelAfterSaveListener
arguments:
......
services:
files.search.search_availability:
class: ACP3\Modules\ACP3\Files\Search\SearchAvailability
arguments:
- '@core.acl'
- '@core.date'
- '@core.router'
- '@files.model.filesrepository'
tags:
- { name: search.available_module }
......@@ -4,4 +4,5 @@ imports:
- { resource: components/events.yml }
- { resource: components/installer.yml }
- { resource: components/models.yml }
- { resource: components/search.yml }
- { resource: components/validation.yml }
<?php
namespace ACP3\Modules\ACP3\Files\Event\Listener;
/**
* Copyright (c) 2016 by the ACP3 Developers.
* See the LICENCE file at the top-level module directory for licencing details.
*/
namespace ACP3\Modules\ACP3\Files\Search;
use ACP3\Core\ACL;
use ACP3\Core\Date;
use ACP3\Core\I18n\Translator;
use ACP3\Core\Router\RouterInterface;
use ACP3\Modules\ACP3\Files\Installer\Schema;
use ACP3\Modules\ACP3\Files\Model\Repository\FilesRepository;
use ACP3\Modules\ACP3\Search\Event\SearchResultsEvent;
use ACP3\Modules\ACP3\Search\Utility\SearchAvailabilityInterface;
/**
* Class OnDisplaySearchResultsListener
* @package ACP3\Modules\ACP3\Files\Event\Listener
*/
class OnDisplaySearchResultsListener
class SearchAvailability implements SearchAvailabilityInterface
{
/**
* @var \ACP3\Core\ACL
......@@ -22,10 +24,6 @@ class OnDisplaySearchResultsListener
* @var \ACP3\Core\Date
*/
private $date;
/**
* @var \ACP3\Core\I18n\Translator
*/
private $translator;
/**
* @var \ACP3\Core\Router\RouterInterface
*/
......@@ -38,40 +36,46 @@ class OnDisplaySearchResultsListener
/**
* OnDisplaySearchResultsListener constructor.
*
* @param \ACP3\Core\ACL $acl
* @param \ACP3\Core\Date $date
* @param \ACP3\Core\I18n\Translator $translator
* @param \ACP3\Core\Router\RouterInterface $router
* @param \ACP3\Core\ACL $acl
* @param \ACP3\Core\Date $date
* @param \ACP3\Core\Router\RouterInterface $router
* @param \ACP3\Modules\ACP3\Files\Model\Repository\FilesRepository $filesRepository
*/
public function __construct(
ACL $acl,
Date $date,
Translator $translator,
RouterInterface $router,
FilesRepository $filesRepository
) {
$this->acl = $acl;
$this->date = $date;
$this->translator = $translator;
$this->router = $router;
$this->filesRepository = $filesRepository;
}
/**
* @param \ACP3\Modules\ACP3\Search\Event\SearchResultsEvent $displaySearchResults
* @return string
*/
public function getModuleName()
{
return Schema::MODULE_NAME;
}
/**
* @param string $searchTerm
* @param string $areas
* @param string $sortDirection
* @return array
*/
public function onDisplaySearchResults(SearchResultsEvent $displaySearchResults)
public function fetchSearchResults($searchTerm, $areas, $sortDirection)
{
if (in_array('files', $displaySearchResults->getModules())
&& $this->acl->hasPermission('frontend/files') === true
) {
$fields = $this->mapSearchAreasToFields($displaySearchResults->getAreas());
if ($this->acl->hasPermission('frontend/files') === true) {
$fields = $this->mapSearchAreasToFields($areas);
$results = $this->filesRepository->getAllSearchResults(
$fields,
$displaySearchResults->getSearchTerm(),
$displaySearchResults->getSortDirection(),
$searchTerm,
$sortDirection,
$this->date->getCurrentDateTime()
);
$cResults = count($results);
......@@ -86,12 +90,11 @@ class OnDisplaySearchResultsListener
);
}
$displaySearchResults->addSearchResultsByModule(
$this->translator->t('files', 'files'),
$searchResults
);
return $searchResults;
}
}
return [];
}
/**
......
<?php
namespace ACP3\Modules\ACP3\News\Event\Listener;
use ACP3\Modules\ACP3\Search\Event\AvailableModulesEvent;
/**
* Class OnAvailableModulesListener
* @package ACP3\Modules\ACP3\News\Event\Listener
*/
class OnAvailableModulesListener
{
/**
* @param \ACP3\Modules\ACP3\Search\Event\AvailableModulesEvent $availableModules
*/
public function onAvailableModules(AvailableModulesEvent $availableModules)
{
$availableModules->addAvailableModule('news');
}
}
......@@ -118,7 +118,7 @@ class NewsRepository extends Core\Model\Repository\AbstractRepository
{
$period = ' AND ' . $this->getPublicationPeriod();
return $this->db->fetchAll(
'SELECT id, title, `text` FROM ' . $this->getTableName() . ' WHERE MATCH (' . $fields . ') AGAINST (' . $this->db->getConnection()->quote($searchTerm) . ' IN BOOLEAN MODE)' . $period . ' ORDER BY `start` ' . $sort . ', `end` ' . $sort . ', id ' . $sort,
'SELECT id, title, `text` FROM ' . $this->getTableName() . ' WHERE MATCH(' . $fields . ') AGAINST (' . $this->db->getConnection()->quote($searchTerm) . ' IN BOOLEAN MODE)' . $period . ' ORDER BY `start` ' . $sort . ', `end` ' . $sort . ', id ' . $sort,
['time' => $time]
);
}
......
......@@ -20,22 +20,6 @@ services:
tags:
- { name: core.eventListener, event: feeds.events.displayFeed.news, method: onDisplayFeed }
news.event.on_available_modules_listener:
class: ACP3\Modules\ACP3\News\Event\Listener\OnAvailableModulesListener
tags:
- { name: core.eventListener, event: search.events.availableModules, method: onAvailableModules }
news.event.on_display_search_results_listener:
class: ACP3\Modules\ACP3\News\Event\Listener\OnDisplaySearchResultsListener
arguments:
- '@core.acl'
- '@core.date'
- '@core.lang'
- '@core.router'
- '@news.model.newsrepository'
tags:
- { name: core.eventListener, event: search.events.displaySearchResults, method: onDisplaySearchResults }
news.event.update_news_cache_on_model_after_save_listener:
class: ACP3\Modules\ACP3\News\Event\Listener\UpdateNewsCacheOnModelAfterSaveListener
arguments:
......
services:
news.search.search_availability:
class: ACP3\Modules\ACP3\News\Search\SearchAvailability
arguments:
- '@core.acl'
- '@core.date'
- '@core.router'
- '@news.model.newsrepository'
tags:
- { name: search.available_module }
......@@ -4,4 +4,5 @@ imports:
- { resource: components/events.yml }
- { resource: components/installer.yml }
- { resource: components/models.yml }
- { resource: components/search.yml }
- { resource: components/validation.yml }
<?php
namespace ACP3\Modules\ACP3\News\Event\Listener;
/**
* Copyright (c) 2016 by the ACP3 Developers.
* See the LICENCE file at the top-level module directory for licencing details.
*/
namespace ACP3\Modules\ACP3\News\Search;
use ACP3\Core\ACL;
use ACP3\Core\Date;
use ACP3\Core\I18n\Translator;
use ACP3\Core\Router\RouterInterface;
use ACP3\Modules\ACP3\News\Installer\Schema;
use ACP3\Modules\ACP3\News\Model\Repository\NewsRepository;
use ACP3\Modules\ACP3\Search\Event\SearchResultsEvent;
use ACP3\Modules\ACP3\Search\Utility\SearchAvailabilityInterface;
/**
* Class OnDisplaySearchResultsListener
* @package ACP3\Modules\ACP3\News\Event\Listener
*/
class OnDisplaySearchResultsListener
class SearchAvailability implements SearchAvailabilityInterface
{
/**
* @var \ACP3\Core\ACL
......@@ -22,10 +24,6 @@ class OnDisplaySearchResultsListener
* @var \ACP3\Core\Date
*/
private $date;
/**
* @var \ACP3\Core\I18n\Translator
*/
private $translator;
/**
* @var \ACP3\Core\Router\RouterInterface
*/
......@@ -38,46 +36,53 @@ class OnDisplaySearchResultsListener
/**
* OnDisplaySearchResultsListener constructor.
*
* @param \ACP3\Core\ACL $acl
* @param \ACP3\Core\Date $date
* @param \ACP3\Core\I18n\Translator $translator
* @param \ACP3\Core\Router\RouterInterface $router
* @param \ACP3\Core\ACL $acl
* @param \ACP3\Core\Date $date
* @param \ACP3\Core\Router\RouterInterface $router
* @param \ACP3\Modules\ACP3\News\Model\Repository\NewsRepository $newsRepository
*/
public function __construct(
ACL $acl,
Date $date,
Translator $translator,
RouterInterface $router,
NewsRepository $newsRepository
) {
$this->acl = $acl;
$this->date = $date;
$this->translator = $translator;
$this->router = $router;
$this->newsRepository = $newsRepository;
}
/**
* @param \ACP3\Modules\ACP3\Search\Event\SearchResultsEvent $displaySearchResults
* @return string
*/
public function getModuleName()
{
return Schema::MODULE_NAME;
}
/**
* @param string $searchTerm
* @param string $areas
* @param string $sortDirection
* @return array
*/
public function onDisplaySearchResults(SearchResultsEvent $displaySearchResults)
public function fetchSearchResults($searchTerm, $areas, $sortDirection)
{
if (in_array('news', $displaySearchResults->getModules())
&& $this->acl->hasPermission('frontend/news') === true) {
$fields = $this->mapSearchAreasToFields($displaySearchResults->getAreas());
if ($this->acl->hasPermission('frontend/news') === true) {
$fields = $this->mapSearchAreasToFields($areas);
$results = $this->newsRepository->getAllSearchResults(
$fields,
$displaySearchResults->getSearchTerm(),
$displaySearchResults->getSortDirection(),
$searchTerm,
$sortDirection,
$this->date->getCurrentDateTime()
);
$cResults = count($results);
if ($cResults > 0) {
$searchResults = [];
$searchResults['dir'] = 'news';
$searchResults['dir'] = $this->getModuleName();
for ($i = 0; $i < $cResults; ++$i) {
$searchResults['results'][$i] = $results[$i];
$searchResults['results'][$i]['hyperlink'] = $this->router->route(
......@@ -85,12 +90,11 @@ class OnDisplaySearchResultsListener
);
}
$displaySearchResults->addSearchResultsByModule(
$this->translator->t('news', 'news'),
$searchResults
);
return $searchResults;
}
}
return [];
}
/**
......
......@@ -27,24 +27,31 @@ class Index extends Core\Controller\AbstractFrontendAction
* @var \ACP3\Core\Helpers\Forms
*/
protected $formsHelper;
/**
* @var Search\Utility\AvailableModulesRegistrar
*/
protected $availableModulesRegistrar;
/**
* @param \ACP3\Core\Controller\Context\FrontendContext $context
* @param \ACP3\Core\Helpers\Forms $formsHelper
* @param \ACP3\Modules\ACP3\Search\Helpers $searchHelpers
* @param \ACP3\Modules\ACP3\Search\Validation\FormValidation $searchValidator
* @param Search\Utility\AvailableModulesRegistrar $availableModulesRegistrar
*/
public function __construct(
Core\Controller\Context\FrontendContext $context,
Core\Helpers\Forms $formsHelper,
Search\Helpers $searchHelpers,
Search\Validation\FormValidation $searchValidator
Search\Validation\FormValidation $searchValidator,
Search\Utility\AvailableModulesRegistrar $availableModulesRegistrar
) {
parent::__construct($context);
$this->formsHelper = $formsHelper;
$this->searchHelpers = $searchHelpers;
$this->searchValidator = $searchValidator;
$this->availableModulesRegistrar = $availableModulesRegistrar;
}
/**
......@@ -143,12 +150,10 @@ class Index extends Core\Controller\AbstractFrontendAction
->append($this->translator->t('search', 'search'), 'search')
->append($this->translator->t('search', 'search_results'));
$searchResultsEvent = new Search\Event\SearchResultsEvent($modules, $searchTerm, $area, $sort);
$this->eventDispatcher->dispatch('search.events.displaySearchResults', $searchResultsEvent);
$this->setTemplate('Search/Frontend/index.results.tpl');
$searchResults = $searchResultsEvent->getSearchResults();
$searchResults = $this->processSearchResults($modules, $searchTerm, $area, $sort);
if (!empty($searchResults)) {
ksort($searchResults);
return [
......@@ -164,4 +169,26 @@ class Index extends Core\Controller\AbstractFrontendAction
)
];
}
/**
* @param array $modules
* @param string $searchTerm
* @param string $area
* @param string $sort
* @return array
*/
protected function processSearchResults(array $modules, $searchTerm, $area, $sort)
{
$searchResults = [];
foreach ($this->availableModulesRegistrar->getAvailableModules() as $moduleName => $searchAvailability) {
if (in_array($moduleName, $modules)) {
$results = $searchAvailability->fetchSearchResults($searchTerm, $area, $sort);
if (!empty($results)) {
$searchResults[$moduleName] = $results;
}
}
}
return $searchResults;
}
}
<?php
/**
* Copyright (c) 2016 by the ACP3 Developers.
* See the LICENCE file at the top-level module directory for licencing details.
*/
namespace ACP3\Modules\ACP3\Search\DependencyInjection;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;
class SearchAvailabilityCompilerPass implements CompilerPassInterface
{
/**
* You can modify the container here before it is dumped to PHP code.
*
* @param ContainerBuilder $container
*/
public function process(ContainerBuilder $container)
{
$definition = $container->findDefinition('search.utility.available_modules_registrar');
$plugins = $container->findTaggedServiceIds('search.available_module');
foreach ($plugins as $serviceId => $tags) {
$definition->addMethodCall(
'registerModule',
[new Reference($serviceId)]
);
}
}
}
<?php
namespace ACP3\Modules\ACP3\Search\Event;
use Symfony\Component\EventDispatcher\Event;
/**
* Class AvailableModulesEvent
* @package ACP3\Modules\ACP3\Search\Event
*/
class AvailableModulesEvent extends Event
{
/**
* @var array
*/
private $availableModules = [];
/**
* @return array