home *** CD-ROM | disk | FTP | other *** search
/ Cricao de Sites - 650 Layouts Prontos / WebMasters.iso / Servidores / xampp-win32-1.6.7-installer.exe / php / PEAR / phing / lib / Capsule.php next >
Encoding:
PHP Script  |  2006-09-14  |  7.9 KB  |  266 lines

  1. <?php
  2.  
  3. /**
  4.  * Capsule is a simple "template" engine that essentially provides an isolated context
  5.  * for PHP scripts.
  6.  * 
  7.  * There is no special templating language, and therefore no limitations to what
  8.  * can be accomplished within templates. The main purpose of Capsule is to separate 
  9.  * the business logic from display / output logic.
  10.  * 
  11.  * @author Hans Lellelid <hans@xmpl.org>
  12.  * @version $Revision: 1.9 $ $Date: 2006-09-14 22:19:08 +0200 (Thu, 14 Sep 2006) $
  13.  */
  14. class Capsule {
  15.     
  16.     /**
  17.      * Look for templates here (if relative path provided).
  18.      * @var string
  19.      */
  20.     protected $templatePath;
  21.     
  22.     /**
  23.      * Where should output files be written?
  24.      * (This is named inconsistently to be compatible w/ Texen.)
  25.      * @var string
  26.      */
  27.     protected $outputDirectory;
  28.     
  29.     /**
  30.      * The variables that can be used by the templates.
  31.      * @var array Hash of variables.
  32.      */
  33.     public $vars = array();
  34.     
  35.     /**
  36.      * Has template been initialized.
  37.      */    
  38.     protected $initialized = false;
  39.     
  40.     /**
  41.      * Stores the pre-parse() include_path.
  42.      * @var string
  43.      */
  44.     private $old_include_path;
  45.     
  46.     function __construct() {
  47.     }
  48.     
  49.     /**
  50.      * Clears one or several or all variables.
  51.      * @param mixed $which String name of var, or array of names.
  52.      * @return void
  53.      */
  54.     function clear($which = null) {
  55.         if ($which === null) {
  56.             $this->vars = array();
  57.         } elseif (is_array($which)) {
  58.             foreach($which as $var) {
  59.                 unset($this->vars[$var]);
  60.             }
  61.         } else {
  62.             unset($this->vars[$which]);
  63.         }
  64.     }
  65.     
  66.     /**
  67.      * Set the basepath to use for template lookups.
  68.      * @param string $v
  69.      */
  70.     function setTemplatePath($v) {
  71.         $this->templatePath = rtrim($v, DIRECTORY_SEPARATOR.'/');
  72.     }
  73.  
  74.     /**
  75.      * Get the basepath to use for template lookups.
  76.      * @return string
  77.      */
  78.     function getTemplatePath() {
  79.         return $this->templatePath;
  80.     }
  81.     
  82.     /**
  83.      * Set a basepath to use for output file creation.
  84.      * @param string $v
  85.      */
  86.     function setOutputDirectory($v) {
  87.         $this->outputDirectory = rtrim($v, DIRECTORY_SEPARATOR.'/');
  88.     }
  89.  
  90.     /**
  91.      * Get basepath to use for output file creation.
  92.      * @return string
  93.      */
  94.     function getOutputDirectory() {
  95.         return $this->outputDirectory;
  96.     }
  97.     
  98.     /**
  99.      * Low overhead (no output buffering) method to simply dump template
  100.      * to buffer.
  101.      * 
  102.      * @param string $__template
  103.      * @return void
  104.      * @throws Exception - if template cannot be found
  105.      */ 
  106.     function display($__template) {
  107.         
  108.         // Prepend "private" variable names with $__ in this function
  109.         // to keep namespace conflict potential to a minimum.
  110.             
  111.         // Alias this class to $generator.
  112.         $generator = $this;
  113.                         
  114.         if (isset($this->vars['this'])) {
  115.             throw new Exception("Assigning a variable named \$this to a context conflicts with class namespace.");
  116.         }
  117.         
  118.         // extract variables into local namespace
  119.         extract($this->vars);
  120.         
  121.         // prepend template path to include path, 
  122.         // so that include "path/relative/to/templates"; can be used within templates
  123.         $__old_inc_path = ini_get('include_path');
  124.         ini_set('include_path', $this->templatePath . PATH_SEPARATOR . $__old_inc_path);
  125.                 
  126.         @ini_set('track_errors', true);
  127.         include $__template;
  128.         @ini_restore('track_errors');
  129.         
  130.         // restore the include path
  131.         ini_set('include_path', $__old_inc_path);
  132.         
  133.         if (!empty($php_errormsg)) {
  134.             throw new Exception("Unable to parse template " . $__template . ": " . $php_errormsg);
  135.         }
  136.     }
  137.     
  138.     /**
  139.      * Fetches the results of a tempalte parse and either returns
  140.      * the string or writes results to a specified output file.
  141.      *
  142.      * @param string $template The template filename (relative to templatePath or absolute).
  143.      * @param string $outputFile If specified, contents of template will also be written to this file.
  144.      * @param boolean $append Should output be appended to source file?
  145.      * @return string The "parsed" template output.
  146.      * @throws Exception - if template not found.
  147.      */
  148.     function parse($template, $outputFile = null, $append = false) {
  149.                 
  150.         // main work done right here:
  151.         // hopefully this works recursively ... fingers crossed.    
  152.         ob_start();
  153.         
  154.         try {
  155.             $this->display($template);
  156.         } catch (Exception $e) {
  157.             ob_end_flush(); // flush the output on error (so we can see up to what point it parsed everything)
  158.             throw $e;
  159.         }
  160.                 
  161.         $output = ob_get_contents();
  162.         ob_end_clean();
  163.         
  164.         if ($outputFile !== null) {
  165.             $outputFile = $this->resolvePath($outputFile, $this->outputDirectory);
  166.             
  167.             $flags = null;
  168.             if ($append) $flags = FILE_APPEND;
  169.             
  170.             if (!file_put_contents($outputFile, $output, $flags) && $output != "") {
  171.                 throw new Exception("Unable to write output to " . $outputFile);
  172.             }
  173.         }
  174.  
  175.         return $output;
  176.     }
  177.     
  178.     /**
  179.      * This returns a "best guess" path for the given file.
  180.      *
  181.      * @param string $file File name or possibly absolute path.
  182.      * @param string $basepath The basepath that should be prepended if $file is not absolute.
  183.      * @return string "Best guess" path for this file.
  184.      */
  185.     protected function resolvePath($file, $basepath) {
  186.         if ( !($file{0} == DIRECTORY_SEPARATOR || $file{0} == '/') 
  187.             // also account for C:\ style path
  188.                 && !($file{1} == ':' && ($file{2} ==  DIRECTORY_SEPARATOR || $file{2} == '/'))) { 
  189.             if ($basepath != null) {
  190.                 $file = $basepath . DIRECTORY_SEPARATOR . $file;
  191.             }
  192.         }
  193.         return $file;
  194.     }
  195.  
  196.     /**
  197.      * Gets value of specified var or NULL if var has not been put().
  198.      * @param string $name Variable name to retrieve.
  199.      * @return mixed
  200.      */
  201.     function get($name) {
  202.         if (!isset($this->vars[$name])) return null;
  203.         return $this->vars[$name];
  204.     }
  205.     
  206.     /**
  207.      * Merges in passed hash to vars array.
  208.      *
  209.      * Given an array like:
  210.      *
  211.      *            array(     'myvar' => 'Hello',
  212.      *                    'myvar2' => 'Hello')
  213.      *
  214.      * Resulting template will have access to $myvar and $myvar2.
  215.      *
  216.      * @param array $vars
  217.      * @param boolean $recursiveMerge Should matching keys be recursively merged?
  218.      * @return void
  219.      */
  220.     function putAll($vars, $recursiveMerge = false) {
  221.         if ($recursiveMerge) {
  222.             $this->vars = array_merge_recursive($this->vars, $vars);
  223.         } else {
  224.             $this->vars = array_merge($this->vars, $vars);
  225.         }
  226.     }
  227.     
  228.     /**
  229.      * Adds a variable to the context.
  230.      * 
  231.      * Resulting template will have access to ${$name$} variable.
  232.      * 
  233.      * @param string $name
  234.      * @param mixed $value
  235.      */
  236.     function put($name, $value) {
  237.         $this->vars[$name] = $value;
  238.     }
  239.         
  240.     /**
  241.      * Put a variable into the context, assigning it by reference.
  242.      * This means that if the template modifies the variable, then it
  243.      * will also be modified in the context.
  244.      *
  245.      * @param $name
  246.      * @param &$value
  247.      */
  248.     function putRef($name, &$value) {
  249.         $this->vars[$name] = &$value;
  250.     }
  251.     
  252.     /**
  253.      * Makes a copy of the value and puts it into the context.
  254.      * This is primarily to force copying (cloning) of objects, rather
  255.      * than the default behavior which is to assign them by reference.
  256.      * @param string $name
  257.      * @param mixed $value
  258.      */
  259.     function putCopy($name, $value) {
  260.         if (is_object($value)) {
  261.             $value = clone $value;
  262.         }
  263.         $this->vars[$name] = $value;
  264.     }
  265.  
  266. }