Skip to content

Commit

Permalink
Merge pull request #3487 from Smile-SA/feature-autocomplete-extension…
Browse files Browse the repository at this point in the history
…-rebase

[Core] Adding fine-tuning options for the autocompletion
  • Loading branch information
rbayet authored Jan 17, 2025
2 parents 2efd9cf + 98aaeb0 commit 492a35a
Show file tree
Hide file tree
Showing 13 changed files with 731 additions and 60 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
use Magento\Search\Model\QueryFactory;
use Smile\ElasticsuiteCatalog\Helper\Autocomplete as ConfigurationHelper;
use Smile\ElasticsuiteCatalog\Model\ResourceModel\Category\Fulltext\CollectionFactory as CategoryCollectionFactory;
use Smile\ElasticsuiteCore\Model\Autocomplete\Terms\DataProvider as TermDataProvider;
use Smile\ElasticsuiteCore\Model\Autocomplete\SuggestedTermsProvider;

/**
* Catalog category autocomplete data provider.
Expand Down Expand Up @@ -49,7 +49,7 @@ class DataProvider implements DataProviderInterface
protected $queryFactory;

/**
* @var TermDataProvider
* @var SuggestedTermsProvider
*/
protected $termDataProvider;

Expand All @@ -73,15 +73,15 @@ class DataProvider implements DataProviderInterface
*
* @param ItemFactory $itemFactory Suggest item factory.
* @param QueryFactory $queryFactory Search query factory.
* @param TermDataProvider $termDataProvider Search terms suggester.
* @param SuggestedTermsProvider $termDataProvider Search terms suggester.
* @param CategoryCollectionFactory $categoryCollectionFactory Category collection factory.
* @param ConfigurationHelper $configurationHelper Autocomplete configuration helper.
* @param string $type Autocomplete provider type.
*/
public function __construct(
ItemFactory $itemFactory,
QueryFactory $queryFactory,
TermDataProvider $termDataProvider,
SuggestedTermsProvider $termDataProvider,
CategoryCollectionFactory $categoryCollectionFactory,
ConfigurationHelper $configurationHelper,
$type = self::AUTOCOMPLETE_TYPE
Expand Down Expand Up @@ -143,23 +143,6 @@ private function isCategoryAvailable(Category $category): bool
;
}

/**
* List of search terms suggested by the search terms data provider.
*
* @return array
*/
private function getSuggestedTerms()
{
$terms = array_map(
function (\Magento\Search\Model\Autocomplete\Item $termItem) {
return $termItem->getTitle();
},
$this->termDataProvider->getItems()
);

return $terms;
}

/**
* Suggested categories collection.
* Returns null if no suggested search terms.
Expand All @@ -171,7 +154,7 @@ private function getCategoryCollection()
{
$categoryCollection = null;

$suggestedTerms = $this->getSuggestedTerms();
$suggestedTerms = $this->termDataProvider->getSuggestedTerms();
$terms = [$this->queryFactory->get()->getQueryText()];

if (!empty($suggestedTerms)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,8 @@
*/
namespace Smile\ElasticsuiteCatalog\Model\Autocomplete\Product\Collection;

use Magento\Search\Model\QueryFactory;
use Smile\ElasticsuiteCore\Model\Autocomplete\Terms\DataProvider as TermDataProvider;
use Magento\Search\Model\Autocomplete\Item as TermItem;
use Smile\ElasticsuiteCatalog\Model\ResourceModel\Product\Fulltext\Collection as ProductCollection;
use Smile\ElasticsuiteCore\Model\Autocomplete\SuggestedTermsProvider;

/**
* Catalog autocomplete product collection filter.
Expand All @@ -27,13 +25,6 @@
*/
class Filter implements PreProcessorInterface
{
/**
* Query factory
*
* @var QueryFactory
*/
private $queryFactory;

/**
* @var TermDataProvider
*/
Expand All @@ -42,12 +33,10 @@ class Filter implements PreProcessorInterface
/**
* Constructor.
*
* @param QueryFactory $queryFactory Search term query factory.
* @param TermDataProvider $termDataProvider Popular search terms provider.
* @param SuggestedTermsProvider $termDataProvider Suggested search terms provider.
*/
public function __construct(QueryFactory $queryFactory, TermDataProvider $termDataProvider)
public function __construct(SuggestedTermsProvider $termDataProvider)
{
$this->queryFactory = $queryFactory;
$this->termDataProvider = $termDataProvider;
}

Expand All @@ -61,31 +50,8 @@ public function __construct(QueryFactory $queryFactory, TermDataProvider $termDa
*/
public function prepareCollection(ProductCollection $collection)
{
$terms = $this->getQueryText();

$collection->setSearchQuery($terms);
$collection->setSearchQuery($this->termDataProvider->getSuggestedTerms());

return $collection;
}

/**
* List of search terms suggested by the search terms data provider.
*
* @return array
*/
private function getQueryText()
{
$terms = array_map(
function (TermItem $termItem) {
return $termItem->getTitle();
},
$this->termDataProvider->getItems()
);

if (empty($terms)) {
$terms = [$this->queryFactory->get()->getQueryText()];
}

return $terms;
}
}
62 changes: 62 additions & 0 deletions src/module-elasticsuite-core/Helper/Autocomplete.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,68 @@ public function isEnabled($type)
return $this->getMaxSize($type) > 0;
}

/**
* Check if Autocomplete "extension" system is enabled.
*
* @return bool
*/
public function isExtensionEnabled()
{
return (bool) $this->scopeConfig->isSetFlag(
self::AUTOCOMPLETE_SETTINGS_CONFIG_XML_PREFIX . "/advanced/extension_enabled",
\Magento\Store\Model\ScopeInterface::SCOPE_STORE
);
}

/**
* Check if Autocomplete "extension" system is limited.
*
* @return bool
*/
public function isExtensionLimited()
{
return (bool) ($this->scopeConfig->isSetFlag(
self::AUTOCOMPLETE_SETTINGS_CONFIG_XML_PREFIX . "/advanced/extension_limited",
\Magento\Store\Model\ScopeInterface::SCOPE_STORE
)) && ($this->getExtensionSize() > 0);
}

/**
* Get the maximum number of popular search terms to use when the "extension" is limited.
*
* @return int
*/
public function getExtensionSize()
{
return (int) $this->getConfigValue("advanced/extension_size");
}

/**
* Check if Autocomplete "extension" system is stopped when having matches.
*
* @return bool
*/
public function isExtensionStoppedOnMatch()
{
return (bool) $this->scopeConfig->isSetFlag(
self::AUTOCOMPLETE_SETTINGS_CONFIG_XML_PREFIX . "/advanced/stop_extension_on_match",
\Magento\Store\Model\ScopeInterface::SCOPE_STORE
);
}

/**
* Check if Autocomplete is supposed to always use the user raw query or not.
*
* @return bool
*/
public function isPreservingBaseQuery()
{
return (bool) $this->scopeConfig->isSetFlag(
self::AUTOCOMPLETE_SETTINGS_CONFIG_XML_PREFIX . "/advanced/preserve_base_query",
\Magento\Store\Model\ScopeInterface::SCOPE_STORE
);
}

/**
* Retrieve a configuration value by its key
*
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
<?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 Romain Ruaud <romain.ruaud@smile.fr>
* @copyright 2024 Smile
* @license Open Software License ("OSL") v. 3.0
*/

namespace Smile\ElasticsuiteCore\Model\Autocomplete;

use Magento\Search\Model\Autocomplete\Item as TermItem;
use Smile\ElasticsuiteCore\Helper\Autocomplete;
use Smile\ElasticsuiteCore\Model\Autocomplete\Terms\DataProvider as TermDataProvider;
use Smile\ElasticsuiteCore\Model\Search\QueryStringProviderFactory;

/**
* Suggested Terms Provider.
* Based on the Term provider but will manipulate it according to configuration.
*
* @category Smile
* @package Smile\ElasticsuiteCore
* @author Romain Ruaud <romain.ruaud@smile.fr>
*/
class SuggestedTermsProvider
{
/**
* @var \Smile\ElasticsuiteCore\Model\Autocomplete\Terms\DataProvider
*/
private $termDataProvider;

/**
* @var \Smile\ElasticsuiteCatalog\Helper\Autocomplete
*/
private $helper;

/**
* @var \Smile\ElasticsuiteCore\Model\Search\QueryStringProviderFactory
*/
private $queryStringProviderFactory;

/**
* @var null|string
*/
private $queryString = null;

/**
* @var null
*/
private $terms = null;

/**
* @param Autocomplete $helper Autocomplete helper
* @param TermDataProvider $termDataProvider Term data provider
* @param QueryStringProviderFactory $queryStringProviderFactory Search Query Factory
*/
public function __construct(
Autocomplete $helper,
TermDataProvider $termDataProvider,
QueryStringProviderFactory $queryStringProviderFactory
) {
$this->helper = $helper;
$this->termDataProvider = $termDataProvider;
$this->queryStringProviderFactory = $queryStringProviderFactory;
}

/**
* List of search terms suggested by the search terms data provider, and reworked according to configuration.
*
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
*
* @return array|string[]
*/
public function getSuggestedTerms()
{
if (null === $this->terms) {
$terms = [];

if ($this->helper->isExtensionEnabled()) {
$terms = array_map(
function (TermItem $termItem) {
return trim($termItem->getTitle());
},
$this->termDataProvider->getItems()
);

$hasAlreadyStoppedExtending = false;
if ($this->helper->isExtensionStoppedOnMatch()) {
if (array_search(trim($this->getQueryString()), $terms) !== false) {
$terms = [$this->getQueryString()];
$hasAlreadyStoppedExtending = true;
}
}

if ($this->helper->isExtensionLimited() && !$hasAlreadyStoppedExtending) {
$terms = array_slice($terms, 0, (int) $this->helper->getExtensionSize());
}

if ($this->helper->isPreservingBaseQuery() && !$hasAlreadyStoppedExtending) {
array_unshift($terms, $this->getQueryString());
}
}

if (empty($terms)) {
$terms = [$this->getQueryString()];
}

$this->terms = array_values(array_unique($terms));
}

return $this->terms;
}

/**
* Retrieve current query string
*
* @return string
*/
private function getQueryString()
{
if ($this->queryString === null) {
$this->queryString = $this->queryStringProviderFactory->create()->get();
}

return $this->queryString;
}
}
Loading

0 comments on commit 492a35a

Please sign in to comment.