PluginProbe ʕ •ᴥ•ʔ
Matomo Analytics – Powerful, Privacy-First Insights for WordPress / trunk
Matomo Analytics – Powerful, Privacy-First Insights for WordPress vtrunk
5.11.1 5.11.0 5.10.2 5.10.1 trunk 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.1.0 1.1.1 1.1.2 1.1.3 1.2.0 1.3.0 1.3.1 1.3.2 4.0.0 4.0.1 4.0.2 4.0.3 4.0.4 4.1.0 4.1.1 4.1.2 4.1.3 4.10.0 4.11.0 4.12.0 4.13.0 4.13.2 4.13.3 4.13.4 4.13.5 4.14.0 4.14.1 4.14.2 4.15.0 4.15.1 4.15.2 4.15.3 4.2.0 4.3.0 4.3.1 4.4.1 4.4.2 4.5.0 4.6.0 5.0.1 5.0.2 5.0.3 5.0.4 5.0.5 5.0.6 5.0.7 5.0.8 5.1.0 5.1.1 5.1.2 5.1.3 5.1.4 5.1.5 5.1.6 5.1.7 5.10.0 5.2.0 5.2.1 5.2.2 5.3.0 5.3.1 5.3.2 5.3.3 5.6.0 5.6.1 5.7.0 5.7.1 5.8.0 5.8.1 5.8.2
matomo / app / libs / HTML / QuickForm2 / Renderer / Default.php
matomo / app / libs / HTML / QuickForm2 / Renderer Last commit date
Array.php 2 years ago Default.php 2 years ago Plugin.php 2 years ago Proxy.php 1 year ago Smarty.php 2 years ago
Default.php
501 lines
1 <?php
2
3 namespace {
4 /**
5 * Default renderer for HTML_QuickForm2
6 *
7 * PHP version 5
8 *
9 * LICENSE:
10 *
11 * Copyright (c) 2006-2010, Alexey Borzov <avb@php.net>,
12 * Bertrand Mansion <golgote@mamasam.com>
13 * All rights reserved.
14 *
15 * Redistribution and use in source and binary forms, with or without
16 * modification, are permitted provided that the following conditions
17 * are met:
18 *
19 * * Redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer.
21 * * Redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in the
23 * documentation and/or other materials provided with the distribution.
24 * * The names of the authors may not be used to endorse or promote products
25 * derived from this software without specific prior written permission.
26 *
27 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
28 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
29 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
30 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
31 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
32 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
33 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
34 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
35 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
36 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
37 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38 *
39 * @category HTML
40 * @package HTML_QuickForm2
41 * @author Alexey Borzov <avb@php.net>
42 * @author Bertrand Mansion <golgote@mamasam.com>
43 * @license http://opensource.org/licenses/bsd-license.php New BSD License
44 * @version SVN: $Id: Default.php 299706 2010-05-24 18:32:37Z avb $
45 * @link http://pear.php.net/package/HTML_QuickForm2
46 */
47 /**
48 * Abstract base class for QuickForm2 renderers
49 */
50 // require_once 'HTML/QuickForm2/Renderer.php';
51 /**
52 * Default renderer for QuickForm2
53 *
54 * Mostly a direct port of Default renderer from QuickForm 3.x package.
55 *
56 * While almost everything in this class is defined as public, its properties
57 * and those methods that are not published (i.e. not in array returned by
58 * exportMethods()) will be available to renderer plugins only.
59 *
60 * The following methods are published:
61 * - {@link reset()}
62 * - {@link setTemplateForClass()}
63 * - {@link setTemplateForId()}
64 * - {@link setErrorTemplate()}
65 * - {@link setElementTemplateForGroupClass()}
66 * - {@link setElementTemplateForGroupId()}
67 *
68 * @category HTML
69 * @package HTML_QuickForm2
70 * @author Alexey Borzov <avb@php.net>
71 * @author Bertrand Mansion <golgote@mamasam.com>
72 * @version Release: @package_version@
73 */
74 class HTML_QuickForm2_Renderer_Default extends \HTML_QuickForm2_Renderer
75 {
76 /**
77 * Whether the form contains required elements
78 * @var bool
79 */
80 public $hasRequired = \false;
81 /**
82 * HTML generated for the form
83 * @var array
84 */
85 public $html = array(array());
86 /**
87 * HTML for hidden elements if 'group_hiddens' option is on
88 * @var string
89 */
90 public $hiddenHtml = '';
91 /**
92 * Array of validation errors if 'group_errors' option is on
93 * @var array
94 */
95 public $errors = array();
96 /**
97 * Default templates for elements of the given class
98 * @var array
99 */
100 public $templatesForClass = array('html_quickform2_element_inputhidden' => '<div style="display: none;">{element}</div>', 'html_quickform2' => '<div class="quickform">{errors}<form{attributes}>{hidden}{content}</form><qf:reqnote><div class="reqnote">{reqnote}</div></qf:reqnote></div>', 'html_quickform2_container_fieldset' => '<fieldset{attributes}><qf:label><legend id="{id}-legend">{label}</legend></qf:label>{content}</fieldset>', 'special:error' => array('prefix' => '<div class="errors"><qf:message><p>{message}</p></qf:message><ul><li>', 'separator' => '</li><li>', 'suffix' => '</li></ul><qf:message><p>{message}</p></qf:message></div>'), 'html_quickform2_element' => '<div class="row"><label for="{id}" class="element"><qf:required><span class="required">* </span></qf:required>{label}</label><div class="element<qf:error> error</qf:error>"><qf:error><span class="error">{error}</span><br /></qf:error>{element}</div></div>', 'html_quickform2_container_group' => '<div class="row"><label class="element"><qf:required><span class="required">* </span></qf:required>{label}</label><div class="element group<qf:error> error</qf:error>"><qf:error><span class="error">{error}</span><br /></qf:error>{content}</div></div>');
101 /**
102 * Custom templates for elements with the given IDs
103 * @var array
104 */
105 public $templatesForId = array();
106 /**
107 * Default templates for elements in groups of the given classes
108 *
109 * Array has the form ('group class' => ('element class' => 'template', ...), ...)
110 *
111 * @var array
112 */
113 public $elementTemplatesForGroupClass = array('html_quickform2_container' => array('html_quickform2_element' => '{element}', 'html_quickform2_container_fieldset' => '<fieldset{attributes}><qf:label><legend id="{id}-legend">{label}</legend></qf:label>{content}</fieldset>'));
114 /**
115 * Custom templates for grouped elements in the given group IDs
116 *
117 * Array has the form ('group id' => ('element class' => 'template', ...), ...)
118 *
119 * @var array
120 */
121 public $elementTemplatesForGroupId = array();
122 /**
123 * Array containing IDs of the groups being rendered
124 * @var array
125 */
126 public $groupId = array();
127 public function exportMethods()
128 {
129 return array('reset', 'setTemplateForClass', 'setTemplateForId', 'setErrorTemplate', 'setGroupedTemplateForClass', 'setElementTemplateForGroupClass', 'setElementTemplateForGroupId');
130 }
131 /**
132 * Sets template for form elements that are instances of the given class
133 *
134 * When searching for a template to use, renderer will check for templates
135 * set for element's class and its parent classes, until found. Thus a more
136 * specific template will override a more generic one.
137 *
138 * @param string Class name
139 * @param mixed Template to use for elements of that class
140 * @return HTML_QuickForm2_Renderer_Default
141 */
142 public function setTemplateForClass($className, $template)
143 {
144 $this->templatesForClass[\strtolower($className)] = $template;
145 return $this;
146 }
147 /**
148 * Sets template for form element with the given id
149 *
150 * If a template is set for an element via this method, it will be used.
151 * In the other case a generic template set by {@link setTemplateForClass()}
152 * or {@link setGroupedTemplateForClass()} will be used.
153 *
154 * @param string Element's id
155 * @param mixed Template to use for rendering of that element
156 * @return HTML_QuickForm2_Renderer_Default
157 */
158 public function setTemplateForId($id, $template)
159 {
160 $this->templatesForId[$id] = $template;
161 return $this;
162 }
163 /**
164 * Sets template for rendering validation errors
165 *
166 * This template will be used if 'group_errors' option is set to true.
167 * The template array should contain 'prefix', 'suffix' and 'separator'
168 * keys.
169 *
170 * @param array Template for validation errors
171 * @return HTML_QuickForm2_Renderer_Default
172 */
173 public function setErrorTemplate(array $template)
174 {
175 return $this->setTemplateForClass('special:error', $template);
176 }
177 /**
178 * Sets grouped elements templates using group class
179 *
180 * Templates set via {@link setTemplateForClass()} will not be used for
181 * grouped form elements. When searching for a template to use, the renderer
182 * will first consider template set for a specific group id, then the
183 * group templates set by group class.
184 *
185 * @param string Group class name
186 * @param string Element class name
187 * @param mixed Template
188 * @return HTML_QuickForm2_Renderer_Default
189 */
190 public function setElementTemplateForGroupClass($groupClass, $elementClass, $template)
191 {
192 $this->elementTemplatesForGroupClass[\strtolower($groupClass)][\strtolower($elementClass)] = $template;
193 return $this;
194 }
195 /**
196 * Sets grouped elements templates using group id
197 *
198 * Templates set via {@link setTemplateForClass()} will not be used for
199 * grouped form elements. When searching for a template to use, the renderer
200 * will first consider template set for a specific group id, then the
201 * group templates set by group class.
202 *
203 * @param string Group id
204 * @param string Element class name
205 * @param mixed Template
206 * @return HTML_QuickForm2_Renderer_Default
207 */
208 public function setElementTemplateForGroupId($groupId, $elementClass, $template)
209 {
210 $this->elementTemplatesForGroupId[$groupId][\strtolower($elementClass)] = $template;
211 return $this;
212 }
213 /**
214 * Resets the accumulated data
215 *
216 * This method is called automatically by startForm() method, but should
217 * be called manually before calling other rendering methods separately.
218 *
219 * @return HTML_QuickForm2_Renderer_Default
220 */
221 public function reset()
222 {
223 $this->html = array(array());
224 $this->hiddenHtml = '';
225 $this->errors = array();
226 $this->hasRequired = \false;
227 $this->groupId = array();
228 return $this;
229 }
230 /**
231 * Returns generated HTML
232 *
233 * @return string
234 */
235 public function __toString()
236 {
237 return (isset($this->html[0][0]) ? $this->html[0][0] : '') . $this->hiddenHtml;
238 }
239 /**
240 * Renders a generic element
241 *
242 * @param HTML_QuickForm2_Node Element being rendered
243 */
244 public function renderElement(\HTML_QuickForm2_Node $element)
245 {
246 $elTpl = $this->prepareTemplate($this->findTemplate($element), $element);
247 $this->html[\count($this->html) - 1][] = \str_replace(array('{element}', '{id}'), array($element, $element->getId()), $elTpl);
248 }
249 /**
250 * Renders a hidden element
251 *
252 * @param HTML_QuickForm2_Node Hidden element being rendered
253 */
254 public function renderHidden(\HTML_QuickForm2_Node $element)
255 {
256 if ($this->options['group_hiddens']) {
257 $this->hiddenHtml .= $element->__toString();
258 } else {
259 $this->html[\count($this->html) - 1][] = \str_replace('{element}', $element, $this->findTemplate($element));
260 }
261 }
262 /**
263 * Starts rendering a generic container, called before processing contained elements
264 *
265 * @param HTML_QuickForm2_Node Container being rendered
266 */
267 public function startContainer(\HTML_QuickForm2_Node $container)
268 {
269 $this->html[] = array();
270 $this->groupId[] = \false;
271 }
272 /**
273 * Finishes rendering a generic container, called after processing contained elements
274 *
275 * @param HTML_QuickForm2_Node Container being rendered
276 */
277 public function finishContainer(\HTML_QuickForm2_Node $container)
278 {
279 \array_pop($this->groupId);
280 $cTpl = \str_replace(array('{attributes}', '{id}'), array($container->getAttributes(\true), $container->getId()), $this->prepareTemplate($this->findTemplate($container, '{content}'), $container));
281 $cHtml = \array_pop($this->html);
282 $break = \HTML_Common2::getOption('linebreak');
283 $indent = \str_repeat(\HTML_Common2::getOption('indent'), \count($this->html));
284 $this->html[\count($this->html) - 1][] = \str_replace('{content}', $break . $indent . \implode($break . $indent, $cHtml), $cTpl);
285 }
286 /**
287 * Starts rendering a group, called before processing grouped elements
288 *
289 * @param HTML_QuickForm2_Node Group being rendered
290 */
291 public function startGroup(\HTML_QuickForm2_Node $group)
292 {
293 $this->html[] = array();
294 $this->groupId[] = $group->getId();
295 }
296 /**
297 * Finishes rendering a group, called after processing grouped elements
298 *
299 * @param HTML_QuickForm2_Node Group being rendered
300 */
301 public function finishGroup(\HTML_QuickForm2_Node $group)
302 {
303 $gTpl = \str_replace(array('{attributes}', '{id}'), array($group->getAttributes(\true), \array_pop($this->groupId)), $this->prepareTemplate($this->findTemplate($group, '{content}'), $group));
304 $separator = $group->getSeparator();
305 $elements = \array_pop($this->html);
306 if (!\is_array($separator)) {
307 $content = \implode((string) $separator, $elements);
308 } else {
309 $content = '';
310 $cSeparator = \count($separator);
311 for ($i = 0, $count = \count($elements); $i < $count; $i++) {
312 $content .= (0 == $i ? '' : $separator[($i - 1) % $cSeparator]) . $elements[$i];
313 }
314 }
315 $this->html[\count($this->html) - 1][] = \str_replace('{content}', $content, $gTpl);
316 }
317 /**
318 * Starts rendering a form, called before processing contained elements
319 *
320 * @param HTML_QuickForm2_Node Form being rendered
321 */
322 public function startForm(\HTML_QuickForm2_Node $form)
323 {
324 $this->reset();
325 }
326 /**
327 * Finishes rendering a form, called after processing contained elements
328 *
329 * @param HTML_QuickForm2_Node Form being rendered
330 */
331 public function finishForm(\HTML_QuickForm2_Node $form)
332 {
333 $formTpl = \str_replace(array('{attributes}', '{hidden}', '{errors}'), array($form->getAttributes(\true), $this->hiddenHtml, $this->outputGroupedErrors()), $this->findTemplate($form, '{content}'));
334 $this->hiddenHtml = '';
335 // required note
336 if (!$this->hasRequired || $form->toggleFrozen() || empty($this->options['required_note'])) {
337 $formTpl = \preg_replace('!<qf:reqnote>.*</qf:reqnote>!isU', '', $formTpl);
338 } else {
339 $formTpl = \str_replace(array('<qf:reqnote>', '</qf:reqnote>', '{reqnote}'), array('', '', $this->options['required_note']), $formTpl);
340 }
341 $break = \HTML_Common2::getOption('linebreak');
342 $script = $this->getJavascriptBuilder()->__toString();
343 $this->html[0] = array((empty($script) ? '' : $script . $break) . \str_replace('{content}', $break . \implode($break, $this->html[0]), $formTpl));
344 }
345 /**
346 * Creates a error list if 'group_errors' option is true
347 *
348 * @return string HTML with a list of all validation errors
349 */
350 public function outputGroupedErrors()
351 {
352 if (empty($this->errors)) {
353 return '';
354 }
355 if (!empty($this->options['errors_prefix'])) {
356 $errorHtml = \str_replace(array('<qf:message>', '</qf:message>', '{message}'), array('', '', $this->options['errors_prefix']), $this->templatesForClass['special:error']['prefix']);
357 } else {
358 $errorHtml = \preg_replace('!<qf:message>.*</qf:message>!isU', '', $this->templatesForClass['special:error']['prefix']);
359 }
360 $errorHtml .= \implode($this->templatesForClass['special:error']['separator'], $this->errors);
361 if (!empty($this->options['errors_suffix'])) {
362 $errorHtml .= \str_replace(array('<qf:message>', '</qf:message>', '{message}'), array('', '', $this->options['errors_suffix']), $this->templatesForClass['special:error']['suffix']);
363 } else {
364 $errorHtml .= \preg_replace('!<qf:message>.*</qf:message>!isU', '', $this->templatesForClass['special:error']['suffix']);
365 }
366 return $errorHtml;
367 }
368 /**
369 * Finds a proper template for the element
370 *
371 * Templates are scanned in a predefined order. First, if a template was
372 * set for a specific element by id, it is returned, no matter if the
373 * element belongs to a group. If the element does not belong to a group,
374 * we try to match a template using the element class.
375 * But, if the element belongs to a group, templates are first looked up
376 * using the containing group id, then using the containing group class.
377 * When no template is found, the provided default template is returned.
378 *
379 * @param HTML_QuickForm2_Node Element being rendered
380 * @param string Default template to use if not found
381 * @return string Template
382 */
383 public function findTemplate(\HTML_QuickForm2_Node $element, $default = '{element}')
384 {
385 if (!empty($this->templatesForId[$element->getId()])) {
386 return $this->templatesForId[$element->getId()];
387 }
388 $class = \strtolower(\get_class($element));
389 $groupId = \end($this->groupId);
390 $elementClasses = array();
391 do {
392 if (empty($groupId) && !empty($this->templatesForClass[$class])) {
393 return $this->templatesForClass[$class];
394 }
395 $elementClasses[$class] = \true;
396 } while ($class = \strtolower(\get_parent_class($class)));
397 if (!empty($groupId)) {
398 if (!empty($this->elementTemplatesForGroupId[$groupId])) {
399 while (list($elClass) = \each($elementClasses)) {
400 if (!empty($this->elementTemplatesForGroupId[$groupId][$elClass])) {
401 return $this->elementTemplatesForGroupId[$groupId][$elClass];
402 }
403 }
404 }
405 $group = $element->getContainer();
406 $grClass = \strtolower(\get_class($group));
407 do {
408 if (!empty($this->elementTemplatesForGroupClass[$grClass])) {
409 \reset($elementClasses);
410 while (list($elClass) = \each($elementClasses)) {
411 if (!empty($this->elementTemplatesForGroupClass[$grClass][$elClass])) {
412 return $this->elementTemplatesForGroupClass[$grClass][$elClass];
413 }
414 }
415 }
416 } while ($grClass = \strtolower(\get_parent_class($grClass)));
417 }
418 return $default;
419 }
420 /**
421 * Processes the element's template, adding label(s), required note and error message
422 *
423 * @param string Element template
424 * @param HTML_QuickForm2_Node Element being rendered
425 * @return string Template with some substitutions done
426 */
427 public function prepareTemplate($elTpl, \HTML_QuickForm2_Node $element)
428 {
429 // if element is required
430 $elTpl = $this->markRequired($elTpl, $element->isRequired());
431 $elTpl = $this->outputError($elTpl, $element->getError());
432 return $this->outputLabel($elTpl, $element->getLabel());
433 }
434 /**
435 * Marks element required or removes "required" block
436 *
437 * @param string Element template
438 * @param bool Whether element is required
439 * @return string Template with processed "required" block
440 */
441 public function markRequired($elTpl, $required)
442 {
443 if ($required) {
444 $this->hasRequired = \true;
445 $elTpl = \str_replace(array('<qf:required>', '</qf:required>'), array('', ''), $elTpl);
446 } else {
447 $elTpl = \preg_replace('!<qf:required>.*</qf:required>!isU', '', $elTpl);
448 }
449 return $elTpl;
450 }
451 /**
452 * Outputs element error, removes empty error blocks
453 *
454 * @param string Element template
455 * @param string Validation error for the element
456 * @return string Template with error substitutions done
457 */
458 public function outputError($elTpl, $error)
459 {
460 if ($error && !$this->options['group_errors']) {
461 $elTpl = \str_replace(array('<qf:error>', '</qf:error>', '{error}'), array('', '', $error), $elTpl);
462 } else {
463 if ($error && $this->options['group_errors']) {
464 $this->errors[] = $error;
465 }
466 $elTpl = \preg_replace('!<qf:error>.*</qf:error>!isU', '', $elTpl);
467 }
468 return $elTpl;
469 }
470 /**
471 * Outputs element's label(s), removes empty label blocks
472 *
473 * @param string Element template
474 * @param mixed Element label(s)
475 * @return string Template with label substitutions done
476 */
477 public function outputLabel($elTpl, $label)
478 {
479 $mainLabel = \is_array($label) ? \array_shift($label) : $label;
480 $elTpl = \str_replace('{label}', $mainLabel, $elTpl);
481 if (\false !== \strpos($elTpl, '<qf:label>')) {
482 if ($mainLabel) {
483 $elTpl = \str_replace(array('<qf:label>', '</qf:label>'), array('', ''), $elTpl);
484 } else {
485 $elTpl = \preg_replace('!<qf:label>.*</qf:label>!isU', '', $elTpl);
486 }
487 }
488 if (\is_array($label)) {
489 foreach ($label as $key => $text) {
490 $key = \is_int($key) ? $key + 2 : $key;
491 $elTpl = \str_replace(array('<qf:label_' . $key . '>', '</qf:label_' . $key . '>', '{label_' . $key . '}'), array('', '', $text), $elTpl);
492 }
493 }
494 if (\strpos($elTpl, '{label_')) {
495 $elTpl = \preg_replace('!<qf:label_([^>]+)>.*</qf:label_\\1>!isU', '', $elTpl);
496 }
497 return $elTpl;
498 }
499 }
500 }
501