@@ -89,21 +89,41 @@ public function resolveRootDeltas()
8989 $ target$ this targetMageRootPackage ;
9090 $ user$ this userRootPackage ;
9191
92-  $ this resolveLinkSection ('require ' , $ originalgetRequires (), $ targetgetRequires (), $ usergetRequires ());
92+  $ this resolveLinkSection (
93+  'require ' ,
94+  $ originalgetRequires (),
95+  $ targetgetRequires (),
96+  $ usergetRequires (),
97+  true 
98+  );
9399 $ this resolveLinkSection (
94100 'require-dev ' ,
95101 $ originalgetDevRequires (),
96102 $ targetgetDevRequires (),
97-  $ usergetDevRequires ()
103+  $ usergetDevRequires (),
104+  true 
98105 );
99106 $ this resolveLinkSection (
100107 'conflict ' ,
101108 $ originalgetConflicts (),
102109 $ targetgetConflicts (),
103-  $ usergetConflicts ()
110+  $ usergetConflicts (),
111+  false 
112+  );
113+  $ this resolveLinkSection (
114+  'provide ' ,
115+  $ originalgetProvides (),
116+  $ targetgetProvides (),
117+  $ usergetProvides (),
118+  false 
119+  );
120+  $ this resolveLinkSection (
121+  'replace ' ,
122+  $ originalgetReplaces (),
123+  $ targetgetReplaces (),
124+  $ usergetReplaces (),
125+  false 
104126 );
105-  $ this resolveLinkSection ('provide ' , $ originalgetProvides (), $ targetgetProvides (), $ usergetProvides ());
106-  $ this resolveLinkSection ('replace ' , $ originalgetReplaces (), $ targetgetReplaces (), $ usergetReplaces ());
107127
108128 $ this resolveArraySection ('autoload ' , $ originalgetAutoload (), $ targetgetAutoload (), $ usergetAutoload ());
109129 $ this resolveArraySection (
@@ -215,53 +235,26 @@ public function findResolution(
215235 * @param Link[] $originalMageLinks 
216236 * @param Link[] $targetMageLinks 
217237 * @param Link[] $userLinks 
238+  * @param bool $verifyOrder 
218239 * @return array 
219240 */ 
220-  public  function  resolveLinkSection ($ section$ originalMageLinks$ targetMageLinks$ userLinks
241+  public  function  resolveLinkSection ($ section$ originalMageLinks$ targetMageLinks$ userLinks,  $ verifyOrder 
221242 {
222-  /** @var Link[] $originalLinkMap */ 
223-  $ originalLinkMapstatic ::linksToMap ($ originalMageLinks
224- 
225-  /** @var Link[] $targetLinkMap */ 
226-  $ targetLinkMapstatic ::linksToMap ($ targetMageLinks
227- 
228-  /** @var Link[] $userLinkMap */ 
229-  $ userLinkMapstatic ::linksToMap ($ userLinks
230- 
231243 $ adds
232244 $ removes
233245 $ changes
234-  $ magePackagesarray_unique (array_merge (array_keys ($ originalLinkMap array_keys ($ targetLinkMap 
246+  $ magePackagesarray_unique (array_merge (array_keys ($ originalMageLinks array_keys ($ targetMageLinks 
235247 foreach  ($ magePackagesas  $ pkg
236248 if  ($ section'require '  && PackageUtils::getMagentoProductEdition ($ pkg
237249 continue ;
238250 }
239-  $ field"$ section: $ pkg ;
240-  $ originalConstraintkey_exists ($ pkg$ originalLinkMap$ originalLinkMap$ pkggetConstraint () : null ;
241-  $ originalMageVal$ originalConstraintnull ) ? null  : $ originalConstraint__toString ();
242-  $ prettyOriginalMageVal$ originalConstraintnull ) ? null  : $ originalConstraintgetPrettyString ();
243-  $ targetConstraintkey_exists ($ pkg$ targetLinkMap$ targetLinkMap$ pkggetConstraint () : null ;
244-  $ targetMageVal$ targetConstraintnull ) ? null  : $ targetConstraint__toString ();
245-  $ prettyTargetMageVal$ targetConstraintnull ) ? null  : $ targetConstraintgetPrettyString ();
246-  $ userConstraintkey_exists ($ pkg$ userLinkMap$ userLinkMap$ pkggetConstraint () : null ;
247-  $ userVal$ userConstraintnull ) ? null  : $ userConstraint__toString ();
248-  $ prettyUserVal$ userConstraintnull ) ? null  : $ userConstraintgetPrettyString ();
249- 
250-  $ action$ this findResolution (
251-  $ field
252-  $ originalMageVal
253-  $ targetMageVal
254-  $ userVal
255-  $ prettyOriginalMageVal
256-  $ prettyTargetMageVal
257-  $ prettyUserVal
258-  );
251+  $ action$ this findLinkResolution ($ section$ pkg$ originalMageLinks$ targetMageLinks$ userLinks
259252 if  ($ actionstatic ::ADD_VAL ) {
260-  $ adds$ pkg$ targetLinkMap $ pkg
253+  $ adds$ pkg$ targetMageLinks $ pkg
261254 } elseif  ($ actionstatic ::REMOVE_VAL ) {
262255 $ removes$ pkg
263256 } elseif  ($ actionstatic ::CHANGE_VAL ) {
264-  $ changes$ pkg$ targetLinkMap $ pkg
257+  $ changes$ pkg$ targetMageLinks $ pkg
265258 }
266259 }
267260
@@ -287,11 +280,26 @@ public function resolveLinkSection($section, $originalMageLinks, $targetMageLink
287280 $ this console ->labeledVerbose ("Updating  $ section constraints:  "  . implode (',  ' , $ prettyChanges
288281 }
289282
283+  $ enforcedOrder
284+  if  ($ verifyOrder
285+  $ enforcedOrder$ this getLinkOrderOverride (
286+  $ section
287+  array_keys ($ originalMageLinks
288+  array_keys ($ targetMageLinks
289+  array_keys ($ userLinks
290+  );
291+  if  ($ enforcedOrder
292+  $ changedtrue ;
293+  $ prettyOrder" [ \n  "  . implode (", \n  " , $ enforcedOrder"\n ] " ;
294+  $ this console ->labeledVerbose ("Updating  $ section order: \n$ prettyOrder );
295+  }
296+  }
297+ 
290298 if  ($ changed
291299 $ replacementsarray_values ($ adds
292300
293301 /** @var Link $userLink */ 
294-  foreach  ($ userLinkMap as  $ pkg$ userLink
302+  foreach  ($ userLinks as  $ pkg$ userLink
295303 if  (in_array ($ pkg$ removes
296304 continue ;
297305 } elseif  (key_exists ($ pkg$ changes
@@ -301,6 +309,12 @@ public function resolveLinkSection($section, $originalMageLinks, $targetMageLink
301309 }
302310 }
303311
312+  usort ($ replacements$ this buildLinkOrderComparator (
313+  $ enforcedOrder
314+  array_keys ($ targetMageLinks
315+  array_keys ($ userLinks
316+  ));
317+ 
304318 $ newJson
305319 /** @var Link $link */ 
306320 foreach  ($ replacementsas  $ link
@@ -349,37 +363,15 @@ public function resolveNestedArray($field, $originalMageVal, $targetMageVal, $us
349363 $ result$ userValnull  ? [] : $ userVal
350364
351365 if  (is_array ($ originalMageValis_array ($ targetMageValis_array ($ userVal
352-  $ originalMageAssociativePart
353-  $ originalMageFlatPart
354-  foreach  ($ originalMageValas  $ key$ value
355-  if  (is_string ($ key
356-  $ originalMageAssociativePart$ key$ value
357-  } else  {
358-  $ originalMageFlatPart$ value
359-  }
360-  }
366+  $ originalMageAssociativePartarray_filter ($ originalMageVal'is_string ' , ARRAY_FILTER_USE_KEY );
367+  $ originalMageFlatPartarray_filter ($ originalMageVal'is_int ' , ARRAY_FILTER_USE_KEY );
361368
362-  $ targetMageAssociativePart
363-  $ targetMageFlatPart
364-  foreach  ($ targetMageValas  $ key$ value
365-  if  (is_string ($ key
366-  $ targetMageAssociativePart$ key$ value
367-  } else  {
368-  $ targetMageFlatPart$ value
369-  }
370-  }
369+  $ targetMageAssociativePartarray_filter ($ targetMageVal'is_string ' , ARRAY_FILTER_USE_KEY );
370+  $ targetMageFlatPartarray_filter ($ targetMageVal'is_int ' , ARRAY_FILTER_USE_KEY );
371371
372-  $ userAssociativePart
373-  $ userFlatPart
374-  foreach  ($ userValas  $ key$ value
375-  if  (is_string ($ key
376-  $ userAssociativePart$ key$ value
377-  } else  {
378-  $ userFlatPart$ value
379-  }
380-  }
372+  $ userAssociativePartarray_filter ($ userVal'is_string ' , ARRAY_FILTER_USE_KEY );
381373
382-  $ associativeResultarray_filter ( $ result ,  ' is_string ' ,  ARRAY_FILTER_USE_KEY ) ;
374+  $ associativeResult$ userAssociativePart 
383375 $ mageKeysarray_unique (
384376 array_merge (array_keys ($ originalMageAssociativePartarray_keys ($ targetMageAssociativePart
385377 );
@@ -417,7 +409,7 @@ public function resolveNestedArray($field, $originalMageVal, $targetMageVal, $us
417409 }
418410 }
419411
420-  $ flatResultarray_filter ($ result 'is_int ' , ARRAY_FILTER_USE_KEY );
412+  $ flatResultarray_filter ($ userVal 'is_int ' , ARRAY_FILTER_USE_KEY );
421413 $ flatAddsarray_diff (array_diff ($ targetMageFlatPart$ originalMageFlatPart$ flatResult
422414 if  ($ flatAdds
423415 $ valChangedtrue ;
@@ -456,17 +448,132 @@ public function resolveNestedArray($field, $originalMageVal, $targetMageVal, $us
456448 }
457449
458450 /** 
459-  * Helper function to convert a set of links to an associative array with target package names as keys  
451+  * Helper function to find the resolution action for a package constraint in the Link sections  
460452 * 
461-  * @param Link[] $links 
462-  * @return array 
453+  * @param string $section 
454+  * @param string $pkg 
455+  * @param Link[] $originalLinkMap 
456+  * @param Link[] $targetLinkMap 
457+  * @param Link[] $userLinkMap 
458+  * @return string|null ADD_VAL|REMOVE_VAL|CHANGE_VAL to adjust the link constraint, null for no change 
463459 */ 
464-  protected  function  linksToMap ( $ links 
460+  protected  function  findLinkResolution ( $ section ,  $ pkg ,  $ originalLinkMap ,  $ targetLinkMap ,  $ userLinkMap 
465461 {
466-  $ targetsarray_map (function  ($ link
467-  /** @var Link $link */ 
468-  return  $ linkgetTarget ();
469-  }, $ links
470-  return  array_combine ($ targets$ links
462+  $ field"$ section: $ pkg ;
463+  $ originalConstraintkey_exists ($ pkg$ originalLinkMap$ originalLinkMap$ pkggetConstraint () : null ;
464+  $ originalMageVal$ originalConstraintnull ) ? null  : $ originalConstraint__toString ();
465+  $ prettyOriginalMageVal$ originalConstraintnull ) ? null  : $ originalConstraintgetPrettyString ();
466+  $ targetConstraintkey_exists ($ pkg$ targetLinkMap$ targetLinkMap$ pkggetConstraint () : null ;
467+  $ targetMageVal$ targetConstraintnull ) ? null  : $ targetConstraint__toString ();
468+  $ prettyTargetMageVal$ targetConstraintnull ) ? null  : $ targetConstraintgetPrettyString ();
469+  $ userConstraintkey_exists ($ pkg$ userLinkMap$ userLinkMap$ pkggetConstraint () : null ;
470+  $ userVal$ userConstraintnull ) ? null  : $ userConstraint__toString ();
471+  $ prettyUserVal$ userConstraintnull ) ? null  : $ userConstraintgetPrettyString ();
472+ 
473+  return  $ this findResolution (
474+  $ field
475+  $ originalMageVal
476+  $ targetMageVal
477+  $ userVal
478+  $ prettyOriginalMageVal
479+  $ prettyTargetMageVal
480+  $ prettyUserVal
481+  );
482+  }
483+ 
484+  /** 
485+  * Get the order to use for a link section if local and target versions disagree 
486+  * 
487+  * @param string $section 
488+  * @param string[] $originalMageOrder 
489+  * @param string[] $targetMageOrder 
490+  * @param string[] $userOrder 
491+  * @return string[] 
492+  */ 
493+  protected  function  getLinkOrderOverride ($ section$ originalMageOrder$ targetMageOrder$ userOrder
494+  {
495+  $ overrideOrder
496+ 
497+  $ conflictTargetOrderarray_values (array_intersect ($ targetMageOrder$ userOrder
498+  $ conflictUserOrderarray_values (array_intersect ($ userOrder$ targetMageOrder
499+ 
500+  // Check if the user's link order does not match the target section for links that appear in both 
501+  if  ($ conflictTargetOrder$ conflictUserOrder
502+  $ conflictOriginalOrderarray_values (array_intersect ($ originalMageOrder$ targetMageOrder
503+ 
504+  // Check if the user's order is different than the target order because the order has changed between 
505+  // the original and target Magento versions 
506+  if  ($ conflictOriginalOrder$ conflictUserOrder
507+  $ targetLabel$ this retriever ->getTargetLabel ();
508+  $ userOrderDesc" [ \n  "  . implode (", \n  " , $ conflictUserOrder"\n ] " ;
509+  $ targetOrderDesc" [ \n  "  . implode (", \n  " , $ conflictTargetOrder"\n ] " ;
510+  $ conflictDesc"$ targetLabel is trying to change the existing order of the  $ section section. \n"  .
511+  "Local order: \n$ userOrderDesc$ targetLabel order: \n$ targetOrderDesc ;
512+  $ shouldOverride$ this overrideUserValues ;
513+  if  ($ this overrideUserValues ) {
514+  $ this console ->log ($ conflictDesc
515+  $ this console ->log (
516+  'Overriding local order due to -- '  . MageRootRequireCommand::OVERRIDE_OPT  . '. ' 
517+  );
518+  } else  {
519+  $ shouldOverride$ this console ->ask (
520+  "$ conflictDescWould you like to override the local order? " 
521+  );
522+  }
523+ 
524+  if  (!$ shouldOverride
525+  $ this console ->comment ("$ conflictDesc but it will not be changed. Re-run using  "  .
526+  '-- '  . MageRootRequireCommand::OVERRIDE_OPT  . ' or  '  .
527+  '-- '  . MageRootRequireCommand::INTERACTIVE_OPT  . ' to override with the Magento order. ' );
528+  $ overrideOrder$ conflictUserOrder
529+  } else  {
530+  $ overrideOrder$ conflictTargetOrder
531+  }
532+  } else  {
533+  $ overrideOrder$ conflictTargetOrder
534+  }
535+  }
536+ 
537+  return  $ overrideOrder
538+  }
539+ 
540+  /** 
541+  * Construct a comparison function to use in sorting an array of links by prioritized order lists 
542+  * 
543+  * @param string[] $overrideOrder 
544+  * @param string[] $targetMageOrder 
545+  * @param string[] $userOrder 
546+  * @return \Closure 
547+  */ 
548+  protected  function  buildLinkOrderComparator ($ overrideOrder$ targetMageOrder$ userOrder
549+  {
550+  $ prioritizedOrderings$ overrideOrder$ targetMageOrder$ userOrder
551+ 
552+  return  function  ($ link1$ link2use  ($ prioritizedOrderings
553+  /** 
554+  * @var Link $link1 
555+  * @var Link $link2 
556+  */ 
557+  $ package1$ link1getTarget ();
558+  $ package2$ link2getTarget ();
559+ 
560+  // Check each ordering array to see if it contains both links and if so use their positions to sort 
561+  // If the ordering array does not contain both links, try the next one 
562+  foreach  ($ prioritizedOrderingsas  $ sortOrder
563+  $ index1array_search ($ package1$ sortOrder
564+  $ index2array_search ($ package2$ sortOrder
565+  if  ($ index1false  && $ index2false ) {
566+  if  ($ index1$ index2
567+  return  0 ;
568+  } else  {
569+  return  $ index1$ index21  : 1 ;
570+  }
571+  }
572+  }
573+ 
574+  // None of the ordering arrays contain both elements, so their relative positions in the sorted array 
575+  // do not matter 
576+  return  0 ;
577+  };
471578 }
472579}
0 commit comments