Default.php 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493
  1. <?php
  2. /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
  3. /**
  4. * A concrete renderer for HTML_QuickForm, based on QuickForm 2.x built-in one
  5. *
  6. * PHP versions 4 and 5
  7. *
  8. * LICENSE: This source file is subject to version 3.01 of the PHP license
  9. * that is available through the world-wide-web at the following URI:
  10. * http://www.php.net/license/3_01.txt If you did not receive a copy of
  11. * the PHP License and are unable to obtain it through the web, please
  12. * send a note to license@php.net so we can mail you a copy immediately.
  13. *
  14. * @category HTML
  15. * @package HTML_QuickForm
  16. * @author Alexey Borzov <avb@php.net>
  17. * @author Adam Daniel <adaniel1@eesus.jnj.com>
  18. * @author Bertrand Mansion <bmansion@mamasam.com>
  19. * @copyright 2001-2009 The PHP Group
  20. * @license http://www.php.net/license/3_01.txt PHP License 3.01
  21. * @version CVS: $Id$
  22. * @link http://pear.php.net/package/HTML_QuickForm
  23. */
  24. /**
  25. * An abstract base class for QuickForm renderers
  26. */
  27. require_once 'HTML/QuickForm/Renderer.php';
  28. /**
  29. * A concrete renderer for HTML_QuickForm, based on QuickForm 2.x built-in one
  30. *
  31. * @category HTML
  32. * @package HTML_QuickForm
  33. * @author Alexey Borzov <avb@php.net>
  34. * @author Adam Daniel <adaniel1@eesus.jnj.com>
  35. * @author Bertrand Mansion <bmansion@mamasam.com>
  36. * @version Release: 3.2.11
  37. * @since 3.0
  38. */
  39. class HTML_QuickForm_Renderer_Default extends HTML_QuickForm_Renderer
  40. {
  41. /**
  42. * The HTML of the form
  43. * @var string
  44. * @access private
  45. */
  46. var $_html;
  47. /**
  48. * Header Template string
  49. * @var string
  50. * @access private
  51. */
  52. var $_headerTemplate =
  53. "\n\t<tr>\n\t\t<td style=\"white-space: nowrap; background-color: #CCCCCC;\" align=\"left\" valign=\"top\" colspan=\"2\"><b>{header}</b></td>\n\t</tr>";
  54. /**
  55. * Element template string
  56. * @var string
  57. * @access private
  58. */
  59. var $_elementTemplate =
  60. "\n\t<tr>\n\t\t<td align=\"right\" valign=\"top\"><!-- BEGIN required --><span style=\"color: #ff0000\">*</span><!-- END required --><b>{label}</b></td>\n\t\t<td valign=\"top\" align=\"left\"><!-- BEGIN error --><span style=\"color: #ff0000\">{error}</span><br /><!-- END error -->\t{element}</td>\n\t</tr>";
  61. /**
  62. * Form template string
  63. * @var string
  64. * @access private
  65. */
  66. var $_formTemplate =
  67. "\n<form{attributes}>\n<div>\n{hidden}<table border=\"0\">\n{content}\n</table>\n</div>\n</form>";
  68. /**
  69. * Required Note template string
  70. * @var string
  71. * @access private
  72. */
  73. var $_requiredNoteTemplate =
  74. "\n\t<tr>\n\t\t<td></td>\n\t<td align=\"left\" valign=\"top\">{requiredNote}</td>\n\t</tr>";
  75. /**
  76. * Array containing the templates for customised elements
  77. * @var array
  78. * @access private
  79. */
  80. var $_templates = array();
  81. /**
  82. * Array containing the templates for group wraps.
  83. *
  84. * These templates are wrapped around group elements and groups' own
  85. * templates wrap around them. This is set by setGroupTemplate().
  86. *
  87. * @var array
  88. * @access private
  89. */
  90. var $_groupWraps = array();
  91. /**
  92. * Array containing the templates for elements within groups
  93. * @var array
  94. * @access private
  95. */
  96. var $_groupTemplates = array();
  97. /**
  98. * True if we are inside a group
  99. * @var bool
  100. * @access private
  101. */
  102. var $_inGroup = false;
  103. /**
  104. * Array with HTML generated for group elements
  105. * @var array
  106. * @access private
  107. */
  108. var $_groupElements = array();
  109. /**
  110. * Template for an element inside a group
  111. * @var string
  112. * @access private
  113. */
  114. var $_groupElementTemplate = '';
  115. /**
  116. * HTML that wraps around the group elements
  117. * @var string
  118. * @access private
  119. */
  120. var $_groupWrap = '';
  121. /**
  122. * HTML for the current group
  123. * @var string
  124. * @access private
  125. */
  126. var $_groupTemplate = '';
  127. /**
  128. * Collected HTML of the hidden fields
  129. * @var string
  130. * @access private
  131. */
  132. var $_hiddenHtml = '';
  133. /**
  134. * Constructor
  135. *
  136. * @access public
  137. */
  138. function HTML_QuickForm_Renderer_Default()
  139. {
  140. parent::__construct();
  141. } // end constructor
  142. /**
  143. * returns the HTML generated for the form
  144. *
  145. * @access public
  146. * @return string
  147. */
  148. function toHtml()
  149. {
  150. // _hiddenHtml is cleared in finishForm(), so this only matters when
  151. // finishForm() was not called (e.g. group::toHtml(), bug #3511)
  152. return $this->_hiddenHtml . $this->_html;
  153. } // end func toHtml
  154. /**
  155. * Called when visiting a form, before processing any form elements
  156. *
  157. * @param HTML_QuickForm form object being visited
  158. * @access public
  159. * @return void
  160. */
  161. function startForm(&$form)
  162. {
  163. $this->_html = '';
  164. $this->_hiddenHtml = '';
  165. } // end func startForm
  166. /**
  167. * Called when visiting a form, after processing all form elements
  168. * Adds required note, form attributes, validation javascript and form content.
  169. *
  170. * @param HTML_QuickForm form object being visited
  171. * @access public
  172. * @return void
  173. */
  174. function finishForm(&$form)
  175. {
  176. // add a required note, if one is needed
  177. if (!empty($form->_required) && !$form->_freezeAll) {
  178. $this->_html .= str_replace('{requiredNote}', $form->getRequiredNote(), $this->_requiredNoteTemplate);
  179. }
  180. // add form attributes and content
  181. $html = str_replace('{attributes}', $form->getAttributes(true), $this->_formTemplate);
  182. if (strpos($this->_formTemplate, '{hidden}')) {
  183. $html = str_replace('{hidden}', $this->_hiddenHtml, $html);
  184. } else {
  185. $this->_html .= $this->_hiddenHtml;
  186. }
  187. $this->_hiddenHtml = '';
  188. $this->_html = str_replace('{content}', $this->_html, $html);
  189. // add a validation script
  190. if ('' != ($script = $form->getValidationScript())) {
  191. $this->_html = $script . "\n" . $this->_html;
  192. }
  193. } // end func finishForm
  194. /**
  195. * Called when visiting a header element
  196. *
  197. * @param HTML_QuickForm_header header element being visited
  198. * @access public
  199. * @return void
  200. */
  201. function renderHeader(&$header)
  202. {
  203. $name = $header->getName();
  204. if (!empty($name) && isset($this->_templates[$name])) {
  205. $this->_html .= str_replace('{header}', $header->toHtml(), $this->_templates[$name]);
  206. } else {
  207. $this->_html .= str_replace('{header}', $header->toHtml(), $this->_headerTemplate);
  208. }
  209. } // end func renderHeader
  210. /**
  211. * Helper method for renderElement
  212. *
  213. * @param string Element name
  214. * @param mixed Element label (if using an array of labels, you should set the appropriate template)
  215. * @param bool Whether an element is required
  216. * @param string Error message associated with the element
  217. * @param string Label for ID
  218. * @access private
  219. * @see renderElement()
  220. * @return string Html for element
  221. */
  222. function _prepareTemplate($name, $label, $required, $error, $labelForId = '')
  223. {
  224. if (is_array($label)) {
  225. $nameLabel = array_shift($label);
  226. } else {
  227. $nameLabel = $label;
  228. }
  229. if (!empty($labelForId)) {
  230. $labelFor = 'for="' . $labelForId . '"';
  231. } else {
  232. $labelFor = '';
  233. }
  234. if (isset($this->_templates[$name])) {
  235. $html = str_replace('{label}', $nameLabel, $this->_templates[$name]);
  236. $html = str_replace('{label-for}', $labelFor, $html);
  237. } else {
  238. $html = str_replace('{label}', $nameLabel, $this->_elementTemplate);
  239. $html = str_replace('{label-for}', $labelFor, $html);
  240. }
  241. if ($required) {
  242. $html = str_replace('<!-- BEGIN required -->', '', $html);
  243. $html = str_replace('<!-- END required -->', '', $html);
  244. } else {
  245. $html = preg_replace("/([ \t\n\r]*)?<!-- BEGIN required -->.*<!-- END required -->([ \t\n\r]*)?/isU", '', $html);
  246. }
  247. if (isset($error)) {
  248. $html = str_replace('{error}', $error, $html);
  249. $html = str_replace('{error_class}', 'error', $html);
  250. $html = str_replace('<!-- BEGIN error -->', '', $html);
  251. $html = str_replace('<!-- END error -->', '', $html);
  252. } else {
  253. $html = str_replace('{error_class}', '', $html);
  254. $html = preg_replace("/([ \t\n\r]*)?<!-- BEGIN error -->.*<!-- END error -->([ \t\n\r]*)?/isU", '', $html);
  255. }
  256. if (is_array($label)) {
  257. foreach($label as $key => $text) {
  258. $key = is_int($key)? $key + 2: $key;
  259. $html = str_replace("{label_{$key}}", $text, $html);
  260. $html = str_replace("<!-- BEGIN label_{$key} -->", '', $html);
  261. $html = str_replace("<!-- END label_{$key} -->", '', $html);
  262. }
  263. }
  264. if (strpos($html, '{label_')) {
  265. $html = preg_replace('/\s*<!-- BEGIN label_(\S+) -->.*<!-- END label_\1 -->\s*/is', '', $html);
  266. }
  267. return $html;
  268. } // end func _prepareTemplate
  269. /**
  270. * Renders an element Html
  271. * Called when visiting an element
  272. *
  273. * @param HTML_QuickForm_element form element being visited
  274. * @param bool Whether an element is required
  275. * @param string An error message associated with an element
  276. * @access public
  277. * @return void
  278. */
  279. function renderElement(&$element, $required, $error) {
  280. if (!$this->_inGroup) {
  281. $html = $this->_prepareTemplate($element->getName(), $element->getLabel(), $required, $error, $element->getLabelFor());
  282. $this->_html .= str_replace('{element}', $element->toHtml(), $html);
  283. } elseif (!empty($this->_groupElementTemplate)) {
  284. $html = str_replace('{label}', $element->getLabel(), $this->_groupElementTemplate);
  285. $html = str_replace('{label-for}', $element->getLabelFor(), $this->_groupElementTemplate);
  286. if ($required) {
  287. $html = str_replace('<!-- BEGIN required -->', '', $html);
  288. $html = str_replace('<!-- END required -->', '', $html);
  289. } else {
  290. $html = preg_replace("/([ \t\n\r]*)?<!-- BEGIN required -->.*<!-- END required -->([ \t\n\r]*)?/isU", '', $html);
  291. }
  292. $this->_groupElements[] = str_replace('{element}', $element->toHtml(), $html);
  293. } else {
  294. $this->_groupElements[] = $element->toHtml();
  295. }
  296. } // end func renderElement
  297. /**
  298. * Renders an hidden element
  299. * Called when visiting a hidden element
  300. *
  301. * @param HTML_QuickForm_element form element being visited
  302. * @access public
  303. * @return void
  304. */
  305. function renderHidden(&$element)
  306. {
  307. $this->_hiddenHtml .= $element->toHtml() . "\n";
  308. } // end func renderHidden
  309. /**
  310. * Called when visiting a raw HTML/text pseudo-element
  311. *
  312. * @param HTML_QuickForm_html element being visited
  313. * @access public
  314. * @return void
  315. */
  316. function renderHtml(&$data)
  317. {
  318. $this->_html .= $data->toHtml();
  319. } // end func renderHtml
  320. /**
  321. * Called when visiting a group, before processing any group elements
  322. *
  323. * @param HTML_QuickForm_group group being visited
  324. * @param bool Whether a group is required
  325. * @param string An error message associated with a group
  326. * @access public
  327. * @return void
  328. */
  329. function startGroup(&$group, $required, $error)
  330. {
  331. $name = $group->getName();
  332. $this->_groupTemplate = $this->_prepareTemplate($name, $group->getLabel(), $required, $error);
  333. $this->_groupElementTemplate = empty($this->_groupTemplates[$name])? '': $this->_groupTemplates[$name];
  334. $this->_groupWrap = empty($this->_groupWraps[$name])? '': $this->_groupWraps[$name];
  335. $this->_groupElements = array();
  336. $this->_inGroup = true;
  337. } // end func startGroup
  338. /**
  339. * Called when visiting a group, after processing all group elements
  340. *
  341. * @param HTML_QuickForm_group group being visited
  342. * @access public
  343. * @return void
  344. */
  345. function finishGroup(&$group)
  346. {
  347. $separator = $group->_separator;
  348. if (is_array($separator)) {
  349. $count = count($separator);
  350. $html = '';
  351. for ($i = 0; $i < count($this->_groupElements); $i++) {
  352. $html .= (0 == $i? '': $separator[($i - 1) % $count]) . $this->_groupElements[$i];
  353. }
  354. } else {
  355. if (is_null($separator)) {
  356. $separator = '&nbsp;';
  357. }
  358. $html = implode((string)$separator, $this->_groupElements);
  359. }
  360. if (!empty($this->_groupWrap)) {
  361. $html = str_replace('{content}', $html, $this->_groupWrap);
  362. }
  363. $this->_html .= str_replace('{element}', $html, $this->_groupTemplate);
  364. $this->_inGroup = false;
  365. } // end func finishGroup
  366. /**
  367. * Sets element template
  368. *
  369. * @param string The HTML surrounding an element
  370. * @param string (optional) Name of the element to apply template for
  371. * @access public
  372. * @return void
  373. */
  374. function setElementTemplate($html, $element = null)
  375. {
  376. if (is_null($element)) {
  377. $this->_elementTemplate = $html;
  378. } else {
  379. $this->_templates[$element] = $html;
  380. }
  381. } // end func setElementTemplate
  382. /**
  383. * Sets template for a group wrapper
  384. *
  385. * This template is contained within a group-as-element template
  386. * set via setTemplate() and contains group's element templates, set
  387. * via setGroupElementTemplate()
  388. *
  389. * @param string The HTML surrounding group elements
  390. * @param string Name of the group to apply template for
  391. * @access public
  392. * @return void
  393. */
  394. function setGroupTemplate($html, $group)
  395. {
  396. $this->_groupWraps[$group] = $html;
  397. } // end func setGroupTemplate
  398. /**
  399. * Sets element template for elements within a group
  400. *
  401. * @param string The HTML surrounding an element
  402. * @param string Name of the group to apply template for
  403. * @access public
  404. * @return void
  405. */
  406. function setGroupElementTemplate($html, $group)
  407. {
  408. $this->_groupTemplates[$group] = $html;
  409. } // end func setGroupElementTemplate
  410. /**
  411. * Sets header template
  412. *
  413. * @param string The HTML surrounding the header
  414. * @access public
  415. * @return void
  416. */
  417. function setHeaderTemplate($html)
  418. {
  419. $this->_headerTemplate = $html;
  420. } // end func setHeaderTemplate
  421. /**
  422. * Sets form template
  423. *
  424. * @param string The HTML surrounding the form tags
  425. * @access public
  426. * @return void
  427. */
  428. function setFormTemplate($html) {
  429. $this->_formTemplate = $html;
  430. } // end func setFormTemplate
  431. /**
  432. * Sets the note indicating required fields template
  433. *
  434. * @param string The HTML surrounding the required note
  435. * @access public
  436. * @return void
  437. */
  438. function setRequiredNoteTemplate($html)
  439. {
  440. $this->_requiredNoteTemplate = $html;
  441. } // end func setRequiredNoteTemplate
  442. /**
  443. * Clears all the HTML out of the templates that surround notes, elements, etc.
  444. * Useful when you want to use addData() to create a completely custom form look
  445. *
  446. * @access public
  447. * @return void
  448. */
  449. function clearAllTemplates()
  450. {
  451. $this->setElementTemplate('{element}');
  452. $this->setFormTemplate("\n\t<form{attributes}>{content}\n\t</form>\n");
  453. $this->setRequiredNoteTemplate('');
  454. $this->_templates = array();
  455. } // end func clearAllTemplates
  456. } // end class HTML_QuickForm_Renderer_Default