1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* Webino™ (http://webino.sk) |
4
|
|
|
* |
5
|
|
|
* @link https://github.com/webino for the canonical source repository |
6
|
|
|
* @copyright Copyright (c) 2015-2017 Webino, s.r.o. (http://webino.sk) |
7
|
|
|
* @author Peter Bačinský <[email protected]> |
8
|
|
|
* @license BSD-3-Clause |
9
|
|
|
*/ |
10
|
|
|
|
11
|
|
|
namespace WebinoHtmlLib\Html; |
12
|
|
|
|
13
|
|
|
use WebinoBaseLib\Util\ToString; |
14
|
|
|
|
15
|
|
|
/** |
16
|
|
|
* Class AbstractHtml |
17
|
|
|
*/ |
18
|
|
|
abstract class AbstractHtml implements HtmlInterface |
19
|
|
|
{ |
20
|
|
|
use EscaperAwareTrait; |
21
|
|
|
use FormatTrait; |
22
|
|
|
|
23
|
|
|
/** |
24
|
|
|
* @var string |
25
|
|
|
*/ |
26
|
|
|
private $value; |
27
|
|
|
|
28
|
|
|
/** |
29
|
|
|
* @var array |
30
|
|
|
*/ |
31
|
|
|
private $attribs = []; |
32
|
|
|
|
33
|
|
|
/** |
34
|
|
|
* @return string |
35
|
|
|
*/ |
36
|
|
|
abstract protected function getTagName(); |
37
|
|
|
|
38
|
|
|
/** |
39
|
|
|
* @param string|array|object $value New value;current value placeholder is `%s` |
40
|
|
|
* @return $this |
41
|
|
|
*/ |
42
|
|
|
public function setValue($value) |
43
|
|
|
{ |
44
|
|
|
$this->value = strtr($this->normalizeValue($value), ['%s' => $this->value]); |
|
|
|
|
45
|
|
|
return $this; |
46
|
|
|
} |
47
|
|
|
|
48
|
|
|
/** |
49
|
|
|
* @param string $name |
50
|
|
|
* @param string $value |
51
|
|
|
* @return $this |
52
|
|
|
*/ |
53
|
|
|
protected function setAttribute($name, $value) |
54
|
|
|
{ |
55
|
|
|
$this->attribs[$name] = $value; |
56
|
|
|
return $this; |
57
|
|
|
} |
58
|
|
|
|
59
|
|
|
/** |
60
|
|
|
* @param $title |
61
|
|
|
* @return $this |
62
|
|
|
*/ |
63
|
|
|
public function setTitle($title) |
64
|
|
|
{ |
65
|
|
|
$this->setAttribute('title', $title); |
66
|
|
|
return $this; |
67
|
|
|
} |
68
|
|
|
|
69
|
|
|
/** |
70
|
|
|
* @param string $class |
71
|
|
|
* @return $this |
72
|
|
|
*/ |
73
|
|
|
public function setClass($class) |
74
|
|
|
{ |
75
|
|
|
$this->setAttribute('class', $class); |
76
|
|
|
return $this; |
77
|
|
|
} |
78
|
|
|
|
79
|
|
|
/** |
80
|
|
|
* @param array|string $style |
81
|
|
|
* @param string|null $value |
82
|
|
|
* @return $this |
83
|
|
|
*/ |
84
|
|
|
public function setStyle($style, $value = null) |
85
|
|
|
{ |
86
|
|
|
$styleData = []; |
87
|
|
|
|
88
|
|
|
if (!empty($this->attribs['style'])) { |
89
|
|
|
call_user_func(function () use (&$styleData) { |
90
|
|
|
foreach (explode(';', $this->attribs['style']) as $pair) { |
91
|
|
|
list($name, $value) = explode(':', $pair); |
92
|
|
|
$styleData[trim($name)] = trim($value); |
93
|
|
|
} |
94
|
|
|
}); |
95
|
|
|
} |
96
|
|
|
|
97
|
|
|
if (is_array($style)) { |
98
|
|
|
foreach ($style as $name => $value) { |
99
|
|
|
$styleData[$name] = $value; |
100
|
|
|
} |
101
|
|
|
|
102
|
|
|
} elseif (null !== $value) { |
103
|
|
|
$styleData[$style] = $value; |
104
|
|
|
|
105
|
|
|
} elseif (isset($styleData[$style])) { |
106
|
|
|
unset($styleData[$style]); |
107
|
|
|
} |
108
|
|
|
|
109
|
|
|
$stylePairs = []; |
110
|
|
|
foreach ($styleData as $name => $value) { |
111
|
|
|
$stylePairs[] = $name . ': ' . $value; |
112
|
|
|
} |
113
|
|
|
|
114
|
|
|
$this->setAttribute('style', join('; ', $stylePairs)); |
115
|
|
|
return $this; |
116
|
|
|
} |
117
|
|
|
|
118
|
|
|
/** |
119
|
|
|
* @param string|array|HtmlInterface $value |
120
|
|
|
* @return string |
121
|
|
|
*/ |
122
|
|
|
private function normalizeValue($value) |
123
|
|
|
{ |
124
|
|
|
if ($value instanceof HtmlInterface) { |
125
|
|
|
return ToString::value($value); |
126
|
|
|
} |
127
|
|
|
|
128
|
|
|
if (is_array($value)) { |
129
|
|
|
$newValue = ''; |
130
|
|
|
foreach ($value as $subValue) { |
131
|
|
|
$newValue .= $this->normalizeValue($subValue); |
132
|
|
|
} |
133
|
|
|
return $newValue; |
134
|
|
|
} |
135
|
|
|
|
136
|
|
|
return $this->getEscaper()->escapeHtml(ToString::value($value)); |
137
|
|
|
} |
138
|
|
|
|
139
|
|
|
/** |
140
|
|
|
* @param string $tag |
141
|
|
|
* @param string $attribs |
142
|
|
|
* @param string $value |
143
|
|
|
* @return string |
144
|
|
|
*/ |
145
|
|
|
protected function toStringInternal($tag, $attribs, $value) |
146
|
|
|
{ |
147
|
|
|
return $this->doFormat(sprintf('<%s %s>%s</%s>', $tag, $attribs, $value, $tag)); |
148
|
|
|
} |
149
|
|
|
|
150
|
|
|
/** |
151
|
|
|
* @return string |
152
|
|
|
*/ |
153
|
|
|
public function __toString() |
154
|
|
|
{ |
155
|
|
|
$escaper = $this->getEscaper(); |
156
|
|
|
$attribs = []; |
157
|
|
|
|
158
|
|
|
foreach ($this->attribs as $attrib => $value) { |
159
|
|
|
|
160
|
|
|
empty($value) |
161
|
|
|
or $attribs[] = sprintf( |
|
|
|
|
162
|
|
|
'%s="%s"', |
163
|
|
|
$escaper->escapeHtml($attrib), |
164
|
|
|
$escaper->escapeHtmlAttr($value) |
165
|
|
|
); |
166
|
|
|
} |
167
|
|
|
|
168
|
|
|
$tag = $this->getTagName(); |
169
|
|
|
return $this->toStringInternal($tag, join(' ', $attribs), $this->value); |
170
|
|
|
} |
171
|
|
|
} |
172
|
|
|
|
This check looks at variables that have been passed in as parameters and are passed out again to other methods.
If the outgoing method call has stricter type requirements than the method itself, an issue is raised.
An additional type check may prevent trouble.