/library/Zend/Form/Decorator/HtmlTag.php

https://gitlab.com/devtoannh/cafe · PHP · 257 lines · 130 code · 17 blank · 110 comment · 21 complexity · d153867266c7acbaa0c7231ab3fe5d62 MD5 · raw file

  1. <?php
  2. /**
  3. * Zend Framework
  4. *
  5. * LICENSE
  6. *
  7. * This source file is subject to the new BSD license that is bundled
  8. * with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://framework.zend.com/license/new-bsd
  11. * If you did not receive a copy of the license and are unable to
  12. * obtain it through the world-wide-web, please send an email
  13. * to license@zend.com so we can send you a copy immediately.
  14. *
  15. * @category Zend
  16. * @package Zend_Form
  17. * @subpackage Decorator
  18. * @copyright Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
  19. * @license http://framework.zend.com/license/new-bsd New BSD License
  20. */
  21. /**
  22. * @see Zend_Form_Decorator_Abstract
  23. */
  24. require_once 'Zend/Form/Decorator/Abstract.php';
  25. /**
  26. * Zend_Form_Decorator_Element_HtmlTag
  27. *
  28. * Wraps content in an HTML block tag.
  29. *
  30. * Options accepted are:
  31. * - tag: tag to use in decorator
  32. * - noAttribs: do not render attributes in the opening tag
  33. * - placement: 'append' or 'prepend'. If 'append', renders opening and
  34. * closing tag after content; if prepend, renders opening and closing tag
  35. * before content.
  36. * - openOnly: render opening tag only
  37. * - closeOnly: render closing tag only
  38. *
  39. * Any other options passed are processed as HTML attributes of the tag.
  40. *
  41. * @category Zend
  42. * @package Zend_Form
  43. * @subpackage Decorator
  44. * @copyright Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
  45. * @license http://framework.zend.com/license/new-bsd New BSD License
  46. * @version $Id: HtmlTag.php 24428 2011-09-02 14:10:03Z matthew $
  47. */
  48. class Zend_Form_Decorator_HtmlTag extends Zend_Form_Decorator_Abstract
  49. {
  50. /**
  51. * Character encoding to use when escaping attributes
  52. * @var string
  53. */
  54. protected $_encoding;
  55. /**
  56. * Placement; default to surround content
  57. * @var string
  58. */
  59. protected $_placement = null;
  60. /**
  61. * HTML tag to use
  62. * @var string
  63. */
  64. protected $_tag;
  65. /**
  66. * @var Zend_Filter
  67. */
  68. protected $_tagFilter;
  69. /**
  70. * Convert options to tag attributes
  71. *
  72. * @return string
  73. */
  74. protected function _htmlAttribs(array $attribs)
  75. {
  76. $xhtml = '';
  77. $enc = $this->_getEncoding();
  78. foreach ((array) $attribs as $key => $val) {
  79. $key = htmlspecialchars($key, ENT_COMPAT, $enc);
  80. if (is_array($val)) {
  81. if (array_key_exists('callback', $val)
  82. && is_callable($val['callback'])
  83. ) {
  84. $val = call_user_func($val['callback'], $this);
  85. } else {
  86. $val = implode(' ', $val);
  87. }
  88. }
  89. $val = htmlspecialchars($val, ENT_COMPAT, $enc);
  90. $xhtml .= " $key=\"$val\"";
  91. }
  92. return $xhtml;
  93. }
  94. /**
  95. * Normalize tag
  96. *
  97. * Ensures tag is alphanumeric characters only, and all lowercase.
  98. *
  99. * @param string $tag
  100. * @return string
  101. */
  102. public function normalizeTag($tag)
  103. {
  104. if (!isset($this->_tagFilter)) {
  105. require_once 'Zend/Filter.php';
  106. require_once 'Zend/Filter/Alnum.php';
  107. require_once 'Zend/Filter/StringToLower.php';
  108. $this->_tagFilter = new Zend_Filter();
  109. $this->_tagFilter->addFilter(new Zend_Filter_Alnum())
  110. ->addFilter(new Zend_Filter_StringToLower());
  111. }
  112. return $this->_tagFilter->filter($tag);
  113. }
  114. /**
  115. * Set tag to use
  116. *
  117. * @param string $tag
  118. * @return Zend_Form_Decorator_HtmlTag
  119. */
  120. public function setTag($tag)
  121. {
  122. $this->_tag = $this->normalizeTag($tag);
  123. return $this;
  124. }
  125. /**
  126. * Get tag
  127. *
  128. * If no tag is registered, either via setTag() or as an option, uses 'div'.
  129. *
  130. * @return string
  131. */
  132. public function getTag()
  133. {
  134. if (null === $this->_tag) {
  135. if (null === ($tag = $this->getOption('tag'))) {
  136. $this->setTag('div');
  137. } else {
  138. $this->setTag($tag);
  139. $this->removeOption('tag');
  140. }
  141. }
  142. return $this->_tag;
  143. }
  144. /**
  145. * Get the formatted open tag
  146. *
  147. * @param string $tag
  148. * @param array $attribs
  149. * @return string
  150. */
  151. protected function _getOpenTag($tag, array $attribs = null)
  152. {
  153. $html = '<' . $tag;
  154. if (null !== $attribs) {
  155. $html .= $this->_htmlAttribs($attribs);
  156. }
  157. $html .= '>';
  158. return $html;
  159. }
  160. /**
  161. * Get formatted closing tag
  162. *
  163. * @param string $tag
  164. * @return string
  165. */
  166. protected function _getCloseTag($tag)
  167. {
  168. return '</' . $tag . '>';
  169. }
  170. /**
  171. * Render content wrapped in an HTML tag
  172. *
  173. * @param string $content
  174. * @return string
  175. */
  176. public function render($content)
  177. {
  178. $tag = $this->getTag();
  179. $placement = $this->getPlacement();
  180. $noAttribs = $this->getOption('noAttribs');
  181. $openOnly = $this->getOption('openOnly');
  182. $closeOnly = $this->getOption('closeOnly');
  183. $this->removeOption('noAttribs');
  184. $this->removeOption('openOnly');
  185. $this->removeOption('closeOnly');
  186. $attribs = null;
  187. if (!$noAttribs) {
  188. $attribs = $this->getOptions();
  189. }
  190. switch ($placement) {
  191. case self::APPEND:
  192. if ($closeOnly) {
  193. return $content . $this->_getCloseTag($tag);
  194. }
  195. if ($openOnly) {
  196. return $content . $this->_getOpenTag($tag, $attribs);
  197. }
  198. return $content
  199. . $this->_getOpenTag($tag, $attribs)
  200. . $this->_getCloseTag($tag);
  201. case self::PREPEND:
  202. if ($closeOnly) {
  203. return $this->_getCloseTag($tag) . $content;
  204. }
  205. if ($openOnly) {
  206. return $this->_getOpenTag($tag, $attribs) . $content;
  207. }
  208. return $this->_getOpenTag($tag, $attribs)
  209. . $this->_getCloseTag($tag)
  210. . $content;
  211. default:
  212. return (($openOnly || !$closeOnly) ? $this->_getOpenTag($tag, $attribs) : '')
  213. . $content
  214. . (($closeOnly || !$openOnly) ? $this->_getCloseTag($tag) : '');
  215. }
  216. }
  217. /**
  218. * Get encoding for use with htmlspecialchars()
  219. *
  220. * @return string
  221. */
  222. protected function _getEncoding()
  223. {
  224. if (null !== $this->_encoding) {
  225. return $this->_encoding;
  226. }
  227. if (null === ($element = $this->getElement())) {
  228. $this->_encoding = 'UTF-8';
  229. } elseif (null === ($view = $element->getView())) {
  230. $this->_encoding = 'UTF-8';
  231. } elseif (!$view instanceof Zend_View_Abstract
  232. && !method_exists($view, 'getEncoding')
  233. ) {
  234. $this->_encoding = 'UTF-8';
  235. } else {
  236. $this->_encoding = $view->getEncoding();
  237. }
  238. return $this->_encoding;
  239. }
  240. }