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
78namespace 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}
0 commit comments