Attribute::__toString()   B
last analyzed

Complexity

Conditions 7
Paths 5

Size

Total Lines 17
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 7.049

Importance

Changes 1
Bugs 0 Features 1
Metric Value
eloc 9
c 1
b 0
f 1
dl 0
loc 17
ccs 9
cts 10
cp 0.9
rs 8.8333
cc 7
nc 5
nop 0
crap 7.049
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Enjoys\Forms;
6
7
use Closure;
8
use Enjoys\Forms\Interfaces\AttributeInterface;
9
use Webmozart\Assert\Assert;
10
use Webmozart\Assert\InvalidArgumentException;
11
12
abstract class Attribute implements AttributeInterface
13
{
14
    protected string $name = '';
15
16
    /**
17
     * @var string[]
18
     */
19
    private array $values = [];
20
21
    protected bool $withoutValue = true;
22
    protected bool $fillNameAsValue = false;
23
    protected bool $multiple = false;
24
    protected string $separator = '';
25
26 333
    public function withName(string $name): AttributeInterface
27
    {
28 333
        $new = clone $this;
29 333
        $new->name = $name;
30 333
        return $new;
31
    }
32
33
34 361
    public function setWithoutValue(bool $withoutValue): AttributeInterface
35
    {
36 361
        $this->withoutValue = $withoutValue;
37 361
        return $this;
38
    }
39
40 1
    public function setFillNameAsValue(bool $fillNameAsValue): AttributeInterface
41
    {
42 1
        $this->fillNameAsValue = $fillNameAsValue;
43 1
        return $this;
44
    }
45
46 32
    public function setMultiple(bool $multiple, string $separator = ' '): AttributeInterface
47
    {
48 32
        $this->multiple = $multiple;
49 32
        $this->separator = $separator;
50 32
        return $this;
51
    }
52
53
54 3
    public function setSeparator(string $separator): AttributeInterface
55
    {
56 3
        $this->separator = $separator;
57 3
        return $this;
58
    }
59
60 356
    public function getName(): string
61
    {
62 356
        return $this->name;
63
    }
64
65 73
    public function __toString(): string
66
    {
67 73
        if ($this->getName() === '') {
68
            return '';
69
        }
70 73
        if ($this->withoutValue && empty($this->values)) {
71 21
            if ($this->fillNameAsValue) {
72 1
                return sprintf('%1$s="%1$s"', $this->getName());
73
            }
74 21
            return $this->getName();
75
        }
76
77 65
        if (!$this->withoutValue && empty($this->values)) {
78 10
            return '';
79
        }
80
81 60
        return sprintf('%s="%s"', $this->getName(), $this->getValueString());
82
    }
83
84
    /**
85
     * @return string[]
86
     */
87 182
    public function getValues(): array
88
    {
89 182
        return $this->values;
90
    }
91
92 174
    public function getValueString(): string
93
    {
94 174
        return implode($this->separator, $this->getValues());
95
    }
96
97
    /**
98
     * @param string[] $values
99
     * @return void
100
     */
101 4
    public function set(array $values): void
102
    {
103 4
        $this->clear();
104 4
        foreach ($values as $item) {
105 4
            $this->add($item);
106
        }
107
    }
108
109 350
    public function clear(): void
110
    {
111 350
        $this->values = [];
112
    }
113
114 359
    public function has(string $value): bool
115
    {
116 359
        return in_array($value, $this->values, true);
117
    }
118
119
120
    /**
121
     * @param Closure|scalar|null $value
122
     * @return AttributeInterface
123
     */
124 366
    public function add($value): AttributeInterface
125
    {
126 366
        if ($value instanceof Closure) {
127
            /** @var null|scalar $value */
128 5
            $value = $value();
129
        }
130
131 366
        $value = $this->normalize($value);
132
133 365
        if ($value === null) {
134 159
            return $this;
135
        }
136
137 359
        if (!$this->multiple) {
138 348
            $this->clear();
139
        }
140
141 359
        $value = (!empty($this->separator)) ? explode($this->separator, $value) : (array) $value;
142
143 359
        foreach ($value as $item) {
144 359
            if (!$this->has($item)) {
145 359
                $this->values[] = $item;
146
            }
147
        }
148
149 359
        return $this;
150
    }
151
152 4
    public function remove(string $value): bool
153
    {
154 4
        $key = array_search($value, $this->values, true);
155
156 4
        if ($key === false) {
157 1
            return false;
158
        }
159
160 4
        unset($this->values[$key]);
161
162 4
        return true;
163
    }
164
165
    /**
166
     * @throws InvalidArgumentException
167
     */
168 365
    private function normalize(float|bool|int|string|null $value): ?string
169
    {
170 365
        Assert::nullOrScalar($value);
171 365
        return ($value === null) ? null : \htmlspecialchars((string) $value, ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401);
172
    }
173
}
174