Source for file Crafty_Block.class.php

Documentation is available at Crafty_Block.class.php

  1. <?PHP
  2.  
  3. /**
  4. * Implementation file of the Crafty_Block 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_Block.class.php
  13. * DESCRIPTION: Implementation file of the Crafty_Block 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_Compiler
  31. * @author Crafty Team <crafty@zulan.net>
  32. * @copyright Copyright (c) Thomas Ilsche 2005
  33. * @version 1.0.4.2005.02.18
  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_Block class implementation
  41. *
  42. * Any crafty block will get it's own Crafty_Block instance with individual
  43. * {@link $content}.<br/>
  44. * Each time the block is used static it will be cloned at compile time
  45. * from {@link Crafty_Compiler::$blocks} and compiled itsself.
  46. *
  47. * @package Crafty_Compiler
  48. * @author Crafty Team <crafty@zulan.net>
  49. * @copyright Copyright (c) Thomas Ilsche 2005
  50. * @version 1.0.4.2005.02.18
  51. * @link http://crafty.zulan.net
  52. * @license http://www.gnu.org/licenses/lgpl.html
  53. * GNU Lesser General Public License Version 2.1
  54. ***/
  55. class Crafty_Block
  56. {
  57.  
  58. /**
  59. * Stores all data the block needs to compile
  60. *
  61. * This is a list of object handles of Crafty_Core_* objects and
  62. * corresponding datasets or other Crafty_Block instances.<br/>
  63. * Since this will be compiled recursively by {@link compileElement()}
  64. * it can be a complex "tree" of arrays.
  65. *
  66. * @var array
  67. ***/
  68. public $content = array();
  69.  
  70. /**
  71. * Object handle of the {@link Crafty_Compiler} for this block.
  72. *
  73. * @var Crafty_Compiler
  74. ***/
  75. public $compiler;
  76.  
  77. /**
  78. * Stores the the name of the block or it's linearized adresses
  79. *
  80. * The original parsed blocks will have it's name in here and the cloned ones
  81. * for static compilation will have it's linearized adresses. For variable
  82. * blocks that are compiled into separate files the blocks of
  83. * {@link Crafty_Compiler::$blocks} will get a variable name/adress using $p.
  84. *
  85. * @var string
  86. ***/
  87. public $name;
  88.  
  89. /**
  90. * Filename where the block is defined
  91. *
  92. * @var string
  93. ***/
  94. public $filename = '';
  95.  
  96. /**
  97. * Line number of the block declaration in the definition file
  98. *
  99. * @var int
  100. ***/
  101. public $line_decl = -1;
  102.  
  103. /**
  104. * Line number of the content begining in the definition file
  105. *
  106. * @var int
  107. ***/
  108. public $line_cont = -1;
  109.  
  110. /**
  111. * The raw content of the block used for error tracing
  112. *
  113. * @var string
  114. ***/
  115. public $raw_content = '';
  116.  
  117. /**
  118. * The path to the template file that generated this block
  119. *
  120. * Set by the constructor using {@link Crafty_Compiler::template_path}
  121. * that is reset by recursion
  122. *
  123. * @var string
  124. ***/
  125. public $template_path;
  126.  
  127. /**
  128. * Defines if a blocks content is stored in an external file
  129. *
  130. * @var bool
  131. ***/
  132. public $is_external = FALSE;
  133.  
  134.  
  135. /**
  136. * Initializes a Crafty_Block instance
  137. *
  138. * The constructor intializes a Crafty_Block instance and sets the
  139. * {@link $name} aswell as the {@link $compiler}.
  140. *
  141. * @param string $name Name of the current block
  142. * @param Crafty_Compiler $compiler Crafty_Compiler object that created
  143. * this Block
  144. ***/
  145. public function __construct($name, crafty_compiler $compiler)
  146. {
  147. $this->name = $name;
  148. $this->compiler = $compiler;
  149. $this->template_path = $compiler->template_path;
  150. }
  151.  
  152. /**
  153. * Compiles a block
  154. *
  155. * This method will compile a block {@link compileElement() compiling}
  156. * all elements} of the {@link $content}.
  157. **/
  158.  
  159. public function compile()
  160. {
  161. ksort($this->content, SORT_NUMERIC);
  162. foreach ($this->content as $element) {
  163. $this->compileElement($element);
  164. }
  165. }
  166.  
  167. /**
  168. * Recursively compile an Element
  169. *
  170. * In case the Element is a {@link Crafty_Block} object this method will
  171. * use its {@link compile()} method.<br/>
  172. * In case it is an array with a "core" index it writes the returned data of
  173. * {@link compileType()} in the binary template file.<br/>
  174. * In case it is a different array it will recursively handle the elements.<br/>
  175. * Otherwise it assumes that the Element a string or something castable as
  176. * string and writes it in the compiled templates. The last way however is
  177. * not currently used.
  178. *
  179. * @param mixed $element
  180. ***/
  181. protected function compileElement($element)
  182. {
  183. if ($element instanceof Crafty_Block) {
  184. $element->compile();
  185. } elseif (is_array($element)) {
  186. if (isset($element['core'])) {
  187. fputs($this->compiler->write_c_file_handle,
  188. $this->compileType($element));
  189. } else {
  190. ksort($element, SORT_NUMERIC);
  191. foreach ($element as $element_i) {
  192. $this->compileElement($element_i);
  193. }
  194. }
  195. } else {
  196. fputs($this->compiler->write_c_file_handle, $element);
  197. }
  198. }
  199.  
  200. /**
  201. * Compiles a set of a core handler and a dataset
  202. *
  203. * This method makes use of the {@link Crafty_Core::compile()}.
  204. *
  205. * @param array $element Element to compile
  206. * @return string Binary data
  207. ***/
  208. protected function compileType($element)
  209. {
  210. try {
  211. $r = $element['core']->compile($element['data'], $this);
  212. } catch ( Crafty_Exception $e ) {
  213. $e->line = $element['line'];
  214. $e->file = $this->filename;
  215. throw $e;
  216. }
  217. return $r;
  218. }
  219.  
  220. /**
  221. * Loads a raw blow of CraftyHTML
  222. *
  223. * First this method replaces the {@link Crafty_Compiler::$preparse_search}
  224. * preparse needles} with the {@link Crafty_Compiler::$preparse_replace}
  225. * preparse replacements}. Then it will try to match each {@link }
  226. * Crafty_Core::getPattern() core pattern}. On success it will hand over the
  227. * results to {@link Crafty_Core::pregCallback()}.<br/>
  228. * All parts of the CraftyHTML that are not matched by any core will be handed
  229. * to a {@link Crafty_Core_String} object.
  230. *
  231. * @param string $raw_content
  232. ***/
  233. public function load($raw_content)
  234. {
  235. /* We replace \\ , \' and \" for a better preg matching */
  236. $this->raw_content = $raw_content;
  237. $raw_content = str_replace($this->compiler->preparse_search,
  238. $this->compiler->preparse_replace,
  239. $raw_content);
  240.  
  241. /* Strip the comments */
  242. $pattern = preg_quote($this->compiler->config->core->comment->left, '/')
  243. . '.*?'
  244. . preg_quote($this->compiler->config->core->comment->right, '/');
  245. $pattern = "/($pattern\\r?\\n?)/se";
  246. $replace = '$this->compiler->config->core->comment->left.'
  247. . 'preg_replace(\'/[^\r\n]/\',\'\',\'\\1\')'
  248. . '.$this->compiler->config->core->comment->right';
  249. $raw_content = preg_replace($pattern, $replace, $raw_content);
  250.  
  251. $marker = array();
  252. foreach ($this->compiler->cores as $x => $core) {
  253. if ($core->getPattern()
  254. && (preg_match_all($core->getPattern(), $raw_content, $matches,
  255. PREG_SET_ORDER | PREG_OFFSET_CAPTURE)
  256. !== FALSE)) {
  257. foreach($matches as $match_num => $match) {
  258. $callback_handover = array();
  259. foreach($match as $sub) {
  260. $callback_handover[] = $sub[0];
  261. }
  262.  
  263. try {
  264. $this->content[$match[0][1]] =
  265. $core->pregCallback($callback_handover);
  266. } catch (Crafty_Exception $e) {
  267. $e->file = $this->filename;
  268. $e->line = $this->compiler->line_number($raw_content,
  269. $match[0][1], $this->line_cont);
  270. throw $e;
  271. }
  272. $this->content[$match[0][1]]['line'] = $this->compiler->
  273. line_number($raw_content, $match[0][1], $this->line_cont);
  274.  
  275. $marker[$match[0][1]] = strlen($match[0][0]);
  276. }
  277. }
  278. }
  279. /* Now it gets tricky. All noncaptured characters will be given to a
  280. core_string obj */
  281. if (!isset($this->compiler->cores['Crafty_Core_String'])
  282. || !($this->compiler->cores['Crafty_Core_String'] instanceof
  283. crafty_core_string)) {
  284. throw new Crafty_Exception('Crafty_Core_String object missing or bogus,
  285. check the "core/Crafty_Core_String.class.php"
  286. file.');
  287. }
  288. $obj = $this->compiler->cores['Crafty_Core_String'];
  289. $marker[strlen($raw_content)] = 0; /* This is finish.. but not the end */
  290. ksort($marker);
  291. $start = 0;
  292. foreach($marker as $offset => $length) {
  293. if ($start < $offset) {
  294. $string = substr($raw_content, $start, ($offset - $start));
  295. $this->content[$start] = array('core' => $obj,
  296. 'data' => array('string' => $string));
  297. }
  298. $start = $offset + $length;
  299. }
  300. }
  301.  
  302. /**
  303. * Returns the linearized adress of the current block
  304. *
  305. * This method makes use of the {@link $name} but strips of the
  306. * "main." prefix.<br/>
  307. * If a suffix is set this will be conatenated to the adress path.
  308. * Useful for getting the adress of a subelement of the current block.
  309. *
  310. * @param string $suffix [optional,default=''] Element suffix
  311. * @return string Linearized adress of the current block
  312. ***/
  313. public function getVarPrefix($suffix = '')
  314. {
  315. /* we just need to strip off the "main." of the name. Thus we can use substr
  316. for now */
  317. return substr($this->name . '.' . $suffix, 5);
  318. }
  319.  
  320.  
  321. /**
  322. * Convert a $data entry to snippet that can be written in our compiled template.
  323. *
  324. * If $add_quotes is TRUE the snippet can be used just like echo <snippet>;<br/>
  325. * If $add_quotes is FALSE the snippet can be used inside single quoted strings.
  326. * <br/>
  327. * If $parse_array is true this will be done on all elements of the
  328. * $param['array'] array and an array of snippets will be returned.
  329. *
  330. * @param array $param
  331. * @param boolean $add_quotes [default=TRUE]
  332. * @param boolean $parse_array [default=FALSE]
  333. * @return mixed
  334. ***/
  335. public function varToStatic($param, $add_quotes = TRUE, $parse_array = FALSE)
  336. {
  337. if ($parse_array) {
  338. $return = array();
  339. foreach ($param['array'] as $key => $param_a) {
  340. $return[$key] = $this->varToStatic($param_a, $add_quotes, FALSE);
  341. }
  342. } elseif (isset($param['variable'])) {
  343. $return = "\$d['" . $this->getVarPrefix() . $param['variable'] . "']";
  344. if (!$add_quotes) {
  345. $return = "'.$return.'";
  346. }
  347. } elseif (isset($param['global'])) {
  348. $return = "\$d['" . $param['global'] . "']";
  349. if (!$add_quotes) {
  350. $return = "'.$return.'";
  351. }
  352. } else {
  353. $return = $param['static'];
  354. if ($add_quotes) {
  355. $return = "'$return'";
  356. }
  357. }
  358. return $return;
  359. }
  360. }
  361. ?>

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