Passed
Push — master ( ef6f5d...60f4bc )
by Alexander
02:52
created

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