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