diff --git a/app/code/Magento/Catalog/Model/Indexer/Product/Price/Action/Full.php b/app/code/Magento/Catalog/Model/Indexer/Product/Price/Action/Full.php
index 88dba03def001..eb15833a7d0b2 100644
--- a/app/code/Magento/Catalog/Model/Indexer/Product/Price/Action/Full.php
+++ b/app/code/Magento/Catalog/Model/Indexer/Product/Price/Action/Full.php
@@ -106,6 +106,9 @@ public function execute($ids = null)
$this->_defaultIndexerResource->getMainTable()
);
+ // Prepare replica table for indexation.
+ $this->_defaultIndexerResource->getConnection()->truncateTable($replicaTable);
+
/** @var \Magento\Catalog\Model\ResourceModel\Product\Indexer\AbstractIndexer $indexer */
foreach ($this->getTypeIndexers() as $indexer) {
$indexer->getTableStrategy()->setUseIdxTable(false);
diff --git a/app/code/Magento/Catalog/Model/ProductRepository.php b/app/code/Magento/Catalog/Model/ProductRepository.php
index aac9ec4807cbf..4a72539e982f2 100644
--- a/app/code/Magento/Catalog/Model/ProductRepository.php
+++ b/app/code/Magento/Catalog/Model/ProductRepository.php
@@ -641,7 +641,7 @@ public function save(\Magento\Catalog\Api\Data\ProductInterface $product, $saveO
}
unset($this->instances[$product->getSku()]);
unset($this->instancesById[$product->getId()]);
- return $this->get($product->getSku());
+ return $this->get($product->getSku(), false, $product->getStoreId());
}
/**
diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Price/BatchSizeCalculator.php b/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Price/BatchSizeCalculator.php
index b31147af2342f..47c23b101a3b2 100644
--- a/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Price/BatchSizeCalculator.php
+++ b/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Price/BatchSizeCalculator.php
@@ -21,15 +21,24 @@ class BatchSizeCalculator
*/
private $estimators;
+ /**
+ * @var \Magento\Catalog\Model\ResourceModel\Product\Indexer\Price\CompositeProductBatchSizeAdjusterInterface[]
+ * @since 2.2.0
+ */
+ private $batchSizeAdjusters;
+
/**
* BatchSizeCalculator constructor.
* @param array $batchRowsCount
* @param array $estimators
+ * @param array $batchSizeAdjusters
+ * @since 2.2.0
*/
- public function __construct(array $batchRowsCount, array $estimators)
+ public function __construct(array $batchRowsCount, array $estimators, array $batchSizeAdjusters)
{
$this->batchRowsCount = $batchRowsCount;
$this->estimators = $estimators;
+ $this->batchSizeAdjusters = $batchSizeAdjusters;
}
/**
@@ -52,6 +61,10 @@ public function estimateBatchSize(\Magento\Framework\DB\Adapter\AdapterInterface
? $this->estimators[$indexerTypeId]
: $this->estimators['default'];
+ $batchRowsCount = isset($this->batchSizeAdjusters[$indexerTypeId])
+ ? $this->batchSizeAdjusters[$indexerTypeId]->adjust($batchRowsCount)
+ : $batchRowsCount;
+
$calculator->ensureBatchSize($connection, $batchRowsCount);
return $batchRowsCount;
diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Price/CompositeProductBatchSizeAdjuster.php b/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Price/CompositeProductBatchSizeAdjuster.php
new file mode 100644
index 0000000000000..0054167c5386f
--- /dev/null
+++ b/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Price/CompositeProductBatchSizeAdjuster.php
@@ -0,0 +1,35 @@
+compositeProductRelationsCalculator = $compositeProductRelationsCalculator;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function adjust($batchSize)
+ {
+ $maxRelationsCount = $this->compositeProductRelationsCalculator->getMaxRelationsCount();
+ return $maxRelationsCount > 0 ? ceil($batchSize / $maxRelationsCount) : $batchSize;
+ }
+}
diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Price/CompositeProductBatchSizeAdjusterInterface.php b/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Price/CompositeProductBatchSizeAdjusterInterface.php
new file mode 100644
index 0000000000000..5472527a85919
--- /dev/null
+++ b/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Price/CompositeProductBatchSizeAdjusterInterface.php
@@ -0,0 +1,22 @@
+indexerResource = $indexerResource;
+ }
+
+ /**
+ * Returns maximum number of composite related products.
+ *
+ * @return int
+ */
+ public function getMaxRelationsCount()
+ {
+ $connection = $this->indexerResource->getConnection();
+ $relationSelect = $connection->select();
+ $relationSelect->from(
+ ['relation' => $this->indexerResource->getTable('catalog_product_relation')],
+ ['count' => new \Zend_Db_Expr('count(relation.child_id)')]
+ );
+ $relationSelect->group('parent_id');
+
+ $maxSelect = $connection->select();
+ $maxSelect->from(
+ ['max_value' => $relationSelect],
+ ['count' => new \Zend_Db_Expr('MAX(count)')]
+ );
+ return $connection->fetchOne($maxSelect);
+ }
+}
diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Price/CompositeProductRowSizeEstimator.php b/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Price/CompositeProductRowSizeEstimator.php
index a3425bfc9d729..94a94c720b026 100644
--- a/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Price/CompositeProductRowSizeEstimator.php
+++ b/app/code/Magento/Catalog/Model/ResourceModel/Product/Indexer/Price/CompositeProductRowSizeEstimator.php
@@ -20,11 +20,6 @@ class CompositeProductRowSizeEstimator implements IndexTableRowSizeEstimatorInte
*/
const MEMORY_SIZE_FOR_ONE_ROW = 200;
- /**
- * @var DefaultPrice
- */
- private $indexerResource;
-
/**
* @var WebsiteManagementInterface
*/
@@ -36,18 +31,25 @@ class CompositeProductRowSizeEstimator implements IndexTableRowSizeEstimatorInte
private $collectionFactory;
/**
- * @param DefaultPrice $indexerResource
+ * @var CompositeProductRelationsCalculator
+ * @since 2.2.0
+ */
+ private $compositeProductRelationsCalculator;
+
+ /**
* @param WebsiteManagementInterface $websiteManagement
* @param CollectionFactory $collectionFactory
+ * @param CompositeProductRelationsCalculator $compositeProductRelationsCalculator
+ * @since 2.2.0
*/
public function __construct(
- DefaultPrice $indexerResource,
WebsiteManagementInterface $websiteManagement,
- CollectionFactory $collectionFactory
+ CollectionFactory $collectionFactory,
+ CompositeProductRelationsCalculator $compositeProductRelationsCalculator
) {
- $this->indexerResource = $indexerResource;
$this->websiteManagement = $websiteManagement;
$this->collectionFactory = $collectionFactory;
+ $this->compositeProductRelationsCalculator = $compositeProductRelationsCalculator;
}
/**
@@ -59,21 +61,7 @@ public function estimateRowSize()
{
$websitesCount = $this->websiteManagement->getCount();
$customerGroupCount = $this->collectionFactory->create()->getSize();
-
- $connection = $this->indexerResource->getConnection();
- $relationSelect = $connection->select();
- $relationSelect->from(
- ['relation' => $this->indexerResource->getTable('catalog_product_relation')],
- ['count' => new \Zend_Db_Expr('count(relation.child_id)')]
- );
- $relationSelect->group('parent_id');
-
- $maxSelect = $connection->select();
- $maxSelect->from(
- ['max_value' => $relationSelect],
- ['count' => new \Zend_Db_Expr('MAX(count)')]
- );
- $maxRelatedProductCount = $connection->fetchOne($maxSelect);
+ $maxRelatedProductCount = $this->compositeProductRelationsCalculator->getMaxRelationsCount();
/**
* Calculate memory size for largest composite product in database.
diff --git a/app/code/Magento/Catalog/Test/Unit/Model/ProductRepositoryTest.php b/app/code/Magento/Catalog/Test/Unit/Model/ProductRepositoryTest.php
index 44d38adc5c15c..b537e2c406cab 100644
--- a/app/code/Magento/Catalog/Test/Unit/Model/ProductRepositoryTest.php
+++ b/app/code/Magento/Catalog/Test/Unit/Model/ProductRepositoryTest.php
@@ -193,7 +193,8 @@ protected function setUp()
'validate',
'save',
'getMediaGalleryEntries',
- 'setData'
+ 'setData',
+ 'getStoreId'
]);
$this->initializedProductMock->expects($this->any())
->method('hasGalleryAttribute')
diff --git a/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Product/Indexer/Price/BatchSizeCalculatorTest.php b/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Product/Indexer/Price/BatchSizeCalculatorTest.php
index 74bce577f53a1..9508782cb4a99 100644
--- a/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Product/Indexer/Price/BatchSizeCalculatorTest.php
+++ b/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Product/Indexer/Price/BatchSizeCalculatorTest.php
@@ -29,7 +29,8 @@ protected function setUp()
$this->batchRowsCount = 200;
$this->model = new \Magento\Catalog\Model\ResourceModel\Product\Indexer\Price\BatchSizeCalculator(
['default' => $this->batchRowsCount],
- ['default' => $this->estimatorMock]
+ ['default' => $this->estimatorMock],
+ []
);
}
diff --git a/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Product/Indexer/Price/CompositeProductBatchSizeAdjusterTest.php b/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Product/Indexer/Price/CompositeProductBatchSizeAdjusterTest.php
new file mode 100644
index 0000000000000..69def72af1669
--- /dev/null
+++ b/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Product/Indexer/Price/CompositeProductBatchSizeAdjusterTest.php
@@ -0,0 +1,39 @@
+relationsCalculatorMock = $this->getMockBuilder(CompositeProductRelationsCalculator::class)
+ ->disableOriginalConstructor()
+ ->getMock();
+ $this->model = new CompositeProductBatchSizeAdjuster($this->relationsCalculatorMock);
+ }
+
+ public function testAdjust()
+ {
+ $this->relationsCalculatorMock->expects($this->once())
+ ->method('getMaxRelationsCount')
+ ->willReturn(200);
+ $this->assertEquals(25, $this->model->adjust(5000));
+ }
+}
diff --git a/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Product/Indexer/Price/CompositeProductRelationsCalculatorTest.php b/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Product/Indexer/Price/CompositeProductRelationsCalculatorTest.php
new file mode 100644
index 0000000000000..3eda8616275a1
--- /dev/null
+++ b/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Product/Indexer/Price/CompositeProductRelationsCalculatorTest.php
@@ -0,0 +1,71 @@
+defaultPriceMock = $this->getMockBuilder(DefaultPrice::class)->disableOriginalConstructor()->getMock();
+ $this->model = new CompositeProductRelationsCalculator($this->defaultPriceMock);
+ }
+
+ public function testGetMaxRelationsCount()
+ {
+ $tableName = 'catalog_product_relation';
+ $maxRelatedProductCount = 200;
+
+ $connectionMock = $this->getMockBuilder(\Magento\Framework\DB\Adapter\AdapterInterface::class)->getMock();
+ $this->defaultPriceMock->expects($this->once())->method('getConnection')->willReturn($connectionMock);
+ $this->defaultPriceMock->expects($this->once())->method('getTable')->with($tableName)->willReturn($tableName);
+
+ $relationSelectMock = $this->getMockBuilder(\Magento\Framework\DB\Select::class)
+ ->disableOriginalConstructor()
+ ->getMock();
+ $relationSelectMock->expects($this->once())
+ ->method('from')
+ ->with(
+ ['relation' => $tableName],
+ ['count' => 'count(relation.child_id)']
+ )
+ ->willReturnSelf();
+ $relationSelectMock->expects($this->once())->method('group')->with('parent_id')->willReturnSelf();
+ $connectionMock->expects($this->at(0))->method('select')->willReturn($relationSelectMock);
+
+ $maxSelectMock = $this->getMockBuilder(\Magento\Framework\DB\Select::class)
+ ->disableOriginalConstructor()
+ ->getMock();
+ $maxSelectMock->expects($this->once())
+ ->method('from')
+ ->with(
+ ['max_value' => $relationSelectMock],
+ ['count' => 'MAX(count)']
+ )
+ ->willReturnSelf();
+ $connectionMock->expects($this->at(1))->method('select')->willReturn($maxSelectMock);
+
+ $connectionMock->expects($this->at(2))
+ ->method('fetchOne')
+ ->with($maxSelectMock)
+ ->willReturn($maxRelatedProductCount);
+
+ $this->assertEquals($maxRelatedProductCount, $this->model->getMaxRelationsCount());
+ }
+}
diff --git a/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Product/Indexer/Price/CompositeProductRowSizeEstimatorTest.php b/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Product/Indexer/Price/CompositeProductRowSizeEstimatorTest.php
index 2eefb4e715ad4..728044b89cafe 100644
--- a/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Product/Indexer/Price/CompositeProductRowSizeEstimatorTest.php
+++ b/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Product/Indexer/Price/CompositeProductRowSizeEstimatorTest.php
@@ -23,7 +23,7 @@ class CompositeProductRowSizeEstimatorTest extends \PHPUnit\Framework\TestCase
/**
* @var \PHPUnit_Framework_MockObject_MockObject
*/
- private $defaultPriceMock;
+ private $relationsCalculatorMock;
/**
* @var \PHPUnit_Framework_MockObject_MockObject
@@ -37,55 +37,27 @@ protected function setUp()
\Magento\Customer\Model\ResourceModel\Group\CollectionFactory::class,
['create']
);
- $this->defaultPriceMock = $this->createMock(
- \Magento\Catalog\Model\ResourceModel\Product\Indexer\Price\DefaultPrice::class
+ $this->relationsCalculatorMock = $this->createMock(
+ \Magento\Catalog\Model\ResourceModel\Product\Indexer\Price\CompositeProductRelationsCalculator::class
);
$this->model = new CompositeProductRowSizeEstimator(
- $this->defaultPriceMock,
$this->websiteManagementMock,
- $this->collectionFactoryMock
+ $this->collectionFactoryMock,
+ $this->relationsCalculatorMock
);
}
public function testEstimateRowSize()
{
$expectedResult = 40000000;
- $tableName = 'catalog_product_relation';
$maxRelatedProductCount = 10;
$this->websiteManagementMock->expects($this->once())->method('getCount')->willReturn(100);
$collectionMock = $this->createMock(\Magento\Customer\Model\ResourceModel\Group\Collection::class);
$this->collectionFactoryMock->expects($this->once())->method('create')->willReturn($collectionMock);
$collectionMock->expects($this->once())->method('getSize')->willReturn(200);
-
- $connectionMock = $this->createMock(\Magento\Framework\DB\Adapter\AdapterInterface::class);
- $this->defaultPriceMock->expects($this->once())->method('getConnection')->willReturn($connectionMock);
- $this->defaultPriceMock->expects($this->once())->method('getTable')->with($tableName)->willReturn($tableName);
-
- $relationSelectMock = $this->createMock(\Magento\Framework\DB\Select::class);
- $relationSelectMock->expects($this->once())
- ->method('from')
- ->with(
- ['relation' => $tableName],
- ['count' => 'count(relation.child_id)']
- )
- ->willReturnSelf();
- $relationSelectMock->expects($this->once())->method('group')->with('parent_id')->willReturnSelf();
- $connectionMock->expects($this->at(0))->method('select')->willReturn($relationSelectMock);
-
- $maxSelectMock = $this->createMock(\Magento\Framework\DB\Select::class);
- $maxSelectMock->expects($this->once())
- ->method('from')
- ->with(
- ['max_value' => $relationSelectMock],
- ['count' => 'MAX(count)']
- )
- ->willReturnSelf();
- $connectionMock->expects($this->at(1))->method('select')->willReturn($maxSelectMock);
-
- $connectionMock->expects($this->at(2))
- ->method('fetchOne')
- ->with($maxSelectMock)
+ $this->relationsCalculatorMock->expects($this->once())
+ ->method('getMaxRelationsCount')
->willReturn($maxRelatedProductCount);
$this->assertEquals(
diff --git a/app/code/Magento/CatalogInventory/Model/Plugin/AroundProductRepositorySave.php b/app/code/Magento/CatalogInventory/Model/Plugin/AroundProductRepositorySave.php
deleted file mode 100644
index d8378556ec3c2..0000000000000
--- a/app/code/Magento/CatalogInventory/Model/Plugin/AroundProductRepositorySave.php
+++ /dev/null
@@ -1,44 +0,0 @@
-get($product->getSku(), false, $product->getStoreId());
- }
-}
diff --git a/app/code/Magento/CatalogInventory/Test/Unit/Model/Plugin/AroundProductRepositorySaveTest.php b/app/code/Magento/CatalogInventory/Test/Unit/Model/Plugin/AroundProductRepositorySaveTest.php
deleted file mode 100644
index 049313a9a3108..0000000000000
--- a/app/code/Magento/CatalogInventory/Test/Unit/Model/Plugin/AroundProductRepositorySaveTest.php
+++ /dev/null
@@ -1,351 +0,0 @@
-markTestSkipped('Test needs to be refactored.');
- $this->stockRegistry = $this->getMockBuilder(StockRegistryInterface::class)
- ->setMethods(['getStockItem', 'updateStockItemBySku'])
- ->getMockForAbstractClass();
- $this->storeManager = $this->getMockBuilder(StoreManagerInterface::class)
- ->getMockForAbstractClass();
- $this->stockConfiguration = $this->getMockBuilder(StockConfigurationInterface::class)
- ->setMethods(['getDefaultScopeId'])
- ->getMockForAbstractClass();
-
- $this->plugin = new AroundProductRepositorySave(
- $this->stockRegistry,
- $this->storeManager,
- $this->stockConfiguration
- );
-
- $this->savedProduct = $this->getMockBuilder(ProductInterface::class)
- ->setMethods(['getExtensionAttributes', 'getStoreId'])
- ->getMockForAbstractClass();
-
- $this->productRepository = $this->getMockBuilder(ProductRepositoryInterface::class)
- ->setMethods(['get'])
- ->getMockForAbstractClass();
- $this->product = $this->getMockBuilder(ProductInterface::class)
- ->setMethods(['getExtensionAttributes', 'getStoreId'])
- ->getMockForAbstractClass();
- $this->productExtension = $this->getMockForAbstractClass(
- ProductExtensionInterface::class,
- [],
- '',
- false,
- false,
- true,
- ['getStockItem']
- );
- $this->stockItem = $this->getMockBuilder(StockItemInterface::class)
- ->setMethods(['setWebsiteId', 'getWebsiteId', 'getStockId'])
- ->getMockForAbstractClass();
- $this->defaultStock = $this->getMockBuilder(StockInterface::class)
- ->setMethods(['getStockId'])
- ->getMockForAbstractClass();
- }
-
- public function testAfterSaveWhenProductHasNoStockItemNeedingToBeUpdated()
- {
- // pretend we have no extension attributes at all
- $this->product->expects($this->once())
- ->method('getExtensionAttributes')
- ->willReturn(null);
- $this->productExtension->expects($this->never())->method('getStockItem');
-
- // pretend that the product already has existing stock item information
- $this->stockRegistry->expects($this->once())->method('getStockItem')->willReturn($this->stockItem);
- $this->stockItem->expects($this->once())->method('getItemId')->willReturn(1);
- $this->stockItem->expects($this->never())->method('setProductId');
- $this->stockItem->expects($this->never())->method('setWebsiteId');
-
- // expect that there are no changes to the existing stock item information
- $result = $this->plugin->afterSave($this->productRepository, $this->savedProduct, $this->product);
- $this->assertEquals(
- $this->savedProduct,
- $result
- );
- }
-
- public function testAfterSaveWhenProductHasNoPersistentStockItemInfo()
- {
- // pretend we do have extension attributes, but none for 'stock_item'
- $this->product->expects($this->once())
- ->method('getExtensionAttributes')
- ->willReturn($this->productExtension);
- $this->productExtension->expects($this->once())
- ->method('getStockItem')
- ->willReturn(null);
-
- $this->stockConfiguration->expects($this->once())->method('getDefaultScopeId')->willReturn(1);
- $this->stockRegistry->expects($this->once())->method('getStockItem')->willReturn($this->stockItem);
- $this->stockRegistry->expects($this->once())->method('updateStockItemBySku');
-
- $this->stockItem->expects($this->once())->method('getItemId')->willReturn(null);
- $this->stockItem->expects($this->once())->method('setProductId');
- $this->stockItem->expects($this->once())->method('setWebsiteId');
- $this->product->expects(($this->atLeastOnce()))->method('getStoreId')->willReturn(20);
-
- $newProductMock = $this->getMockBuilder(\Magento\Catalog\Api\Data\ProductInterface::class)
- ->disableOriginalConstructor()->getMock();
- $this->productRepository->expects($this->once())->method('get')->willReturn($newProductMock);
-
- $this->assertEquals(
- $newProductMock,
- $this->plugin->afterSave($this->productRepository, $this->savedProduct, $this->product)
- );
- }
-
- public function testAfterSave()
- {
- $productId = 5494;
- $storeId = 2;
- $sku = 'my product that needs saving';
- $defaultScopeId = 100;
- $this->stockConfiguration->expects($this->exactly(2))
- ->method('getDefaultScopeId')
- ->willReturn($defaultScopeId);
- $this->stockRegistry->expects($this->once())
- ->method('getStock')
- ->with($defaultScopeId)
- ->willReturn($this->defaultStock);
-
- $this->product->expects($this->once())
- ->method('getExtensionAttributes')
- ->willReturn($this->productExtension);
- $this->productExtension->expects($this->once())
- ->method('getStockItem')
- ->willReturn($this->stockItem);
-
- $storedStockItem = $this->getMockBuilder(StockItemInterface::class)
- ->setMethods(['getItemId'])
- ->getMockForAbstractClass();
- $storedStockItem->expects($this->once())
- ->method('getItemId')
- ->willReturn(500);
- $this->stockRegistry->expects($this->once())
- ->method('getStockItem')
- ->willReturn($storedStockItem);
-
- $this->product->expects(($this->exactly(2)))->method('getId')->willReturn($productId);
- $this->product->expects(($this->atLeastOnce()))->method('getStoreId')->willReturn($storeId);
- $this->product->expects($this->atLeastOnce())->method('getSku')->willReturn($sku);
-
- $this->stockItem->expects($this->once())->method('setProductId')->with($productId);
- $this->stockItem->expects($this->once())->method('setWebsiteId')->with($defaultScopeId);
-
- $this->stockRegistry->expects($this->once())
- ->method('updateStockItemBySku')
- ->with($sku, $this->stockItem);
-
- $newProductMock = $this->getMockBuilder(\Magento\Catalog\Api\Data\ProductInterface::class)
- ->disableOriginalConstructor()->getMock();
- $this->productRepository->expects($this->once())
- ->method('get')
- ->with($sku, false, $storeId, true)
- ->willReturn($newProductMock);
-
- $this->assertEquals(
- $newProductMock,
- $this->plugin->afterSave($this->productRepository, $this->savedProduct, $this->product)
- );
- }
-
- /**
- * @expectedException \Magento\Framework\Exception\LocalizedException
- * @expectedExceptionMessage Invalid stock id: 100500. Only default stock with id 50 allowed
- */
- public function testAfterSaveWithInvalidStockId()
- {
- $stockId = 100500;
- $defaultScopeId = 100;
- $defaultStockId = 50;
-
- $this->stockItem->expects($this->once())
- ->method('getStockId')
- ->willReturn($stockId);
- $this->stockRegistry->expects($this->once())
- ->method('getStock')
- ->with($defaultScopeId)
- ->willReturn($this->defaultStock);
- $this->stockConfiguration->expects($this->once())
- ->method('getDefaultScopeId')
- ->willReturn($defaultScopeId);
- $this->defaultStock->expects($this->once())
- ->method('getStockId')
- ->willReturn($defaultStockId);
-
- $this->product->expects($this->once())
- ->method('getExtensionAttributes')
- ->willReturn($this->productExtension);
- $this->productExtension->expects($this->once())
- ->method('getStockItem')
- ->willReturn($this->stockItem);
-
- $this->plugin->afterSave($this->productRepository, $this->savedProduct, $this->product);
- }
-
- /**
- * @expectedException \Magento\Framework\Exception\LocalizedException
- * @expectedExceptionMessage Invalid stock item id: 0. Should be null or numeric value greater than 0
- */
- public function testAfterSaveWithInvalidStockItemId()
- {
- $stockId = 80;
- $stockItemId = 0;
- $defaultScopeId = 100;
- $defaultStockId = 80;
-
- $this->stockItem->expects($this->once())
- ->method('getStockId')
- ->willReturn($stockId);
- $this->stockRegistry->expects($this->once())
- ->method('getStock')
- ->with($defaultScopeId)
- ->willReturn($this->defaultStock);
- $this->stockConfiguration->expects($this->once())
- ->method('getDefaultScopeId')
- ->willReturn($defaultScopeId);
- $this->defaultStock->expects($this->once())
- ->method('getStockId')
- ->willReturn($defaultStockId);
-
- $this->product->expects($this->once())
- ->method('getExtensionAttributes')
- ->willReturn($this->productExtension);
- $this->productExtension->expects($this->once())
- ->method('getStockItem')
- ->willReturn($this->stockItem);
-
- $this->stockItem->expects($this->once())
- ->method('getItemId')
- ->willReturn($stockItemId);
-
- $this->plugin->afterSave($this->productRepository, $this->savedProduct, $this->product);
- }
-
- /**
- * @expectedException \Magento\Framework\Exception\LocalizedException
- * @expectedExceptionMessage Invalid stock item id: 35. Assigned stock item id is 40
- */
- public function testAfterSaveWithNotAssignedStockItemId()
- {
- $stockId = 80;
- $stockItemId = 35;
- $defaultScopeId = 100;
- $defaultStockId = 80;
- $storedStockitemId = 40;
-
- $this->stockItem->expects($this->once())
- ->method('getStockId')
- ->willReturn($stockId);
- $this->stockRegistry->expects($this->once())
- ->method('getStock')
- ->with($defaultScopeId)
- ->willReturn($this->defaultStock);
- $this->stockConfiguration->expects($this->once())
- ->method('getDefaultScopeId')
- ->willReturn($defaultScopeId);
- $this->defaultStock->expects($this->once())
- ->method('getStockId')
- ->willReturn($defaultStockId);
-
- $this->product->expects($this->once())
- ->method('getExtensionAttributes')
- ->willReturn($this->productExtension);
- $this->productExtension->expects($this->once())
- ->method('getStockItem')
- ->willReturn($this->stockItem);
-
- $this->stockItem->expects($this->once())
- ->method('getItemId')
- ->willReturn($stockItemId);
-
- $storedStockItem = $this->getMockBuilder(StockItemInterface::class)
- ->setMethods(['getItemId'])
- ->getMockForAbstractClass();
- $storedStockItem->expects($this->once())
- ->method('getItemId')
- ->willReturn($storedStockitemId);
- $this->stockRegistry->expects($this->once())
- ->method('getStockItem')
- ->willReturn($storedStockItem);
-
- $this->plugin->afterSave($this->productRepository, $this->savedProduct, $this->product);
- }
-}
diff --git a/app/code/Magento/CatalogInventory/etc/di.xml b/app/code/Magento/CatalogInventory/etc/di.xml
index e62470b3ae0fb..2f64d71595c86 100644
--- a/app/code/Magento/CatalogInventory/etc/di.xml
+++ b/app/code/Magento/CatalogInventory/etc/di.xml
@@ -71,9 +71,6 @@
-
-
-
Magento\CatalogInventory\Model\Indexer\Stock\Processor
diff --git a/app/code/Magento/ConfigurableProduct/Model/Plugin/ProductRepositorySave.php b/app/code/Magento/ConfigurableProduct/Model/Plugin/ProductRepositorySave.php
index 075b07c38eb9f..54b6e42ff7678 100644
--- a/app/code/Magento/ConfigurableProduct/Model/Plugin/ProductRepositorySave.php
+++ b/app/code/Magento/ConfigurableProduct/Model/Plugin/ProductRepositorySave.php
@@ -81,9 +81,9 @@ public function afterSave(
$attributeCodes[] = $attributeCode;
}
$this->validateProductLinks($attributeCodes, $configurableLinks);
- $product->getTypeInstance()->resetConfigurableAttributes($product);
+ $result->getTypeInstance()->resetConfigurableAttributes($product);
- return $product;
+ return $result;
}
/**
diff --git a/app/code/Magento/ConfigurableProduct/etc/di.xml b/app/code/Magento/ConfigurableProduct/etc/di.xml
index 1ec382bf37b29..30fd8737c3820 100644
--- a/app/code/Magento/ConfigurableProduct/etc/di.xml
+++ b/app/code/Magento/ConfigurableProduct/etc/di.xml
@@ -180,6 +180,9 @@
- Magento\Catalog\Model\Indexer\Price\CompositeProductBatchSizeManagement
+
+ - Magento\Catalog\Model\ResourceModel\Product\Indexer\Price\CompositeProductBatchSizeAdjuster
+
diff --git a/app/code/Magento/GroupedProduct/etc/di.xml b/app/code/Magento/GroupedProduct/etc/di.xml
index ff2cac0bd3186..f39bcfa01453c 100644
--- a/app/code/Magento/GroupedProduct/etc/di.xml
+++ b/app/code/Magento/GroupedProduct/etc/di.xml
@@ -94,6 +94,9 @@
- Magento\Catalog\Model\Indexer\Price\CompositeProductBatchSizeManagement
+
+ - Magento\Catalog\Model\ResourceModel\Product\Indexer\Price\CompositeProductBatchSizeAdjuster
+
diff --git a/app/code/Magento/ProductVideo/view/frontend/web/js/fotorama-add-video-events.js b/app/code/Magento/ProductVideo/view/frontend/web/js/fotorama-add-video-events.js
index f78e424d741eb..03ce42bf25c4a 100644
--- a/app/code/Magento/ProductVideo/view/frontend/web/js/fotorama-add-video-events.js
+++ b/app/code/Magento/ProductVideo/view/frontend/web/js/fotorama-add-video-events.js
@@ -617,6 +617,7 @@ define([
var videoSettings;
videoSettings = this.options.videoSettings[0];
+ $image.find('.' + this.PV).remove();
$image.append(
'
+ - catalog_category_product
+ - catalog_product_category
+
@@ -45,6 +49,10 @@
4
catalogProductSimple::default_in_custom_website
catalogProductSimple::default
+
+ - catalog_category_product
+ - catalog_product_category
+
@@ -61,6 +69,10 @@
7
7
catalogProductSimple::default_in_custom_website
+
+ - catalog_category_product
+ - catalog_product_category
+
diff --git a/dev/tests/functional/tests/app/Magento/CatalogImportExport/Test/etc/testcase.xml b/dev/tests/functional/tests/app/Magento/CatalogImportExport/Test/etc/testcase.xml
index 3438787d668f7..be8bf8b89dd16 100644
--- a/dev/tests/functional/tests/app/Magento/CatalogImportExport/Test/etc/testcase.xml
+++ b/dev/tests/functional/tests/app/Magento/CatalogImportExport/Test/etc/testcase.xml
@@ -11,6 +11,7 @@
-
+
+
diff --git a/dev/tests/functional/tests/app/Magento/Indexer/Test/TestStep/ReindexStep.php b/dev/tests/functional/tests/app/Magento/Indexer/Test/TestStep/ReindexStep.php
new file mode 100644
index 0000000000000..1a3cb4a034765
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Indexer/Test/TestStep/ReindexStep.php
@@ -0,0 +1,50 @@
+indexer = $indexer;
+ $this->indexerType = $indexerType;
+ }
+
+ /**
+ * Run reindex process.
+ * All indexers will be refreshed in a case of empty $indexerType array.
+ *
+ * @return void
+ */
+ public function run()
+ {
+ $this->indexer->reindex($this->indexerType);
+ }
+}
diff --git a/lib/internal/Magento/Framework/EntityManager/OperationPool.php b/lib/internal/Magento/Framework/EntityManager/OperationPool.php
index f79df58f89a24..97d580e328b1b 100644
--- a/lib/internal/Magento/Framework/EntityManager/OperationPool.php
+++ b/lib/internal/Magento/Framework/EntityManager/OperationPool.php
@@ -8,12 +8,28 @@
use Magento\Framework\ObjectManagerInterface as ObjectManager;
use Magento\Framework\EntityManager\OperationInterface;
+use Magento\Framework\EntityManager\Operation\CheckIfExists;
+use Magento\Framework\EntityManager\Operation\Read;
+use Magento\Framework\EntityManager\Operation\Create;
+use Magento\Framework\EntityManager\Operation\Update;
+use Magento\Framework\EntityManager\Operation\Delete;
/**
* Class OperationPool
*/
class OperationPool
{
+ /**
+ * @var array
+ */
+ private $defaultOperations = [
+ 'checkIfExists' => CheckIfExists::class,
+ 'read' => Read::class,
+ 'create' => Create::class,
+ 'update' => Update::class,
+ 'delete' => Delete::class,
+ ];
+
/**
* @var array
*/
@@ -31,10 +47,13 @@ class OperationPool
*/
public function __construct(
ObjectManager $objectManager,
- $operations
+ $operations = []
) {
$this->objectManager = $objectManager;
- $this->operations = $operations;
+ $this->operations = array_replace_recursive(
+ ['default' => $this->defaultOperations],
+ $operations
+ );
}
/**
diff --git a/lib/internal/Magento/Framework/EntityManager/Test/Unit/OperationPoolTest.php b/lib/internal/Magento/Framework/EntityManager/Test/Unit/OperationPoolTest.php
new file mode 100644
index 0000000000000..cd44a3088122f
--- /dev/null
+++ b/lib/internal/Magento/Framework/EntityManager/Test/Unit/OperationPoolTest.php
@@ -0,0 +1,47 @@
+createMock(ObjectManagerInterface::class);
+ $operationPool = new OperationPool(
+ $objectManagerMock,
+ []
+ );
+
+ $objectManagerMock->expects($this->once())
+ ->method('get')
+ ->with(\Magento\Framework\EntityManager\Operation\Read::class);
+ $operationPool->getOperation('entity_type', 'read');
+ }
+
+ public function testGetOperationUsesOverriddenDefaultValueForEntityThatDoesNotProvideCustomMapping()
+ {
+ $customReadOperation = 'CustomReadOperation';
+ $objectManagerMock = $this->createMock(ObjectManagerInterface::class);
+ $operationPool = new OperationPool(
+ $objectManagerMock,
+ [
+ 'default' => [
+ 'read' => $customReadOperation,
+ 'new' => 'CustomNewOperation',
+ ],
+ ]
+ );
+
+ $objectManagerMock->expects($this->once())
+ ->method('get')
+ ->with($customReadOperation);
+ $operationPool->getOperation('entity_type', 'read');
+ }
+}