Completed
Pull Request — master (#248)
by Rudie
05:43
created

Form::getValidatedValues()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 14
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 4

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 8
cts 8
cp 1
crap 4
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 15
    public function rebuildForm()
128
    {
129 15
        $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 15
        if (get_class($this) === 'Kris\LaravelFormBuilder\Form') {
133 14
            foreach ($this->fields as $name => $field) {
134
                // Remove any temp variables added in previous instance
135 6
                $options = array_except($field->getOptions(), 'tmp');
136 14
                $this->add($name, $field->getType(), $options);
137
            }
138
        } else {
139 3
            $this->buildForm();
140
        }
141 15
        $this->rebuilding = false;
142
143 15
        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 43
    protected function makeField($name, $type = 'text', array $options = [])
155
    {
156 43
        $this->setupFieldOptions($name, $options);
157
158 43
        $fieldName = $this->getFieldName($name);
159
160 43
        $fieldType = $this->getFieldType($type);
161
162 42
        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 45
    public function add($name, $type = 'text', array $options = [], $modify = false)
175
    {
176 45
        $this->formHelper->checkFieldName($name, get_class($this));
177
178 43
        if ($this->rebuilding && !$this->has($name)) {
179
            return $this;
180
        }
181
182 43
        $this->addField($this->makeField($name, $type, $options), $modify);
183
184 39
        return $this;
185
    }
186
187
    /**
188
     * Add a FormField to the form's fields
189
     *
190
     * @param FormField $field
191
     * @return $this
192
     */
193 39
    protected function addField(FormField $field, $modify = false)
194
    {
195 39
        if (!$modify && !$this->rebuilding) {
196 39
            $this->preventDuplicate($field->getRealName());
197
        }
198
199
200 39
        if ($field->getType() == 'file') {
201 3
            $this->formOptions['files'] = true;
202
        }
203
204 39
        $this->fields[$field->getRealName()] = $field;
205
206 39
        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 39
    public function has($name)
412
    {
413 39
        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 94
    public function getFormOption($option, $default = null)
434
    {
435 94
        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 94
    public function setFormOptions($formOptions)
460
    {
461 94
        $this->formOptions = $this->formHelper->mergeOptions($this->formOptions, $formOptions);
462 94
        $this->checkIfNamedForm();
463 94
        $this->pullFromOptions('data', 'addData');
464 94
        $this->pullFromOptions('model', 'setupModel');
465 94
        $this->pullFromOptions('errors_enabled', 'setErrorsEnabled');
466 94
        $this->pullFromOptions('client_validation', 'setClientValidationEnabled');
467 94
        $this->pullFromOptions('template_prefix', 'setTemplatePrefix');
468 94
        $this->pullFromOptions('language_name', 'setLanguageName');
469
470 94
        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 94
    protected function pullFromOptions($name, $method)
480
    {
481 94
        if (array_get($this->formOptions, $name) !== null) {
482 15
            $this->{$method}(array_pull($this->formOptions, $name));
483
        }
484 94
    }
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 48
    public function getName()
536
    {
537 48
        return $this->name;
538
    }
539
540
    /**
541
     * @param string $name
542
     * @param bool $rebuild
543
     *
544
     * @return $this
545
     */
546 9
    public function setName($name, $rebuild = true)
547
    {
548 9
        $this->name = $name;
549
550 9
        if ($rebuild) {
551 9
            $this->rebuildForm();
552
        }
553
554 9
        return $this;
555
    }
556
557
    /**
558
     * Get model that is bind to form object
559
     *
560
     * @return mixed
561
     */
562 68
    public function getModel()
563
    {
564 68
        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 19
    public function getFields()
604
    {
605 19
        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 94
    public function setFormHelper(FormHelper $formHelper)
628
    {
629 94
        $this->formHelper = $formHelper;
630
631 94
        return $this;
632
    }
633
634
    /**
635
     * Get form helper
636
     *
637
     * @return FormHelper
638
     */
639 72
    public function getFormHelper()
640
    {
641 72
        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 72
    public function haveErrorsEnabled()
661
    {
662 72
        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 72
    public function clientValidationEnabled()
684
    {
685 72
        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 14
    public function getData($name = null, $default = null)
722
    {
723 14
        if (is_null($name)) {
724 13
            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 72
    public function getRequest()
753
    {
754 72
        return $this->request;
755
    }
756
757
    /**
758
     * Set request on form
759
     *
760
     * @param Request $request
761
     * @return $this
762
     */
763 94
    public function setRequest(Request $request)
764
    {
765 94
        $this->request = $request;
766
767 94
        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 70
    public function getLanguageName()
803
    {
804 70
        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 10
    public function setLanguageName($prefix)
814
    {
815 10
        $this->languageName = (string) $prefix;
816
817 10
        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 39
    protected function preventDuplicate($name)
882
    {
883 39
        if ($this->has($name)) {
884 1
            throw new \InvalidArgumentException('Field ['.$name.'] already exists in the form '.get_class($this));
885
        }
886 39
    }
887
888
    /**
889
     * @param string $type
890
     * @return string
891
     */
892 43
    protected function getFieldType($type)
893
    {
894 43
        $fieldType = $this->formHelper->getFieldType($type);
895
896 42
        return $fieldType;
897
    }
898
899
    /**
900
     * Check if form is named form
901
     */
902 94
    protected function checkIfNamedForm()
903
    {
904 94
        if ($this->getFormOption('name')) {
905 5
            $this->name = array_pull($this->formOptions, 'name', $this->name);
906
        }
907 94
    }
908
909
    /**
910
     * Set up options on single field depending on form options
911
     *
912
     * @param string $name
913
     * @param $options
914
     */
915 43
    protected function setupFieldOptions($name, &$options)
916
    {
917 43
        $options['real_name'] = $name;
918 43
    }
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 27
    protected function setupNamedModel()
927
    {
928 27
        if (!$this->getModel() || !$this->getName()) {
929 26
            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 94
    public function setFormBuilder(FormBuilder $formBuilder)
954
    {
955 94
        $this->formBuilder = $formBuilder;
956
957 94
        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 94
    public function setValidator(ValidatorFactory $validator)
973
    {
974 94
        $this->validatorFactory = $validator;
975
976 94
        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 43
    protected function getFieldName($name)
999
    {
1000 43
        if ($this->getName() !== null) {
1001 11
            return $this->getName().'['.$name.']';
1002
        }
1003
1004 43
        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 1
    public function getAllAttributes()
1065
    {
1066 1
        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 1
    public function getValidatedValues($with_nulls = true)
1108
    {
1109 1
        $request_values = $this->getRequest()->all();
1110
1111 1
        $values = [];
1112 1
        foreach ($this->getAllAttributes() as $attribute) {
1113 1
            $value = Arr::get($request_values, $attribute);
1114 1
            if ($with_nulls || $value !== null) {
1115 1
                Arr::set($values, $attribute, $value);
1116
            }
1117
        }
1118
1119 1
        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