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

Range::run()   B

Complexity

Conditions 7
Paths 3

Size

Total Lines 33
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 22
CRAP Score 7

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 7
eloc 22
c 1
b 0
f 0
nc 3
nop 0
dl 0
loc 33
ccs 22
cts 22
cp 1
crap 7
rs 8.6346
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Form\Widget;
6
7
use InvalidArgumentException;
8
use Yiisoft\Form\Widget\Attribute\InputAttributes;
9
use Yiisoft\Form\Widget\Validator\NumberInterface;
10
use Yiisoft\Html\Html;
11
use Yiisoft\Html\Tag\CustomTag;
12
use Yiisoft\Html\Tag\Input;
13
14
/**
15
 * The input element with a type attribute whose value is "range" represents an imprecise control for setting the
16
 * element’s value to a string representing a number.
17
 *
18
 * @link https://www.w3.org/TR/2012/WD-html-markup-20120329/input.range.html
19
 */
20
final class Range extends InputAttributes implements NumberInterface
21
{
22
    private array $outputAttributes = [];
23
    private string $outputTag = 'output';
24
25 3
    public function max(int $value): self
26
    {
27 3
        $new = clone $this;
28 3
        $new->attributes['max'] = $value;
29 3
        return $new;
30
    }
31
32 3
    public function min(int $value): self
33
    {
34 3
        $new = clone $this;
35 3
        $new->attributes['min'] = $value;
36 3
        return $new;
37
    }
38
39
    /**
40
     * The HTML attributes for output tag. The following special options are recognized.
41
     *
42
     * @param array $value
43
     *
44
     * @return static
45
     *
46
     * See {@see \Yiisoft\Html\Html::renderTagAttributes()} for details on how attributes are being rendered.
47
     */
48 3
    public function outputAttributes(array $value): self
49
    {
50 3
        $new = clone $this;
51 3
        $new->outputAttributes = $value;
52 3
        return $new;
53
    }
54
55
    /**
56
     * The tag name of the output tag.
57
     *
58
     * Empty to render error messages without container {@see Html::tag()}.
59
     *
60
     * @param string $value
61
     *
62
     * @return static
63
     */
64 5
    public function outputTag(string $value): self
65
    {
66 5
        $new = clone $this;
67 5
        $new->outputTag = $value;
68 5
        return $new;
69
    }
70
71
    /**
72
     * @return string the generated input tag.
73
     */
74 38
    protected function run(): string
75
    {
76 38
        $attributes = $this->build($this->attributes);
77 38
        $outputAttributes = $this->outputAttributes;
78
79 38
        if (empty($this->outputTag)) {
80 2
            throw new InvalidArgumentException('The output tag name it cannot be empty value.');
81
        }
82
83
        /** @link https://www.w3.org/TR/2012/WD-html-markup-20120329/input.range.html#input.range.attrs.value */
84 36
        $value = $attributes['value'] ?? $this->getAttributeValue();
85 36
        unset($attributes['value']);
86
87 36
        if (!is_numeric($value) && null !== $value && '' !== $value) {
88 2
            throw new InvalidArgumentException('Range widget must be a numeric or null value.');
89
        }
90
91 34
        $nameOutput = Html::generateId();
92
        /** @var string|null */
93 34
        $outputAttributes['for'] = $attributes['name'] ?? null;
94 34
        $outputAttributes['name'] = $nameOutput;
95 34
        $attributes['oninput'] = "$nameOutput.value=this.value";
96
97
        return
98 34
            Input::tag()
99 34
                ->type('range')
100 34
                ->attributes($attributes)
101 34
                ->value($value > 0 ? $value : 0)->render() . PHP_EOL .
102 34
            CustomTag::name($this->outputTag)
103 34
                ->attributes($outputAttributes)
104 34
                ->content($value > 0 ? (string)$value : '0')
105 34
                ->id($nameOutput)
106 34
                ->render();
107
    }
108
}
109