diff options
| author | Michael Foster <savetheinternet@tinyboard.org> | 2013-08-01 15:20:12 -0400 |
|---|---|---|
| committer | Michael Foster <savetheinternet@tinyboard.org> | 2013-08-01 15:20:12 -0400 |
| commit | 0fe552857468aa12097a74e08f51f5aaa983be07 (patch) | |
| tree | 22dbca1be90d7086b20a077752552296abf23325 /inc/lib/Twig/Loader | |
| parent | 22f3a95e0e421de05a11633eac846df96a2a4768 (diff) | |
Upgrade Twig library
Diffstat (limited to 'inc/lib/Twig/Loader')
| -rw-r--r-- | inc/lib/Twig/Loader/Array.php | 39 | ||||
| -rw-r--r-- | inc/lib/Twig/Loader/Chain.php | 79 | ||||
| -rw-r--r-- | inc/lib/Twig/Loader/Filesystem.php | 129 | ||||
| -rw-r--r-- | inc/lib/Twig/Loader/String.php | 34 |
4 files changed, 197 insertions, 84 deletions
diff --git a/inc/lib/Twig/Loader/Array.php b/inc/lib/Twig/Loader/Array.php index e8dc1605..89087aea 100644 --- a/inc/lib/Twig/Loader/Array.php +++ b/inc/lib/Twig/Loader/Array.php @@ -17,10 +17,9 @@ * source code of the template). If you don't want to see your cache grows out of * control, you need to take care of clearing the old cache file by yourself. * - * @package twig - * @author Fabien Potencier <fabien@symfony.com> + * @author Fabien Potencier <fabien@symfony.com> */ -class Twig_Loader_Array implements Twig_LoaderInterface +class Twig_Loader_Array implements Twig_LoaderInterface, Twig_ExistsLoaderInterface { protected $templates; @@ -47,18 +46,15 @@ class Twig_Loader_Array implements Twig_LoaderInterface */ public function setTemplate($name, $template) { - $this->templates[$name] = $template; + $this->templates[(string) $name] = $template; } /** - * Gets the source code of a template, given its name. - * - * @param string $name The name of the template to load - * - * @return string The template source code + * {@inheritdoc} */ public function getSource($name) { + $name = (string) $name; if (!isset($this->templates[$name])) { throw new Twig_Error_Loader(sprintf('Template "%s" is not defined.', $name)); } @@ -67,14 +63,19 @@ class Twig_Loader_Array implements Twig_LoaderInterface } /** - * Gets the cache key to use for the cache for a given template name. - * - * @param string $name The name of the template to load - * - * @return string The cache key + * {@inheritdoc} + */ + public function exists($name) + { + return isset($this->templates[(string) $name]); + } + + /** + * {@inheritdoc} */ public function getCacheKey($name) { + $name = (string) $name; if (!isset($this->templates[$name])) { throw new Twig_Error_Loader(sprintf('Template "%s" is not defined.', $name)); } @@ -83,13 +84,15 @@ class Twig_Loader_Array implements Twig_LoaderInterface } /** - * Returns true if the template is still fresh. - * - * @param string $name The template name - * @param timestamp $time The last modification time of the cached template + * {@inheritdoc} */ public function isFresh($name, $time) { + $name = (string) $name; + if (!isset($this->templates[$name])) { + throw new Twig_Error_Loader(sprintf('Template "%s" is not defined.', $name)); + } + return true; } } diff --git a/inc/lib/Twig/Loader/Chain.php b/inc/lib/Twig/Loader/Chain.php index 48dd8b84..1f1cf065 100644 --- a/inc/lib/Twig/Loader/Chain.php +++ b/inc/lib/Twig/Loader/Chain.php @@ -12,11 +12,11 @@ /** * Loads templates from other loaders. * - * @package twig - * @author Fabien Potencier <fabien@symfony.com> + * @author Fabien Potencier <fabien@symfony.com> */ -class Twig_Loader_Chain implements Twig_LoaderInterface +class Twig_Loader_Chain implements Twig_LoaderInterface, Twig_ExistsLoaderInterface { + private $hasSourceCache = array(); protected $loaders; /** @@ -40,61 +40,100 @@ class Twig_Loader_Chain implements Twig_LoaderInterface public function addLoader(Twig_LoaderInterface $loader) { $this->loaders[] = $loader; + $this->hasSourceCache = array(); } /** - * Gets the source code of a template, given its name. - * - * @param string $name The name of the template to load - * - * @return string The template source code + * {@inheritdoc} */ public function getSource($name) { + $exceptions = array(); foreach ($this->loaders as $loader) { + if ($loader instanceof Twig_ExistsLoaderInterface && !$loader->exists($name)) { + continue; + } + try { return $loader->getSource($name); } catch (Twig_Error_Loader $e) { + $exceptions[] = $e->getMessage(); } } - throw new Twig_Error_Loader(sprintf('Template "%s" is not defined.', $name)); + throw new Twig_Error_Loader(sprintf('Template "%s" is not defined (%s).', $name, implode(', ', $exceptions))); } /** - * Gets the cache key to use for the cache for a given template name. - * - * @param string $name The name of the template to load - * - * @return string The cache key + * {@inheritdoc} + */ + public function exists($name) + { + $name = (string) $name; + + if (isset($this->hasSourceCache[$name])) { + return $this->hasSourceCache[$name]; + } + + foreach ($this->loaders as $loader) { + if ($loader instanceof Twig_ExistsLoaderInterface) { + if ($loader->exists($name)) { + return $this->hasSourceCache[$name] = true; + } + + continue; + } + + try { + $loader->getSource($name); + + return $this->hasSourceCache[$name] = true; + } catch (Twig_Error_Loader $e) { + } + } + + return $this->hasSourceCache[$name] = false; + } + + /** + * {@inheritdoc} */ public function getCacheKey($name) { + $exceptions = array(); foreach ($this->loaders as $loader) { + if ($loader instanceof Twig_ExistsLoaderInterface && !$loader->exists($name)) { + continue; + } + try { return $loader->getCacheKey($name); } catch (Twig_Error_Loader $e) { + $exceptions[] = get_class($loader).': '.$e->getMessage(); } } - throw new Twig_Error_Loader(sprintf('Template "%s" is not defined.', $name)); + throw new Twig_Error_Loader(sprintf('Template "%s" is not defined (%s).', $name, implode(' ', $exceptions))); } /** - * Returns true if the template is still fresh. - * - * @param string $name The template name - * @param timestamp $time The last modification time of the cached template + * {@inheritdoc} */ public function isFresh($name, $time) { + $exceptions = array(); foreach ($this->loaders as $loader) { + if ($loader instanceof Twig_ExistsLoaderInterface && !$loader->exists($name)) { + continue; + } + try { return $loader->isFresh($name, $time); } catch (Twig_Error_Loader $e) { + $exceptions[] = get_class($loader).': '.$e->getMessage(); } } - throw new Twig_Error_Loader(sprintf('Template "%s" is not defined.', $name)); + throw new Twig_Error_Loader(sprintf('Template "%s" is not defined (%s).', $name, implode(' ', $exceptions))); } } diff --git a/inc/lib/Twig/Loader/Filesystem.php b/inc/lib/Twig/Loader/Filesystem.php index be348aa3..f9211cbd 100644 --- a/inc/lib/Twig/Loader/Filesystem.php +++ b/inc/lib/Twig/Loader/Filesystem.php @@ -12,10 +12,9 @@ /** * Loads template from the filesystem. * - * @package twig - * @author Fabien Potencier <fabien@symfony.com> + * @author Fabien Potencier <fabien@symfony.com> */ -class Twig_Loader_Filesystem implements Twig_LoaderInterface +class Twig_Loader_Filesystem implements Twig_LoaderInterface, Twig_ExistsLoaderInterface { protected $paths; protected $cache; @@ -25,44 +24,64 @@ class Twig_Loader_Filesystem implements Twig_LoaderInterface * * @param string|array $paths A path or an array of paths where to look for templates */ - public function __construct($paths) + public function __construct($paths = array()) { - $this->setPaths($paths); + if ($paths) { + $this->setPaths($paths); + } } /** * Returns the paths to the templates. * + * @param string $namespace A path namespace + * * @return array The array of paths where to look for templates */ - public function getPaths() + public function getPaths($namespace = '__main__') + { + return isset($this->paths[$namespace]) ? $this->paths[$namespace] : array(); + } + + /** + * Returns the path namespaces. + * + * The "__main__" namespace is always defined. + * + * @return array The array of defined namespaces + */ + public function getNamespaces() { - return $this->paths; + return array_keys($this->paths); } /** * Sets the paths where templates are stored. * - * @param string|array $paths A path or an array of paths where to look for templates + * @param string|array $paths A path or an array of paths where to look for templates + * @param string $namespace A path namespace */ - public function setPaths($paths) + public function setPaths($paths, $namespace = '__main__') { if (!is_array($paths)) { $paths = array($paths); } - $this->paths = array(); + $this->paths[$namespace] = array(); foreach ($paths as $path) { - $this->addPath($path); + $this->addPath($path, $namespace); } } /** * Adds a path where templates are stored. * - * @param string $path A path where to look for templates + * @param string $path A path where to look for templates + * @param string $namespace A path name + * + * @throws Twig_Error_Loader */ - public function addPath($path) + public function addPath($path, $namespace = '__main__') { // invalidate the cache $this->cache = array(); @@ -71,15 +90,37 @@ class Twig_Loader_Filesystem implements Twig_LoaderInterface throw new Twig_Error_Loader(sprintf('The "%s" directory does not exist.', $path)); } - $this->paths[] = $path; + $this->paths[$namespace][] = rtrim($path, '/\\'); } /** - * Gets the source code of a template, given its name. + * Prepends a path where templates are stored. * - * @param string $name The name of the template to load + * @param string $path A path where to look for templates + * @param string $namespace A path name * - * @return string The template source code + * @throws Twig_Error_Loader + */ + public function prependPath($path, $namespace = '__main__') + { + // invalidate the cache + $this->cache = array(); + + if (!is_dir($path)) { + throw new Twig_Error_Loader(sprintf('The "%s" directory does not exist.', $path)); + } + + $path = rtrim($path, '/\\'); + + if (!isset($this->paths[$namespace])) { + $this->paths[$namespace][] = $path; + } else { + array_unshift($this->paths[$namespace], $path); + } + } + + /** + * {@inheritdoc} */ public function getSource($name) { @@ -87,11 +128,7 @@ class Twig_Loader_Filesystem implements Twig_LoaderInterface } /** - * Gets the cache key to use for the cache for a given template name. - * - * @param string $name The name of the template to load - * - * @return string The cache key + * {@inheritdoc} */ public function getCacheKey($name) { @@ -99,18 +136,36 @@ class Twig_Loader_Filesystem implements Twig_LoaderInterface } /** - * Returns true if the template is still fresh. - * - * @param string $name The template name - * @param timestamp $time The last modification time of the cached template + * {@inheritdoc} + */ + public function exists($name) + { + $name = (string) $name; + if (isset($this->cache[$name])) { + return true; + } + + try { + $this->findTemplate($name); + + return true; + } catch (Twig_Error_Loader $exception) { + return false; + } + } + + /** + * {@inheritdoc} */ public function isFresh($name, $time) { - return filemtime($this->findTemplate($name)) < $time; + return filemtime($this->findTemplate($name)) <= $time; } protected function findTemplate($name) { + $name = (string) $name; + // normalize name $name = preg_replace('#/{2,}#', '/', strtr($name, '\\', '/')); @@ -120,13 +175,28 @@ class Twig_Loader_Filesystem implements Twig_LoaderInterface $this->validateName($name); - foreach ($this->paths as $path) { + $namespace = '__main__'; + if (isset($name[0]) && '@' == $name[0]) { + if (false === $pos = strpos($name, '/')) { + throw new Twig_Error_Loader(sprintf('Malformed namespaced template name "%s" (expecting "@namespace/template_name").', $name)); + } + + $namespace = substr($name, 1, $pos - 1); + + $name = substr($name, $pos + 1); + } + + if (!isset($this->paths[$namespace])) { + throw new Twig_Error_Loader(sprintf('There are no registered paths for namespace "%s".', $namespace)); + } + + foreach ($this->paths[$namespace] as $path) { if (is_file($path.'/'.$name)) { return $this->cache[$name] = $path.'/'.$name; } } - throw new Twig_Error_Loader(sprintf('Unable to find template "%s" (looked into: %s).', $name, implode(', ', $this->paths))); + throw new Twig_Error_Loader(sprintf('Unable to find template "%s" (looked into: %s).', $name, implode(', ', $this->paths[$namespace]))); } protected function validateName($name) @@ -135,6 +205,7 @@ class Twig_Loader_Filesystem implements Twig_LoaderInterface throw new Twig_Error_Loader('A template name cannot contain NUL bytes.'); } + $name = ltrim($name, '/'); $parts = explode('/', $name); $level = 0; foreach ($parts as $part) { diff --git a/inc/lib/Twig/Loader/String.php b/inc/lib/Twig/Loader/String.php index 26eb0096..8ad9856c 100644 --- a/inc/lib/Twig/Loader/String.php +++ b/inc/lib/Twig/Loader/String.php @@ -12,22 +12,21 @@ /** * Loads a template from a string. * + * This loader should only be used for unit testing as it has many limitations + * (for instance, the include or extends tag does not make any sense for a string + * loader). + * * When using this loader with a cache mechanism, you should know that a new cache * key is generated each time a template content "changes" (the cache key being the * source code of the template). If you don't want to see your cache grows out of * control, you need to take care of clearing the old cache file by yourself. * - * @package twig - * @author Fabien Potencier <fabien@symfony.com> + * @author Fabien Potencier <fabien@symfony.com> */ -class Twig_Loader_String implements Twig_LoaderInterface +class Twig_Loader_String implements Twig_LoaderInterface, Twig_ExistsLoaderInterface { /** - * Gets the source code of a template, given its name. - * - * @param string $name The name of the template to load - * - * @return string The template source code + * {@inheritdoc} */ public function getSource($name) { @@ -35,11 +34,15 @@ class Twig_Loader_String implements Twig_LoaderInterface } /** - * Gets the cache key to use for the cache for a given template name. - * - * @param string $name The name of the template to load - * - * @return string The cache key + * {@inheritdoc} + */ + public function exists($name) + { + return true; + } + + /** + * {@inheritdoc} */ public function getCacheKey($name) { @@ -47,10 +50,7 @@ class Twig_Loader_String implements Twig_LoaderInterface } /** - * Returns true if the template is still fresh. - * - * @param string $name The template name - * @param timestamp $time The last modification time of the cached template + * {@inheritdoc} */ public function isFresh($name, $time) { |
