SchemaParser::down()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

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