Completed
Push — master ( d51707...dd5aae )
by Nicolas
04:02
created

SchemaParser::addRelationColumn()   A

Complexity

Conditions 5
Paths 5

Size

Total Lines 18

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 5.5069

Importance

Changes 0
Metric Value
cc 5
nc 5
nop 3
dl 0
loc 18
ccs 8
cts 11
cp 0.7272
crap 5.5069
rs 9.3554
c 0
b 0
f 0
1
<?php
2
3
namespace Nwidart\Modules\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 13
    public function __construct($schema = null)
43
    {
44 13
        $this->schema = $schema;
45 13
    }
46
47
    /**
48
     * Parse a string to array of formatted schema.
49
     *
50
     * @param string $schema
51
     *
52
     * @return array
53
     */
54 13
    public function parse($schema)
55
    {
56 13
        $this->schema = $schema;
57
58 13
        $parsed = [];
59
60 13
        foreach ($this->getSchemas() as $schemaArray) {
61 4
            $column = $this->getColumn($schemaArray);
62
63 4
            $attributes = $this->getAttributes($column, $schemaArray);
64
65 4
            $parsed[$column] = $attributes;
66
        }
67
68 13
        return $parsed;
69
    }
70
71
    /**
72
     * Get array of schema.
73
     *
74
     * @return array
75
     */
76 13
    public function getSchemas()
77
    {
78 13
        if (is_null($this->schema)) {
79 9
            return [];
80
        }
81
82 4
        return explode(',', str_replace(' ', '', $this->schema));
83
    }
84
85
    /**
86
     * Convert string migration to array.
87
     *
88
     * @return array
89
     */
90 13
    public function toArray()
91
    {
92 13
        return $this->parse($this->schema);
93
    }
94
95
    /**
96
     * Render the migration to formatted script.
97
     *
98
     * @return string
99
     */
100 12
    public function render()
101
    {
102 12
        $results = '';
103
104 12
        foreach ($this->toArray() as $column => $attributes) {
105 3
            $results .= $this->createField($column, $attributes);
106
        }
107
108 12
        return $results;
109
    }
110
111
    /**
112
     * Render up migration fields.
113
     *
114
     * @return string
115
     */
116 3
    public function up()
117
    {
118 3
        return $this->render();
119
    }
120
121
    /**
122
     * Render down migration fields.
123
     *
124
     * @return string
125
     */
126 3
    public function down()
127
    {
128 3
        $results = '';
129
130 3
        foreach ($this->toArray() as $column => $attributes) {
131 1
            $attributes = [head($attributes)];
132 1
            $results .= $this->createField($column, $attributes, 'remove');
133
        }
134
135 3
        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 4
    public function createField($column, $attributes, $type = 'add')
148
    {
149 4
        $results = "\t\t\t" . '$table';
150
151 4
        foreach ($attributes as $key => $field) {
152 4
            if (in_array($column, $this->relationshipKeys)) {
153 1
                $results .= $this->addRelationColumn($key, $field, $column);
154
            } else {
155 3
                $results .= $this->{"{$type}Column"}($key, $field, $column);
156
            }
157
        }
158
159 4
        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 1
    protected function addRelationColumn($key, $field, $column)
172
    {
173 1
        if ($key === 0) {
174 1
            $relatedColumn = Str::snake(class_basename($field)) . '_id';
175
176 1
            return "->integer('{$relatedColumn}')->unsigned();" . PHP_EOL . "\t\t\t" . "\$table->foreign('{$relatedColumn}')";
177
        }
178 1
        if ($key === 1) {
179 1
            return "->references('{$field}')";
180
        }
181 1
        if ($key === 2) {
182 1
            return "->on('{$field}')";
183
        }
184
        if (Str::contains($field, '(')) {
185
            return '->' . $field;
186
        }
187
        return '->' . $field . '()';
188
    }
189
190
    /**
191
     * Format field to script.
192
     *
193
     * @param int    $key
194
     * @param string $field
195
     * @param string $column
196
     *
197
     * @return string
198
     */
199 2
    protected function addColumn($key, $field, $column)
200
    {
201 2
        if ($this->hasCustomAttribute($column)) {
202
            return '->' . $field;
203
        }
204
205 2
        if ($key == 0) {
206 2
            return '->' . $field . "('" . $column . "')";
207
        }
208
209
        if (Str::contains($field, '(')) {
210
            return '->' . $field;
211
        }
212
213
        return '->' . $field . '()';
214
    }
215
216
    /**
217
     * Format field to script.
218
     *
219
     * @param int    $key
220
     * @param string $field
221
     * @param string $column
222
     *
223
     * @return string
224
     */
225 1
    protected function removeColumn($key, $field, $column)
226
    {
227 1
        if ($this->hasCustomAttribute($column)) {
228
            return '->' . $field;
229
        }
230
231 1
        return '->dropColumn(' . "'" . $column . "')";
232
    }
233
234
    /**
235
     * Get column name from schema.
236
     *
237
     * @param string $schema
238
     *
239
     * @return string
240
     */
241 4
    public function getColumn($schema)
242
    {
243 4
        return Arr::get(explode(':', $schema), 0);
244
    }
245
246
    /**
247
     * Get column attributes.
248
     *
249
     * @param string $column
250
     * @param string $schema
251
     *
252
     * @return array
253
     */
254 4
    public function getAttributes($column, $schema)
255
    {
256 4
        $fields = str_replace($column . ':', '', $schema);
257
258 4
        return $this->hasCustomAttribute($column) ? $this->getCustomAttribute($column) : explode(':', $fields);
259
    }
260
261
    /**
262
     * Determine whether the given column is exist in customAttributes array.
263
     *
264
     * @param string $column
265
     *
266
     * @return bool
267
     */
268 4
    public function hasCustomAttribute($column)
269
    {
270 4
        return array_key_exists($column, $this->customAttributes);
271
    }
272
273
    /**
274
     * Get custom attributes value.
275
     *
276
     * @param string $column
277
     *
278
     * @return array
279
     */
280
    public function getCustomAttribute($column)
281
    {
282
        return (array) $this->customAttributes[$column];
283
    }
284
}
285