Completed
Push — master ( 5ad49a...8e57d3 )
by Amine
02:19
created

ResourceCommand::hasSoftDeletes()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 5
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 3
nc 1
nop 0
1
<?php namespace Wn\Generators\Commands;
2
3
4
class ResourceCommand extends BaseCommand {
5
6
    protected $signature = 'wn:resource
7
        {name : Name of the resource.}
8
        {fields : fields description.}
9
        {--has-many= : hasMany relationships.}
10
        {--has-one= : hasOne relationships.}
11
        {--belongs-to= : belongsTo relationships.}
12
        {--belongs-to-many= : belongsToMany relationships.}
13
        {--migration-file= : the migration file name.}
14
        {--add= : specifies additional columns like timestamps, softDeletes, rememberToken and nullableTimestamps.}
15
        {--path=app : where to store the model file.}
16
        {--parsed : tells the command that arguments have been already parsed. To use when calling the command from an other command and passing the parsed arguments and options}
17
        {--force= : override the existing files}
18
    ';
19
20
    protected $description = 'Generates a model, migration, controller and routes for RESTful resource';
21
22
    protected $fields;
23
24
    public function handle()
25
    {
26
        $this->parseFields();
27
28
        $resourceName = $this->argument('name');
29
        $modelName = ucwords(camel_case($resourceName));
0 ignored issues
show
Bug introduced by
It seems like $resourceName defined by $this->argument('name') on line 28 can also be of type array; however, camel_case() 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...
30
        $tableName = str_plural($resourceName);
0 ignored issues
show
Bug introduced by
It seems like $resourceName defined by $this->argument('name') on line 28 can also be of type array; however, str_plural() 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...
31
32
        // generating the model
33
        $this->call('wn:model', [
34
            'name' => $modelName,
35
            '--fillable' => $this->fieldsHavingTag('fillable'),
36
            '--dates' => $this->fieldsHavingTag('date'),
37
            '--has-many' => $this->option('has-many'),
38
            '--has-one' => $this->option('has-one'),
39
            '--belongs-to' => $this->option('belongs-to'),
40
            '--belongs-to-many' => $this->option('belongs-to-many'),
41
            '--rules' => $this->rules(),
42
            '--path' => $this->option('path'),
43
            '--force' => $this->option('force'),
44
            '--timestamps' => $this->hasTimestamps() ? 'true' : 'false',
45
            '--soft-deletes' => $this->hasSoftDeletes() ? 'true' : 'false',
46
            '--parsed' => true
47
        ]);
48
49
        // generating the migration
50
        $this->call('wn:migration', [
51
            'table' => $tableName,
52
            '--schema' => $this->schema(),
53
            '--keys' => $this->migrationKeys(),
54
            '--file' => $this->option('migration-file'),
55
            '--force' => $this->option('force'),
56
            '--add' => $this->option('add'),
57
            '--parsed' => true
58
        ]);
59
60
        // generating REST actions trait if doesn't exist
61
        if(! $this->fs->exists('./app/Http/Controllers/RESTActions.php')){
62
            $this->call('wn:controller:rest-actions');
63
        }
64
65
        // generating the controller and routes
66
        $this->call('wn:controller', [
67
            'model' => $modelName,
68
            '--force' => $this->option('force'),
69
            '--no-routes' => false
70
        ]);
71
72
        // generating model factory
73
        $this->call('wn:factory', [
74
            'model' => 'App\\' . $modelName,
75
            '--fields' => $this->factoryFields(),
76
            '--force' => $this->option('force'),
77
            '--parsed' => true
78
        ]);
79
80
        // generating database seeder
81
        // $this->call('wn:seeder', [
0 ignored issues
show
Unused Code Comprehensibility introduced by
67% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
82
        //     'model' => 'App\\' . $modelName
0 ignored issues
show
Unused Code Comprehensibility introduced by
40% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
83
        // ]);
84
85
    }
86
87
    protected function parseFields()
88
    {
89
        $fields = $this->argument('fields');
90
        if($this->option('parsed')){
91
            $this->fields = $fields;
92
        } else {
93
            if(! $fields){
94
                $this->fields = [];
95
            } else {
96
                $this->fields = $this->getArgumentParser('fields')
97
                    ->parse($fields);
98
            }
99
            $this->fields = array_merge($this->fields, array_map(function($name) {
100
                return [
101
                    'name' => $name,
102
                    'schema' => [
103
                        ['name' => 'integer', 'args' => []],
104
                        ['name' => 'unsigned', 'args' => []]
105
                    ],
106
                    'rules' => 'required|numeric',
107
                    'tags' => ['fillable', 'key'],
108
                    'factory' => 'key'
109
                ];
110
            }, $this->foreignKeys()));
111
        }
112
113
    }
114
115
    protected function fieldsHavingTag($tag)
116
    {
117
        return array_map(function($field){
118
            return $field['name'];
119
        }, array_filter($this->fields, function($field) use($tag){
120
            return in_array($tag, $field['tags']);
121
        }));
122
    }
123
124 View Code Duplication
    protected function rules()
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...
125
    {
126
        return array_map(function($field){
127
            return [
128
                'name' => $field['name'],
129
                'rule' => $field['rules']
130
            ];
131
        }, array_filter($this->fields, function($field){
132
            return !empty($field['rules']);
133
        }));
134
    }
135
136
    protected function schema()
137
    {
138
        return array_map(function($field){
139
            return array_merge([[
140
                'name' => $field['name'],
141
                'args' => []
142
            ]], $field['schema']);
143
        }, $this->fields);
144
    }
145
146
    protected function foreignKeys()
147
    {
148
        $belongsTo = $this->option('belongs-to');
149
        if(! $belongsTo) {
150
            return [];
151
        }
152
        $relations = $this->getArgumentParser('relations')->parse($belongsTo);
153
        return array_map(function($relation){
154
            $name = $relation['model'] ? $relation['model'] : $relation['name'];
155
            $index = strrpos($name, "\\");
156
            if($index) {
157
                $name = substr($name, $index + 1);
158
            }
159
            return snake_case(str_singular($name)) . '_id';
160
        }, $relations);
161
    }
162
163
    protected function migrationKeys() {
164
        return array_map(function($name) {
165
            return [
166
                'name' => $name,
167
                'column' => '',
168
                'table' => '',
169
                'on_delete' => '',
170
                'on_update' => ''
171
            ];
172
        }, $this->foreignKeys());
173
    }
174
175 View Code Duplication
    protected function factoryFields()
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...
176
    {
177
        return array_map(function($field){
178
            return [
179
                'name' => $field['name'],
180
                'type' => $field['factory']
181
            ];
182
        }, array_filter($this->fields, function($field){
183
            return isset($field['factory']) && $field['factory'];
184
        }));
185
    }
186
187
    protected function hasTimestamps()
188
    {
189
        $additionals = explode(',', $this->option('add'));
190
        return in_array('nullableTimestamps', $additionals)
191
            || in_array('timestamps', $additionals)
192
            || in_array('timestampsTz', $additionals);
193
    }
194
195
    protected function hasSoftDeletes()
196
    {
197
        $additionals = explode(',', $this->option('add'));
198
        return in_array('softDeletes', $additionals);
199
    }
200
201
}
202