44
55use CodedMonkey \Dirigent \Attribute \IsGrantedAccess ;
66use CodedMonkey \Dirigent \Doctrine \Entity \Package ;
7+ use CodedMonkey \Dirigent \Doctrine \Entity \PackageProvideLink ;
8+ use CodedMonkey \Dirigent \Doctrine \Entity \PackageRequireLink ;
9+ use CodedMonkey \Dirigent \Doctrine \Entity \PackageSuggestLink ;
710use CodedMonkey \Dirigent \Doctrine \Repository \PackageRepository ;
11+ use CodedMonkey \Dirigent \EasyAdmin \PackagePaginator ;
812use Composer \Semver \VersionParser ;
13+ use Doctrine \ORM \EntityManagerInterface ;
14+ use Doctrine \ORM \QueryBuilder ;
915use Symfony \Bundle \FrameworkBundle \Controller \AbstractController ;
16+ use Symfony \Component \HttpFoundation \Request ;
1017use Symfony \Component \HttpFoundation \Response ;
1118use Symfony \Component \Routing \Attribute \Route ;
1219
1320class DashboardPackagesInfoController extends AbstractController
1421{
1522 public function __construct (
23+ private readonly EntityManagerInterface $ entityManager ,
1624 private readonly PackageRepository $ packageRepository ,
1725 ) {
1826 }
@@ -24,10 +32,7 @@ public function info(string $packageName): Response
2432 $ package = $ this ->packageRepository ->findOneBy (['name ' => $ packageName ]);
2533 $ version = $ package ->getLatestVersion ();
2634
27- return $ this ->render ('dashboard/packages/package_info.html.twig ' , [
28- 'package ' => $ package ,
29- 'version ' => $ version ,
30- ]);
35+ return $ this ->versionInfo ($ packageName , $ version ->getNormalizedVersion ());
3136 }
3237
3338 #[Route('/packages/{packageName}/v/{packageVersion} ' , name: 'dashboard_packages_version_info ' , requirements: ['packageName ' => '[a-z0-9_.-]+/[a-z0-9_.-]+ ' ])]
@@ -37,9 +42,19 @@ public function versionInfo(string $packageName, string $packageVersion): Respon
3742 $ package = $ this ->packageRepository ->findOneBy (['name ' => $ packageName ]);
3843 $ version = $ package ->getVersion ((new VersionParser ())->normalize ($ packageVersion ));
3944
45+ $ dependentCount = $ this ->entityManager ->getRepository (PackageRequireLink::class)->count (['linkedPackageName ' => $ package ->getName ()]);
46+ $ implementationCount = $ this ->entityManager ->getRepository (PackageProvideLink::class)->count (['linkedPackageName ' => $ package ->getName (), 'implementation ' => true ]);
47+ $ providerCount = $ this ->entityManager ->getRepository (PackageProvideLink::class)->count (['linkedPackageName ' => $ package ->getName (), 'implementation ' => false ]);
48+ $ suggesterCount = $ this ->entityManager ->getRepository (PackageSuggestLink::class)->count (['linkedPackageName ' => $ package ->getName ()]);
49+
4050 return $ this ->render ('dashboard/packages/package_info.html.twig ' , [
4151 'package ' => $ package ,
4252 'version ' => $ version ,
53+
54+ 'dependentCount ' => $ dependentCount ,
55+ 'implementationCount ' => $ implementationCount ,
56+ 'providerCount ' => $ providerCount ,
57+ 'suggesterCount ' => $ suggesterCount ,
4358 ]);
4459 }
4560
@@ -58,6 +73,80 @@ public function versions(string $packageName): Response
5873 ]);
5974 }
6075
76+ #[Route('/packages/{packageName}/dependents ' , name: 'dashboard_packages_dependents ' , requirements: ['packageName ' => '[a-z0-9_.-]+/[a-z0-9_.-]+ ' ])]
77+ #[IsGrantedAccess]
78+ public function dependents (Request $ request , string $ packageName ): Response
79+ {
80+ $ package = $ this ->packageRepository ->findOneBy (['name ' => $ packageName ]);
81+
82+ return $ this ->packageLinks ($ request , $ package , PackageRequireLink::class, 'Dependents ' );
83+ }
84+
85+ #[Route('/packages/{packageName}/implementations ' , name: 'dashboard_packages_implementations ' , requirements: ['packageName ' => '[a-z0-9_.-]+/[a-z0-9_.-]+ ' ])]
86+ #[IsGrantedAccess]
87+ public function implementations (Request $ request , string $ packageName ): Response
88+ {
89+ $ package = $ this ->packageRepository ->findOneBy (['name ' => $ packageName ]);
90+
91+ $ providerRepository = $ this ->entityManager ->getRepository (PackageProvideLink::class);
92+ $ queryBuilder = $ providerRepository ->createQueryBuilder ('provider ' );
93+ $ queryBuilder
94+ ->leftJoin ('provider.package ' , 'package ' )
95+ ->andWhere ('provider.linkedPackageName = :packageName ' )
96+ ->andWhere ('provider.implementation = true ' )
97+ ->setParameter ('packageName ' , $ package ->getName ());
98+
99+ return $ this ->packageLinks ($ request , $ package , PackageProvideLink::class, 'Implementations ' , queryBuilder: $ queryBuilder );
100+ }
101+
102+ #[Route('/packages/{packageName}/providers ' , name: 'dashboard_packages_providers ' , requirements: ['packageName ' => '[a-z0-9_.-]+/[a-z0-9_.-]+ ' ])]
103+ #[IsGrantedAccess]
104+ public function providers (Request $ request , string $ packageName ): Response
105+ {
106+ $ package = $ this ->packageRepository ->findOneBy (['name ' => $ packageName ]);
107+
108+ $ providerRepository = $ this ->entityManager ->getRepository (PackageProvideLink::class);
109+ $ queryBuilder = $ providerRepository ->createQueryBuilder ('provider ' );
110+ $ queryBuilder
111+ ->leftJoin ('provider.package ' , 'package ' )
112+ ->andWhere ('provider.linkedPackageName = :packageName ' )
113+ ->andWhere ('provider.implementation = false ' )
114+ ->setParameter ('packageName ' , $ package ->getName ());
115+
116+ return $ this ->packageLinks ($ request , $ package , PackageProvideLink::class, 'Providers ' , queryBuilder: $ queryBuilder );
117+ }
118+
119+ #[Route('/packages/{packageName}/suggesters ' , name: 'dashboard_packages_suggesters ' , requirements: ['packageName ' => '[a-z0-9_.-]+/[a-z0-9_.-]+ ' ])]
120+ #[IsGrantedAccess]
121+ public function suggesters (Request $ request , string $ packageName ): Response
122+ {
123+ $ package = $ this ->packageRepository ->findOneBy (['name ' => $ packageName ]);
124+
125+ return $ this ->packageLinks ($ request , $ package , PackageSuggestLink::class, 'Suggesters ' );
126+ }
127+
128+ private function packageLinks (Request $ request , Package $ package , string $ linkClass , string $ title , ?QueryBuilder $ queryBuilder = null ): Response
129+ {
130+ if (!$ queryBuilder ) {
131+ $ dependentRepository = $ this ->entityManager ->getRepository ($ linkClass );
132+ $ queryBuilder = $ dependentRepository ->createQueryBuilder ('link ' );
133+ $ queryBuilder
134+ ->leftJoin ('link.package ' , 'package ' )
135+ ->andWhere ('link.linkedPackageName = :packageName ' )
136+ ->setParameter ('packageName ' , $ package ->getName ());
137+ }
138+
139+ $ paginator = PackagePaginator::fromRequest ($ request , $ queryBuilder , $ this ->container ->get ('router ' ));
140+ $ packageLinks = $ paginator ->getResults ();
141+
142+ return $ this ->render ('dashboard/packages/package_links.html.twig ' , [
143+ 'package ' => $ package ,
144+ 'packageLinks ' => $ packageLinks ,
145+ 'paginator ' => $ paginator ,
146+ 'title ' => $ title ,
147+ ]);
148+ }
149+
61150 #[Route('/packages/{packageName}/statistics ' , name: 'dashboard_packages_statistics ' , requirements: ['packageName ' => '[a-z0-9_.-]+/[a-z0-9_.-]+ ' ])]
62151 #[IsGrantedAccess]
63152 public function statistics (string $ packageName ): Response
0 commit comments