Skip to content

Commit f5a2bc8

Browse files
author
Volodymyr Kublytskyi
authored
Merge branch '2.3-develop' into base64-upload-processor
2 parents 1496207 + f16221f commit f5a2bc8

18 files changed

+788
-33
lines changed

app/code/Magento/ImportService/Api/Data/SourceInterface.php

+3
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ interface SourceInterface extends ExtensibleDataInterface
2020
const IMPORT_DATA = 'import_data';
2121
const CREATED_AT = 'created_at';
2222
const STATUS = 'status';
23+
const STATUS_UPLOADED = 'uploaded';
24+
const STATUS_COMPLETED = 'completed';
25+
const STATUS_FAILED = 'failed';
2326

2427
/**
2528
* @return int

app/code/Magento/ImportService/Api/Data/SourceUploadResponseInterface.php

+15-6
Original file line numberDiff line numberDiff line change
@@ -12,18 +12,14 @@
1212
*/
1313
interface SourceUploadResponseInterface
1414
{
15-
const STATUS_UPLOADED = 'uploaded';
16-
17-
const STATUS_COMPLETED = 'completed';
18-
19-
const STATUS_FAILED = 'failed';
20-
2115
const SOURCE_ID = 'source_id';
2216

2317
const STATUS = 'status';
2418

2519
const ERROR = 'error';
2620

21+
const SOURCE_MODEL = 'source';
22+
2723
/**
2824
* Get file ID
2925
*
@@ -45,6 +41,13 @@ public function getStatus();
4541
*/
4642
public function getError();
4743

44+
/**
45+
* Get source
46+
*
47+
* @return \Magento\ImportService\Api\Data\SourceInterface
48+
*/
49+
public function getSource();
50+
4851
/**
4952
* @param $sourceId
5053
* @return mixed
@@ -62,4 +65,10 @@ public function setStatus($status);
6265
* @return mixed
6366
*/
6467
public function setError($error);
68+
69+
/**
70+
* @param \Magento\ImportService\Api\Data\SourceInterface $source
71+
* @return mixed
72+
*/
73+
public function setSource(\Magento\ImportService\Api\Data\SourceInterface $source);
6574
}

app/code/Magento/ImportService/Exception.php app/code/Magento/ImportService/ImportServiceException.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,6 @@
88
/**
99
* @api
1010
*/
11-
class Exception extends \Magento\Framework\Exception\LocalizedException
11+
class ImportServiceException extends \Magento\Framework\Exception\LocalizedException
1212
{
1313
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
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\ImportService\Model\Import\Processor;
9+
10+
use Magento\Framework\App\Filesystem\DirectoryList;
11+
use Magento\Framework\Filesystem;
12+
use Magento\ImportService\Exception as ImportServiceException;
13+
use Magento\ImportService\Model\Import\SourceProcessorPool;
14+
use Magento\ImportService\Model\Source\Validator;
15+
16+
/**
17+
* CSV files processor for asynchronous import
18+
*/
19+
class ExternalFileProcessor implements SourceProcessorInterface
20+
{
21+
/**
22+
* @var \Magento\Framework\Filesystem
23+
*/
24+
private $fileSystem;
25+
26+
/**
27+
* @var \Magento\ImportService\Model\Source\Validator
28+
*/
29+
private $validator;
30+
31+
/**
32+
* LocalPathFileProcessor constructor
33+
*
34+
* @param FileSystem $fileSystem
35+
* @param Validator $validator
36+
*/
37+
public function __construct(
38+
FileSystem $fileSystem,
39+
Validator $validator
40+
) {
41+
$this->fileSystem = $fileSystem;
42+
$this->validator = $validator;
43+
}
44+
45+
/**
46+
* {@inheritdoc}
47+
*/
48+
public function processUpload(\Magento\ImportService\Api\Data\SourceInterface $source, \Magento\ImportService\Api\Data\SourceUploadResponseInterface $response)
49+
{
50+
/** Validate the $source object */
51+
if ($errors = $this->validator->validateRequest($source)) {
52+
throw new ImportServiceException(
53+
__('Invalid request: %1', implode(", ", $errors))
54+
);
55+
}
56+
57+
/** Check if the domain exists and the file within that domain exists */
58+
if (!$this->validator->checkIfRemoteFileExists($source->getImportData())) {
59+
throw new ImportServiceException(
60+
__('Remote file %1 does not exist.', $source->getImportData())
61+
);
62+
}
63+
64+
/** Validate the remote file content type */
65+
if (!$this->validator->validateMimeTypeForRemoteFile($source->getImportData())) {
66+
throw new ImportServiceException(
67+
__('Invalid mime type, expected is one of: %1', implode(", ", $this->validator->getAllowedMimeTypes()))
68+
);
69+
}
70+
71+
/** @var string $workingDirectory */
72+
$workingDirectory = SourceProcessorPool::WORKING_DIR;
73+
74+
/** @var string $fileName */
75+
$fileName = uniqid() . '.' . $source->getSourceType();
76+
77+
/** @var \Magento\Framework\Filesystem\Directory\WriteInterface $writeInterface */
78+
$writeInterface = $this->fileSystem->getDirectoryWrite(DirectoryList::VAR_DIR);
79+
80+
/** If the directory is not present, it will be created */
81+
$writeInterface->create($workingDirectory);
82+
83+
/** @var string $copyFileFullPath*/
84+
$copyFileFullPath = $writeInterface->getAbsolutePath($workingDirectory) . $fileName;
85+
86+
/** Attempt a copy, may throw \Magento\Framework\Exception\FileSystemException */
87+
$writeInterface->getDriver()->copy($source->getImportData(), $copyFileFullPath);
88+
89+
return $response->setSource($source->setImportData($fileName))
90+
->setStatus($response::STATUS_UPLOADED);
91+
}
92+
}

app/code/Magento/ImportService/Model/Import/Processor/LocalPathFileProcessor.php

+162-5
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,17 @@
77

88
namespace Magento\ImportService\Model\Import\Processor;
99

10+
use Magento\Framework\Exception\CouldNotSaveException;
1011
use Magento\Framework\Filesystem\Io\File;
12+
use Magento\ImportService\Api\Data\SourceInterface;
13+
use Magento\ImportService\Api\Data\SourceUploadResponseInterface;
14+
use Magento\Framework\Filesystem\Directory\WriteInterface;
15+
use Magento\Framework\App\Filesystem\DirectoryList;
16+
use Magento\Framework\Exception\FileSystemException;
17+
use Magento\Framework\Filesystem;
18+
use Magento\ImportService\Api\SourceRepositoryInterface;
19+
use Magento\ImportService\ImportServiceException;
20+
use Magento\ImportService\Model\Import\SourceTypesValidatorInterface;
1121

1222
/**
1323
* CSV files processor for asynchronous import
@@ -23,27 +33,174 @@ class LocalPathFileProcessor implements SourceProcessorInterface
2333
* CSV Source Type
2434
*/
2535
const SOURCE_TYPE_CSV = 'csv';
36+
37+
/**
38+
* @var SourceTypesValidatorInterface
39+
*/
40+
private $sourceTypesValidator;
2641

2742
/**
28-
* @var \Magento\Framework\Filesystem\Io\File
43+
* @var File
2944
*/
3045
private $fileSystemIo;
3146

3247
/**
33-
* LocalPathFileProcessor constructor.
48+
* @var Filesystem
49+
*/
50+
private $fileSystem;
51+
52+
/**
53+
* @var WriteInterface
54+
*/
55+
private $directoryWrite;
56+
57+
/**
58+
* @var SourceRepositoryInterface
59+
*/
60+
private $sourceRepository;
61+
62+
/**
63+
* @var string
64+
*/
65+
private $newFileName;
66+
67+
/**
68+
* @var SourceInterface
69+
*/
70+
private $source;
71+
72+
/**
73+
* LocalPathFileProcessor constructor
74+
*
3475
* @param File $fileSystemIo
76+
* @param Filesystem $fileSystem
77+
* @param SourceTypesValidatorInterface $sourceTypesValidator
78+
* @param SourceRepositoryInterface $sourceRepository
3579
*/
3680
public function __construct(
37-
File $fileSystemIo
81+
File $fileSystemIo,
82+
Filesystem $fileSystem,
83+
SourceTypesValidatorInterface $sourceTypesValidator,
84+
SourceRepositoryInterface $sourceRepository
3885
) {
3986
$this->fileSystemIo = $fileSystemIo;
87+
$this->sourceTypesValidator = $sourceTypesValidator;
88+
$this->fileSystem = $fileSystem;
89+
$this->sourceRepository = $sourceRepository;
4090
}
4191

4292
/**
43-
* {@inheritdoc}
93+
* Uploads process
94+
*
95+
* @inheritdoc
96+
* @throws FileSystemException
97+
* @throws ImportServiceException
4498
*/
45-
public function processUpload(\Magento\ImportService\Api\Data\SourceInterface $source, \Magento\ImportService\Api\Data\SourceUploadResponseInterface $response)
99+
public function processUpload(SourceInterface $source, SourceUploadResponseInterface $response)
46100
{
101+
$this->source = $source;
102+
try {
103+
$this->validateSource();
104+
$this->saveFile();
105+
$source = $this->saveSource();
106+
$response->setStatus($source->getStatus());
107+
$response->setSourceId($source->getSourceId());
108+
} catch (CouldNotSaveException $e) {
109+
$this->removeFile($source->getImportData());
110+
throw new ImportServiceException(__($e->getMessage()));
111+
}
112+
47113
return $response;
48114
}
115+
116+
/**
117+
* Saves source in DB
118+
*
119+
* @return SourceInterface
120+
*/
121+
private function saveSource()
122+
{
123+
$this->source->setImportData($this->getNewFileName());
124+
$this->source->setStatus(SourceInterface::STATUS_UPLOADED);
125+
126+
return $this->sourceRepository->save($this->source);
127+
}
128+
129+
/**
130+
* Saves file at the storage
131+
*
132+
* @return string
133+
* @throws FileSystemException
134+
*/
135+
private function saveFile()
136+
{
137+
$this->directoryWrite->copyFile(
138+
$this->source->getImportData(),
139+
$this->getNewFileName()
140+
);
141+
142+
return $this->getNewFileName();
143+
}
144+
145+
/**
146+
* Generates new file name
147+
*
148+
* @return string
149+
*/
150+
private function getNewFileName()
151+
{
152+
if (!$this->newFileName) {
153+
$this->newFileName = self::IMPORT_SOURCE_FILE_PATH . '/'
154+
. uniqid()
155+
. '.' . $this->source->getSourceType();
156+
}
157+
158+
return $this->newFileName;
159+
}
160+
161+
/**
162+
* Provides configured directoryWrite
163+
*
164+
* @return WriteInterface
165+
* @throws FileSystemException
166+
*/
167+
private function getDirectoryWrite()
168+
{
169+
if (!$this->directoryWrite) {
170+
$this->directoryWrite = $this->fileSystem
171+
->getDirectoryWrite(DirectoryList::ROOT);
172+
}
173+
174+
return $this->directoryWrite;
175+
}
176+
177+
/**
178+
* Validates source
179+
*
180+
* @throws FileSystemException
181+
* @throws ImportServiceException
182+
*/
183+
private function validateSource()
184+
{
185+
$absoluteSourcePath = $this->getDirectoryWrite()
186+
->getAbsolutePath($this->source->getImportData());
187+
if (!$this->fileSystemIo->read($absoluteSourcePath)) {
188+
throw new ImportServiceException(
189+
__("Cannot read from file system. File not existed or cannot be read")
190+
);
191+
}
192+
$this->sourceTypesValidator->execute($this->source);
193+
}
194+
195+
/**
196+
* Removes source
197+
*
198+
* @param string $filename
199+
* @return bool
200+
* @throws FileSystemException
201+
*/
202+
private function removeFile($filename)
203+
{
204+
return $this->getDirectoryWrite()->delete($filename);
205+
}
49206
}

app/code/Magento/ImportService/Model/Import/Processor/SourceProcessorInterface.php

+8-5
Original file line numberDiff line numberDiff line change
@@ -3,24 +3,27 @@
33
* Copyright © Magento, Inc. All rights reserved.
44
* See COPYING.txt for license details.
55
*/
6+
67
declare(strict_types=1);
78

89
namespace Magento\ImportService\Model\Import\Processor;
910

10-
use \Magento\ImportService\Api\Data\SourceInterface;
11-
use \Magento\ImportService\Api\Data\SourceUploadResponseInterface;
11+
use Magento\ImportService\Api\Data\SourceInterface;
12+
use Magento\ImportService\Api\Data\SourceUploadResponseInterface;
13+
use Magento\ImportService\ImportServiceException;
1214

1315
/**
1416
* Request processor interface
1517
*/
1618
interface SourceProcessorInterface
1719
{
20+
// todo discuss the name of constant
21+
const IMPORT_SOURCE_FILE_PATH = "var/import";
22+
1823
/**
1924
* @param SourceInterface $source
2025
* @param SourceUploadResponseInterface $response
21-
* @throws AuthorizationException
22-
* @throws InputException
23-
* @throws Exception
26+
* @throws ImportServiceException
2427
* @return SourceUploadResponseInterface
2528
*/
2629
public function processUpload(SourceInterface $source, SourceUploadResponseInterface $response);

0 commit comments

Comments
 (0)