forked from Smile-SA/elasticsuite
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request Smile-SA#3089 from rbayet/feat-catalogoptimizer-st…
…ock-search-special-attributes Ability to create rules based on stock qty and searchable content
- Loading branch information
Showing
5 changed files
with
344 additions
and
0 deletions.
There are no files selected for viewing
231 changes: 231 additions & 0 deletions
231
...module-elasticsuite-catalog-rule/Model/Rule/Condition/Product/SpecialAttribute/Search.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,231 @@ | ||
<?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\ElasticsuiteCatalogRule | ||
* @author Richard Bayet <richard.bayet@smile.fr> | ||
* @copyright 2021 Smile | ||
* @license Open Software License ("OSL") v. 3.0 | ||
*/ | ||
|
||
namespace Smile\ElasticsuiteCatalogRule\Model\Rule\Condition\Product\SpecialAttribute; | ||
|
||
use Smile\ElasticsuiteCatalogRule\Api\Rule\Condition\Product\SpecialAttributeInterface; | ||
use Smile\ElasticsuiteCatalogRule\Model\Rule\Condition\Product as ProductCondition; | ||
use Smile\ElasticsuiteCore\Api\Search\ContextInterface; | ||
use Smile\ElasticsuiteCore\Api\Search\Request\ContainerConfigurationInterface; | ||
use Smile\ElasticsuiteCore\Api\Search\Spellchecker\RequestInterfaceFactory as SpellcheckRequestFactory; | ||
use Smile\ElasticsuiteCore\Api\Search\SpellcheckerInterface; | ||
use Smile\ElasticsuiteCore\Search\Request\ContainerConfigurationFactory; | ||
use Smile\ElasticsuiteCore\Search\Request\Query\Builder as QueryBuilder; | ||
use Smile\ElasticsuiteCore\Search\Request\Query\QueryFactory; | ||
use Smile\ElasticsuiteCore\Search\Request\QueryInterface; | ||
|
||
/** | ||
* Class Search | ||
* | ||
* @category Elasticsuite | ||
* @package Elasticsuite\CatalogRule | ||
* @author Richard Bayet <richard.bayet@smile.fr> | ||
*/ | ||
class Search implements SpecialAttributeInterface | ||
{ | ||
/** | ||
* @var ContainerConfigurationFactory | ||
*/ | ||
private $containerConfigFactory; | ||
|
||
/** | ||
* @var ContextInterface | ||
*/ | ||
private $searchContext; | ||
|
||
/** | ||
* @var QueryBuilder | ||
*/ | ||
private $queryBuilder; | ||
|
||
/** | ||
* @var QueryFactory | ||
*/ | ||
private $queryFactory; | ||
|
||
/** | ||
* @var SpellcheckRequestFactory | ||
*/ | ||
private $spellcheckRequestFactory; | ||
|
||
/** | ||
* @var SpellcheckerInterface | ||
*/ | ||
private $spellchecker; | ||
|
||
/** | ||
* Search constructor. | ||
* | ||
* @param ContainerConfigurationFactory $containerConfigFactory Container configuration factory. | ||
* @param ContextInterface $searchContext Search context. | ||
* @param QueryBuilder $queryBuilder Query builder. | ||
* @param QueryFactory $queryFactory Query factory. | ||
* @param SpellcheckRequestFactory $spellcheckRequestFactory Spellcheck request factory. | ||
* @param SpellcheckerInterface $spellchecker Spellchecker. | ||
*/ | ||
public function __construct( | ||
ContainerConfigurationFactory $containerConfigFactory, | ||
ContextInterface $searchContext, | ||
QueryBuilder $queryBuilder, | ||
QueryFactory $queryFactory, | ||
SpellcheckRequestFactory $spellcheckRequestFactory, | ||
SpellcheckerInterface $spellchecker | ||
) { | ||
$this->containerConfigFactory = $containerConfigFactory; | ||
$this->searchContext = $searchContext; | ||
$this->queryBuilder = $queryBuilder; | ||
$this->queryFactory = $queryFactory; | ||
$this->spellcheckRequestFactory = $spellcheckRequestFactory; | ||
$this->spellchecker = $spellchecker; | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function getAttributeCode() | ||
{ | ||
return 'search'; | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function getSearchQuery(ProductCondition $condition) | ||
{ | ||
$containerConfiguration = $this->getContainerConfiguration(); | ||
$queryText = $condition->getValue(); | ||
$searchQuery = $this->getFullTextQuery($containerConfiguration, $queryText); | ||
|
||
if (substr($condition->getOperator(), 0, 1) === '!') { | ||
$searchQuery = $this->queryFactory->create(QueryInterface::TYPE_NOT, ['query' => $searchQuery]); | ||
} | ||
|
||
return $searchQuery; | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function getOperatorName() | ||
{ | ||
return null; | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function getInputType() | ||
{ | ||
return 'string'; | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function getValueElementType() | ||
{ | ||
return 'text'; | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function getValueName($value) | ||
{ | ||
if ($value === null || '' === $value) { | ||
return '...'; | ||
} | ||
|
||
return $value; | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function getValue($value) | ||
{ | ||
return $value; | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function getValueOptions() | ||
{ | ||
return []; | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function getLabel() | ||
{ | ||
return __('Searchable content'); | ||
} | ||
|
||
/** | ||
* Get fulltext container configuration. | ||
* | ||
* @return ContainerConfigurationInterface | ||
*/ | ||
private function getContainerConfiguration() | ||
{ | ||
return $this->containerConfigFactory->create( | ||
['containerName' => 'quick_search_container', 'storeId' => (int) $this->searchContext->getStoreId()] | ||
); | ||
} | ||
|
||
/** | ||
* Retrieve fulltext search query for a given query text | ||
* | ||
* @param ContainerConfigurationInterface $containerConfiguration Container configuration. | ||
* @param string $queryText The query text. | ||
* | ||
* @return QueryInterface | ||
*/ | ||
private function getFullTextQuery(ContainerConfigurationInterface $containerConfiguration, $queryText) | ||
{ | ||
$spellingType = $this->getSpellingType($containerConfiguration, $queryText); | ||
|
||
return $this->queryBuilder->createFulltextQuery($containerConfiguration, $queryText, $spellingType); | ||
} | ||
|
||
/** | ||
* Retrieve the spelling type for a fulltext query. | ||
* | ||
* @param ContainerConfigurationInterface $containerConfiguration Container configuration. | ||
* @param string $queryText Query text. | ||
* | ||
* @return int | ||
*/ | ||
private function getSpellingType(ContainerConfigurationInterface $containerConfiguration, $queryText) | ||
{ | ||
if (is_array($queryText)) { | ||
$queryText = implode(" ", $queryText); | ||
} | ||
|
||
$spellcheckRequestParams = [ | ||
'index' => $containerConfiguration->getIndexName(), | ||
'queryText' => $queryText, | ||
'cutoffFrequency' => $containerConfiguration->getRelevanceConfig()->getCutOffFrequency(), | ||
'isUsingAllTokens' => $containerConfiguration->getRelevanceConfig()->isUsingAllTokens(), | ||
'isUsingReference' => $containerConfiguration->getRelevanceConfig()->isUsingReferenceAnalyzer(), | ||
'isUsingEdgeNgram' => $containerConfiguration->getRelevanceConfig()->isUsingEdgeNgramAnalyzer(), | ||
]; | ||
|
||
$spellcheckRequest = $this->spellcheckRequestFactory->create($spellcheckRequestParams); | ||
|
||
return $this->spellchecker->getSpellingType($spellcheckRequest); | ||
} | ||
} |
107 changes: 107 additions & 0 deletions
107
...dule-elasticsuite-catalog-rule/Model/Rule/Condition/Product/SpecialAttribute/StockQty.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
<?php | ||
/** | ||
* Elasticsuite stock qty catalog rule special attribute provider. | ||
* Allows to use the stock qty (self or those of children for configurable products) to build catalog rules for | ||
* search optimizers or virtual categories rules. | ||
* Please note that indexed stock.qty for configurable or bundle products will vary depending on your usage | ||
* of Multi Source Inventory modules: it will be left at 0 if you use the default source and stock. | ||
* | ||
* @category Smile | ||
* @package Smile\ElasticsuiteCatalogRule | ||
* @author Richard Bayet <richard.bayet@smile.fr> | ||
* @copyright 2021 Smile | ||
* @license Open Software License ("OSL") v. 3.0 | ||
*/ | ||
|
||
namespace Smile\ElasticsuiteCatalogRule\Model\Rule\Condition\Product\SpecialAttribute; | ||
|
||
use Smile\ElasticsuiteCatalogRule\Api\Rule\Condition\Product\SpecialAttributeInterface; | ||
use Smile\ElasticsuiteCatalogRule\Model\Rule\Condition\Product as ProductCondition; | ||
|
||
/** | ||
* Class StockQty | ||
* | ||
* @category Elasticsuite | ||
* @package Elasticsuite\CatalogRule | ||
* @author Richard Bayet <richard.bayet@smile.fr> | ||
*/ | ||
class StockQty implements SpecialAttributeInterface | ||
{ | ||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function getAttributeCode() | ||
{ | ||
return 'stock.qty'; | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
* @SuppressWarnings(PHPMD.UnusedFormalParameter) | ||
*/ | ||
public function getSearchQuery(ProductCondition $condition) | ||
{ | ||
// Query can be computed directly with the attribute code and value. (eg. stock.qty < 5). | ||
return null; | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function getOperatorName() | ||
{ | ||
return null; | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function getInputType() | ||
{ | ||
return 'numeric'; | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function getValueElementType() | ||
{ | ||
return 'text'; | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function getValueName($value) | ||
{ | ||
if ($value === null || '' === $value) { | ||
return '...'; | ||
} | ||
|
||
return $value; | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function getValue($rawValue) | ||
{ | ||
return $rawValue; | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function getValueOptions() | ||
{ | ||
return []; | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function getLabel() | ||
{ | ||
return __('Stock qty'); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters