ITDynamic.php 9.5 KB

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