1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* This file is part of AirTemplate. |
4
|
|
|
* |
5
|
|
|
* (c) 2016 Andreas Blaser |
6
|
|
|
* |
7
|
|
|
* For the full copyright and license information, please view the LICENSE |
8
|
|
|
* file that was distributed with this source code. |
9
|
|
|
* |
10
|
|
|
* @package AirTemplate |
11
|
|
|
* @author Andreas Blaser <[email protected]> |
12
|
|
|
* @license http://www.spdx.org/licenses/MIT MIT License |
13
|
|
|
*/ |
14
|
|
|
|
15
|
|
|
namespace AirTemplate\Loader; |
16
|
|
|
|
17
|
|
|
use AirTemplate\Parser; |
18
|
|
|
|
19
|
|
|
/** |
20
|
|
|
* FilesystemLoader reads templates from the filesystem. |
21
|
|
|
*/ |
22
|
|
|
class FilesystemLoader extends Loader |
23
|
|
|
{ |
24
|
|
|
/** |
25
|
|
|
* Array of parse options. |
26
|
|
|
* |
27
|
|
|
* @see Template::__construct() |
28
|
|
|
* |
29
|
|
|
* @var array |
30
|
|
|
*/ |
31
|
|
|
protected $parseOptions = []; |
32
|
|
|
|
33
|
|
|
/** |
34
|
|
|
* Template directory. |
35
|
|
|
* |
36
|
|
|
* @see Template::__construct() |
37
|
|
|
* |
38
|
|
|
* @var string |
39
|
|
|
*/ |
40
|
|
|
protected $dir = ''; |
41
|
|
|
|
42
|
|
|
/** |
43
|
|
|
* Constructor. |
44
|
|
|
* |
45
|
|
|
* @param string $dir Path to template directory |
46
|
|
|
* @param array $parseOptions Template parser options |
47
|
|
|
*/ |
48
|
|
|
public function __construct($dir = '', $parseOptions = []) |
49
|
|
|
{ |
50
|
|
|
$this->dir = $dir; |
51
|
|
|
$this->parseOptions = $parseOptions; |
52
|
|
|
} |
53
|
|
|
|
54
|
|
|
/** |
55
|
|
|
* Reads template files and returns them as a templates array. |
56
|
|
|
* |
57
|
|
|
* @param array|string $templates Array of filenames or file mask (regex). |
58
|
|
|
* |
59
|
|
|
* @return array|bool An array of templates or false |
60
|
|
|
*/ |
61
|
|
View Code Duplication |
public function load($templates) |
|
|
|
|
62
|
|
|
{ |
63
|
|
|
$templates = $this->loadTemplateFiles($templates); |
64
|
|
|
if (!empty($templates)) { |
65
|
|
|
$parser = new Parser($this->parseOptions); |
66
|
|
|
$templates = $parser->parse($templates); |
67
|
|
|
return $templates; |
68
|
|
|
} |
69
|
|
|
return false; |
70
|
|
|
} |
71
|
|
|
|
72
|
|
|
/** |
73
|
|
|
* Sets a new template directory. |
74
|
|
|
* |
75
|
|
|
* @param string $dir Path to template directory |
76
|
|
|
* |
77
|
|
|
* @return FilesystemLoader |
78
|
|
|
*/ |
79
|
|
|
public function setDir($dir) |
80
|
|
|
{ |
81
|
|
|
$this->dir = $dir; |
82
|
|
|
return $this; |
83
|
|
|
} |
84
|
|
|
|
85
|
|
|
/** |
86
|
|
|
* Get the current template directory. |
87
|
|
|
* |
88
|
|
|
* @return string |
89
|
|
|
*/ |
90
|
|
|
public function getDir() |
91
|
|
|
{ |
92
|
|
|
return $this->dir; |
93
|
|
|
} |
94
|
|
|
|
95
|
|
|
/** |
96
|
|
|
* Load templates from external files into an array. |
97
|
|
|
* |
98
|
|
|
* Returns an array where the file basenames (including extension) are |
99
|
|
|
* used as array-keys (e.g. 'table.tmpl'). |
100
|
|
|
* |
101
|
|
|
* @param string|array $files Reg. expression or array of filenames |
102
|
|
|
* |
103
|
|
|
* @return array Array of source templates |
104
|
|
|
*/ |
105
|
|
|
protected function loadTemplateFiles($files) |
106
|
|
|
{ |
107
|
|
|
$templates = []; |
108
|
|
|
$failures = []; |
109
|
|
|
$files = $this->getFilenames($files); |
110
|
|
|
foreach ($files as $name => $file) { |
111
|
|
|
$temp = self::readFile($file); |
112
|
|
|
if ($temp === false) { |
113
|
|
|
$failures[] = $file; |
114
|
|
|
continue; |
115
|
|
|
} |
116
|
|
|
$templates[$name] = $temp; |
117
|
|
|
$this->debugLog('Template loaded: ' . $file); |
118
|
|
|
} |
119
|
|
|
if (!empty($templates)) { |
120
|
|
|
$this->debugLog('Templates loaded: ' . count($templates)); |
121
|
|
|
} else { |
122
|
|
|
foreach ($failures as $file) { |
123
|
|
|
$this->debugLog('Template not loaded: ' . $file); |
124
|
|
|
} |
125
|
|
|
} |
126
|
|
|
return $templates; |
127
|
|
|
} |
128
|
|
|
|
129
|
|
|
|
130
|
|
|
/** |
131
|
|
|
* Write debug log message if a logger is set. |
132
|
|
|
* |
133
|
|
|
* @param string $msg The log message |
134
|
|
|
* |
135
|
|
|
* @return void |
136
|
|
|
*/ |
137
|
|
|
private function debugLog($msg) |
138
|
|
|
{ |
139
|
|
|
if ($this->logger !== null) { |
140
|
|
|
$this->logger->debug($msg); |
141
|
|
|
} |
142
|
|
|
} |
143
|
|
|
|
144
|
|
|
/** |
145
|
|
|
* Build a list of qualified filenames. |
146
|
|
|
* |
147
|
|
|
* The keys of the returned array represents the template names. |
148
|
|
|
* Non-numeric keys in the incoming array will be used as template |
149
|
|
|
* names, otherwise the file basename is used. |
150
|
|
|
* |
151
|
|
|
* @param string|array $files Reg. expression or array of filenames |
152
|
|
|
* @param string $dir Path to template directory |
|
|
|
|
153
|
|
|
* |
154
|
|
|
* @return array Array of filenames |
155
|
|
|
*/ |
156
|
|
|
protected function getFilenames($files) |
157
|
|
|
{ |
158
|
|
|
if (!is_array($files)) { |
159
|
|
|
return $this->matchFilenames($files); |
160
|
|
|
} |
161
|
|
|
$fnames = []; |
162
|
|
|
foreach ($files as $key => $file) { |
163
|
|
|
if (is_numeric($key)) { |
164
|
|
|
$key = explode('.', basename($file))[0]; |
165
|
|
|
} |
166
|
|
|
$fnames[$key] = ($this->dir != '') |
167
|
|
|
? $this->dir . DIRECTORY_SEPARATOR . $file |
168
|
|
|
: $file; |
169
|
|
|
} |
170
|
|
|
return $fnames; |
171
|
|
|
} |
172
|
|
|
|
173
|
|
|
/** |
174
|
|
|
* Get a list of files from $dir matching $pattern. |
175
|
|
|
* |
176
|
|
|
* @param string $pattern Regular expression |
177
|
|
|
* |
178
|
|
|
* @return array Array of filenames |
179
|
|
|
*/ |
180
|
|
|
protected function matchFilenames($pattern) |
181
|
|
|
{ |
182
|
|
|
$files = new \GlobIterator(realpath($this->dir) . DIRECTORY_SEPARATOR . $pattern); |
183
|
|
|
$filenames = []; |
184
|
|
|
foreach ($files as $fileinfo) { |
185
|
|
|
$name = explode('.', $fileinfo->getBasename())[0]; |
186
|
|
|
$filenames[$name] = $fileinfo->getPathname(); |
187
|
|
|
} |
188
|
|
|
return $filenames; |
189
|
|
|
} |
190
|
|
|
|
191
|
|
|
/** |
192
|
|
|
* Read a file. |
193
|
|
|
* |
194
|
|
|
* @param string $filename Filename |
195
|
|
|
* |
196
|
|
|
* @return mixed File content or false on error |
197
|
|
|
*/ |
198
|
|
|
protected static function readFile($filename) |
199
|
|
|
{ |
200
|
|
|
if (is_readable($filename) && is_file($filename)) { |
201
|
|
|
return file_get_contents($filename); |
202
|
|
|
} |
203
|
|
|
return false; |
204
|
|
|
} |
205
|
|
|
} |
206
|
|
|
|
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.