PHP Classes

File: libs/smarty/sysplugins/smarty_resource.php

Recommend this page to a friend!
  Classes of Ali Sharifi   MVC 4 Dummies   libs/smarty/sysplugins/smarty_resource.php   Download  
File: libs/smarty/sysplugins/smarty_resource.php
Role: Auxiliary script
Content type: text/plain
Description: smarty lib
Class: MVC 4 Dummies
Web development PHP MVC framework
Author: By
Last change:
Date: 9 years ago
Size: 29,943 bytes
 

Contents

Class file image Download
<?php /** * Smarty Resource Plugin * * @package Smarty * @subpackage TemplateResources * @author Rodney Rehm */ /** * Smarty Resource Plugin * Base implementation for resource plugins * * @package Smarty * @subpackage TemplateResources */ abstract class Smarty_Resource { /** * cache for Smarty_Template_Source instances * * @var array */ public static $sources = array(); /** * cache for Smarty_Template_Compiled instances * * @var array */ public static $compileds = array(); /** * cache for Smarty_Resource instances * * @var array */ public static $resources = array(); /** * resource types provided by the core * * @var array */ protected static $sysplugins = array( 'file' => true, 'string' => true, 'extends' => true, 'stream' => true, 'eval' => true, 'php' => true ); /** * Name of the Class to compile this resource's contents with * * @var string */ public $compiler_class = 'Smarty_Internal_SmartyTemplateCompiler'; /** * Name of the Class to tokenize this resource's contents with * * @var string */ public $template_lexer_class = 'Smarty_Internal_Templatelexer'; /** * Name of the Class to parse this resource's contents with * * @var string */ public $template_parser_class = 'Smarty_Internal_Templateparser'; /** * Load template's source into current template object * {@internal The loaded source is assigned to $_template->source->content directly.}} * * @param Smarty_Template_Source $source source object * * @return string template source * @throws SmartyException if source cannot be loaded */ abstract public function getContent(Smarty_Template_Source $source); /** * populate Source Object with meta data from Resource * * @param Smarty_Template_Source $source source object * @param Smarty_Internal_Template $_template template object */ abstract public function populate(Smarty_Template_Source $source, Smarty_Internal_Template $_template = null); /** * populate Source Object with timestamp and exists from Resource * * @param Smarty_Template_Source $source source object */ public function populateTimestamp(Smarty_Template_Source $source) { // intentionally left blank } /** * modify resource_name according to resource handlers specifications * * @param Smarty $smarty Smarty instance * @param string $resource_name resource_name to make unique * @param boolean $is_config flag for config resource * * @return string unique resource name */ protected function buildUniqueResourceName(Smarty $smarty, $resource_name, $is_config = false) { if ($is_config) { return get_class($this) . '#' . $smarty->joined_config_dir . '#' . $resource_name; } else { return get_class($this) . '#' . $smarty->joined_template_dir . '#' . $resource_name; } } /** * populate Compiled Object with compiled filepath * * @param Smarty_Template_Compiled $compiled compiled object * @param Smarty_Internal_Template $_template template object */ public function populateCompiledFilepath(Smarty_Template_Compiled $compiled, Smarty_Internal_Template $_template) { $_compile_id = isset($_template->compile_id) ? preg_replace('![^\w\|]+!', '_', $_template->compile_id) : null; $_filepath = $compiled->source->uid; // if use_sub_dirs, break file into directories if ($_template->smarty->use_sub_dirs) { $_filepath = substr($_filepath, 0, 2) . DS . substr($_filepath, 2, 2) . DS . substr($_filepath, 4, 2) . DS . $_filepath; } $_compile_dir_sep = $_template->smarty->use_sub_dirs ? DS : '^'; if (isset($_compile_id)) { $_filepath = $_compile_id . $_compile_dir_sep . $_filepath; } // caching token if ($_template->caching) { $_cache = '.cache'; } else { $_cache = ''; } $_compile_dir = $_template->smarty->getCompileDir(); // set basename if not specified $_basename = $this->getBasename($compiled->source); if ($_basename === null) { $_basename = basename(preg_replace('![^\w\/]+!', '_', $compiled->source->name)); } // separate (optional) basename by dot if ($_basename) { $_basename = '.' . $_basename; } $compiled->filepath = $_compile_dir . $_filepath . '.' . $compiled->source->type . $_basename . $_cache . '.php'; } /** * Normalize Paths "foo/../bar" to "bar" * * @param string $_path path to normalize * @param boolean $ds respect windows directory separator * * @return string normalized path */ protected function normalizePath($_path, $ds = true) { if ($ds) { // don't we all just love windows? $_path = str_replace('\\', '/', $_path); } $offset = 0; // resolve simples $_path = preg_replace('#/\./(\./)*#', '/', $_path); // resolve parents while (true) { $_parent = strpos($_path, '/../', $offset); if (!$_parent) { break; } elseif ($_path[$_parent - 1] === '.') { $offset = $_parent + 3; continue; } $_pos = strrpos($_path, '/', $_parent - strlen($_path) - 1); if ($_pos === false) { // don't we all just love windows? $_pos = $_parent; } $_path = substr_replace($_path, '', $_pos, $_parent + 3 - $_pos); } if ($ds && DS != '/') { // don't we all just love windows? $_path = str_replace('/', '\\', $_path); } return $_path; } /** * build template filepath by traversing the template_dir array * * @param Smarty_Template_Source $source source object * @param Smarty_Internal_Template $_template template object * * @return string fully qualified filepath * @throws SmartyException if default template handler is registered but not callable */ protected function buildFilepath(Smarty_Template_Source $source, Smarty_Internal_Template $_template = null) { $file = $source->name; if ($source instanceof Smarty_Config_Source) { $_directories = $source->smarty->getConfigDir(); $_default_handler = $source->smarty->default_config_handler_func; } else { $_directories = $source->smarty->getTemplateDir(); $_default_handler = $source->smarty->default_template_handler_func; } // go relative to a given template? $_file_is_dotted = $file[0] == '.' && ($file[1] == '.' || $file[1] == '/' || $file[1] == "\\"); if ($_template && $_template->parent instanceof Smarty_Internal_Template && $_file_is_dotted) { if ($_template->parent->source->type != 'file' && $_template->parent->source->type != 'extends' && !$_template->parent->allow_relative_path) { throw new SmartyException("Template '{$file}' cannot be relative to template of resource type '{$_template->parent->source->type}'"); } $file = dirname($_template->parent->source->filepath) . DS . $file; $_file_exact_match = true; if (!preg_match('/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/', $file)) { // the path gained from the parent template is relative to the current working directory // as expansions (like include_path) have already been done $file = getcwd() . DS . $file; } } // resolve relative path if (!preg_match('/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/', $file)) { // don't we all just love windows? $_path = DS . trim($file, '/'); $_was_relative = true; } else { // don't we all just love windows? $_path = str_replace('\\', '/', $file); } $_path = $this->normalizePath($_path, false); if (DS != '/') { // don't we all just love windows? $_path = str_replace('/', '\\', $_path); } // revert to relative if (isset($_was_relative)) { $_path = substr($_path, 1); } // this is only required for directories $file = rtrim($_path, '/\\'); // files relative to a template only get one shot if (isset($_file_exact_match)) { return $this->fileExists($source, $file) ? $file : false; } // template_dir index? if (preg_match('#^\[(?P<key>[^\]]+)\](?P<file>.+)$#', $file, $match)) { $_directory = null; // try string indexes if (isset($_directories[$match['key']])) { $_directory = $_directories[$match['key']]; } elseif (is_numeric($match['key'])) { // try numeric index $match['key'] = (int) $match['key']; if (isset($_directories[$match['key']])) { $_directory = $_directories[$match['key']]; } else { // try at location index $keys = array_keys($_directories); $_directory = $_directories[$keys[$match['key']]]; } } if ($_directory) { $_file = substr($file, strpos($file, ']') + 1); $_filepath = $_directory . $_file; if ($this->fileExists($source, $_filepath)) { return $_filepath; } } } $_stream_resolve_include_path = function_exists('stream_resolve_include_path'); // relative file name? if (!preg_match('/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/', $file)) { foreach ($_directories as $_directory) { $_filepath = $_directory . $file; if ($this->fileExists($source, $_filepath)) { return $this->normalizePath($_filepath); } if ($source->smarty->use_include_path && !preg_match('/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/', $_directory)) { // try PHP include_path if ($_stream_resolve_include_path) { $_filepath = stream_resolve_include_path($_filepath); } else { $_filepath = Smarty_Internal_Get_Include_Path::getIncludePath($_filepath); } if ($_filepath !== false) { if ($this->fileExists($source, $_filepath)) { return $this->normalizePath($_filepath); } } } } } // try absolute filepath if ($this->fileExists($source, $file)) { return $file; } // no tpl file found if ($_default_handler) { if (!is_callable($_default_handler)) { if ($source instanceof Smarty_Config_Source) { throw new SmartyException("Default config handler not callable"); } else { throw new SmartyException("Default template handler not callable"); } } $_return = call_user_func_array($_default_handler, array($source->type, $source->name, &$_content, &$_timestamp, $source->smarty)); if (is_string($_return)) { $source->timestamp = @filemtime($_return); $source->exists = !!$source->timestamp; return $_return; } elseif ($_return === true) { $source->content = $_content; $source->timestamp = $_timestamp; $source->exists = true; return $_filepath; } } // give up return false; } /** * test is file exists and save timestamp * * @param Smarty_Template_Source $source source object * @param string $file file name * * @return bool true if file exists */ protected function fileExists(Smarty_Template_Source $source, $file) { $source->timestamp = is_file($file) ? @filemtime($file) : false; return $source->exists = !!$source->timestamp; } /** * Determine basename for compiled filename * * @param Smarty_Template_Source $source source object * * @return string resource's basename */ protected function getBasename(Smarty_Template_Source $source) { return null; } /** * Load Resource Handler * * @param Smarty $smarty smarty object * @param string $type name of the resource * * @throws SmartyException * @return Smarty_Resource Resource Handler */ public static function load(Smarty $smarty, $type) { // try smarty's cache if (isset($smarty->_resource_handlers[$type])) { return $smarty->_resource_handlers[$type]; } // try registered resource if (isset($smarty->registered_resources[$type])) { if ($smarty->registered_resources[$type] instanceof Smarty_Resource) { $smarty->_resource_handlers[$type] = $smarty->registered_resources[$type]; // note registered to smarty is not kept unique! return $smarty->_resource_handlers[$type]; } if (!isset(self::$resources['registered'])) { self::$resources['registered'] = new Smarty_Internal_Resource_Registered(); } if (!isset($smarty->_resource_handlers[$type])) { $smarty->_resource_handlers[$type] = self::$resources['registered']; } return $smarty->_resource_handlers[$type]; } // try sysplugins dir if (isset(self::$sysplugins[$type])) { if (!isset(self::$resources[$type])) { $_resource_class = 'Smarty_Internal_Resource_' . ucfirst($type); self::$resources[$type] = new $_resource_class(); } return $smarty->_resource_handlers[$type] = self::$resources[$type]; } // try plugins dir $_resource_class = 'Smarty_Resource_' . ucfirst($type); if ($smarty->loadPlugin($_resource_class)) { if (isset(self::$resources[$type])) { return $smarty->_resource_handlers[$type] = self::$resources[$type]; } if (class_exists($_resource_class, false)) { self::$resources[$type] = new $_resource_class(); return $smarty->_resource_handlers[$type] = self::$resources[$type]; } else { $smarty->registerResource($type, array( "smarty_resource_{$type}_source", "smarty_resource_{$type}_timestamp", "smarty_resource_{$type}_secure", "smarty_resource_{$type}_trusted" )); // give it another try, now that the resource is registered properly return self::load($smarty, $type); } } // try streams $_known_stream = stream_get_wrappers(); if (in_array($type, $_known_stream)) { // is known stream if (is_object($smarty->security_policy)) { $smarty->security_policy->isTrustedStream($type); } if (!isset(self::$resources['stream'])) { self::$resources['stream'] = new Smarty_Internal_Resource_Stream(); } return $smarty->_resource_handlers[$type] = self::$resources['stream']; } // TODO: try default_(template|config)_handler // give up throw new SmartyException("Unknown resource type '{$type}'"); } /** * extract resource_type and resource_name from template_resource and config_resource * @note "C:/foo.tpl" was forced to file resource up till Smarty 3.1.3 (including). * * @param string $resource_name template_resource or config_resource to parse * @param string $default_resource the default resource_type defined in $smarty * @param string &$name the parsed resource name * @param string &$type the parsed resource type * * @return void */ protected static function parseResourceName($resource_name, $default_resource, &$name, &$type) { $parts = explode(':', $resource_name, 2); if (!isset($parts[1]) || !isset($parts[0][1])) { // no resource given, use default // or single character before the colon is not a resource type, but part of the filepath $type = $default_resource; $name = $resource_name; } else { $type = $parts[0]; $name = $parts[1]; } } /** * modify resource_name according to resource handlers specifications * * @param Smarty $smarty Smarty instance * @param string $resource_name resource_name to make unique * * @return string unique resource name */ /** * modify template_resource according to resource handlers specifications * * @param Smarty_Internal_template $template Smarty instance * @param string $template_resource template_resource to extract resource handler and name of * * @return string unique resource name */ public static function getUniqueTemplateName($template, $template_resource) { self::parseResourceName($template_resource, $template->smarty->default_resource_type, $name, $type); // TODO: optimize for Smarty's internal resource types $resource = Smarty_Resource::load($template->smarty, $type); // go relative to a given template? $_file_is_dotted = $name[0] == '.' && ($name[1] == '.' || $name[1] == '/' || $name[1] == "\\"); if ($template instanceof Smarty_Internal_Template && $_file_is_dotted && ($template->source->type == 'file' || $template->parent->source->type == 'extends')) { $name = dirname($template->source->filepath) . DS . $name; } return $resource->buildUniqueResourceName($template->smarty, $name); } /** * initialize Source Object for given resource * Either [$_template] or [$smarty, $template_resource] must be specified * * @param Smarty_Internal_Template $_template template object * @param Smarty $smarty smarty object * @param string $template_resource resource identifier * * @return Smarty_Template_Source Source Object */ public static function source(Smarty_Internal_Template $_template = null, Smarty $smarty = null, $template_resource = null) { if ($_template) { $smarty = $_template->smarty; $template_resource = $_template->template_resource; } // parse resource_name, load resource handler, identify unique resource name self::parseResourceName($template_resource, $smarty->default_resource_type, $name, $type); $resource = Smarty_Resource::load($smarty, $type); // go relative to a given template? $_file_is_dotted = isset($name[0]) && $name[0] == '.' && ($name[1] == '.' || $name[1] == '/' || $name[1] == "\\"); if ($_file_is_dotted && isset($_template) && $_template->parent instanceof Smarty_Internal_Template && ($_template->parent->source->type == 'file' || $_template->parent->source->type == 'extends')) { $name2 = dirname($_template->parent->source->filepath) . DS . $name; } else { $name2 = $name; } $unique_resource_name = $resource->buildUniqueResourceName($smarty, $name2); // check runtime cache $_cache_key = 'template|' . $unique_resource_name; if ($smarty->compile_id) { $_cache_key .= '|' . $smarty->compile_id; } if (isset(self::$sources[$_cache_key])) { return self::$sources[$_cache_key]; } // create source $source = new Smarty_Template_Source($resource, $smarty, $template_resource, $type, $name, $unique_resource_name); $resource->populate($source, $_template); // runtime cache self::$sources[$_cache_key] = $source; return $source; } /** * initialize Config Source Object for given resource * * @param Smarty_Internal_Config $_config config object * * @throws SmartyException * @return Smarty_Config_Source Source Object */ public static function config(Smarty_Internal_Config $_config) { static $_incompatible_resources = array('eval' => true, 'string' => true, 'extends' => true, 'php' => true); $config_resource = $_config->config_resource; $smarty = $_config->smarty; // parse resource_name self::parseResourceName($config_resource, $smarty->default_config_type, $name, $type); // make sure configs are not loaded via anything smarty can't handle if (isset($_incompatible_resources[$type])) { throw new SmartyException ("Unable to use resource '{$type}' for config"); } // load resource handler, identify unique resource name $resource = Smarty_Resource::load($smarty, $type); $unique_resource_name = $resource->buildUniqueResourceName($smarty, $name, true); // check runtime cache $_cache_key = 'config|' . $unique_resource_name; if (isset(self::$sources[$_cache_key])) { return self::$sources[$_cache_key]; } // create source $source = new Smarty_Config_Source($resource, $smarty, $config_resource, $type, $name, $unique_resource_name); $resource->populate($source, null); // runtime cache self::$sources[$_cache_key] = $source; return $source; } } /** * Smarty Resource Data Object * Meta Data Container for Template Files * * @package Smarty * @subpackage TemplateResources * @author Rodney Rehm * @property integer $timestamp Source Timestamp * @property boolean $exists Source Existence * @property boolean $template Extended Template reference * @property string $content Source Content */ class Smarty_Template_Source { /** * Name of the Class to compile this resource's contents with * * @var string */ public $compiler_class = null; /** * Name of the Class to tokenize this resource's contents with * * @var string */ public $template_lexer_class = null; /** * Name of the Class to parse this resource's contents with * * @var string */ public $template_parser_class = null; /** * Unique Template ID * * @var string */ public $uid = null; /** * Template Resource (Smarty_Internal_Template::$template_resource) * * @var string */ public $resource = null; /** * Resource Type * * @var string */ public $type = null; /** * Resource Name * * @var string */ public $name = null; /** * Unique Resource Name * * @var string */ public $unique_resource = null; /** * Source Filepath * * @var string */ public $filepath = null; /** * Source is bypassing compiler * * @var boolean */ public $uncompiled = null; /** * Source must be recompiled on every occasion * * @var boolean */ public $recompiled = null; /** * The Components an extended template is made of * * @var array */ public $components = null; /** * Resource Handler * * @var Smarty_Resource */ public $handler = null; /** * Smarty instance * * @var Smarty */ public $smarty = null; /** * create Source Object container * * @param Smarty_Resource $handler Resource Handler this source object communicates with * @param Smarty $smarty Smarty instance this source object belongs to * @param string $resource full template_resource * @param string $type type of resource * @param string $name resource name * @param string $unique_resource unique resource name */ public function __construct(Smarty_Resource $handler, Smarty $smarty, $resource, $type, $name, $unique_resource) { $this->handler = $handler; // Note: prone to circular references $this->compiler_class = $handler->compiler_class; $this->template_lexer_class = $handler->template_lexer_class; $this->template_parser_class = $handler->template_parser_class; $this->uncompiled = $this->handler instanceof Smarty_Resource_Uncompiled; $this->recompiled = $this->handler instanceof Smarty_Resource_Recompiled; $this->smarty = $smarty; $this->resource = $resource; $this->type = $type; $this->name = $name; $this->unique_resource = $unique_resource; } /** * get a Compiled Object of this source * * @param Smarty_Internal_Template|Smarty_Internal_Config $_template template object * * @return Smarty_Template_Compiled compiled object */ public function getCompiled($_template) { // check runtime cache $_cache_key = $this->unique_resource . '#' . $_template->compile_id; if (isset(Smarty_Resource::$compileds[$_cache_key])) { return Smarty_Resource::$compileds[$_cache_key]; } $compiled = new Smarty_Template_Compiled($this); $this->handler->populateCompiledFilepath($compiled, $_template); $compiled->timestamp = @filemtime($compiled->filepath); $compiled->exists = !!$compiled->timestamp; // runtime cache Smarty_Resource::$compileds[$_cache_key] = $compiled; return $compiled; } /** * render the uncompiled source * * @param Smarty_Internal_Template $_template template object */ public function renderUncompiled(Smarty_Internal_Template $_template) { return $this->handler->renderUncompiled($this, $_template); } /** * <<magic>> Generic Setter. * * @param string $property_name valid: timestamp, exists, content, template * @param mixed $value new value (is not checked) * * @throws SmartyException if $property_name is not valid */ public function __set($property_name, $value) { switch ($property_name) { // regular attributes case 'timestamp': case 'exists': case 'content': // required for extends: only case 'template': $this->$property_name = $value; break; default: throw new SmartyException("invalid source property '$property_name'."); } } /** * <<magic>> Generic getter. * * @param string $property_name valid: timestamp, exists, content * * @return mixed * @throws SmartyException if $property_name is not valid */ public function __get($property_name) { switch ($property_name) { case 'timestamp': case 'exists': $this->handler->populateTimestamp($this); return $this->$property_name; case 'content': return $this->content = $this->handler->getContent($this); default: throw new SmartyException("source property '$property_name' does not exist."); } } } /** * Smarty Resource Data Object * Meta Data Container for Template Files * * @package Smarty * @subpackage TemplateResources * @author Rodney Rehm * @property string $content compiled content */ class Smarty_Template_Compiled { /** * Compiled Filepath * * @var string */ public $filepath = null; /** * Compiled Timestamp * * @var integer */ public $timestamp = null; /** * Compiled Existence * * @var boolean */ public $exists = false; /** * Compiled Content Loaded * * @var boolean */ public $loaded = false; /** * Template was compiled * * @var boolean */ public $isCompiled = false; /** * Source Object * * @var Smarty_Template_Source */ public $source = null; /** * Metadata properties * populated by Smarty_Internal_Template::decodeProperties() * * @var array */ public $_properties = null; /** * create Compiled Object container * * @param Smarty_Template_Source $source source object this compiled object belongs to */ public function __construct(Smarty_Template_Source $source) { $this->source = $source; } }