Skip to content

Commit 92d686d

Browse files
Merge remote-tracking branch '38554/patch-17' into comprs_jul4
2 parents ae32626 + d8fded6 commit 92d686d

File tree

2 files changed

+85
-59
lines changed

2 files changed

+85
-59
lines changed

lib/internal/Magento/Framework/Setup/Patch/PatchApplier.php

Lines changed: 75 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
<?php
22
/**
3-
* Copyright © Magento, Inc. All rights reserved.
4-
* See COPYING.txt for license details.
3+
* Copyright 2018 Adobe
4+
* All Rights Reserved.
55
*/
6+
declare(strict_types=1);
67

78
namespace Magento\Framework\Setup\Patch;
89

@@ -153,19 +154,15 @@ public function applyDataPatch($moduleName = null)
153154
new Phrase("Patch %1 should implement DataPatchInterface", [get_class($dataPatch)])
154155
);
155156
}
157+
if ($this->isApplied($dataPatch)) {
158+
continue;
159+
}
156160
if ($dataPatch instanceof NonTransactionableInterface) {
157-
$dataPatch->apply();
158-
$this->patchHistory->fixPatch(get_class($dataPatch));
161+
$this->applyPatch($dataPatch);
159162
} else {
160163
try {
161164
$this->moduleDataSetup->getConnection()->beginTransaction();
162-
$dataPatch->apply();
163-
$this->patchHistory->fixPatch(get_class($dataPatch));
164-
foreach ($dataPatch->getAliases() as $patchAlias) {
165-
if (!$this->patchHistory->isApplied($patchAlias)) {
166-
$this->patchHistory->fixPatch($patchAlias);
167-
}
168-
}
165+
$this->applyPatch($dataPatch);
169166
$this->moduleDataSetup->getConnection()->commit();
170167
} catch (\Exception $e) {
171168
$this->moduleDataSetup->getConnection()->rollBack();
@@ -187,35 +184,6 @@ public function applyDataPatch($moduleName = null)
187184
}
188185
}
189186

190-
/**
191-
* Register all patches in registry in order to manipulate chains and dependencies of patches of patches
192-
*
193-
* @param string $moduleName
194-
* @param string $patchType
195-
* @return PatchRegistry
196-
*/
197-
private function prepareRegistry($moduleName, $patchType)
198-
{
199-
$reader = $patchType === self::DATA_PATCH ? $this->dataPatchReader : $this->schemaPatchReader;
200-
$registry = $this->patchRegistryFactory->create();
201-
202-
//Prepare modules to read
203-
if ($moduleName === null) {
204-
$patchNames = [];
205-
foreach ($this->moduleList->getNames() as $moduleName) {
206-
$patchNames += $reader->read($moduleName);
207-
}
208-
} else {
209-
$patchNames = $reader->read($moduleName);
210-
}
211-
212-
foreach ($patchNames as $patchName) {
213-
$registry->registerPatch($patchName);
214-
}
215-
216-
return $registry;
217-
}
218-
219187
/**
220188
* Apply all patches for one module
221189
*
@@ -240,12 +208,8 @@ public function applySchemaPatch($moduleName = null)
240208
* @var SchemaPatchInterface $schemaPatch
241209
*/
242210
$schemaPatch = $this->patchFactory->create($schemaPatch, ['schemaSetup' => $this->schemaSetup]);
243-
$schemaPatch->apply();
244-
$this->patchHistory->fixPatch(get_class($schemaPatch));
245-
foreach ($schemaPatch->getAliases() as $patchAlias) {
246-
if (!$this->patchHistory->isApplied($patchAlias)) {
247-
$this->patchHistory->fixPatch($patchAlias);
248-
}
211+
if (!$this->isApplied($schemaPatch)) {
212+
$this->applyPatch($schemaPatch);
249213
}
250214
} catch (\Exception $e) {
251215
$schemaPatchClass = is_object($schemaPatch) ? get_class($schemaPatch) : $schemaPatch;
@@ -297,4 +261,69 @@ public function revertDataPatches($moduleName = null)
297261
}
298262
}
299263
}
264+
265+
/**
266+
* Register all patches in registry in order to manipulate chains and dependencies of patches of patches
267+
*
268+
* @param string $moduleName
269+
* @param string $patchType
270+
* @return PatchRegistry
271+
*/
272+
private function prepareRegistry(string $moduleName, string $patchType): PatchRegistry
273+
{
274+
$reader = $patchType === self::DATA_PATCH ? $this->dataPatchReader : $this->schemaPatchReader;
275+
$registry = $this->patchRegistryFactory->create();
276+
277+
//Prepare modules to read
278+
if ($moduleName === null) {
279+
$patchNames = [];
280+
foreach ($this->moduleList->getNames() as $moduleName) {
281+
$patchNames += $reader->read($moduleName);
282+
}
283+
} else {
284+
$patchNames = $reader->read($moduleName);
285+
}
286+
287+
foreach ($patchNames as $patchName) {
288+
$registry->registerPatch($patchName);
289+
}
290+
291+
return $registry;
292+
}
293+
294+
/**
295+
* Apply the given patch. The patch is and its aliases are added to the history.
296+
*
297+
* @param PatchInterface $patch
298+
*/
299+
private function applyPatch(PatchInterface $patch): void
300+
{
301+
$patch->apply();
302+
$this->patchHistory->fixPatch(get_class($patch));
303+
foreach ($patch->getAliases() ?? [] as $patchAlias) {
304+
if (!$this->patchHistory->isApplied($patchAlias)) {
305+
$this->patchHistory->fixPatch($patchAlias);
306+
}
307+
}
308+
}
309+
310+
/**
311+
* Check wether the given patch or any of its aliases are already applied or not.
312+
*
313+
* @param PatchInterface $patch
314+
*/
315+
private function isApplied(PatchInterface $patch): bool
316+
{
317+
$patchIdentity = get_class($patch);
318+
if (!$this->patchHistory->isApplied($patchIdentity)) {
319+
foreach ($patch->getAliases() ?? [] as $alias) {
320+
if ($this->patchHistory->isApplied($alias)) {
321+
$this->patchHistory->fixPatch($patchIdentity);
322+
return true;
323+
}
324+
}
325+
}
326+
327+
return false;
328+
}
300329
}

lib/internal/Magento/Framework/Setup/Test/Unit/Patch/PatchApplierTest.php

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?php
22
/**
3-
* Copyright © Magento, Inc. All rights reserved.
4-
* See COPYING.txt for license details.
3+
* Copyright 2018 Adobe
4+
* All Rights Reserved.
55
*/
66
declare(strict_types=1);
77

@@ -166,20 +166,17 @@ public function testApplyDataPatchForNewlyInstalledModule($moduleName, $dataPatc
166166
\OtherDataPatch::class
167167
];
168168
$patchRegistryMock = $this->createAggregateIteratorMock(PatchRegistry::class, $patches, ['registerPatch']);
169-
$patchRegistryMock->expects($this->exactly(2))
170-
->method('registerPatch');
169+
$patchRegistryMock->expects($this->exactly(2))->method('registerPatch');
171170

172-
$this->patchRegistryFactoryMock->expects($this->any())
173-
->method('create')
174-
->willReturn($patchRegistryMock);
171+
$this->patchRegistryFactoryMock->expects($this->any())->method('create')->willReturn($patchRegistryMock);
175172
// phpstan:ignore "Class SomeDataPatch not found."
176173
$patch1 = $this->createMock(\SomeDataPatch::class);
177174
$patch1->expects($this->once())->method('apply');
178-
$patch1->expects($this->once())->method('getAliases')->willReturn([]);
175+
$patch1->expects($this->any())->method('getAliases')->willReturn([]);
179176
// phpstan:ignore "Class OtherDataPatch not found."
180177
$patch2 = $this->createMock(\OtherDataPatch::class);
181178
$patch2->expects($this->once())->method('apply');
182-
$patch2->expects($this->once())->method('getAliases')->willReturn([]);
179+
$patch2->expects($this->any())->method('getAliases')->willReturn([]);
183180

184181
$this->objectManagerMock->expects($this->any())->method('create')->willReturnMap(
185182
[
@@ -221,7 +218,7 @@ public function testApplyDataPatchForAlias($moduleName, $dataPatches, $moduleVer
221218
);
222219

223220
$patch1 = $this->getMockForAbstractClass(DataPatchInterface::class);
224-
$patch1->expects($this->once())->method('getAliases')->willReturn(['PatchAlias']);
221+
$patch1->expects($this->any())->method('getAliases')->willReturn(['PatchAlias']);
225222
$patchClass = get_class($patch1);
226223

227224
$patchRegistryMock = $this->createAggregateIteratorMock(PatchRegistry::class, [$patchClass], ['registerPatch']);
@@ -326,7 +323,7 @@ public function testApplyDataPatchForInstalledModule($moduleName, $dataPatches,
326323
public static function applyDataPatchDataInstalledModuleProvider()
327324
{
328325
return [
329-
'upgrade module iwth only OtherDataPatch' => [
326+
'upgrade module with only OtherDataPatch' => [
330327
'moduleName' => 'Module1',
331328
'dataPatches' => [
332329
// phpstan:ignore
@@ -548,7 +545,7 @@ public function testSchemaPatchApplyForPatchAlias($moduleName, $schemaPatches, $
548545
);
549546

550547
$patch1 = $this->getMockForAbstractClass(PatchInterface::class);
551-
$patch1->expects($this->once())->method('getAliases')->willReturn(['PatchAlias']);
548+
$patch1->expects($this->any())->method('getAliases')->willReturn(['PatchAlias']);
552549
$patchClass = get_class($patch1);
553550

554551
$patchRegistryMock = $this->createAggregateIteratorMock(PatchRegistry::class, [$patchClass], ['registerPatch']);
@@ -611,7 +608,7 @@ public function testRevertDataPatches()
611608
public static function schemaPatchDataProvider()
612609
{
613610
return [
614-
'upgrade module iwth only OtherSchemaPatch' => [
611+
'upgrade module with only OtherSchemaPatch' => [
615612
'moduleName' => 'Module1',
616613
'schemaPatches' => [
617614
// phpstan:ignore

0 commit comments

Comments
 (0)