Passed
Push — master ( f76100...0ef3ba )
by CodexShaper
04:52
created

RecordTrait::prepareRules()   A

Complexity

Conditions 6
Paths 4

Size

Total Lines 16
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 42

Importance

Changes 0
Metric Value
cc 6
eloc 11
nc 4
nop 3
dl 0
loc 16
ccs 0
cts 14
cp 0
crap 42
rs 9.2222
c 0
b 0
f 0
1
<?php
2
3
namespace CodexShaper\DBM\Traits;
4
5
use CodexShaper\DBM\Database\Drivers\MongoDB\Type;
6
use CodexShaper\DBM\Facades\Driver;
7
use CodexShaper\DBM\Facades\Manager as DBM;
8
use CodexShaper\DBM\Models\DBM_Collection;
9
use Illuminate\Support\Facades\DB;
10
use Illuminate\Support\Facades\Validator;
11
use Illuminate\Support\Str;
12
13
trait RecordTrait
14
{
15
    protected $name;
16
    protected $function_name;
17
    protected $localModel;
18
    protected $create;
19
    protected $relatedPivotKey;
20
    protected $parentPivotKey;
21
    protected $relationType;
22
    protected $details;
23
    protected $rules;
24
    protected $update;
25
    protected $type;
26
    protected $settings;
27
    protected $validation;
28
    protected $pivotTable;
29
    protected $foreignModel;
30
    protected $localTable;
31
32
    public function saveFiles($request, $column, $tableName)
33
    {
34
        $files  = $request->file($column);
35
        $values = [];
36
        foreach ($files as $file) {
37
            $fileName = Str::random(config('dbm.filesystem.random_length')) . '.' . $file->getClientOriginalExtension();
38
            $path     = 'public/dbm/' . $tableName;
39
            $file->storeAs($path, $fileName);
40
            $values[] = $fileName;
41
        }
42
43
        if (count($values) > 1) {
44
            $value = $values;
45
            if (!Driver::isMongoDB()) {
46
                $value = json_encode($values);
47
            }
48
        } else if (count($values) == 1) {
49
            $value = $values[0];
50
        }
51
52
        return $value;
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $value does not seem to be defined for all execution paths leading up to this point.
Loading history...
53
    }
54
55
    public function prepareStoreField($value, $tableName, $column)
56
    {
57
        $value = is_array($value) ? json_encode($value) : $value;
58
59
        if (Driver::isMongoDB()) {
60
61
            $fieldType = $this->getFieldType($tableName, $column);
62
63
            if (!in_array($fieldType, Type::getTypes())) {
64
                $this->generateError([$fieldType . " type not supported."]);
65
            }
66
67
            if ($fieldType != 'timestamp') {
68
                $value = Type::$fieldType($value);
69
            }
70
71
        }
72
73
        return $value;
74
    }
75
76
    public function prepareRecordFields($fields)
77
    {
78
        foreach ($fields as $key => $field) {
79
80
            if ($field->type == 'relationship') {
81
82
                $relationship            = $field->settings;
83
                $foreignModel            = $relationship['foreignModel'];
84
                $foreignKey              = $relationship['foreignKey'];
85
                $fields                  = $this->removeRelationshipKeyForBelongsTo($fields, $foreignKey);
0 ignored issues
show
Bug introduced by
It seems like removeRelationshipKeyForBelongsTo() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

85
                /** @scrutinizer ignore-call */ 
86
                $fields                  = $this->removeRelationshipKeyForBelongsTo($fields, $foreignKey);
Loading history...
86
                $field->foreignTableData = $foreignModel::all();
87
                $field->relationship     = $relationship;
88
                continue;
89
            }
90
91
            if (isset($field->settings['options'])) {
92
                $options = $this->getSettingOptions($field);
93
                if (is_array($options)) {
94
                    $fields[$key]->options = $options;
95
                }
96
            }
97
        }
98
99
        return $fields;
100
    }
101
102
    public function prepareJsonFieldData($records, $fields, $object, $findValue)
103
    {
104
        $newRecords = [];
105
        $newRecord  = new \stdClass();
106
107
        foreach ($records as $item => $record) {
108
109
            foreach ($fields as $key => &$field) {
110
111
                if (isset($record->{$field->name})) {
112
113
                    $record->{$field->name} = is_json($record->{$field->name}) ? json_decode($record->{$field->name}, true) : $record->{$field->name};
114
                }
115
            }
116
117
            if ($findValue && $record->{$object->details['findColumn']} == $findValue) {
118
                $newRecord = $record;
119
            }
120
121
            $newRecords[] = $record;
122
        }
123
124
        return [
125
            "records" => $newRecords,
126
            "record"  => $newRecord,
127
        ];
128
    }
129
130
    public function sync($request, $object)
131
    {
132
        $tableName       = $request->table;
133
        $originalColumns = Table::getColumnsName($tableName);
0 ignored issues
show
Bug introduced by
The type CodexShaper\DBM\Traits\Table was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
134
        $columns         = json_decode($request->columns);
135
        $fields          = json_decode($request->fields);
136
        $key             = $object->details['findColumn'];
137
138
        $table = DBM::model($object->model, $tableName)->where($key, $columns->{$key})->first();
139
140
        foreach ($columns as $column => $value) {
141
142
            if (in_array($column, $originalColumns)) {
143
144
                if ($request->hasFile($column)) {
145
                    $value = $this->saveFiles($request, $column, $tableName);
146
                }
147
148
                if ($value !== null && $value !== "") {
149
150
                    if (!Driver::isMongoDB()) {
151
                        if ($functionName = $this->hasFunction($fields, $column)) {
152
                            $value = $this->executeFunction($functionName, $value);
153
                        }
154
                    }
155
156
                    $table->{$column} = $this->prepareStoreField($value, $tableName, $column);
157
                }
158
            }
159
        }
160
161
        if ($table->update()) {
162
            $this->updateRelationshipData($fields, $columns, $object, $table);
0 ignored issues
show
Bug introduced by
It seems like updateRelationshipData() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

162
            $this->/** @scrutinizer ignore-call */ 
163
                   updateRelationshipData($fields, $columns, $object, $table);
Loading history...
163
            return response()->json(['success' => true]);
164
        }
165
    }
166
167
    public function getSettingOptions($field)
168
    {
169
        $options = $field->settings['options'];
170
        if (isset($options['controller'])) {
171
            $partials       = explode('@', $options['controller']);
172
            $controllerName = $partials[0];
173
            $methodName     = $partials[1];
174
175
            return app($controllerName)->{$methodName}();
176
        }
177
    }
178
179
    public function validation($fields, $columns, $action = "create")
180
    {
181
        $errors = [];
182
        foreach ($fields as $field) {
183
            $name = $field->name;
184
185
            if (is_object($field->settings) && property_exists($field->settings, 'validation') !== false) {
186
187
                $validationSettings = $field->settings->validation;
188
                $rules              = $this->prepareRules($columns, $action, $validationSettings);
189
                $data               = [$name => $columns->{$name}];
190
                $validator          = Validator::make($data, [$name => $rules]);
191
                if ($validator->fails()) {
192
                    foreach ($validator->errors()->all() as $error) {
193
                        $errors[] = $error;
194
                    }
195
                }
196
            }
197
        }
198
199
        return $errors;
200
    }
201
202
    public function prepareRules($columns, $action, $settings)
203
    {
204
        $rules = '';
205
206
        if (is_string($settings)) {
207
            $rules = $settings;
208
        } else if ($action == 'create' && isset($settings->create)) {
209
            $createSettings = $settings->create;
210
            $rules          = $createSettings->rules;
211
        } else if ($action == 'update' && isset($settings->update)) {
212
            $updateSettings = $settings->update;
213
            $localKey       = $updateSettings->localKey;
214
            $rules          = $updateSettings->rules . ',' . $columns->{$localKey};
215
        }
216
217
        return $rules;
218
    }
219
220
    public function getFieldType($collectionName, $fieldName)
221
    {
222
        $collection = DBM_Collection::where('name', $collectionName)->first();
223
224
        return $collection->fields()->where('name', $fieldName)->first()->type;
225
    }
226
227
    public function generateError($errors)
228
    {
229
        return response()->json([
230
            'success' => false,
231
            'errors'  => $errors,
232
        ], 400);
233
    }
234
235
    public function hasFunction($fields, $column)
236
    {
237
        foreach ($fields as $field) {
238
            if ($field->name == $column && ($field->function_name != null || $field->function_name != "")) {
239
                return $field->function_name;
240
            }
241
        }
242
243
        return false;
244
    }
245
246
    public function executeFunction($functionName, $value = null)
247
    {
248
        $signature = ($value != null) ? "{$functionName}('{$value}')" : "{$functionName}()";
249
250
        $result = DB::raw("{$signature}");
251
252
        return $result;
253
    }
254
}
255