Completed
Pull Request — master (#248)
by Rudie
09:41
created

Form::getValidatedValues()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 14
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 20

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 4
eloc 8
c 1
b 0
f 0
nc 3
nop 1
dl 0
loc 14
ccs 0
cts 0
cp 0
crap 20
rs 9.2
1
<?php namespace Kris\LaravelFormBuilder;
2
3
use Illuminate\Contracts\Validation\Factory as ValidatorFactory;
4
use Illuminate\Contracts\Validation\Validator;
5
use Illuminate\Http\Request;
6
use Illuminate\Support\Arr;
7
use Kris\LaravelFormBuilder\Fields\FormField;
8
9
class Form
10
{
11
12
    /**
13
     * All fields that are added
14
     *
15
     * @var array
16
     */
17
    protected $fields = [];
18
19
    /**
20
     * Model to use
21
     *
22
     * @var mixed
23
     */
24
    protected $model = [];
25
26
    /**
27
     * @var FormHelper
28
     */
29
    protected $formHelper;
30
31
    /**
32
     * Form options
33
     *
34
     * @var array
35
     */
36
    protected $formOptions = [
37
        'method' => 'GET',
38
        'url' => null
39
    ];
40
41
    /**
42
     * Additional data which can be used to build fields
43
     *
44
     * @var array
45
     */
46
    protected $data = [];
47
48
    /**
49
     * Should errors for each field be shown when called form($form) or form_rest($form) ?
50
     *
51
     * @var bool
52
     */
53
    protected $showFieldErrors = true;
54
55
    /**
56
     * Enable html5 validation
57
     *
58
     * @var bool
59
     */
60
    protected $clientValidationEnabled = true;
61
62
    /**
63
     * Name of the parent form if any
64
     *
65
     * @var string|null
66
     */
67
    protected $name = null;
68
69
    /**
70
     * @var FormBuilder
71
     */
72
    protected $formBuilder;
73
74
    /**
75
     * @var ValidatorFactory
76
     */
77
    protected $validatorFactory;
78
79
    /**
80
     * @var Validator
81
     */
82
    protected $validator = null;
83
84
    /**
85
     * @var Request
86
     */
87
    protected $request;
88
89
    /**
90
     * List of fields to not render
91
     *
92
     * @var array
93
     **/
94
    protected $exclude = [];
95
96
    /**
97
     * Are form being rebuilt?
98
     *
99
     * @var bool
100
     */
101
    protected $rebuilding = false;
102
103
    /**
104
     * @var string
105
     */
106
    protected $templatePrefix;
107
108
    /**
109
     * @var string
110
     */
111
    protected $languageName;
112
113
    /**
114
     * Build the form
115
     *
116
     * @return mixed
117
     */
118 2
    public function buildForm()
119
    {
120 2
    }
121
122
    /**
123
     * Rebuild the form from scratch
124
     *
125
     * @return $this
126
     */
127 14
    public function rebuildForm()
128
    {
129 14
        $this->rebuilding = true;
130
        // If form is plain, buildForm method is empty, so we need to take
131
        // existing fields and add them again
132 14
        if (get_class($this) === 'Kris\LaravelFormBuilder\Form') {
133 13
            foreach ($this->fields as $name => $field) {
134
                // Remove any temp variables added in previous instance
135 5
                $options = array_except($field->getOptions(), 'tmp');
136 13
                $this->add($name, $field->getType(), $options);
137
            }
138
        } else {
139 3
            $this->buildForm();
140
        }
141 14
        $this->rebuilding = false;
142
143 14
        return $this;
144
    }
145
146
    /**
147
     * Create the FormField object
148
     *
149
     * @param string $name
150
     * @param string $type
151
     * @param array  $options
152
     * @return FormField
153
     */
154 42
    protected function makeField($name, $type = 'text', array $options = [])
155
    {
156 42
        $this->setupFieldOptions($name, $options);
157
158 42
        $fieldName = $this->getFieldName($name);
159
160 42
        $fieldType = $this->getFieldType($type);
161
162 41
        return new $fieldType($fieldName, $type, $this, $options);
163
    }
164
165
    /**
166
     * Create a new field and add it to the form
167
     *
168
     * @param string $name
169
     * @param string $type
170
     * @param array  $options
171
     * @param bool   $modify
172
     * @return $this
173
     */
174 44
    public function add($name, $type = 'text', array $options = [], $modify = false)
175
    {
176 44
        $this->formHelper->checkFieldName($name, get_class($this));
177
178 42
        if ($this->rebuilding && !$this->has($name)) {
179
            return $this;
180
        }
181
182 42
        $this->addField($this->makeField($name, $type, $options), $modify);
183
184 38
        return $this;
185
    }
186
187
    /**
188
     * Add a FormField to the form's fields
189
     *
190
     * @param FormField $field
191
     * @return $this
192
     */
193 38
    protected function addField(FormField $field, $modify = false)
194
    {
195 38
        if (!$modify && !$this->rebuilding) {
196 38
            $this->preventDuplicate($field->getRealName());
197
        }
198
199
200 38
        if ($field->getType() == 'file') {
201 3
            $this->formOptions['files'] = true;
202
        }
203
204 38
        $this->fields[$field->getRealName()] = $field;
205
206 38
        return $this;
207
    }
208
209
    /**
210
     * Add field before another field
211
     *
212
     * @param string  $name         Name of the field before which new field is added
213
     * @param string  $fieldName    Field name which will be added
214
     * @param string  $type
215
     * @param array   $options
216
     * @param boolean $modify
217
     * @return $this
218
     */
219 1
    public function addBefore($name, $fieldName, $type = 'text', $options = [], $modify = false)
220
    {
221 1
        $offset = array_search($name, array_keys($this->fields));
222
223 1
        $beforeFields = array_slice($this->fields, 0, $offset);
224 1
        $afterFields = array_slice($this->fields, $offset);
225
226 1
        $this->fields = $beforeFields;
227
228 1
        $this->add($fieldName, $type, $options, $modify);
229
230 1
        $this->fields += $afterFields;
231
232 1
        return $this;
233
    }
234
235
    /**
236
     * Add field before another field
237
     * @param string  $name         Name of the field after which new field is added
238
     * @param string  $fieldName    Field name which will be added
239
     * @param string  $type
240
     * @param array   $options
241
     * @param boolean $modify
242
     * @return $this
243
     */
244 1
    public function addAfter($name, $fieldName, $type = 'text', $options = [], $modify = false)
245
    {
246 1
        $offset = array_search($name, array_keys($this->fields));
247
248 1
        $beforeFields = array_slice($this->fields, 0, $offset + 1);
249 1
        $afterFields = array_slice($this->fields, $offset + 1);
250
251 1
        $this->fields = $beforeFields;
252
253 1
        $this->add($fieldName, $type, $options, $modify);
254
255 1
        $this->fields += $afterFields;
256
257 1
        return $this;
258
    }
259
260
    /**
261
     * Take another form and add it's fields directly to this form
262
     * @param mixed   $class        Form to merge
263
     * @param array   $options
264
     * @param boolean $modify
265
     * @return $this
266
     */
267 1
    public function compose($class, array $options = [], $modify = false)
268
    {
269 1
        $options['class'] = $class;
270
271
        // If we pass a ready made form just extract the fields
272 1
        if ($class instanceof Form) {
273 1
            $fields = $class->getFields();
274
        } elseif ($class instanceof Fields\ChildFormType) {
275
            $fields = $class->getForm()->getFields();
276
        } elseif (is_string($class)) {
277
            // If its a string of a class make it the usual way
278
            $options['model'] = $this->model;
279
            $options['name'] = $this->name;
280
281
            $form = $this->formBuilder->create($class, $options);
282
            $fields = $form->getFields();
283
        } else {
284
            throw new \InvalidArgumentException(
285
                "[{$class}] is invalid. Please provide either a full class name, Form or ChildFormType"
286
            );
287
        }
288
289 1
        foreach ($fields as $field) {
290 1
            $this->addField($field, $modify);
291
        }
292
293 1
        return $this;
294
    }
295
296
    /**
297
     * Remove field with specified name from the form
298
     *
299
     * @param $name
300
     * @return $this
301
     */
302 2
    public function remove($name)
303
    {
304 2
        if ($this->has($name)) {
305 2
            unset($this->fields[$name]);
306
        }
307
308 2
        return $this;
309
    }
310
311
    /**
312
     * Modify existing field. If it doesn't exist, it is added to form
313
     *
314
     * @param        $name
315
     * @param string $type
316
     * @param array  $options
317
     * @param bool   $overwriteOptions
318
     * @return Form
319
     */
320 1
    public function modify($name, $type = 'text', array $options = [], $overwriteOptions = false)
321
    {
322
        // If we don't want to overwrite options, we merge them with old options
323 1
        if ($overwriteOptions === false && $this->has($name)) {
324 1
            $options = $this->formHelper->mergeOptions(
325 1
                $this->getField($name)->getOptions(),
326
                $options
327
            );
328
        }
329
330 1
        return $this->add($name, $type, $options, true);
331
    }
332
333
    /**
334
     * Render full form
335
     *
336
     * @param array $options
337
     * @param bool  $showStart
338
     * @param bool  $showFields
339
     * @param bool  $showEnd
340
     * @return string
341
     */
342 6
    public function renderForm(array $options = [], $showStart = true, $showFields = true, $showEnd = true)
343
    {
344 6
        return $this->render($options, $this->fields, $showStart, $showFields, $showEnd);
345
    }
346
347
    /**
348
     * Render rest of the form
349
     *
350
     * @param bool $showFormEnd
351
     * @param bool $showFields
352
     * @return string
353
     */
354 1
    public function renderRest($showFormEnd = true, $showFields = true)
355
    {
356 1
        $fields = $this->getUnrenderedFields();
357
358 1
        return $this->render([], $fields, false, $showFields, $showFormEnd);
359
    }
360
361
    /**
362
     * Renders the rest of the form up until the specified field name
363
     *
364
     * @param string $field_name
365
     * @param bool   $showFormEnd
366
     * @param bool   $showFields
367
     * @return string
368
     */
369 2
    public function renderUntil($field_name, $showFormEnd = true, $showFields = true)
370
    {
371 2
        if (!$this->has($field_name)) {
372 1
            $this->fieldDoesNotExist($field_name);
373
        }
374
375 1
        $fields = $this->getUnrenderedFields();
376
377 1
        $i = 1;
378 1
        foreach ($fields as $key => $value) {
379 1
            if ($value->getRealName() == $field_name) {
380 1
                break;
381
            }
382 1
            $i++;
383
        }
384
385 1
        $fields = array_slice($fields, 0, $i, true);
386
387 1
        return $this->render([], $fields, false, $showFields, $showFormEnd);
388
    }
389
390
    /**
391
     * Get single field instance from form object
392
     *
393
     * @param $name
394
     * @return FormField
395
     */
396 24
    public function getField($name)
397
    {
398 24
        if ($this->has($name)) {
399 23
            return $this->fields[$name];
400
        }
401
402 1
        $this->fieldDoesNotExist($name);
403
    }
404
405
    /**
406
     * Check if form has field
407
     *
408
     * @param $name
409
     * @return bool
410
     */
411 38
    public function has($name)
412
    {
413 38
        return array_key_exists($name, $this->fields);
414
    }
415
416
    /**
417
     * Get all form options
418
     *
419
     * @return array
420
     */
421 2
    public function getFormOptions()
422
    {
423 2
        return $this->formOptions;
424
    }
425
426
    /**
427
     * Get single form option
428
     *
429
     * @param string $option
430
     * @param $default
431
     * @return mixed
432
     */
433 93
    public function getFormOption($option, $default = null)
434
    {
435 93
        return array_get($this->formOptions, $option, $default);
436
    }
437
438
    /**
439
     * Set single form option on form
440
     *
441
     * @param string $option
442
     * @param mixed $value
443
     *
444
     * @return $this
445
     */
446 2
    public function setFormOption($option, $value)
447
    {
448 2
        $this->formOptions[$option] = $value;
449
450 2
        return $this;
451
    }
452
453
    /**
454
     * Set form options
455
     *
456
     * @param array $formOptions
457
     * @return $this
458
     */
459 93
    public function setFormOptions($formOptions)
460
    {
461 93
        $this->formOptions = $this->formHelper->mergeOptions($this->formOptions, $formOptions);
462 93
        $this->checkIfNamedForm();
463 93
        $this->pullFromOptions('data', 'addData');
464 93
        $this->pullFromOptions('model', 'setupModel');
465 93
        $this->pullFromOptions('errors_enabled', 'setErrorsEnabled');
466 93
        $this->pullFromOptions('client_validation', 'setClientValidationEnabled');
467 93
        $this->pullFromOptions('template_prefix', 'setTemplatePrefix');
468 93
        $this->pullFromOptions('language_name', 'setLanguageName');
469
470 93
        return $this;
471
    }
472
473
    /**
474
     * Get an option from provided options and call method with that value
475
     *
476
     * @param $name
477
     * @param $method
478
     */
479 93
    protected function pullFromOptions($name, $method)
480
    {
481 93
        if (array_get($this->formOptions, $name) !== null) {
482 15
            $this->{$method}(array_pull($this->formOptions, $name));
483
        }
484 93
    }
485
486
    /**
487
     * Get form http method
488
     *
489
     * @return string
490
     */
491 3
    public function getMethod()
492
    {
493 3
        return $this->formOptions['method'];
494
    }
495
496
    /**
497
     * Set form http method
498
     *
499
     * @param string $method
500
     * @return $this
501
     */
502 1
    public function setMethod($method)
503
    {
504 1
        $this->formOptions['method'] = $method;
505
506 1
        return $this;
507
    }
508
509
    /**
510
     * Get form action url
511
     *
512
     * @return string
513
     */
514 3
    public function getUrl()
515
    {
516 3
        return $this->formOptions['url'];
517
    }
518
519
    /**
520
     * Set form action url
521
     *
522
     * @param string $url
523
     * @return $this
524
     */
525 1
    public function setUrl($url)
526
    {
527 1
        $this->formOptions['url'] = $url;
528
529 1
        return $this;
530
    }
531
532
    /**
533
     * @return string|null
534
     */
535 47
    public function getName()
536
    {
537 47
        return $this->name;
538
    }
539
540
    /**
541
     * @param string $name
542
     * @param bool $rebuild
543
     *
544
     * @return $this
545
     */
546 8
    public function setName($name, $rebuild = true)
547
    {
548 8
        $this->name = $name;
549
550 8
        if ($rebuild) {
551 8
            $this->rebuildForm();
552
        }
553
554 8
        return $this;
555
    }
556
557
    /**
558
     * Get model that is bind to form object
559
     *
560
     * @return mixed
561
     */
562 67
    public function getModel()
563
    {
564 67
        return $this->model;
565
    }
566
567
    /**
568
     * Set model to form object
569
     *
570
     * @param mixed $model
571
     * @return $this
572
     * @deprecated deprecated since 1.6.31, will be removed in 1.7 - pass model as option when creating a form
573
     */
574
    public function setModel($model)
575
    {
576
        $this->model = $model;
577
578
        $this->setupNamedModel();
579
580
        $this->rebuildForm();
581
582
        return $this;
583
    }
584
585
    /**
586
     * Setup model for form, add namespace if needed for child forms
587
     * @return $this
588
     */
589 9
    protected function setupModel($model)
590
    {
591 9
        $this->model = $model;
592
593 9
        $this->setupNamedModel();
594
595 9
        return $this;
596
    }
597
598
    /**
599
     * Get all fields
600
     *
601
     * @return FormField[]
602
     */
603 18
    public function getFields()
604
    {
605 18
        return $this->fields;
606
    }
607
608
    /**
609
     * Get field dynamically
610
     *
611
     * @param $name
612
     * @return FormField
613
     */
614 19
    public function __get($name)
615
    {
616 19
        if ($this->has($name)) {
617 18
            return $this->getField($name);
618
        }
619 3
    }
620
621
    /**
622
     * Set the form helper only on first instantiation
623
     *
624
     * @param FormHelper $formHelper
625
     * @return $this
626
     */
627 93
    public function setFormHelper(FormHelper $formHelper)
628
    {
629 93
        $this->formHelper = $formHelper;
630
631 93
        return $this;
632
    }
633
634
    /**
635
     * Get form helper
636
     *
637
     * @return FormHelper
638
     */
639 71
    public function getFormHelper()
640
    {
641 71
        return $this->formHelper;
642
    }
643
644
    /**
645
     * Add custom field
646
     *
647
     * @param $name
648
     * @param $class
649
     */
650 2
    public function addCustomField($name, $class)
651
    {
652 2
        $this->formHelper->addCustomField($name, $class);
653 2
    }
654
655
    /**
656
     * Should form errors be shown under every field ?
657
     *
658
     * @return bool
659
     */
660 71
    public function haveErrorsEnabled()
661
    {
662 71
        return $this->showFieldErrors;
663
    }
664
665
    /**
666
     * Enable or disable showing errors under fields
667
     *
668
     * @param boolean $enabled
669
     * @return $this
670
     */
671 1
    public function setErrorsEnabled($enabled)
672
    {
673 1
        $this->showFieldErrors = (boolean) $enabled;
674
675 1
        return $this;
676
    }
677
678
    /**
679
     * Is client validation enabled?
680
     *
681
     * @return boolean
682
     */
683 71
    public function clientValidationEnabled()
684
    {
685 71
        return $this->clientValidationEnabled;
686
    }
687
688
    /**
689
     * Enable/disable client validation
690
     *
691
     * @param boolean $enable
692
     * @return $this
693
     */
694 1
    public function setClientValidationEnabled($enable)
695
    {
696 1
        $this->clientValidationEnabled = (boolean) $enable;
697
698 1
        return $this;
699
    }
700
701
    /**
702
     * Add any aditional data that field needs (ex. array of choices)
703
     *
704
     * @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
705
     * will be switched to protected in 1.7
706
     * @param string $name
707
     * @param mixed $data
708
     */
709
    public function setData($name, $data)
710
    {
711
        $this->data[$name] = $data;
712
    }
713
714
    /**
715
     * Get single additional data
716
     *
717
     * @param string $name
718
     * @param null   $default
719
     * @return mixed
720
     */
721 13
    public function getData($name = null, $default = null)
722
    {
723 13
        if (is_null($name)) {
724 12
            return $this->data;
725
        }
726
727 1
        return array_get($this->data, $name, $default);
728
    }
729
730
    /**
731
     * Add multiple peices of data at once
732
     *
733
     * @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
734
     * will be switched to protected in 1.7
735
     * @param $data
736
     * @return $this
737
     **/
738
    public function addData(array $data)
739
    {
740
        foreach ($data as $key => $value) {
741
            $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...
742
        }
743
744
        return $this;
745
    }
746
747
    /**
748
     * Get current request
749
     *
750
     * @return \Illuminate\Http\Request
751
     */
752 71
    public function getRequest()
753
    {
754 71
        return $this->request;
755
    }
756
757
    /**
758
     * Set request on form
759
     *
760
     * @param Request $request
761
     * @return $this
762
     */
763 93
    public function setRequest(Request $request)
764
    {
765 93
        $this->request = $request;
766
767 93
        return $this;
768
    }
769
770
    /**
771
     * Get template prefix that is prepended to all template paths
772
     *
773
     * @return string
774
     */
775 31
    public function getTemplatePrefix()
776
    {
777 31
        if ($this->templatePrefix !== null) {
778 4
            return $this->templatePrefix;
779
        }
780
781 27
        return $this->formHelper->getConfig('template_prefix');
782
    }
783
784
    /**
785
     * Set a template prefix for the form and its fields
786
     *
787
     * @param string $prefix
788
     * @return $this
789
     */
790 4
    public function setTemplatePrefix($prefix)
791
    {
792 4
        $this->templatePrefix = (string) $prefix;
793
794 4
        return $this;
795
    }
796
797
    /**
798
     * Get the language name
799
     *
800
     * @return string
801
     */
802 69
    public function getLanguageName()
803
    {
804 69
        return $this->languageName;
805
    }
806
807
    /**
808
     * Set a language name, used as prefix for translated strings
809
     *
810
     * @param string $prefix
811
     * @return $this
812
     */
813 9
    public function setLanguageName($prefix)
814
    {
815 9
        $this->languageName = (string) $prefix;
816
817 9
        return $this;
818
    }
819
820
    /**
821
     * Render the form
822
     *
823
     * @param $options
824
     * @param $fields
825
     * @param boolean $showStart
826
     * @param boolean $showFields
827
     * @param boolean $showEnd
828
     * @return string
829
     */
830 8
    protected function render($options, $fields, $showStart, $showFields, $showEnd)
831
    {
832 8
        $formOptions = $this->formHelper->mergeOptions($this->formOptions, $options);
833
834 8
        $this->setupNamedModel();
835
836 8
        return $this->formHelper->getView()
837 8
            ->make($this->getTemplate())
838 8
            ->with(compact('showStart', 'showFields', 'showEnd'))
839 8
            ->with('formOptions', $formOptions)
840 8
            ->with('fields', $fields)
841 8
            ->with('model', $this->getModel())
842 8
            ->with('exclude', $this->exclude)
843 8
            ->with('form', $this)
844 8
            ->render();
845
    }
846
847
    /**
848
     * Get template from options if provided, otherwise fallback to config
849
     *
850
     * @return mixed
851
     */
852 8
    protected function getTemplate()
853
    {
854 8
        return $this->getTemplatePrefix() . $this->getFormOption('template', $this->formHelper->getConfig('form'));
855
    }
856
857
    /**
858
     * Get all fields that are not rendered
859
     *
860
     * @return array
861
     */
862 2
    protected function getUnrenderedFields()
863
    {
864 2
        $unrenderedFields = [];
865
866 2
        foreach ($this->fields as $field) {
867 2
            if (!$field->isRendered()) {
868 2
                $unrenderedFields[] = $field;
869 2
                continue;
870
            }
871
        }
872
873 2
        return $unrenderedFields;
874
    }
875
876
    /**
877
     * Prevent adding fields with same name
878
     *
879
     * @param string $name
880
     */
881 38
    protected function preventDuplicate($name)
882
    {
883 38
        if ($this->has($name)) {
884 1
            throw new \InvalidArgumentException('Field ['.$name.'] already exists in the form '.get_class($this));
885
        }
886 38
    }
887
888
    /**
889
     * @param string $type
890
     * @return string
891
     */
892 42
    protected function getFieldType($type)
893
    {
894 42
        $fieldType = $this->formHelper->getFieldType($type);
895
896 41
        return $fieldType;
897
    }
898
899
    /**
900
     * Check if form is named form
901
     */
902 93
    protected function checkIfNamedForm()
903
    {
904 93
        if ($this->getFormOption('name')) {
905 5
            $this->name = array_pull($this->formOptions, 'name', $this->name);
906
        }
907 93
    }
908
909
    /**
910
     * Set up options on single field depending on form options
911
     *
912
     * @param string $name
913
     * @param $options
914
     */
915 42
    protected function setupFieldOptions($name, &$options)
916
    {
917 42
        $options['real_name'] = $name;
918 42
    }
919
920
    /**
921
     * Set namespace to model if form is named so the data is bound properly
922
     * Returns true if model is changed, otherwise false
923
     *
924
     * @return bool
925
     */
926 26
    protected function setupNamedModel()
927
    {
928 26
        if (!$this->getModel() || !$this->getName()) {
929 25
            return false;
930
        }
931
932 4
        $dotName = $this->formHelper->transformToDotSyntax($this->getName());
933 4
        $model = $this->formHelper->convertModelToArray($this->getModel());
934
935 4
        if (!array_get($model, $dotName)) {
936 4
            $newModel = [];
937 4
            array_set($newModel, $dotName, $model);
938 4
            $this->model = $newModel;
939
940 4
            return true;
941
        }
942
943 3
        return false;
944
    }
945
946
947
    /**
948
     * Set form builder instance on helper so we can use it later
949
     *
950
     * @param FormBuilder $formBuilder
951
     * @return $this
952
     */
953 93
    public function setFormBuilder(FormBuilder $formBuilder)
954
    {
955 93
        $this->formBuilder = $formBuilder;
956
957 93
        return $this;
958
    }
959
960
    /**
961
     * @return FormBuilder
962
     */
963 9
    public function getFormBuilder()
964
    {
965 9
        return $this->formBuilder;
966
    }
967
968
    /**
969
     * @param ValidatorFactory $validator
970
     * @return $this
971
     */
972 93
    public function setValidator(ValidatorFactory $validator)
973
    {
974 93
        $this->validatorFactory = $validator;
975
976 93
        return $this;
977
    }
978
979
    /**
980
     * Exclude some fields from rendering
981
     *
982
     * @return $this
983
     */
984
    public function exclude(array $fields)
985
    {
986
        $this->exclude = array_merge($this->exclude, $fields);
987
988
        return $this;
989
    }
990
991
992
    /**
993
     * If form is named form, modify names to be contained in single key (parent[child_field_name])
994
     *
995
     * @param string $name
996
     * @return string
997
     */
998 42
    protected function getFieldName($name)
999
    {
1000 42
        if ($this->getName() !== null) {
1001 10
            return $this->getName().'['.$name.']';
1002
        }
1003
1004 42
        return $name;
1005
    }
1006
1007
    /**
1008
     * Disable all fields in a form
1009
     */
1010 1
    public function disableFields()
1011
    {
1012 1
        foreach ($this->fields as $field) {
1013 1
            $field->disable();
1014
        }
1015 1
    }
1016
1017
    /**
1018
     * Enable all fields in a form
1019
     */
1020 1
    public function enableFields()
1021
    {
1022 1
        foreach ($this->fields as $field) {
1023 1
            $field->enable();
1024
        }
1025 1
    }
1026
1027
    /**
1028
     * Validate the form
1029
     *
1030
     * @param array $validationRules
1031
     * @param array $messages
1032
     * @return Validator
1033
     */
1034 4
    public function validate($validationRules = [], $messages = [])
1035
    {
1036 4
        $fieldRules = $this->formHelper->mergeFieldsRules($this->fields);
1037 4
        $rules = array_merge($fieldRules['rules'], $validationRules);
1038 4
        $messages = array_merge($fieldRules['error_messages'], $messages);
1039
1040 4
        $this->validator = $this->validatorFactory->make($this->getRequest()->all(), $rules, $messages);
1041 4
        $this->validator->setAttributeNames($fieldRules['attributes']);
1042
1043 4
        return $this->validator;
1044
    }
1045
1046
    /**
1047
     * Get validatdion rules for the form
1048
     *
1049
     * @param array $overrideRules
1050
     * @return array
1051
     */
1052 1
    public function getRules($overrideRules = [])
1053
    {
1054 1
        $fieldRules = $this->formHelper->mergeFieldsRules($this->fields);
1055
1056 1
        return array_merge($fieldRules['rules'], $overrideRules);
1057
    }
1058
1059
    /**
1060
     * Get all form field attributes, including child forms, in a flat array.
1061
     *
1062
     * @return array
1063
     */
1064
    public function getAllAttributes()
1065
    {
1066
        return $this->formHelper->mergeAttributes($this->fields);
1067
    }
1068
1069
    /**
1070
     * Check if the form is valid
1071
     *
1072
     * @return bool
1073
     */
1074 4
    public function isValid()
1075
    {
1076 4
        if (!$this->validator) {
1077 3
            $this->validate();
1078
        }
1079
1080 4
        return !$this->validator->fails();
1081
    }
1082
1083
    /**
1084
     * Get validation errors
1085
     *
1086
     * @return array
1087
     */
1088 4
    public function getErrors()
1089
    {
1090 4
        if (!$this->validator || !$this->validator instanceof Validator) {
1091 1
            throw new \InvalidArgumentException(
1092
                sprintf(
1093 1
                    'Form %s was not validated. To validate it, call "isValid" method before retrieving the errors',
1094
                    get_class($this)
1095
                )
1096
            );
1097
        }
1098
1099 3
        return $this->validator->getMessageBag()->getMessages();
1100
    }
1101
1102
    /**
1103
     * Get all Request values from all fields, and nothing else.
1104
     *
1105
     * @return array
1106
     */
1107
    public function getValidatedValues($with_nulls = true)
1108
    {
1109
        $request_values = $this->getRequest()->all();
1110
1111
        $values = [];
1112
        foreach ($this->getAllAttributes() as $attribute) {
1113
            $value = Arr::get($request_values, $attribute);
1114
            if ($with_nulls || $value !== null) {
1115
                Arr::set($values, $attribute, $value);
1116
            }
1117
        }
1118
1119
        return $values;
1120
    }
1121
1122
    /**
1123
     * Throw an exception indicating a field does not exist on the class
1124
     *
1125
     * @param string $name
1126
     * @throws \InvalidArgumentException
1127
     */
1128 2
    protected function fieldDoesNotExist($name)
1129
    {
1130 2
        throw new \InvalidArgumentException('Field ['.$name.'] does not exist in '.get_class($this));
1131
    }
1132
}
1133