4
4
5
5
namespace DragonCode \LaravelHttpMacros \Commands ;
6
6
7
+ use Closure ;
7
8
use DragonCode \LaravelHttpMacros \Macros \Macro ;
8
9
use DragonCode \Support \Facades \Filesystem \Directory ;
9
10
use DragonCode \Support \Facades \Filesystem \File ;
10
11
use Illuminate \Console \Command ;
12
+ use Illuminate \Support \Collection ;
11
13
use Illuminate \Support \Str ;
14
+ use ReflectionFunction ;
15
+ use ReflectionNamedType ;
16
+ use ReflectionParameter ;
17
+ use ReflectionUnionType ;
12
18
13
- use function array_map ;
14
19
use function base_path ;
20
+ use function class_exists ;
15
21
use function collect ;
16
22
use function config ;
17
23
use function file_get_contents ;
18
- use function implode ;
19
- use function is_string ;
24
+ use function is_numeric ;
25
+ use function Laravel \Prompts \intro ;
26
+ use function Laravel \Prompts \outro ;
20
27
use function sprintf ;
21
-
22
- use const PHP_EOL ;
28
+ use function var_export ;
23
29
24
30
class GenerateHelperCommand extends Command
25
31
{
@@ -29,71 +35,124 @@ class GenerateHelperCommand extends Command
29
35
30
36
public function handle (): void
31
37
{
32
- $ names = $ this ->names ();
38
+ $ this ->sections ()->map (function (array $ macros , string $ section ) {
39
+ intro ($ section );
40
+
41
+ return $ this ->macros ($ macros );
42
+ })
43
+ ->tap (fn () => outro ('storing ' ))
44
+ ->tap (fn () => $ this ->cleanUp ())
45
+ ->each (fn (Collection $ blocks , string $ section ) => $ this ->store (
46
+ $ section ,
47
+ $ this ->compileBlocks ($ section , $ blocks ->flatten ())
48
+ ));
49
+ }
50
+
51
+ protected function cleanUp (): void
52
+ {
53
+ $ this ->components ->task ('clean up ' , fn () => Directory::ensureDelete ($ this ->directory ()));
54
+ }
55
+
56
+ protected function macros (array $ macros ): Collection
57
+ {
58
+ return collect ($ macros )->map (function (Macro |string $ macro , int |string $ name ) {
59
+ $ name = $ this ->resolveName ($ macro , $ name );
33
60
34
- $ static = $ this ->make ($ names , true );
35
- $ dynamic = $ this ->make ($ names );
61
+ $ this ->components ->task ($ name , function () use ($ macro , $ name , &$ result ) {
62
+ $ result = $ this ->prepare ($ name , $ this ->reflectionCallback ($ macro ::callback ())->getParameters ());
63
+ });
36
64
37
- $ this ->cleanUp ();
38
- $ this ->store ($ static , true );
39
- $ this ->store ($ dynamic );
65
+ return $ result ;
66
+ });
40
67
}
41
68
42
- protected function make ( array $ names , bool $ isStatic = false ): array
69
+ protected function store ( string $ section , string $ content ): void
43
70
{
44
- return array_map (
45
- fn (string $ name ) => sprintf (
46
- ' * @method %s $this %s(\Closure|string $class, int|string|null $key = null) ' ,
47
- $ isStatic ? 'static ' : '' ,
48
- $ name
49
- ),
50
- $ names
51
- );
71
+ $ this ->components ->task ($ section , fn () => File::store ($ this ->helperPath ($ section ), $ content ));
52
72
}
53
73
54
- protected function store ( array $ methods , bool $ isStatic = false ): void
74
+ protected function compileBlocks ( string $ section , Collection $ blocks ): string
55
75
{
56
- File::store (
57
- $ this ->path ($ this ->filename ($ isStatic )),
58
- $ this ->makeDocBlock ($ methods )
76
+ return Str::replace (
77
+ ['{class} ' , '{methods} ' ],
78
+ [
79
+ Str::studly ($ section ),
80
+ $ blocks ->implode ("\n" ),
81
+ ],
82
+ $ this ->stub ()
59
83
);
60
84
}
61
85
62
- protected function makeDocBlock ( array $ methods ): string
86
+ protected function prepare ( string $ name , array $ functions ): array
63
87
{
64
- return Str:: replace ( ' {methods} ' , implode ( PHP_EOL , $ methods ) , $ this ->template ( ));
88
+ return $ this -> docBlock ( $ name , $ this ->docBlockParameters ( $ functions ));
65
89
}
66
90
67
- protected function names ( ): array
91
+ protected function docBlock ( string $ name , string $ parameters ): array
68
92
{
69
- return collect ($ this ->macros ())->map (
70
- fn (Macro |string $ macro , int |string $ name ) => is_string ($ name ) ? $ name : $ macro ::name ()
71
- )->all ();
93
+ return [
94
+ sprintf (' * @method $this %s(%s) ' , $ name , $ parameters ),
95
+ sprintf (' * @method static $this %s(%s) ' , $ name , $ parameters ),
96
+ ];
72
97
}
73
98
74
- protected function path (?string $ filename = null ): string
99
+ /**
100
+ * @param array<ReflectionParameter> $functions
101
+ *
102
+ * @return Collection
103
+ */
104
+ protected function docBlockParameters (array $ functions ): string
75
105
{
76
- return base_path ('vendor/_http_macros/ ' . $ filename );
106
+ return collect ($ functions )->map (function (ReflectionParameter $ parameter ) {
107
+ $ result = $ parameter ->hasType () ? $ this ->compactTypes ($ parameter ->getType ()) : 'mixed ' ;
108
+
109
+ $ result .= ' $ ' . $ parameter ->getName ();
110
+
111
+ if ($ parameter ->isDefaultValueAvailable ()) {
112
+ $ result .= ' = ' . var_export ($ parameter ->getDefaultValue (), true );
113
+ }
114
+
115
+ return $ result ;
116
+ })->implode (', ' );
77
117
}
78
118
79
- protected function filename ( bool $ isStatic ): string
119
+ protected function compactTypes ( ReflectionNamedType | ReflectionUnionType $ type ): string
80
120
{
81
- return $ isStatic
82
- ? '_ide_helper_macro_static.php '
83
- : '_ide_helper_macro.php ' ;
121
+ if ($ type instanceof ReflectionNamedType) {
122
+ return class_exists ($ type ->getName ()) ? '\\' . $ type ->getName () : $ type ->getName ();
123
+ }
124
+
125
+ return collect ($ type ->getTypes ())->map (
126
+ fn (ReflectionNamedType $ type ) => $ this ->compactTypes ($ type )
127
+ )->implode ('| ' );
84
128
}
85
129
86
- protected function cleanUp (): void
130
+ protected function reflectionCallback (Closure $ callback ): ReflectionFunction
131
+ {
132
+ return new ReflectionFunction ($ callback );
133
+ }
134
+
135
+ protected function resolveName (Macro |string $ macro , int |string $ name ): string
136
+ {
137
+ return is_numeric ($ name ) ? $ macro ::name () : $ name ;
138
+ }
139
+
140
+ protected function sections (): Collection
141
+ {
142
+ return collect (config ('http.macros ' , []));
143
+ }
144
+
145
+ protected function helperPath (string $ name ): string
87
146
{
88
- Directory:: ensureDelete ( $ this ->path ()) ;
147
+ return $ this ->directory () . " /_ide_helper_macro_ $ name .php " ;
89
148
}
90
149
91
- protected function macros (): array
150
+ protected function directory (): string
92
151
{
93
- return config ( ' http.macros.response ' , [] );
152
+ return base_path ( ' vendor/_http_macros ' );
94
153
}
95
154
96
- protected function template (): string
155
+ protected function stub (): string
97
156
{
98
157
return file_get_contents (__DIR__ . '/../../stubs/helper.stub ' );
99
158
}
0 commit comments