Skip to content

Commit 00aa174

Browse files
committed
ACP2E-2152: Error while making concurrent requests to rest/V1/products/<sku>/media
1 parent 0b41085 commit 00aa174

File tree

2 files changed

+96
-19
lines changed

2 files changed

+96
-19
lines changed

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

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,44 @@ private function cacheProduct($cacheKey, ProductInterface $product)
374374
}
375375
}
376376

377+
/**
378+
* If the request is for adding, keep the initial media_gallery data; if it is for deleting, unset it.
379+
*
380+
* @param array $productData
381+
* @return array
382+
*/
383+
private function resetMediaGalleryData(array $productData): array
384+
{
385+
$unset = true;
386+
if (isset($productData['media_gallery'])) {
387+
krsort($productData['media_gallery']['images']);
388+
$isNewEntry = false;
389+
foreach ($productData['media_gallery']['images'] as $entry) {
390+
if (!isset($entry['value_id'])) {
391+
$isNewEntry = true;
392+
break;
393+
}
394+
}
395+
if ($isNewEntry) {
396+
$existingMediaGallery = [];
397+
foreach ($productData['media_gallery']['images'] as $entry) {
398+
if (isset($entry['value_id'])) {
399+
$existingMediaGallery['media_gallery']['images'][$entry['value_id']] = $entry;
400+
}
401+
}
402+
if (isset($existingMediaGallery['media_gallery'])) {
403+
$productData['media_gallery'] = $existingMediaGallery['media_gallery'];
404+
$unset = false;
405+
}
406+
}
407+
}
408+
if ($unset) {
409+
unset($productData['media_gallery']);
410+
}
411+
412+
return $productData;
413+
}
414+
377415
/**
378416
* Merge data from DB and updates from request
379417
*
@@ -384,7 +422,7 @@ private function cacheProduct($cacheKey, ProductInterface $product)
384422
*/
385423
protected function initializeProductData(array $productData, $createNew)
386424
{
387-
unset($productData['media_gallery']);
425+
$productData = $this->resetMediaGalleryData($productData);
388426
if ($createNew) {
389427
$product = $this->productFactory->create();
390428
$this->assignProductToWebsites($product);
@@ -940,7 +978,7 @@ private function joinPositionField(
940978
foreach ($filterGroup->getFilters() as $filter) {
941979
if ($filter->getField() === 'category_id') {
942980
$filterValue = $filter->getValue();
943-
$categoryIds[] = is_array($filterValue) ? $filterValue : explode(',', $filterValue ?? '');
981+
$categoryIds[] = is_array($filterValue) ? $filterValue : explode(',', $filterValue);
944982
}
945983
}
946984
}

app/code/Magento/Catalog/Test/Unit/Model/ProductRepositoryTest.php

Lines changed: 56 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1367,23 +1367,53 @@ protected function setupProductMocksForSave(): void
13671367
public function testSaveExistingWithNewMediaGalleryEntries(): void
13681368
{
13691369
$this->storeManager->expects($this->any())->method('getWebsites')->willReturn([1 => 'default']);
1370+
$newEntry = [
1371+
'value_id' => null,
1372+
'label' => "label_text",
1373+
'position' => 10,
1374+
'disabled' => false,
1375+
'types' => ['image', 'small_image'],
1376+
'content' => [
1377+
'data' => [
1378+
ImageContentInterface::NAME => 'filename',
1379+
ImageContentInterface::TYPE => 'image/jpeg',
1380+
ImageContentInterface::BASE64_ENCODED_DATA => 'encoded_content'
1381+
]
1382+
],
1383+
'media_type' => 'media_type'
1384+
];
13701385
$newEntriesData = [
13711386
'images' => [
13721387
[
1373-
'value_id' => null,
1374-
'label' => "label_text",
1388+
'value_id' => 5,
1389+
"label" => "new_label_text",
1390+
'file' => 'filename1',
13751391
'position' => 10,
13761392
'disabled' => false,
1377-
'types' => ['image', 'small_image'],
1378-
'content' => [
1379-
'data' => [
1380-
ImageContentInterface::NAME => 'filename',
1381-
ImageContentInterface::TYPE => 'image/jpeg',
1382-
ImageContentInterface::BASE64_ENCODED_DATA => 'encoded_content'
1383-
]
1384-
],
1385-
'media_type' => 'media_type'
1386-
]
1393+
'types' => ['image', 'small_image']
1394+
],
1395+
$newEntry
1396+
]
1397+
];
1398+
$initializedEntriesData = [
1399+
'images' => [
1400+
[
1401+
'value_id' => 5,
1402+
"label" => "label_text",
1403+
'file' => 'filename1',
1404+
'position' => 10,
1405+
'disabled' => false,
1406+
'types' => ['image', 'small_image']
1407+
],
1408+
[
1409+
'value_id' => 6,
1410+
"label" => "label_text2",
1411+
'file' => 'filename2',
1412+
'position' => 10,
1413+
'disabled' => false,
1414+
'types' => ['image', 'small_image']
1415+
],
1416+
$newEntry
13871417
]
13881418
];
13891419

@@ -1395,7 +1425,7 @@ public function testSaveExistingWithNewMediaGalleryEntries(): void
13951425
->method('toNestedArray')
13961426
->willReturn($this->productData);
13971427

1398-
$this->initializedProduct->setData('media_gallery', $newEntriesData);
1428+
$this->initializedProduct->setData('media_gallery', $initializedEntriesData);
13991429
$this->initializedProduct->expects($this->any())
14001430
->method('getMediaAttributes')
14011431
->willReturn(["image" => "imageAttribute", "small_image" => "small_image_attribute"]);
@@ -1431,10 +1461,19 @@ public function testSaveExistingWithNewMediaGalleryEntries(): void
14311461
->method('processImageContent')
14321462
->willReturn($absolutePath);
14331463

1434-
$imageFileUri = "imageFileUri";
1435-
$this->processor->expects($this->once())->method('addImage')
1436-
->with($this->initializedProduct, $mediaTmpPath . $absolutePath, ['image', 'small_image'], true, false)
1437-
->willReturn($imageFileUri);
1464+
$imageFileUri = $mediaTmpPath . $absolutePath;
1465+
1466+
$this->processor->expects($this->once())
1467+
->method('addImage')
1468+
->willReturnCallback(
1469+
function ($product, $imageFileUri) use ($newEntriesData) {
1470+
foreach ($product['media_gallery']['images'] as $entry) {
1471+
$this->assertArrayNotHasKey('removed', $entry);
1472+
}
1473+
$this->initializedProduct->setData('media_gallery', $newEntriesData);
1474+
return $imageFileUri;
1475+
}
1476+
);
14381477
$this->processor->expects($this->once())->method('updateImage')
14391478
->with(
14401479
$this->initializedProduct,

0 commit comments

Comments
 (0)