diff options
Diffstat (limited to 'vendor/twig/twig/lib/Twig/Loader/Filesystem.php')
-rw-r--r-- | vendor/twig/twig/lib/Twig/Loader/Filesystem.php | 226 |
1 files changed, 226 insertions, 0 deletions
diff --git a/vendor/twig/twig/lib/Twig/Loader/Filesystem.php b/vendor/twig/twig/lib/Twig/Loader/Filesystem.php new file mode 100644 index 00000000..d47781ab --- /dev/null +++ b/vendor/twig/twig/lib/Twig/Loader/Filesystem.php | |||
@@ -0,0 +1,226 @@ | |||
1 | <?php | ||
2 | |||
3 | /* | ||
4 | * This file is part of Twig. | ||
5 | * | ||
6 | * (c) 2009 Fabien Potencier | ||
7 | * | ||
8 | * For the full copyright and license information, please view the LICENSE | ||
9 | * file that was distributed with this source code. | ||
10 | */ | ||
11 | |||
12 | /** | ||
13 | * Loads template from the filesystem. | ||
14 | * | ||
15 | * @author Fabien Potencier <fabien@symfony.com> | ||
16 | */ | ||
17 | class Twig_Loader_Filesystem implements Twig_LoaderInterface, Twig_ExistsLoaderInterface | ||
18 | { | ||
19 | /** Identifier of the main namespace. */ | ||
20 | const MAIN_NAMESPACE = '__main__'; | ||
21 | |||
22 | protected $paths; | ||
23 | protected $cache; | ||
24 | |||
25 | /** | ||
26 | * Constructor. | ||
27 | * | ||
28 | * @param string|array $paths A path or an array of paths where to look for templates | ||
29 | */ | ||
30 | public function __construct($paths = array()) | ||
31 | { | ||
32 | if ($paths) { | ||
33 | $this->setPaths($paths); | ||
34 | } | ||
35 | } | ||
36 | |||
37 | /** | ||
38 | * Returns the paths to the templates. | ||
39 | * | ||
40 | * @param string $namespace A path namespace | ||
41 | * | ||
42 | * @return array The array of paths where to look for templates | ||
43 | */ | ||
44 | public function getPaths($namespace = self::MAIN_NAMESPACE) | ||
45 | { | ||
46 | return isset($this->paths[$namespace]) ? $this->paths[$namespace] : array(); | ||
47 | } | ||
48 | |||
49 | /** | ||
50 | * Returns the path namespaces. | ||
51 | * | ||
52 | * The main namespace is always defined. | ||
53 | * | ||
54 | * @return array The array of defined namespaces | ||
55 | */ | ||
56 | public function getNamespaces() | ||
57 | { | ||
58 | return array_keys($this->paths); | ||
59 | } | ||
60 | |||
61 | /** | ||
62 | * Sets the paths where templates are stored. | ||
63 | * | ||
64 | * @param string|array $paths A path or an array of paths where to look for templates | ||
65 | * @param string $namespace A path namespace | ||
66 | */ | ||
67 | public function setPaths($paths, $namespace = self::MAIN_NAMESPACE) | ||
68 | { | ||
69 | if (!is_array($paths)) { | ||
70 | $paths = array($paths); | ||
71 | } | ||
72 | |||
73 | $this->paths[$namespace] = array(); | ||
74 | foreach ($paths as $path) { | ||
75 | $this->addPath($path, $namespace); | ||
76 | } | ||
77 | } | ||
78 | |||
79 | /** | ||
80 | * Adds a path where templates are stored. | ||
81 | * | ||
82 | * @param string $path A path where to look for templates | ||
83 | * @param string $namespace A path name | ||
84 | * | ||
85 | * @throws Twig_Error_Loader | ||
86 | */ | ||
87 | public function addPath($path, $namespace = self::MAIN_NAMESPACE) | ||
88 | { | ||
89 | // invalidate the cache | ||
90 | $this->cache = array(); | ||
91 | |||
92 | if (!is_dir($path)) { | ||
93 | throw new Twig_Error_Loader(sprintf('The "%s" directory does not exist.', $path)); | ||
94 | } | ||
95 | |||
96 | $this->paths[$namespace][] = rtrim($path, '/\\'); | ||
97 | } | ||
98 | |||
99 | /** | ||
100 | * Prepends a path where templates are stored. | ||
101 | * | ||
102 | * @param string $path A path where to look for templates | ||
103 | * @param string $namespace A path name | ||
104 | * | ||
105 | * @throws Twig_Error_Loader | ||
106 | */ | ||
107 | public function prependPath($path, $namespace = self::MAIN_NAMESPACE) | ||
108 | { | ||
109 | // invalidate the cache | ||
110 | $this->cache = array(); | ||
111 | |||
112 | if (!is_dir($path)) { | ||
113 | throw new Twig_Error_Loader(sprintf('The "%s" directory does not exist.', $path)); | ||
114 | } | ||
115 | |||
116 | $path = rtrim($path, '/\\'); | ||
117 | |||
118 | if (!isset($this->paths[$namespace])) { | ||
119 | $this->paths[$namespace][] = $path; | ||
120 | } else { | ||
121 | array_unshift($this->paths[$namespace], $path); | ||
122 | } | ||
123 | } | ||
124 | |||
125 | /** | ||
126 | * {@inheritdoc} | ||
127 | */ | ||
128 | public function getSource($name) | ||
129 | { | ||
130 | return file_get_contents($this->findTemplate($name)); | ||
131 | } | ||
132 | |||
133 | /** | ||
134 | * {@inheritdoc} | ||
135 | */ | ||
136 | public function getCacheKey($name) | ||
137 | { | ||
138 | return $this->findTemplate($name); | ||
139 | } | ||
140 | |||
141 | /** | ||
142 | * {@inheritdoc} | ||
143 | */ | ||
144 | public function exists($name) | ||
145 | { | ||
146 | $name = (string) $name; | ||
147 | if (isset($this->cache[$name])) { | ||
148 | return true; | ||
149 | } | ||
150 | |||
151 | try { | ||
152 | $this->findTemplate($name); | ||
153 | |||
154 | return true; | ||
155 | } catch (Twig_Error_Loader $exception) { | ||
156 | return false; | ||
157 | } | ||
158 | } | ||
159 | |||
160 | /** | ||
161 | * {@inheritdoc} | ||
162 | */ | ||
163 | public function isFresh($name, $time) | ||
164 | { | ||
165 | return filemtime($this->findTemplate($name)) <= $time; | ||
166 | } | ||
167 | |||
168 | protected function findTemplate($name) | ||
169 | { | ||
170 | $name = (string) $name; | ||
171 | |||
172 | // normalize name | ||
173 | $name = preg_replace('#/{2,}#', '/', strtr($name, '\\', '/')); | ||
174 | |||
175 | if (isset($this->cache[$name])) { | ||
176 | return $this->cache[$name]; | ||
177 | } | ||
178 | |||
179 | $this->validateName($name); | ||
180 | |||
181 | $namespace = self::MAIN_NAMESPACE; | ||
182 | if (isset($name[0]) && '@' == $name[0]) { | ||
183 | if (false === $pos = strpos($name, '/')) { | ||
184 | throw new Twig_Error_Loader(sprintf('Malformed namespaced template name "%s" (expecting "@namespace/template_name").', $name)); | ||
185 | } | ||
186 | |||
187 | $namespace = substr($name, 1, $pos - 1); | ||
188 | |||
189 | $name = substr($name, $pos + 1); | ||
190 | } | ||
191 | |||
192 | if (!isset($this->paths[$namespace])) { | ||
193 | throw new Twig_Error_Loader(sprintf('There are no registered paths for namespace "%s".', $namespace)); | ||
194 | } | ||
195 | |||
196 | foreach ($this->paths[$namespace] as $path) { | ||
197 | if (is_file($path.'/'.$name)) { | ||
198 | return $this->cache[$name] = $path.'/'.$name; | ||
199 | } | ||
200 | } | ||
201 | |||
202 | throw new Twig_Error_Loader(sprintf('Unable to find template "%s" (looked into: %s).', $name, implode(', ', $this->paths[$namespace]))); | ||
203 | } | ||
204 | |||
205 | protected function validateName($name) | ||
206 | { | ||
207 | if (false !== strpos($name, "\0")) { | ||
208 | throw new Twig_Error_Loader('A template name cannot contain NUL bytes.'); | ||
209 | } | ||
210 | |||
211 | $name = ltrim($name, '/'); | ||
212 | $parts = explode('/', $name); | ||
213 | $level = 0; | ||
214 | foreach ($parts as $part) { | ||
215 | if ('..' === $part) { | ||
216 | --$level; | ||
217 | } elseif ('.' !== $part) { | ||
218 | ++$level; | ||
219 | } | ||
220 | |||
221 | if ($level < 0) { | ||
222 | throw new Twig_Error_Loader(sprintf('Looks like you try to load a template outside configured directories (%s).', $name)); | ||
223 | } | ||
224 | } | ||
225 | } | ||
226 | } | ||