Completed
Pull Request — master (#2262)
by
unknown
05:24
created

FormCommand::checkColumn()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
nc 3
nop 2
dl 0
loc 9
rs 9.9666
c 0
b 0
f 0
1
<?php
2
3
namespace Encore\Admin\Console;
4
5
use Illuminate\Console\Command;
6
use Symfony\Component\Console\Input\InputOption;
7
8
class FormCommand extends Command
9
{
10
    /**
11
     * The console command name.
12
     *
13
     * @var string
14
     */
15
    protected $name = 'admin:form';
16
17
    /**
18
     * The console command description.
19
     *
20
     * @var string
21
     */
22
    protected $description = 'laravel-admin form filed generator';
23
24
    /**
25
     * Execute the console command.
26
     *
27
     * @return bool
28
     */
29
    public function handle()
30
    {
31
        $modelName = $this->option('model');
32
        if (empty($modelName) || !class_exists($modelName)) {
33
            $this->error('Model does not exists !');
34
            return false;
35
        }
36
37
        // use doctrine/dbal
38
        $model = $this->laravel->make($modelName);
0 ignored issues
show
Bug introduced by
It seems like $modelName defined by $this->option('model') on line 31 can also be of type array; however, Illuminate\Contracts\Container\Container::make() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
39
        $table = $model->getConnection()->getTablePrefix() . $model->getTable();
40
        $schema = $model->getConnection()->getDoctrineSchemaManager($table);
41
42
        if (!method_exists($schema, 'getDatabasePlatform')) {
43
            $this->error('You need to require doctrine/dbal: ~2.3 in your own composer.json to get database columns. ');
44
            $this->info('Using install command: composer require doctrine/dbal');
45
            return false;
46
47
        }
48
49
        // custom mapping the types that doctrine/dbal does not support
50
        $databasePlatform = $schema->getDatabasePlatform();
51
        $databasePlatform->registerDoctrineTypeMapping('enum', 'string');
52
        $databasePlatform->registerDoctrineTypeMapping('geometry', 'string');
53
        $databasePlatform->registerDoctrineTypeMapping('geometrycollection', 'string');
54
        $databasePlatform->registerDoctrineTypeMapping('linestring', 'string');
55
        $databasePlatform->registerDoctrineTypeMapping('multilinestring', 'string');
56
        $databasePlatform->registerDoctrineTypeMapping('multipoint', 'string');
57
        $databasePlatform->registerDoctrineTypeMapping('multipolygon', 'string');
58
        $databasePlatform->registerDoctrineTypeMapping('point', 'string');
59
        $databasePlatform->registerDoctrineTypeMapping('polygon', 'string');
60
        $databasePlatform->registerDoctrineTypeMapping('multipolygon', 'string');
61
        $databasePlatform->registerDoctrineTypeMapping('multipolygon', 'string');
62
63
        $database = null;
64
        if (strpos($table, '.')) {
65
            list($database, $table) = explode('.', $table);
66
        }
67
        $columns = $schema->listTableColumns($table, $database);
68
69
        $adminForm = '';
70
        if ($columns) {
71
            foreach ($columns as $column) {
72
                $name = $column->getName();
73
                if (in_array($name, ['id', 'created_at', 'deleted_at'])) {
74
                    continue;
75
                }
76
                $type = $column->getType()->getName();
77
                $comment = $column->getComment();
78
                $default = $column->getDefault();
79
80
                switch ($type) {
81
                    case 'boolean':
82
                    case 'bool':
83
                        $fieldType = 'switch';
84
                        break;
85
                    case 'json':
86
                    case 'array':
87
                    case 'object':
88
                        $fieldType = 'text';
89
                        break;
90
                    case 'string':
91
                        switch ($name) {
92
                            case $this->checkColumn($name, ['email']):
93
                                $fieldType = 'email';
94
                                break;
95
                            case $this->checkColumn($name, ['password', 'pwd']):
96
                                $fieldType = 'password';
97
                                break;
98
                            case $this->checkColumn($name, ['url', 'link', 'src', 'href']):
99
                                $fieldType = 'url';
100
                                break;
101
                            case $this->checkColumn($name, ['ip']):
102
                                $fieldType = 'ip';
103
                                break;
104
                            case $this->checkColumn($name, ['mobile', 'phone']):
105
                                $fieldType = 'mobile';
106
                                break;
107
                            case $this->checkColumn($name, ['color', 'rgb']):
108
                                $fieldType = 'color';
109
                                break;
110
                            case $this->checkColumn($name, ['image', 'img', 'avatar']) :
0 ignored issues
show
Coding Style introduced by
There must be no space before the colon in a CASE statement

As per the PSR-2 coding standard, there must not be a space in front of the colon in case statements.

switch ($selector) {
    case "A": //right
        doSomething();
        break;
    case "B" : //wrong
        doSomethingElse();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
111
                                $fieldType = 'image';
112
                                break;
113
                            case $this->checkColumn($name, ['file', 'attachment']) :
0 ignored issues
show
Coding Style introduced by
There must be no space before the colon in a CASE statement

As per the PSR-2 coding standard, there must not be a space in front of the colon in case statements.

switch ($selector) {
    case "A": //right
        doSomething();
        break;
    case "B" : //wrong
        doSomethingElse();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
114
                                $fieldType = 'file';
115
                                break;
116
                            default:
117
                                $fieldType = 'text';
118
                        }
119
                        break;
120
                    case 'integer':
121
                    case 'bigint':
122
                    case 'smallint':
123
                    case 'timestamp':
124
                        $fieldType = 'number';
125
                        break;
126
                    case 'decimal':
127
                    case 'float':
128
                    case 'real':
129
                        $fieldType = 'decimal';
130
                        break;
131
                    case 'datetime':
132
                        $fieldType = 'datetime';
133
                        $default = "date('Y-m-d H:i:s')";
134
                        break;
135
                    case 'date':
136
                        $fieldType = 'date';
137
                        $default = "date('Y-m-d')";
138
                        break;
139
                    case 'text':
140
                    case 'blob':
141
                        $fieldType = 'textarea';
142
                        $default = "''";
143
                        break;
144
                    default:
145
                        $fieldType = 'text';
146
                }
147
148
                $adminForm .= "\$form->{$fieldType}('{$name}', '{$comment}')->default('{$default}');\n";
149
            }
150
            $this->alert("laravel-admin form filed generator for {$modelName}:");
151
            $this->info($adminForm);
152
        }
153
154
    }
155
156
    /**
157
     * Check if the table column contains the specified keywords of the array.
158
     *
159
     * @param string $haystack
160
     * @param array $needle
161
     * @return bool
162
     */
163
    private function checkColumn(string $haystack, array $needle)
164
    {
165
        foreach ($needle as $value) {
166
            if (strstr($haystack, $value) !== false) {
167
                return true;
168
            }
169
        }
170
        return false;
171
    }
172
173
174
    /**
175
     * Get the console command options.
176
     *
177
     * @return array
178
     */
179
    protected function getOptions()
180
    {
181
        return [
182
            ['model', null, InputOption::VALUE_REQUIRED,
183
                'The eloquent model that should be use as controller data source.',],
184
        ];
185
    }
186
}
187