1 | <?php |
||
2 | |||
3 | /** |
||
4 | * @package s9e\TextFormatter |
||
5 | * @copyright Copyright (c) The s9e authors |
||
6 | * @license http://www.opensource.org/licenses/mit-license.php The MIT License |
||
7 | */ |
||
8 | namespace s9e\TextFormatter\Configurator\Items; |
||
9 | |||
10 | use InvalidArgumentException; |
||
11 | use s9e\TextFormatter\Configurator\Collections\AttributeCollection; |
||
12 | use s9e\TextFormatter\Configurator\Collections\AttributePreprocessorCollection; |
||
13 | use s9e\TextFormatter\Configurator\Collections\Ruleset; |
||
14 | use s9e\TextFormatter\Configurator\Collections\TagFilterChain; |
||
15 | use s9e\TextFormatter\Configurator\ConfigProvider; |
||
16 | use s9e\TextFormatter\Configurator\Helpers\ConfigHelper; |
||
17 | use s9e\TextFormatter\Configurator\Items\Template; |
||
18 | use s9e\TextFormatter\Configurator\Traits\Configurable; |
||
19 | |||
20 | /** |
||
21 | * @property AttributeCollection $attributes This tag's attributes |
||
22 | * @property AttributePreprocessorCollection $attributePreprocessors This tag's attribute parsers |
||
23 | * @property TagFilterChain $filterChain This tag's filter chain |
||
24 | * @property integer $nestingLimit Maximum nesting level for this tag |
||
25 | * @property Ruleset $rules Rules associated with this tag |
||
26 | * @property integer $tagLimit Maximum number of this tag per message |
||
27 | * @property-read Template $template Template associated with this tag |
||
28 | * @property-write string|Template $template Template associated with this tag |
||
29 | */ |
||
30 | class Tag implements ConfigProvider |
||
31 | { |
||
32 | use Configurable; |
||
33 | |||
34 | /** |
||
35 | * @var AttributeCollection This tag's attributes |
||
36 | */ |
||
37 | protected $attributes; |
||
38 | |||
39 | /** |
||
40 | * @var AttributePreprocessorCollection This tag's attribute parsers |
||
41 | */ |
||
42 | protected $attributePreprocessors; |
||
43 | |||
44 | /** |
||
45 | * @var TagFilterChain This tag's filter chain |
||
46 | */ |
||
47 | protected $filterChain; |
||
48 | |||
49 | /** |
||
50 | * @var integer Maximum nesting level for this tag |
||
51 | */ |
||
52 | protected $nestingLimit = 10; |
||
53 | |||
54 | /** |
||
55 | * @var Ruleset Rules associated with this tag |
||
56 | */ |
||
57 | protected $rules; |
||
58 | |||
59 | /** |
||
60 | * @var integer Maximum number of this tag per message |
||
61 | */ |
||
62 | protected $tagLimit = 5000; |
||
63 | |||
64 | /** |
||
65 | * @var Template Template associated with this tag |
||
66 | */ |
||
67 | protected $template; |
||
68 | |||
69 | /** |
||
70 | * Constructor |
||
71 | * |
||
72 | * @param array $options This tag's options |
||
73 | */ |
||
74 | 22 | public function __construct(?array $options = null) |
|
75 | { |
||
76 | 22 | $this->attributes = new AttributeCollection; |
|
77 | 22 | $this->attributePreprocessors = new AttributePreprocessorCollection; |
|
78 | 22 | $this->filterChain = new TagFilterChain; |
|
79 | 22 | $this->rules = new Ruleset; |
|
80 | |||
81 | // Start the filterChain with the default processing |
||
82 | 22 | $this->filterChain->append('s9e\\TextFormatter\\Parser\\FilterProcessing::executeAttributePreprocessors') |
|
83 | 22 | ->addParameterByName('tagConfig') |
|
84 | 22 | ->setJS('executeAttributePreprocessors'); |
|
85 | |||
86 | 22 | $this->filterChain->append('s9e\\TextFormatter\\Parser\\FilterProcessing::filterAttributes') |
|
87 | 22 | ->addParameterByName('tagConfig') |
|
88 | 22 | ->addParameterByName('registeredVars') |
|
89 | 22 | ->addParameterByName('logger') |
|
90 | 22 | ->setJS('filterAttributes'); |
|
91 | |||
92 | 22 | if (isset($options)) |
|
93 | { |
||
94 | // Sort the options by name so that attributes are set before the template, which is |
||
95 | // necessary to evaluate whether the template is safe |
||
96 | 1 | ksort($options); |
|
97 | |||
98 | 1 | foreach ($options as $optionName => $optionValue) |
|
99 | { |
||
100 | 1 | $this->__set($optionName, $optionValue); |
|
101 | } |
||
102 | } |
||
103 | } |
||
104 | |||
105 | /** |
||
106 | * {@inheritdoc} |
||
107 | */ |
||
108 | 3 | public function asConfig() |
|
109 | { |
||
110 | 3 | $vars = get_object_vars($this); |
|
111 | |||
112 | // Remove properties that are not needed during parsing |
||
113 | 3 | unset($vars['template']); |
|
114 | |||
115 | // If there are no attribute preprocessors defined, we can remove the step from this tag's |
||
116 | // filterChain |
||
117 | 3 | if (!count($this->attributePreprocessors)) |
|
118 | { |
||
119 | 3 | $callback = 's9e\\TextFormatter\\Parser\\FilterProcessing::executeAttributePreprocessors'; |
|
120 | |||
121 | // We operate on a copy of the filterChain, without modifying the original |
||
122 | 3 | $filterChain = clone $vars['filterChain']; |
|
123 | |||
124 | // Process the chain in reverse order so that we don't skip indices |
||
125 | 3 | $i = count($filterChain); |
|
126 | 3 | while (--$i >= 0) |
|
127 | { |
||
128 | 3 | if ($filterChain[$i]->getCallback() === $callback) |
|
129 | { |
||
130 | 3 | unset($filterChain[$i]); |
|
131 | } |
||
132 | } |
||
133 | |||
134 | 3 | $vars['filterChain'] = $filterChain; |
|
135 | } |
||
136 | |||
137 | 3 | return ConfigHelper::toArray($vars) + ['attributes' => [], 'filterChain' => []]; |
|
138 | } |
||
139 | |||
140 | /** |
||
141 | * Return this tag's template |
||
142 | * |
||
143 | * @return Template |
||
144 | */ |
||
145 | 1 | public function getTemplate() |
|
146 | { |
||
147 | 1 | return $this->template; |
|
0 ignored issues
–
show
Bug
Best Practice
introduced
by
Loading history...
|
|||
148 | } |
||
149 | |||
150 | /** |
||
151 | * Test whether this tag has a template |
||
152 | * |
||
153 | * @return bool |
||
154 | */ |
||
155 | 2 | public function issetTemplate() |
|
156 | { |
||
157 | 2 | return isset($this->template); |
|
158 | } |
||
159 | |||
160 | /** |
||
161 | * Set this tag's attribute preprocessors |
||
162 | * |
||
163 | * @param array|AttributePreprocessorCollection $attributePreprocessors 2D array of [attrName=>[regexp]], or an instance of AttributePreprocessorCollection |
||
164 | * @return void |
||
165 | */ |
||
166 | 3 | public function setAttributePreprocessors($attributePreprocessors) |
|
167 | { |
||
168 | 3 | $this->attributePreprocessors->clear(); |
|
169 | 3 | $this->attributePreprocessors->merge($attributePreprocessors); |
|
170 | } |
||
171 | |||
172 | /** |
||
173 | * Set this tag's nestingLimit |
||
174 | * |
||
175 | * @param integer $limit |
||
176 | * @return void |
||
177 | */ |
||
178 | 5 | public function setNestingLimit($limit) |
|
179 | { |
||
180 | 5 | $limit = (int) $limit; |
|
181 | |||
182 | 5 | if ($limit < 1) |
|
183 | { |
||
184 | 2 | throw new InvalidArgumentException('nestingLimit must be a number greater than 0'); |
|
185 | } |
||
186 | |||
187 | 3 | $this->nestingLimit = $limit; |
|
188 | } |
||
189 | |||
190 | /** |
||
191 | * Set this tag's rules |
||
192 | * |
||
193 | * @param array|Ruleset $rules 2D array of rule definitions, or instance of Ruleset |
||
194 | * @return void |
||
195 | */ |
||
196 | 3 | public function setRules($rules) |
|
197 | { |
||
198 | 3 | $this->rules->clear(); |
|
199 | 3 | $this->rules->merge($rules); |
|
200 | } |
||
201 | |||
202 | /** |
||
203 | * Set this tag's tagLimit |
||
204 | * |
||
205 | * @param integer $limit |
||
206 | * @return void |
||
207 | */ |
||
208 | 4 | public function setTagLimit($limit) |
|
209 | { |
||
210 | 4 | $limit = (int) $limit; |
|
211 | |||
212 | 4 | if ($limit < 1) |
|
213 | { |
||
214 | 2 | throw new InvalidArgumentException('tagLimit must be a number greater than 0'); |
|
215 | } |
||
216 | |||
217 | 2 | $this->tagLimit = $limit; |
|
218 | } |
||
219 | |||
220 | /** |
||
221 | * Set the template associated with this tag |
||
222 | * |
||
223 | * @param string|Template $template |
||
224 | * @return void |
||
225 | */ |
||
226 | 5 | public function setTemplate($template) |
|
227 | { |
||
228 | 5 | if (!($template instanceof Template)) |
|
229 | { |
||
230 | 5 | $template = new Template($template); |
|
231 | } |
||
232 | |||
233 | 5 | $this->template = $template; |
|
234 | } |
||
235 | |||
236 | /** |
||
237 | * Unset this tag's template |
||
238 | * |
||
239 | * @return void |
||
240 | */ |
||
241 | 1 | public function unsetTemplate() |
|
242 | { |
||
243 | 1 | unset($this->template); |
|
244 | } |
||
245 | } |