Completed
Push — master ( 14ef77...89c348 )
by Kristijan
18:04
created

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