Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix search api #700

Merged
merged 3 commits into from
Jan 22, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
212 changes: 212 additions & 0 deletions src/module-elasticsuite-catalog/Plugin/Search/RequestMapperPlugin.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,212 @@
<?php
/**
* DISCLAIMER
* Do not edit or add to this file if you wish to upgrade Smile Elastic Suite to newer
* versions in the future.
*
* @category Smile
* @package Smile\ElasticsuiteCatalog
* @author Aurelien FOUCRET <[email protected]>
* @copyright 2018 Smile
* @license Open Software License ("OSL") v. 3.0
*/
namespace Smile\ElasticsuiteCatalog\Plugin\Search;

use Smile\ElasticsuiteCore\Model\Search\RequestMapper;
use Smile\ElasticsuiteCore\Api\Search\Request\ContainerConfigurationInterface;
use Magento\Framework\Api\Search\SearchCriteriaInterface;
use Smile\ElasticsuiteCore\Search\Request\SortOrderInterface;

/**
* Apply catalog product settings to the search API request mapper.
*
* @category Smile
* @package Smile\ElasticsuiteCatalog
* @author Aurelien FOUCRET <[email protected]>
*/
class RequestMapperPlugin
{
/**
* @var array
*/
private $productSearchContainers = [
'quick_search_container',
'catalog_view_container',
];

/**
* @var array
*/
private $fieldMapper = [
'price' => 'price.price',
'position' => 'category.position',
'category_ids' => 'category.category_id',
];

/**
* @var \Magento\Customer\Model\Session
*/
private $customerSession;

/**
* @var \Magento\Store\Model\StoreManagerInterface
*/
private $storeManager;

/**
* @var \Smile\ElasticsuiteCore\Helper\Mapping
*/
private $mappingHelper;

/**
* Constructor.
*
* @param \Magento\Customer\Model\Session $customerSession Customer session.
* @param \Magento\Store\Model\StoreManagerInterface $storeManager Store manager.
* @param \Smile\ElasticsuiteCore\Helper\Mapping $mappingHelper Mapping helper.
*/
public function __construct(
\Magento\Customer\Model\Session $customerSession,
\Magento\Store\Model\StoreManagerInterface $storeManager,
\Smile\ElasticsuiteCore\Helper\Mapping $mappingHelper
) {
$this->customerSession = $customerSession;
$this->storeManager = $storeManager;
$this->mappingHelper = $mappingHelper;
}

/**
* Post process catalog sort orders.
*
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*
* @param RequestMapper $subject Request mapper.
* @param array $result Original sort orders.
* @param ContainerConfigurationInterface $containerConfiguration Container configuration.
* @param SearchCriteriaInterface $searchCriteria Search criteria.
*
* @return array[]
*/
public function afterGetSortOrders(
RequestMapper $subject,
$result,
ContainerConfigurationInterface $containerConfiguration,
SearchCriteriaInterface $searchCriteria
) {
if ($this->isEnabled($containerConfiguration)) {
$sortOrders = [];

if ($containerConfiguration->getName() == "catalog_view_container" && empty($result)) {
$result['position'] = ['direction' => SortOrderInterface::SORT_ASC];
}

foreach ($result as $sortField => $sortParams) {
if ($sortField == 'price') {
$sortParams['nestedFilter'] = ['price.customer_group_id' => $this->customerSession->getCustomerGroupId()];
} elseif ($sortField == 'position') {
$categoryId = $this->getCurrentCategoryId($containerConfiguration, $searchCriteria);
$sortParams['nestedFilter'] = ['category.category_id' => $categoryId];
}

$sortOrders[$this->getMappingField($containerConfiguration, $sortField)] = $sortParams;
}

$result = $sortOrders;
}

return $result;
}

/**
* Post process catalog filters.
*
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*
* @param RequestMapper $subject Request mapper.
* @param array $result Original filters.
* @param ContainerConfigurationInterface $containerConfiguration Container configuration.
* @param SearchCriteriaInterface $searchCriteria Search criteria.
*
* @return array[]
*/
public function afterGetFilters(
RequestMapper $subject,
$result,
ContainerConfigurationInterface $containerConfiguration,
SearchCriteriaInterface $searchCriteria
) {
if ($this->isEnabled($containerConfiguration)) {
$filters = [];

foreach ($result as $fieldName => $filterValue) {
$fieldName = $this->getMappingField($containerConfiguration, $fieldName);
$filters[$fieldName] = $filterValue;
}

$result = $filters;
}

return $result;
}

/**
* Name of the field in the search engine mapping.
*
* @param ContainerConfigurationInterface $containerConfiguration Container configuration.
* @param string $fieldName Request field name.
*
* @return string
*/
private function getMappingField(ContainerConfigurationInterface $containerConfiguration, $fieldName)
{
if (isset($this->fieldMapper[$fieldName])) {
$fieldName = $this->fieldMapper[$fieldName];
}

try {
$optionTextFieldName = $this->mappingHelper->getOptionTextFieldName($fieldName);
$containerConfiguration->getMapping()->getField($optionTextFieldName);
$fieldName = $optionTextFieldName;
} catch (\Exception $e) {
;
}

return $fieldName;
}

/**
* Return current category id for the search request.
*
* @param ContainerConfigurationInterface $containerConfiguration Container configuration.
* @param SearchCriteriaInterface $searchCriteria Search criteria.
*
* @return integer
*/
private function getCurrentCategoryId(ContainerConfigurationInterface $containerConfiguration, SearchCriteriaInterface $searchCriteria)
{
$store = $this->storeManager->getStore($containerConfiguration->getStoreId());
$categoryId = $this->storeManager->getGroup($store->getStoreGroupId())->getRootCategoryId();

foreach ($searchCriteria->getFilterGroups() as $filterGroup) {
foreach ($filterGroup->getFilters() as $filter) {
if ($filter->getField() == "category_ids") {
$categoryId = $filter->getValue();
}
}
}

return $categoryId;
}

/**
* Indicates if the plugin should be used or not.
*
* @param ContainerConfigurationInterface $containerConfiguration Container configuration.
*
* @return boolean
*/
private function isEnabled(ContainerConfigurationInterface $containerConfiguration)
{
return in_array($containerConfiguration->getName(), $this->productSearchContainers);
}
}
4 changes: 4 additions & 0 deletions src/module-elasticsuite-catalog/etc/di.xml
Original file line number Diff line number Diff line change
Expand Up @@ -200,4 +200,8 @@
</argument>
</arguments>
</type>

<type name="Smile\ElasticsuiteCore\Model\Search\RequestMapper">
<plugin name="catalogProductRequestMapper" type="Smile\ElasticsuiteCatalog\Plugin\Search\RequestMapperPlugin" sortOrder="10"/>
</type>
</config>
77 changes: 77 additions & 0 deletions src/module-elasticsuite-core/Model/Search.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
<?php
/**
* DISCLAIMER
* Do not edit or add to this file if you wish to upgrade Smile Elastic Suite to newer
* versions in the future.
*
* @category Smile
* @package Smile\ElasticsuiteCore
* @author Aurelien FOUCRET <[email protected]>
* @copyright 2016 Smile
* @license Open Software License ("OSL") v. 3.0
*/

namespace Smile\ElasticSuiteCore\Model;

/**
* SearchInterface implementation using elasticsuite.
*
* @category Smile
* @package Smile\ElasticsuiteCore
* @author Aurelien FOUCRET <[email protected]>
*/
class Search implements \Magento\Framework\Api\Search\SearchInterface
{
/**
* @var \Smile\ElasticsuiteCore\Model\Search\RequestBuilder
*/
private $searchRequestBuilder;

/**
* @var \Magento\Framework\Search\SearchEngineInterface
*/
private $searchEngine;

/**
* @var \Magento\Framework\Search\SearchResponseBuilder
*/
private $searchResponseBuilder;

/**
* Constructor.
*
* @param \Magento\Framework\Search\SearchEngineInterface $searchEngine Search engine.
* @param \Smile\ElasticsuiteCore\Model\Search\RequestBuilder $searchRequestBuilder Search request builder.
* @param \Magento\Framework\Search\SearchResponseBuilder $searchResponseBuilder Search response builder.
*/
public function __construct(
\Magento\Framework\Search\SearchEngineInterface $searchEngine,
\Smile\ElasticsuiteCore\Model\Search\RequestBuilder $searchRequestBuilder,
\Magento\Framework\Search\SearchResponseBuilder $searchResponseBuilder
) {
$this->searchRequestBuilder = $searchRequestBuilder;
$this->searchEngine = $searchEngine;
$this->searchResponseBuilder = $searchResponseBuilder;
}


/**
* Execute search.
*
* @param \Magento\Framework\Api\Search\SearchCriteriaInterface $searchCriteria Search criteria.
*
* @return \Magento\Framework\Api\Search\SearchResultInterface
*/
public function search(\Magento\Framework\Api\Search\SearchCriteriaInterface $searchCriteria)
{
$searchRequest = $this->searchRequestBuilder->getRequest($searchCriteria);
$searchResponse = $this->searchEngine->search($searchRequest);
$searchResult = $this->searchResponseBuilder->build($searchResponse);

$totalCount = $searchResponse->count();
$searchResult->setTotalCount($totalCount);
$searchResult->setSearchCriteria($searchCriteria);

return $searchResult;
}
}
Loading