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 | /* |
||
4 | * This file is part of EC-CUBE |
||
5 | * |
||
6 | * Copyright(c) 2000-2015 LOCKON CO.,LTD. All Rights Reserved. |
||
7 | * |
||
8 | * http://www.lockon.co.jp/ |
||
9 | * |
||
10 | * This program is free software; you can redistribute it and/or |
||
11 | * modify it under the terms of the GNU General Public License |
||
12 | * as published by the Free Software Foundation; either version 2 |
||
13 | * of the License, or (at your option) any later version. |
||
14 | * |
||
15 | * This program is distributed in the hope that it will be useful, |
||
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
18 | * GNU General Public License for more details. |
||
19 | * |
||
20 | * You should have received a copy of the GNU General Public License |
||
21 | * along with this program; if not, write to the Free Software |
||
22 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
||
23 | */ |
||
24 | |||
25 | namespace Eccube\Command\GeneratorCommand; |
||
26 | |||
27 | use Doctrine\Common\Inflector\Inflector; |
||
28 | use Doctrine\ORM\Mapping\ClassMetadataInfo; |
||
29 | use Doctrine\ORM\Tools\EntityGenerator; |
||
30 | use Doctrine\ORM\Tools\EntityRepositoryGenerator; |
||
31 | use Eccube\Application; |
||
32 | use Symfony\Component\Console\Question\Question; |
||
33 | use Symfony\Component\Finder\Finder; |
||
34 | |||
35 | abstract class AbstractPluginGenerator |
||
36 | { |
||
37 | |||
38 | const DEFAULT_NESTING_LEVEL = 100; |
||
39 | const NEW_HOOK_VERSION = '3.0.9'; |
||
40 | const STOP_PROCESS = 'quit'; |
||
41 | const INPUT_OPEN = '['; |
||
42 | const INPUT_CLOSE = ']'; |
||
43 | const PLUGIN_PREFIX = 'plg_'; |
||
44 | |||
45 | /** |
||
46 | * app |
||
47 | * |
||
48 | * @var \Eccube\Application |
||
49 | */ |
||
50 | protected $app; |
||
51 | |||
52 | /** |
||
53 | * QuestionHelper |
||
54 | * |
||
55 | * @var \Symfony\Component\Console\Helper\QuestionHelper |
||
56 | */ |
||
57 | protected $dialog; |
||
58 | |||
59 | /** |
||
60 | * InputInterface |
||
61 | * |
||
62 | * @var \Symfony\Component\Console\Input\InputInterface |
||
63 | */ |
||
64 | protected $input; |
||
65 | |||
66 | /** |
||
67 | * InputInterface |
||
68 | * |
||
69 | * @var \Symfony\Component\Console\Output\OutputInterface |
||
70 | */ |
||
71 | protected $output; |
||
72 | |||
73 | /** |
||
74 | * $paramList |
||
75 | * @var array $paramList |
||
76 | */ |
||
77 | protected $paramList; |
||
78 | |||
79 | /** |
||
80 | * |
||
81 | * @var int |
||
82 | */ |
||
83 | private $nestingLevel; |
||
84 | |||
85 | /** |
||
86 | * ヘッダー |
||
87 | */ |
||
88 | abstract protected function getHeader(); |
||
89 | |||
90 | /** |
||
91 | * start() |
||
92 | */ |
||
93 | abstract protected function start(); |
||
94 | |||
95 | /** |
||
96 | * フィルドーセット |
||
97 | */ |
||
98 | abstract protected function initFieldSet(); |
||
99 | |||
100 | public function __construct(Application $app) |
||
101 | { |
||
102 | $this->app = $app; |
||
103 | $this->nestingLevel = self::DEFAULT_NESTING_LEVEL; |
||
104 | } |
||
105 | |||
106 | /** |
||
107 | * |
||
108 | * @param \Symfony\Component\Console\Helper\QuestionHelper $dialog |
||
109 | * @param \Symfony\Component\Console\Input\InputInterface $input |
||
110 | * @param \Symfony\Component\Console\Output\OutputInterface $output |
||
111 | */ |
||
112 | public function init($dialog, $input, $output) |
||
113 | { |
||
114 | $this->dialog = $dialog; |
||
115 | $this->input = $input; |
||
116 | $this->output = $output; |
||
117 | $this->initFieldSet(); |
||
118 | } |
||
119 | |||
120 | public function run() |
||
121 | { |
||
122 | // ヘッダー部分 |
||
123 | $this->getHeader(); |
||
124 | |||
125 | foreach ($this->paramList as $paramKey => $params) { |
||
126 | $value = $this->makeLineRequest($params); |
||
127 | if ($value === false) { |
||
128 | $this->exitGenerator(); |
||
129 | |||
130 | return; |
||
131 | } |
||
132 | $this->paramList[$paramKey]['value'] = $value; |
||
133 | } |
||
134 | |||
135 | $this->output->writeln(''); |
||
136 | $this->output->writeln('---Entry confirmation'); |
||
137 | foreach ($this->paramList as $paramKey => $params) { |
||
138 | if (is_array($params['value'])) { |
||
139 | $this->output->writeln($params['label']); |
||
140 | foreach ($params['value'] as $keys => $val) { |
||
141 | $this->output->writeln('<info> '.$keys.'</info>'); |
||
142 | } |
||
143 | } else { |
||
144 | if (isset($params['show'])) { |
||
145 | $disp = $params['show'][$params['value']]; |
||
146 | } else { |
||
147 | $disp = $params['value']; |
||
148 | } |
||
149 | $this->output->writeln($params['label'].' <info>'.$disp.'</info>'); |
||
150 | } |
||
151 | } |
||
152 | $this->output->writeln(''); |
||
153 | $Question = new Question('<comment>[confirm] Do you want to proceed? [y/n] : </comment>', ''); |
||
154 | $value = $this->dialog->ask($this->input, $this->output, $Question); |
||
155 | if ($value != 'y') { |
||
156 | $this->exitGenerator(); |
||
157 | |||
158 | return; |
||
159 | } |
||
160 | |||
161 | $this->start(); |
||
162 | } |
||
163 | |||
164 | protected function exitGenerator($msg = 'Quitting Bye bye.') |
||
165 | { |
||
166 | $this->output->writeln($msg); |
||
167 | } |
||
168 | |||
169 | protected function makeLineRequest($params) |
||
170 | { |
||
171 | // nesting loop protection |
||
172 | if ($this->getNestingLevel() < 0) { |
||
173 | rewind($this->output->getStream()); |
||
174 | $display = stream_get_contents($this->output->getStream()); |
||
175 | throw new \Exception($display); |
||
176 | } |
||
177 | $this->nestingLevel--; |
||
178 | |||
179 | $this->output->writeln($params['name']); |
||
180 | $Question = new Question('<comment>Input'.self::INPUT_OPEN.$params['no'].self::INPUT_CLOSE.' : </comment>', ''); |
||
181 | $value = $this->dialog->ask($this->input, $this->output, $Question); |
||
182 | $value = trim($value); |
||
183 | if ($value === self::STOP_PROCESS) { |
||
184 | return false; |
||
185 | } |
||
186 | foreach ($params['validation'] as $key => $row) { |
||
187 | |||
188 | if ($key == 'isRequired' && $row == true) { |
||
189 | if ($value === '' || strlen($value) == 0) { |
||
190 | |||
191 | $this->output->writeln('[!] Value cannot be empty.'); |
||
192 | |||
193 | return $this->makeLineRequest($params); |
||
194 | } |
||
195 | } elseif ($key == 'pattern' && preg_match($row, $value) == false) { |
||
196 | $this->output->writeln('<error>[!] Value is not valid.</error>'); |
||
197 | |||
198 | return $this->makeLineRequest($params); |
||
199 | } elseif ($key == 'isCode') { |
||
0 ignored issues
–
show
Coding Style
introduced
by
Loading history...
|
|||
200 | |||
201 | if (in_array($value, $row)) { |
||
202 | $this->output->writeln('<error>[!] Plugin with this code already exists.</error>'); |
||
203 | |||
204 | return $this->makeLineRequest($params); |
||
205 | } |
||
206 | } elseif ($key == 'isNotCode') { |
||
0 ignored issues
–
show
|
|||
207 | |||
208 | if (!in_array($value, $row)) { |
||
209 | $this->output->writeln('<error>[!] This plugin code does not exist.</error>'); |
||
210 | |||
211 | return $this->makeLineRequest($params); |
||
212 | } |
||
213 | |||
0 ignored issues
–
show
|
|||
214 | } elseif ($key == 'inArray' || $key == 'choice') { |
||
215 | |||
216 | if (is_string($row)) { |
||
217 | $row = $this->$row(); |
||
218 | } |
||
219 | if ($value == '') { |
||
220 | return $params['value']; |
||
221 | } |
||
222 | if (isset($row[$value])) { |
||
223 | if (!is_array($params['value'])) { |
||
224 | $value = $row[$value]; |
||
225 | continue; |
||
226 | } |
||
227 | $params['value'][$value] = $row[$value]; |
||
228 | $this->output->writeln('<info>--- your entry list</info>'); |
||
229 | foreach ($params['value'] as $subKey => $node) { |
||
230 | $this->output->writeln('<info> - '.$subKey.'</info>'); |
||
231 | } |
||
232 | $this->output->writeln(''); |
||
233 | $this->output->writeln('--- Press Enter to move to the next step ---'); |
||
234 | |||
235 | return $this->makeLineRequest($params); |
||
236 | } else { |
||
237 | $searchList = array(); |
||
238 | $max = 16; |
||
239 | foreach ($row as $eventKey => $eventConst) { |
||
240 | if (strpos($eventKey, $value) !== false || strpos($eventConst, $value) !== false) { |
||
241 | if (count($searchList) >= $max) { |
||
242 | $searchList['-- there are more then '.$max.''] = ''; |
||
243 | break; |
||
244 | } |
||
245 | $searchList[$eventKey] = $eventConst; |
||
246 | } |
||
247 | } |
||
248 | $this->output->writeln('<error>[!] No results have been found</error>'); |
||
249 | if (!empty($searchList)) { |
||
250 | $this->output->writeln('--- there are more then one search result'); |
||
251 | } |
||
252 | foreach ($searchList as $subKey => $node) { |
||
253 | $this->output->writeln(' - '.$subKey); |
||
254 | } |
||
255 | |||
256 | if (!empty($searchList)) { |
||
257 | $this->output->writeln(''); |
||
258 | } |
||
259 | |||
260 | return $this->makeLineRequest($params); |
||
261 | } |
||
262 | } |
||
263 | } |
||
264 | |||
265 | return $value; |
||
266 | } |
||
267 | |||
268 | protected function getNestingLevel() |
||
269 | { |
||
270 | return $this->nestingLevel; |
||
271 | } |
||
272 | |||
273 | protected function setNestingLevel($nestingLevel) |
||
274 | { |
||
275 | $this->nestingLevel = $nestingLevel; |
||
276 | } |
||
277 | |||
278 | |||
279 | /** |
||
280 | * app/Plugin直下にあるディレクトリ名(プラグインコード)を取得 |
||
281 | * |
||
282 | * @return array |
||
283 | */ |
||
284 | protected function getPluginCodes() |
||
285 | { |
||
286 | $finder = new Finder(); |
||
287 | |||
288 | $finder->directories()->depth('== 0'); |
||
289 | |||
290 | $dirs = $finder->in($this->app['config']['root_dir'].'/app/Plugin/'); |
||
291 | |||
292 | $codes = array(); |
||
293 | foreach ($dirs as $item) { |
||
294 | $codes[] = $item->getRelativePathname(); |
||
295 | } |
||
296 | |||
297 | return $codes; |
||
298 | } |
||
299 | |||
300 | /** |
||
301 | * Entity、Repositoryファイルの作成 |
||
302 | * |
||
303 | * @param array $metadatas |
||
304 | * @param array $fsList |
||
305 | */ |
||
306 | protected function generateEntities(array $metadatas, array &$fsList) |
||
307 | { |
||
308 | /** @var ClassMetadataInfo $class */ |
||
309 | foreach ($metadatas as $class) { |
||
0 ignored issues
–
show
|
|||
310 | |||
311 | // Entity作成 |
||
312 | $EntityGenerator = new EntityGenerator(); |
||
313 | $EntityGenerator->setBackupExisting(false); |
||
314 | $EntityGenerator->setClassToExtend('Eccube\\Entity\\AbstractEntity'); |
||
315 | $EntityGenerator->setGenerateAnnotations(false); |
||
316 | $EntityGenerator->setRegenerateEntityIfExists(true); |
||
317 | $EntityGenerator->setGenerateStubMethods(true); |
||
318 | $EntityGenerator->setUpdateEntityIfExists(false); |
||
319 | |||
320 | $appPath = $this->app['config']['root_dir'].'/app/'; |
||
321 | $EntityGenerator->generate(array($class), $appPath); |
||
322 | |||
323 | $filename = $appPath.str_replace('\\', DIRECTORY_SEPARATOR, $class->name).'.php'; |
||
324 | View Code Duplication | if (is_file($filename)) { |
|
0 ignored issues
–
show
This code seems to be duplicated across 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.
Loading history...
|
|||
325 | $fsList['file'][$filename] = true; |
||
326 | } else { |
||
327 | $fsList['file'][$filename] = false; |
||
328 | } |
||
329 | |||
330 | // Repository作成 |
||
331 | $RepositoryGenerator = new EntityRepositoryGenerator(); |
||
332 | $RepositoryGenerator->writeEntityRepositoryClass($class->customRepositoryClassName, $appPath); |
||
333 | |||
334 | $filename = $appPath.str_replace('\\', DIRECTORY_SEPARATOR, $class->customRepositoryClassName).'.php'; |
||
335 | View Code Duplication | if (is_file($filename)) { |
|
0 ignored issues
–
show
This code seems to be duplicated across 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.
Loading history...
|
|||
336 | $fsList['file'][$filename] = true; |
||
337 | } else { |
||
338 | $fsList['file'][$filename] = false; |
||
339 | } |
||
340 | } |
||
341 | |||
342 | } |
||
343 | |||
344 | |||
345 | /** |
||
346 | * migraionファイルの作成 |
||
347 | * |
||
348 | * @param array $metadatas |
||
349 | * @param array $fsList |
||
350 | * @param $pluginCode |
||
351 | * @param $codePath |
||
352 | */ |
||
353 | protected function generateMigration(array $metadatas, array &$fsList = array(), $pluginCode, $codePath) |
||
0 ignored issues
–
show
Parameters which have default values should be placed at the end.
If you place a parameter with a default value before a parameter with a default value, the default value of the first parameter will never be used as it will always need to be passed anyway: // $a must always be passed; it's default value is never used.
function someFunction($a = 5, $b) { }
Loading history...
|
|||
354 | { |
||
355 | if (count($metadatas)) { |
||
356 | $migrationContent = $this->makeMigration($pluginCode, $metadatas); |
||
357 | $date = date('YmdHis'); |
||
358 | $migrationContent = str_replace('[datetime]', $date, $migrationContent); |
||
359 | $migPath = $codePath.'/Resource/doctrine/migration/Version'.$date.'.php'; |
||
360 | |||
361 | file_put_contents($migPath, $migrationContent); |
||
362 | View Code Duplication | if (is_file($migPath)) { |
|
0 ignored issues
–
show
This code seems to be duplicated across 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.
Loading history...
|
|||
363 | $fsList['file'][$migPath] = true; |
||
364 | } else { |
||
365 | $fsList['file'][$migPath] = false; |
||
366 | } |
||
367 | } |
||
368 | } |
||
369 | |||
370 | |||
371 | /** |
||
372 | * migrationファイルの作成 |
||
373 | * |
||
374 | * @param $pluginCode |
||
375 | * @param array $metadatas |
||
376 | * @return mixed|string |
||
377 | */ |
||
378 | protected function makeMigration($pluginCode, array $metadatas) |
||
379 | { |
||
380 | if ($this->paramList['supportFlag']['value']) { |
||
381 | $migrationFileCont = file_get_contents($this->app['config']['root_dir'].'/src/Eccube/Command/GeneratorCommand/generatortemplate/MigrationVersionSupport.php'); |
||
382 | } else { |
||
383 | $migrationFileCont = file_get_contents($this->app['config']['root_dir'].'/src/Eccube/Command/GeneratorCommand/generatortemplate/MigrationVersion.php'); |
||
384 | } |
||
385 | |||
386 | $migrationFileCont = str_replace('[code]', $pluginCode, $migrationFileCont); |
||
387 | |||
388 | $entityList = array(); |
||
389 | foreach ($metadatas as $metadata) { |
||
390 | $entityList[] = ' \''.$metadata->name.'\''; |
||
391 | } |
||
392 | |||
393 | $entityListStr = join(','.PHP_EOL, $entityList); |
||
394 | $migrationFileCont = str_replace('[entityList]', $entityListStr, $migrationFileCont); |
||
395 | if ($this->paramList['supportFlag']['value']) { |
||
396 | $createParts = $this->makeCreateParts($metadatas); |
||
397 | $tableNameArr = array(); |
||
398 | foreach ($createParts as $tableName => $tableArr) { |
||
399 | $tableNameArr[] = ' $this->createTable'.$tableName.'($schema);'; |
||
400 | } |
||
401 | $tableNameStr = join(PHP_EOL, $tableNameArr); |
||
402 | $migrationFileCont = str_replace('[createTable]', $tableNameStr, $migrationFileCont); |
||
403 | |||
404 | $createPartsStr = ''; |
||
405 | foreach ($createParts as $parts) { |
||
406 | $createPartsStr .= join(PHP_EOL, $parts); |
||
407 | } |
||
408 | $migrationFileCont = str_replace('[createFunction]', $createPartsStr, $migrationFileCont); |
||
409 | |||
410 | $dropParts = $this->makeDropParts($metadatas); |
||
411 | $dropPartsStr = join(PHP_EOL, $dropParts); |
||
412 | $migrationFileCont = str_replace('[dropTable]', $dropPartsStr, $migrationFileCont); |
||
413 | } |
||
414 | |||
415 | return $migrationFileCont; |
||
416 | } |
||
417 | |||
418 | |||
419 | protected function makeCreateParts($metadatas) |
||
420 | { |
||
421 | $ret = array(); |
||
422 | foreach ($metadatas as $metadata) { |
||
0 ignored issues
–
show
|
|||
423 | |||
424 | $nameFormated = Inflector::camelize($metadata->table['name']); |
||
425 | $tmp = array(); |
||
426 | $tmp[] = ''; |
||
427 | $tmp[] = ' /**'; |
||
428 | $tmp[] = ' * @param Schema $schema'; |
||
429 | $tmp[] = ' */'; |
||
430 | $tmp[] = ' public function createTable'.ucfirst($nameFormated).'(Schema $schema)'; |
||
431 | $tmp[] = ' {'; |
||
432 | $tmp[] = ' $table = $schema->createTable(\''.$metadata->table['name'].'\');'; |
||
433 | $columns = $metadata->fieldMappings; |
||
434 | foreach ($columns as $column) { |
||
0 ignored issues
–
show
|
|||
435 | |||
436 | $typeName = $column['type']; |
||
437 | $tmp[] = ' $table->addColumn(\''.$column['columnName'].'\', \''.$typeName.'\', array('; |
||
438 | $param = array(); |
||
439 | if (isset($column['nullable']) && $column['nullable']) { |
||
440 | $param['notnull'] = 'true'; |
||
441 | } else { |
||
442 | $param['notnull'] = 'false'; |
||
443 | } |
||
444 | |||
445 | foreach ($param as $parKey => $parVal) { |
||
446 | $tmp[] = ' \''.$parKey.'\' => '.$parVal.','; |
||
447 | } |
||
448 | $tmp[] = ' ));'; |
||
449 | } |
||
450 | |||
451 | |||
452 | $tmp[] = ' }'; |
||
453 | $tmp[] = ''; |
||
454 | $ret[ucfirst($nameFormated)] = $tmp; |
||
455 | } |
||
456 | |||
457 | return $ret; |
||
458 | } |
||
459 | |||
460 | protected function makeDropParts($metadatas) |
||
461 | { |
||
462 | $ret = array(); |
||
463 | foreach ($metadatas as $metadata) { |
||
464 | $ret[] = ' $schema->dropTable(\''.$metadata->table['name'].'\');'; |
||
465 | } |
||
466 | |||
467 | return $ret; |
||
468 | } |
||
469 | |||
470 | |||
471 | /** |
||
472 | * メッセージ表示 |
||
473 | * |
||
474 | * @param array $fsList |
||
475 | */ |
||
476 | protected function completeMessage(array $fsList) |
||
477 | { |
||
478 | |||
479 | $dirFileNg = array(); |
||
480 | $dirFileOk = array(); |
||
481 | View Code Duplication | foreach ($fsList['dir'] as $path => $flag) { |
|
0 ignored issues
–
show
This code seems to be duplicated across 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.
Loading history...
|
|||
482 | if ($flag) { |
||
483 | $dirFileOk[] = $path; |
||
484 | } else { |
||
485 | $dirFileNg[] = $path; |
||
486 | } |
||
487 | } |
||
488 | View Code Duplication | foreach ($fsList['file'] as $path => $flag) { |
|
0 ignored issues
–
show
This code seems to be duplicated across 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.
Loading history...
|
|||
489 | if ($flag) { |
||
490 | $dirFileOk[] = $path; |
||
491 | } else { |
||
492 | $dirFileNg[] = $path; |
||
493 | } |
||
494 | } |
||
495 | $this->output->writeln(''); |
||
496 | $this->output->writeln('[+]File system'); |
||
497 | View Code Duplication | if (!empty($dirFileOk)) { |
|
0 ignored issues
–
show
This code seems to be duplicated across 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.
Loading history...
|
|||
498 | $this->output->writeln(''); |
||
499 | $this->output->writeln(' this files and folders were created.'); |
||
500 | foreach ($dirFileOk as $path) { |
||
501 | $this->output->writeln('<info> - '.$path.'</info>'); |
||
502 | } |
||
503 | } |
||
504 | |||
505 | View Code Duplication | if (!empty($dirFileNg)) { |
|
0 ignored issues
–
show
This code seems to be duplicated across 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.
Loading history...
|
|||
506 | $this->output->writeln(''); |
||
507 | $this->output->writeln(' this files and folders was not created.'); |
||
508 | foreach ($dirFileOk as $path) { |
||
509 | $this->output->writeln('<error> - '.$path.'</error>'); |
||
510 | } |
||
511 | } |
||
512 | |||
513 | } |
||
514 | } |
||
515 |