33namespace CodedMonkey \Dirigent \Controller \Dashboard ;
44
55use CodedMonkey \Dirigent \Attribute \IsGrantedAccess ;
6+ use CodedMonkey \Dirigent \Doctrine \Entity \Dependent ;
67use CodedMonkey \Dirigent \Doctrine \Entity \Package ;
8+ use CodedMonkey \Dirigent \Doctrine \Entity \PackageProvideLink ;
9+ use CodedMonkey \Dirigent \Doctrine \Entity \PackageRequireLink ;
10+ use CodedMonkey \Dirigent \Doctrine \Entity \PackageSuggestLink ;
11+ use CodedMonkey \Dirigent \Doctrine \Entity \Provider ;
12+ use CodedMonkey \Dirigent \Doctrine \Entity \Suggester ;
713use CodedMonkey \Dirigent \Doctrine \Repository \PackageRepository ;
14+ use CodedMonkey \Dirigent \EasyAdmin \PackagePaginator ;
815use Composer \Semver \VersionParser ;
16+ use Doctrine \ORM \EntityManagerInterface ;
17+ use Doctrine \ORM \QueryBuilder ;
918use Symfony \Bundle \FrameworkBundle \Controller \AbstractController ;
19+ use Symfony \Component \HttpFoundation \Request ;
1020use Symfony \Component \HttpFoundation \Response ;
1121use Symfony \Component \Routing \Attribute \Route ;
1222
1323class DashboardPackagesInfoController extends AbstractController
1424{
1525 public function __construct (
26+ private readonly EntityManagerInterface $ entityManager ,
1627 private readonly PackageRepository $ packageRepository ,
1728 ) {
1829 }
@@ -37,9 +48,19 @@ public function versionInfo(string $packageName, string $packageVersion): Respon
3748 $ package = $ this ->packageRepository ->findOneBy (['name ' => $ packageName ]);
3849 $ version = $ package ->getVersion ((new VersionParser ())->normalize ($ packageVersion ));
3950
51+ $ dependentCount = $ this ->entityManager ->getRepository (PackageRequireLink::class)->count (['dependentPackageName ' => $ package ->getName ()]);
52+ $ implementationCount = $ this ->entityManager ->getRepository (PackageProvideLink::class)->count (['providedPackageName ' => $ package ->getName (), 'implementation ' => true ]);
53+ $ providerCount = $ this ->entityManager ->getRepository (PackageProvideLink::class)->count (['providedPackageName ' => $ package ->getName (), 'implementation ' => false ]);
54+ $ suggesterCount = $ this ->entityManager ->getRepository (PackageSuggestLink::class)->count (['suggestedPackageName ' => $ package ->getName ()]);
55+
4056 return $ this ->render ('dashboard/packages/package_info.html.twig ' , [
4157 'package ' => $ package ,
4258 'version ' => $ version ,
59+
60+ 'dependentCount ' => $ dependentCount ,
61+ 'implementationCount ' => $ implementationCount ,
62+ 'providerCount ' => $ providerCount ,
63+ 'suggesterCount ' => $ suggesterCount ,
4364 ]);
4465 }
4566
@@ -58,6 +79,60 @@ public function versions(string $packageName): Response
5879 ]);
5980 }
6081
82+ #[Route('/packages/{packageName}/dependents ' , name: 'dashboard_packages_dependents ' , requirements: ['packageName ' => '[a-z0-9_.-]+/[a-z0-9_.-]+ ' ])]
83+ #[IsGrantedAccess]
84+ public function dependents (Request $ request , string $ packageName ): Response
85+ {
86+ $ package = $ this ->packageRepository ->findOneBy (['name ' => $ packageName ]);
87+
88+ return $ this ->packageLinks ($ request , $ package , PackageProvideLink::class, 'Dependents ' );
89+ }
90+
91+ #[Route('/packages/{packageName}/implementations ' , name: 'dashboard_packages_implementations ' , requirements: ['packageName ' => '[a-z0-9_.-]+/[a-z0-9_.-]+ ' ])]
92+ #[IsGrantedAccess]
93+ public function implementations (Request $ request , string $ packageName ): Response
94+ {
95+ $ package = $ this ->packageRepository ->findOneBy (['name ' => $ packageName ]);
96+
97+ $ providerRepository = $ this ->entityManager ->getRepository (Provider::class);
98+ $ queryBuilder = $ providerRepository ->createQueryBuilder ('provider ' );
99+ $ queryBuilder
100+ ->leftJoin ('provider.package ' , 'package ' )
101+ ->andWhere ('provider.providedPackageName = :packageName ' )
102+ ->andWhere ('provider.implementation = true ' )
103+ ->setParameter ('packageName ' , $ package ->getName ())
104+ ->addOrderBy ('package.name ' , 'ASC ' );
105+
106+ return $ this ->packageLinks ($ request , $ package , PackageProvideLink::class, 'Implementations ' , queryBuilder: $ queryBuilder );
107+ }
108+
109+ #[Route('/packages/{packageName}/providers ' , name: 'dashboard_packages_providers ' , requirements: ['packageName ' => '[a-z0-9_.-]+/[a-z0-9_.-]+ ' ])]
110+ #[IsGrantedAccess]
111+ public function providers (Request $ request , string $ packageName ): Response
112+ {
113+ $ package = $ this ->packageRepository ->findOneBy (['name ' => $ packageName ]);
114+
115+ $ providerRepository = $ this ->entityManager ->getRepository (Provider::class);
116+ $ queryBuilder = $ providerRepository ->createQueryBuilder ('provider ' );
117+ $ queryBuilder
118+ ->leftJoin ('provider.package ' , 'package ' )
119+ ->andWhere ('provider.providedPackageName = :packageName ' )
120+ ->andWhere ('provider.implementation = false ' )
121+ ->setParameter ('packageName ' , $ package ->getName ())
122+ ->addOrderBy ('package.name ' , 'ASC ' );
123+
124+ return $ this ->packageLinks ($ request , $ package , PackageProvideLink::class, 'Providers ' , queryBuilder: $ queryBuilder );
125+ }
126+
127+ #[Route('/packages/{packageName}/suggesters ' , name: 'dashboard_packages_suggesters ' , requirements: ['packageName ' => '[a-z0-9_.-]+/[a-z0-9_.-]+ ' ])]
128+ #[IsGrantedAccess]
129+ public function suggesters (Request $ request , string $ packageName ): Response
130+ {
131+ $ package = $ this ->packageRepository ->findOneBy (['name ' => $ packageName ]);
132+
133+ return $ this ->packageLinks ($ request , $ package , PackageSuggestLink::class, 'Suggesters ' );
134+ }
135+
61136 #[Route('/packages/{packageName}/statistics ' , name: 'dashboard_packages_statistics ' , requirements: ['packageName ' => '[a-z0-9_.-]+/[a-z0-9_.-]+ ' ])]
62137 #[IsGrantedAccess]
63138 public function statistics (string $ packageName ): Response
@@ -99,4 +174,27 @@ public function statistics(string $packageName): Response
99174 'installationsToday ' => $ installationsToday ,
100175 ]);
101176 }
177+
178+ private function packageLinks (Request $ request , Package $ package , string $ linkClass , string $ title , ?QueryBuilder $ queryBuilder = null ): Response
179+ {
180+ if (!$ queryBuilder ) {
181+ $ dependentRepository = $ this ->entityManager ->getRepository ($ linkClass );
182+ $ queryBuilder = $ dependentRepository ->createQueryBuilder ('link ' );
183+ $ queryBuilder
184+ ->leftJoin ('link.package ' , 'package ' )
185+ ->andWhere ('link.linkedPackageName = :packageName ' )
186+ ->setParameter ('packageName ' , $ package ->getName ())
187+ ->addOrderBy ('package.name ' , 'ASC ' );
188+ }
189+
190+ $ paginator = PackagePaginator::fromRequest ($ request , $ queryBuilder , $ this ->container ->get ('router ' ));
191+ $ packageLinks = $ paginator ->getResults ();
192+
193+ return $ this ->render ('dashboard/packages/package_links.html.twig ' , [
194+ 'package ' => $ package ,
195+ 'packageLinks ' => $ packageLinks ,
196+ 'paginator ' => $ paginator ,
197+ 'title ' => $ title ,
198+ ]);
199+ }
102200}
0 commit comments