Completed
Push — master ( 551415...4aebb4 )
by Kristijan
05:35
created

Form::__isset()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 1
dl 0
loc 4
ccs 0
cts 0
cp 0
crap 2
rs 10
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
     * Check if field exists when fetched using magic methods
637
     * @param $name
638
     * @return bool
639
     */
640
    public function __isset($name)
641
    {
642
        return $this->has($name);
643
    }
644
645
    /**
646
     * Set the Event Dispatcher to fire Laravel events
647
     *
648
     * @param EventDispatcher $eventDispatcher
649
     * @return $this
650
     */
651 106
    public function setEventDispatcher(EventDispatcher $eventDispatcher)
652
    {
653 106
        $this->eventDispatcher = $eventDispatcher;
654
655 106
        return $this;
656
    }
657
658
    /**
659
     * Set the form helper only on first instantiation
660
     *
661
     * @param FormHelper $formHelper
662
     * @return $this
663
     */
664 106
    public function setFormHelper(FormHelper $formHelper)
665
    {
666 106
        $this->formHelper = $formHelper;
667
668 106
        return $this;
669
    }
670
671
    /**
672
     * Get form helper
673
     *
674
     * @return FormHelper
675
     */
676 84
    public function getFormHelper()
677
    {
678 84
        return $this->formHelper;
679
    }
680
681
    /**
682
     * Add custom field
683
     *
684
     * @param $name
685
     * @param $class
686
     */
687 2
    public function addCustomField($name, $class)
688
    {
689 2
        $this->formHelper->addCustomField($name, $class);
690 2
    }
691
692
    /**
693
     * Should form errors be shown under every field ?
694
     *
695
     * @return bool
696
     */
697 84
    public function haveErrorsEnabled()
698
    {
699 84
        return $this->showFieldErrors;
700
    }
701
702
    /**
703
     * Enable or disable showing errors under fields
704
     *
705
     * @param boolean $enabled
706
     * @return $this
707
     */
708 1
    public function setErrorsEnabled($enabled)
709
    {
710 1
        $this->showFieldErrors = (boolean) $enabled;
711
712 1
        return $this;
713
    }
714
715
    /**
716
     * Is client validation enabled?
717
     *
718
     * @return boolean
719
     */
720 20
    public function clientValidationEnabled()
721
    {
722 20
        return $this->clientValidationEnabled;
723
    }
724
725
    /**
726
     * Enable/disable client validation
727
     *
728
     * @param boolean $enable
729
     * @return $this
730
     */
731 2
    public function setClientValidationEnabled($enable)
732
    {
733 2
        $this->clientValidationEnabled = (boolean) $enable;
734
735 2
        return $this;
736
    }
737
738
    /**
739
     * Add any aditional data that field needs (ex. array of choices)
740
     *
741
     * @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
742
     * will be switched to protected in 1.7
743
     * @param string $name
744
     * @param mixed $data
745
     */
746
    public function setData($name, $data)
747
    {
748
        $this->data[$name] = $data;
749
    }
750
751
    /**
752
     * Get single additional data
753
     *
754
     * @param string $name
755
     * @param null   $default
756
     * @return mixed
757
     */
758 17
    public function getData($name = null, $default = null)
759
    {
760 17
        if (is_null($name)) {
761 16
            return $this->data;
762
        }
763
764 1
        return array_get($this->data, $name, $default);
765
    }
766
767
    /**
768
     * Add multiple peices of data at once
769
     *
770
     * @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
771
     * will be switched to protected in 1.7
772
     * @param $data
773
     * @return $this
774
     **/
775
    public function addData(array $data)
776
    {
777
        foreach ($data as $key => $value) {
778
            $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...
779
        }
780
781
        return $this;
782
    }
783
784
    /**
785
     * Get current request
786
     *
787
     * @return \Illuminate\Http\Request
788
     */
789 84
    public function getRequest()
790
    {
791 84
        return $this->request;
792
    }
793
794
    /**
795
     * Set request on form
796
     *
797
     * @param Request $request
798
     * @return $this
799
     */
800 106
    public function setRequest(Request $request)
801
    {
802 106
        $this->request = $request;
803
804 106
        return $this;
805
    }
806
807
    /**
808
     * Get template prefix that is prepended to all template paths
809
     *
810
     * @return string
811
     */
812 36
    public function getTemplatePrefix()
813
    {
814 36
        if ($this->templatePrefix !== null) {
815 4
            return $this->templatePrefix;
816
        }
817
818 32
        return $this->formHelper->getConfig('template_prefix');
819
    }
820
821
    /**
822
     * Set a template prefix for the form and its fields
823
     *
824
     * @param string $prefix
825
     * @return $this
826
     */
827 4
    public function setTemplatePrefix($prefix)
828
    {
829 4
        $this->templatePrefix = (string) $prefix;
830
831 4
        return $this;
832
    }
833
834
    /**
835
     * Get the language name
836
     *
837
     * @return string
838
     */
839 82
    public function getLanguageName()
840
    {
841 82
        return $this->languageName;
842
    }
843
844
    /**
845
     * Set a language name, used as prefix for translated strings
846
     *
847
     * @param string $prefix
848
     * @return $this
849
     */
850 11
    public function setLanguageName($prefix)
851
    {
852 11
        $this->languageName = (string) $prefix;
853
854 11
        return $this;
855
    }
856
857
    /**
858
     * Render the form
859
     *
860
     * @param $options
861
     * @param $fields
862
     * @param boolean $showStart
863
     * @param boolean $showFields
864
     * @param boolean $showEnd
865
     * @return string
866
     */
867 9
    protected function render($options, $fields, $showStart, $showFields, $showEnd)
868
    {
869 9
        $formOptions = $this->formHelper->mergeOptions($this->formOptions, $options);
870
871 9
        $this->setupNamedModel();
872
873 9
        return $this->formHelper->getView()
874 9
            ->make($this->getTemplate())
875 9
            ->with(compact('showStart', 'showFields', 'showEnd'))
876 9
            ->with('formOptions', $formOptions)
877 9
            ->with('fields', $fields)
878 9
            ->with('model', $this->getModel())
879 9
            ->with('exclude', $this->exclude)
880 9
            ->with('form', $this)
881 9
            ->render();
882
    }
883
884
    /**
885
     * Get template from options if provided, otherwise fallback to config
886
     *
887
     * @return mixed
888
     */
889 9
    protected function getTemplate()
890
    {
891 9
        return $this->getTemplatePrefix() . $this->getFormOption('template', $this->formHelper->getConfig('form'));
892
    }
893
894
    /**
895
     * Get all fields that are not rendered
896
     *
897
     * @return array
898
     */
899 2
    protected function getUnrenderedFields()
900
    {
901 2
        $unrenderedFields = [];
902
903 2
        foreach ($this->fields as $field) {
904 2
            if (!$field->isRendered()) {
905 2
                $unrenderedFields[] = $field;
906 2
                continue;
907
            }
908
        }
909
910 2
        return $unrenderedFields;
911
    }
912
913
    /**
914
     * Prevent adding fields with same name
915
     *
916
     * @param string $name
917
     */
918 47
    protected function preventDuplicate($name)
919
    {
920 47
        if ($this->has($name)) {
921 1
            throw new \InvalidArgumentException('Field ['.$name.'] already exists in the form '.get_class($this));
922
        }
923 47
    }
924
925
    /**
926
     * @param string $type
927
     * @return string
928
     */
929 51
    protected function getFieldType($type)
930
    {
931 51
        $fieldType = $this->formHelper->getFieldType($type);
932
933 50
        return $fieldType;
934
    }
935
936
    /**
937
     * Check if form is named form
938
     */
939 106
    protected function checkIfNamedForm()
940
    {
941 106
        if ($this->getFormOption('name')) {
942 7
            $this->name = array_pull($this->formOptions, 'name', $this->name);
943
        }
944 106
    }
945
946
    /**
947
     * Set up options on single field depending on form options
948
     *
949
     * @param string $name
950
     * @param $options
951
     */
952 51
    protected function setupFieldOptions($name, &$options)
953
    {
954 51
        $options['real_name'] = $name;
955 51
    }
956
957
    /**
958
     * Set namespace to model if form is named so the data is bound properly
959
     * Returns true if model is changed, otherwise false
960
     *
961
     * @return bool
962
     */
963 31
    protected function setupNamedModel()
964
    {
965 31
        if (!$this->getModel() || !$this->getName()) {
966 30
            return false;
967
        }
968
969 4
        $dotName = $this->formHelper->transformToDotSyntax($this->getName());
970 4
        $model = $this->formHelper->convertModelToArray($this->getModel());
971
972 4
        if (!array_get($model, $dotName)) {
973 4
            $newModel = [];
974 4
            array_set($newModel, $dotName, $model);
975 4
            $this->model = $newModel;
976
977 4
            return true;
978
        }
979
980 3
        return false;
981
    }
982
983
984
    /**
985
     * Set form builder instance on helper so we can use it later
986
     *
987
     * @param FormBuilder $formBuilder
988
     * @return $this
989
     */
990 106
    public function setFormBuilder(FormBuilder $formBuilder)
991
    {
992 106
        $this->formBuilder = $formBuilder;
993
994 106
        return $this;
995
    }
996
997
    /**
998
     * @return FormBuilder
999
     */
1000 11
    public function getFormBuilder()
1001
    {
1002 11
        return $this->formBuilder;
1003
    }
1004
1005
    /**
1006
     * @param ValidatorFactory $validator
1007
     * @return $this
1008
     */
1009 106
    public function setValidator(ValidatorFactory $validator)
1010
    {
1011 106
        $this->validatorFactory = $validator;
1012
1013 106
        return $this;
1014
    }
1015
1016
    /**
1017
     * @return Validator
1018
     */
1019 1
    public function getValidator()
1020
    {
1021 1
        return $this->validator;
1022
    }
1023
1024
    /**
1025
     * Exclude some fields from rendering
1026
     *
1027
     * @return $this
1028
     */
1029
    public function exclude(array $fields)
1030
    {
1031
        $this->exclude = array_merge($this->exclude, $fields);
1032
1033
        return $this;
1034
    }
1035
1036
1037
    /**
1038
     * If form is named form, modify names to be contained in single key (parent[child_field_name])
1039
     *
1040
     * @param string $name
1041
     * @return string
1042
     */
1043 51
    protected function getFieldName($name)
1044
    {
1045 51
        $formName = $this->getName();
1046 51
        if ($formName !== null) {
1047 14
            if (strpos($formName, '[') !== false || strpos($formName, ']') !== false) {
1048 6
                return $this->formHelper->transformToBracketSyntax(
1049 6
                    $this->formHelper->transformToDotSyntax(
1050 6
                        $formName . '[' . $name . ']'
1051
                    )
1052
                );
1053
            }
1054
1055 11
            return $formName . '[' . $name . ']';
1056
        }
1057
1058 51
        return $name;
1059
    }
1060
1061
    /**
1062
     * Disable all fields in a form
1063
     */
1064 1
    public function disableFields()
1065
    {
1066 1
        foreach ($this->fields as $field) {
1067 1
            $field->disable();
1068
        }
1069 1
    }
1070
1071
    /**
1072
     * Enable all fields in a form
1073
     */
1074 1
    public function enableFields()
1075
    {
1076 1
        foreach ($this->fields as $field) {
1077 1
            $field->enable();
1078
        }
1079 1
    }
1080
1081
    /**
1082
     * Validate the form
1083
     *
1084
     * @param array $validationRules
1085
     * @param array $messages
1086
     * @return Validator
1087
     */
1088 8
    public function validate($validationRules = [], $messages = [])
1089
    {
1090 8
        $fieldRules = $this->formHelper->mergeFieldsRules($this->fields);
1091 8
        $rules = array_merge($fieldRules['rules'], $validationRules);
1092 8
        $messages = array_merge($fieldRules['error_messages'], $messages);
1093
1094 8
        $this->validator = $this->validatorFactory->make($this->getRequest()->all(), $rules, $messages);
1095 8
        $this->validator->setAttributeNames($fieldRules['attributes']);
1096
1097 8
        $this->eventDispatcher->fire(new BeforeFormValidation($this, $this->validator));
1098
1099 8
        return $this->validator;
1100
    }
1101
1102
    /**
1103
     * Get validatdion rules for the form
1104
     *
1105
     * @param array $overrideRules
1106
     * @return array
1107
     */
1108 1
    public function getRules($overrideRules = [])
1109
    {
1110 1
        $fieldRules = $this->formHelper->mergeFieldsRules($this->fields);
1111
1112 1
        return array_merge($fieldRules['rules'], $overrideRules);
1113
    }
1114
1115 2
    public function redirectIfNotValid($destination = null)
1116
    {
1117 2
        if (! $this->isValid()) {
1118 2
            $response = redirect($destination);
1119
1120 2
            if (is_null($destination)) {
1121 1
                $response = $response->back();
1122
            }
1123
1124 2
            $response = $response->withErrors($this->getErrors())->withInput();
1125
1126 2
            throw new HttpResponseException($response);
1127
        }
1128
    }
1129
1130
    /**
1131
     * Get all form field attributes, including child forms, in a flat array.
1132
     *
1133
     * @return array
1134
     */
1135 3
    public function getAllAttributes()
1136
    {
1137 3
        return $this->formHelper->mergeAttributes($this->fields);
1138
    }
1139
1140
    /**
1141
     * Check if the form is valid
1142
     *
1143
     * @return bool
1144
     */
1145 8
    public function isValid()
1146
    {
1147 8
        if (!$this->validator) {
1148 7
            $this->validate();
1149
        }
1150
1151 8
        $isValid = !$this->validator->fails();
1152
1153 8
        $this->formHelper->alterValid($this, $this, $isValid);
1154
1155 8
        $this->eventDispatcher->fire(new AfterFormValidation($this, $this->validator, $isValid));
1156
1157 8
        return $isValid;
1158
    }
1159
1160
    /**
1161
     * Optionally change the validation result, and/or add error messages
1162
     *
1163
     * @return void|array
1164
     */
1165 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...
1166
    {
1167
        // return ['name' => ['Some other error about the Name field.']];
1168 8
    }
1169
1170
    /**
1171
     * Get validation errors
1172
     *
1173
     * @return array
1174
     */
1175 7
    public function getErrors()
1176
    {
1177 7
        if (!$this->validator || !$this->validator instanceof Validator) {
1178 1
            throw new \InvalidArgumentException(
1179
                sprintf(
1180 1
                    'Form %s was not validated. To validate it, call "isValid" method before retrieving the errors',
1181
                    get_class($this)
1182
                )
1183
            );
1184
        }
1185
1186 6
        return $this->validator->getMessageBag()->getMessages();
1187
    }
1188
1189
    /**
1190
     * Get all Request values from all fields, and nothing else.
1191
     *
1192
     * @return array
1193
     */
1194 3
    public function getFieldValues($with_nulls = true)
1195
    {
1196 3
        $request_values = $this->getRequest()->all();
1197
1198 3
        $values = [];
1199 3
        foreach ($this->getAllAttributes() as $attribute) {
1200 3
            $value = Arr::get($request_values, $attribute);
1201 3
            if ($with_nulls || $value !== null) {
1202 3
                Arr::set($values, $attribute, $value);
1203
            }
1204
        }
1205
1206
        // If this form is a child form, cherry pick a part
1207 3
        if ($prefix = $this->getName()) {
1208 1
            $prefix = $this->formHelper->transformToDotSyntax($prefix);
1209 1
            $values = Arr::get($values, $prefix);
1210
        }
1211
1212
        // Allow form-specific value alters
1213 3
        $this->formHelper->alterFieldValues($this, $values);
1214
1215 3
        return $values;
1216
    }
1217
1218
    /**
1219
     * Optionally mess with this form's $values before it's returned from getFieldValues()
1220
     */
1221 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...
1222
    {
1223 3
    }
1224
1225
    /**
1226
     * Throw an exception indicating a field does not exist on the class
1227
     *
1228
     * @param string $name
1229
     * @throws \InvalidArgumentException
1230
     */
1231 2
    protected function fieldDoesNotExist($name)
1232
    {
1233 2
        throw new \InvalidArgumentException('Field ['.$name.'] does not exist in '.get_class($this));
1234
    }
1235
}
1236