--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/vendor/symfony/src/Symfony/Component/Templating/PhpEngine.php Sat Sep 24 15:40:41 2011 +0200
@@ -0,0 +1,546 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Templating;
+
+use Symfony\Component\Templating\Storage\Storage;
+use Symfony\Component\Templating\Storage\FileStorage;
+use Symfony\Component\Templating\Storage\StringStorage;
+use Symfony\Component\Templating\Helper\HelperInterface;
+use Symfony\Component\Templating\Loader\LoaderInterface;
+
+/**
+ * PhpEngine is an engine able to render PHP templates.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ *
+ * @api
+ */
+class PhpEngine implements EngineInterface, \ArrayAccess
+{
+ protected $loader;
+ protected $current;
+ protected $helpers;
+ protected $parents;
+ protected $stack;
+ protected $charset;
+ protected $cache;
+ protected $escapers;
+ protected $globals;
+ protected $parser;
+
+ /**
+ * Constructor.
+ *
+ * @param TemplateNameParserInterface $parser A TemplateNameParserInterface instance
+ * @param LoaderInterface $loader A loader instance
+ * @param array $helpers An array of helper instances
+ */
+ public function __construct(TemplateNameParserInterface $parser, LoaderInterface $loader, array $helpers = array())
+ {
+ $this->parser = $parser;
+ $this->loader = $loader;
+ $this->parents = array();
+ $this->stack = array();
+ $this->charset = 'UTF-8';
+ $this->cache = array();
+ $this->globals = array();
+
+ $this->setHelpers($helpers);
+
+ $this->initializeEscapers();
+ foreach ($this->escapers as $context => $escaper) {
+ $this->setEscaper($context, $escaper);
+ }
+ }
+
+ /**
+ * Renders a template.
+ *
+ * @param mixed $name A template name or a TemplateReferenceInterface instance
+ * @param array $parameters An array of parameters to pass to the template
+ *
+ * @return string The evaluated template as a string
+ *
+ * @throws \InvalidArgumentException if the template does not exist
+ * @throws \RuntimeException if the template cannot be rendered
+ *
+ * @api
+ */
+ public function render($name, array $parameters = array())
+ {
+ $storage = $this->load($name);
+ $key = md5(serialize($storage));
+ $this->current = $key;
+ $this->parents[$key] = null;
+
+ // attach the global variables
+ $parameters = array_replace($this->getGlobals(), $parameters);
+ // render
+ if (false === $content = $this->evaluate($storage, $parameters)) {
+ throw new \RuntimeException(sprintf('The template "%s" cannot be rendered.', $this->parser->parse($name)));
+ }
+
+ // decorator
+ if ($this->parents[$key]) {
+ $slots = $this->get('slots');
+ $this->stack[] = $slots->get('_content');
+ $slots->set('_content', $content);
+
+ $content = $this->render($this->parents[$key], $parameters);
+
+ $slots->set('_content', array_pop($this->stack));
+ }
+
+ return $content;
+ }
+
+ /**
+ * Returns true if the template exists.
+ *
+ * @param mixed $name A template name or a TemplateReferenceInterface instance
+ *
+ * @return Boolean true if the template exists, false otherwise
+ *
+ * @api
+ */
+ public function exists($name)
+ {
+ try {
+ $this->load($name);
+ } catch (\InvalidArgumentException $e) {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Returns true if this class is able to render the given template.
+ *
+ * @param mixed $name A template name or a TemplateReferenceInterface instance
+ *
+ * @return Boolean true if this class supports the given resource, false otherwise
+ *
+ * @api
+ */
+ public function supports($name)
+ {
+ $template = $this->parser->parse($name);
+
+ return 'php' === $template->get('engine');
+ }
+
+ /**
+ * Evaluates a template.
+ *
+ * @param Storage $template The template to render
+ * @param array $parameters An array of parameters to pass to the template
+ *
+ * @return string|false The evaluated template, or false if the engine is unable to render the template
+ */
+ protected function evaluate(Storage $template, array $parameters = array())
+ {
+ $__template__ = $template;
+ if ($__template__ instanceof FileStorage) {
+ extract($parameters);
+ $view = $this;
+ ob_start();
+ require $__template__;
+
+ return ob_get_clean();
+ } elseif ($__template__ instanceof StringStorage) {
+ extract($parameters);
+ $view = $this;
+ ob_start();
+ eval('; ?>'.$__template__.'<?php ;');
+
+ return ob_get_clean();
+ }
+
+ return false;
+ }
+
+ /**
+ * Gets a helper value.
+ *
+ * @param string $name The helper name
+ *
+ * @return mixed The helper value
+ *
+ * @throws \InvalidArgumentException if the helper is not defined
+ *
+ * @api
+ */
+ public function offsetGet($name)
+ {
+ return $this->get($name);
+ }
+
+ /**
+ * Returns true if the helper is defined.
+ *
+ * @param string $name The helper name
+ *
+ * @return Boolean true if the helper is defined, false otherwise
+ *
+ * @api
+ */
+ public function offsetExists($name)
+ {
+ return isset($this->helpers[$name]);
+ }
+
+ /**
+ * Sets a helper.
+ *
+ * @param HelperInterface $name The helper instance
+ * @param string $value An alias
+ *
+ * @api
+ */
+ public function offsetSet($name, $value)
+ {
+ $this->set($name, $value);
+ }
+
+ /**
+ * Removes a helper.
+ *
+ * @param string $name The helper name
+ *
+ * @api
+ */
+ public function offsetUnset($name)
+ {
+ throw new \LogicException(sprintf('You can\'t unset a helper (%s).', $name));
+ }
+
+ /**
+ * @param Helper[] $helpers An array of helper
+ *
+ * @api
+ */
+ public function addHelpers(array $helpers)
+ {
+ foreach ($helpers as $alias => $helper) {
+ $this->set($helper, is_int($alias) ? null : $alias);
+ }
+ }
+
+ /**
+ * Sets the helpers.
+ *
+ * @params Helper[] $helpers An array of helper
+ *
+ * @api
+ */
+ public function setHelpers(array $helpers)
+ {
+ $this->helpers = array();
+ $this->addHelpers($helpers);
+ }
+
+ /**
+ * Sets a helper.
+ *
+ * @param HelperInterface $helper The helper instance
+ * @param string $alias An alias
+ *
+ * @api
+ */
+ public function set(HelperInterface $helper, $alias = null)
+ {
+ $this->helpers[$helper->getName()] = $helper;
+ if (null !== $alias) {
+ $this->helpers[$alias] = $helper;
+ }
+
+ $helper->setCharset($this->charset);
+ }
+
+ /**
+ * Returns true if the helper if defined.
+ *
+ * @param string $name The helper name
+ *
+ * @return Boolean true if the helper is defined, false otherwise
+ *
+ * @api
+ */
+ public function has($name)
+ {
+ return isset($this->helpers[$name]);
+ }
+
+ /**
+ * Gets a helper value.
+ *
+ * @param string $name The helper name
+ *
+ * @return HelperInterface The helper instance
+ *
+ * @throws \InvalidArgumentException if the helper is not defined
+ *
+ * @api
+ */
+ public function get($name)
+ {
+ if (!isset($this->helpers[$name])) {
+ throw new \InvalidArgumentException(sprintf('The helper "%s" is not defined.', $name));
+ }
+
+ return $this->helpers[$name];
+ }
+
+ /**
+ * Decorates the current template with another one.
+ *
+ * @param string $template The decorator logical name
+ *
+ * @api
+ */
+ public function extend($template)
+ {
+ $this->parents[$this->current] = $template;
+ }
+
+ /**
+ * Escapes a string by using the current charset.
+ *
+ * @param mixed $value A variable to escape
+ * @param string $context The context name
+ *
+ * @return string The escaped value
+ *
+ * @api
+ */
+ public function escape($value, $context = 'html')
+ {
+ return call_user_func($this->getEscaper($context), $value);
+ }
+
+ /**
+ * Sets the charset to use.
+ *
+ * @param string $charset The charset
+ *
+ * @api
+ */
+ public function setCharset($charset)
+ {
+ $this->charset = $charset;
+ }
+
+ /**
+ * Gets the current charset.
+ *
+ * @return string The current charset
+ *
+ * @api
+ */
+ public function getCharset()
+ {
+ return $this->charset;
+ }
+
+ /**
+ * Adds an escaper for the given context.
+ *
+ * @param string $context The escaper context (html, js, ...)
+ * @param mixed $escaper A PHP callable
+ *
+ * @api
+ */
+ public function setEscaper($context, $escaper)
+ {
+ $this->escapers[$context] = $escaper;
+ }
+
+ /**
+ * Gets an escaper for a given context.
+ *
+ * @param string $context The context name
+ *
+ * @return mixed $escaper A PHP callable
+ *
+ * @api
+ */
+ public function getEscaper($context)
+ {
+ if (!isset($this->escapers[$context])) {
+ throw new \InvalidArgumentException(sprintf('No registered escaper for context "%s".', $context));
+ }
+
+ return $this->escapers[$context];
+ }
+
+ /**
+ * @param string $name
+ * @param mixed $value
+ *
+ * @api
+ */
+ public function addGlobal($name, $value)
+ {
+ $this->globals[$name] = $value;
+ }
+
+ /**
+ * Returns the assigned globals.
+ *
+ * @return array
+ *
+ * @api
+ */
+ public function getGlobals()
+ {
+ return $this->globals;
+ }
+
+ /**
+ * Initializes the built-in escapers.
+ *
+ * Each function specifies a way for applying a transformation to a string
+ * passed to it. The purpose is for the string to be "escaped" so it is
+ * suitable for the format it is being displayed in.
+ *
+ * For example, the string: "It's required that you enter a username & password.\n"
+ * If this were to be displayed as HTML it would be sensible to turn the
+ * ampersand into '&' and the apostrophe into '&aps;'. However if it were
+ * going to be used as a string in JavaScript to be displayed in an alert box
+ * it would be right to leave the string as-is, but c-escape the apostrophe and
+ * the new line.
+ *
+ * For each function there is a define to avoid problems with strings being
+ * incorrectly specified.
+ */
+ protected function initializeEscapers()
+ {
+ $that = $this;
+
+ $this->escapers = array(
+ 'html' =>
+ /**
+ * Runs the PHP function htmlspecialchars on the value passed.
+ *
+ * @param string $value the value to escape
+ *
+ * @return string the escaped value
+ */
+ function ($value) use ($that)
+ {
+ // Numbers and Boolean values get turned into strings which can cause problems
+ // with type comparisons (e.g. === or is_int() etc).
+ return is_string($value) ? htmlspecialchars($value, ENT_QUOTES, $that->getCharset(), false) : $value;
+ },
+
+ 'js' =>
+ /**
+ * A function that escape all non-alphanumeric characters
+ * into their \xHH or \uHHHH representations
+ *
+ * @param string $value the value to escape
+ * @return string the escaped value
+ */
+ function ($value) use ($that)
+ {
+ if ('UTF-8' != $that->getCharset()) {
+ $value = $that->convertEncoding($value, 'UTF-8', $that->getCharset());
+ }
+
+ $callback = function ($matches) use ($that)
+ {
+ $char = $matches[0];
+
+ // \xHH
+ if (!isset($char[1])) {
+ return '\\x'.substr('00'.bin2hex($char), -2);
+ }
+
+ // \uHHHH
+ $char = $that->convertEncoding($char, 'UTF-16BE', 'UTF-8');
+
+ return '\\u'.substr('0000'.bin2hex($char), -4);
+ };
+
+ if (null === $value = preg_replace_callback('#[^\p{L}\p{N} ]#u', $callback, $value)) {
+ throw new \InvalidArgumentException('The string to escape is not a valid UTF-8 string.');
+ }
+
+ if ('UTF-8' != $that->getCharset()) {
+ $value = $that->convertEncoding($value, $that->getCharset(), 'UTF-8');
+ }
+
+ return $value;
+ },
+ );
+ }
+
+ /**
+ * Convert a string from one encoding to another.
+ *
+ * @param string $string The string to convert
+ * @param string $to The input encoding
+ * @param string $from The output encoding
+ *
+ * @return string The string with the new encoding
+ *
+ * @throws \RuntimeException if no suitable encoding function is found (iconv or mbstring)
+ */
+ public function convertEncoding($string, $to, $from)
+ {
+ if (function_exists('iconv')) {
+ return iconv($from, $to, $string);
+ } elseif (function_exists('mb_convert_encoding')) {
+ return mb_convert_encoding($string, $to, $from);
+ }
+
+ throw new \RuntimeException('No suitable convert encoding function (use UTF-8 as your encoding or install the iconv or mbstring extension).');
+ }
+
+ /**
+ * Gets the loader associated with this engine.
+ *
+ * @return LoaderInterface A LoaderInterface instance
+ */
+ public function getLoader()
+ {
+ return $this->loader;
+ }
+
+ /**
+ * Loads the given template.
+ *
+ * @param mixed $name A template name or a TemplateReferenceInterface instance
+ *
+ * @return Storage A Storage instance
+ *
+ * @throws \InvalidArgumentException if the template cannot be found
+ */
+ protected function load($name)
+ {
+ $template = $this->parser->parse($name);
+
+ $key = $template->getLogicalName();
+ if (isset($this->cache[$key])) {
+ return $this->cache[$key];
+ }
+
+ $storage = $this->loader->load($template);
+
+ if (false === $storage) {
+ throw new \InvalidArgumentException(sprintf('The template "%s" does not exist.', $template));
+ }
+
+ return $this->cache[$key] = $storage;
+ }
+}