Skip to content

Commit f4a7067

Browse files
committed
Merge remote-tracking branch 'origin/MC-29959' into 2.4-develop-pr9
2 parents a94cddf + d546aa2 commit f4a7067

File tree

11 files changed

+399
-34
lines changed

11 files changed

+399
-34
lines changed

app/code/Magento/DownloadableImportExport/Helper/Data.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
use Magento\DownloadableImportExport\Model\Import\Product\Type\Downloadable;
99

1010
/**
11-
* Class Data
11+
* Helper for import-export downloadable product
1212
*/
1313
class Data extends \Magento\Framework\App\Helper\AbstractHelper
1414
{
@@ -47,6 +47,7 @@ public function isRowDownloadableNoValid(array $rowData)
4747
* @param array $option
4848
* @param array $existingOptions
4949
* @return array
50+
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
5051
*/
5152
public function fillExistOptions(array $base, array $option, array $existingOptions)
5253
{
@@ -59,6 +60,9 @@ public function fillExistOptions(array $base, array $option, array $existingOpti
5960
&& $option['sample_file'] == $existingOption['sample_file']
6061
&& $option['sample_type'] == $existingOption['sample_type']
6162
&& $option['product_id'] == $existingOption['product_id']) {
63+
if (empty($existingOption['website_id'])) {
64+
unset($existingOption['website_id']);
65+
}
6266
$result = array_replace($base, $option, $existingOption);
6367
}
6468
}

app/code/Magento/DownloadableImportExport/Helper/Uploader.php

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
use Magento\Framework\App\Filesystem\DirectoryList;
99

1010
/**
11-
* Class Uploader
11+
* Uploader helper for downloadable products
1212
*/
1313
class Uploader extends \Magento\Framework\App\Helper\AbstractHelper
1414
{
@@ -105,6 +105,17 @@ public function getUploader($type, $parameters)
105105
return $this->fileUploader;
106106
}
107107

108+
/**
109+
* Check a file or directory exists
110+
*
111+
* @param string $fileName
112+
* @return bool
113+
*/
114+
public function isFileExist(string $fileName): bool
115+
{
116+
return $this->mediaDirectory->isExist($this->fileUploader->getDestDir().$fileName);
117+
}
118+
108119
/**
109120
* Get all allowed extensions
110121
*
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
namespace Magento\DownloadableImportExport\Model\Export\Product\Type;
7+
8+
use Magento\CatalogImportExport\Model\Export\Product\Type\AbstractType;
9+
10+
/**
11+
* Class Downloadable for composite CatalogImportExport
12+
*/
13+
class Downloadable extends AbstractType
14+
{
15+
}
Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\DownloadableImportExport\Model\Export;
9+
10+
use Magento\Downloadable\Model\LinkRepository;
11+
use Magento\Downloadable\Model\SampleRepository;
12+
use Magento\Catalog\Model\ResourceModel\Product\Collection as ProductCollection;
13+
use Magento\CatalogImportExport\Model\Export\RowCustomizerInterface;
14+
use Magento\CatalogImportExport\Model\Import\Product as ImportProduct;
15+
use Magento\Downloadable\Model\Product\Type as Type;
16+
use Magento\ImportExport\Model\Import;
17+
use Magento\Store\Model\Store;
18+
use Magento\Store\Model\StoreManagerInterface;
19+
use Magento\DownloadableImportExport\Model\Import\Product\Type\Downloadable;
20+
21+
/**
22+
* Customizes output during export
23+
*/
24+
class RowCustomizer implements RowCustomizerInterface
25+
{
26+
/**
27+
* @var array
28+
*/
29+
private $downloadableData = [];
30+
31+
/**
32+
* @var string[]
33+
*/
34+
private $downloadableColumns = [
35+
Downloadable::COL_DOWNLOADABLE_LINKS,
36+
Downloadable::COL_DOWNLOADABLE_SAMPLES,
37+
];
38+
39+
/**
40+
* @var LinkRepository
41+
*/
42+
private $linkRepository;
43+
44+
/**
45+
* @var SampleRepository
46+
*/
47+
private $sampleRepository;
48+
49+
/**
50+
* @var StoreManagerInterface
51+
*/
52+
private $storeManager;
53+
54+
/**
55+
* @param StoreManagerInterface $storeManager
56+
* @param LinkRepository $linkRepository
57+
* @param SampleRepository $sampleRepository
58+
*/
59+
public function __construct(
60+
StoreManagerInterface $storeManager,
61+
LinkRepository $linkRepository,
62+
SampleRepository $sampleRepository
63+
) {
64+
$this->storeManager = $storeManager;
65+
$this->linkRepository = $linkRepository;
66+
$this->sampleRepository = $sampleRepository;
67+
}
68+
69+
/**
70+
* Prepare configurable data for export
71+
*
72+
* @param ProductCollection $collection
73+
* @param int[] $productIds
74+
* @return void
75+
*/
76+
public function prepareData($collection, $productIds): void
77+
{
78+
$productCollection = clone $collection;
79+
$productCollection->addAttributeToFilter('entity_id', ['in' => $productIds])
80+
->addAttributeToFilter('type_id', ['eq' => Type::TYPE_DOWNLOADABLE])
81+
->addAttributeToSelect('links_title')
82+
->addAttributeToSelect('samples_title');
83+
// set global scope during export
84+
$this->storeManager->setCurrentStore(Store::DEFAULT_STORE_ID);
85+
foreach ($collection as $product) {
86+
$productLinks = $this->linkRepository->getLinksByProduct($product);
87+
$productSamples = $this->sampleRepository->getSamplesByProduct($product);
88+
$this->downloadableData[$product->getId()] = [];
89+
$linksData = [];
90+
$samplesData = [];
91+
foreach ($productLinks as $linkId => $link) {
92+
$linkData = $link->getData();
93+
$linkData['group_title'] = $product->getData('links_title');
94+
$linksData[$linkId] = $this->optionRowToCellString($linkData);
95+
}
96+
foreach ($productSamples as $sampleId => $sample) {
97+
$sampleData = $sample->getData();
98+
$sampleData['group_title'] = $product->getData('samples_title');
99+
$samplesData[$sampleId] = $this->optionRowToCellString($sampleData);
100+
}
101+
$this->downloadableData[$product->getId()] = [
102+
Downloadable::COL_DOWNLOADABLE_LINKS => implode(
103+
ImportProduct::PSEUDO_MULTI_LINE_SEPARATOR,
104+
$linksData
105+
),
106+
Downloadable::COL_DOWNLOADABLE_SAMPLES => implode(
107+
Import::DEFAULT_GLOBAL_MULTI_VALUE_SEPARATOR,
108+
$samplesData
109+
)];
110+
}
111+
}
112+
113+
/**
114+
* Convert option row to cell string
115+
*
116+
* @param array $option
117+
* @return string
118+
*/
119+
private function optionRowToCellString(array $option): string
120+
{
121+
$result = [];
122+
foreach ($option as $attributeCode => $value) {
123+
if ($value) {
124+
$result[] = $attributeCode . ImportProduct::PAIR_NAME_VALUE_SEPARATOR . $value;
125+
}
126+
}
127+
return implode(Import::DEFAULT_GLOBAL_MULTI_VALUE_SEPARATOR, $result);
128+
}
129+
130+
/**
131+
* Set headers columns
132+
*
133+
* @param array $columns
134+
* @return array
135+
*/
136+
public function addHeaderColumns($columns): array
137+
{
138+
return array_merge($columns, $this->downloadableColumns);
139+
}
140+
141+
/**
142+
* Add downloadable data for export
143+
*
144+
* @param array $dataRow
145+
* @param int $productId
146+
* @return array
147+
*/
148+
public function addData($dataRow, $productId): array
149+
{
150+
if (!empty($this->downloadableData[$productId])) {
151+
$dataRow = array_merge($dataRow, $this->downloadableData[$productId]);
152+
}
153+
return $dataRow;
154+
}
155+
156+
/**
157+
* Calculate the largest links block
158+
*
159+
* @param array $additionalRowsCount
160+
* @param int $productId
161+
* @return array
162+
*/
163+
public function getAdditionalRowsCount($additionalRowsCount, $productId): array
164+
{
165+
if (!empty($this->downloadableData[$productId])) {
166+
$additionalRowsCount = max($additionalRowsCount, count($this->downloadableData[$productId]));
167+
}
168+
return $additionalRowsCount;
169+
}
170+
}

app/code/Magento/DownloadableImportExport/Model/Import/Product/Type/Downloadable.php

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -896,12 +896,16 @@ protected function parseSampleOption($values)
896896
protected function uploadDownloadableFiles($fileName, $type = 'links', $renameFileOff = false)
897897
{
898898
try {
899-
$res = $this->uploaderHelper->getUploader($type, $this->parameters)->move($fileName, $renameFileOff);
900-
return $res['file'];
899+
$uploader = $this->uploaderHelper->getUploader($type, $this->parameters);
900+
if (!$this->uploaderHelper->isFileExist($fileName)) {
901+
$uploader->move($fileName, $renameFileOff);
902+
$fileName = $uploader['file'];
903+
}
901904
} catch (\Exception $e) {
902905
$this->_entityModel->addRowError(self::ERROR_MOVE_FILE, $this->rowNum);
903-
return '';
906+
$fileName = '';
904907
}
908+
return $fileName;
905909
}
906910

907911
/**

app/code/Magento/DownloadableImportExport/Test/Unit/Model/Import/Product/Type/DownloadableTest.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManager;
1010

1111
/**
12-
* Class DownloadableTest
12+
* Class DownloadableTest for downloadable products import
1313
*
1414
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
1515
*/
@@ -164,7 +164,7 @@ protected function setUp()
164164
// 7. $fileHelper
165165
$this->uploaderHelper = $this->createPartialMock(
166166
\Magento\DownloadableImportExport\Helper\Uploader::class,
167-
['getUploader']
167+
['getUploader', 'isFileExist']
168168
);
169169
$this->uploaderHelper->expects($this->any())->method('getUploader')->willReturn($this->uploaderMock);
170170
$this->downloadableHelper = $this->createPartialMock(
@@ -660,6 +660,7 @@ public function testSetUploaderDirFalse($newSku, $bunch, $allowImport, $parsedOp
660660
$metadataPoolMock->expects($this->any())->method('getLinkField')->willReturn('entity_id');
661661
$this->downloadableHelper->expects($this->atLeastOnce())
662662
->method('fillExistOptions')->willReturn($parsedOptions['link']);
663+
$this->uploaderHelper->method('isFileExist')->willReturn(false);
663664

664665
$this->downloadableModelMock = $this->objectManagerHelper->getObject(
665666
\Magento\DownloadableImportExport\Model\Import\Product\Type\Downloadable::class,
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?xml version="1.0"?>
2+
<!--
3+
/**
4+
* Copyright © Magento, Inc. All rights reserved.
5+
* See COPYING.txt for license details.
6+
*/
7+
-->
8+
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
9+
<type name="Magento\CatalogImportExport\Model\Export\RowCustomizer\Composite">
10+
<arguments>
11+
<argument name="customizers" xsi:type="array">
12+
<item name="downloadableProduct" xsi:type="string">Magento\DownloadableImportExport\Model\Export\RowCustomizer</item>
13+
</argument>
14+
</arguments>
15+
</type>
16+
</config>
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?xml version="1.0"?>
2+
<!--
3+
/**
4+
* Copyright © Magento, Inc. All rights reserved.
5+
* See COPYING.txt for license details.
6+
*/
7+
-->
8+
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_ImportExport:etc/export.xsd">
9+
<entityType entity="catalog_product" name="downloadable" model="Magento\DownloadableImportExport\Model\Export\Product\Type\Downloadable" />
10+
</config>

0 commit comments

Comments
 (0)