Test Failed
Pull Request — master (#160)
by Wilmer
03:21 queued 47s
created

Checkbox::value()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 3
c 0
b 0
f 0
nc 1
nop 1
dl 0
loc 5
ccs 4
cts 4
cp 1
crap 1
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Form\Widget;
6
7
use InvalidArgumentException;
8
use Stringable;
9
use Yiisoft\Form\Widget\Attribute\InputAttributes;
10
use Yiisoft\Html\Tag\Input\Checkbox as CheckboxTag;
11
12
/**
13
 * The input element with a type attribute whose value is "checkbox" represents a state or option that can be toggled.
14
 *
15
 * This method will generate the "checked" tag attribute according to the form attribute value.
16
 *
17
 * @link https://www.w3.org/TR/2012/WD-html-markup-20120329/input.checkbox.html#input.checkbox
18
 */
19
final class Checkbox extends InputAttributes
20
{
21
    private bool $checked = false;
22
    private bool $enclosedByLabel = true;
23
    private ?string $label = '';
24
    private array $labelAttributes = [];
25
    /** @var bool|float|int|string|Stringable|null */
26
    private $uncheckValue = '0';
27
28
    /**
29
     * Check the checkbox button.
30
     *
31
     * @param bool $value Whether the checkbox button is checked.
32
     *
33
     * @return static
34
     */
35
    public function checked(bool $value = true): self
36
    {
37
        $new = clone $this;
38
        $new->checked = $value;
39
        return $new;
40
    }
41
42 12
    /**
43
     * If the widget should be enclosed by label.
44 12
     *
45 12
     * @param bool $value If the widget should be en closed by label.
46 12
     *
47
     * @return static
48
     */
49
    public function enclosedByLabel(bool $value): self
50
    {
51
        $new = clone $this;
52
        $new->enclosedByLabel = $value;
53
        return $new;
54
    }
55
56
    /**
57
     * Label displayed next to the checkbox.
58
     *
59
     * It will NOT be HTML-encoded, therefore you can pass in HTML code such as an image tag. If this is coming from
60
     * end users, you should {@see encode()} it to prevent XSS attacks.
61
     *
62
     * When this option is specified, the checkbox will be enclosed by a label tag.
63 3
     *
64
     * @param string|null $value
65 3
     *
66 3
     * @return static
67 3
     *
68
     * @link https://www.w3.org/TR/html52/sec-forms.html#the-label-element
69
     */
70
    public function label(?string $value): self
71
    {
72
        $new = clone $this;
73
        $new->label = $value;
74
        return $new;
75
    }
76
77
    /**
78
     * HTML attributes for the label tag.
79
     *
80
     * Do not set this option unless you set the "label" attributes.
81 3
     *
82
     * @param array $attributes
83 3
     *
84 3
     * @return static
85 3
     *
86
     * {@see \Yiisoft\Html\Html::renderTagAttributes()} for details on how attributes are being rendered.
87
     */
88
    public function labelAttributes(array $attributes = []): self
89
    {
90
        $new = clone $this;
91
        $new->labelAttributes = $attributes;
92
        return $new;
93 5
    }
94
95 5
    /**
96 5
     * @param bool|float|int|string|Stringable|null $value Value that corresponds to "unchecked" state of the input.
97 5
     *
98
     * @return static
99
     */
100
    public function uncheckValue($value): self
101
    {
102
        $new = clone $this;
103
        $new->uncheckValue = is_bool($value) ? (int) $value : $value;
104
        return $new;
105
    }
106
107
    /**
108
     * @return string the generated checkbox tag.
109 2
     */
110
    protected function run(): string
111 2
    {
112 2
        $attributes = $this->build($this->attributes);
113 2
114
        /** @link https://www.w3.org/TR/2012/WD-html-markup-20120329/input.checkbox.html#input.checkbox.attrs.value */
115
        $value = $this->getAttributeValue();
116
117
        /** @var iterable<int, scalar|Stringable>|scalar|Stringable|null */
118
        $valueDefault = array_key_exists('value', $attributes) ? $attributes['value'] : null;
119 18
120
        if (is_iterable($value) || is_object($value) || is_iterable($valueDefault) || is_object($valueDefault)) {
121 18
            throw new InvalidArgumentException('Checkbox widget value can not be an iterable or an object.');
122
        }
123 18
124 18
        $checkbox = CheckboxTag::tag();
125
126 18
        if ($this->enclosedByLabel === true) {
127 2
            $checkbox = $checkbox->label(
128
                empty($this->label) ? $this->getAttributeLabel() : $this->label,
129
                $this->labelAttributes,
130
            );
131 16
        }
132 16
133
        if (empty($value)) {
134 16
            $checkbox = $checkbox->checked($this->checked);
135 14
        } else {
136 14
            $checkbox = $checkbox->checked("$value" === "$valueDefault");
137 14
        }
138
139
        return $checkbox
140
            ->attributes($attributes)
141 16
            ->uncheckValue($this->uncheckValue)
142 16
            ->value(is_bool($valueDefault) ? (int) $valueDefault : $valueDefault)
143 16
            ->render();
144 16
    }
145
}
146