Completed
Pull Request — master (#376)
by
unknown
08:23
created

FormField   D

Complexity

Total Complexity 101

Size/Duplication

Total Lines 836
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 8

Test Coverage

Coverage 82.49%

Importance

Changes 0
Metric Value
dl 0
loc 836
ccs 212
cts 257
cp 0.8249
rs 4.4444
c 0
b 0
f 0
wmc 101
lcom 1
cbo 8

44 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 11 1
B setupValue() 0 15 6
getTemplate() 0 1 ?
A getViewTemplate() 0 4 1
B render() 0 38 6
A getRenderData() 0 3 1
A getModelValueAttribute() 0 11 4
A transformKey() 0 4 1
D prepareOptions() 0 62 13
A getName() 0 4 1
A setName() 0 6 1
A getNameKey() 0 4 1
A getOptions() 0 4 1
A getOption() 0 4 1
A setOptions() 0 6 1
A setOption() 0 6 1
A getType() 0 4 1
A setType() 0 8 2
A getParent() 0 4 1
A isRendered() 0 4 1
A getDefaults() 0 4 1
A allDefaults() 0 19 1
A getRealName() 0 4 1
B setValue() 0 20 5
A setTemplate() 0 4 1
B addErrorClass() 0 14 5
A setDefaultOptions() 0 10 1
B setDefaultClasses() 0 18 7
A setupLabel() 0 14 3
A needsLabel() 0 11 4
A disable() 0 6 1
A enable() 0 6 1
B getValidationRules() 0 26 5
A getAllAttributes() 0 4 1
A getValue() 0 4 1
A getDefaultValue() 0 4 1
A isValidValue() 0 4 1
A initFilters() 0 19 3
A setFilters() 0 9 2
A getFilters() 0 4 1
B addFilter() 0 28 4
A removeFilter() 0 10 2
A removeFilters() 0 12 3
A clearFilters() 0 5 1

How to fix   Complexity   

Complex Class

Complex classes like FormField often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use FormField, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace Kris\LaravelFormBuilder\Fields;
4
5
use Kris\LaravelFormBuilder\Filters\Exception\FilterAlreadyBindedException;
6
use Kris\LaravelFormBuilder\Filters\FilterInterface;
7
use Kris\LaravelFormBuilder\Filters\FilterResolver;
8
use Kris\LaravelFormBuilder\Form;
9
use Illuminate\Database\Eloquent\Model;
10
use Kris\LaravelFormBuilder\FormHelper;
11
use Illuminate\Database\Eloquent\Collection;
12
13
/**
14
 * Class FormField
15
 *
16
 * @package Kris\LaravelFormBuilder\Fields
17
 */
18
abstract class FormField
19
{
20
    /**
21
     * Name of the field.
22
     *
23
     * @var string
24
     */
25
    protected $name;
26
27
    /**
28
     * Type of the field.
29
     *
30
     * @var string
31
     */
32
    protected $type;
33
34
    /**
35
     * All options for the field.
36
     *
37
     * @var array
38
     */
39
    protected $options = [];
40
41
    /**
42
     * Is field rendered.
43
     *
44
     * @var bool
45
     */
46
    protected $rendered = false;
47
48
    /**
49
     * @var Form
50
     */
51
    protected $parent;
52
53
    /**
54
     * @var string
55
     */
56
    protected $template;
57
58
    /**
59
     * @var FormHelper
60
     */
61
    protected $formHelper;
62
63
    /**
64
     * Name of the property for value setting.
65
     *
66
     * @var string
67
     */
68
    protected $valueProperty = 'value';
69
70
    /**
71
     * Name of the property for default value.
72
     *
73
     * @var string
74
     */
75
    protected $defaultValueProperty = 'default_value';
76
77
    /**
78
     * Is default value set?
79
     *
80
     * @var bool|false
81
     */
82
    protected $hasDefault = false;
83
84
    /**
85
     * @var \Closure|null
86
     */
87
    protected $valueClosure = null;
88
89
    /**
90
     * Array of filters key => objects.
91
     *
92
     * @var array
93
     */
94
    protected $filters = [];
95
96
    /**
97
     * Override filters with same alias/name for field.
98
     *
99
     * @var bool
100
     */
101
    protected $filtersOverride = false;
102
103
    /**
104
     * @param string $name
105
     * @param string $type
106
     * @param Form $parent
107
     * @param array $options
108
     */
109 87
    public function __construct($name, $type, Form $parent, array $options = [])
110
    {
111 87
        $this->name = $name;
112 87
        $this->type = $type;
113 87
        $this->parent = $parent;
114 87
        $this->formHelper = $this->parent->getFormHelper();
115 87
        $this->setTemplate();
116 87
        $this->setDefaultOptions($options);
117 87
        $this->setupValue();
118 82
        $this->initFilters();
119 82
    }
120
121
122
    /**
123
     * Setup the value of the form field.
124
     *
125
     * @return void
126
     */
127 87
    protected function setupValue()
128
    {
129 87
        $value = $this->getOption($this->valueProperty);
130 87
        $isChild = $this->getOption('is_child');
131
132 87
        if ($value instanceof \Closure) {
133
            $this->valueClosure = $value;
134
        }
135
136 87
        if (($value === null || $value instanceof \Closure) && !$isChild) {
137 77
            $this->setValue($this->getModelValueAttribute($this->parent->getModel(), $this->name));
138 21
        } elseif (!$isChild) {
139 13
            $this->hasDefault = true;
140
        }
141 82
    }
142
143
    /**
144
     * Get the template, can be config variable or view path.
145
     *
146
     * @return string
147
     */
148
    abstract protected function getTemplate();
149
150
    /**
151
     * @return string
152
     */
153 33
    protected function getViewTemplate()
154
    {
155 33
        return $this->parent->getTemplatePrefix() . $this->getOption('template', $this->template);
156
    }
157
158
    /**
159
     * Render the field.
160
     *
161
     * @param array $options
162
     * @param bool  $showLabel
163
     * @param bool  $showField
164
     * @param bool  $showError
165
     * @return string
166
     */
167 33
    public function render(array $options = [], $showLabel = true, $showField = true, $showError = true)
168
    {
169 33
        $this->prepareOptions($options);
170 33
        $value = $this->getValue();
171 33
        $defaultValue = $this->getDefaultValue();
172
173 33
        if ($showField) {
174 33
            $this->rendered = true;
175
        }
176
177
        // Override default value with value
178 33
        if (!$this->isValidValue($value) && $this->isValidValue($defaultValue)) {
179
            $this->setOption($this->valueProperty, $defaultValue);
180
        }
181
182 33
        if (!$this->needsLabel()) {
183 9
            $showLabel = false;
184
        }
185
186 33
        if ($showError) {
187 32
            $showError = $this->parent->haveErrorsEnabled();
188
        }
189
190 33
        $data = $this->getRenderData();
191
192 33
        return $this->formHelper->getView()->make(
193 33
            $this->getViewTemplate(),
194
            $data + [
195 33
                'name' => $this->name,
196 33
                'nameKey' => $this->getNameKey(),
197 33
                'type' => $this->type,
198 33
                'options' => $this->options,
199 33
                'showLabel' => $showLabel,
200 33
                'showField' => $showField,
201 33
                'showError' => $showError
202
            ]
203 33
        )->render();
204
    }
205
206
    /**
207
     * Return the extra render data for this form field, passed into the field's template directly.
208
     *
209
     * @return array
210
     */
211 33
    protected function getRenderData() {
212 33
        return [];
213
    }
214
215
    /**
216
     * Get the attribute value from the model by name.
217
     *
218
     * @param mixed $model
219
     * @param string $name
220
     * @return mixed
221
     */
222 79
    protected function getModelValueAttribute($model, $name)
223
    {
224 79
        $transformedName = $this->transformKey($name);
225 79
        if (is_string($model)) {
226
            return $model;
227 79
        } elseif (is_object($model)) {
228 3
            return object_get($model, $transformedName);
229 79
        } elseif (is_array($model)) {
230 78
            return array_get($model, $transformedName);
231
        }
232 5
    }
233
234
    /**
235
     * Transform array like syntax to dot syntax.
236
     *
237
     * @param string $key
238
     * @return mixed
239
     */
240 87
    protected function transformKey($key)
241
    {
242 87
        return $this->formHelper->transformToDotSyntax($key);
243
    }
244
245
    /**
246
     * Prepare options for rendering.
247
     *
248
     * @param array $options
249
     * @return array
250
     */
251 87
    protected function prepareOptions(array $options = [])
252
    {
253 87
        $helper = $this->formHelper;
254 87
        $rulesParser = $helper->createRulesParser($this);
255 87
        $rules = $this->getOption('rules');
256 87
        $parsedRules = $rules ? $rulesParser->parse($rules) : [];
257
258 87
        $this->options = $helper->mergeOptions($this->options, $options);
259
260 87
        foreach (['attr', 'label_attr', 'wrapper'] as $appendable) {
261
            // Append values to the 'class' attribute
262 87
            if ($this->getOption("{$appendable}.class_append")) {
263
                // Combine the current class attribute with the appends
264 3
                $append = $this->getOption("{$appendable}.class_append");
265 3
                $classAttribute = $this->getOption("{$appendable}.class", '').' '.$append;
266 3
                $this->setOption("{$appendable}.class", $classAttribute);
267
268
                // Then remove the class_append option to prevent it from showing up as an attribute in the HTML
269 87
                $this->setOption("{$appendable}.class_append", null);
270
            }
271
        }
272
273 87
        if ($this->getOption('attr.multiple') && !$this->getOption('tmp.multipleBracesSet')) {
274 2
            $this->name = $this->name.'[]';
275 2
            $this->setOption('tmp.multipleBracesSet', true);
276
        }
277
278 87
        if ($this->parent->haveErrorsEnabled()) {
279 87
            $this->addErrorClass();
280
        }
281
282 87
        if ($this->getOption('required') === true || isset($parsedRules['required'])) {
283 4
            $lblClass = $this->getOption('label_attr.class', '');
284 4
            $requiredClass = $helper->getConfig('defaults.required_class', 'required');
285
286 4
            if (! str_contains($lblClass, $requiredClass)) {
287 4
                $lblClass .= ' '.$requiredClass;
288 4
                $this->setOption('label_attr.class', $lblClass);
289
            }
290
291 4
            if ($this->parent->clientValidationEnabled()) {
292 3
                $this->setOption('attr.required', 'required');
293
294 3
                if ($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...
295 1
                    $attrs = $this->getOption('attr') + $parsedRules;
296 1
                    $this->setOption('attr', $attrs);
297
                }
298
            }
299
        }
300
301 87
        $this->setOption('wrapperAttrs', $helper->prepareAttributes($this->getOption('wrapper')));
302 87
        $this->setOption('errorAttrs', $helper->prepareAttributes($this->getOption('errors')));
303
304 87
        if ($this->getOption('help_block.text')) {
305 1
            $this->setOption(
306 1
                'help_block.helpBlockAttrs',
307 1
                $helper->prepareAttributes($this->getOption('help_block.attr'))
308
            );
309
        }
310
311 87
        return $this->options;
312
    }
313
314
    /**
315
     * Get name of the field.
316
     *
317
     * @return string
318
     */
319 36
    public function getName()
320
    {
321 36
        return $this->name;
322
    }
323
324
    /**
325
     * Set name of the field.
326
     *
327
     * @param string $name
328
     * @return $this
329
     */
330 12
    public function setName($name)
331
    {
332 12
        $this->name = $name;
333
334 12
        return $this;
335
    }
336
337
    /**
338
     * Get dot notation key for fields.
339
     *
340
     * @return string
341
     **/
342 52
    public function getNameKey()
343
    {
344 52
        return $this->transformKey($this->name);
345
    }
346
347
    /**
348
     * Get field options.
349
     *
350
     * @return array
351
     */
352 12
    public function getOptions()
353
    {
354 12
        return $this->options;
355
    }
356
357
    /**
358
     * Get single option from options array. Can be used with dot notation ('attr.class').
359
     *
360
     * @param string $option
361
     * @param mixed|null $default
362
     * @return mixed
363
     */
364 87
    public function getOption($option, $default = null)
365
    {
366 87
        return array_get($this->options, $option, $default);
367
    }
368
369
    /**
370
     * Set field options.
371
     *
372
     * @param array $options
373
     * @return $this
374
     */
375 12
    public function setOptions($options)
376
    {
377 12
        $this->options = $this->prepareOptions($options);
378
379 12
        return $this;
380
    }
381
382
    /**
383
     * Set single option on the field.
384
     *
385
     * @param string $name
386
     * @param mixed $value
387
     * @return $this
388
     */
389 87
    public function setOption($name, $value)
390
    {
391 87
        array_set($this->options, $name, $value);
392
393 87
        return $this;
394
    }
395
396
    /**
397
     * Get the type of the field.
398
     *
399
     * @return string
400
     */
401 53
    public function getType()
402
    {
403 53
        return $this->type;
404
    }
405
406
    /**
407
     * Set type of the field.
408
     *
409
     * @param mixed $type
410
     * @return $this
411
     */
412 1
    public function setType($type)
413
    {
414 1
        if ($this->formHelper->getFieldType($type)) {
415 1
            $this->type = $type;
416
        }
417
418 1
        return $this;
419
    }
420
421
    /**
422
     * @return Form
423
     */
424 87
    public function getParent()
425
    {
426 87
        return $this->parent;
427
    }
428
429
    /**
430
     * Check if the field is rendered.
431
     *
432
     * @return bool
433
     */
434 4
    public function isRendered()
435
    {
436 4
        return $this->rendered;
437
    }
438
439
    /**
440
     * Default options for field.
441
     *
442
     * @return array
443
     */
444 66
    protected function getDefaults()
445
    {
446 66
        return [];
447
    }
448
449
    /**
450
     * Defaults used across all fields.
451
     *
452
     * @return array
453
     */
454 87
    private function allDefaults()
455
    {
456
        return [
457 87
            'wrapper' => ['class' => $this->formHelper->getConfig('defaults.wrapper_class')],
458 87
            'attr' => ['class' => $this->formHelper->getConfig('defaults.field_class')],
459 87
            'help_block' => ['text' => null, 'tag' => 'p', 'attr' => [
460 87
                'class' => $this->formHelper->getConfig('defaults.help_block_class')
461
            ]],
462
            'value' => null,
463
            'default_value' => null,
464
            'label' => null,
465
            'label_show' => true,
466
            'is_child' => false,
467 87
            'label_attr' => ['class' => $this->formHelper->getConfig('defaults.label_class')],
468 87
            'errors' => ['class' => $this->formHelper->getConfig('defaults.error_class')],
469
            'rules' => [],
470
            'error_messages' => []
471
        ];
472
    }
473
474
    /**
475
     * Get real name of the field without form namespace.
476
     *
477
     * @return string
478
     */
479 86
    public function getRealName()
480
    {
481 86
        return $this->getOption('real_name', $this->name);
482
    }
483
484
    /**
485
     * @param $value
486
     * @return $this
487
     */
488 81
    public function setValue($value)
489
    {
490 81
        if ($this->hasDefault) {
491 1
            return $this;
492
        }
493
494 81
        $closure = $this->valueClosure;
495
496 81
        if ($closure instanceof \Closure) {
497
            $value = $closure($value ?: null);
498
        }
499
500 81
        if (!$this->isValidValue($value)) {
501 78
            $value = $this->getOption($this->defaultValueProperty);
502
        }
503
504 81
        $this->options[$this->valueProperty] = $value;
505
506 81
        return $this;
507
    }
508
509
    /**
510
     * Set the template property on the object.
511
     *
512
     * @return void
513
     */
514 87
    private function setTemplate()
515
    {
516 87
        $this->template = $this->formHelper->getConfig($this->getTemplate(), $this->getTemplate());
517 87
    }
518
519
    /**
520
     * Add error class to wrapper if validation errors exist.
521
     *
522
     * @return void
523
     */
524 87
    protected function addErrorClass()
525
    {
526 87
        $errors = $this->parent->getRequest()->session()->get('errors');
527
528 87
        if ($errors && $errors->has($this->getNameKey())) {
529
            $errorClass = $this->formHelper->getConfig('defaults.wrapper_error_class');
530
            $wrapperClass = $this->getOption('wrapper.class');
531
532
            if ($this->getOption('wrapper') && !str_contains($wrapperClass, $errorClass)) {
533
                $wrapperClass .= ' ' . $errorClass;
534
                $this->setOption('wrapper.class', $wrapperClass);
535
            }
536
        }
537 87
    }
538
539
    /**
540
     * Merge all defaults with field specific defaults and set template if passed.
541
     *
542
     * @param array $options
543
     */
544 87
    protected function setDefaultOptions(array $options = [])
545
    {
546 87
        $this->options = $this->formHelper->mergeOptions($this->allDefaults(), $this->getDefaults());
547 87
        $this->options = $this->prepareOptions($options);
548
549 87
        $defaults = $this->setDefaultClasses($options);
550 87
        $this->options = $this->formHelper->mergeOptions($this->options, $defaults);
551
552 87
        $this->setupLabel();
553 87
    }
554
555
    /**
556
     * Creates default wrapper classes for the form element.
557
     *
558
     * @param array $options
559
     * @return array
560
     */
561 87
    protected function setDefaultClasses(array $options = [])
562
    {
563 87
        $wrapper_class = $this->formHelper->getConfig('defaults.' . $this->type . '.wrapper_class', '');
564 87
        $label_class = $this->formHelper->getConfig('defaults.' . $this->type . '.label_class', '');
565 87
        $field_class = $this->formHelper->getConfig('defaults.' . $this->type . '.field_class', '');
566
567 87
        $defaults = [];
568 87
        if ($wrapper_class && !array_get($options, 'wrapper.class')) {
569
            $defaults['wrapper']['class'] = $wrapper_class;
570
        }
571 87
        if ($label_class && !array_get($options, 'label_attr.class')) {
572
            $defaults['label_attr']['class'] = $label_class;
573
        }
574 87
        if ($field_class && !array_get($options, 'attr.class')) {
575 1
            $defaults['attr']['class'] = $field_class;
576
        }
577 87
        return $defaults;
578
    }
579
580
    /**
581
     * Setup the label for the form field.
582
     *
583
     * @return void
584
     */
585 87
    protected function setupLabel()
586
    {
587 87
        if ($this->getOption('label') !== null) {
588 22
            return;
589
        }
590
591 85
        if ($langName = $this->parent->getLanguageName()) {
592 4
            $label = sprintf('%s.%s', $langName, $this->getRealName());
593
        } else {
594 82
            $label = $this->getRealName();
595
        }
596
597 85
        $this->setOption('label', $this->formHelper->formatLabel($label));
598 85
    }
599
600
    /**
601
     * Check if fields needs label.
602
     *
603
     * @return bool
604
     */
605 33
    protected function needsLabel()
606
    {
607
        // If field is <select> and child of choice, we don't need label for it
608 33
        $isChildSelect = $this->type == 'select' && $this->getOption('is_child') === true;
609
610 33
        if ($this->type == 'hidden' || $isChildSelect) {
611 9
            return false;
612
        }
613
614 29
        return true;
615
    }
616
617
    /**
618
     * Disable field.
619
     *
620
     * @return $this
621
     */
622 1
    public function disable()
623
    {
624 1
        $this->setOption('attr.disabled', 'disabled');
625
626 1
        return $this;
627
    }
628
629
    /**
630
     * Enable field.
631
     *
632
     * @return $this
633
     */
634 1
    public function enable()
635
    {
636 1
        array_forget($this->options, 'attr.disabled');
637
638 1
        return $this;
639
    }
640
641
    /**
642
     * Get validation rules for a field if any with label for attributes.
643
     *
644
     * @return array|null
645
     */
646 9
    public function getValidationRules()
647
    {
648 9
        $rules = $this->getOption('rules', []);
649 9
        $name = $this->getNameKey();
650 9
        $messages = $this->getOption('error_messages', []);
651 9
        $formName = $this->formHelper->transformToDotSyntax($this->parent->getName());
652
653 9
        if ($messages && $formName) {
654 1
            $newMessages = [];
655 1
            foreach ($messages as $messageKey => $message) {
656 1
                $messageKey = sprintf('%s.%s', $formName, $messageKey);
657 1
                $newMessages[$messageKey] = $message;
658
            }
659 1
            $messages = $newMessages;
660
        }
661
662 9
        if (!$rules) {
663 2
            return [];
664
        }
665
666
        return [
667 8
            'rules' => [$name => $rules],
668 8
            'attributes' => [$name => $this->getOption('label')],
669 8
            'error_messages' => $messages
670
        ];
671
    }
672
673
    /**
674
     * Get this field's attributes, probably just one.
675
     *
676
     * @return array
677
     */
678 3
    public function getAllAttributes()
679
    {
680 3
        return [$this->getNameKey()];
681
    }
682
683
    /**
684
     * Get value property.
685
     *
686
     * @param mixed|null $default
687
     * @return mixed
688
     */
689 36
    public function getValue($default = null)
690
    {
691 36
        return $this->getOption($this->valueProperty, $default);
692
    }
693
694
    /**
695
     * Get default value property.
696
     *
697
     * @param mixed|null $default
698
     * @return mixed
699
     */
700 33
    public function getDefaultValue($default = null)
701
    {
702 33
        return $this->getOption($this->defaultValueProperty, $default);
703
    }
704
705
    /**
706
     * Check if provided value is valid for this type.
707
     *
708
     * @return bool
709
     */
710 82
    protected function isValidValue($value)
711
    {
712 82
        return $value !== null;
713
    }
714
715
    /**
716
     * Method initFilters used to initialize filters
717
     * from field options and bind it to the same.
718
     *
719
     * @return $this
720
     */
721 82
    protected function initFilters()
722
    {
723
        // If override status is set in field options to true
724
        // we will change filtersOverride property value to true
725
        // so we can override existing filters with registered
726
        // alias/name in addFilter method.
727 82
        $overrideStatus = $this->getOption('filters_override', false);
728 82
        if ($overrideStatus) {
729
            $this->filtersOverride = true;
730
        }
731
732
        // Get filters and bind it to field.
733 82
        $filters = $this->getOption('filters', []);
734 82
        foreach ($filters as $filter) {
735
            $this->addFilter($filter);
736
        }
737
738 82
        return $this;
739
    }
740
741
    /**
742
     * Method setFilters used to set filters to current filters property.
743
     *
744
     * @param  array $filters
745
     *
746
     * @return \Kris\LaravelFormBuilder\Fields\FormField
747
     */
748
    public function setFilters(array $filters)
749
    {
750
        $this->clearFilters();
751
        foreach ($filters as $filter) {
752
            $this->addFilter($filter);
753
        }
754
755
        return $this;
756
    }
757
758
    /**
759
     * Method getFilters returns array of binded filters
760
     * if there are any binded. Otherwise empty array.
761
     *
762
     * @return array
763
     */
764 15
    public function getFilters()
765
    {
766 15
        return $this->filters;
767
    }
768
769
    /**
770
     * @param  string|FilterInterface $filter
771
     *
772
     * @return \Kris\LaravelFormBuilder\Fields\FormField
773
     *
774
     * @throws FilterAlreadyBindedException
775
     */
776
    public function addFilter($filter)
777
    {
778
        // Resolve filter object from string, object or throw Ex.
779
        $filterObj = FilterResolver::instance($filter);
780
781
        // If filtersOverride is allowed we will override filter
782
        // with same alias/name if there is one with new resolved filter.
783
        if ($this->filtersOverride) {
784
            if ($key = array_search($filterObj->getName(), $this->getFilters())) {
785
                $this->filters[$key] = $filterObj;
786
            } else {
787
                $this->filters[$filterObj->getName()] = $filterObj;
788
            }
789
        } else {
790
            // If filtersOverride is disabled and we found
791
            // equal alias defined we will throw Ex.
792
            if (array_key_exists($filterObj->getName(), $this->getFilters())) {
793
                $ex = new FilterAlreadyBindedException($filterObj->getName(), $this->getName());
794
                throw $ex;
795
            }
796
797
            // Filter with resolvedFilter alias/name doesn't exist
798
            // so we will bind it as new one to field.
799
            $this->filters[$filterObj->getName()] = $filter;
800
        }
801
802
        return $this;
803
    }
804
805
    /**
806
     * Method removeFilter used to remove filter by provided alias/name.
807
     *
808
     * @param  string $name
809
     *
810
     * @return \Kris\LaravelFormBuilder\Fields\FormField
811
     */
812
    public function removeFilter($name)
813
    {
814
        $filters = $this->getFilters();
815
        if (array_key_exists($name, $filters)) {
816
            unset($filters[$name]);
817
            $this->filters = $filters;
818
        }
819
820
        return $this;
821
    }
822
823
    /**
824
     * Method removeFilters used to remove filters by provided aliases/names.
825
     *
826
     * @param  array $filterNames
827
     *
828
     * @return \Kris\LaravelFormBuilder\Fields\FormField
829
     */
830
    public function removeFilters(array $filterNames)
831
    {
832
        $filters = $this->getFilters();
833
        foreach ($filterNames as $filterName) {
834
            if (array_key_exists($filterName, $filters)) {
835
                unset($filters[$filterName]);
836
                $this->filters = $filters;
837
            }
838
        }
839
840
        return $this;
841
    }
842
843
    /**
844
     * Method clearFilters used to empty current filters property.
845
     *
846
     * @return \Kris\LaravelFormBuilder\Fields\FormField
847
     */
848
    public function clearFilters()
849
    {
850
        $this->filters = [];
851
        return $this;
852
    }
853
}
854