Skip to content

Commit bfe081b

Browse files
committed
Merge remote-tracking branch 'origin/MAGETWO-59720' into 2.1-develop-pr30
2 parents 6e6dbf8 + b862756 commit bfe081b

File tree

5 files changed

+266
-101
lines changed

5 files changed

+266
-101
lines changed

app/code/Magento/CatalogImportExport/Model/Import/Product.php

Lines changed: 120 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1418,7 +1418,7 @@ protected function initMediaGalleryResources()
14181418
}
14191419

14201420
/**
1421-
* Get existing images for current bucnh
1421+
* Get existing images for current bunch.
14221422
*
14231423
* @param array $bunch
14241424
* @return array
@@ -1438,7 +1438,21 @@ protected function getExistingImages($bunch)
14381438
)->joinInner(
14391439
['mgvte' => $this->mediaGalleryEntityToValueTableName],
14401440
'(mg.value_id = mgvte.value_id)',
1441-
[$this->getProductEntityLinkField() => 'mgvte.' . $this->getProductEntityLinkField()]
1441+
[
1442+
$this->getProductEntityLinkField() => 'mgvte.' . $this->getProductEntityLinkField(),
1443+
'value_id' => 'mgvte.value_id',
1444+
]
1445+
)->joinLeft(
1446+
['mgv' => $this->mediaGalleryValueTableName],
1447+
sprintf(
1448+
'(mg.value_id = mgv.value_id AND mgv.%s = mgvte.%s AND mgv.store_id = %d)',
1449+
$this->getProductEntityLinkField(),
1450+
$this->getProductEntityLinkField(),
1451+
\Magento\Store\Model\Store::DEFAULT_STORE_ID
1452+
),
1453+
[
1454+
'label' => 'mgv.label',
1455+
]
14421456
)->joinInner(
14431457
['pe' => $this->productEntityTableName],
14441458
"(mgvte.{$this->getProductEntityLinkField()} = pe.{$this->getProductEntityLinkField()})",
@@ -1449,7 +1463,7 @@ protected function getExistingImages($bunch)
14491463
);
14501464

14511465
foreach ($this->_connection->fetchAll($select) as $image) {
1452-
$result[$image['sku']][$image['value']] = true;
1466+
$result[$image['sku']][$image['value']] = $image;
14531467
}
14541468

14551469
return $result;
@@ -1464,22 +1478,21 @@ public function getImagesFromRow(array $rowData)
14641478
$images = [];
14651479
$labels = [];
14661480
foreach ($this->_imagesArrayKeys as $column) {
1467-
$images[$column] = [];
1468-
$labels[$column] = [];
14691481
if (!empty($rowData[$column])) {
14701482
$images[$column] = array_unique(
1471-
explode($this->getMultipleValueSeparator(), $rowData[$column])
1483+
array_map(
1484+
'trim',
1485+
explode($this->getMultipleValueSeparator(), $rowData[$column])
1486+
)
14721487
);
1473-
}
14741488

1475-
if (!empty($rowData[$column . '_label'])) {
1476-
$labels[$column] = explode($this->getMultipleValueSeparator(), $rowData[$column . '_label']);
1477-
}
1489+
if (!empty($rowData[$column . '_label'])) {
1490+
$labels[$column] = $this->parseMultipleValues($rowData[$column . '_label']);
14781491

1479-
if (count($labels[$column]) > count($images[$column])) {
1480-
$labels[$column] = array_slice($labels[$column], 0, count($images[$column]));
1481-
} elseif (count($labels[$column]) < count($images[$column])) {
1482-
$labels[$column] = array_pad($labels[$column], count($images[$column]), '');
1492+
if (count($labels[$column]) > count($images[$column])) {
1493+
$labels[$column] = array_slice($labels[$column], 0, count($images[$column]));
1494+
}
1495+
}
14831496
}
14841497
}
14851498

@@ -1509,6 +1522,7 @@ protected function _saveProducts()
15091522
$this->categoriesCache = [];
15101523
$tierPrices = [];
15111524
$mediaGallery = [];
1525+
$labelsForUpdate = [];
15121526
$uploadedImages = [];
15131527
$previousType = null;
15141528
$prevAttributeSet = null;
@@ -1624,7 +1638,7 @@ protected function _saveProducts()
16241638
foreach ($rowImages as $column => $columnImages) {
16251639
foreach ($columnImages as $columnImageKey => $columnImage) {
16261640
if (!isset($uploadedImages[$columnImage])) {
1627-
$uploadedFile = $this->uploadMediaFiles(trim($columnImage), true);
1641+
$uploadedFile = $this->uploadMediaFiles($columnImage, true);
16281642
if ($uploadedFile) {
16291643
$uploadedImages[$columnImage] = $uploadedFile;
16301644
} else {
@@ -1644,22 +1658,30 @@ protected function _saveProducts()
16441658
$rowData[$column] = $uploadedFile;
16451659
}
16461660

1647-
$imageNotAssigned = !isset($existingImages[$rowSku][$uploadedFile]);
1648-
1649-
if ($uploadedFile && $imageNotAssigned) {
1650-
if ($column == self::COL_MEDIA_IMAGE) {
1651-
$rowData[$column][] = $uploadedFile;
1661+
if ($uploadedFile && !isset($mediaGallery[$rowSku][$uploadedFile])) {
1662+
if (isset($existingImages[$rowSku][$uploadedFile])) {
1663+
if (isset($rowLabels[$column][$columnImageKey])
1664+
&& $rowLabels[$column][$columnImageKey]
1665+
!= $existingImages[$rowSku][$uploadedFile]['label']
1666+
) {
1667+
$labelsForUpdate[] = [
1668+
'label' => $rowLabels[$column][$columnImageKey],
1669+
'imageData' => $existingImages[$rowSku][$uploadedFile]
1670+
];
1671+
}
1672+
} else {
1673+
if ($column == self::COL_MEDIA_IMAGE) {
1674+
$rowData[$column][] = $uploadedFile;
1675+
}
1676+
$mediaGallery[$rowSku][$uploadedFile] = [
1677+
'attribute_id' => $this->getMediaGalleryAttributeId(),
1678+
'label' => isset($rowLabels[$column][$columnImageKey])
1679+
? $rowLabels[$column][$columnImageKey] : '',
1680+
'position' => ++$position,
1681+
'disabled' => isset($disabledImages[$columnImage]) ? '1' : '0',
1682+
'value' => $uploadedFile,
1683+
];
16521684
}
1653-
$label = isset($rowLabels[$column][$columnImageKey]) ?
1654-
$rowLabels[$column][$columnImageKey] : '';
1655-
$mediaGallery[$rowSku][] = [
1656-
'attribute_id' => $this->getMediaGalleryAttributeId(),
1657-
'label' => $label,
1658-
'position' => ++$position,
1659-
'disabled' => isset($disabledImages[$columnImage]) ? '1' : '0',
1660-
'value' => $uploadedFile,
1661-
];
1662-
$existingImages[$rowSku][$uploadedFile] = true;
16631685
}
16641686
}
16651687
}
@@ -1777,6 +1799,8 @@ protected function _saveProducts()
17771799
$mediaGallery
17781800
)->_saveProductAttributes(
17791801
$attributes
1802+
)->updateMediaGalleryLabels(
1803+
$labelsForUpdate
17801804
);
17811805

17821806
$this->_eventManager->dispatch(
@@ -2263,9 +2287,7 @@ public function validateRow(array $rowData, $rowNum)
22632287
$this->_processedEntitiesCount++;
22642288

22652289
$sku = $rowData[self::COL_SKU];
2266-
2267-
$isNewProduct = !isset($this->_oldSku[$sku]) || (Import::BEHAVIOR_REPLACE == $this->getBehavior());
2268-
if (!$isNewProduct) {
2290+
if (isset($this->_oldSku[$sku]) && Import::BEHAVIOR_REPLACE !== $this->getBehavior()) {
22692291
// can we get all necessary data from existent DB product?
22702292
// check for supported type of existing product
22712293
if (isset($this->_productTypeModels[$this->_oldSku[$sku]['type_id']])) {
@@ -2315,7 +2337,7 @@ public function validateRow(array $rowData, $rowNum)
23152337
$rowAttributesValid = $this->_productTypeModels[$newSku['type_id']]->isRowValid(
23162338
$rowData,
23172339
$rowNum,
2318-
$isNewProduct
2340+
!(isset($this->_oldSku[$sku]) && Import::BEHAVIOR_REPLACE !== $this->getBehavior())
23192341
);
23202342
if (!$rowAttributesValid && self::SCOPE_DEFAULT == $rowScope) {
23212343
// mark SCOPE_DEFAULT row as invalid for future child rows if product not in DB already
@@ -2484,18 +2506,20 @@ private function parseAttributesWithWrappedValues($attributesData)
24842506
* Parse values of multiselect attributes depends on "Fields Enclosure" parameter
24852507
*
24862508
* @param string $values
2509+
* @param string $delimiter
24872510
* @return array
24882511
*/
2489-
public function parseMultiselectValues($values)
2512+
public function parseMultiselectValues($values, $delimiter = self::PSEUDO_MULTI_LINE_SEPARATOR)
24902513
{
24912514
if (empty($this->_parameters[Import::FIELDS_ENCLOSURE])) {
2492-
return explode(self::PSEUDO_MULTI_LINE_SEPARATOR, $values);
2515+
return explode($delimiter, $values);
24932516
}
24942517
if (preg_match_all('~"((?:[^"]|"")*)"~', $values, $matches)) {
24952518
return $values = array_map(function ($value) {
24962519
return str_replace('""', '"', $value);
24972520
}, $matches[1]);
24982521
}
2522+
24992523
return [$values];
25002524
}
25012525

@@ -2771,4 +2795,64 @@ private function formatBunchToStockDataRows(
27712795
$indexer->reindexList($productIdsToReindex);
27722796
}
27732797
}
2798+
2799+
/**
2800+
* Update media gallery labels.
2801+
*
2802+
* @param array $labels
2803+
* @return void
2804+
*/
2805+
private function updateMediaGalleryLabels(array $labels)
2806+
{
2807+
if (empty($labels)) {
2808+
return;
2809+
}
2810+
2811+
$insertData = [];
2812+
foreach ($labels as $label) {
2813+
$imageData = $label['imageData'];
2814+
2815+
if ($imageData['label'] === null) {
2816+
$insertData[] = [
2817+
'label' => $label['label'],
2818+
$this->getProductEntityLinkField() => $imageData[$this->getProductEntityLinkField()],
2819+
'value_id' => $imageData['value_id'],
2820+
'store_id' => \Magento\Store\Model\Store::DEFAULT_STORE_ID,
2821+
];
2822+
} else {
2823+
$this->_connection->update(
2824+
$this->mediaGalleryValueTableName,
2825+
[
2826+
'label' => $label['label'],
2827+
],
2828+
[
2829+
$this->getProductEntityLinkField() . ' = ?' => $imageData[$this->getProductEntityLinkField()],
2830+
'value_id = ?' => $imageData['value_id'],
2831+
'store_id = ?' => \Magento\Store\Model\Store::DEFAULT_STORE_ID,
2832+
]
2833+
);
2834+
}
2835+
}
2836+
2837+
if (!empty($insertData)) {
2838+
$this->_connection->insertMultiple(
2839+
$this->mediaGalleryValueTableName,
2840+
$insertData
2841+
);
2842+
}
2843+
}
2844+
2845+
/**
2846+
* Parse values from multiple attributes fields.
2847+
*
2848+
* @param string $labelRow
2849+
* @return array
2850+
*/
2851+
private function parseMultipleValues($labelRow)
2852+
{
2853+
return $this->parseMultiselectValues(
2854+
$labelRow,
2855+
$this->getMultipleValueSeparator()
2856+
);
2857+
}
27742858
}

app/code/Magento/CatalogImportExport/Model/Import/Product/Validator/Media.php

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
*/
66
namespace Magento\CatalogImportExport\Model\Import\Product\Validator;
77

8-
use Magento\CatalogImportExport\Model\Import\Product\Validator\AbstractImportValidator;
98
use Magento\CatalogImportExport\Model\Import\Product\RowValidatorInterface;
109

1110
class Media extends AbstractImportValidator implements RowValidatorInterface
@@ -15,7 +14,11 @@ class Media extends AbstractImportValidator implements RowValidatorInterface
1514
const PATH_REGEXP = '#^(?!.*[\\/]\.{2}[\\/])(?!\.{2}[\\/])[-\w.\\/]+$#';
1615

1716
const ADDITIONAL_IMAGES = 'additional_images';
18-
17+
18+
/**
19+
* @deprecated
20+
* @see \Magento\CatalogImportExport\Model\Import\Product::getMultipleValueSeparator()
21+
*/
1922
const ADDITIONAL_IMAGES_DELIMITER = ',';
2023

2124
/** @var array */
@@ -83,7 +86,7 @@ public function isValid($value)
8386
}
8487
}
8588
if (isset($value[self::ADDITIONAL_IMAGES]) && strlen($value[self::ADDITIONAL_IMAGES])) {
86-
foreach (explode(self::ADDITIONAL_IMAGES_DELIMITER, $value[self::ADDITIONAL_IMAGES]) as $image) {
89+
foreach (explode($this->context->getMultipleValueSeparator(), $value[self::ADDITIONAL_IMAGES]) as $image) {
8790
if (!$this->checkPath($image) && !$this->checkValidUrl($image)) {
8891
$this->_addMessages(
8992
[

app/code/Magento/CatalogImportExport/Test/Unit/Model/Import/Product/Validator/MediaTest.php

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,14 @@
66

77
namespace Magento\CatalogImportExport\Test\Unit\Model\Import\Product\Validator;
88

9+
use Magento\CatalogImportExport\Model\Import\Product;
10+
use Magento\CatalogImportExport\Model\Import\Product\Validator\Media;
911
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper;
12+
use Magento\ImportExport\Model\Import;
1013

1114
class MediaTest extends \PHPUnit_Framework_TestCase
1215
{
13-
/** @var \Magento\CatalogImportExport\Model\Import\Product\Validator\Media */
16+
/** @var Media */
1417
protected $media;
1518

1619
/** @var ObjectManagerHelper */
@@ -21,10 +24,8 @@ protected function setUp()
2124

2225
$this->objectManagerHelper = new ObjectManagerHelper($this);
2326
$this->media = $this->objectManagerHelper->getObject(
24-
'Magento\CatalogImportExport\Model\Import\Product\Validator\Media',
25-
[
26-
27-
]
27+
Media::class,
28+
[]
2829
);
2930
}
3031

@@ -41,6 +42,18 @@ public function testInit()
4142
*/
4243
public function testIsValid($data, $expected)
4344
{
45+
$contextMock = $this->getMockBuilder(Product::class)
46+
->disableOriginalConstructor()
47+
->getMock();
48+
$contextMock->expects($this->any())
49+
->method('getMultipleValueSeparator')
50+
->willReturn(Import::DEFAULT_GLOBAL_MULTI_VALUE_SEPARATOR);
51+
$contextMock->expects($this->any())
52+
->method('retrieveMessageTemplate')
53+
->with(Media::ERROR_INVALID_MEDIA_URL_OR_PATH)
54+
->willReturn('%s');
55+
$this->media->init($contextMock);
56+
4457
$result = $this->media->isValid($data);
4558
$this->assertEquals($expected['result'], $result);
4659
$messages = $this->media->getMessages();
@@ -50,7 +63,7 @@ public function testIsValid($data, $expected)
5063
public function testIsValidClearMessagesCall()
5164
{
5265
$media = $this->getMock(
53-
'\Magento\CatalogImportExport\Model\Import\Product\Validator\Media',
66+
Media::class,
5467
['_clearMessages'],
5568
[],
5669
'',
@@ -78,7 +91,15 @@ public function isMediaValidDataProvider()
7891
'invalid' => [
7992
['_media_image' => 1],
8093
['result' => true,'messages' => []],
81-
]
94+
],
95+
'additional_images' => [
96+
['additional_images' => 'image1.png,image2.jpg'],
97+
['result' => true, 'messages' => []],
98+
],
99+
'additional_images_fail' => [
100+
['additional_images' => 'image1.png|image2.jpg|image3.gif'],
101+
['result' => false, 'messages' => [0 => 'additional_images']],
102+
],
82103
];
83104
}
84105
}

0 commit comments

Comments
 (0)