Completed
Push — master ( ffc04d...c04ae0 )
by Kristijan
06:37
created

Form::add()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 12
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 3.0416

Importance

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