Completed
Push — master ( 4cd325...0e7ea3 )
by Kristijan
05:44
created

Form::getFieldValues()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 14
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 4

Importance

Changes 0
Metric Value
cc 4
eloc 8
nc 3
nop 1
dl 0
loc 14
rs 9.2
c 0
b 0
f 0
ccs 10
cts 10
cp 1
crap 4
1
<?php namespace Kris\LaravelFormBuilder;
2
3
use Illuminate\Contracts\Events\Dispatcher as EventDispatcher;
4
use Illuminate\Contracts\Validation\Factory as ValidatorFactory;
5
use Illuminate\Contracts\Validation\Validator;
6
use Illuminate\Http\Exception\HttpResponseException;
7
use Illuminate\Http\Request;
8
use Illuminate\Support\Arr;
9
use Kris\LaravelFormBuilder\Events\AfterFieldCreation;
10
use Kris\LaravelFormBuilder\Events\AfterFormValidation;
11
use Kris\LaravelFormBuilder\Events\BeforeFormValidation;
12
use Kris\LaravelFormBuilder\Fields\FormField;
13
14
class Form
15
{
16
17
    /**
18
     * All fields that are added
19
     *
20
     * @var array
21
     */
22
    protected $fields = [];
23
24
    /**
25
     * Model to use
26
     *
27
     * @var mixed
28
     */
29
    protected $model = [];
30
31
    /**
32
     * @var EventDispatcher
33
     */
34
    protected $eventDispatcher;
35
36
    /**
37
     * @var FormHelper
38
     */
39
    protected $formHelper;
40
41
    /**
42
     * Form options
43
     *
44
     * @var array
45
     */
46
    protected $formOptions = [
47
        'method' => 'GET',
48
        'url' => null
49
    ];
50
51
    /**
52
     * Additional data which can be used to build fields
53
     *
54
     * @var array
55
     */
56
    protected $data = [];
57
58
    /**
59
     * Should errors for each field be shown when called form($form) or form_rest($form) ?
60
     *
61
     * @var bool
62
     */
63
    protected $showFieldErrors = true;
64
65
    /**
66
     * Enable html5 validation
67
     *
68
     * @var bool
69
     */
70
    protected $clientValidationEnabled = true;
71
72
    /**
73
     * Name of the parent form if any
74
     *
75
     * @var string|null
76
     */
77
    protected $name = null;
78
79
    /**
80
     * @var FormBuilder
81
     */
82
    protected $formBuilder;
83
84
    /**
85
     * @var ValidatorFactory
86
     */
87
    protected $validatorFactory;
88
89
    /**
90
     * @var Validator
91
     */
92
    protected $validator = null;
93
94
    /**
95
     * @var Request
96
     */
97
    protected $request;
98
99
    /**
100
     * List of fields to not render
101
     *
102
     * @var array
103
     **/
104
    protected $exclude = [];
105
106
    /**
107
     * Are form being rebuilt?
108
     *
109
     * @var bool
110
     */
111
    protected $rebuilding = false;
112
113
    /**
114
     * @var string
115
     */
116
    protected $templatePrefix;
117
118
    /**
119
     * @var string
120
     */
121
    protected $languageName;
122
123
    /**
124
     * Build the form
125
     *
126
     * @return mixed
127
     */
128 2
    public function buildForm()
129
    {
130 2
    }
131
132
    /**
133
     * Rebuild the form from scratch
134
     *
135
     * @return $this
136
     */
137 15
    public function rebuildForm()
138
    {
139 15
        $this->rebuilding = true;
140
        // If form is plain, buildForm method is empty, so we need to take
141
        // existing fields and add them again
142 15
        if (get_class($this) === 'Kris\LaravelFormBuilder\Form') {
143 14
            foreach ($this->fields as $name => $field) {
144
                // Remove any temp variables added in previous instance
145 6
                $options = array_except($field->getOptions(), 'tmp');
146 6
                $this->add($name, $field->getType(), $options);
147 14
            }
148 14
        } else {
149 3
            $this->buildForm();
150
        }
151 15
        $this->rebuilding = false;
152
153 15
        return $this;
154
    }
155
156
    /**
157
     * Create the FormField object
158
     *
159
     * @param string $name
160
     * @param string $type
161
     * @param array  $options
162
     * @return FormField
163
     */
164 47
    protected function makeField($name, $type = 'text', array $options = [])
165
    {
166 47
        $this->setupFieldOptions($name, $options);
167
168 47
        $fieldName = $this->getFieldName($name);
169
170 47
        $fieldType = $this->getFieldType($type);
171
172 46
        $field = new $fieldType($fieldName, $type, $this, $options);
173
174 43
        $this->eventDispatcher->fire(new AfterFieldCreation($this, $field));
175
176 43
        return $field;
177
    }
178
179
    /**
180
     * Create a new field and add it to the form
181
     *
182
     * @param string $name
183
     * @param string $type
184
     * @param array  $options
185
     * @param bool   $modify
186
     * @return $this
187
     */
188 49
    public function add($name, $type = 'text', array $options = [], $modify = false)
189
    {
190 49
        $this->formHelper->checkFieldName($name, get_class($this));
191
192 47
        if ($this->rebuilding && !$this->has($name)) {
193
            return $this;
194
        }
195
196 47
        $this->addField($this->makeField($name, $type, $options), $modify);
197
198 43
        return $this;
199
    }
200
201
    /**
202
     * Add a FormField to the form's fields
203
     *
204
     * @param FormField $field
205
     * @return $this
206
     */
207 43
    protected function addField(FormField $field, $modify = false)
208
    {
209 43
        if (!$modify && !$this->rebuilding) {
210 43
            $this->preventDuplicate($field->getRealName());
211 43
        }
212
213
214 43
        if ($field->getType() == 'file') {
215 3
            $this->formOptions['files'] = true;
216 3
        }
217
218 43
        $this->fields[$field->getRealName()] = $field;
219
220 43
        return $this;
221
    }
222
223
    /**
224
     * Add field before another field
225
     *
226
     * @param string  $name         Name of the field before which new field is added
227
     * @param string  $fieldName    Field name which will be added
228
     * @param string  $type
229
     * @param array   $options
230
     * @param boolean $modify
231
     * @return $this
232
     */
233 1
    public function addBefore($name, $fieldName, $type = 'text', $options = [], $modify = false)
234
    {
235 1
        $offset = array_search($name, array_keys($this->fields));
236
237 1
        $beforeFields = array_slice($this->fields, 0, $offset);
238 1
        $afterFields = array_slice($this->fields, $offset);
239
240 1
        $this->fields = $beforeFields;
241
242 1
        $this->add($fieldName, $type, $options, $modify);
243
244 1
        $this->fields += $afterFields;
245
246 1
        return $this;
247
    }
248
249
    /**
250
     * Add field before another field
251
     * @param string  $name         Name of the field after which new field is added
252
     * @param string  $fieldName    Field name which will be added
253
     * @param string  $type
254
     * @param array   $options
255
     * @param boolean $modify
256
     * @return $this
257
     */
258 1
    public function addAfter($name, $fieldName, $type = 'text', $options = [], $modify = false)
259
    {
260 1
        $offset = array_search($name, array_keys($this->fields));
261
262 1
        $beforeFields = array_slice($this->fields, 0, $offset + 1);
263 1
        $afterFields = array_slice($this->fields, $offset + 1);
264
265 1
        $this->fields = $beforeFields;
266
267 1
        $this->add($fieldName, $type, $options, $modify);
268
269 1
        $this->fields += $afterFields;
270
271 1
        return $this;
272
    }
273
274
    /**
275
     * Take another form and add it's fields directly to this form
276
     * @param mixed   $class        Form to merge
277
     * @param array   $options
278
     * @param boolean $modify
279
     * @return $this
280
     */
281 1
    public function compose($class, array $options = [], $modify = false)
282
    {
283 1
        $options['class'] = $class;
284
285
        // If we pass a ready made form just extract the fields
286 1
        if ($class instanceof Form) {
287 1
            $fields = $class->getFields();
288 1
        } elseif ($class instanceof Fields\ChildFormType) {
289
            $fields = $class->getForm()->getFields();
290
        } elseif (is_string($class)) {
291
            // If its a string of a class make it the usual way
292
            $options['model'] = $this->model;
293
            $options['name'] = $this->name;
294
295
            $form = $this->formBuilder->create($class, $options);
296
            $fields = $form->getFields();
297
        } else {
298
            throw new \InvalidArgumentException(
299
                "[{$class}] is invalid. Please provide either a full class name, Form or ChildFormType"
300
            );
301
        }
302
303 1
        foreach ($fields as $field) {
304 1
            $this->addField($field, $modify);
305 1
        }
306
307 1
        return $this;
308
    }
309
310
    /**
311
     * Remove field with specified name from the form
312
     *
313
     * @param $name
314
     * @return $this
315
     */
316 2
    public function remove($name)
317
    {
318 2
        if ($this->has($name)) {
319 2
            unset($this->fields[$name]);
320 2
        }
321
322 2
        return $this;
323
    }
324
325
    /**
326
     * Modify existing field. If it doesn't exist, it is added to form
327
     *
328
     * @param        $name
329
     * @param string $type
330
     * @param array  $options
331
     * @param bool   $overwriteOptions
332
     * @return Form
333
     */
334 1
    public function modify($name, $type = 'text', array $options = [], $overwriteOptions = false)
335
    {
336
        // If we don't want to overwrite options, we merge them with old options
337 1
        if ($overwriteOptions === false && $this->has($name)) {
338 1
            $options = $this->formHelper->mergeOptions(
339 1
                $this->getField($name)->getOptions(),
340
                $options
341 1
            );
342 1
        }
343
344 1
        return $this->add($name, $type, $options, true);
345
    }
346
347
    /**
348
     * Render full form
349
     *
350
     * @param array $options
351
     * @param bool  $showStart
352
     * @param bool  $showFields
353
     * @param bool  $showEnd
354
     * @return string
355
     */
356 6
    public function renderForm(array $options = [], $showStart = true, $showFields = true, $showEnd = true)
357
    {
358 6
        return $this->render($options, $this->fields, $showStart, $showFields, $showEnd);
359
    }
360
361
    /**
362
     * Render rest of the form
363
     *
364
     * @param bool $showFormEnd
365
     * @param bool $showFields
366
     * @return string
367
     */
368 1
    public function renderRest($showFormEnd = true, $showFields = true)
369
    {
370 1
        $fields = $this->getUnrenderedFields();
371
372 1
        return $this->render([], $fields, false, $showFields, $showFormEnd);
373
    }
374
375
    /**
376
     * Renders the rest of the form up until the specified field name
377
     *
378
     * @param string $field_name
379
     * @param bool   $showFormEnd
380
     * @param bool   $showFields
381
     * @return string
382
     */
383 2
    public function renderUntil($field_name, $showFormEnd = true, $showFields = true)
384
    {
385 2
        if (!$this->has($field_name)) {
386 1
            $this->fieldDoesNotExist($field_name);
387
        }
388
389 1
        $fields = $this->getUnrenderedFields();
390
391 1
        $i = 1;
392 1
        foreach ($fields as $key => $value) {
393 1
            if ($value->getRealName() == $field_name) {
394 1
                break;
395
            }
396 1
            $i++;
397 1
        }
398
399 1
        $fields = array_slice($fields, 0, $i, true);
400
401 1
        return $this->render([], $fields, false, $showFields, $showFormEnd);
402
    }
403
404
    /**
405
     * Get single field instance from form object
406
     *
407
     * @param $name
408
     * @return FormField
409
     */
410 24
    public function getField($name)
411
    {
412 24
        if ($this->has($name)) {
413 23
            return $this->fields[$name];
414
        }
415
416 1
        $this->fieldDoesNotExist($name);
417
    }
418
419
    /**
420
     * Check if form has field
421
     *
422
     * @param $name
423
     * @return bool
424
     */
425 43
    public function has($name)
426
    {
427 43
        return array_key_exists($name, $this->fields);
428
    }
429
430
    /**
431
     * Get all form options
432
     *
433
     * @return array
434
     */
435 2
    public function getFormOptions()
436
    {
437 2
        return $this->formOptions;
438
    }
439
440
    /**
441
     * Get single form option
442
     *
443
     * @param string $option
444
     * @param $default
445
     * @return mixed
446
     */
447 102
    public function getFormOption($option, $default = null)
448
    {
449 102
        return array_get($this->formOptions, $option, $default);
450
    }
451
452
    /**
453
     * Set single form option on form
454
     *
455
     * @param string $option
456
     * @param mixed $value
457
     *
458
     * @return $this
459
     */
460 2
    public function setFormOption($option, $value)
461
    {
462 2
        $this->formOptions[$option] = $value;
463
464 2
        return $this;
465
    }
466
467
    /**
468
     * Set form options
469
     *
470
     * @param array $formOptions
471
     * @return $this
472
     */
473 102
    public function setFormOptions($formOptions)
474
    {
475 102
        $this->formOptions = $this->formHelper->mergeOptions($this->formOptions, $formOptions);
476 102
        $this->checkIfNamedForm();
477 102
        $this->pullFromOptions('data', 'addData');
478 102
        $this->pullFromOptions('model', 'setupModel');
479 102
        $this->pullFromOptions('errors_enabled', 'setErrorsEnabled');
480 102
        $this->pullFromOptions('client_validation', 'setClientValidationEnabled');
481 102
        $this->pullFromOptions('template_prefix', 'setTemplatePrefix');
482 102
        $this->pullFromOptions('language_name', 'setLanguageName');
483
484 102
        return $this;
485
    }
486
487
    /**
488
     * Get an option from provided options and call method with that value
489
     *
490
     * @param $name
491
     * @param $method
492
     */
493 102
    protected function pullFromOptions($name, $method)
494
    {
495 102
        if (array_get($this->formOptions, $name) !== null) {
496 15
            $this->{$method}(array_pull($this->formOptions, $name));
497 15
        }
498 102
    }
499
500
    /**
501
     * Get form http method
502
     *
503
     * @return string
504
     */
505 3
    public function getMethod()
506
    {
507 3
        return $this->formOptions['method'];
508
    }
509
510
    /**
511
     * Set form http method
512
     *
513
     * @param string $method
514
     * @return $this
515
     */
516 1
    public function setMethod($method)
517
    {
518 1
        $this->formOptions['method'] = $method;
519
520 1
        return $this;
521
    }
522
523
    /**
524
     * Get form action url
525
     *
526
     * @return string
527
     */
528 3
    public function getUrl()
529
    {
530 3
        return $this->formOptions['url'];
531
    }
532
533
    /**
534
     * Set form action url
535
     *
536
     * @param string $url
537
     * @return $this
538
     */
539 1
    public function setUrl($url)
540
    {
541 1
        $this->formOptions['url'] = $url;
542
543 1
        return $this;
544
    }
545
546
    /**
547
     * @return string|null
548
     */
549 52
    public function getName()
550
    {
551 52
        return $this->name;
552
    }
553
554
    /**
555
     * @param string $name
556
     * @param bool $rebuild
557
     *
558
     * @return $this
559
     */
560 9
    public function setName($name, $rebuild = true)
561
    {
562 9
        $this->name = $name;
563
564 9
        if ($rebuild) {
565 9
            $this->rebuildForm();
566 9
        }
567
568 9
        return $this;
569
    }
570
571
    /**
572
     * Get model that is bind to form object
573
     *
574
     * @return mixed
575
     */
576 76
    public function getModel()
577
    {
578 76
        return $this->model;
579
    }
580
581
    /**
582
     * Set model to form object
583
     *
584
     * @param mixed $model
585
     * @return $this
586
     * @deprecated deprecated since 1.6.31, will be removed in 1.7 - pass model as option when creating a form
587
     */
588
    public function setModel($model)
589
    {
590
        $this->model = $model;
591
592
        $this->setupNamedModel();
593
594
        $this->rebuildForm();
595
596
        return $this;
597
    }
598
599
    /**
600
     * Setup model for form, add namespace if needed for child forms
601
     * @return $this
602
     */
603 9
    protected function setupModel($model)
604
    {
605 9
        $this->model = $model;
606
607 9
        $this->setupNamedModel();
608
609 9
        return $this;
610
    }
611
612
    /**
613
     * Get all fields
614
     *
615
     * @return FormField[]
616
     */
617 19
    public function getFields()
618
    {
619 19
        return $this->fields;
620
    }
621
622
    /**
623
     * Get field dynamically
624
     *
625
     * @param $name
626
     * @return FormField
627
     */
628 19
    public function __get($name)
629
    {
630 19
        if ($this->has($name)) {
631 18
            return $this->getField($name);
632
        }
633 3
    }
634
635
    /**
636
     * Set the Event Dispatcher to fire Laravel events
637
     *
638
     * @param EventDispatcher $eventDispatcher
639
     * @return $this
640
     */
641 102
    public function setEventDispatcher(EventDispatcher $eventDispatcher)
642
    {
643 102
        $this->eventDispatcher = $eventDispatcher;
644
645 102
        return $this;
646
    }
647
648
    /**
649
     * Set the form helper only on first instantiation
650
     *
651
     * @param FormHelper $formHelper
652
     * @return $this
653
     */
654 102
    public function setFormHelper(FormHelper $formHelper)
655
    {
656 102
        $this->formHelper = $formHelper;
657
658 102
        return $this;
659
    }
660
661
    /**
662
     * Get form helper
663
     *
664
     * @return FormHelper
665
     */
666 80
    public function getFormHelper()
667
    {
668 80
        return $this->formHelper;
669
    }
670
671
    /**
672
     * Add custom field
673
     *
674
     * @param $name
675
     * @param $class
676
     */
677 2
    public function addCustomField($name, $class)
678
    {
679 2
        $this->formHelper->addCustomField($name, $class);
680 2
    }
681
682
    /**
683
     * Should form errors be shown under every field ?
684
     *
685
     * @return bool
686
     */
687 80
    public function haveErrorsEnabled()
688
    {
689 80
        return $this->showFieldErrors;
690
    }
691
692
    /**
693
     * Enable or disable showing errors under fields
694
     *
695
     * @param boolean $enabled
696
     * @return $this
697
     */
698 1
    public function setErrorsEnabled($enabled)
699
    {
700 1
        $this->showFieldErrors = (boolean) $enabled;
701
702 1
        return $this;
703
    }
704
705
    /**
706
     * Is client validation enabled?
707
     *
708
     * @return boolean
709
     */
710 17
    public function clientValidationEnabled()
711
    {
712 17
        return $this->clientValidationEnabled;
713
    }
714
715
    /**
716
     * Enable/disable client validation
717
     *
718
     * @param boolean $enable
719
     * @return $this
720
     */
721 2
    public function setClientValidationEnabled($enable)
722
    {
723 2
        $this->clientValidationEnabled = (boolean) $enable;
724
725 2
        return $this;
726
    }
727
728
    /**
729
     * Add any aditional data that field needs (ex. array of choices)
730
     *
731
     * @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
732
     * will be switched to protected in 1.7
733
     * @param string $name
734
     * @param mixed $data
735
     */
736
    public function setData($name, $data)
737
    {
738
        $this->data[$name] = $data;
739
    }
740
741
    /**
742
     * Get single additional data
743
     *
744
     * @param string $name
745
     * @param null   $default
746
     * @return mixed
747
     */
748 14
    public function getData($name = null, $default = null)
749
    {
750 14
        if (is_null($name)) {
751 13
            return $this->data;
752
        }
753
754 1
        return array_get($this->data, $name, $default);
755
    }
756
757
    /**
758
     * Add multiple peices of data at once
759
     *
760
     * @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
761
     * will be switched to protected in 1.7
762
     * @param $data
763
     * @return $this
764
     **/
765
    public function addData(array $data)
766
    {
767
        foreach ($data as $key => $value) {
768
            $this->setData($key, $value);
0 ignored issues
show
Deprecated Code introduced by
The method Kris\LaravelFormBuilder\Form::setData() has been deprecated with message: deprecated since 1.6.20, will be removed in 1.7 - use 3rd param on create, or 2nd on plain method to pass data
will be switched to protected in 1.7

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.

Loading history...
769
        }
770
771
        return $this;
772
    }
773
774
    /**
775
     * Get current request
776
     *
777
     * @return \Illuminate\Http\Request
778
     */
779 80
    public function getRequest()
780
    {
781 80
        return $this->request;
782
    }
783
784
    /**
785
     * Set request on form
786
     *
787
     * @param Request $request
788
     * @return $this
789
     */
790 102
    public function setRequest(Request $request)
791
    {
792 102
        $this->request = $request;
793
794 102
        return $this;
795
    }
796
797
    /**
798
     * Get template prefix that is prepended to all template paths
799
     *
800
     * @return string
801
     */
802 35
    public function getTemplatePrefix()
803
    {
804 35
        if ($this->templatePrefix !== null) {
805 4
            return $this->templatePrefix;
806
        }
807
808 31
        return $this->formHelper->getConfig('template_prefix');
809
    }
810
811
    /**
812
     * Set a template prefix for the form and its fields
813
     *
814
     * @param string $prefix
815
     * @return $this
816
     */
817 4
    public function setTemplatePrefix($prefix)
818
    {
819 4
        $this->templatePrefix = (string) $prefix;
820
821 4
        return $this;
822
    }
823
824
    /**
825
     * Get the language name
826
     *
827
     * @return string
828
     */
829 78
    public function getLanguageName()
830
    {
831 78
        return $this->languageName;
832
    }
833
834
    /**
835
     * Set a language name, used as prefix for translated strings
836
     *
837
     * @param string $prefix
838
     * @return $this
839
     */
840 10
    public function setLanguageName($prefix)
841
    {
842 10
        $this->languageName = (string) $prefix;
843
844 10
        return $this;
845
    }
846
847
    /**
848
     * Render the form
849
     *
850
     * @param $options
851
     * @param $fields
852
     * @param boolean $showStart
853
     * @param boolean $showFields
854
     * @param boolean $showEnd
855
     * @return string
856
     */
857 8
    protected function render($options, $fields, $showStart, $showFields, $showEnd)
858
    {
859 8
        $formOptions = $this->formHelper->mergeOptions($this->formOptions, $options);
860
861 8
        $this->setupNamedModel();
862
863 8
        return $this->formHelper->getView()
864 8
            ->make($this->getTemplate())
865 8
            ->with(compact('showStart', 'showFields', 'showEnd'))
866 8
            ->with('formOptions', $formOptions)
867 8
            ->with('fields', $fields)
868 8
            ->with('model', $this->getModel())
869 8
            ->with('exclude', $this->exclude)
870 8
            ->with('form', $this)
871 8
            ->render();
872
    }
873
874
    /**
875
     * Get template from options if provided, otherwise fallback to config
876
     *
877
     * @return mixed
878
     */
879 8
    protected function getTemplate()
880
    {
881 8
        return $this->getTemplatePrefix() . $this->getFormOption('template', $this->formHelper->getConfig('form'));
882
    }
883
884
    /**
885
     * Get all fields that are not rendered
886
     *
887
     * @return array
888
     */
889 2
    protected function getUnrenderedFields()
890
    {
891 2
        $unrenderedFields = [];
892
893 2
        foreach ($this->fields as $field) {
894 2
            if (!$field->isRendered()) {
895 2
                $unrenderedFields[] = $field;
896 2
                continue;
897
            }
898 2
        }
899
900 2
        return $unrenderedFields;
901
    }
902
903
    /**
904
     * Prevent adding fields with same name
905
     *
906
     * @param string $name
907
     */
908 43
    protected function preventDuplicate($name)
909
    {
910 43
        if ($this->has($name)) {
911 1
            throw new \InvalidArgumentException('Field ['.$name.'] already exists in the form '.get_class($this));
912
        }
913 43
    }
914
915
    /**
916
     * @param string $type
917
     * @return string
918
     */
919 47
    protected function getFieldType($type)
920
    {
921 47
        $fieldType = $this->formHelper->getFieldType($type);
922
923 46
        return $fieldType;
924
    }
925
926
    /**
927
     * Check if form is named form
928
     */
929 102
    protected function checkIfNamedForm()
930
    {
931 102
        if ($this->getFormOption('name')) {
932 5
            $this->name = array_pull($this->formOptions, 'name', $this->name);
933 5
        }
934 102
    }
935
936
    /**
937
     * Set up options on single field depending on form options
938
     *
939
     * @param string $name
940
     * @param $options
941
     */
942 47
    protected function setupFieldOptions($name, &$options)
943
    {
944 47
        $options['real_name'] = $name;
945 47
    }
946
947
    /**
948
     * Set namespace to model if form is named so the data is bound properly
949
     * Returns true if model is changed, otherwise false
950
     *
951
     * @return bool
952
     */
953 27
    protected function setupNamedModel()
954
    {
955 27
        if (!$this->getModel() || !$this->getName()) {
956 26
            return false;
957
        }
958
959 4
        $dotName = $this->formHelper->transformToDotSyntax($this->getName());
960 4
        $model = $this->formHelper->convertModelToArray($this->getModel());
961
962 4
        if (!array_get($model, $dotName)) {
963 4
            $newModel = [];
964 4
            array_set($newModel, $dotName, $model);
965 4
            $this->model = $newModel;
966
967 4
            return true;
968
        }
969
970 3
        return false;
971
    }
972
973
974
    /**
975
     * Set form builder instance on helper so we can use it later
976
     *
977
     * @param FormBuilder $formBuilder
978
     * @return $this
979
     */
980 102
    public function setFormBuilder(FormBuilder $formBuilder)
981
    {
982 102
        $this->formBuilder = $formBuilder;
983
984 102
        return $this;
985
    }
986
987
    /**
988
     * @return FormBuilder
989
     */
990 9
    public function getFormBuilder()
991
    {
992 9
        return $this->formBuilder;
993
    }
994
995
    /**
996
     * @param ValidatorFactory $validator
997
     * @return $this
998
     */
999 102
    public function setValidator(ValidatorFactory $validator)
1000
    {
1001 102
        $this->validatorFactory = $validator;
1002
1003 102
        return $this;
1004
    }
1005
1006
    /**
1007
     * Exclude some fields from rendering
1008
     *
1009
     * @return $this
1010
     */
1011
    public function exclude(array $fields)
1012
    {
1013
        $this->exclude = array_merge($this->exclude, $fields);
1014
1015
        return $this;
1016
    }
1017
1018
1019
    /**
1020
     * If form is named form, modify names to be contained in single key (parent[child_field_name])
1021
     *
1022
     * @param string $name
1023
     * @return string
1024
     */
1025 47
    protected function getFieldName($name)
1026
    {
1027 47
        if ($this->getName() !== null) {
1028 11
            return $this->getName().'['.$name.']';
1029
        }
1030
1031 47
        return $name;
1032
    }
1033
1034
    /**
1035
     * Disable all fields in a form
1036
     */
1037 1
    public function disableFields()
1038
    {
1039 1
        foreach ($this->fields as $field) {
1040 1
            $field->disable();
1041 1
        }
1042 1
    }
1043
1044
    /**
1045
     * Enable all fields in a form
1046
     */
1047 1
    public function enableFields()
1048
    {
1049 1
        foreach ($this->fields as $field) {
1050 1
            $field->enable();
1051 1
        }
1052 1
    }
1053
1054
    /**
1055
     * Validate the form
1056
     *
1057
     * @param array $validationRules
1058
     * @param array $messages
1059
     * @return Validator
1060
     */
1061 7
    public function validate($validationRules = [], $messages = [])
1062
    {
1063 7
        $fieldRules = $this->formHelper->mergeFieldsRules($this->fields);
1064 7
        $rules = array_merge($fieldRules['rules'], $validationRules);
1065 7
        $messages = array_merge($fieldRules['error_messages'], $messages);
1066
1067 7
        $this->validator = $this->validatorFactory->make($this->getRequest()->all(), $rules, $messages);
1068 7
        $this->validator->setAttributeNames($fieldRules['attributes']);
1069
1070 7
        $this->eventDispatcher->fire(new BeforeFormValidation($this, $this->validator));
1071
1072 7
        return $this->validator;
1073
    }
1074
1075
    /**
1076
     * Get validatdion rules for the form
1077
     *
1078
     * @param array $overrideRules
1079
     * @return array
1080
     */
1081 1
    public function getRules($overrideRules = [])
1082
    {
1083 1
        $fieldRules = $this->formHelper->mergeFieldsRules($this->fields);
1084
1085 1
        return array_merge($fieldRules['rules'], $overrideRules);
1086
    }
1087
1088 2
    public function redirectIfNotValid($destination = null)
1089
    {
1090 2
        if (! $this->isValid()) {
1091 2
            $response = redirect($destination);
1092
1093 2
            if (is_null($destination)) {
1094 1
                $response = $response->back();
1095 1
            }
1096
1097 2
            $response = $response->withErrors($this->getErrors())->withInput();
1098
1099 2
            throw new HttpResponseException($response);
1100
        }
1101
    }
1102
1103
    /**
1104
     * Get all form field attributes, including child forms, in a flat array.
1105
     *
1106
     * @return array
1107
     */
1108 1
    public function getAllAttributes()
1109
    {
1110 1
        return $this->formHelper->mergeAttributes($this->fields);
1111
    }
1112
1113
    /**
1114
     * Check if the form is valid
1115
     *
1116
     * @return bool
1117
     */
1118 7
    public function isValid()
1119
    {
1120 7
        if (!$this->validator) {
1121 6
            $this->validate();
1122 6
        }
1123
1124 7
        $isValid = !$this->validator->fails();
1125
1126 7
        $this->eventDispatcher->fire(new AfterFormValidation($this, $this->validator, $isValid));
1127
1128 7
        return $isValid;
1129
    }
1130
1131
    /**
1132
     * Get validation errors
1133
     *
1134
     * @return array
1135
     */
1136 6
    public function getErrors()
1137
    {
1138 6
        if (!$this->validator || !$this->validator instanceof Validator) {
1139 1
            throw new \InvalidArgumentException(
1140 1
                sprintf(
1141 1
                    'Form %s was not validated. To validate it, call "isValid" method before retrieving the errors',
1142 1
                    get_class($this)
1143 1
                )
1144 1
            );
1145
        }
1146
1147 5
        return $this->validator->getMessageBag()->getMessages();
1148
    }
1149
1150
    /**
1151
     * Get all Request values from all fields, and nothing else.
1152
     *
1153
     * @return array
1154
     */
1155 1
    public function getFieldValues($with_nulls = true)
1156
    {
1157 1
        $request_values = $this->getRequest()->all();
1158
1159 1
        $values = [];
1160 1
        foreach ($this->getAllAttributes() as $attribute) {
1161 1
            $value = Arr::get($request_values, $attribute);
1162 1
            if ($with_nulls || $value !== null) {
1163 1
                Arr::set($values, $attribute, $value);
1164 1
            }
1165 1
        }
1166
1167 1
        return $values;
1168
    }
1169
1170
    /**
1171
     * Throw an exception indicating a field does not exist on the class
1172
     *
1173
     * @param string $name
1174
     * @throws \InvalidArgumentException
1175
     */
1176 2
    protected function fieldDoesNotExist($name)
1177
    {
1178 2
        throw new \InvalidArgumentException('Field ['.$name.'] does not exist in '.get_class($this));
1179
    }
1180
}
1181