/htdocs/symfony/2.0.0pr2/src/vendor/symfony/src/Symfony/Components/Templating/Engine.php

https://github.com/ad2joe/php-framework-benchmarks · PHP · 298 lines · 136 code · 37 blank · 125 comment · 13 complexity · d4fe4806b7642b2bd9d4f614f4980f4a MD5 · raw file

  1. <?php
  2. namespace Symfony\Components\Templating;
  3. use Symfony\Components\Templating\Loader\LoaderInterface;
  4. use Symfony\Components\Templating\Renderer\PhpRenderer;
  5. use Symfony\Components\Templating\Renderer\RendererInterface;
  6. use Symfony\Components\Templating\Helper\HelperInterface;
  7. /*
  8. * This file is part of the Symfony package.
  9. *
  10. * (c) Fabien Potencier <fabien.potencier@symfony-project.com>
  11. *
  12. * For the full copyright and license information, please view the LICENSE
  13. * file that was distributed with this source code.
  14. */
  15. /**
  16. * Engine is the main class of the templating component.
  17. *
  18. * @package Symfony
  19. * @subpackage Components_Templating
  20. * @author Fabien Potencier <fabien.potencier@symfony-project.com>
  21. */
  22. class Engine
  23. {
  24. protected $loader;
  25. protected $renderers;
  26. protected $current;
  27. protected $helpers;
  28. protected $parents;
  29. protected $stack;
  30. protected $charset;
  31. protected $cache;
  32. /**
  33. * Constructor.
  34. *
  35. * @param LoaderInterface $loader A loader instance
  36. * @param array $renderers An array of renderer instances
  37. * @param array $helpers A array of helper instances
  38. */
  39. public function __construct(LoaderInterface $loader, array $renderers = array(), array $helpers = array())
  40. {
  41. $this->loader = $loader;
  42. $this->renderers = $renderers;
  43. $this->helpers = array();
  44. $this->parents = array();
  45. $this->stack = array();
  46. $this->charset = 'UTF-8';
  47. $this->cache = array();
  48. $this->addHelpers($helpers);
  49. if (!isset($this->renderers['php'])) {
  50. $this->renderers['php'] = new PhpRenderer();
  51. }
  52. foreach ($this->renderers as $renderer) {
  53. $renderer->setEngine($this);
  54. }
  55. }
  56. /**
  57. * Renders a template.
  58. *
  59. * The template name is composed of segments separated by a colon (:).
  60. * By default, this engine knows how to parse templates with one or two segments:
  61. *
  62. * * index: The template logical name is index and the renderer is php
  63. * * index:twig: The template logical name is index and the renderer is twig
  64. *
  65. * @param string $name A template name
  66. * @param array $parameters An array of parameters to pass to the template
  67. *
  68. * @return string The evaluated template as a string
  69. *
  70. * @throws \InvalidArgumentException if the renderer does not exist or if the template does not exist
  71. * @throws \RuntimeException if the template cannot be rendered
  72. */
  73. public function render($name, array $parameters = array())
  74. {
  75. if (isset($this->cache[$name])) {
  76. list($name, $options, $template) = $this->cache[$name];
  77. } else {
  78. list($name, $options) = $this->splitTemplateName($old = $name);
  79. // load
  80. $template = $this->loader->load($name, $options);
  81. if (false === $template) {
  82. throw new \InvalidArgumentException(sprintf('The template "%s" does not exist (renderer: %s).', $name, $options['renderer']));
  83. }
  84. $this->cache[$old] = array($name, $options, $template);
  85. }
  86. $this->current = $name;
  87. $this->parents[$name] = null;
  88. // renderer
  89. $renderer = $template->getRenderer() ? $template->getRenderer() : $options['renderer'];
  90. if (!isset($this->renderers[$options['renderer']])) {
  91. throw new \InvalidArgumentException(sprintf('The renderer "%s" is not registered.', $renderer));
  92. }
  93. // render
  94. if (false === $content = $this->renderers[$renderer]->evaluate($template, $parameters)) {
  95. throw new \RuntimeException(sprintf('The template "%s" cannot be rendered (renderer: %s).', $name, $renderer));
  96. }
  97. // decorator
  98. if ($this->parents[$name]) {
  99. $slots = $this->get('slots');
  100. $this->stack[] = $slots->get('_content');
  101. $slots->set('_content', $content);
  102. $content = $this->render($this->parents[$name], $parameters);
  103. $slots->set('_content', array_pop($this->stack));
  104. }
  105. return $content;
  106. }
  107. /**
  108. * Outputs a rendered template.
  109. *
  110. * @param string $name A template name
  111. * @param array $parameters An array of parameters to pass to the template
  112. *
  113. * @see render()
  114. */
  115. public function output($name, array $parameters = array())
  116. {
  117. echo $this->render($name, $parameters);
  118. }
  119. /**
  120. * Gets a helper value.
  121. *
  122. * @param string $name The helper name
  123. *
  124. * @return mixed The helper value
  125. *
  126. * @throws \InvalidArgumentException if the helper is not defined
  127. */
  128. public function __get($name)
  129. {
  130. return $this->$name = $this->get($name);
  131. }
  132. /**
  133. * Returns true if the helper is defined.
  134. *
  135. * @param string $name The helper name
  136. *
  137. * @return Boolean true if the helper is defined, false otherwise
  138. */
  139. public function __isset($name)
  140. {
  141. return isset($this->helpers[$name]);
  142. }
  143. /**
  144. * @param Helper[] $helpers An array of helper
  145. */
  146. public function addHelpers(array $helpers = array())
  147. {
  148. foreach ($helpers as $alias => $helper) {
  149. $this->set($helper, is_int($alias) ? null : $alias);
  150. }
  151. }
  152. /**
  153. * Sets a helper.
  154. *
  155. * @param HelperInterface $value The helper instance
  156. * @param string $alias An alias
  157. */
  158. public function set(HelperInterface $helper, $alias = null)
  159. {
  160. $this->helpers[$helper->getName()] = $helper;
  161. if (null !== $alias) {
  162. $this->helpers[$alias] = $helper;
  163. }
  164. $helper->setCharset($this->charset);
  165. }
  166. /**
  167. * Returns true if the helper if defined.
  168. *
  169. * @param string $name The helper name
  170. *
  171. * @return Boolean true if the helper is defined, false otherwise
  172. */
  173. public function has($name)
  174. {
  175. return isset($this->helpers[$name]);
  176. }
  177. /**
  178. * Gets a helper value.
  179. *
  180. * @param string $name The helper name
  181. *
  182. * @return HelperInterface The helper instance
  183. *
  184. * @throws \InvalidArgumentException if the helper is not defined
  185. */
  186. public function get($name)
  187. {
  188. if (!isset($this->helpers[$name])) {
  189. throw new \InvalidArgumentException(sprintf('The helper "%s" is not defined.', $name));
  190. }
  191. return $this->helpers[$name];
  192. }
  193. /**
  194. * Decorates the current template with another one.
  195. *
  196. * @param string $template The decorator logical name
  197. */
  198. public function extend($template)
  199. {
  200. $this->parents[$this->current] = $template;
  201. }
  202. /**
  203. * Escapes a string by using the current charset.
  204. *
  205. * @param string $value A string to escape
  206. *
  207. * @return string The escaped string or the original value if not a string
  208. */
  209. public function escape($value)
  210. {
  211. return is_string($value) || (is_object($value) && method_exists($value, '__toString')) ? htmlspecialchars($value, ENT_QUOTES, $this->charset) : $value;
  212. }
  213. /**
  214. * Sets the charset to use.
  215. *
  216. * @param string $charset The charset
  217. */
  218. public function setCharset($charset)
  219. {
  220. $this->charset = $charset;
  221. }
  222. /**
  223. * Gets the current charset.
  224. *
  225. * @return string The current charset
  226. */
  227. public function getCharset()
  228. {
  229. return $this->charset;
  230. }
  231. /**
  232. * Gets the loader associated with this engine.
  233. *
  234. * @return LoaderInterface A LoaderInterface instance
  235. */
  236. public function getLoader()
  237. {
  238. return $this->loader;
  239. }
  240. /**
  241. * Sets a template renderer.
  242. *
  243. * @param string $name The renderer name
  244. * @param RendererInterface $renderer A RendererInterface instance
  245. */
  246. public function setRenderer($name, RendererInterface $renderer)
  247. {
  248. $this->renderers[$name] = $renderer;
  249. $renderer->setEngine($this);
  250. }
  251. public function splitTemplateName($name)
  252. {
  253. if (false !== $pos = strpos($name, ':')) {
  254. $renderer = substr($name, $pos + 1);
  255. $name = substr($name, 0, $pos);
  256. } else {
  257. $renderer = 'php';
  258. }
  259. return array($name, array('renderer' => $renderer));
  260. }
  261. }