keeko /
tools
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 | namespace keeko\tools\command; |
||
| 3 | |||
| 4 | use gossi\codegen\model\PhpClass; |
||
| 5 | use gossi\codegen\model\PhpMethod; |
||
| 6 | use gossi\codegen\model\PhpProperty; |
||
| 7 | use keeko\tools\generator\serializer\base\ModelSerializerTraitGenerator; |
||
| 8 | use keeko\tools\generator\serializer\ModelSerializerGenerator; |
||
| 9 | use keeko\tools\generator\serializer\SkeletonSerializerGenerator; |
||
| 10 | use keeko\tools\helpers\QuestionHelperTrait; |
||
| 11 | use keeko\tools\ui\SerializerUI; |
||
| 12 | use keeko\tools\utils\NamespaceResolver; |
||
| 13 | use phootwork\lang\Text; |
||
| 14 | use phpDocumentor\Reflection\DocBlock\Serializer; |
||
| 15 | use Symfony\Component\Console\Input\InputArgument; |
||
| 16 | use Symfony\Component\Console\Input\InputInterface; |
||
| 17 | use Symfony\Component\Console\Input\InputOption; |
||
| 18 | use Symfony\Component\Console\Output\OutputInterface; |
||
| 19 | use Propel\Generator\Model\Table; |
||
| 20 | use keeko\tools\generator\serializer\TypeInferencerGenerator; |
||
| 21 | |||
| 22 | class GenerateSerializerCommand extends AbstractKeekoCommand { |
||
| 23 | |||
| 24 | use QuestionHelperTrait; |
||
| 25 | |||
| 26 | private $twig; |
||
| 27 | |||
| 28 | protected function configure() { |
||
| 29 | $this |
||
| 30 | ->setName('generate:serializer') |
||
| 31 | ->setDescription('Generates a serializer') |
||
| 32 | ->addArgument( |
||
| 33 | 'name', |
||
| 34 | InputArgument::OPTIONAL, |
||
| 35 | 'The name of the action for which the serializer should be generated.' |
||
| 36 | ) |
||
| 37 | ->addOption( |
||
| 38 | 'model', |
||
| 39 | 'm', |
||
| 40 | InputOption::VALUE_OPTIONAL, |
||
| 41 | 'The model for which the serializer should be generated, when there is no name argument (if ommited all models will be generated)' |
||
| 42 | ) |
||
| 43 | ; |
||
| 44 | |||
| 45 | $this->configureGenerateOptions(); |
||
| 46 | |||
| 47 | parent::configure(); |
||
| 48 | } |
||
| 49 | |||
| 50 | protected function initialize(InputInterface $input, OutputInterface $output) { |
||
| 51 | parent::initialize($input, $output); |
||
| 52 | |||
| 53 | $loader = new \Twig_Loader_Filesystem($this->service->getConfig()->getTemplateRoot() . '/serializer'); |
||
| 54 | $this->twig = new \Twig_Environment($loader); |
||
| 55 | } |
||
| 56 | |||
| 57 | /** |
||
| 58 | * Checks whether actions can be generated at all by reading composer.json and verify |
||
| 59 | * all required information are available |
||
| 60 | */ |
||
| 61 | private function check() { |
||
| 62 | $module = $this->packageService->getModule(); |
||
| 63 | if ($module === null) { |
||
| 64 | throw new \DomainException('No module definition found in composer.json - please run `keeko init`.'); |
||
| 65 | } |
||
| 66 | } |
||
| 67 | |||
| 68 | protected function interact(InputInterface $input, OutputInterface $output) { |
||
| 69 | $this->check(); |
||
| 70 | |||
| 71 | $ui = new SerializerUI($this); |
||
| 72 | $ui->show(); |
||
| 73 | } |
||
| 74 | |||
| 75 | protected function execute(InputInterface $input, OutputInterface $output) { |
||
| 76 | $this->check(); |
||
| 77 | |||
| 78 | $name = $input->getArgument('name'); |
||
| 79 | $modelName = $input->getOption('model'); |
||
| 80 | |||
| 81 | // only a specific action |
||
| 82 | if ($name) { |
||
| 83 | $this->generateSkeleton($name); |
||
| 84 | } |
||
| 85 | |||
| 86 | // create action(s) from a model |
||
| 87 | else if ($modelName) { |
||
| 88 | if (!$this->modelService->hasModel($modelName)) { |
||
| 89 | throw new \RuntimeException(sprintf('Model (%s) does not exist.', $modelName)); |
||
| 90 | } |
||
| 91 | $this->generateModel($this->modelService->getModel($modelName)); |
||
|
0 ignored issues
–
show
|
|||
| 92 | } |
||
| 93 | |||
| 94 | // anyway, generate all models |
||
| 95 | else { |
||
| 96 | foreach ($this->modelService->getModels() as $model) { |
||
| 97 | $this->generateModel($model); |
||
| 98 | } |
||
| 99 | } |
||
| 100 | |||
| 101 | // generate type inferencer |
||
| 102 | $this->generateInferencer(); |
||
| 103 | } |
||
| 104 | |||
| 105 | private function generateModel(Table $model) { |
||
| 106 | $this->logger->info('Generate Serializer from Model: ' . $model->getOriginCommonName()); |
||
| 107 | |||
| 108 | // generate class |
||
| 109 | $generator = new ModelSerializerGenerator($this->service); |
||
| 110 | $serializer = $generator->generate($model); |
||
| 111 | $this->codeService->dumpStruct($serializer, true); |
||
| 112 | |||
| 113 | // generate trait |
||
| 114 | $generator = new ModelSerializerTraitGenerator($this->service); |
||
| 115 | $trait = $generator->generate($model); |
||
| 116 | $this->codeService->dumpStruct($trait, true); |
||
| 117 | |||
| 118 | // add serializer + ApiModelInterface on the model |
||
| 119 | $class = new PhpClass(str_replace('\\\\', '\\', $model->getNamespace() . '\\' . $model->getPhpName())); |
||
| 120 | $file = $this->codeService->getFile($class); |
||
| 121 | if ($file->exists()) { |
||
| 122 | $class = PhpClass::fromFile($this->codeService->getFilename($class)); |
||
| 123 | $class |
||
| 124 | ->addUseStatement($serializer->getQualifiedName()) |
||
| 125 | ->addUseStatement('keeko\\framework\\model\\ApiModelInterface') |
||
| 126 | ->addInterface('ApiModelInterface') |
||
| 127 | ->setProperty(PhpProperty::create('serializer') |
||
| 128 | ->setStatic(true) |
||
| 129 | ->setVisibility('private') |
||
| 130 | ) |
||
| 131 | ->setMethod(PhpMethod::create('getSerializer') |
||
| 132 | ->setStatic(true) |
||
| 133 | ->setType($serializer->getName()) |
||
| 134 | ->setBody($this->twig->render('get-serializer.twig', [ |
||
| 135 | 'class' => $serializer->getName() |
||
| 136 | ])) |
||
| 137 | ) |
||
| 138 | ; |
||
| 139 | |||
| 140 | $this->codeService->dumpStruct($class, true); |
||
| 141 | } |
||
| 142 | } |
||
| 143 | |||
| 144 | /** |
||
| 145 | * Generates a skeleton serializer |
||
| 146 | * |
||
| 147 | * @param string $name |
||
| 148 | */ |
||
| 149 | private function generateSkeleton($name) { |
||
| 150 | $this->logger->info('Generate Skeleton Serializer: ' . $name); |
||
| 151 | $input = $this->io->getInput(); |
||
| 152 | |||
| 153 | $className = NamespaceResolver::getNamespace('src/serializer', $this->package) . '\\' . $name; |
||
| 154 | |||
| 155 | if (!Text::create($className)->endsWith('Serializer')) { |
||
| 156 | $className .= 'Serializer'; |
||
| 157 | } |
||
| 158 | |||
| 159 | // generate code |
||
| 160 | $generator = new SkeletonSerializerGenerator($this->service); |
||
| 161 | $class = $generator->generate($className); |
||
| 162 | $this->codeService->dumpStruct($class, $input->getOption('force')); |
||
| 163 | } |
||
| 164 | |||
| 165 | private function generateInferencer() { |
||
| 166 | $generator = new TypeInferencerGenerator($this->service); |
||
| 167 | $class = $generator->generate(); |
||
| 168 | $this->codeService->dumpStruct($class, true); |
||
| 169 | } |
||
| 170 | |||
| 171 | } |
||
| 172 |
Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code: