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 the PetkoparaCrudGeneratorBundle |
||
5 | * |
||
6 | * (c) Petko Petkov <[email protected]> |
||
7 | * |
||
8 | * For the full copyright and license information, please view the LICENSE |
||
9 | * file that was distributed with this source code. |
||
10 | */ |
||
11 | |||
12 | namespace Petkopara\CrudGeneratorBundle\Command; |
||
13 | |||
14 | use Doctrine\Bundle\DoctrineBundle\Mapping\DisconnectedMetadataFactory; |
||
15 | use Petkopara\CrudGeneratorBundle\Configuration\ConfigurationBuilder; |
||
16 | use Petkopara\CrudGeneratorBundle\Generator\Guesser\MetadataGuesser; |
||
17 | use Petkopara\CrudGeneratorBundle\Generator\PetkoparaCrudGenerator; |
||
18 | use Petkopara\CrudGeneratorBundle\Generator\PetkoparaFilterGenerator; |
||
19 | use Petkopara\CrudGeneratorBundle\Generator\PetkoparaFormGenerator; |
||
20 | use Sensio\Bundle\GeneratorBundle\Command\AutoComplete\EntitiesAutoCompleter; |
||
21 | use Sensio\Bundle\GeneratorBundle\Command\GenerateDoctrineCrudCommand; |
||
22 | use Sensio\Bundle\GeneratorBundle\Command\Validators; |
||
23 | use Symfony\Component\Config\Definition\Exception\Exception; |
||
24 | use Symfony\Component\Console\Input\InputArgument; |
||
25 | use Symfony\Component\Console\Input\InputInterface; |
||
26 | use Symfony\Component\Console\Input\InputOption; |
||
27 | use Symfony\Component\Console\Output\OutputInterface; |
||
28 | use Symfony\Component\Console\Question\ConfirmationQuestion; |
||
29 | use Symfony\Component\Console\Question\Question; |
||
30 | use Symfony\Component\HttpKernel\Bundle\BundleInterface; |
||
31 | use Symfony\Component\Yaml\Exception\RuntimeException; |
||
32 | |||
33 | class CrudGeneratorCommand extends GenerateDoctrineCrudCommand |
||
34 | { |
||
35 | |||
36 | const FILTER_TYPE_FORM = 'form'; |
||
37 | const FILTER_TYPE_INPUT = 'input'; |
||
38 | const FILTER_TYPE_NONE = 'none'; |
||
39 | |||
40 | protected $generator; |
||
41 | protected $formGenerator; |
||
42 | private $filterGenerator; |
||
43 | |||
44 | 15 | protected function configure() |
|
45 | { |
||
46 | |||
47 | 15 | $this |
|
48 | 15 | ->setName('petkopara:generate:crud') |
|
49 | 15 | ->setDescription('A CRUD generator with pagination, filters, bulk delete and bootstrap markdown.') |
|
50 | 15 | ->setDefinition(array( |
|
51 | 15 | new InputArgument('entity', InputArgument::OPTIONAL, 'The entity class name to initialize (shortcut notation)'), |
|
52 | 15 | new InputOption('entity', '', InputOption::VALUE_REQUIRED, 'The entity class name to initialize (shortcut notation)'), |
|
53 | 15 | new InputOption('route-prefix', 'r', InputOption::VALUE_REQUIRED, 'The route prefix'), |
|
54 | 15 | new InputOption('template', 't', InputOption::VALUE_REQUIRED, 'The base template which will be extended by the templates', 'PetkoparaCrudGeneratorBundle::base.html.twig'), |
|
55 | 15 | new InputOption('format', 'f', InputOption::VALUE_REQUIRED, 'The format used for configuration files (php, xml, yml, or annotation)', 'annotation'), |
|
56 | 15 | new InputOption('overwrite', 'o', InputOption::VALUE_NONE, 'Overwrite any existing controller or form class when generating the CRUD contents'), |
|
57 | 15 | new InputOption('bundle-views', 'b', InputOption::VALUE_NONE, 'Whether or not to store the view files in app/Resources/views/ or in bundle dir'), |
|
58 | 15 | new InputOption('without-sorting', 'wsr', InputOption::VALUE_NONE, 'Whether or not have sorting in the index'), |
|
59 | 15 | new InputOption('without-page-size', 'wps', InputOption::VALUE_NONE, 'Whether or not to show items per page select in the index'), |
|
60 | 15 | new InputOption('without-write', 'ww', InputOption::VALUE_NONE, 'Whether or not to generate create, new and delete actions'), |
|
61 | 15 | new InputOption('without-show', 'ws', InputOption::VALUE_NONE, 'Whether or not to generate create, new and delete actions'), |
|
62 | 15 | new InputOption('without-bulk', 'wb', InputOption::VALUE_NONE, 'Whether or not to generate bulk actions'), |
|
63 | 15 | new InputOption('filter-type', 'ft', InputOption::VALUE_REQUIRED, 'What type of filtrations to be used. Multi search input, Form filter or none', 'form'), |
|
64 | 15 | )) |
|
65 | 15 | ->setHelp(<<<EOT |
|
66 | The <info>%command.name%</info> command generates a CRUD based on a Doctrine entity. |
||
67 | |||
68 | The default command only generates the list and show actions. |
||
69 | |||
70 | <info>php %command.full_name% --entity=AcmeBlogBundle:Post --route-prefix=post_admin</info> |
||
71 | |||
72 | Using the --without-write to not generate the new, edit, bulk and delete actions. |
||
73 | |||
74 | Using the --bundle-views option store the view files in the bundles dir. |
||
75 | |||
76 | Using the --without-bulk use this option tp not generate bulk actions code. |
||
77 | |||
78 | Using the --template option allows to set base template from which the crud views to overide. |
||
79 | |||
80 | <info>php %command.full_name% doctrine:generate:crud --entity=AcmeBlogBundle:Post --route-prefix=post_admin </info> |
||
81 | |||
82 | Every generated file is based on a template. There are default templates but they can be overridden by placing custom templates in one of the following locations, by order of priority: |
||
83 | |||
84 | <info>BUNDLE_PATH/Resources/PetkoparaCrudGeneratorBundle/skeleton/crud |
||
85 | APP_PATH/Resources/PetkoparaCrudGeneratorBundle/skeleton/crud</info> |
||
86 | |||
87 | And |
||
88 | |||
89 | <info>BUNDLE_PATH/Resources/PetkoparaCrudGeneratorBundle/skeleton/form |
||
90 | APP_PATH/Resources/PetkoparaCrudGeneratorBundle/skeleton/form</info> |
||
91 | |||
92 | EOT |
||
93 | 15 | ); |
|
94 | 15 | } |
|
95 | |||
96 | protected function createGenerator($bundle = null) |
||
97 | { |
||
98 | return new PetkoparaCrudGenerator($this->getContainer()->get('filesystem'), $this->getContainer()->getParameter('kernel.root_dir')); |
||
99 | } |
||
100 | |||
101 | protected function getSkeletonDirs(BundleInterface $bundle = null) |
||
102 | { |
||
103 | $skeletonDirs = array(); |
||
104 | if (isset($bundle) && is_dir($dir = $bundle->getPath() . '/Resources/PetkoparaCrudGeneratorBundle/skeleton')) { |
||
105 | $skeletonDirs[] = $dir; |
||
106 | } |
||
107 | |||
108 | if (is_dir($dir = $this->getContainer()->get('kernel')->getRootdir() . '/Resources/PetkoparaCrudGeneratorBundle/skeleton')) { |
||
109 | $skeletonDirs[] = $dir; |
||
110 | } |
||
111 | |||
112 | $skeletonDirs[] = $this->getContainer()->get('kernel')->locateResource('@PetkoparaCrudGeneratorBundle/Resources/skeleton'); |
||
113 | $skeletonDirs[] = $this->getContainer()->get('kernel')->locateResource('@PetkoparaCrudGeneratorBundle/Resources'); |
||
114 | |||
115 | return $skeletonDirs; |
||
116 | } |
||
117 | |||
118 | 11 | protected function interact(InputInterface $input, OutputInterface $output) |
|
119 | { |
||
120 | |||
121 | 11 | $questionHelper = $this->getQuestionHelper(); |
|
122 | 11 | $questionHelper->writeSection($output, 'Welcome to the Petkopara CRUD generator'); |
|
123 | |||
124 | // namespace |
||
125 | 11 | $output->writeln(array( |
|
126 | 11 | '', |
|
127 | 11 | 'This command helps you generate CRUD controllers and templates.', |
|
128 | 11 | '', |
|
129 | 11 | 'First, give the name of the existing entity for which you want to generate a CRUD', |
|
130 | 11 | '(use the shortcut notation like <comment>AcmeBlogBundle:Post</comment>)', |
|
131 | 11 | '', |
|
132 | 11 | )); |
|
133 | |||
134 | 11 | if ($input->hasArgument('entity') && $input->getArgument('entity') != '') { |
|
135 | $input->setOption('entity', $input->getArgument('entity')); |
||
136 | } |
||
137 | |||
138 | 11 | $question = new Question($questionHelper->getQuestion('The Entity shortcut name', $input->getOption('entity')), $input->getOption('entity')); |
|
139 | 11 | $question->setValidator(array('Sensio\Bundle\GeneratorBundle\Command\Validators', 'validateEntityName')); |
|
140 | |||
141 | |||
142 | 11 | $autocompleter = new EntitiesAutoCompleter($this->getContainer()->get('doctrine')->getManager()); |
|
143 | 11 | $autocompleteEntities = $autocompleter->getSuggestions(); |
|
144 | 11 | $question->setAutocompleterValues($autocompleteEntities); |
|
145 | 11 | $entity = $questionHelper->ask($input, $output, $question); |
|
146 | |||
147 | 11 | $input->setOption('entity', $entity); |
|
148 | 11 | list($bundle, $entity) = $this->parseShortcutNotation($entity); |
|
149 | |||
150 | try { |
||
151 | 11 | $entityClass = $this->getContainer()->get('doctrine')->getAliasNamespace($bundle) . '\\' . $entity; |
|
152 | 11 | $this->getEntityMetadata($entityClass); |
|
153 | 11 | } catch (\Exception $e) { |
|
154 | throw new \RuntimeException(sprintf('Entity "%s" does not exist in the "%s" bundle. You may have mistyped the bundle name or maybe the entity doesn\'t exist yet (create it first with the "doctrine:generate:entity" command).', $entity, $bundle)); |
||
155 | } |
||
156 | |||
157 | // write? |
||
158 | 11 | $withoutWrite = $input->getOption('without-write') ? true : false; //default false |
|
159 | 11 | $output->writeln(array( |
|
160 | 11 | '', |
|
161 | 11 | 'By default, the generator creates all actions: list and show, new, update, and delete.', |
|
162 | 11 | 'You can also skip it and to generate only "list and show" actions:', |
|
163 | 11 | '', |
|
164 | 11 | )); |
|
165 | 11 | $question = new ConfirmationQuestion($questionHelper->getQuestion('Do you want to skip generating of the "write" actions', $withoutWrite ? 'yes' : 'no', '?', $withoutWrite), $withoutWrite); |
|
166 | 11 | $withoutWrite = $questionHelper->ask($input, $output, $question); |
|
167 | 11 | $input->setOption('without-write', $withoutWrite); |
|
168 | |||
169 | // filters? |
||
170 | 11 | $filterType = $input->getOption('filter-type'); |
|
171 | 11 | $output->writeln(array( |
|
172 | 11 | '', |
|
173 | 11 | 'By default, the generator generate filter code.', |
|
174 | 11 | '<comment>form</comment> to use LexikFormFilterBundle to search in the entity.', |
|
175 | 11 | '<comment>input</comment> to use PetkoparaMultiSearchBundle to search only with one input in the entity.', |
|
176 | 11 | '<comment>none</comment> use this to not generate any filter code.', |
|
177 | 11 | '', |
|
178 | 11 | )); |
|
179 | 11 | $question = new Question($questionHelper->getQuestion('Filter Type (form, input, none)', $filterType), $filterType); |
|
180 | 11 | $question->setValidator(array('Petkopara\CrudGeneratorBundle\Command\CrudValidators', 'validateFilterType')); |
|
181 | 11 | $filterType = $questionHelper->ask($input, $output, $question); |
|
182 | 11 | $input->setOption('filter-type', $filterType); |
|
183 | |||
184 | |||
185 | // template? |
||
186 | 11 | $template = $input->getOption('template'); |
|
187 | 11 | $output->writeln(array( |
|
188 | 11 | '', |
|
189 | 11 | 'By default, the created views extends the CrudGeneratorBundle::base.html.twig', |
|
190 | 11 | 'You can also set your template which the views to extend, for example base.html.twig ', |
|
191 | 11 | '', |
|
192 | 11 | )); |
|
193 | 11 | $question = new Question($questionHelper->getQuestion('Base template for the views', $template), $template); |
|
194 | 11 | $template = $questionHelper->ask($input, $output, $question); |
|
195 | 11 | $input->setOption('template', $template); |
|
196 | |||
197 | |||
198 | // format |
||
199 | 11 | $format = $input->getOption('format'); |
|
200 | 11 | $output->writeln(array( |
|
201 | 11 | '', |
|
202 | 11 | 'Determine the format to use for the generated CRUD.', |
|
203 | 11 | '', |
|
204 | 11 | )); |
|
205 | 11 | $question = new Question($questionHelper->getQuestion('Configuration format (yml, xml, php, or annotation)', $format), $format); |
|
206 | 11 | $question->setValidator(array('Sensio\Bundle\GeneratorBundle\Command\Validators', 'validateFormat')); |
|
207 | 11 | $format = $questionHelper->ask($input, $output, $question); |
|
208 | 11 | $input->setOption('format', $format); |
|
209 | |||
210 | // route prefix |
||
211 | 11 | $prefix = $this->getRoutePrefix($input, $entity); |
|
212 | 11 | $output->writeln(array( |
|
213 | 11 | '', |
|
214 | 11 | 'Determine the routes prefix (all the routes will be "mounted" under this', |
|
215 | 11 | 'prefix: /prefix/, /prefix/new, ...).', |
|
216 | 11 | '', |
|
217 | 11 | )); |
|
218 | 11 | $prefix = $questionHelper->ask($input, $output, new Question($questionHelper->getQuestion('Routes prefix', '/' . $prefix), '/' . $prefix)); |
|
219 | 11 | $input->setOption('route-prefix', $prefix); |
|
220 | |||
221 | // summary |
||
222 | 11 | $output->writeln(array( |
|
223 | 11 | '', |
|
224 | 11 | $this->getHelper('formatter')->formatBlock('Summary before generation', 'bg=blue;fg=white', true), |
|
0 ignored issues
–
show
|
|||
225 | 11 | '', |
|
226 | 11 | sprintf('You are going to generate a CRUD controller for "<info>%s:%s</info>"', $bundle, $entity), |
|
227 | 11 | sprintf('Using the "<info>%s</info>" format.', $format), |
|
228 | 11 | sprintf('Route prefix "<info>%s</info>" format.', $prefix), |
|
229 | 11 | sprintf('Base template "<info>%s</info>".', $template), |
|
230 | 11 | sprintf('With write "<info>%s</info>".', (!$withoutWrite) ? 'yes' : 'no'), |
|
231 | 11 | sprintf('Filters "<info>%s</info>".', $filterType), |
|
232 | 11 | '', |
|
233 | 11 | )); |
|
234 | 11 | } |
|
235 | |||
236 | /** |
||
237 | * @see Command |
||
238 | */ |
||
239 | 15 | protected function execute(InputInterface $input, OutputInterface $output) |
|
240 | { |
||
241 | 15 | $questionHelper = $this->getQuestionHelper(); |
|
242 | |||
243 | 15 | if ($input->isInteractive()) { |
|
244 | 11 | $question = new ConfirmationQuestion($questionHelper->getQuestion('Do you confirm generation', 'yes', '?'), true); |
|
245 | 11 | if (!$questionHelper->ask($input, $output, $question)) { |
|
246 | $output->writeln('<error>Command aborted</error>'); |
||
247 | return 1; |
||
248 | } |
||
249 | 11 | } |
|
250 | |||
251 | 15 | $entity = Validators::validateEntityName($input->getOption('entity')); |
|
252 | 15 | list($bundle, $entity) = $this->parseShortcutNotation($entity); |
|
253 | |||
254 | //get the options |
||
255 | 15 | $format = Validators::validateFormat($input->getOption('format')); |
|
256 | 15 | $prefix = $this->getRoutePrefix($input, $entity); |
|
257 | 15 | $withoutWrite = $input->getOption('without-write'); //default with write |
|
258 | 15 | $filterType = CrudValidators::validateFilterType($input->getOption('filter-type')); |
|
259 | 15 | $withoutBulk = $input->getOption('without-bulk'); |
|
260 | 15 | $withoutShow = $input->getOption('without-show'); |
|
261 | 15 | $withoutSorting = $input->getOption('without-sorting'); |
|
262 | 15 | $withoutPageSize = $input->getOption('without-page-size'); |
|
263 | 15 | $bundleViews = $input->getOption('bundle-views'); |
|
264 | 15 | $template = $input->getOption('template'); |
|
265 | |||
266 | 15 | $forceOverwrite = $input->getOption('overwrite'); |
|
267 | |||
268 | 15 | $questionHelper->writeSection($output, 'CRUD generation'); |
|
269 | |||
270 | try { |
||
271 | 15 | $entityClass = $this->getContainer()->get('doctrine')->getAliasNamespace($bundle) . '\\' . $entity; |
|
272 | 15 | $metadata = $this->getEntityMetadata($entityClass); |
|
273 | 15 | } catch (Exception $e) { |
|
274 | throw new RuntimeException(sprintf('Entity "%s" does not exist in the "%s" bundle. Create it with the "doctrine:generate:entity" command and then execute this command again.', $entity, $bundle)); |
||
275 | } |
||
276 | |||
277 | 15 | $bundle = $this->getContainer()->get('kernel')->getBundle($bundle); |
|
278 | |||
279 | |||
280 | 15 | $configBuilder = new ConfigurationBuilder(); |
|
281 | $configuration = $configBuilder |
||
282 | 15 | ->setBaseTemplate($template) |
|
283 | 15 | ->setBundleViews($bundleViews) |
|
284 | 15 | ->setFilterType($filterType) |
|
285 | 15 | ->setWithoutWrite($withoutWrite) |
|
286 | 15 | ->setWithoutBulk($withoutBulk) |
|
287 | 15 | ->setWithoutShow($withoutShow) |
|
288 | 15 | ->setWithoutSorting($withoutSorting) |
|
289 | 15 | ->setWithoutPageSize($withoutPageSize) |
|
290 | 15 | ->setOverwrite($forceOverwrite) |
|
291 | 15 | ->setFormat($format) |
|
292 | 15 | ->setRoutePrefix($prefix) |
|
293 | 15 | ->getConfiguration() |
|
294 | 15 | ; |
|
295 | 15 | $generator = $this->getGenerator($bundle); |
|
296 | |||
297 | 15 | $generator->generateCrud($bundle, $entity, $metadata[0], $configuration); |
|
298 | |||
299 | 15 | $output->writeln('Generating the CRUD code: <info>OK</info>'); |
|
300 | |||
301 | 15 | $errors = array(); |
|
302 | 15 | $runner = $questionHelper->getRunner($output, $errors); |
|
303 | |||
304 | // form |
||
305 | 15 | if ($withoutWrite === false) { |
|
306 | 13 | $this->generateForm($bundle, $entity, $metadata, $forceOverwrite); |
|
307 | 13 | $output->writeln('Generating the Form code: <info>OK</info>'); |
|
308 | 13 | } |
|
309 | |||
310 | 15 | if ($filterType !== self::FILTER_TYPE_NONE) { |
|
311 | |||
312 | 14 | $this->generateFilter($bundle, $entity, $metadata, $forceOverwrite, $filterType); |
|
313 | 14 | $output->writeln('Generating the Filter code: <info>OK</info>'); |
|
314 | 14 | } |
|
315 | // routing |
||
316 | 15 | $output->write('Updating the routing: '); |
|
317 | 15 | if ('annotation' != $format) { |
|
318 | 4 | $runner($this->updateRouting($questionHelper, $input, $output, $bundle, $format, $entity, $prefix)); |
|
319 | 4 | } else { |
|
320 | 11 | $runner($this->updateAnnotationRouting($bundle, $entity, $prefix)); |
|
321 | } |
||
322 | |||
323 | 15 | $questionHelper->writeGeneratorSummary($output, $errors); |
|
324 | 15 | } |
|
325 | |||
326 | /** |
||
327 | * Tries to generate filtlers if they don't exist yet and if we need write operations on entities. |
||
328 | * @param string $entity |
||
329 | */ |
||
330 | 14 | protected function generateFilter($bundle, $entity, $metadata, $forceOverwrite = false, $type = self::FILTER_TYPE_INPUT) |
|
331 | { |
||
332 | 14 | $this->getFilterGenerator($bundle)->generate($bundle, $entity, $metadata[0], $forceOverwrite, $type); |
|
333 | 14 | } |
|
334 | |||
335 | 14 | View Code Duplication | protected function getFilterGenerator($bundle = 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. ![]() |
|||
336 | { |
||
337 | 14 | if (null === $this->filterGenerator) { |
|
338 | $metadataGuesser = new MetadataGuesser(new DisconnectedMetadataFactory($this->getContainer()->get('doctrine'))); |
||
339 | $this->filterGenerator = new PetkoparaFilterGenerator($metadataGuesser); |
||
340 | $this->filterGenerator->setSkeletonDirs($this->getSkeletonDirs($bundle)); |
||
341 | } |
||
342 | |||
343 | 14 | return $this->filterGenerator; |
|
344 | } |
||
345 | |||
346 | 13 | View Code Duplication | protected function getFormGenerator($bundle = 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. ![]() |
|||
347 | { |
||
348 | 13 | if (null === $this->formGenerator) { |
|
349 | $metadataGuesser = new MetadataGuesser(new DisconnectedMetadataFactory($this->getContainer()->get('doctrine'))); |
||
350 | $this->formGenerator = new PetkoparaFormGenerator($metadataGuesser); |
||
351 | $this->formGenerator->setSkeletonDirs($this->getSkeletonDirs($bundle)); |
||
352 | } |
||
353 | |||
354 | 13 | return $this->formGenerator; |
|
355 | } |
||
356 | |||
357 | 15 | public function setFilterGenerator(PetkoparaFilterGenerator $filterGenerator) |
|
358 | { |
||
359 | 15 | $this->filterGenerator = $filterGenerator; |
|
360 | 15 | } |
|
361 | |||
362 | 15 | public function setFormCrudGenerator(PetkoparaFormGenerator $formGenerator) |
|
363 | { |
||
364 | 15 | $this->formGenerator = $formGenerator; |
|
365 | 15 | } |
|
366 | |||
367 | } |
||
368 |
Let’s take a look at an example:
In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.
Available Fixes
Change the type-hint for the parameter:
Add an additional type-check:
Add the method to the interface: