Completed
Push — master ( 3d1d4f...7dac91 )
by
unknown
05:13
created

MiniCrud::getResults()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 2.0625

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 7
ccs 3
cts 4
cp 0.75
rs 9.4285
cc 2
eloc 4
nc 2
nop 0
crap 2.0625
1
<?php
2
namespace Anavel\Crud\Abstractor\Eloquent\Relation;
3
4
use Anavel\Crud\Abstractor\Eloquent\Relation\Traits\CheckRelationCompatibility;
5
use Anavel\Crud\Abstractor\Eloquent\Traits\HandleFiles;
6
use Anavel\Crud\Contracts\Abstractor\Field;
7
use Anavel\Crud\Contracts\Abstractor\Relation as RelationContract;
8
use App;
9
use Illuminate\Database\Eloquent\Model;
10
use Illuminate\Http\Request;
11
use Illuminate\Support\Collection;
12
13
class MiniCrud extends Relation
14
{
15
    use CheckRelationCompatibility;
16
    use HandleFiles;
17
18
    /** @var \ANavallaSuiza\Laravel\Database\Contracts\Dbal\AbstractionLayer $dbal */
19
    protected $dbal;
20
21
    /** @var  Collection */
22
    protected $results;
23
24
    protected $compatibleEloquentRelations = array(
25
        'Illuminate\Database\Eloquent\Relations\HasMany'
26
    );
27
28
    /**
29
     * @return Collection
30
     */
31 4
    protected function getResults()
32
    {
33 4
        if (empty($this->results)) {
34 4
            return $this->results = $this->eloquentRelation->getResults();
35
        }
36
        return $this->results;
37
    }
38
39 8
    public function setup()
40
    {
41 8
        $this->checkRelationCompatibility();
42 6
    }
43
44
    /**
45
     * @return array
46
     */
47 2
    public function getEditFields($arrayKey = null)
48
    {
49 2
        $fields = [];
50 2
        if (empty($arrayKey)) {
51 2
            $arrayKey = $this->name;
52 2
        }
53
54 2
        $fieldsBase = $this->getEditFieldsBase();
55
56
57
        /** @var Collection $results */
58 2
        $results = $this->getResults();
59
60 2
        $results->put('emptyResult', '');
61 2
        if (!empty($fieldsBase)) {
62 2
            foreach ($results as $key => $result) {
63 2
                $tempFields = [];
64 2
                $index = $key === 'emptyResult' ? 0 : $result->id;
65
66 2
                foreach ($fieldsBase as $columnName => $fieldBase) {
67 2
                    $field = clone $fieldBase;
68 2
                    if ($this->skipField($columnName, $key)) {
69
                        continue;
70
                    }
71
72 2
                    if ($key !== 'emptyResult') {
73 2
                        $field->setValue($result->getAttribute($columnName));
74 2
                    }
75 2
                    $tempFields[$columnName] = $field;
76
77 2
                }
78
79 2
                $relationModel = $this->eloquentRelation->getRelated()->newInstance();
80 2
                if (!empty($result)) {
81 2
                    $relationModel = $result;
82 2
                }
83
84 2
                $this->modelAbstractor->setInstance($relationModel);
85 2
                $secondaryRelations = $this->getSecondaryRelations();
86 2
                if (!empty($secondaryRelations)) {
87 2 View Code Duplication
                    foreach ($secondaryRelations as $secondaryRelationKey => $secondaryRelation) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
88 2
                        foreach ($secondaryRelation->getEditFields($secondaryRelationKey) as $editGroupName => $editGroup) {
89
                            if ($secondaryRelation->getType() === 'Anavel\Crud\Abstractor\Eloquent\Relation\Select') {
90
                                $tempFields[key($editGroup)] = $editGroup[key($editGroup)];
91
                            } else {
92
                                $tempFields[$editGroupName] = $editGroup;
93
                            }
94 2
                        };
95 2
                    }
96 2
                }
97
98
99 2
                $fields[$arrayKey][$index] = $tempFields;
100 2
            }
101 2
        }
102
103 2
        return $fields;
104
    }
105
106 4
    public function getEditFieldsBase()
107
    {
108 4
        $fields = [];
109 4
        $columns = $this->modelAbstractor->getColumns('edit');
110 4
        $this->readConfig('edit');
111
112 4
        if (!empty($columns)) {
113 4
            $readOnly = [Model::CREATED_AT, Model::UPDATED_AT];
114 4
            foreach ($columns as $columnName => $column) {
115 4
                if (in_array($columnName, $readOnly, true)) {
116
                    continue;
117
                }
118
119 4
                $formType = null;
120 4
                if ($columnName === $this->eloquentRelation->getParent()->getKeyName()) {
121
                    $formType = 'hidden';
122
                }
123
124
                $config = [
125 4
                    'name' => $columnName,
126 4
                    'presentation' => $this->name . ' ' . ucfirst(transcrud($columnName)),
127 4
                    'form_type' => $formType,
128 4
                    'no_validate' => true,
129 4
                    'validation' => null,
130
                    'functions' => null
131 4
                ];
132
133 4
                $config = $this->setConfig($config, $columnName);
134
135
                /** @var Field $field */
136 4
                $field = $this->fieldFactory
137 4
                    ->setColumn($column)
138 4
                    ->setConfig($config)
139 4
                    ->get();
140
141 4
                $fields[$columnName] = $field;
142
143 4 View Code Duplication
                if (!empty($config['form_type']) && $config['form_type'] === 'file') {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
144
                    $field = $this->fieldFactory
145
                        ->setColumn($column)
146
                        ->setConfig([
147
                            'name' => $columnName . '__delete',
148
                            'presentation' => null,
149
                            'form_type' => 'checkbox',
150
                            'no_validate' => true,
151
                            'validation' => null,
152
                            'functions' => null
153
                        ])
154
                        ->get();
155
                    $fields[$columnName . '__delete'] = $field;
156
                }
157 4
            }
158 4
        }
159
160 4
        return $fields;
161
    }
162
163
    /**
164
     * @param array|null $relationArray
165
     * @return mixed
166
     */
167 2
    public function persist(array $relationArray = null, Request $request)
168
    {
169 2
        if (!empty($relationArray)) {
170 2
            $keyName = $this->eloquentRelation->getParent()->getKeyName();
171 2
            $currentRelations = $this->getResults()->keyBy($keyName);
172
173 2
            $this->readConfig('edit');
174 2
            $fieldsBase = $this->getEditFieldsBase();
175
176 2
            foreach ($relationArray as $relationIndex => &$relation) {
177 2
                if (!empty($relation[$keyName])
178 2
                    && ($currentRelations->has($relation[$keyName]))
179 2
                ) {
180
                    $relationModel = $currentRelations->get($relation[$keyName]);
181
                } else {
182 2
                    $relationModel = $this->eloquentRelation->getRelated()->newInstance();
183
                }
184
185 2
                $this->modelAbstractor->setInstance($relationModel);
186 2
                $secondaryRelations = $this->getSecondaryRelations();
187
188
189 2
                $this->setKeys($relationModel);
190
191 2
                $shouldBeSkipped = true;
192 2
                $delayedRelations = collect();
193
194
195 2
                foreach ($fieldsBase as $fieldBaseKey => $field) {
196 2
                    $fieldName = $field->getName();
197
198 2
                    if (get_class($field->getFormField()) === \FormManager\Fields\File::class) {
199
                        $handleResult = $this->handleField($request, $relationModel, $relation, $this->name . ".$relationIndex", $fieldName);
200
                        if (! empty($handleResult['skipNext'])) {
201
                            unset($relationArray[$relationIndex][$handleResult['skipNext']]);
202
                        }
203
                        if (! empty($handleResult['requestValue'])) {
204
                            $relationArray[$relationIndex][$fieldName] = $handleResult['requestValue'];
205
                        }
206
                    }
207 2
                }
208
209
210 2
                foreach ($relation as $fieldKey => $fieldValue) {
211 2
                    if ($secondaryRelations->has($fieldKey)) {
212 1
                        $delayedRelations->put($fieldKey, $fieldValue);
213 1
                        continue;
214
                    }
215
216 2
                    if ($shouldBeSkipped) {
217 2
                        $shouldBeSkipped = ($shouldBeSkipped === ($fieldValue === ''));
218 2
                    }
219
220 2
                    $relationModel->setAttribute($fieldKey, $fieldValue);
221 2
                }
222
223 2
                if (!$shouldBeSkipped) {
224 2
                    $relationModel->save();
225
226 2
                    if (!$delayedRelations->isEmpty()) {
227 1
                        foreach ($delayedRelations as $relationKey => $delayedRelation) {
228
                            /** @var RelationContract $secondaryRelation */
229 1
                            $secondaryRelation = $secondaryRelations->get($relationKey);
230
231 1
                            $secondaryRelation->persist($delayedRelation, $request);
232 1
                        }
233 1
                    }
234 2
                }
235 2
            }
236 2
        }
237 2
    }
238
239 1
    protected function setKeys(Model $relationModel)
240
    {
241 1
        $relationModel->setAttribute($this->eloquentRelation->getForeignKey(), $this->relatedModel->id);
242 1
    }
243
244 1 View Code Duplication
    protected function skipField($columnName, $key)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
245
    {
246 1
        if ($columnName === $this->eloquentRelation->getPlainForeignKey()) {
247
            return true;
248
        }
249
250 1
        if ($key === 'emptyResult' && ($columnName === $this->eloquentRelation->getParent()->getKeyName())) {
251
            return true;
252
        }
253
254 1
        return false;
255
    }
256
257
    /**
258
     * @return string
259
     */
260
    public function getDisplayType()
261
    {
262
        return self::DISPLAY_TYPE_TAB;
263
    }
264
265
    /**
266
     * @param array $fields
267
     * @return array
268
     */
269
    public function addSecondaryRelationFields(array $fields)
270
    {
271
        $tempFields = [];
272 View Code Duplication
        foreach ($this->getSecondaryRelations() as $relationKey => $relation) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
273
            foreach ($relation->getEditFields($relationKey) as $editGroupName => $editGroup) {
274
                if ($relation->getType() === 'Anavel\Crud\Abstractor\Eloquent\Relation\Select') {
275
                    $tempFields[key($editGroup)] = $editGroup[key($editGroup)];
276
                } else {
277
                    $tempFields[$editGroupName] = $editGroup;
278
                }
279
            };
280
        }
281
        foreach ($fields[$this->name] as $groupKey => $mainFields) {
282
            $combinedFields = array_merge($mainFields, $tempFields);
283
            $fields[$this->name][$groupKey] = $combinedFields;
284
        }
285
286
        return $fields;
287
    }
288
}
289
290