Completed
Pull Request — master (#666)
by reallyli
02:28
created

SchemaParser::getCustomAttribute()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 1
dl 0
loc 4
ccs 0
cts 2
cp 0
crap 2
rs 10
c 0
b 0
f 0
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 3
    public function __construct($schema = null)
41
    {
42 3
        $this->schema = $schema;
43 3
    }
44
45
    /**
46
     * Parse a string to array of formatted schema.
47
     *
48
     * @param string $schema
49
     *
50
     * @return array
51
     */
52 3
    public function parse($schema)
53
    {
54 3
        $this->schema = $schema;
55
56 3
        $parsed = [];
57
58 3
        foreach ($this->getSchemas() as $schemaArray) {
59 3
            $column = $this->getColumn($schemaArray);
60
61 3
            $attributes = $this->getAttributes($column, $schemaArray);
62
63 3
            $parsed[$column] = $attributes;
64
        }
65
66 3
        return $parsed;
67
    }
68
69
    /**
70
     * Get array of schema.
71
     *
72
     * @return array
73
     */
74 3
    public function getSchemas()
75
    {
76 3
        if (is_null($this->schema)) {
77
            return [];
78
        }
79
80 3
        return explode(',', str_replace(' ', '', $this->schema));
81
    }
82
83
    /**
84
     * Convert string migration to array.
85
     *
86
     * @return array
87
     */
88 3
    public function toArray()
89
    {
90 3
        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 2
            $results .= $this->createField($column, $attributes);
104
        }
105
106 2
        return $results;
107
    }
108
109
    /**
110
     * Render up migration fields.
111
     *
112
     * @return string
113
     */
114 1
    public function up()
115
    {
116 1
        return $this->render();
117
    }
118
119
    /**
120
     * Render down migration fields.
121
     *
122
     * @return string
123
     */
124 1
    public function down()
125
    {
126 1
        $results = '';
127
128 1
        foreach ($this->toArray() as $column => $attributes) {
129 1
            $attributes = [head($attributes)];
130 1
            $results .= $this->createField($column, $attributes, 'remove');
131
        }
132
133 1
        return $results;
134
    }
135
136
    /**
137
     * Create field.
138
     *
139
     * @param string $column
140
     * @param array  $attributes
141
     * @param string $type
142
     *
143
     * @return string
144
     */
145 3
    public function createField($column, $attributes, $type = 'add')
146
    {
147 3
        $results = "\t\t\t" . '$table';
148
149 3
        foreach ($attributes as $key => $field) {
150 3
            if (in_array($column, $this->relationshipKeys)) {
151
                $results .= $this->addRelationColumn($key, $field, $column);
152
            } else {
153 3
                $results .= $this->{"{$type}Column"}($key, $field, $column);
154
            }
155
        }
156
157 3
        return $results . ';' . PHP_EOL;
158
    }
159
160
    /**
161
     * Add relation column.
162
     *
163
     * @param int    $key
164
     * @param string $field
165
     * @param string $column
166
     *
167
     * @return string
168
     */
169
    protected function addRelationColumn($key, $field, $column)
170
    {
171
        $relatedColumn = snake_case(class_basename($field)) . '_id';
172
173
        $method = 'integer';
174
175
        return "->{$method}('{$relatedColumn}')";
176
    }
177
178
    /**
179
     * Format field to script.
180
     *
181
     * @param int    $key
182
     * @param string $field
183
     * @param string $column
184
     *
185
     * @return string
186
     */
187 2
    protected function addColumn($key, $field, $column)
188
    {
189 2
        if ($this->hasCustomAttribute($column)) {
190
            return '->' . $field;
191
        }
192
193 2
        if ($key == 0) {
194 2
            return '->' . $field . "('" . $column . "')";
195
        }
196
197
        if (str_contains($field, '(')) {
198
            return '->' . $field;
199
        }
200
201
        return '->' . $field . '()';
202
    }
203
204
    /**
205
     * Format field to script.
206
     *
207
     * @param int    $key
208
     * @param string $field
209
     * @param string $column
210
     *
211
     * @return string
212
     */
213 1
    protected function removeColumn($key, $field, $column)
214
    {
215 1
        if ($this->hasCustomAttribute($column)) {
216
            return '->' . $field;
217
        }
218
219 1
        return '->dropColumn(' . "'" . $column . "')";
220
    }
221
222
    /**
223
     * Get column name from schema.
224
     *
225
     * @param string $schema
226
     *
227
     * @return string
228
     */
229 3
    public function getColumn($schema)
230
    {
231 3
        return array_get(explode(':', $schema), 0);
232
    }
233
234
    /**
235
     * Get column attributes.
236
     *
237
     * @param string $column
238
     * @param string $schema
239
     *
240
     * @return array
241
     */
242 3
    public function getAttributes($column, $schema)
243
    {
244 3
        $fields = str_replace($column . ':', '', $schema);
245
246 3
        return $this->hasCustomAttribute($column) ? $this->getCustomAttribute($column) : explode(':', $fields);
247
    }
248
249
    /**
250
     * Determine whether the given column is exist in customAttributes array.
251
     *
252
     * @param string $column
253
     *
254
     * @return bool
255
     */
256 3
    public function hasCustomAttribute($column)
257
    {
258 3
        return array_key_exists($column, $this->customAttributes);
259
    }
260
261
    /**
262
     * Get custom attributes value.
263
     *
264
     * @param string $column
265
     *
266
     * @return array
267
     */
268
    public function getCustomAttribute($column)
269
    {
270
        return (array) $this->customAttributes[$column];
271
    }
272
}
273