Fast Template CVS Revision 1.2.2

Publicado por Ragen Dazs 04/02/2004

[ Hits: 7.270 ]

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

Criando um menu de paginação de resultados com algumas funcionalidades

Função para remover acentuação de uma string

Criando um menu de paginação de resultados com algumas funcionalidades

Gráfico de Pizza em PHP

Contador


  

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