Test Failed
Pull Request — master (#160)
by Wilmer
02:22
created

Radio::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\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
    public function checked(bool $value = true): self
34
    {
35
        $new = clone $this;
36
        $new->checked = $value;
37
        return $new;
38
    }
39
40 11
    /**
41
     * If the widget should be enclosed by label.
42 11
     *
43 11
     * @param bool $value If the widget should be en closed by label.
44 11
     *
45
     * @return static
46
     */
47
    public function enclosedByLabel(bool $value): self
48
    {
49
        $new = clone $this;
50
        $new->enclosedByLabel = $value;
51
        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 3
     *
60
     * When this option is specified, the radio will be enclosed by a label tag.
61 3
     *
62 3
     * @param string|null $value
63 3
     *
64
     * @return static
65
     */
66
    public function label(?string $value): self
67
    {
68
        $new = clone $this;
69
        $new->label = $value;
70
        return $new;
71
    }
72
73
    /**
74
     * HTML attributes for the label tag.
75 3
     *
76
     * Do not set this option unless you set the "label" option.
77 3
     *
78 3
     * @param array $value
79 3
     *
80
     * @return static
81
     */
82
    public function labelAttributes(array $value = []): self
83
    {
84
        $new = clone $this;
85
        $new->labelAttributes = $value;
86
        return $new;
87 2
    }
88
89 2
    /**
90 2
     * @param bool|float|int|string|Stringable|null $value Value that corresponds to "unchecked" state of the input.
91 2
     *
92
     * @return static
93
     */
94
    public function uncheckValue($value): self
95
    {
96
        $new = clone $this;
97
        $new->uncheckValue = $value === null ? null : (string) $value;
98
        return $new;
99
    }
100
101
    /**
102
     * Generates a radio button tag together with a label for the given form attribute.
103 6
     *
104
     * @return string the generated radio button tag.
105 6
     */
106 6
    protected function run(): string
107 6
    {
108
        $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
        $value = $this->getAttributeValue();
112
113
        /** @var iterable<int, scalar|Stringable>|scalar|Stringable|null */
114
        $valueDefault = array_key_exists('value', $attributes) ? $attributes['value'] : null;
115 16
116
        if (is_iterable($value) || is_object($value) || is_iterable($valueDefault) || is_object($valueDefault)) {
117 16
            throw new InvalidArgumentException('Radio widget value can not be an iterable or an object.');
118 16
        }
119
120 16
        $radio = RadioTag::tag();
121
122 16
        if ($this->enclosedByLabel === true) {
123 2
            $radio = $radio->label(
124
                empty($this->label) ? $this->getAttributeLabel() : $this->label,
125
                $this->labelAttributes,
126
            );
127 14
        }
128
129 14
        if (empty($value)) {
130 12
            $radio = $radio->checked($this->checked);
131 12
        } else {
132 12
            $radio = $radio->checked("$value" === "$valueDefault");
133
        }
134
135
        return $radio
136 14
            ->attributes($attributes)
137 14
            ->uncheckValue($this->uncheckValue)
138 14
            ->value(is_bool($valueDefault) ? (int) $valueDefault : $valueDefault)
139 14
            ->render();
140 14
    }
141
}
142