Completed
Push — master ( 9919f9...1d1ba6 )
by Anton
09:31
created

CrudCommand   A

Complexity

Total Complexity 15

Size/Duplication

Total Lines 155
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 10

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 15
lcom 2
cbo 10
dl 0
loc 155
ccs 40
cts 40
cp 1
rs 10
c 0
b 0
f 0

4 Methods

Rating   Name   Duplication   Size   Complexity  
A configure() 0 16 1
B execute() 0 42 6
B generate() 0 57 5
A verify() 0 14 3
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\Generate
20
 */
21
class CrudCommand extends AbstractGenerateCommand
22
{
23
    /**
24
     * Command configuration
25
     */
26 14
    protected function configure()
27
    {
28
        $this
29
            // the name of the command (the part after "bin/bluzman")
30 14
            ->setName('generate:crud')
31
            // the short description shown while running "php bin/bluzman list"
32 14
            ->setDescription('Generate a CRUD for model')
33
            // the full command description shown when running the command with
34
            // the "--help" option
35 14
            ->setHelp('This command allows you to generate CRUD files');
36
37
        $this
38 14
            ->addModelArgument()
39 14
            ->addModuleArgument(InputArgument::OPTIONAL)
40
        ;
41 14
    }
42
43
    /**
44
     * @param InputInterface $input
45
     * @param OutputInterface $output
46
     * @return void
47
     */
48 3
    protected function execute(InputInterface $input, OutputInterface $output)
49
    {
50
        try {
51 3
            $this->write("Running <info>generate:crud</info> command");
52
53 3
            $model = $input->getArgument('model');
54 3
            $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...
55
56 1
            if (!$this->getApplication()->isModelExists($model)) {
57
                throw new InputException(
58
                    "Model $model is not exist, " .
59
                    "run command <question>bluzman generate:model $model</question> before"
60
                );
61
            }
62
63 1
            if ($module = $input->getArgument('module')) {
64
                $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...
65
66
                if (!$this->getApplication()->isModuleExists($module)) {
67
                    throw new InputException(
68
                        "Module $module is not exist, " .
69
                        "run command <question>bluzman generate:module $module</question> before"
70
                    );
71
                }
72
            }
73
74
            // generate directories and files
75 1
            $this->generate($input, $output);
76
77
            // verify it
78 1
            $this->verify($input, $output);
79
80 1
            $this->write("CRUD for <info>{$model}</info> has been successfully created.");
81 1
            if ($module = $input->getArgument('module')) {
82
                $this->write(
83 1
                    "Open page <info>/acl</info> in your browser and set permissions for <info>{$module}</info>"
84
                );
85
            }
86 2
        } catch (InputException $e) {
87 2
            $this->error("ERROR: {$e->getMessage()}");
88
        }
89 3
    }
90
91
    /**
92
     * @param InputInterface $input
93
     * @param OutputInterface $output
94
     * @return void
95
     * @throws InputException
96
     */
97 1
    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...
98
    {
99 1
        $model = ucfirst($input->getArgument('model'));
100
101
        // generate CRUD
102 1
        $crudFile = $this->getApplication()->getModelPath($model) . DS . 'Crud.php';
103
104 1
        if (file_exists($crudFile)) {
105
            $this->comment("Crud file <info>$model/Crud.php</info> already exists");
106
        } else {
107 1
            $template = $this->getTemplate('CrudTemplate');
108 1
            $template->setFilePath($crudFile);
109 1
            $template->setTemplateData(
110
                [
111 1
                    'model' => $model
112
                ]
113
            );
114
115 1
            $generator = new Generator\Generator($template);
116 1
            $generator->make();
117
        }
118
119 1
        if ($module = $input->getArgument('module')) {
120
            $this->write("Generate <info>$module/controllers/crud.php</info>");
121
122
            $controllerFile = $this->getControllerPath($module, 'crud');
123
            if (file_exists($controllerFile)) {
124
                $this->comment("Controller file <info>$module/crud</info> already exists");
125
            } else {
126
                $template = new Generator\Template\CrudControllerTemplate();
127
                $template->setFilePath($controllerFile);
128
                $template->setTemplateData(['model' => $model]);
129
130
                $generator = new Generator\Generator($template);
131
                $generator->make();
132
            }
133
134
            $this->write("Generate <info>$module/views/crud.phtml</info>");
135
136
            $viewFile = $this->getViewPath($module, 'crud');
137
            if (file_exists($viewFile)) {
138
                $this->comment("View file <info>$module/crud</info> already exists");
139
            } else {
140
                $template = new Generator\Template\CrudViewTemplate();
141
                $template->setFilePath($viewFile);
142
                $template->setTemplateData(
143
                    [
144
                        'model' => $model,
145
                        'module' => $module
146
                    ]
147
                );
148
149
                $generator = new Generator\Generator($template);
150
                $generator->make();
151
            }
152
        }
153 1
    }
154
155
    /**
156
     * @param InputInterface $input
157
     * @param OutputInterface $output
158
     * @return void
159
     * @throws \Bluzman\Generator\GeneratorException
160
     */
161 1
    public function verify(InputInterface $input, OutputInterface $output)
162
    {
163 1
        $modelPath = $this->getApplication()->getModelPath($input->getArgument('model'));
164
165
        $paths = [
166 1
            $modelPath . DS . 'Crud.php',
167
        ];
168
169 1
        foreach ($paths as $path) {
170 1
            if (!$this->getFs()->exists($path)) {
171 1
                throw new Generator\GeneratorException("File `$path` is not exists");
172
            }
173
        }
174 1
    }
175
}
176