Completed
Push — master ( 550846...8c8483 )
by Anton
09:53
created

GridCommand::execute()   B

Complexity

Conditions 6
Paths 23

Size

Total Lines 41
Code Lines 23

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 41
rs 8.439
c 0
b 0
f 0
cc 6
eloc 23
nc 23
nop 2
1
<?php
2
/**
3
 * @copyright Bluz PHP Team
4
 * @link https://github.com/bluzphp/bluzman
5
 */
6
7
namespace Bluzman\Command\Generate;
8
9
use Bluz\Validator\Validator as v;
10
use Bluzman\Input\InputArgument;
11
use Bluzman\Input\InputException;
12
use Bluzman\Generator;
13
use Symfony\Component\Console\Input\InputInterface;
14
use Symfony\Component\Console\Output\OutputInterface;
15
16
/**
17
 * ModelCommand
18
 *
19
 * @package  Bluzman\Command
20
 */
21
class GridCommand extends AbstractGenerateCommand
22
{
23
    /**
24
     * Command configuration
25
     */
26
    protected function configure()
27
    {
28
        $this
29
            // the name of the command (the part after "bin/bluzman")
30
            ->setName('generate:grid')
31
            // the short description shown while running "php bin/bluzman list"
32
            ->setDescription('Generate a GRID for model')
33
            // the full command description shown when running the command with
34
            // the "--help" option
35
            ->setHelp('This command allows you to generate GRID files')
36
        ;
37
38
        $this->addModelArgument();
39
40
        $module = new InputArgument(
41
            'module',
42
            InputArgument::OPTIONAL,
43
            'Module name, if you need to generate `view` controller and view'
44
        );
45
46
        $module->setValidator(
47
            v::string()->alphaNumeric('-_')->noWhitespace()
48
        );
49
50
51
        $this->getDefinition()->addArgument($module);
52
    }
53
54
    /**
55
     * @param InputInterface $input
56
     * @param OutputInterface $output
57
     * @return void
58
     */
59
    protected function execute(InputInterface $input, OutputInterface $output)
60
    {
61
        try {
62
            $this->write("Running <info>generate:grid</info> command");
63
64
            $model = $input->getArgument('model');
65
            $this->getDefinition()->getArgument('model')->validate($model);
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class Symfony\Component\Console\Input\InputArgument as the method validate() does only exist in the following sub-classes of Symfony\Component\Console\Input\InputArgument: Bluzman\Input\InputArgument. 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...
66
67
            if (!$this->getApplication()->isModelExists($model)) {
68
                throw new InputException(
69
                    "Model $model is not exist, ".
70
                    "run command <question>bluzman generate:model $model</question> before");
71
            }
72
73
            if ($module = $input->getArgument('module')) {
74
                $this->getDefinition()->getArgument('module')->validate($module);
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class Symfony\Component\Console\Input\InputArgument as the method validate() does only exist in the following sub-classes of Symfony\Component\Console\Input\InputArgument: Bluzman\Input\InputArgument. 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...
75
76
                if (!$this->getApplication()->isModuleExists($module)) {
77
                    throw new InputException(
78
                        "Module $module is not exist, ".
79
                        "run command <question>bluzman generate:module $module</question> before");
80
                }
81
            }
82
83
            // generate directories and files
84
            $this->generate($input, $output);
85
86
            // verify it
87
            $this->verify($input, $output);
88
89
            $this->write("GRID for <info>{$model}</info> has been successfully created.");
90
91
            if ($module = $input->getArgument('module')) {
92
                $this->write(
93
                    "Open page <info>/acl</info> in your browser and set permissions for <info>{$module}</info>"
94
                );
95
            }
96
        } catch (InputException $e) {
97
            $this->error("ERROR: {$e->getMessage()}");
98
        }
99
    }
100
101
    /**
102
     * @param InputInterface $input
103
     * @param OutputInterface $output
104
     * @return void
105
     * @throws InputException
106
     */
107
    protected function generate(InputInterface $input, OutputInterface $output)
0 ignored issues
show
Unused Code introduced by
The parameter $output is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
108
    {
109
        $model = ucfirst($input->getArgument('model'));
110
111
        // generate CRUD
112
        $crudFile = $this->getApplication()->getModelPath($model) .DS. 'Grid.php';
113
114
        if (file_exists($crudFile)) {
115
            $this->comment("Crud file <info>$model/Grid.php</info> already exists");
116
        } else {
117
            $template = $this->getTemplate('GridTemplate');
118
            $template->setFilePath($crudFile);
119
            $template->setTemplateData([
120
                'model' => $model
121
            ]);
122
123
            $generator = new Generator\Generator($template);
124
            $generator->make();
125
        }
126
127
        if ($module = $input->getArgument('module')) {
128
            $this->write("Generate <info>$module/controllers/grid.php</info>");
129
130
            $controllerFile = $this->getControllerPath($module, 'grid');
131
            if (file_exists($controllerFile)) {
132
                $this->comment("Controller file <info>$module/grid</info> already exists");
133
            } else {
134
                $template = new Generator\Template\GridControllerTemplate();
135
                $template->setFilePath($controllerFile);
136
                $template->setTemplateData(['model' => $model]);
137
138
                $generator = new Generator\Generator($template);
139
                $generator->make();
140
            }
141
142
            $this->write("Generate <info>$module/views/grid.phtml</info>");
143
144
            $viewFile = $this->getViewPath($module, 'grid');
145
            if (file_exists($viewFile)) {
146
                $this->comment("View file <info>$module/grid</info> already exists");
147
            } else {
148
                $template = new Generator\Template\GridViewTemplate();
149
                $template->setFilePath($viewFile);
150
                $template->setTemplateData(['model' => $model]);
151
152
                $generator = new Generator\Generator($template);
153
                $generator->make();
154
            }
155
        }
156
    }
157
158
    /**
159
     * @param InputInterface $input
160
     * @param OutputInterface $output
161
     * @return void
162
     * @throws \Bluzman\Generator\GeneratorException
163
     */
164
    public function verify(InputInterface $input, OutputInterface $output)
165
    {
166
        $modelPath = $this->getApplication()->getModelPath($input->getArgument('model'));
167
168
        $paths = [
169
            $modelPath . DS . 'Grid.php',
170
        ];
171
172
        foreach ($paths as $path) {
173
            if (!$this->getFs()->exists($path)) {
174
                throw new Generator\GeneratorException("File `$path` is not exists");
175
            }
176
        }
177
    }
178
}
179