CheckboxList   A
last analyzed

Complexity

Total Complexity 23

Size/Duplication

Total Lines 193
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 23
eloc 77
c 1
b 0
f 0
dl 0
loc 193
ccs 93
cts 93
cp 1
rs 10

19 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 3 1
A addCheckboxAttributes() 0 5 1
A checkboxAttributes() 0 5 1
A generateInput() 0 29 4
A disabled() 0 5 1
A renderError() 0 5 1
A form() 0 5 1
A itemsFromValues() 0 5 1
A renderHint() 0 5 1
A uncheckValue() 0 5 1
A items() 0 5 1
A checkboxLabelAttributes() 0 5 1
A separator() 0 5 1
A addCheckboxLabelAttributes() 0 5 1
A addIndividualInputAttributes() 0 5 1
A itemFormatter() 0 5 1
A prepareContainerAttributes() 0 6 2
A individualInputAttributes() 0 5 1
A renderLabel() 0 6 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Form\Field;
6
7
use Closure;
8
use InvalidArgumentException;
9
use LogicException;
10
use Stringable;
11
use Yiisoft\Form\Field\Base\InputData\InputDataWithCustomNameAndValueTrait;
12
use Yiisoft\Form\Field\Base\PartsField;
13
use Yiisoft\Form\Field\Base\ValidationClass\ValidationClassInterface;
14
use Yiisoft\Form\Field\Base\ValidationClass\ValidationClassTrait;
15
use Yiisoft\Form\Field\Part\Error;
16
use Yiisoft\Form\Field\Part\Hint;
17
use Yiisoft\Form\Field\Part\Label;
18
use Yiisoft\Html\Widget\CheckboxList\CheckboxItem;
19
use Yiisoft\Html\Widget\CheckboxList\CheckboxList as CheckboxListWidget;
20
21
/**
22
 * Represents a list of checkboxes with multiple selection.
23
 *
24
 * @see CheckboxListWidget
25
 */
26
final class CheckboxList extends PartsField implements ValidationClassInterface
27
{
28
    use InputDataWithCustomNameAndValueTrait;
29
    use ValidationClassTrait;
30
31
    private CheckboxListWidget $widget;
32
    private array $checkboxAttributes = [];
33
34 25
    public function __construct()
35
    {
36 25
        $this->widget = CheckboxListWidget::create('');
37
    }
38
39 2
    public function checkboxAttributes(array $attributes): self
40
    {
41 2
        $new = clone $this;
42 2
        $new->checkboxAttributes = $attributes;
43 2
        return $new;
44
    }
45
46 2
    public function addCheckboxAttributes(array $attributes): self
47
    {
48 2
        $new = clone $this;
49 2
        $new->checkboxAttributes = array_merge($new->checkboxAttributes, $attributes);
50 2
        return $new;
51
    }
52
53 2
    public function checkboxLabelAttributes(array $attributes): self
54
    {
55 2
        $new = clone $this;
56 2
        $new->widget = $this->widget->checkboxLabelAttributes($attributes);
57 2
        return $new;
58
    }
59
60 2
    public function addCheckboxLabelAttributes(array $attributes): self
61
    {
62 2
        $new = clone $this;
63 2
        $new->widget = $this->widget->addCheckboxLabelAttributes($attributes);
64 2
        return $new;
65
    }
66
67
    /**
68
     * @param array[] $attributes
69
     */
70 2
    public function individualInputAttributes(array $attributes): self
71
    {
72 2
        $new = clone $this;
73 2
        $new->widget = $this->widget->individualInputAttributes($attributes);
74 2
        return $new;
75
    }
76
77
    /**
78
     * @param array[] $attributes
79
     */
80 2
    public function addIndividualInputAttributes(array $attributes): self
81
    {
82 2
        $new = clone $this;
83 2
        $new->widget = $this->widget->addIndividualInputAttributes($attributes);
84 2
        return $new;
85
    }
86
87
    /**
88
     * @param string[] $items
89
     * @param bool $encodeLabels Whether labels should be encoded.
90
     */
91 14
    public function items(array $items, bool $encodeLabels = true): self
92
    {
93 14
        $new = clone $this;
94 14
        $new->widget = $this->widget->items($items, $encodeLabels);
95 14
        return $new;
96
    }
97
98
    /**
99
     * Fills items from an array provided. Array values are used for both input labels and input values.
100
     *
101
     * @param bool[]|float[]|int[]|string[]|Stringable[] $values
102
     * @param bool $encodeLabels Whether labels should be encoded.
103
     */
104 9
    public function itemsFromValues(array $values, bool $encodeLabels = true): self
105
    {
106 9
        $new = clone $this;
107 9
        $new->widget = $this->widget->itemsFromValues($values, $encodeLabels);
108 9
        return $new;
109
    }
110
111
    /**
112
     * Specifies the form element the tag input element belongs to. The value of this attribute must be the ID
113
     * attribute of a form element in the same document.
114
     *
115
     * @link https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#attr-fae-form
116
     */
117 2
    public function form(?string $formId): self
118
    {
119 2
        $new = clone $this;
120 2
        $new->widget = $this->widget->form($formId);
121 2
        return $new;
122
    }
123
124
    /**
125
     * @param bool $disabled Whether checkboxes is disabled.
126
     *
127
     * @link https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#attr-fe-disabled
128
     */
129 2
    public function disabled(bool $disabled = true): self
130
    {
131 2
        $new = clone $this;
132 2
        $new->widget = $this->widget->disabled($disabled);
133 2
        return $new;
134
    }
135
136 2
    public function uncheckValue(bool|float|int|string|Stringable|null $value): self
137
    {
138 2
        $new = clone $this;
139 2
        $new->widget = $this->widget->uncheckValue($value);
140 2
        return $new;
141
    }
142
143 2
    public function separator(string $separator): self
144
    {
145 2
        $new = clone $this;
146 2
        $new->widget = $this->widget->separator($separator);
147 2
        return $new;
148
    }
149
150
    /**
151
     * @psalm-param Closure(CheckboxItem):string|null $formatter
152
     */
153 2
    public function itemFormatter(?Closure $formatter): self
154
    {
155 2
        $new = clone $this;
156 2
        $new->widget = $this->widget->itemFormatter($formatter);
157 2
        return $new;
158
    }
159
160 24
    protected function generateInput(): string
161
    {
162 24
        $name = $this->getName();
163 24
        if (empty($name)) {
164 2
            throw new LogicException('"CheckboxList" field requires non-empty name.');
165
        }
166
167 22
        $value = $this->getValue();
168
169 22
        $value ??= [];
170 22
        if (!is_iterable($value)) {
171 1
            throw new InvalidArgumentException(
172 1
                '"CheckboxList" field requires iterable or null value.'
173 1
            );
174
        }
175
        /** @psalm-var iterable<int, Stringable|scalar> $value */
176
177 21
        $checkboxAttributes = $this->checkboxAttributes;
178 21
        $this->addInputValidationClassToAttributes(
179 21
            $checkboxAttributes,
180 21
            $this->getInputData(),
181 21
            $this->hasCustomError() ? true : null,
182 21
        );
183
184 21
        return $this->widget
185 21
            ->name($name)
186 21
            ->values($value)
187 21
            ->addCheckboxAttributes($checkboxAttributes)
188 21
            ->render();
189
    }
190
191 21
    protected function renderLabel(Label $label): string
192
    {
193 21
        return $label
194 21
            ->inputData($this->getInputData())
195 21
            ->useInputId(false)
196 21
            ->render();
197
    }
198
199 21
    protected function renderHint(Hint $hint): string
200
    {
201 21
        return $hint
202 21
            ->inputData($this->getInputData())
203 21
            ->render();
204
    }
205
206 21
    protected function renderError(Error $error): string
207
    {
208 21
        return $error
209 21
            ->inputData($this->getInputData())
210 21
            ->render();
211
    }
212
213 21
    protected function prepareContainerAttributes(array &$attributes): void
214
    {
215 21
        $this->addValidationClassToAttributes(
216 21
            $attributes,
217 21
            $this->getInputData(),
218 21
            $this->hasCustomError() ? true : null,
219 21
        );
220
    }
221
}
222