Source for file Crafty.class.php

Documentation is available at Crafty.class.php

  1. <?PHP
  2.  
  3. /**
  4. * Implementation file of the Crafty main class.
  5. *
  6. * <pre>
  7. * PROJECT : Crafty
  8. * Template Engine.
  9. * AUTHOR : Crafty Team <crafty@zulan.net>
  10. * COPYRIGHT : (c) Thomas Ilsche, 2004
  11. *
  12. * FILE : [ROOT]\Crafty.class.php
  13. * DESCRIPTION: Implementation file of the Crafty main class.
  14. * </pre>
  15. *
  16. * This library is free software; you can redistribute it and/or
  17. * modify it under the terms of the GNU Lesser General Public
  18. * License as published by the Free Software Foundation; either
  19. * version 2.1 of the License, or (at your option) any later version.
  20. *
  21. * This library is distributed in the hope that it will be useful,
  22. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  23. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  24. * Lesser General Public License for more details.
  25. *
  26. * You should have received a copy of the GNU Lesser General Public
  27. * License along with this library; if not, write to the Free Software
  28. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  29. *
  30. * @package Crafty
  31. * @author Crafty Team <crafty@zulan.net>
  32. * @copyright Copyright (c) Thomas Ilsche 2004
  33. * @version 1.0.4.2005.02.16
  34. * @link http://crafty.zulan.net
  35. * @license http://www.gnu.org/licenses/lgpl.html
  36. * GNU Lesser General Public License Version 2.1
  37. ***/
  38.  
  39. /**
  40. * Crafty version number
  41. **/
  42.  
  43. define('CRAFTY_VERSION', '1.0.4.2005.02.18');
  44.  
  45. /**#@+
  46. * Constant for use in {@link Crafty::display()}
  47. **/
  48.  
  49. /**
  50. * Compile if template file date is more recent than compiled template file
  51. * date. Counts only for the initial template file.
  52. * If you only changed a .block tpl then simply `touch` the initial template.
  53. **/
  54.  
  55. define('CRAFTY_COMPILE_AUTO', 1);
  56.  
  57. /**
  58. * Compile unconditionally whenever {@link Crafty::display()} is called.
  59. **/
  60.  
  61. define('CRAFTY_COMPILE_ALWAYS', 2);
  62.  
  63. /**
  64. * Never compile, except the include file does not exists.
  65. **/
  66.  
  67. define('CRAFTY_COMPILE_NEVER', 3);
  68. /**#@-*/ * Crafty main class implementation
  69. *
  70. * This is the main class of the Crafty template engine. You should always
  71. * instantiate this and make use of it's member functions. See also the Crafty
  72. * Usage and Syntax manual for further information.
  73. *
  74. * @package Crafty
  75. * @author Crafty Team <crafty@zulan.net>
  76. * @copyright Copyright (c) Thomas Ilsche
  77. * @version 1.0.4.2005.02.16
  78. * @link http://crafty.zulan.net
  79. * @license http://www.gnu.org/licenses/lgpl.html
  80. * GNU Lesser General Public License Version 2.1
  81. **/
  82. class Crafty
  83. {
  84. /**
  85. * Stores assigned values
  86. *
  87. * This array is used to store the values assigned to this template by
  88. * {@link assign()}, {@link assignRef()}, {@link append()} or
  89. * {@link appendRef()}.
  90. *
  91. * @var array
  92. * @access private
  93. ***/
  94. private $_output_data = array();
  95.  
  96. /**
  97. * Path to Crafty directory
  98. *
  99. * Stores the absolute path to the Crafty directory. It is set by the {@link }
  100. * __construct() constructor}, so you will have to pass it at least once.
  101. *
  102. * @var string
  103. ***/
  104. public $path_crafty;
  105.  
  106. /**
  107. * Root path to the compiled templates
  108. *
  109. * Stores the absolute path to the compiled template files. This is
  110. * automatically set by the constructor, you will not have to take care of it.
  111. *
  112. * @var string
  113. ***/
  114. public $path_templates_c;
  115.  
  116. /**
  117. * Object handle of a Compiler object
  118. *
  119. * If compiling is neccessary (display modes CRAFTY_COMPILE_AUTO and
  120. * CRAFTY_COMPILE_ALWAYS), this will contain an object handle of a
  121. * Crafty_Compiler object. It is only for internal use.
  122. *
  123. * @var Crafty_Compiler
  124. ***/
  125. public $compiler;
  126.  
  127. /**
  128. * Initializes a Crafty instance
  129. *
  130. * The constructor intializes a Crafty instance and sets up the neccessary
  131. * internal path variables. It also includes the {@link Crafty_Exception}
  132. * Exception classes}. You have to pass the absolute or relative path to
  133. * the constructor so Crafty can find it's files.<br />
  134. * <br />
  135. * From version 1.0.1 the parameter is optional and will be acquired using
  136. * the __FILE__ magic constant by default.
  137. *
  138. * @param string $path_crafty [optional] Path to the crafty directory
  139. ***/
  140. public function __construct($path_crafty = '')
  141. {
  142. if (empty($path_crafty)) {
  143. $path_crafty = dirname(__FILE__);
  144. } else {
  145. $path_crafty = realpath($path_crafty);
  146. }
  147. /* Backwards compabilitiy */
  148. $path_crafty = $path_crafty . DIRECTORY_SEPARATOR;
  149. require_once($path_crafty . 'Crafty_Exceptions.class.php');
  150. $this->path_crafty = $path_crafty;
  151. $this->path_templates_c = $path_crafty . 'templates_c' . DIRECTORY_SEPARATOR;
  152. }
  153.  
  154. /**
  155. * Assign a variable content
  156. *
  157. * This assigns a variable content to a template before its beeing displayed
  158. * by {@link display()}. If $extract is true and data is an associative array,
  159. * every key will be taken as sub-variable and the corresponding value as
  160. * sub-variable content. The array itself will still be assigned.
  161. * $extract also works recursive
  162. *
  163. * @param string $name Variable path and name
  164. * @param mixed $data Variable content
  165. * @param boolean $extract [optional, default=false] Whether or not to
  166. * extract an array as multiple variables.
  167. ***/
  168. public function assign($name, $data, $extract = FALSE)
  169. {
  170. $this->_output_data[$name] = $data;
  171. if ($extract && is_array($data)) {
  172. foreach($data as $key => $value) {
  173. $this->assign("$name.$key", $value, TRUE);
  174. }
  175. }
  176. }
  177.  
  178. /**
  179. * Assign variable content as reference
  180. *
  181. * This assigns a variable content as reference. So you can first assign
  182. * the variable and then manipulate it's content. There's no extraction for
  183. * references like in {@link assign()}.
  184. *
  185. * @param string $name Variable path and name
  186. * @param reference $data Variable reference
  187. ***/
  188. public function assignRef($name, &$data)
  189. {
  190. $this->_output_data[$name] = &$data;
  191. }
  192.  
  193. /**
  194. * Append a content to an data array
  195. *
  196. * Appends content $data to the assigned data array $name.
  197. * $data will allways be appended at the end.<br/>
  198. * If the array is not yet assigned, a new one will be created,
  199. * if only a value is set this value will be used as first element of the
  200. * array and $data as the second one.<br/>
  201. * If $index is set it will not just append to the main array but append
  202. * with a $index as key for the main array. However this will not influence
  203. * the order of the displayed blocks.<br/>
  204. * If $index_sub is set it will create and append the following array:<br/>
  205. * array($index_sub => $data) then the value of $index can be used as
  206. * variablename inside a blocklist, instead of $value. This is useful for
  207. * cascaded blocklists.
  208. *
  209. * @param string $name Variable path and name
  210. * @param mixed $data Variable content
  211. * @param string $index [optional, default=''] Index
  212. * for main array
  213. * @param string $index_sub [optional, default=''] Index
  214. * for subarray
  215. ***/
  216. public function append($name, $data, $index = '', $index_sub = '')
  217. {
  218. if (!empty($index_sub)) {
  219. $data = array($index_sub => $data);
  220. }
  221.  
  222. if (empty($index)) {
  223. if (!isset($this->_output_data[$name])) {
  224. $this->_output_data[$name] = array($data);
  225. } elseif (is_array($this->_output_data[$name])) {
  226. $this->_output_data[$name][] = $data;
  227. } else {
  228. $this->_output_data[$name] = array($this->_output_data[$name],
  229. $data);
  230. }
  231. } else {
  232. if (!isset($this->_output_data[$name])) {
  233. $this->_output_data[$name] = array($index => $data);
  234. } elseif (is_array($this->_output_data[$name])) {
  235. $this->_output_data[$name][$index] = $data;
  236. } else {
  237. $this->_output_data[$name] = array($this->_output_data[$name],
  238. $index => $data);
  239. }
  240. }
  241. }
  242.  
  243. /**
  244. * Append a reference to an data array
  245. *
  246. * Same as {@link append()}, but uses an reference instead of "real" values.
  247. *
  248. * @param string $name Variable path and name
  249. * @param mixed $data Variable content
  250. * @param string $index [optional, default=''] Index
  251. * for main array
  252. * @param string $index_sub [optional, default=''] Index
  253. * for subarray
  254. ***/
  255. public function appendRef($name, &$data, $index = '', $index_sub = '')
  256. {
  257. if (!empty($index_sub)) {
  258. $data = array($index_sub => &$data);
  259. }
  260.  
  261. if (empty($index)) {
  262. if (!isset($this->_output_data[$name])) {
  263. $this->_output_data[$name] = array(&$data);
  264. } elseif (is_array($this->_output_data[$name])) {
  265. $this->_output_data[$name][] = &$data;
  266. } else {
  267. $this->_output_data[$name] = array($this->_output_data[$name],
  268. &$data);
  269. }
  270. } else {
  271. if (!isset($this->_output_data[$name])) {
  272. $this->_output_data[$name] = array($index => &$data);
  273. } elseif (is_array($this->_output_data[$name])) {
  274. $this->_output_data[$name][$index] = &$data;
  275. } else {
  276. $this->_output_data[$name] = array($this->_output_data[$name],
  277. $index => &$data);
  278. }
  279. }
  280. }
  281.  
  282. /**
  283. * Display template
  284. *
  285. * Displays template $template_name in compilation mode $compile_mode. Call
  286. * this from your file after all values are assigned.
  287. *
  288. * @param string $template_name Filename of template to display
  289. * @param integer $compile_mode [optional, default=
  290. * {@link CRAFTY_COMPILE_AUTO}]<br/>
  291. * Compilation method.<br/>
  292. * Other possible values:<br/>
  293. * {@link CRAFTY_COMPILE_ALWAYS},
  294. * {@link CRAFTY_COMPILE_NEVER}
  295. * @return boolean State of success
  296. ***/
  297. public function display($template_name, $compile_mode = CRAFTY_COMPILE_AUTO)
  298. {
  299. $d =& $this->_output_data;
  300.  
  301. $template_hash = md5(realpath($template_name) . CRAFTY_VERSION);
  302. $template_c = $this->path_templates_c . $template_hash . '.tpl.php';
  303. ob_start();
  304. set_error_handler(array($this,'error_handler'));
  305. if (($compile_mode == CRAFTY_COMPILE_ALWAYS)
  306. || (!file_exists($template_c))
  307. || (($compile_mode == CRAFTY_COMPILE_AUTO) &&
  308. (filemtime($template_name) > filemtime($template_c)))
  309. || (FALSE === @include($template_c))) {
  310. try {
  311. require_once($this->path_crafty . 'Crafty_Compiler.class.php');
  312. $this->compiler = new crafty_compiler($this);
  313. $this->compiler->load($template_name);
  314. $this->compiler->compile($template_hash);
  315. if (!function_exists('_' . $template_hash . '_main')) {
  316. include($template_c);
  317. } else {
  318. call_user_func('_' . $template_hash . '_main','',$d);
  319. }
  320. } catch (Crafty_Exception $e) {
  321. ob_clean();
  322. exit($e->getFormattedMessage('HTML_FULL'));
  323. }
  324. }
  325. restore_error_handler();
  326. ob_flush();
  327. return TRUE;
  328. }
  329.  
  330. /**
  331. * Error handler method for compiled templates
  332. *
  333. * See {@link set_error_handler} for the parameters.
  334. **/
  335.  
  336. public function error_handler($errno, $errstr, $errfile, $errline, $errcontext)
  337. {
  338. ob_clean();
  339. echo '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"';
  340. echo '"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">';
  341. echo '<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">';
  342. echo '<head><title>Error</title>';
  343. echo '<body><h1>The following error occured in the compiled template:</h1>';
  344. echo "'<b>$errstr</b>' - in <b>$errfile</b> on line <b>$errline</b><br />";
  345. echo 'Undefined indexes are usually caused by missing assignes.<br />';
  346. echo 'Please check your code for missing assignes and your template for';
  347. echo ' references to unassigned variables.<br />';
  348. echo 'Include errors are caused by variable block(list)s that reference to';
  349. echo ' non compiled blocks. Do not forget to [REQUIRE file_1,file_2,file3]';
  350. echo ' if the files are external.';
  351. echo '</body></html>';
  352. exit;
  353. }
  354.  
  355. /**
  356. * Checks security integrity of a string
  357. *
  358. * This checks whether or not it is secure to print the string $param in a
  359. * template. If not, an exception will be thrown, and Crafty will refuse
  360. * further work.
  361. *
  362. * @param string $param String to check
  363. ***/
  364. public function securityCheck($param)
  365. {
  366. if (strstr($param, '../')) {
  367. throw new Crafty_Exception("Invalid parameter. Parameters must not
  368. contain '../'");
  369. }
  370. }
  371. }
  372.  
  373. ?>

Documentation generated on Sat, 19 Feb 2005 01:43:38 +0100 by phpDocumentor 1.3.0RC3