Skip to content

Commit

Permalink
Merge pull request #3054 from magento-tsg/2.2.6-develop-pr41
Browse files Browse the repository at this point in the history
[TSG] Backporting for 2.2 (pr41) (2.2.6)
  • Loading branch information
Lysenko Olexandr authored Aug 20, 2018
2 parents 79110b8 + fe1a615 commit 04113a9
Show file tree
Hide file tree
Showing 5 changed files with 122 additions and 79 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -56,39 +56,36 @@ public function __construct(
* @return \Magento\Catalog\Model\Indexer\Product\Flat
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
* @SuppressWarnings(PHPMD.NPathComplexity)
*/
public function write($storeId, $productId, $valueFieldSuffix = '')
{
$flatTable = $this->_productIndexerHelper->getFlatTableName($storeId);
$entityTableName = $this->_productIndexerHelper->getTable('catalog_product_entity');

$attributes = $this->_productIndexerHelper->getAttributes();
$eavAttributes = $this->_productIndexerHelper->getTablesStructure($attributes);
$updateData = [];
$describe = $this->_connection->describeTable($flatTable);
$metadata = $this->getMetadataPool()->getMetadata(ProductInterface::class);
$linkField = $metadata->getLinkField();

foreach ($eavAttributes as $tableName => $tableColumns) {
$columnsChunks = array_chunk($tableColumns, self::ATTRIBUTES_CHUNK_SIZE, true);

foreach ($columnsChunks as $columns) {
$select = $this->_connection->select();
$selectValue = $this->_connection->select();
$keyColumns = [
'entity_id' => 'e.entity_id',
'attribute_id' => 't.attribute_id',
'value' => $this->_connection->getIfNullSql('`t2`.`value`', '`t`.`value`'),
];

if ($tableName != $this->_productIndexerHelper->getTable('catalog_product_entity')) {

if ($tableName != $entityTableName) {
$valueColumns = [];
$ids = [];
$select->from(
['e' => $this->_productIndexerHelper->getTable('catalog_product_entity')],
$keyColumns
);

$selectValue->from(
['e' => $this->_productIndexerHelper->getTable('catalog_product_entity')],
$keyColumns
['e' => $entityTableName],
[
'entity_id' => 'e.entity_id',
'attribute_id' => 't.attribute_id',
'value' => $this->_connection->getIfNullSql('`t2`.`value`', '`t`.`value`'),
]
);

/** @var $attribute \Magento\Catalog\Model\ResourceModel\Eav\Attribute */
Expand All @@ -97,8 +94,7 @@ public function write($storeId, $productId, $valueFieldSuffix = '')
$ids[$attribute->getId()] = $columnName;
}
}
$linkField = $this->getMetadataPool()->getMetadata(ProductInterface::class)->getLinkField();
$select->joinLeft(
$select->joinInner(
['t' => $tableName],
sprintf('e.%s = t.%s ', $linkField, $linkField) . $this->_connection->quoteInto(
' AND t.attribute_id IN (?)',
Expand All @@ -116,8 +112,6 @@ public function write($storeId, $productId, $valueFieldSuffix = '')
[]
)->where(
'e.entity_id = ' . $productId
)->where(
't.attribute_id IS NOT NULL'
);
$cursor = $this->_connection->query($select);
while ($row = $cursor->fetch(\Zend_Db::FETCH_ASSOC)) {
Expand Down Expand Up @@ -157,7 +151,7 @@ public function write($storeId, $productId, $valueFieldSuffix = '')
$columnNames[] = 'attribute_set_id';
$columnNames[] = 'type_id';
$select->from(
['e' => $this->_productIndexerHelper->getTable('catalog_product_entity')],
['e' => $entityTableName],
$columnNames
)->where(
'e.entity_id = ' . $productId
Expand All @@ -175,7 +169,9 @@ public function write($storeId, $productId, $valueFieldSuffix = '')

if (!empty($updateData)) {
$updateData += ['entity_id' => $productId];
$updateData += ['row_id' => $productId];
if ($linkField !== $metadata->getIdentifierField()) {
$updateData += [$linkField => $productId];
}
$updateFields = [];
foreach ($updateData as $key => $value) {
$updateFields[$key] = $key;
Expand Down
69 changes: 39 additions & 30 deletions app/code/Magento/Catalog/Model/Indexer/Product/Flat/Action/Row.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,20 @@
*/
namespace Magento\Catalog\Model\Indexer\Product\Flat\Action;

use Magento\Catalog\Api\Data\ProductInterface;
use Magento\Catalog\Model\Indexer\Product\Flat\FlatTableBuilder;
use Magento\Catalog\Model\Indexer\Product\Flat\TableBuilder;
use Magento\Framework\EntityManager\MetadataPool;

/**
* Class Row reindex action
* Class Row reindex action.
*
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
*/
class Row extends \Magento\Catalog\Model\Indexer\Product\Flat\AbstractAction
{
/**
* @var \Magento\Catalog\Model\Indexer\Product\Flat\Action\Indexer
* @var Indexer
*/
protected $flatItemWriter;

Expand All @@ -23,6 +27,11 @@ class Row extends \Magento\Catalog\Model\Indexer\Product\Flat\AbstractAction
*/
protected $flatItemEraser;

/**
* @var MetadataPool
*/
private $metadataPool;

/**
* @param \Magento\Framework\App\ResourceConnection $resource
* @param \Magento\Store\Model\StoreManagerInterface $storeManager
Expand All @@ -32,6 +41,7 @@ class Row extends \Magento\Catalog\Model\Indexer\Product\Flat\AbstractAction
* @param FlatTableBuilder $flatTableBuilder
* @param Indexer $flatItemWriter
* @param Eraser $flatItemEraser
* @param MetadataPool|null $metadataPool
*/
public function __construct(
\Magento\Framework\App\ResourceConnection $resource,
Expand All @@ -41,7 +51,8 @@ public function __construct(
TableBuilder $tableBuilder,
FlatTableBuilder $flatTableBuilder,
Indexer $flatItemWriter,
Eraser $flatItemEraser
Eraser $flatItemEraser,
MetadataPool $metadataPool = null
) {
parent::__construct(
$resource,
Expand All @@ -53,6 +64,8 @@ public function __construct(
);
$this->flatItemWriter = $flatItemWriter;
$this->flatItemEraser = $flatItemEraser;
$this->metadataPool = $metadataPool ?:
\Magento\Framework\App\ObjectManager::getInstance()->get(MetadataPool::class);
}

/**
Expand All @@ -61,7 +74,6 @@ public function __construct(
* @param int|null $id
* @return \Magento\Catalog\Model\Indexer\Product\Flat\Action\Row
* @throws \Magento\Framework\Exception\LocalizedException
* @throws \Zend_Db_Statement_Exception
*/
public function execute($id = null)
{
Expand All @@ -71,50 +83,47 @@ public function execute($id = null)
);
}
$ids = [$id];
foreach ($this->_storeManager->getStores() as $store) {
$linkField = $this->metadataPool->getMetadata(ProductInterface::class)->getLinkField();

$stores = $this->_storeManager->getStores();
foreach ($stores as $store) {
$tableExists = $this->_isFlatTableExists($store->getId());
if ($tableExists) {
$this->flatItemEraser->removeDeletedProducts($ids, $store->getId());
}

/* @var $status \Magento\Eav\Model\Entity\Attribute */
$status = $this->_productIndexerHelper->getAttribute('status');
$status = $this->_productIndexerHelper->getAttribute(ProductInterface::STATUS);
$statusTable = $status->getBackend()->getTable();
$statusConditions = [
'store_id IN(0,' . (int)$store->getId() . ')',
'attribute_id = ' . (int)$status->getId(),
'entity_id = ' . (int)$id
$linkField . ' = ' . (int)$id,
];
$select = $this->_connection->select();
$select->from(
$statusTable,
['value']
)->where(
implode(' AND ', $statusConditions)
)->order(
'store_id DESC'
);
$select->from($statusTable, ['value'])
->where(implode(' AND ', $statusConditions))
->order('store_id DESC')
->limit(1);
$result = $this->_connection->query($select);
$status = $result->fetch(1);
$status = $result->fetchColumn(0);

if ($status['value'] == \Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED) {
if (isset($ids[0])) {
if (!$tableExists) {
$this->_flatTableBuilder->build(
$store->getId(),
[$ids[0]],
$this->_valueFieldSuffix,
$this->_tableDropSuffix,
false
);
}
$this->flatItemWriter->write($store->getId(), $ids[0], $this->_valueFieldSuffix);
if ($status == \Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED) {
if (!$tableExists) {
$this->_flatTableBuilder->build(
$store->getId(),
$ids,
$this->_valueFieldSuffix,
$this->_tableDropSuffix,
false
);
}
}
if ($status['value'] == \Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_DISABLED) {
$this->flatItemWriter->write($store->getId(), $id, $this->_valueFieldSuffix);
} else {
$this->flatItemEraser->deleteProductsFromStore($id, $store->getId());
}
}

return $this;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@

namespace Magento\Catalog\Test\Unit\Model\Indexer\Product\Flat\Action;

use Magento\Catalog\Api\Data\ProductInterface;
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
use PHPUnit_Framework_MockObject_MockObject as MockObject;

/**
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
Expand All @@ -21,45 +23,48 @@ class RowTest extends \PHPUnit\Framework\TestCase
protected $model;

/**
* @var \PHPUnit_Framework_MockObject_MockObject
* @var MockObject
*/
protected $storeManager;

/**
* @var \PHPUnit_Framework_MockObject_MockObject
* @var MockObject
*/
protected $store;

/**
* @var \PHPUnit_Framework_MockObject_MockObject
* @var MockObject
*/
protected $productIndexerHelper;

/**
* @var \PHPUnit_Framework_MockObject_MockObject
* @var MockObject
*/
protected $resource;

/**
* @var \PHPUnit_Framework_MockObject_MockObject
* @var MockObject
*/
protected $connection;

/**
* @var \PHPUnit_Framework_MockObject_MockObject
* @var MockObject
*/
protected $flatItemWriter;

/**
* @var \PHPUnit_Framework_MockObject_MockObject
* @var MockObject
*/
protected $flatItemEraser;

/**
* @var \PHPUnit_Framework_MockObject_MockObject
* @var MockObject
*/
protected $flatTableBuilder;

/**
* @inheritdoc
*/
protected function setUp()
{
$objectManager = new ObjectManager($this);
Expand All @@ -70,11 +75,11 @@ protected function setUp()
$this->resource = $this->createMock(\Magento\Framework\App\ResourceConnection::class);
$this->resource->expects($this->any())->method('getConnection')
->with('default')
->will($this->returnValue($this->connection));
->willReturn($this->connection);
$this->storeManager = $this->createMock(\Magento\Store\Model\StoreManagerInterface::class);
$this->store = $this->createMock(\Magento\Store\Model\Store::class);
$this->store->expects($this->any())->method('getId')->will($this->returnValue('store_id_1'));
$this->storeManager->expects($this->any())->method('getStores')->will($this->returnValue([$this->store]));
$this->store->expects($this->any())->method('getId')->willReturn('store_id_1');
$this->storeManager->expects($this->any())->method('getStores')->willReturn([$this->store]);
$this->flatItemEraser = $this->createMock(\Magento\Catalog\Model\Indexer\Product\Flat\Action\Eraser::class);
$this->flatItemWriter = $this->createMock(\Magento\Catalog\Model\Indexer\Product\Flat\Action\Indexer::class);
$this->flatTableBuilder = $this->createMock(\Magento\Catalog\Model\Indexer\Product\Flat\FlatTableBuilder::class);
Expand All @@ -89,9 +94,7 @@ protected function setUp()
->disableOriginalConstructor()
->getMock();
$backendMock->expects($this->any())->method('getTable')->willReturn($attributeTable);
$statusAttributeMock->expects($this->any())->method('getBackend')->willReturn(
$backendMock
);
$statusAttributeMock->expects($this->any())->method('getBackend')->willReturn($backendMock);
$statusAttributeMock->expects($this->any())->method('getId')->willReturn($statusId);
$selectMock = $this->getMockBuilder(\Magento\Framework\DB\Select::class)
->disableOriginalConstructor()
Expand All @@ -102,19 +105,30 @@ protected function setUp()
['value']
)->willReturnSelf();
$selectMock->expects($this->any())->method('where')->willReturnSelf();
$selectMock->expects($this->any())->method('order')->willReturnSelf();
$selectMock->expects($this->any())->method('limit')->willReturnSelf();
$pdoMock = $this->createMock(\Zend_Db_Statement_Pdo::class);
$this->connection->expects($this->any())->method('query')->with($selectMock)->will($this->returnValue($pdoMock));
$pdoMock->expects($this->any())->method('fetch')->will($this->returnValue(['value' => 1]));
$this->connection->expects($this->any())->method('query')->with($selectMock)->willReturn($pdoMock);
$pdoMock->expects($this->any())->method('fetchColumn')->willReturn('1');

$metadataPool = $this->createMock(\Magento\Framework\EntityManager\MetadataPool::class);
$productMetadata = $this->getMockBuilder(\Magento\Framework\EntityManager\EntityMetadataInterface::class)
->getMockForAbstractClass();
$metadataPool->expects($this->any())->method('getMetadata')->with(ProductInterface::class)
->willReturn($productMetadata);
$productMetadata->expects($this->any())->method('getLinkField')->willReturn('entity_id');

$this->model = $objectManager->getObject(
\Magento\Catalog\Model\Indexer\Product\Flat\Action\Row::class, [
'resource' => $this->resource,
'storeManager' => $this->storeManager,
'productHelper' => $this->productIndexerHelper,
'flatItemEraser' => $this->flatItemEraser,
'flatItemWriter' => $this->flatItemWriter,
'resource' => $this->resource,
'storeManager' => $this->storeManager,
'productHelper' => $this->productIndexerHelper,
'flatItemEraser' => $this->flatItemEraser,
'flatItemWriter' => $this->flatItemWriter,
'flatTableBuilder' => $this->flatTableBuilder,
]);

$objectManager->setBackwardCompatibleProperty($this->model, 'metadataPool', $metadataPool);
}

/**
Expand All @@ -129,9 +143,9 @@ public function testExecuteWithEmptyId()
public function testExecuteWithNonExistingFlatTablesCreatesTables()
{
$this->productIndexerHelper->expects($this->any())->method('getFlatTableName')
->will($this->returnValue('store_flat_table'));
->willReturn('store_flat_table');
$this->connection->expects($this->any())->method('isTableExists')->with('store_flat_table')
->will($this->returnValue(false));
->willReturn(false);
$this->flatItemEraser->expects($this->never())->method('removeDeletedProducts');
$this->flatTableBuilder->expects($this->once())->method('build')->with('store_id_1', ['product_id_1']);
$this->flatItemWriter->expects($this->once())->method('write')->with('store_id_1', 'product_id_1');
Expand All @@ -141,12 +155,11 @@ public function testExecuteWithNonExistingFlatTablesCreatesTables()
public function testExecuteWithExistingFlatTablesCreatesTables()
{
$this->productIndexerHelper->expects($this->any())->method('getFlatTableName')
->will($this->returnValue('store_flat_table'));
->willReturn('store_flat_table');
$this->connection->expects($this->any())->method('isTableExists')->with('store_flat_table')
->will($this->returnValue(true));
->willReturn(true);
$this->flatItemEraser->expects($this->once())->method('removeDeletedProducts');
$this->flatTableBuilder->expects($this->never())->method('build')->with('store_id_1', ['product_id_1']);
$this->model->execute('product_id_1');
}
}

Loading

0 comments on commit 04113a9

Please sign in to comment.