ITDynamic.php 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295
  1. <?php
  2. /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
  3. /**
  4. * A concrete renderer for HTML_QuickForm, using Integrated Templates.
  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. * @copyright 2001-2009 The PHP Group
  18. * @license http://www.php.net/license/3_01.txt PHP License 3.01
  19. * @version CVS: $Id: ITDynamic.php,v 1.7 2009/04/04 21:34:04 avb Exp $
  20. * @link http://pear.php.net/package/HTML_QuickForm
  21. */
  22. /**
  23. * A concrete renderer for HTML_QuickForm, using Integrated Templates.
  24. *
  25. * This is a "dynamic" renderer, which means that concrete form look
  26. * is defined at runtime. This also means that you can define
  27. * <b>one</b> template file for <b>all</b> your forms. That template
  28. * should contain a block for every element 'look' appearing in your
  29. * forms and also some special blocks (consult the examples). If a
  30. * special block is not set for an element, the renderer falls back to
  31. * a default one.
  32. *
  33. * @category HTML
  34. * @package HTML_QuickForm
  35. * @author Alexey Borzov <avb@php.net>
  36. * @version Release: 3.2.11
  37. * @since 3.0
  38. */
  39. class HTML_QuickForm_Renderer_ITDynamic extends HTML_QuickForm_Renderer
  40. {
  41. /**#@+
  42. * @access private
  43. */
  44. /**
  45. * A template class (HTML_Template_ITX or HTML_Template_Sigma) instance
  46. * @var HTML_Template_ITX|HTML_Template_Sigma
  47. */
  48. var $_tpl = null;
  49. /**
  50. * The errors that were not shown near concrete fields go here
  51. * @var array
  52. */
  53. var $_errors = array();
  54. /**
  55. * Show the block with required note?
  56. * @var bool
  57. */
  58. var $_showRequired = false;
  59. /**
  60. * A separator for group elements
  61. * @var mixed
  62. */
  63. var $_groupSeparator = null;
  64. /**
  65. * The current element index inside a group
  66. * @var integer
  67. */
  68. var $_groupElementIdx = 0;
  69. /**
  70. * Blocks to use for different elements
  71. * @var array
  72. */
  73. var $_elementBlocks = array();
  74. /**
  75. * Block to use for headers
  76. * @var string
  77. */
  78. var $_headerBlock = null;
  79. /**#@-*/
  80. /**
  81. * Constructor
  82. *
  83. * @param HTML_Template_ITX|HTML_Template_Sigma Template object to use
  84. */
  85. function HTML_QuickForm_Renderer_ITDynamic(&$tpl)
  86. {
  87. $this->HTML_QuickForm_Renderer();
  88. $this->_tpl =& $tpl;
  89. $this->_tpl->setCurrentBlock('qf_main_loop');
  90. }
  91. function finishForm(&$form)
  92. {
  93. // display errors above form
  94. if (!empty($this->_errors) && $this->_tpl->blockExists('qf_error_loop')) {
  95. foreach ($this->_errors as $error) {
  96. $this->_tpl->setVariable('qf_error', $error);
  97. $this->_tpl->parse('qf_error_loop');
  98. }
  99. }
  100. // show required note
  101. if ($this->_showRequired) {
  102. $this->_tpl->setVariable('qf_required_note', $form->getRequiredNote());
  103. }
  104. // assign form attributes
  105. $this->_tpl->setVariable('qf_attributes', $form->getAttributes(true));
  106. // assign javascript validation rules
  107. $this->_tpl->setVariable('qf_javascript', $form->getValidationScript());
  108. }
  109. function renderHeader(&$header)
  110. {
  111. $blockName = $this->_matchBlock($header);
  112. if ('qf_header' == $blockName && isset($this->_headerBlock)) {
  113. $blockName = $this->_headerBlock;
  114. }
  115. $this->_tpl->setVariable('qf_header', $header->toHtml());
  116. $this->_tpl->parse($blockName);
  117. $this->_tpl->parse('qf_main_loop');
  118. }
  119. function renderElement(&$element, $required, $error)
  120. {
  121. $blockName = $this->_matchBlock($element);
  122. // are we inside a group?
  123. if ('qf_main_loop' != $this->_tpl->currentBlock) {
  124. if (0 != $this->_groupElementIdx && $this->_tpl->placeholderExists('qf_separator', $blockName)) {
  125. if (is_array($this->_groupSeparator)) {
  126. $this->_tpl->setVariable('qf_separator', $this->_groupSeparator[($this->_groupElementIdx - 1) % count($this->_groupSeparator)]);
  127. } else {
  128. $this->_tpl->setVariable('qf_separator', (string)$this->_groupSeparator);
  129. }
  130. }
  131. $this->_groupElementIdx++;
  132. } elseif(!empty($error)) {
  133. // show the error message or keep it for later use
  134. if ($this->_tpl->blockExists($blockName . '_error')) {
  135. $this->_tpl->setVariable('qf_error', $error);
  136. } else {
  137. $this->_errors[] = $error;
  138. }
  139. }
  140. // show an '*' near the required element
  141. if ($required) {
  142. $this->_showRequired = true;
  143. if ($this->_tpl->blockExists($blockName . '_required')) {
  144. $this->_tpl->touchBlock($blockName . '_required');
  145. }
  146. }
  147. // Prepare multiple labels
  148. $labels = $element->getLabel();
  149. if (is_array($labels)) {
  150. $mainLabel = array_shift($labels);
  151. } else {
  152. $mainLabel = $labels;
  153. }
  154. // render the element itself with its main label
  155. $this->_tpl->setVariable('qf_element', $element->toHtml());
  156. if ($this->_tpl->placeholderExists('qf_label', $blockName)) {
  157. $this->_tpl->setVariable('qf_label', $mainLabel);
  158. }
  159. // render extra labels, if any
  160. if (is_array($labels)) {
  161. foreach($labels as $key => $label) {
  162. $key = is_int($key)? $key + 2: $key;
  163. if ($this->_tpl->blockExists($blockName . '_label_' . $key)) {
  164. $this->_tpl->setVariable('qf_label_' . $key, $label);
  165. }
  166. }
  167. }
  168. $this->_tpl->parse($blockName);
  169. $this->_tpl->parseCurrentBlock();
  170. }
  171. function renderHidden(&$element)
  172. {
  173. $this->_tpl->setVariable('qf_hidden', $element->toHtml());
  174. $this->_tpl->parse('qf_hidden_loop');
  175. }
  176. function startGroup(&$group, $required, $error)
  177. {
  178. $blockName = $this->_matchBlock($group);
  179. $this->_tpl->setCurrentBlock($blockName . '_loop');
  180. $this->_groupElementIdx = 0;
  181. $this->_groupSeparator = is_null($group->_separator)? '&nbsp;': $group->_separator;
  182. // show an '*' near the required element
  183. if ($required) {
  184. $this->_showRequired = true;
  185. if ($this->_tpl->blockExists($blockName . '_required')) {
  186. $this->_tpl->touchBlock($blockName . '_required');
  187. }
  188. }
  189. // show the error message or keep it for later use
  190. if (!empty($error)) {
  191. if ($this->_tpl->blockExists($blockName . '_error')) {
  192. $this->_tpl->setVariable('qf_error', $error);
  193. } else {
  194. $this->_errors[] = $error;
  195. }
  196. }
  197. $this->_tpl->setVariable('qf_group_label', $group->getLabel());
  198. }
  199. function finishGroup(&$group)
  200. {
  201. $this->_tpl->parse($this->_matchBlock($group));
  202. $this->_tpl->setCurrentBlock('qf_main_loop');
  203. $this->_tpl->parseCurrentBlock();
  204. }
  205. /**
  206. * Returns the name of a block to use for element rendering
  207. *
  208. * If a name was not explicitly set via setElementBlock(), it tries
  209. * the names '{prefix}_{element type}' and '{prefix}_{element}', where
  210. * prefix is either 'qf' or the name of the current group's block
  211. *
  212. * @param HTML_QuickForm_element form element being rendered
  213. * @access private
  214. * @return string block name
  215. */
  216. function _matchBlock(&$element)
  217. {
  218. $name = $element->getName();
  219. $type = $element->getType();
  220. if (isset($this->_elementBlocks[$name]) && $this->_tpl->blockExists($this->_elementBlocks[$name])) {
  221. if (('group' == $type) || ($this->_elementBlocks[$name] . '_loop' != $this->_tpl->currentBlock)) {
  222. return $this->_elementBlocks[$name];
  223. }
  224. }
  225. if ('group' != $type && 'qf_main_loop' != $this->_tpl->currentBlock) {
  226. $prefix = substr($this->_tpl->currentBlock, 0, -5); // omit '_loop' postfix
  227. } else {
  228. $prefix = 'qf';
  229. }
  230. if ($this->_tpl->blockExists($prefix . '_' . $type)) {
  231. return $prefix . '_' . $type;
  232. } elseif ($this->_tpl->blockExists($prefix . '_' . $name)) {
  233. return $prefix . '_' . $name;
  234. } else {
  235. return $prefix . '_element';
  236. }
  237. }
  238. /**
  239. * Sets the block to use for element rendering
  240. *
  241. * @param mixed element name or array ('element name' => 'block name')
  242. * @param string block name if $elementName is not an array
  243. * @access public
  244. * @return void
  245. */
  246. function setElementBlock($elementName, $blockName = null)
  247. {
  248. if (is_array($elementName)) {
  249. $this->_elementBlocks = array_merge($this->_elementBlocks, $elementName);
  250. } else {
  251. $this->_elementBlocks[$elementName] = $blockName;
  252. }
  253. }
  254. /**
  255. * Sets the name of a block to use for header rendering
  256. *
  257. * @param string block name
  258. * @access public
  259. * @return void
  260. */
  261. function setHeaderBlock($blockName)
  262. {
  263. $this->_headerBlock = $blockName;
  264. }
  265. }
  266. ?>