PageRenderTime 42ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/libs/HTML/QuickForm2/Renderer/Array.php

https://github.com/CodeYellowBV/piwik
PHP | 376 lines | 166 code | 23 blank | 187 comment | 25 complexity | add33fbd588592ec5946b8201686ccc3 MD5 | raw file
Possible License(s): LGPL-3.0, JSON, MIT, GPL-3.0, LGPL-2.1, GPL-2.0, AGPL-1.0, BSD-2-Clause, BSD-3-Clause
  1. <?php
  2. /**
  3. * A renderer for HTML_QuickForm2 building an array of form elements
  4. *
  5. * PHP version 5
  6. *
  7. * LICENSE:
  8. *
  9. * Copyright (c) 2006-2010, Alexey Borzov <avb@php.net>,
  10. * Bertrand Mansion <golgote@mamasam.com>
  11. * All rights reserved.
  12. *
  13. * Redistribution and use in source and binary forms, with or without
  14. * modification, are permitted provided that the following conditions
  15. * are met:
  16. *
  17. * * Redistributions of source code must retain the above copyright
  18. * notice, this list of conditions and the following disclaimer.
  19. * * Redistributions in binary form must reproduce the above copyright
  20. * notice, this list of conditions and the following disclaimer in the
  21. * documentation and/or other materials provided with the distribution.
  22. * * The names of the authors may not be used to endorse or promote products
  23. * derived from this software without specific prior written permission.
  24. *
  25. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
  26. * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
  27. * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  28. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
  29. * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  30. * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  31. * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  32. * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
  33. * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  34. * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  35. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  36. *
  37. * @category HTML
  38. * @package HTML_QuickForm2
  39. * @author Alexey Borzov <avb@php.net>
  40. * @author Bertrand Mansion <golgote@mamasam.com>
  41. * @author Thomas Schulz <ths@4bconsult.de>
  42. * @license http://opensource.org/licenses/bsd-license.php New BSD License
  43. * @version SVN: $Id: Array.php 294052 2010-01-26 20:00:22Z avb $
  44. * @link http://pear.php.net/package/HTML_QuickForm2
  45. */
  46. /**
  47. * Abstract base class for QuickForm2 renderers
  48. */
  49. // require_once 'HTML/QuickForm2/Renderer.php';
  50. /**
  51. * A renderer for HTML_QuickForm2 building an array of form elements
  52. *
  53. * Based on Array renderer from HTML_QuickForm 3.x package
  54. *
  55. * The form array structure is the following:
  56. * <pre>
  57. * array(
  58. * 'id' => form's "id" attribute (string),
  59. * 'frozen' => whether the form is frozen (bool),
  60. * 'attributes' => attributes for &lt;form&gt; tag (string),
  61. * // if form contains required elements:
  62. * 'required_note' => note about the required elements (string),
  63. * // if 'group_hiddens' option is true:
  64. * 'hidden' => array with html of hidden elements (array),
  65. * // if 'group_errors' option is true:
  66. * 'errors' => array(
  67. * '1st element id' => 'Error for the 1st element',
  68. * ...
  69. * 'nth element id' => 'Error for the nth element'
  70. * ),
  71. * 'elements' => array(
  72. * element_1,
  73. * ...
  74. * element_N
  75. * )
  76. * );
  77. * </pre>
  78. * Where element_i is an array of the form
  79. * <pre>
  80. * array(
  81. * 'id' => element id (string),
  82. * 'type' => type of the element (string),
  83. * 'frozen' => whether element is frozen (bool),
  84. * // if element has a label:
  85. * 'label' => 'label for the element',
  86. * // note that if 'static_labels' option is true and element's label is an
  87. * // array then there will be several 'label_*' keys corresponding to
  88. * // labels' array keys
  89. * 'required' => whether element is required (bool),
  90. * // if a validation error is present and 'group_errors' option is false:
  91. * 'error' => error associated with the element (string),
  92. * // if some style was associated with an element:
  93. * 'style' => 'some information about element style (e.g. for Smarty)',
  94. *
  95. * // if element is not a Container
  96. * 'value' => element value (mixed),
  97. * 'html' => HTML for the element (string),
  98. *
  99. * // if element is a Container
  100. * 'attributes' => container attributes (string)
  101. * // only for groups, if separator is set:
  102. * 'separator' => separator for group elements (mixed),
  103. * 'elements' => array(
  104. * element_1,
  105. * ...
  106. * element_N
  107. * )
  108. * );
  109. * </pre>
  110. *
  111. * While almost everything in this class is defined as public, its properties
  112. * and those methods that are not published (i.e. not in array returned by
  113. * exportMethods()) will be available to renderer plugins only.
  114. *
  115. * The following methods are published:
  116. * - {@link reset()}
  117. * - {@link toArray()}
  118. * - {@link setStyleForId()}
  119. *
  120. * @category HTML
  121. * @package HTML_QuickForm2
  122. * @author Alexey Borzov <avb@php.net>
  123. * @author Bertrand Mansion <golgote@mamasam.com>
  124. * @author Thomas Schulz <ths@4bconsult.de>
  125. * @version Release: @package_version@
  126. */
  127. class HTML_QuickForm2_Renderer_Array extends HTML_QuickForm2_Renderer
  128. {
  129. /**
  130. * An array being generated
  131. * @var array
  132. */
  133. public $array = array();
  134. /**
  135. * Array with references to 'elements' fields of currently processed containers
  136. * @var unknown_type
  137. */
  138. public $containers = array();
  139. /**
  140. * Whether the form contains required elements
  141. * @var bool
  142. */
  143. public $hasRequired = false;
  144. /**
  145. * Additional style information for elements
  146. * @var array
  147. */
  148. public $styles = array();
  149. /**
  150. * Constructor, adds a new 'static_labels' option
  151. */
  152. protected function __construct()
  153. {
  154. $this->options['static_labels'] = false;
  155. }
  156. public function exportMethods()
  157. {
  158. return array(
  159. 'reset',
  160. 'toArray',
  161. 'setStyleForId'
  162. );
  163. }
  164. /**
  165. * Resets the accumulated data
  166. *
  167. * This method is called automatically by startForm() method, but should
  168. * be called manually before calling other rendering methods separately.
  169. *
  170. * @return HTML_QuickForm2_Renderer_Array
  171. */
  172. public function reset()
  173. {
  174. $this->array = array();
  175. $this->containers = array();
  176. $this->hasRequired = false;
  177. return $this;
  178. }
  179. /**
  180. * Returns the resultant array
  181. *
  182. * @return array
  183. */
  184. public function toArray()
  185. {
  186. return $this->array;
  187. }
  188. /**
  189. * Creates an array with fields that are common to all elements
  190. *
  191. * @param HTML_QuickForm2_Node Element being rendered
  192. * @return array
  193. */
  194. public function buildCommonFields(HTML_QuickForm2_Node $element)
  195. {
  196. $ary = array(
  197. 'id' => $element->getId(),
  198. 'frozen' => $element->toggleFrozen()
  199. );
  200. if ($labels = $element->getLabel()) {
  201. if (!is_array($labels) || !$this->options['static_labels']) {
  202. $ary['label'] = $labels;
  203. } else {
  204. foreach ($labels as $key => $label) {
  205. $key = is_int($key)? $key + 1: $key;
  206. if (1 === $key) {
  207. $ary['label'] = $label;
  208. } else {
  209. $ary['label_' . $key] = $label;
  210. }
  211. }
  212. }
  213. }
  214. if (($error = $element->getError()) && $this->options['group_errors']) {
  215. $this->array['errors'][$ary['id']] = $error;
  216. } elseif ($error) {
  217. $ary['error'] = $error;
  218. }
  219. if (isset($this->styles[$ary['id']])) {
  220. $ary['style'] = $this->styles[$ary['id']];
  221. }
  222. if (!$element instanceof HTML_QuickForm2_Container) {
  223. $ary['html'] = $element->__toString();
  224. } else {
  225. $ary['elements'] = array();
  226. $ary['attributes'] = $element->getAttributes(true);
  227. }
  228. return $ary;
  229. }
  230. /**
  231. * Stores an array representing "scalar" element in the form array
  232. *
  233. * @param array
  234. */
  235. public function pushScalar(array $element)
  236. {
  237. if (!empty($element['required'])) {
  238. $this->hasRequired = true;
  239. }
  240. if (empty($this->containers)) {
  241. $this->array += $element;
  242. } else {
  243. $this->containers[count($this->containers) - 1][] = $element;
  244. }
  245. }
  246. /**
  247. * Stores an array representing a Container in the form array
  248. *
  249. * @param array
  250. */
  251. public function pushContainer(array $container)
  252. {
  253. if (!empty($container['required'])) {
  254. $this->hasRequired = true;
  255. }
  256. if (empty($this->containers)) {
  257. $this->array += $container;
  258. $this->containers = array(&$this->array['elements']);
  259. } else {
  260. $cntIndex = count($this->containers) - 1;
  261. $myIndex = count($this->containers[$cntIndex]);
  262. $this->containers[$cntIndex][$myIndex] = $container;
  263. $this->containers[$cntIndex + 1] =& $this->containers[$cntIndex][$myIndex]['elements'];
  264. }
  265. }
  266. /**
  267. * Sets a style for element rendering
  268. *
  269. * "Style" is some information that is opaque to Array Renderer but may be
  270. * of use to e.g. template engine that receives the resultant array.
  271. *
  272. * @param string|array Element id or array ('element id' => 'style')
  273. * @param sting Element style if $idOrStyles is not an array
  274. * @return HTML_QuickForm2_Renderer_Array
  275. */
  276. public function setStyleForId($idOrStyles, $style = null)
  277. {
  278. if (is_array($idOrStyles)) {
  279. $this->styles = array_merge($this->styles, $idOrStyles);
  280. } else {
  281. $this->styles[$idOrStyles] = $style;
  282. }
  283. return $this;
  284. }
  285. /**#@+
  286. * Implementations of abstract methods from {@link HTML_QuickForm2_Renderer}
  287. */
  288. public function renderElement(HTML_QuickForm2_Node $element)
  289. {
  290. $ary = $this->buildCommonFields($element) + array(
  291. 'value' => $element->getValue(),
  292. 'type' => $element->getType(),
  293. 'required' => $element->isRequired(),
  294. );
  295. $this->pushScalar($ary);
  296. }
  297. public function renderHidden(HTML_QuickForm2_Node $element)
  298. {
  299. if ($this->options['group_hiddens']) {
  300. $this->array['hidden'][] = $element->__toString();
  301. } else {
  302. $this->renderElement($element);
  303. }
  304. }
  305. public function startForm(HTML_QuickForm2_Node $form)
  306. {
  307. $this->reset();
  308. $this->array = $this->buildCommonFields($form);
  309. if ($this->options['group_errors']) {
  310. $this->array['errors'] = array();
  311. }
  312. if ($this->options['group_hiddens']) {
  313. $this->array['hidden'] = array();
  314. }
  315. $this->containers = array(&$this->array['elements']);
  316. }
  317. public function finishForm(HTML_QuickForm2_Node $form)
  318. {
  319. $this->finishContainer($form);
  320. if ($this->hasRequired) {
  321. $this->array['required_note'] = $this->options['required_note'];
  322. }
  323. }
  324. public function startContainer(HTML_QuickForm2_Node $container)
  325. {
  326. $ary = $this->buildCommonFields($container) + array(
  327. 'required' => $container->isRequired(),
  328. 'type' => $container->getType()
  329. );
  330. $this->pushContainer($ary);
  331. }
  332. public function finishContainer(HTML_QuickForm2_Node $container)
  333. {
  334. array_pop($this->containers);
  335. }
  336. public function startGroup(HTML_QuickForm2_Node $group)
  337. {
  338. $ary = $this->buildCommonFields($group) + array(
  339. 'required' => $group->isRequired(),
  340. 'type' => $group->getType()
  341. );
  342. if ($separator = $group->getSeparator()) {
  343. $ary['separator'] = $separator;
  344. }
  345. $this->pushContainer($ary);
  346. }
  347. public function finishGroup(HTML_QuickForm2_Node $group)
  348. {
  349. $this->finishContainer($group);
  350. }
  351. /**#@-*/
  352. }
  353. ?>