Location: PHPKode > scripts > Haanga > lib/Haanga.php
<?php
/*
  +---------------------------------------------------------------------------------+
  | Copyright (c) 2010 Haanga                                                       |
  +---------------------------------------------------------------------------------+
  | Redistribution and use in source and binary forms, with or without              |
  | modification, are permitted provided that the following conditions are met:     |
  | 1. Redistributions of source code must retain the above copyright               |
  |    notice, this list of conditions and the following disclaimer.                |
  |                                                                                 |
  | 2. Redistributions in binary form must reproduce the above copyright            |
  |    notice, this list of conditions and the following disclaimer in the          |
  |    documentation and/or other materials provided with the distribution.         |
  |                                                                                 |
  | 3. All advertising materials mentioning features or use of this software        |
  |    must display the following acknowledgement:                                  |
  |    This product includes software developed by César D. Rodas.                  |
  |                                                                                 |
  | 4. Neither the name of the César D. Rodas nor the                               |
  |    names of its contributors may be used to endorse or promote products         |
  |    derived from this software without specific prior written permission.        |
  |                                                                                 |
  | THIS SOFTWARE IS PROVIDED BY CÉSAR D. RODAS ''AS IS'' AND ANY                   |
  | EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED       |
  | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE          |
  | DISCLAIMED. IN NO EVENT SHALL CÉSAR D. RODAS BE LIABLE FOR ANY                  |
  | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES      |
  | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;    |
  | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND     |
  | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT      |
  | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS   |
  | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE                     |
  +---------------------------------------------------------------------------------+
  | Authors: César Rodas <hide@address.com>                                           |
  +---------------------------------------------------------------------------------+
*/


/**
 *  Haanga Runtime class
 *
 *  Simple class to call templates efficiently. This class aims
 *  to reduce the compilation of a template as less a possible. Also
 *  it will not load in memory the compiler, except when there is not
 *  cache (compiled template) or it is out-dated.
 *
 */
class Haanga
{
    protected static $cache_dir;
    protected static $templates_dir='.';
    protected static $debug;
    public static $has_compiled;

    private function __construct()
    {
        /* The class can't be instanced */
    }

    final public static function RegisterAutoLoad()
    {
        set_include_path(get_include_path().PATH_SEPARATOR.dirname(__FILE__));
        spl_autoload_register(array(__CLASS__, 'AutoLoad'));
    }

    final public static function AutoLoad($class)
    {
        static $loaded = array();

        if (!isset($loaded[$class]) && substr($class, 0, 6) === 'Haanga' && !class_exists($class, false)) {
            $file = str_replace('_', '/', $class);
            @include $file.'.php';
            $loaded[$class] = TRUE;
        }
    }

    // setCacheDir(string $dir) {{{
    /**
     *  Set the directory where the compiled templates
     *  are stored.
     *
     *  @param string $dir 
     *
     *  @return void
     */
    public static function setCacheDir($dir)
    {
        if (!is_dir($dir)) {
            throw new Haanga_Exception("{$dir} is not a valid directory");
        }
        if (!is_writable($dir)) {
            throw new Haanga_Exception("{$dir} can't be written");
        }
        self::$cache_dir = $dir;
    }
    // }}}

    // setTemplateDir(string $dir) {{{
    /**
     *  Set the directory where the templates are located.
     *
     *  @param string $dir
     *
     *  @return void
     */
    public static function setTemplateDir($dir)
    {
        if (!is_dir($dir)) {
            throw new Haanga_Exception("{$dir} is not a valid directory");
        }
        self::$templates_dir = $dir;
    }
    // }}}

    // enableDebug($bool) {{{
    public static function enableDebug($bool)
    {
        self::$debug = $bool;
    }
    // }}}

    // load(string $file, array $vars, bool $return, array $blocks) {{{
    /**
     *  Load
     *
     *  Load template. If the template is already compiled, just the compiled
     *  PHP file will be included an used. If the template is new, or it 
     *  had changed, the Haanga compiler is loaded in memory, and the template
     *  is compiled.
     *
     *
     *  @param string $file
     *  @param array  $vars 
     *  @param bool   $return
     *  @param array  $blocks   
     *
     *  @return string|NULL
     */
    public static function Load($file, $vars = array(), $return=FALSE, $blocks=array())
    {
        static $compiler;
        if (empty(self::$cache_dir) || empty(self::$templates_dir)) {
            throw new Haanga_Exception("Cache dir or template dir is missing");
        }

        self::$has_compiled = FALSE;

        $tpl      = self::$templates_dir.'/'.$file;
        $fnc      =  sha1($tpl);
        $php      = self::$cache_dir.'/'.$fnc.'.php';
        $callback = "haanga_".$fnc;

        if (is_callable($callback)) {
            return $callback($vars, $return, $blocks);
        }

        if (!is_file($php) && !is_file($tpl)) {
            throw new Exception("View {$file} doesn't exists");
        }

        if (!is_file($php) || filemtime($tpl) > filemtime($php)) {
            if (!$compiler) {
                $compiler = new Haanga_Compiler_Runtime;
            }
            $compiler->reset();
            if (self::$debug) {
                $compiler->setDebug($php.".dump");
            }

            try {
                $code = $compiler->compile_file($tpl, FALSE);
            } catch (Exception $e) {
                throw new Haanga_Compiler_Exception($tpl.' :'.$e->getMessage().' on '.$e->getfile(). ':'.$e->Getline());
            }

            file_put_contents($php, "<?php".$code);
            self::$has_compiled = TRUE;
        }
        if (!is_callable($callback)) {
            require_once $php;
        }

        return $callback($vars, $return, $blocks);
    }
    // }}}

}

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * End:
 * vim600: sw=4 ts=4 fdm=marker
 * vim<600: sw=4 ts=4
 */
Return current item: Haanga