Location: PHPKode > projects > SithTemplate > SithTemplate-1.1/docs/html/_compiler_ex_8php_source.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<title>SithTemplate: CompilerEx.php Source File</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<link href="doxygen.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<!-- Generated by Doxygen 1.7.2 -->
<div class="navigation" id="top">
  <div class="tabs">
    <ul class="tablist">
      <li><a href="index.html"><span>Main&#160;Page</span></a></li>
      <li><a href="pages.html"><span>Related&#160;Pages</span></a></li>
      <li><a href="annotated.html"><span>Classes</span></a></li>
      <li class="current"><a href="files.html"><span>Files</span></a></li>
      <li><a href="examples.html"><span>Examples</span></a></li>
    </ul>
  </div>
  <div class="tabs2">
    <ul class="tablist">
      <li><a href="files.html"><span>File&#160;List</span></a></li>
      <li><a href="globals.html"><span>File&#160;Members</span></a></li>
    </ul>
  </div>
<div class="header">
  <div class="headertitle">
<h1>CompilerEx.php</h1>  </div>
</div>
<div class="contents">
<a href="_compiler_ex_8php.html">Go to the documentation of this file.</a><div class="fragment"><pre class="fragment"><a name="l00001"></a>00001 &lt;?php
<a name="l00029"></a><a class="code" href="class_template_compiler_ex.html">00029</a> <span class="keyword">class </span><a class="code" href="class_template_compiler_ex.html" title="Primary compiler driver.">TemplateCompilerEx</a> {
<a name="l00033"></a><a class="code" href="class_template_compiler_ex.html#a7436ce4d99eb25b14012d0fea3329545">00033</a>  <span class="keyword">public</span> <a class="code" href="class_template_compiler_ex.html#a7436ce4d99eb25b14012d0fea3329545" title="Current settings (reference to TemplateEnviron::$settings).">$settings</a> = null;
<a name="l00034"></a>00034  
<a name="l00035"></a>00035  <span class="comment">// Plugins part</span>
<a name="l00039"></a><a class="code" href="class_template_compiler_ex.html#ac6a93435059bcde30df1f24bfbfa53e3">00039</a> <span class="comment"></span> <span class="keyword">public</span> <a class="code" href="class_template_compiler_ex.html#ac6a93435059bcde30df1f24bfbfa53e3" title="Registry of available plugins.">$plugins</a>       = null;
<a name="l00043"></a><a class="code" href="class_template_compiler_ex.html#ae1e96f5d9cdab5a8cef660e9bd0347c1">00043</a>  <span class="keyword">public</span> <a class="code" href="class_template_compiler_ex.html#ae1e96f5d9cdab5a8cef660e9bd0347c1" title="Registry of loaded plugins (per-template).">$loadedPlugins</a> = array();
<a name="l00044"></a>00044  
<a name="l00045"></a>00045  <span class="comment">// Parser part</span>
<a name="l00050"></a><a class="code" href="class_template_compiler_ex.html#a96c1fa9a15fb7c1a36a3a212073f97f4">00050</a> <span class="comment"></span> <span class="keyword">private</span> <a class="code" href="class_template_compiler_ex.html#a96c1fa9a15fb7c1a36a3a212073f97f4" title="Currently processed token.">$parserCurrentToken</a> = null;
<a name="l00054"></a><a class="code" href="class_template_compiler_ex.html#a04c4c26c3f5b84a7f2743fd6253fbce9">00054</a>  <span class="keyword">private</span> <a class="code" href="class_template_compiler_ex.html#a04c4c26c3f5b84a7f2743fd6253fbce9" title="Currently processed line (approx).">$parserCurrentLine</a>  = 1;
<a name="l00058"></a><a class="code" href="class_template_compiler_ex.html#af3d5cc74f7c0cc06676b50a5efe95112">00058</a>  <span class="keyword">private</span> <a class="code" href="class_template_compiler_ex.html#af3d5cc74f7c0cc06676b50a5efe95112" title="Currently processed template.">$parserCurrentFile</a>  = null;
<a name="l00062"></a><a class="code" href="class_template_compiler_ex.html#ab61b2762e9cea921fd26a4153067f983">00062</a>  <span class="keyword">private</span> <a class="code" href="class_template_compiler_ex.html#ab61b2762e9cea921fd26a4153067f983" title="Regular expression used to split template into tokens.">$parserTokenRegexp</a>  = <span class="stringliteral">&#39;~(\{\%.*?\%\})|(\{\{.*?\}\})|(\{\#.*?\#\})~u&#39;</span>;
<a name="l00063"></a>00063 
<a name="l00064"></a>00064  <span class="comment">// CodeGen part</span>
<a name="l00068"></a><a class="code" href="class_template_compiler_ex.html#a6c58447a001891500c54f1e9afc30b20">00068</a> <span class="comment"></span> <span class="keyword">public</span> <a class="code" href="class_template_compiler_ex.html#a6c58447a001891500c54f1e9afc30b20" title="Already constructed code blocks.">$blocks</a>         = array();
<a name="l00072"></a><a class="code" href="class_template_compiler_ex.html#aa33edba89e0e64230b47973bbf33ef4e">00072</a>  <span class="keyword">public</span> <a class="code" href="class_template_compiler_ex.html#aa33edba89e0e64230b47973bbf33ef4e" title="Template&amp;#39;s metadata.">$metadata</a>       = array();
<a name="l00076"></a><a class="code" href="class_template_compiler_ex.html#a47169b58844fe3ddabd63f7d6af5067d">00076</a>  <span class="keyword">public</span> <a class="code" href="class_template_compiler_ex.html#a47169b58844fe3ddabd63f7d6af5067d" title="Template&amp;#39;s classname.">$className</a>      = null;
<a name="l00077"></a>00077 
<a name="l00078"></a>00078  <span class="comment">// public API</span>
<a name="l00082"></a><a class="code" href="class_template_compiler_ex.html#a1e3e1ada9beabf25c6ae30b2978b44c2">00082</a> <span class="comment"></span> <span class="keyword">public</span> function <a class="code" href="class_template_compiler_ex.html#a1e3e1ada9beabf25c6ae30b2978b44c2" title="Constructor.">__construct</a>() {
<a name="l00083"></a>00083   <span class="comment">// create plugins registry, and register built-ins</span>
<a name="l00084"></a>00084   $this-&gt;plugins = <span class="keyword">new</span> <a class="code" href="class_template_plugins.html" title="Handles discovery, registration and utilization of plugins.">TemplatePlugins</a>(array(
<a name="l00085"></a>00085    <span class="stringliteral">&#39;tags&#39;</span> =&gt; array(
<a name="l00086"></a>00086     <span class="stringliteral">&#39;load&#39;</span>    =&gt; array(
<a name="l00087"></a>00087      <span class="stringliteral">&#39;plugin&#39;</span> =&gt; null, <span class="stringliteral">&#39;type&#39;</span> =&gt; <span class="stringliteral">&#39;inline&#39;</span>, <span class="stringliteral">&#39;handler&#39;</span> =&gt; array($this, <span class="stringliteral">&#39;handleLoadBuiltin&#39;</span>), <span class="stringliteral">&#39;minArgs&#39;</span> =&gt; 1
<a name="l00088"></a>00088     ),
<a name="l00089"></a>00089     <span class="stringliteral">&#39;comment&#39;</span> =&gt; array(
<a name="l00090"></a>00090      <span class="stringliteral">&#39;plugin&#39;</span> =&gt; null, <span class="stringliteral">&#39;type&#39;</span> =&gt; <span class="stringliteral">&#39;ignore&#39;</span>, <span class="stringliteral">&#39;handler&#39;</span> =&gt; array($this, <span class="stringliteral">&#39;handleCommentBuiltin&#39;</span>), <span class="stringliteral">&#39;minArgs&#39;</span> =&gt; 0
<a name="l00091"></a>00091     ),
<a name="l00092"></a>00092    ),
<a name="l00093"></a>00093    <span class="stringliteral">&#39;filters&#39;</span> =&gt; array(),
<a name="l00094"></a>00094    <span class="stringliteral">&#39;hooks&#39;</span>   =&gt; array(),
<a name="l00095"></a>00095   ));
<a name="l00096"></a>00096  }
<a name="l00097"></a>00097  
<a name="l00102"></a><a class="code" href="class_template_compiler_ex.html#a8d7a65c59cb37d96d9ebc5c655a8a1e7">00102</a>  <span class="keyword">public</span> function <a class="code" href="class_template_compiler_ex.html#a8d7a65c59cb37d96d9ebc5c655a8a1e7" title="Resets compiler to pristine state, and loads plugins specified in &amp;#39;loadPlugins&amp;#39; setting...">reset</a>() {
<a name="l00103"></a>00103   $this-&gt;plugins-&gt;searchPaths = &amp;$this-&gt;settings[<span class="stringliteral">&#39;pluginsPaths&#39;</span>];
<a name="l00104"></a>00104   $this-&gt;blocks = $this-&gt;metadata = $this-&gt;loadedPlugins = array();
<a name="l00105"></a>00105   $this-&gt;className = $this-&gt;parserCurrentToken = $this-&gt;parserCurrentFile = null;
<a name="l00106"></a>00106   $this-&gt;parserCurrentLine = 1;
<a name="l00107"></a>00107   
<a name="l00108"></a>00108   $this-&gt;plugins-&gt;loadMultiple($this, null, $this-&gt;settings[<span class="stringliteral">&#39;loadPlugins&#39;</span>]);
<a name="l00109"></a>00109  }
<a name="l00110"></a>00110  
<a name="l00117"></a><a class="code" href="class_template_compiler_ex.html#a13570ae4a6d834431eeb3c84a5051ac3">00117</a>  <span class="keyword">public</span> function <a class="code" href="class_template_compiler_ex.html#a13570ae4a6d834431eeb3c84a5051ac3" title="Compiles given template into output package.">compile</a>(<a class="code" href="interface_i_template_i_o_driver.html" title="Interface required for all I/O drivers.">ITemplateIODriver</a> $io, $template) {
<a name="l00118"></a>00118   $this-&gt;<a class="code" href="class_template_compiler_ex.html#a8d7a65c59cb37d96d9ebc5c655a8a1e7" title="Resets compiler to pristine state, and loads plugins specified in &amp;#39;loadPlugins&amp;#39; setting...">reset</a>();
<a name="l00119"></a>00119   
<a name="l00120"></a>00120   <span class="keywordflow">if</span> (($tpl = $io-&gt;<a class="code" href="interface_i_template_i_o_driver.html#a58d4f66a849626b7341eafeb3f456c03" title="Should read template source code as whole, and return it.">loadTemplate</a>($this-&gt;settings, $template)) === <span class="keyword">false</span>) {
<a name="l00121"></a>00121    <span class="keywordflow">throw</span> <span class="keyword">new</span> <a class="code" href="class_template_error.html" title="Main and currently the only exception type thrown by SithTemplate internals.">TemplateError</a>(<span class="stringliteral">&#39;Could not load template &quot;&#39;</span>.$in.<span class="charliteral">&#39;&quot;&#39;</span>, <a class="code" href="class_template_error.html#a1c6f0bf460ba23e1593231b9dca910a1" title="An I/O read error.">TemplateError::E_IO_LOAD_FAILURE</a>);
<a name="l00122"></a>00122   }
<a name="l00123"></a>00123   
<a name="l00124"></a>00124   $this-&gt;className          = $io-&gt;<a class="code" href="interface_i_template_i_o_driver.html#a4422ce31a10074ea6af13594efd757b1" title="Should return template&amp;#39;s classname.">className</a>($this-&gt;settings, $template);
<a name="l00125"></a>00125   $this-&gt;parserCurrentFile  = $template;
<a name="l00126"></a>00126   $this-&gt;metadata[<span class="stringliteral">&#39;usedIO&#39;</span>] = $io-&gt;driverID;
<a name="l00127"></a>00127   
<a name="l00128"></a>00128   $genAST  = $this-&gt;<a class="code" href="class_template_compiler_ex.html#a8c314644ad54b574e55cce1e56bf5d33" title="Creates and returns an Abstract Syntax Tree of given template.">createAST</a>($tpl);
<a name="l00129"></a>00129   $genCode = $this-&gt;<a class="code" href="class_template_compiler_ex.html#a3f16537377363532ad1d4fd33b6a4fca" title="Constructs blocks and generates code for the entire AST.">generateCode</a>($genAST);
<a name="l00130"></a>00130   
<a name="l00131"></a>00131   <span class="comment">// determine template&#39;s parent class</span>
<a name="l00132"></a>00132   $classCode = <span class="stringliteral">&#39;&lt;?php class &#39;</span>.$this-&gt;className.<span class="stringliteral">&#39; extends &#39;</span>;
<a name="l00133"></a>00133   <span class="keywordflow">if</span> (isset($this-&gt;metadata[<span class="stringliteral">&#39;parentTemplate&#39;</span>])) {
<a name="l00134"></a>00134    list($parentIO,$parent)  = <a class="code" href="class_template_utils.html#a3c4884dc20fe80e13a23f36f09663220" title="Splits I/O DSN, and creates correct driver object.">TemplateUtils::parseIODSN</a>($this-&gt;settings, $this-&gt;metadata[<span class="stringliteral">&#39;parentTemplate&#39;</span>]);
<a name="l00135"></a>00135    $classCode              .= $parentIO-&gt;className($this-&gt;settings, $parent);
<a name="l00136"></a>00136    <span class="comment">// main content is ignored, when template extends another</span>
<a name="l00137"></a>00137    unset($genCode[<span class="stringliteral">&#39;main&#39;</span>]);
<a name="l00138"></a>00138   } <span class="keywordflow">else</span> {
<a name="l00139"></a>00139    $classCode .= <span class="stringliteral">&#39;Template&#39;</span>;
<a name="l00140"></a>00140   }
<a name="l00141"></a>00141   
<a name="l00142"></a>00142   $classCode .= <span class="charliteral">&#39;{&#39;</span>;
<a name="l00143"></a>00143   <span class="keywordflow">foreach</span> ($genCode as $blockName =&gt; &amp;$blockCode) {
<a name="l00144"></a>00144    $classCode .= <span class="stringliteral">&#39;function _&#39;</span>.TemplateUtils::sanitize($blockName).<span class="stringliteral">&#39;($e){&#39;</span>;
<a name="l00145"></a>00145    <span class="comment">// TODO: is constructor support really needed?</span>
<a name="l00146"></a>00146    <span class="keywordflow">if</span> ($blockName == <span class="stringliteral">&#39;_constructor&#39;</span>) $classCode .= <span class="stringliteral">&#39;parent::__constructor();&#39;</span>;
<a name="l00147"></a>00147    $classCode .= $blockCode.<span class="charliteral">&#39;}&#39;</span>;
<a name="l00148"></a>00148   }
<a name="l00149"></a>00149   $classCode .= <span class="charliteral">&#39;}&#39;</span>;
<a name="l00150"></a>00150   
<a name="l00151"></a>00151   <span class="keywordflow">if</span> ($io-&gt;<a class="code" href="interface_i_template_i_o_driver.html#a09fcd13602951d6617d9af68118ef851" title="Should save template metadata.">saveMetadata</a>($this-&gt;settings, $template, $this-&gt;metadata) === <span class="keyword">false</span>) {
<a name="l00152"></a>00152    <span class="keywordflow">throw</span> <span class="keyword">new</span> <a class="code" href="class_template_error.html" title="Main and currently the only exception type thrown by SithTemplate internals.">TemplateError</a>(
<a name="l00153"></a>00153     <span class="stringliteral">&#39;Could not save template metadata (compiled from &quot;&#39;</span>.$template.<span class="stringliteral">&#39;&quot;)&#39;</span>,
<a name="l00154"></a>00154     <a class="code" href="class_template_error.html#a9bb22dc143f3bc58bd4db9f87fae4178" title="An I/O save error.">TemplateError::E_IO_SAVE_FAILURE</a>
<a name="l00155"></a>00155    );
<a name="l00156"></a>00156   }
<a name="l00157"></a>00157   
<a name="l00158"></a>00158   <span class="keywordflow">if</span> ($io-&gt;<a class="code" href="interface_i_template_i_o_driver.html#ace0d5330b5b82578b4d3a5021eb1cdd7" title="Should save compiled template code.">saveTemplate</a>($this-&gt;settings, $template, $classCode) === <span class="keyword">false</span>) {
<a name="l00159"></a>00159    <span class="keywordflow">throw</span> <span class="keyword">new</span> <a class="code" href="class_template_error.html" title="Main and currently the only exception type thrown by SithTemplate internals.">TemplateError</a>(
<a name="l00160"></a>00160     <span class="stringliteral">&#39;Could not save template code (compiled from &quot;&#39;</span>.$template.<span class="stringliteral">&#39;&quot;).&#39;</span>,
<a name="l00161"></a>00161     <a class="code" href="class_template_error.html#a9bb22dc143f3bc58bd4db9f87fae4178" title="An I/O save error.">TemplateError::E_IO_SAVE_FAILURE</a>
<a name="l00162"></a>00162    );
<a name="l00163"></a>00163   }
<a name="l00164"></a>00164  }
<a name="l00165"></a>00165  
<a name="l00166"></a>00166  <span class="comment">// Parser part</span>
<a name="l00174"></a><a class="code" href="class_template_compiler_ex.html#a8c314644ad54b574e55cce1e56bf5d33">00174</a> <span class="comment"></span> <span class="keyword">private</span> function <a class="code" href="class_template_compiler_ex.html#a8c314644ad54b574e55cce1e56bf5d33" title="Creates and returns an Abstract Syntax Tree of given template.">createAST</a>(&amp;$tpl) {
<a name="l00175"></a>00175   $root = <span class="keyword">new</span> <a class="code" href="class_template_node_ex.html" title="Class-container for AST nodes.">TemplateNodeEx</a>(<span class="stringliteral">&#39;root&#39;</span>, null, null, $this-&gt;parserCurrentFile, -1);
<a name="l00176"></a>00176   
<a name="l00177"></a>00177   $tokens = preg_split($this-&gt;parserTokenRegexp, $tpl, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
<a name="l00178"></a>00178   $this-&gt;<a class="code" href="class_template_compiler_ex.html#a9cc09b0d1f776e7f4361e9e41dd3bb10" title="Parses token stream until it runs out of tokens, or when it encounters given tag name.">parseTokenStream</a>($root, $tokens);
<a name="l00179"></a>00179   
<a name="l00180"></a>00180   <span class="keywordflow">return</span> $root;
<a name="l00181"></a>00181  }
<a name="l00182"></a>00182  
<a name="l00191"></a><a class="code" href="class_template_compiler_ex.html#a2138fe87678a9a13b2d6f7da426a7459">00191</a>  <span class="keyword">private</span> function <a class="code" href="class_template_compiler_ex.html#a2138fe87678a9a13b2d6f7da426a7459" title="Fetches next token from given stream, preprocesses it, and stores it in TemplateCompilerEx::$parserCu...">parserGetNextToken</a>(array &amp;$tokens) {
<a name="l00192"></a>00192   $this-&gt;parserCurrentToken = array_shift($tokens);
<a name="l00193"></a>00193   
<a name="l00194"></a>00194   <span class="keywordflow">if</span> ($this-&gt;parserCurrentToken === null) {
<a name="l00195"></a>00195    <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00196"></a>00196   } elseif (mb_substr($this-&gt;parserCurrentToken, 0, 2) == <span class="stringliteral">&#39;{%&#39;</span>) {
<a name="l00197"></a>00197    $this-&gt;parserCurrentToken = array(
<a name="l00198"></a>00198     <span class="stringliteral">&#39;type&#39;</span>    =&gt; <span class="stringliteral">&#39;tag&#39;</span>,
<a name="l00199"></a>00199     <span class="stringliteral">&#39;content&#39;</span> =&gt; <a class="code" href="class_template_utils.html#a28bd46df8e8547dd387e2047733d8f87" title="Properly splits given expression using given delimiter.">TemplateUtils::splitEscaped</a>(
<a name="l00200"></a>00200      <span class="charliteral">&#39; &#39;</span>, trim(mb_substr($this-&gt;parserCurrentToken, 2, -2))
<a name="l00201"></a>00201     )
<a name="l00202"></a>00202    );
<a name="l00203"></a>00203   } elseif (mb_substr($this-&gt;parserCurrentToken, 0, 2) == <span class="stringliteral">&#39;{{&#39;</span>) {
<a name="l00204"></a>00204    $this-&gt;parserCurrentToken = array(
<a name="l00205"></a>00205     <span class="stringliteral">&#39;type&#39;</span>    =&gt; <span class="stringliteral">&#39;var&#39;</span>,
<a name="l00206"></a>00206     <span class="stringliteral">&#39;content&#39;</span> =&gt; <a class="code" href="class_template_utils.html#ad8600ee16ab4bcfc0575696c8e2520d2" title="Split string into two.">TemplateUtils::split</a>(
<a name="l00207"></a>00207      <span class="charliteral">&#39;|&#39;</span>, trim(mb_substr($this-&gt;parserCurrentToken, 2, -2))
<a name="l00208"></a>00208     ),
<a name="l00209"></a>00209    );
<a name="l00210"></a>00210   } elseif (mb_substr($this-&gt;parserCurrentToken, 0, 2) == <span class="stringliteral">&#39;{#&#39;</span>) {
<a name="l00211"></a>00211    $this-&gt;parserCurrentToken = array(
<a name="l00212"></a>00212     <span class="stringliteral">&#39;type&#39;</span>    =&gt; <span class="stringliteral">&#39;comment&#39;</span>,
<a name="l00213"></a>00213     <span class="stringliteral">&#39;content&#39;</span> =&gt; null,
<a name="l00214"></a>00214    );
<a name="l00215"></a>00215   } <span class="keywordflow">else</span> {
<a name="l00216"></a>00216    $this-&gt;parserCurrentToken = array(
<a name="l00217"></a>00217     <span class="stringliteral">&#39;type&#39;</span>    =&gt; <span class="stringliteral">&#39;text&#39;</span>,
<a name="l00218"></a>00218     <span class="stringliteral">&#39;content&#39;</span> =&gt; $this-&gt;parserCurrentToken,
<a name="l00219"></a>00219    );
<a name="l00220"></a>00220   }
<a name="l00221"></a>00221   
<a name="l00222"></a>00222   <span class="keywordflow">return</span> <span class="keyword">true</span>;
<a name="l00223"></a>00223  }
<a name="l00224"></a>00224  
<a name="l00235"></a><a class="code" href="class_template_compiler_ex.html#adb1366c4bf94900c7b8e765caf1d43a6">00235</a>  <span class="keyword">private</span> function <a class="code" href="class_template_compiler_ex.html#adb1366c4bf94900c7b8e765caf1d43a6" title="Checks whether the parser has encountered ending tag with given name.">parserEncounteredEndTag</a>(<a class="code" href="class_template_node_ex.html" title="Class-container for AST nodes.">TemplateNodeEx</a> $node, $tag, $type) {
<a name="l00236"></a>00236   <span class="keywordflow">if</span> ($tag === null || $this-&gt;parserCurrentToken[<span class="stringliteral">&#39;type&#39;</span>] != <span class="stringliteral">&#39;tag&#39;</span>) <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00237"></a>00237   
<a name="l00238"></a>00238   $gotTag = &amp;$this-&gt;parserCurrentToken[<span class="stringliteral">&#39;content&#39;</span>][0];
<a name="l00239"></a>00239   $tag    = <span class="stringliteral">&#39;end&#39;</span>.$tag;
<a name="l00240"></a>00240   
<a name="l00241"></a>00241   <span class="keywordflow">if</span> (mb_substr($gotTag, 0, 3) != <span class="stringliteral">&#39;end&#39;</span>) {
<a name="l00242"></a>00242    <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00243"></a>00243   } elseif ($gotTag != $tag &amp;&amp; $type == <span class="stringliteral">&#39;block&#39;</span>) {
<a name="l00244"></a>00244    $this-&gt;<span class="keyword">raise</span>(
<a name="l00245"></a>00245     $node,
<a name="l00246"></a>00246     <span class="stringliteral">&#39;Invalid ending tag encountered - expected &quot;&#39;</span>.$tag.<span class="stringliteral">&#39;&quot;, got &quot;&#39;</span>.$gotTag.<span class="charliteral">&#39;&quot;&#39;</span>,
<a name="l00247"></a>00247     <a class="code" href="class_template_error.html#ac502ffee5019e6d870c25083af550454" title="An invalid syntax error.">TemplateError::E_INVALID_SYNTAX</a>
<a name="l00248"></a>00248    );
<a name="l00249"></a>00249   } elseif ($gotTag == $tag) {
<a name="l00250"></a>00250    <span class="keywordflow">return</span> <span class="keyword">true</span>;
<a name="l00251"></a>00251   }
<a name="l00252"></a>00252   <span class="keywordflow">return</span> <span class="keyword">true</span>;
<a name="l00253"></a>00253  }
<a name="l00254"></a>00254  
<a name="l00261"></a><a class="code" href="class_template_compiler_ex.html#ac14ed87a62f7b5a59b0e9fe5ce72b4b6">00261</a>  <span class="keyword">private</span> function <a class="code" href="class_template_compiler_ex.html#ac14ed87a62f7b5a59b0e9fe5ce72b4b6" title="Converts current token&amp;#39;s array into the node, and adds it to given node&amp;#39;s children...">createNodeFromToken</a>(<a class="code" href="class_template_node_ex.html" title="Class-container for AST nodes.">TemplateNodeEx</a> $node) {
<a name="l00262"></a>00262   $token = &amp;$this-&gt;parserCurrentToken;
<a name="l00263"></a>00263   $node-&gt;<a class="code" href="class_template_node_ex.html#ac4a2737627e12bace528ee449b45943f" title="Creates a new TemplateNodeEx instance and adds it to this node children.">addChild</a>($token[<span class="stringliteral">&#39;type&#39;</span>], $token[<span class="stringliteral">&#39;content&#39;</span>], $this-&gt;parserCurrentFile, $this-&gt;parserCurrentLine);
<a name="l00264"></a>00264  }
<a name="l00265"></a>00265  
<a name="l00274"></a><a class="code" href="class_template_compiler_ex.html#a9cc09b0d1f776e7f4361e9e41dd3bb10">00274</a>  <span class="keyword">private</span> function <a class="code" href="class_template_compiler_ex.html#a9cc09b0d1f776e7f4361e9e41dd3bb10" title="Parses token stream until it runs out of tokens, or when it encounters given tag name.">parseTokenStream</a>(<a class="code" href="class_template_node_ex.html" title="Class-container for AST nodes.">TemplateNodeEx</a> $node, array &amp;$tokens, $parseUntil = null, $blockTagType = null) {
<a name="l00275"></a>00275   <span class="keywordflow">while</span> ($this-&gt;<a class="code" href="class_template_compiler_ex.html#a2138fe87678a9a13b2d6f7da426a7459" title="Fetches next token from given stream, preprocesses it, and stores it in TemplateCompilerEx::$parserCu...">parserGetNextToken</a>($tokens) &amp;&amp; !$this-&gt;<a class="code" href="class_template_compiler_ex.html#adb1366c4bf94900c7b8e765caf1d43a6" title="Checks whether the parser has encountered ending tag with given name.">parserEncounteredEndTag</a>($node, $parseUntil, $blockTagType)) {
<a name="l00276"></a>00276    <span class="keywordflow">switch</span> ($this-&gt;parserCurrentToken[<span class="stringliteral">&#39;type&#39;</span>]) {
<a name="l00277"></a>00277     <span class="keywordflow">case</span> <span class="stringliteral">&#39;tag&#39;</span>:
<a name="l00278"></a>00278      $tag  = array_shift($this-&gt;parserCurrentToken[<span class="stringliteral">&#39;content&#39;</span>]);
<a name="l00279"></a>00279      $args = &amp;$this-&gt;parserCurrentToken[<span class="stringliteral">&#39;content&#39;</span>];
<a name="l00280"></a>00280      
<a name="l00281"></a>00281      <span class="keywordflow">if</span> (!$this-&gt;plugins-&gt;known(<span class="stringliteral">&#39;tag&#39;</span>, $tag)) {
<a name="l00282"></a>00282       <span class="comment">// if doesn&#39;t exist, assume inline</span>
<a name="l00283"></a>00283       $tagInfo = array(<span class="stringliteral">&#39;type&#39;</span> =&gt; <span class="stringliteral">&#39;inline&#39;</span>);
<a name="l00284"></a>00284      } <span class="keywordflow">else</span> {
<a name="l00285"></a>00285       $tagInfo = $this-&gt;plugins-&gt;get(<span class="stringliteral">&#39;tag&#39;</span>, $tag);
<a name="l00286"></a>00286      }
<a name="l00287"></a>00287      
<a name="l00288"></a>00288      $newNode = <span class="keyword">new</span> <a class="code" href="class_template_node_ex.html" title="Class-container for AST nodes.">TemplateNodeEx</a>(<span class="stringliteral">&#39;inlineTag&#39;</span>, $node, array($tag, $args), $this-&gt;parserCurrentFile, $this-&gt;parserCurrentLine);
<a name="l00289"></a>00289      <span class="keywordflow">if</span> (in_array($tagInfo[<span class="stringliteral">&#39;type&#39;</span>], array(<span class="stringliteral">&#39;block&#39;</span>, <span class="stringliteral">&#39;ignore&#39;</span>))) {
<a name="l00290"></a>00290       $newNode-&gt;nodeID = <span class="stringliteral">&#39;blockTag&#39;</span>;
<a name="l00291"></a>00291       <span class="comment">// capture block content</span>
<a name="l00292"></a>00292       $this-&gt;<a class="code" href="class_template_compiler_ex.html#a9cc09b0d1f776e7f4361e9e41dd3bb10" title="Parses token stream until it runs out of tokens, or when it encounters given tag name.">parseTokenStream</a>($newNode, $tokens, $tag, ($blockTagType == <span class="stringliteral">&#39;ignore&#39;</span> ? <span class="stringliteral">&#39;ignore&#39;</span> : $tagInfo[<span class="stringliteral">&#39;type&#39;</span>]));
<a name="l00293"></a>00293      }
<a name="l00294"></a>00294      
<a name="l00295"></a>00295      $node-&gt;nodeChildren[] = $newNode;
<a name="l00296"></a>00296     <span class="keywordflow">break</span>;
<a name="l00297"></a>00297     <span class="keywordflow">case</span> <span class="stringliteral">&#39;var&#39;</span>:
<a name="l00298"></a>00298     <span class="keywordflow">case</span> <span class="stringliteral">&#39;text&#39;</span>:
<a name="l00299"></a>00299      $this-&gt;<a class="code" href="class_template_compiler_ex.html#ac14ed87a62f7b5a59b0e9fe5ce72b4b6" title="Converts current token&amp;#39;s array into the node, and adds it to given node&amp;#39;s children...">createNodeFromToken</a>($node);
<a name="l00300"></a>00300      <span class="keywordflow">if</span> ($this-&gt;parserCurrentToken[<span class="stringliteral">&#39;type&#39;</span>] == <span class="stringliteral">&#39;text&#39;</span>) {
<a name="l00301"></a>00301       <span class="comment">// update current line counter</span>
<a name="l00302"></a>00302       $this-&gt;parserCurrentLine += mb_substr_count($this-&gt;parserCurrentToken[<span class="stringliteral">&#39;content&#39;</span>], <span class="stringliteral">&quot;\n&quot;</span>);
<a name="l00303"></a>00303      }
<a name="l00304"></a>00304     <span class="keywordflow">break</span>;
<a name="l00305"></a>00305    }
<a name="l00306"></a>00306   }
<a name="l00307"></a>00307  }
<a name="l00308"></a>00308  
<a name="l00309"></a>00309  <span class="comment">// CodeGen part</span>
<a name="l00317"></a><a class="code" href="class_template_compiler_ex.html#a3f16537377363532ad1d4fd33b6a4fca">00317</a> <span class="comment"></span> <span class="keyword">private</span> function <a class="code" href="class_template_compiler_ex.html#a3f16537377363532ad1d4fd33b6a4fca" title="Constructs blocks and generates code for the entire AST.">generateCode</a>(<a class="code" href="class_template_node_ex.html" title="Class-container for AST nodes.">TemplateNodeEx</a> $root) {
<a name="l00318"></a>00318   $this-&gt;<a class="code" href="class_template_compiler_ex.html#a616eb81be4f686387ecd3f778eca26a5" title="Creates code block from raw node.">createBlock</a>(<span class="stringliteral">&#39;main&#39;</span>, $root);
<a name="l00319"></a>00319   <span class="keywordflow">return</span> $this-&gt;blocks;
<a name="l00320"></a>00320  }
<a name="l00321"></a>00321  
<a name="l00330"></a><a class="code" href="class_template_compiler_ex.html#a91899408f7ddf3173a8932bb8277aad7">00330</a>  <span class="keyword">public</span> function <a class="code" href="class_template_compiler_ex.html#a91899408f7ddf3173a8932bb8277aad7" title="Generates code from given node&amp;#39;s children.">handleChildren</a>(array &amp;$children) {
<a name="l00331"></a>00331   $code = <span class="stringliteral">&#39;&#39;</span>;
<a name="l00332"></a>00332   <span class="keywordflow">foreach</span> ($children as $child) {
<a name="l00333"></a>00333    $code .= $this-&gt;<a class="code" href="class_template_compiler_ex.html#a773e98ffac99fdbe9f8934768f840d3c" title="Creates code from given node.">handleNode</a>($child);
<a name="l00334"></a>00334   }
<a name="l00335"></a>00335   <span class="keywordflow">return</span> $code;
<a name="l00336"></a>00336  }
<a name="l00337"></a>00337  
<a name="l00345"></a><a class="code" href="class_template_compiler_ex.html#a616eb81be4f686387ecd3f778eca26a5">00345</a>  <span class="keyword">public</span> function <a class="code" href="class_template_compiler_ex.html#a616eb81be4f686387ecd3f778eca26a5" title="Creates code block from raw node.">createBlock</a>($block, <a class="code" href="class_template_node_ex.html" title="Class-container for AST nodes.">TemplateNodeEx</a> $node) {
<a name="l00346"></a>00346   $this-&gt;blocks[$block] = <span class="stringliteral">&#39;$b=\&#39;\&#39;;&#39;</span>.$this-&gt;handleChildren($node-&gt;nodeChildren).<span class="stringliteral">&#39;return $b;&#39;</span>;
<a name="l00347"></a>00347  }
<a name="l00348"></a>00348  
<a name="l00356"></a><a class="code" href="class_template_compiler_ex.html#a773e98ffac99fdbe9f8934768f840d3c">00356</a>  <span class="keyword">public</span> function <a class="code" href="class_template_compiler_ex.html#a773e98ffac99fdbe9f8934768f840d3c" title="Creates code from given node.">handleNode</a>(<a class="code" href="class_template_node_ex.html" title="Class-container for AST nodes.">TemplateNodeEx</a> $node) {
<a name="l00357"></a>00357   <span class="keywordflow">switch</span> ($node-&gt;nodeID) {
<a name="l00358"></a>00358    <span class="keywordflow">case</span> <span class="stringliteral">&#39;text&#39;</span>     : <span class="keywordflow">return</span> <span class="stringliteral">&#39;$b.=\&#39;&#39;</span>.TemplateUtils::escape($node-&gt;nodeContent).<span class="charliteral">&#39;\&#39;</span>;<span class="stringliteral">&#39;;</span>
<a name="l00359"></a>00359 <span class="stringliteral">   case &#39;</span>var<span class="stringliteral">&#39;      : return $this-&gt;handleVariable($node);</span>
<a name="l00360"></a>00360 <span class="stringliteral">   case &#39;</span>blockTag<span class="stringliteral">&#39; :</span>
<a name="l00361"></a>00361 <span class="stringliteral">   case &#39;</span>inlineTag<span class="stringliteral">&#39;: return $this-&gt;handleTag($node);</span>
<a name="l00362"></a>00362 <span class="stringliteral">  }</span>
<a name="l00363"></a>00363 <span class="stringliteral"> }</span>
<a name="l00364"></a>00364 <span class="stringliteral"> </span>
<a name="l00372"></a><a class="code" href="class_template_compiler_ex.html#af0951cb966c81753464771dfaeffa625">00372</a> <span class="stringliteral"> private function handleTag(TemplateNodeEx $node) {</span>
<a name="l00373"></a>00373 <span class="stringliteral">  $tag  = &amp;$node-&gt;nodeContent[0];</span>
<a name="l00374"></a>00374 <span class="stringliteral">  $args = &amp;$node-&gt;nodeContent[1];</span>
<a name="l00375"></a>00375 <span class="stringliteral">  </span>
<a name="l00376"></a>00376 <span class="stringliteral">  $tagInfo = $this-&gt;commonVerifyElement($node, &#39;</span>tag<span class="stringliteral">&#39;, $tag, $args);</span>
<a name="l00377"></a>00377 <span class="stringliteral">  </span>
<a name="l00378"></a>00378 <span class="stringliteral">  if (isset($tagInfo[&#39;</span>parent<span class="stringliteral">&#39;])) {</span>
<a name="l00379"></a>00379 <span class="stringliteral">   $pattern  = &#39;</span>~^<span class="stringliteral">&#39;.str_replace(&#39;</span>\\*<span class="stringliteral">&#39;, &#39;</span>.*?<span class="stringliteral">&#39;, preg_quote($tagInfo[&#39;</span>parent<span class="stringliteral">&#39;], &#39;</span>~<span class="stringliteral">&#39;)).&#39;</span>$~su<span class="stringliteral">&#39;;</span>
<a name="l00380"></a>00380 <span class="stringliteral">   </span>
<a name="l00381"></a>00381 <span class="stringliteral">   $this-&gt;raiseIf(</span>
<a name="l00382"></a>00382 <span class="stringliteral">    (!($node-&gt;nodeParent instanceof TemplateNodeEx) || !preg_match($pattern, $node-&gt;nodeParent-&gt;nodeContent[0])),</span>
<a name="l00383"></a>00383 <span class="stringliteral">    $node,</span>
<a name="l00384"></a>00384 <span class="stringliteral">    &#39;</span>Invalid tag nesting - tag <span class="stringliteral">&quot;&#39;.$tag.&#39;&quot;</span> requires <span class="stringliteral">&quot;&#39;.$tagInfo[&#39;parent&#39;].&#39;&quot;</span> tag as immediate parent, <span class="stringliteral">&#39;.</span>
<a name="l00385"></a>00385 <span class="stringliteral">    &#39;</span><span class="stringliteral">&quot;&#39;.$node-&gt;nodeParent-&gt;nodeContent[0].&#39;&quot;</span> found<span class="stringliteral">&#39;,</span>
<a name="l00386"></a>00386 <span class="stringliteral">    TemplateError::E_INVALID_SYNTAX</span>
<a name="l00387"></a>00387 <span class="stringliteral">   );</span>
<a name="l00388"></a>00388 <span class="stringliteral">   </span>
<a name="l00389"></a>00389 <span class="stringliteral">   unset($pattern);</span>
<a name="l00390"></a>00390 <span class="stringliteral">  }</span>
<a name="l00391"></a>00391 <span class="stringliteral">  </span>
<a name="l00392"></a>00392 <span class="stringliteral">  return call_user_func_array($tagInfo[&#39;</span>handler<span class="stringliteral">&#39;], array($this, $node, &amp;$tag, &amp;$args));</span>
<a name="l00393"></a>00393 <span class="stringliteral"> }</span>
<a name="l00394"></a>00394 <span class="stringliteral"> </span>
<a name="l00401"></a><a class="code" href="class_template_compiler_ex.html#ad4a05c2ff0b4e3ae9ee530780dc129b1">00401</a> <span class="stringliteral"> private function handleVariable(TemplateNodeEx $node) {</span>
<a name="l00402"></a>00402 <span class="stringliteral">  list($variable, $filters) = $node-&gt;nodeContent;</span>
<a name="l00403"></a>00403 <span class="stringliteral">  $noCheck                  = false;</span>
<a name="l00404"></a>00404 <span class="stringliteral">  </span>
<a name="l00405"></a>00405 <span class="stringliteral">  if (mb_substr($variable, 0, 1) == &#39;</span>@<span class="stringliteral">&#39;) {</span>
<a name="l00406"></a>00406 <span class="stringliteral">   $noCheck  = true;</span>
<a name="l00407"></a>00407 <span class="stringliteral">   $variable = mb_substr($variable, 1);</span>
<a name="l00408"></a>00408 <span class="stringliteral">  }</span>
<a name="l00409"></a>00409 <span class="stringliteral">  </span>
<a name="l00410"></a>00410 <span class="stringliteral">  list($variableCode, $variableCheck) = $this-&gt;parseVariableExpression($node, $variable);</span>
<a name="l00411"></a>00411 <span class="stringliteral">  $variableCode                       = $this-&gt;parseFilterChain($node, $filters, &#39;</span>@<span class="stringliteral">&#39;.$variableCode);</span>
<a name="l00412"></a>00412 <span class="stringliteral">  </span>
<a name="l00413"></a>00413 <span class="stringliteral">  return ($noCheck ? &#39;</span><span class="stringliteral">&#39; : $variableCheck).&#39;</span>$b.=<span class="stringliteral">&#39;.$variableCode.&#39;</span>;<span class="stringliteral">&#39;;</span>
<a name="l00414"></a>00414 <span class="stringliteral"> }</span>
<a name="l00415"></a>00415 <span class="stringliteral"> </span>
<a name="l00423"></a><a class="code" href="class_template_compiler_ex.html#a8efc4fef1f377e69631fe3de4c2033e3">00423</a> <span class="stringliteral"> public function parseVariableExpression(TemplateNodeEx $node, $variable) {</span>
<a name="l00424"></a>00424 <span class="stringliteral">  $ast   = $this-&gt;generateVariableAST($variable);</span>
<a name="l00425"></a>00425 <span class="stringliteral">  $code  = $this-&gt;generateVariableCode($node, $ast);</span>
<a name="l00426"></a>00426 <span class="stringliteral">  $check = &#39;</span><span class="keywordflow">if</span>(!isset(<span class="stringliteral">&#39;.$code.&#39;</span>)&amp;&amp;!is_null(@<span class="stringliteral">&#39;.$code.&#39;</span>)){$this-&gt;warnVar(\<span class="stringliteral">&#39;&#39;</span>.<a class="code" href="class_template_utils.html#aa3553ef2c1e54e0e99ad38a7fe931efa" title="Escape string to use in template class.">TemplateUtils::escape</a>($variable).<span class="charliteral">&#39;\&#39;</span>);}<span class="stringliteral">&#39;;</span>
<a name="l00427"></a>00427 <span class="stringliteral">  </span>
<a name="l00428"></a>00428 <span class="stringliteral">  // Hook-point: parseVariableExpression:postCodeGen</span>
<a name="l00429"></a>00429 <span class="stringliteral">  $this-&gt;runHooks(&#39;</span><a class="code" href="class_template_compiler_ex.html#a8efc4fef1f377e69631fe3de4c2033e3" title="Parses variable expression, and creates runtime PHP access code.">parseVariableExpression</a>:postCodeGen<span class="stringliteral">&#39;, array($node, &amp;$code, &amp;$check));</span>
<a name="l00430"></a>00430 <span class="stringliteral">  //</span>
<a name="l00431"></a>00431 <span class="stringliteral">  </span>
<a name="l00432"></a>00432 <span class="stringliteral">  return array($code, $check);</span>
<a name="l00433"></a>00433 <span class="stringliteral"> }</span>
<a name="l00434"></a>00434 <span class="stringliteral"> </span>
<a name="l00442"></a><a class="code" href="class_template_compiler_ex.html#a9e9d99501cd4def7eb25dc93cbef94b5">00442</a> <span class="stringliteral"> private function generateVariableAST($variable) {</span>
<a name="l00443"></a>00443 <span class="stringliteral">  $chunks = preg_split(</span>
<a name="l00444"></a>00444 <span class="stringliteral">   &#39;</span>/(\[.*?\]|\.|\-\&gt;)/s<span class="stringliteral">&#39;, $variable, -1,</span>
<a name="l00445"></a>00445 <span class="stringliteral">   PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY</span>
<a name="l00446"></a>00446 <span class="stringliteral">  );</span>
<a name="l00447"></a>00447 <span class="stringliteral">  </span>
<a name="l00448"></a>00448 <span class="stringliteral">  foreach ($chunks as &amp;$chunk) {</span>
<a name="l00449"></a>00449 <span class="stringliteral">   if (mb_substr($chunk, 0, 1) == &#39;</span>[<span class="stringliteral">&#39;) {</span>
<a name="l00450"></a>00450 <span class="stringliteral">    $chunk = $this-&gt;generateVariableAST(mb_substr($chunk, 1, -1));</span>
<a name="l00451"></a>00451 <span class="stringliteral">   }</span>
<a name="l00452"></a>00452 <span class="stringliteral">  }</span>
<a name="l00453"></a>00453 <span class="stringliteral">  </span>
<a name="l00454"></a>00454 <span class="stringliteral">  return array_filter($chunks, array(&#39;</span><a class="code" href="class_template_utils.html" title="Namespace-acting all-static class.">TemplateUtils</a><span class="stringliteral">&#39;, &#39;</span>filterEmpty<span class="stringliteral">&#39;));</span>
<a name="l00455"></a>00455 <span class="stringliteral"> }</span>
<a name="l00456"></a>00456 <span class="stringliteral"> </span>
<a name="l00464"></a><a class="code" href="class_template_compiler_ex.html#af68b6944da2fc99dfda0c7a89f11656d">00464</a> <span class="stringliteral"> private function generateVariableCode(TemplateNodeEx $node, &amp;$ast) {</span>
<a name="l00465"></a>00465 <span class="stringliteral">  $code      = &#39;</span>$this-&gt;ctx<span class="stringliteral">&#39;;</span>
<a name="l00466"></a>00466 <span class="stringliteral">  $nextChunk = &#39;</span>array<span class="stringliteral">&#39;; // array, object or operator</span>
<a name="l00467"></a>00467 <span class="stringliteral">  $operators = array(&#39;</span>.<span class="stringliteral">&#39; =&gt; &#39;</span>array<span class="stringliteral">&#39;, &#39;</span>-&gt;<span class="stringliteral">&#39; =&gt; &#39;</span><span class="keywordtype">object</span><span class="stringliteral">&#39;);</span>
<a name="l00468"></a>00468 <span class="stringliteral">  </span>
<a name="l00469"></a>00469 <span class="stringliteral">  while (($currentChunk = array_shift($ast)) !== null) {</span>
<a name="l00470"></a>00470 <span class="stringliteral">   if ($nextChunk == &#39;</span><span class="keyword">operator</span><span class="stringliteral">&#39;) {</span>
<a name="l00471"></a>00471 <span class="stringliteral">    $this-&gt;raiseIf(</span>
<a name="l00472"></a>00472 <span class="stringliteral">     (!isset($operators[$currentChunk])),</span>
<a name="l00473"></a>00473 <span class="stringliteral">     $node,</span>
<a name="l00474"></a>00474 <span class="stringliteral">     &#39;</span>Variable access <span class="keyword">operator</span> expected (<span class="stringliteral">&quot;.&quot;</span> or <span class="stringliteral">&quot;-&gt;&quot;</span>), but <span class="stringliteral">&quot;&#39;.$currentChunk.&#39;&quot;</span> found<span class="stringliteral">&#39;,</span>
<a name="l00475"></a>00475 <span class="stringliteral">     TemplateError::E_INVALID_SYNTAX</span>
<a name="l00476"></a>00476 <span class="stringliteral">    );</span>
<a name="l00477"></a>00477 <span class="stringliteral">    </span>
<a name="l00478"></a>00478 <span class="stringliteral">    $nextChunk = $operators[$currentChunk];</span>
<a name="l00479"></a>00479 <span class="stringliteral">   } else {</span>
<a name="l00480"></a>00480 <span class="stringliteral">    switch ($nextChunk) {</span>
<a name="l00481"></a>00481 <span class="stringliteral">     case &#39;</span>array<span class="stringliteral">&#39;:</span>
<a name="l00482"></a>00482 <span class="stringliteral">      $chunkTemplate         = &#39;</span>[%s]<span class="stringliteral">&#39;;</span>
<a name="l00483"></a>00483 <span class="stringliteral">      $chunkVariableTemplate = &#39;</span>@%s<span class="stringliteral">&#39;;</span>
<a name="l00484"></a>00484 <span class="stringliteral">      $chunkNumberTemplate   = &#39;</span>%d<span class="stringliteral">&#39;;</span>
<a name="l00485"></a>00485 <span class="stringliteral">      $chunkStringTemplate   = &#39;</span>\<span class="stringliteral">&#39;%s\&#39;&#39;</span>;
<a name="l00486"></a>00486      <span class="keywordflow">break</span>;
<a name="l00487"></a>00487      <span class="keywordflow">case</span> <span class="stringliteral">&#39;object&#39;</span>:
<a name="l00488"></a>00488       $chunkTemplate         = <span class="stringliteral">&#39;-&gt;%s&#39;</span>;
<a name="l00489"></a>00489       $chunkVariableTemplate = <span class="stringliteral">&#39;{@%s}&#39;</span>;
<a name="l00490"></a>00490       $chunkNumberTemplate   = <span class="stringliteral">&#39;{%d}&#39;</span>;
<a name="l00491"></a>00491       $chunkStringTemplate   = null;
<a name="l00492"></a>00492      <span class="keywordflow">break</span>;
<a name="l00493"></a>00493      <span class="keywordflow">default</span>:
<a name="l00494"></a>00494       <a class="code" href="class_template_utils.html#a9756a1cc5232e00302a0b52c3a1e8e10" title="Panics.">TemplateUtils::panic</a>(__FILE__, __LINE__);
<a name="l00495"></a>00495      <span class="keywordflow">break</span>;
<a name="l00496"></a>00496     }
<a name="l00497"></a>00497     
<a name="l00498"></a>00498     <span class="keywordflow">if</span> (is_array($currentChunk)) {
<a name="l00499"></a>00499      <span class="comment">// variable index</span>
<a name="l00500"></a>00500      $chunkCode = sprintf($chunkVariableTemplate, $this-&gt;<a class="code" href="class_template_compiler_ex.html#af68b6944da2fc99dfda0c7a89f11656d" title="Recursively parses variable AST, and generates PHP access code.">generateVariableCode</a>($node, $currentChunk));
<a name="l00501"></a>00501     } elseif (ctype_digit($currentChunk)) {
<a name="l00502"></a>00502      <span class="comment">// integer index</span>
<a name="l00503"></a>00503      $chunkCode = sprintf($chunkNumberTemplate, $currentChunk);
<a name="l00504"></a>00504     } <span class="keywordflow">else</span> {
<a name="l00505"></a>00505      <span class="keywordflow">if</span> ($chunkStringTemplate) {
<a name="l00506"></a>00506       $currentChunk = sprintf($chunkStringTemplate, <a class="code" href="class_template_utils.html#aa3553ef2c1e54e0e99ad38a7fe931efa" title="Escape string to use in template class.">TemplateUtils::escape</a>($currentChunk));
<a name="l00507"></a>00507      }
<a name="l00508"></a>00508      $chunkCode = $currentChunk;
<a name="l00509"></a>00509     }
<a name="l00510"></a>00510     
<a name="l00511"></a>00511     $code .= sprintf($chunkTemplate, $chunkCode);
<a name="l00512"></a>00512     
<a name="l00513"></a>00513     $nextChunk = <span class="stringliteral">&#39;operator&#39;</span>;
<a name="l00514"></a>00514    }
<a name="l00515"></a>00515   }
<a name="l00516"></a>00516   
<a name="l00517"></a>00517   <span class="keywordflow">return</span> $code;
<a name="l00518"></a>00518  }
<a name="l00519"></a>00519  
<a name="l00528"></a><a class="code" href="class_template_compiler_ex.html#a0e954efa4b344518798797fe3bc6dd14">00528</a>  <span class="keyword">public</span> function <a class="code" href="class_template_compiler_ex.html#a0e954efa4b344518798797fe3bc6dd14" title="Handles filter chains.">parseFilterChain</a>(<a class="code" href="class_template_node_ex.html" title="Class-container for AST nodes.">TemplateNodeEx</a> $node, $filterExpr, $code) {
<a name="l00529"></a>00529   $filterChain = <a class="code" href="class_template_utils.html#a28bd46df8e8547dd387e2047733d8f87" title="Properly splits given expression using given delimiter.">TemplateUtils::splitEscaped</a>(<span class="charliteral">&#39;|&#39;</span>, $filterExpr);
<a name="l00530"></a>00530   $resultCode  = $code;
<a name="l00531"></a>00531   
<a name="l00532"></a>00532   <span class="comment">// Hook-point: parseFilterChain:entry</span>
<a name="l00533"></a>00533   $this-&gt;runHooks(<span class="stringliteral">&#39;parseFilterChain:entry&#39;</span>, array(&amp;$filterChain));
<a name="l00534"></a>00534   <span class="comment">//</span>
<a name="l00535"></a>00535   
<a name="l00536"></a>00536   <span class="keywordflow">foreach</span> ($filterChain as &amp;$filter) {
<a name="l00537"></a>00537    list($name, $args) = <a class="code" href="class_template_utils.html#ad8600ee16ab4bcfc0575696c8e2520d2" title="Split string into two.">TemplateUtils::split</a>(<span class="charliteral">&#39;:&#39;</span>, $filter);
<a name="l00538"></a>00538    <span class="keywordflow">if</span> ($args) {
<a name="l00539"></a>00539     $args = <a class="code" href="class_template_utils.html#a28bd46df8e8547dd387e2047733d8f87" title="Properly splits given expression using given delimiter.">TemplateUtils::splitEscaped</a>(<span class="charliteral">&#39;,&#39;</span>, $args);
<a name="l00540"></a>00540    } <span class="keywordflow">else</span> {
<a name="l00541"></a>00541     $args = array();
<a name="l00542"></a>00542    }
<a name="l00543"></a>00543    
<a name="l00544"></a>00544    <span class="keywordflow">foreach</span> ($args as &amp;$arg) {
<a name="l00545"></a>00545     <span class="keywordflow">if</span> (mb_substr($arg, 0, 1) == <span class="charliteral">&#39;&quot;&#39;</span>) {
<a name="l00546"></a>00546      $arg = array(<span class="stringliteral">&#39;string&#39;</span>, <span class="charliteral">&#39;\&#39;&#39;</span>.<a class="code" href="class_template_utils.html#aa3553ef2c1e54e0e99ad38a7fe931efa" title="Escape string to use in template class.">TemplateUtils::escape</a>(mb_substr($arg, 1, -1)).<span class="charliteral">&#39;\&#39;&#39;</span>);
<a name="l00547"></a>00547     } elseif (preg_match(<span class="stringliteral">&#39;~^\-?[0-9]+(?:\.[0-9]+)?$~&#39;</span>, $arg)) {
<a name="l00548"></a>00548      $arg = array(<span class="stringliteral">&#39;number&#39;</span>, $arg);
<a name="l00549"></a>00549     } <span class="keywordflow">else</span> {
<a name="l00550"></a>00550      list($code,) = $this-&gt;parseVariableExpression($node, $arg);
<a name="l00551"></a>00551      $arg = array(<span class="stringliteral">&#39;variable&#39;</span>, <span class="charliteral">&#39;@&#39;</span>.$code);
<a name="l00552"></a>00552     }
<a name="l00553"></a>00553    }
<a name="l00554"></a>00554    
<a name="l00555"></a>00555    $filterInfo = $this-&gt;commonVerifyElement($node, <span class="stringliteral">&#39;filter&#39;</span>, $name, $args);
<a name="l00556"></a>00556    $filterCode = call_user_func_array(
<a name="l00557"></a>00557     $filterInfo[<span class="stringliteral">&#39;handler&#39;</span>], array($this, $node, &amp;$name, &amp;$args)
<a name="l00558"></a>00558    );
<a name="l00559"></a>00559    
<a name="l00560"></a>00560    $resultCode = sprintf($filterCode, $resultCode);
<a name="l00561"></a>00561   }
<a name="l00562"></a>00562   
<a name="l00563"></a>00563   <span class="keywordflow">return</span> $resultCode;
<a name="l00564"></a>00564  }
<a name="l00565"></a>00565  
<a name="l00580"></a><a class="code" href="class_template_compiler_ex.html#aa45b715a26c3bd45064f4eee890c1dad">00580</a>  <span class="keyword">private</span> function <a class="code" href="class_template_compiler_ex.html#aa45b715a26c3bd45064f4eee890c1dad" title="Verifies correctness of given element.">commonVerifyElement</a>(<a class="code" href="class_template_node_ex.html" title="Class-container for AST nodes.">TemplateNodeEx</a> $node, $element, &amp;$name, array &amp;$args) {
<a name="l00581"></a>00581   <span class="keywordflow">if</span> (!in_array($element, array(<span class="stringliteral">&#39;tag&#39;</span>, <span class="stringliteral">&#39;filter&#39;</span>))) {
<a name="l00582"></a>00582    <a class="code" href="class_template_utils.html#a9756a1cc5232e00302a0b52c3a1e8e10" title="Panics.">TemplateUtils::panic</a>(__FILE__, __LINE__);
<a name="l00583"></a>00583   }
<a name="l00584"></a>00584   
<a name="l00585"></a>00585   $this-&gt;raiseIf(
<a name="l00586"></a>00586    (!$this-&gt;plugins-&gt;known($element, $name)),
<a name="l00587"></a>00587    $node,
<a name="l00588"></a>00588    <span class="stringliteral">&#39;Unknown &#39;</span>.$element.<span class="stringliteral">&#39; &quot;&#39;</span>.$name.<span class="stringliteral">&#39;&quot; encountered&#39;</span>,
<a name="l00589"></a>00589    ($element == <span class="stringliteral">&#39;tag&#39;</span> ? <a class="code" href="class_template_error.html#ae678eee4aca2972c0490ac727ef5416f" title="An unknown tag error.">TemplateError::E_UNKNOWN_TAG</a> : <a class="code" href="class_template_error.html#a3846fc5ce9f8f386092174ca142be11e" title="An unknown filter error.">TemplateError::E_UNKNOWN_FILTER</a>)
<a name="l00590"></a>00590   );
<a name="l00591"></a>00591   
<a name="l00592"></a>00592   $elementInfo = $this-&gt;plugins-&gt;get($element, $name);
<a name="l00593"></a>00593   
<a name="l00594"></a>00594   <a class="code" href="class_template_utils.html#a9ded2c07232134c25d3cf9300822e7d8" title="Checks whether element is allowed.">TemplateUtils::checkIfAllowed</a>($this, $element, $name, $node);
<a name="l00595"></a>00595   
<a name="l00596"></a>00596   <span class="keywordflow">if</span> (!is_callable($elementInfo[<span class="stringliteral">&#39;handler&#39;</span>])) {
<a name="l00597"></a>00597    <span class="keywordflow">throw</span> <span class="keyword">new</span> <a class="code" href="class_template_error.html" title="Main and currently the only exception type thrown by SithTemplate internals.">TemplateError</a>(
<a name="l00598"></a>00598     <span class="stringliteral">&#39;Invalid handler [&#39;</span>.<a class="code" href="class_template_utils.html#a486a01915d89b3a87095461329a3a7e6" title="Strip newlines and spaces from string.">TemplateUtils::strip</a>(var_export($elementInfo[<span class="stringliteral">&#39;handler&#39;</span>], <span class="keyword">true</span>)).
<a name="l00599"></a>00599     <span class="stringliteral">&#39;] supplied for &#39;</span>.$element.<span class="stringliteral">&#39; &quot;&#39;</span>.$name.<span class="stringliteral">&#39;&quot; by plugin &quot;&#39;</span>.$elementInfo[<span class="stringliteral">&#39;plugin&#39;</span>].<span class="charliteral">&#39;&quot;&#39;</span>,
<a name="l00600"></a>00600     <a class="code" href="class_template_error.html#a197d3675b19ddab587d765167ba142d2" title="An invalid handler error.">TemplateError::E_INVALID_HANDLER</a>
<a name="l00601"></a>00601    );
<a name="l00602"></a>00602   }
<a name="l00603"></a>00603   
<a name="l00604"></a>00604   <span class="keywordflow">if</span> (isset($elementInfo[<span class="stringliteral">&#39;minArgs&#39;</span>])) {
<a name="l00605"></a>00605    $this-&gt;raiseIf(
<a name="l00606"></a>00606     (count($args) &lt; $elementInfo[<span class="stringliteral">&#39;minArgs&#39;</span>]),
<a name="l00607"></a>00607     $node,
<a name="l00608"></a>00608     <span class="stringliteral">&#39;Invalid &#39;</span>.$element.<span class="stringliteral">&#39; call - &#39;</span>.$element.<span class="stringliteral">&#39; &quot;&#39;</span>.$name.<span class="stringliteral">&#39;&quot; requires at least &#39;</span>.
<a name="l00609"></a>00609     <span class="charliteral">&#39;&quot;&#39;</span>.$elementInfo[<span class="stringliteral">&#39;minArgs&#39;</span>].<span class="stringliteral">&#39;&quot; arguments &#39;</span>,
<a name="l00610"></a>00610     <a class="code" href="class_template_error.html#ac502ffee5019e6d870c25083af550454" title="An invalid syntax error.">TemplateError::E_INVALID_SYNTAX</a>
<a name="l00611"></a>00611    );
<a name="l00612"></a>00612   }
<a name="l00613"></a>00613   
<a name="l00614"></a>00614   <span class="keywordflow">return</span> $elementInfo;
<a name="l00615"></a>00615  }
<a name="l00616"></a>00616  
<a name="l00617"></a>00617  <span class="comment">// Bulitins part</span>
<a name="l00618"></a>00618  
<a name="l00628"></a><a class="code" href="class_template_compiler_ex.html#a49ac9c78629669903684589ebcd76033">00628</a>  <span class="keyword">private</span> function <a class="code" href="class_template_compiler_ex.html#a49ac9c78629669903684589ebcd76033" title="Handler for load built-in tag.">handleLoadBuiltin</a>(<a class="code" href="class_template_compiler_ex.html" title="Primary compiler driver.">TemplateCompilerEx</a> $compiler, <a class="code" href="class_template_node_ex.html" title="Class-container for AST nodes.">TemplateNodeEx</a> $node, &amp;$tag, array &amp;$args) {
<a name="l00629"></a>00629   $this-&gt;raiseIf(
<a name="l00630"></a>00630    ($this-&gt;plugins-&gt;load($this, $node, $args[0], null, <span class="keyword">true</span>) === <span class="keyword">false</span>),
<a name="l00631"></a>00631    $node,
<a name="l00632"></a>00632    <span class="stringliteral">&#39;Tried to load non-existant or invalid plugin &quot;&#39;</span>.$args[0].<span class="charliteral">&#39;&quot;&#39;</span>,
<a name="l00633"></a>00633    <a class="code" href="class_template_error.html#adcc81c7e44a611c01e633f0c7f88a89d" title="An unknown plugin error.">TemplateError::E_UNKNOWN_PLUGIN</a>
<a name="l00634"></a>00634   );
<a name="l00635"></a>00635   
<a name="l00636"></a>00636   <span class="comment">// {% load %} generates no code</span>
<a name="l00637"></a>00637   <span class="keywordflow">return</span> <span class="stringliteral">&#39;&#39;</span>;
<a name="l00638"></a>00638  }
<a name="l00639"></a>00639  
<a name="l00649"></a><a class="code" href="class_template_compiler_ex.html#ac5ba453fe0497c6a97e01b3ecc7b9c30">00649</a>  <span class="keyword">private</span> function <a class="code" href="class_template_compiler_ex.html#ac5ba453fe0497c6a97e01b3ecc7b9c30" title="Handler for comment built-in tag.">handleCommentBuiltin</a>(<a class="code" href="class_template_compiler_ex.html" title="Primary compiler driver.">TemplateCompilerEx</a> $compiler, <a class="code" href="class_template_node_ex.html" title="Class-container for AST nodes.">TemplateNodeEx</a> $node, &amp;$tag, array &amp;$args) {
<a name="l00650"></a>00650   <span class="comment">// no block-level code generated</span>
<a name="l00651"></a>00651   <span class="keywordflow">return</span> <span class="stringliteral">&#39;&#39;</span>;
<a name="l00652"></a>00652  }
<a name="l00653"></a>00653  
<a name="l00654"></a>00654  <span class="comment">// Compiler-specific utils</span>
<a name="l00655"></a>00655  
<a name="l00665"></a><a class="code" href="class_template_compiler_ex.html#a8f7f10bdd17ee4be906b39cff3f0d13d">00665</a>  <span class="keyword">public</span> function <span class="keyword">raise</span>(<a class="code" href="class_template_node_ex.html" title="Class-container for AST nodes.">TemplateNodeEx</a> $node, $message, $code) {
<a name="l00666"></a>00666   <span class="keywordflow">throw</span> <span class="keyword">new</span> <a class="code" href="class_template_error.html" title="Main and currently the only exception type thrown by SithTemplate internals.">TemplateError</a>(
<a name="l00667"></a>00667    $message.<span class="stringliteral">&#39; (in template &quot;&#39;</span>.$node-&gt;nodeFile.<span class="stringliteral">&#39;&quot; somewhere around line &#39;</span>.$node-&gt;nodeLine.<span class="charliteral">&#39;)&#39;</span>,
<a name="l00668"></a>00668    $code
<a name="l00669"></a>00669   );
<a name="l00670"></a>00670  }
<a name="l00671"></a>00671  
<a name="l00682"></a><a class="code" href="class_template_compiler_ex.html#af8bc3411f0f8bcfbd153a8d56f0ae2e7">00682</a>  <span class="keyword">public</span> function <a class="code" href="class_template_compiler_ex.html#af8bc3411f0f8bcfbd153a8d56f0ae2e7" title="Shorthand for conditional call to TemplateCompilerEx::raise.">raiseIf</a>($cond, <a class="code" href="class_template_node_ex.html" title="Class-container for AST nodes.">TemplateNodeEx</a> $node, $message, $code) {
<a name="l00683"></a>00683   <span class="keywordflow">if</span> ($cond === <span class="keyword">true</span>) $this-&gt;<span class="keyword">raise</span>($node, $message, $code);
<a name="l00684"></a>00684  }
<a name="l00685"></a>00685  
<a name="l00695"></a><a class="code" href="class_template_compiler_ex.html#a9ce1b5f9a87d8fdbadfad18bb440efff">00695</a>  <span class="keyword">public</span> function <a class="code" href="class_template_compiler_ex.html#a9ce1b5f9a87d8fdbadfad18bb440efff" title="Used to find and isolate alternative branch of given node, starting with given inline tag...">findAlternativeBranch</a>(<a class="code" href="class_template_node_ex.html" title="Class-container for AST nodes.">TemplateNodeEx</a> $node, $tag) {
<a name="l00696"></a>00696   $alternativeIdx = null;
<a name="l00697"></a>00697 
<a name="l00698"></a>00698   <span class="keywordflow">foreach</span> ($node-&gt;nodeChildren as $idx =&gt; $childNode) {
<a name="l00699"></a>00699    <span class="keywordflow">if</span> ($childNode-&gt;nodeID == <span class="stringliteral">&#39;inlineTag&#39;</span> &amp;&amp; $childNode-&gt;nodeContent[0] == $tag) {
<a name="l00700"></a>00700     $alternativeIdx = $idx;
<a name="l00701"></a>00701     <span class="keywordflow">break</span>;
<a name="l00702"></a>00702    }
<a name="l00703"></a>00703   }
<a name="l00704"></a>00704 
<a name="l00705"></a>00705   <span class="keywordflow">if</span> ($alternativeIdx) {
<a name="l00706"></a>00706    $mainNodes        = array_slice($node-&gt;nodeChildren, 0, $alternativeIdx);
<a name="l00707"></a>00707    $alternativeNodes = array_slice($node-&gt;nodeChildren, $alternativeIdx + 1);
<a name="l00708"></a>00708   } <span class="keywordflow">else</span> {
<a name="l00709"></a>00709    $mainNodes        = &amp;$node-&gt;nodeChildren;
<a name="l00710"></a>00710    $alternativeNodes = array();
<a name="l00711"></a>00711   }
<a name="l00712"></a>00712 
<a name="l00713"></a>00713   <span class="keywordflow">return</span> array($mainNodes, $alternativeNodes);
<a name="l00714"></a>00714  }
<a name="l00715"></a>00715  
<a name="l00729"></a><a class="code" href="class_template_compiler_ex.html#a0cee437cbd376a2ad926de8b745e120c">00729</a>  <span class="keyword">public</span> function <a class="code" href="class_template_compiler_ex.html#a0cee437cbd376a2ad926de8b745e120c" title="Generates prefixed block name that is guaranteed to be unique in current template.">generateUniqueBlock</a>($idPrefix, $blockPrefix = <span class="stringliteral">&#39;custom:&#39;</span>, $keyLength = 5) {
<a name="l00730"></a>00730   <span class="keywordflow">if</span> (32 - $keyLength &lt;= 0) {
<a name="l00731"></a>00731    <a class="code" href="class_template_utils.html#a9756a1cc5232e00302a0b52c3a1e8e10" title="Panics.">TemplateUtils::panic</a>(__FILE__, __LINE__);
<a name="l00732"></a>00732   }
<a name="l00733"></a>00733   
<a name="l00734"></a>00734   <span class="keywordflow">do</span> {
<a name="l00735"></a>00735    $generatedID  = md5(uniqid($idPrefix, <span class="keyword">true</span>));
<a name="l00736"></a>00736    $randomOffset = mt_rand(0, 32 - $keyLength);
<a name="l00737"></a>00737 
<a name="l00738"></a>00738    $blockName = $blockPrefix.mb_substr($generatedID, $randomOffset, $keyLength);
<a name="l00739"></a>00739   } <span class="keywordflow">while</span> (isset($this-&gt;blocks[$blockName]));
<a name="l00740"></a>00740 
<a name="l00741"></a>00741   <span class="keywordflow">return</span> $blockName;
<a name="l00742"></a>00742  }
<a name="l00743"></a>00743  
<a name="l00744"></a>00744  <span class="comment">// Hooks</span>
<a name="l00745"></a>00745  
<a name="l00756"></a><a class="code" href="class_template_compiler_ex.html#adb76060dfb9e369b12ee21bea4a51b8d">00756</a>  <span class="keyword">private</span> function <a class="code" href="class_template_compiler_ex.html#adb76060dfb9e369b12ee21bea4a51b8d" title="Runs handlers associated with given hook-point.">runHooks</a>($hookPoint, array $args) {
<a name="l00757"></a>00757   array_unshift($args, $this);
<a name="l00758"></a>00758   $handlers = $this-&gt;plugins-&gt;get(<span class="stringliteral">&#39;hook&#39;</span>, $hookPoint);
<a name="l00759"></a>00759   
<a name="l00760"></a>00760   <span class="keywordflow">foreach</span> ($handlers as &amp;$hookInfo) {
<a name="l00761"></a>00761    $handler = &amp;$hookInfo[<span class="stringliteral">&#39;handler&#39;</span>];
<a name="l00762"></a>00762    
<a name="l00763"></a>00763    <span class="keywordflow">if</span> (!is_callable($handler)) {
<a name="l00764"></a>00764     <span class="keywordflow">throw</span> <span class="keyword">new</span> <a class="code" href="class_template_error.html" title="Main and currently the only exception type thrown by SithTemplate internals.">TemplateError</a>(
<a name="l00765"></a>00765      <span class="stringliteral">&#39;Invalid handler [&#39;</span>.<a class="code" href="class_template_utils.html#a486a01915d89b3a87095461329a3a7e6" title="Strip newlines and spaces from string.">TemplateUtils::strip</a>(var_export($hookInfo[<span class="stringliteral">&#39;handler&#39;</span>], <span class="keyword">true</span>)).
<a name="l00766"></a>00766      <span class="stringliteral">&#39;] hooked into &quot;&#39;</span>.$hookPoint.<span class="stringliteral">&#39;&quot; point by plugin &quot;&#39;</span>.$hookInfo[<span class="stringliteral">&#39;plugin&#39;</span>].<span class="charliteral">&#39;&quot;&#39;</span>,
<a name="l00767"></a>00767      <a class="code" href="class_template_error.html#a197d3675b19ddab587d765167ba142d2" title="An invalid handler error.">TemplateError::E_INVALID_HANDLER</a>
<a name="l00768"></a>00768     );
<a name="l00769"></a>00769    }
<a name="l00770"></a>00770    
<a name="l00771"></a>00771    <span class="keywordflow">if</span> (call_user_func_array($handler, $args) === <span class="keyword">true</span>) <span class="keywordflow">return</span> <span class="keyword">true</span>;
<a name="l00772"></a>00772   }
<a name="l00773"></a>00773   
<a name="l00774"></a>00774   <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00775"></a>00775  }
<a name="l00776"></a>00776 }
<a name="l00777"></a>00777 
<a name="l00784"></a><a class="code" href="class_template_node_ex.html">00784</a> <span class="keyword">class </span><a class="code" href="class_template_node_ex.html" title="Class-container for AST nodes.">TemplateNodeEx</a> {
<a name="l00790"></a><a class="code" href="class_template_node_ex.html#a197e9a2189b3f2e5da6960792c2b0bc2">00790</a>  <span class="keyword">public</span> <a class="code" href="class_template_node_ex.html#a197e9a2189b3f2e5da6960792c2b0bc2" title="Type of this node.">$nodeID</a>       = <span class="stringliteral">&#39;&#39;</span>;
<a name="l00794"></a><a class="code" href="class_template_node_ex.html#a52572f655c352c200900c661fced7c7f">00794</a>  <span class="keyword">public</span> <a class="code" href="class_template_node_ex.html#a52572f655c352c200900c661fced7c7f" title="Parent of this node.">$nodeParent</a>   = null;
<a name="l00798"></a><a class="code" href="class_template_node_ex.html#a11071f5a75e8b01504b94c70b20a16f9">00798</a>  <span class="keyword">public</span> <a class="code" href="class_template_node_ex.html#a11071f5a75e8b01504b94c70b20a16f9" title="Children of this node.">$nodeChildren</a> = array();
<a name="l00803"></a><a class="code" href="class_template_node_ex.html#a02b43357ebf9a8c78a4b7ed6d50f666a">00803</a>  <span class="keyword">public</span> <a class="code" href="class_template_node_ex.html#a02b43357ebf9a8c78a4b7ed6d50f666a" title="Content of this node.">$nodeContent</a>  = null;
<a name="l00807"></a><a class="code" href="class_template_node_ex.html#a90a4bddb119982b9e11fd7293768e387">00807</a>  <span class="keyword">public</span> <a class="code" href="class_template_node_ex.html#a90a4bddb119982b9e11fd7293768e387" title="Aid for template debugging, source line where the parser constructed this node.">$nodeLine</a>     = 0;
<a name="l00811"></a><a class="code" href="class_template_node_ex.html#aa00e50823c505da795c0b2381badc312">00811</a>  <span class="keyword">public</span> <a class="code" href="class_template_node_ex.html#aa00e50823c505da795c0b2381badc312" title="Aid for template debugging, source file where the parser constructed this node.">$nodeFile</a>     = null;
<a name="l00812"></a>00812  
<a name="l00822"></a><a class="code" href="class_template_node_ex.html#aa44f330a0ecb8832f1990f5e3b6de712">00822</a>  <span class="keyword">public</span> function <a class="code" href="class_template_node_ex.html#aa44f330a0ecb8832f1990f5e3b6de712" title="Constructor.">__construct</a>($id, $parent = null, $content = null, $file = null, $line = 0) {
<a name="l00823"></a>00823   $this-&gt;nodeID      = $id;
<a name="l00824"></a>00824   $this-&gt;nodeParent  = $parent;
<a name="l00825"></a>00825   $this-&gt;nodeContent = $content;
<a name="l00826"></a>00826   $this-&gt;nodeLine    = $line;
<a name="l00827"></a>00827   $this-&gt;nodeFile    = $file;
<a name="l00828"></a>00828  }
<a name="l00829"></a>00829 
<a name="l00838"></a><a class="code" href="class_template_node_ex.html#ac4a2737627e12bace528ee449b45943f">00838</a>  <span class="keyword">public</span> function <a class="code" href="class_template_node_ex.html#ac4a2737627e12bace528ee449b45943f" title="Creates a new TemplateNodeEx instance and adds it to this node children.">addChild</a>($id, $content = null, $file = null, $line = 0) {
<a name="l00839"></a>00839   $this-&gt;nodeChildren[] = <span class="keyword">new</span> <a class="code" href="class_template_node_ex.html" title="Class-container for AST nodes.">TemplateNodeEx</a>($id, $this, $content, $file, $line);
<a name="l00840"></a>00840  }
<a name="l00841"></a>00841  
<a name="l00848"></a><a class="code" href="class_template_node_ex.html#a91391755954ef38c641ba68c1f752871">00848</a>  <span class="keyword">public</span> function <a class="code" href="class_template_node_ex.html#a91391755954ef38c641ba68c1f752871" title="Debugging aid.">dump</a>($level = 0) {
<a name="l00849"></a>00849   $out = <span class="stringliteral">&#39;&#39;</span>;
<a name="l00850"></a>00850   <span class="keywordflow">for</span> ($i = 0; $i &lt; $level; ++$i) { $out .= <span class="charliteral">&#39; &#39;</span>; }
<a name="l00851"></a>00851   $out .= <span class="stringliteral">&#39;ast&lt;&#39;</span>.$this-&gt;nodeID.<span class="charliteral">&#39;&gt;&#39;</span>;
<a name="l00852"></a>00852   <span class="keywordflow">if</span> (is_array($this-&gt;nodeContent)) {
<a name="l00853"></a>00853    $out .= <span class="charliteral">&#39;(&#39;</span>.$this-&gt;nodeContent[0];
<a name="l00854"></a>00854    <span class="keywordflow">if</span> (count($this-&gt;nodeContent[1]) &gt; 0) {
<a name="l00855"></a>00855     $out .= <span class="stringliteral">&#39;, &#39;</span>.implode(<span class="stringliteral">&#39;, &#39;</span>, $this-&gt;nodeContent[1]);
<a name="l00856"></a>00856    }
<a name="l00857"></a>00857    $out .= <span class="charliteral">&#39;)&#39;</span>;
<a name="l00858"></a>00858   } <span class="keywordflow">else</span> {
<a name="l00859"></a>00859    $s = str_replace(<span class="stringliteral">&quot;\n&quot;</span>, <span class="charliteral">&#39;\n&#39;</span>, $this-&gt;nodeContent);
<a name="l00860"></a>00860    <span class="keywordflow">if</span> (mb_strlen($s) &gt; 30) $s = mb_substr($s, 0, 30).<span class="stringliteral">&#39;[...]&#39;</span>;
<a name="l00861"></a>00861    $out .= <span class="stringliteral">&#39;(&quot;&#39;</span>.$s.<span class="stringliteral">&#39;&quot;)&#39;</span>;
<a name="l00862"></a>00862   }
<a name="l00863"></a>00863   $out .= <span class="stringliteral">&#39; @ &#39;</span>.$this-&gt;nodeFile.<span class="charliteral">&#39;:&#39;</span>.$this-&gt;nodeLine.<span class="stringliteral">&quot; =&gt; [\n&quot;</span>;
<a name="l00864"></a>00864   <span class="keywordflow">foreach</span> ($this-&gt;nodeChildren as $child) { $out .= $child-&gt;dump($level + 1); }
<a name="l00865"></a>00865   <span class="keywordflow">for</span> ($i = 0; $i &lt; $level; ++$i) { $out .= <span class="charliteral">&#39; &#39;</span>; }
<a name="l00866"></a>00866   <span class="keywordflow">return</span> $out . <span class="stringliteral">&quot;]\n&quot;</span>;
<a name="l00867"></a>00867  }
<a name="l00868"></a>00868 }
</pre></div></div>
</div>
<hr class="footer"/><address class="footer"><small>Generated on Fri Jan 14 2011 20:08:36 for SithTemplate by&#160;
<a href="http://www.doxygen.org/index.html">
<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.7.2 </small></address>
</body>
</html>
Return current item: SithTemplate