/
FileLoader.php
93 lines (72 loc) · 2.04 KB
/
FileLoader.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
<?php
/**
* This file is part of the Latte (https://latte.nette.org)
* Copyright (c) 2008 David Grudl (https://davidgrudl.com)
*/
declare(strict_types=1);
namespace Latte\Loaders;
use Latte;
/**
* Template loader.
*/
class FileLoader implements Latte\Loader
{
use Latte\Strict;
/** @var string|null */
private $baseDir;
public function __construct($baseDir = null)
{
$this->baseDir = $baseDir ? $this->normalizePath("$baseDir/") : null;
}
/**
* Returns template source code.
*/
public function getContent($fileName): string
{
$file = $this->baseDir . $fileName;
if ($this->baseDir && !Latte\Helpers::startsWith($this->normalizePath($file), $this->baseDir)) {
throw new \RuntimeException("Template '$file' is not within the allowed path '$this->baseDir'.");
} elseif (!is_file($file)) {
throw new \RuntimeException("Missing template file '$file'.");
} elseif ($this->isExpired($fileName, time())) {
if (@touch($file) === false) {
trigger_error("File's modification time is in the future. Cannot update it: " . error_get_last()['message'], E_USER_WARNING);
}
}
return file_get_contents($file);
}
public function isExpired($file, $time): bool
{
$mtime = @filemtime($this->baseDir . $file); // @ - stat may fail
return !$mtime || $mtime > $time;
}
/**
* Returns referred template name.
*/
public function getReferredName($file, $referringFile): string
{
if ($this->baseDir || !preg_match('#/|\\\\|[a-z][a-z0-9+.-]*:#iA', $file)) {
$file = $this->normalizePath($referringFile . '/../' . $file);
}
return $file;
}
/**
* Returns unique identifier for caching.
*/
public function getUniqueId($file): string
{
return $this->baseDir . strtr($file, '/', DIRECTORY_SEPARATOR);
}
private static function normalizePath(string $path): string
{
$res = [];
foreach (explode('/', strtr($path, '\\', '/')) as $part) {
if ($part === '..' && $res && end($res) !== '..') {
array_pop($res);
} elseif ($part !== '.') {
$res[] = $part;
}
}
return implode(DIRECTORY_SEPARATOR, $res);
}
}