Completed
Pull Request — master (#254)
by Rudie
07:17
created

Form::setEventDispatcher()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

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