Completed
Push — master ( aca347...733456 )
by Nicolas
08:33
created

SchemaParser   A

Complexity

Total Complexity 26

Size/Duplication

Total Lines 267
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 0

Test Coverage

Coverage 27.94%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 26
c 1
b 0
f 0
lcom 1
cbo 0
dl 0
loc 267
ccs 19
cts 68
cp 0.2794
rs 10

15 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A parse() 0 16 2
A getSchemas() 0 8 2
A toArray() 0 4 1
A render() 0 10 2
A up() 0 4 1
A down() 0 11 2
A createField() 0 14 3
A addRelationColumn() 0 8 1
A addColumn() 0 16 4
A removeColumn() 0 8 2
A getColumn() 0 6 1
A getAttributes() 0 6 2
A hasCustomAttribute() 0 4 1
A getCustomAttribute() 0 4 1
1
<?php
2
3
namespace Nwidart\Modules\Support\Migrations;
4
5
use Illuminate\Contracts\Support\Arrayable;
6
7
class SchemaParser implements Arrayable
8
{
9
    /**
10
     * The array of custom attributes.
11
     *
12
     * @var array
13
     */
14
    protected $customAttributes = [
15
        'remember_token' => 'rememberToken()',
16
        'soft_delete' => 'softDeletes()',
17
    ];
18
19
    /**
20
     * The migration schema.
21
     *
22
     * @var string
23
     */
24
    protected $schema;
25
26
    /**
27
     * The relationship keys.
28
     *
29
     * @var array
30
     */
31
    protected $relationshipKeys = [
32
        'belongsTo',
33
    ];
34
35
    /**
36
     * Create new instance.
37
     *
38
     * @param string|null $schema
39
     */
40 2
    public function __construct($schema = null)
41
    {
42 2
        $this->schema = $schema;
43 2
    }
44
45
    /**
46
     * Parse a string to array of formatted schema.
47
     *
48
     * @param string $schema
49
     *
50
     * @return array
51
     */
52 2
    public function parse($schema)
53
    {
54 2
        $this->schema = $schema;
55
56 2
        $parsed = [];
57
58 2
        foreach ($this->getSchemas() as $schemaArray) {
59
            $column = $this->getColumn($schemaArray);
60
61
            $attributes = $this->getAttributes($column, $schemaArray);
62
63
            $parsed[$column] = $attributes;
64 2
        }
65
66 2
        return $parsed;
67
    }
68
69
    /**
70
     * Get array of schema.
71
     *
72
     * @return array
73
     */
74 2
    public function getSchemas()
75
    {
76 2
        if (is_null($this->schema)) {
77 2
            return [];
78
        }
79
80
        return explode(',', str_replace(' ', '', $this->schema));
81
    }
82
83
    /**
84
     * Convert string migration to array.
85
     *
86
     * @return array
87
     */
88 2
    public function toArray()
89
    {
90 2
        return $this->parse($this->schema);
91
    }
92
93
    /**
94
     * Render the migration to formatted script.
95
     *
96
     * @return string
97
     */
98 2
    public function render()
99
    {
100 2
        $results = '';
101
102 2
        foreach ($this->toArray() as $column => $attributes) {
103
            $results .= $this->createField($column, $attributes);
104 2
        }
105
106 2
        return $results;
107
    }
108
109
    /**
110
     * Render up migration fields.
111
     *
112
     * @return string
113
     */
114
    public function up()
115
    {
116
        return $this->render();
117
    }
118
119
    /**
120
     * Render down migration fields.
121
     *
122
     * @return string
123
     */
124
    public function down()
125
    {
126
        $results = '';
127
128
        foreach ($this->toArray() as $column => $attributes) {
129
            $attributes = [head($attributes)];
130
            $results .= $this->createField($column, $attributes, 'remove');
131
        }
132
133
        return $results;
134
    }
135
136
    /**
137
     * Create field.
138
     *
139
     * @param string $column
140
     * @param array  $attributes
141
     *
142
     * @return string
143
     */
144
    public function createField($column, $attributes, $type = 'add')
145
    {
146
        $results = "\t\t\t" . '$table';
147
148
        foreach ($attributes as $key => $field) {
149
            if (in_array($column, $this->relationshipKeys)) {
150
                $results .= $this->addRelationColumn($key, $field, $column);
151
            } else {
152
                $results .= $this->{"{$type}Column"}($key, $field, $column);
153
            }
154
        }
155
156
        return $results .= ';' . PHP_EOL;
157
    }
158
159
    /**
160
     * Add relation column.
161
     *
162
     * @param int    $key
163
     * @param string $field
164
     * @param string $column
165
     *
166
     * @return string
167
     */
168
    protected function addRelationColumn($key, $field, $column)
0 ignored issues
show
Unused Code introduced by
The parameter $key 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...
Unused Code introduced by
The parameter $column 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...
169
    {
170
        $relatedColumn = snake_case(class_basename($field)) . '_id';
171
172
        $method = 'integer';
173
174
        return "->{$method}('{$relatedColumn}')";
175
    }
176
177
    /**
178
     * Format field to script.
179
     *
180
     * @param int    $key
181
     * @param string $field
182
     * @param string $column
183
     *
184
     * @return string
185
     */
186
    protected function addColumn($key, $field, $column)
187
    {
188
        if ($this->hasCustomAttribute($column)) {
189
            return '->' . $field;
190
        }
191
192
        if ($key == 0) {
193
            return '->' . $field . "('" . $column . "')";
194
        }
195
196
        if (str_contains($field, '(')) {
197
            return '->' . $field;
198
        }
199
200
        return '->' . $field . '()';
201
    }
202
203
    /**
204
     * Format field to script.
205
     *
206
     * @param int    $key
207
     * @param string $field
208
     * @param string $column
209
     *
210
     * @return string
211
     */
212
    protected function removeColumn($key, $field, $column)
0 ignored issues
show
Unused Code introduced by
The parameter $key 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...
213
    {
214
        if ($this->hasCustomAttribute($column)) {
215
            return '->' . $field;
216
        }
217
218
        return '->dropColumn(' . "'" . $column . "')";
219
    }
220
221
    /**
222
     * Get column name from schema.
223
     *
224
     * @param string $schema
225
     *
226
     * @return string
227
     */
228
    public function getColumn($schema)
229
    {
230
        return array_first(explode(':', $schema), function ($key, $value) {
231
            return $value;
232
        });
233
    }
234
235
    /**
236
     * Get column attributes.
237
     *
238
     * @param string $column
239
     * @param string $schema
240
     *
241
     * @return array
242
     */
243
    public function getAttributes($column, $schema)
244
    {
245
        $fields = str_replace($column . ':', '', $schema);
246
247
        return $this->hasCustomAttribute($column) ? $this->getCustomAttribute($column) : explode(':', $fields);
248
    }
249
250
    /**
251
     * Determinte whether the given column is exist in customAttributes array.
252
     *
253
     * @param string $column
254
     *
255
     * @return bool
256
     */
257
    public function hasCustomAttribute($column)
258
    {
259
        return array_key_exists($column, $this->customAttributes);
260
    }
261
262
    /**
263
     * Get custom attributes value.
264
     *
265
     * @param string $column
266
     *
267
     * @return array
268
     */
269
    public function getCustomAttribute($column)
270
    {
271
        return (array) $this->customAttributes[$column];
272
    }
273
}
274