Completed
Push — master ( cb1113...b09b3a )
by Maarten
16s queued 11s
created

CreateColumnsMigrationAction::setDownChanges()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 11
rs 9.9
c 0
b 0
f 0
cc 2
nc 2
nop 1
1
<?php
2
3
namespace Mtolhuys\LaravelSchematics\Actions\Migration;
4
5
use Illuminate\Support\Str;
6
use Illuminate\Support\Facades\File;
7
use Mtolhuys\LaravelSchematics\Services\RuleParser;
8
use Mtolhuys\LaravelSchematics\Actions\Migration\Traits\CreatesMigrations;
9
10
class CreateColumnsMigrationAction
11
{
12
    use CreatesMigrations;
13
14
    /**
15
     * @param $request
16
     */
17
    public function execute($request)
18
    {
19
        $model = $request['model'];
20
        $table = app($model)->getTable();
21
        $stub = __DIR__ . '/../../../resources/stubs/migration/columns.stub';
22
        $title = $this->title($request, $table);
23
        $this->filename = 'database/migrations/' . date('Y_m_d_His') . '_' . Str::snake($title) . '.php';
24
        $request = $this->separateNameAndTypeChanges($request);
25
26
        File::put(base_path($this->filename), str_replace([
27
            '$classname$',
28
            '$table$',
29
            '$columnsUp$',
30
            '$columnsDown$'
31
        ], [
32
            $title,
33
            $table,
34
            rtrim($this->getUpMethods($request)),
35
            rtrim($this->getDownMethods($request)),
36
        ], File::get($stub)));
37
    }
38
39
    /**
40
     * Combine and return all up methods
41
     *
42
     * @param $request
43
     * @return string
44
     */
45
    private function getUpMethods($request): string
46
    {
47
        $changes = array_filter(
48
            $this->changes($request['fields'], true)
49
        );
50
51
        return (empty($changes) ? '' : RuleParser::fieldsToMigrationMethods($this->getFields($changes)))
52
            . (empty($request['created']) ? '' : RuleParser::fieldsToMigrationMethods(
53
                $this->getFields($request['created'])
54
            ))
55
            . (empty($request['deleted']) ? '' : RuleParser::fieldsToMigrationMethods(
56
                $this->getFields($this->deleted($request['deleted']))
57
            ));
58
    }
59
60
    /**
61
     * Combine and return all down methods
62
     *
63
     * @param $request
64
     * @return string
65
     */
66
    private function getDownMethods($request): string
67
    {
68
        $changes = array_filter(
69
            $this->changes(array_reverse($request['fields']), false)
70
        );
71
72
        return
73
            (empty($changes) ? '' : RuleParser::fieldsToMigrationMethods($this->getFields($changes)))
74
            . (empty($request['deleted']) ? '' : RuleParser::fieldsToMigrationMethods(
75
                $this->getFields(array_map(function ($field) {
76
                    $field['type'] = $this->parseColumnType($field['columnType']);
77
78
                    return $field;
79
                }, $request['deleted']))
80
            ))
81
            . (empty($request['created']) ? '' : RuleParser::fieldsToMigrationMethods(
82
                $this->getFields(
83
                    $this->deleted($request['created']))
84
            ));
85
    }
86
87
    /**
88
     * Add change specific type fields
89
     *
90
     * @param $fields
91
     * @param bool $up
92
     * @return array
93
     */
94
    private function changes($fields, bool $up): array
95
    {
96
        return array_map(function ($field) use ($up) {
97
            $changedField = json_decode($field['exists'], false)
98
                && json_decode($field['changed'], false);
99
100
            if ($changedField) {
101
                $field = $up ? $this->setUpChanges($field)
102
                    : $field = $this->setDownChanges($field);
103
104
                return $field;
105
            }
106
        }, $fields);
107
    }
108
109
    /**
110
     * @param $field
111
     * @return mixed
112
     */
113
    private function setUpChanges($field)
114
    {
115
        if (isset($field['from'])) {
116
            $field['type'] = "renameColumn|from:{$field['from']}|required";
117
        } else {
118
            $field['type'] .= '|change';
119
        }
120
121
        return $field;
122
    }
123
124
    /**
125
     * @param $field
126
     * @return mixed
127
     */
128
    private function setDownChanges($field)
129
    {
130
        if (isset($field['from'])) {
131
            $field['type'] = "renameColumn|from:{$field['to']}|required";
132
            $field['name'] = $field['from'];
133
        } else {
134
            $field['type'] = $this->parseColumnType($field['columnType']). '|change';
135
        }
136
137
        return $field;
138
    }
139
140
    /**
141
     * Add dropColumn for deleted fields
142
     *
143
     * @param $deleted
144
     * @return array
145
     */
146
    private function deleted($deleted): array
147
    {
148
        return array_map(static function ($field) {
149
            $field['type'] = 'dropColumn|required';
150
151
            return $field;
152
        }, $deleted);
153
    }
154
155
    /**
156
     * Get array of field names
157
     *
158
     * @param $request
159
     * @param string $table
160
     * @return string
161
     */
162
    private function title($request, string $table): string
163
    {
164
        $actions = static function ($action) use ($request) {
165
            if (isset($request[$action])) {
166
                return ucfirst($action)
167
                    . ucfirst(Str::camel(
168
                        implode('_and_', array_map(static function ($field) {
169
                            return empty($field['from']) ? $field['name'] : $field['from'];
170
                        }, array_merge(
171
                            $request[$action]
172
                        )))
173
                    ));
174
            }
175
        };
176
177
        return implode('', array_filter([
178
                $actions('created'),
179
                $actions('changed'),
180
                $actions('deleted')
181
            ])) . 'ColumnIn' . ucfirst(Str::camel($table)) . 'Table';
182
    }
183
184
    private function separateNameAndTypeChanges($request)
185
    {
186
        if (empty($request['changed'])) {
187
            return $request;
188
        }
189
190
        $changes = array_filter(array_map(static function($field) {
191
            if (!empty($field['from']) && !empty($field['type'])) {
192
                $field['name'] = $field['from'];
193
                $field['changed'] = true;
194
                $field['from'] = null;
195
196
                return $field;
197
            }
198
        }, $request['changed']));
199
200
        if (! empty($changes)) {
201
            $request['fields'] = array_merge([array_unique($changes[0])], $request['fields']);
202
        }
203
204
        return $request;
205
    }
206
}
207