source: branches/0.4/web/addons/job_monarch/dwoo/Dwoo/Template/File.php @ 755

Last change on this file since 755 was 755, checked in by ramonb, 11 years ago
  • add Dwoo
File size: 8.2 KB
Line 
1<?php
2
3/**
4 * represents a Dwoo template contained in a file
5 *
6 * This software is provided 'as-is', without any express or implied warranty.
7 * In no event will the authors be held liable for any damages arising from the use of this software.
8 *
9 * @author     Jordi Boggiano <j.boggiano@seld.be>
10 * @copyright  Copyright (c) 2008, Jordi Boggiano
11 * @license    http://dwoo.org/LICENSE   Modified BSD License
12 * @link       http://dwoo.org/
13 * @version    1.1.0
14 * @date       2009-07-18
15 * @package    Dwoo
16 */
17class Dwoo_Template_File extends Dwoo_Template_String
18{
19        /**
20         * template filename
21         *
22         * @var string
23         */
24        protected $file;
25
26        /**
27         * include path(s) to look into to find this template
28         *
29         * @var array
30         */
31        protected $includePath = null;
32
33        /**
34         * resolved path cache when looking for a file in multiple include paths
35         *
36         * this is reset when the include path is changed
37         *
38         * @var string
39         */
40        protected $resolvedPath = null;
41
42        /**
43         * creates a template from a file
44         *
45         * @param string $file the path to the template file, make sure it exists
46         * @param int $cacheTime duration of the cache validity for this template,
47         *                                               if null it defaults to the Dwoo instance that will
48         *                                               render this template
49         * @param string $cacheId the unique cache identifier of this page or anything else that
50         *                                                makes this template's content unique, if null it defaults
51         *                                                to the current url
52         * @param string $compileId the unique compiled identifier, which is used to distinguish this
53         *                                                      template from others, if null it defaults to the filename+bits of the path
54         * @param mixed $includePath a string for a single path to look into for the given file, or an array of paths
55         */
56        public function __construct($file, $cacheTime = null, $cacheId = null, $compileId = null, $includePath = null)
57        {
58                $this->file = $file;
59                $this->name = basename($file);
60                $this->cacheTime = $cacheTime;
61
62                if ($compileId !== null) {
63                        $this->compileId = str_replace('../', '__', strtr($compileId, '\\%?=!:;'.PATH_SEPARATOR, '/-------'));
64                }
65
66                if ($cacheId !== null) {
67                        $this->cacheId = str_replace('../', '__', strtr($cacheId, '\\%?=!:;'.PATH_SEPARATOR, '/-------'));
68                }
69
70                if (is_string($includePath)) {
71                        $this->includePath = array($includePath);
72                } elseif (is_array($includePath)) {
73                        $this->includePath = $includePath;
74                }
75        }
76
77        /**
78         * sets the include path(s) to where the given template filename must be looked up
79         *
80         * @param mixed $paths the path to look into, can be string for a single path or an array of paths
81         */
82        public function setIncludePath($paths)
83        {
84                if (is_array($paths) === false) {
85                        $paths = array($paths);
86                }
87
88                $this->includePath = $paths;
89                $this->resolvedPath = null;
90        }
91
92        /**
93         * return the current include path(s)
94         *
95         * @return array
96         */
97        public function getIncludePath()
98        {
99                return $this->includePath;
100        }
101
102        /**
103         * Checks if compiled file is valid (exists and it's the modification is greater or
104         * equal to the modification time of the template file)
105         *
106         * @param string file
107         * @return boolean True cache file existance and it's modification time
108         */
109        protected function isValidCompiledFile($file) {
110                return parent::isValidCompiledFile($file) && (int)$this->getUid() <= filemtime($file);
111        }
112
113        /**
114         * returns the template source of this template
115         *
116         * @return string
117         */
118        public function getSource()
119        {
120                return file_get_contents($this->getResourceIdentifier());
121        }
122
123        /**
124         * returns the resource name for this template class
125         *
126         * @return string
127         */
128        public function getResourceName()
129        {
130                return 'file';
131        }
132
133        /**
134         * returns this template's source filename
135         *
136         * @return string
137         */
138        public function getResourceIdentifier()
139        {
140                if ($this->resolvedPath !== null) {
141                        return $this->resolvedPath;
142                } elseif ($this->includePath === null) {
143                        return $this->file;
144                } else {
145                        foreach ($this->includePath as $path) {
146                                $path = rtrim($path, DIRECTORY_SEPARATOR);
147                                if (file_exists($path.DIRECTORY_SEPARATOR.$this->file) === true) {
148                                        $this->resolvedPath = $path . DIRECTORY_SEPARATOR . $this->file;
149                                        return $this->resolvedPath;
150                                }
151                        }
152
153                        throw new Dwoo_Exception('Template "'.$this->file.'" could not be found in any of your include path(s)');
154                }
155        }
156
157        /**
158         * returns an unique value identifying the current version of this template,
159         * in this case it's the unix timestamp of the last modification
160         *
161         * @return string
162         */
163        public function getUid()
164        {
165                return (string) filemtime($this->getResourceIdentifier());
166        }
167
168        /**
169         * returns a new template object from the given include name, null if no include is
170         * possible (resource not found), or false if include is not permitted by this resource type
171         *
172         * @param Dwoo_Core $dwoo the dwoo instance requiring it
173         * @param mixed $resourceId the filename (relative to this template's dir) of the template to include
174         * @param int $cacheTime duration of the cache validity for this template,
175         *                                               if null it defaults to the Dwoo instance that will
176         *                                               render this template
177         * @param string $cacheId the unique cache identifier of this page or anything else that
178         *                                                makes this template's content unique, if null it defaults
179         *                                                to the current url
180         * @param string $compileId the unique compiled identifier, which is used to distinguish this
181         *                                                      template from others, if null it defaults to the filename+bits of the path
182         * @param Dwoo_ITemplate $parentTemplate the template that is requesting a new template object (through
183         *                                                                                      an include, extends or any other plugin)
184         * @return Dwoo_Template_File|null
185         */
186        public static function templateFactory(Dwoo_Core $dwoo, $resourceId, $cacheTime = null, $cacheId = null, $compileId = null, Dwoo_ITemplate $parentTemplate = null)
187        {
188                if (DIRECTORY_SEPARATOR === '\\') {
189                        $resourceId = str_replace(array("\t", "\n", "\r", "\f", "\v"), array('\\t', '\\n', '\\r', '\\f', '\\v'), $resourceId);
190                }
191                $resourceId = strtr($resourceId, '\\', '/');
192
193                $includePath = null;
194
195                if (file_exists($resourceId) === false) {
196                        if ($parentTemplate === null) {
197                                $parentTemplate = $dwoo->getTemplate();
198                        }
199                        if ($parentTemplate instanceof Dwoo_Template_File) {
200                                if ($includePath = $parentTemplate->getIncludePath()) {
201                                        if (strstr($resourceId, '../')) {
202                                                throw new Dwoo_Exception('When using an include path you can not reference a template into a parent directory (using ../)');
203                                        }
204                                } else {
205                                        $resourceId = dirname($parentTemplate->getResourceIdentifier()).DIRECTORY_SEPARATOR.$resourceId;
206                                        if (file_exists($resourceId) === false) {
207                                                return null;
208                                        }
209                                }
210                        } else {
211                                return null;
212                        }
213                }
214
215                if ($policy = $dwoo->getSecurityPolicy()) {
216                        while (true) {
217                                if (preg_match('{^([a-z]+?)://}i', $resourceId)) {
218                                        throw new Dwoo_Security_Exception('The security policy prevents you to read files from external sources : <em>'.$resourceId.'</em>.');
219                                }
220
221                                if ($includePath) {
222                                        break;
223                                }
224
225                                $resourceId = realpath($resourceId);
226                                $dirs = $policy->getAllowedDirectories();
227                                foreach ($dirs as $dir=>$dummy) {
228                                        if (strpos($resourceId, $dir) === 0) {
229                                                break 2;
230                                        }
231                                }
232                                throw new Dwoo_Security_Exception('The security policy prevents you to read <em>'.$resourceId.'</em>');
233                        }
234                }
235
236                $class = 'Dwoo_Template_File';
237                if ($parentTemplate) {
238                        $class = get_class($parentTemplate);
239                }
240                return new $class($resourceId, $cacheTime, $cacheId, $compileId, $includePath);
241        }
242
243        /**
244         * returns the full compiled file name and assigns a default value to it if
245         * required
246         *
247         * @param Dwoo_Core $dwoo the dwoo instance that requests the file name
248         * @return string the full path to the compiled file
249         */
250        protected function getCompiledFilename(Dwoo_Core $dwoo)
251        {
252                // no compile id was provided, set default
253                if ($this->compileId===null) {
254                        $this->compileId = str_replace('../', '__', strtr($this->getResourceIdentifier(), '\\:', '/-'));
255                }
256                return $dwoo->getCompileDir() . $this->compileId.'.d'.Dwoo_Core::RELEASE_TAG.'.php';
257        }
258
259        /**
260         * returns some php code that will check if this template has been modified or not
261         *
262         * if the function returns null, the template will be instanciated and then the Uid checked
263         *
264         * @return string
265         */
266        public function getIsModifiedCode()
267        {
268                return '"'.$this->getUid().'" == filemtime('.var_export($this->getResourceIdentifier(), true).')';
269        }
270}
Note: See TracBrowser for help on using the repository browser.