Skip to content

Commit

Permalink
Fixes #1223 Prevent indexed data loss on multiple batch pages
Browse files Browse the repository at this point in the history
  • Loading branch information
Swahjak committed Dec 11, 2018
1 parent 7b093e9 commit 1722dc8
Show file tree
Hide file tree
Showing 3 changed files with 109 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@
* @copyright 2018 Smile
* @license Open Software License ("OSL") v. 3.0
*/

namespace Smile\ElasticsuiteCatalog\Data\Collection\Db\FetchStrategy;

use Magento\Customer\Model\Session;
use Magento\Framework\Data\Collection\Db\FetchStrategyInterface;
use Magento\Framework\DB\Select;
use Magento\Search\Model\SearchEngine;
Expand All @@ -32,7 +34,7 @@ class SearchQuery extends Query implements FetchStrategyInterface
private $request;

/**
*
* Search response
*
* @var \Magento\Framework\Search\ResponseInterface
*/
Expand All @@ -52,6 +54,25 @@ class SearchQuery extends Query implements FetchStrategyInterface
*/
private $productListingHelper;

/**
* @var Session
*/
private $customerSession;

/**
* @var string[]
*/
private $listingAttributes = [
'entity_id',
'attribute_set_id',
'type_id',
'sku',
'has_options',
'required_options',
'updated_at',
'created_at',
];

/**
* SearchQuery constructor.
*
Expand All @@ -60,10 +81,12 @@ class SearchQuery extends Query implements FetchStrategyInterface
*/
public function __construct(
SearchEngine $searchEngine,
ProductListing $productListingHelper
ProductListing $productListingHelper,
Session $customerSession
) {
$this->searchEngine = $searchEngine;
$this->productListingHelper = $productListingHelper;
$this->customerSession = $customerSession;
}

/**
Expand Down Expand Up @@ -100,25 +123,72 @@ public function fetchAll(Select $select, array $bindParams = [])
foreach ($this->response->getIterator() as $item) {
/** @var \Smile\ElasticsuiteCore\Search\Adapter\Elasticsuite\Response\Document $item */
$source = $item->getSource();
$source = array_merge($source, $source['price'][0]);

foreach ($source as $attributeCode => $value) {
$source[$attributeCode] = in_array($attributeCode, $source['indexed_attributes'])
&& is_array($value) ? count($value) > 1 ? $value : $value[0] : $value;

if (0 === strpos($attributeCode, Mapping::OPTION_TEXT_PREFIX)) {
$key = str_replace(
Mapping::OPTION_TEXT_PREFIX.'_',
'',
$attributeCode
);
$source[$key.'_value'] = is_array($value) ? count($value) > 1 ? $value : $value[0] : $value;
}
$products[] = $this->getProductData($source);
}

return $products;
}

/**
* @param string[][] $source
* @return string[][]
*/
private function getProductData(array $source)
{
$productData = [
'entity_id' => (int)$source['entity_id'],
];

$listingAttributes = array_merge($source['product_listing_attributes'], $this->listingAttributes);

foreach ($listingAttributes as $listingAttributeCode) {

if (!isset($source[$listingAttributeCode])) {
$productData[$listingAttributeCode] = null;
}

$productData[$listingAttributeCode] = is_array($source[$listingAttributeCode])
? count($source[$listingAttributeCode]) > 1
? $source[$listingAttributeCode]
: $source[$listingAttributeCode][0]
: $source[$listingAttributeCode];

$attributeValueCode = Mapping::OPTION_TEXT_PREFIX.'_'.$listingAttributeCode;

if (!isset($source[$attributeValueCode])) {
continue;
}

$products[] = $source;
/** Mimic Magento flat which uses _value postfixes to save option values */
$productData[$listingAttributeCode.'_value'] = is_array($source[$attributeValueCode])
? count($source[$attributeValueCode]) > 1
? $source[$attributeValueCode]
: $source[$attributeValueCode][0]
: $source[$attributeValueCode];
}

return $products;
$productData = array_merge($productData, $this->getProductPriceData($source));

return $productData;
}

/**
* @param array $source
* @return string[]
*/
private function getProductPriceData(array $source)
{
$customGroupId = (int)$this->customerSession->getCustomerGroupId();

foreach ($source['price'] as $priceData) {
if ($customGroupId !== (int)$priceData['customer_group_id']) {
continue;
}
unset($priceData['customer_group_id']);

return $priceData;
}

return [];
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ private function addAttributeData($storeId, $productIds, $indexData = [])
$indexData[$productId] += $indexValues;

$this->addIndexedAttribute($indexData[$productId], $attribute);
$this->addProductListingAttribute($indexData[$productId], $attribute);
}
}

Expand Down Expand Up @@ -220,6 +221,24 @@ private function addChildSku(&$parentData, $relation)
$parentData['sku'] = array_unique($parentData['sku']);
}

/**
* Append an indexed attributes to indexed data of a given product.
*
* @param array $productIndexData Product Index data
* @param \Magento\Eav\Model\Entity\Attribute\AttributeInterface $attribute The attribute
*/
private function addProductListingAttribute(&$productIndexData, $attribute)
{
if (!isset($productIndexData['product_listing_attributes'])) {
$productIndexData['product_listing_attributes'] = [];
}

// Data can be missing for this attribute (Eg : due to null value being escaped).
if ($attribute->getUsedInProductListing() && isset($productIndexData[$attribute->getAttributeCode()])) {
$productIndexData['product_listing_attributes'][] = $attribute->getAttributeCode();
}
}

/**
* Append an indexed attributes to indexed data of a given product.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,8 @@ public function loadInventoryData($storeId, $productIds)
'qty' => 'stock_index.' . IndexStructure::QUANTITY,
]
)
->where('product.entity_id IN(?)', $productIds);
->where('product.entity_id IN (?)', $productIds)
->group('product.entity_id');

return $this->getConnection()->fetchAll($select);
}
Expand Down

0 comments on commit 1722dc8

Please sign in to comment.