1: <?php
2: /**
3: * Smarty Internal Plugin Resource File
4: *
5: * @package Smarty
6: * @subpackage TemplateResources
7: * @author Uwe Tews
8: * @author Rodney Rehm
9: */
10:
11: /**
12: * Smarty Internal Plugin Resource File
13: * Implements the file system as resource for Smarty templates
14: *
15: * @package Smarty
16: * @subpackage TemplateResources
17: */
18: class Smarty_Internal_Resource_File extends Smarty_Resource
19: {
20: /**
21: * populate Source Object with meta data from Resource
22: *
23: * @param Smarty_Template_Source $source source object
24: * @param Smarty_Internal_Template $_template template object
25: *
26: * @throws \SmartyException
27: */
28: public function populate(Smarty_Template_Source $source, Smarty_Internal_Template $_template = null)
29: {
30: $source->filepath = $this->buildFilepath($source, $_template);
31: if ($source->filepath !== false) {
32: if (isset($source->smarty->security_policy) && is_object($source->smarty->security_policy)) {
33: $source->smarty->security_policy->isTrustedResourceDir($source->filepath, $source->isConfig);
34: }
35: $source->exists = true;
36: $source->uid = sha1(
37: $source->filepath . ($source->isConfig ? $source->smarty->_joined_config_dir :
38: $source->smarty->_joined_template_dir)
39: );
40: $source->timestamp = filemtime($source->filepath);
41: } else {
42: $source->timestamp = $source->exists = false;
43: }
44: }
45:
46: /**
47: * populate Source Object with timestamp and exists from Resource
48: *
49: * @param Smarty_Template_Source $source source object
50: */
51: public function populateTimestamp(Smarty_Template_Source $source)
52: {
53: if (!$source->exists) {
54: $source->timestamp = $source->exists = is_file($source->filepath);
55: }
56: if ($source->exists) {
57: $source->timestamp = filemtime($source->filepath);
58: }
59: }
60:
61: /**
62: * Load template's source from file into current template object
63: *
64: * @param Smarty_Template_Source $source source object
65: *
66: * @return string template source
67: * @throws SmartyException if source cannot be loaded
68: */
69: public function getContent(Smarty_Template_Source $source)
70: {
71: if ($source->exists) {
72: return file_get_contents($source->filepath);
73: }
74: throw new SmartyException(
75: 'Unable to read ' . ($source->isConfig ? 'config' : 'template') .
76: " {$source->type} '{$source->name}'"
77: );
78: }
79:
80: /**
81: * Determine basename for compiled filename
82: *
83: * @param Smarty_Template_Source $source source object
84: *
85: * @return string resource's basename
86: */
87: public function getBasename(Smarty_Template_Source $source)
88: {
89: return basename($source->filepath);
90: }
91:
92: /**
93: * build template filepath by traversing the template_dir array
94: *
95: * @param Smarty_Template_Source $source source object
96: * @param Smarty_Internal_Template $_template template object
97: *
98: * @return string fully qualified filepath
99: * @throws SmartyException
100: */
101: protected function buildFilepath(Smarty_Template_Source $source, Smarty_Internal_Template $_template = null)
102: {
103: $file = $source->name;
104: // absolute file ?
105: if ($file[ 0 ] === '/' || $file[ 1 ] === ':') {
106: $file = $source->smarty->_realpath($file, true);
107: return is_file($file) ? $file : false;
108: }
109: // go relative to a given template?
110: if ($file[ 0 ] === '.' && $_template && $_template->_isSubTpl()
111: && preg_match('#^[.]{1,2}[\\\/]#', $file)
112: ) {
113: if ($_template->parent->source->type !== 'file' && $_template->parent->source->type !== 'extends'
114: && !isset($_template->parent->_cache[ 'allow_relative_path' ])
115: ) {
116: throw new SmartyException("Template '{$file}' cannot be relative to template of resource type '{$_template->parent->source->type}'");
117: }
118: // normalize path
119: $path =
120: $source->smarty->_realpath(dirname($_template->parent->source->filepath) . DIRECTORY_SEPARATOR . $file);
121: // files relative to a template only get one shot
122: return is_file($path) ? $path : false;
123: }
124: // normalize DIRECTORY_SEPARATOR
125: if (strpos($file, DIRECTORY_SEPARATOR === '/' ? '\\' : '/') !== false) {
126: $file = str_replace(DIRECTORY_SEPARATOR === '/' ? '\\' : '/', DIRECTORY_SEPARATOR, $file);
127: }
128: $_directories = $source->smarty->getTemplateDir(null, $source->isConfig);
129: // template_dir index?
130: if ($file[ 0 ] === '[' && preg_match('#^\[([^\]]+)\](.+)$#', $file, $fileMatch)) {
131: $file = $fileMatch[ 2 ];
132: $_indices = explode(',', $fileMatch[ 1 ]);
133: $_index_dirs = array();
134: foreach ($_indices as $index) {
135: $index = trim($index);
136: // try string indexes
137: if (isset($_directories[ $index ])) {
138: $_index_dirs[] = $_directories[ $index ];
139: } elseif (is_numeric($index)) {
140: // try numeric index
141: $index = (int)$index;
142: if (isset($_directories[ $index ])) {
143: $_index_dirs[] = $_directories[ $index ];
144: } else {
145: // try at location index
146: $keys = array_keys($_directories);
147: if (isset($_directories[ $keys[ $index ] ])) {
148: $_index_dirs[] = $_directories[ $keys[ $index ] ];
149: }
150: }
151: }
152: }
153: if (empty($_index_dirs)) {
154: // index not found
155: return false;
156: } else {
157: $_directories = $_index_dirs;
158: }
159: }
160: // relative file name?
161: foreach ($_directories as $_directory) {
162: $path = $_directory . $file;
163: if (is_file($path)) {
164: return (strpos($path, '.' . DIRECTORY_SEPARATOR) !== false) ? $source->smarty->_realpath($path) : $path;
165: }
166: }
167: if (!isset($_index_dirs)) {
168: // Could be relative to cwd
169: $path = $source->smarty->_realpath($file, true);
170: if (is_file($path)) {
171: return $path;
172: }
173: }
174: // Use include path ?
175: if ($source->smarty->use_include_path) {
176: return $source->smarty->ext->_getIncludePath->getIncludePath($_directories, $file, $source->smarty);
177: }
178: return false;
179: }
180: }
181: