PageRenderTime 49ms CodeModel.GetById 26ms RepoModel.GetById 0ms app.codeStats 0ms

/Widget/SchemaFormatter.php

https://github.com/rande/sfFormBundle
PHP | 350 lines | 225 code | 53 blank | 72 comment | 23 complexity | 4ec9ce046b19d4d5d10d84369c7f3148 MD5 | raw file
Possible License(s): ISC
  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. namespace Bundle\sfFormBundle\Widget;
  10. use Bundle\sfFormBundle\Tool\Callable;
  11. /**
  12. * sfWidgetFormSchemaFormatter allows to format a form schema with HTML formats.
  13. *
  14. * @package symfony
  15. * @subpackage widget
  16. * @author Fabien Potencier <fabien.potencier@symfony-project.com>
  17. * @version SVN: $Id: sfWidgetFormSchemaFormatter.class.php 21908 2009-09-11 12:06:21Z fabien $
  18. */
  19. abstract class SchemaFormatter
  20. {
  21. protected static
  22. $translationCallable = null;
  23. protected
  24. $rowFormat = '',
  25. $helpFormat = '%help%',
  26. $errorRowFormat = '%errors%',
  27. $errorListFormatInARow = " <ul class=\"error_list\">\n%errors% </ul>\n",
  28. $errorRowFormatInARow = " <li>%error%</li>\n",
  29. $namedErrorRowFormatInARow = " <li>%name%: %error%</li>\n",
  30. $decoratorFormat = '',
  31. $widgetSchema = null,
  32. $translationCatalogue = null;
  33. /**
  34. * Constructor
  35. *
  36. * @param sfWidgetFormSchema $widgetSchema
  37. */
  38. public function __construct(Schema $widgetSchema)
  39. {
  40. $this->setWidgetSchema($widgetSchema);
  41. }
  42. public function formatRow($label, $field, $errors = array(), $help = '', $hiddenFields = null)
  43. {
  44. return strtr($this->getRowFormat(), array(
  45. '%label%' => $label,
  46. '%field%' => $field,
  47. '%error%' => $this->formatErrorsForRow($errors),
  48. '%help%' => $this->formatHelp($help),
  49. '%hidden_fields%' => null === $hiddenFields ? '%hidden_fields%' : $hiddenFields,
  50. ));
  51. }
  52. /**
  53. * Translates a string using an i18n callable, if it has been provided
  54. *
  55. * @param mixed $subject The subject to translate
  56. * @param array $parameters Additional parameters to pass back to the callable
  57. * @return string
  58. */
  59. public function translate($subject, $parameters = array())
  60. {
  61. if (false === $subject)
  62. {
  63. return false;
  64. }
  65. if (null === self::$translationCallable)
  66. {
  67. // replace object with strings
  68. foreach ($parameters as $key => $value)
  69. {
  70. if (is_object($value) && method_exists($value, '__toString'))
  71. {
  72. $parameters[$key] = $value->__toString();
  73. }
  74. }
  75. return strtr($subject, $parameters);
  76. }
  77. $catalogue = $this->getTranslationCatalogue();
  78. if (self::$translationCallable instanceof Callable)
  79. {
  80. return self::$translationCallable->call($subject, $parameters, $catalogue);
  81. }
  82. return call_user_func(self::$translationCallable, $subject, $parameters, $catalogue);
  83. }
  84. /**
  85. * Returns the current i18n callable
  86. *
  87. * @return mixed
  88. */
  89. static public function getTranslationCallable()
  90. {
  91. return self::$translationCallable;
  92. }
  93. /**
  94. * Sets a callable which aims to translate form labels, errors and help messages
  95. *
  96. * @param mixed $callable
  97. *
  98. * @throws \InvalidArgumentException if an invalid php callable or Callable has been provided
  99. */
  100. static public function setTranslationCallable($callable)
  101. {
  102. if (!$callable instanceof Callable && !is_callable($callable))
  103. {
  104. throw new \InvalidArgumentException('Provided i18n callable should be either an instance of Callable or a valid PHP callable');
  105. }
  106. self::$translationCallable = $callable;
  107. }
  108. public function formatHelp($help)
  109. {
  110. if (!$help)
  111. {
  112. return '';
  113. }
  114. return strtr($this->getHelpFormat(), array('%help%' => $this->translate($help)));
  115. }
  116. public function formatErrorRow($errors)
  117. {
  118. if (null === $errors || !$errors)
  119. {
  120. return '';
  121. }
  122. return strtr($this->getErrorRowFormat(), array('%errors%' => $this->formatErrorsForRow($errors)));
  123. }
  124. public function formatErrorsForRow($errors)
  125. {
  126. if (null === $errors || !$errors)
  127. {
  128. return '';
  129. }
  130. if (!is_array($errors))
  131. {
  132. $errors = array($errors);
  133. }
  134. return strtr($this->getErrorListFormatInARow(), array('%errors%' => implode('', $this->unnestErrors($errors))));
  135. }
  136. /**
  137. * Generates a label for the given field name.
  138. *
  139. * @param string $name The field name
  140. * @param array $attributes Optional html attributes for the label tag
  141. *
  142. * @return string The label tag
  143. */
  144. public function generateLabel($name, $attributes = array())
  145. {
  146. $labelName = $this->generateLabelName($name);
  147. if (false === $labelName)
  148. {
  149. return '';
  150. }
  151. if (!isset($attributes['for']))
  152. {
  153. $attributes['for'] = $this->widgetSchema->generateId($this->widgetSchema->generateName($name));
  154. }
  155. return $this->widgetSchema->renderContentTag('label', $labelName, $attributes);
  156. }
  157. /**
  158. * Generates the label name for the given field name.
  159. *
  160. * @param string $name The field name
  161. *
  162. * @return string The label name
  163. */
  164. public function generateLabelName($name)
  165. {
  166. $label = $this->widgetSchema->getLabel($name);
  167. if (!$label && false !== $label)
  168. {
  169. $label = str_replace('_', ' ', ucfirst('_id' == substr($name, -3) ? substr($name, 0, -3) : $name));
  170. }
  171. return $this->translate($label);
  172. }
  173. /**
  174. * Get i18n catalogue name
  175. *
  176. * @return string
  177. */
  178. public function getTranslationCatalogue()
  179. {
  180. return $this->translationCatalogue;
  181. }
  182. /**
  183. * Set an i18n catalogue name
  184. *
  185. * @param string $catalogue
  186. *
  187. * @throws \InvalidArgumentException when the catalogue is not a string
  188. */
  189. public function setTranslationCatalogue($catalogue)
  190. {
  191. if (!is_string($catalogue))
  192. {
  193. throw new \InvalidArgumentException('Catalogue name must be a string');
  194. }
  195. $this->translationCatalogue = $catalogue;
  196. }
  197. protected function unnestErrors($errors, $prefix = '')
  198. {
  199. $newErrors = array();
  200. foreach ($errors as $name => $error)
  201. {
  202. if ($error instanceof \ArrayAccess || is_array($error))
  203. {
  204. $newErrors = array_merge($newErrors, $this->unnestErrors($error, ($prefix ? $prefix.' > ' : '').$name));
  205. }
  206. else
  207. {
  208. if ($error instanceof Bundle\sfFormBundle\Validator\Error)
  209. {
  210. $err = $this->translate($error->getMessageFormat(), $error->getArguments());
  211. }
  212. else
  213. {
  214. $err = $this->translate($error);
  215. }
  216. if (!is_integer($name))
  217. {
  218. $newErrors[] = strtr($this->getNamedErrorRowFormatInARow(), array('%error%' => $err, '%name%' => ($prefix ? $prefix.' > ' : '').$name));
  219. }
  220. else
  221. {
  222. $newErrors[] = strtr($this->getErrorRowFormatInARow(), array('%error%' => $err));
  223. }
  224. }
  225. }
  226. return $newErrors;
  227. }
  228. public function setRowFormat($format)
  229. {
  230. $this->rowFormat = $format;
  231. }
  232. public function getRowFormat()
  233. {
  234. return $this->rowFormat;
  235. }
  236. public function setErrorRowFormat($format)
  237. {
  238. $this->errorRowFormat = $format;
  239. }
  240. public function getErrorRowFormat()
  241. {
  242. return $this->errorRowFormat;
  243. }
  244. public function setErrorListFormatInARow($format)
  245. {
  246. $this->errorListFormatInARow = $format;
  247. }
  248. public function getErrorListFormatInARow()
  249. {
  250. return $this->errorListFormatInARow;
  251. }
  252. public function setErrorRowFormatInARow($format)
  253. {
  254. $this->errorRowFormatInARow = $format;
  255. }
  256. public function getErrorRowFormatInARow()
  257. {
  258. return $this->errorRowFormatInARow;
  259. }
  260. public function setNamedErrorRowFormatInARow($format)
  261. {
  262. $this->namedErrorRowFormatInARow = $format;
  263. }
  264. public function getNamedErrorRowFormatInARow()
  265. {
  266. return $this->namedErrorRowFormatInARow;
  267. }
  268. public function setDecoratorFormat($format)
  269. {
  270. $this->decoratorFormat = $format;
  271. }
  272. public function getDecoratorFormat()
  273. {
  274. return $this->decoratorFormat;
  275. }
  276. public function setHelpFormat($format)
  277. {
  278. $this->helpFormat = $format;
  279. }
  280. public function getHelpFormat()
  281. {
  282. return $this->helpFormat;
  283. }
  284. /**
  285. * Sets the widget schema associated with this formatter instance.
  286. *
  287. * @param sfWidgetFormSchema $widgetSchema A sfWidgetFormSchema instance
  288. */
  289. public function setWidgetSchema(Schema $widgetSchema)
  290. {
  291. $this->widgetSchema = $widgetSchema;
  292. }
  293. public function getWidgetSchema()
  294. {
  295. return $this->widgetSchema;
  296. }
  297. }