smarty_resource.php (9717B)
1 <?php 2 /** 3 * Smarty Resource Plugin 4 * 5 * @package Smarty 6 * @subpackage TemplateResources 7 * @author Rodney Rehm 8 */ 9 10 /** 11 * Smarty Resource Plugin 12 * Base implementation for resource plugins 13 * 14 * @package Smarty 15 * @subpackage TemplateResources 16 */ 17 abstract class Smarty_Resource 18 { 19 /** 20 * Source is bypassing compiler 21 * 22 * @var boolean 23 */ 24 public $uncompiled = false; 25 26 /** 27 * Source must be recompiled on every occasion 28 * 29 * @var boolean 30 */ 31 public $recompiled = false; 32 /** 33 * resource handler object 34 * 35 * @var Smarty_Resource 36 */ 37 public $handler = null; 38 /** 39 * cache for Smarty_Template_Source instances 40 * 41 * @var array 42 */ 43 public static $sources = array(); 44 /** 45 * cache for Smarty_Template_Compiled instances 46 * 47 * @var array 48 */ 49 public static $compileds = array(); 50 /** 51 * resource types provided by the core 52 * 53 * @var array 54 */ 55 protected static $sysplugins = array( 56 'file' => 'smarty_internal_resource_file.php', 57 'string' => 'smarty_internal_resource_string.php', 58 'extends' => 'smarty_internal_resource_extends.php', 59 'stream' => 'smarty_internal_resource_stream.php', 60 'eval' => 'smarty_internal_resource_eval.php', 61 'php' => 'smarty_internal_resource_php.php' 62 ); 63 64 /** 65 * Name of the Class to compile this resource's contents with 66 * 67 * @var string 68 */ 69 public $compiler_class = 'Smarty_Internal_SmartyTemplateCompiler'; 70 71 /** 72 * Name of the Class to tokenize this resource's contents with 73 * 74 * @var string 75 */ 76 public $template_lexer_class = 'Smarty_Internal_Templatelexer'; 77 78 /** 79 * Name of the Class to parse this resource's contents with 80 * 81 * @var string 82 */ 83 public $template_parser_class = 'Smarty_Internal_Templateparser'; 84 85 /** 86 * Load template's source into current template object 87 * {@internal The loaded source is assigned to $_template->source->content directly.}} 88 * 89 * @param Smarty_Template_Source $source source object 90 * 91 * @return string template source 92 * @throws SmartyException if source cannot be loaded 93 */ 94 abstract public function getContent(Smarty_Template_Source $source); 95 96 /** 97 * populate Source Object with meta data from Resource 98 * 99 * @param Smarty_Template_Source $source source object 100 * @param Smarty_Internal_Template $_template template object 101 */ 102 abstract public function populate(Smarty_Template_Source $source, Smarty_Internal_Template $_template = null); 103 104 /** 105 * populate Source Object with timestamp and exists from Resource 106 * 107 * @param Smarty_Template_Source $source source object 108 */ 109 public function populateTimestamp(Smarty_Template_Source $source) 110 { 111 // intentionally left blank 112 } 113 114 /** 115 * modify resource_name according to resource handlers specifications 116 * 117 * @param Smarty $smarty Smarty instance 118 * @param string $resource_name resource_name to make unique 119 * @param boolean $isConfig flag for config resource 120 * 121 * @return string unique resource name 122 */ 123 public function buildUniqueResourceName(Smarty $smarty, $resource_name, $isConfig = false) 124 { 125 if ($isConfig) { 126 return get_class($this) . '#' . $smarty->joined_config_dir . '#' . $resource_name; 127 } else { 128 return get_class($this) . '#' . $smarty->joined_template_dir . '#' . $resource_name; 129 } 130 } 131 132 /** 133 * Determine basename for compiled filename 134 * 135 * @param Smarty_Template_Source $source source object 136 * 137 * @return string resource's basename 138 */ 139 public function getBasename(Smarty_Template_Source $source) 140 { 141 return null; 142 } 143 144 /** 145 * Load Resource Handler 146 * 147 * @param Smarty $smarty smarty object 148 * @param string $type name of the resource 149 * 150 * @throws SmartyException 151 * @return Smarty_Resource Resource Handler 152 */ 153 public static function load(Smarty $smarty, $type) 154 { 155 // try smarty's cache 156 if (isset($smarty->_resource_handlers[$type])) { 157 return $smarty->_resource_handlers[$type]; 158 } 159 160 // try registered resource 161 if (isset($smarty->registered_resources[$type])) { 162 if ($smarty->registered_resources[$type] instanceof Smarty_Resource) { 163 $smarty->_resource_handlers[$type] = $smarty->registered_resources[$type]; 164 } else { 165 $smarty->_resource_handlers[$type] = new Smarty_Internal_Resource_Registered(); 166 } 167 168 return $smarty->_resource_handlers[$type]; 169 } 170 171 // try sysplugins dir 172 if (isset(self::$sysplugins[$type])) { 173 $_resource_class = 'Smarty_Internal_Resource_' . ucfirst($type); 174 if (!class_exists($_resource_class, false)) { 175 require SMARTY_SYSPLUGINS_DIR . self::$sysplugins[$type]; 176 } 177 return $smarty->_resource_handlers[$type] = new $_resource_class(); 178 } 179 180 // try plugins dir 181 $_resource_class = 'Smarty_Resource_' . ucfirst($type); 182 if ($smarty->loadPlugin($_resource_class)) { 183 if (class_exists($_resource_class, false)) { 184 return $smarty->_resource_handlers[$type] = new $_resource_class(); 185 } else { 186 $smarty->registerResource($type, array( 187 "smarty_resource_{$type}_source", 188 "smarty_resource_{$type}_timestamp", 189 "smarty_resource_{$type}_secure", 190 "smarty_resource_{$type}_trusted" 191 )); 192 // give it another try, now that the resource is registered properly 193 return self::load($smarty, $type); 194 } 195 } 196 197 // try streams 198 $_known_stream = stream_get_wrappers(); 199 if (in_array($type, $_known_stream)) { 200 // is known stream 201 if (is_object($smarty->security_policy)) { 202 $smarty->security_policy->isTrustedStream($type); 203 } 204 return $smarty->_resource_handlers[$type] = new Smarty_Internal_Resource_Stream();; 205 } 206 207 // TODO: try default_(template|config)_handler 208 209 // give up 210 throw new SmartyException("Unknown resource type '{$type}'"); 211 } 212 213 /** 214 * extract resource_type and resource_name from template_resource and config_resource 215 * @note "C:/foo.tpl" was forced to file resource up till Smarty 3.1.3 (including). 216 * 217 * @param string $resource_name template_resource or config_resource to parse 218 * @param string $default_resource the default resource_type defined in $smarty 219 * 220 * @return array with parsed resource name and type 221 */ 222 public static function parseResourceName($resource_name, $default_resource) 223 { 224 if (preg_match('/^([A-Za-z0-9_\-]{2,})[:]/', $resource_name, $match)) { 225 $type = $match[1]; 226 $name = substr($resource_name, strlen($match[0])); 227 } else { 228 // no resource given, use default 229 // or single character before the colon is not a resource type, but part of the filepath 230 $type = $default_resource; 231 $name = $resource_name; 232 233 } 234 return array($name, $type); 235 } 236 237 /** 238 * modify resource_name according to resource handlers specifications 239 * 240 * @param Smarty $smarty Smarty instance 241 * @param string $resource_name resource_name to make unique 242 * 243 * @return string unique resource name 244 */ 245 246 /** 247 * modify template_resource according to resource handlers specifications 248 * 249 * @param Smarty_Internal_template $template Smarty instance 250 * @param string $template_resource template_resource to extract resource handler and name of 251 * 252 * @return string unique resource name 253 */ 254 public static function getUniqueTemplateName($template, $template_resource) 255 { 256 $smarty = isset($template->smarty) ? $template->smarty : $template; 257 list($name, $type) = self::parseResourceName($template_resource, $smarty->default_resource_type); 258 // TODO: optimize for Smarty's internal resource types 259 $resource = Smarty_Resource::load($smarty, $type); 260 // go relative to a given template? 261 $_file_is_dotted = $name[0] == '.' && ($name[1] == '.' || $name[1] == '/'); 262 if ($template instanceof Smarty_Internal_Template && $_file_is_dotted && ($template->source->type == 'file' || $template->parent->source->type == 'extends')) { 263 $name = dirname($template->source->filepath) . DS . $name; 264 } 265 return $resource->buildUniqueResourceName($smarty, $name); 266 } 267 268 /** 269 * initialize Source Object for given resource 270 * wrapper for backward compatibility to versions < 3.1.22 271 * Either [$_template] or [$smarty, $template_resource] must be specified 272 * 273 * @param Smarty_Internal_Template $_template template object 274 * @param Smarty $smarty smarty object 275 * @param string $template_resource resource identifier 276 * 277 * @return Smarty_Template_Source Source Object 278 */ 279 public static function source(Smarty_Internal_Template $_template = null, Smarty $smarty = null, $template_resource = null) 280 { 281 return Smarty_Template_Source::load($_template, $smarty, $template_resource); 282 } 283 } 284