Completed
Push — master ( 419c88...940d42 )
by Nicolas
03:31
created

SchemaParser::createField()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 3.0261

Importance

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