These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | /** |
||
3 | * Copyright (c) 2013-2017 |
||
4 | * |
||
5 | * @category Library |
||
6 | * @package Dwoo\Template |
||
7 | * @author Jordi Boggiano <[email protected]> |
||
8 | * @author David Sanchez <[email protected]> |
||
9 | * @copyright 2008-2013 Jordi Boggiano |
||
10 | * @copyright 2013-2017 David Sanchez |
||
11 | * @license http://dwoo.org/LICENSE Modified BSD License |
||
12 | * @version 1.3.4 |
||
13 | * @date 2017-03-07 |
||
14 | * @link http://dwoo.org/ |
||
15 | */ |
||
16 | |||
17 | namespace Dwoo\Template; |
||
18 | |||
19 | use Dwoo\Exception as DwooException; |
||
20 | use Dwoo\Core as Core; |
||
21 | use Dwoo\ICompiler; |
||
22 | use Dwoo\ITemplate as ITemplate; |
||
23 | use Dwoo\Security\Exception as SecurityException; |
||
24 | use Dwoo\Template\File as TemplateFile; |
||
25 | |||
26 | /** |
||
27 | * Represents a Dwoo template contained in a file. |
||
28 | * This software is provided 'as-is', without any express or implied warranty. |
||
29 | * In no event will the authors be held liable for any damages arising from the use of this software. |
||
30 | */ |
||
31 | class File extends Str |
||
32 | { |
||
33 | /** |
||
34 | * Template filename. |
||
35 | * |
||
36 | * @var string |
||
37 | */ |
||
38 | protected $file; |
||
39 | |||
40 | /** |
||
41 | * Include path(s) to look into to find this template. |
||
42 | * |
||
43 | * @var array |
||
44 | */ |
||
45 | protected $includePath = array(); |
||
46 | |||
47 | /** |
||
48 | * Resolved path cache when looking for a file in multiple include paths. |
||
49 | * this is reset when the include path is changed |
||
50 | * |
||
51 | * @var string |
||
52 | */ |
||
53 | protected $resolvedPath = null; |
||
54 | |||
55 | /** |
||
56 | * Creates a template from a file. |
||
57 | * |
||
58 | * @param string $file the path to the template file, make sure it exists |
||
59 | * @param int $cacheTime duration of the cache validity for this template, |
||
60 | * if null it defaults to the Dwoo instance that will |
||
61 | * render this template |
||
62 | * @param string $cacheId the unique cache identifier of this page or anything else that |
||
63 | * makes this template's content unique, if null it defaults |
||
64 | * to the current url |
||
65 | * @param string $compileId the unique compiled identifier, which is used to distinguish this |
||
66 | * template from others, if null it defaults to the filename+bits of the path |
||
67 | * @param mixed $includePath a string for a single path to look into for the given file, or an array of paths |
||
68 | */ |
||
69 | public function __construct($file, $cacheTime = null, $cacheId = null, $compileId = null, $includePath = array()) |
||
70 | { |
||
71 | parent::__construct($file, $cacheTime, $cacheId, $compileId); |
||
72 | $this->template = null; |
||
73 | $this->file = $file; |
||
74 | $this->name = basename($file); |
||
75 | $this->setIncludePath($includePath); |
||
76 | } |
||
77 | |||
78 | /** |
||
79 | * Sets the include path(s) to where the given template filename must be looked up. |
||
80 | * |
||
81 | * @param mixed $paths the path to look into, can be string for a single path or an array of paths |
||
82 | */ |
||
83 | public function setIncludePath($paths) |
||
84 | { |
||
85 | if (is_array($paths) === false) { |
||
86 | $paths = array($paths); |
||
87 | } |
||
88 | |||
89 | $this->includePath = $paths; |
||
90 | $this->resolvedPath = null; |
||
91 | } |
||
92 | |||
93 | /** |
||
94 | * Return the current include path(s). |
||
95 | * |
||
96 | * @return array |
||
97 | */ |
||
98 | public function getIncludePath() |
||
99 | { |
||
100 | return $this->includePath; |
||
101 | } |
||
102 | |||
103 | /** |
||
104 | * Checks if compiled file is valid (exists and it's the modification is greater or |
||
105 | * equal to the modification time of the template file). |
||
106 | * |
||
107 | * @param string file |
||
108 | * |
||
109 | * @return bool True cache file existance and it's modification time |
||
110 | */ |
||
111 | protected function isValidCompiledFile($file) |
||
112 | { |
||
113 | return parent::isValidCompiledFile($file) && (int)$this->getUid() <= filemtime($file); |
||
114 | } |
||
115 | |||
116 | /** |
||
117 | * Returns the template source of this template. |
||
118 | * |
||
119 | * @return string |
||
120 | */ |
||
121 | public function getSource() |
||
122 | { |
||
123 | return file_get_contents($this->getResourceIdentifier()); |
||
124 | } |
||
125 | |||
126 | /** |
||
127 | * Returns the resource name for this template class. |
||
128 | * |
||
129 | * @return string |
||
130 | */ |
||
131 | public function getResourceName() |
||
132 | { |
||
133 | return 'file'; |
||
134 | } |
||
135 | |||
136 | /** |
||
137 | * Returns this template's source filename. |
||
138 | * |
||
139 | * @return string |
||
140 | * @throws DwooException |
||
141 | */ |
||
142 | public function getResourceIdentifier() |
||
143 | { |
||
144 | if ($this->resolvedPath !== null) { |
||
145 | return $this->resolvedPath; |
||
146 | } elseif (array_filter($this->getIncludePath()) == array()) { |
||
147 | return $this->file; |
||
148 | } else { |
||
149 | foreach ($this->getIncludePath() as $path) { |
||
150 | $path = rtrim($path, DIRECTORY_SEPARATOR); |
||
151 | if (file_exists($path . DIRECTORY_SEPARATOR . $this->file) === true) { |
||
152 | return $this->resolvedPath = $path . DIRECTORY_SEPARATOR . $this->file; |
||
153 | } |
||
154 | } |
||
155 | |||
156 | throw new DwooException('Template "' . $this->file . '" could not be found in any of your include path(s)'); |
||
157 | } |
||
158 | } |
||
159 | |||
160 | /** |
||
161 | * Returns an unique value identifying the current version of this template, |
||
162 | * in this case it's the unix timestamp of the last modification. |
||
163 | * |
||
164 | * @return string |
||
165 | */ |
||
166 | public function getUid() |
||
167 | { |
||
168 | return (string)filemtime($this->getResourceIdentifier()); |
||
169 | } |
||
170 | |||
171 | /** |
||
172 | * Returns a new template object from the given include name, null if no include is |
||
173 | * possible (resource not found), or false if include is not permitted by this resource type. |
||
174 | * |
||
175 | * @param Core $core the dwoo instance requiring it |
||
176 | * @param mixed $resourceId the filename (relative to this template's dir) of the template to |
||
177 | * include |
||
178 | * @param int $cacheTime duration of the cache validity for this template, if null it defaults |
||
179 | * to the Dwoo instance that will render this template if null it |
||
180 | * defaults to the Dwoo instance that will render this template if null |
||
181 | * it defaults to the Dwoo instance that will render this template |
||
182 | * @param string $cacheId the unique cache identifier of this page or anything else that makes |
||
183 | * this template's content unique, if null it defaults to the current |
||
184 | * url makes this template's content unique, if null it defaults to the |
||
185 | * current url makes this template's content unique, if null it defaults |
||
186 | * to the current url |
||
187 | * @param string $compileId the unique compiled identifier, which is used to distinguish this |
||
188 | * template from others, if null it defaults to the filename+bits of the |
||
189 | * path template from others, if null it defaults to the filename+bits |
||
190 | * of the path template from others, if null it defaults to the |
||
191 | * filename+bits of the path |
||
192 | * @param ITemplate $parentTemplate the template that is requesting a new template object (through an |
||
193 | * include, extends or any other plugin) an include, extends or any |
||
194 | * other plugin) an include, extends or any other plugin) |
||
195 | * |
||
196 | * @return TemplateFile|null |
||
197 | * @throws DwooException |
||
198 | * @throws SecurityException |
||
199 | */ |
||
200 | public static function templateFactory(Core $core, $resourceId, $cacheTime = null, $cacheId = null, |
||
201 | $compileId = null, ITemplate $parentTemplate = null) |
||
202 | { |
||
203 | if (DIRECTORY_SEPARATOR === '\\') { |
||
204 | $resourceId = str_replace(array("\t", "\n", "\r", "\f", "\v"), array( |
||
205 | '\\t', |
||
206 | '\\n', |
||
207 | '\\r', |
||
208 | '\\f', |
||
209 | '\\v' |
||
210 | ), $resourceId); |
||
211 | } |
||
212 | $resourceId = strtr($resourceId, '\\', '/'); |
||
213 | |||
214 | $includePath = null; |
||
215 | |||
216 | if (file_exists($resourceId) === false) { |
||
217 | if ($parentTemplate === null) { |
||
218 | $parentTemplate = $core->getTemplate(); |
||
219 | } |
||
220 | if ($parentTemplate instanceof self) { |
||
221 | if ($includePath = $parentTemplate->getIncludePath()) { |
||
222 | if (strstr($resourceId, '../')) { |
||
223 | throw new DwooException('When using an include path you can not reference a template into a parent directory (using ../)'); |
||
224 | } |
||
225 | } else { |
||
226 | $resourceId = dirname($parentTemplate->getResourceIdentifier()) . DIRECTORY_SEPARATOR . $resourceId; |
||
227 | if (file_exists($resourceId) === false) { |
||
228 | return null; |
||
229 | } |
||
230 | } |
||
231 | } else { |
||
232 | return null; |
||
233 | } |
||
234 | } |
||
235 | |||
236 | if ($policy = $core->getSecurityPolicy()) { |
||
237 | while (true) { |
||
238 | if (preg_match('{^([a-z]+?)://}i', $resourceId)) { |
||
239 | throw new SecurityException('The security policy prevents you to read files from external sources : <em>' . $resourceId . '</em>.'); |
||
240 | } |
||
241 | |||
242 | if ($includePath) { |
||
243 | break; |
||
244 | } |
||
245 | |||
246 | $resourceId = realpath($resourceId); |
||
247 | $dirs = $policy->getAllowedDirectories(); |
||
248 | foreach ($dirs as $dir => $dummy) { |
||
249 | if (strpos($resourceId, $dir) === 0) { |
||
250 | break 2; |
||
251 | } |
||
252 | } |
||
253 | throw new SecurityException('The security policy prevents you to read <em>' . $resourceId . '</em>'); |
||
254 | } |
||
255 | } |
||
256 | |||
257 | $class = 'Dwoo\Template\File'; |
||
258 | if ($parentTemplate) { |
||
259 | $class = get_class($parentTemplate); |
||
260 | } |
||
261 | |||
262 | return new $class($resourceId, $cacheTime, $cacheId, $compileId, $includePath); |
||
263 | } |
||
264 | |||
265 | /** |
||
266 | * Returns the full compiled file name and assigns a default value to it if |
||
267 | * required. |
||
268 | * |
||
269 | * @param Core $core the Core instance that requests the file name |
||
270 | * |
||
271 | * @return string the full path to the compiled file |
||
272 | */ |
||
273 | View Code Duplication | protected function getCompiledFilename(Core $core) |
|
0 ignored issues
–
show
|
|||
274 | { |
||
275 | // no compile id was provided, set default |
||
276 | if ($this->compileId === null) { |
||
277 | $this->compileId = $this->getResourceIdentifier(); |
||
278 | } |
||
279 | |||
280 | return $this->compileId . '.d' . Core::RELEASE_TAG . '.php'; |
||
281 | } |
||
282 | |||
283 | /** |
||
284 | * Returns some php code that will check if this template has been modified or not. |
||
285 | * if the function returns null, the template will be instanciated and then the Uid checked |
||
286 | * |
||
287 | * @return string |
||
288 | */ |
||
289 | public function getIsModifiedCode() |
||
290 | { |
||
291 | return '"' . $this->getUid() . '" == filemtime(' . var_export($this->getResourceIdentifier(), true) . ')'; |
||
292 | } |
||
293 | } |
||
294 |
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.