Skip to content

Commit e77bc6b

Browse files
committed
IP-314 Expand the CMS import / export module to cover store blocks/pages
1 parent 3bda7c7 commit e77bc6b

File tree

2 files changed

+78
-17
lines changed

2 files changed

+78
-17
lines changed

Console/Command/ImportCmsData.php

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ class ImportCmsData extends \Symfony\Component\Console\Command\Command
2828
private const INPUT_TYPE_VALUES = ['block', 'page', 'all'];
2929
private const INPUT_KEY_IDENTIFIER = 'identifier';
3030
private const INPUT_KEY_IMPORT_ALL = 'importAll';
31+
private const INPUT_KEY_STORE = 'store';
3132
private \RocketWeb\CmsImportExport\Model\Service\ImportCmsDataService $importCmsDataService;
3233

3334
public function __construct(
@@ -60,6 +61,12 @@ protected function configure()
6061
'a',
6162
InputOption::VALUE_NONE,
6263
'Flag to import all files'
64+
),
65+
new InputOption(
66+
self::INPUT_KEY_STORE,
67+
's',
68+
InputOption::VALUE_OPTIONAL,
69+
'Specific Store Code'
6370
)
6471
]);
6572
parent::configure();
@@ -88,7 +95,11 @@ protected function execute(InputInterface $input, OutputInterface $output): int
8895
$identifiers = explode(',', $identifiers);
8996
}
9097

91-
$this->importCmsDataService->execute($types, $identifiers, $importAll);
98+
$storeCode = empty($input->getOption(self::INPUT_KEY_STORE)) ?
99+
null :
100+
$input->getOption(self::INPUT_KEY_STORE);
101+
102+
$this->importCmsDataService->execute($types, $identifiers, $importAll, $storeCode);
92103

93104
return 0;
94105
}

Model/Service/ImportCmsDataService.php

Lines changed: 66 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,9 @@ public function __construct(
3939
\Magento\Framework\Filesystem\DirectoryList $directoryList,
4040
\Magento\Framework\Filesystem $filesystem,
4141
\Magento\Framework\Serialize\SerializerInterface $serializer,
42-
\Magento\Store\Api\StoreRepositoryInterface $storeRepository
42+
\Magento\Store\Api\StoreRepositoryInterface $storeRepository,
43+
private readonly \Magento\Cms\Api\GetBlockByIdentifierInterface $getBlockByIdentifier,
44+
private readonly \Magento\Cms\Api\GetPageByIdentifierInterface $getPageByIdentifier
4345
) {
4446
$this->pageRepository = $pageRepository;
4547
$this->blockRepository = $blockRepository;
@@ -51,7 +53,7 @@ public function __construct(
5153
$this->storeRepository = $storeRepository;
5254
}
5355

54-
public function execute(array $types, ?array $identifiers, bool $importAll)
56+
public function execute(array $types, ?array $identifiers, bool $importAll, ?string $storeCode)
5557
{
5658
$workingDirPath = 'sync_cms_data';
5759

@@ -70,9 +72,9 @@ public function execute(array $types, ?array $identifiers, bool $importAll)
7072
}
7173

7274
if ($type == 'block') {
73-
$this->importBlocks($typeDirPath, $identifiers);
75+
$this->importBlocks($typeDirPath, $identifiers, $storeCode);
7476
} else if ($type == 'page') {
75-
$this->importPages($typeDirPath, $identifiers);
77+
$this->importPages($typeDirPath, $identifiers, $storeCode);
7678
}
7779
}
7880
}
@@ -97,7 +99,7 @@ private function getStoreIds($storeCodes): array
9799
return $storeIds;
98100
}
99101

100-
private function importBlocks(string $dirPath, ?array $identifiers): void
102+
private function importBlocks(string $dirPath, ?array $identifiers, ?string $storeCode): void
101103
{
102104
$filePaths = $this->directoryRead->read($this->varPath . $dirPath);
103105
foreach ($filePaths as $filePath) {
@@ -112,12 +114,11 @@ private function importBlocks(string $dirPath, ?array $identifiers): void
112114
// If we have a list of items, we skip if its not in the list
113115
continue;
114116
}
115-
116-
try {
117-
$block = $this->blockRepository->getById($identifier);
118-
} catch (\Magento\Framework\Exception\NoSuchEntityException $exception) {
119-
$block = $this->blockFactory->create();
117+
if ($storeCode !== null && ($this->getStoreCode($filePath) !== $storeCode)) {
118+
// Skip identifiers not assigned to specific store when storeCode parameter is set
119+
continue;
120120
}
121+
121122
$content = $this->directoryRead->readFile($filePath);
122123
$jsonData = $this->directoryRead->readFile(str_replace('.html', '.json', $filePath));
123124
$jsonData = $this->serializer->unserialize($jsonData);
@@ -128,6 +129,13 @@ private function importBlocks(string $dirPath, ?array $identifiers): void
128129
'is_active' => $block->isActive()
129130
];*/
130131
$storeIds = $this->getStoreIds($jsonData['stores']);
132+
try {
133+
$block = $this->getBlockByIdentifier->execute($identifier, (int)reset($storeIds));
134+
$this->validateStoreAssociation($filePath, $block, $storeIds, 'Block');
135+
} catch (\Magento\Framework\Exception\NoSuchEntityException $exception) {
136+
$block = $this->blockFactory->create();
137+
}
138+
131139
$block->setTitle($jsonData['title']);
132140
$block->setContent($content);
133141
$block->setIdentifier($jsonData['identifier']);
@@ -145,7 +153,7 @@ private function importBlocks(string $dirPath, ?array $identifiers): void
145153
}
146154
}
147155

148-
private function importPages(string $dirPath, ?array $identifiers): void
156+
private function importPages(string $dirPath, ?array $identifiers, ?string $storeCode): void
149157
{
150158
$filePaths = $this->directoryRead->read($this->varPath . $dirPath);
151159
foreach ($filePaths as $filePath) {
@@ -155,23 +163,29 @@ private function importPages(string $dirPath, ?array $identifiers): void
155163
}
156164
$identifier = str_replace($dirPath, '', $filePath);
157165
$identifier = str_replace('.html', '', $identifier);
158-
$identifier = substr_replace($identifier, '', strpos($identifier, '---'));
166+
$identifier = substr_replace($identifier, '', strrpos($identifier, '---'));
159167
$identifier = str_replace('---', '/', $identifier);
160168
$identifier = str_replace('_html', '.html', $identifier);
161169
if ($identifiers !== null && !in_array($identifier, $identifiers)) {
162170
// If we have a list of items, we skip if its not in the list
163171
continue;
164172
}
165173

166-
try {
167-
$page = $this->pageRepository->getById($identifier);
168-
} catch (\Magento\Framework\Exception\NoSuchEntityException $exception) {
169-
$page = $this->pageFactory->create();
174+
if ($storeCode !== null && ($this->getStoreCode($filePath) !== $storeCode)) {
175+
// Skip identifiers not assigned to specific store when storeCode parameter is set
176+
continue;
170177
}
178+
171179
$content = $this->directoryRead->readFile($filePath);
172180
$jsonData = $this->directoryRead->readFile(str_replace('.html', '.json', $filePath));
173181
$jsonData = $this->serializer->unserialize($jsonData);
174182
$storeIds = $this->getStoreIds($jsonData['stores']);
183+
try {
184+
$page = $this->getPageByIdentifier->execute($identifier, (int)reset($storeIds));
185+
$this->validateStoreAssociation($filePath, $page, $storeIds, 'Page');
186+
} catch (\Magento\Framework\Exception\NoSuchEntityException $exception) {
187+
$page = $this->pageFactory->create();
188+
}
175189
/*$jsonContent = [
176190
'title' => $page->getTitle(),
177191
'is_active' => $page->isActive(),
@@ -197,4 +211,40 @@ private function importPages(string $dirPath, ?array $identifiers): void
197211
}
198212
}
199213
}
214+
215+
private function validateStoreAssociation(
216+
string $filePath,
217+
mixed $entity,
218+
array $storeIds,
219+
string $entityType
220+
) : void {
221+
$exceptionMessage = sprintf('%s with path %s has incosistent store data', $entityType, $filePath);
222+
if (count($storeIds) > 1) {
223+
throw new \LogicException($exceptionMessage);
224+
}
225+
$storeCode = $this->getStoreCode($filePath);
226+
$storeId = (int)reset($storeIds);
227+
$currentStoreIds = $entity->getStoreId();
228+
if ($storeCode === '_all_') {
229+
if ($storeId !== 0 || count($currentStoreIds) > 1 || (int)reset($currentStoreIds) !== 0) {
230+
throw new \LogicException($exceptionMessage);
231+
}
232+
return ;
233+
}
234+
$store = $this->storeRepository->get($storeId);
235+
if ($store->getCode() !== $storeCode) {
236+
throw new \LogicException($exceptionMessage);
237+
}
238+
239+
if (array_diff($currentStoreIds, $storeIds) !== []) {
240+
throw new \LogicException($exceptionMessage);
241+
}
242+
}
243+
244+
private function getStoreCode(string $filePath) : string
245+
{
246+
$storeCode = str_replace('.html', '', $filePath);
247+
$storeCode = substr($storeCode, strrpos($storeCode, '---') + 3);
248+
return $storeCode;
249+
}
200250
}

0 commit comments

Comments
 (0)