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 <j.boggiano@seld.be>
  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.      * chmod value for all files written (cached or compiled ones)
  85.      *
  86.      * set to null if you don't want any chmod operation to happen
  87.      *
  88.      * @var int 
  89.      */
  90.     protected $chmod = 0777;
  91.  
  92.     /**
  93.      * creates a template from a string
  94.      *
  95.      * @param string $templateString the template to use
  96.      * @param int $cacheTime duration of the cache validity for this template,
  97.      *                           if null it defaults to the Dwoo instance that will
  98.      *                           render this template, set to -1 for infinite cache or 0 to disable
  99.      * @param string $cacheId the unique cache identifier of this page or anything else that
  100.      *                            makes this template's content unique, if null it defaults
  101.      *                            to the current url
  102.      * @param string $compileId the unique compiled identifier, which is used to distinguish this
  103.      *                              template from others, if null it defaults to the md4 hash of the template
  104.      */
  105.     public function __construct($templateString$cacheTime null$cacheId null$compileId null)
  106.     {
  107.         $this->template $templateString;
  108.         if (function_exists('hash')) {
  109.             $this->name = hash('md4'$templateString);
  110.         else {
  111.             $this->name = md5($templateString);
  112.         }
  113.         $this->cacheTime = $cacheTime;
  114.  
  115.         if ($compileId !== null{
  116.             $this->compileId = str_replace('../''__'strtr($compileId'\\%?=!:;'.PATH_SEPARATOR'/-------'));
  117.         }
  118.  
  119.         if ($cacheId !== null{
  120.             $this->cacheId = str_replace('../''__'strtr($cacheId'\\%?=!:;'.PATH_SEPARATOR'/-------'));
  121.         }
  122.     }
  123.  
  124.     /**
  125.      * returns the cache duration for this template
  126.      *
  127.      * defaults to null if it was not provided
  128.      *
  129.      * @return int|null
  130.      */
  131.     public function getCacheTime()
  132.     {
  133.         return $this->cacheTime;
  134.     }
  135.  
  136.     /**
  137.      * sets the cache duration for this template
  138.      *
  139.      * can be used to set it after the object is created if you did not provide
  140.      * it in the constructor
  141.      *
  142.      * @param int $seconds duration of the cache validity for this template, if
  143.      *  null it defaults to the Dwoo instance's cache time. 0 = disable and
  144.      *  -1 = infinite cache
  145.      */
  146.     public function setCacheTime($seconds null)
  147.     {
  148.         $this->cacheTime = $seconds;
  149.     }
  150.  
  151.     /**
  152.      * returns the chmod value for all files written (cached or compiled ones)
  153.      *
  154.      * defaults to 0777
  155.      *
  156.      * @return int|null
  157.      */
  158.     public function getChmod()
  159.     {
  160.         return $this->chmod;
  161.     }
  162.  
  163.     /**
  164.      * set the chmod value for all files written (cached or compiled ones)
  165.      *
  166.      * set to null if you don't want to do any chmod() operation
  167.      *
  168.      * @param int $mask new bitmask to use for all files
  169.      */
  170.     public function setChmod($mask null)
  171.     {
  172.         $this->chmod = $mask;
  173.     }
  174.  
  175.     /**
  176.      * returns the template name
  177.      *
  178.      * @return string 
  179.      */
  180.     public function getName()
  181.     {
  182.         return $this->name;
  183.     }
  184.  
  185.     /**
  186.      * returns the resource name for this template class
  187.      *
  188.      * @return string 
  189.      */
  190.     public function getResourceName()
  191.     {
  192.         return 'string';
  193.     }
  194.  
  195.     /**
  196.      * returns the resource identifier for this template, false here as strings don't have identifiers
  197.      *
  198.      * @return false 
  199.      */
  200.     public function getResourceIdentifier()
  201.     {
  202.         return false;
  203.     }
  204.  
  205.     /**
  206.      * returns the template source of this template
  207.      *
  208.      * @return string 
  209.      */
  210.     public function getSource()
  211.     {
  212.         return $this->template;
  213.     }
  214.  
  215.     /**
  216.      * returns an unique value identifying the current version of this template,
  217.      * in this case it's the md4 hash of the content
  218.      *
  219.      * @return string 
  220.      */
  221.     public function getUid()
  222.     {
  223.         return $this->name;
  224.     }
  225.  
  226.     /**
  227.      * returns the compiler used by this template, if it was just compiled, or null
  228.      *
  229.      * @return Dwoo_ICompiler 
  230.      */
  231.     public function getCompiler()
  232.     {
  233.         return $this->compiler;
  234.     }
  235.  
  236.     /**
  237.      * marks this template as compile-forced, which means it will be recompiled even if it
  238.      * was already saved and wasn't modified since the last compilation. do not use this in production,
  239.      * it's only meant to be used in development (and the development of dwoo particularly)
  240.      */
  241.     public function forceCompilation()
  242.     {
  243.         $this->compilationEnforced = true;
  244.     }
  245.  
  246.     /**
  247.      * returns the cached template output file name, true if it's cache-able but not cached
  248.      * or false if it's not cached
  249.      *
  250.      * @param Dwoo $dwoo the dwoo instance that requests it
  251.      * @return string|bool
  252.      */
  253.     public function getCachedTemplate(Dwoo $dwoo)
  254.     {
  255.         if ($this->cacheTime !== null{
  256.             $cacheLength $this->cacheTime;
  257.         else {
  258.             $cacheLength $dwoo->getCacheTime();
  259.         }
  260.  
  261.         // file is not cacheable
  262.         if ($cacheLength === 0{
  263.             return false;
  264.         }
  265.  
  266.         $cachedFile $this->getCacheFilename($dwoo);
  267.  
  268.         if (isset(self::$cache['cached'][$this->cacheId]=== true && file_exists($cachedFile)) {
  269.             // already checked, return cache file
  270.             return $cachedFile;
  271.         elseif ($this->compilationEnforced !== true && file_exists($cachedFile&& ($cacheLength === -|| filemtime($cachedFile($_SERVER['REQUEST_TIME'$cacheLength))) {
  272.             // cache is still valid and can be loaded
  273.             self::$cache['cached'][$this->cacheIdtrue;
  274.             return $cachedFile;
  275.         else {
  276.             // file is cacheable
  277.             return true;
  278.         }
  279.     }
  280.  
  281.     /**
  282.      * caches the provided output into the cache file
  283.      *
  284.      * @param Dwoo $dwoo the dwoo instance that requests it
  285.      * @param string $output the template output
  286.      * @return mixed full path of the cached file or false upon failure
  287.      */
  288.     public function cache(Dwoo $dwoo$output)
  289.     {
  290.         $cacheDir $dwoo->getCacheDir();
  291.         $cachedFile $this->getCacheFilename($dwoo);
  292.  
  293.         // the code below is courtesy of Rasmus Schultz,
  294.         // thanks for his help on avoiding concurency issues
  295.         $temp tempnam($cacheDir'temp');
  296.         if (!($file @fopen($temp'wb'))) {
  297.             $temp $cacheDir DIRECTORY_SEPARATOR uniqid('temp');
  298.             if (!($file @fopen($temp'wb'))) {
  299.                 trigger_error('Error writing temporary file \''.$temp.'\''E_USER_WARNING);
  300.                 return false;
  301.             }
  302.         }
  303.  
  304.         fwrite($file$output);
  305.         fclose($file);
  306.  
  307.         $this->makeDirectory(dirname($cachedFile));
  308.         if (!@rename($temp$cachedFile)) {
  309.             @unlink($cachedFile);
  310.             @rename($temp$cachedFile);
  311.         }
  312.  
  313.         if ($this->chmod !== null{
  314.             chmod($cachedFile$this->chmod);
  315.         }
  316.  
  317.         self::$cache['cached'][$this->cacheIdtrue;
  318.  
  319.         return $cachedFile;
  320.     }
  321.  
  322.     /**
  323.      * clears the cached template if it's older than the given time
  324.      *
  325.      * @param Dwoo $dwoo the dwoo instance that was used to cache that template
  326.      * @param int $olderThan minimum time (in seconds) required for the cache to be cleared
  327.      * @return bool true if the cache was not present or if it was deleted, false if it remains there
  328.      */
  329.     public function clearCache(Dwoo $dwoo$olderThan = -1)
  330.     {
  331.         $cachedFile $this->getCacheFilename($dwoo);
  332.  
  333.         return !file_exists($cachedFile|| (filectime($cachedFile(time($olderThan&& unlink($cachedFile));
  334.     }
  335.  
  336.     /**
  337.      * returns the compiled template file name
  338.      *
  339.      * @param Dwoo $dwoo the dwoo instance that requests it
  340.      * @param Dwoo_ICompiler $compiler the compiler that must be used
  341.      * @return string 
  342.      */
  343.     public function getCompiledTemplate(Dwoo $dwooDwoo_ICompiler $compiler null)
  344.     {
  345.         $compiledFile $this->getCompiledFilename($dwoo);
  346.  
  347.         if ($this->compilationEnforced !== true && isset(self::$cache['compiled'][$this->compileId]=== true{
  348.             // already checked, return compiled file
  349.         elseif ($this->compilationEnforced !== true && file_exists($compiledFile)===true{
  350.             // template is compiled
  351.             self::$cache['compiled'][$this->compileIdtrue;
  352.         else {
  353.             // compiles the template
  354.             $this->compilationEnforced = false;
  355.  
  356.             if ($compiler === null{
  357.                 $compiler $dwoo->getDefaultCompilerFactory('string');
  358.  
  359.                 if ($compiler === null || $compiler === array('Dwoo_Compiler''compilerFactory')) {
  360.                     if (class_exists('Dwoo_Compiler'false=== false{
  361.                         include DWOO_DIRECTORY 'Dwoo/Compiler.php';
  362.                     }
  363.                     $compiler Dwoo_Compiler::compilerFactory();
  364.                 else {
  365.                     $compiler call_user_func($compiler);
  366.                 }
  367.             }
  368.  
  369.             $this->compiler = $compiler;
  370.  
  371.             $compiler->setCustomPlugins($dwoo->getCustomPlugins());
  372.             $compiler->setSecurityPolicy($dwoo->getSecurityPolicy());
  373.             $this->makeDirectory(dirname($compiledFile));
  374.             file_put_contents($compiledFile$compiler->compile($dwoo$this));
  375.             if ($this->chmod !== null{
  376.                 chmod($compiledFile$this->chmod);
  377.             }
  378.  
  379.             self::$cache['compiled'][$this->compileIdtrue;
  380.         }
  381.  
  382.         return $compiledFile;
  383.     }
  384.  
  385.     /**
  386.      * returns a new template string object with the resource id being the template source code
  387.      *
  388.      * @param Dwoo $dwoo the dwoo instance requiring it
  389.      * @param mixed $resourceId the filename (relative to this template's dir) of the template to include
  390.      * @param int $cacheTime duration of the cache validity for this template,
  391.      *                           if null it defaults to the Dwoo instance that will
  392.      *                           render this template
  393.      * @param string $cacheId the unique cache identifier of this page or anything else that
  394.      *                            makes this template's content unique, if null it defaults
  395.      *                            to the current url
  396.      * @param string $compileId the unique compiled identifier, which is used to distinguish this
  397.      *                              template from others, if null it defaults to the filename+bits of the path
  398.      * @param Dwoo_ITemplate $parentTemplate the template that is requesting a new template object (through
  399.      *                                              an include, extends or any other plugin)
  400.      * @return Dwoo_Template_String 
  401.      */
  402.     public static function templateFactory(Dwoo $dwoo$resourceId$cacheTime null$cacheId null$compileId nullDwoo_ITemplate $parentTemplate null)
  403.     {
  404.         return new self($resourceId$cacheTime$cacheId$compileId);
  405.     }
  406.  
  407.     /**
  408.      * returns the full compiled file name and assigns a default value to it if
  409.      * required
  410.      *
  411.      * @param Dwoo $dwoo the dwoo instance that requests the file name
  412.      * @return string the full path to the compiled file
  413.      */
  414.     protected function getCompiledFilename(Dwoo $dwoo)
  415.     {
  416.         // no compile id was provided, set default
  417.         if ($this->compileId===null{
  418.             $this->compileId = $this->name;
  419.         }
  420.         return $dwoo->getCompileDir($this->compileId.'.d'.Dwoo::RELEASE_TAG.'.php';
  421.     }
  422.  
  423.     /**
  424.      * returns the full cached file name and assigns a default value to it if
  425.      * required
  426.      *
  427.      * @param Dwoo $dwoo the dwoo instance that requests the file name
  428.      * @return string the full path to the cached file
  429.      */
  430.     protected function getCacheFilename(Dwoo $dwoo)
  431.     {
  432.         // no cache id provided, use request_uri as default
  433.         if ($this->cacheId === null{
  434.             if (isset($_SERVER['REQUEST_URI']=== true{
  435.                 $cacheId $_SERVER['REQUEST_URI'];
  436.             elseif (isset($_SERVER['SCRIPT_FILENAME']&& isset($_SERVER['argv'])) {
  437.                 $cacheId $_SERVER['SCRIPT_FILENAME'].'-'.implode('-'$_SERVER['argv']);
  438.             else {
  439.                 $cacheId '';
  440.             }
  441.             // force compiled id generation
  442.             $this->getCompiledFilename($dwoo);
  443.  
  444.             $this->cacheId = str_replace('../''__'$this->compileId . strtr($cacheId'\\%?=!:;'.PATH_SEPARATOR'/-------'));
  445.         }
  446.         return $dwoo->getCacheDir($this->cacheId.'.html';
  447.     }
  448.  
  449.     /**
  450.      * ensures the given path exists
  451.      *
  452.      * @param string $path any path
  453.      */
  454.     protected function makeDirectory($path)
  455.     {
  456.         if (is_dir($path=== true{
  457.             return;
  458.         }
  459.  
  460.         if ($this->chmod !== null{
  461.             mkdir($path$this->chmodtrue);
  462.         else {
  463.             mkdir($path0777true);
  464.         }
  465.     }
  466. }

Documentation generated on Sun, 07 Sep 2008 23:57:58 +0200 by phpDocumentor 1.4.0