1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Encore\Admin\Form; |
4
|
|
|
|
5
|
|
|
use Encore\Admin\Form; |
6
|
|
|
use Encore\Admin\Widgets\Form as WidgetForm; |
7
|
|
|
use Illuminate\Support\Arr; |
8
|
|
|
use Illuminate\Support\Collection; |
9
|
|
|
|
10
|
|
|
/** |
11
|
|
|
* Class EmbeddedForm. |
12
|
|
|
* |
13
|
|
|
* @method Field\Text text($column, $label = '') |
14
|
|
|
* @method Field\Checkbox checkbox($column, $label = '') |
15
|
|
|
* @method Field\Radio radio($column, $label = '') |
16
|
|
|
* @method Field\Select select($column, $label = '') |
17
|
|
|
* @method Field\MultipleSelect multipleSelect($column, $label = '') |
18
|
|
|
* @method Field\Textarea textarea($column, $label = '') |
19
|
|
|
* @method Field\Hidden hidden($column, $label = '') |
20
|
|
|
* @method Field\Id id($column, $label = '') |
21
|
|
|
* @method Field\Ip ip($column, $label = '') |
22
|
|
|
* @method Field\Url url($column, $label = '') |
23
|
|
|
* @method Field\Color color($column, $label = '') |
24
|
|
|
* @method Field\Email email($column, $label = '') |
25
|
|
|
* @method Field\Mobile mobile($column, $label = '') |
26
|
|
|
* @method Field\Slider slider($column, $label = '') |
27
|
|
|
* @method Field\Map map($latitude, $longitude, $label = '') |
28
|
|
|
* @method Field\Editor editor($column, $label = '') |
29
|
|
|
* @method Field\File file($column, $label = '') |
30
|
|
|
* @method Field\Image image($column, $label = '') |
31
|
|
|
* @method Field\Date date($column, $label = '') |
32
|
|
|
* @method Field\Datetime datetime($column, $label = '') |
33
|
|
|
* @method Field\Time time($column, $label = '') |
34
|
|
|
* @method Field\Year year($column, $label = '') |
35
|
|
|
* @method Field\Month month($column, $label = '') |
36
|
|
|
* @method Field\DateRange dateRange($start, $end, $label = '') |
37
|
|
|
* @method Field\DateTimeRange datetimeRange($start, $end, $label = '') |
38
|
|
|
* @method Field\TimeRange timeRange($start, $end, $label = '') |
39
|
|
|
* @method Field\Number number($column, $label = '') |
40
|
|
|
* @method Field\Currency currency($column, $label = '') |
41
|
|
|
* @method Field\HasMany hasMany($relationName, $callback) |
42
|
|
|
* @method Field\SwitchField switch($column, $label = '') |
43
|
|
|
* @method Field\Display display($column, $label = '') |
44
|
|
|
* @method Field\Rate rate($column, $label = '') |
45
|
|
|
* @method Field\Divide divider() |
46
|
|
|
* @method Field\Password password($column, $label = '') |
47
|
|
|
* @method Field\Decimal decimal($column, $label = '') |
48
|
|
|
* @method Field\Html html($html, $label = '') |
49
|
|
|
* @method Field\Tags tags($column, $label = '') |
50
|
|
|
* @method Field\Icon icon($column, $label = '') |
51
|
|
|
* @method Field\Embeds embeds($column, $label = '') |
52
|
|
|
*/ |
53
|
|
|
class EmbeddedForm |
54
|
|
|
{ |
55
|
|
|
/** |
56
|
|
|
* @var Form|WidgetForm |
57
|
|
|
*/ |
58
|
|
|
protected $parent = null; |
59
|
|
|
|
60
|
|
|
/** |
61
|
|
|
* Fields in form. |
62
|
|
|
* |
63
|
|
|
* @var Collection |
64
|
|
|
*/ |
65
|
|
|
protected $fields; |
66
|
|
|
|
67
|
|
|
/** |
68
|
|
|
* Original data for this field. |
69
|
|
|
* |
70
|
|
|
* @var array |
71
|
|
|
*/ |
72
|
|
|
protected $original = []; |
73
|
|
|
|
74
|
|
|
/** |
75
|
|
|
* Column name for this form. |
76
|
|
|
* |
77
|
|
|
* @var string |
78
|
|
|
*/ |
79
|
|
|
protected $column; |
80
|
|
|
|
81
|
|
|
/** |
82
|
|
|
* EmbeddedForm constructor. |
83
|
|
|
* |
84
|
|
|
* @param string $column |
85
|
|
|
*/ |
86
|
|
|
public function __construct($column) |
87
|
|
|
{ |
88
|
|
|
$this->column = $column; |
89
|
|
|
|
90
|
|
|
$this->fields = new Collection(); |
91
|
|
|
} |
92
|
|
|
|
93
|
|
|
/** |
94
|
|
|
* Get all fields in current form. |
95
|
|
|
* |
96
|
|
|
* @return Collection |
97
|
|
|
*/ |
98
|
|
|
public function fields() |
99
|
|
|
{ |
100
|
|
|
return $this->fields; |
101
|
|
|
} |
102
|
|
|
|
103
|
|
|
/** |
104
|
|
|
* Set parent form for this form. |
105
|
|
|
* |
106
|
|
|
* @param Form $parent |
107
|
|
|
* |
108
|
|
|
* @return $this |
109
|
|
|
*/ |
110
|
|
|
public function setParent(Form $parent) |
111
|
|
|
{ |
112
|
|
|
$this->parent = $parent; |
113
|
|
|
|
114
|
|
|
return $this; |
115
|
|
|
} |
116
|
|
|
|
117
|
|
|
/** |
118
|
|
|
* Set parent form for this form. |
119
|
|
|
* |
120
|
|
|
* @param WidgetForm $parent |
121
|
|
|
* |
122
|
|
|
* @return $this |
123
|
|
|
*/ |
124
|
|
|
public function setParentWidgetForm(WidgetForm $parent) |
125
|
|
|
{ |
126
|
|
|
$this->parent = $parent; |
127
|
|
|
|
128
|
|
|
return $this; |
129
|
|
|
} |
130
|
|
|
|
131
|
|
|
/** |
132
|
|
|
* Set original values for fields. |
133
|
|
|
* |
134
|
|
|
* @param array $data |
135
|
|
|
* |
136
|
|
|
* @return $this |
137
|
|
|
*/ |
138
|
|
|
public function setOriginal($data) |
139
|
|
|
{ |
140
|
|
|
if (empty($data)) { |
141
|
|
|
return $this; |
142
|
|
|
} |
143
|
|
|
|
144
|
|
|
if (is_string($data)) { |
145
|
|
|
$data = json_decode($data, true); |
146
|
|
|
} |
147
|
|
|
|
148
|
|
|
$this->original = $data; |
149
|
|
|
|
150
|
|
|
return $this; |
151
|
|
|
} |
152
|
|
|
|
153
|
|
|
/** |
154
|
|
|
* Prepare for insert or update. |
155
|
|
|
* |
156
|
|
|
* @param array $input |
157
|
|
|
* |
158
|
|
|
* @return mixed |
159
|
|
|
*/ |
160
|
|
|
public function prepare($input) |
161
|
|
|
{ |
162
|
|
|
foreach ($input as $key => $record) { |
163
|
|
|
$this->setFieldOriginalValue($key); |
164
|
|
|
$input[$key] = $this->prepareValue($key, $record); |
165
|
|
|
} |
166
|
|
|
|
167
|
|
|
return $input; |
168
|
|
|
} |
169
|
|
|
|
170
|
|
|
/** |
171
|
|
|
* Do prepare work for each field. |
172
|
|
|
* |
173
|
|
|
* @param string $key |
174
|
|
|
* @param string $record |
175
|
|
|
* |
176
|
|
|
* @return mixed |
177
|
|
|
*/ |
178
|
|
|
protected function prepareValue($key, $record) |
179
|
|
|
{ |
180
|
|
|
$field = $this->fields->first(function (Field $field) use ($key) { |
181
|
|
|
return in_array($key, (array) $field->column()); |
182
|
|
|
}); |
183
|
|
|
|
184
|
|
|
if (method_exists($field, 'prepare')) { |
185
|
|
|
return $field->prepare($record); |
186
|
|
|
} |
187
|
|
|
|
188
|
|
|
return $record; |
189
|
|
|
} |
190
|
|
|
|
191
|
|
|
/** |
192
|
|
|
* Set original data for each field. |
193
|
|
|
* |
194
|
|
|
* @param string $key |
195
|
|
|
* |
196
|
|
|
* @return void |
197
|
|
|
*/ |
198
|
|
View Code Duplication |
protected function setFieldOriginalValue($key) |
|
|
|
|
199
|
|
|
{ |
200
|
|
|
if (array_key_exists($key, $this->original)) { |
201
|
|
|
$values = $this->original[$key]; |
202
|
|
|
|
203
|
|
|
$this->fields->each(function (Field $field) use ($values) { |
204
|
|
|
$field->setOriginal($values); |
205
|
|
|
}); |
206
|
|
|
} |
207
|
|
|
} |
208
|
|
|
|
209
|
|
|
/** |
210
|
|
|
* Fill data to all fields in form. |
211
|
|
|
* |
212
|
|
|
* @param array $data |
213
|
|
|
* |
214
|
|
|
* @return $this |
215
|
|
|
*/ |
216
|
|
|
public function fill(array $data) |
217
|
|
|
{ |
218
|
|
|
$this->fields->each(function (Field $field) use ($data) { |
219
|
|
|
$field->fill($data); |
220
|
|
|
}); |
221
|
|
|
|
222
|
|
|
return $this; |
223
|
|
|
} |
224
|
|
|
|
225
|
|
|
/** |
226
|
|
|
* Format form, set `element name` `error key` and `element class`. |
227
|
|
|
* |
228
|
|
|
* @param Field $field |
229
|
|
|
* |
230
|
|
|
* @return Field |
231
|
|
|
*/ |
232
|
|
|
protected function formatField(Field $field) |
233
|
|
|
{ |
234
|
|
|
$jsonKey = $field->column(); |
235
|
|
|
|
236
|
|
|
$elementName = $elementClass = $errorKey = []; |
237
|
|
|
|
238
|
|
|
if (is_array($jsonKey)) { |
239
|
|
|
foreach ($jsonKey as $index => $name) { |
240
|
|
|
$elementName[$index] = "{$this->column}[$name]"; |
241
|
|
|
$errorKey[$index] = "{$this->column}.$name"; |
242
|
|
|
$elementClass[$index] = "{$this->column}_$name"; |
243
|
|
|
} |
244
|
|
|
} else { |
245
|
|
|
$elementName = "{$this->column}[$jsonKey]"; |
246
|
|
|
$errorKey = "{$this->column}.$jsonKey"; |
247
|
|
|
$elementClass = "{$this->column}_$jsonKey"; |
248
|
|
|
} |
249
|
|
|
|
250
|
|
|
$field->setElementName($elementName) |
251
|
|
|
->setErrorKey($errorKey) |
252
|
|
|
->setElementClass($elementClass); |
253
|
|
|
|
254
|
|
|
return $field; |
255
|
|
|
} |
256
|
|
|
|
257
|
|
|
/** |
258
|
|
|
* Add a field to form. |
259
|
|
|
* |
260
|
|
|
* @param Field $field |
261
|
|
|
* |
262
|
|
|
* @return $this |
263
|
|
|
*/ |
264
|
|
|
public function pushField(Field $field) |
265
|
|
|
{ |
266
|
|
|
$field = $this->formatField($field); |
267
|
|
|
|
268
|
|
|
$this->fields->push($field); |
269
|
|
|
|
270
|
|
|
return $this; |
271
|
|
|
} |
272
|
|
|
|
273
|
|
|
/** |
274
|
|
|
* Add nested-form fields dynamically. |
275
|
|
|
* |
276
|
|
|
* @param string $method |
277
|
|
|
* @param array $arguments |
278
|
|
|
* |
279
|
|
|
* @return Field|$this |
280
|
|
|
*/ |
281
|
|
View Code Duplication |
public function __call($method, $arguments) |
|
|
|
|
282
|
|
|
{ |
283
|
|
|
if ($className = Form::findFieldClass($method)) { |
284
|
|
|
$column = Arr::get($arguments, 0, ''); |
285
|
|
|
|
286
|
|
|
/** @var Field $field */ |
287
|
|
|
$field = new $className($column, array_slice($arguments, 1)); |
288
|
|
|
|
289
|
|
|
if ($this->parent instanceof WidgetForm) { |
290
|
|
|
$field->setWidgetForm($this->parent); |
291
|
|
|
} else { |
292
|
|
|
$field->setForm($this->parent); |
293
|
|
|
} |
294
|
|
|
|
295
|
|
|
$this->pushField($field); |
296
|
|
|
|
297
|
|
|
return $field; |
298
|
|
|
} |
299
|
|
|
|
300
|
|
|
return $this; |
301
|
|
|
} |
302
|
|
|
} |
303
|
|
|
|
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.