Skip to content
This repository was archived by the owner on Apr 29, 2019. It is now read-only.

Commit 499cdd7

Browse files
Merge pull request #1 from magento/2.3-develop
marge new change
2 parents 8a7f23e + 1548cc2 commit 499cdd7

File tree

44 files changed

+921
-132
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+921
-132
lines changed

app/code/Magento/Catalog/Model/Product.php

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,11 @@ class Product extends \Magento\Catalog\Model\AbstractModel implements
7171
*/
7272
const STORE_ID = 'store_id';
7373

74+
/**
75+
* Product Url path.
76+
*/
77+
const URL_PATH = 'url_path';
78+
7479
/**
7580
* @var string
7681
*/
@@ -923,8 +928,8 @@ public function beforeSave()
923928
*
924929
* If value specified, it will be set.
925930
*
926-
* @param bool $value
927-
* @return bool
931+
* @param bool $value
932+
* @return bool
928933
*/
929934
public function canAffectOptions($value = null)
930935
{

app/code/Magento/Catalog/Model/Product/Attribute/Backend/TierPrice/UpdateHandler.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,12 @@ public function execute($entity, $arguments = [])
9292
$productId = (int) $entity->getData($identifierField);
9393

9494
// prepare original data to compare
95-
$origPrices = $entity->getOrigData($attribute->getName());
95+
$origPrices = [];
96+
$originalId = $entity->getOrigData($identifierField);
97+
if (empty($originalId) || $entity->getData($identifierField) == $originalId) {
98+
$origPrices = $entity->getOrigData($attribute->getName());
99+
}
100+
96101
$old = $this->prepareOriginalDataToCompare($origPrices, $isGlobal);
97102
// prepare data for save
98103
$new = $this->prepareNewDataForSave($priceRows, $isGlobal);

app/code/Magento/Catalog/Model/Product/Copier.php

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,11 @@
88
namespace Magento\Catalog\Model\Product;
99

1010
use Magento\Catalog\Api\Data\ProductInterface;
11+
use Magento\Catalog\Model\Product;
1112

13+
/**
14+
* The copier creates product duplicates.
15+
*/
1216
class Copier
1317
{
1418
/**
@@ -49,7 +53,7 @@ public function __construct(
4953
* @param \Magento\Catalog\Model\Product $product
5054
* @return \Magento\Catalog\Model\Product
5155
*/
52-
public function copy(\Magento\Catalog\Model\Product $product)
56+
public function copy(Product $product)
5357
{
5458
$product->getWebsiteIds();
5559
$product->getCategoryIds();
@@ -79,6 +83,7 @@ public function copy(\Magento\Catalog\Model\Product $product)
7983
? $matches[1] . '-' . ($matches[2] + 1)
8084
: $urlKey . '-1';
8185
$duplicate->setUrlKey($urlKey);
86+
$duplicate->setData(Product::URL_PATH, null);
8287
try {
8388
$duplicate->save();
8489
$isDuplicateSaved = true;
@@ -94,6 +99,8 @@ public function copy(\Magento\Catalog\Model\Product $product)
9499
}
95100

96101
/**
102+
* Returns product option repository.
103+
*
97104
* @return Option\Repository
98105
* @deprecated 101.0.0
99106
*/
@@ -107,6 +114,8 @@ private function getOptionRepository()
107114
}
108115

109116
/**
117+
* Returns metadata pool.
118+
*
110119
* @return \Magento\Framework\EntityManager\MetadataPool
111120
* @deprecated 101.0.0
112121
*/

app/code/Magento/Catalog/Test/Mftf/Data/ProductData.xml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -420,4 +420,17 @@
420420
<data key="status">1</data>
421421
<requiredEntity type="product_extension_attribute">EavStock100</requiredEntity>
422422
</entity>
423+
<entity name="ApiSimpleSingleQty" type="product2">
424+
<data key="sku" unique="suffix">api-simple-product</data>
425+
<data key="type_id">simple</data>
426+
<data key="attribute_set_id">4</data>
427+
<data key="visibility">4</data>
428+
<data key="name" unique="suffix">Api Simple Product</data>
429+
<data key="price">123.00</data>
430+
<data key="urlKey" unique="suffix">api-simple-product</data>
431+
<data key="status">1</data>
432+
<data key="quantity">1</data>
433+
<requiredEntity type="product_extension_attribute">EavStock1</requiredEntity>
434+
<requiredEntity type="custom_attribute">CustomAttributeProductAttribute</requiredEntity>
435+
</entity>
423436
</entities>

app/code/Magento/Catalog/Test/Mftf/Data/ProductExtensionAttributeData.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,7 @@
1717
<entity name="EavStock10" type="product_extension_attribute">
1818
<requiredEntity type="stock_item">Qty_10</requiredEntity>
1919
</entity>
20+
<entity name="EavStock1" type="product_extension_attribute">
21+
<requiredEntity type="stock_item">Qty_1</requiredEntity>
22+
</entity>
2023
</entities>

app/code/Magento/Catalog/Test/Mftf/Data/StockItemData.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,8 @@
2828
<data key="qty">101</data>
2929
<data key="is_in_stock">true</data>
3030
</entity>
31+
<entity name="Qty_1" type="stock_item">
32+
<data key="qty">1</data>
33+
<data key="is_in_stock">true</data>
34+
</entity>
3135
</entities>

app/code/Magento/Catalog/Test/Unit/Model/Attribute/Backend/TierPrice/UpdateHandlerTest.php

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,8 +120,13 @@ public function testExecute(): void
120120
['entity_id', $productId]
121121
]
122122
);
123-
$product->expects($this->atLeastOnce())->method('getOrigData')->with('tier_price')
124-
->willReturn($originalTierPrices);
123+
$product->expects($this->atLeastOnce())->method('getOrigData')
124+
->willReturnMap(
125+
[
126+
['tier_price', $originalTierPrices],
127+
['entity_id', $productId]
128+
]
129+
);
125130
$product->expects($this->atLeastOnce())->method('getStoreId')->willReturn(0);
126131
$product->expects($this->atLeastOnce())->method('setData')->with('tier_price_changed', 1);
127132
$store = $this->getMockBuilder(\Magento\Store\Api\Data\StoreInterface::class)

app/code/Magento/Catalog/Test/Unit/Model/Product/CopierTest.php

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
use Magento\Catalog\Api\Data\ProductInterface;
99
use \Magento\Catalog\Model\Product\Copier;
10+
use Magento\Catalog\Model\Product;
1011

1112
/**
1213
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
@@ -54,7 +55,7 @@ protected function setUp()
5455
\Magento\Catalog\Model\Product\Option\Repository::class
5556
);
5657
$this->optionRepositoryMock;
57-
$this->productMock = $this->createMock(\Magento\Catalog\Model\Product::class);
58+
$this->productMock = $this->createMock(Product::class);
5859
$this->productMock->expects($this->any())->method('getEntityId')->willReturn(1);
5960

6061
$this->metadata = $this->getMockBuilder(\Magento\Framework\EntityManager\EntityMetadata::class)
@@ -106,7 +107,7 @@ public function testCopy()
106107
$this->productMock->expects($this->once())->method('getResource')->will($this->returnValue($resourceMock));
107108

108109
$duplicateMock = $this->createPartialMock(
109-
\Magento\Catalog\Model\Product::class,
110+
Product::class,
110111
[
111112
'__wakeup',
112113
'setData',
@@ -147,10 +148,10 @@ public function testCopy()
147148
)->with(
148149
\Magento\Store\Model\Store::DEFAULT_STORE_ID
149150
);
150-
$duplicateMock->expects($this->once())->method('setData')->with($productData);
151+
$duplicateMock->expects($this->atLeastOnce())->method('setData')->willReturn($duplicateMock);
151152
$this->copyConstructorMock->expects($this->once())->method('build')->with($this->productMock, $duplicateMock);
152153
$duplicateMock->expects($this->once())->method('getUrlKey')->willReturn('urk-key-1');
153-
$duplicateMock->expects($this->once())->method('setUrlKey')->with('urk-key-2');
154+
$duplicateMock->expects($this->once())->method('setUrlKey')->with('urk-key-2')->willReturn($duplicateMock);
154155
$duplicateMock->expects($this->once())->method('save');
155156

156157
$this->metadata->expects($this->any())->method('getLinkField')->willReturn('linkField');

app/code/Magento/CatalogInventory/Model/Indexer/Stock/CacheCleaner.php

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,10 @@
1010

1111
use Magento\CatalogInventory\Api\StockConfigurationInterface;
1212
use Magento\Framework\App\ResourceConnection;
13+
use Magento\Framework\App\ObjectManager;
1314
use Magento\Framework\DB\Adapter\AdapterInterface;
1415
use Magento\Framework\Event\ManagerInterface;
16+
use Magento\Framework\EntityManager\MetadataPool;
1517
use Magento\Framework\Indexer\CacheContext;
1618
use Magento\CatalogInventory\Model\Stock;
1719
use Magento\Catalog\Model\Product;
@@ -46,25 +48,35 @@ class CacheCleaner
4648
*/
4749
private $connection;
4850

51+
/**
52+
* @var MetadataPool
53+
*/
54+
private $metadataPool;
55+
4956
/**
5057
* @param ResourceConnection $resource
5158
* @param StockConfigurationInterface $stockConfiguration
5259
* @param CacheContext $cacheContext
5360
* @param ManagerInterface $eventManager
61+
* @param MetadataPool|null $metadataPool
5462
*/
5563
public function __construct(
5664
ResourceConnection $resource,
5765
StockConfigurationInterface $stockConfiguration,
5866
CacheContext $cacheContext,
59-
ManagerInterface $eventManager
67+
ManagerInterface $eventManager,
68+
MetadataPool $metadataPool = null
6069
) {
6170
$this->resource = $resource;
6271
$this->stockConfiguration = $stockConfiguration;
6372
$this->cacheContext = $cacheContext;
6473
$this->eventManager = $eventManager;
74+
$this->metadataPool = $metadataPool ?: ObjectManager::getInstance()->get(MetadataPool::class);
6575
}
6676

6777
/**
78+
* Clean cache by product ids.
79+
*
6880
* @param array $productIds
6981
* @param callable $reindex
7082
* @return void
@@ -76,22 +88,37 @@ public function clean(array $productIds, callable $reindex)
7688
$productStatusesAfter = $this->getProductStockStatuses($productIds);
7789
$productIds = $this->getProductIdsForCacheClean($productStatusesBefore, $productStatusesAfter);
7890
if ($productIds) {
79-
$this->cacheContext->registerEntities(Product::CACHE_TAG, $productIds);
91+
$this->cacheContext->registerEntities(Product::CACHE_TAG, array_unique($productIds));
8092
$this->eventManager->dispatch('clean_cache_by_tags', ['object' => $this->cacheContext]);
8193
}
8294
}
8395

8496
/**
97+
* Get current stock statuses for product ids.
98+
*
8599
* @param array $productIds
86100
* @return array
87101
*/
88102
private function getProductStockStatuses(array $productIds)
89103
{
104+
$linkField = $this->metadataPool->getMetadata(\Magento\Catalog\Api\Data\ProductInterface::class)
105+
->getLinkField();
90106
$select = $this->getConnection()->select()
91107
->from(
92-
$this->resource->getTableName('cataloginventory_stock_status'),
108+
['css' => $this->resource->getTableName('cataloginventory_stock_status')],
93109
['product_id', 'stock_status', 'qty']
94-
)->where('product_id IN (?)', $productIds)
110+
)
111+
->joinLeft(
112+
['cpr' => $this->resource->getTableName('catalog_product_relation')],
113+
'css.product_id = cpr.child_id',
114+
[]
115+
)
116+
->joinLeft(
117+
['cpe' => $this->resource->getTableName('catalog_product_entity')],
118+
'cpr.parent_id = cpe.' . $linkField,
119+
['parent_id' => 'cpe.entity_id']
120+
)
121+
->where('product_id IN (?)', $productIds)
95122
->where('stock_id = ?', Stock::DEFAULT_STOCK_ID)
96123
->where('website_id = ?', $this->stockConfiguration->getDefaultScopeId());
97124

@@ -125,13 +152,18 @@ private function getProductIdsForCacheClean(array $productStatusesBefore, array
125152
if ($statusBefore['stock_status'] !== $statusAfter['stock_status']
126153
|| ($stockThresholdQty && $statusAfter['qty'] <= $stockThresholdQty)) {
127154
$productIds[] = $productId;
155+
if (isset($statusAfter['parent_id'])) {
156+
$productIds[] = $statusAfter['parent_id'];
157+
}
128158
}
129159
}
130160

131161
return $productIds;
132162
}
133163

134164
/**
165+
* Get database connection.
166+
*
135167
* @return AdapterInterface
136168
*/
137169
private function getConnection()

0 commit comments

Comments
 (0)