GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Branch master (c6c701)
by Petko
30:18 queued 26:36
created

CrudGeneratorCommand::interact()   B

Complexity

Conditions 6
Paths 8

Size

Total Lines 114
Code Lines 79

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 84
CRAP Score 6.0014

Importance

Changes 0
Metric Value
dl 0
loc 114
ccs 84
cts 87
cp 0.9655
rs 8.1463
c 0
b 0
f 0
cc 6
eloc 79
nc 8
nop 2
crap 6.0014

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/*
4
 * This file is part of the CrudBundle
5
 *
6
 * It is based/extended from SensioGeneratorBundle
7
 *
8
 * (c) Petko Petkov <[email protected]>
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
namespace Petkopara\CrudGeneratorBundle\Command;
15
16
use Doctrine\Bundle\DoctrineBundle\Mapping\DisconnectedMetadataFactory;
17
use Petkopara\CrudGeneratorBundle\Configuration\ConfigurationBuilder;
18
use Petkopara\CrudGeneratorBundle\Generator\Guesser\MetadataGuesser;
19
use Petkopara\CrudGeneratorBundle\Generator\PetkoparaCrudGenerator;
20
use Petkopara\CrudGeneratorBundle\Generator\PetkoparaFilterGenerator;
21
use Petkopara\CrudGeneratorBundle\Generator\PetkoparaFormGenerator;
22
use Sensio\Bundle\GeneratorBundle\Command\AutoComplete\EntitiesAutoCompleter;
23
use Sensio\Bundle\GeneratorBundle\Command\GenerateDoctrineCrudCommand;
24
use Sensio\Bundle\GeneratorBundle\Command\Validators;
25
use Symfony\Component\Config\Definition\Exception\Exception;
26
use Symfony\Component\Console\Input\InputArgument;
27
use Symfony\Component\Console\Input\InputInterface;
28
use Symfony\Component\Console\Input\InputOption;
29
use Symfony\Component\Console\Output\OutputInterface;
30
use Symfony\Component\Console\Question\ConfirmationQuestion;
31
use Symfony\Component\Console\Question\Question;
32
use Symfony\Component\HttpKernel\Bundle\BundleInterface;
33
use Symfony\Component\Yaml\Exception\RuntimeException;
34
35
class CrudGeneratorCommand extends GenerateDoctrineCrudCommand
36
{
37
38
    const FILTER_TYPE_FORM = 'form';
39
    const FILTER_TYPE_INPUT = 'input';
40
    const FILTER_TYPE_NONE = 'none';
41
42
    protected $generator;
43
    protected $formGenerator;
44
    private $filterGenerator;
45
46 15
    protected function configure()
47
    {
48
49 15
        $this
50 15
                ->setName('petkopara:generate:crud')
51 15
                ->setDescription('A CRUD generator with pagination, filters, bulk delete and bootstrap markdown.')
52 15
                ->setDefinition(array(
53 15
                    new InputArgument('entity', InputArgument::OPTIONAL, 'The entity class name to initialize (shortcut notation)'),
54 15
                    new InputOption('entity', '', InputOption::VALUE_REQUIRED, 'The entity class name to initialize (shortcut notation)'),
55 15
                    new InputOption('route-prefix', 'r', InputOption::VALUE_REQUIRED, 'The route prefix'),
56 15
                    new InputOption('template', 't', InputOption::VALUE_REQUIRED, 'The base template which will be extended by the templates', 'PetkoparaCrudGeneratorBundle::base.html.twig'),
57 15
                    new InputOption('format', 'f', InputOption::VALUE_REQUIRED, 'The format used for configuration files (php, xml, yml, or annotation)', 'annotation'),
58 15
                    new InputOption('overwrite', 'o', InputOption::VALUE_NONE, 'Overwrite any existing controller or form class when generating the CRUD contents'),
59 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'),
60 15
                    new InputOption('without-sorting', 'wsr', InputOption::VALUE_NONE, 'Whether or not have sorting in the index'),
61 15
                    new InputOption('without-page-size', 'wps', InputOption::VALUE_NONE, 'Whether or not to show items per page select in the index'),
62 15
                    new InputOption('without-write', 'ww', InputOption::VALUE_NONE, 'Whether or not to generate create, new and delete actions'),
63 15
                    new InputOption('without-show', 'ws', InputOption::VALUE_NONE, 'Whether or not to generate create, new and delete actions'),
64 15
                    new InputOption('without-bulk', 'wb', InputOption::VALUE_NONE, 'Whether or not to generate bulk actions'),
65 15
                    new InputOption('filter-type', 'ft', InputOption::VALUE_REQUIRED, 'What type of filtrations to be used. Multi search input, Form filter or none', 'input'),
66 15
                ))
67 15
                ->setHelp(<<<EOT
68
The <info>%command.name%</info> command generates a CRUD based on a Doctrine entity.
69
70
The default command only generates the list and show actions.
71
72
<info>php %command.full_name% --entity=AcmeBlogBundle:Post --route-prefix=post_admin</info>
73
74
Using the --without-write to not generate the new, edit, bulk and delete actions.
75
                
76
Using the --bundle-views option store the view files in the bundles dir.
77
                
78
Using the --without-bulk  use this option tp not generate bulk actions code.
79
                
80
Using the --template option allows to set base template from which the crud views to overide.
81
                
82
<info>php %command.full_name% doctrine:generate:crud --entity=AcmeBlogBundle:Post --route-prefix=post_admin </info>
83
84
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:
85
86
<info>BUNDLE_PATH/Resources/CrudGeneratorBundle/skeleton/crud
87
APP_PATH/Resources/CrudGeneratorBundle/skeleton/crud</info>
88
89
And
90
91
<info>__bundle_path__/Resources/CrudGeneratorBundle/skeleton/form
92
__project_root__/app/Resources/CrudGeneratorBundle/skeleton/form</info>
93
94
EOT
95 15
        );
96 15
    }
97
98
    protected function createGenerator($bundle = null)
99
    {
100
        return new PetkoparaCrudGenerator($this->getContainer()->get('filesystem'), $this->getContainer()->getParameter('kernel.root_dir'));
101
    }
102
103
    protected function getSkeletonDirs(BundleInterface $bundle = null)
104
    {
105
        $skeletonDirs = array();
106
        if (isset($bundle) && is_dir($dir = $bundle->getPath() . '/Resources/PetkoparaCrudGeneratorBundle/skeleton')) {
107
            $skeletonDirs[] = $dir;
108
        }
109
110
        if (is_dir($dir = $this->getContainer()->get('kernel')->getRootdir() . '/Resources/PetkoparaCrudGeneratorBundle/skeleton')) {
111
            $skeletonDirs[] = $dir;
112
        }
113
114
        $skeletonDirs[] = $this->getContainer()->get('kernel')->locateResource('@PetkoparaCrudGeneratorBundle/Resources/skeleton');
115
        $skeletonDirs[] = $this->getContainer()->get('kernel')->locateResource('@PetkoparaCrudGeneratorBundle/Resources');
116
117
        return $skeletonDirs;
118
    }
119
120 11
    protected function interact(InputInterface $input, OutputInterface $output)
121
    {
122
123 11
        $questionHelper = $this->getQuestionHelper();
124 11
        $questionHelper->writeSection($output, 'Welcome to the Petkopara CRUD generator');
125
126
        // namespace
127 11
        $output->writeln(array(
128 11
            '',
129 11
            'This command helps you generate CRUD controllers and templates.',
130 11
            '',
131 11
            'First, give the name of the existing entity for which you want to generate a CRUD',
132 11
            '(use the shortcut notation like <comment>AcmeBlogBundle:Post</comment>)',
133 11
            '',
134 11
        ));
135
136 11
        if ($input->hasArgument('entity') && $input->getArgument('entity') != '') {
137
            $input->setOption('entity', $input->getArgument('entity'));
138
        }
139
140 11
        $question = new Question($questionHelper->getQuestion('The Entity shortcut name', $input->getOption('entity')), $input->getOption('entity'));
141 11
        $question->setValidator(array('Sensio\Bundle\GeneratorBundle\Command\Validators', 'validateEntityName'));
142
143
144 11
        $autocompleter = new EntitiesAutoCompleter($this->getContainer()->get('doctrine')->getManager());
145 11
        $autocompleteEntities = $autocompleter->getSuggestions();
146 11
        $question->setAutocompleterValues($autocompleteEntities);
147 11
        $entity = $questionHelper->ask($input, $output, $question);
148
149 11
        $input->setOption('entity', $entity);
150 11
        list($bundle, $entity) = $this->parseShortcutNotation($entity);
151
152
        try {
153 11
            $entityClass = $this->getContainer()->get('doctrine')->getAliasNamespace($bundle) . '\\' . $entity;
154 11
            $this->getEntityMetadata($entityClass);
155 11
        } catch (\Exception $e) {
156
            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));
157
        }
158
159
        // write?
160 11
        $withoutWrite = $input->getOption('without-write') ? true : false; //default false
161
162 11
        $output->writeln(array(
163 11
            '',
164 11
            'By default, the generator creates all actions: list and show, new, update, and delete.',
165 11
            'You can also ask it to generate only "list and show" actions:',
166 11
            '',
167 11
        ));
168 11
        $question = new ConfirmationQuestion($questionHelper->getQuestion('Do you want to generate the "write" actions', $withoutWrite ? 'no' : 'yes', '?', $withoutWrite), $withoutWrite);
169 11
        $withoutWrite = $questionHelper->ask($input, $output, $question);
170 11
        $input->setOption('without-write', $withoutWrite);
171
172
        // filters?
173 11
        $filterType = $input->getOption('filter-type');
174 11
        $output->writeln(array(
175 11
            '',
176 11
            'By default, the generator creates filter',
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
Bug introduced by
It seems like you code against a concrete implementation and not the interface Symfony\Component\Console\Helper\HelperInterface as the method formatBlock() does only exist in the following implementations of said interface: Symfony\Component\Console\Helper\FormatterHelper.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

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

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
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('base template "<info>%s</info>".', $template),
229 11
            sprintf('without write "<info>%s</info>".', $withoutWrite),
230 11
            sprintf('Filters "<info>%s</info>".', $filterType),
231 11
            '',
232 11
        ));
233 11
    }
234
235
    /**
236
     * @see Command
237
     */
238 15
    protected function execute(InputInterface $input, OutputInterface $output)
239
    {
240 15
        $questionHelper = $this->getQuestionHelper();
241
242 15
        if ($input->isInteractive()) {
243 11
            $question = new ConfirmationQuestion($questionHelper->getQuestion('Do you confirm generation', 'yes', '?'), true);
244 11
            if (!$questionHelper->ask($input, $output, $question)) {
245
                $output->writeln('<error>Command aborted</error>');
246
                return 1;
247
            }
248 11
        }
249
250 15
        $entity = Validators::validateEntityName($input->getOption('entity'));
251 15
        list($bundle, $entity) = $this->parseShortcutNotation($entity);
252
253
        //get the options
254 15
        $format = Validators::validateFormat($input->getOption('format'));
255 15
        $prefix = $this->getRoutePrefix($input, $entity);
256 15
        $withoutWrite = $input->getOption('without-write'); //default with write
257 15
        $filterType = CrudValidators::validateFilterType($input->getOption('filter-type'));
258 15
        $withoutBulk = $input->getOption('without-bulk');
259 15
        $withoutShow = $input->getOption('without-show');
260 15
        $withoutSorting = $input->getOption('without-sorting');
261 15
        $withoutPageSize = $input->getOption('without-page-size');
262 15
        $bundleViews = $input->getOption('bundle-views');
263 15
        $template = $input->getOption('template');
264
265 15
        $forceOverwrite = $input->getOption('overwrite');
266
267 15
        $questionHelper->writeSection($output, 'CRUD generation');
268
269
        try {
270 15
            $entityClass = $this->getContainer()->get('doctrine')->getAliasNamespace($bundle) . '\\' . $entity;
271 15
            $metadata = $this->getEntityMetadata($entityClass);
272 15
        } catch (Exception $e) {
273
            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));
274
        }
275
276 15
        $bundle = $this->getContainer()->get('kernel')->getBundle($bundle);
277
278
279 15
        $configBuilder = new ConfigurationBuilder();
280
        $configuration = $configBuilder
281 15
                ->setBaseTemplate($template)
282 15
                ->setBundleViews($bundleViews)
283 15
                ->setFilterType($filterType)
284 15
                ->setWithoutBulk($withoutBulk)
285 15
                ->setWithoutShow($withoutShow)
286 15
                ->setWithoutWrite($withoutWrite)
287 15
                ->setWithoutSorting($withoutSorting)
288 15
                ->setWithoutPageSize($withoutPageSize)
289 15
                ->setOverwrite($forceOverwrite)
290 15
                ->setFormat($format)
291 15
                ->setRoutePrefix($prefix)
292 15
                ->getConfiguration()
293 15
        ;
294 15
        $generator = $this->getGenerator($bundle);
295
296 15
        $generator->generateCrud($bundle, $entity, $metadata[0], $configuration);
297
298 15
        $output->writeln('Generating the CRUD code: <info>OK</info>');
299
300 15
        $errors = array();
301 15
        $runner = $questionHelper->getRunner($output, $errors);
302
303
        // form
304 15
        if ($withoutWrite === false) {
305 13
            $this->generateForm($bundle, $entity, $metadata, $forceOverwrite);
306 13
            $output->writeln('Generating the Form code: <info>OK</info>');
307 13
        }
308
309 15
        if ($filterType !== self::FILTER_TYPE_NONE) {
310
311 14
            $this->generateFilter($bundle, $entity, $metadata, $forceOverwrite, $filterType);
312 14
            $output->writeln('Generating the Filter code: <info>OK</info>');
313 14
        }
314
        // routing
315 15
        $output->write('Updating the routing: ');
316 15
        if ('annotation' != $format) {
317 4
            $runner($this->updateRouting($questionHelper, $input, $output, $bundle, $format, $entity, $prefix));
318 4
        } else {
319 11
            $runner($this->updateAnnotationRouting($bundle, $entity, $prefix));
320
        }
321
322 15
        $questionHelper->writeGeneratorSummary($output, $errors);
323 15
    }
324
325
    /**
326
     * Tries to generate filtlers if they don't exist yet and if we need write operations on entities.
327
     * @param string $entity
328
     */
329 14
    protected function generateFilter($bundle, $entity, $metadata, $forceOverwrite = false, $type = self::FILTER_TYPE_INPUT)
330
    {
331 14
        $this->getFilterGenerator($bundle)->generate($bundle, $entity, $metadata[0], $forceOverwrite, $type);
332 14
    }
333
334 14 View Code Duplication
    protected function getFilterGenerator($bundle = null)
0 ignored issues
show
Duplication introduced by
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.

Loading history...
335
    {
336 14
        if (null === $this->filterGenerator) {
337
            $metadataGuesser = new MetadataGuesser(new DisconnectedMetadataFactory($this->getContainer()->get('doctrine')));
338
            $this->filterGenerator = new PetkoparaFilterGenerator($metadataGuesser);
339
            $this->filterGenerator->setSkeletonDirs($this->getSkeletonDirs($bundle));
340
        }
341
342 14
        return $this->filterGenerator;
343
    }
344
345 13 View Code Duplication
    protected function getFormGenerator($bundle = null)
0 ignored issues
show
Duplication introduced by
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.

Loading history...
346
    {
347 13
        if (null === $this->formGenerator) {
348
            $metadataGuesser = new MetadataGuesser(new DisconnectedMetadataFactory($this->getContainer()->get('doctrine')));
349
            $this->formGenerator = new PetkoparaFormGenerator($metadataGuesser);
350
            $this->formGenerator->setSkeletonDirs($this->getSkeletonDirs($bundle));
351
        }
352
353 13
        return $this->formGenerator;
354
    }
355
356 15
    public function setFilterGenerator(PetkoparaFilterGenerator $filterGenerator)
357
    {
358 15
        $this->filterGenerator = $filterGenerator;
359 15
    }
360
361 15
    public function setFormCrudGenerator(PetkoparaFormGenerator $formGenerator)
362
    {
363 15
        $this->formGenerator = $formGenerator;
364 15
    }
365
366
}
367