From 9b098109acd80e851c5815c09287c760deb476c6 Mon Sep 17 00:00:00 2001 From: Romain Ruaud Date: Thu, 9 May 2019 15:43:42 +0200 Subject: [PATCH] Refactoring aggregation to be compliant with Elasticsuite 2.8 --- Model/Layer/Filter/Rating.php | 40 ++++------- .../Product/Attribute/AggregationResolver.php | 66 +++++++++++++++++++ .../Product/Attribute/Aggregation/Rating.php | 62 +++++++++++++++++ composer.json | 6 +- etc/di.xml | 35 ++++++++++ etc/elasticsuite_indices.xml | 3 - 6 files changed, 177 insertions(+), 35 deletions(-) create mode 100644 Plugin/Search/Request/Product/Attribute/AggregationResolver.php create mode 100644 Search/Request/Product/Attribute/Aggregation/Rating.php create mode 100644 etc/di.xml diff --git a/Model/Layer/Filter/Rating.php b/Model/Layer/Filter/Rating.php index c3f72c2..352757a 100644 --- a/Model/Layer/Filter/Rating.php +++ b/Model/Layer/Filter/Rating.php @@ -10,6 +10,7 @@ * @copyright 2017 Smile * @license Open Software License ("OSL") v. 3.0 */ + namespace Smile\ElasticsuiteRating\Model\Layer\Filter; /** @@ -26,25 +27,6 @@ class Rating extends \Smile\ElasticsuiteCatalog\Model\Layer\Filter\Attribute */ const RATING_AGG_INTERVAL = 20; - /** - * {@inheritDoc} - */ - public function addFacetToCollection($config = []) - { - $facetConfig = [ - 'name' => $this->getFilterField(), - 'type' => \Smile\ElasticsuiteCore\Search\Request\BucketInterface::TYPE_HISTOGRAM, - 'minDocCount' => 1, - 'interval' => (int) self::RATING_AGG_INTERVAL - ]; - - /** @var \Smile\ElasticsuiteCatalog\Model\ResourceModel\Product\Fulltext\Collection $productCollection */ - $productCollection = $this->getLayer()->getProductCollection(); - $productCollection->addFacet($facetConfig); - - return $this; - } - /** * {@inheritDoc} */ @@ -123,18 +105,18 @@ protected function _getItemsData() } } krsort($optionsFacetedData); - + $minCount = !empty($optionsFacetedData) ? min(array_column($optionsFacetedData, 'count')) : 0; - if (!empty($this->currentFilterValue) || $minCount < $productCollection->getSize()) { - foreach ($optionsFacetedData as $value => $data) { - $sumCount += (int) $data['count']; - $items[$value] = [ - 'label' => $value, - 'value' => $value, - 'count' => $sumCount, - ]; - } + if (!empty($this->currentFilterValue) || $minCount < $productCollection->getSize()) { + foreach ($optionsFacetedData as $value => $data) { + $sumCount += (int) $data['count']; + $items[$value] = [ + 'label' => $value, + 'value' => $value, + 'count' => $sumCount, + ]; + } } return $items; diff --git a/Plugin/Search/Request/Product/Attribute/AggregationResolver.php b/Plugin/Search/Request/Product/Attribute/AggregationResolver.php new file mode 100644 index 0000000..23028fe --- /dev/null +++ b/Plugin/Search/Request/Product/Attribute/AggregationResolver.php @@ -0,0 +1,66 @@ + + * @copyright 2019 Smile + * @license Open Software License ("OSL") v. 3.0 + */ +namespace Smile\ElasticsuiteRating\Plugin\Search\Request\Product\Attribute; + +/** + * Plugin to set aggregation builder for ratings. + * + * @category Smile + * @package Smile\ElasticsuiteRating + * @author Romain Ruaud + */ +class AggregationResolver +{ + /** + * Rating Summary attribute code. + */ + const RATING_SUMMARY_ATTRIBUTE = 'ratings_summary'; + + /** + * @var \Smile\ElasticsuiteRating\Search\Request\Product\Attribute\Aggregation\Rating + */ + private $ratingAggregation; + + /** + * AggregationResolver constructor. + * + * @param \Smile\ElasticsuiteRating\Search\Request\Product\Attribute\Aggregation\Rating $ratingAggregation Rating Aggregation + */ + public function __construct(\Smile\ElasticsuiteRating\Search\Request\Product\Attribute\Aggregation\Rating $ratingAggregation) + { + $this->ratingAggregation = $ratingAggregation; + } + + /** + * Set default facet size to 0 for swatches attributes before adding it as aggregation. + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + * + * @param \Smile\ElasticsuiteCatalog\Search\Request\Product\Attribute\AggregationResolver $subject Aggregation Resolver + * @param array $result Aggregation Config + * @param \Magento\Catalog\Model\ResourceModel\Eav\Attribute $attribute Attribute + * + * @return array + */ + public function afterGetAggregationData( + \Smile\ElasticsuiteCatalog\Search\Request\Product\Attribute\AggregationResolver $subject, + $result, + $attribute + ) { + if ($attribute->getAttributeCode() === self::RATING_SUMMARY_ATTRIBUTE) { + $result = $this->ratingAggregation->getAggregationData($attribute); + } + + return $result; + } +} diff --git a/Search/Request/Product/Attribute/Aggregation/Rating.php b/Search/Request/Product/Attribute/Aggregation/Rating.php new file mode 100644 index 0000000..cc2f797 --- /dev/null +++ b/Search/Request/Product/Attribute/Aggregation/Rating.php @@ -0,0 +1,62 @@ + + * @copyright 2019 Smile + * @license Open Software License ("OSL") v. 3.0 + */ + +namespace Smile\ElasticsuiteRating\Search\Request\Product\Attribute\Aggregation; + +use Smile\ElasticsuiteCatalog\Search\Request\Product\Attribute\AggregationInterface; +use Smile\ElasticsuiteCore\Search\Request\BucketInterface; + +/** + * Aggregation builder for product ratings. + * + * @category Smile + * @package Smile\ElasticsuiteRating + * @author Romain Ruaud + */ +class Rating implements AggregationInterface +{ + /** + * Default interval, based on 0-100 divided in five stars. + */ + const RATING_AGG_INTERVAL = 20; + + /** + * {@inheritdoc} + */ + public function getAggregationData(\Magento\Catalog\Model\ResourceModel\Eav\Attribute $attribute) + { + $bucketConfig = [ + 'name' => $this->getFilterField($attribute), + 'type' => BucketInterface::TYPE_HISTOGRAM, + 'minDocCount' => 1, + 'interval' => (int) self::RATING_AGG_INTERVAL, + ]; + + return $bucketConfig; + } + + /** + * Retrieve ES filter field. + * + * @param \Magento\Catalog\Model\ResourceModel\Eav\Attribute $attribute Attribute + * + * @return string + */ + private function getFilterField(\Magento\Catalog\Model\ResourceModel\Eav\Attribute $attribute) + { + $field = $attribute->getAttributeCode(); + + return $field; + } + +} diff --git a/composer.json b/composer.json index 6b620af..7149c4f 100644 --- a/composer.json +++ b/composer.json @@ -13,7 +13,7 @@ } ], "description" : "Smile ElasticSuite - Rating search module.", - "homepage" : "https://github.com/Smile-SA/module-elasticsuite-catalog", + "homepage" : "https://github.com/Smile-SA/magento2-module-elasticsuite-rating", "keywords" : [ "magento", "magento2", @@ -29,10 +29,10 @@ } ], "require" : { - "magento/framework" : ">=100.1.0", + "magento/framework" : ">=102.0.0", "magento/magento-composer-installer" : "*", "magento/module-review" : ">=100.1.0", - "smile/elasticsuite" : "~2.7.0" + "smile/elasticsuite" : "~2.8.0" }, "require-dev" : { "smile/magento2-smilelab-quality-suite" : "1.0.0" diff --git a/etc/di.xml b/etc/di.xml new file mode 100644 index 0000000..1221e7b --- /dev/null +++ b/etc/di.xml @@ -0,0 +1,35 @@ + + + + + + + + + + Smile\ElasticsuiteRating\Model\Product\Indexer\Fulltext\Datasource\RatingData + + + + + + + + + + diff --git a/etc/elasticsuite_indices.xml b/etc/elasticsuite_indices.xml index a84c0ab..301e4a3 100644 --- a/etc/elasticsuite_indices.xml +++ b/etc/elasticsuite_indices.xml @@ -20,9 +20,6 @@ xsi:noNamespaceSchemaLocation="urn:magento:module:Smile_ElasticsuiteCore:etc/elasticsuite_indices.xsd"> - - Smile\ElasticsuiteRating\Model\Product\Indexer\Fulltext\Datasource\RatingData -