Passed
Pull Request — master (#160)
by Wilmer
02:18
created

Checkbox::run()   B

Complexity

Conditions 6
Paths 7

Size

Total Lines 32
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 20
CRAP Score 6

Importance

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