Completed
Push — master ( 54b1af...d6de97 )
by Kristijan
11s
created

Form::setName()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 2

Importance

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

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $isValid is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1156
    {
1157
        // return ['name' => ['Some other error about the Name field.']];
1158 8
    }
1159
1160
    /**
1161
     * Get validation errors
1162
     *
1163
     * @return array
1164
     */
1165 7
    public function getErrors()
1166
    {
1167 7
        if (!$this->validator || !$this->validator instanceof Validator) {
1168 1
            throw new \InvalidArgumentException(
1169
                sprintf(
1170 1
                    'Form %s was not validated. To validate it, call "isValid" method before retrieving the errors',
1171
                    get_class($this)
1172
                )
1173
            );
1174
        }
1175
1176 6
        return $this->validator->getMessageBag()->getMessages();
1177
    }
1178
1179
    /**
1180
     * Get all Request values from all fields, and nothing else.
1181
     *
1182
     * @return array
1183
     */
1184 3
    public function getFieldValues($with_nulls = true)
1185
    {
1186 3
        $request_values = $this->getRequest()->all();
1187
1188 3
        $values = [];
1189 3
        foreach ($this->getAllAttributes() as $attribute) {
1190 3
            $value = Arr::get($request_values, $attribute);
1191 3
            if ($with_nulls || $value !== null) {
1192 3
                Arr::set($values, $attribute, $value);
1193
            }
1194
        }
1195
1196
        // If this form is a child form, cherry pick a part
1197 3
        if ($prefix = $this->getName()) {
1198 1
            $prefix = $this->formHelper->transformToDotSyntax($prefix);
1199 1
            $values = Arr::get($values, $prefix);
1200
        }
1201
1202
        // Allow form-specific value alters
1203 3
        $this->formHelper->alterFieldValues($this, $values);
1204
1205 3
        return $values;
1206
    }
1207
1208
    /**
1209
     * Optionally mess with this form's $values before it's returned from getFieldValues()
1210
     */
1211 3
    public function alterFieldValues(array &$values)
0 ignored issues
show
Unused Code introduced by
The parameter $values is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1212
    {
1213 3
    }
1214
1215
    /**
1216
     * Throw an exception indicating a field does not exist on the class
1217
     *
1218
     * @param string $name
1219
     * @throws \InvalidArgumentException
1220
     */
1221 2
    protected function fieldDoesNotExist($name)
1222
    {
1223 2
        throw new \InvalidArgumentException('Field ['.$name.'] does not exist in '.get_class($this));
1224
    }
1225
}
1226