Completed
Pull Request — master (#254)
by Rudie
11:44
created

Form::getFields()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

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