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

Documentation generated on Sat, 18 Jul 2009 21:05:21 +0200 by phpDocumentor 1.4.0