Skip to content

Commit

Permalink
Fixes Smile-SA#1322 Support price index dimensions/segmentation
Browse files Browse the repository at this point in the history
  • Loading branch information
rbayet committed Feb 28, 2019
1 parent 7083c0f commit 943a30a
Showing 1 changed file with 171 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@
namespace Smile\ElasticsuiteCatalog\Model\ResourceModel\Product\Indexer\Fulltext\Datasource;

use Smile\ElasticsuiteCatalog\Model\ResourceModel\Eav\Indexer\Indexer;
use Magento\Framework\App\ResourceConnection;
use Magento\Framework\EntityManager\MetadataPool;
use Magento\Store\Model\StoreManagerInterface;
use Magento\Catalog\Model\Indexer\Product\Price\DimensionCollectionFactory;
use Magento\Store\Model\Indexer\WebsiteDimensionProvider;
use Magento\Catalog\Model\Indexer\Product\Price\PriceTableResolver;

/**
* Prices data datasource resource model.
Expand All @@ -25,6 +31,52 @@
*/
class PriceData extends Indexer
{
/**
* @var DimensionCollectionFactory
*/
private $dimensionCollectionFactory;

/**
* @var array
*/
private $dimensions;

/**
* @var array
*/
private $dimensionsByWebsite;

/**
* @var PriceTableResolver
*/
private $priceTableResolver;

/**
* PriceData constructor.
*
* @param ResourceConnection $resource Database adapter.
* @param StoreManagerInterface $storeManager Store Manager.
* @param MetadataPool $metadataPool Metadata Pool.
* @param DimensionCollectionFactory $dimensionCollectionFactory Dimension collection factory.
* @param PriceTableResolver $priceTableResolver Price index table resolver.
*/
public function __construct(
ResourceConnection $resource,
StoreManagerInterface $storeManager,
MetadataPool $metadataPool,
DimensionCollectionFactory $dimensionCollectionFactory,
PriceTableResolver $priceTableResolver
) {
// \Smile\ElasticsuiteCatalog\Model\ResourceModel\Product\Indexer\Fulltext\Datasource\CategoryData::getCategoryProductIndexTable

$this->dimensionCollectionFactory = $dimensionCollectionFactory;
$this->dimensions = null;
$this->dimensionsByWebsite = [];
$this->priceTableResolver = $priceTableResolver;

parent::__construct($resource, $storeManager, $metadataPool);
}

/**
* Load prices data for a list of product ids and a given store.
*
Expand All @@ -37,11 +89,130 @@ public function loadPriceData($storeId, $productIds)
{
$websiteId = $this->getStore($storeId)->getWebsiteId();

/*
$select = $this->getConnection()->select()
->from(['p' => $this->getTable('catalog_product_index_price')])
->where('p.website_id = ?', $websiteId)
->where('p.entity_id IN(?)', $productIds);
*/
$baseQueries = [];
foreach ($this->getPriceIndexDimensionsTables($websiteId) as $dimensionsTable) {
$baseQueries[] = $this->getLoadPriceDataSelect($dimensionsTable, $websiteId, $productIds);
}
$select = $this->getConnection()->select()->union($baseQueries);

$writer = new \Zend\Log\Writer\Stream(BP . '/var/log/index-select.log');
$logger = new \Zend\Log\Logger();
$logger->addWriter($writer);
$logger->info('--- UNION SELECT ---');
$logger->info((string) $select);

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

/**
* Return a single price loading query against a specific price index table.
*
* @param string $indexTable Price index table.
* @param integer $websiteId Website id.
* @param array $productIds Product ids list.
*
* @return \Magento\Framework\DB\Select
*/
private function getLoadPriceDataSelect($indexTable, $websiteId, $productIds)
{
$select = $this->getConnection()->select()
->from(['p' => $indexTable])
->where('p.website_id = ?', $websiteId)
->where('p.entity_id IN(?)', $productIds);

$writer = new \Zend\Log\Writer\Stream(BP . '/var/log/index-select.log');
$logger = new \Zend\Log\Logger();
$logger->addWriter($writer);
$logger->info('--- SINGLE SELECT ---');
$logger->info((string) $select);

return $select;
}

/**
* Return the price index tables according to the price index dimensions for the given website.
*
* @param integer $websiteId Website id.
*
* @return array
*/
private function getPriceIndexDimensionsTables($websiteId)
{
$tables = [];

$indexDimensions = $this->getPriceIndexDimensions($websiteId);
foreach ($indexDimensions as $dimensions) {
$tables[] = $this->priceTableResolver->resolve('catalog_product_index_price', $dimensions);
}

return $tables;
}

/**
* Return price index dimensions applicable for the given website.
*
* @param integer $websiteId Website id.
*
* @return array
*/
private function getPriceIndexDimensions($websiteId)
{
if (!array_key_exists($websiteId, $this->dimensionsByWebsite)) {
$indexDimensions = $this->getAllPriceIndexDimensions();

$relevantDimensions = [];
foreach ($indexDimensions as $dimensions) {
if (array_key_exists(WebsiteDimensionProvider::DIMENSION_NAME, $dimensions)) {
$websiteDimension = $dimensions[WebsiteDimensionProvider::DIMENSION_NAME];
if ((string) $websiteDimension->getValue() == $websiteId) {
$relevantDimensions[] = $dimensions;
}
} else {
$relevantDimensions[] = $dimensions;
}
}

$writer = new \Zend\Log\Writer\Stream(BP . '/var/log/dimensions.log');
$logger = new \Zend\Log\Logger();
$logger->addWriter($writer);
$logger->info('--- RELEVANT DIMENSIONS ---');
foreach ($relevantDimensions as $currentDimension) {
$logger->info(print_r($currentDimension, true));
}

$this->dimensionsByWebsite[$websiteId] = $relevantDimensions;
}

return $this->dimensionsByWebsite[$websiteId];
}

/**
* Return all price index dimensions.
*
* @return array
*/
private function getAllPriceIndexDimensions()
{
if ($this->dimensions === null) {
$dimensions = $this->dimensionCollectionFactory->create();

$writer = new \Zend\Log\Writer\Stream(BP . '/var/log/dimensions.log');
$logger = new \Zend\Log\Logger();
$logger->addWriter($writer);
$logger->info('--- DIMENSIONS ---');
foreach ($dimensions as $currentDimension) {
$logger->info(print_r($currentDimension, true));
}

$this->dimensions = $dimensions;
}

return $this->dimensions;
}
}

0 comments on commit 943a30a

Please sign in to comment.