From 21b128a89c66b73cb59cbc487b5395821a392be1 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Sat, 22 Aug 2015 14:42:57 +0200 Subject: [PATCH] optimized the filesystem loader * added a cache for templates that do not exist * sped up Filesystem::exists() by avoiding the creation of exceptions same as d2b97b49f240efb453e75558f00e17ccb1d915c5 that was reverted because of a BC break and same as what is in 2.0 (but in a BC way). --- lib/Twig/Loader/Filesystem.php | 34 +++++++++++++++++++++++++++------- 1 file changed, 27 insertions(+), 7 deletions(-) diff --git a/lib/Twig/Loader/Filesystem.php b/lib/Twig/Loader/Filesystem.php index 818a461c58..a68876cee3 100644 --- a/lib/Twig/Loader/Filesystem.php +++ b/lib/Twig/Loader/Filesystem.php @@ -21,6 +21,7 @@ class Twig_Loader_Filesystem implements Twig_LoaderInterface, Twig_ExistsLoaderI protected $paths = array(); protected $cache = array(); + protected $errorCache = array(); /** * Constructor. @@ -87,7 +88,7 @@ public function setPaths($paths, $namespace = self::MAIN_NAMESPACE) public function addPath($path, $namespace = self::MAIN_NAMESPACE) { // invalidate the cache - $this->cache = array(); + $this->cache = $this->errorCache = array(); if (!is_dir($path)) { throw new Twig_Error_Loader(sprintf('The "%s" directory does not exist.', $path)); @@ -107,7 +108,7 @@ public function addPath($path, $namespace = self::MAIN_NAMESPACE) public function prependPath($path, $namespace = self::MAIN_NAMESPACE) { // invalidate the cache - $this->cache = array(); + $this->cache = $this->errorCache = array(); if (!is_dir($path)) { throw new Twig_Error_Loader(sprintf('The "%s" directory does not exist.', $path)); @@ -150,9 +151,7 @@ public function exists($name) } try { - $this->findTemplate($name); - - return true; + return false !== $this->findTemplate($name, false); } catch (Twig_Error_Loader $exception) { return false; } @@ -168,18 +167,33 @@ public function isFresh($name, $time) protected function findTemplate($name) { + $throw = func_num_args() > 1 ? func_get_arg(1) : true; $name = $this->normalizeName($name); if (isset($this->cache[$name])) { return $this->cache[$name]; } + if (isset($this->errorCache[$name])) { + if (!$throw) { + return false; + } + + throw new Twig_Error_Loader($this->errorCache[$name]); + } + $this->validateName($name); list($namespace, $shortname) = $this->parseName($name); if (!isset($this->paths[$namespace])) { - throw new Twig_Error_Loader(sprintf('There are no registered paths for namespace "%s".', $namespace)); + $this->errorCache[$name] = sprintf('There are no registered paths for namespace "%s".', $namespace); + + if (!$throw) { + return false; + } + + throw new Twig_Error_Loader($this->errorCache[$name]); } foreach ($this->paths[$namespace] as $path) { @@ -192,7 +206,13 @@ protected function findTemplate($name) } } - throw new Twig_Error_Loader(sprintf('Unable to find template "%s" (looked into: %s).', $name, implode(', ', $this->paths[$namespace]))); + $this->errorCache[$name] = sprintf('Unable to find template "%s" (looked into: %s).', $name, implode(', ', $this->paths[$namespace])); + + if (!$throw) { + return false; + } + + throw new Twig_Error_Loader($this->errorCache[$name]); } protected function parseName($name, $default = self::MAIN_NAMESPACE)