Completed
Push — master ( 91fdab...75a7b9 )
by
unknown
13:37
created

Command/GenerateAdminListCommand.php (1 issue)

Upgrade to new PHP Analysis Engine

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 Kunstmaan\GeneratorBundle\Command;
4
5
use Kunstmaan\GeneratorBundle\Generator\AdminListGenerator;
6
use Kunstmaan\GeneratorBundle\Helper\GeneratorUtils;
7
use Sensio\Bundle\GeneratorBundle\Command\GenerateDoctrineCommand;
8
use Sensio\Bundle\GeneratorBundle\Command\Helper\QuestionHelper;
9
use Sensio\Bundle\GeneratorBundle\Command\Validators;
10
use Symfony\Component\Console\Input\InputInterface;
11
use Symfony\Component\Console\Input\InputOption;
12
use Symfony\Component\Console\Output\OutputInterface;
13
use Symfony\Component\Console\Question\ConfirmationQuestion;
14
use Symfony\Component\Console\Question\Question;
15
use Symfony\Component\HttpKernel\Bundle\Bundle;
16
17
/**
18
 * Generates a KunstmaanAdminList
19
 */
20
class GenerateAdminListCommand extends GenerateDoctrineCommand
21
{
22
    /**
23
     * @see Command
24
     */
25
    protected function configure()
26
    {
27
        $this
28
            ->setDefinition(
29
                array(
30
                    new InputOption(
31
                        'entity',
32
                        '',
33
                        InputOption::VALUE_REQUIRED,
34
                        'The entity class name to create an admin list for (shortcut notation)'
35
                    ),
36
                    new InputOption(
37
                        'sortfield',
38
                        '',
39
                        InputOption::VALUE_OPTIONAL,
40
                        'The name of the sort field if entity needs to be sortable'
41
                    ),
42
                )
43
            )
44
            ->setDescription('Generates a KunstmaanAdminList')
45
            ->setHelp(
46
                <<<EOT
47
                The <info>kuma:generate:adminlist</info> command generates an AdminList for a Doctrine ORM entity.
48
49
<info>php bin/console kuma:generate:adminlist Bundle:Entity</info>
50
EOT
51
            )
52
            ->setName('kuma:generate:adminlist');
53
    }
54
55
    /**
56
     * Executes the command.
57
     *
58
     * @param InputInterface  $input  An InputInterface instance
59
     * @param OutputInterface $output An OutputInterface instance
60
     *
61
     * @throws \RuntimeException
62
     * @return int|null|void
63
     */
64
    protected function execute(InputInterface $input, OutputInterface $output)
65
    {
66
        $questionHelper = $this->getQuestionHelper();
67
68
        GeneratorUtils::ensureOptionsProvided($input, array('entity'));
69
70
        $entity = Validators::validateEntityName($input->getOption('entity'));
71
        list($bundle, $entity) = $this->parseShortcutNotation($entity);
72
73
        $entityClass = $this->getContainer()->get('doctrine')->getAliasNamespace($bundle) . '\\' . $entity;
74
        $metadata    = $this->getEntityMetadata($entityClass);
75
        $bundle      = $this->getContainer()->get('kernel')->getBundle($bundle);
76
77
        $questionHelper->writeSection($output, 'AdminList Generation');
78
79
        $generator = $this->getGenerator($this->getApplication()->getKernel()->getBundle("KunstmaanGeneratorBundle"));
0 ignored issues
show
It seems like you code against a specific sub-type and not the parent class Symfony\Component\Console\Application as the method getKernel() does only exist in the following sub-classes of Symfony\Component\Console\Application: Symfony\Bundle\FrameworkBundle\Console\Application. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

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

class MyUser extends 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 sub-classes 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 parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
80
        $generator->setQuestion($questionHelper);
81
        $generator->generate($bundle, $entityClass, $metadata[0], $output, $input->getOption('sortfield'));
82
83
84
        $parts       = explode('\\', $entity);
85
        $entityClass = array_pop($parts);
86
87
        $this->updateRouting($questionHelper, $input, $output, $bundle, $entityClass);
88
    }
89
90
    /**
91
     * Interacts with the user.
92
     *
93
     * @param InputInterface  $input  An InputInterface instance
94
     * @param OutputInterface $output An OutputInterface instance
95
     */
96
    protected function interact(InputInterface $input, OutputInterface $output)
97
    {
98
        $questionHelper = $this->getQuestionHelper();
99
        $questionHelper->writeSection($output, 'Welcome to the Kunstmaan admin list generator');
100
101
        // entity
102
        $entity = null;
103
        try {
104
            $entity = $input->getOption('entity') ? Validators::validateEntityName($input->getOption('entity')) : null;
105
        } catch (\Exception $error) {
106
            $output->writeln(
107
                $questionHelper->getHelperSet()->get('formatter')->formatBlock($error->getMessage(), 'error')
108
            );
109
        }
110
111
        if (is_null($entity)) {
112
            $output->writeln(
113
                array(
114
                    '',
115
                    'This command helps you to generate an admin list for your entity.',
116
                    '',
117
                    'You must use the shortcut notation like <comment>AcmeBlogBundle:Post</comment>.',
118
                    '',
119
                )
120
            );
121
122
            $question = new Question($questionHelper->getQuestion('The entity shortcut name', $entity), $entity);
123
            $question->setValidator(array('Sensio\Bundle\GeneratorBundle\Command\Validators', 'validateEntityName'));
124
            $entity = $questionHelper->ask($input, $output, $question);
125
            $input->setOption('entity', $entity);
126
127
            $question = new Question($questionHelper->getQuestion('The name of the sort field if entity needs to be sortable', false, '?'), false);
128
            $sortfield = $questionHelper->ask($input, $output, $question);
129
            $input->setOption('sortfield', $sortfield);
130
        }
131
    }
132
133
    /**
134
     * @param QuestionHelper  $questionHelper The question helper
135
     * @param InputInterface  $input          The command input
136
     * @param OutputInterface $output         The command output
137
     * @param Bundle          $bundle         The bundle
138
     * @param string          $entityClass    The classname of the entity
139
     *
140
     * @return void
141
     */
142
    protected function updateRouting(
143
        QuestionHelper $questionHelper,
144
        InputInterface $input,
145
        OutputInterface $output,
146
        Bundle $bundle,
147
        $entityClass
148
    ) {
149
        $adminKey = $this->getContainer()->getParameter('kunstmaan_admin.admin_prefix');
150
        $auto      = true;
151
        $multilang = false;
152
        if ($input->isInteractive()) {
153
            $confirmationQuestion = new ConfirmationQuestion(
154
                $questionHelper->getQuestion('Is it a multilanguage site', 'yes', '?'), true
155
            );
156
            $multilang            = $questionHelper->ask($input, $output, $confirmationQuestion);
157
            $confirmationQuestion = new ConfirmationQuestion(
158
                $questionHelper->getQuestion('Do you want to update the routing automatically', 'yes', '?'), true
159
            );
160
            $auto                 = $questionHelper->ask($input, $output, $confirmationQuestion);
161
        }
162
163
        $prefix = $multilang ? '/{_locale}' : '';
164
165
        $code = sprintf("%s:\n", strtolower($bundle->getName()) . '_' . strtolower($entityClass) . '_admin_list');
166
        $code .= sprintf("    resource: '@%s/Controller/%sAdminListController.php'\n", $bundle->getName(), $entityClass, "'");
167
        $code .= "    type:     annotation\n";
168
        $code .= sprintf("    prefix:   %s/%s/%s/\n", $prefix, $adminKey, strtolower($entityClass));
169
        if ($multilang) {
170
            $code .= "    requirements:\n";
171
            $code .= "         _locale: \"%requiredlocales%\"\n";
172
        }
173
174
        if ($auto) {
175
            $file    = $bundle->getPath() . '/Resources/config/routing.yml';
176
            $content = '';
177
178
            if (file_exists($file)) {
179
                $content = file_get_contents($file);
180
            } elseif (!is_dir($dir = dirname($file))) {
181
                mkdir($dir, 0777, true);
182
            }
183
184
            $content .= "\n";
185
            $content .= $code;
186
187
            if (false === file_put_contents($file, $content)) {
188
                $output->writeln(
189
                    $questionHelper->getHelperSet()->get('formatter')->formatBlock(
190
                        "Failed adding the content automatically",
191
                        'error'
192
                    )
193
                );
194
            } else {
195
                return;
196
            }
197
        }
198
199
        $output->writeln('Add the following to your routing.yml');
200
        $output->writeln('/*******************************/');
201
        $output->write($code);
202
        $output->writeln('/*******************************/');
203
    }
204
205
    /**
206
     * KunstmaanTestBundle_TestEntity:
207
     * resource: "@KunstmaanTestBundle/Controller/TestEntityAdminListController.php"
208
     * type:     annotation
209
     * prefix:   /{_locale}/%kunstmaan_admin.admin_prefix%/testentity/
210
     * requirements:
211
     * _locale: "%requiredlocales%"
212
     */
213
    protected function createGenerator()
214
    {
215
        return new AdminListGenerator(GeneratorUtils::getFullSkeletonPath('adminlist'));
216
    }
217
}
218