Completed
Pull Request — master (#248)
by Rudie
13:15
created

Form::setRequest()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

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