1+ <?php
2+
3+ namespace Ensi \LaravelOpenApiServerGenerator \Generators ;
4+
5+ use cebe \openapi \SpecObjectInterface ;
6+ use RuntimeException ;
7+
8+ class PoliciesGenerator extends BaseGenerator implements GeneratorInterface
9+ {
10+ public function generate (SpecObjectInterface $ specObject ): void
11+ {
12+ $ policies = $ this ->extractPolicies ($ specObject );
13+ $ this ->createPoliciesFiles ($ policies , $ this ->templatesManager ->getTemplate ('Policy.template ' ));
14+ }
15+
16+ // TODO: предварительная версия, необходим рефакторинг и доп. проверки
17+ protected function extractPolicies (SpecObjectInterface $ specObject ): array
18+ {
19+ $ openApiData = $ specObject ->getSerializableData ();
20+
21+ $ policies = [];
22+ $ paths = $ openApiData ->paths ?: [];
23+ foreach ($ paths as $ routes ) {
24+ foreach ($ routes as $ route ) {
25+ if (!empty ($ route ->{'x-lg-skip-policy-generation ' })) {
26+ continue ;
27+ }
28+
29+ if (empty ($ route ->{'x-lg-handler ' })) {
30+ continue ;
31+ }
32+
33+ $ response = $ route ->responses ->{403 } ?? null ;
34+ if (!$ response ) {
35+ continue ;
36+ }
37+
38+ $ handler = $ this ->routeHandlerParser ->parse ($ route ->{'x-lg-handler ' });
39+
40+ try {
41+ $ namespace = $ this ->getReplacedNamespace ($ handler ->namespace , 'Controllers ' , 'Policies ' );
42+ $ className = $ handler ->class . 'Policy ' ;
43+ } catch (RuntimeException ) {
44+ continue ;
45+ }
46+
47+ if (empty ($ handler ->method )) {
48+ continue ;
49+ }
50+
51+ if (isset ($ policies ["$ namespace \\$ className " ])) {
52+ $ policies ["$ namespace \\$ className " ]['methods ' ][] = $ handler ->method ;
53+ } else {
54+ $ methods = [$ handler ->method ];
55+ $ policies ["$ namespace \\$ className " ] = compact ('className ' , 'namespace ' , 'methods ' );
56+ }
57+ }
58+ }
59+
60+ return $ policies ;
61+ }
62+
63+ // TODO: протестировать
64+ protected function createPoliciesFiles (array $ policies , string $ template ): void
65+ {
66+ foreach ($ policies as ['className ' => $ className , 'namespace ' => $ namespace , 'methods ' => $ methods ]) {
67+ $ filePath = $ this ->getNamespacedFilePath ($ className , $ namespace );
68+ if ($ this ->filesystem ->exists ($ filePath )) {
69+ continue ;
70+ }
71+
72+ $ this ->filesystem ->put (
73+ $ filePath ,
74+ $ this ->replacePlaceholders ($ template , [
75+ '{{ namespace }} ' => $ namespace ,
76+ '{{ className }} ' => $ className ,
77+ '{{ methods }} ' => $ this ->convertToString ($ methods ),
78+ ])
79+ );
80+
81+ die ();
82+ }
83+ }
84+
85+ private function convertToString (array $ methods ): string
86+ {
87+ $ methodsStrings = [];
88+
89+ foreach ($ methods as $ method ) {
90+ $ methodsStrings [] = $ this ->replacePlaceholders (
91+ $ this ->templatesManager ->getTemplate ('PolicyGate.template ' ),
92+ [
93+ '{{ method }} ' => $ method ,
94+ ]
95+ );
96+ }
97+
98+ return implode ("\n\n " , $ methodsStrings );
99+ }
100+ }
0 commit comments