API Docs for: WebTemplate API v2.0
Show:

File: /data/www/webtemplate/wtv2/codedoc/wtTemplate.php

<?php

/**
 *  WebTemplate Core
 *
 *  @version 2.0
 *  @module WebTemplate Core
 */


$GLOBALS["WTTEMPLATESTACK"] = Array();

/**
 *  The class representing wtTemplate Nodes
 *
 *  @class WTTemplate
 *  @extends WTNode
 */
class WTTemplate extends WTNode 
{

  function getFormAttributeHTML($attributeInfo, $values) 
  {
/*    $attributeName = $attributeInfo["Attribute Name"];
    if($attributeName != "Name" && $attributeName != "Available") {
      return "";
    }*/
    return parent::getFormAttributeHTML($attributeInfo, $values);
  }

  /**
   *  Return the contents of a file
   *
   *  @method load
   *  @static
   *  @param {String} filepath The path to the file to load
   *  @return {String} Returns the contents of the file or false if the file does not exist
   */
  public static function load($filepath) 
  {
    if(file_exists($filepath)) {
      $fd = fopen($filepath, "r");
      $contents = fread($fd, filesize($filepath));
      fclose($fd);
      return $contents;
    }
    return false;
  }

  /**
   *  Returns the output of a template
   *
   *  @method compileAndEvaluate
   *  @static
   *  @param {String} template The template containing WebTemplate Tags
   *  @param {Array} templateData An associative array of data to pass to the template
   *  @return {String} The evaluated output of the template
   */
  public static function compileAndEvaluate($template, $templateData) 
  {
    ob_start();
    eval('?>' . WTTemplate::compile($template));
    return ob_get_clean();
  }


  /** 
   *  Read the &lt;wt:input&gt; tags in a template and return them as an associative array
   *
   *  @method readInputs
   *  @static
   *  @param {String} template The source of the template
   *  @return {Array} An associative array of the input tags
   */
  public static function readInputs($template) 
  {
    $inputs = Array();
    $i = 0;
    $templateLength = strlen($template);
    $i = strpos($template, '<wt:input');
    while($i !== false) {
      $i += 9;
      while($i < $templateLength && ($template[$i] == ' ' || $template[$i] == '\t' || $template[$i] == '\n' || $template[$i] == '\r')) {
        $i++;
      }

      $attributes = Array();
      while($i < $templateLength) {
        $attributeName = "";
        $attributeValue = "";

        while($i < $templateLength && ($template[$i] == ' ' || $template[$i] == '\t' || $template[$i] == '\n' || $template[$i] == '\r')) {
          $i++;
        }


        while($i < $templateLength && ($template[$i] != ' ' && $template[$i] != '\t' && $template != '\n' && $template[$i] != '=' && $template[$i] != '>')) {
          $attributeName .= $template[$i];
          $i++;
        }

        if($i >= $templateLength) {
          break;
        }

        while($i < $templateLength && ($template[$i] == ' ' || $template[$i] == '\t' || $template[$i] == '\n' || $template[$i] == '\r')) {
          $i++;
        }

        if($template[$i] == ">") {
          $i++;
          break;
        }

        if($i < ($templateLength - 1) && $template[$i] == "/" && $template[$i + 1] == ">") { 
          $i += 2;
          break;
        }

        if($template[$i] == '=') {
          $i++;
          while($i < $templateLength && ($template[$i] == ' ' || $template[$i] == '\t' || $template[$i] == '\n')) {
            $i++;
          }

          if($i >= $templateLength) {
            break;
          }

          if($template[$i] == '"') {
            $i++;
            while($i < $templateLength) {
              if($template[$i] == '"' && $template[$i - 1] != "\\") {
                $i++;
                break;
              }
              $attributeValue .= $template[$i];
              $i++;
            }
          }
        }
        $attributes[$attributeName] = $attributeValue;
      }

      if(array_key_exists("name", $attributes)) {
        $inputs[$attributes["name"]] = $attributes;
      }
      $i = strpos($template, '<wt:input', $i);
      
    }
    //print_r($inputs);
    return $inputs;
  }


  /**
   *  Compile a template containing WebTemplate Tags into PHP code
   *
   *  @method compile
   *  @static 
   *  @param template {String} The source of the template to compile
   *  @return {String} Returns the PHP code produced from the compilation   
   */
  public static function compile($template, $inphp = false, $templateName = "") 
  {
    $innerTemplateCount = 0;

    // the current depth of the stack
    $depth = 0;   

    // a stack of the content for each tag
    $stack = Array();
    $stack[0] = "";

    // map from source lines to produced lines
    $stackLineMap = Array();
    $stackLineMap[0] = Array();

    // stack ops contains the actual php code for each stack level
    $stackOps = Array();
    $stackOps[0] = "";

    $stackOpsLineMap = Array();
    $stackOpsLineMap[0] = Array();
    
    $stackCondition = Array();
    $stackCondition[0] = "";


    // inner templates is a string of the final output
    $innerTemplates = "";
    $innerTemplatesLineCount = Array();
 
    $line = 1;
    $errors = "";

    $i = 0;
    $templateLength = strlen($template);

    // tag stack is used for outputting error information.. eg non closed tags
    $tagStack = Array();

    $sourceLine = 1;

    while($i < $templateLength) {

      // need to know if the square wt tags are being used inside php
      if($template[$i] == '<' && $i < ($templateLength - 1) && $template[$i + 1] == '?') {
        $inphp = true;
      } else if($inphp && $template[$i] == '?' && ($templateLength - 1) && $template[$i + 1] == '>') {
        $inphp = false;
      }


      // is it the beginning of a square wt tag?
      if($template[$i] == '[' && $i < ($templateLength - 3) ) {

        // a square bracket tag
        if($template[$i + 1] == 'w' && $template[$i + 2] == 't' && $template[$i + 3] == ':') {
          $i += 4;
          $squaretag = "";
          $quote = "";
          $squaretagCount = 1;

          // loop until the end of the square tag, or the end of the template
          while($i < $templateLength) {
            if($template[$i] == "\n") {
              $sourceLine++;
              $stackLineMap[$depth][] = $sourceLine;

            }

            if($template[$i] == ']' && $quote == "") {
              $squaretagCount--;
              if($squaretagCount == 0) {
                $i++;
                break;
              }
            }

            if($template[$i] == '"' && $quote == "") {
              // entering a quote
              $quote = '"';
            } else if($template[$i] == '"' && $template[$i - 1] != "\\" && $quote == '"' ) {
              // exiting a quote
              $quote = "";
            } else if($template[$i] == "'" && $quote == "") {
              // entering a quote
              $quote = "'";
            } else if($template[$i] == "'" && $template[$i - 1] != "\\" && $quote == "'") {
              // exiting a quote
              $quote = "";
            } else if($quote == "" && $template[$i] == "[" && $i < ($templateLength - 3) && $template[$i + 1] == 'w' && $template[$i + 2] == 't' && $template[$i + 3] == ':') {
              // entering another square wt tag
              $squaretagCount++;
            } else if($template[$i] == "[" && $i < ($templateLength - 3) && $template[$i + 1] == 'w' && $template[$i + 2] == 't' && $template[$i + 3] == ':') {
              // entering a square wt tag inside a quote
              $squaretag .= "&sq;";
              $i++;
              continue;
            } else if( ($quote != "" || $squaretagCount > 1) && $template[$i] == '|') {
              // found a pipe
              $squaretag .= '&pipe;';
              $i++;
              continue;
            }
            $squaretag .= $template[$i];
            $i++;
          }
          // have now read in a complete square wt tag


          //  find any formatting functions within the square wt tag
          $formattingFunction = "";
          if(strpos($squaretag, "|") !== false) {
            $tagElements = explode("|", $squaretag);
            $squaretag = $tagElements[0];
            $formattingFunction = "%val%";

            // nest the formatting functions within each other, the initial value of the tag to be substituted for %val%
            for($j = 1; $j < count($tagElements); $j++) {
              $bracketpos = strpos($tagElements[$j], "(");
              if($bracketpos !== false) {
                if($tagElements[$j][$bracketpos + 1] == ')') {
                  $formattingFunction = str_replace("(", "($formattingFunction", "wtFmt" . ucfirst($tagElements[$j]));
                } else {
                  $formattingFunction = str_replace("(", "($formattingFunction, ", "wtFmt" . ucfirst($tagElements[$j]));
                }
              } else {
                $formattingFunction = "wtFmt" . ucfirst($tagElements[$j]) . "($formattingFunction)";
              }
            }

          }


          // get the initial value of the tag
          $value = "";
          if(strpos($squaretag, ".") !== false) {
            $tagElements = explode(".", $squaretag);
            if($tagElements[0] == "wt") {              
              $squaretag = str_replace('"', "\\\"", $squaretag);
              $value = '$GLOBALS["WT"]->getWTValue("' . $squaretag . '")';
            } else {
            }          
          } else {
            $value = '$templateData["' . $squaretag . '"]';
          }


          // substitute any formatting functions
          if($formattingFunction != "") {
            $value = str_replace("%val%", $value, $formattingFunction);
          }

          // if pipes withing quotes had been escaped, unescape them
          $value = str_replace('&pipe;', '|', $value);

          if(!$inphp) {
            $value = '<?php print ' . $value . '?>';
          }

          $value = WTTemplate::compile($value, $inphp, $templateName);
          $value = str_replace('&sq;', '[', $value);
          $stack[$depth] .= $value;

        } else {
          // it wasn't a square wt tag, but just a square opening bracket
          if($template[$i] == "\n") {
            $sourceLine++; 
            $line++;
            $stackLineMap[$depth][] = $sourceLine;
          }
          $stack[$depth] .= $template[$i];
          $i++;
        }
      } else if($template[$i] == "<" && $i < ($templateLength - 4)) {

        // is it the html <head> tag? if so, insert the wt head code
        if($i < ($templateLength - 6) && $template[$i + 1] == 'h' && $template[$i + 2] == 'e' && $template[$i + 3] == 'a' && $template[$i + 4] == 'd' && $template[$i + 5] == '>') {
          $i += 6;
          $stack[$depth] .= '<head>' . "\n";
          $stackLineMap[$depth][] = $sourceLine;
          $stack[$depth] .= '<?php'  . "\n";
          $stackLineMap[$depth][] = $sourceLine;
          $stack[$depth] .= 'wtHeaders();' . "\n";
          $stackLineMap[$depth][] = $sourceLine;
          $stack[$depth] .= '?>';
        } else if($template[$i + 1] == 'w' && $template[$i + 2] == 't' && $template[$i + 3] == ':') {

          // it's a wt tag...


          // attributes stores the attributes for the tag..
          $attributes = Array();
          $i += 4;
          $tag = "";

          // read in the type of tag
          while($i < $templateLength && $template[$i] != ' ' && $template[$i] != '>' && $template[$i] != '/') {
            if($template[$i] == "\n") {
              $line++;
              $sourceLine++;
            }
            $tag .= $template[$i];
            $i++;
          }


          $depth++;
          $stackOps[$depth] = '';
          $stackOpsLineMap[$depth] = Array();

          $stack[$depth] = "";
          $stackLineMap[$depth] = Array();
          
          while($i < $templateLength) {

            // skip over whitespace
            while($i < $templateLength && ($template[$i] == ' ' || $template[$i] == '\t' || $template[$i] == '\n' || $template[$i] == '\r')) {
              if($template[$i] == "\n") {
                $sourceLine++;
                $line++;
              }
              $i++;
            }

            if($i >= $templateLength) {
              break;
            }

            // reached the end of a non self closing tag
            if($template[$i] == ">") {
              array_push($tagStack, Array("tag" => $tag, "line" => $line));

              if($tag == "choose") {
                $stackCondition[$depth] = md5(uniqid());

                // this variable is set to true if one of the conditions of the choose is met
                // if it's not true then the otherwise part is executed
                $stackOps[$depth] = '$m' . $stackCondition[$depth] . ' = false;' . "\n";
                $stackOpsLineMap[$depth] = Array();
                $stackOpsLineMap[$depth][] = $sourceLine;

              } else if($tag == "when") { 
                $stackOps[$depth] = 'if(' . $attributes["test"] . ') { ' . "\n";
                $stackOpsLineMap[$depth] = Array();
                $stackOpsLineMap[$depth][] = $sourceLine;

                $stackOps[$depth] .= '$m' . $stackCondition[$depth - 1] . ' = true;' . "\n";
                $stackOpsLineMap[$depth][] = $sourceLine;
               
              } else if($tag == "otherwise") {
                $stackOps[$depth] = 'if(!$m' . $stackCondition[$depth - 1] . ') {' . "\n";
                $stackOpsLineMap[$depth] = Array();
                $stackOpsLineMap[$depth][] = $sourceLine;

              } else if($tag == "if") {
                $stackOps[$depth] = 'if(' . $attributes["test"] . ') { ' . "\n";
                $stackOpsLineMap[$depth] = Array();
                $stackOpsLineMap[$depth][] = $sourceLine;

              } else {
                $tag = "wt" . ucfirst($tag);
                $stackOps[$depth] .= 'if(function_exists("' . $tag . '")) {' . "\n";
                $stackOpsLineMap[$depth][] = $sourceLine;
                $stackOps[$depth] .= "  " . $tag . '($args, $templateData);' . "\n";
                $stackOpsLineMap[$depth][] = $sourceLine;
                $stackOps[$depth] .= '}' . "\n";
                $stackOpsLineMap[$depth][] = $sourceLine;
              }

              $i++;
              break;
            }

            // reached the end of a self closing tag
            if($i < ($templateLength - 1) && $template[$i] == "/" && $template[$i + 1] == ">") {

              $tag = "wt" . ucfirst($tag);
              $stackOps[$depth] .= 'if(function_exists("' . $tag . '")) {' . "\n";
              $stackOpsLineMap[$depth][] = $sourceLine;
              $stackOps[$depth] .= "  " . $tag . '($args, $templateData);' . "\n";
              $stackOpsLineMap[$depth][] = $sourceLine;
              $stackOps[$depth] .= '}' . "\n";
              $stackOpsLineMap[$depth][] = $sourceLine;

              $depth--;
              $stack[$depth] .= $stack[$depth + 1];
              foreach($stackLineMap[$depth + 1] as $mappedLine) {
                $stackLineMap[$depth][] = $mappedLine;
              }

              $stack[$depth] .= '<?php ' . "\n";
              $stackLineMap[$depth][] = $sourceLine;
              $stack[$depth] .= '$args = Array();' . "\n";
              $stackLineMap[$depth][] = $sourceLine;
              $stack[$depth] .= $stackOps[$depth + 1];

              foreach($stackOpsLineMap[$depth + 1] as $mappedLine) {
                $stackLineMap[$depth][] = $mappedLine;
              }

              $stack[$depth] .= '?>';

              $i += 2;
              break;
            }


            // haven't reached the end of the tag, so must be reading in an attribute name
            $attributeValue = "";
            $attributeName = "";
            while($i < $templateLength && ($template[$i] != ' ' && $template[$i] != '\t' && $template != '\n' && $template[$i] != '=' && $template[$i] != '>')) {
              $attributeName .= $template[$i];          
              $i++;
            }

  
            if($i >= $templateLength) {
              break;
            }
           
            // does the attribute have a value? 
            if($template[$i] == '=') {
              $i++;
              while($i < $templateLength && ($template[$i] == ' ' || $template[$i] == '\t' || $template[$i] == '\n')) {
                if($template[$i] == "\n") {
                  $sourceLine++;
                  $line++;
                }
                $i++;
              }
  
              if($i >= $templateLength) {
                break;
              } 

              
              if($template[$i] == '"') {                      
                // the attribute value is within double quotes
                $i++;
                while($i < $templateLength) {
 
                  // a non escaped double quote ends the attribute value
                  if($template[$i] == '"' && $template[$i - 1] != "\\") {
                    break;
                  }

                  // is there a square bracket wt tag within the value
                  if($template[$i] == '[' && $i < ($templateLength - 3) && $i < ($templateLength + 3) && $template[$i + 1] == 'w' && $template[$i + 2] == 't' && $template[$i + 3] == ':') {
                    $i+= 4;
                    $squaretag = "";
                    $squaretagCount = 1;

                    
                    $quote = "";
                    while($i < $templateLength) {

                      if($template[$i] == "\n") {
                        $sourceLine++;
                      }

                      // if not in a quote, then a closing square bracket ends the tag... should also test for whether within round brackets 
                      if($template[$i] == ']' && $quote == "") {                      
                        break;
                      }

                      if($template[$i] == '"' && $quote == "") {
                        $quote = '"';
                      } else if($template[$i] == '"' && $template[$i - 1] != "\\" && $quote == '"' ) {
                        $quote = "";
                      } /*else if($template[$i] == "'" && $quote == "") {
                        $quote = "'";
                      } else if($template[$i] == "'" && $template[$i - 1] != "\\" && $quote == "'") {
                        $quote = "";
                      } else if($quote == "" && $template[$i] == "[" && $i < ($templateLength - 3) && $template[$i + 1] == 'w' && $template[$i + 2] == 't' && $template[$i + 3] == ':') {
                        $squaretagCount++;
                      } else if($template[$i] == "[" && $i < ($templateLength - 3) && $template[$i + 1] == 'w' && $template[$i + 2] == 't' && $template[$i + 3] == ':') {
                        $squaretag .= "&sq;";
                        $i++;
                        continue;
                      } else if( ($quote != "" || $squaretagCount > 1) && $template[$i] == '|') {
                        $squaretag .= '&pipe;';
                        $i++;
                        continue;

                      }
*/
                      $squaretag .= $template[$i];
                      $i++;
                    }


                    // convert the formatting functions to their php equivalent
                    $formattingFunction = "";
                    if(strpos($squaretag, "|") !== false) {
                      $tagElements = explode("|", $squaretag);
                      $squaretag = $tagElements[0];
                      $formattingFunction = "%val%";

                      for($j = 1; $j < count($tagElements); $j++) {
                        $bracketpos = strpos($tagElements[$j], "(");
                        if($bracketpos !== false) {
                          if($tagElements[$j][$bracketpos + 1] == ')') {
                            $formattingFunction = str_replace("(", "($formattingFunction", "wtFmt" . ucfirst($tagElements[$j]));
                          } else {
                            $formattingFunction = str_replace("(", "($formattingFunction, ", "wtFmt" . ucfirst($tagElements[$j]));
                          }
                        } else {
                          $formattingFunction = "wtFmt" . ucfirst($tagElements[$j]) . "($formattingFunction)";
                        }
                      }
                    }

                    $value = "";
                    if(strpos($squaretag, ".") !== false) {
                      $tagElements = explode(".", $squaretag);
                      if($tagElements[0] == "wt") {
                        $squaretag = str_replace('"', "\\\"", $squaretag);
                        $value = '$GLOBALS["WT"]->getWTValue("' . $squaretag . '")';

                      } else {
                      }
                    } else {
                      $value = '$templateData["' . $squaretag . '"]';
                    }
                    if($formattingFunction != "") {
                      $value = str_replace("%val%", $value, $formattingFunction);
                    }

                    if($tag == "if" || $tag == "when") {
                      $attributeValue .= $value;
                    } else {
                      $attributeValue .= '" . ' . $value . ' . "';
                    }


                
                  } else {
                    $attributeValue .= $template[$i];
                  }
                  $i++;
                }  
  
                if($tag != "if" && $tag != "when") { 
                  $attributeValue = '"' . $attributeValue . '"';
                }
                $i++;
              } else if($template[$i] == "'") {
                // attribute value is within single quoted tags
                $i++;
                while($i < $templateLength) {
                  if($template[$i] == "\n") {
                    $sourceLine++;
                  }
                  if($template[$i] == "'" && $template[$i - 1] != "\\") {
                    break;
                  }
                  if($template[$i] == "\\") {
                    $i++;
                    continue;
                  }
                  $attributeValue .= $template[$i];
                  $i++;
                }
                $i++;
              } else {
                // attribute value is not within tags
                while($i < $templateLength && ($template[$i] != '>' && $template[$i] != ' ' && $template[$i] != '\n' && $template[$i] != '\t')) {
                  $attributeValue .= $template[$i];
                  $i++;
                }
              }
            }

            // prob need to test if attribute is alphanumeric
            if($attributeValue == "") {
              $attributeValue = '""';
            }
            $attributes[$attributeName] = $attributeValue;
            $stackOps[$depth] .= '$args["' . $attributeName . '"] = ' . $attributeValue . ';' . "\n";
            $stackOpsLineMap[$depth][] = $sourceLine;
          }

        } else if($template[$i + 1] == '/' && $template[$i + 2] == 'w' && $template[$i + 3] == 't' && $template[$i + 4] == ':') {
          // have found the closing tag, read until the end of it
          $i += 5;
   
          $tag = "";
          while($i < $templateLength) {
            if($template[$i] == "\n") {
              $sourceLine++;
            }

            if($template[$i] == '>') {
              $i++;
              break;
            }
            $tag .= $template[$i]; 
            $i++;
          }   
          $depth--;

          // make sure the closing tag has a matching opening tag..
          $stackCount = count($tagStack);
          if($stackCount > 0) {
            if($tagStack[$stackCount - 1]["tag"] == $tag) {
              array_pop($tagStack);
            } else { 
              $errors .= "No matching closing tag for <wt:" . $tagStack[$stackCount - 1]["tag"] . "> on line " . $tagStack[$stackCount - 1]["line"] . " instead found </wt:$tag> on line $line in '$templateName'\n";
              
              for($sc = $stackCount - 1; $sc >= 0; $sc--) {
                if($tagStack[$sc]["tag"] == $tag) {
                  while(count($tagStack) > $sc) {
                    array_pop($tagStack);
                  }
                  break;
                }
              }
            }
          } else {
            $errors .= "ERROR no opening tag for </wt:$tag> on line $line in '$templateName'\n";
          }

          if($tag == "comment") {
          } else if($stack[$depth + 1] != "" && ($tag == "list" || $tag == "node" || $tag == "widget" || $tag == "files" || $tag == "noresults" || $tag == "image" || $tag == "form" || $tag == "productoptions" || $tag == "cart" || $tag == "extension" || $tag == "head" || $tag == "search" || $tag == "mlSearch") ) {

            // the inner template for the tag is everything within the tag..
            $innerTemplateID = md5(uniqid('', true));
            $functionName = "innerTemplate$innerTemplateID";
            $innerTemplates .= 'if(!function_exists("' . $functionName . '")) {' . "\n";
            $innerTemplatesLineCount[] = $sourceLine;

            $innerTemplates .= '  function ' . $functionName . '($templateData, $args = NULL) {' . "\n";
            $innerTemplatesLineCount[] = $sourceLine;

            $innerTemplates .= '    if($args != NULL && array_key_exists("WTFUNCTION", $args)) { ' . "\n";
            $innerTemplatesLineCount[] = $sourceLine;

            $innerTemplates .= '      $wtFunction = $args["WTFUNCTION"];' . "\n";
            $innerTemplatesLineCount[] = $sourceLine;

            $innerTemplates .= '    }' . "\n";
            $innerTemplatesLineCount[] = $sourceLine;

            $innerTemplates .= ' ?>';
            $innerTemplates .= $stack[$depth + 1];

            foreach($stackLineMap[$depth + 1] as $mappedLine) {
              $innerTemplatesLineCount[] = $mappedLine;
            }

            $innerTemplates .= '<?php' . "\n";
            $innerTemplatesLineCount[] = $sourceLine;
            $innerTemplates .= "  }\n";
            $innerTemplatesLineCount[] = $sourceLine;
            $innerTemplates .= "}\n";
            $innerTemplatesLineCount[] = $sourceLine;
        


            if($tag == "noresults") {
              $stackOps[$depth] = '$args["No Results Template Function"] = "innerTemplate' . $innerTemplateID . '";' . "\n" . $stackOps[$depth];
              array_unshift($stackOpsLineMap[$depth], $sourceLine);
            } else {
              if(!$stackOpsLineMap[$depth + 1]) {
                $stackOpsLineMap[$depth + 1] = Array();
              }
              $stackOps[$depth + 1] = '$args = Array();' . "\n" . '$args["Template Function"] = "innerTemplate' . $innerTemplateID . '";' . "\n" . $stackOps[$depth + 1];
              array_unshift($stackOpsLineMap[$depth + 1], $sourceLine);
              array_unshift($stackOpsLineMap[$depth + 1], $sourceLine);
            }
            $innerTemplateCount++;
            $stack[$depth] .= '<?php ' . "\n";
            $stackLineMap[$depth][] = $sourceLine;
            $stack[$depth] .= $stackOps[$depth + 1];
            foreach($stackOpsLineMap[$depth + 1] as $mappedLine) {
              $stackLineMap[$depth][] = $mappedLine;
            }
            $stack[$depth] .= '?>';


          } else {
            $stack[$depth] .= '<?php' . "\n";
            $stackLineMap[$depth][] = $sourceLine;
            $stack[$depth] .= '$args = Array();' . "\n";
            $stackLineMap[$depth][] = $sourceLine;


            // not sure what this is for? something to do with telling if in wtNode or wtList
            if($tag == "editable") {
              $stack[$depth] .= 'if(isset($wtFunction)) {' . "\n";
              $stackLineMap[$depth][] = $sourceLine;
              $stack[$depth] .= '$args["WTFUNCTION"] = $wtFunction; // ' . "$tag\n";
              $stackLineMap[$depth][] = $sourceLine;
              $stack[$depth] .= '}' . "\n";
              $stackLineMap[$depth][] = $sourceLine;
            }

            $stack[$depth] .= $stackOps[$depth + 1];
            foreach($stackOpsLineMap[$depth + 1] as $mappedLine) {
              $stackLineMap[$depth][] = $mappedLine;
            }

            $stack[$depth] .= '?>';


            $stack[$depth] .= $stack[$depth + 1];
            foreach($stackLineMap[$depth + 1] as $mappedLine) {
              $stackLineMap[$depth][] = $mappedLine;
            }

            if($tag == "if" || $tag == "when" || $tag == "otherwise") {
              $stack[$depth] .= '<?php } ?>';
            } else if($tag != "choose") {
              // need an end tag for editable and capture  (ie call the function wtEndEditable, wtEndCapture
              $stack[$depth] .= '<?php' . "\n";
              $stackLineMap[$depth][] = $sourceLine;
              $stack[$depth] .= '$args = Array();' . "\n";
              $stackLineMap[$depth][] = $sourceLine;
              $stack[$depth] .= str_replace("wt" . ucfirst($tag), "wtEnd" . ucfirst($tag), $stackOps[$depth + 1]);
              foreach($stackOpsLineMap[$depth + 1] as $mappedLine) {
                $stackLineMap[$depth][] = $mappedLine;
              }
              $stack[$depth] .= '?>';
            }

          }
        } else {
          // opening triangle bracket, but its not a wt tag
          $stack[$depth] .= $template[$i];
 
          if($template[$i] == "\n") {
            $sourceLine++;
            $line++;
            $stackLineMap[$depth][] = $sourceLine;
          }
          $i++;
        }
  
      } else {
        // haven't found any webtemplate tag
        $stack[$depth] .= $template[$i];
        if($template[$i] == "\n") {
          $stackLineMap[$depth][] = $sourceLine; 
          $sourceLine++;
          $line++;
        } 
        $i++;
      }
    }

    // need to make sure closing depth is 0!!


    $stackCount = count($tagStack);
    if($stackCount > 0) {
      $errors .= "No matching closing tag for <wt:" . $tagStack[$stackCount - 1]["tag"] . "> on line " . $tagStack[$stackCount - 1]["line"] . " instead found the End of the File in '$templateName'\n";
    }


    if($errors != "") {
    
      if($GLOBALS["WTSITEID"] > 11734 || $GLOBALS["WTSITEID"] < 10000 || $GLOBALS["WTSITEID"] == 11725) { 
        $errors = htmlentities($errors);
        $errors = nl2br($errors);
        return $errors;
      }
    }


    foreach($stackLineMap[$depth] as $mappedLine) {
      $innerTemplatesLineCount[] = $mappedLine;
    }

    array_unshift($innerTemplatesLineCount, 0);

    if(trim($innerTemplates) != "") {
      // add in a line for the initial php tag
      array_unshift($innerTemplatesLineCount, 0);
      $GLOBALS["WTTEMPLATELINEMAP"] = $innerTemplatesLineCount;
      return '<?php' . "\n" . $innerTemplates . '?>' . $stack[$depth];
    } else {
      $GLOBALS["WTTEMPLATELINEMAP"] = $innerTemplatesLineCount;
      return $stack[$depth];
    }
  }



  /**
   *  Return the inputs for the template in an associative array
   *
   *  @method getInputs
   *  @return {Array} An associative array of the inputs for the template
   */
  function getInputs() 
  {
    $inputs = $this->getAttribute("Inputs");
    if($inputs != "") {
      return unserialize($inputs);
    }
    return Array();
  }


  /**
   *  Produce the output for a template given some data to pass to the template
   *
   *  @method evaluate
   *  @param {Array} templateData An Associative array of data to pass to the template
   *  @return {String} The output of the template
   */
  function evaluate($templateData) 
  {
    $sourceFile = $this->getAttribute("Source File");

    if($sourceFile != "") {
      $filepath = trim($sourceFile);
      if(strlen($filepath) > 0 && $filepath[0] != "/") {
//        $filepath = $GLOBALS["WTTEMPLATEDIRECTORY"] . $filepath;
        $filepath = $GLOBALS["WT"]->getSiteSetting("Template Directory") . $filepath;
      }

//print $filepath;
      if(file_exists($filepath)) {
        $modifiedDate = filemtime($filepath);
        if($modifiedDate != $this->getAttribute("Source File Modified")) {

          $file = $this->getAttribute("Source File");
          $filepath = trim($file);
          if(strlen($filepath) > 0 && $filepath[0] != "/") {
            $filepath = $GLOBALS["WT"]->getSiteSetting("Template Directory") . $filepath;
          }

          // TODO: maybe the wrong place for this...causes errors if wt tags are in the php

/*
          if(file_exists($filepath)) {
            $errors = shell_exec("php -l $filepath");
            if(strpos($errors, "No syntax errors") === false) {
              print "<b>Syntax errors in: " . $this->getAttribute("Source File") . "</b>";
              print nl2br($errors);
              return;
            } 
          }
*/
          $this->setAttributes(Array("Source File" => $sourceFile));
        }
      }
    }


    if($GLOBALS["WTSITEID"] == 11244 || $GLOBALS["WTSITEID"] == 11636 || $GLOBALS["WTSITEID"] == 11473 || $GLOBALS["WTSITEID"] == 11358 || $GLOBALS["WTSITEID"] == 11249 || $GLOBALS["WTSITEID"] == 11694 || $GLOBALS["WTSITEID"] == 11588  || $GLOBALS["WTSITEID"] == 11299 || $GLOBALS["WTSITEID"] == 11635 ||  $GLOBALS["WTSITEID"] == 11542) {

      $filesDirectory = $GLOBALS["WTSITEDIRECTORY"] . $GLOBALS["WT"]->m_siteSettings["Site Directory"] . "/files/";
      $templateDirectory = $filesDirectory . "templates/";
      $templateFile = $templateDirectory . $this->m_guid . ".php";
      if(!file_exists($templateFile)) {
        $this->setAttributes(Array("Source File" => $sourceFile));
      }


      ob_start();
      if(!file_exists($templateFile)) {
        print "id = " . $GLOBALS["WTSITEID"];
      }
      include $templateFile;
      return ob_get_clean();


    } else {

      
      $compiledTemplate = $this->getAttribute("Compiled");   
      ob_start();

      array_push($GLOBALS["WTTEMPLATESTACK"], $this->getAttribute("Name"));
      eval('?>' . $compiledTemplate);
      array_pop($GLOBALS["WTTEMPLATESTACK"]);

      return ob_get_clean();
    }
  }


  /**
   *  Set the attributes of the template<br/>
   *  If the Source File attribute is passed in, the template will be read from the file
   *
   *  @method setAttributes
   *  @param {Array} An associative array of attributes
   */
  function setAttributes($attributes) 
  {
    if(array_key_exists("Source File", $attributes)) {
      $file = $attributes["Source File"];
      $filepath = trim($file);
      if(strlen($filepath) > 0 && $filepath[0] != "/") {
//        $filepath = $GLOBALS["WTTEMPLATEDIRECTORY"] . $filepath;
        $filepath = $GLOBALS["WT"]->getSiteSetting("Template Directory") . $filepath;
        //print "\n$filepath\n"; 
      }

      if(file_exists($filepath)) {
        $attributes["Source"] = file_get_contents($filepath);
        $attributes["Source File Modified"] = filemtime($filepath);
      } else {
        print "template file {$attributes["Source File"]} does not exist";
      }
    }

    if(array_key_exists("Source", $attributes)) {
      $templateName = "";
      if(array_key_exists("Name", $attributes)) {
        $templateName = $attributes["Name"];
      }
      if(!$templateName) {
        $templateName = $this->getAttribute("Name");
      }
      $attributes["Compiled"] = WTTemplate::compile($attributes["Source"], false, $templateName);

      if($GLOBALS["WTSITEID"] == 11244 || $GLOBALS["WTSITEID"] == 11636 || $GLOBALS["WTSITEID"] == 11473  || $GLOBALS["WTSITEID"] == 11358  || $GLOBALS["WTSITEID"] == 11249 || $GLOBALS["WTSITEID"] == 11694 || $GLOBALS["WTSITEID"] == 11588 || $GLOBALS["WTSITEID"] == 11299 || $GLOBALS["WTSITEID"] == 11635 ||  $GLOBALS["WTSITEID"] == 11542) {
        $filesDirectory = $GLOBALS["WTSITEDIRECTORY"] . $GLOBALS["WT"]->m_siteSettings["Site Directory"] . "/files/";
        $templateDirectory = $filesDirectory . "templates/";
        if(!file_exists($templateDirectory)) {
          mkdir($templateDirectory);
        }
        $templateFile = $templateDirectory . $this->m_guid . ".php";
        $fp = fopen($templateFile, "w");
        fwrite($fp, $attributes["Compiled"]);
        fclose($fp);
      }

      $inputs = WTTemplate::readInputs($attributes["Source"]);
      if(count($inputs) > 0) {
        $attributes["Inputs"] = serialize($inputs);
      } else {
        $attributes["Inputs"] = "";
      }
    }

    parent::setAttributes($attributes);
  }
}

//$GLOBALS["WT"]->registerNodeTypeClass("Template", "WTTemplate");

?>