11<?php
22
3+ declare (strict_types=1 );
4+
35namespace App \Presenter \Analyze \Class \Bubble ;
46
57use Exception ;
68use Throwable ;
79use App \Application \Analyze \AnalyzeResponse ;
810use App \Application \Analyze \AnalyzePresenter ;
11+ use App \Application \Analyze \AnalyzeMetric ;
912
1013class BubblePresenter implements AnalyzePresenter
1114{
1215 public function present (AnalyzeResponse $ response ): void
1316 {
1417 $ metrics = $ response ->metrics ;
1518
16- dd ($ metrics );
19+ $ foldersData = $ this ->transformMetricsToFoldersData ($ metrics );
20+
21+ echo json_encode ($ foldersData , JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES );
22+ }
23+
24+ /**
25+ * @param array<AnalyzeMetric> $metrics
26+ * @return array<string, array{classes: int, interfaces: int, abstracts: int, total: int, relations: array<string>, metrics: array{efferent_coupling: float, afferent_coupling: float, instability: float, loc_total: int, ccn_total: int}}>
27+ */
28+ private function transformMetricsToFoldersData (array $ metrics ): array
29+ {
30+ $ foldersData = [];
31+
32+ foreach ($ metrics as $ metric ) {
33+ $ folderPath = $ this ->fqcnToFolderPath ($ metric ->name ());
34+ $ dependencies = $ metric ->dependencies ();
35+
36+ if (!isset ($ foldersData [$ folderPath ])) {
37+ $ foldersData [$ folderPath ] = [
38+ 'classes ' => 0 ,
39+ 'interfaces ' => 0 ,
40+ 'abstracts ' => 0 ,
41+ 'total ' => 0 ,
42+ 'relations ' => [],
43+ 'metrics ' => [
44+ 'efferent_coupling ' => 0.0 ,
45+ 'afferent_coupling ' => 0.0 ,
46+ 'instability ' => 0.0 ,
47+ 'loc_total ' => 0 ,
48+ 'ccn_total ' => 0 ,
49+ ],
50+ ];
51+ }
52+
53+ // Compter le type de classe
54+ if ($ metric ->isInterface ()) {
55+ $ foldersData [$ folderPath ]['interfaces ' ]++;
56+ } elseif ($ metric ->abstract ()) {
57+ $ foldersData [$ folderPath ]['abstracts ' ]++;
58+ } else {
59+ $ foldersData [$ folderPath ]['classes ' ]++;
60+ }
61+
62+ $ foldersData [$ folderPath ]['total ' ]++;
63+
64+ // Ajouter les métriques de couplage
65+ $ foldersData [$ folderPath ]['metrics ' ]['efferent_coupling ' ] += $ metric ->efferentCoupling ();
66+ $ foldersData [$ folderPath ]['metrics ' ]['afferent_coupling ' ] += $ metric ->afferentCoupling ();
67+ $ foldersData [$ folderPath ]['metrics ' ]['instability ' ] += $ metric ->instability ();
68+
69+ // Convertir les dépendances en chemins de dossiers et les ajouter aux relations
70+ foreach ($ dependencies as $ dependency ) {
71+ $ dependencyFolderPath = $ this ->fqcnToFolderPath ($ dependency );
72+
73+ // Ne pas ajouter de relation vers le même dossier
74+ if ($ dependencyFolderPath !== $ folderPath && !in_array ($ dependencyFolderPath , $ foldersData [$ folderPath ]['relations ' ], true )) {
75+ $ foldersData [$ folderPath ]['relations ' ][] = $ dependencyFolderPath ;
76+ }
77+ }
78+ }
79+
80+ // Calculer les moyennes d'instabilité par dossier
81+ foreach ($ foldersData as $ folderPath => &$ data ) {
82+ $ count = $ data ['total ' ];
83+ if ($ count > 0 ) {
84+ $ data ['metrics ' ]['instability ' ] = number_format ($ data ['metrics ' ]['instability ' ] / $ count , 2 );
85+ }
86+ }
87+
88+ return $ foldersData ;
89+ }
90+
91+ private function fqcnToFolderPath (string $ fqcn ): string
92+ {
93+ // Séparer le namespace et le nom de classe
94+ $ parts = explode ('\\' , $ fqcn );
95+
96+ // Retirer le nom de classe (dernier élément)
97+ array_pop ($ parts );
98+
99+ if (empty ($ parts )) {
100+ return '' ;
101+ }
102+
103+ // Convertir en chemin de dossier
104+ $ path = implode ('/ ' , $ parts );
105+
106+ // Mettre en minuscule la première partie (ex: App -> app)
107+ $ firstSlash = strpos ($ path , '/ ' );
108+ if ($ firstSlash !== false ) {
109+ $ firstPart = substr ($ path , 0 , $ firstSlash );
110+ $ rest = substr ($ path , $ firstSlash );
111+ return strtolower ($ firstPart ) . $ rest ;
112+ }
17113
18- //
114+ return strtolower ( $ path );
19115 }
20116
21117 public function hello (): void
22118 {
23- throw new Exception ('Not implemented ' );
24119 }
25120
26121 public function error (Throwable $ e ): void
27122 {
28- throw new \Exception ('Not implemented ' );
29123 }
30124}
0 commit comments