PageRenderTime 46ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/vendor/symfony/lib/widget/sfWidget.class.php

https://github.com/openpne/OpenPNE3
PHP | 411 lines | 150 code | 44 blank | 217 comment | 10 complexity | 616ed221ab31228de9a5e3d0bf36f857 MD5 | raw file
Possible License(s): Apache-2.0, LGPL-2.1
  1. <?php
  2. /*
  3. * This file is part of the symfony package.
  4. * (c) Fabien Potencier <fabien.potencier@symfony-project.com>
  5. *
  6. * For the full copyright and license information, please view the LICENSE
  7. * file that was distributed with this source code.
  8. */
  9. /**
  10. * sfWidget is the base class for all widgets.
  11. *
  12. * @package symfony
  13. * @subpackage widget
  14. * @author Fabien Potencier <fabien.potencier@symfony-project.com>
  15. * @version SVN: $Id$
  16. */
  17. abstract class sfWidget
  18. {
  19. protected
  20. $requiredOptions = array(),
  21. $attributes = array(),
  22. $options = array();
  23. protected static
  24. $xhtml = true,
  25. $charset = 'UTF-8';
  26. /**
  27. * Constructor.
  28. *
  29. * @param array $options An array of options
  30. * @param array $attributes An array of default HTML attributes
  31. *
  32. * @throws InvalidArgumentException when a option is not supported
  33. * @throws RuntimeException when a required option is not given
  34. */
  35. public function __construct($options = array(), $attributes = array())
  36. {
  37. $this->configure($options, $attributes);
  38. $currentOptionKeys = array_keys($this->options);
  39. $optionKeys = array_keys($options);
  40. // check option names
  41. if ($diff = array_diff($optionKeys, array_merge($currentOptionKeys, $this->requiredOptions)))
  42. {
  43. throw new InvalidArgumentException(sprintf('%s does not support the following options: \'%s\'.', get_class($this), implode('\', \'', $diff)));
  44. }
  45. // check required options
  46. if ($diff = array_diff($this->requiredOptions, array_merge($currentOptionKeys, $optionKeys)))
  47. {
  48. throw new RuntimeException(sprintf('%s requires the following options: \'%s\'.', get_class($this), implode('\', \'', $diff)));
  49. }
  50. $this->options = array_merge($this->options, $options);
  51. $this->attributes = array_merge($this->attributes, $attributes);
  52. }
  53. /**
  54. * Configures the current widget.
  55. *
  56. * This method allows each widget to add options or HTML attributes
  57. * during widget creation.
  58. *
  59. * If some options and HTML attributes are given in the sfWidget constructor
  60. * they will take precedence over the options and HTML attributes you configure
  61. * in this method.
  62. *
  63. * @param array $options An array of options
  64. * @param array $attributes An array of HTML attributes
  65. *
  66. * @see __construct()
  67. */
  68. protected function configure($options = array(), $attributes = array())
  69. {
  70. }
  71. /**
  72. * Renders the widget as HTML.
  73. *
  74. * All subclasses must implement this method.
  75. *
  76. * @param string $name The name of the HTML widget
  77. * @param mixed $value The value of the widget
  78. * @param array $attributes An array of HTML attributes
  79. * @param array $errors An array of errors
  80. *
  81. * @return string A HTML representation of the widget
  82. */
  83. abstract public function render($name, $value = null, $attributes = array(), $errors = array());
  84. /**
  85. * Adds a required option.
  86. *
  87. * @param string $name The option name
  88. *
  89. * @return sfWidget The current widget instance
  90. */
  91. public function addRequiredOption($name)
  92. {
  93. $this->requiredOptions[] = $name;
  94. return $this;
  95. }
  96. /**
  97. * Returns all required option names.
  98. *
  99. * @return array An array of required option names
  100. */
  101. public function getRequiredOptions()
  102. {
  103. return $this->requiredOptions;
  104. }
  105. /**
  106. * Adds a new option value with a default value.
  107. *
  108. * @param string $name The option name
  109. * @param mixed $value The default value
  110. *
  111. * @return sfWidget The current widget instance
  112. */
  113. public function addOption($name, $value = null)
  114. {
  115. $this->options[$name] = $value;
  116. return $this;
  117. }
  118. /**
  119. * Changes an option value.
  120. *
  121. * @param string $name The option name
  122. * @param mixed $value The value
  123. *
  124. * @return sfWidget The current widget instance
  125. *
  126. * @throws InvalidArgumentException when a option is not supported
  127. */
  128. public function setOption($name, $value)
  129. {
  130. if (!in_array($name, array_merge(array_keys($this->options), $this->requiredOptions)))
  131. {
  132. throw new InvalidArgumentException(sprintf('%s does not support the following option: \'%s\'.', get_class($this), $name));
  133. }
  134. $this->options[$name] = $value;
  135. return $this;
  136. }
  137. /**
  138. * Gets an option value.
  139. *
  140. * @param string $name The option name
  141. * @param string $default A default value if option does not exists
  142. *
  143. * @return mixed The option value
  144. */
  145. public function getOption($name, $default = null)
  146. {
  147. return isset($this->options[$name]) ? $this->options[$name] : $default;
  148. }
  149. /**
  150. * Returns true if the option exists.
  151. *
  152. * @param string $name The option name
  153. *
  154. * @return bool true if the option exists, false otherwise
  155. */
  156. public function hasOption($name)
  157. {
  158. return array_key_exists($name, $this->options);
  159. }
  160. /**
  161. * Gets all options.
  162. *
  163. * @return array An array of named options
  164. */
  165. public function getOptions()
  166. {
  167. return $this->options;
  168. }
  169. /**
  170. * Sets the options.
  171. *
  172. * @param array $options An array of options
  173. *
  174. * @return sfWidget The current widget instance
  175. */
  176. public function setOptions($options)
  177. {
  178. $this->options = $options;
  179. return $this;
  180. }
  181. /**
  182. * Returns the default HTML attributes.
  183. *
  184. * @param array An array of HTML attributes
  185. */
  186. public function getAttributes()
  187. {
  188. return $this->attributes;
  189. }
  190. /**
  191. * Sets a default HTML attribute.
  192. *
  193. * @param string $name The attribute name
  194. * @param string $value The attribute value
  195. *
  196. * @return sfWidget The current widget instance
  197. */
  198. public function setAttribute($name, $value)
  199. {
  200. $this->attributes[$name] = $value;
  201. return $this;
  202. }
  203. /**
  204. * Returns the HTML attribute value for a given attribute name.
  205. *
  206. * @param string $name The attribute name.
  207. *
  208. * @return string The attribute value, or null if the attribute does not exist
  209. */
  210. public function getAttribute($name)
  211. {
  212. return isset($this->attributes[$name]) ? $this->attributes[$name] : null;
  213. }
  214. /**
  215. * Sets the HTML attributes.
  216. *
  217. * @param array $attributes An array of HTML attributes
  218. *
  219. * @return sfWidget The current widget instance
  220. */
  221. public function setAttributes($attributes)
  222. {
  223. $this->attributes = $attributes;
  224. return $this;
  225. }
  226. /**
  227. * Gets the stylesheet paths associated with the widget.
  228. *
  229. * The array keys are files and values are the media names (separated by a ,):
  230. *
  231. * array('/path/to/file.css' => 'all', '/another/file.css' => 'screen,print')
  232. *
  233. * @return array An array of stylesheet paths
  234. */
  235. public function getStylesheets()
  236. {
  237. return array();
  238. }
  239. /**
  240. * Gets the JavaScript paths associated with the widget.
  241. *
  242. * @return array An array of JavaScript paths
  243. */
  244. public function getJavaScripts()
  245. {
  246. return array();
  247. }
  248. /**
  249. * Sets the charset to use when rendering widgets.
  250. *
  251. * @param string $charset The charset
  252. */
  253. static public function setCharset($charset)
  254. {
  255. self::$charset = $charset;
  256. }
  257. /**
  258. * Returns the charset to use when rendering widgets.
  259. *
  260. * @return string The charset (defaults to UTF-8)
  261. */
  262. static public function getCharset()
  263. {
  264. return self::$charset;
  265. }
  266. /**
  267. * Sets the XHTML generation flag.
  268. *
  269. * @param bool $boolean true if widgets must be generated as XHTML, false otherwise
  270. */
  271. static public function setXhtml($boolean)
  272. {
  273. self::$xhtml = (boolean) $boolean;
  274. }
  275. /**
  276. * Returns whether to generate XHTML tags or not.
  277. *
  278. * @return bool true if widgets must be generated as XHTML, false otherwise
  279. */
  280. static public function isXhtml()
  281. {
  282. return self::$xhtml;
  283. }
  284. /**
  285. * Renders a HTML tag.
  286. *
  287. * @param string $tag The tag name
  288. * @param array $attributes An array of HTML attributes to be merged with the default HTML attributes
  289. *
  290. * @param string An HTML tag string
  291. */
  292. public function renderTag($tag, $attributes = array())
  293. {
  294. if (empty($tag))
  295. {
  296. return '';
  297. }
  298. return sprintf('<%s%s%s', $tag, $this->attributesToHtml($attributes), self::$xhtml ? ' />' : (strtolower($tag) == 'input' ? '>' : sprintf('></%s>', $tag)));
  299. }
  300. /**
  301. * Renders a HTML content tag.
  302. *
  303. * @param string $tag The tag name
  304. * @param string $content The content of the tag
  305. * @param array $attributes An array of HTML attributes to be merged with the default HTML attributes
  306. *
  307. * @param string An HTML tag string
  308. */
  309. public function renderContentTag($tag, $content = null, $attributes = array())
  310. {
  311. if (empty($tag))
  312. {
  313. return '';
  314. }
  315. return sprintf('<%s%s>%s</%s>', $tag, $this->attributesToHtml($attributes), $content, $tag);
  316. }
  317. /**
  318. * Escapes a string.
  319. *
  320. * @param string $value string to escape
  321. * @return string escaped string
  322. */
  323. static public function escapeOnce($value)
  324. {
  325. return self::fixDoubleEscape(htmlspecialchars((string) $value, ENT_QUOTES, self::getCharset()));
  326. }
  327. /**
  328. * Fixes double escaped strings.
  329. *
  330. * @param string $escaped string to fix
  331. * @return string single escaped string
  332. */
  333. static public function fixDoubleEscape($escaped)
  334. {
  335. return preg_replace('/&amp;([a-z]+|(#\d+)|(#x[\da-f]+));/i', '&$1;', $escaped);
  336. }
  337. /**
  338. * Converts an array of attributes to its HTML representation.
  339. *
  340. * @param array $attributes An array of attributes
  341. *
  342. * @return string The HTML representation of the HTML attribute array.
  343. */
  344. public function attributesToHtml($attributes)
  345. {
  346. $attributes = array_merge($this->attributes, $attributes);
  347. foreach ($attributes as $key => &$value)
  348. {
  349. $value = $this->attributesToHtmlCallback($key, $value);
  350. }
  351. return implode('', $attributes);
  352. }
  353. /**
  354. * Prepares an attribute key and value for HTML representation.
  355. *
  356. * It removes empty attributes, except for the value one.
  357. *
  358. * @param string $k The attribute key
  359. * @param string $v The attribute value
  360. *
  361. * @return string The HTML representation of the HTML key attribute pair.
  362. */
  363. protected function attributesToHtmlCallback($k, $v)
  364. {
  365. return false === $v || null === $v || ('' === $v && 'value' != $k) ? '' : sprintf(' %s="%s"', $k, $this->escapeOnce($v));
  366. }
  367. }