src/module-elasticsuite-core/Model/Search/RequestBuilder.php
<?php
/**
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade Smile ElasticSuite to newer
* versions in the future.
*
* @category Smile
* @package Smile\ElasticsuiteCore
* @author Aurelien FOUCRET <aurelien.foucret@smile.fr>
* @copyright 2020 Smile
* @license Open Software License ("OSL") v. 3.0
*/
namespace Smile\ElasticsuiteCore\Model\Search;
/**
* ElasticSuite search API implementation : convert search criteria to search request.
*
* @category Smile
* @package Smile\ElasticsuiteCore
* @author Aurelien FOUCRET <aurelien.foucret@smile.fr>
*/
class RequestBuilder
{
/**
* @var integer
*/
const DEFAULT_PAGE_SIZE = 20;
/**
* @var \Smile\ElasticsuiteCore\Search\Request\Builder
*/
private $searchRequestBuilder;
/**
* @var \Magento\Store\Model\StoreManagerInterface
*/
private $storeManager;
/**
* @var \Smile\ElasticsuiteCore\Api\Search\Request\ContainerConfigurationInterfaceFactory
*/
private $containerConfigFactory;
/**
* @var RequestMapper
*/
private $requestMapper;
/**
* @var \Smile\ElasticsuiteCore\Api\Search\ContextInterface
*/
private $searchContext;
/**
* @var \Magento\Search\Model\QueryFactory
*/
private $queryFactory;
/**
* Constructor.
*
* @param \Smile\ElasticsuiteCore\Search\Request\Builder $searchRequestBuilder Search request
* builder.
* @param \Magento\Store\Model\StoreManagerInterface $storeManager Store resolver.
* @param \Smile\ElasticsuiteCore\Api\Search\Request\ContainerConfigurationInterfaceFactory $containerConfigFactory Container config
* factory.
* @param \Smile\ElasticsuiteCore\Api\Search\ContextInterface $searchContext Search context.
* @param \Magento\Search\Model\QueryFactory $queryFactory Search query factory
* @param RequestMapper $requestMapper Request mapper.
*/
public function __construct(
\Smile\ElasticsuiteCore\Search\Request\Builder $searchRequestBuilder,
\Magento\Store\Model\StoreManagerInterface $storeManager,
\Smile\ElasticsuiteCore\Api\Search\Request\ContainerConfigurationInterfaceFactory $containerConfigFactory,
\Smile\ElasticsuiteCore\Api\Search\ContextInterface $searchContext,
\Magento\Search\Model\QueryFactory $queryFactory,
RequestMapper $requestMapper
) {
$this->searchRequestBuilder = $searchRequestBuilder;
$this->storeManager = $storeManager;
$this->requestMapper = $requestMapper;
$this->containerConfigFactory = $containerConfigFactory;
$this->searchContext = $searchContext;
$this->queryFactory = $queryFactory;
}
/**
* Build a search request from a search criteria.
*
* @param \Smile\ElasticsuiteCore\Api\Search\SearchCriteriaInterface $searchCriteria Search criteria.
*
* @return \Smile\ElasticsuiteCore\Search\RequestInterface
*/
public function getRequest(\Smile\ElasticsuiteCore\Api\Search\SearchCriteriaInterface $searchCriteria)
{
$storeId = $this->getCurrentStoreId();
$containerName = $searchCriteria->getRequestName();
$containerConfiguration = $this->getSearchContainerConfiguration($storeId, $containerName);
$size = $searchCriteria->getPageSize() ?? self::DEFAULT_PAGE_SIZE;
$from = max(0, (int) $searchCriteria->getCurrentPage() - 1) * $size;
$queryText = $this->getFulltextFilter($searchCriteria);
$this->updateSearchContext($storeId, $queryText);
$sortOrders = $this->requestMapper->getSortOrders($containerConfiguration, $searchCriteria);
$filters = $this->requestMapper->getFilters($containerConfiguration, $searchCriteria);
$trackTotalHits = $searchCriteria->getTrackTotalHits() ?? null;
return $this->searchRequestBuilder->create(
$storeId,
$containerName,
$from,
$size,
$queryText,
$sortOrders,
$filters,
[],
[],
$trackTotalHits
);
}
/**
* Update the search context using current store id and query text.
*
* @param integer $storeId Store id.
* @param string $queryText Fulltext query text.
*
* @return void
*/
private function updateSearchContext($storeId, $queryText)
{
$this->searchContext->setStoreId($storeId);
$query = $this->queryFactory->create();
$query->setStoreId($storeId);
$query->loadByQueryText($queryText);
if ($query->getId()) {
$this->searchContext->setCurrentSearchQuery($query);
}
}
/**
* Return current store id.
*
* @return integer
*/
private function getCurrentStoreId()
{
$storeId = $this->storeManager->getStore()->getId();
if ($storeId == 0) {
$storeId = $this->storeManager->getDefaultStoreView()->getId();
}
return $storeId;
}
/**
* Extract fulltext search query from search criteria.
*
* @param \Magento\Framework\Api\Search\SearchCriteriaInterface $searchCriteria Search criteria.
*
* @return NULL|string
*/
private function getFulltextFilter(\Magento\Framework\Api\Search\SearchCriteriaInterface $searchCriteria)
{
$queryText = null;
foreach ($searchCriteria->getFilterGroups() as $filterGroup) {
foreach ($filterGroup->getFilters() as $filter) {
if ($filter->getField() == "search_term") {
$queryText = $filter->getValue();
}
}
}
return $queryText;
}
/**
* Get current search container.
*
* @param int $storeId Store id.
* @param string $containerName Container name.
*
* @return \Smile\ElasticsuiteCore\Api\Search\Request\ContainerConfigurationInterface
*/
private function getSearchContainerConfiguration($storeId, $containerName)
{
return $this->containerConfigFactory->create(['storeId' => $storeId, 'containerName' => $containerName]);
}
}