search_core/Classes/Domain/Search/SearchService.php
Daniel Siepmann 769fb8237b
TASK: Add data processing to search result
Search results are now processed through data processing by search
service. The result will be a SearchResult model from our domain. Also
SearchResult will execute new queries, e.g. from paginate widget,
through SearchService to apply data processing again.

Remove duplicate stub code to trait, to keep own logic and code clean.
2018-03-06 09:04:47 +01:00

181 lines
5.7 KiB
PHP

<?php
namespace Codappix\SearchCore\Domain\Search;
/*
* Copyright (C) 2016 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 Codappix\SearchCore\Configuration\ConfigurationContainerInterface;
use Codappix\SearchCore\Configuration\InvalidArgumentException;
use Codappix\SearchCore\Connection\ConnectionInterface;
use Codappix\SearchCore\Connection\SearchRequestInterface;
use Codappix\SearchCore\Connection\SearchResultInterface;
use Codappix\SearchCore\DataProcessing\Service as DataProcessorService;
use Codappix\SearchCore\Domain\Model\FacetRequest;
use Codappix\SearchCore\Domain\Model\SearchResult;
use TYPO3\CMS\Core\Utility\ArrayUtility;
use TYPO3\CMS\Extbase\Object\ObjectManagerInterface;
/**
* Service to process a search request.
*/
class SearchService
{
/**
* @var ConnectionInterface
*/
protected $connection;
/**
* @var ConfigurationContainerInterface
*/
protected $configuration;
/**
* @var ObjectManagerInterface
*/
protected $objectManager;
/**
* @var DataProcessorService
*/
protected $dataProcessorService;
/**
* @param ConnectionInterface $connection
* @param ConfigurationContainerInterface $configuration
* @param ObjectManagerInterface $objectManager
* @param DataProcessorService $dataProcessorService
*/
public function __construct(
ConnectionInterface $connection,
ConfigurationContainerInterface $configuration,
ObjectManagerInterface $objectManager,
DataProcessorService $dataProcessorService
) {
$this->connection = $connection;
$this->configuration = $configuration;
$this->objectManager = $objectManager;
$this->dataProcessorService = $dataProcessorService;
}
/**
* @param SearchRequestInterface $searchRequest
* @return SearchResultInterface
*/
public function search(SearchRequestInterface $searchRequest)
{
$this->addSize($searchRequest);
$this->addConfiguredFacets($searchRequest);
$this->addConfiguredFilters($searchRequest);
// Add connection to request to enable paginate widget support
$searchRequest->setConnection($this->connection);
$searchRequest->setSearchService($this);
return $this->processResult($this->connection->search($searchRequest));
}
/**
* Add configured size of search result items to request.
*
* @param SearchRequestInterface $searchRequest
*/
protected function addSize(SearchRequestInterface $searchRequest)
{
$searchRequest->setLimit(
$this->configuration->getIfExists('searching.size') ?: 10
);
}
/**
* Add facets from configuration to request.
*
* @param SearchRequestInterface $searchRequest
*/
protected function addConfiguredFacets(SearchRequestInterface $searchRequest)
{
$facetsConfig = $this->configuration->getIfExists('searching.facets');
if ($facetsConfig === null) {
return;
}
foreach ($facetsConfig as $identifier => $facetConfig) {
if (!isset($facetConfig['field']) || trim($facetConfig['field']) === '') {
// TODO: Finish throw
throw new \Exception('message', 1499171142);
}
$searchRequest->addFacet($this->objectManager->get(
FacetRequest::class,
$identifier,
$facetConfig['field']
));
}
}
/**
* Add filters from configuration, e.g. flexform or TypoScript.
*
* @param SearchRequestInterface $searchRequest
*/
protected function addConfiguredFilters(SearchRequestInterface $searchRequest)
{
try {
$filter = $searchRequest->getFilter();
ArrayUtility::mergeRecursiveWithOverrule(
$filter,
$this->configuration->get('searching.filter'),
true,
false
);
$searchRequest->setFilter($filter);
} catch (InvalidArgumentException $e) {
// Nothing todo, no filter configured.
}
}
/**
* Processes the result, e.g. applies configured data processing to result.
*/
public function processResult(SearchResultInterface $searchResult) : SearchResultInterface
{
try {
$newSearchResultItems = [];
foreach ($this->configuration->get('searching.dataProcessing') as $configuration) {
foreach ($searchResult as $resultItem) {
$newSearchResultItems[] = $this->dataProcessorService->executeDataProcessor(
$configuration,
$resultItem->getPlainData()
);
}
}
return $this->objectManager->get(
SearchResult::class,
$searchResult,
$newSearchResultItems
);
}
catch (InvalidArgumentException $e) {
return $searchResult;
}
}
}