1
|
|
|
<?php |
2
|
|
|
namespace Caffeinated\Modules\Console\Generators; |
3
|
|
|
|
4
|
|
|
use Caffeinated\Modules\Modules; |
5
|
|
|
use Illuminate\Console\Command; |
6
|
|
|
use Illuminate\Filesystem\Filesystem; |
7
|
|
|
use Illuminate\Support\Str; |
8
|
|
|
use Symfony\Component\Console\Helper\ProgressBar; |
9
|
|
|
use Symfony\Component\Console\Input\InputArgument; |
10
|
|
|
|
11
|
|
|
class MakeModuleCommand extends Command |
12
|
|
|
{ |
13
|
|
|
/** |
14
|
|
|
* The console command name. |
15
|
|
|
* |
16
|
|
|
* @var string |
17
|
|
|
*/ |
18
|
|
|
protected $name = 'make:module'; |
19
|
|
|
|
20
|
|
|
/** |
21
|
|
|
* The console command description. |
22
|
|
|
* |
23
|
|
|
* @var string |
24
|
|
|
*/ |
25
|
|
|
protected $description = 'Create a new Caffeinated module and bootstrap it'; |
26
|
|
|
|
27
|
|
|
/** |
28
|
|
|
* Module folders to be created. |
29
|
|
|
* |
30
|
|
|
* @var array |
31
|
|
|
*/ |
32
|
|
|
protected $moduleFolders = [ |
33
|
|
|
'Console/', |
34
|
|
|
'Database/', |
35
|
|
|
'Database/Migrations/', |
36
|
|
|
'Database/Seeds/', |
37
|
|
|
'Http/', |
38
|
|
|
'Http/Controllers/', |
39
|
|
|
'Http/Middleware/', |
40
|
|
|
'Http/Requests/', |
41
|
|
|
'Providers/', |
42
|
|
|
'Resources/', |
43
|
|
|
'Resources/Lang/', |
44
|
|
|
'Resources/Views/', |
45
|
|
|
]; |
46
|
|
|
|
47
|
|
|
/** |
48
|
|
|
* Module files to be created. |
49
|
|
|
* |
50
|
|
|
* @var array |
51
|
|
|
*/ |
52
|
|
|
protected $moduleFiles = [ |
53
|
|
|
'Database/Seeds/{{namespace}}DatabaseSeeder.php', |
54
|
|
|
'Http/routes.php', |
55
|
|
|
'Providers/{{namespace}}ServiceProvider.php', |
56
|
|
|
'Providers/RouteServiceProvider.php', |
57
|
|
|
'module.json' |
58
|
|
|
]; |
59
|
|
|
|
60
|
|
|
/** |
61
|
|
|
* Module stubs used to populate defined files. |
62
|
|
|
* |
63
|
|
|
* @var array |
64
|
|
|
*/ |
65
|
|
|
protected $moduleStubs = [ |
66
|
|
|
'seeder.stub', |
67
|
|
|
'routes.stub', |
68
|
|
|
'moduleserviceprovider.stub', |
69
|
|
|
'routeserviceprovider.stub', |
70
|
|
|
'manifest.stub' |
71
|
|
|
]; |
72
|
|
|
|
73
|
|
|
/** |
74
|
|
|
* The modules instance. |
75
|
|
|
* |
76
|
|
|
* @var Modules |
77
|
|
|
*/ |
78
|
|
|
protected $module; |
79
|
|
|
|
80
|
|
|
/** |
81
|
|
|
* The filesystem instance. |
82
|
|
|
* |
83
|
|
|
* @var Filesystem |
84
|
|
|
*/ |
85
|
|
|
protected $files; |
86
|
|
|
|
87
|
|
|
/** |
88
|
|
|
* Array to store the configuration details. |
89
|
|
|
* |
90
|
|
|
* @var array |
91
|
|
|
*/ |
92
|
|
|
protected $container; |
93
|
|
|
|
94
|
|
|
/** |
95
|
|
|
* Create a new command instance. |
96
|
|
|
* |
97
|
|
|
* @param Filesystem $files |
98
|
|
|
* @param Modules $module |
99
|
|
|
*/ |
100
|
|
|
public function __construct(Filesystem $files, Modules $module) |
101
|
|
|
{ |
102
|
|
|
parent::__construct(); |
103
|
|
|
|
104
|
|
|
$this->files = $files; |
105
|
|
|
$this->module = $module; |
106
|
|
|
} |
107
|
|
|
|
108
|
|
|
/** |
109
|
|
|
* Execute the console command. |
110
|
|
|
* |
111
|
|
|
* @return mixed |
112
|
|
|
*/ |
113
|
|
|
public function fire() |
114
|
|
|
{ |
115
|
|
|
$this->container['slug'] = strtolower($this->argument('slug')); |
116
|
|
|
$this->container['name'] = Str::studly($this->container['slug']); |
117
|
|
|
$this->container['namespace'] = Str::studly($this->container['slug']); |
118
|
|
|
|
119
|
|
|
$this->displayHeader('make_module_introduction'); |
120
|
|
|
|
121
|
|
|
$this->stepOne(); |
122
|
|
|
} |
123
|
|
|
|
124
|
|
|
/** |
125
|
|
|
* Step 1: Configure module manifest. |
126
|
|
|
* |
127
|
|
|
* @return mixed |
128
|
|
|
*/ |
129
|
|
|
private function stepOne() |
130
|
|
|
{ |
131
|
|
|
$this->displayHeader('make_module_step_1'); |
132
|
|
|
|
133
|
|
|
$this->container['name'] = $this->ask('Please enter the name of the module:', $this->container['name']); |
134
|
|
|
$this->container['slug'] = $this->ask('Please enter the slug for the module:', $this->container['slug']); |
135
|
|
|
$this->container['namespace'] = $this->ask('Please enter the namespace for the module:', $this->container['namespace']); |
136
|
|
|
$this->container['version'] = $this->ask('Please enter the module version:', '1.0'); |
137
|
|
|
$this->container['description'] = $this->ask('Please enter the description of the module:', 'This is the description for the '.$this->container['name'].' module.'); |
138
|
|
|
$this->container['author'] = $this->ask('Please enter the author of the module:', ' '); |
139
|
|
|
$this->container['license'] = $this->ask('Please enter the module license:', 'MIT'); |
140
|
|
|
|
141
|
|
|
$this->comment('You have provided the following manifest information:'); |
142
|
|
|
$this->comment('Name: '.$this->container['name']); |
143
|
|
|
$this->comment('Slug: '.$this->container['slug']); |
144
|
|
|
$this->comment('Namespace: '.$this->container['namespace']); |
145
|
|
|
$this->comment('Version: '.$this->container['version']); |
146
|
|
|
$this->comment('Description: '.$this->container['description']); |
147
|
|
|
$this->comment('Author: '.$this->container['author']); |
148
|
|
|
$this->comment('License: '.$this->container['license']); |
149
|
|
|
|
150
|
|
|
if ($this->confirm('Do you wish to continue?')) { |
151
|
|
|
$this->comment('Thanks! That\'s all we need.'); |
152
|
|
|
$this->comment('Now relax while your module is generated for you.'); |
153
|
|
|
|
154
|
|
|
$this->generate(); |
155
|
|
|
} else { |
156
|
|
|
return $this->stepOne(); |
157
|
|
|
} |
158
|
|
|
|
159
|
|
|
return true; |
160
|
|
|
} |
161
|
|
|
|
162
|
|
|
/** |
163
|
|
|
* Generate the module. |
164
|
|
|
*/ |
165
|
|
|
protected function generate() |
166
|
|
|
{ |
167
|
|
|
$steps = [ |
168
|
|
|
'Generating folders...' => 'generateFolders', |
169
|
|
|
'Generating .gitkeep...' => 'generateGitkeep', |
170
|
|
|
'Generating files...' => 'generateFiles', |
171
|
|
|
'Optimizing module cache...' => 'optimizeModules' |
172
|
|
|
]; |
173
|
|
|
|
174
|
|
|
$progress = new ProgressBar($this->output, count($steps)); |
175
|
|
|
$progress->start(); |
176
|
|
|
|
177
|
|
|
foreach ($steps as $message => $function) { |
178
|
|
|
$progress->setMessage($message); |
179
|
|
|
|
180
|
|
|
$this->$function(); |
181
|
|
|
|
182
|
|
|
$progress->advance(); |
183
|
|
|
} |
184
|
|
|
|
185
|
|
|
$progress->finish(); |
186
|
|
|
|
187
|
|
|
$this->info("\nModule generated successfully."); |
188
|
|
|
} |
189
|
|
|
|
190
|
|
|
/** |
191
|
|
|
* Generate defined module folders. |
192
|
|
|
* |
193
|
|
|
* @return void |
194
|
|
|
*/ |
195
|
|
|
protected function generateFolders() |
196
|
|
|
{ |
197
|
|
|
if (! $this->files->isDirectory($this->module->getPath())) { |
198
|
|
|
$this->files->makeDirectory($this->module->getPath()); |
199
|
|
|
} |
200
|
|
|
|
201
|
|
|
$this->files->makeDirectory($this->getModulePath($this->container['slug'], true)); |
202
|
|
|
|
203
|
|
|
foreach ($this->moduleFolders as $folder) { |
204
|
|
|
$this->files->makeDirectory($this->getModulePath($this->container['slug']).$folder); |
205
|
|
|
} |
206
|
|
|
} |
207
|
|
|
|
208
|
|
|
/** |
209
|
|
|
* Generate defined module files. |
210
|
|
|
* |
211
|
|
|
* @return void |
212
|
|
|
*/ |
213
|
|
|
protected function generateFiles() |
214
|
|
|
{ |
215
|
|
|
foreach ($this->moduleFiles as $key => $file) { |
216
|
|
|
$file = $this->formatContent($file); |
217
|
|
|
|
218
|
|
|
$this->files->put($this->getDestinationFile($file), $this->getStubContent($key)); |
219
|
|
|
} |
220
|
|
|
} |
221
|
|
|
|
222
|
|
|
/** |
223
|
|
|
* Generate .gitkeep files within generated folders. |
224
|
|
|
* |
225
|
|
|
* @return null |
226
|
|
|
*/ |
227
|
|
|
protected function generateGitkeep() |
228
|
|
|
{ |
229
|
|
|
$modulePath = $this->getModulePath($this->container['slug']); |
230
|
|
|
foreach ($this->moduleFolders as $folder) { |
231
|
|
|
$gitkeep = $modulePath.$folder.'/.gitkeep'; |
232
|
|
|
$this->files->put($gitkeep, ''); |
233
|
|
|
} |
234
|
|
|
} |
235
|
|
|
|
236
|
|
|
/** |
237
|
|
|
* Reset module cache of enabled and disabled modules. |
238
|
|
|
* |
239
|
|
|
* @return void |
240
|
|
|
*/ |
241
|
|
|
protected function optimizeModules() |
242
|
|
|
{ |
243
|
|
|
return $this->callSilent('module:optimize'); |
244
|
|
|
} |
245
|
|
|
|
246
|
|
|
/** |
247
|
|
|
* Get the path to the module. |
248
|
|
|
* |
249
|
|
|
* @param string $slug |
250
|
|
|
* @return string |
251
|
|
|
*/ |
252
|
|
|
protected function getModulePath($slug = null, $allowNotExists = false) |
253
|
|
|
{ |
254
|
|
|
if ($slug) { |
|
|
|
|
255
|
|
|
return $this->module->getModulePath($slug, $allowNotExists); |
|
|
|
|
256
|
|
|
} |
257
|
|
|
|
258
|
|
|
return $this->module->getPath(); |
259
|
|
|
} |
260
|
|
|
|
261
|
|
|
/** |
262
|
|
|
* Get destination file. |
263
|
|
|
* |
264
|
|
|
* @param string $file |
265
|
|
|
* @return string |
266
|
|
|
*/ |
267
|
|
|
protected function getDestinationFile($file) |
268
|
|
|
{ |
269
|
|
|
return $this->getModulePath($this->container['slug']).$this->formatContent($file); |
270
|
|
|
} |
271
|
|
|
|
272
|
|
|
/** |
273
|
|
|
* Get stub content by key. |
274
|
|
|
* |
275
|
|
|
* @param int $key |
276
|
|
|
* @return string |
277
|
|
|
*/ |
278
|
|
|
protected function getStubContent($key) |
279
|
|
|
{ |
280
|
|
|
return $this->formatContent($this->files->get(__DIR__.'/../../../resources/stubs/'.$this->moduleStubs[$key])); |
281
|
|
|
} |
282
|
|
|
|
283
|
|
|
/** |
284
|
|
|
* Replace placeholder text with correct values. |
285
|
|
|
* |
286
|
|
|
* @return string |
287
|
|
|
*/ |
288
|
|
|
protected function formatContent($content) |
289
|
|
|
{ |
290
|
|
|
return str_replace( |
291
|
|
|
['{{slug}}', '{{name}}', '{{namespace}}', '{{version}}', '{{description}}', '{{author}}', '{{path}}'], |
292
|
|
|
[$this->container['slug'], $this->container['name'], $this->container['namespace'], $this->container['version'], $this->container['description'], $this->container['author'], $this->module->getNamespace()], |
293
|
|
|
$content |
294
|
|
|
); |
295
|
|
|
} |
296
|
|
|
|
297
|
|
|
/** |
298
|
|
|
* Pull the given stub file contents and display them on screen. |
299
|
|
|
* |
300
|
|
|
* @param string $file |
301
|
|
|
* @param string $level |
302
|
|
|
* @return mixed |
303
|
|
|
*/ |
304
|
|
|
protected function displayHeader($file = '', $level = 'info') |
305
|
|
|
{ |
306
|
|
|
$stub = $this->files->get(__DIR__.'/../../../resources/stubs/console/'.$file.'.stub'); |
307
|
|
|
return $this->$level($stub); |
308
|
|
|
} |
309
|
|
|
|
310
|
|
|
/** |
311
|
|
|
* Get the console command arguments. |
312
|
|
|
* |
313
|
|
|
* @return array |
314
|
|
|
*/ |
315
|
|
|
protected function getArguments() |
316
|
|
|
{ |
317
|
|
|
return [ |
318
|
|
|
['slug', InputArgument::REQUIRED, 'The slug of the module'] |
319
|
|
|
]; |
320
|
|
|
} |
321
|
|
|
} |
322
|
|
|
|
In PHP, under loose comparison (like
==
, or!=
, orswitch
conditions), values of different types might be equal.For
string
values, the empty string''
is a special case, in particular the following results might be unexpected: