Completed
Pull Request — master (#588)
by
unknown
02:50
created

FormField::isValidValue()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 1
dl 0
loc 4
rs 10
c 0
b 0
f 0
ccs 2
cts 2
cp 1
crap 1
1
<?php
2
3
namespace Kris\LaravelFormBuilder\Fields;
4
5
use Illuminate\Support\Arr;
6
use Illuminate\Support\Str;
7
use Kris\LaravelFormBuilder\Filters\Exception\FilterAlreadyBindedException;
8
use Kris\LaravelFormBuilder\Filters\FilterInterface;
9
use Kris\LaravelFormBuilder\Filters\FilterResolver;
10
use Kris\LaravelFormBuilder\Form;
11
use Kris\LaravelFormBuilder\FormHelper;
12
use Kris\LaravelFormBuilder\Rules;
13
14
/**
15
 * Class FormField
16
 *
17
 * @package Kris\LaravelFormBuilder\Fields
18
 */
19
abstract class FormField
20
{
21
    /**
22
     * Name of the field.
23
     *
24
     * @var string
25
     */
26
    protected $name;
27
28
    /**
29
     * Type of the field.
30
     *
31
     * @var string
32
     */
33
    protected $type;
34
35
    /**
36
     * All options for the field.
37
     *
38
     * @var array
39
     */
40
    protected $options = [];
41
42
    /**
43
     * Is field rendered.
44
     *
45
     * @var bool
46
     */
47
    protected $rendered = false;
48
49
    /**
50
     * @var Form
51
     */
52
    protected $parent;
53
54
    /**
55
     * @var string
56
     */
57
    protected $template;
58
59
    /**
60
     * @var FormHelper
61
     */
62
    protected $formHelper;
63
64
    /**
65
     * Name of the property for value setting.
66
     *
67
     * @var string
68
     */
69
    protected $valueProperty = 'value';
70
71
    /**
72
     * Name of the property for default value.
73
     *
74
     * @var string
75
     */
76
    protected $defaultValueProperty = 'default_value';
77
78
    /**
79
     * Is default value set?
80
     *
81
     * @var bool|false
82
     */
83
    protected $hasDefault = false;
84
85
    /**
86
     * @var \Closure|null
87
     */
88
    protected $valueClosure = null;
89
90
    /**
91
     * Array of filters key(alias/name) => objects.
92
     *
93
     * @var array
94
     */
95
    protected $filters = [];
96
97
    /**
98
     * Raw/unfiltered field value.
99
     *
100
     * @var mixed $rawValues
101
     */
102
    protected $rawValue;
103
104
    /**
105
     * Override filters with same alias/name for field.
106
     *
107
     * @var bool
108
     */
109
    protected $filtersOverride = false;
110
111
    /**
112
     * @param string $name
113
     * @param string $type
114
     * @param Form $parent
115
     * @param array $options
116
     */
117 104
    public function __construct($name, $type, Form $parent, array $options = [])
118
    {
119 104
        $this->name = $name;
120 104
        $this->type = $type;
121 104
        $this->parent = $parent;
122 104
        $this->formHelper = $this->parent->getFormHelper();
123 104
        $this->setTemplate();
124 104
        $this->setDefaultOptions($options);
125 104
        $this->setupValue();
126 99
        $this->initFilters();
127 99
    }
128
129
130
    /**
131
     * Setup the value of the form field.
132
     *
133
     * @return void
134
     */
135 104
    protected function setupValue()
136
    {
137 104
        $value = $this->getOption($this->valueProperty);
138 104
        $isChild = $this->getOption('is_child');
139
140 104
        if ($value instanceof \Closure) {
141
            $this->valueClosure = $value;
142
        }
143
144 104
        if (($value === null || $value instanceof \Closure) && !$isChild) {
145 93
            $this->setValue($this->getModelValueAttribute($this->parent->getModel(), $this->name));
146 24
        } elseif (!$isChild) {
147 14
            $this->hasDefault = true;
148
        }
149 99
    }
150
151
    /**
152
     * Get the template, can be config variable or view path.
153
     *
154
     * @return string
155
     */
156
    abstract protected function getTemplate();
157
158
    /**
159
     * @return string
160
     */
161 35
    protected function getViewTemplate()
162
    {
163 35
        return $this->parent->getTemplatePrefix() . $this->getOption('template', $this->template);
164
    }
165
166
    /**
167
     * Render the field.
168
     *
169
     * @param array $options
170
     * @param bool  $showLabel
171
     * @param bool  $showField
172
     * @param bool  $showError
173
     * @return string
174
     */
175 35
    public function render(array $options = [], $showLabel = true, $showField = true, $showError = true)
176
    {
177 35
        $this->prepareOptions($options);
178 35
        $value = $this->getValue();
179 35
        $defaultValue = $this->getDefaultValue();
180
181 35
        if ($showField) {
182 35
            $this->rendered = true;
183
        }
184
185
        // Override default value with value
186 35
        if (!$this->isValidValue($value) && $this->isValidValue($defaultValue)) {
187
            $this->setOption($this->valueProperty, $defaultValue);
188
        }
189
190 35
        if (!$this->needsLabel()) {
191 11
            $showLabel = false;
192
        }
193
194 35
        if ($showError) {
195 34
            $showError = $this->parent->haveErrorsEnabled();
196
        }
197
198 35
        $data = $this->getRenderData();
199
200 35
        return $this->formHelper->getView()->make(
201 35
            $this->getViewTemplate(),
202
            $data + [
203 35
                'name' => $this->name,
204 35
                'nameKey' => $this->getNameKey(),
205 35
                'type' => $this->type,
206 35
                'options' => $this->options,
207 35
                'showLabel' => $showLabel,
208 35
                'showField' => $showField,
209 35
                'showError' => $showError,
210 35
                'errorBag'  => $this->parent->getErrorBag(),
211 35
                'translationTemplate' => $this->parent->getTranslationTemplate(),
212
            ]
213 35
        )->render();
214
    }
215
216
    /**
217
     * Return the extra render data for this form field, passed into the field's template directly.
218
     *
219
     * @return array
220
     */
221 35
    protected function getRenderData()
222
    {
223 35
        return [];
224
    }
225
226
    /**
227
     * Get the attribute value from the model by name.
228
     *
229
     * @param mixed $model
230
     * @param string $name
231
     * @return mixed
232
     */
233 95
    protected function getModelValueAttribute($model, $name)
234
    {
235 95
        $transformedName = $this->transformKey($name);
236 95
        if (is_string($model)) {
237
            return $model;
238 95
        } elseif (is_object($model)) {
239 3
            return object_get($model, $transformedName);
240 95
        } elseif (is_array($model)) {
241 94
            return Arr::get($model, $transformedName);
242
        }
243 5
    }
244
245
    /**
246
     * Transform array like syntax to dot syntax.
247
     *
248
     * @param string $key
249
     * @return mixed
250
     */
251 104
    protected function transformKey($key)
252
    {
253 104
        return $this->formHelper->transformToDotSyntax($key);
254
    }
255
256
    /**
257
     * Prepare options for rendering.
258
     *
259
     * @param array $options
260
     * @return array The parsed options
261
     */
262 104
    protected function prepareOptions(array $options = [])
263
    {
264 104
        $helper = $this->formHelper;
265
266 104
        $this->options = $this->prepareRules($options);
267 104
        $this->options = $helper->mergeOptions($this->options, $options);
268
269 104
        $rulesParser = $helper->createRulesParser($this);
270 104
        $rules = $this->getOption('rules');
271 104
        $parsedRules = $rules ? $rulesParser->parse($rules) : [];
272
273
274 104
        foreach (['attr', 'label_attr', 'wrapper'] as $appendable) {
275
            // Append values to the 'class' attribute
276 104
            if ($this->getOption("{$appendable}.class_append")) {
277
                // Combine the current class attribute with the appends
278 3
                $append = $this->getOption("{$appendable}.class_append");
279 3
                $classAttribute = $this->getOption("{$appendable}.class", '') . ' ' . $append;
280 3
                $this->setOption("{$appendable}.class", $classAttribute);
281
282
                // Then remove the class_append option to prevent it from showing up as an attribute in the HTML
283 104
                $this->setOption("{$appendable}.class_append", null);
284
            }
285
        }
286
287 104
        if ($this->getOption('attr.multiple') && !$this->getOption('tmp.multipleBracesSet')) {
288 2
            $this->name = $this->name . '[]';
289 2
            $this->setOption('tmp.multipleBracesSet', true);
290
        }
291
292 104
        if ($this->parent->haveErrorsEnabled()) {
293 104
            $this->addErrorClass();
294
        }
295
296 104
        if ($this->getOption('required') === true || isset($parsedRules['required'])) {
297 16
            $lblClass = $this->getOption('label_attr.class', '');
298 16
            $requiredClass = $this->getConfig('defaults.required_class', 'required');
299
300 16
            if (!Str::contains($lblClass, $requiredClass)) {
301 16
                $lblClass .= ' ' . $requiredClass;
302 16
                $this->setOption('label_attr.class', $lblClass);
303
            }
304
305 16
            if ($this->parent->clientValidationEnabled()) {
306 15
                $this->setOption('attr.required', 'required');
307
            }
308
        }
309
310 104
        if ($this->parent->clientValidationEnabled() && $parsedRules) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $parsedRules of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
311 13
            $attrs = $this->getOption('attr') + $parsedRules;
312 13
            $this->setOption('attr', $attrs);
313
        }
314
315 104
        $this->setOption('wrapperAttrs', $helper->prepareAttributes($this->getOption('wrapper')));
316 104
        $this->setOption('errorAttrs', $helper->prepareAttributes($this->getOption('errors')));
317
318 104
        if ($this->getOption('help_block.text')) {
319 1
            $this->setOption(
320 1
                'help_block.helpBlockAttrs',
321 1
                $helper->prepareAttributes($this->getOption('help_block.attr'))
322
            );
323
        }
324
325 104
        return $this->options;
326
    }
327
328
    /**
329
     * Normalize and merge rules.
330
     * @param array $sourceOptions
331
     * @return array
332
     */
333 104
    protected function prepareRules(array &$sourceOptions = [])
334
    {
335 104
        $options = $this->options;
336
337
        // Normalize rules
338 104
        if (array_key_exists('rules_append', $sourceOptions)) {
339 1
            $sourceOptions['rules_append'] = $this->normalizeRules($sourceOptions['rules_append']);
340
        }
341
342 104
        if (array_key_exists('rules', $sourceOptions)) {
343 25
            $sourceOptions['rules'] = $this->normalizeRules($sourceOptions['rules']);
344
        }
345
346 104
        if (array_key_exists('rules', $options)) {
347 104
            $options['rules'] = $this->normalizeRules($options['rules']);
348
        }
349
350
351
        // Append rules
352 104
        if ($rulesToBeAppended = Arr::pull($sourceOptions, 'rules_append')) {
353 1
            $mergedRules = array_values(array_unique(array_merge($options['rules'], $rulesToBeAppended), SORT_REGULAR));
354 1
            $options['rules'] = $mergedRules;
355
        }
356
357 104
        return $options;
358
    }
359
360
    /**
361
     * Normalize the the given rule expression to an array.
362
     * @param mixed $rules
363
     * @return array
364
     */
365 104
    protected function normalizeRules($rules)
366
    {
367 104
        if (empty($rules)) {
368 103
            return [];
369
        }
370
371 14
        if (is_string($rules)) {
372 14
            return explode('|', $rules);
373
        }
374
375 8
        if (is_array($rules)) {
376 8
            $normalizedRules = [];
377 8
            foreach ($rules as $rule) {
378 8
                $normalizedRules[] = $this->normalizeRules($rule);
379
            }
380
381 8
            return array_values(array_unique(Arr::flatten($normalizedRules), SORT_REGULAR));
0 ignored issues
show
Documentation introduced by
$normalizedRules is of type array, but the function expects a object<Illuminate\Support\iterable>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
382
        }
383
384 1
        return $rules;
385
    }
386
387
388
    /**
389
     * Get name of the field.
390
     *
391
     * @return string
392
     */
393 41
    public function getName()
394
    {
395 41
        return $this->name;
396
    }
397
398
    /**
399
     * Set name of the field.
400
     *
401
     * @param string $name
402
     * @return $this
403
     */
404 13
    public function setName($name)
405
    {
406 13
        $this->name = $name;
407
408 13
        return $this;
409
    }
410
411
    /**
412
     * Get dot notation key for fields.
413
     *
414
     * @return string
415
     **/
416 56
    public function getNameKey()
417
    {
418 56
        return $this->transformKey($this->name);
419
    }
420
421
    /**
422
     * Get field options.
423
     *
424
     * @return array
425
     */
426 12
    public function getOptions()
427
    {
428 12
        return $this->options;
429
    }
430
431
    /**
432
     * Get single option from options array. Can be used with dot notation ('attr.class').
433
     *
434
     * @param string $option
435
     * @param mixed|null $default
436
     * @return mixed
437
     */
438 104
    public function getOption($option, $default = null)
439
    {
440 104
        return Arr::get($this->options, $option, $default);
441
    }
442
443
    /**
444
     * Set field options.
445
     *
446
     * @param array $options
447
     * @return $this
448
     */
449 13
    public function setOptions($options)
450
    {
451 13
        $this->options = $this->prepareOptions($options);
452
453 13
        return $this;
454
    }
455
456
    /**
457
     * Set single option on the field.
458
     *
459
     * @param string $name
460
     * @param mixed $value
461
     * @return $this
462
     */
463 104
    public function setOption($name, $value)
464
    {
465 104
        Arr::set($this->options, $name, $value);
466
467 104
        return $this;
468
    }
469
470
    /**
471
     * Get the type of the field.
472
     *
473
     * @return string
474
     */
475 68
    public function getType()
476
    {
477 68
        return $this->type;
478
    }
479
480
    /**
481
     * Set type of the field.
482
     *
483
     * @param mixed $type
484
     * @return $this
485
     */
486 1
    public function setType($type)
487
    {
488 1
        if ($this->formHelper->getFieldType($type)) {
489 1
            $this->type = $type;
490
        }
491
492 1
        return $this;
493
    }
494
495
    /**
496
     * @return Form
497
     */
498 104
    public function getParent()
499
    {
500 104
        return $this->parent;
501
    }
502
503
    /**
504
     * Check if the field is rendered.
505
     *
506
     * @return bool
507
     */
508 4
    public function isRendered()
509
    {
510 4
        return $this->rendered;
511
    }
512
513
    /**
514
     * Default options for field.
515
     *
516
     * @return array
517
     */
518 77
    protected function getDefaults()
519
    {
520 77
        return [];
521
    }
522
523
    /**
524
     * Defaults used across all fields.
525
     *
526
     * @return array
527
     */
528 104
    private function allDefaults()
529
    {
530
        return [
531 104
            'wrapper' => ['class' => $this->getConfig('defaults.wrapper_class')],
532 104
            'attr' => ['class' => $this->getConfig('defaults.field_class')],
533 104
            'help_block' => ['text' => null, 'tag' => 'p', 'attr' => [
534 104
                'class' => $this->getConfig('defaults.help_block_class')
535
            ]],
536
            'value' => null,
537
            'default_value' => null,
538
            'label' => null,
539
            'label_show' => true,
540
            'is_child' => false,
541 104
            'label_attr' => ['class' => $this->getConfig('defaults.label_class')],
542 104
            'errors' => ['class' => $this->getConfig('defaults.error_class')],
543
            'rules' => [],
544
            'error_messages' => []
545
        ];
546
    }
547
548
    /**
549
     * Get real name of the field without form namespace.
550
     *
551
     * @return string
552
     */
553 103
    public function getRealName()
554
    {
555 103
        return $this->getOption('real_name', $this->name);
556
    }
557
558
    /**
559
     * @param $value
560
     * @return $this
561
     */
562 97
    public function setValue($value)
563
    {
564 97
        if ($this->hasDefault) {
565 1
            return $this;
566
        }
567
568 97
        $closure = $this->valueClosure;
569
570 97
        if ($closure instanceof \Closure) {
571
            $value = $closure($value ?: null);
572
        }
573
574 97
        if (!$this->isValidValue($value)) {
575 94
            $value = $this->getOption($this->defaultValueProperty);
576
        }
577
578 97
        $this->options[$this->valueProperty] = $value;
579
580 97
        return $this;
581
    }
582
583
    /**
584
     * Set the template property on the object.
585
     *
586
     * @return void
587
     */
588 104
    private function setTemplate()
589
    {
590 104
        $this->template = $this->getConfig($this->getTemplate(), $this->getTemplate());
591 104
    }
592
593
    /**
594
     * Add error class to wrapper if validation errors exist.
595
     *
596
     * @return void
597
     */
598 104
    protected function addErrorClass()
599
    {
600 104
        $errors = [];
601 104
        if ($this->parent->getRequest()->hasSession()) {
602 103
            $errors = $this->parent->getRequest()->session()->get('errors');
603
        }
604 104
        $errorBag = $this->parent->getErrorBag();
605
606 104
        if ($errors && $errors->hasBag($errorBag) && $errors->getBag($errorBag)->has($this->getNameKey())) {
607
            $fieldErrorClass = $this->getConfig('defaults.field_error_class');
608
            $fieldClass = $this->getOption('attr.class');
609
610
            if ($fieldErrorClass && !Str::contains($fieldClass, $fieldErrorClass)) {
611
                $fieldClass .= ' ' . $fieldErrorClass;
612
                $this->setOption('attr.class', $fieldClass);
613
            }
614
615
            $wrapperErrorClass = $this->getConfig('defaults.wrapper_error_class');
616
            $wrapperClass = $this->getOption('wrapper.class');
617
618
            if ($wrapperErrorClass && $this->getOption('wrapper') && !Str::contains($wrapperClass, $wrapperErrorClass)) {
619
                $wrapperClass .= ' ' . $wrapperErrorClass;
620
                $this->setOption('wrapper.class', $wrapperClass);
621
            }
622
        }
623 104
    }
624
625
    /**
626
     * Merge all defaults with field specific defaults and set template if passed.
627
     *
628
     * @param array $options
629
     */
630 104
    protected function setDefaultOptions(array $options = [])
631
    {
632 104
        $this->options = $options;
633 104
        $this->options = $this->formHelper->mergeOptions($this->allDefaults(), $this->getDefaults());
634 104
        $this->options = $this->prepareOptions($options);
635
636 104
        $defaults = $this->setDefaultClasses($options);
637 104
        $this->options = $this->formHelper->mergeOptions($this->options, $defaults);
638
639 104
        $this->setupLabel();
640 104
    }
641
642
    /**
643
     * Creates default wrapper classes for the form element.
644
     *
645
     * @param array $options
646
     * @return array
647
     */
648 104
    protected function setDefaultClasses(array $options = [])
649
    {
650 104
        $wrapper_class = $this->getConfig('defaults.' . $this->type . '.wrapper_class', '');
651 104
        $label_class = $this->getConfig('defaults.' . $this->type . '.label_class', '');
652 104
        $field_class = $this->getConfig('defaults.' . $this->type . '.field_class', '');
653
654 104
        $defaults = [];
655 104
        if ($wrapper_class && !Arr::get($options, 'wrapper.class')) {
656
            $defaults['wrapper']['class'] = $wrapper_class;
657
        }
658 104
        if ($label_class && !Arr::get($options, 'label_attr.class')) {
659
            $defaults['label_attr']['class'] = $label_class;
660
        }
661 104
        if ($field_class && !Arr::get($options, 'attr.class')) {
662 1
            $defaults['attr']['class'] = $field_class;
663
        }
664 104
        return $defaults;
665
    }
666
667
    /**
668
     * Setup the label for the form field.
669
     *
670
     * @return void
671
     */
672 104
    protected function setupLabel()
673
    {
674 104
        if ($this->getOption('label') !== null) {
675 24
            return;
676
        }
677
678 102
        if ($template = $this->parent->getTranslationTemplate()) {
679 3
            $label = str_replace(
680 3
                ['{name}', '{type}'],
681 3
                [$this->getRealName(), 'label'],
682 3
                $template
683
            );
684 99
        } elseif ($langName = $this->parent->getLanguageName()) {
685 4
            $label = sprintf('%s.%s', $langName, $this->getRealName());
686
        } else {
687 96
            $label = $this->getRealName();
688
        }
689
690 102
        $this->setOption('label', $this->formHelper->formatLabel($label));
691 102
    }
692
693
    /**
694
     * Check if fields needs label.
695
     *
696
     * @return bool
697
     */
698 35
    protected function needsLabel()
699
    {
700
        // If field is <select> and child of choice, we don't need label for it
701 35
        $isChildSelect = $this->type == 'select' && $this->getOption('is_child') === true;
702
703 35
        if ($this->type == 'hidden' || $isChildSelect) {
704 11
            return false;
705
        }
706
707 31
        return true;
708
    }
709
710
    /**
711
     * Disable field.
712
     *
713
     * @return $this
714
     */
715 1
    public function disable()
716
    {
717 1
        $this->setOption('attr.disabled', 'disabled');
718
719 1
        return $this;
720
    }
721
722
    /**
723
     * Enable field.
724
     *
725
     * @return $this
726
     */
727 1
    public function enable()
728
    {
729 1
        Arr::forget($this->options, 'attr.disabled');
730
731 1
        return $this;
732
    }
733
734
    /**
735
     * Get validation rules for a field if any with label for attributes.
736
     *
737
     * @return array|null
738
     */
739 10
    public function getValidationRules()
740
    {
741 10
        $rules = $this->getOption('rules', []);
742 10
        $name = $this->getNameKey();
743 10
        $messages = $this->getOption('error_messages', []);
744 10
        $formName = $this->parent->getNameKey();
745
746 10
        if ($messages && $formName) {
747 1
            $newMessages = [];
748 1
            foreach ($messages as $messageKey => $message) {
749 1
                $messageKey = sprintf('%s.%s', $formName, $messageKey);
750 1
                $newMessages[$messageKey] = $message;
751
            }
752 1
            $messages = $newMessages;
753
        }
754
755 10
        if (!$rules) {
756 2
            return (new Rules([]))->setFieldName($this->getNameKey());
757
        }
758
759 9
        return (new Rules(
760 9
            [$name => $rules],
761 9
            [$name => $this->getOption('label')],
762 9
            $messages
763 9
        ))->setFieldName($this->getNameKey());
764
    }
765
766
    /**
767
     * Get this field's attributes, probably just one.
768
     *
769
     * @return array
770
     */
771 3
    public function getAllAttributes()
772
    {
773 3
        return [$this->getNameKey()];
774
    }
775
776
    /**
777
     * Get value property.
778
     *
779
     * @param mixed|null $default
780
     * @return mixed
781
     */
782 38
    public function getValue($default = null)
783
    {
784 38
        return $this->getOption($this->valueProperty, $default);
785
    }
786
787
    /**
788
     * Get default value property.
789
     *
790
     * @param mixed|null $default
791
     * @return mixed
792
     */
793 35
    public function getDefaultValue($default = null)
794
    {
795 35
        return $this->getOption($this->defaultValueProperty, $default);
796
    }
797
798
    /**
799
     * Check if provided value is valid for this type.
800
     *
801
     * @return bool
802
     */
803 97
    protected function isValidValue($value)
804
    {
805 97
        return $value !== null;
806
    }
807
808
    /**
809
     * Method initFilters used to initialize filters
810
     * from field options and bind it to the same.
811
     *
812
     * @return $this
813
     */
814 99
    protected function initFilters()
815
    {
816
        // If override status is set in field options to true
817
        // we will change filtersOverride property value to true
818
        // so we can override existing filters with registered
819
        // alias/name in addFilter method.
820 99
        $overrideStatus = $this->getOption('filters_override', false);
821 99
        if ($overrideStatus) {
822 2
            $this->setFiltersOverride(true);
823
        }
824
825
        // Get filters and bind it to field.
826 99
        $filters = $this->getOption('filters', []);
827 99
        foreach ($filters as $filter) {
828 8
            $this->addFilter($filter);
829
        }
830
831 99
        return $this;
832
    }
833
834
    /**
835
     * Method setFilters used to set filters to current filters property.
836
     *
837
     * @param  array $filters
838
     *
839
     * @return \Kris\LaravelFormBuilder\Fields\FormField
840
     */
841
    public function setFilters(array $filters)
842
    {
843
        $this->clearFilters();
844
        foreach ($filters as $filter) {
845
            $this->addFilter($filter);
846
        }
847
848
        return $this;
849
    }
850
851
    /**
852
     * Method getFilters returns array of binded filters
853
     * if there are any binded. Otherwise empty array.
854
     *
855
     * @return array
856
     */
857 23
    public function getFilters()
858
    {
859 23
        return $this->filters;
860
    }
861
862
    /**
863
     * @param  string|FilterInterface $filter
864
     *
865
     * @return \Kris\LaravelFormBuilder\Fields\FormField
866
     *
867
     * @throws FilterAlreadyBindedException
868
     */
869 8
    public function addFilter($filter)
870
    {
871
        // Resolve filter object from string/object or throw Ex.
872 8
        $filterObj = FilterResolver::instance($filter);
873
874
        // If filtersOverride is allowed we will override filter
875
        // with same alias/name if there is one with new resolved filter.
876 8
        if ($this->getFiltersOverride()) {
877 1
            if ($key = array_search($filterObj->getName(), $this->getFilters())) {
878
                $this->filters[$key] = $filterObj;
879
            } else {
880 1
                $this->filters[$filterObj->getName()] = $filterObj;
881
            }
882
        } else {
883
            // If filtersOverride is disabled and we found
884
            // equal alias defined we will throw Ex.
885 7
            if (array_key_exists($filterObj->getName(), $this->getFilters())) {
886 1
                $ex = new FilterAlreadyBindedException($filterObj->getName(), $this->getName());
887 1
                throw $ex;
888
            }
889
890
            // Filter with resolvedFilter alias/name doesn't exist
891
            // so we will bind it as new one to field.
892 7
            $this->filters[$filterObj->getName()] = $filterObj;
893
        }
894
895 8
        return $this;
896
    }
897
898
    /**
899
     * Method removeFilter used to remove filter by provided alias/name.
900
     *
901
     * @param  string $name
902
     *
903
     * @return \Kris\LaravelFormBuilder\Fields\FormField
904
     */
905 1
    public function removeFilter($name)
906
    {
907 1
        $filters = $this->getFilters();
908 1
        if (array_key_exists($name, $filters)) {
909 1
            unset($filters[$name]);
910 1
            $this->filters = $filters;
911
        }
912
913 1
        return $this;
914
    }
915
916
    /**
917
     * Method removeFilters used to remove filters by provided aliases/names.
918
     *
919
     * @param  array $filterNames
920
     *
921
     * @return \Kris\LaravelFormBuilder\Fields\FormField
922
     */
923 1
    public function removeFilters(array $filterNames)
924
    {
925 1
        $filters = $this->getFilters();
926 1
        foreach ($filterNames as $filterName) {
927 1
            if (array_key_exists($filterName, $filters)) {
928 1
                unset($filters[$filterName]);
929 1
                $this->filters = $filters;
930
            }
931
        }
932
933 1
        return $this;
934
    }
935
936
    /**
937
     * Method clearFilters used to empty current filters property.
938
     *
939
     * @return \Kris\LaravelFormBuilder\Fields\FormField
940
     */
941 1
    public function clearFilters()
942
    {
943 1
        $this->filters = [];
944 1
        return $this;
945
    }
946
947
    /**
948
     * Method used to set FiltersOverride status to provided value.
949
     *
950
     * @param $status
951
     *
952
     * @return \Kris\LaravelFormBuilder\Fields\FormField
953
     */
954 2
    public function setFiltersOverride($status)
955
    {
956 2
        $this->filtersOverride = $status;
957 2
        return $this;
958
    }
959
960
    /**
961
     * @return bool
962
     */
963 9
    public function getFiltersOverride()
964
    {
965 9
        return $this->filtersOverride;
966
    }
967
968
    /**
969
     * Method used to set Unfiltered/Unmutated field value.
970
     * Method is called before field value mutating starts - request value filtering.
971
     *
972
     * @param mixed $value
973
     *
974
     * @return \Kris\LaravelFormBuilder\Fields\FormField
975
     */
976 1
    public function setRawValue($value)
977
    {
978 1
        $this->rawValue = $value;
979 1
        return $this;
980
    }
981
982
    /**
983
     * Returns unfiltered raw value of field.
984
     *
985
     * @return mixed
986
     */
987
    public function getRawValue()
988
    {
989
        return $this->rawValue;
990
    }
991
992
    /**
993
     * Get config from the form.
994
     *
995
     * @return mixed
996
     */
997 104
    private function getConfig($key = null, $default = null)
998
    {
999 104
        return $this->parent->getConfig($key, $default);
1000
    }
1001
}
1002