This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | class TimberLoader { |
||
4 | |||
5 | const CACHEGROUP = 'timberloader'; |
||
6 | |||
7 | const TRANS_KEY_LEN = 50; |
||
8 | |||
9 | const CACHE_NONE = 'none'; |
||
10 | const CACHE_OBJECT = 'cache'; |
||
11 | const CACHE_TRANSIENT = 'transient'; |
||
12 | const CACHE_SITE_TRANSIENT = 'site-transient'; |
||
13 | const CACHE_USE_DEFAULT = 'default'; |
||
14 | |||
15 | public static $cache_modes = array( |
||
16 | self::CACHE_NONE, |
||
17 | self::CACHE_OBJECT, |
||
18 | self::CACHE_TRANSIENT, |
||
19 | self::CACHE_SITE_TRANSIENT |
||
20 | ); |
||
21 | |||
22 | protected $cache_mode = self::CACHE_TRANSIENT; |
||
23 | |||
24 | public $locations; |
||
25 | |||
26 | /** |
||
27 | * @param bool|string $caller the calling directory or false |
||
28 | */ |
||
29 | function __construct($caller = false) { |
||
30 | $this->locations = $this->get_locations($caller); |
||
31 | $this->cache_mode = apply_filters('timber_cache_mode', $this->cache_mode); |
||
32 | $this->cache_mode = apply_filters('timber/cache/mode', $this->cache_mode); |
||
33 | } |
||
34 | |||
35 | /** |
||
36 | * @param string $file |
||
37 | * @param array $data |
||
38 | * @param bool $expires |
||
39 | * @param string $cache_mode |
||
40 | * @return bool|string |
||
41 | */ |
||
42 | function render($file, $data = null, $expires = false, $cache_mode = self::CACHE_USE_DEFAULT) { |
||
43 | // Different $expires if user is anonymous or logged in |
||
44 | if (is_array($expires)) { |
||
45 | if (is_user_logged_in() && isset($expires[1])) { |
||
46 | $expires = $expires[1]; |
||
47 | } else { |
||
48 | $expires = $expires[0]; |
||
49 | } |
||
50 | } |
||
51 | |||
52 | $key = null; |
||
53 | $output = false; |
||
54 | if (false !== $expires) { |
||
55 | ksort($data); |
||
56 | $key = md5($file . json_encode($data)); |
||
57 | $output = $this->get_cache($key, self::CACHEGROUP, $cache_mode); |
||
58 | } |
||
59 | |||
60 | if (false === $output || null === $output) { |
||
61 | $twig = $this->get_twig(); |
||
62 | if (strlen($file)) { |
||
63 | $loader = $this->get_loader(); |
||
64 | $result = $loader->getCacheKey($file); |
||
65 | do_action('timber_loader_render_file', $result); |
||
66 | } |
||
67 | $data = apply_filters('timber_loader_render_data', $data); |
||
68 | $data = apply_filters('timber/loader/render_data', $data); |
||
69 | $output = $twig->render($file, $data); |
||
70 | } |
||
71 | |||
72 | if (false !== $output && false !== $expires && null !== $key) { |
||
73 | $this->set_cache($key, $output, self::CACHEGROUP, $expires, $cache_mode); |
||
74 | } |
||
75 | $output = apply_filters('timber_output', $output); |
||
76 | return apply_filters('timber/output', $output); |
||
77 | } |
||
78 | |||
79 | /** |
||
80 | * @param array $filenames |
||
81 | * @return bool |
||
82 | */ |
||
83 | public function choose_template($filenames) { |
||
84 | if (is_array($filenames)) { |
||
85 | /* its an array so we have to figure out which one the dev wants */ |
||
86 | foreach ($filenames as $filename) { |
||
87 | if (self::template_exists($filename)) { |
||
88 | return $filename; |
||
89 | } |
||
90 | } |
||
91 | return $filenames[0]; |
||
92 | } |
||
93 | return $filenames; |
||
94 | } |
||
95 | |||
96 | /** |
||
97 | * @param string $file |
||
98 | * @return bool |
||
99 | */ |
||
100 | protected function template_exists($file) { |
||
101 | foreach ($this->locations as $dir) { |
||
102 | $look_for = trailingslashit($dir) . $file; |
||
103 | if (file_exists($look_for)) { |
||
104 | return true; |
||
105 | } |
||
106 | } |
||
107 | return false; |
||
108 | } |
||
109 | |||
110 | /** |
||
111 | * @return array |
||
112 | */ |
||
113 | function get_locations_theme() { |
||
114 | $theme_locs = array(); |
||
115 | $child_loc = get_stylesheet_directory(); |
||
116 | $parent_loc = get_template_directory(); |
||
117 | if (DIRECTORY_SEPARATOR == '\\') { |
||
118 | $child_loc = str_replace('/', '\\', $child_loc); |
||
119 | $parent_loc = str_replace('/', '\\', $parent_loc); |
||
120 | } |
||
121 | $theme_locs[] = $child_loc; |
||
122 | foreach ($this->get_locations_theme_dir() as $dirname) { |
||
123 | $theme_locs[] = trailingslashit($child_loc) . trailingslashit($dirname); |
||
124 | } |
||
125 | if ($child_loc != $parent_loc) { |
||
126 | $theme_locs[] = $parent_loc; |
||
127 | foreach ($this->get_locations_theme_dir() as $dirname) { |
||
128 | $theme_locs[] = trailingslashit($parent_loc) . trailingslashit($dirname); |
||
129 | } |
||
130 | } |
||
131 | //now make sure theres a trailing slash on everything |
||
132 | $theme_locs = array_map('trailingslashit', $theme_locs); |
||
133 | return $theme_locs; |
||
134 | } |
||
135 | |||
136 | /** |
||
137 | * returns an array of the directory inside themes that holds twig files |
||
138 | * @return string[] the names of directores, ie: array('templats', 'views'); |
||
139 | */ |
||
140 | private function get_locations_theme_dir() { |
||
141 | if (is_string(Timber::$dirname)) { |
||
142 | return array(Timber::$dirname); |
||
143 | } |
||
144 | return Timber::$dirname; |
||
145 | } |
||
146 | |||
147 | /** |
||
148 | * @return array |
||
149 | */ |
||
150 | function get_locations_user() { |
||
151 | $locs = array(); |
||
152 | if (isset(Timber::$locations)) { |
||
153 | if (is_string(Timber::$locations)) { |
||
154 | Timber::$locations = array(Timber::$locations); |
||
155 | } |
||
156 | foreach (Timber::$locations as $tloc) { |
||
157 | $tloc = realpath($tloc); |
||
158 | if (is_dir($tloc)) { |
||
159 | $locs[] = $tloc; |
||
160 | } |
||
161 | } |
||
162 | } |
||
163 | return $locs; |
||
164 | } |
||
165 | |||
166 | /** |
||
167 | * @param bool|string $caller the calling directory |
||
168 | * @return array |
||
169 | */ |
||
170 | function get_locations_caller($caller = false) { |
||
171 | $locs = array(); |
||
172 | if ($caller && is_string($caller)) { |
||
173 | $caller = trailingslashit($caller); |
||
174 | if (is_dir($caller)) { |
||
175 | $locs[] = $caller; |
||
176 | } |
||
177 | foreach ($this->get_locations_theme_dir() as $dirname) { |
||
178 | $caller_sub = $caller . trailingslashit($dirname); |
||
179 | if (is_dir($caller_sub)) { |
||
180 | $locs[] = $caller_sub; |
||
181 | } |
||
182 | } |
||
183 | } |
||
184 | return $locs; |
||
185 | } |
||
186 | |||
187 | /** |
||
188 | * @param bool|string $caller the calling directory (or false) |
||
189 | * @return array |
||
190 | */ |
||
191 | function get_locations($caller = false) { |
||
192 | //prioirty: user locations, caller (but not theme), child theme, parent theme, caller |
||
193 | $locs = array(); |
||
194 | $locs = array_merge($locs, $this->get_locations_user()); |
||
195 | $locs = array_merge($locs, $this->get_locations_caller($caller)); |
||
196 | //remove themes from caller |
||
197 | $locs = array_diff($locs, $this->get_locations_theme()); |
||
198 | $locs = array_merge($locs, $this->get_locations_theme()); |
||
199 | $locs = array_merge($locs, $this->get_locations_caller($caller)); |
||
200 | $locs = array_unique($locs); |
||
201 | $locs = apply_filters('timber_locations', $locs); |
||
202 | $locs = apply_filters('timber/locations', $locs); |
||
203 | return $locs; |
||
204 | } |
||
205 | |||
206 | /** |
||
207 | * @return Twig_Loader_Filesystem |
||
208 | */ |
||
209 | function get_loader() { |
||
210 | $paths = array(); |
||
211 | foreach ($this->locations as $loc) { |
||
212 | $loc = realpath($loc); |
||
213 | if (is_dir($loc)) { |
||
214 | $loc = realpath($loc); |
||
215 | $paths[] = $loc; |
||
216 | } else { |
||
0 ignored issues
–
show
|
|||
217 | //error_log($loc.' is not a directory'); |
||
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
72% of this comment could be valid code. Did you maybe forget this after debugging?
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it. The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production. This check looks for comments that seem to be mostly valid code and reports them. ![]() |
|||
218 | } |
||
219 | } |
||
220 | if (!ini_get('open_basedir')) { |
||
221 | $paths[] = '/'; |
||
222 | } else { |
||
223 | $paths[] = ABSPATH; |
||
224 | } |
||
225 | $paths = apply_filters('timber/loader/paths', $paths); |
||
226 | $loader = new Twig_Loader_Filesystem($paths); |
||
227 | return $loader; |
||
228 | } |
||
229 | |||
230 | /** |
||
231 | * @return Twig_Environment |
||
232 | */ |
||
233 | function get_twig() { |
||
234 | $loader = $this->get_loader(); |
||
235 | $params = array('debug' => WP_DEBUG, 'autoescape' => false); |
||
236 | if (isset(Timber::$autoescape)) { |
||
237 | $params['autoescape'] = Timber::$autoescape; |
||
238 | } |
||
239 | if (Timber::$cache === true) { |
||
240 | Timber::$twig_cache = true; |
||
241 | } |
||
242 | if (Timber::$twig_cache) { |
||
243 | $twig_cache_loc = apply_filters( 'timber/cache/location', TIMBER_LOC . '/cache/twig' ); |
||
244 | if (!file_exists($twig_cache_loc)) { |
||
245 | mkdir($twig_cache_loc, 0777, true); |
||
246 | } |
||
247 | $params['cache'] = $twig_cache_loc; |
||
248 | } |
||
249 | $twig = new Twig_Environment($loader, $params); |
||
250 | if ( WP_DEBUG ) { |
||
251 | $twig->addExtension(new Twig_Extension_Debug()); |
||
252 | } |
||
253 | $twig->addExtension($this->_get_cache_extension()); |
||
254 | |||
255 | $twig = apply_filters('twig_apply_filters', $twig); |
||
256 | $twig = apply_filters('timber/twig/filters', $twig); |
||
257 | $twig = apply_filters('timber/loader/twig', $twig); |
||
258 | return $twig; |
||
259 | } |
||
260 | |||
261 | public function clear_cache_timber($cache_mode = self::CACHE_USE_DEFAULT){ |
||
262 | //_transient_timberloader |
||
263 | $object_cache = false; |
||
264 | if (isset($GLOBALS['wp_object_cache']) && is_object($GLOBALS['wp_object_cache'])) { |
||
265 | $object_cache = true; |
||
266 | } |
||
267 | $cache_mode = $this->_get_cache_mode($cache_mode); |
||
268 | if (self::CACHE_TRANSIENT === $cache_mode) { |
||
269 | global $wpdb; |
||
270 | $query = $wpdb->prepare("DELETE FROM $wpdb->options WHERE option_name LIKE '%s'", '_transient_timberloader_%'); |
||
271 | $wpdb->query( $query ); |
||
272 | return true; |
||
273 | } else if (self::CACHE_SITE_TRANSIENT === $cache_mode) { |
||
274 | global $wpdb; |
||
275 | $query = $wpdb->prepare("DELETE FROM $wpdb->options WHERE option_name LIKE '%s'", '_transient_timberloader_%'); |
||
276 | $wpdb->query( $query ); |
||
277 | return true; |
||
278 | } else if (self::CACHE_OBJECT === $cache_mode && $object_cache) { |
||
279 | global $wp_object_cache; |
||
280 | if (isset($wp_object_cache->cache[self::CACHEGROUP])){ |
||
281 | unset($wp_object_cache->cache[self::CACHEGROUP]); |
||
282 | return true; |
||
283 | } |
||
284 | } |
||
285 | return false; |
||
286 | } |
||
287 | |||
288 | public function clear_cache_twig() { |
||
289 | $twig = $this->get_twig(); |
||
290 | $twig->clearCacheFiles(); |
||
291 | $cache = $twig->getCache(); |
||
292 | if ($cache){ |
||
293 | self::rrmdir($twig->getCache()); |
||
294 | return true; |
||
295 | } |
||
296 | return false; |
||
297 | } |
||
298 | |||
299 | /** |
||
300 | * @param string|false $dirPath |
||
301 | */ |
||
302 | public static function rrmdir($dirPath) { |
||
303 | if (! is_dir($dirPath)) { |
||
304 | throw new InvalidArgumentException("$dirPath must be a directory"); |
||
305 | } |
||
306 | if (substr($dirPath, strlen($dirPath) - 1, 1) != '/') { |
||
307 | $dirPath .= '/'; |
||
308 | } |
||
309 | $files = glob($dirPath . '*', GLOB_MARK); |
||
310 | foreach ($files as $file) { |
||
311 | if (is_dir($file)) { |
||
312 | self::rrmdir($file); |
||
313 | } else { |
||
314 | unlink($file); |
||
315 | } |
||
316 | } |
||
317 | rmdir($dirPath); |
||
318 | } |
||
319 | |||
320 | /** |
||
321 | * @return \Asm89\Twig\CacheExtension\Extension |
||
322 | */ |
||
323 | private function _get_cache_extension() { |
||
324 | |||
325 | $key_generator = new \Timber\Cache\KeyGenerator(); |
||
326 | $cache_provider = new \Timber\Cache\WPObjectCacheAdapter( $this ); |
||
327 | $cache_strategy = new \Asm89\Twig\CacheExtension\CacheStrategy\GenerationalCacheStrategy( $cache_provider, $key_generator ); |
||
328 | $cache_extension = new \Asm89\Twig\CacheExtension\Extension( $cache_strategy ); |
||
329 | |||
330 | return $cache_extension; |
||
331 | } |
||
332 | |||
333 | /** |
||
334 | * @param string $key |
||
335 | * @param string $group |
||
336 | * @param string $cache_mode |
||
337 | * @return bool |
||
338 | */ |
||
339 | public function get_cache($key, $group = self::CACHEGROUP, $cache_mode = self::CACHE_USE_DEFAULT) { |
||
340 | $object_cache = false; |
||
341 | |||
342 | if (isset($GLOBALS['wp_object_cache']) && is_object($GLOBALS['wp_object_cache'])) { |
||
343 | $object_cache = true; |
||
344 | } |
||
345 | |||
346 | $cache_mode = $this->_get_cache_mode($cache_mode); |
||
347 | |||
348 | $value = false; |
||
349 | |||
350 | $trans_key = substr($group . '_' . $key, 0, self::TRANS_KEY_LEN); |
||
351 | if (self::CACHE_TRANSIENT === $cache_mode) |
||
352 | $value = get_transient($trans_key); |
||
353 | |||
354 | elseif (self::CACHE_SITE_TRANSIENT === $cache_mode) |
||
355 | $value = get_site_transient($trans_key); |
||
356 | |||
357 | elseif (self::CACHE_OBJECT === $cache_mode && $object_cache) |
||
358 | $value = wp_cache_get($key, $group); |
||
359 | |||
360 | return $value; |
||
361 | } |
||
362 | |||
363 | /** |
||
364 | * @param string $key |
||
365 | * @param string|boolean $value |
||
366 | * @param string $group |
||
367 | * @param int $expires |
||
368 | * @param string $cache_mode |
||
369 | * @return string|boolean |
||
370 | */ |
||
371 | public function set_cache($key, $value, $group = self::CACHEGROUP, $expires = 0, $cache_mode = self::CACHE_USE_DEFAULT) { |
||
372 | $object_cache = false; |
||
373 | |||
374 | if (isset($GLOBALS['wp_object_cache']) && is_object($GLOBALS['wp_object_cache'])) { |
||
375 | $object_cache = true; |
||
376 | } |
||
377 | |||
378 | if ((int)$expires < 1) |
||
379 | $expires = 0; |
||
380 | |||
381 | $cache_mode = self::_get_cache_mode($cache_mode); |
||
382 | $trans_key = substr($group . '_' . $key, 0, self::TRANS_KEY_LEN); |
||
383 | |||
384 | if (self::CACHE_TRANSIENT === $cache_mode) |
||
385 | set_transient($trans_key, $value, $expires); |
||
386 | |||
387 | elseif (self::CACHE_SITE_TRANSIENT === $cache_mode) |
||
388 | set_site_transient($trans_key, $value, $expires); |
||
389 | |||
390 | elseif (self::CACHE_OBJECT === $cache_mode && $object_cache) |
||
391 | wp_cache_set($key, $value, $group, $expires); |
||
392 | |||
393 | return $value; |
||
394 | } |
||
395 | |||
396 | /** |
||
397 | * @param string $cache_mode |
||
398 | * @return string |
||
399 | */ |
||
400 | private function _get_cache_mode($cache_mode) { |
||
401 | if (empty($cache_mode) || self::CACHE_USE_DEFAULT === $cache_mode) { |
||
402 | $cache_mode = $this->cache_mode; |
||
403 | } |
||
404 | |||
405 | // Fallback if self::$cache_mode did not get a valid value |
||
406 | if (!in_array($cache_mode, self::$cache_modes)) { |
||
407 | $cache_mode = self::CACHE_OBJECT; |
||
408 | } |
||
409 | |||
410 | return $cache_mode; |
||
411 | } |
||
412 | |||
413 | } |
||
414 |
This check looks for the
else
branches ofif
statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.These
else
branches can be removed.could be turned into
This is much more concise to read.