ITStatic.php 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504
  1. <?php
  2. /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
  3. /**
  4. * A static renderer for HTML_QuickForm compatible
  5. * with HTML_Template_IT and HTML_Template_Sigma.
  6. *
  7. * PHP versions 4 and 5
  8. *
  9. * LICENSE: This source file is subject to version 3.01 of the PHP license
  10. * that is available through the world-wide-web at the following URI:
  11. * http://www.php.net/license/3_01.txt If you did not receive a copy of
  12. * the PHP License and are unable to obtain it through the web, please
  13. * send a note to license@php.net so we can mail you a copy immediately.
  14. *
  15. * @category HTML
  16. * @package HTML_QuickForm
  17. * @author Bertrand Mansion <bmansion@mamasam.com>
  18. * @copyright 2001-2009 The PHP Group
  19. * @license http://www.php.net/license/3_01.txt PHP License 3.01
  20. * @version CVS: $Id: ITStatic.php,v 1.9 2009/04/04 21:34:04 avb Exp $
  21. * @link http://pear.php.net/package/HTML_QuickForm
  22. */
  23. /**
  24. * An abstract base class for QuickForm renderers
  25. */
  26. require_once 'HTML/QuickForm/Renderer.php';
  27. /**
  28. * A static renderer for HTML_QuickForm compatible
  29. * with HTML_Template_IT and HTML_Template_Sigma.
  30. *
  31. * As opposed to the dynamic renderer, this renderer needs
  32. * every elements and labels in the form to be specified by
  33. * placeholders at the position you want them to be displayed.
  34. *
  35. * @category HTML
  36. * @package HTML_QuickForm
  37. * @author Bertrand Mansion <bmansion@mamasam.com>
  38. * @version Release: 3.2.11
  39. * @since 3.0
  40. */
  41. class HTML_QuickForm_Renderer_ITStatic extends HTML_QuickForm_Renderer
  42. {
  43. /**#@+
  44. * @access private
  45. */
  46. /**
  47. * An HTML_Template_IT or some other API compatible Template instance
  48. * @var object
  49. */
  50. var $_tpl = null;
  51. /**
  52. * Rendered form name
  53. * @var string
  54. */
  55. var $_formName = 'form';
  56. /**
  57. * The errors that were not shown near concrete fields go here
  58. * @var array
  59. */
  60. var $_errors = array();
  61. /**
  62. * Show the block with required note?
  63. * @var bool
  64. */
  65. var $_showRequired = false;
  66. /**
  67. * Which group are we currently parsing ?
  68. * @var string
  69. */
  70. var $_inGroup;
  71. /**
  72. * Index of the element in its group
  73. * @var int
  74. */
  75. var $_elementIndex = 0;
  76. /**
  77. * If elements have been added with the same name
  78. * @var array
  79. */
  80. var $_duplicateElements = array();
  81. /**
  82. * How to handle the required tag for required fields
  83. * @var string
  84. */
  85. var $_required = '{label}<font size="1" color="red">*</font>';
  86. /**
  87. * How to handle error messages in form validation
  88. * @var string
  89. */
  90. var $_error = '<font color="red">{error}</font><br />{html}';
  91. /**
  92. * Collected HTML for hidden elements, if needed
  93. * @var string
  94. */
  95. var $_hidden = '';
  96. /**#@-*/
  97. /**
  98. * Constructor
  99. *
  100. * @param HTML_Template_IT|HTML_Template_Sigma Template object to use
  101. */
  102. function HTML_QuickForm_Renderer_ITStatic(&$tpl)
  103. {
  104. $this->HTML_QuickForm_Renderer();
  105. $this->_tpl =& $tpl;
  106. } // end constructor
  107. /**
  108. * Called when visiting a form, before processing any form elements
  109. *
  110. * @param HTML_QuickForm form object being visited
  111. * @access public
  112. * @return void
  113. */
  114. function startForm(&$form)
  115. {
  116. $this->_formName = $form->getAttribute('id');
  117. if (count($form->_duplicateIndex) > 0) {
  118. // Take care of duplicate elements
  119. foreach ($form->_duplicateIndex as $elementName => $indexes) {
  120. $this->_duplicateElements[$elementName] = 0;
  121. }
  122. }
  123. } // end func startForm
  124. /**
  125. * Called when visiting a form, after processing all form elements
  126. *
  127. * @param HTML_QuickForm form object being visited
  128. * @access public
  129. * @return void
  130. */
  131. function finishForm(&$form)
  132. {
  133. // display errors above form
  134. if (!empty($this->_errors) && $this->_tpl->blockExists($this->_formName.'_error_loop')) {
  135. foreach ($this->_errors as $error) {
  136. $this->_tpl->setVariable($this->_formName.'_error', $error);
  137. $this->_tpl->parse($this->_formName.'_error_loop');
  138. }
  139. }
  140. // show required note
  141. if ($this->_showRequired) {
  142. $this->_tpl->setVariable($this->_formName.'_required_note', $form->getRequiredNote());
  143. }
  144. // add hidden elements, if collected
  145. if (!empty($this->_hidden)) {
  146. $this->_tpl->setVariable($this->_formName . '_hidden', $this->_hidden);
  147. }
  148. // assign form attributes
  149. $this->_tpl->setVariable($this->_formName.'_attributes', $form->getAttributes(true));
  150. // assign javascript validation rules
  151. $this->_tpl->setVariable($this->_formName.'_javascript', $form->getValidationScript());
  152. } // end func finishForm
  153. /**
  154. * Called when visiting a header element
  155. *
  156. * @param HTML_QuickForm_header header element being visited
  157. * @access public
  158. * @return void
  159. */
  160. function renderHeader(&$header)
  161. {
  162. $name = $header->getName();
  163. $varName = $this->_formName.'_header';
  164. // Find placeHolder
  165. if (!empty($name) && $this->_tpl->placeHolderExists($this->_formName.'_header_'.$name)) {
  166. $varName = $this->_formName.'_header_'.$name;
  167. }
  168. $this->_tpl->setVariable($varName, $header->toHtml());
  169. } // end func renderHeader
  170. /**
  171. * Called when visiting an element
  172. *
  173. * @param HTML_QuickForm_element form element being visited
  174. * @param bool Whether an element is required
  175. * @param string An error message associated with an element
  176. * @access public
  177. * @return void
  178. */
  179. function renderElement(&$element, $required, $error)
  180. {
  181. $name = $element->getName();
  182. // are we inside a group?
  183. if (!empty($this->_inGroup)) {
  184. $varName = $this->_formName.'_'.str_replace(array('[', ']'), '_', $name);
  185. if (substr($varName, -2) == '__') {
  186. // element name is of type : group[]
  187. $varName = $this->_inGroup.'_'.$this->_elementIndex.'_';
  188. $this->_elementIndex++;
  189. }
  190. if ($varName != $this->_inGroup) {
  191. $varName .= '_' == substr($varName, -1)? '': '_';
  192. // element name is of type : group[name]
  193. $label = $element->getLabel();
  194. $html = $element->toHtml();
  195. if ($required && !$element->isFrozen()) {
  196. $this->_renderRequired($label, $html);
  197. $this->_showRequired = true;
  198. }
  199. if (!empty($label)) {
  200. if (is_array($label)) {
  201. foreach ($label as $key => $value) {
  202. $this->_tpl->setVariable($varName.'label_'.$key, $value);
  203. }
  204. } else {
  205. $this->_tpl->setVariable($varName.'label', $label);
  206. }
  207. }
  208. $this->_tpl->setVariable($varName.'html', $html);
  209. }
  210. } else {
  211. $name = str_replace(array('[', ']'), array('_', ''), $name);
  212. if (isset($this->_duplicateElements[$name])) {
  213. // Element is a duplicate
  214. $varName = $this->_formName.'_'.$name.'_'.$this->_duplicateElements[$name];
  215. $this->_duplicateElements[$name]++;
  216. } else {
  217. $varName = $this->_formName.'_'.$name;
  218. }
  219. $label = $element->getLabel();
  220. $html = $element->toHtml();
  221. if ($required) {
  222. $this->_showRequired = true;
  223. $this->_renderRequired($label, $html);
  224. }
  225. if (!empty($error)) {
  226. $this->_renderError($label, $html, $error);
  227. }
  228. if (is_array($label)) {
  229. foreach ($label as $key => $value) {
  230. $this->_tpl->setVariable($varName.'_label_'.$key, $value);
  231. }
  232. } else {
  233. $this->_tpl->setVariable($varName.'_label', $label);
  234. }
  235. $this->_tpl->setVariable($varName.'_html', $html);
  236. }
  237. } // end func renderElement
  238. /**
  239. * Called when visiting a hidden element
  240. *
  241. * @param HTML_QuickForm_element hidden element being visited
  242. * @access public
  243. * @return void
  244. */
  245. function renderHidden(&$element)
  246. {
  247. if ($this->_tpl->placeholderExists($this->_formName . '_hidden')) {
  248. $this->_hidden .= $element->toHtml();
  249. } else {
  250. $name = $element->getName();
  251. $name = str_replace(array('[', ']'), array('_', ''), $name);
  252. $this->_tpl->setVariable($this->_formName.'_'.$name.'_html', $element->toHtml());
  253. }
  254. } // end func renderHidden
  255. /**
  256. * Called when visiting a group, before processing any group elements
  257. *
  258. * @param HTML_QuickForm_group group being visited
  259. * @param bool Whether a group is required
  260. * @param string An error message associated with a group
  261. * @access public
  262. * @return void
  263. */
  264. function startGroup(&$group, $required, $error)
  265. {
  266. $name = $group->getName();
  267. $varName = $this->_formName.'_'.$name;
  268. $this->_elementIndex = 0;
  269. $html = $this->_tpl->placeholderExists($varName.'_html') ? $group->toHtml() : '';
  270. $label = $group->getLabel();
  271. if ($required) {
  272. $this->_renderRequired($label, $html);
  273. }
  274. if (!empty($error)) {
  275. $this->_renderError($label, $html, $error);
  276. }
  277. if (!empty($html)) {
  278. $this->_tpl->setVariable($varName.'_html', $html);
  279. } else {
  280. // Uses error blocks to set the special groups layout error
  281. // <!-- BEGIN form_group_error -->{form_group_error}<!-- END form_group_error -->
  282. if (!empty($error)) {
  283. if ($this->_tpl->placeholderExists($varName.'_error')) {
  284. if ($this->_tpl->blockExists($this->_formName . '_error_block')) {
  285. $this->_tpl->setVariable($this->_formName . '_error', $error);
  286. $error = $this->_getTplBlock($this->_formName . '_error_block');
  287. } elseif (strpos($this->_error, '{html}') !== false || strpos($this->_error, '{label}') !== false) {
  288. $error = str_replace('{error}', $error, $this->_error);
  289. }
  290. }
  291. $this->_tpl->setVariable($varName . '_error', $error);
  292. array_pop($this->_errors);
  293. }
  294. }
  295. if (is_array($label)) {
  296. foreach ($label as $key => $value) {
  297. $this->_tpl->setVariable($varName.'_label_'.$key, $value);
  298. }
  299. } else {
  300. $this->_tpl->setVariable($varName.'_label', $label);
  301. }
  302. $this->_inGroup = $varName;
  303. } // end func startGroup
  304. /**
  305. * Called when visiting a group, after processing all group elements
  306. *
  307. * @param HTML_QuickForm_group group being visited
  308. * @access public
  309. * @return void
  310. */
  311. function finishGroup(&$group)
  312. {
  313. $this->_inGroup = '';
  314. } // end func finishGroup
  315. /**
  316. * Sets the way required elements are rendered
  317. *
  318. * You can use {label} or {html} placeholders to let the renderer know where
  319. * where the element label or the element html are positionned according to the
  320. * required tag. They will be replaced accordingly with the right value.
  321. * For example:
  322. * <font color="red">*</font>{label}
  323. * will put a red star in front of the label if the element is required.
  324. *
  325. * @param string The required element template
  326. * @access public
  327. * @return void
  328. */
  329. function setRequiredTemplate($template)
  330. {
  331. $this->_required = $template;
  332. } // end func setRequiredTemplate
  333. /**
  334. * Sets the way elements with validation errors are rendered
  335. *
  336. * You can use {label} or {html} placeholders to let the renderer know where
  337. * where the element label or the element html are positionned according to the
  338. * error message. They will be replaced accordingly with the right value.
  339. * The error message will replace the {error} place holder.
  340. * For example:
  341. * <font color="red">{error}</font><br />{html}
  342. * will put the error message in red on top of the element html.
  343. *
  344. * If you want all error messages to be output in the main error block, do not specify
  345. * {html} nor {label}.
  346. *
  347. * Groups can have special layouts. With this kind of groups, the renderer will need
  348. * to know where to place the error message. In this case, use error blocks like:
  349. * <!-- BEGIN form_group_error -->{form_group_error}<!-- END form_group_error -->
  350. * where you want the error message to appear in the form.
  351. *
  352. * @param string The element error template
  353. * @access public
  354. * @return void
  355. */
  356. function setErrorTemplate($template)
  357. {
  358. $this->_error = $template;
  359. } // end func setErrorTemplate
  360. /**
  361. * Called when an element is required
  362. *
  363. * This method will add the required tag to the element label and/or the element html
  364. * such as defined with the method setRequiredTemplate
  365. *
  366. * @param string The element label
  367. * @param string The element html rendering
  368. * @see setRequiredTemplate()
  369. * @access private
  370. * @return void
  371. */
  372. function _renderRequired(&$label, &$html)
  373. {
  374. if ($this->_tpl->blockExists($tplBlock = $this->_formName . '_required_block')) {
  375. if (!empty($label) && $this->_tpl->placeholderExists($this->_formName . '_label', $tplBlock)) {
  376. $this->_tpl->setVariable($this->_formName . '_label', is_array($label)? $label[0]: $label);
  377. if (is_array($label)) {
  378. $label[0] = $this->_getTplBlock($tplBlock);
  379. } else {
  380. $label = $this->_getTplBlock($tplBlock);
  381. }
  382. }
  383. if (!empty($html) && $this->_tpl->placeholderExists($this->_formName . '_html', $tplBlock)) {
  384. $this->_tpl->setVariable($this->_formName . '_html', $html);
  385. $html = $this->_getTplBlock($tplBlock);
  386. }
  387. } else {
  388. if (!empty($label) && strpos($this->_required, '{label}') !== false) {
  389. if (is_array($label)) {
  390. $label[0] = str_replace('{label}', $label[0], $this->_required);
  391. } else {
  392. $label = str_replace('{label}', $label, $this->_required);
  393. }
  394. }
  395. if (!empty($html) && strpos($this->_required, '{html}') !== false) {
  396. $html = str_replace('{html}', $html, $this->_required);
  397. }
  398. }
  399. } // end func _renderRequired
  400. /**
  401. * Called when an element has a validation error
  402. *
  403. * This method will add the error message to the element label or the element html
  404. * such as defined with the method setErrorTemplate. If the error placeholder is not found
  405. * in the template, the error will be displayed in the form error block.
  406. *
  407. * @param string The element label
  408. * @param string The element html rendering
  409. * @param string The element error
  410. * @see setErrorTemplate()
  411. * @access private
  412. * @return void
  413. */
  414. function _renderError(&$label, &$html, $error)
  415. {
  416. if ($this->_tpl->blockExists($tplBlock = $this->_formName . '_error_block')) {
  417. $this->_tpl->setVariable($this->_formName . '_error', $error);
  418. if (!empty($label) && $this->_tpl->placeholderExists($this->_formName . '_label', $tplBlock)) {
  419. $this->_tpl->setVariable($this->_formName . '_label', is_array($label)? $label[0]: $label);
  420. if (is_array($label)) {
  421. $label[0] = $this->_getTplBlock($tplBlock);
  422. } else {
  423. $label = $this->_getTplBlock($tplBlock);
  424. }
  425. } elseif (!empty($html) && $this->_tpl->placeholderExists($this->_formName . '_html', $tplBlock)) {
  426. $this->_tpl->setVariable($this->_formName . '_html', $html);
  427. $html = $this->_getTplBlock($tplBlock);
  428. }
  429. // clean up after ourselves
  430. $this->_tpl->setVariable($this->_formName . '_error', null);
  431. } elseif (!empty($label) && strpos($this->_error, '{label}') !== false) {
  432. if (is_array($label)) {
  433. $label[0] = str_replace(array('{label}', '{error}'), array($label[0], $error), $this->_error);
  434. } else {
  435. $label = str_replace(array('{label}', '{error}'), array($label, $error), $this->_error);
  436. }
  437. } elseif (!empty($html) && strpos($this->_error, '{html}') !== false) {
  438. $html = str_replace(array('{html}', '{error}'), array($html, $error), $this->_error);
  439. } else {
  440. $this->_errors[] = $error;
  441. }
  442. }// end func _renderError
  443. /**
  444. * Returns the block's contents
  445. *
  446. * The method is needed because ITX and Sigma implement clearing
  447. * the block contents on get() a bit differently
  448. *
  449. * @param string Block name
  450. * @return string Block contents
  451. */
  452. function _getTplBlock($block)
  453. {
  454. $this->_tpl->parse($block);
  455. if (is_a($this->_tpl, 'html_template_sigma')) {
  456. $ret = $this->_tpl->get($block, true);
  457. } else {
  458. $oldClear = $this->_tpl->clearCache;
  459. $this->_tpl->clearCache = true;
  460. $ret = $this->_tpl->get($block);
  461. $this->_tpl->clearCache = $oldClear;
  462. }
  463. return $ret;
  464. }
  465. } // end class HTML_QuickForm_Renderer_ITStatic
  466. ?>