1
+ <?php /** @noinspection PhpIllegalPsrClassPathInspection */
2
+
3
+ namespace App \Console \Commands \LaravelProjectAssist ;
4
+
5
+ use Illuminate \Console \Command ;
6
+ use Illuminate \Support \Facades \File ;
7
+ use Illuminate \Support \Str ;
8
+
9
+ class MakeClassLikeEnum extends Command
10
+ {
11
+ /**
12
+ * The name and signature of the console command.
13
+ *
14
+ * @var string
15
+ */
16
+ protected $ signature = 'make:class-like-enum {name} ' ;
17
+
18
+ /**
19
+ * The console command description.
20
+ *
21
+ * @var string
22
+ */
23
+ protected $ description = 'Generates a data class file like enum but with int values to each field ' ;
24
+
25
+ /**
26
+ * Execute the console command.
27
+ *
28
+ * @return void
29
+ */
30
+ public function handle (): void
31
+ {
32
+ $ name = $ this ->argument ('name ' );
33
+ $ className = Str::studly (class_basename ($ name ));
34
+ $ subdirectory = rtrim (dirname ($ name ), '/ \\' );
35
+
36
+ $ onlyValues = $ this ->ask ('Do you want the fields to have a label or you want them only by values? (y/n) ' , 'n ' ) == "n " ;
37
+ $ prefix = $ this ->ask ('Do you want to add a prefix to the fields? (e.g., "TYPE1 TYPE2" becomes "PREFIX_TYPE1 PREFIX_TYPE2") leave it blank if you dont ' , '' );
38
+ if ($ onlyValues ) {
39
+ $ fields = $ this ->collectFields ($ prefix );
40
+ } else {
41
+ $ fields = $ this ->collectFieldsWithLabels ($ prefix );
42
+ }
43
+
44
+ $ defaultStartingNumber = 1 ;
45
+ do {
46
+ $ defaultStartingNumber *= 10 ;
47
+ } while (count ($ fields ) >= $ defaultStartingNumber );
48
+
49
+
50
+
51
+
52
+ $ startingNumber = $ this ->ask ('What number do you want to start the values from? ' , $ defaultStartingNumber );
53
+
54
+ while (!$ this ->checkStartingNumber ($ startingNumber , $ fields )) {
55
+ $ this ->error ("The number you entered is too small, please enter a number greater like " . $ defaultStartingNumber . " or more (add a zero) " );
56
+ $ startingNumber = $ this ->ask ('What number do you want to start the values from? ' , $ defaultStartingNumber );
57
+ }
58
+
59
+ $ replaceFields = "" ;
60
+ foreach ($ fields as $ key => $ field ) {
61
+ $ f = $ onlyValues ? $ field : $ key ;
62
+ $ replaceFields .= "\n const " . $ f . " = " . ($ startingNumber ) . "; " ;
63
+ $ startingNumber ++;
64
+ }
65
+
66
+
67
+ $ replaceInAllMethod = "" ;
68
+ if ($ onlyValues ) {
69
+ for ($ i = 0 ; $ i < count ($ fields ); $ i ++) {
70
+ $ replaceInAllMethod .= "\n self:: " . $ fields [$ i ] . ", " ;
71
+ }
72
+ } else {
73
+ foreach ($ fields as $ key => $ value ) {
74
+ $ value = str_replace ("' " , "\\' " , $ value );
75
+ $ replaceInAllMethod .= "\n self:: " . $ key . " => ' " . $ value . "', " ;
76
+ }
77
+ }
78
+
79
+ $ replacements = [
80
+ '{{class}} ' => $ className ,
81
+ '\{{subdirectory}} ' => ($ subdirectory != ". " ? "\\" .$ subdirectory : "" ),
82
+ '{{fields}} ' => $ replaceFields ,
83
+ '{{values}} ' => $ replaceInAllMethod ,
84
+ ];
85
+
86
+ $ extended = (!$ onlyValues ) ? "classLikeEnumKeyAndValue " : "classLikeEnumValueOnly " ;
87
+
88
+ $ template = File::get (app_path ('Console/Commands/LaravelProjectAssist/stubs/ ' .$ extended .'.stub ' ));
89
+ $ generatedClass = str_replace (array_keys ($ replacements ), array_values ($ replacements ), $ template );
90
+
91
+ $ classPath = app_path ('Enums/ ' .$ subdirectory .'/ ' .$ className . '.php ' );
92
+ File::ensureDirectoryExists (dirname ($ classPath ));
93
+ File::put ($ classPath , $ generatedClass );
94
+
95
+ $ this ->info ("Class generated successfully! " );
96
+ }
97
+
98
+ function checkStartingNumber ($ startingNumber , $ fields ): bool
99
+ {
100
+ if ($ startingNumber <= count ($ fields )) {
101
+ return false ;
102
+ }
103
+ $ str = strval ($ startingNumber );
104
+ $ n = intval ((intval ($ str [0 ])+1 ).str_repeat ("0 " , strlen ($ str ) - 1 ));
105
+ return ($ n - $ startingNumber ) > count ($ fields );
106
+ }
107
+
108
+ protected function collectFields ($ prefix ): array
109
+ {
110
+ $ fields = $ this ->ask ("Add fields separated by white space (e.g., TYPE1 TYPE2...)? " );
111
+ $ fields = trim ($ fields );
112
+ $ fields = explode (" " , $ fields );
113
+ $ fields = array_map (function ($ field ) use ($ prefix ) {
114
+ $ field = trim ($ field );
115
+ if ($ prefix != "" ) {
116
+ $ field = $ prefix . "_ " . $ field ;
117
+ }
118
+ $ field = strtoupper ($ field );
119
+ return preg_replace ("/[^a-zA-Z0-9_ \x7f- \xff]/ " , "" , $ field );
120
+ }, $ fields );
121
+ $ fields = array_filter ($ fields , function ($ field ) {
122
+ return $ field != "" ;
123
+ });
124
+ return array_values (array_unique ($ fields ));
125
+ }
126
+
127
+ protected function collectFieldsWithLabels ($ prefix ): array
128
+ {
129
+ $ fields = [];
130
+ do {
131
+ $ field = $ this ->ask ("Add field with label separated by ,,(e.g., first type,,TYPE1)? " );
132
+ $ field = trim ($ field );
133
+ $ fields [] = $ field ;
134
+ if (Str::startsWith ($ field , "/ " )) {
135
+ $ fields = $ field ;
136
+ break ;
137
+ }
138
+ } while ($ field != "" );
139
+ if (is_array ($ fields )) {
140
+ array_pop ($ fields );
141
+ }
142
+ else {
143
+ $ fields = substr ($ fields , 1 );
144
+ $ fields = explode ("// " , $ fields );
145
+ $ fields = array_map ('trim ' , $ fields );
146
+ }
147
+ $ fields_ = array_filter ($ fields , function ($ field ) {
148
+ return $ field != "" AND Str::contains ($ field , ",, " );
149
+ });
150
+ $ fields_2 = [];
151
+ for ($ i = 0 ; $ i < count ($ fields_ ); $ i ++) {
152
+ $ parts = explode (",, " , $ fields_ [$ i ]);
153
+ $ fields_2 [$ parts [1 ]] = $ parts [0 ];
154
+ }
155
+
156
+ $ keys = array_keys ($ fields_2 );
157
+ $ keys = array_values (array_unique ($ keys ));
158
+ $ fields = [];
159
+ for ($ i = 0 ; $ i < count ($ keys ); $ i ++) {
160
+ $ fields [$ keys [$ i ]] = $ fields_2 [$ keys [$ i ]];
161
+ }
162
+
163
+ return array_combine (
164
+ array_map (function ($ key ) use ($ prefix ) {
165
+ $ key = trim ($ key );
166
+ if ($ prefix != "" ) {
167
+ $ key = $ prefix . "_ " . $ key ;
168
+ }
169
+ $ key = strtoupper ($ key );
170
+ return preg_replace ("/[^a-zA-Z0-9_ \x7f- \xff]/ " , "" , $ key );
171
+ }, array_keys ($ fields )),
172
+ array_map ('trim ' , array_values ($ fields ))
173
+ );
174
+ }
175
+ }
0 commit comments