This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
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 Apiato\Core\Generator; |
||
4 | |||
5 | use Apiato\Core\Generator\Exceptions\GeneratorErrorException; |
||
6 | use Apiato\Core\Generator\Interfaces\ComponentsGenerator; |
||
7 | use Apiato\Core\Generator\Traits\FileSystemTrait; |
||
8 | use Apiato\Core\Generator\Traits\FormatterTrait; |
||
9 | use Apiato\Core\Generator\Traits\ParserTrait; |
||
10 | use Apiato\Core\Generator\Traits\PrinterTrait; |
||
11 | use Illuminate\Console\Command; |
||
12 | use Illuminate\Filesystem\Filesystem as IlluminateFilesystem; |
||
13 | use Illuminate\Support\Str; |
||
14 | use Symfony\Component\Console\Input\InputOption; |
||
15 | |||
16 | /** |
||
17 | * Class GeneratorCommand |
||
18 | * |
||
19 | * @author Mahmoud Zalt <[email protected]> |
||
20 | */ |
||
21 | abstract class GeneratorCommand extends Command |
||
22 | { |
||
23 | |||
24 | use ParserTrait, PrinterTrait, FileSystemTrait, FormatterTrait; |
||
25 | |||
26 | /** |
||
27 | * Root directory of all containers |
||
28 | * |
||
29 | * @var string |
||
30 | */ |
||
31 | CONST ROOT = 'app'; |
||
32 | |||
33 | /** |
||
34 | * Relative path for the stubs (relative to this directory / file) |
||
35 | * |
||
36 | * @var string |
||
37 | */ |
||
38 | CONST STUB_PATH = 'Stubs/*'; |
||
39 | |||
40 | /** |
||
41 | * Relative path for the custom stubs (relative to the app/Ship directory! |
||
42 | */ |
||
43 | CONST CUSTOM_STUB_PATH = 'Generators/CustomStubs/*'; |
||
44 | |||
45 | /** |
||
46 | * Containers main folder |
||
47 | * |
||
48 | * @var string |
||
49 | */ |
||
50 | CONST CONTAINER_DIRECTORY_NAME = 'Containers'; |
||
51 | |||
52 | /** |
||
53 | * @var string |
||
54 | */ |
||
55 | protected $filePath; |
||
56 | |||
57 | /** |
||
58 | * @var string the name of the container to generate the stubs |
||
59 | */ |
||
60 | protected $containerName; |
||
61 | |||
62 | /** |
||
63 | * @var string The name of the file to be created (entered by the user) |
||
64 | */ |
||
65 | protected $fileName; |
||
66 | |||
67 | /** |
||
68 | * @var string |
||
69 | */ |
||
70 | protected $userData; |
||
71 | |||
72 | /** |
||
73 | * @var string |
||
74 | */ |
||
75 | protected $parsedFileName; |
||
76 | |||
77 | /** |
||
78 | * @var string |
||
79 | */ |
||
80 | protected $stubContent; |
||
81 | |||
82 | /** |
||
83 | * @var string |
||
84 | */ |
||
85 | protected $renderedStubContent; |
||
86 | |||
87 | /** |
||
88 | * @var \Illuminate\Filesystem\Filesystem |
||
89 | */ |
||
90 | private $fileSystem; |
||
91 | |||
92 | private $defaultInputs = [ |
||
93 | ['container', null, InputOption::VALUE_OPTIONAL, 'The name of the container'], |
||
94 | ['file', null, InputOption::VALUE_OPTIONAL, 'The name of the file'], |
||
95 | ]; |
||
96 | |||
97 | /** |
||
98 | * GeneratorCommand constructor. |
||
99 | * |
||
100 | * @param \Illuminate\Filesystem\Filesystem $fileSystem |
||
101 | */ |
||
102 | public function __construct(IlluminateFilesystem $fileSystem) |
||
103 | { |
||
104 | parent::__construct(); |
||
105 | |||
106 | $this->fileSystem = $fileSystem; |
||
107 | } |
||
108 | |||
109 | /** |
||
110 | * @void |
||
111 | * |
||
112 | * @throws \Apiato\Core\Generator\Exceptions\GeneratorErrorException |
||
113 | */ |
||
114 | public function handle() |
||
115 | { |
||
116 | $this->validateGenerator($this); |
||
117 | |||
118 | $this->containerName = ucfirst($this->checkParameterOrAsk('container', 'Enter the name of the Container')); |
||
119 | $this->fileName = $this->checkParameterOrAsk('file', 'Enter the name of the ' . $this->fileType . ' file', $this->getDefaultFileName()); |
||
120 | |||
121 | // now fix the container and file name |
||
122 | $this->containerName = $this->removeSpecialChars($this->containerName); |
||
123 | $this->fileName = $this->removeSpecialChars($this->fileName); |
||
124 | |||
125 | // and we are ready to start |
||
126 | $this->printStartedMessage($this->containerName, $this->fileName); |
||
127 | |||
128 | // get user inputs |
||
129 | $this->userData = $this->getUserInputs(); |
||
130 | |||
131 | if ($this->userData === null) { |
||
132 | // the user skipped this step |
||
133 | return; |
||
134 | } |
||
135 | $this->userData = $this->sanitizeUserData($this->userData); |
||
136 | |||
137 | // get the actual path of the output file as well as the correct filename |
||
138 | $this->parsedFileName = $this->parseFileStructure($this->nameStructure, $this->userData['file-parameters']); |
||
139 | $this->filePath = $this->getFilePath($this->parsePathStructure($this->pathStructure, $this->userData['path-parameters'])); |
||
140 | |||
141 | if (! $this->fileSystem->exists($this->filePath)) { |
||
142 | |||
143 | // prepare stub content |
||
144 | $this->stubContent = $this->getStubContent(); |
||
145 | $this->renderedStubContent = $this->parseStubContent($this->stubContent, $this->userData['stub-parameters']); |
||
146 | |||
147 | $this->generateFile($this->filePath, $this->renderedStubContent); |
||
148 | |||
149 | $this->printFinishedMessage($this->fileType); |
||
150 | } |
||
151 | |||
152 | // exit the command successfully |
||
153 | return 0; |
||
154 | } |
||
155 | |||
156 | /** |
||
157 | * @param $generator |
||
158 | * |
||
159 | * @throws \Apiato\Core\Generator\Exceptions\GeneratorErrorException |
||
160 | */ |
||
161 | private function validateGenerator($generator) |
||
162 | { |
||
163 | if (!$generator instanceof ComponentsGenerator) { |
||
164 | throw new GeneratorErrorException( |
||
165 | 'Your component maker command should implement ComponentsGenerator interface.' |
||
166 | ); |
||
167 | } |
||
168 | } |
||
169 | |||
170 | /** |
||
171 | * @param $path |
||
172 | * |
||
173 | * @return string |
||
174 | */ |
||
175 | protected function getFilePath($path) |
||
176 | { |
||
177 | // complete the missing parts of the path |
||
178 | $path = base_path() . '/' . |
||
179 | str_replace('\\', '/', self::ROOT . '/' . self::CONTAINER_DIRECTORY_NAME . '/' . $path) . '.' . $this->getDefaultFileExtension(); |
||
180 | |||
181 | // try to create directory |
||
182 | $this->createDirectory($path); |
||
183 | |||
184 | // return full path |
||
185 | return $path; |
||
186 | } |
||
187 | |||
188 | /** |
||
189 | * @return mixed |
||
190 | */ |
||
191 | protected function getStubContent() |
||
192 | { |
||
193 | // check if there is a custom file that overrides the default stubs |
||
194 | $path = app_path() . '/Ship/' . self::CUSTOM_STUB_PATH; |
||
195 | $file = str_replace('*', $this->stubName, $path); |
||
196 | |||
197 | // check if the custom file exists |
||
198 | if (! $this->fileSystem->exists($file)) { |
||
199 | // it does not exist - so take the default file! |
||
200 | $path = __DIR__ . '/' . self::STUB_PATH; |
||
201 | $file = str_replace('*', $this->stubName, $path); |
||
202 | } |
||
203 | |||
204 | // now load the stub |
||
205 | $stub = $this->fileSystem->get($file); |
||
206 | return $stub; |
||
207 | } |
||
208 | |||
209 | /** |
||
210 | * Get all the console command arguments, from the components. The default arguments are prepended |
||
211 | * |
||
212 | * @return array |
||
213 | */ |
||
214 | protected function getOptions() |
||
215 | { |
||
216 | $arguments = array_merge($this->defaultInputs, $this->inputs); |
||
217 | return $arguments; |
||
218 | } |
||
219 | |||
220 | /** |
||
221 | * @param $arg |
||
222 | * @param bool $trim |
||
223 | * |
||
224 | * @return array|string |
||
225 | */ |
||
226 | protected function getInput($arg, $trim = true) |
||
227 | { |
||
228 | return $trim ? $this->trimString($this->argument($arg)) : $this->argument($arg); |
||
229 | } |
||
230 | |||
231 | /** |
||
232 | * Checks if the param is set (via CLI), otherwise asks the user for a value |
||
233 | * |
||
234 | * @param $param |
||
235 | * @param $question |
||
236 | * @param null $default |
||
237 | * @return array|string |
||
238 | */ |
||
239 | View Code Duplication | protected function checkParameterOrAsk($param, $question, $default = null) |
|
0 ignored issues
–
show
|
|||
240 | { |
||
241 | // check if we have already have a param set |
||
242 | $value = $this->option($param); |
||
243 | if($value == null) |
||
244 | { |
||
245 | // there was no value provided via CLI, so ask the user.. |
||
246 | $value = $this->ask($question, $default); |
||
247 | } |
||
248 | |||
249 | return $value; |
||
250 | } |
||
251 | |||
252 | /** |
||
253 | * Checks if the param is set (via CLI), otherwise proposes choices to the user |
||
254 | * |
||
255 | * @param $param |
||
256 | * @param $question |
||
257 | * @param $choices |
||
258 | * @param null $default |
||
259 | * @return array|string |
||
260 | */ |
||
261 | View Code Duplication | protected function checkParameterOrChoice($param, $question, $choices, $default = null) |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
262 | { |
||
263 | // check if we have already have a param set |
||
264 | $value = $this->option($param); |
||
265 | if($value == null) |
||
266 | { |
||
267 | // there was no value provided via CLI, so ask the user.. |
||
268 | $value = $this->choice($question, $choices, $default); |
||
269 | } |
||
270 | |||
271 | return $value; |
||
272 | } |
||
273 | |||
274 | /** |
||
275 | * @param $param |
||
276 | * @param $question |
||
277 | * @param bool $default |
||
278 | * |
||
279 | * @return mixed |
||
280 | */ |
||
281 | View Code Duplication | protected function checkParameterOrConfirm($param, $question, $default = false) |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
282 | { |
||
283 | // check if we have already have a param set |
||
284 | $value = $this->option($param); |
||
285 | if ($value === null) |
||
286 | { |
||
287 | // there was no value provided via CLI, so ask the user.. |
||
288 | $value = $this->confirm($question, $default); |
||
289 | } |
||
290 | |||
291 | return $value; |
||
292 | } |
||
293 | |||
294 | /** |
||
295 | * Checks, if the data from the generator contains path, stub and file-parameters. |
||
296 | * Adds empty arrays, if they are missing |
||
297 | * |
||
298 | * @param $data |
||
299 | * @return mixed |
||
300 | */ |
||
301 | private function sanitizeUserData($data) { |
||
302 | |||
303 | if (! array_key_exists('path-parameters', $data)) { |
||
304 | $data['path-parameters'] = []; |
||
305 | } |
||
306 | |||
307 | if (! array_key_exists('stub-parameters', $data)) { |
||
308 | $data['stub-parameters'] = []; |
||
309 | } |
||
310 | |||
311 | if (! array_key_exists('file-parameters', $data)) { |
||
312 | $data['file-parameters'] = []; |
||
313 | } |
||
314 | |||
315 | return $data; |
||
316 | } |
||
317 | |||
318 | /** |
||
319 | * Get the default file name for this component to be generated |
||
320 | * |
||
321 | * @return string |
||
322 | */ |
||
323 | protected function getDefaultFileName() |
||
324 | { |
||
325 | return 'Default' . Str::ucfirst($this->fileType); |
||
326 | } |
||
327 | |||
328 | /** |
||
329 | * Get the default file extension for the file to be created. |
||
330 | * |
||
331 | * @return string |
||
332 | */ |
||
333 | protected function getDefaultFileExtension() |
||
334 | { |
||
335 | return 'php'; |
||
336 | } |
||
337 | |||
338 | /** |
||
339 | * Removes "special characters" from a string |
||
340 | * |
||
341 | * @param $str |
||
342 | * |
||
343 | * @return string |
||
344 | */ |
||
345 | protected function removeSpecialChars($str) |
||
346 | { |
||
347 | // remove everything that is NOT a character or digit |
||
348 | $str = preg_replace('/[^A-Za-z0-9]/', '', $str); |
||
349 | |||
350 | return $str; |
||
351 | } |
||
352 | |||
353 | } |
||
354 |
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.