Fast Template CVS Revision 1.2.2

Publicado por Ragen Dazs 04/02/2004

[ Hits: 7.402 ]

Homepage: http://www.orkut.com

Download FastTemplate.class.php




A Fast Template é uma classe muito eficiente na utilização de modelos
para scripts PHP. Elas nos permite ganho de
tempo e facilita em muito a tarefa do web designer, que deixa
de ter acesso aos códigos PHP do site.

Fiz algumas implementações nessa classe e estou diponibilizando aqui:

- Sistema de cache
- Suporte a script tags '<? ?>' em blocos dinâmicos, gerando assim páginas cacheadas dinâmicas
- Pequenas correções de bugs

  



Esconder código-fonte

<?

/*
    CVS Revision. 1.1.0 - Default Fast Template

   
   CVS Revision [1.2] tree 
                  |
                  +-- 1.2.0 - Cache functions added
                |         - Extension php3 deprecated
                |
                  +-- 1.2.2 - Fixed clear_parse() in ambiguous mode

   CVS 1.2 tree author: Allyson Francisco de Paula Reis
                E-mail: ragen@oquerola.com
*/

class FastTemplate {

   var $FILELIST   =   array();   //   Holds the array of filehandles
                           //   FILELIST[HANDLE] == "fileName"

   var $DYNAMIC   =   array();   //   Holds the array of dynamic
                           //   blocks, and the fileHandles they
                           //   live in.

   var $PARSEVARS   =   array();   //   Holds the array of Variable
                           //   handles.
                           //   PARSEVARS[HANDLE] == "value"

   var   $LOADED      =   array();   //   We only want to load a template
                           //   once - when it's used.
                           //   LOADED[FILEHANDLE] == 1 if loaded
                           //   undefined if not loaded yet.

   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

   var $ERROR      =   "";         //   Holds the last error message

   var $LAST      =   "";         //   Holds the HANDLE to the last
                           //   template parsed by parse()

   var $STRICT      =   true;      //   Strict template checking.
                           //   Unresolved vars in templates will
                           //   generate a warning when found.

   var $USE_CACHE  =   false;      //  Enable caching mode. 
                                   //  Default: false

   var $UPDT_TIME  =   '60';       //  Time in seconds to expire cache 
                                   //  files
   
   var $CACHE_PATH =   './cache';  //  Dir for save cached files 


//   ************************************************************

   function FastTemplate ($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.

   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 getmicrotime(){ 
      list($usec, $sec) = explode(" ",microtime()); 
      return ((float)$usec + (float)$sec); 
    }

   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 (ereg("({[A-Z0-9_]+})",$Line,$unknown))
      {
         $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");
            }

            $template = ereg_replace("{$key}","$val","$template");
            //$template = str_replace("{$key}","$val","$template");
         }
      }

      if(!$this->STRICT)
      {
         // Silently remove anything not already found

         $template = ereg_replace("{([A-Z0-9_]+)}","",$template);
      }
      else
      {
         // Warn about unresolved template variables
         if (ereg("({[A-Z0-9_]+})",$template))
         {
            $unknown = 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()


//   ************************************************************
//  Cache in CVS revision 1.2.0 by ragen@oquerola.com

   function FastPrint ( $template = "", $return="" )
   {
      if(empty($template))
      {
         $template = $this->LAST;
      }

      if( (!(isset($this->$template))) || (empty($this->$template)) )
      {
         $this->error("Nothing parsed, nothing printed",0);
         return;
      }
      elseif ($this->USE_CACHE)
      {
         $this->cache_file($this->$template,$this->CACHING);         
      }
      else {
         if (!$return) {
            print $this->$template;
         }
         else {
            return $this->$template;
         }
      }
      return;
   }

//   ************************************************************
//  Try to use cached files. Duh! - ragen@oquerola.com

   function USE_CACHE ( $fname="" ) {

      $this->USE_CACHE = true;

      if ($fname) {

         $this->CACHING = $this->cache_path($fname);
      }

      $this->verify_cached_files($fname);
   }

//   ************************************************************
//  Verify if cache files are updated (in function of $UPDT_TIME)
//  then return cached page and exit - ragen@oquerola.com

   function verify_cached_files () {

      if (($this->USE_CACHE) && ($this->cache_file_is_updated())) 
      {

         // self_script() - return script as called Fast Template class

         if (!$this->CACHING) {
            include $this->self_script();
         }
         else {
            include $this->CACHING;
         }
         //echo "<script>alert('Usando cache')</script>";
         exit(1);
      }

   }

//   ************************************************************
//   Return script as called Fast Template class 
//  by ragen@oquerola.com

   function self_script () {

      $fname = getenv('SCRIPT_NAME');
      $fname = $this->cache_path($fname);

      return $fname;
   }

//   ************************************************************
//   Return the real path for write cache files 
//  by ragen@oquerola.com

   function cache_path ( $fname )
   {
      $fname = explode("/",$fname);
      $fname = $fname[count($fname) - 1];
      return $this->CACHE_PATH."/".$fname;
   }

// *************************************************************
// Return the script as called Fast Template in cache dir
// by ragen@oquerola.com

   function self_script_in_cache_path ()
   {
      $fname = explode("/",$this->self_script());
      $fname = $fname[count($fname) - 1];
      return $this->CACHE_PATH."/".$fname;
   }


//   ************************************************************
//   Verify if cache file is updated or expired 
//  by ragen@oquerola.com

   function cache_file_is_updated() {

      // Verification of cache expiration
      // filemtime() -> return unix time of last modification in file
      // time() -> return unix time

      if (!$this->CACHING) {
         
         $fname = $this->self_script_in_cache_path();
      } else {

         $fname = $this->CACHING;
      }

      if (!file_exists($fname)) {
         return false;         
      }
      
      $expire_time = time() - filemtime($fname);
      
      if ($expire_time >= $this->UPDT_TIME) 
      {
         return false;         
      } 
      else 
      { 
         return true;
      }

   }

//   ************************************************************
//   The meat of the whole class. The magic happens here.
//  by ragen@oquerola.com

   function cache_file ( $content = "" )
   {

      if (($this->USE_CACHE) && (!$this->cache_file_is_updated())) {

         if (!$this->CACHING) {

            $fname = $this->self_script_in_cache_path();
         } else {

            $fname = $this->CACHING;
         }

         // Tendo certeza que o arquivo existe e que há permissão de escrita primeiro.
         //if (is_writable($fname)) {
            
            // Opening $fname in writing only mode
            
            if (!$fp = fopen($fname, 'w')) {
               $this->error("Error while opening cache file ($fname)",0);
               return;
            }

            // Writing $content to open file.
            
            if (!fwrite($fp, $content)) {
               $this->error("Error while writing cache file ($fname)",0);
               return;
            }
            else {
               fclose($fp);
               include $fname;
               return;
            }

            fclose($fp);

         //} else {
         //   $this->error("The cache file $fname is not writable",0);
         //   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 ( $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 - by ragen@oquerola.com

   function clear_parse ( $ReturnVar = "" )
   {
      if ($ReturnVar) {
         $this->clear($ReturnVar);   
      }
      else {
         $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;
         }
      }
   }

//   ************************************************************

   function ext_assign ($tpl_array, $trailer="", &$instancia)
   {
      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 "ERRO: $this->ERROR <BR> \n";
      if ($die == 1)
      {
         exit;
      }

      return;

   } // end error()


//   ************************************************************


//   ************************************************************

} // End FastTemplate.class.php

?>

Scripts recomendados

Contador

Exemplo de recursividade: gerador de sequências de tamanho e soma dos elementos fixos

Crivo de Eratóstenes Simples em PHP

catdoc

Saber se acesso a aplicação web é feito pela rede interna ou externa


  

Comentários
[1] Comentário enviado por removido em 13/03/2006 - 15:29h

Excelente script funciona de verdade

[2] Comentário enviado por Ragen em 13/03/2006 - 15:32h

Olá,

Essa versão já encontra-se bastante desatualizada. Procure pelas novas no repositório oficial.

Valeu =]


Contribuir com comentário




Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts