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) { |
|
|
|
|
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') { |
|
|
|
|
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) |
|
|
|
|
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) { |
|
|
|
|
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
|
|
|
|
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.