Source for file String.php

Documentation is available at String.php

  1. <?php
  2.  
  3. /**
  4.  * represents a Dwoo template contained in a string
  5.  *
  6.  * This software is provided 'as-is', without any express or implied warranty.
  7.  * In no event will the authors be held liable for any damages arising from the use of this software.
  8.  *
  9.  * This file is released under the LGPL
  10.  * "GNU Lesser General Public License"
  11.  * More information can be found here:
  12.  * {@link http://www.gnu.org/copyleft/lesser.html}
  13.  *
  14.  * @author     Jordi Boggiano <[email protected]>
  15.  * @copyright  Copyright (c) 2008, Jordi Boggiano
  16.  * @license    http://www.gnu.org/copyleft/lesser.html  GNU Lesser General Public License
  17.  * @link       http://dwoo.org/
  18.  * @version    0.9.1
  19.  * @date       2008-05-30
  20.  * @package    Dwoo
  21.  */
  22. class Dwoo_Template_String implements Dwoo_ITemplate
  23. {
  24.     /**
  25.      * template name
  26.      *
  27.      * @var string 
  28.      */
  29.     protected $name;
  30.  
  31.     /**
  32.      * template compilation id
  33.      *
  34.      * @var string 
  35.      */
  36.     protected $compileId;
  37.  
  38.     /**
  39.      * template cache id, if not provided in the constructor, it is set to
  40.      * the md4 hash of the request_uri. it is however highly recommended to
  41.      * provide one that will fit your needs.
  42.      *
  43.      * in all cases, the compilation id is prepended to the cache id to separate
  44.      * templates with similar cache ids from one another
  45.      *
  46.      * @var string 
  47.      */
  48.     protected $cacheId;
  49.  
  50.     /**
  51.      * validity duration of the generated cache file (in seconds)
  52.      *
  53.      * set to -1 for infinite cache, 0 to disable and null to inherit the Dwoo instance's cache time
  54.      *
  55.      * @var int 
  56.      */
  57.     protected $cacheTime;
  58.  
  59.     /**
  60.      * boolean flag that defines whether the compilation should be enforced (once) or
  61.      * not use this if you have issues with the compiled templates not being updated
  62.      * but if you do need this it's most likely that you should file a bug report
  63.      *
  64.      * @var bool 
  65.      */
  66.     protected $compilationEnforced;
  67.  
  68.     /**
  69.      * caches the results of the file checks to save some time when the same
  70.      * templates is rendered several times
  71.      *
  72.      * @var array 
  73.      */
  74.     protected static $cache array('cached'=>array()'compiled'=>array());
  75.  
  76.     /**
  77.      * holds the compiler that built this template
  78.      *
  79.      * @var Dwoo_ICompiler 
  80.      */
  81.     protected $compiler;
  82.  
  83.     /**
  84.      * creates a template from a string
  85.      *
  86.      * @param string $templateString the template to use
  87.      * @param int $cacheTime duration of the cache validity for this template,
  88.      *                           if null it defaults to the Dwoo instance that will
  89.      *                           render this template, set to -1 for infinite cache or 0 to disable
  90.      * @param string $cacheId the unique cache identifier of this page or anything else that
  91.      *                            makes this template's content unique, if null it defaults
  92.      *                            to the current url
  93.      * @param string $compileId the unique compiled identifier, which is used to distinguish this
  94.      *                              template from others, if null it defaults to the md4 hash of the template
  95.      */
  96.     public function __construct($templateString$cacheTime null$cacheId null$compileId null)
  97.     {
  98.         $this->template $templateString;
  99.         if (function_exists('hash')) {
  100.             $this->name = hash('md4'$templateString);
  101.         else {
  102.             $this->name = md5($templateString);
  103.         }
  104.         $this->cacheTime = $cacheTime;
  105.  
  106.         if ($compileId !== null{
  107.             $this->compileId = strtr($compileId'\\%?=!:;'.PATH_SEPARATOR'/-------');
  108.         }
  109.  
  110.         if ($cacheId !== null{
  111.             $this->cacheId = strtr($cacheId'\\%?=!:;'.PATH_SEPARATOR'/-------');
  112.         }
  113.     }
  114.  
  115.     /**
  116.      * returns the cache duration for this template
  117.      *
  118.      * defaults to null if it was not provided
  119.      *
  120.      * @return int|null
  121.      */
  122.     public function getCacheTime()
  123.     {
  124.         return $this->cacheTime;
  125.     }
  126.  
  127.     /**
  128.      * sets the cache duration for this template
  129.      *
  130.      * can be used to set it after the object is created if you did not provide
  131.      * it in the constructor
  132.      *
  133.      * @param int $seconds duration of the cache validity for this template, if
  134.      *  null it defaults to the Dwoo instance's cache time. 0 = disable and
  135.      *  -1 = infinite cache
  136.      */
  137.     public function setCacheTime($seconds null)
  138.     {
  139.         $this->cacheTime = $seconds;
  140.     }
  141.  
  142.     /**
  143.      * returns the template name
  144.      *
  145.      * @return string 
  146.      */
  147.     public function getName()
  148.     {
  149.         return $this->name;
  150.     }
  151.  
  152.     /**
  153.      * returns the resource name for this template class
  154.      *
  155.      * @return string 
  156.      */
  157.     public function getResourceName()
  158.     {
  159.         return 'string';
  160.     }
  161.  
  162.     /**
  163.      * returns the resource identifier for this template, false here as strings don't have identifiers
  164.      *
  165.      * @return false 
  166.      */
  167.     public function getResourceIdentifier()
  168.     {
  169.         return false;
  170.     }
  171.  
  172.     /**
  173.      * returns the template source of this template
  174.      *
  175.      * @return string 
  176.      */
  177.     public function getSource()
  178.     {
  179.         return $this->template;
  180.     }
  181.  
  182.     /**
  183.      * returns an unique value identifying the current version of this template,
  184.      * in this case it's the md4 hash of the content
  185.      *
  186.      * @return string 
  187.      */
  188.     public function getUid()
  189.     {
  190.         return $this->name;
  191.     }
  192.  
  193.     /**
  194.      * returns the compiler used by this template, if it was just compiled, or null
  195.      *
  196.      * @return Dwoo_ICompiler 
  197.      */
  198.     public function getCompiler()
  199.     {
  200.         return $this->compiler;
  201.     }
  202.  
  203.     /**
  204.      * marks this template as compile-forced, which means it will be recompiled even if it
  205.      * was already saved and wasn't modified since the last compilation. do not use this in production,
  206.      * it's only meant to be used in development (and the development of dwoo particularly)
  207.      */
  208.     public function forceCompilation()
  209.     {
  210.         $this->compilationEnforced = true;
  211.     }
  212.  
  213.     /**
  214.      * returns the cached template output file name, true if it's cache-able but not cached
  215.      * or false if it's not cached
  216.      *
  217.      * @param Dwoo $dwoo the dwoo instance that requests it
  218.      * @return string|bool
  219.      */
  220.     public function getCachedTemplate(Dwoo $dwoo)
  221.     {
  222.         if ($this->cacheTime !== null{
  223.             $cacheLength $this->cacheTime;
  224.         else {
  225.             $cacheLength $dwoo->getCacheTime();
  226.         }
  227.  
  228.         // file is not cacheable
  229.         if ($cacheLength === 0{
  230.             return false;
  231.         }
  232.  
  233.         $cachedFile $this->getCacheFilename($dwoo);
  234.  
  235.         if (isset(self::$cache['cached'][$this->cacheId]=== true && file_exists($cachedFile)) {
  236.             // already checked, return cache file
  237.             return $cachedFile;
  238.         elseif ($this->compilationEnforced !== true && file_exists($cachedFile&& ($cacheLength === -|| filemtime($cachedFile($_SERVER['REQUEST_TIME'$cacheLength))) {
  239.             // cache is still valid and can be loaded
  240.             self::$cache['cached'][$this->cacheIdtrue;
  241.             return $cachedFile;
  242.         else {
  243.             // file is cacheable
  244.             return true;
  245.         }
  246.     }
  247.  
  248.     /**
  249.      * caches the provided output into the cache file
  250.      *
  251.      * @param Dwoo $dwoo the dwoo instance that requests it
  252.      * @param string $output the template output
  253.      * @return mixed full path of the cached file or false upon failure
  254.      */
  255.     public function cache(Dwoo $dwoo$output)
  256.     {
  257.         $cacheDir $dwoo->getCacheDir();
  258.         $cachedFile $this->getCacheFilename($dwoo);
  259.  
  260.         // the code below is courtesy of Rasmus Schultz,
  261.         // thanks for his help on avoiding concurency issues
  262.         $temp tempnam($cacheDir'temp');
  263.         if (!($file @fopen($temp'wb'))) {
  264.             $temp $cacheDir DIRECTORY_SEPARATOR uniqid('temp');
  265.             if (!($file @fopen($temp'wb'))) {
  266.                 trigger_error('Error writing temporary file \''.$temp.'\''E_USER_WARNING);
  267.                 return false;
  268.             }
  269.         }
  270.  
  271.         fwrite($file$output);
  272.         fclose($file);
  273.  
  274.         $this->makeDirectory(dirname($cachedFile));
  275.         if (!@rename($temp$cachedFile)) {
  276.             @unlink($cachedFile);
  277.             @rename($temp$cachedFile);
  278.         }
  279.  
  280.         chmod($cachedFileDWOO_CHMOD);
  281.  
  282.         self::$cache['cached'][$this->cacheIdtrue;
  283.  
  284.         return $cachedFile;
  285.     }
  286.  
  287.     /**
  288.      * clears the cached template if it's older than the given time
  289.      *
  290.      * @param Dwoo $dwoo the dwoo instance that was used to cache that template
  291.      * @param int $olderThan minimum time (in seconds) required for the cache to be cleared
  292.      * @return bool true if the cache was not present or if it was deleted, false if it remains there
  293.      */
  294.     public function clearCache(Dwoo $dwoo$olderThan = -1)
  295.     {
  296.         $cachedFile $this->getCacheFilename($dwoo);
  297.  
  298.         return !file_exists($cachedFile|| (filectime($cachedFile(time($olderThan&& unlink($cachedFile));
  299.     }
  300.  
  301.     /**
  302.      * returns the compiled template file name
  303.      *
  304.      * @param Dwoo $dwoo the dwoo instance that requests it
  305.      * @param Dwoo_ICompiler $compiler the compiler that must be used
  306.      * @return string 
  307.      */
  308.     public function getCompiledTemplate(Dwoo $dwooDwoo_ICompiler $compiler null)
  309.     {
  310.         $compiledFile $this->getCompiledFilename($dwoo);
  311.  
  312.         if ($this->compilationEnforced !== true && isset(self::$cache['compiled'][$this->compileId]=== true{
  313.             // already checked, return compiled file
  314.         elseif ($this->compilationEnforced !== true && file_exists($compiledFile)===true{
  315.             // template is compiled
  316.             self::$cache['compiled'][$this->compileIdtrue;
  317.         else {
  318.             // compiles the template
  319.             $this->compilationEnforced = false;
  320.  
  321.             if ($compiler === null{
  322.                 $compiler $dwoo->getDefaultCompilerFactory('string');
  323.  
  324.                 if ($compiler === null || $compiler === array('Dwoo_Compiler''compilerFactory')) {
  325.                     if (class_exists('Dwoo_Compiler'false=== false{
  326.                         include 'Dwoo/Compiler.php';
  327.                     }
  328.                     $compiler Dwoo_Compiler::compilerFactory();
  329.                 else {
  330.                     $compiler call_user_func($compiler);
  331.                 }
  332.             }
  333.  
  334.             $this->compiler = $compiler;
  335.  
  336.             $compiler->setCustomPlugins($dwoo->getCustomPlugins());
  337.             $compiler->setSecurityPolicy($dwoo->getSecurityPolicy());
  338.             $this->makeDirectory(dirname($compiledFile));
  339.             file_put_contents($compiledFile$compiler->compile($dwoo$this));
  340.             chmod($compiledFileDWOO_CHMOD);
  341.  
  342.             self::$cache['compiled'][$this->compileIdtrue;
  343.         }
  344.  
  345.         return $compiledFile;
  346.     }
  347.  
  348.     /**
  349.      * returns false as this template type does not support inclusions
  350.      *
  351.      * @param mixed $resourceId the filename (relative to this template's dir) of the template to include
  352.      * @param int $cacheTime duration of the cache validity for this template,
  353.      *                           if null it defaults to the Dwoo instance that will
  354.      *                           render this template
  355.      * @param string $cacheId the unique cache identifier of this page or anything else that
  356.      *                            makes this template's content unique, if null it defaults
  357.      *                            to the current url
  358.      * @param string $compileId the unique compiled identifier, which is used to distinguish this
  359.      *                              template from others, if null it defaults to the filename+bits of the path
  360.      * @return false 
  361.      */
  362.     public static function templateFactory(Dwoo $dwoo$resourceId$cacheTime null$cacheId null$compileId null)
  363.     {
  364.         return false;
  365.     }
  366.  
  367.     /**
  368.      * returns the full compiled file name and assigns a default value to it if
  369.      * required
  370.      *
  371.      * @param Dwoo $dwoo the dwoo instance that requests the file name
  372.      * @return string the full path to the compiled file
  373.      */
  374.     protected function getCompiledFilename(Dwoo $dwoo)
  375.     {
  376.         // no compile id was provided, set default
  377.         if ($this->compileId===null{
  378.             $this->compileId = $this->name;
  379.         }
  380.         return $dwoo->getCompileDir($this->compileId.'.d'.Dwoo::RELEASE_TAG.'.php';
  381.     }
  382.  
  383.     /**
  384.      * returns the full cached file name and assigns a default value to it if
  385.      * required
  386.      *
  387.      * @param Dwoo $dwoo the dwoo instance that requests the file name
  388.      * @return string the full path to the cached file
  389.      */
  390.     protected function getCacheFilename(Dwoo $dwoo)
  391.     {
  392.         // no cache id provided, use request_uri as default
  393.         if ($this->cacheId === null{
  394.             if (isset($_SERVER['REQUEST_URI']=== true{
  395.                 $cacheId $_SERVER['REQUEST_URI'];
  396.             elseif (isset($_SERVER['SCRIPT_FILENAME']&& isset($_SERVER['argv'])) {
  397.                 $cacheId $_SERVER['SCRIPT_FILENAME'].'-'.implode('-'$_SERVER['argv']);
  398.             else {
  399.                 $cacheId '';
  400.             }
  401.             // force compiled id generation
  402.             $this->getCompiledFilename($dwoo);
  403.  
  404.             $this->cacheId = $this->compileId . strtr($cacheId'\\%?=!:;'.PATH_SEPARATOR'/-------');
  405.         }
  406.         return $dwoo->getCacheDir($this->cacheId.'.html';
  407.     }
  408.  
  409.     /**
  410.      * ensures the given path exists
  411.      *
  412.      * @param string $path any path
  413.      */
  414.     protected function makeDirectory($path)
  415.     {
  416.         if (is_dir($path=== true{
  417.             return;
  418.         }
  419.  
  420.         mkdir($pathDWOO_CHMODtrue);
  421.     }
  422. }

Documentation generated on Sun, 03 Aug 2008 15:12:45 +0200 by phpDocumentor 1.4.0