PageRenderTime 59ms CodeModel.GetById 30ms RepoModel.GetById 0ms app.codeStats 0ms

/Template.php

https://bitbucket.org/wl-framework-dev/weblab-framework
PHP | 350 lines | 157 code | 57 blank | 136 comment | 27 complexity | 0651fb25c193547fa755c273a825e648 MD5 | raw file
  1. <?php
  2. /**
  3. * Represents a PHP Template file
  4. *
  5. * @author Jorgen Evens <jorgen@wlab.be>
  6. * @package WebLab
  7. *
  8. */
  9. class WebLab_Template
  10. {
  11. /**
  12. *
  13. * @var stdClass Contains config for templates.
  14. */
  15. protected static $_config;
  16. /**
  17. * Contains the root template, if set.
  18. * @var WebLab_Template
  19. */
  20. protected static $_root;
  21. /**
  22. * Lazy load config.
  23. */
  24. protected static function _getConfig() {
  25. if( empty( self::$_config ) ) {
  26. self::$_config = WebLab_Config::getApplicationConfig()->get( 'Application.Templates', WebLab_Config::OBJECT, false );
  27. }
  28. return self::$_config;
  29. }
  30. /**
  31. * Set the root template for current request.
  32. * @param WebLab_Template $template
  33. */
  34. public static function setRootTemplate( WebLab_Template $template ) {
  35. self::$_root = $template;
  36. }
  37. /**
  38. * Get the root template for current request.
  39. */
  40. public static function &getRootTemplate() {
  41. return self::$_root;
  42. }
  43. /**
  44. * @var int The maximum age in seconds of a cached template.
  45. */
  46. public $max_cache_age = 0;
  47. /**
  48. *
  49. * @var String Contains the path to the template file.
  50. */
  51. protected $_template;
  52. /**
  53. *
  54. * @var Array All variables assigned to this template.
  55. */
  56. protected $_variables;
  57. /**
  58. *
  59. * @var String The directory in which to search for the templates.
  60. */
  61. protected $_dir;
  62. /**
  63. * @var String The directory of a specific theme. Defaults to 'source'.
  64. */
  65. protected $_theme = null;
  66. /**
  67. * @var string Determines if logic should be called.
  68. */
  69. protected $_setup = false;
  70. /**
  71. * Constructs a new Template
  72. * @param String $template The path to the template, relative to the configured template directory.
  73. * @param String $theme The name of the theme to be used. default theme is 'source'
  74. * @param String $directory The directory in which to look for the template. Defaults to configuration setting.
  75. */
  76. public function __construct( $template, $theme=null, $directory=null ) {
  77. $config = self::_getConfig();
  78. if( !empty( $directory ) && is_string( $directory ) ) {
  79. $this->setTemplateDir( $directory );
  80. } elseif( is_string( $config->directory ) ) {
  81. $this->setTemplateDir( $config->directory );
  82. }
  83. if( $theme === null && !empty( $config->theme ) && is_string( $config->theme ) ) {
  84. $this->setTheme( $config->theme );
  85. }
  86. if( is_string( $theme ) ) {
  87. $this->setTheme( $theme );
  88. }
  89. //$variables['variables'] = array();
  90. $this->_variables = array();
  91. if( !is_string( $template ) ) {
  92. throw new WebLab_Exception_Template( 'Template name shoud refer to the path within the theme.' );
  93. }
  94. $this->_template = $template;
  95. $this->_init();
  96. $this->setBasicVariables();
  97. }
  98. /**
  99. * Set some default settings for a template.
  100. */
  101. protected function setBasicVariables() {}
  102. /**
  103. * Attaches a template as a variable to this template.
  104. * @param WebLab_Template $template Template you would like to attach to this template.
  105. * @param String $moduleName Variable name for $template.
  106. * @return WebLab_Template This template instance.
  107. * @deprecated Use WebLab_Template::set now.
  108. */
  109. public function attach( WebLab_Template &$template, $moduleName ) {
  110. $this->_variables[ $moduleName ] = &$template;
  111. return $this;
  112. }
  113. /**
  114. * Set a template variable value.
  115. *
  116. * @param string $variable
  117. * @param mixed $value
  118. * @return WebLab_Template
  119. */
  120. public function set( $variable, $value ) {
  121. $this->_variables[ $variable ] = $value;
  122. return $this;
  123. }
  124. /**
  125. * Get a template variable.
  126. *
  127. * @param string $variable
  128. * @return mixed:
  129. */
  130. public function get( $variable ) {
  131. if( isset( $this->_variables[ $variable ] ) ) {
  132. return $this->_variables[ $variable ];
  133. }
  134. return null;
  135. }
  136. /**
  137. * Set the theme folder within the template directory.
  138. * @param String $dir Foldername of the theme.
  139. * @return WebLab_Template This template instance.
  140. */
  141. public function setTheme( $dir ) {
  142. $this->_theme = $dir;
  143. return $this;
  144. }
  145. /**
  146. * Set the location of the template directory.
  147. * This directory contains all of the themes.
  148. * @param String $dir The directory to look for templates and themes.
  149. */
  150. public function setTemplateDir( $dir ) {
  151. $this->_dir = $dir;
  152. return $this;
  153. }
  154. /**
  155. * Get the entire stack of variables currently attached to this template.
  156. * @return Array Return an array of attached variables. VariableNames as keys.
  157. */
  158. public function getVars() {
  159. return $this->_variables;
  160. }
  161. /**
  162. * Catches all the property calls to set the appropriate variable.
  163. * @param String $name The name of the property (variable) being set.
  164. * @param Object &$value The value to be set.
  165. * @return WebLab_Template This template instance.
  166. */
  167. public function __set( $name, $value ) {
  168. $this->_variables[ $name ] = &$value;
  169. return $this;
  170. }
  171. /**
  172. * Catches all the property calls to return the appropriate variable.
  173. * @param String $name The name of the property (variable) te get.
  174. * @return Object The value of this property.
  175. */
  176. public function &__get( $name ) {
  177. return $this->_variables[ $name ];
  178. }
  179. /**
  180. * Renders the template to its compiled HTML form.
  181. * @param bool $show Whether to send the output to the browser requesting it. Defaults to false.
  182. * @return mixed The HTML code rendered or true if $show==true
  183. */
  184. public function render( $flush=true ) {
  185. if( !$this->_setup ) {
  186. $this->_setup = true;
  187. $this->_load( 'setup' );
  188. }
  189. if( $flush ) {
  190. $this->_load();
  191. flush();
  192. return true;
  193. }
  194. ob_start();
  195. $this->_load();
  196. return ob_get_clean();
  197. }
  198. /**
  199. * Include a component file for current template
  200. * $component will be attached behind the filename, including a suffix .php
  201. *
  202. * @param string $component
  203. * @param array $variables
  204. */
  205. protected function _load( $component='', $extract=true ) {
  206. if( !empty( $component ) ) {
  207. $component = '.' . $component;
  208. }
  209. $namespace = explode( NAMESPACE_SEPARATOR, $this->_template );
  210. $name = array_pop( $namespace );
  211. $namespace = implode( DIRECTORY_SEPARATOR, $namespace );
  212. $theme = $this->_theme;
  213. if( !empty( $theme ) )
  214. $theme .= '/';
  215. $path = $this->_dir . '/' . $theme . $name . $component . '.php';
  216. if( isset( self::_getConfig()->extract_vars ) && self::_getConfig()->extract_vars && $extract ) {
  217. extract( $this->_variables );
  218. }
  219. // Load the template
  220. $error_report = error_reporting();
  221. error_reporting( $error_report & ( E_ALL ^ E_WARNING ) );
  222. $exists = !!include( $path );
  223. if( !$exists && !empty( $namespace ) ) {
  224. $exists = !!include( $namespace . DIRECTORY_SEPARATOR . $path );
  225. }
  226. error_reporting( $error_report );
  227. if( $exists === false && empty( $component ) ) {
  228. throw new WebLab_Exception_Template( 'Template (' . $this->_template . ') not found!' );
  229. }
  230. }
  231. /**
  232. * Loads the init component of a template.
  233. * Injecting headers, scripts or styles should be done here.
  234. */
  235. protected function _init() {
  236. $this->_load( 'init', false );
  237. }
  238. /**
  239. * Retrieve cached template
  240. * @return string|NULL
  241. */
  242. protected function _getCache( $path ) {
  243. if( file_exists( $path ) && ( time() - filemtime( $path ) ) < $this->max_cache_age ) {
  244. return file_get_contents( $path, true );
  245. }
  246. return null;
  247. }
  248. /**
  249. * Put cached code
  250. * @param string $code
  251. */
  252. protected function _putCache( $path, $code ) {
  253. $folder = dirname( $path );
  254. if( !is_dir( $folder ) ) {
  255. mkdir( $folder, 0755, true );
  256. }
  257. if( !empty( $this->max_cache_age ) ) {
  258. file_put_contents( $path, $code );
  259. }
  260. }
  261. /**
  262. * Returns the value of the function render.
  263. * @return String Returns HTML that has been rendered by the render function. If a Exception occurs the message of this exception will be returned.
  264. */
  265. final public function __toString() {
  266. try {
  267. /*
  268. * Hot path for uncached templates.
  269. */
  270. if( empty( $this->max_cache_age ) ) {
  271. return $this->render( false );
  272. } else {
  273. /*
  274. * Slower path, cache lookup
  275. */
  276. $cache_dir = $path = WebLab_Config::getApplicationConfig()->get( 'Application.Templates.cache_dir', WebLab_Config::RAW );
  277. $theme_dir = empty( $this->_theme ) ? '/' : '/' . $this->_theme . '/';
  278. $param = md5( serialize( $this->_variables ) );
  279. $cache_file = $theme_dir . $this->_template . $param . '.php';
  280. $cache_file = $_SERVER['DOCUMENT_ROOT'] . BASE . $cache_dir . '/' . $theme_dir . md5( $cache_file );
  281. $cache = $this->_getCache( $cache_file );
  282. if( !empty( $cache ) ) {
  283. return $cache;
  284. }
  285. $code = $this->render( false );
  286. $this->_putCache( $cache_file, $code );
  287. return $code;
  288. }
  289. } catch( Exception $ex ) {
  290. return $ex->getMessage();
  291. }
  292. }
  293. }