PageRenderTime 112ms CodeModel.GetById 3ms RepoModel.GetById 0ms app.codeStats 0ms

/system/library/PEAR/HTML/QuickForm2/Renderer/Array.php

https://bitbucket.org/spekkionu/passworddb
PHP | 401 lines | 177 code | 24 blank | 200 comment | 26 complexity | 7fba01ac84c7566a6575fea034a57ccf MD5 | raw file
Possible License(s): BSD-2-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-2012, 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 325717 2012-05-16 13:00:13Z 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 form has some javascript for setup or validation:
  66. * 'javascript' => form javascript (string)
  67. * // if 'group_errors' option is true:
  68. * 'errors' => array(
  69. * '1st element id' => 'Error for the 1st element',
  70. * ...
  71. * 'nth element id' => 'Error for the nth element'
  72. * ),
  73. * 'elements' => array(
  74. * element_1,
  75. * ...
  76. * element_N
  77. * )
  78. * );
  79. * </pre>
  80. * Where element_i is an array of the form
  81. * <pre>
  82. * array(
  83. * 'id' => element id (string),
  84. * 'type' => type of the element (string),
  85. * 'frozen' => whether element is frozen (bool),
  86. * // if element has a label:
  87. * 'label' => 'label for the element',
  88. * // note that if 'static_labels' option is true and element's label is an
  89. * // array then there will be several 'label_*' keys corresponding to
  90. * // labels' array keys
  91. * 'required' => whether element is required (bool),
  92. * // if a validation error is present and 'group_errors' option is false:
  93. * 'error' => error associated with the element (string),
  94. * // if some style was associated with an element:
  95. * 'style' => 'some information about element style (e.g. for Smarty)',
  96. *
  97. * // if element is not a Container
  98. * 'value' => element value (mixed),
  99. * 'html' => HTML for the element (string),
  100. *
  101. * // if element is a Container
  102. * 'attributes' => container attributes (string)
  103. * // if element is a Group
  104. * 'class' => element's 'class' attribute
  105. * // only for groups, if separator is set:
  106. * 'separator' => separator for group elements (array),
  107. * 'elements' => array(
  108. * element_1,
  109. * ...
  110. * element_N
  111. * )
  112. * );
  113. * </pre>
  114. *
  115. * While almost everything in this class is defined as public, its properties
  116. * and those methods that are not published (i.e. not in array returned by
  117. * exportMethods()) will be available to renderer plugins only.
  118. *
  119. * The following methods are published:
  120. * - {@link toArray()}
  121. * - {@link setStyleForId()}
  122. *
  123. * @category HTML
  124. * @package HTML_QuickForm2
  125. * @author Alexey Borzov <avb@php.net>
  126. * @author Bertrand Mansion <golgote@mamasam.com>
  127. * @author Thomas Schulz <ths@4bconsult.de>
  128. * @license http://opensource.org/licenses/bsd-license.php New BSD License
  129. * @version Release: 2.0.0
  130. * @link http://pear.php.net/package/HTML_QuickForm2
  131. */
  132. class HTML_QuickForm2_Renderer_Array extends HTML_QuickForm2_Renderer
  133. {
  134. /**
  135. * An array being generated
  136. * @var array
  137. */
  138. public $array = array();
  139. /**
  140. * Array with references to 'elements' fields of currently processed containers
  141. * @var array
  142. */
  143. public $containers = array();
  144. /**
  145. * Whether the form contains required elements
  146. * @var bool
  147. */
  148. public $hasRequired = false;
  149. /**
  150. * Additional style information for elements
  151. * @var array
  152. */
  153. public $styles = array();
  154. /**
  155. * Constructor, adds a new 'static_labels' option
  156. */
  157. protected function __construct()
  158. {
  159. $this->options['static_labels'] = false;
  160. }
  161. protected function exportMethods()
  162. {
  163. return array(
  164. 'toArray',
  165. 'setStyleForId'
  166. );
  167. }
  168. /**
  169. * Resets the accumulated data
  170. *
  171. * This method is called automatically by startForm() method, but should
  172. * be called manually before calling other rendering methods separately.
  173. *
  174. * @return HTML_QuickForm2_Renderer_Array
  175. */
  176. public function reset()
  177. {
  178. $this->array = array();
  179. $this->containers = array();
  180. $this->hasRequired = false;
  181. return $this;
  182. }
  183. /**
  184. * Returns the resultant array
  185. *
  186. * @return array
  187. */
  188. public function toArray()
  189. {
  190. return $this->array;
  191. }
  192. /**
  193. * Creates an array with fields that are common to all elements
  194. *
  195. * @param HTML_QuickForm2_Node $element Element being rendered
  196. *
  197. * @return array
  198. */
  199. public function buildCommonFields(HTML_QuickForm2_Node $element)
  200. {
  201. $ary = array(
  202. 'id' => $element->getId(),
  203. 'frozen' => $element->toggleFrozen()
  204. );
  205. if ($labels = $element->getLabel()) {
  206. if (!is_array($labels) || !$this->options['static_labels']) {
  207. $ary['label'] = $labels;
  208. } else {
  209. foreach ($labels as $key => $label) {
  210. $key = is_int($key)? $key + 1: $key;
  211. if (1 === $key) {
  212. $ary['label'] = $label;
  213. } else {
  214. $ary['label_' . $key] = $label;
  215. }
  216. }
  217. }
  218. }
  219. if (($error = $element->getError()) && $this->options['group_errors']) {
  220. $this->array['errors'][$ary['id']] = $error;
  221. } elseif ($error) {
  222. $ary['error'] = $error;
  223. }
  224. if (isset($this->styles[$ary['id']])) {
  225. $ary['style'] = $this->styles[$ary['id']];
  226. }
  227. return $ary;
  228. }
  229. /**
  230. * Creates an array with fields that are common to all Containers
  231. *
  232. * @param HTML_QuickForm2_Node $container Container being rendered
  233. *
  234. * @return array
  235. */
  236. public function buildCommonContainerFields(HTML_QuickForm2_Node $container)
  237. {
  238. return $this->buildCommonFields($container) + array(
  239. 'elements' => array(),
  240. 'attributes' => $container->getAttributes(true)
  241. );
  242. }
  243. /**
  244. * Stores an array representing "scalar" element in the form array
  245. *
  246. * @param array $element
  247. */
  248. public function pushScalar(array $element)
  249. {
  250. if (!empty($element['required'])) {
  251. $this->hasRequired = true;
  252. }
  253. if (empty($this->containers)) {
  254. $this->array += $element;
  255. } else {
  256. $this->containers[count($this->containers) - 1][] = $element;
  257. }
  258. }
  259. /**
  260. * Stores an array representing a Container in the form array
  261. *
  262. * @param array $container
  263. */
  264. public function pushContainer(array $container)
  265. {
  266. if (!empty($container['required'])) {
  267. $this->hasRequired = true;
  268. }
  269. if (empty($this->containers)) {
  270. $this->array += $container;
  271. $this->containers = array(&$this->array['elements']);
  272. } else {
  273. $cntIndex = count($this->containers) - 1;
  274. $myIndex = count($this->containers[$cntIndex]);
  275. $this->containers[$cntIndex][$myIndex] = $container;
  276. $this->containers[$cntIndex + 1] =& $this->containers[$cntIndex][$myIndex]['elements'];
  277. }
  278. }
  279. /**
  280. * Sets a style for element rendering
  281. *
  282. * "Style" is some information that is opaque to Array Renderer but may be
  283. * of use to e.g. template engine that receives the resultant array.
  284. *
  285. * @param string|array $idOrStyles Element id or array ('element id' => 'style')
  286. * @param mixed $style Element style if $idOrStyles is not an array
  287. *
  288. * @return HTML_QuickForm2_Renderer_Array
  289. */
  290. public function setStyleForId($idOrStyles, $style = null)
  291. {
  292. if (is_array($idOrStyles)) {
  293. $this->styles = array_merge($this->styles, $idOrStyles);
  294. } else {
  295. $this->styles[$idOrStyles] = $style;
  296. }
  297. return $this;
  298. }
  299. /**#@+
  300. * Implementations of abstract methods from {@link HTML_QuickForm2_Renderer}
  301. */
  302. public function renderElement(HTML_QuickForm2_Node $element)
  303. {
  304. $ary = $this->buildCommonFields($element) + array(
  305. 'html' => $element->__toString(),
  306. 'value' => $element->getValue(),
  307. 'type' => $element->getType(),
  308. 'required' => $element->isRequired(),
  309. );
  310. $this->pushScalar($ary);
  311. }
  312. public function renderHidden(HTML_QuickForm2_Node $element)
  313. {
  314. if ($this->options['group_hiddens']) {
  315. $this->array['hidden'][] = $element->__toString();
  316. } else {
  317. $this->renderElement($element);
  318. }
  319. }
  320. public function startForm(HTML_QuickForm2_Node $form)
  321. {
  322. $this->reset();
  323. $this->array = $this->buildCommonContainerFields($form);
  324. if ($this->options['group_errors']) {
  325. $this->array['errors'] = array();
  326. }
  327. if ($this->options['group_hiddens']) {
  328. $this->array['hidden'] = array();
  329. }
  330. $this->containers = array(&$this->array['elements']);
  331. }
  332. public function finishForm(HTML_QuickForm2_Node $form)
  333. {
  334. $this->finishContainer($form);
  335. if ($this->hasRequired) {
  336. $this->array['required_note'] = $this->options['required_note'];
  337. }
  338. $this->array['javascript'] = $this->getJavascriptBuilder()->getFormJavascript($form->getId());
  339. }
  340. public function startContainer(HTML_QuickForm2_Node $container)
  341. {
  342. $ary = $this->buildCommonContainerFields($container) + array(
  343. 'required' => $container->isRequired(),
  344. 'type' => $container->getType()
  345. );
  346. $this->pushContainer($ary);
  347. }
  348. public function finishContainer(HTML_QuickForm2_Node $container)
  349. {
  350. array_pop($this->containers);
  351. }
  352. public function startGroup(HTML_QuickForm2_Node $group)
  353. {
  354. $ary = $this->buildCommonContainerFields($group) + array(
  355. 'required' => $group->isRequired(),
  356. 'type' => $group->getType(),
  357. 'class' => $group->getAttribute('class')
  358. );
  359. if ($separator = $group->getSeparator()) {
  360. $ary['separator'] = array();
  361. for ($i = 0, $count = count($group); $i < $count - 1; $i++) {
  362. if (!is_array($separator)) {
  363. $ary['separator'][] = (string)$separator;
  364. } else {
  365. $ary['separator'][] = $separator[$i % count($separator)];
  366. }
  367. }
  368. }
  369. $this->pushContainer($ary);
  370. }
  371. public function finishGroup(HTML_QuickForm2_Node $group)
  372. {
  373. $this->finishContainer($group);
  374. }
  375. /**#@-*/
  376. }
  377. ?>