Completed
Pull Request — master (#399)
by
unknown
08:18
created

FormField   D

Complexity

Total Complexity 109

Size/Duplication

Total Lines 905
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 9

Test Coverage

Coverage 92.83%

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 905
ccs 259
cts 279
cp 0.9283
rs 4.4444
wmc 109
lcom 1
cbo 9

48 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 39 6
A getRenderData() 0 3 1
A getModelValueAttribute() 0 11 4
A transformKey() 0 4 1
D prepareOptions() 0 62 14
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 20 4
A needsLabel() 0 11 4
A disable() 0 6 1
A enable() 0 6 1
C getValidationRules() 0 36 7
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
A setFiltersOverride() 0 5 1
A getFiltersOverride() 0 4 1
A setRawValue() 0 5 1
A getRawValue() 0 4 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 Kris\LaravelFormBuilder\FormHelper;
10
11
/**
12
 * Class FormField
13
 *
14
 * @package Kris\LaravelFormBuilder\Fields
15
 */
16
abstract class FormField
17
{
18
    /**
19
     * Name of the field.
20
     *
21
     * @var string
22
     */
23
    protected $name;
24
25
    /**
26
     * Type of the field.
27
     *
28
     * @var string
29
     */
30
    protected $type;
31
32
    /**
33
     * All options for the field.
34
     *
35
     * @var array
36
     */
37
    protected $options = [];
38
39
    /**
40
     * Is field rendered.
41
     *
42
     * @var bool
43
     */
44
    protected $rendered = false;
45
46
    /**
47
     * @var Form
48
     */
49
    protected $parent;
50
51
    /**
52
     * @var string
53
     */
54
    protected $template;
55
56
    /**
57
     * @var FormHelper
58
     */
59
    protected $formHelper;
60
61
    /**
62
     * Name of the property for value setting.
63
     *
64
     * @var string
65
     */
66
    protected $valueProperty = 'value';
67
68
    /**
69
     * Name of the property for default value.
70
     *
71
     * @var string
72
     */
73
    protected $defaultValueProperty = 'default_value';
74
75
    /**
76
     * Is default value set?
77
     *
78
     * @var bool|false
79
     */
80
    protected $hasDefault = false;
81
82
    /**
83
     * @var \Closure|null
84
     */
85
    protected $valueClosure = null;
86
87
    /**
88
     * Array of filters key(alias/name) => objects.
89
     *
90
     * @var array
91
     */
92
    protected $filters = [];
93
94
    /**
95
     * Raw/unfiltered field value.
96
     *
97
     * @var mixed $rawValues
98
     */
99
    protected $rawValue;
100
101
    /**
102
     * Override filters with same alias/name for field.
103
     *
104
     * @var bool
105
     */
106
    protected $filtersOverride = false;
107
108
    /**
109
     * @param string $name
110
     * @param string $type
111
     * @param Form $parent
112
     * @param array $options
113
     */
114 100
    public function __construct($name, $type, Form $parent, array $options = [])
115
    {
116 100
        $this->name = $name;
117 100
        $this->type = $type;
118 100
        $this->parent = $parent;
119 100
        $this->formHelper = $this->parent->getFormHelper();
120 100
        $this->setTemplate();
121 100
        $this->setDefaultOptions($options);
122 100
        $this->setupValue();
123 95
        $this->initFilters();
124 95
    }
125
126
127
    /**
128
     * Setup the value of the form field.
129
     *
130
     * @return void
131
     */
132 100
    protected function setupValue()
133
    {
134 100
        $value = $this->getOption($this->valueProperty);
135 100
        $isChild = $this->getOption('is_child');
136
137 100
        if ($value instanceof \Closure) {
138
            $this->valueClosure = $value;
139
        }
140
141 100
        if (($value === null || $value instanceof \Closure) && !$isChild) {
142 89
            $this->setValue($this->getModelValueAttribute($this->parent->getModel(), $this->name));
143 22
        } elseif (!$isChild) {
144 14
            $this->hasDefault = true;
145
        }
146 95
    }
147
148
    /**
149
     * Get the template, can be config variable or view path.
150
     *
151
     * @return string
152
     */
153
    abstract protected function getTemplate();
154
155
    /**
156
     * @return string
157
     */
158 34
    protected function getViewTemplate()
159
    {
160 34
        return $this->parent->getTemplatePrefix() . $this->getOption('template', $this->template);
161
    }
162
163
    /**
164
     * Render the field.
165
     *
166
     * @param array $options
167
     * @param bool  $showLabel
168
     * @param bool  $showField
169
     * @param bool  $showError
170
     * @return string
171
     */
172 34
    public function render(array $options = [], $showLabel = true, $showField = true, $showError = true)
173
    {
174 34
        $this->prepareOptions($options);
175 34
        $value = $this->getValue();
176 34
        $defaultValue = $this->getDefaultValue();
177
178 34
        if ($showField) {
179 34
            $this->rendered = true;
180
        }
181
182
        // Override default value with value
183 34
        if (!$this->isValidValue($value) && $this->isValidValue($defaultValue)) {
184
            $this->setOption($this->valueProperty, $defaultValue);
185
        }
186
187 34
        if (!$this->needsLabel()) {
188 10
            $showLabel = false;
189
        }
190
191 34
        if ($showError) {
192 33
            $showError = $this->parent->haveErrorsEnabled();
193
        }
194
195 34
        $data = $this->getRenderData();
196
197 34
        return $this->formHelper->getView()->make(
198 34
            $this->getViewTemplate(),
199
            $data + [
200 34
                'name' => $this->name,
201 34
                'nameKey' => $this->getNameKey(),
202 34
                'type' => $this->type,
203 34
                'options' => $this->options,
204 34
                'showLabel' => $showLabel,
205 34
                'showField' => $showField,
206 34
                'showError' => $showError,
207 34
                'translationTemplate' => $this->parent->getTranslationTemplate(),
208
            ]
209 34
        )->render();
210
    }
211
212
    /**
213
     * Return the extra render data for this form field, passed into the field's template directly.
214
     *
215
     * @return array
216
     */
217 34
    protected function getRenderData() {
218 34
        return [];
219
    }
220
221
    /**
222
     * Get the attribute value from the model by name.
223
     *
224
     * @param mixed $model
225
     * @param string $name
226
     * @return mixed
227
     */
228 91
    protected function getModelValueAttribute($model, $name)
229
    {
230 91
        $transformedName = $this->transformKey($name);
231 91
        if (is_string($model)) {
232
            return $model;
233 91
        } elseif (is_object($model)) {
234 3
            return object_get($model, $transformedName);
235 91
        } elseif (is_array($model)) {
236 90
            return array_get($model, $transformedName);
237
        }
238 5
    }
239
240
    /**
241
     * Transform array like syntax to dot syntax.
242
     *
243
     * @param string $key
244
     * @return mixed
245
     */
246 100
    protected function transformKey($key)
247
    {
248 100
        return $this->formHelper->transformToDotSyntax($key);
249
    }
250
251
    /**
252
     * Prepare options for rendering.
253
     *
254
     * @param array $options
255
     * @return array
256
     */
257 100
    protected function prepareOptions(array $options = [])
258
    {
259 100
        $helper = $this->formHelper;
260 100
        $rulesParser = $helper->createRulesParser($this);
261 100
        $rules = $this->getOption('rules');
262 100
        $parsedRules = $rules ? $rulesParser->parse($rules) : [];
263
264 100
        $this->options = $helper->mergeOptions($this->options, $options);
265
266 100
        foreach (['attr', 'label_attr', 'wrapper'] as $appendable) {
267
            // Append values to the 'class' attribute
268 100
            if ($this->getOption("{$appendable}.class_append")) {
269
                // Combine the current class attribute with the appends
270 3
                $append = $this->getOption("{$appendable}.class_append");
271 3
                $classAttribute = $this->getOption("{$appendable}.class", '').' '.$append;
272 3
                $this->setOption("{$appendable}.class", $classAttribute);
273
274
                // Then remove the class_append option to prevent it from showing up as an attribute in the HTML
275 100
                $this->setOption("{$appendable}.class_append", null);
276
            }
277
        }
278
279 100
        if ($this->getOption('attr.multiple') && !$this->getOption('tmp.multipleBracesSet')) {
280 2
            $this->name = $this->name.'[]';
281 2
            $this->setOption('tmp.multipleBracesSet', true);
282
        }
283
284 100
        if ($this->parent->haveErrorsEnabled()) {
285 100
            $this->addErrorClass();
286
        }
287
288 100
        if ($this->getOption('required') === true || isset($parsedRules['required'])) {
289 4
            $lblClass = $this->getOption('label_attr.class', '');
290 4
            $requiredClass = $helper->getConfig('defaults.required_class', 'required');
291
292 4
            if (! str_contains($lblClass, $requiredClass)) {
293 4
                $lblClass .= ' '.$requiredClass;
294 4
                $this->setOption('label_attr.class', $lblClass);
295
            }
296
297 4
            if ($this->parent->clientValidationEnabled()) {
298 3
                $this->setOption('attr.required', 'required');
299
            }
300
        }
301
302 100
        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...
303 1
            $attrs = $this->getOption('attr') + $parsedRules;
304 1
            $this->setOption('attr', $attrs);
305
        }
306
307 100
        $this->setOption('wrapperAttrs', $helper->prepareAttributes($this->getOption('wrapper')));
308 100
        $this->setOption('errorAttrs', $helper->prepareAttributes($this->getOption('errors')));
309
310 100
        if ($this->getOption('help_block.text')) {
311 1
            $this->setOption(
312 1
                'help_block.helpBlockAttrs',
313 1
                $helper->prepareAttributes($this->getOption('help_block.attr'))
314
            );
315
        }
316
317 100
        return $this->options;
318
    }
319
320
    /**
321
     * Get name of the field.
322
     *
323
     * @return string
324
     */
325 39
    public function getName()
326
    {
327 39
        return $this->name;
328
    }
329
330
    /**
331
     * Set name of the field.
332
     *
333
     * @param string $name
334
     * @return $this
335
     */
336 12
    public function setName($name)
337
    {
338 12
        $this->name = $name;
339
340 12
        return $this;
341
    }
342
343
    /**
344
     * Get dot notation key for fields.
345
     *
346
     * @return string
347
     **/
348 53
    public function getNameKey()
349
    {
350 53
        return $this->transformKey($this->name);
351
    }
352
353
    /**
354
     * Get field options.
355
     *
356
     * @return array
357
     */
358 12
    public function getOptions()
359
    {
360 12
        return $this->options;
361
    }
362
363
    /**
364
     * Get single option from options array. Can be used with dot notation ('attr.class').
365
     *
366
     * @param string $option
367
     * @param mixed|null $default
368
     * @return mixed
369
     */
370 100
    public function getOption($option, $default = null)
371
    {
372 100
        return array_get($this->options, $option, $default);
373
    }
374
375
    /**
376
     * Set field options.
377
     *
378
     * @param array $options
379
     * @return $this
380
     */
381 12
    public function setOptions($options)
382
    {
383 12
        $this->options = $this->prepareOptions($options);
384
385 12
        return $this;
386
    }
387
388
    /**
389
     * Set single option on the field.
390
     *
391
     * @param string $name
392
     * @param mixed $value
393
     * @return $this
394
     */
395 100
    public function setOption($name, $value)
396
    {
397 100
        array_set($this->options, $name, $value);
398
399 100
        return $this;
400
    }
401
402
    /**
403
     * Get the type of the field.
404
     *
405
     * @return string
406
     */
407 65
    public function getType()
408
    {
409 65
        return $this->type;
410
    }
411
412
    /**
413
     * Set type of the field.
414
     *
415
     * @param mixed $type
416
     * @return $this
417
     */
418 1
    public function setType($type)
419
    {
420 1
        if ($this->formHelper->getFieldType($type)) {
421 1
            $this->type = $type;
422
        }
423
424 1
        return $this;
425
    }
426
427
    /**
428
     * @return Form
429
     */
430 100
    public function getParent()
431
    {
432 100
        return $this->parent;
433
    }
434
435
    /**
436
     * Check if the field is rendered.
437
     *
438
     * @return bool
439
     */
440 4
    public function isRendered()
441
    {
442 4
        return $this->rendered;
443
    }
444
445
    /**
446
     * Default options for field.
447
     *
448
     * @return array
449
     */
450 76
    protected function getDefaults()
451
    {
452 76
        return [];
453
    }
454
455
    /**
456
     * Defaults used across all fields.
457
     *
458
     * @return array
459
     */
460 100
    private function allDefaults()
461
    {
462
        return [
463 100
            'wrapper' => ['class' => $this->formHelper->getConfig('defaults.wrapper_class')],
464 100
            'attr' => ['class' => $this->formHelper->getConfig('defaults.field_class')],
465 100
            'help_block' => ['text' => null, 'tag' => 'p', 'attr' => [
466 100
                'class' => $this->formHelper->getConfig('defaults.help_block_class')
467
            ]],
468
            'value' => null,
469
            'default_value' => null,
470
            'label' => null,
471
            'label_show' => true,
472
            'is_child' => false,
473 100
            'label_attr' => ['class' => $this->formHelper->getConfig('defaults.label_class')],
474 100
            'errors' => ['class' => $this->formHelper->getConfig('defaults.error_class')],
475
            'rules' => [],
476
            'error_messages' => []
477
        ];
478
    }
479
480
    /**
481
     * Get real name of the field without form namespace.
482
     *
483
     * @return string
484
     */
485 99
    public function getRealName()
486
    {
487 99
        return $this->getOption('real_name', $this->name);
488
    }
489
490
    /**
491
     * @param $value
492
     * @return $this
493
     */
494 93
    public function setValue($value)
495
    {
496 93
        if ($this->hasDefault) {
497 1
            return $this;
498
        }
499
500 93
        $closure = $this->valueClosure;
501
502 93
        if ($closure instanceof \Closure) {
503
            $value = $closure($value ?: null);
504
        }
505
506 93
        if (!$this->isValidValue($value)) {
507 90
            $value = $this->getOption($this->defaultValueProperty);
508
        }
509
510 93
        $this->options[$this->valueProperty] = $value;
511
512 93
        return $this;
513
    }
514
515
    /**
516
     * Set the template property on the object.
517
     *
518
     * @return void
519
     */
520 100
    private function setTemplate()
521
    {
522 100
        $this->template = $this->formHelper->getConfig($this->getTemplate(), $this->getTemplate());
523 100
    }
524
525
    /**
526
     * Add error class to wrapper if validation errors exist.
527
     *
528
     * @return void
529
     */
530 100
    protected function addErrorClass()
531
    {
532 100
        $errors = $this->parent->getRequest()->session()->get('errors');
533
534 100
        if ($errors && $errors->has($this->getNameKey())) {
535
            $errorClass = $this->formHelper->getConfig('defaults.wrapper_error_class');
536
            $wrapperClass = $this->getOption('wrapper.class');
537
538
            if ($this->getOption('wrapper') && !str_contains($wrapperClass, $errorClass)) {
539
                $wrapperClass .= ' ' . $errorClass;
540
                $this->setOption('wrapper.class', $wrapperClass);
541
            }
542
        }
543 100
    }
544
545
    /**
546
     * Merge all defaults with field specific defaults and set template if passed.
547
     *
548
     * @param array $options
549
     */
550 100
    protected function setDefaultOptions(array $options = [])
551
    {
552 100
        $this->options = $this->formHelper->mergeOptions($this->allDefaults(), $this->getDefaults());
553 100
        $this->options = $this->prepareOptions($options);
554
555 100
        $defaults = $this->setDefaultClasses($options);
556 100
        $this->options = $this->formHelper->mergeOptions($this->options, $defaults);
557
558 100
        $this->setupLabel();
559 100
    }
560
561
    /**
562
     * Creates default wrapper classes for the form element.
563
     *
564
     * @param array $options
565
     * @return array
566
     */
567 100
    protected function setDefaultClasses(array $options = [])
568
    {
569 100
        $wrapper_class = $this->formHelper->getConfig('defaults.' . $this->type . '.wrapper_class', '');
570 100
        $label_class = $this->formHelper->getConfig('defaults.' . $this->type . '.label_class', '');
571 100
        $field_class = $this->formHelper->getConfig('defaults.' . $this->type . '.field_class', '');
572
573 100
        $defaults = [];
574 100
        if ($wrapper_class && !array_get($options, 'wrapper.class')) {
575
            $defaults['wrapper']['class'] = $wrapper_class;
576
        }
577 100
        if ($label_class && !array_get($options, 'label_attr.class')) {
578
            $defaults['label_attr']['class'] = $label_class;
579
        }
580 100
        if ($field_class && !array_get($options, 'attr.class')) {
581 1
            $defaults['attr']['class'] = $field_class;
582
        }
583 100
        return $defaults;
584
    }
585
586
    /**
587
     * Setup the label for the form field.
588
     *
589
     * @return void
590
     */
591 100
    protected function setupLabel()
592
    {
593 100
        if ($this->getOption('label') !== null) {
594 23
            return;
595
        }
596
597 98
        if ($template = $this->parent->getTranslationTemplate()) {
598 3
            $label = str_replace(
599 3
                ['{name}', '{type}'],
600 3
                [$this->getRealName(), 'label'],
601 3
                $template
602
            );
603 95
        } elseif ($langName = $this->parent->getLanguageName()) {
604 4
            $label = sprintf('%s.%s', $langName, $this->getRealName());
605
        } else {
606 92
            $label = $this->getRealName();
607
        }
608
609 98
        $this->setOption('label', $this->formHelper->formatLabel($label));
610 98
    }
611
612
    /**
613
     * Check if fields needs label.
614
     *
615
     * @return bool
616
     */
617 34
    protected function needsLabel()
618
    {
619
        // If field is <select> and child of choice, we don't need label for it
620 34
        $isChildSelect = $this->type == 'select' && $this->getOption('is_child') === true;
621
622 34
        if ($this->type == 'hidden' || $isChildSelect) {
623 10
            return false;
624
        }
625
626 30
        return true;
627
    }
628
629
    /**
630
     * Disable field.
631
     *
632
     * @return $this
633
     */
634 1
    public function disable()
635
    {
636 1
        $this->setOption('attr.disabled', 'disabled');
637
638 1
        return $this;
639
    }
640
641
    /**
642
     * Enable field.
643
     *
644
     * @return $this
645
     */
646 1
    public function enable()
647
    {
648 1
        array_forget($this->options, 'attr.disabled');
649
650 1
        return $this;
651
    }
652
653
    /**
654
     * Get validation rules for a field if any with label for attributes.
655
     *
656
     * @return array|null
657
     */
658 9
    public function getValidationRules()
659
    {
660 9
        $rules = $this->getOption('rules', []);
661 9
        $name = $this->getNameKey();
662 9
        $messages = $this->getOption('error_messages', []);
663 9
        $formName = $this->formHelper->transformToDotSyntax($this->parent->getName());
664
665 9
        if ($messages && $formName) {
666 1
            $newMessages = [];
667 1
            foreach ($messages as $messageKey => $message) {
668 1
                $messageKey = sprintf('%s.%s', $formName, $messageKey);
669 1
                $newMessages[$messageKey] = $message;
670
            }
671 1
            $messages = $newMessages;
672
        }
673
674 9
        if (!$rules) {
675 2
            return [];
676
        }
677
678 8
        if (is_array($rules)) {
679 2
            $rules = array_map(function($rule) {
680 2
                if ($rule instanceof \Closure) {
681
                    return $rule($name);
0 ignored issues
show
Bug introduced by
The variable $name does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
682
                }
683
684 2
                return $rule;
685 2
            }, $rules);
686
        }
687
688
        return [
689 8
            'rules' => [$name => $rules],
690 8
            'attributes' => [$name => $this->getOption('label')],
691 8
            'error_messages' => $messages
692
        ];
693
    }
694
695
    /**
696
     * Get this field's attributes, probably just one.
697
     *
698
     * @return array
699
     */
700 3
    public function getAllAttributes()
701
    {
702 3
        return [$this->getNameKey()];
703
    }
704
705
    /**
706
     * Get value property.
707
     *
708
     * @param mixed|null $default
709
     * @return mixed
710
     */
711 37
    public function getValue($default = null)
712
    {
713 37
        return $this->getOption($this->valueProperty, $default);
714
    }
715
716
    /**
717
     * Get default value property.
718
     *
719
     * @param mixed|null $default
720
     * @return mixed
721
     */
722 34
    public function getDefaultValue($default = null)
723
    {
724 34
        return $this->getOption($this->defaultValueProperty, $default);
725
    }
726
727
    /**
728
     * Check if provided value is valid for this type.
729
     *
730
     * @return bool
731
     */
732 93
    protected function isValidValue($value)
733
    {
734 93
        return $value !== null;
735
    }
736
737
    /**
738
     * Method initFilters used to initialize filters
739
     * from field options and bind it to the same.
740
     *
741
     * @return $this
742
     */
743 95
    protected function initFilters()
744
    {
745
        // If override status is set in field options to true
746
        // we will change filtersOverride property value to true
747
        // so we can override existing filters with registered
748
        // alias/name in addFilter method.
749 95
        $overrideStatus = $this->getOption('filters_override', false);
750 95
        if ($overrideStatus) {
751 2
            $this->setFiltersOverride(true);
752
        }
753
754
        // Get filters and bind it to field.
755 95
        $filters = $this->getOption('filters', []);
756 95
        foreach ($filters as $filter) {
757 8
            $this->addFilter($filter);
758
        }
759
760 95
        return $this;
761
    }
762
763
    /**
764
     * Method setFilters used to set filters to current filters property.
765
     *
766
     * @param  array $filters
767
     *
768
     * @return \Kris\LaravelFormBuilder\Fields\FormField
769
     */
770
    public function setFilters(array $filters)
771
    {
772
        $this->clearFilters();
773
        foreach ($filters as $filter) {
774
            $this->addFilter($filter);
775
        }
776
777
        return $this;
778
    }
779
780
    /**
781
     * Method getFilters returns array of binded filters
782
     * if there are any binded. Otherwise empty array.
783
     *
784
     * @return array
785
     */
786 23
    public function getFilters()
787
    {
788 23
        return $this->filters;
789
    }
790
791
    /**
792
     * @param  string|FilterInterface $filter
793
     *
794
     * @return \Kris\LaravelFormBuilder\Fields\FormField
795
     *
796
     * @throws FilterAlreadyBindedException
797
     */
798 8
    public function addFilter($filter)
799
    {
800
        // Resolve filter object from string/object or throw Ex.
801 8
        $filterObj = FilterResolver::instance($filter);
802
803
        // If filtersOverride is allowed we will override filter
804
        // with same alias/name if there is one with new resolved filter.
805 8
        if ($this->getFiltersOverride()) {
806 1
            if ($key = array_search($filterObj->getName(), $this->getFilters())) {
807
                $this->filters[$key] = $filterObj;
808
            } else {
809 1
                $this->filters[$filterObj->getName()] = $filterObj;
810
            }
811
        } else {
812
            // If filtersOverride is disabled and we found
813
            // equal alias defined we will throw Ex.
814 7
            if (array_key_exists($filterObj->getName(), $this->getFilters())) {
815 1
                $ex = new FilterAlreadyBindedException($filterObj->getName(), $this->getName());
816 1
                throw $ex;
817
            }
818
819
            // Filter with resolvedFilter alias/name doesn't exist
820
            // so we will bind it as new one to field.
821 7
            $this->filters[$filterObj->getName()] = $filterObj;
822
        }
823
824 8
        return $this;
825
    }
826
827
    /**
828
     * Method removeFilter used to remove filter by provided alias/name.
829
     *
830
     * @param  string $name
831
     *
832
     * @return \Kris\LaravelFormBuilder\Fields\FormField
833
     */
834 1
    public function removeFilter($name)
835
    {
836 1
        $filters = $this->getFilters();
837 1
        if (array_key_exists($name, $filters)) {
838 1
            unset($filters[$name]);
839 1
            $this->filters = $filters;
840
        }
841
842 1
        return $this;
843
    }
844
845
    /**
846
     * Method removeFilters used to remove filters by provided aliases/names.
847
     *
848
     * @param  array $filterNames
849
     *
850
     * @return \Kris\LaravelFormBuilder\Fields\FormField
851
     */
852 1
    public function removeFilters(array $filterNames)
853
    {
854 1
        $filters = $this->getFilters();
855 1
        foreach ($filterNames as $filterName) {
856 1
            if (array_key_exists($filterName, $filters)) {
857 1
                unset($filters[$filterName]);
858 1
                $this->filters = $filters;
859
            }
860
        }
861
862 1
        return $this;
863
    }
864
865
    /**
866
     * Method clearFilters used to empty current filters property.
867
     *
868
     * @return \Kris\LaravelFormBuilder\Fields\FormField
869
     */
870 1
    public function clearFilters()
871
    {
872 1
        $this->filters = [];
873 1
        return $this;
874
    }
875
876
    /**
877
     * Method used to set FiltersOverride status to provided value.
878
     *
879
     * @param $status
880
     *
881
     * @return \Kris\LaravelFormBuilder\Fields\FormField
882
     */
883 2
    public function setFiltersOverride($status)
884
    {
885 2
        $this->filtersOverride = $status;
886 2
        return $this;
887
    }
888
889
    /**
890
     * @return bool
891
     */
892 9
    public function getFiltersOverride()
893
    {
894 9
        return $this->filtersOverride;
895
    }
896
897
    /**
898
     * Method used to set Unfiltered/Unmutated field value.
899
     * Method is called before field value mutating starts - request value filtering.
900
     *
901
     * @param mixed $value
902
     *
903
     * @return \Kris\LaravelFormBuilder\Fields\FormField
904
     */
905 1
    public function setRawValue($value)
906
    {
907 1
        $this->rawValue = $value;
908 1
        return $this;
909
    }
910
911
    /**
912
     * Returns unfiltered raw value of field.
913
     *
914
     * @return mixed
915
     */
916
    public function getRawValue()
917
    {
918
        return $this->rawValue;
919
    }
920
}
921