Newer
Older
ubFramework / Portal / docroot / include / core / templates.php
@Christopher W. Olsen Christopher W. Olsen on 10 Dec 2017 17 KB Cleaning Up Making It A Sub Module
<?php
class ubF_templates {
  
  // Holds the array of filehandles FILELIST[HANDLE] == "fileName"
  var $FILELIST = array ();
  
  // Holds the array of dynamic blocks, and the fileHandles they live in.
  var $DYNAMIC = array ();
  
  // Holds the array of Variable handles. PARSEVARS[HANDLE] == "value"
  var $PARSEVARS = array ();
  
  // We only want to load a template once - when it's used. LOADED[FILEHANDLE] == 1 if loaded undefined if not loaded yet.
  var $LOADED = array ();
  var $HANDLE = array ();
  // Holds the handle names assigned by a call to parse()
  var $ROOT = "";
  // Holds path-to-templates
  var $WIN32 = false;
  // Set to true if this is a WIN32 server
  
  // Holds the last error message
  var $ERROR = "";
  
  // Holds the HANDLE to the last template parsed by parse()
  var $LAST = "";
  
  // Strict template checking. Unresolved vars in templates will generate a warning when found.
  var $STRICT = true;
  
  // ************************************************************
  function ubF_templates($pathToTemplates = "") {
    global $php_errormsg;
    
    if (! empty ( $pathToTemplates ))
      $this->set_root ( $pathToTemplates );
  }
  // end (new) FastTemplate ()
  
  /**
   *
   * All templates will be loaded from this "root" directory
   * Can be changed in mid-process by re-calling with a new
   * value.
   *
   * @param unknown $root          
   */
  public function set_root($root) {
    $trailer = substr ( $root, - 1 );
    
    if (! $this->WIN32) {
      if ((ord ( $trailer )) != 47)
        $root = "$root" . chr ( 47 );
      
      if (is_dir ( $root ))
        $this->ROOT = $root;
      else {
        $this->ROOT = "";
        $this->error ( "Specified ROOT dir [$root] is not a directory" );
      }
    }
    else {
      // WIN32 box - no testing
      if ((ord ( $trailer )) != 92)
        $root = "$root" . chr ( 92 );
      
      $this->ROOT = $root;
    }
  }
  // End set_root()
  
  // **************************************************************
  // Calculates current microtime
  // I throw this into all my classes for benchmarking purposes
  // It's not used by anything in this class and can be removed
  // if you don't need it.
  function utime() {
    $time = explode ( " ", microtime () );
    $usec = ( double ) $time [0];
    $sec = ( double ) $time [1];
    return $sec + $usec;
  }
  
  // **************************************************************
  // Strict template checking, if true sends warnings to STDOUT when
  // parsing a template with undefined variable references
  // Used for tracking down bugs-n-such. Use no_strict() to disable.
  function strict() {
    $this->STRICT = true;
  }
  
  // ************************************************************
  // Silently discards (removes) undefined variable references
  // found in templates
  function no_strict() {
    $this->STRICT = false;
  }
  
  // ************************************************************
  // A quick check of the template file before reading it.
  // This is -not- a reliable check, mostly due to inconsistencies
  // in the way PHP determines if a file is readable.
  function is_safe($filename) {
    if (! file_exists ( $filename )) {
      $this->error ( "[$filename] does not exist", 0 );
      return false;
    }
    return true;
  }
  
  // ************************************************************
  // Grabs a template from the root dir and
  // reads it into a (potentially REALLY) big string
  function get_template($template) {
    if (empty ( $this->ROOT )) {
      $this->error ( "Cannot open template. Root not valid.", 1 );
      return false;
    }
    
    $filename = "$this->ROOT" . "$template";
    $contents = implode ( "", (@file ( $filename )) );
    if ((! $contents) or (empty ( $contents ))) {
      $this->error ( "get_template() failure: [$filename] $php_errormsg", 1 );
    }
    
    return $contents;
  }
  // end get_template
  
  // ************************************************************
  // Prints the warnings for unresolved variable references
  // in template files. Used if STRICT is true
  function show_unknowns($Line) {
    $unknown = array ();
    if (preg_match ( "({[A-Z0-9_]+})", $Line, $unknown )) {
      if (isset ( $unknown [1] ))
        $UnkVar = $unknown [1];
      if (! (empty ( $UnkVar ))) {
        @error_log ( "[FastTemplate] Warning: no value found for variable: $UnkVar ", 0 );
      }
    }
  }
  // end show_unknowns()
  
  // ************************************************************
  // This routine get's called by parse() and does the actual
  // {VAR} to VALUE conversion within the template.
  function parse_template($template, $tpl_array) {
    while ( list ( $key, $val ) = each ( $tpl_array ) ) {
      if (! (empty ( $key ))) {
        if (gettype ( $val ) != "string") {
          settype ( $val, "string" );
        }
        
        // php4 doesn't like '{$' combinations.
        $key = '{' . "$key" . '}';
        // $template = preg_replace("$key","$val","$template");
        $template = str_replace ( "$key", "$val", "$template" );
      }
    }
    
    if (! $this->STRICT) {
      // Silently remove anything not already found
      
      $template = preg_replace ( "{([A-Z0-9_]+)}", "", $template );
    }
    else {
      // Warn about unresolved template variables
      if (preg_match ( "({[A-Z0-9_]+})", $template )) {
        $unknown = preg_split ( "/\n/", $template );
        while ( list ( $Element, $Line ) = each ( $unknown ) ) {
          $UnkVar = $Line;
          if (! (empty ( $UnkVar ))) {
            $this->show_unknowns ( $UnkVar );
          }
        }
      }
    }
    return $template;
  }
  // end parse_template();
  
  // ************************************************************
  // The meat of the whole class. The magic happens here.
  function parse($ReturnVar, $FileTags) {
    $append = false;
    $this->LAST = $ReturnVar;
    $this->HANDLE [$ReturnVar] = 1;
    
    if (gettype ( $FileTags ) == "array") {
      unset ( $this->$ReturnVar ); // Clear any previous data
      
      while ( list ( $key, $val ) = each ( $FileTags ) ) {
        if ((! isset ( $this->$val )) || (empty ( $this->$val ))) {
          $this->LOADED ["$val"] = 1;
          if (isset ( $this->DYNAMIC ["$val"] )) {
            $this->parse_dynamic ( $val, $ReturnVar );
          }
          else {
            $fileName = $this->FILELIST [$val];
            $this->$val = $this->get_template ( $fileName );
          }
        }
        
        // Array context implies overwrite
        
        $this->$ReturnVar = $this->parse_template ( $this->$val, $this->PARSEVARS );
        
        // For recursive calls.
        
        $this->assign ( array (
          $ReturnVar => $this->$ReturnVar 
        ) );
      }
    } // end if FileTags is array()
    else {
      // FileTags is not an array
      
      $val = $FileTags;
      
      if ((substr ( $val, 0, 1 )) == '.') {
        // Append this template to a previous ReturnVar
        
        $append = true;
        $val = substr ( $val, 1 );
      }
      
      if ((! isset ( $this->$val )) || (empty ( $this->$val ))) {
        $this->LOADED ["$val"] = 1;
        if (isset ( $this->DYNAMIC ["$val"] )) {
          $this->parse_dynamic ( $val, $ReturnVar );
        }
        else {
          $fileName = $this->FILELIST [$val];
          $this->$val = $this->get_template ( $fileName );
        }
      }
      
      if ($append) {
        $this->$ReturnVar .= $this->parse_template ( $this->$val, $this->PARSEVARS );
      }
      else {
        $this->$ReturnVar = $this->parse_template ( $this->$val, $this->PARSEVARS );
      }
      
      // For recursive calls.
      
      $this->assign ( array (
        $ReturnVar => $this->$ReturnVar 
      ) );
    }
    return;
  }
  // End parse()
  
  // ************************************************************
  function FastPrint($template = "") {
    if (empty ( $template )) {
      $template = $this->LAST;
    }
    
    if ((! (isset ( $this->$template ))) || (empty ( $this->$template ))) {
      $this->error ( "Nothing parsed, nothing printed", 0 );
      return;
    }
    else {
      print $this->$template;
    }
    return;
  }
  
  // ************************************************************
  function fetch($template = "") {
    if (empty ( $template ))
      $template = $this->LAST;
    
    if ((! (isset ( $this->$template ))) || (empty ( $this->$template ))) {
      $this->error ( "Nothing parsed, nothing printed", 0 );
      return "";
    }
    return ($this->$template);
  }
  
  // ************************************************************
  function define_dynamic($Macro, $ParentName) {
    // A dynamic block lives inside another template file.
    // It will be stripped from the template when parsed
    // and replaced with the {$Tag}.
    $this->DYNAMIC ["$Macro"] = $ParentName;
    return true;
  }
  
  // ************************************************************
  function parse_dynamic($Macro, $MacroName) {
    // The file must already be in memory.
    $ParentTag = $this->DYNAMIC ["$Macro"];
    if ((! $this->$ParentTag) or (empty ( $this->$ParentTag ))) {
      $fileName = $this->FILELIST [$ParentTag];
      $this->$ParentTag = $this->get_template ( $fileName );
      $this->LOADED [$ParentTag] = 1;
    }
    if ($this->$ParentTag) {
      $template = $this->$ParentTag;
      $DataArray = split ( "\n", $template );
      $newMacro = "";
      $newParent = "";
      $outside = true;
      $start = false;
      $end = false;
      while ( list ( $lineNum, $lineData ) = each ( $DataArray ) ) {
        $lineTest = trim ( $lineData );
        if ("<!-- BEGIN DYNAMIC BLOCK: $Macro -->" == "$lineTest") {
          $start = true;
          $end = false;
          $outside = false;
        }
        if ("<!-- END DYNAMIC BLOCK: $Macro -->" == "$lineTest") {
          $start = false;
          $end = true;
          $outside = true;
        }
        if ((! $outside) and (! $start) and (! $end)) {
          $newMacro .= "$lineData\n"; // Restore linebreaks
        }
        if (($outside) and (! $start) and (! $end)) {
          $newParent .= "$lineData\n"; // Restore linebreaks
        }
        if ($end) {
          $newParent .= '{' . "$MacroName}\n";
        }
        // Next line please
        if ($end) {
          $end = false;
        }
        if ($start) {
          $start = false;
        }
      } // end While
      
      $this->$Macro = $newMacro;
      $this->$ParentTag = $newParent;
      return true;
    } // $ParentTag NOT loaded - MAJOR oopsie
    else {
      @error_log ( "ParentTag: [$ParentTag] not loaded!", 0 );
      $this->error ( "ParentTag: [$ParentTag] not loaded!", 0 );
    }
    return false;
  }
  
  // ************************************************************
  // Strips a DYNAMIC BLOCK from a template.
  function clear_dynamic($Macro = "") {
    if (empty ( $Macro )) {
      return false;
    }
    
    // The file must already be in memory.
    
    $ParentTag = $this->DYNAMIC ["$Macro"];
    
    if ((! $this->$ParentTag) or (empty ( $this->$ParentTag ))) {
      $fileName = $this->FILELIST [$ParentTag];
      $this->$ParentTag = $this->get_template ( $fileName );
      $this->LOADED [$ParentTag] = 1;
    }
    
    if ($this->$ParentTag) {
      $template = $this->$ParentTag;
      $DataArray = split ( "\n", $template );
      $newParent = "";
      $outside = true;
      $start = false;
      $end = false;
      while ( list ( $lineNum, $lineData ) = each ( $DataArray ) ) {
        $lineTest = trim ( $lineData );
        if ("<!-- BEGIN DYNAMIC BLOCK: $Macro -->" == "$lineTest") {
          $start = true;
          $end = false;
          $outside = false;
        }
        if ("<!-- END DYNAMIC BLOCK: $Macro -->" == "$lineTest") {
          $start = false;
          $end = true;
          $outside = true;
        }
        if (($outside) and (! $start) and (! $end)) {
          $newParent .= "$lineData\n"; // Restore linebreaks
        }
        // Next line please
        if ($end) {
          $end = false;
        }
        if ($start) {
          $start = false;
        }
      } // end While
      
      $this->$ParentTag = $newParent;
      return true;
    } // $ParentTag NOT loaded - MAJOR oopsie
    else {
      @error_log ( "ParentTag: [$ParentTag] not loaded!", 0 );
      $this->error ( "ParentTag: [$ParentTag] not loaded!", 0 );
    }
    return false;
  }
  
  // ************************************************************
  function define($fileList) {
    while ( list ( $FileTag, $FileName ) = each ( $fileList ) ) {
      $this->FILELIST [$FileTag] = $FileName;
    }
    return true;
  }
  
  // ************************************************************
  function clear_parse($ReturnVar = "") {
    $this->clear ( $ReturnVar );
  }
  
  // ************************************************************
  function clear($ReturnVar = "") {
    // Clears out hash created by call to parse()
    if (! empty ( $ReturnVar )) {
      if ((gettype ( $ReturnVar )) != "array") {
        unset ( $this->$ReturnVar );
        return;
      }
      else {
        while ( list ( $key, $val ) = each ( $ReturnVar ) ) {
          unset ( $this->$val );
        }
        return;
      }
    }
    
    // Empty - clear all of them
    
    while ( list ( $key, $val ) = each ( $this->HANDLE ) ) {
      $KEY = $key;
      unset ( $this->$KEY );
    }
    return;
  }
  // end clear()
  
  // ************************************************************
  function clear_all() {
    $this->clear ();
    $this->clear_assign ();
    $this->clear_define ();
    $this->clear_tpl ();
    
    return;
  }
  // end clear_all
  
  // ************************************************************
  function clear_tpl($fileHandle = "") {
    if (empty ( $this->LOADED )) {
      // Nothing loaded, nothing to clear
      
      return true;
    }
    if (empty ( $fileHandle )) {
      // Clear ALL fileHandles
      
      while ( list ( $key, $val ) = each ( $this->LOADED ) ) {
        unset ( $this->$key );
      }
      unset ( $this->LOADED );
      
      return true;
    }
    else {
      if ((gettype ( $fileHandle )) != "array") {
        if ((isset ( $this->$fileHandle )) || (! empty ( $this->$fileHandle ))) {
          unset ( $this->LOADED [$fileHandle] );
          unset ( $this->$fileHandle );
          return true;
        }
      }
      else {
        while ( list ( $Key, $Val ) = each ( $fileHandle ) ) {
          unset ( $this->LOADED [$Key] );
          unset ( $this->$Key );
        }
        return true;
      }
    }
    
    return false;
  }
  // end clear_tpl
  
  // ************************************************************
  function clear_define($FileTag = "") {
    if (empty ( $FileTag )) {
      unset ( $this->FILELIST );
      return;
    }
    
    if ((gettype ( $Files )) != "array") {
      unset ( $this->FILELIST [$FileTag] );
      return;
    }
    else {
      while ( list ( $Tag, $Val ) = each ( $FileTag ) ) {
        unset ( $this->FILELIST [$Tag] );
      }
      return;
    }
  }
  
  // ************************************************************
  // Aliased function - used for compatibility with CGI::FastTemplate
  // function clear_parse ()
  // {
  // $this->clear_assign();
  // }
  
  // ************************************************************
  // Clears all variables set by assign()
  function clear_assign() {
    if (! (empty ( $this->PARSEVARS ))) {
      while ( list ( $Ref, $Val ) = each ( $this->PARSEVARS ) ) {
        unset ( $this->PARSEVARS ["$Ref"] );
      }
    }
  }
  
  // ************************************************************
  function clear_href($href) {
    if (! empty ( $href )) {
      if ((gettype ( $href )) != "array") {
        unset ( $this->PARSEVARS [$href] );
        return;
      }
      else {
        while ( list ( $Ref, $val ) = each ( $href ) ) {
          unset ( $this->PARSEVARS [$Ref] );
        }
        return;
      }
    }
    else {
      // Empty - clear them all
      
      $this->clear_assign ();
    }
    return;
  }
  
  // ************************************************************
  function assign($tpl_array, $trailer = "") {
    if (gettype ( $tpl_array ) == "array") {
      while ( list ( $key, $val ) = each ( $tpl_array ) ) {
        if (! (empty ( $key ))) {
          // Empty values are allowed
          // Empty Keys are NOT
          
          $this->PARSEVARS ["$key"] = $val;
        }
      }
    }
    else {
      // Empty values are allowed in non-array context now.
      if (! empty ( $tpl_array )) {
        $this->PARSEVARS ["$tpl_array"] = $trailer;
      }
    }
  }
  
  // ************************************************************
  // Return the value of an assigned variable.
  // Christian Brandel cbrandel@gmx.de
  function get_assigned($tpl_name = "") {
    if (empty ( $tpl_name )) {
      return false;
    }
    if (isset ( $this->PARSEVARS ["$tpl_name"] )) {
      return ($this->PARSEVARS ["$tpl_name"]);
    }
    else {
      return false;
    }
  }
  
  // ************************************************************
  function error($errorMsg, $die = 0) {
    $this->ERROR = $errorMsg;
    echo "ERROR: $this->ERROR <BR> \n";
    if ($die == 1) {
      exit ();
    }
    
    return;
  }
  // end error()
  
  // ************************************************************
  
  // ************************************************************
} // End class.FastTemplate.php3

?>