1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Kris\LaravelFormBuilder; |
4
|
|
|
|
5
|
|
|
use Illuminate\Contracts\Events\Dispatcher as EventDispatcher; |
6
|
|
|
use Illuminate\Contracts\Validation\Factory as ValidatorFactory; |
7
|
|
|
use Illuminate\Contracts\Validation\Validator; |
8
|
|
|
use Illuminate\Http\Exceptions\HttpResponseException; |
9
|
|
|
use Illuminate\Http\Request; |
10
|
|
|
use Illuminate\Support\Arr; |
11
|
|
|
use Kris\LaravelFormBuilder\Events\AfterFieldCreation; |
12
|
|
|
use Kris\LaravelFormBuilder\Events\AfterFormValidation; |
13
|
|
|
use Kris\LaravelFormBuilder\Events\BeforeFormValidation; |
14
|
|
|
use Kris\LaravelFormBuilder\Fields\FormField; |
15
|
|
|
use Kris\LaravelFormBuilder\Filters\FilterResolver; |
16
|
|
|
|
17
|
|
|
class Form |
18
|
|
|
{ |
19
|
|
|
/** |
20
|
|
|
* All fields that are added. |
21
|
|
|
* |
22
|
|
|
* @var array |
23
|
|
|
*/ |
24
|
|
|
protected $fields = []; |
25
|
|
|
|
26
|
|
|
/** |
27
|
|
|
* Model to use. |
28
|
|
|
* |
29
|
|
|
* @var mixed |
30
|
|
|
*/ |
31
|
|
|
protected $model = []; |
32
|
|
|
|
33
|
|
|
/** |
34
|
|
|
* @var EventDispatcher |
35
|
|
|
*/ |
36
|
|
|
protected $eventDispatcher; |
37
|
|
|
|
38
|
|
|
/** |
39
|
|
|
* @var FormHelper |
40
|
|
|
*/ |
41
|
|
|
protected $formHelper; |
42
|
|
|
|
43
|
|
|
/** |
44
|
|
|
* Form options. |
45
|
|
|
* |
46
|
|
|
* @var array |
47
|
|
|
*/ |
48
|
|
|
protected $formOptions = [ |
49
|
|
|
'method' => 'GET', |
50
|
|
|
'url' => null, |
51
|
|
|
'attr' => [], |
52
|
|
|
]; |
53
|
|
|
|
54
|
|
|
/** |
55
|
|
|
* Form specific configuration. |
56
|
|
|
* |
57
|
|
|
* @var array |
58
|
|
|
*/ |
59
|
|
|
protected $formConfig = []; |
60
|
|
|
|
61
|
|
|
/** |
62
|
|
|
* Additional data which can be used to build fields. |
63
|
|
|
* |
64
|
|
|
* @var array |
65
|
|
|
*/ |
66
|
|
|
protected $data = []; |
67
|
|
|
|
68
|
|
|
/** |
69
|
|
|
* Wether errors for each field should be shown when calling form($form) or form_rest($form). |
70
|
|
|
* |
71
|
|
|
* @var bool |
72
|
|
|
*/ |
73
|
|
|
protected $showFieldErrors = true; |
74
|
|
|
|
75
|
|
|
/** |
76
|
|
|
* Enable html5 validation. |
77
|
|
|
* |
78
|
|
|
* @var bool |
79
|
|
|
*/ |
80
|
|
|
protected $clientValidationEnabled = true; |
81
|
|
|
|
82
|
|
|
/** |
83
|
|
|
* Name of the parent form if any. |
84
|
|
|
* |
85
|
|
|
* @var string|null |
86
|
|
|
*/ |
87
|
|
|
protected $name = null; |
88
|
|
|
|
89
|
|
|
/** |
90
|
|
|
* @var FormBuilder |
91
|
|
|
*/ |
92
|
|
|
protected $formBuilder; |
93
|
|
|
|
94
|
|
|
/** |
95
|
|
|
* @var ValidatorFactory |
96
|
|
|
*/ |
97
|
|
|
protected $validatorFactory; |
98
|
|
|
|
99
|
|
|
/** |
100
|
|
|
* @var Validator |
101
|
|
|
*/ |
102
|
|
|
protected $validator = null; |
103
|
|
|
|
104
|
|
|
/** |
105
|
|
|
* @var Request |
106
|
|
|
*/ |
107
|
|
|
protected $request; |
108
|
|
|
|
109
|
|
|
/** |
110
|
|
|
* List of fields to not render. |
111
|
|
|
* |
112
|
|
|
* @var array |
113
|
|
|
**/ |
114
|
|
|
protected $exclude = []; |
115
|
|
|
|
116
|
|
|
/** |
117
|
|
|
* Wether the form is beign rebuild. |
118
|
|
|
* |
119
|
|
|
* @var bool |
120
|
|
|
*/ |
121
|
|
|
protected $rebuilding = false; |
122
|
|
|
|
123
|
|
|
/** |
124
|
|
|
* @var string |
125
|
|
|
*/ |
126
|
|
|
protected $templatePrefix; |
127
|
|
|
|
128
|
|
|
/** |
129
|
|
|
* @var string |
130
|
|
|
*/ |
131
|
|
|
protected $languageName; |
132
|
|
|
|
133
|
|
|
/** |
134
|
|
|
* @var string |
135
|
|
|
*/ |
136
|
|
|
protected $translationTemplate; |
137
|
|
|
|
138
|
|
|
/** |
139
|
|
|
* To filter and mutate request values or not. |
140
|
|
|
* |
141
|
|
|
* @var bool |
142
|
|
|
*/ |
143
|
|
|
protected $lockFiltering = false; |
144
|
|
|
|
145
|
|
|
/** |
146
|
|
|
* Define the error bag name for the form. |
147
|
|
|
* |
148
|
|
|
* @var string |
149
|
|
|
*/ |
150
|
|
|
protected $errorBag = 'default'; |
151
|
|
|
|
152
|
|
|
/** |
153
|
|
|
* Build the form. |
154
|
|
|
* |
155
|
|
|
* @return mixed |
156
|
|
|
*/ |
157
|
3 |
|
public function buildForm() |
158
|
|
|
{ |
159
|
3 |
|
} |
160
|
|
|
|
161
|
|
|
/** |
162
|
|
|
* Rebuild the form from scratch. |
163
|
|
|
* |
164
|
|
|
* @return $this |
165
|
|
|
*/ |
166
|
20 |
|
public function rebuildForm() |
167
|
|
|
{ |
168
|
20 |
|
$this->rebuilding = true; |
169
|
|
|
// If form is plain, buildForm method is empty, so we need to take |
170
|
|
|
// existing fields and add them again |
171
|
20 |
|
if (get_class($this) === 'Kris\LaravelFormBuilder\Form') { |
172
|
19 |
|
foreach ($this->fields as $name => $field) { |
173
|
|
|
// Remove any temp variables added in previous instance |
174
|
8 |
|
$options = Arr::except($field->getOptions(), 'tmp'); |
175
|
19 |
|
$this->add($name, $field->getType(), $options); |
176
|
|
|
} |
177
|
|
|
} else { |
178
|
3 |
|
$this->buildForm(); |
179
|
|
|
} |
180
|
20 |
|
$this->rebuilding = false; |
181
|
|
|
|
182
|
20 |
|
return $this; |
183
|
|
|
} |
184
|
|
|
|
185
|
|
|
/** |
186
|
|
|
* Create the FormField object. |
187
|
|
|
* |
188
|
|
|
* @param string $name |
189
|
|
|
* @param string $type |
190
|
|
|
* @param array $options |
191
|
|
|
* @return FormField |
192
|
|
|
*/ |
193
|
68 |
|
protected function makeField($name, $type = 'text', array $options = []) |
194
|
|
|
{ |
195
|
68 |
|
$this->setupFieldOptions($name, $options); |
196
|
|
|
|
197
|
68 |
|
$fieldName = $this->getFieldName($name); |
198
|
|
|
|
199
|
68 |
|
$fieldType = $this->getFieldType($type); |
200
|
|
|
|
201
|
67 |
|
$field = new $fieldType($fieldName, $type, $this, $options); |
202
|
|
|
|
203
|
64 |
|
$this->eventDispatcher->dispatch(new AfterFieldCreation($this, $field)); |
204
|
|
|
|
205
|
64 |
|
return $field; |
206
|
|
|
} |
207
|
|
|
|
208
|
|
|
/** |
209
|
|
|
* Create a new field and add it to the form. |
210
|
|
|
* |
211
|
|
|
* @param string $name |
212
|
|
|
* @param string $type |
213
|
|
|
* @param array $options |
214
|
|
|
* @param bool $modify |
215
|
|
|
* @return $this |
216
|
|
|
*/ |
217
|
70 |
|
public function add($name, $type = 'text', array $options = [], $modify = false) |
218
|
|
|
{ |
219
|
70 |
|
$this->formHelper->checkFieldName($name, get_class($this)); |
220
|
|
|
|
221
|
68 |
|
if ($this->rebuilding && !$this->has($name)) { |
222
|
|
|
return $this; |
223
|
|
|
} |
224
|
|
|
|
225
|
68 |
|
$this->addField($this->makeField($name, $type, $options), $modify); |
226
|
|
|
|
227
|
64 |
|
return $this; |
228
|
|
|
} |
229
|
|
|
|
230
|
|
|
/** |
231
|
|
|
* Add a FormField to the form's fields. |
232
|
|
|
* |
233
|
|
|
* @param FormField $field |
234
|
|
|
* @return $this |
235
|
|
|
*/ |
236
|
64 |
|
protected function addField(FormField $field, $modify = false) |
237
|
|
|
{ |
238
|
64 |
|
if (!$modify && !$this->rebuilding) { |
239
|
64 |
|
$this->preventDuplicate($field->getRealName()); |
240
|
|
|
} |
241
|
|
|
|
242
|
|
|
|
243
|
64 |
|
if ($field->getType() == 'file') { |
244
|
3 |
|
$this->formOptions['files'] = true; |
245
|
|
|
} |
246
|
|
|
|
247
|
64 |
|
$this->fields[$field->getRealName()] = $field; |
248
|
|
|
|
249
|
64 |
|
return $this; |
250
|
|
|
} |
251
|
|
|
|
252
|
|
|
/** |
253
|
|
|
* Add field before another field. |
254
|
|
|
* |
255
|
|
|
* @param string $name Name of the field before which new field is added. |
256
|
|
|
* @param string $fieldName Field name which will be added. |
257
|
|
|
* @param string $type |
258
|
|
|
* @param array $options |
259
|
|
|
* @param bool $modify |
260
|
|
|
* @return $this |
261
|
|
|
*/ |
262
|
1 |
|
public function addBefore($name, $fieldName, $type = 'text', $options = [], $modify = false) |
263
|
|
|
{ |
264
|
1 |
|
$offset = array_search($name, array_keys($this->fields)); |
265
|
|
|
|
266
|
1 |
|
$beforeFields = array_slice($this->fields, 0, $offset); |
267
|
1 |
|
$afterFields = array_slice($this->fields, $offset); |
268
|
|
|
|
269
|
1 |
|
$this->fields = $beforeFields; |
270
|
|
|
|
271
|
1 |
|
$this->add($fieldName, $type, $options, $modify); |
272
|
|
|
|
273
|
1 |
|
$this->fields += $afterFields; |
274
|
|
|
|
275
|
1 |
|
return $this; |
276
|
|
|
} |
277
|
|
|
|
278
|
|
|
/** |
279
|
|
|
* Add field before another field. |
280
|
|
|
* |
281
|
|
|
* @param string $name Name of the field after which new field is added. |
282
|
|
|
* @param string $fieldName Field name which will be added. |
283
|
|
|
* @param string $type |
284
|
|
|
* @param array $options |
285
|
|
|
* @param bool $modify |
286
|
|
|
* @return $this |
287
|
|
|
*/ |
288
|
1 |
|
public function addAfter($name, $fieldName, $type = 'text', $options = [], $modify = false) |
289
|
|
|
{ |
290
|
1 |
|
$offset = array_search($name, array_keys($this->fields)); |
291
|
|
|
|
292
|
1 |
|
$beforeFields = array_slice($this->fields, 0, $offset + 1); |
293
|
1 |
|
$afterFields = array_slice($this->fields, $offset + 1); |
294
|
|
|
|
295
|
1 |
|
$this->fields = $beforeFields; |
296
|
|
|
|
297
|
1 |
|
$this->add($fieldName, $type, $options, $modify); |
298
|
|
|
|
299
|
1 |
|
$this->fields += $afterFields; |
300
|
|
|
|
301
|
1 |
|
return $this; |
302
|
|
|
} |
303
|
|
|
|
304
|
|
|
/** |
305
|
|
|
* @param \Closure $callback |
306
|
|
|
* @param FieldGroup|null $fieldGroup |
307
|
|
|
* @param Form|null $parent |
308
|
|
|
* @return $this |
309
|
|
|
*/ |
310
|
1 |
|
public function group(\Closure $callback, FieldGroup $fieldGroup = null, Form $parent = null) |
311
|
|
|
{ |
312
|
1 |
|
$fieldGroup = $fieldGroup ?? new FieldGroup($parent ?? $this); |
313
|
|
|
|
314
|
1 |
|
$callback($fieldGroup); |
315
|
|
|
|
316
|
1 |
|
$this->compose($fieldGroup->getForm()); |
317
|
|
|
|
318
|
1 |
|
return $this; |
319
|
|
|
} |
320
|
|
|
|
321
|
|
|
/** |
322
|
|
|
* Take another form and add it's fields directly to this form. |
323
|
|
|
* |
324
|
|
|
* @param mixed $class Form to merge. |
325
|
|
|
* @param array $options |
326
|
|
|
* @param boolean $modify |
327
|
|
|
* @return $this |
328
|
|
|
*/ |
329
|
2 |
|
public function compose($class, array $options = [], $modify = false) |
330
|
|
|
{ |
331
|
2 |
|
$options['class'] = $class; |
332
|
|
|
|
333
|
|
|
// If we pass a ready made form just extract the fields. |
334
|
2 |
|
if ($class instanceof Form) { |
335
|
2 |
|
$fields = $class->getFields(); |
336
|
|
|
} elseif ($class instanceof Fields\ChildFormType) { |
337
|
|
|
$fields = $class->getForm()->getFields(); |
338
|
|
|
} elseif (is_string($class)) { |
339
|
|
|
// If its a string of a class make it the usual way. |
340
|
|
|
$options['model'] = $this->model; |
341
|
|
|
$options['name'] = $this->name; |
342
|
|
|
|
343
|
|
|
$form = $this->formBuilder->create($class, $options); |
344
|
|
|
$fields = $form->getFields(); |
345
|
|
|
} else { |
346
|
|
|
throw new \InvalidArgumentException( |
347
|
|
|
"[{$class}] is invalid. Please provide either a full class name, Form or ChildFormType" |
348
|
|
|
); |
349
|
|
|
} |
350
|
|
|
|
351
|
2 |
|
foreach ($fields as $field) { |
352
|
2 |
|
$this->addField($field, $modify); |
353
|
|
|
} |
354
|
|
|
|
355
|
2 |
|
return $this; |
356
|
|
|
} |
357
|
|
|
|
358
|
|
|
/** |
359
|
|
|
* Remove field with specified name from the form. |
360
|
|
|
* |
361
|
|
|
* @param string|string[] $names |
362
|
|
|
* @return $this |
363
|
|
|
*/ |
364
|
3 |
|
public function remove($names) |
365
|
|
|
{ |
366
|
3 |
|
foreach (is_array($names) ? $names : func_get_args() as $name) { |
367
|
3 |
|
if ($this->has($name)) { |
368
|
3 |
|
unset($this->fields[$name]); |
369
|
|
|
} |
370
|
|
|
} |
371
|
|
|
|
372
|
3 |
|
return $this; |
373
|
|
|
} |
374
|
|
|
|
375
|
|
|
/** |
376
|
|
|
* Remove all the fields. |
377
|
|
|
* @return $this |
378
|
|
|
*/ |
379
|
1 |
|
public function removeAll() |
380
|
|
|
{ |
381
|
1 |
|
$this->fields = []; |
382
|
|
|
|
383
|
1 |
|
return $this; |
384
|
|
|
} |
385
|
|
|
|
386
|
|
|
/** |
387
|
|
|
* Take only the given fields from the form. |
388
|
|
|
* |
389
|
|
|
* @param string|string[] $fieldNames |
390
|
|
|
* @return $this |
391
|
|
|
*/ |
392
|
1 |
|
public function only($fieldNames) |
393
|
|
|
{ |
394
|
1 |
|
$newFields = []; |
395
|
|
|
|
396
|
1 |
|
foreach (is_array($fieldNames) ? $fieldNames : func_get_args() as $fieldName) { |
397
|
1 |
|
$newFields[$fieldName] = $this->getField($fieldName); |
398
|
|
|
} |
399
|
|
|
|
400
|
1 |
|
$this->fields = $newFields; |
401
|
|
|
|
402
|
1 |
|
return $this; |
403
|
|
|
} |
404
|
|
|
|
405
|
|
|
/** |
406
|
|
|
* Modify existing field. If it doesn't exist, it is added to form. |
407
|
|
|
* |
408
|
|
|
* @param string $name |
409
|
|
|
* @param string $type |
410
|
|
|
* @param array $options |
411
|
|
|
* @param bool $overwriteOptions |
412
|
|
|
* @return Form |
413
|
|
|
*/ |
414
|
2 |
|
public function modify($name, $type = 'text', array $options = [], $overwriteOptions = false) |
415
|
|
|
{ |
416
|
|
|
// If we don't want to overwrite options, we merge them with old options. |
417
|
2 |
|
if ($overwriteOptions === false && $this->has($name)) { |
418
|
2 |
|
$options = $this->formHelper->mergeOptions( |
419
|
2 |
|
$this->getField($name)->getOptions(), |
420
|
2 |
|
$options |
421
|
|
|
); |
422
|
|
|
} |
423
|
|
|
|
424
|
2 |
|
return $this->add($name, $type, $options, true); |
425
|
|
|
} |
426
|
|
|
|
427
|
|
|
/** |
428
|
|
|
* Render full form. |
429
|
|
|
* |
430
|
|
|
* @param array $options |
431
|
|
|
* @param bool $showStart |
432
|
|
|
* @param bool $showFields |
433
|
|
|
* @param bool $showEnd |
434
|
|
|
* @return string |
435
|
|
|
*/ |
436
|
8 |
|
public function renderForm(array $options = [], $showStart = true, $showFields = true, $showEnd = true) |
437
|
|
|
{ |
438
|
8 |
|
return $this->render($options, FieldGroup::buildFieldsForRendering($this), $showStart, $showFields, $showEnd); |
439
|
|
|
} |
440
|
|
|
|
441
|
|
|
/** |
442
|
|
|
* Render rest of the form. |
443
|
|
|
* |
444
|
|
|
* @param bool $showFormEnd |
445
|
|
|
* @param bool $showFields |
446
|
|
|
* @return string |
447
|
|
|
*/ |
448
|
1 |
|
public function renderRest($showFormEnd = true, $showFields = true) |
449
|
|
|
{ |
450
|
1 |
|
$fields = $this->getUnrenderedFields(); |
451
|
|
|
|
452
|
1 |
|
return $this->render([], $fields, false, $showFields, $showFormEnd); |
453
|
|
|
} |
454
|
|
|
|
455
|
|
|
/** |
456
|
|
|
* Renders the rest of the form up until the specified field name. |
457
|
|
|
* |
458
|
|
|
* @param string $field_name |
459
|
|
|
* @param bool $showFormEnd |
460
|
|
|
* @param bool $showFields |
461
|
|
|
* @return string |
462
|
|
|
*/ |
463
|
2 |
|
public function renderUntil($field_name, $showFormEnd = true, $showFields = true) |
464
|
|
|
{ |
465
|
2 |
|
if (!$this->has($field_name)) { |
466
|
1 |
|
$this->fieldDoesNotExist($field_name); |
467
|
|
|
} |
468
|
|
|
|
469
|
1 |
|
$fields = $this->getUnrenderedFields(); |
470
|
|
|
|
471
|
1 |
|
$i = 1; |
472
|
1 |
|
foreach ($fields as $key => $value) { |
473
|
1 |
|
if ($value->getRealName() == $field_name) { |
474
|
1 |
|
break; |
475
|
|
|
} |
476
|
1 |
|
$i++; |
477
|
|
|
} |
478
|
|
|
|
479
|
1 |
|
$fields = array_slice($fields, 0, $i, true); |
480
|
|
|
|
481
|
1 |
|
return $this->render([], $fields, false, $showFields, $showFormEnd); |
482
|
|
|
} |
483
|
|
|
|
484
|
|
|
/** |
485
|
|
|
* Get single field instance from form object. |
486
|
|
|
* |
487
|
|
|
* @param string $name |
488
|
|
|
* @return FormField |
489
|
|
|
*/ |
490
|
38 |
|
public function getField($name) |
491
|
|
|
{ |
492
|
38 |
|
if ($this->has($name)) { |
493
|
37 |
|
return $this->fields[$name]; |
494
|
|
|
} |
495
|
|
|
|
496
|
1 |
|
$this->fieldDoesNotExist($name); |
497
|
|
|
} |
498
|
|
|
|
499
|
104 |
|
public function getErrorBag() |
500
|
|
|
{ |
501
|
104 |
|
return $this->errorBag; |
502
|
|
|
} |
503
|
|
|
|
504
|
|
|
/** |
505
|
|
|
* Check if form has field. |
506
|
|
|
* |
507
|
|
|
* @param string $name |
508
|
|
|
* @return bool |
509
|
|
|
*/ |
510
|
64 |
|
public function has($name) |
511
|
|
|
{ |
512
|
64 |
|
return array_key_exists($name, $this->fields); |
513
|
|
|
} |
514
|
|
|
|
515
|
|
|
/** |
516
|
|
|
* Get all form options. |
517
|
|
|
* |
518
|
|
|
* @return array |
519
|
|
|
*/ |
520
|
2 |
|
public function getFormOptions() |
521
|
|
|
{ |
522
|
2 |
|
return $this->formOptions; |
523
|
|
|
} |
524
|
|
|
|
525
|
|
|
/** |
526
|
|
|
* Get single form option. |
527
|
|
|
* |
528
|
|
|
* @param string $option |
529
|
|
|
* @param mixed|null $default |
530
|
|
|
* @return mixed |
531
|
|
|
*/ |
532
|
132 |
|
public function getFormOption($option, $default = null) |
533
|
|
|
{ |
534
|
132 |
|
return Arr::get($this->formOptions, $option, $default); |
535
|
|
|
} |
536
|
|
|
|
537
|
|
|
/** |
538
|
|
|
* Set single form option on form. |
539
|
|
|
* |
540
|
|
|
* @param string $option |
541
|
|
|
* @param mixed $value |
542
|
|
|
* |
543
|
|
|
* @return $this |
544
|
|
|
*/ |
545
|
2 |
|
public function setFormOption($option, $value) |
546
|
|
|
{ |
547
|
2 |
|
$this->formOptions[$option] = $value; |
548
|
|
|
|
549
|
2 |
|
return $this; |
550
|
|
|
} |
551
|
|
|
|
552
|
|
|
/** |
553
|
|
|
* Get the passed config key using the custom |
554
|
|
|
* form config, if any. |
555
|
|
|
* |
556
|
|
|
* @param string $key |
557
|
|
|
* @param mixed $default |
558
|
|
|
* |
559
|
|
|
* @return mixed |
560
|
|
|
*/ |
561
|
106 |
|
public function getConfig($key = null, $default = null) |
562
|
|
|
{ |
563
|
106 |
|
return $this->formHelper->getConfig($key, $default, $this->formConfig); |
564
|
|
|
} |
565
|
|
|
|
566
|
|
|
/** |
567
|
|
|
* Set form options. |
568
|
|
|
* |
569
|
|
|
* @param array $formOptions |
570
|
|
|
* @return $this |
571
|
|
|
*/ |
572
|
132 |
|
public function setFormOptions(array $formOptions) |
573
|
|
|
{ |
574
|
132 |
|
$this->formOptions = $this->formHelper->mergeOptions($this->formOptions, $formOptions); |
575
|
132 |
|
$this->checkIfNamedForm(); |
576
|
132 |
|
$this->pullFromOptions('data', 'addData'); |
577
|
132 |
|
$this->pullFromOptions('model', 'setupModel'); |
578
|
132 |
|
$this->pullFromOptions('errors_enabled', 'setErrorsEnabled'); |
579
|
132 |
|
$this->pullFromOptions('client_validation', 'setClientValidationEnabled'); |
580
|
132 |
|
$this->pullFromOptions('template_prefix', 'setTemplatePrefix'); |
581
|
132 |
|
$this->pullFromOptions('language_name', 'setLanguageName'); |
582
|
132 |
|
$this->pullFromOptions('translation_template', 'setTranslationTemplate'); |
583
|
|
|
|
584
|
132 |
|
return $this; |
585
|
|
|
} |
586
|
|
|
|
587
|
|
|
/** |
588
|
|
|
* Get an option from provided options and call method with that value. |
589
|
|
|
* |
590
|
|
|
* @param string $name |
591
|
|
|
* @param string $method |
592
|
|
|
*/ |
593
|
132 |
|
protected function pullFromOptions($name, $method) |
594
|
|
|
{ |
595
|
132 |
|
if (Arr::get($this->formOptions, $name) !== null) { |
596
|
20 |
|
$this->{$method}(Arr::pull($this->formOptions, $name)); |
597
|
|
|
} |
598
|
132 |
|
} |
599
|
|
|
|
600
|
|
|
/** |
601
|
|
|
* Get form http method. |
602
|
|
|
* |
603
|
|
|
* @return string |
604
|
|
|
*/ |
605
|
3 |
|
public function getMethod() |
606
|
|
|
{ |
607
|
3 |
|
return $this->formOptions['method']; |
608
|
|
|
} |
609
|
|
|
|
610
|
|
|
/** |
611
|
|
|
* Set form http method. |
612
|
|
|
* |
613
|
|
|
* @param string $method |
614
|
|
|
* @return $this |
615
|
|
|
*/ |
616
|
1 |
|
public function setMethod($method) |
617
|
|
|
{ |
618
|
1 |
|
$this->formOptions['method'] = $method; |
619
|
|
|
|
620
|
1 |
|
return $this; |
621
|
|
|
} |
622
|
|
|
|
623
|
|
|
/** |
624
|
|
|
* Get form action url. |
625
|
|
|
* |
626
|
|
|
* @return string |
627
|
|
|
*/ |
628
|
3 |
|
public function getUrl() |
629
|
|
|
{ |
630
|
3 |
|
return $this->formOptions['url']; |
631
|
|
|
} |
632
|
|
|
|
633
|
|
|
/** |
634
|
|
|
* Set form action url. |
635
|
|
|
* |
636
|
|
|
* @param string $url |
637
|
|
|
* @return $this |
638
|
|
|
*/ |
639
|
1 |
|
public function setUrl($url) |
640
|
|
|
{ |
641
|
1 |
|
$this->formOptions['url'] = $url; |
642
|
|
|
|
643
|
1 |
|
return $this; |
644
|
|
|
} |
645
|
|
|
|
646
|
|
|
/** |
647
|
|
|
* Returns the name of the form. |
648
|
|
|
* |
649
|
|
|
* @return string|null |
650
|
|
|
*/ |
651
|
72 |
|
public function getName() |
652
|
|
|
{ |
653
|
72 |
|
return $this->name; |
654
|
|
|
} |
655
|
|
|
|
656
|
|
|
/** |
657
|
|
|
* Get dot notation key for the form. |
658
|
|
|
* |
659
|
|
|
* @return string |
660
|
|
|
**/ |
661
|
14 |
|
public function getNameKey() |
662
|
|
|
{ |
663
|
14 |
|
return $this->formHelper->transformToDotSyntax($this->name); |
664
|
|
|
} |
665
|
|
|
|
666
|
|
|
/** |
667
|
|
|
* Set the name of the form. |
668
|
|
|
* |
669
|
|
|
* @param string $name |
670
|
|
|
* @param bool $rebuild |
671
|
|
|
* @return $this |
672
|
|
|
*/ |
673
|
13 |
|
public function setName($name, $rebuild = true) |
674
|
|
|
{ |
675
|
13 |
|
$this->name = $name; |
676
|
|
|
|
677
|
13 |
|
if ($rebuild) { |
678
|
13 |
|
$this->rebuildForm(); |
679
|
|
|
} |
680
|
|
|
|
681
|
13 |
|
return $this; |
682
|
|
|
} |
683
|
|
|
|
684
|
|
|
/** |
685
|
|
|
* Get model that is bind to form object. |
686
|
|
|
* |
687
|
|
|
* @return mixed |
688
|
|
|
*/ |
689
|
99 |
|
public function getModel() |
690
|
|
|
{ |
691
|
99 |
|
return $this->model; |
692
|
|
|
} |
693
|
|
|
|
694
|
|
|
/** |
695
|
|
|
* Set model to form object. |
696
|
|
|
* |
697
|
|
|
* @param mixed $model |
698
|
|
|
* @return $this |
699
|
|
|
* @deprecated deprecated since 1.6.31, will be removed in 1.7 - pass model as option when creating a form |
700
|
|
|
*/ |
701
|
17 |
|
public function setModel($model) |
702
|
|
|
{ |
703
|
17 |
|
$this->model = $model; |
704
|
|
|
|
705
|
17 |
|
$this->rebuildForm(); |
706
|
|
|
|
707
|
17 |
|
return $this; |
708
|
|
|
} |
709
|
|
|
|
710
|
|
|
/** |
711
|
|
|
* Setup model for form, add namespace if needed for child forms. |
712
|
|
|
* |
713
|
|
|
* @return $this |
714
|
|
|
*/ |
715
|
12 |
|
protected function setupModel($model) |
716
|
|
|
{ |
717
|
12 |
|
$this->model = $model; |
718
|
12 |
|
$this->setupNamedModel(); |
719
|
|
|
|
720
|
12 |
|
return $this; |
721
|
|
|
} |
722
|
|
|
|
723
|
|
|
/** |
724
|
|
|
* Get all fields. |
725
|
|
|
* |
726
|
|
|
* @return FormField[] |
727
|
|
|
*/ |
728
|
132 |
|
public function getFields() |
729
|
|
|
{ |
730
|
132 |
|
return $this->fields; |
731
|
|
|
} |
732
|
|
|
|
733
|
|
|
/** |
734
|
|
|
* Get field dynamically. |
735
|
|
|
* |
736
|
|
|
* @param string $name |
737
|
|
|
* @return FormField |
738
|
|
|
*/ |
739
|
20 |
|
public function __get($name) |
740
|
|
|
{ |
741
|
20 |
|
if ($this->has($name)) { |
742
|
19 |
|
return $this->getField($name); |
743
|
|
|
} |
744
|
3 |
|
} |
745
|
|
|
|
746
|
|
|
/** |
747
|
|
|
* Check if field exists when fetched using magic methods. |
748
|
|
|
* |
749
|
|
|
* @param string $name |
750
|
|
|
* @return bool |
751
|
|
|
*/ |
752
|
|
|
public function __isset($name) |
753
|
|
|
{ |
754
|
|
|
return $this->has($name); |
755
|
|
|
} |
756
|
|
|
|
757
|
|
|
/** |
758
|
|
|
* Set the Event Dispatcher to fire Laravel events. |
759
|
|
|
* |
760
|
|
|
* @param EventDispatcher $eventDispatcher |
761
|
|
|
* @return $this |
762
|
|
|
*/ |
763
|
132 |
|
public function setEventDispatcher(EventDispatcher $eventDispatcher) |
764
|
|
|
{ |
765
|
132 |
|
$this->eventDispatcher = $eventDispatcher; |
766
|
|
|
|
767
|
132 |
|
return $this; |
768
|
|
|
} |
769
|
|
|
|
770
|
|
|
/** |
771
|
|
|
* Set the form helper only on first instantiation. |
772
|
|
|
* |
773
|
|
|
* @param FormHelper $formHelper |
774
|
|
|
* @return $this |
775
|
|
|
*/ |
776
|
132 |
|
public function setFormHelper(FormHelper $formHelper) |
777
|
|
|
{ |
778
|
132 |
|
$this->formHelper = $formHelper; |
779
|
|
|
|
780
|
132 |
|
return $this; |
781
|
|
|
} |
782
|
|
|
|
783
|
|
|
/** |
784
|
|
|
* Get form helper. |
785
|
|
|
* |
786
|
|
|
* @return FormHelper |
787
|
|
|
*/ |
788
|
104 |
|
public function getFormHelper() |
789
|
|
|
{ |
790
|
104 |
|
return $this->formHelper; |
791
|
|
|
} |
792
|
|
|
|
793
|
|
|
/** |
794
|
|
|
* Add custom field. |
795
|
|
|
* |
796
|
|
|
* @param $name |
797
|
|
|
* @param $class |
798
|
|
|
*/ |
799
|
3 |
|
public function addCustomField($name, $class) |
800
|
|
|
{ |
801
|
3 |
|
if ($this->rebuilding && $this->formHelper->hasCustomField($name)) { |
802
|
|
|
return $this; |
803
|
|
|
} |
804
|
|
|
|
805
|
3 |
|
$this->formHelper->addCustomField($name, $class); |
806
|
3 |
|
} |
807
|
|
|
|
808
|
|
|
/** |
809
|
|
|
* Returns wether form errors should be shown under every field. |
810
|
|
|
* |
811
|
|
|
* @return bool |
812
|
|
|
*/ |
813
|
104 |
|
public function haveErrorsEnabled() |
814
|
|
|
{ |
815
|
104 |
|
return $this->showFieldErrors; |
816
|
|
|
} |
817
|
|
|
|
818
|
|
|
/** |
819
|
|
|
* Enable or disable showing errors under fields |
820
|
|
|
* |
821
|
|
|
* @param bool $enabled |
822
|
|
|
* @return $this |
823
|
|
|
*/ |
824
|
1 |
|
public function setErrorsEnabled($enabled) |
825
|
|
|
{ |
826
|
1 |
|
$this->showFieldErrors = (bool) $enabled; |
827
|
|
|
|
828
|
1 |
|
return $this; |
829
|
|
|
} |
830
|
|
|
|
831
|
|
|
/** |
832
|
|
|
* Is client validation enabled? |
833
|
|
|
* |
834
|
|
|
* @return bool |
835
|
|
|
*/ |
836
|
104 |
|
public function clientValidationEnabled() |
837
|
|
|
{ |
838
|
104 |
|
return $this->clientValidationEnabled; |
839
|
|
|
} |
840
|
|
|
|
841
|
|
|
/** |
842
|
|
|
* Enable/disable client validation. |
843
|
|
|
* |
844
|
|
|
* @param bool $enable |
845
|
|
|
* @return $this |
846
|
|
|
*/ |
847
|
2 |
|
public function setClientValidationEnabled($enable) |
848
|
|
|
{ |
849
|
2 |
|
$this->clientValidationEnabled = (bool) $enable; |
850
|
|
|
|
851
|
2 |
|
return $this; |
852
|
|
|
} |
853
|
|
|
|
854
|
|
|
/** |
855
|
|
|
* Add any aditional data that field needs (ex. array of choices). |
856
|
|
|
* |
857
|
|
|
* @deprecated deprecated since 1.6.20, will be removed in 1.7 - use 3rd param on create, or 2nd on plain method to pass data |
858
|
|
|
* will be switched to protected in 1.7. |
859
|
|
|
* @param string $name |
860
|
|
|
* @param mixed $data |
861
|
|
|
*/ |
862
|
1 |
|
public function setData($name, $data) |
863
|
|
|
{ |
864
|
1 |
|
$this->data[$name] = $data; |
865
|
1 |
|
} |
866
|
|
|
|
867
|
|
|
/** |
868
|
|
|
* Get single additional data. |
869
|
|
|
* |
870
|
|
|
* @param string $name |
871
|
|
|
* @param null $default |
872
|
|
|
* @return mixed |
873
|
|
|
*/ |
874
|
20 |
|
public function getData($name = null, $default = null) |
875
|
|
|
{ |
876
|
20 |
|
if (is_null($name)) { |
877
|
19 |
|
return $this->data; |
878
|
|
|
} |
879
|
|
|
|
880
|
1 |
|
return Arr::get($this->data, $name, $default); |
881
|
|
|
} |
882
|
|
|
|
883
|
|
|
/** |
884
|
|
|
* Add multiple peices of data at once. |
885
|
|
|
* |
886
|
|
|
* @deprecated deprecated since 1.6.12, will be removed in 1.7 - use 3rd param on create, or 2nd on plain method to pass data |
887
|
|
|
* will be switched to protected in 1.7. |
888
|
|
|
* @param $data |
889
|
|
|
* @return $this |
890
|
|
|
**/ |
891
|
132 |
|
public function addData(array $data) |
892
|
|
|
{ |
893
|
132 |
|
foreach ($data as $key => $value) { |
894
|
1 |
|
$this->setData($key, $value); |
|
|
|
|
895
|
|
|
} |
896
|
|
|
|
897
|
132 |
|
return $this; |
898
|
|
|
} |
899
|
|
|
|
900
|
|
|
/** |
901
|
|
|
* Get current request. |
902
|
|
|
* |
903
|
|
|
* @return \Illuminate\Http\Request |
904
|
|
|
*/ |
905
|
104 |
|
public function getRequest() |
906
|
|
|
{ |
907
|
104 |
|
return $this->request; |
908
|
|
|
} |
909
|
|
|
|
910
|
|
|
/** |
911
|
|
|
* Set request on form. |
912
|
|
|
* |
913
|
|
|
* @param Request $request |
914
|
|
|
* @return $this |
915
|
|
|
*/ |
916
|
132 |
|
public function setRequest(Request $request) |
917
|
|
|
{ |
918
|
132 |
|
$this->request = $request; |
919
|
|
|
|
920
|
132 |
|
return $this; |
921
|
|
|
} |
922
|
|
|
|
923
|
|
|
/** |
924
|
|
|
* Get template prefix that is prepended to all template paths. |
925
|
|
|
* |
926
|
|
|
* @return string |
927
|
|
|
*/ |
928
|
40 |
|
public function getTemplatePrefix() |
929
|
|
|
{ |
930
|
40 |
|
if ($this->templatePrefix !== null) { |
931
|
4 |
|
return $this->templatePrefix; |
932
|
|
|
} |
933
|
|
|
|
934
|
36 |
|
return $this->getConfig('template_prefix'); |
935
|
|
|
} |
936
|
|
|
|
937
|
|
|
/** |
938
|
|
|
* Set a template prefix for the form and its fields. |
939
|
|
|
* |
940
|
|
|
* @param string $prefix |
941
|
|
|
* @return $this |
942
|
|
|
*/ |
943
|
4 |
|
public function setTemplatePrefix($prefix) |
944
|
|
|
{ |
945
|
4 |
|
$this->templatePrefix = (string) $prefix; |
946
|
|
|
|
947
|
4 |
|
return $this; |
948
|
|
|
} |
949
|
|
|
|
950
|
|
|
/** |
951
|
|
|
* Get the language name. |
952
|
|
|
* |
953
|
|
|
* @return string |
954
|
|
|
*/ |
955
|
101 |
|
public function getLanguageName() |
956
|
|
|
{ |
957
|
101 |
|
return $this->languageName; |
958
|
|
|
} |
959
|
|
|
|
960
|
|
|
/** |
961
|
|
|
* Set a language name, used as prefix for translated strings. |
962
|
|
|
* |
963
|
|
|
* @param string $prefix |
964
|
|
|
* @return $this |
965
|
|
|
*/ |
966
|
13 |
|
public function setLanguageName($prefix) |
967
|
|
|
{ |
968
|
13 |
|
$this->languageName = (string) $prefix; |
969
|
|
|
|
970
|
13 |
|
return $this; |
971
|
|
|
} |
972
|
|
|
|
973
|
|
|
/** |
974
|
|
|
* Get the translation template. |
975
|
|
|
* |
976
|
|
|
* @return string |
977
|
|
|
*/ |
978
|
103 |
|
public function getTranslationTemplate() |
979
|
|
|
{ |
980
|
103 |
|
return $this->translationTemplate; |
981
|
|
|
} |
982
|
|
|
|
983
|
|
|
/** |
984
|
|
|
* Set a translation template, used to determine labels for fields. |
985
|
|
|
* |
986
|
|
|
* @param string $template |
987
|
|
|
* @return $this |
988
|
|
|
*/ |
989
|
11 |
|
public function setTranslationTemplate($template) |
990
|
|
|
{ |
991
|
11 |
|
$this->translationTemplate = (string) $template; |
992
|
|
|
|
993
|
11 |
|
return $this; |
994
|
|
|
} |
995
|
|
|
|
996
|
|
|
/** |
997
|
|
|
* Render the form. |
998
|
|
|
* |
999
|
|
|
* @param array $options |
1000
|
|
|
* @param array $fields |
1001
|
|
|
* @param bool $showStart |
1002
|
|
|
* @param bool $showFields |
1003
|
|
|
* @param bool $showEnd |
1004
|
|
|
* @return string |
1005
|
|
|
*/ |
1006
|
10 |
|
protected function render($options, $fields, $showStart, $showFields, $showEnd) |
1007
|
|
|
{ |
1008
|
10 |
|
$formOptions = $this->buildFormOptionsForFormBuilder( |
1009
|
10 |
|
$this->formHelper->mergeOptions($this->formOptions, $options) |
1010
|
|
|
); |
1011
|
|
|
|
1012
|
10 |
|
$this->setupNamedModel(); |
1013
|
|
|
|
1014
|
10 |
|
return $this->formHelper->getView() |
1015
|
10 |
|
->make($this->getTemplate()) |
1016
|
10 |
|
->with(compact('showStart', 'showFields', 'showEnd')) |
1017
|
10 |
|
->with('formOptions', $formOptions) |
1018
|
10 |
|
->with('fields', $fields) |
1019
|
10 |
|
->with('model', $this->getModel()) |
1020
|
10 |
|
->with('exclude', $this->exclude) |
1021
|
10 |
|
->with('form', $this) |
1022
|
10 |
|
->render(); |
1023
|
|
|
} |
1024
|
|
|
|
1025
|
|
|
/** |
1026
|
|
|
* @param $formOptions |
1027
|
|
|
* @return array |
1028
|
|
|
*/ |
1029
|
10 |
|
protected function buildFormOptionsForFormBuilder($formOptions) |
1030
|
|
|
{ |
1031
|
10 |
|
$reserved = ['method', 'url', 'route', 'action', 'files']; |
1032
|
10 |
|
$formAttributes = Arr::get($formOptions, 'attr', []); |
1033
|
|
|
|
1034
|
|
|
// move string value to `attr` to maintain backward compatibility |
1035
|
10 |
|
foreach ($formOptions as $key => $formOption) { |
1036
|
10 |
|
if (!in_array($formOption, $reserved) && is_string($formOption)) { |
1037
|
10 |
|
$formAttributes[$key] = $formOption; |
1038
|
|
|
} |
1039
|
|
|
} |
1040
|
|
|
|
1041
|
10 |
|
return array_merge( |
1042
|
10 |
|
$formAttributes, Arr::only($formOptions, $reserved) |
1043
|
|
|
); |
1044
|
|
|
} |
1045
|
|
|
|
1046
|
|
|
|
1047
|
|
|
/** |
1048
|
|
|
* Get template from options if provided, otherwise fallback to config. |
1049
|
|
|
* |
1050
|
|
|
* @return mixed |
1051
|
|
|
*/ |
1052
|
10 |
|
protected function getTemplate() |
1053
|
|
|
{ |
1054
|
10 |
|
return $this->getTemplatePrefix() . $this->getFormOption('template', $this->getConfig('form')); |
1055
|
|
|
} |
1056
|
|
|
|
1057
|
|
|
/** |
1058
|
|
|
* Get all fields that are not rendered. |
1059
|
|
|
* |
1060
|
|
|
* @return array |
1061
|
|
|
*/ |
1062
|
2 |
|
protected function getUnrenderedFields() |
1063
|
|
|
{ |
1064
|
2 |
|
$unrenderedFields = []; |
1065
|
|
|
|
1066
|
2 |
|
foreach ($this->fields as $field) { |
1067
|
2 |
|
if (!$field->isRendered()) { |
1068
|
2 |
|
$unrenderedFields[] = $field; |
1069
|
2 |
|
continue; |
1070
|
|
|
} |
1071
|
|
|
} |
1072
|
|
|
|
1073
|
2 |
|
return $unrenderedFields; |
1074
|
|
|
} |
1075
|
|
|
|
1076
|
|
|
/** |
1077
|
|
|
* Prevent adding fields with same name. |
1078
|
|
|
* |
1079
|
|
|
* @param string $name |
1080
|
|
|
* @throws \InvalidArgumentException |
1081
|
|
|
* @return void |
1082
|
|
|
*/ |
1083
|
64 |
|
protected function preventDuplicate($name) |
1084
|
|
|
{ |
1085
|
64 |
|
if ($this->has($name)) { |
1086
|
1 |
|
throw new \InvalidArgumentException('Field ['.$name.'] already exists in the form '.get_class($this)); |
1087
|
|
|
} |
1088
|
64 |
|
} |
1089
|
|
|
|
1090
|
|
|
/** |
1091
|
|
|
* Returns and checks the type of the field. |
1092
|
|
|
* |
1093
|
|
|
* @param string $type |
1094
|
|
|
* @return string |
1095
|
|
|
*/ |
1096
|
68 |
|
protected function getFieldType($type) |
1097
|
|
|
{ |
1098
|
68 |
|
$fieldType = $this->formHelper->getFieldType($type); |
1099
|
|
|
|
1100
|
67 |
|
return $fieldType; |
1101
|
|
|
} |
1102
|
|
|
|
1103
|
|
|
/** |
1104
|
|
|
* Check if form is named form. |
1105
|
|
|
* |
1106
|
|
|
* @return void |
1107
|
|
|
*/ |
1108
|
132 |
|
protected function checkIfNamedForm() |
1109
|
|
|
{ |
1110
|
132 |
|
if ($this->getFormOption('name')) { |
1111
|
8 |
|
$this->name = Arr::pull($this->formOptions, 'name', $this->name); |
1112
|
|
|
} |
1113
|
132 |
|
} |
1114
|
|
|
|
1115
|
|
|
/** |
1116
|
|
|
* Set up options on single field depending on form options. |
1117
|
|
|
* |
1118
|
|
|
* @param string $name |
1119
|
|
|
* @param $options |
1120
|
|
|
*/ |
1121
|
68 |
|
protected function setupFieldOptions($name, &$options) |
1122
|
|
|
{ |
1123
|
68 |
|
$options['real_name'] = $name; |
1124
|
68 |
|
} |
1125
|
|
|
|
1126
|
|
|
/** |
1127
|
|
|
* Set namespace to model if form is named so the data is bound properly. |
1128
|
|
|
* Returns true if model is changed, otherwise false. |
1129
|
|
|
* |
1130
|
|
|
* @return bool |
1131
|
|
|
*/ |
1132
|
22 |
|
protected function setupNamedModel() |
1133
|
|
|
{ |
1134
|
22 |
|
if (!$this->getModel() || !$this->getName()) { |
1135
|
20 |
|
return false; |
1136
|
|
|
} |
1137
|
|
|
|
1138
|
3 |
|
$dotName = $this->getNameKey(); |
1139
|
3 |
|
$model = $this->formHelper->convertModelToArray($this->getModel()); |
1140
|
3 |
|
$isCollectionFormModel = (bool) preg_match('/^.*\.\d+$/', $dotName); |
1141
|
3 |
|
$isCollectionPrototype = strpos($dotName, '__NAME__') !== false; |
1142
|
|
|
|
1143
|
3 |
|
if (!Arr::get($model, $dotName) && !$isCollectionFormModel && !$isCollectionPrototype) { |
|
|
|
|
1144
|
1 |
|
$newModel = []; |
1145
|
1 |
|
Arr::set($newModel, $dotName, $model); |
1146
|
1 |
|
$this->model = $newModel; |
1147
|
|
|
|
1148
|
1 |
|
return true; |
1149
|
|
|
} |
1150
|
|
|
|
1151
|
2 |
|
return false; |
1152
|
|
|
} |
1153
|
|
|
|
1154
|
|
|
/** |
1155
|
|
|
* Set form builder instance on helper so we can use it later. |
1156
|
|
|
* |
1157
|
|
|
* @param FormBuilder $formBuilder |
1158
|
|
|
* @return $this |
1159
|
|
|
*/ |
1160
|
132 |
|
public function setFormBuilder(FormBuilder $formBuilder) |
1161
|
|
|
{ |
1162
|
132 |
|
$this->formBuilder = $formBuilder; |
1163
|
|
|
|
1164
|
132 |
|
return $this; |
1165
|
|
|
} |
1166
|
|
|
|
1167
|
|
|
/** |
1168
|
|
|
* Returns the instance of the FormBuilder. |
1169
|
|
|
* |
1170
|
|
|
* @return FormBuilder |
1171
|
|
|
*/ |
1172
|
21 |
|
public function getFormBuilder() |
1173
|
|
|
{ |
1174
|
21 |
|
return $this->formBuilder; |
1175
|
|
|
} |
1176
|
|
|
|
1177
|
|
|
/** |
1178
|
|
|
* Set the Validator instance on this so we can use it later. |
1179
|
|
|
* |
1180
|
|
|
* @param ValidatorFactory $validator |
1181
|
|
|
* @return $this |
1182
|
|
|
*/ |
1183
|
132 |
|
public function setValidator(ValidatorFactory $validator) |
1184
|
|
|
{ |
1185
|
132 |
|
$this->validatorFactory = $validator; |
1186
|
|
|
|
1187
|
132 |
|
return $this; |
1188
|
|
|
} |
1189
|
|
|
|
1190
|
|
|
/** |
1191
|
|
|
* Returns the validator instance. |
1192
|
|
|
* |
1193
|
|
|
* @return Validator |
1194
|
|
|
*/ |
1195
|
1 |
|
public function getValidator() |
1196
|
|
|
{ |
1197
|
1 |
|
return $this->validator; |
1198
|
|
|
} |
1199
|
|
|
|
1200
|
|
|
/** |
1201
|
|
|
* Exclude some fields from rendering. |
1202
|
|
|
* |
1203
|
|
|
* @return $this |
1204
|
|
|
*/ |
1205
|
|
|
public function exclude(array $fields) |
1206
|
|
|
{ |
1207
|
|
|
$this->exclude = array_merge($this->exclude, $fields); |
1208
|
|
|
|
1209
|
|
|
return $this; |
1210
|
|
|
} |
1211
|
|
|
|
1212
|
|
|
/** |
1213
|
|
|
* If form is named form, modify names to be contained in single key (parent[child_field_name]). |
1214
|
|
|
* |
1215
|
|
|
* @param string $name |
1216
|
|
|
* @return string |
1217
|
|
|
*/ |
1218
|
68 |
|
protected function getFieldName($name) |
1219
|
|
|
{ |
1220
|
68 |
|
$formName = $this->getName(); |
1221
|
68 |
|
if ($formName !== null) { |
1222
|
15 |
|
if (strpos($formName, '[') !== false || strpos($formName, ']') !== false) { |
1223
|
6 |
|
return $this->formHelper->transformToBracketSyntax( |
1224
|
6 |
|
$this->formHelper->transformToDotSyntax( |
1225
|
6 |
|
$formName . '[' . $name . ']' |
1226
|
|
|
) |
1227
|
|
|
); |
1228
|
|
|
} |
1229
|
|
|
|
1230
|
12 |
|
return $formName . '[' . $name . ']'; |
1231
|
|
|
} |
1232
|
|
|
|
1233
|
68 |
|
return $name; |
1234
|
|
|
} |
1235
|
|
|
|
1236
|
|
|
/** |
1237
|
|
|
* Disable all fields in a form. |
1238
|
|
|
*/ |
1239
|
1 |
|
public function disableFields() |
1240
|
|
|
{ |
1241
|
1 |
|
foreach ($this->fields as $field) { |
1242
|
1 |
|
$field->disable(); |
1243
|
|
|
} |
1244
|
1 |
|
} |
1245
|
|
|
|
1246
|
|
|
/** |
1247
|
|
|
* Enable all fields in a form. |
1248
|
|
|
*/ |
1249
|
1 |
|
public function enableFields() |
1250
|
|
|
{ |
1251
|
1 |
|
foreach ($this->fields as $field) { |
1252
|
1 |
|
$field->enable(); |
1253
|
|
|
} |
1254
|
1 |
|
} |
1255
|
|
|
|
1256
|
|
|
/** |
1257
|
|
|
* Validate the form. |
1258
|
|
|
* |
1259
|
|
|
* @param array $validationRules |
1260
|
|
|
* @param array $messages |
1261
|
|
|
* @return Validator |
1262
|
|
|
*/ |
1263
|
10 |
|
public function validate($validationRules = [], $messages = []) |
1264
|
|
|
{ |
1265
|
10 |
|
$fieldRules = $this->formHelper->mergeFieldsRules($this->fields); |
1266
|
10 |
|
$rules = array_merge($fieldRules->getRules(), $validationRules); |
1267
|
10 |
|
$messages = array_merge($fieldRules->getMessages(), $messages); |
1268
|
|
|
|
1269
|
10 |
|
$this->validator = $this->validatorFactory->make($this->getRequest()->all(), $rules, $messages); |
1270
|
10 |
|
$this->validator->setAttributeNames($fieldRules->getAttributes()); |
1271
|
|
|
|
1272
|
10 |
|
$this->eventDispatcher->dispatch(new BeforeFormValidation($this, $this->validator)); |
1273
|
|
|
|
1274
|
10 |
|
return $this->validator; |
1275
|
|
|
} |
1276
|
|
|
|
1277
|
|
|
/** |
1278
|
|
|
* Get validation rules for the form. |
1279
|
|
|
* |
1280
|
|
|
* @param array $overrideRules |
1281
|
|
|
* @return array |
1282
|
|
|
*/ |
1283
|
1 |
|
public function getRules($overrideRules = []) |
1284
|
|
|
{ |
1285
|
1 |
|
$fieldRules = $this->formHelper->mergeFieldsRules($this->fields); |
1286
|
|
|
|
1287
|
1 |
|
return array_merge($fieldRules->getRules(), $overrideRules); |
1288
|
|
|
} |
1289
|
|
|
|
1290
|
|
|
/** |
1291
|
|
|
* Redirects to a destination when form is invalid. |
1292
|
|
|
* |
1293
|
|
|
* @param string|null $destination The target url. |
1294
|
|
|
* @return HttpResponseException |
1295
|
|
|
*/ |
1296
|
3 |
|
public function redirectIfNotValid($destination = null) |
1297
|
|
|
{ |
1298
|
3 |
|
if (! $this->isValid()) { |
1299
|
3 |
|
$response = redirect($destination); |
1300
|
|
|
|
1301
|
3 |
|
if (is_null($destination)) { |
1302
|
2 |
|
$response = $response->back(); |
1303
|
|
|
} |
1304
|
|
|
|
1305
|
3 |
|
$response = $response->withErrors($this->getErrors(), $this->getErrorBag())->withInput(); |
1306
|
|
|
|
1307
|
3 |
|
throw new HttpResponseException($response); |
1308
|
|
|
} |
1309
|
|
|
} |
1310
|
|
|
|
1311
|
|
|
/** |
1312
|
|
|
* Get all form field attributes, including child forms, in a flat array. |
1313
|
|
|
* |
1314
|
|
|
* @return array |
1315
|
|
|
*/ |
1316
|
3 |
|
public function getAllAttributes() |
1317
|
|
|
{ |
1318
|
3 |
|
return $this->formHelper->mergeAttributes($this->fields); |
1319
|
|
|
} |
1320
|
|
|
|
1321
|
|
|
/** |
1322
|
|
|
* Check if the form is valid. |
1323
|
|
|
* |
1324
|
|
|
* @return bool |
1325
|
|
|
*/ |
1326
|
10 |
|
public function isValid() |
1327
|
|
|
{ |
1328
|
10 |
|
if (!$this->validator) { |
1329
|
9 |
|
$this->validate(); |
1330
|
|
|
} |
1331
|
|
|
|
1332
|
10 |
|
$isValid = !$this->validator->fails(); |
1333
|
|
|
|
1334
|
10 |
|
$this->formHelper->alterValid($this, $this, $isValid); |
1335
|
|
|
|
1336
|
10 |
|
$this->eventDispatcher->dispatch(new AfterFormValidation($this, $this->validator, $isValid)); |
1337
|
|
|
|
1338
|
10 |
|
return $isValid; |
1339
|
|
|
} |
1340
|
|
|
|
1341
|
|
|
/** |
1342
|
|
|
* Optionally change the validation result, and/or add error messages. |
1343
|
|
|
* |
1344
|
|
|
* @param Form $mainForm |
1345
|
|
|
* @param bool $isValid |
1346
|
|
|
* @return void|array |
1347
|
|
|
*/ |
1348
|
10 |
|
public function alterValid(Form $mainForm, &$isValid) |
|
|
|
|
1349
|
|
|
{ |
1350
|
|
|
// return ['name' => ['Some other error about the Name field.']]; |
1351
|
10 |
|
} |
1352
|
|
|
|
1353
|
|
|
/** |
1354
|
|
|
* Get validation errors. |
1355
|
|
|
* |
1356
|
|
|
* @return array |
1357
|
|
|
*/ |
1358
|
8 |
|
public function getErrors() |
1359
|
|
|
{ |
1360
|
8 |
|
if (!$this->validator || !$this->validator instanceof Validator) { |
1361
|
1 |
|
throw new \InvalidArgumentException( |
1362
|
1 |
|
sprintf( |
1363
|
1 |
|
'Form %s was not validated. To validate it, call "isValid" method before retrieving the errors', |
1364
|
1 |
|
get_class($this) |
1365
|
|
|
) |
1366
|
|
|
); |
1367
|
|
|
} |
1368
|
|
|
|
1369
|
7 |
|
return $this->validator->getMessageBag()->getMessages(); |
1370
|
|
|
} |
1371
|
|
|
|
1372
|
|
|
/** |
1373
|
|
|
* Get all Request values from all fields, and nothing else. |
1374
|
|
|
* |
1375
|
|
|
* @param bool $with_nulls |
1376
|
|
|
* @return array |
1377
|
|
|
*/ |
1378
|
3 |
|
public function getFieldValues($with_nulls = true) |
1379
|
|
|
{ |
1380
|
3 |
|
$request_values = $this->getRequest()->all(); |
1381
|
|
|
|
1382
|
3 |
|
$values = []; |
1383
|
3 |
|
foreach ($this->getAllAttributes() as $attribute) { |
1384
|
3 |
|
$value = Arr::get($request_values, $attribute); |
1385
|
3 |
|
if ($with_nulls || $value !== null) { |
1386
|
3 |
|
Arr::set($values, $attribute, $value); |
1387
|
|
|
} |
1388
|
|
|
} |
1389
|
|
|
|
1390
|
|
|
// If this form is a child form, cherry pick a part |
1391
|
3 |
|
if ($this->getName()) { |
|
|
|
|
1392
|
1 |
|
$prefix = $this->getNameKey(); |
1393
|
1 |
|
$values = Arr::get($values, $prefix); |
1394
|
|
|
} |
1395
|
|
|
|
1396
|
|
|
// Allow form-specific value alters |
1397
|
3 |
|
$this->formHelper->alterFieldValues($this, $values); |
1398
|
|
|
|
1399
|
3 |
|
return $values; |
1400
|
|
|
} |
1401
|
|
|
|
1402
|
|
|
/** |
1403
|
|
|
* Optionally mess with this form's $values before it's returned from getFieldValues(). |
1404
|
|
|
* |
1405
|
|
|
* @param array $values |
1406
|
|
|
* @return void |
1407
|
|
|
*/ |
1408
|
3 |
|
public function alterFieldValues(array &$values) |
|
|
|
|
1409
|
|
|
{ |
1410
|
3 |
|
} |
1411
|
|
|
|
1412
|
|
|
/** |
1413
|
|
|
* Throw an exception indicating a field does not exist on the class. |
1414
|
|
|
* |
1415
|
|
|
* @param string $name |
1416
|
|
|
* @throws \InvalidArgumentException |
1417
|
|
|
* @return void |
1418
|
|
|
*/ |
1419
|
2 |
|
protected function fieldDoesNotExist($name) |
1420
|
|
|
{ |
1421
|
2 |
|
throw new \InvalidArgumentException('Field ['.$name.'] does not exist in '.get_class($this)); |
1422
|
|
|
} |
1423
|
|
|
|
1424
|
|
|
/** |
1425
|
|
|
* Method filterFields used as *Main* method for starting |
1426
|
|
|
* filtering and request field mutating process. |
1427
|
|
|
* |
1428
|
|
|
* @return \Kris\LaravelFormBuilder\Form |
1429
|
|
|
*/ |
1430
|
132 |
|
public function filterFields() |
1431
|
|
|
{ |
1432
|
|
|
// If filtering is unlocked/allowed we can start with filtering process. |
1433
|
132 |
|
if (!$this->isFilteringLocked()) { |
1434
|
132 |
|
$filters = array_filter($this->getFilters()); |
1435
|
|
|
|
1436
|
132 |
|
if (count($filters)) { |
1437
|
1 |
|
$dotForm = $this->getNameKey(); |
1438
|
|
|
|
1439
|
1 |
|
$request = $this->getRequest(); |
1440
|
1 |
|
$requestData = $request->all(); |
1441
|
|
|
|
1442
|
1 |
|
foreach ($filters as $field => $fieldFilters) { |
1443
|
1 |
|
$dotField = $this->formHelper->transformToDotSyntax($field); |
1444
|
1 |
|
$fieldData = Arr::get($requestData, $dotField); |
1445
|
1 |
|
if ($fieldData !== null) { |
1446
|
|
|
// Assign current Raw/Unmutated value from request. |
1447
|
1 |
|
$localDotField = preg_replace('#^' . preg_quote("$dotForm.", '#') . '#', '', $dotField); |
1448
|
1 |
|
$localBracketField = $this->formHelper->transformToBracketSyntax($localDotField); |
1449
|
1 |
|
$this->getField($localBracketField)->setRawValue($fieldData); |
1450
|
1 |
|
foreach ($fieldFilters as $filter) { |
1451
|
1 |
|
$filterObj = FilterResolver::instance($filter); |
1452
|
1 |
|
$fieldData = $filterObj->filter($fieldData); |
1453
|
|
|
} |
1454
|
1 |
|
Arr::set($requestData, $dotField, $fieldData); |
1455
|
|
|
} |
1456
|
|
|
} |
1457
|
|
|
|
1458
|
1 |
|
foreach ($requestData as $name => $value) { |
1459
|
1 |
|
$request[$name] = $value; |
1460
|
|
|
} |
1461
|
|
|
} |
1462
|
|
|
} |
1463
|
|
|
|
1464
|
132 |
|
return $this; |
1465
|
|
|
} |
1466
|
|
|
|
1467
|
|
|
/** |
1468
|
|
|
* Method getFilters used to return array of all binded filters to form fields. |
1469
|
|
|
* |
1470
|
|
|
* @return array |
1471
|
|
|
*/ |
1472
|
132 |
|
public function getFilters() |
1473
|
|
|
{ |
1474
|
132 |
|
$filters = []; |
1475
|
132 |
|
foreach ($this->getFields() as $field) { |
1476
|
17 |
|
$filters[$field->getName()] = $field->getFilters(); |
1477
|
|
|
} |
1478
|
|
|
|
1479
|
132 |
|
return $filters; |
1480
|
|
|
} |
1481
|
|
|
|
1482
|
|
|
/** |
1483
|
|
|
* If lockFiltering is set to true then we will not |
1484
|
|
|
* filter fields and mutate request data binded to fields. |
1485
|
|
|
* |
1486
|
|
|
* @return \Kris\LaravelFormBuilder\Form |
1487
|
|
|
*/ |
1488
|
1 |
|
public function lockFiltering() |
1489
|
|
|
{ |
1490
|
1 |
|
$this->lockFiltering = true; |
1491
|
1 |
|
return $this; |
1492
|
|
|
} |
1493
|
|
|
|
1494
|
|
|
/** |
1495
|
|
|
* Unlock fields filtering/mutating. |
1496
|
|
|
* |
1497
|
|
|
* @return \Kris\LaravelFormBuilder\Form |
1498
|
|
|
*/ |
1499
|
|
|
public function unlockFiltering() |
1500
|
|
|
{ |
1501
|
|
|
$this->lockFiltering = false; |
1502
|
|
|
return $this; |
1503
|
|
|
} |
1504
|
|
|
|
1505
|
|
|
/** |
1506
|
|
|
* Method isFilteringLocked used to check |
1507
|
|
|
* if current filteringLocked property status is set to true. |
1508
|
|
|
* |
1509
|
|
|
* @return bool |
1510
|
|
|
*/ |
1511
|
132 |
|
public function isFilteringLocked() |
1512
|
|
|
{ |
1513
|
132 |
|
return !$this->lockFiltering ? false : true; |
1514
|
|
|
} |
1515
|
|
|
|
1516
|
|
|
/** |
1517
|
|
|
* Method getRawValues returns Unfiltered/Unmutated fields -> values. |
1518
|
|
|
* |
1519
|
|
|
* @return array |
1520
|
|
|
*/ |
1521
|
|
|
public function getRawValues() |
1522
|
|
|
{ |
1523
|
|
|
$rawValues = []; |
1524
|
|
|
foreach ($this->getFields() as $field) { |
1525
|
|
|
$rawValues[$field->getName()] = $field->getRawValue(); |
1526
|
|
|
} |
1527
|
|
|
|
1528
|
|
|
return $rawValues; |
1529
|
|
|
} |
1530
|
|
|
} |
1531
|
|
|
|
This method has been deprecated. The supplier of the class has supplied an explanatory message.
The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.