These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | namespace Acacha\AdminLTETemplateLaravel\Console; |
||
4 | |||
5 | use Acacha\AdminLTETemplateLaravel\Console\Routes\Controller; |
||
6 | use Acacha\AdminLTETemplateLaravel\Console\Routes\ControllerResourceRoute; |
||
7 | use Acacha\AdminLTETemplateLaravel\Console\Routes\ControllerRoute; |
||
8 | use Acacha\AdminLTETemplateLaravel\Console\Routes\GeneratesCode; |
||
9 | use Acacha\AdminLTETemplateLaravel\Console\Routes\RegularRoute; |
||
10 | use Acacha\AdminLTETemplateLaravel\Exceptions\RouteTypeNotValid; |
||
11 | use Acacha\AdminLTETemplateLaravel\Exceptions\SpatieMenuDoesNotExists; |
||
12 | use Acacha\Filesystem\Compiler\StubFileCompiler; |
||
13 | use Acacha\Filesystem\Filesystem; |
||
14 | use Illuminate\Console\Command; |
||
15 | use Illuminate\Routing\Router; |
||
16 | use Illuminate\Support\Facades\Artisan; |
||
17 | use Route; |
||
18 | use Symfony\Component\Routing\Exception\MethodNotAllowedException; |
||
19 | |||
20 | /** |
||
21 | * Class MakeRoute. |
||
22 | */ |
||
23 | class MakeRoute extends Command |
||
24 | { |
||
25 | use Controller, CreatesModels; |
||
26 | |||
27 | /** |
||
28 | * Path to web routes file. |
||
29 | * |
||
30 | * @var string |
||
31 | */ |
||
32 | protected $web_routes_path = 'routes/web.php'; |
||
33 | |||
34 | /** |
||
35 | * Path to api routes file. |
||
36 | * |
||
37 | * @var string |
||
38 | */ |
||
39 | protected $api_routes_path = 'routes/api.php'; |
||
40 | |||
41 | /** |
||
42 | * Compiler for stub file. |
||
43 | * |
||
44 | * @var StubFileCompiler |
||
45 | */ |
||
46 | protected $compiler; |
||
47 | |||
48 | /** |
||
49 | * Compiler for stub file. |
||
50 | * |
||
51 | * @var Filesystem |
||
52 | */ |
||
53 | protected $filesystem; |
||
54 | |||
55 | /** |
||
56 | * @var array |
||
57 | */ |
||
58 | protected static $lookup = [ |
||
59 | 'regular' => RegularRoute::class, |
||
60 | 'controller' => ControllerRoute::class, |
||
61 | 'resource' => ControllerResourceRoute::class, |
||
62 | ]; |
||
63 | |||
64 | /** |
||
65 | * The name and signature of the console command. |
||
66 | */ |
||
67 | protected $signature = 'make:route {link : The route link} {action? : View or controller to create} |
||
68 | {--t|type=regular : Type of route to create (regular,controller,resource)} {--m|method=get : HTTP method} |
||
69 | {--api : Route is an api route} {--a|createaction : Create view or controller after route} |
||
70 | {--menu : Create also menu entry using make:menu command} {--model : Create also a model using command make:model}'; |
||
71 | |||
72 | /** |
||
73 | * The console command description. |
||
74 | * |
||
75 | * @var string |
||
76 | */ |
||
77 | protected $description = 'Insert a route to routes/web.php file'; |
||
78 | |||
79 | /** |
||
80 | * AdminLTERoute constructor. |
||
81 | * |
||
82 | * @param StubFileCompiler $compiler |
||
83 | * @param Filesystem $filesystem |
||
84 | */ |
||
85 | public function __construct(StubFileCompiler $compiler, Filesystem $filesystem) |
||
86 | { |
||
87 | parent::__construct(); |
||
88 | $this->compiler = $compiler; |
||
89 | $this->filesystem = $filesystem; |
||
90 | } |
||
91 | |||
92 | /** |
||
93 | * Execute the console command. |
||
94 | */ |
||
95 | public function handle() |
||
96 | { |
||
97 | $this->processInput(); |
||
98 | $this->warnIfRouteAlreadyExists($link = $this->argument('link')); |
||
99 | $tmpfile = $this->createTmpFileWithRoute(); |
||
100 | $path = $this->getPath($tmpfile); |
||
101 | add_file_into_file($this->mountpoint(), $path, $dstFile = $this->destinationFile()); |
||
102 | $this->info('Route ' . undot_path($link) . ' added to ' . $dstFile . '.'); |
||
103 | $this->postActions(); |
||
104 | } |
||
105 | |||
106 | /** |
||
107 | * Get mountpoint. |
||
108 | * |
||
109 | * @return string |
||
110 | */ |
||
111 | protected function mountpoint() |
||
112 | { |
||
113 | if ($this->option('api')) { |
||
114 | return '#adminlte_api_routes'; |
||
115 | } |
||
116 | return '#adminlte_routes'; |
||
117 | } |
||
118 | |||
119 | /** |
||
120 | * Destination route file. |
||
121 | * |
||
122 | * @return string |
||
123 | */ |
||
124 | protected function destinationFile() |
||
125 | { |
||
126 | if ($this->option('api')) { |
||
127 | return base_path($this->api_routes_path); |
||
128 | } |
||
129 | return base_path($this->web_routes_path); |
||
130 | } |
||
131 | |||
132 | /** |
||
133 | * Warn if route already exists. |
||
134 | * |
||
135 | * @param $link |
||
136 | */ |
||
137 | protected function warnIfRouteAlreadyExists($link) |
||
138 | { |
||
139 | if ($this->routeExists($link)) { |
||
140 | if ($this->confirm('Route already exists. Do you wish to continue?')) { |
||
141 | return; |
||
142 | } |
||
143 | die(); |
||
0 ignored issues
–
show
|
|||
144 | } |
||
145 | } |
||
146 | |||
147 | /** |
||
148 | * Check if route exists. |
||
149 | * |
||
150 | * @param $link |
||
151 | * @return mixed |
||
152 | */ |
||
153 | protected function routeExists($link) |
||
154 | { |
||
155 | if ($this->option('api')) { |
||
156 | return $this->apiRouteExists($link); |
||
157 | } |
||
158 | return $this->webRouteExists($link); |
||
159 | } |
||
160 | |||
161 | /** |
||
162 | * Check if web route exists. |
||
163 | * |
||
164 | * @param $link |
||
165 | * @return mixed |
||
166 | */ |
||
167 | protected function webRouteExists($link) |
||
168 | { |
||
169 | $link = $this->removeTrailingSlashIfExists($link); |
||
170 | $link = $this->removeDuplicatedTrailingSlashes($link); |
||
171 | foreach (Route::getRoutes() as $value) { |
||
172 | if (in_array(strtoupper($this->option('method')), array_merge($value->methods(), ['ANY'])) && |
||
173 | $value->uri() === $link) { |
||
174 | return true; |
||
175 | } |
||
176 | } |
||
177 | return false; |
||
178 | } |
||
179 | |||
180 | /** |
||
181 | * Remove (if exists) trailing slash from link. |
||
182 | * |
||
183 | * @param $link |
||
184 | * @return string |
||
185 | */ |
||
186 | protected function removeTrailingSlashIfExists($link) |
||
187 | { |
||
188 | if (starts_with($link, '/')) { |
||
189 | return substr($link, 1); |
||
190 | } |
||
191 | return $link; |
||
192 | } |
||
193 | |||
194 | /** |
||
195 | * Remove duplicated trailing slashes. |
||
196 | * |
||
197 | * @param $link |
||
198 | * @return mixed |
||
199 | */ |
||
200 | protected function removeDuplicatedTrailingSlashes($link) |
||
201 | { |
||
202 | return preg_replace('/(\/+)/', '/', $link); |
||
203 | } |
||
204 | |||
205 | /** |
||
206 | * Check if api route exists. |
||
207 | * |
||
208 | * @param $link |
||
209 | * @return mixed |
||
210 | */ |
||
211 | protected function apiRouteExists($link) |
||
212 | { |
||
213 | return $this->webRouteExists('api/v1/' . $link); |
||
214 | } |
||
215 | |||
216 | /** |
||
217 | * Crete tmp file with route to add. |
||
218 | * |
||
219 | * @return mixed |
||
220 | */ |
||
221 | protected function createTmpFileWithRoute() |
||
222 | { |
||
223 | $temp = tmpfile(); |
||
224 | fwrite($temp, $this->getRouteCode()); |
||
225 | return $temp; |
||
226 | } |
||
227 | |||
228 | /** |
||
229 | * Get path from file resource. |
||
230 | * |
||
231 | * @param $tmpfile |
||
232 | * @return mixed |
||
233 | */ |
||
234 | protected function getPath($tmpfile) |
||
235 | { |
||
236 | return stream_get_meta_data($tmpfile)['uri']; |
||
237 | } |
||
238 | |||
239 | /** |
||
240 | * Get route code to insert depending on type. |
||
241 | * |
||
242 | * @return mixed |
||
243 | */ |
||
244 | View Code Duplication | protected function getRouteCode() |
|
245 | { |
||
246 | $type = $this->option('type'); |
||
247 | $class = isset(static::$lookup[$type]) |
||
248 | ? static::$lookup[$type] |
||
249 | : RegularRoute::class; |
||
250 | /** @var GeneratesCode $route */ |
||
251 | $route = new $class($this->compiler, $this->filesystem); |
||
252 | $route->setReplacements([ |
||
253 | undot_path($this->argument('link')), |
||
254 | $this->action(), |
||
255 | $this->method() |
||
256 | ]); |
||
257 | return $route->code(); |
||
258 | } |
||
259 | |||
260 | /** |
||
261 | * Get method. |
||
262 | * |
||
263 | * @return string |
||
264 | */ |
||
265 | View Code Duplication | protected function method() |
|
266 | { |
||
267 | if (strtolower($this->option('method')) == 'head') { |
||
268 | return 'get'; |
||
269 | } |
||
270 | return strtolower($this->option('method')); |
||
271 | } |
||
272 | |||
273 | /** |
||
274 | * Get the action replacement. |
||
275 | * |
||
276 | * @return array|string |
||
277 | */ |
||
278 | protected function action() |
||
279 | { |
||
280 | if ($this->argument('action') != null) { |
||
281 | return $this->argument('action'); |
||
282 | } |
||
283 | if (strtolower($this->option('type')) != 'regular') { |
||
284 | return $this->argument('link') . 'Controller'; |
||
285 | } |
||
286 | return $this->argument('link'); |
||
287 | } |
||
288 | |||
289 | /** |
||
290 | * Process input. |
||
291 | */ |
||
292 | protected function processInput() |
||
293 | { |
||
294 | $this->validateMethod(); |
||
295 | $this->validateType(); |
||
296 | } |
||
297 | |||
298 | /** |
||
299 | * Validate option method. |
||
300 | */ |
||
301 | protected function validateMethod() |
||
302 | { |
||
303 | if (! in_array(strtoupper($this->option('method')), $methods = array_merge(Router::$verbs, ['ANY']))) { |
||
304 | throw new MethodNotAllowedException($methods); |
||
305 | } |
||
306 | } |
||
307 | |||
308 | /** |
||
309 | * Validate option type. |
||
310 | */ |
||
311 | protected function validateType() |
||
312 | { |
||
313 | if (! in_array(strtolower($this->option('type')), ['regular','controller','resource'])) { |
||
314 | throw new RouteTypeNotValid(); |
||
315 | } |
||
316 | } |
||
317 | |||
318 | /** |
||
319 | * Execute post actions (if exists) |
||
320 | */ |
||
321 | protected function postActions() |
||
322 | { |
||
323 | if ($this->option('createaction') != null) { |
||
324 | $this->createAction(); |
||
325 | } |
||
326 | if ($this->option('menu') != null) { |
||
327 | $this->createMenu(); |
||
328 | } |
||
329 | if ($this->option('model') != null) { |
||
330 | $this->createModel($this->argument('link')); |
||
331 | } |
||
332 | } |
||
333 | |||
334 | /** |
||
335 | * Create menu. |
||
336 | */ |
||
337 | protected function createMenu() |
||
338 | { |
||
339 | try { |
||
340 | $this->warnIfSpatieMenuIsNotInstalled(); |
||
341 | } catch (\Exception $e) { |
||
342 | //Skip installation of menu |
||
343 | $this->error($e->getMessage()); |
||
344 | return; |
||
345 | } |
||
346 | Artisan::call('make:menu', [ |
||
347 | 'link' => $link = undot_path($this->argument('link')), |
||
348 | 'name' => ucfirst($link), |
||
349 | ]); |
||
350 | $this->info('Menu entry ' . $link .' added to config/menu.php file.'); |
||
351 | } |
||
352 | |||
353 | /** |
||
354 | * Warn if spatie menu ins not installed. |
||
355 | * |
||
356 | * @throws SpatieMenuDoesNotExists |
||
357 | */ |
||
358 | protected function warnIfSpatieMenuIsNotInstalled() |
||
359 | { |
||
360 | if (!(app()->getProvider('Spatie\Menu\Laravel\MenuServiceProvider'))) { |
||
361 | throw new SpatieMenuDoesNotExists(); |
||
362 | } |
||
363 | } |
||
364 | |||
365 | /** |
||
366 | * Create action (view|controller). |
||
367 | */ |
||
368 | protected function createAction() |
||
369 | { |
||
370 | if (strtolower($this->option('type')) == 'regular' || $this->option('type') == null) { |
||
371 | return $this->createView(); |
||
372 | } |
||
373 | if (strtolower($this->option('type')) == 'controller') { |
||
374 | return $this->createController(); |
||
375 | } |
||
376 | return $this->createResourceController(); |
||
377 | } |
||
378 | |||
379 | /** |
||
380 | * Create View. |
||
381 | * |
||
382 | * @param null $name |
||
383 | */ |
||
384 | protected function createView($name = null) |
||
385 | { |
||
386 | if ($name == null) { |
||
387 | $name = $this->action(); |
||
388 | } |
||
389 | Artisan::call('make:view', [ |
||
390 | 'name' => $name |
||
391 | ]); |
||
392 | $this->info('View ' . undot_path($name) .'.blade.php created.'); |
||
393 | } |
||
394 | |||
395 | /** |
||
396 | * Create regular controller. |
||
397 | */ |
||
398 | protected function createController() |
||
399 | { |
||
400 | Artisan::call('make:controller', [ |
||
401 | 'name' => $controller = $this->controllerWithoutMethod($this->action()) |
||
402 | ]); |
||
403 | $this->addMethodToController($controller, $this->controllerMethod($this->action())); |
||
404 | $this->info('Controller ' . $controller .' created.'); |
||
405 | $this->createView($this->argument('link')); |
||
406 | } |
||
407 | |||
408 | /** |
||
409 | * Create resource controller. |
||
410 | */ |
||
411 | protected function createResourceController() |
||
412 | { |
||
413 | Artisan::call('make:controller', [ |
||
414 | 'name' => $controller = $this->controllerWithoutMethod($this->action()), |
||
415 | '--resource' => true |
||
416 | ]); |
||
417 | $this->info('Resource Controller ' . $controller .' created.'); |
||
418 | $this->createView($this->argument('link')); |
||
419 | } |
||
420 | |||
421 | /** |
||
422 | * Add method to controller. |
||
423 | * |
||
424 | * @param $controller |
||
425 | * @param $controllerMethod * |
||
426 | */ |
||
427 | protected function addMethodToController($controller, $controllerMethod) |
||
428 | { |
||
429 | $tmpfile = $this->createTmpFileWithMethod($controllerMethod); |
||
430 | $path = $this->getPath($tmpfile); |
||
431 | add_file_into_file('\/\/', $path, app_path('Http/Controllers/' . $controller . '.php')); |
||
432 | } |
||
433 | |||
434 | /** |
||
435 | * Crete tmp file with route to add. |
||
436 | * |
||
437 | * @param $controllerMethod |
||
438 | * @return mixed |
||
439 | */ |
||
440 | protected function createTmpFileWithMethod($controllerMethod) |
||
441 | { |
||
442 | $temp = tmpfile(); |
||
443 | fwrite($temp, $this->getMethodCode($controllerMethod)); |
||
444 | return $temp; |
||
445 | } |
||
446 | |||
447 | /** |
||
448 | * Get method code. |
||
449 | * |
||
450 | * @param $controllerMethod |
||
451 | * @return mixed |
||
452 | */ |
||
453 | protected function getMethodCode($controllerMethod) |
||
454 | { |
||
455 | return $this->compiler->compile( |
||
456 | $this->filesystem->get($this->getMethodStubPath()), |
||
457 | [ |
||
458 | 'METHOD' => $controllerMethod, |
||
459 | 'VIEW' => $this->argument('link') |
||
460 | ] |
||
461 | ); |
||
462 | } |
||
463 | |||
464 | /** |
||
465 | * Get method stub path. |
||
466 | * |
||
467 | * @return string |
||
468 | */ |
||
469 | protected function getMethodStubPath() |
||
470 | { |
||
471 | return __DIR__ . '/stubs/method.stub'; |
||
472 | } |
||
473 | } |
||
474 |
An exit expression should only be used in rare cases. For example, if you write a short command line script.
In most cases however, using an
exit
expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.