Completed
Push — master ( b6a4c4...e23742 )
by Rudie
14s queued 11s
created

FormField::prepareRules()   A

Complexity

Conditions 5
Paths 16

Size

Total Lines 26

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 5

Importance

Changes 0
Metric Value
cc 5
nc 16
nop 1
dl 0
loc 26
ccs 12
cts 12
cp 1
crap 5
rs 9.1928
c 0
b 0
f 0
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
            $attributeName = $this->getOption('property', $this->name);
146 93
            $this->setValue($this->getModelValueAttribute($this->parent->getModel(), $attributeName));
147 24
        } elseif (!$isChild) {
148 14
            $this->hasDefault = true;
149
        }
150 99
    }
151
152
    /**
153
     * Get the template, can be config variable or view path.
154
     *
155
     * @return string
156
     */
157
    abstract protected function getTemplate();
158
159
    /**
160
     * @return string
161
     */
162 35
    protected function getViewTemplate()
163
    {
164 35
        return $this->parent->getTemplatePrefix() . $this->getOption('template', $this->template);
165
    }
166
167
    /**
168
     * Render the field.
169
     *
170
     * @param array $options
171
     * @param bool  $showLabel
172
     * @param bool  $showField
173
     * @param bool  $showError
174
     * @return string
175
     */
176 35
    public function render(array $options = [], $showLabel = true, $showField = true, $showError = true)
177
    {
178 35
        $this->prepareOptions($options);
179 35
        $value = $this->getValue();
180 35
        $defaultValue = $this->getDefaultValue();
181
182 35
        if ($showField) {
183 35
            $this->rendered = true;
184
        }
185
186
        // Override default value with value
187 35
        if (!$this->isValidValue($value) && $this->isValidValue($defaultValue)) {
188
            $this->setOption($this->valueProperty, $defaultValue);
189
        }
190
191 35
        if (!$this->needsLabel()) {
192 11
            $showLabel = false;
193
        }
194
195 35
        if ($showError) {
196 34
            $showError = $this->parent->haveErrorsEnabled();
197
        }
198
199 35
        $data = $this->getRenderData();
200
201 35
        return $this->formHelper->getView()->make(
202 35
            $this->getViewTemplate(),
203
            $data + [
204 35
                'name' => $this->name,
205 35
                'nameKey' => $this->getNameKey(),
206 35
                'type' => $this->type,
207 35
                'options' => $this->options,
208 35
                'showLabel' => $showLabel,
209 35
                'showField' => $showField,
210 35
                'showError' => $showError,
211 35
                'errorBag'  => $this->parent->getErrorBag(),
212 35
                'translationTemplate' => $this->parent->getTranslationTemplate(),
213
            ]
214 35
        )->render();
215
    }
216
217
    /**
218
     * Return the extra render data for this form field, passed into the field's template directly.
219
     *
220
     * @return array
221
     */
222 35
    protected function getRenderData()
223
    {
224 35
        return [];
225
    }
226
227
    /**
228
     * Get the attribute value from the model by name.
229
     *
230
     * @param mixed $model
231
     * @param string $name
232
     * @return mixed
233
     */
234 95
    protected function getModelValueAttribute($model, $name)
235
    {
236 95
        $transformedName = $this->transformKey($name);
237 95
        if (is_string($model)) {
238
            return $model;
239 95
        } elseif (is_object($model)) {
240 4
            return object_get($model, $transformedName);
241 94
        } elseif (is_array($model)) {
242 93
            return Arr::get($model, $transformedName);
243
        }
244 5
    }
245
246
    /**
247
     * Transform array like syntax to dot syntax.
248
     *
249
     * @param string $key
250
     * @return mixed
251
     */
252 104
    protected function transformKey($key)
253
    {
254 104
        return $this->formHelper->transformToDotSyntax($key);
255
    }
256
257
    /**
258
     * Prepare options for rendering.
259
     *
260
     * @param array $options
261
     * @return array The parsed options
262
     */
263 104
    protected function prepareOptions(array $options = [])
264
    {
265 104
        $helper = $this->formHelper;
266
267 104
        $this->options = $this->prepareRules($options);
268 104
        $this->options = $helper->mergeOptions($this->options, $options);
269
270 104
        $rulesParser = $helper->createRulesParser($this);
271 104
        $rules = $this->getOption('rules');
272 104
        $parsedRules = $rules ? $rulesParser->parse($rules) : [];
273
274
275 104
        foreach (['attr', 'label_attr', 'wrapper'] as $appendable) {
276
            // Append values to the 'class' attribute
277 104
            if ($this->getOption("{$appendable}.class_append")) {
278
                // Combine the current class attribute with the appends
279 3
                $append = $this->getOption("{$appendable}.class_append");
280 3
                $classAttribute = $this->getOption("{$appendable}.class", '') . ' ' . $append;
281 3
                $this->setOption("{$appendable}.class", $classAttribute);
282
283
                // Then remove the class_append option to prevent it from showing up as an attribute in the HTML
284 104
                $this->setOption("{$appendable}.class_append", null);
285
            }
286
        }
287
288 104
        if ($this->getOption('attr.multiple') && !$this->getOption('tmp.multipleBracesSet')) {
289 2
            $this->name = $this->name . '[]';
290 2
            $this->setOption('tmp.multipleBracesSet', true);
291
        }
292
293 104
        if ($this->parent->haveErrorsEnabled()) {
294 104
            $this->addErrorClass();
295
        }
296
297 104
        if ($this->getOption('required') === true || isset($parsedRules['required'])) {
298 16
            $lblClass = $this->getOption('label_attr.class', '');
299 16
            $requiredClass = $this->getConfig('defaults.required_class', 'required');
300
301 16
            if (!Str::contains($lblClass, $requiredClass)) {
302 16
                $lblClass .= ' ' . $requiredClass;
303 16
                $this->setOption('label_attr.class', $lblClass);
304
            }
305
306 16
            if ($this->parent->clientValidationEnabled()) {
307 15
                $this->setOption('attr.required', 'required');
308
            }
309
        }
310
311 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...
312 13
            $attrs = $this->getOption('attr') + $parsedRules;
313 13
            $this->setOption('attr', $attrs);
314
        }
315
316 104
        $this->setOption('wrapperAttrs', $helper->prepareAttributes($this->getOption('wrapper')));
317 104
        $this->setOption('errorAttrs', $helper->prepareAttributes($this->getOption('errors')));
318
319 104
        if ($this->getOption('help_block.text')) {
320 1
            $this->setOption(
321 1
                'help_block.helpBlockAttrs',
322 1
                $helper->prepareAttributes($this->getOption('help_block.attr'))
323
            );
324
        }
325
326 104
        return $this->options;
327
    }
328
329
    /**
330
     * Normalize and merge rules.
331
     * @param array $sourceOptions
332
     * @return array
333
     */
334 104
    protected function prepareRules(array &$sourceOptions = [])
335
    {
336 104
        $options = $this->options;
337
338
        // Normalize rules
339 104
        if (array_key_exists('rules_append', $sourceOptions)) {
340 1
            $sourceOptions['rules_append'] = $this->normalizeRules($sourceOptions['rules_append']);
341
        }
342
343 104
        if (array_key_exists('rules', $sourceOptions)) {
344 26
            $sourceOptions['rules'] = $this->normalizeRules($sourceOptions['rules']);
345
        }
346
347 104
        if (array_key_exists('rules', $options)) {
348 104
            $options['rules'] = $this->normalizeRules($options['rules']);
349
        }
350
351
352
        // Append rules
353 104
        if ($rulesToBeAppended = Arr::pull($sourceOptions, 'rules_append')) {
354 1
            $mergedRules = array_values(array_unique(array_merge($options['rules'], $rulesToBeAppended), SORT_REGULAR));
355 1
            $options['rules'] = $mergedRules;
356
        }
357
358 104
        return $options;
359
    }
360
361
    /**
362
     * Normalize the the given rule expression to an array.
363
     * @param mixed $rules
364
     * @return array
365
     */
366 104
    protected function normalizeRules($rules)
367
    {
368 104
        if (empty($rules)) {
369 103
            return [];
370
        }
371
372 14
        if (is_string($rules)) {
373 14
            return explode('|', $rules);
374
        }
375
376 8
        if (is_array($rules)) {
377 8
            $normalizedRules = [];
378 8
            foreach ($rules as $rule) {
379 8
                $normalizedRules[] = $this->normalizeRules($rule);
380
            }
381
382 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...
383
        }
384
385 1
        return $rules;
386
    }
387
388
389
    /**
390
     * Get name of the field.
391
     *
392
     * @return string
393
     */
394 40
    public function getName()
395
    {
396 40
        return $this->name;
397
    }
398
399
    /**
400
     * Set name of the field.
401
     *
402
     * @param string $name
403
     * @return $this
404
     */
405 12
    public function setName($name)
406
    {
407 12
        $this->name = $name;
408
409 12
        return $this;
410
    }
411
412
    /**
413
     * Get dot notation key for fields.
414
     *
415
     * @return string
416
     **/
417 55
    public function getNameKey()
418
    {
419 55
        return $this->transformKey($this->name);
420
    }
421
422
    /**
423
     * Get field options.
424
     *
425
     * @return array
426
     */
427 12
    public function getOptions()
428
    {
429 12
        return $this->options;
430
    }
431
432
    /**
433
     * Get single option from options array. Can be used with dot notation ('attr.class').
434
     *
435
     * @param string $option
436
     * @param mixed|null $default
437
     * @return mixed
438
     */
439 104
    public function getOption($option, $default = null)
440
    {
441 104
        return Arr::get($this->options, $option, $default);
442
    }
443
444
    /**
445
     * Set field options.
446
     *
447
     * @param array $options
448
     * @return $this
449
     */
450 12
    public function setOptions($options)
451
    {
452 12
        $this->options = $this->prepareOptions($options);
453
454 12
        return $this;
455
    }
456
457
    /**
458
     * Set single option on the field.
459
     *
460
     * @param string $name
461
     * @param mixed $value
462
     * @return $this
463
     */
464 104
    public function setOption($name, $value)
465
    {
466 104
        Arr::set($this->options, $name, $value);
467
468 104
        return $this;
469
    }
470
471
    /**
472
     * Get the type of the field.
473
     *
474
     * @return string
475
     */
476 68
    public function getType()
477
    {
478 68
        return $this->type;
479
    }
480
481
    /**
482
     * Set type of the field.
483
     *
484
     * @param mixed $type
485
     * @return $this
486
     */
487 1
    public function setType($type)
488
    {
489 1
        if ($this->formHelper->getFieldType($type)) {
490 1
            $this->type = $type;
491
        }
492
493 1
        return $this;
494
    }
495
496
    /**
497
     * @return Form
498
     */
499 104
    public function getParent()
500
    {
501 104
        return $this->parent;
502
    }
503
504
    /**
505
     * Check if the field is rendered.
506
     *
507
     * @return bool
508
     */
509 4
    public function isRendered()
510
    {
511 4
        return $this->rendered;
512
    }
513
514
    /**
515
     * Default options for field.
516
     *
517
     * @return array
518
     */
519 77
    protected function getDefaults()
520
    {
521 77
        return [];
522
    }
523
524
    /**
525
     * Defaults used across all fields.
526
     *
527
     * @return array
528
     */
529 104
    private function allDefaults()
530
    {
531
        return [
532 104
            'wrapper' => ['class' => $this->getConfig('defaults.wrapper_class')],
533 104
            'attr' => ['class' => $this->getConfig('defaults.field_class')],
534 104
            'help_block' => ['text' => null, 'tag' => 'p', 'attr' => [
535 104
                'class' => $this->getConfig('defaults.help_block_class')
536
            ]],
537
            'value' => null,
538
            'default_value' => null,
539
            'label' => null,
540
            'label_show' => true,
541
            'is_child' => false,
542 104
            'label_attr' => ['class' => $this->getConfig('defaults.label_class')],
543 104
            'errors' => ['class' => $this->getConfig('defaults.error_class')],
544
            'rules' => [],
545
            'error_messages' => []
546
        ];
547
    }
548
549
    /**
550
     * Get real name of the field without form namespace.
551
     *
552
     * @return string
553
     */
554 103
    public function getRealName()
555
    {
556 103
        return $this->getOption('real_name', $this->name);
557
    }
558
559
    /**
560
     * @param $value
561
     * @return $this
562
     */
563 97
    public function setValue($value)
564
    {
565 97
        if ($this->hasDefault) {
566 1
            return $this;
567
        }
568
569 97
        $closure = $this->valueClosure;
570
571 97
        if ($closure instanceof \Closure) {
572
            $value = $closure($value ?: null);
573
        }
574
575 97
        if (!$this->isValidValue($value)) {
576 93
            $value = $this->getOption($this->defaultValueProperty);
577
        }
578
579 97
        $this->options[$this->valueProperty] = $value;
580
581 97
        return $this;
582
    }
583
584
    /**
585
     * Set the template property on the object.
586
     *
587
     * @return void
588
     */
589 104
    private function setTemplate()
590
    {
591 104
        $this->template = $this->getConfig($this->getTemplate(), $this->getTemplate());
592 104
    }
593
594
    /**
595
     * Add error class to wrapper if validation errors exist.
596
     *
597
     * @return void
598
     */
599 104
    protected function addErrorClass()
600
    {
601 104
        $errors = [];
602 104
        if ($this->parent->getRequest()->hasSession()) {
603 103
            $errors = $this->parent->getRequest()->session()->get('errors');
604
        }
605 104
        $errorBag = $this->parent->getErrorBag();
606
607 104
        if ($errors && $errors->hasBag($errorBag) && $errors->getBag($errorBag)->has($this->getNameKey())) {
608
            $fieldErrorClass = $this->getConfig('defaults.field_error_class');
609
            $fieldClass = $this->getOption('attr.class');
610
611
            if ($fieldErrorClass && !Str::contains($fieldClass, $fieldErrorClass)) {
612
                $fieldClass .= ' ' . $fieldErrorClass;
613
                $this->setOption('attr.class', $fieldClass);
614
            }
615
616
            $wrapperErrorClass = $this->getConfig('defaults.wrapper_error_class');
617
            $wrapperClass = $this->getOption('wrapper.class');
618
619
            if ($wrapperErrorClass && $this->getOption('wrapper') && !Str::contains($wrapperClass, $wrapperErrorClass)) {
620
                $wrapperClass .= ' ' . $wrapperErrorClass;
621
                $this->setOption('wrapper.class', $wrapperClass);
622
            }
623
        }
624 104
    }
625
626
    /**
627
     * Merge all defaults with field specific defaults and set template if passed.
628
     *
629
     * @param array $options
630
     */
631 104
    protected function setDefaultOptions(array $options = [])
632
    {
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 25
            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 39
    public function getValue($default = null)
783
    {
784 39
        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