44
55use CodedMonkey \Dirigent \Doctrine \Repository \PackageRepository ;
66use CodedMonkey \Dirigent \Validator \UniquePackage ;
7+ use Composer \Package \Version \VersionParser ;
78use Composer \Pcre \Preg ;
89use Doctrine \Common \Collections \ArrayCollection ;
910use Doctrine \Common \Collections \Collection ;
@@ -91,6 +92,8 @@ class Package
9192 */
9293 private array $ cachedVersions ;
9394
95+ private array $ sortedVersions ;
96+
9497 public function __construct ()
9598 {
9699 $ this ->installations = new PackageInstallations ($ this );
@@ -376,18 +379,30 @@ public function getPrettyBrowsableRepositoryUrl(): ?string
376379 }
377380
378381 /**
379- * Returns the default branch or latest version of the package.
382+ * @return Version[]
383+ */
384+ public function getSortedVersions (): array
385+ {
386+ if (!isset ($ this ->sortedVersions )) {
387+ $ this ->sortedVersions = $ this ->versions ->toArray ();
388+
389+ usort ($ this ->sortedVersions , [static ::class, 'sortVersions ' ]);
390+ }
391+
392+ return $ this ->sortedVersions ;
393+ }
394+
395+ /**
396+ * Returns the default branch or the latest version of the package.
380397 */
381398 public function getDefaultVersion (): ?Version
382399 {
383- $ versions = $ this ->versions -> toArray ();
400+ $ versions = $ this ->getSortedVersions ();
384401
385402 if (!count ($ versions )) {
386403 return null ;
387404 }
388405
389- usort ($ versions , [static ::class, 'sortVersions ' ]);
390-
391406 $ latestVersion = reset ($ versions );
392407 foreach ($ versions as $ version ) {
393408 if ($ version ->isDefaultBranch ()) {
@@ -403,14 +418,12 @@ public function getDefaultVersion(): ?Version
403418 */
404419 public function getLatestVersion (): ?Version
405420 {
406- $ versions = $ this ->versions -> toArray ();
421+ $ versions = $ this ->getSortedVersions ();
407422
408423 if (!count ($ versions )) {
409424 return null ;
410425 }
411426
412- usort ($ versions , [static ::class, 'sortVersions ' ]);
413-
414427 foreach ($ versions as $ version ) {
415428 if (!$ version ->isDevelopment ()) {
416429 return $ version ;
@@ -420,6 +433,108 @@ public function getLatestVersion(): ?Version
420433 return $ this ->getDefaultVersion ();
421434 }
422435
436+ public function getActiveVersions (): array
437+ {
438+ $ versionParser = new VersionParser ();
439+
440+ $ activeVersions = [];
441+ $ activePrereleaseVersions = [];
442+
443+ foreach ($ this ->getSortedVersions () as $ version ) {
444+ [$ majorVersion , $ minorVersion ] = explode ('. ' , $ version ->getNormalizedVersion ());
445+
446+ if ('7.3.0.0 ' === $ version ->getNormalizedVersion ()) {
447+ // todo REMOVE break for testing
448+ continue ;
449+ }
450+
451+ if ('stable ' !== VersionParser::parseStability ($ version ->getNormalizedVersion ())) {
452+ continue ;
453+ }
454+
455+ if ('0 ' === $ majorVersion ) {
456+ $ prereleaseVersion = "$ majorVersion. $ minorVersion " ;
457+
458+ $ activePrereleaseVersions [$ prereleaseVersion ] ??= $ version ;
459+ if (version_compare ($ version ->getNormalizedVersion (), $ activePrereleaseVersions [$ prereleaseVersion ]->getNormalizedVersion (), '> ' )) {
460+ $ activePrereleaseVersions [$ prereleaseVersion ] = $ version ;
461+ }
462+
463+ continue ;
464+ }
465+
466+ $ activeVersions [$ majorVersion ] ??= $ version ;
467+ if (version_compare ($ version ->getNormalizedVersion (), $ activeVersions [$ majorVersion ]->getNormalizedVersion (), '> ' )) {
468+ $ activeVersions [$ majorVersion ] = $ version ;
469+ }
470+ }
471+
472+ $ activeDevelopmentVersions = [];
473+ $ activePrereleaseDevelopmentVersions = [];
474+
475+ // Find newer unstable releases of active versions
476+ foreach ($ this ->getSortedVersions () as $ version ) {
477+ [$ majorVersion , $ minorVersion ] = explode ('. ' , $ version ->getNormalizedVersion ());
478+
479+ if (in_array (VersionParser::parseStability ($ version ->getNormalizedVersion ()), ['stable ' , 'dev ' ], true )) {
480+ continue ;
481+ }
482+
483+ $ developmentVersion = "$ majorVersion. $ minorVersion " ;
484+
485+ if ('0 ' === $ majorVersion ) {
486+ if (isset ($ activePrereleaseVersions [$ developmentVersion ]) && !version_compare ($ version ->getNormalizedVersion (), $ activePrereleaseVersions [$ developmentVersion ]->getNormalizedVersion (), '> ' )) {
487+ continue ;
488+ }
489+
490+ $ activePrereleaseDevelopmentVersions [$ developmentVersion ] ??= $ version ;
491+ if (version_compare ($ version ->getNormalizedVersion (), $ activePrereleaseDevelopmentVersions [$ developmentVersion ]->getNormalizedVersion (), '> ' )) {
492+ $ activePrereleaseDevelopmentVersions [$ developmentVersion ] = $ version ;
493+ }
494+
495+ continue ;
496+ }
497+
498+ if (isset ($ activeVersions [$ majorVersion ]) && !version_compare ($ version ->getNormalizedVersion (), $ activeVersions [$ majorVersion ]->getNormalizedVersion (), '> ' )) {
499+ continue ;
500+ }
501+
502+ $ activeDevelopmentVersions [$ developmentVersion ] ??= $ version ;
503+ if (version_compare ($ version ->getNormalizedVersion (), $ activeDevelopmentVersions [$ developmentVersion ]->getNormalizedVersion (), '> ' )) {
504+ $ activeDevelopmentVersions [$ version ->getNormalizedVersion ()] = $ version ;
505+ }
506+ }
507+
508+ $ activeVersions = [...$ activeVersions , ...$ activeDevelopmentVersions ];
509+
510+ if (count ($ activeVersions )) {
511+ usort ($ activeVersions , [static ::class, 'sortVersions ' ]);
512+
513+ return $ activeVersions ;
514+ }
515+
516+ $ activePrereleaseVersions = [...$ activePrereleaseVersions , ...$ activePrereleaseDevelopmentVersions ];
517+
518+ usort ($ activePrereleaseVersions , [static ::class, 'sortVersions ' ]);
519+
520+ return $ activePrereleaseVersions ;
521+ }
522+
523+ public function getHistoricalVersions (): array
524+ {
525+
526+ }
527+
528+ public function getDevelopmentVersions (): array
529+ {
530+
531+ }
532+
533+ public function getDevelopmentBranchVersions (): array
534+ {
535+
536+ }
537+
423538 public static function sortVersions (Version $ a , Version $ b ): int
424539 {
425540 $ aVersion = $ a ->getNormalizedVersion ();
0 commit comments