Adding template engine
Adding error handling Adding basic SMTP class core routing is working
This commit is contained in:
		
							
								
								
									
										1
									
								
								system/.htaccess
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								system/.htaccess
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
Deny from all
 | 
			
		||||
							
								
								
									
										1
									
								
								system/engine/.htaccess
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								system/engine/.htaccess
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
Deny from all
 | 
			
		||||
							
								
								
									
										80
									
								
								system/engine/SMTP.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										80
									
								
								system/engine/SMTP.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,80 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
// Based on tutorial from here: https://portal.cyberhostpro.com/knowledgebase/170/PHP-Mail-Script-with-SMTP-Authentication.html
 | 
			
		||||
class HF_SMTP
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
    private $from = "";
 | 
			
		||||
    private $to = "";
 | 
			
		||||
    private $subject = "";
 | 
			
		||||
    private $msg = "";
 | 
			
		||||
    private $user = null;
 | 
			
		||||
    private $password = null;
 | 
			
		||||
    private $port = 25;
 | 
			
		||||
    private $server = "localhost";
 | 
			
		||||
 | 
			
		||||
    private $smtpserverconn = null;
 | 
			
		||||
 | 
			
		||||
    public function __construct($from, $to, $subject, $msg, $server = "localhost", $user = null, $password = null, $port = 25)
 | 
			
		||||
    {
 | 
			
		||||
        $this->from = $from;
 | 
			
		||||
        $this->to = $to;
 | 
			
		||||
        $this->subject = $subject;
 | 
			
		||||
        $this->msg = $msg;
 | 
			
		||||
        $this->user = $user;
 | 
			
		||||
        $this->password = $password;
 | 
			
		||||
        $this->port = $port;
 | 
			
		||||
        $this->server = $server;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function send($html=false)
 | 
			
		||||
    {
 | 
			
		||||
        $err = null;
 | 
			
		||||
        $errstr = "";
 | 
			
		||||
        $this->smtpserverconn = fsockopen($this->server, $this->port, $err, $errstr, 100);
 | 
			
		||||
        $response = fgets($this->smtpserverconn, 515);
 | 
			
		||||
        if ($response === false)
 | 
			
		||||
        {
 | 
			
		||||
            throw new Exception("Could not connect to SMTP server!");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if ($this->user != null && $this->password != null)
 | 
			
		||||
        {
 | 
			
		||||
            $this->sendCommand("AUTH LOGIN");
 | 
			
		||||
            $this->sendCommand(base64_encode($this->user));
 | 
			
		||||
            $this->sendCommand(base64_encode($this->password));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $this->sendCommand("HELO " . $_SERVER["SERVER_NAME"]);
 | 
			
		||||
        $this->sendCommand("MAIL FROM: " . $this->from);
 | 
			
		||||
        $this->sendCommand("RCPT TO: " . $this->to);
 | 
			
		||||
        $this->sendCommand("DATA");
 | 
			
		||||
 | 
			
		||||
        if ($html)
 | 
			
		||||
        {
 | 
			
		||||
            $this->sendCommand("MIME-Version: 1.0", false);
 | 
			
		||||
            $this->sendCommand("Content-type: text/html; charset=iso-8859-1", false);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $this->sendCommand("From: " . $this->from, false);
 | 
			
		||||
        $this->sendCommand("To: " . $this->to, false);
 | 
			
		||||
        $this->sendCommand("Subject: " . $this->subject, false);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        $this->sendCommand($this->msg, false);
 | 
			
		||||
 | 
			
		||||
        $this->sendCommand("", false);
 | 
			
		||||
        $this->sendCommand(".", false);
 | 
			
		||||
        $this->sendCommand("QUIT");
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private function sendCommand($command, $return = true)
 | 
			
		||||
    {
 | 
			
		||||
        fputs($this->smtpserverconn, $command . "\r\n");
 | 
			
		||||
        if ($return)
 | 
			
		||||
            return fgets($this->smtpserverconn, 515);
 | 
			
		||||
        else
 | 
			
		||||
            return null;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										14
									
								
								system/engine/config-default.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								system/engine/config-default.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,14 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
$config["DEFAULT_ROUTE"] = "main";
 | 
			
		||||
$config["USE_H20_TPL"] = true;
 | 
			
		||||
$config["SMTP_SERVER"] = "localhost";
 | 
			
		||||
$config["SMTP_USER"] = "";
 | 
			
		||||
$config["SMTP_PASS"] = "";
 | 
			
		||||
$config["SMTP_PORT"] = 25;
 | 
			
		||||
$config["SMTP_FROM"] = "HF-noreply@yoursite.com";
 | 
			
		||||
$config["DEBUG"] = true;
 | 
			
		||||
$config["USE_HF_SMTP"] = true;
 | 
			
		||||
$config["SITE_NAME"] = "default";
 | 
			
		||||
 | 
			
		||||
return $config;
 | 
			
		||||
							
								
								
									
										15
									
								
								system/engine/controller.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								system/engine/controller.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,15 @@
 | 
			
		||||
<?php
 | 
			
		||||
class HF_Controller
 | 
			
		||||
{
 | 
			
		||||
    protected $config;
 | 
			
		||||
    protected $tpl;
 | 
			
		||||
    protected $core;
 | 
			
		||||
 | 
			
		||||
    public function __construct($config, $core, $tpl = null)
 | 
			
		||||
    {
 | 
			
		||||
        $this->config = $config;
 | 
			
		||||
        $this->tpl = $tpl;
 | 
			
		||||
        $this->core = $core;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,63 +1,235 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
include "system/engine/controller.php";
 | 
			
		||||
include "system/engine/SMTP.php";
 | 
			
		||||
include "system/engine/exceptions.php";
 | 
			
		||||
 | 
			
		||||
class HF_Core
 | 
			
		||||
{
 | 
			
		||||
	private $class;
 | 
			
		||||
	private $method;
 | 
			
		||||
	private $classname;
 | 
			
		||||
	private $args = array();
 | 
			
		||||
    private $config = array();
 | 
			
		||||
    private $tpl;
 | 
			
		||||
	
 | 
			
		||||
	public function __construct()
 | 
			
		||||
	{
 | 
			
		||||
		$this->findController();
 | 
			
		||||
        $config = include("system/engine/config-default.php");
 | 
			
		||||
        if (is_file("application/config.php"))
 | 
			
		||||
        {
 | 
			
		||||
            $newconfig = include("application/config.php");
 | 
			
		||||
        }
 | 
			
		||||
        $this->config = array_merge($config, $newconfig);
 | 
			
		||||
        if ($this->config["USE_H20_TPL"])
 | 
			
		||||
            $this->tpl = new H2o(null, array(
 | 
			
		||||
                "searchpath" => getcwd() . "/application/views/", "cache_dir" => "application/tmp/",
 | 
			
		||||
            ));
 | 
			
		||||
        set_error_handler("HF_Core::error_handler");
 | 
			
		||||
        $this->findController();
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	private function findController()
 | 
			
		||||
	{
 | 
			
		||||
		$request = $_SERVER["REQUEST_URI"];
 | 
			
		||||
		if ($request == "" || $request == "/")
 | 
			
		||||
		{
 | 
			
		||||
			require("../../application/controllers/main.php");
 | 
			
		||||
			$this->$class = new main();
 | 
			
		||||
			$this->$method = "index";
 | 
			
		||||
			$this->$classname = "main";
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
		$arr = explode("/", $request);
 | 
			
		||||
		$path = "../../application/controllers/";
 | 
			
		||||
		for($i = 0; $i < count($arr); $i++)
 | 
			
		||||
		{
 | 
			
		||||
			if ($is_file($path . $arr[$i] . ".php")) // found the controller
 | 
			
		||||
			{
 | 
			
		||||
				include($path . $arr[$i] . ".php");
 | 
			
		||||
				$this->$class = new $arr[$i];
 | 
			
		||||
				
 | 
			
		||||
				if ($i + 1 != count($arr)) // if there is a define after the controller name - this would be the method name
 | 
			
		||||
				{
 | 
			
		||||
					$this->$method = $arr[$i+1];
 | 
			
		||||
					$this->$args = array_slice ($arr, 2);
 | 
			
		||||
					$this->$classname = $arr[$i];
 | 
			
		||||
				} else { // call index
 | 
			
		||||
					$this->$method = "index";
 | 
			
		||||
					$this->$classname = $arr[$i];
 | 
			
		||||
				}
 | 
			
		||||
				return;
 | 
			
		||||
			}
 | 
			
		||||
			
 | 
			
		||||
			if (is_dir($path . $arr[$i])) // controller is hidden deeper
 | 
			
		||||
			{
 | 
			
		||||
				$path = $path . $arr[$i] . "/";
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
			
 | 
			
		||||
			// throw exception controller not found
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
        try
 | 
			
		||||
        {
 | 
			
		||||
            $request = $_SERVER["PHP_SELF"];
 | 
			
		||||
            $splitreq = explode("/", $request);
 | 
			
		||||
            $request = "";
 | 
			
		||||
            for($i = 0; $i < count($splitreq); $i++)
 | 
			
		||||
            {
 | 
			
		||||
                if ($splitreq[$i] == "index.php")
 | 
			
		||||
                {
 | 
			
		||||
                    $request = implode("/", array_splice($splitreq, $i+1));
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if ($request == "" || $request == "/")
 | 
			
		||||
            {
 | 
			
		||||
                require("application/controllers/" . $this->config["DEFAULT_ROUTE"] . ".php");
 | 
			
		||||
                $this->loadController(new $this->config["DEFAULT_ROUTE"]($this->config, $this, $this->tpl), $this->config["DEFAULT_ROUTE"], "index");
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            if ($request[strlen($request)-1] == "/")
 | 
			
		||||
                $request = substr($request, 0, -1);
 | 
			
		||||
            $arr = explode("/", $request);
 | 
			
		||||
            $path = "application/controllers/";
 | 
			
		||||
            for($i = 0; $i < count($arr); $i++)
 | 
			
		||||
            {
 | 
			
		||||
                if (is_file($path . $arr[$i] . ".php")) // found the controller
 | 
			
		||||
                {
 | 
			
		||||
                    include($path . $arr[$i] . ".php");
 | 
			
		||||
                    if ($i + 1 < count($arr)) // if there is a define after the controller name - this would be the method name
 | 
			
		||||
                    {
 | 
			
		||||
                        $this->loadController(new $arr[$i]($this->config, $this, $this->tpl), $arr[$i], $arr[$i+1], array_slice ($arr, 2));
 | 
			
		||||
                    } else { // call index
 | 
			
		||||
                        $this->loadController(new $arr[$i]($this->config, $this, $this->tpl), $arr[$i], "index");
 | 
			
		||||
                    }
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (is_dir($path . $arr[$i])) // controller is hidden deeper
 | 
			
		||||
                {
 | 
			
		||||
                    $path = $path . $arr[$i] . "/";
 | 
			
		||||
                    continue;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                $this->load404Controller();
 | 
			
		||||
                break;
 | 
			
		||||
                // throw exception controller not found
 | 
			
		||||
            }
 | 
			
		||||
        } catch (Exception $e) {
 | 
			
		||||
            if ($this->config["DEBUG"])
 | 
			
		||||
                echo vdump($e, $this);
 | 
			
		||||
            else
 | 
			
		||||
                $this->mail_admins("[Exception - " . $this->config["SITE_NAME"] . "]", vdump($e, $this), true);
 | 
			
		||||
        }
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
    private function load404Controller()
 | 
			
		||||
    {
 | 
			
		||||
        if (is_file(getcwd() . "/application/status.php"))
 | 
			
		||||
        {
 | 
			
		||||
            include_once (getcwd() . "/application/status.php");
 | 
			
		||||
            $this->loadController(new status($this->config, $this, $this->tpl), "status", "Status404");
 | 
			
		||||
        } else {
 | 
			
		||||
            include_once(getcwd() . "/system/engine/status.php");
 | 
			
		||||
            $this->loadController(new HF_Status($this->config, $this, $this->tpl), "HF_Status", "Status404");
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private function load500Controller()
 | 
			
		||||
    {
 | 
			
		||||
        if (is_file(getcwd() . "/application/status.php"))
 | 
			
		||||
        {
 | 
			
		||||
            include_once (getcwd() . "/application/status.php");
 | 
			
		||||
            $this->loadController(new status($this->config, $this, $this->tpl), "status", "Status500");
 | 
			
		||||
        } else {
 | 
			
		||||
            include_once (getcwd() . "/system/engine/status.php");
 | 
			
		||||
            $this->loadController(new HF_Status($this->config, $this, $this->tpl), "HF_Status", "Status500");
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private function loadController($class, $classname, $method, $args = array())
 | 
			
		||||
    {
 | 
			
		||||
        $this->class = $class;
 | 
			
		||||
        $this->classname = $classname;
 | 
			
		||||
        $this->method = $method;
 | 
			
		||||
        $this->args = $args;
 | 
			
		||||
    }
 | 
			
		||||
	
 | 
			
		||||
	public function run()
 | 
			
		||||
	public function run($err=false)
 | 
			
		||||
	{
 | 
			
		||||
		$call = new ReflectionFunction($this->$classname, $this->$method);
 | 
			
		||||
		$call->invokeArgs($this->$class, $this->$args);
 | 
			
		||||
        try
 | 
			
		||||
        {
 | 
			
		||||
            $call = new ReflectionMethod($this->classname, $this->method);
 | 
			
		||||
            if ($err)
 | 
			
		||||
            {
 | 
			
		||||
                $call->invokeArgs($this->class, $this->args);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            $numOfReqPara = $call->getNumberOfRequiredParameters();
 | 
			
		||||
            $numOfOptPara = $call->getNumberOfParameters() - $numOfReqPara;
 | 
			
		||||
            $remainparas = count($this->args) - $numOfReqPara;
 | 
			
		||||
            if ($remainparas >= 0 && $remainparas <= $numOfOptPara)
 | 
			
		||||
            {
 | 
			
		||||
                $call->invokeArgs($this->class, $this->args);
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                $this->load404Controller();
 | 
			
		||||
                $this->run(true);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        } catch (ReflectionException $e)
 | 
			
		||||
        {
 | 
			
		||||
            if (strstr($e->getMessage(), "does not exist") !== false)
 | 
			
		||||
            {
 | 
			
		||||
                $this->load404Controller();
 | 
			
		||||
            } else {
 | 
			
		||||
                $this->load500Controller();
 | 
			
		||||
            }
 | 
			
		||||
            $this->run(true);
 | 
			
		||||
            if ($this->config["DEBUG"])
 | 
			
		||||
                echo vdump($e, $this);
 | 
			
		||||
            else
 | 
			
		||||
                $this->mail_admins("[Exception - " . $this->config["SITE_NAME"] . "]", vdump($e, $this), true);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        } catch (Exception $e) {
 | 
			
		||||
            $this->load500Controller();
 | 
			
		||||
            $this->run(true);
 | 
			
		||||
            if ($this->config["DEBUG"])
 | 
			
		||||
                echo vdump($e, $this);
 | 
			
		||||
            else
 | 
			
		||||
                $this->mail_admins("[Exception - " . $this->config["SITE_NAME"] . "]", vdump($e, $this), true);
 | 
			
		||||
        }
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
    public function mail_admins($subject, $msg, $html = false)
 | 
			
		||||
    {
 | 
			
		||||
        if (array_key_exists("ADMINS", $this->config))
 | 
			
		||||
        {
 | 
			
		||||
            foreach($this->config["ADMINS"] as $email)
 | 
			
		||||
            {
 | 
			
		||||
                $this->mail_user($email, $subject, $msg, $html);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function mail_user($to, $subject, $msg, $html = false)
 | 
			
		||||
    {
 | 
			
		||||
        if ($this->config["USE_HF_SMTP"])
 | 
			
		||||
        {
 | 
			
		||||
            $smtp = new HF_SMTP($this->config["SMTP_FROM"], $to, $subject, $msg, $this->config["SMTP_SERVER"], $this->config["SMTP_USER"], $this->config["SMTP_PASS"], $this->config["SMTP_PORT"]);
 | 
			
		||||
            $smtp->send($html);
 | 
			
		||||
        } else {
 | 
			
		||||
            require_once "Mail.php";
 | 
			
		||||
            $smtp = null;
 | 
			
		||||
            if ($this->$this->config["SMTP_USER"] && $this->config["SMTP_PASS"])
 | 
			
		||||
                $smtp = Mail::factory('smtp', array(
 | 
			
		||||
                    "host" => $this->config["SMTP_SERVER"],
 | 
			
		||||
                    "port" => $this->config["SMTP_PORT"],
 | 
			
		||||
                    "auth" => true,
 | 
			
		||||
                    'username' => $this->config["SMTP_USER"],
 | 
			
		||||
                    'password' => $this->config["SMTP_PASS"]
 | 
			
		||||
                ));
 | 
			
		||||
            else
 | 
			
		||||
                $smtp = Mail::factory('smtp', array(
 | 
			
		||||
                    "host" => $this->config["SMTP_SERVER"],
 | 
			
		||||
                    "port" => $this->config["SMTP_PORT"]
 | 
			
		||||
                ));
 | 
			
		||||
            $headers = array ('From' => $this->config["SMTP_FROM"],
 | 
			
		||||
                'To' => $to,
 | 
			
		||||
                'Subject' => $subject);
 | 
			
		||||
            $smtp->send($to, $headers, $msg);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static function error_handler($err_severity, $err_msg, $err_file, $err_line, array $err_context)
 | 
			
		||||
    {
 | 
			
		||||
        if (0 === error_reporting()) { return false;}
 | 
			
		||||
        switch($err_severity)
 | 
			
		||||
        {
 | 
			
		||||
            case E_ERROR:               throw new ErrorException            ($err_msg, 0, $err_severity, $err_file, $err_line);
 | 
			
		||||
            case E_WARNING:             throw new WarningException          ($err_msg, 0, $err_severity, $err_file, $err_line);
 | 
			
		||||
            case E_PARSE:               throw new ParseException            ($err_msg, 0, $err_severity, $err_file, $err_line);
 | 
			
		||||
            case E_NOTICE:              throw new NoticeException           ($err_msg, 0, $err_severity, $err_file, $err_line);
 | 
			
		||||
            case E_CORE_ERROR:          throw new CoreErrorException        ($err_msg, 0, $err_severity, $err_file, $err_line);
 | 
			
		||||
            case E_CORE_WARNING:        throw new CoreWarningException      ($err_msg, 0, $err_severity, $err_file, $err_line);
 | 
			
		||||
            case E_COMPILE_ERROR:       throw new CompileErrorException     ($err_msg, 0, $err_severity, $err_file, $err_line);
 | 
			
		||||
            case E_COMPILE_WARNING:     throw new CoreWarningException      ($err_msg, 0, $err_severity, $err_file, $err_line);
 | 
			
		||||
            case E_USER_ERROR:          throw new UserErrorException        ($err_msg, 0, $err_severity, $err_file, $err_line);
 | 
			
		||||
            case E_USER_WARNING:        throw new UserWarningException      ($err_msg, 0, $err_severity, $err_file, $err_line);
 | 
			
		||||
            case E_USER_NOTICE:         throw new UserNoticeException       ($err_msg, 0, $err_severity, $err_file, $err_line);
 | 
			
		||||
            case E_STRICT:              throw new StrictException           ($err_msg, 0, $err_severity, $err_file, $err_line);
 | 
			
		||||
            case E_RECOVERABLE_ERROR:   throw new RecoverableErrorException ($err_msg, 0, $err_severity, $err_file, $err_line);
 | 
			
		||||
            case E_DEPRECATED:          throw new DeprecatedException       ($err_msg, 0, $err_severity, $err_file, $err_line);
 | 
			
		||||
            case E_USER_DEPRECATED:     throw new UserDeprecatedException   ($err_msg, 0, $err_severity, $err_file, $err_line);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										18
									
								
								system/engine/exceptions.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								system/engine/exceptions.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,18 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
//Original idea by http://www.php.net/manual/en/function.set-error-handler.php#112881
 | 
			
		||||
 | 
			
		||||
class WarningException              extends ErrorException {}
 | 
			
		||||
class ParseException                extends ErrorException {}
 | 
			
		||||
class NoticeException               extends ErrorException {}
 | 
			
		||||
class CoreErrorException            extends ErrorException {}
 | 
			
		||||
class CoreWarningException          extends ErrorException {}
 | 
			
		||||
class CompileErrorException         extends ErrorException {}
 | 
			
		||||
class CompileWarningException       extends ErrorException {}
 | 
			
		||||
class UserErrorException            extends ErrorException {}
 | 
			
		||||
class UserWarningException          extends ErrorException {}
 | 
			
		||||
class UserNoticeException           extends ErrorException {}
 | 
			
		||||
class StrictException               extends ErrorException {}
 | 
			
		||||
class RecoverableErrorException     extends ErrorException {}
 | 
			
		||||
class DeprecatedException           extends ErrorException {}
 | 
			
		||||
class UserDeprecatedException       extends ErrorException {}
 | 
			
		||||
							
								
								
									
										15
									
								
								system/engine/status.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								system/engine/status.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,15 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
class HF_Status extends HF_Controller
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
    public function Status404()
 | 
			
		||||
    {
 | 
			
		||||
        echo "Page not found!";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function Status500()
 | 
			
		||||
    {
 | 
			
		||||
        echo "System error";
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										1
									
								
								system/vendor/.htaccess
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								system/vendor/.htaccess
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
Deny from all
 | 
			
		||||
							
								
								
									
										453
									
								
								system/vendor/README.md
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										453
									
								
								system/vendor/README.md
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,453 @@
 | 
			
		||||
H2O template markup
 | 
			
		||||
========================
 | 
			
		||||
Being a martial arts fan, I borrow a quote.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
H2O template
 | 
			
		||||
------------------------
 | 
			
		||||
H2O is markup language for PHP that has taken a lot of inspiration from Django.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
__Features__
 | 
			
		||||
 * Readable and human-friendly syntax.
 | 
			
		||||
 * Easy to use and maintain
 | 
			
		||||
 * Encourages reuse in templates by allowing template inclusion and inheritance.
 | 
			
		||||
 * Highly extensible through filters, tags, and template extensions.
 | 
			
		||||
 * Includes a rich set of filters and tags for string formatting, HTML helpers and 
 | 
			
		||||
   internationalization support.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Requirement
 | 
			
		||||
------------------------
 | 
			
		||||
 | 
			
		||||
 - PHP 5.1 +
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
News
 | 
			
		||||
------------------------
 | 
			
		||||
 | 
			
		||||
 - version 0.4 
 | 
			
		||||
   1. **Breaking changes** autoescape is now turned on by default
 | 
			
		||||
   2. Improved searchpath and file loading handling
 | 
			
		||||
   3. Improved handling on PHP overloaded objects
 | 
			
		||||
   4. Plenty of bug fixes
 | 
			
		||||
 - version 0.3
 | 
			
		||||
   1. Support internationalized templates and translation parsing toolkit
 | 
			
		||||
   2. Performance optimization on context lookup
 | 
			
		||||
   3. Fixed operator parsing
 | 
			
		||||
 | 
			
		||||
Getting started
 | 
			
		||||
------------------------
 | 
			
		||||
 | 
			
		||||
### Getting h2o
 | 
			
		||||
 | 
			
		||||
Download
 | 
			
		||||
 | 
			
		||||
[<img src="http://github.com/images/modules/download/zip.png">](http://code.google.com/p/h2o-template/downloads)
 | 
			
		||||
 
 | 
			
		||||
With Git
 | 
			
		||||
 | 
			
		||||
`git clone http://github.com/speedmax/h2o-php.git`
 | 
			
		||||
 | 
			
		||||
With SVN 
 | 
			
		||||
 | 
			
		||||
`svn checkout http://h2o-template.googlecode.com/svn/trunk/ h2o`
 | 
			
		||||
 | 
			
		||||
### Installation
 | 
			
		||||
 1. Download and extract h2o into your project path or your php include path
 | 
			
		||||
 | 
			
		||||
    Sample file structure setup 
 | 
			
		||||
     
 | 
			
		||||
        myawesome_app/
 | 
			
		||||
            index.php
 | 
			
		||||
            templates/
 | 
			
		||||
              index.html
 | 
			
		||||
            h2o/
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 2. Use `require 'h2o/h2o.php'` in your php files to include the h2o library.
 | 
			
		||||
 3. Below is a basic code sample to get your project going. 
 | 
			
		||||
 3. Check out the *\example* and *\specs* dirs to see some of h2o's more interesting features in action. 
 | 
			
		||||
 
 | 
			
		||||
*templates/index.html*
 | 
			
		||||
 | 
			
		||||
    <body>
 | 
			
		||||
        <head><title>Hello world</title></head>
 | 
			
		||||
        <body>
 | 
			
		||||
            Greetings {{ name }}
 | 
			
		||||
        </body>
 | 
			
		||||
    </body>
 | 
			
		||||
 | 
			
		||||
*index.php*
 | 
			
		||||
 | 
			
		||||
    <?php
 | 
			
		||||
        require 'h2o/h2o.php';
 | 
			
		||||
        $h2o = new h2o('templates/index.html');
 | 
			
		||||
        echo $h2o->render(array('name'=>'Peter Jackson'));
 | 
			
		||||
    ?>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Useful links
 | 
			
		||||
------------------------
 | 
			
		||||
 | 
			
		||||
 * Please submit patches or bug reports to our [lighthouse bug tracker][issue].
 | 
			
		||||
 * Check out our [Google group][group] for h2o-related discussion.
 | 
			
		||||
 | 
			
		||||
 [issue]:http://idealian.lighthouseapp.com/projects/11041-h2o-template-language
 | 
			
		||||
 [group]:http://groups.google.com/group/h2o-template-php
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Syntax explanation
 | 
			
		||||
------------------------
 | 
			
		||||
 | 
			
		||||
## variable
 | 
			
		||||
`{{ variable }}`
 | 
			
		||||
 | 
			
		||||
Use dot (.) to access attributes of a variable
 | 
			
		||||
 | 
			
		||||
#### variable lookup order
 | 
			
		||||
1. key of an associative array
 | 
			
		||||
2. array-index 
 | 
			
		||||
3. object attribute
 | 
			
		||||
4. object method call
 | 
			
		||||
 | 
			
		||||
**Example**
 | 
			
		||||
 | 
			
		||||
*in your template*
 | 
			
		||||
 | 
			
		||||
    {{ person.name }} 
 | 
			
		||||
 | 
			
		||||
*in php*
 | 
			
		||||
 | 
			
		||||
    <?php 
 | 
			
		||||
        $h2o = new H2o('template.tpl');
 | 
			
		||||
        $person =array(
 | 
			
		||||
                'name' => 'Peter Jackson', 'age' => 25
 | 
			
		||||
        );
 | 
			
		||||
        $h2o->render(compact('person'));
 | 
			
		||||
    ?>
 | 
			
		||||
    
 | 
			
		||||
Let's say that you have assigned the value `Peter Jackson` to a 'person' variable in your php script. The following 
 | 
			
		||||
variable tag will print out `Peter Jackson`.
 | 
			
		||||
 | 
			
		||||
## Filters
 | 
			
		||||
 | 
			
		||||
Filters are variable modifiers that manipulate or format the value of a variable. 
 | 
			
		||||
A filter usually looks like this `{{ person.name|capitalize }}`, a pipe ( | ) 
 | 
			
		||||
character after a variable, plus a filter name, will cause H2O to apply the filter.
 | 
			
		||||
 | 
			
		||||
__Filter chaining__
 | 
			
		||||
 | 
			
		||||
  
 | 
			
		||||
Let me borrow the image from liquid template
 | 
			
		||||
 | 
			
		||||
You can chain multiple filters together and use a pipe ( | ) character to separate 
 | 
			
		||||
them. `{{ document.body|escape|nl2br }}`
 | 
			
		||||
 | 
			
		||||
__Filter arguments__  
 | 
			
		||||
Filters can accept arguments. For example:
 | 
			
		||||
`{{ document.description|truncate 20 }}` 
 | 
			
		||||
will display the first 20 characters of the document's description.
 | 
			
		||||
 | 
			
		||||
Moreover, there are cases where you might want to pass in multiple arguments. 
 | 
			
		||||
Use commas ( , ) to separate them:
 | 
			
		||||
`{{ person.bio|truncate 20, "..." }}`
 | 
			
		||||
 | 
			
		||||
__Filter named arguments__  
 | 
			
		||||
h2o uses colons ( : ) for named arguments. These allow you to build 'optional argument' arrays. 
 | 
			
		||||
 | 
			
		||||
`{{ '/images/logo.png' | image_tag width:450, height:250, alt:"company logo" }}`
 | 
			
		||||
 | 
			
		||||
The above code translated to php will be like the below snippet, which resembles what happens internally:
 | 
			
		||||
    
 | 
			
		||||
    <?php
 | 
			
		||||
        echo image_tag("/image/logo.png", array(
 | 
			
		||||
            'width' => 450, 
 | 
			
		||||
            'height' => 250, 
 | 
			
		||||
            'alt'=>'company logo'
 | 
			
		||||
        ));
 | 
			
		||||
    ?>
 | 
			
		||||
 | 
			
		||||
Note: Difference with Django, Smarty 
 | 
			
		||||
H2o does not use the colon ( : ) character to separate arguments for readability reasons, 
 | 
			
		||||
H2o uses the comma ( , ) which is more logical.
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
## Tag  
 | 
			
		||||
 | 
			
		||||
`{% tag %}`
 | 
			
		||||
 | 
			
		||||
Tags are very powerful, as they control the logical flow and structure of a template, 
 | 
			
		||||
There are inline tags `{% inline_tag %}` or tags that requires a 
 | 
			
		||||
close tag. For example: `{% if condition %} ... {% endif %}` 
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### The "if" tag
 | 
			
		||||
 | 
			
		||||
`if` tags evaluate either a variable or a simple expression. If the result of the `if` 
 | 
			
		||||
expression is *true*, then the contents of the `if` block will be allowed to render.
 | 
			
		||||
    
 | 
			
		||||
    {% if person.is_adult %}
 | 
			
		||||
        You are old enough.
 | 
			
		||||
    {% else %}
 | 
			
		||||
        sorry, you are too young for that.
 | 
			
		||||
    {% endif %}
 | 
			
		||||
 | 
			
		||||
### The "for" tag
 | 
			
		||||
 | 
			
		||||
`for` tags allow iteratation over an array of items. 
 | 
			
		||||
 
 | 
			
		||||
    {% for task in tasks %}
 | 
			
		||||
        {{ task }}
 | 
			
		||||
    {% endfor %}
 | 
			
		||||
 | 
			
		||||
The above snippet will print out each "task" in the "tasks" array.
 | 
			
		||||
 | 
			
		||||
Template inheritance
 | 
			
		||||
------------------------
 | 
			
		||||
H2o supports template inheritance. Inheritance allows you to factor out a lot 
 | 
			
		||||
of common code that would otherwise be duplicated across most of your templates.
 | 
			
		||||
 | 
			
		||||
Template inheritance is implemented using the `block` and `extends` tags, with child templates
 | 
			
		||||
*extending* their parent templates.
 | 
			
		||||
**Word of Caution:**
 | 
			
		||||
 * H2o templates only support single inheritance (just like PHP!), and currently do not support deep inheritance chains.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Quote from the Django docs:
 | 
			
		||||
> ... a base skeleton template that contains all the common elements of your 
 | 
			
		||||
> site and defines blocks that child templates can override.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
*Example:*
 | 
			
		||||
 | 
			
		||||
_base.html_ - defines the base structure of our pages.
 | 
			
		||||
 | 
			
		||||
    <html>
 | 
			
		||||
     <head><title>{%block title %}This is a page title {% endblock %}</title></head>
 | 
			
		||||
     <body>
 | 
			
		||||
     <div id="content">
 | 
			
		||||
       {% block content%}
 | 
			
		||||
           <h1> Page title </h1>
 | 
			
		||||
           <p> H2O template inheritance is a powerful tool </p> 
 | 
			
		||||
       {% endblock %}
 | 
			
		||||
     </div>
 | 
			
		||||
    
 | 
			
		||||
     <div id="sidebar">
 | 
			
		||||
       {% block sidebar %}{% endblock %}
 | 
			
		||||
     </div>
 | 
			
		||||
     </body>
 | 
			
		||||
    </html>
 | 
			
		||||
 | 
			
		||||
As you can see, the base template is a typical web page using a two column layout. 
 | 
			
		||||
We defined two blocks (`content` and `sidebar`) and HTML code common across all of our pages.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
_page.html_ - defines a page-specific template.
 | 
			
		||||
 | 
			
		||||
    {% extends 'base.html' %}
 | 
			
		||||
    
 | 
			
		||||
    {% block content %}
 | 
			
		||||
        <h1> extended page </h1>
 | 
			
		||||
        <p> Body of extended page </p>
 | 
			
		||||
    {% endblock %}
 | 
			
		||||
    
 | 
			
		||||
    {% block sidebar %}
 | 
			
		||||
        Sidebar contains use links.
 | 
			
		||||
    {% endblock %}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
The `page.html` extends `base.html`, allowing us to override any block 
 | 
			
		||||
previously defined in `base.html`. 
 | 
			
		||||
 | 
			
		||||
Below is an excellent article about template inheritance in Django. If you wish to understand H2o's
 | 
			
		||||
template-inheritance system, this would be a great spot to start, since H2o's template-inheritance system 
 | 
			
		||||
is strongly influenced by Django's.
 | 
			
		||||
 | 
			
		||||
[Power of inheritance][3] is a very good blog post explaining inheritance 
 | 
			
		||||
 | 
			
		||||
 [3]:http://www2.jeffcroft.com/blog/2006/feb/25/django-templates-the-power-of-inheritance/
 | 
			
		||||
 | 
			
		||||
*Tips*
 | 
			
		||||
 | 
			
		||||
* If you have found that you have several common elements inside the same template, it may be a 
 | 
			
		||||
  good idea to put that portion of the template inside a `block` in a base template. 
 | 
			
		||||
* `block` give you a hook, which is useful, since these can help with javascript and css too.
 | 
			
		||||
* When defining a block use a short and distinctive name
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### Configuration
 | 
			
		||||
There are a range of options for configuring the template engine.
 | 
			
		||||
 | 
			
		||||
    <?php
 | 
			
		||||
        $h2o = new H2o('template.tpl', array(
 | 
			
		||||
            [option_name] => [option_value]
 | 
			
		||||
        ));
 | 
			
		||||
    ?>
 | 
			
		||||
 | 
			
		||||
#### Loader
 | 
			
		||||
The name of the loader or an instance of H2o_Loader
 | 
			
		||||
 | 
			
		||||
__Use file loader [default]__
 | 
			
		||||
 | 
			
		||||
` $template = new H2o('index.html', array('loader'=>'file'); `
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
__Advanced setup__
 | 
			
		||||
    <?php
 | 
			
		||||
    $loader = new H2o_File_Loader($custom_searchpath);
 | 
			
		||||
    $template = new H2o('index.html', array('loader'=> $loader );
 | 
			
		||||
    ?>
 | 
			
		||||
    
 | 
			
		||||
__Use dictionary loader__
 | 
			
		||||
 | 
			
		||||
If you want to load templates from resources other than files, then this will be your
 | 
			
		||||
friend. H2o uses `dict_loader()` for testing.
 | 
			
		||||
 | 
			
		||||
    <?php
 | 
			
		||||
        $loader = dict_loader(array(
 | 
			
		||||
            "index.html" => 'Hello {{ person }}'
 | 
			
		||||
        ));
 | 
			
		||||
        $template = new H2o('index.html', array('loader' => $loader'));
 | 
			
		||||
    ?> 
 | 
			
		||||
 | 
			
		||||
#### Searchpath
 | 
			
		||||
 | 
			
		||||
default: this will be the base path of your template
 | 
			
		||||
 | 
			
		||||
H2o use this path to load additional templates and extensions. 
 | 
			
		||||
 | 
			
		||||
You can either explicity set the search path,
 | 
			
		||||
 | 
			
		||||
`$template = new H2o('index.html', array('searchpath' => '/sites/common_templates'));`
 | 
			
		||||
 | 
			
		||||
or h2o will try to find the searchpath for you.
 | 
			
		||||
 | 
			
		||||
`$template = new H2o('/sites/common_templates/index.html');`
 | 
			
		||||
 | 
			
		||||
#### Cache
 | 
			
		||||
You can define the type of caching engine h2o should use, if any. 
 | 
			
		||||
Set 'cache' to false to disable caching.
 | 
			
		||||
You can read more about performance and caching in following sections
 | 
			
		||||
 | 
			
		||||
Use file cache [default]
 | 
			
		||||
 | 
			
		||||
`$template = new H2o('index.html', array('cache'=>'file'));`
 | 
			
		||||
 | 
			
		||||
Use apc cache:
 | 
			
		||||
 | 
			
		||||
`$template = new H2o('index.html', array('cache'=>'apc'));`
 | 
			
		||||
 | 
			
		||||
Use memcache cache
 | 
			
		||||
 | 
			
		||||
`$template = new H2o('index.html', array('cache'=>'memcache'));`
 | 
			
		||||
 | 
			
		||||
Disable caching
 | 
			
		||||
 | 
			
		||||
`$template = new H2o('index.html', array('cache'=>false));`
 | 
			
		||||
 | 
			
		||||
#### Cache_dir
 | 
			
		||||
When the file cache is used, you can define where you want templates to be cached. 
 | 
			
		||||
 | 
			
		||||
It will put a cached template in same location as the normal template
 | 
			
		||||
 | 
			
		||||
`$template = new H2o('index.html', array('cache_dir'=>'/tmp/cached_templates'));`
 | 
			
		||||
 | 
			
		||||
#### Cache_ttl
 | 
			
		||||
"cache_ttl" specifies how long a cached template should be used (defaults: 1 hour) before it is recompiled. The template fragment cache
 | 
			
		||||
that is bundled in the cache extension will use this as default ttl value.
 | 
			
		||||
 | 
			
		||||
`$template = new H2o('index.html', array('cache_ttl' => 3600));`
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Performance and Caching
 | 
			
		||||
------------------------
 | 
			
		||||
 | 
			
		||||
Caching can increase performance since it skips step of inefficient template parsing. 
 | 
			
		||||
H2o caches the template objects (the internal data structure of a template) and the bundled
 | 
			
		||||
caching backends include File, APC, and Memcache.
 | 
			
		||||
 | 
			
		||||
### File cache
 | 
			
		||||
By default h2o uses the file cache to store template objects. Change h2o option `cache_dir` to where you 
 | 
			
		||||
want to store template cache (ie: /tmp).
 | 
			
		||||
  
 | 
			
		||||
    <?php
 | 
			
		||||
        $template = new H2o('homepage.tpl', array(
 | 
			
		||||
            'cache' => 'file',
 | 
			
		||||
            'cache_dir' => '/tmp'
 | 
			
		||||
        ));
 | 
			
		||||
    ?>
 | 
			
		||||
 | 
			
		||||
### APC cache
 | 
			
		||||
APC is an op-code and object cache extension for php whose performance is 
 | 
			
		||||
generally 10-30% better than just plain file caching. 
 | 
			
		||||
 | 
			
		||||
    <?php
 | 
			
		||||
        $template = new h2o('homepage.tpl', array('cache' => 'apc'));
 | 
			
		||||
    ?>
 | 
			
		||||
 | 
			
		||||
### Memcache
 | 
			
		||||
Currently not implemented
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Extending H2o
 | 
			
		||||
------------------------
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Known issues
 | 
			
		||||
------------------------
 | 
			
		||||
Yes, h2o has them. However, if you are careful, these shouldn't hinder your template development.
 | 
			
		||||
The deep inheritance issue is a bit problematic for some template architectures, but again, if you 
 | 
			
		||||
are careful, and perhaps a bit inventive, it won't hinder you terribly much.
 | 
			
		||||
 | 
			
		||||
 * `{{ block.super }}` doesn't work with more than 1 level of inheritance yet, so if `{{ block.super }}`
 | 
			
		||||
   invokes another `{{ block.super }}` it won't work just yet.  
 | 
			
		||||
 * 'if' conditions don't support multiple expressions or mathematical expressions yet, like: 
 | 
			
		||||
   `{% if something > 3 or something < 2 %}` or `{% if something + else > 12 %}`
 | 
			
		||||
    These likely will not be implemented in the future unless some daring soul implements them and 
 | 
			
		||||
    contributes the code back to the h2o-php project.
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
Contributors
 | 
			
		||||
---
 | 
			
		||||
  - Taylor Luk - Founder of [Issue publishing](http://issueapp.com)
 | 
			
		||||
  - jlogsdon - Major refactoring (wip) and bug fixes
 | 
			
		||||
  - cyberklin - Added filter support for any context resolve
 | 
			
		||||
  - idlesign - Added if_changed tag support
 | 
			
		||||
  - metropolis - Improved our test coverage
 | 
			
		||||
  - plus many others
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Credit
 | 
			
		||||
------------------------
 | 
			
		||||
H2o borrows ideas and/or concepts from the following projects:
 | 
			
		||||
 | 
			
		||||
 - Django template - Django web development framework.
 | 
			
		||||
 - Ptemplates - Armin Ronacher's pet project for a django port in PHP.
 | 
			
		||||
 - Jinja - Django inspired template in Python.
 | 
			
		||||
 | 
			
		||||
Special Thanks: Armin Ronacher, since early versions of h2o were based off of his Ptemplates project.
 | 
			
		||||
 | 
			
		||||
The MIT License
 | 
			
		||||
------------------------
 | 
			
		||||
Copyright (c) 2008 Taylor Luk 
 | 
			
		||||
 | 
			
		||||
Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
			
		||||
of this software and associated documentation files (the "Software"), to deal
 | 
			
		||||
in the Software without restriction, including without limitation the rights
 | 
			
		||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | 
			
		||||
copies of the Software, and to permit persons to whom the Software is
 | 
			
		||||
furnished to do so, subject to the following conditions:
 | 
			
		||||
 | 
			
		||||
The above copyright notice and this permission notice shall be included in
 | 
			
		||||
all copies or substantial portions of the Software.
 | 
			
		||||
 | 
			
		||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | 
			
		||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | 
			
		||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | 
			
		||||
THE SOFTWARE.
 | 
			
		||||
							
								
								
									
										66
									
								
								system/vendor/StackTracePrint.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								system/vendor/StackTracePrint.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,66 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
// Original http://stackoverflow.com/a/4282133/195722
 | 
			
		||||
function vdump() {
 | 
			
		||||
 | 
			
		||||
    $args = func_get_args();
 | 
			
		||||
 | 
			
		||||
    $backtrace = debug_backtrace();
 | 
			
		||||
    $code = file($backtrace[0]['file']);
 | 
			
		||||
 | 
			
		||||
    $ret = "<pre style='background: #eee; border: 1px solid #aaa; clear: both; overflow: auto; padding: 10px; text-align: left; margin-bottom: 5px'>";
 | 
			
		||||
 | 
			
		||||
    $ret .- "<b>".htmlspecialchars(trim($code[$backtrace[0]['line']-1]))."</b>\n";
 | 
			
		||||
 | 
			
		||||
    $ret .= "\n";
 | 
			
		||||
 | 
			
		||||
    ob_start();
 | 
			
		||||
 | 
			
		||||
    foreach ($args as $arg)
 | 
			
		||||
        var_dump($arg);
 | 
			
		||||
 | 
			
		||||
    $str = ob_get_contents();
 | 
			
		||||
 | 
			
		||||
    ob_end_clean();
 | 
			
		||||
 | 
			
		||||
    $str = preg_replace('/=>(\s+)/', ' => ', $str);
 | 
			
		||||
    $str = preg_replace('/ => NULL/', ' → <b style="color: #000">NULL</b>', $str);
 | 
			
		||||
    $str = preg_replace('/}\n(\s+)\[/', "}\n\n".'$1[', $str);
 | 
			
		||||
    $str = preg_replace('/ (float|int)\((\-?[\d\.]+)\)/', " <span style='color: #888'>$1</span> <b style='color: brown'>$2</b>", $str);
 | 
			
		||||
 | 
			
		||||
    $str = preg_replace('/array\((\d+)\) {\s+}\n/', "<span style='color: #888'>array•$1</span> <b style='color: brown'>[]</b>", $str);
 | 
			
		||||
    $str = preg_replace('/ string\((\d+)\) \"(.*)\"/', " <span style='color: #888'>str•$1</span> <b style='color: brown'>'$2'</b>", $str);
 | 
			
		||||
    $str = preg_replace('/\[\"(.+)\"\] => /', "<span style='color: purple'>'$1'</span> → ", $str);
 | 
			
		||||
    $str = preg_replace('/object\((\S+)\)#(\d+) \((\d+)\) {/', "<span style='color: #888'>obj•$2</span> <b style='color: #0C9136'>$1[$3]</b> {", $str);
 | 
			
		||||
    $str = str_replace("bool(false)", "<span style='color:#888'>bool•</span><span style='color: red'>false</span>", $str);
 | 
			
		||||
    $str = str_replace("bool(true)", "<span style='color:#888'>bool•</span><span style='color: green'>true</span>", $str);
 | 
			
		||||
 | 
			
		||||
    $ret .= $str;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    $ret .= "</pre>";
 | 
			
		||||
 | 
			
		||||
    return $ret;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Original - http://www.php.net/manual/en/function.debug-print-backtrace.php#86932
 | 
			
		||||
function debug_string_backtrace() {
 | 
			
		||||
    ob_start();
 | 
			
		||||
    debug_print_backtrace();
 | 
			
		||||
    $trace = ob_get_contents();
 | 
			
		||||
    ob_end_clean();
 | 
			
		||||
 | 
			
		||||
    // Remove first item from backtrace as it's this function which
 | 
			
		||||
    // is redundant.
 | 
			
		||||
    $trace = preg_replace ('/^#0\s+' . __FUNCTION__ . "[^\n]*\n/", '', $trace, 1);
 | 
			
		||||
 | 
			
		||||
    // Renumber backtrace items.
 | 
			
		||||
    $trace = preg_replace ('/^#(\d+)/me', '\'#\' . ($1 - 1)', $trace);
 | 
			
		||||
 | 
			
		||||
    $trace = wordwrap($trace, 123, "<br>");
 | 
			
		||||
    return $trace;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										266
									
								
								system/vendor/h2o.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										266
									
								
								system/vendor/h2o.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,266 @@
 | 
			
		||||
<?php
 | 
			
		||||
define('H2O_VERSION', '0.3');
 | 
			
		||||
defined('DS') or define('DS', DIRECTORY_SEPARATOR);
 | 
			
		||||
defined('H2O_ROOT') or define('H2O_ROOT', dirname(__FILE__) . DS);
 | 
			
		||||
 | 
			
		||||
require H2O_ROOT.'h2o/datatype.php';
 | 
			
		||||
require H2O_ROOT.'h2o/loaders.php';
 | 
			
		||||
require H2O_ROOT.'h2o/nodes.php';
 | 
			
		||||
require H2O_ROOT.'h2o/tags.php';
 | 
			
		||||
require H2O_ROOT.'h2o/errors.php';
 | 
			
		||||
require H2O_ROOT.'h2o/filters.php';
 | 
			
		||||
require H2O_ROOT.'h2o/context.php';
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Example:
 | 
			
		||||
 *  $h2o = new H2O('./template.html', array("loader"=>'file'));
 | 
			
		||||
 *
 | 
			
		||||
 *
 | 
			
		||||
 *  $h2o = new H2O('template.html', array("loader"=>'hash'));
 | 
			
		||||
 */
 | 
			
		||||
class H2o {
 | 
			
		||||
    var $searchpath;
 | 
			
		||||
    var $context;
 | 
			
		||||
    var $loader = false;
 | 
			
		||||
 | 
			
		||||
    static $tags = array();
 | 
			
		||||
    static $filters = array();
 | 
			
		||||
    static $extensions = array();
 | 
			
		||||
 | 
			
		||||
    static function getOptions($options = array()) {
 | 
			
		||||
        return array_merge(array(
 | 
			
		||||
            'loader'            =>       'file',
 | 
			
		||||
            'cache'             =>      'file',     // file | apc | memcache
 | 
			
		||||
            'cache_prefix'      =>      'h2o_',
 | 
			
		||||
            'cache_ttl'         =>      3600,     // file | apc | memcache
 | 
			
		||||
            'searchpath'        =>      false,
 | 
			
		||||
            'autoescape'        =>      true,
 | 
			
		||||
 | 
			
		||||
            // Enviroment setting
 | 
			
		||||
            'BLOCK_START'       =>      '{%',
 | 
			
		||||
            'BLOCK_END'         =>      '%}',
 | 
			
		||||
            'VARIABLE_START'    =>      '{{',
 | 
			
		||||
            'VARIABLE_END'      =>      '}}',
 | 
			
		||||
            'COMMENT_START'     =>      '{*',
 | 
			
		||||
            'COMMENT_END'       =>      '*}',
 | 
			
		||||
            'TRIM_TAGS'         =>      true
 | 
			
		||||
        ), $options);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function __construct($file = null, $options = array()) {
 | 
			
		||||
        # Init a environment
 | 
			
		||||
        $this->options = $this->getOptions($options);
 | 
			
		||||
        $loader = $this->options['loader'];
 | 
			
		||||
 | 
			
		||||
        if (!$loader)
 | 
			
		||||
            return true;
 | 
			
		||||
 | 
			
		||||
        if (is_object($loader)) {
 | 
			
		||||
            $this->loader = $loader;
 | 
			
		||||
            $this->loader->setOptions($this->options);
 | 
			
		||||
        } else {
 | 
			
		||||
            $loader = "H2o_{$loader}_Loader";
 | 
			
		||||
            if (!class_exists($loader, false))
 | 
			
		||||
                throw new Exception('Invalid template loader');
 | 
			
		||||
 | 
			
		||||
            if (isset($options['searchpath'])){
 | 
			
		||||
                $this->searchpath = $options['searchpath'];
 | 
			
		||||
            } else if ($file) {
 | 
			
		||||
                $this->searchpath = dirname(realpath($file)).DS;
 | 
			
		||||
            } else {
 | 
			
		||||
                $this->searchpath = getcwd().DS;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            $loader_searchpath = is_array($this->searchpath) ? $this->searchpath : array($this->searchpath);
 | 
			
		||||
            $this->loader = new $loader($loader_searchpath, $this->options);
 | 
			
		||||
        }
 | 
			
		||||
        $this->loader->runtime = $this;
 | 
			
		||||
 | 
			
		||||
        if (isset($options['i18n'])) {
 | 
			
		||||
            h2o::load('i18n');
 | 
			
		||||
            $this->i18n = new H2o_I18n($this->searchpath, $options['i18n']);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if ($file) {
 | 
			
		||||
            $this->nodelist = $this->loadTemplate($file);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function loadTemplate($file) {
 | 
			
		||||
        return $this->nodelist = $this->loader->read_cache($file);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function loadSubTemplate($file) {
 | 
			
		||||
        return $this->loader->read($file);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    # Build a finalized nodelist from template ready to be cached
 | 
			
		||||
    function parse($source, $filename = '', $env = null) {
 | 
			
		||||
        if (!$env)
 | 
			
		||||
            $env = $this->options;
 | 
			
		||||
 | 
			
		||||
        if (!class_exists('H2o_Parser', false))
 | 
			
		||||
            require H2O_ROOT.'h2o/parser.php';
 | 
			
		||||
 | 
			
		||||
        $parser = new H2o_Parser($source, $filename, $this, $env);
 | 
			
		||||
        $nodelist = $parser->parse();
 | 
			
		||||
        return $nodelist;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function set($context, $value = null) {
 | 
			
		||||
        # replace with new context object
 | 
			
		||||
        if (is_object($context) && $context instanceof H2o_Context) {
 | 
			
		||||
            return $this->context = $context;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        # Init context
 | 
			
		||||
        if (!$this->context) {
 | 
			
		||||
            $this->context = new H2o_Context($this->defaultContext(), $this->options);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        # Extend or set value
 | 
			
		||||
        if (is_array($context)) {
 | 
			
		||||
            return $this->context->extend($context);
 | 
			
		||||
        }
 | 
			
		||||
        elseif (is_string($context)) {
 | 
			
		||||
            return $this->context[$context] = $value;
 | 
			
		||||
        }
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    # Render the nodelist
 | 
			
		||||
    function render($context = array()) {
 | 
			
		||||
        $this->set($context);
 | 
			
		||||
 | 
			
		||||
        $this->stream = new StreamWriter;
 | 
			
		||||
        $this->nodelist->render($this->context, $this->stream);
 | 
			
		||||
        return $this->stream->close();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static function parseString($source, $options = array()) {
 | 
			
		||||
        $instance = new H2o(null, array_merge($options, array('loader' => false)));
 | 
			
		||||
        $instance->nodelist = $instance->parse($source);
 | 
			
		||||
        return $instance;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static function &createTag($tag, $args = null, $parser, $position = 0) {
 | 
			
		||||
        if (!isset(self::$tags[$tag])) {
 | 
			
		||||
            throw new H2o_Error($tag . " tag doesn't exist");
 | 
			
		||||
        }
 | 
			
		||||
        $tagClass = self::$tags[$tag];
 | 
			
		||||
        $tag = new $tagClass($args, $parser, $position);
 | 
			
		||||
        return $tag;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Register a new tag
 | 
			
		||||
     *
 | 
			
		||||
     *
 | 
			
		||||
     * h2o::addTag('tag_name', 'ClassName');
 | 
			
		||||
     *
 | 
			
		||||
     * h2o::addTag(array(
 | 
			
		||||
     *      'tag_name' => 'MagClass',
 | 
			
		||||
     *      'tag_name2' => 'TagClass2'
 | 
			
		||||
     * ));
 | 
			
		||||
     *
 | 
			
		||||
     *  h2o::addTag('tag_name');      // Tag_name_Tag
 | 
			
		||||
     *
 | 
			
		||||
     * h2o::addTag(array('tag_name',
 | 
			
		||||
     * @param unknown_type $tag
 | 
			
		||||
     * @param unknown_type $class
 | 
			
		||||
     */
 | 
			
		||||
    static function addTag($tag, $class = null) {
 | 
			
		||||
        $tags = array();
 | 
			
		||||
        if (is_string($tag)) {
 | 
			
		||||
            if (is_null($class))
 | 
			
		||||
                $class = ucwords("{$tag}_Tag");
 | 
			
		||||
            $tags[$tag] = $class;
 | 
			
		||||
        } elseif (is_array($tag)) {
 | 
			
		||||
            $tags = $tag;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        foreach ($tags as $tag => $tagClass) {
 | 
			
		||||
            if (is_integer($tag)) {
 | 
			
		||||
                unset($tags[$tag]);
 | 
			
		||||
                $tag = $tagClass;
 | 
			
		||||
                $tagClass = ucwords("{$tagClass}_Tag");
 | 
			
		||||
            }
 | 
			
		||||
            if (!class_exists($tagClass, false)) {
 | 
			
		||||
                throw new H2o_Error("{$tagClass} tag is not found");
 | 
			
		||||
            }
 | 
			
		||||
            $tags[$tag] = $tagClass;
 | 
			
		||||
        }
 | 
			
		||||
        self::$tags = array_merge(self::$tags, $tags);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Register a new filter to h2o runtime
 | 
			
		||||
     *
 | 
			
		||||
     * @param unknown_type $filter
 | 
			
		||||
     * @param unknown_type $callback
 | 
			
		||||
     * @return unknown
 | 
			
		||||
     */
 | 
			
		||||
    static function addFilter($filter, $callback = null) {
 | 
			
		||||
        if (is_array($filter)) {
 | 
			
		||||
            $filters = $filter;
 | 
			
		||||
            foreach($filters as $key => $filter) {
 | 
			
		||||
                if (is_numeric($key))
 | 
			
		||||
                    $key = $filter;
 | 
			
		||||
                self::addFilter($key, $filter);
 | 
			
		||||
            }
 | 
			
		||||
            return true;
 | 
			
		||||
        } elseif (is_string($filter) && class_exists($filter, false) && is_subclass_of($filter, 'FilterCollection')) {
 | 
			
		||||
            foreach (get_class_methods($filter) as $f) {
 | 
			
		||||
                if (is_callable(array($filter, $f)))
 | 
			
		||||
                    self::$filters[$f] = array($filter, $f);
 | 
			
		||||
            }
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
        if (is_null($callback))
 | 
			
		||||
            $callback = $filter;
 | 
			
		||||
 | 
			
		||||
        if (!is_callable($callback)) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        self::$filters[$filter] = $callback;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static function addLookup($callback) {
 | 
			
		||||
        if (is_callable($callback)) {
 | 
			
		||||
            H2o_Context::$lookupTable[] = $callback;
 | 
			
		||||
        } else die('damm it');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static function load($extension, $file = null) {
 | 
			
		||||
        if (!$file) {
 | 
			
		||||
            $file = H2O_ROOT.'ext'.DS.$extension.'.php';
 | 
			
		||||
        }
 | 
			
		||||
        if (is_file($file)) {
 | 
			
		||||
            include_once ($file);
 | 
			
		||||
            self::$extensions[$extension] = $file;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function defaultContext() {
 | 
			
		||||
        return array('h2o' => new H2o_Info);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Convenient wrapper for loading template file or string
 | 
			
		||||
 * @param $name
 | 
			
		||||
 * @param $options - H2o options
 | 
			
		||||
 * @return Instance of H2o Template
 | 
			
		||||
 */
 | 
			
		||||
function h2o($name, $options = array()) {
 | 
			
		||||
    $is_file = '/([^\s]*?)(\.[^.\s]*$)/';
 | 
			
		||||
 | 
			
		||||
    if (!preg_match($is_file, $name)) {
 | 
			
		||||
        return H2o::parseString($name, $options);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    $instance = new H2o($name, $options);
 | 
			
		||||
    return $instance;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
?>
 | 
			
		||||
							
								
								
									
										1
									
								
								system/vendor/h2o/.htaccess
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								system/vendor/h2o/.htaccess
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
Deny from all
 | 
			
		||||
							
								
								
									
										266
									
								
								system/vendor/h2o/context.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										266
									
								
								system/vendor/h2o/context.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,266 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Context object
 | 
			
		||||
 *  encapsulate context, resolve name
 | 
			
		||||
 */
 | 
			
		||||
class H2o_Context implements ArrayAccess {
 | 
			
		||||
    public $safeClass = array('stdClass', 'BlockContext');
 | 
			
		||||
    public $scopes;
 | 
			
		||||
    public $options;
 | 
			
		||||
    public $autoescape = true;
 | 
			
		||||
    
 | 
			
		||||
    private $arrayMethods = array('first'=> 0, 'last'=> 1, 'length'=> 2, 'size'=> 3);
 | 
			
		||||
    static $lookupTable = array();
 | 
			
		||||
    
 | 
			
		||||
    function __construct($context = array(), $options = array()){
 | 
			
		||||
        if (is_object($context))
 | 
			
		||||
           $context = get_object_vars($context);
 | 
			
		||||
        $this->scopes = array($context);
 | 
			
		||||
        
 | 
			
		||||
        if (isset($options['safeClass'])) 
 | 
			
		||||
            $this->safeClass = array_merge($this->safeClass, $options['safeClass']);
 | 
			
		||||
            
 | 
			
		||||
        if (isset($options['autoescape'])) 
 | 
			
		||||
            $this->autoescape = $options['autoescape'];
 | 
			
		||||
            
 | 
			
		||||
        $this->options = $options;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function push($layer = array()){
 | 
			
		||||
        return array_unshift($this->scopes, $layer);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * pop the most recent layer
 | 
			
		||||
     */
 | 
			
		||||
    function pop() {
 | 
			
		||||
        if (!isset($this->scopes[1]))
 | 
			
		||||
            throw new Exception('cannnot pop from empty stack');
 | 
			
		||||
        return array_shift($this->scopes);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function offsetExists($offset) {
 | 
			
		||||
        foreach ($this->scopes as $layer) {
 | 
			
		||||
            if (isset($layer[$offset])) return true;
 | 
			
		||||
        }
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function offsetGet($key) {
 | 
			
		||||
        foreach ($this->scopes as $layer) {
 | 
			
		||||
            if (isset($layer[$key]))
 | 
			
		||||
                return $layer[$key];
 | 
			
		||||
        }
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    function offsetSet($key, $value) {
 | 
			
		||||
        if (strpos($key, '.') > -1)
 | 
			
		||||
            throw new Exception('cannot set non local variable');
 | 
			
		||||
        return $this->scopes[0][$key] = $value;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    function offsetUnset($key) {
 | 
			
		||||
        foreach ($this->scopes as $layer) {
 | 
			
		||||
            if (isset($layer[$key])) unset($layer[$key]);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function extend($context) {
 | 
			
		||||
        $this->scopes[0] = array_merge($this->scopes[0], $context);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function set($key, $value) {
 | 
			
		||||
        return $this->offsetSet($key, $value);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function get($key) {
 | 
			
		||||
        return $this->offsetGet($key);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function isDefined($key) {
 | 
			
		||||
        return $this->offsetExists($key);
 | 
			
		||||
    }
 | 
			
		||||
    /**
 | 
			
		||||
     * 
 | 
			
		||||
     * 
 | 
			
		||||
     * 
 | 
			
		||||
     *  Variable name
 | 
			
		||||
     * 
 | 
			
		||||
     * @param $var variable name or array(0 => variable name, 'filters' => filters array)
 | 
			
		||||
     * @return unknown_type
 | 
			
		||||
     */
 | 
			
		||||
    function resolve($var) {
 | 
			
		||||
 | 
			
		||||
        # if $var is array - it contains filters to apply
 | 
			
		||||
        $filters = array();
 | 
			
		||||
        if ( is_array($var) ) {
 | 
			
		||||
        	
 | 
			
		||||
            $name = array_shift($var);
 | 
			
		||||
            $filters = isset($var['filters'])? $var['filters'] : array();
 | 
			
		||||
        
 | 
			
		||||
        } 
 | 
			
		||||
        else $name = $var;
 | 
			
		||||
        
 | 
			
		||||
        $result = null;
 | 
			
		||||
	
 | 
			
		||||
        # Lookup basic types, null, boolean, numeric and string
 | 
			
		||||
        # Variable starts with : (:users.name) to short-circuit lookup
 | 
			
		||||
        if ($name[0] === ':') {
 | 
			
		||||
            $object =  $this->getVariable(substr($name, 1));
 | 
			
		||||
            if (!is_null($object)) $result = $object;
 | 
			
		||||
        } else {
 | 
			
		||||
            if ($name === 'true') {
 | 
			
		||||
                $result = true;
 | 
			
		||||
            }
 | 
			
		||||
            elseif ($name === 'false') {
 | 
			
		||||
                $result = false;
 | 
			
		||||
            } 
 | 
			
		||||
            elseif (preg_match('/^-?\d+(\.\d+)?$/', $name, $matches)) {
 | 
			
		||||
                $result = isset($matches[1])? floatval($name) : intval($name);
 | 
			
		||||
            }
 | 
			
		||||
            elseif (preg_match('/^"([^"\\\\]*(?:\\.[^"\\\\]*)*)"|' .
 | 
			
		||||
                           '\'([^\'\\\\]*(?:\\.[^\'\\\\]*)*)\'$/', $name)) {            
 | 
			
		||||
                $result = stripcslashes(substr($name, 1, -1));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        if (!empty(self::$lookupTable) && $result == Null) {
 | 
			
		||||
            $result = $this->externalLookup($name);
 | 
			
		||||
        }
 | 
			
		||||
        $result = $this->applyFilters($result,$filters);
 | 
			
		||||
        return $result;
 | 
			
		||||
    }
 | 
			
		||||
        
 | 
			
		||||
    function getVariable($name) {
 | 
			
		||||
        # Local variables. this gives as a bit of performance improvement
 | 
			
		||||
        if (!strpos($name, '.'))
 | 
			
		||||
            return $this[$name];
 | 
			
		||||
 | 
			
		||||
        # Prepare for Big lookup
 | 
			
		||||
        $parts = explode('.', $name);
 | 
			
		||||
        $object = $this[array_shift($parts)];
 | 
			
		||||
 | 
			
		||||
        # Lookup context
 | 
			
		||||
        foreach ($parts as $part) {
 | 
			
		||||
            if (is_array($object) or $object instanceof ArrayAccess) {
 | 
			
		||||
                if (isset($object[$part])) {
 | 
			
		||||
                    $object = $object[$part];
 | 
			
		||||
                } elseif ($part === 'first') {
 | 
			
		||||
                    $object = isset($object[0])?$object[0]:null;
 | 
			
		||||
                } elseif ($part === 'last') {
 | 
			
		||||
                    $last = count($object)-1;
 | 
			
		||||
                    $object = isset($object[$last])?$object[$last]:null;
 | 
			
		||||
                } elseif ($part === 'size' or $part === 'length') {
 | 
			
		||||
                    return count($object);
 | 
			
		||||
                } else {
 | 
			
		||||
                    return null;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            elseif (is_object($object)) {
 | 
			
		||||
                if (isset($object->$part))
 | 
			
		||||
                    $object = $object->$part;
 | 
			
		||||
                elseif (is_callable(array($object, $part))) {
 | 
			
		||||
                    $methodAllowed = in_array(get_class($object), $this->safeClass) || 
 | 
			
		||||
                        (isset($object->h2o_safe) && (
 | 
			
		||||
                            $object->h2o_safe === true || in_array($part, $object->h2o_safe)
 | 
			
		||||
                        )
 | 
			
		||||
                    );
 | 
			
		||||
                    $object = $methodAllowed ? $object->$part() : null;
 | 
			
		||||
                }
 | 
			
		||||
                else return null;
 | 
			
		||||
            }
 | 
			
		||||
            else return null;
 | 
			
		||||
        }
 | 
			
		||||
        return $object;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function applyFilters($object, $filters) {
 | 
			
		||||
        
 | 
			
		||||
        foreach ($filters as $filter) {
 | 
			
		||||
            $name = substr(array_shift($filter), 1);
 | 
			
		||||
            $args = $filter;
 | 
			
		||||
            
 | 
			
		||||
            if (isset(h2o::$filters[$name])) {                
 | 
			
		||||
                foreach ($args as $i => $argument) {
 | 
			
		||||
                    # name args
 | 
			
		||||
                    if (is_array($argument)) {
 | 
			
		||||
                        foreach ($argument as $n => $arg) {
 | 
			
		||||
                            $args[$i][$n] = $this->resolve($arg);
 | 
			
		||||
                        }
 | 
			
		||||
                    } else {
 | 
			
		||||
                    # resolve argument values
 | 
			
		||||
                       $args[$i] = $this->resolve($argument);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                array_unshift($args, $object);
 | 
			
		||||
                $object = call_user_func_array(h2o::$filters[$name], $args);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return $object;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function escape($value, $var) {
 | 
			
		||||
		
 | 
			
		||||
        $safe = false;
 | 
			
		||||
        $filters = (is_array($var) && isset($var['filters']))? $var['filters'] : array();
 | 
			
		||||
 | 
			
		||||
        foreach ( $filters as $filter ) {
 | 
			
		||||
        	
 | 
			
		||||
            $name = substr(array_shift($filter), 1);
 | 
			
		||||
            $safe = !$safe && ($name === 'safe');
 | 
			
		||||
        
 | 
			
		||||
            $escaped = $name === 'escape';
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        $should_escape = $this->autoescape || isset($escaped) && $escaped;
 | 
			
		||||
        
 | 
			
		||||
        if ( ($should_escape && !$safe)) {
 | 
			
		||||
            $value = htmlspecialchars($value);
 | 
			
		||||
        }		
 | 
			
		||||
        
 | 
			
		||||
        return $value;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
    function externalLookup($name) {
 | 
			
		||||
        if (!empty(self::$lookupTable)) {
 | 
			
		||||
            foreach (self::$lookupTable as $lookup) {
 | 
			
		||||
                $tmp = call_user_func_array($lookup, array($name, $this));
 | 
			
		||||
                if ($tmp !== null)
 | 
			
		||||
                return $tmp;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class BlockContext {
 | 
			
		||||
    var $h2o_safe = array('name', 'depth', 'super');
 | 
			
		||||
    var $block, $index;
 | 
			
		||||
    private $context;
 | 
			
		||||
    
 | 
			
		||||
    function __construct($block, $context, $index) {
 | 
			
		||||
        $this->block =& $block;
 | 
			
		||||
        $this->context = $context;
 | 
			
		||||
        $this->index = $index;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function name() {
 | 
			
		||||
        return $this->block->name;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function depth() {
 | 
			
		||||
        return $this->index;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function super() {
 | 
			
		||||
        $stream = new StreamWriter;
 | 
			
		||||
        $this->block->parent->render($this->context, $stream, $this->index+1);
 | 
			
		||||
        return $stream->close(); 
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    function __toString() {
 | 
			
		||||
        return "[BlockContext : {$this->block->name}, {$this->block->filename}]";
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
?>
 | 
			
		||||
							
								
								
									
										173
									
								
								system/vendor/h2o/datatype.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										173
									
								
								system/vendor/h2o/datatype.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,173 @@
 | 
			
		||||
<?php
 | 
			
		||||
class StreamWriter {
 | 
			
		||||
    var $buffer = array();
 | 
			
		||||
    var $close;
 | 
			
		||||
 | 
			
		||||
    function __construct() {
 | 
			
		||||
        $this->close = false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function write($data) {
 | 
			
		||||
        if ($this->close)
 | 
			
		||||
            new Exception('tried to write to closed stream');
 | 
			
		||||
        $this->buffer[] = $data;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function close() {
 | 
			
		||||
        $this->close = true;
 | 
			
		||||
        return implode('', $this->buffer);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class Evaluator {
 | 
			
		||||
    static function gt($l, $r) { return $l > $r; }
 | 
			
		||||
    static function ge($l, $r) { return $l >= $r; }
 | 
			
		||||
 | 
			
		||||
    static function lt($l, $r) { return $l < $r; }
 | 
			
		||||
    static function le($l, $r) { return $l <= $r; }
 | 
			
		||||
 | 
			
		||||
    static function eq($l, $r) { return $l == $r; }
 | 
			
		||||
    static function ne($l, $r) { return $l != $r; }
 | 
			
		||||
 | 
			
		||||
    static function not_($bool) { return !$bool; }
 | 
			
		||||
    static function and_($l, $r) { return ($l && $r); }
 | 
			
		||||
    static function or_($l, $r) { return ($l && $r); }
 | 
			
		||||
 | 
			
		||||
    # Currently only support single expression with no preceddence ,no boolean expression
 | 
			
		||||
    #    [expression] =  [optional binary] ? operant [ optional compare operant]
 | 
			
		||||
    #    [operant] = variable|string|numeric|boolean
 | 
			
		||||
    #    [compare] = > | < | == | >= | <=
 | 
			
		||||
    #    [binary]    = not | !
 | 
			
		||||
    static function exec($args, $context) {
 | 
			
		||||
        $argc = count($args);
 | 
			
		||||
        $first = array_shift($args);
 | 
			
		||||
        $first = $context->resolve($first);
 | 
			
		||||
        switch ($argc) {
 | 
			
		||||
            case 1 :
 | 
			
		||||
                return $first;
 | 
			
		||||
            case 2 :
 | 
			
		||||
                if (is_array($first) && isset($first['operator']) && $first['operator'] == 'not') {
 | 
			
		||||
                    $operant = array_shift($args);
 | 
			
		||||
                    $operant = $context->resolve($operant);
 | 
			
		||||
                    return !($operant);
 | 
			
		||||
                }
 | 
			
		||||
            case 3 :
 | 
			
		||||
                list($op, $right) = $args;
 | 
			
		||||
                $right = $context->resolve($right);
 | 
			
		||||
                return call_user_func(array("Evaluator", $op['operator']), $first, $right);
 | 
			
		||||
            default:
 | 
			
		||||
                return false;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * $type of token, Block | Variable
 | 
			
		||||
 */
 | 
			
		||||
class H2o_Token {
 | 
			
		||||
    function __construct ($type, $content, $position) {
 | 
			
		||||
        $this->type = $type;
 | 
			
		||||
        $this->content = $content;
 | 
			
		||||
        $this->result='';
 | 
			
		||||
        $this->position = $position;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function write($content){
 | 
			
		||||
        $this->result= $content;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * a token stream
 | 
			
		||||
 */
 | 
			
		||||
class TokenStream  {
 | 
			
		||||
    var $pushed;
 | 
			
		||||
    var $stream;
 | 
			
		||||
    var $closed;
 | 
			
		||||
    var $c;
 | 
			
		||||
 | 
			
		||||
    function __construct() {
 | 
			
		||||
        $this->pushed = array();
 | 
			
		||||
        $this->stream = array();
 | 
			
		||||
        $this->closed = false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function pop() {
 | 
			
		||||
        if (count($this->pushed))
 | 
			
		||||
        return array_pop($this->pushed);
 | 
			
		||||
        return array_pop($this->stream);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function feed($type, $contents, $position) {
 | 
			
		||||
        if ($this->closed)
 | 
			
		||||
            throw new Exception('cannot feed closed stream');
 | 
			
		||||
        $this->stream[] = new H2o_Token($type, $contents, $position);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function push($token) {
 | 
			
		||||
        if (is_null($token))
 | 
			
		||||
            throw new Exception('cannot push NULL');
 | 
			
		||||
        if ($this->closed)
 | 
			
		||||
            $this->pushed[] = $token;
 | 
			
		||||
        else
 | 
			
		||||
            $this->stream[] = $token;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function close() {
 | 
			
		||||
        if ($this->closed)
 | 
			
		||||
        new Exception('cannot close already closed stream');
 | 
			
		||||
        $this->closed = true;
 | 
			
		||||
        $this->stream = array_reverse($this->stream);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function isClosed() {
 | 
			
		||||
        return $this->closed;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function current() {
 | 
			
		||||
        return $this->c ;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function next() {
 | 
			
		||||
        return $this->c = $this->pop();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class H2o_Info {
 | 
			
		||||
    var $h2o_safe = array('filters', 'extensions', 'tags');
 | 
			
		||||
    var $name = 'H2o Template engine';
 | 
			
		||||
    var $description = "Django inspired template system";
 | 
			
		||||
    var $version = H2O_VERSION;
 | 
			
		||||
 | 
			
		||||
    function filters() {
 | 
			
		||||
        return array_keys(h2o::$filters);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    function tags() {
 | 
			
		||||
        return array_keys(h2o::$tags);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    function extensions() {
 | 
			
		||||
        return array_keys(h2o::$extensions);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Functions
 | 
			
		||||
 */
 | 
			
		||||
function sym_to_str($string) {
 | 
			
		||||
    return substr($string, 1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function is_sym($string) {
 | 
			
		||||
    return isset($string[0]) && $string[0] === ':';
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function symbol($string) {
 | 
			
		||||
    return ':'.$string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function strip_regex($regex, $delimiter = '/') {
 | 
			
		||||
    return substr($regex, 1, strrpos($regex, $delimiter)-1);
 | 
			
		||||
}
 | 
			
		||||
?>
 | 
			
		||||
							
								
								
									
										10
									
								
								system/vendor/h2o/errors.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								system/vendor/h2o/errors.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,10 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#	Errors
 | 
			
		||||
class H2o_Error extends Exception {}
 | 
			
		||||
class ParseError extends H2o_Error {}
 | 
			
		||||
class TemplateNotFound extends H2o_Error {}
 | 
			
		||||
class TemplateSyntaxError extends H2o_Error {}
 | 
			
		||||
 | 
			
		||||
?>
 | 
			
		||||
							
								
								
									
										369
									
								
								system/vendor/h2o/filters.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										369
									
								
								system/vendor/h2o/filters.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,369 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
class FilterCollection {};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class CoreFilters extends FilterCollection {
 | 
			
		||||
    static function first($value) {
 | 
			
		||||
        return $value[0];
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    static function last($value) {
 | 
			
		||||
        return $value[count($value) - 1];
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    static function join($value, $delimiter = ', ') {
 | 
			
		||||
        return join($delimiter, $value);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static function length($value) {
 | 
			
		||||
        return count($value);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    static function urlencode($data) {
 | 
			
		||||
        if (is_array($data)) {
 | 
			
		||||
            $result;
 | 
			
		||||
            foreach ($data as $name => $value) {
 | 
			
		||||
                $result .= $name.'='.urlencode($value).'&'.$querystring;
 | 
			
		||||
            }
 | 
			
		||||
            $querystring = substr($result, 0, strlen($result)-1);
 | 
			
		||||
            return htmlspecialchars($result);
 | 
			
		||||
        } else {
 | 
			
		||||
            return urlencode($data);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    static function hyphenize ($string) {
 | 
			
		||||
        $rules = array('/[^\w\s-]+/'=>'','/\s+/'=>'-', '/-{2,}/'=>'-');
 | 
			
		||||
        $string = preg_replace(array_keys($rules), $rules, trim($string));
 | 
			
		||||
        return $string = trim(strtolower($string));
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
    static function urlize( $string, $truncate = false ) {
 | 
			
		||||
        $reg_exUrl = "/(http|https|ftp|ftps)\:\/\/[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,3}(\/\S*)?/";
 | 
			
		||||
        preg_match_all($reg_exUrl, $string, $matches);
 | 
			
		||||
        $usedPatterns = array();
 | 
			
		||||
        foreach($matches[0] as $pattern){
 | 
			
		||||
            if(!array_key_exists($pattern, $usedPatterns)){
 | 
			
		||||
                $usedPatterns[$pattern]=true;
 | 
			
		||||
                $string = str_replace($pattern, "<a href=\"{$pattern}\" rel=\"nofollow\">{$pattern}</a>", $string);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $reg_exEmail = "/[a-zA-Z0-9._%-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}/";
 | 
			
		||||
        preg_match_all($reg_exEmail, $string, $matches);
 | 
			
		||||
        $usedPatterns = array();
 | 
			
		||||
        foreach($matches[0] as $pattern){
 | 
			
		||||
            if(!array_key_exists($pattern, $usedPatterns)){
 | 
			
		||||
                $usedPatterns[$pattern]=true;
 | 
			
		||||
                $string = str_replace($pattern, "<a href=\"mailto:{$pattern}\">{$pattern}</a>", $string);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return $string;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static function set_default($object, $default) {
 | 
			
		||||
        return !$object ? $default : $object;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class StringFilters extends FilterCollection {
 | 
			
		||||
 | 
			
		||||
    static function humanize($string) {
 | 
			
		||||
        $string = preg_replace('/\s+/', ' ', trim(preg_replace('/[^A-Za-z0-9()!,?$]+/', ' ', $string)));
 | 
			
		||||
        return capfirst($string);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    static function capitalize($string) {
 | 
			
		||||
        return ucwords(strtolower($string)) ;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    static function titlize($string) {
 | 
			
		||||
        return self::capitalize($string);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    static function capfirst($string) {
 | 
			
		||||
        $string = strtolower($string);
 | 
			
		||||
        return strtoupper($string{0}). substr($string, 1, strlen($string));
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    static function tighten_space($value) {
 | 
			
		||||
        return preg_replace("/\s{2,}/", ' ', $value);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    static function escape($value, $attribute = false) {
 | 
			
		||||
        return htmlspecialchars($value, $attribute ? ENT_QUOTES : ENT_NOQUOTES);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static function escapejson($value) {
 | 
			
		||||
        // The standard django escapejs converts all non-ascii characters into hex codes.
 | 
			
		||||
        // This function encodes the entire data structure, and strings get quotes around them.
 | 
			
		||||
        return json_encode($value);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    static function force_escape($value, $attribute = false) {
 | 
			
		||||
        return self::escape($value, $attribute);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    static function e($value, $attribute = false) {
 | 
			
		||||
        return self::escape($value, $attribute);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    static function safe($value) {
 | 
			
		||||
        return $value;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    static function truncate ($string, $max = 50, $ends = '...') {
 | 
			
		||||
		return (strlen($string) > $max ? substr($string, 0, $max).$ends : $string);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    static function limitwords($text, $limit = 50, $ends = '...') {
 | 
			
		||||
        if (strlen($text) > $limit) {
 | 
			
		||||
            $words = str_word_count($text, 2);
 | 
			
		||||
            $pos = array_keys($words);
 | 
			
		||||
 | 
			
		||||
            if (isset($pos[$limit])) {
 | 
			
		||||
                $text = substr($text, 0, $pos[$limit]) . $ends;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return $text;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class NumberFilters extends FilterCollection {
 | 
			
		||||
    static function filesize ($bytes, $round = 1) {
 | 
			
		||||
        if ($bytes === 0)
 | 
			
		||||
            return '0 bytes';
 | 
			
		||||
        elseif ($bytes === 1)
 | 
			
		||||
            return '1 byte';
 | 
			
		||||
    
 | 
			
		||||
        $units = array(
 | 
			
		||||
            'bytes' => pow(2, 0), 'kB' => pow(2, 10),
 | 
			
		||||
            'BM' => pow(2, 20), 'GB' => pow(2, 30),
 | 
			
		||||
            'TB' => pow(2, 40), 'PB' => pow(2, 50),
 | 
			
		||||
            'EB' => pow(2, 60), 'ZB' => pow(2, 70)
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        $lastUnit = 'bytes';
 | 
			
		||||
        foreach ($units as $unitName => $unitFactor) {
 | 
			
		||||
            if ($bytes >= $unitFactor) {
 | 
			
		||||
                $lastUnit = $unitName;
 | 
			
		||||
            } else {
 | 
			
		||||
                $number = round( $bytes / $units[$lastUnit], $round );
 | 
			
		||||
                return number_format($number) . ' ' . $lastUnit;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static function currency($amount, $currency = 'USD', $precision = 2, $negateWithParentheses = false) {
 | 
			
		||||
        $definition = array(
 | 
			
		||||
            'EUR' => array('<27>','.',','), 'GBP' => '<27>', 'JPY' => '<27>', 
 | 
			
		||||
            'USD'=>'$', 'AU' => '$', 'CAN' => '$'
 | 
			
		||||
        );
 | 
			
		||||
        $negative = false;
 | 
			
		||||
        $separator = ',';
 | 
			
		||||
        $decimals = '.';
 | 
			
		||||
        $currency = strtoupper($currency);
 | 
			
		||||
    
 | 
			
		||||
        // Is negative
 | 
			
		||||
        if (strpos('-', $amount) !== false) {
 | 
			
		||||
            $negative = true;
 | 
			
		||||
            $amount = str_replace("-","",$amount);
 | 
			
		||||
        }
 | 
			
		||||
        $amount = (float) $amount;
 | 
			
		||||
 | 
			
		||||
        if (!$negative) {
 | 
			
		||||
            $negative = $amount < 0;
 | 
			
		||||
        }
 | 
			
		||||
        if ($negateWithParentheses) {
 | 
			
		||||
            $amount = abs($amount);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Get rid of negative zero
 | 
			
		||||
        $zero = round(0, $precision);
 | 
			
		||||
        if (round($amount, $precision) === $zero) {
 | 
			
		||||
            $amount = $zero;
 | 
			
		||||
        }
 | 
			
		||||
    
 | 
			
		||||
        if (isset($definition[$currency])) {
 | 
			
		||||
            $symbol = $definition[$currency];
 | 
			
		||||
            if (is_array($symbol))
 | 
			
		||||
                @list($symbol, $separator, $decimals) = $symbol;
 | 
			
		||||
        } else {
 | 
			
		||||
            $symbol = $currency;
 | 
			
		||||
        }
 | 
			
		||||
        $amount = number_format($amount, $precision, $decimals, $separator);
 | 
			
		||||
 | 
			
		||||
        return $negateWithParentheses ? "({$symbol}{$amount})" : "{$symbol}{$amount}";
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class HtmlFilters extends FilterCollection {
 | 
			
		||||
    static function base_url($url, $options = array()) {
 | 
			
		||||
        return $url;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    static function asset_url($url, $options = array()) {
 | 
			
		||||
        return self::base_url($url, $options);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    static function image_tag($url, $options = array()) {
 | 
			
		||||
        $attr = self::htmlAttribute(array('alt','width','height','border'), $options);
 | 
			
		||||
        return sprintf('<img src="%s" %s/>', $url, $attr);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static function css_tag($url, $options = array()) {
 | 
			
		||||
        $attr = self::htmlAttribute(array('media'), $options);
 | 
			
		||||
        return sprintf('<link rel="stylesheet" href="%s" type="text/css" %s />', $url, $attr);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static function script_tag($url, $options = array()) {
 | 
			
		||||
        return sprintf('<script src="%s" type="text/javascript"></script>', $url);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    static function links_to($text, $url, $options = array()) {
 | 
			
		||||
        $attrs = self::htmlAttribute(array('ref'), $options);
 | 
			
		||||
        $url = self::base_url($url, $options);
 | 
			
		||||
        return sprintf('<a href="%s" %s>%s</a>', $url, $attrs, $text);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    static function links_with ($url, $text, $options = array()) {
 | 
			
		||||
        return self::links_to($text, $url, $options);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    static function strip_tags($text) {
 | 
			
		||||
        $text = preg_replace(array('/</', '/>/'), array(' <', '> '),$text);
 | 
			
		||||
        return strip_tags($text);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static function linebreaks($value, $format = 'p') {
 | 
			
		||||
        if ($format === 'br')
 | 
			
		||||
            return HtmlFilters::nl2br($value);
 | 
			
		||||
        return HtmlFilters::nl2pbr($value);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    static function nl2br($value) {
 | 
			
		||||
        return str_replace("\n", "<br />\n", $value);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    static function nl2pbr($value) {
 | 
			
		||||
        $result = array();
 | 
			
		||||
        $parts = preg_split('/(\r?\n){2,}/m', $value);
 | 
			
		||||
        foreach ($parts as $part) {
 | 
			
		||||
            array_push($result, '<p>' . HtmlFilters::nl2br($part) . '</p>');
 | 
			
		||||
        }
 | 
			
		||||
        return implode("\n", $result);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected static function htmlAttribute($attrs = array(), $data = array()) {
 | 
			
		||||
        $attrs = self::extract(array_merge(array('id', 'class', 'title', "style"), $attrs), $data);
 | 
			
		||||
        
 | 
			
		||||
        $result = array();
 | 
			
		||||
        foreach ($attrs as $name => $value) {
 | 
			
		||||
            $result[] = "{$name}=\"{$value}\"";
 | 
			
		||||
        }
 | 
			
		||||
        return join(' ', $result);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected static function extract($attrs = array(), $data=array()) {
 | 
			
		||||
        $result = array();
 | 
			
		||||
        if (empty($data)) return array();
 | 
			
		||||
        foreach($data as $k => $e) {
 | 
			
		||||
            if (in_array($k, $attrs)) $result[$k] = $e;
 | 
			
		||||
        }
 | 
			
		||||
        return $result;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class DatetimeFilters extends FilterCollection {
 | 
			
		||||
    static function date($time, $format = 'jS F Y H:i') {
 | 
			
		||||
        if ($time instanceof DateTime) 
 | 
			
		||||
            $time  = (int) $time->format('U');
 | 
			
		||||
        if (!is_numeric($time)) 
 | 
			
		||||
          $time = strtotime($time);
 | 
			
		||||
          
 | 
			
		||||
        return date($format, $time);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static function relative_time($timestamp, $format = 'g:iA') {
 | 
			
		||||
        if ($timestamp instanceof DateTime) 
 | 
			
		||||
            $timestamp = (int) $timestamp->format('U');
 | 
			
		||||
 | 
			
		||||
        $timestamp = is_numeric($timestamp) ? $timestamp: strtotime($timestamp);
 | 
			
		||||
        
 | 
			
		||||
        $time   = mktime(0, 0, 0);
 | 
			
		||||
        $delta  = time() - $timestamp;
 | 
			
		||||
        $string = '';
 | 
			
		||||
        
 | 
			
		||||
        if ($timestamp < $time - 86400) {
 | 
			
		||||
            return date("F j, Y, g:i a", $timestamp);
 | 
			
		||||
        }
 | 
			
		||||
        if ($delta > 86400 && $timestamp < $time) {
 | 
			
		||||
            return "Yesterday at " . date("g:i a", $timestamp);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if ($delta > 7200)
 | 
			
		||||
            $string .= floor($delta / 3600) . " hours, ";
 | 
			
		||||
        else if ($delta > 3660)
 | 
			
		||||
            $string .= "1 hour, ";
 | 
			
		||||
        else if ($delta >= 3600)
 | 
			
		||||
            $string .= "1 hour ";
 | 
			
		||||
        $delta  %= 3600;
 | 
			
		||||
        
 | 
			
		||||
        if ($delta > 60)
 | 
			
		||||
            $string .= floor($delta / 60) . " minutes ";
 | 
			
		||||
        else
 | 
			
		||||
            $string .= $delta . " seconds ";
 | 
			
		||||
        return "$string ago";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static function relative_date($time) {
 | 
			
		||||
        if ($time instanceof DateTime) 
 | 
			
		||||
            $time = (int) $time->format('U');
 | 
			
		||||
 | 
			
		||||
        $time = is_numeric($time) ? $time: strtotime($time);
 | 
			
		||||
        $today = strtotime(date('M j, Y'));
 | 
			
		||||
        $reldays = ($time - $today)/86400;
 | 
			
		||||
        
 | 
			
		||||
        if ($reldays >= 0 && $reldays < 1)
 | 
			
		||||
            return 'today';
 | 
			
		||||
        else if ($reldays >= 1 && $reldays < 2)
 | 
			
		||||
            return 'tomorrow';
 | 
			
		||||
        else if ($reldays >= -1 && $reldays < 0)
 | 
			
		||||
            return 'yesterday';
 | 
			
		||||
 | 
			
		||||
        if (abs($reldays) < 7) {
 | 
			
		||||
            if ($reldays > 0) {
 | 
			
		||||
                $reldays = floor($reldays);
 | 
			
		||||
                return 'in ' . $reldays . ' day' . ($reldays != 1 ? 's' : '');
 | 
			
		||||
            } else {
 | 
			
		||||
                $reldays = abs(floor($reldays));
 | 
			
		||||
                return $reldays . ' day'  . ($reldays != 1 ? 's' : '') . ' ago';
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        if (abs($reldays) < 182)
 | 
			
		||||
            return date('l, F j',$time ? $time : time());
 | 
			
		||||
        else
 | 
			
		||||
            return date('l, F j, Y',$time ? $time : time());
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    static function relative_datetime($time) {
 | 
			
		||||
        $date = self::relative_date($time);
 | 
			
		||||
        
 | 
			
		||||
        if ($date === 'today')
 | 
			
		||||
            return self::relative_time($time);
 | 
			
		||||
        
 | 
			
		||||
        return $date;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*  Ultizie php funciton as Filters */
 | 
			
		||||
h2o::addFilter(array('md5', 'sha1', 'numberformat'=>'number_format', 'wordwrap', 'trim', 'upper' => 'strtoupper', 'lower' => 'strtolower'));
 | 
			
		||||
 | 
			
		||||
/* Add filter collections */
 | 
			
		||||
h2o::addFilter(array('CoreFilters', 'StringFilters', 'NumberFilters', 'DatetimeFilters', 'HtmlFilters'));
 | 
			
		||||
 | 
			
		||||
/* Alias default to set_default */
 | 
			
		||||
h2o::addFilter('default', array('CoreFilters', 'set_default'));
 | 
			
		||||
 | 
			
		||||
?>
 | 
			
		||||
							
								
								
									
										290
									
								
								system/vendor/h2o/loaders.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										290
									
								
								system/vendor/h2o/loaders.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,290 @@
 | 
			
		||||
<?php
 | 
			
		||||
/**
 | 
			
		||||
 * 
 | 
			
		||||
 * @author taylor.luk
 | 
			
		||||
 * @todo FileLoader need more test coverage
 | 
			
		||||
 */
 | 
			
		||||
class H2o_Loader {
 | 
			
		||||
    public $parser;
 | 
			
		||||
    public $runtime;
 | 
			
		||||
    public $cached = false;
 | 
			
		||||
    protected $cache = false;
 | 
			
		||||
    public $searchpath = false;
 | 
			
		||||
    
 | 
			
		||||
    function read($filename) {}
 | 
			
		||||
    function cache_read($file, $object, $ttl = 3600) {}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class H2o_File_Loader extends H2o_Loader {
 | 
			
		||||
 | 
			
		||||
    function __construct($searchpath, $options = array()) {
 | 
			
		||||
        // if (is_file($searchpath)) {
 | 
			
		||||
        //     $searthpath = dirname($searchpath).DS;
 | 
			
		||||
        // }
 | 
			
		||||
        // if (!is_dir($searchpath))
 | 
			
		||||
        //     throw new TemplateNotFound($filename);
 | 
			
		||||
        //
 | 
			
		||||
        
 | 
			
		||||
        if (!is_array($searchpath))
 | 
			
		||||
             throw new Exception("searchpath must be an array");
 | 
			
		||||
        
 | 
			
		||||
        
 | 
			
		||||
		$this->searchpath = (array) $searchpath;
 | 
			
		||||
		$this->setOptions($options);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function setOptions($options = array()) {
 | 
			
		||||
        if (isset($options['cache']) && $options['cache']) {
 | 
			
		||||
            $this->cache = h2o_cache($options);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    function read($filename) {
 | 
			
		||||
                
 | 
			
		||||
        if (!is_file($filename))
 | 
			
		||||
            $filename = $this->get_template_path($this->searchpath,$filename);
 | 
			
		||||
 | 
			
		||||
        if (is_file($filename)) {
 | 
			
		||||
            $source = file_get_contents($filename);
 | 
			
		||||
            return $this->runtime->parse($source);
 | 
			
		||||
        } else {
 | 
			
		||||
            throw new TemplateNotFound($filename);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	function get_template_path($search_path, $filename){
 | 
			
		||||
 | 
			
		||||
        
 | 
			
		||||
        for ($i=0 ; $i < count($search_path) ; $i++) 
 | 
			
		||||
        { 
 | 
			
		||||
            
 | 
			
		||||
            if(file_exists($search_path[$i] . $filename)) {
 | 
			
		||||
                $filename = $search_path[$i] . $filename;
 | 
			
		||||
                return $filename;
 | 
			
		||||
                break;
 | 
			
		||||
            } else {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        throw new Exception('TemplateNotFound - Looked for template: ' . $filename);
 | 
			
		||||
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
    function read_cache($filename) {        
 | 
			
		||||
        if (!$this->cache){
 | 
			
		||||
             $filename = $this->get_template_path($this->searchpath,$filename);
 | 
			
		||||
             return $this->read($filename);
 | 
			
		||||
        }
 | 
			
		||||
            
 | 
			
		||||
        if (!is_file($filename)){
 | 
			
		||||
            $filename = $this->get_template_path($this->searchpath,$filename);
 | 
			
		||||
        }
 | 
			
		||||
            
 | 
			
		||||
        $filename = realpath($filename);
 | 
			
		||||
        
 | 
			
		||||
        $cache = md5($filename);
 | 
			
		||||
        $object = $this->cache->read($cache);
 | 
			
		||||
        $this->cached = $object && !$this->expired($object);
 | 
			
		||||
        
 | 
			
		||||
        if (!$this->cached) {
 | 
			
		||||
            $nodelist = $this->read($filename);
 | 
			
		||||
            $object = (object) array(
 | 
			
		||||
                'filename' => $filename,
 | 
			
		||||
                'content' => serialize($nodelist),
 | 
			
		||||
                'created' => time(),
 | 
			
		||||
                'templates' => $nodelist->parser->storage['templates'],
 | 
			
		||||
                'included' => $nodelist->parser->storage['included'] + array_values(h2o::$extensions)
 | 
			
		||||
            );
 | 
			
		||||
            $this->cache->write($cache, $object);
 | 
			
		||||
        } else {
 | 
			
		||||
            foreach($object->included as $ext => $file) {
 | 
			
		||||
                include_once (h2o::$extensions[$ext] = $file);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return unserialize($object->content);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function flush_cache() {
 | 
			
		||||
        $this->cache->flush();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function expired($object) {
 | 
			
		||||
        if (!$object) return false;
 | 
			
		||||
        
 | 
			
		||||
        $files = array_merge(array($object->filename), $object->templates);
 | 
			
		||||
        foreach ($files as $file) {
 | 
			
		||||
            if (!is_file($file))
 | 
			
		||||
                $file = $this->get_template_path($this->searchpath, $file);
 | 
			
		||||
            
 | 
			
		||||
            if ($object->created < filemtime($file))
 | 
			
		||||
                return true;
 | 
			
		||||
        }
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function file_loader($file) {
 | 
			
		||||
    return new H2o_File_Loader($file);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class H2o_Hash_Loader {
 | 
			
		||||
 | 
			
		||||
    function __construct($scope, $options = array()) {
 | 
			
		||||
        $this->scope = $scope;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    function setOptions() {}
 | 
			
		||||
 | 
			
		||||
    function read($file) {
 | 
			
		||||
        if (!isset($this->scope[$file]))
 | 
			
		||||
            throw new TemplateNotFound;
 | 
			
		||||
        return $this->runtime->parse($this->scope[$file], $file);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    function read_cache($file) {
 | 
			
		||||
        return $this->read($file);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function hash_loader($hash = array()) {
 | 
			
		||||
    return new H2o_Hash_Loader($hash);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Cache subsystem
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
function h2o_cache($options = array()) {
 | 
			
		||||
    $type = $options['cache'];
 | 
			
		||||
    $className = "H2o_".ucwords($type)."_Cache";
 | 
			
		||||
 | 
			
		||||
    if (class_exists($className, false)) {
 | 
			
		||||
        return new $className($options);
 | 
			
		||||
    }
 | 
			
		||||
    return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class H2o_File_Cache {
 | 
			
		||||
    var $ttl = 3600;
 | 
			
		||||
    var $prefix = 'h2o_';
 | 
			
		||||
    
 | 
			
		||||
    function __construct($options = array()) {
 | 
			
		||||
        if (isset($options['cache_dir']) && is_writable($options['cache_dir'])) {
 | 
			
		||||
            $path = $options['cache_dir'];
 | 
			
		||||
        } else {
 | 
			
		||||
            $path = dirname($tmp = tempnam(uniqid(rand(), true), ''));
 | 
			
		||||
 | 
			
		||||
            if (file_exists($tmp)) unlink($tmp);
 | 
			
		||||
        }
 | 
			
		||||
        if (isset($options['cache_ttl'])) {
 | 
			
		||||
            $this->ttl = $options['cache_ttl'];
 | 
			
		||||
        }
 | 
			
		||||
        if(isset($options['cache_prefix'])) {
 | 
			
		||||
            $this->prefix = $options['cache_prefix'];
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        $this->path = realpath($path). DS;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function read($filename) {
 | 
			
		||||
        if (!file_exists($this->path . $this->prefix. $filename))
 | 
			
		||||
            return false;
 | 
			
		||||
 | 
			
		||||
        $content = file_get_contents($this->path . $this->prefix. $filename);
 | 
			
		||||
        $expires = (int)substr($content, 0, 10);
 | 
			
		||||
 | 
			
		||||
        if (time() >= $expires) 
 | 
			
		||||
            return false;
 | 
			
		||||
        return unserialize(trim(substr($content, 10)));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function write($filename, &$object) {
 | 
			
		||||
        $expires = time() + $this->ttl;
 | 
			
		||||
        $content = $expires . serialize($object);
 | 
			
		||||
        return file_put_contents($this->path . $this->prefix. $filename, $content);   
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    function flush() {
 | 
			
		||||
        foreach (glob($this->path. $this->prefix. '*') as $file) {
 | 
			
		||||
            @unlink($file);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class H2o_Apc_Cache {
 | 
			
		||||
    var $ttl = 3600;
 | 
			
		||||
    var $prefix = 'h2o_';
 | 
			
		||||
    
 | 
			
		||||
    function __construct($options = array()) {
 | 
			
		||||
        if (!function_exists('apc_add'))
 | 
			
		||||
            throw new Exception('APC extension needs to be loaded to use APC cache');
 | 
			
		||||
            
 | 
			
		||||
        if (isset($options['cache_ttl'])) {
 | 
			
		||||
            $this->ttl = $options['cache_ttl'];
 | 
			
		||||
        } 
 | 
			
		||||
        if(isset($options['cache_prefix'])) {
 | 
			
		||||
            $this->prefix = $options['cache_prefix'];
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    function read($filename) {
 | 
			
		||||
        return apc_fetch($this->prefix.$filename);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function write($filename, $object) {
 | 
			
		||||
        return apc_store($this->prefix.$filename, $object, $this->ttl);   
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    function flush() {
 | 
			
		||||
        return apc_clear_cache('user');
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class H2o_Memcache_Cache {
 | 
			
		||||
	var $ttl	= 3600;
 | 
			
		||||
    var $prefix = 'h2o_';
 | 
			
		||||
	/**
 | 
			
		||||
	 * @var host default is file socket 
 | 
			
		||||
	 */
 | 
			
		||||
	var $host	= 'unix:///tmp/memcached.sock';
 | 
			
		||||
	var $port	= 0;
 | 
			
		||||
    var $object;
 | 
			
		||||
    function __construct( $scope, $options = array() ) {
 | 
			
		||||
    	if ( !function_exists( 'memcache_set' ) )
 | 
			
		||||
            throw new Exception( 'Memcache extension needs to be loaded to use memcache' );
 | 
			
		||||
            
 | 
			
		||||
        if ( isset( $options['cache_ttl'] ) ) {
 | 
			
		||||
            $this->ttl = $options['cache_ttl'];
 | 
			
		||||
        } 
 | 
			
		||||
        if( isset( $options['cache_prefix'] ) ) {
 | 
			
		||||
            $this->prefix = $options['cache_prefix'];
 | 
			
		||||
        }
 | 
			
		||||
		
 | 
			
		||||
		if( isset( $options['host'] ) ) {
 | 
			
		||||
            $this->host = $options['host'];
 | 
			
		||||
        }
 | 
			
		||||
		
 | 
			
		||||
		if( isset( $options['port'] ) ) {
 | 
			
		||||
            $this->port = $options['port'];
 | 
			
		||||
        }
 | 
			
		||||
		
 | 
			
		||||
        $this->object = memcache_connect( $this->host, $this->port );
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    function read( $filename ){
 | 
			
		||||
    	return memcache_get( $this->object, $this->prefix.$filename );
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    function write( $filename, $content ) {
 | 
			
		||||
    	return memcache_set( $this->object,$this->prefix.$filename,$content , MEMCACHE_COMPRESSED,$this->ttl );
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    function flush(){
 | 
			
		||||
    	return memcache_flush( $this->object );
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										84
									
								
								system/vendor/h2o/nodes.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										84
									
								
								system/vendor/h2o/nodes.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,84 @@
 | 
			
		||||
<?php
 | 
			
		||||
/*
 | 
			
		||||
		Nodes
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
class H2o_Node {
 | 
			
		||||
    var $position;
 | 
			
		||||
	function __construct($argstring) {}
 | 
			
		||||
	
 | 
			
		||||
	function render($context, $stream) {}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class NodeList extends H2o_Node implements IteratorAggregate  {
 | 
			
		||||
	var $parser;
 | 
			
		||||
	var $list;
 | 
			
		||||
	
 | 
			
		||||
	function __construct(&$parser, $initial = null, $position = 0) {
 | 
			
		||||
	    $this->parser = $parser;
 | 
			
		||||
        if (is_null($initial))
 | 
			
		||||
            $initial = array();
 | 
			
		||||
        $this->list = $initial;
 | 
			
		||||
        $this->position = $position;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	function render($context, $stream) {
 | 
			
		||||
		foreach($this->list as $node) {
 | 
			
		||||
			$node->render($context, $stream);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
    function append($node) {
 | 
			
		||||
        array_push($this->list, $node);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function extend($nodes) {
 | 
			
		||||
        array_merge($this->list, $nodes);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function getLength() {
 | 
			
		||||
        return count($this->list);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    function getIterator() {
 | 
			
		||||
        return new ArrayIterator( $this->list );
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class VariableNode extends H2o_Node {
 | 
			
		||||
    private $filters = array();
 | 
			
		||||
    var $variable;
 | 
			
		||||
    
 | 
			
		||||
	function __construct($variable, $filters, $position = 0) {
 | 
			
		||||
        if (!empty($filters))
 | 
			
		||||
            $this->filters = $filters;
 | 
			
		||||
		$this->variable = $variable;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	function render($context, $stream) {
 | 
			
		||||
        $value = $context->resolve($this->variable);
 | 
			
		||||
        $value = $context->escape($value, $this->variable);
 | 
			
		||||
        $stream->write($value);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class CommentNode extends H2o_Node {}
 | 
			
		||||
 | 
			
		||||
class TextNode extends H2o_Node {
 | 
			
		||||
    var $content;
 | 
			
		||||
	function __construct($content, $position = 0) {
 | 
			
		||||
		$this->content = $content;
 | 
			
		||||
		$this->position = $position;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	function render($context, $stream) {
 | 
			
		||||
		$stream->write($this->content);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	function is_blank() {
 | 
			
		||||
	    return strlen(trim($this->content));
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
?>
 | 
			
		||||
							
								
								
									
										290
									
								
								system/vendor/h2o/parser.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										290
									
								
								system/vendor/h2o/parser.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,290 @@
 | 
			
		||||
<?php
 | 
			
		||||
class H2o_Lexer {
 | 
			
		||||
    function __construct($options = array()) {
 | 
			
		||||
        $this->options = $options;
 | 
			
		||||
 | 
			
		||||
        $trim = '';
 | 
			
		||||
        if ($this->options['TRIM_TAGS'])
 | 
			
		||||
            $trim = '(?:\r?\n)?';
 | 
			
		||||
 | 
			
		||||
        $this->pattern = ('/\G(.*?)(?:' .
 | 
			
		||||
            preg_quote($this->options['BLOCK_START']). '(.*?)' .preg_quote($this->options['BLOCK_END']) . $trim . '|' .
 | 
			
		||||
            preg_quote($this->options['VARIABLE_START']). '(.*?)' .preg_quote($this->options['VARIABLE_END']) . '|' .
 | 
			
		||||
            preg_quote($this->options['COMMENT_START']). '(.*?)' .preg_quote($this->options['COMMENT_END']) . $trim . ')/sm'
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function tokenize($source) {
 | 
			
		||||
        $result = new TokenStream;
 | 
			
		||||
        $pos = 0;
 | 
			
		||||
        $matches = array();
 | 
			
		||||
        preg_match_all($this->pattern, $source, $matches, PREG_SET_ORDER);
 | 
			
		||||
 | 
			
		||||
        foreach ($matches as $match) {
 | 
			
		||||
            if ($match[1])
 | 
			
		||||
            $result->feed('text', $match[1], $pos);
 | 
			
		||||
            $tagpos = $pos + strlen($match[1]);
 | 
			
		||||
            if ($match[2])
 | 
			
		||||
            $result->feed('block', trim($match[2]), $tagpos);
 | 
			
		||||
            elseif ($match[3])
 | 
			
		||||
            $result->feed('variable', trim($match[3]), $tagpos);
 | 
			
		||||
            elseif ($match[4])
 | 
			
		||||
            $result->feed('comment', trim($match[4]), $tagpos);
 | 
			
		||||
            $pos += strlen($match[0]);
 | 
			
		||||
        }
 | 
			
		||||
        if ($pos < strlen($source)){
 | 
			
		||||
            $result->feed('text', substr($source, $pos), $pos);
 | 
			
		||||
        }
 | 
			
		||||
        $result->close();
 | 
			
		||||
        return $result;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class H2o_Parser {
 | 
			
		||||
    var $first;
 | 
			
		||||
    var $storage = array();
 | 
			
		||||
    var $filename;
 | 
			
		||||
    var $runtime;
 | 
			
		||||
 | 
			
		||||
    function __construct($source, $filename, $runtime, $options) {
 | 
			
		||||
        $this->options = $options;
 | 
			
		||||
        //$this->source = $source;
 | 
			
		||||
        $this->runtime = $runtime;
 | 
			
		||||
        $this->filename = $filename;
 | 
			
		||||
        $this->first = true;
 | 
			
		||||
 | 
			
		||||
        $this->lexer = new H2o_Lexer($options);
 | 
			
		||||
        $this->tokenstream = $this->lexer->tokenize($source);
 | 
			
		||||
        $this->storage = array(
 | 
			
		||||
          'blocks' => array(),
 | 
			
		||||
          'templates' => array(),
 | 
			
		||||
          'included' => array()
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function &parse() {
 | 
			
		||||
        $until = func_get_args();
 | 
			
		||||
        $nodelist = new NodeList($this);
 | 
			
		||||
        while($token = $this->tokenstream->next()) {
 | 
			
		||||
            //$token = $this->tokenstream->current();
 | 
			
		||||
            switch($token->type) {
 | 
			
		||||
                case 'text' :
 | 
			
		||||
                    $node = new TextNode($token->content, $token->position);
 | 
			
		||||
                    break;
 | 
			
		||||
                case 'variable' :
 | 
			
		||||
                    $args = H2o_Parser::parseArguments($token->content, $token->position);
 | 
			
		||||
                    $variable = array_shift($args);
 | 
			
		||||
                    $filters = $args;
 | 
			
		||||
                    $node = new VariableNode($variable, $filters, $token->position);
 | 
			
		||||
                    break;
 | 
			
		||||
                case 'comment' :
 | 
			
		||||
                    $node = new CommentNode($token->content);
 | 
			
		||||
                    break;
 | 
			
		||||
                case 'block' :
 | 
			
		||||
                    if (in_array($token->content, $until)) {
 | 
			
		||||
                        $this->token = $token;
 | 
			
		||||
                        return $nodelist;
 | 
			
		||||
                    }
 | 
			
		||||
                    $temp = preg_split('/\s+/',$token->content, 2);
 | 
			
		||||
                    $name = $temp[0];
 | 
			
		||||
                    $args = (count($temp) > 1 ? $temp[1] : null);
 | 
			
		||||
                    $node = H2o::createTag($name, $args, $this, $token->position);
 | 
			
		||||
                    $this->token = $token;
 | 
			
		||||
            }
 | 
			
		||||
            $this->searching = join(',',$until);
 | 
			
		||||
            $this->first = false;
 | 
			
		||||
            $nodelist->append($node);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if ($until) {
 | 
			
		||||
            throw new TemplateSyntaxError('Unclose tag, expecting '. $until[0]);
 | 
			
		||||
        }
 | 
			
		||||
        return $nodelist;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function skipTo($until) {
 | 
			
		||||
        $this->parse($until);
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    # Parse arguments
 | 
			
		||||
    static function parseArguments($source = null, $fpos = 0){
 | 
			
		||||
        $parser = new ArgumentLexer($source, $fpos);
 | 
			
		||||
        $result = array();
 | 
			
		||||
        $current_buffer = &$result;
 | 
			
		||||
        $filter_buffer = array();
 | 
			
		||||
        $tokens = $parser->parse();
 | 
			
		||||
        foreach ($tokens as $token) {
 | 
			
		||||
            list($token, $data) = $token;
 | 
			
		||||
            if ($token == 'filter_start') {
 | 
			
		||||
                $filter_buffer = array();
 | 
			
		||||
                $current_buffer = &$filter_buffer;
 | 
			
		||||
            }
 | 
			
		||||
            elseif ($token == 'filter_end') {
 | 
			
		||||
                if (count($filter_buffer)) {
 | 
			
		||||
 | 
			
		||||
                    $i = count($result)-1;
 | 
			
		||||
                    if ( is_array($result[$i]) ) $result[$i]['filters'][] = $filter_buffer;
 | 
			
		||||
                    else $result[$i] = array(0 => $result[$i], 'filters' => array($filter_buffer));
 | 
			
		||||
                }
 | 
			
		||||
                $current_buffer = &$result;
 | 
			
		||||
            }
 | 
			
		||||
            elseif ($token == 'boolean') {
 | 
			
		||||
                $current_buffer[] = ($data === 'true'? true : false);
 | 
			
		||||
            }
 | 
			
		||||
            elseif ($token == 'name') {
 | 
			
		||||
                $current_buffer[] = symbol($data);
 | 
			
		||||
            }
 | 
			
		||||
            elseif ($token == 'number' || $token == 'string') {
 | 
			
		||||
                $current_buffer[] = $data;
 | 
			
		||||
            }
 | 
			
		||||
            elseif ($token == 'named_argument') {
 | 
			
		||||
                $last = $current_buffer[count($current_buffer) - 1];
 | 
			
		||||
                if (!is_array($last))
 | 
			
		||||
                    $current_buffer[] = array();
 | 
			
		||||
 | 
			
		||||
                $namedArgs =& $current_buffer[count($current_buffer) - 1];
 | 
			
		||||
                list($name,$value) = array_map('trim', explode(':', $data, 2));
 | 
			
		||||
 | 
			
		||||
                # if argument value is variable mark it
 | 
			
		||||
                $value = self::parseArguments($value);
 | 
			
		||||
                $namedArgs[$name] = $value[0];
 | 
			
		||||
            }
 | 
			
		||||
            elseif( $token == 'operator') {
 | 
			
		||||
                $current_buffer[] = array('operator'=>$data);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return $result;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class H2O_RE {
 | 
			
		||||
    static $whitespace, $seperator, $parentheses, $pipe, $filter_end, $operator, $boolean, $number,  $string, $i18n_string, $name, $named_args;
 | 
			
		||||
 | 
			
		||||
    static function init() {
 | 
			
		||||
        $r = 'strip_regex';
 | 
			
		||||
 | 
			
		||||
        self::$whitespace   = '/\s+/m';
 | 
			
		||||
        self::$parentheses  = '/\(|\)/m';
 | 
			
		||||
        self::$filter_end   = '/;/';
 | 
			
		||||
        self::$boolean    = '/true|false/';
 | 
			
		||||
        self::$seperator    = '/,/';
 | 
			
		||||
        self::$pipe         = '/\|/';
 | 
			
		||||
        self::$operator     = '/\s?(>|<|>=|<=|!=|==|!|and |not |or )\s?/i';
 | 
			
		||||
        self::$number       = '/\d+(\.\d*)?/';
 | 
			
		||||
        self::$name         = '/[a-zA-Z][a-zA-Z0-9-_]*(?:\.[a-zA-Z_0-9][a-zA-Z0-9_-]*)*/';
 | 
			
		||||
 | 
			
		||||
        self::$string       = '/(?:
 | 
			
		||||
                "([^"\\\\]*(?:\\\\.[^"\\\\]*)*)" |   # Double Quote string
 | 
			
		||||
                \'([^\'\\\\]*(?:\\\\.[^\'\\\\]*)*)\' # Single Quote String
 | 
			
		||||
        )/xsm';
 | 
			
		||||
        self::$i18n_string  = "/_\({$r(self::$string)}\) | {$r(self::$string)}/xsm";
 | 
			
		||||
 | 
			
		||||
        self::$named_args   = "{
 | 
			
		||||
            ({$r(self::$name)})(?:{$r(self::$whitespace)})?
 | 
			
		||||
            :
 | 
			
		||||
            (?:{$r(self::$whitespace)})?({$r(self::$i18n_string)}|{$r(self::$number)}|{$r(self::$name)})
 | 
			
		||||
        }x";
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
H2O_RE::init();
 | 
			
		||||
 | 
			
		||||
class ArgumentLexer {
 | 
			
		||||
    private $source;
 | 
			
		||||
    private $match;
 | 
			
		||||
    private $pos = 0, $fpos, $eos;
 | 
			
		||||
    private $operator_map = array(
 | 
			
		||||
        '!' => 'not', '!='=> 'ne', '==' => 'eq', '>' => 'gt', '<' => 'lt', '<=' => 'le', '>=' => 'ge'
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    function __construct($source, $fpos = 0){
 | 
			
		||||
        if (!is_null($source))
 | 
			
		||||
          $this->source = $source;
 | 
			
		||||
        $this->fpos=$fpos;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function parse(){
 | 
			
		||||
        $result = array();
 | 
			
		||||
        $filtering = false;
 | 
			
		||||
        while (!$this->eos()) {
 | 
			
		||||
            $this->scan(H2O_RE::$whitespace);
 | 
			
		||||
            if (!$filtering) {
 | 
			
		||||
                if ($this->scan(H2O_RE::$operator)){
 | 
			
		||||
                    $operator = trim($this->match);
 | 
			
		||||
                    if(isset($this->operator_map[$operator]))
 | 
			
		||||
                        $operator = $this->operator_map[$operator];
 | 
			
		||||
                    $result[] = array('operator', $operator);
 | 
			
		||||
                }
 | 
			
		||||
                elseif ($this->scan(H2O_RE::$boolean))
 | 
			
		||||
                    $result[] = array('boolean', $this->match);
 | 
			
		||||
                elseif ($this->scan(H2O_RE::$named_args))
 | 
			
		||||
                    $result[] = array('named_argument', $this->match);
 | 
			
		||||
                elseif ($this->scan(H2O_RE::$name))
 | 
			
		||||
                    $result[] = array('name', $this->match);
 | 
			
		||||
                elseif ($this->scan(H2O_RE::$pipe)) {
 | 
			
		||||
                    $filtering = true;
 | 
			
		||||
                    $result[] = array('filter_start', $this->match);
 | 
			
		||||
                }
 | 
			
		||||
                elseif ($this->scan(H2O_RE::$seperator))
 | 
			
		||||
                    $result[] = array('separator', null);
 | 
			
		||||
                elseif ($this->scan(H2O_RE::$i18n_string))
 | 
			
		||||
                    $result[] = array('string', $this->match);
 | 
			
		||||
                elseif ($this->scan(H2O_RE::$number))
 | 
			
		||||
                    $result[] = array('number', $this->match);
 | 
			
		||||
                else
 | 
			
		||||
                    throw new TemplateSyntaxError('unexpected character in filters : "'. $this->source[$this->pos]. '" at '.$this->getPosition());
 | 
			
		||||
            }
 | 
			
		||||
            else {
 | 
			
		||||
                // parse filters, with chaining and ";" as filter end character
 | 
			
		||||
                if ($this->scan(H2O_RE::$pipe)) {
 | 
			
		||||
                    $result[] = array('filter_end', null);
 | 
			
		||||
                    $result[] = array('filter_start', null);
 | 
			
		||||
                }
 | 
			
		||||
                elseif ($this->scan(H2O_RE::$seperator))
 | 
			
		||||
                    $result[] = array('separator', null);
 | 
			
		||||
                elseif ($this->scan(H2O_RE::$filter_end)) {
 | 
			
		||||
                    $result[] = array('filter_end', null);
 | 
			
		||||
                    $filtering = false;
 | 
			
		||||
                }
 | 
			
		||||
                elseif ($this->scan(H2O_RE::$boolean))
 | 
			
		||||
                    $result[] = array('boolean', $this->match);
 | 
			
		||||
                elseif ($this->scan(H2O_RE::$named_args))
 | 
			
		||||
                    $result[] = array('named_argument', $this->match);
 | 
			
		||||
                elseif ($this->scan(H2O_RE::$name))
 | 
			
		||||
                    $result[] = array('name', $this->match);
 | 
			
		||||
                elseif ($this->scan(H2O_RE::$i18n_string))
 | 
			
		||||
                    $result[] = array('string', $this->match);
 | 
			
		||||
                elseif ($this->scan(H2O_RE::$number))
 | 
			
		||||
                    $result[] = array('number', $this->match);
 | 
			
		||||
                else
 | 
			
		||||
                    throw new TemplateSyntaxError('unexpected character in filters : "'. $this->source[$this->pos]. '" at '.$this->getPosition());
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        // if we are still in the filter state, we add a filter_end token.
 | 
			
		||||
        if ($filtering)
 | 
			
		||||
            $result[] = array('filter_end', null);
 | 
			
		||||
        return $result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    # String scanner
 | 
			
		||||
    function scan($regexp) {
 | 
			
		||||
        if (preg_match($regexp . 'A', $this->source, $match, null, $this->pos)) {
 | 
			
		||||
            $this->match = $match[0];
 | 
			
		||||
            $this->pos += strlen($this->match);
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function eos() {
 | 
			
		||||
        return $this->pos >= strlen($this->source);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * return the position in the template
 | 
			
		||||
     */
 | 
			
		||||
    function getPosition() {
 | 
			
		||||
        return $this->fpos + $this->pos;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
?>
 | 
			
		||||
							
								
								
									
										483
									
								
								system/vendor/h2o/tags.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										483
									
								
								system/vendor/h2o/tags.php
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,483 @@
 | 
			
		||||
<?php
 | 
			
		||||
/**
 | 
			
		||||
 *
 | 
			
		||||
 * @author taylor.luk
 | 
			
		||||
 * @todo tags need more test coverage
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * ifchanged tag
 | 
			
		||||
 *
 | 
			
		||||
 * Usage:
 | 
			
		||||
 *
 | 
			
		||||
 * Variable mode
 | 
			
		||||
 * {% ifchanged data.date %}...{% endifchanged %}
 | 
			
		||||
 *
 | 
			
		||||
 * Lazy mode *not implemented in h2o yet
 | 
			
		||||
 * {% ifchanged %}...{{ data.date }}...{% endifchanged %}
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
class IfChanged_Tag extends H2o_Node {
 | 
			
		||||
    private $nodelist_true;
 | 
			
		||||
    private $nodelist_false;
 | 
			
		||||
    private $_varlist = null;
 | 
			
		||||
    private $_last_seen = null;
 | 
			
		||||
 | 
			
		||||
    function __construct($argstring, $parser, $position = 0) {
 | 
			
		||||
        $this->nodelist_true = $parser->parse('endifchanged', 'else');
 | 
			
		||||
 | 
			
		||||
        if ($parser->token->content === 'else')
 | 
			
		||||
            $this->nodelist_false = $parser->parse('endifchanged');
 | 
			
		||||
 | 
			
		||||
        $this->_varlist = current(H2o_Parser::parseArguments($argstring));
 | 
			
		||||
 | 
			
		||||
        if (!$this->_varlist)
 | 
			
		||||
            throw new TemplateSyntaxError('H2o doesn\'t support lazy ifchanged yet. Please, supply a variable.');
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function render($context, $stream) {
 | 
			
		||||
 | 
			
		||||
        if ($this->_varlist) {
 | 
			
		||||
            $compare_to = $context->resolve($this->_varlist);
 | 
			
		||||
        } else {
 | 
			
		||||
            /**
 | 
			
		||||
             * @todo Rendering method $this->nodelist_true->render() should return a result.
 | 
			
		||||
             * Further more $compare_to variable should be set to this result.
 | 
			
		||||
             */
 | 
			
		||||
            $compare_to = '';
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if ($compare_to != $this->_last_seen) {
 | 
			
		||||
            $this->_last_seen = $compare_to;
 | 
			
		||||
            $this->nodelist_true->render($context, $stream);
 | 
			
		||||
        } elseif ($this->nodelist_false) {
 | 
			
		||||
            $this->nodelist_false->render($context, $stream);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class If_Tag extends H2o_Node {
 | 
			
		||||
    private $body;
 | 
			
		||||
    private $else;
 | 
			
		||||
    private $negate;
 | 
			
		||||
 | 
			
		||||
    function __construct($argstring, $parser, $position = 0) {
 | 
			
		||||
        if (preg_match('/\s(and|or)\s/', $argstring))
 | 
			
		||||
            throw new TemplateSyntaxError('H2o doesn\'t support multiple expressions');
 | 
			
		||||
 | 
			
		||||
        $this->body = $parser->parse('endif', 'else');
 | 
			
		||||
 | 
			
		||||
        if ($parser->token->content === 'else')
 | 
			
		||||
            $this->else = $parser->parse('endif');
 | 
			
		||||
 | 
			
		||||
        $this->args = H2o_Parser::parseArguments($argstring);
 | 
			
		||||
 | 
			
		||||
        $first = current($this->args);
 | 
			
		||||
        if (isset($first['operator']) && $first['operator'] === 'not') {
 | 
			
		||||
            array_shift($this->args);
 | 
			
		||||
            $this->negate = true;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function render($context, $stream) {
 | 
			
		||||
        if ($this->test($context))
 | 
			
		||||
            $this->body->render($context, $stream);
 | 
			
		||||
        elseif ($this->else)
 | 
			
		||||
            $this->else->render($context, $stream);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function test($context) {
 | 
			
		||||
        $test = Evaluator::exec($this->args, $context);
 | 
			
		||||
        return $this->negate? !$test : $test;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class For_Tag extends H2o_Node {
 | 
			
		||||
    public $position;
 | 
			
		||||
    private $iteratable, $key, $item, $body, $else, $limit, $reversed;
 | 
			
		||||
    private $syntax = '{
 | 
			
		||||
        ([a-zA-Z][a-zA-Z0-9-_]*)(?:,\s?([a-zA-Z][a-zA-Z0-9-_]*))?
 | 
			
		||||
        \s+in\s+
 | 
			
		||||
        ([a-zA-Z][a-zA-Z0-9-_]*(?:\.[a-zA-Z_0-9][a-zA-Z0-9_-]*)*)\s*   # Iteratable name
 | 
			
		||||
        (?:limit\s*:\s*(\d+))?\s*
 | 
			
		||||
        (reversed)?                                                     # Reverse keyword
 | 
			
		||||
    }x';
 | 
			
		||||
 | 
			
		||||
    function __construct($argstring, $parser, $position) {
 | 
			
		||||
        if (!preg_match($this->syntax, $argstring, $match))
 | 
			
		||||
            throw new TemplateSyntaxError("Invalid for loop syntax ");
 | 
			
		||||
 | 
			
		||||
        $this->body = $parser->parse('endfor', 'else');
 | 
			
		||||
 | 
			
		||||
        if ($parser->token->content === 'else')
 | 
			
		||||
            $this->else = $parser->parse('endfor');
 | 
			
		||||
 | 
			
		||||
        $match = array_pad($match, 6, '');
 | 
			
		||||
        list(,$this->key, $this->item, $this->iteratable, $this->limit, $this->reversed) = $match;
 | 
			
		||||
 | 
			
		||||
        if ($this->limit)
 | 
			
		||||
            $this->limit = (int) $this->limit;
 | 
			
		||||
 | 
			
		||||
        # Swap value if no key found
 | 
			
		||||
        if (!$this->item) {
 | 
			
		||||
            list($this->key, $this->item) = array($this->item, $this->key);
 | 
			
		||||
        }
 | 
			
		||||
        $this->iteratable = symbol($this->iteratable);
 | 
			
		||||
        $this->reversed = (bool) $this->reversed;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function render($context, $stream) {
 | 
			
		||||
        $iteratable = $context->resolve($this->iteratable);
 | 
			
		||||
 | 
			
		||||
        if ($this->reversed)
 | 
			
		||||
            $iteratable = array_reverse($iteratable);
 | 
			
		||||
 | 
			
		||||
        if ($this->limit)
 | 
			
		||||
            $iteratable = array_slice($iteratable, 0, $this->limit);
 | 
			
		||||
 | 
			
		||||
        $length = count($iteratable);
 | 
			
		||||
 | 
			
		||||
        if ($length) {
 | 
			
		||||
            $parent = $context['loop'];
 | 
			
		||||
            $context->push();
 | 
			
		||||
            $rev_count = $is_even = $idx = 0;
 | 
			
		||||
            foreach($iteratable as $key => $value) {
 | 
			
		||||
                $is_even =  $idx % 2;
 | 
			
		||||
                $rev_count = $length - $idx;
 | 
			
		||||
 | 
			
		||||
                if ($this->key) {
 | 
			
		||||
                    $context[$this->key] = $key;
 | 
			
		||||
                }
 | 
			
		||||
                $context[$this->item] =  $value;
 | 
			
		||||
                $context['loop'] = array(
 | 
			
		||||
                    'parent' => $parent,
 | 
			
		||||
                    'first' => $idx === 0,
 | 
			
		||||
                    'last'  => $rev_count === 1,
 | 
			
		||||
                    'odd'   => !$is_even,
 | 
			
		||||
                    'even'  => $is_even,
 | 
			
		||||
                    'length' => $length,
 | 
			
		||||
                    'counter' => $idx + 1,
 | 
			
		||||
                    'counter0' => $idx,
 | 
			
		||||
                    'revcounter' => $rev_count,
 | 
			
		||||
                    'revcounter0' => $rev_count - 1
 | 
			
		||||
                );
 | 
			
		||||
                $this->body->render($context, $stream);
 | 
			
		||||
                ++$idx;
 | 
			
		||||
            }
 | 
			
		||||
            $context->pop();
 | 
			
		||||
        } elseif ($this->else)
 | 
			
		||||
            $this->else->render($context, $stream);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class Block_Tag extends H2o_Node {
 | 
			
		||||
    public $name;
 | 
			
		||||
    public $position;
 | 
			
		||||
    public $stack;
 | 
			
		||||
    private $syntax = '/^[a-zA-Z_][a-zA-Z0-9_-]*$/';
 | 
			
		||||
 | 
			
		||||
    function __construct($argstring, $parser, $position) {
 | 
			
		||||
        if (!preg_match($this->syntax, $argstring))
 | 
			
		||||
            throw new TemplateSyntaxError('Block tag expects a name, example: block [content]');
 | 
			
		||||
 | 
			
		||||
        $this->name = $argstring;
 | 
			
		||||
 | 
			
		||||
        if (isset($parser->storage['blocks'][$this->name]))
 | 
			
		||||
            throw new TemplateSyntaxError('Block name exists, Please select a different block name');
 | 
			
		||||
 | 
			
		||||
        $this->filename = $parser->filename;
 | 
			
		||||
        $this->stack = array($parser->parse('endblock', "endblock {$this->name}"));
 | 
			
		||||
 | 
			
		||||
        $parser->storage['blocks'][$this->name] = $this;
 | 
			
		||||
        $this->position = $position;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function addLayer(&$nodelist) {
 | 
			
		||||
        $nodelist->parent = $this;
 | 
			
		||||
        array_push($this->stack, $nodelist);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function render($context, $stream, $index = 1) {
 | 
			
		||||
        $key = count($this->stack) - $index;
 | 
			
		||||
 | 
			
		||||
        if (isset($this->stack[$key])) {
 | 
			
		||||
            $context->push();
 | 
			
		||||
            $context['block'] = new BlockContext($this, $context, $index);
 | 
			
		||||
            $this->stack[$key]->render($context, $stream);
 | 
			
		||||
            $context->pop();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class Extends_Tag extends H2o_Node {
 | 
			
		||||
    public $filename;
 | 
			
		||||
    public $position;
 | 
			
		||||
    public $nodelist;
 | 
			
		||||
    private $syntax = '/^["\'](.*?)["\']$/';
 | 
			
		||||
 | 
			
		||||
    function __construct($argstring, $parser, $position = 0) {
 | 
			
		||||
      if (!$parser->first)
 | 
			
		||||
            throw new TemplateSyntaxError('extends must be first in file');
 | 
			
		||||
 | 
			
		||||
      if (!preg_match($this->syntax, $argstring))
 | 
			
		||||
            throw new TemplatesyntaxError('filename must be quoted');
 | 
			
		||||
 | 
			
		||||
        $this->filename = stripcslashes(substr($argstring, 1, -1));
 | 
			
		||||
 | 
			
		||||
        # Parse the current template
 | 
			
		||||
        $parser->parse();
 | 
			
		||||
 | 
			
		||||
        # Parse parent template
 | 
			
		||||
        $this->nodelist = $parser->runtime->loadSubTemplate($this->filename, $parser->options);
 | 
			
		||||
        $parser->storage['templates'] = array_merge(
 | 
			
		||||
            $parser->storage['templates'], $this->nodelist->parser->storage['templates']
 | 
			
		||||
        );
 | 
			
		||||
        $parser->storage['templates'][] = $this->filename;
 | 
			
		||||
 | 
			
		||||
        if (!isset($this->nodelist->parser->storage['blocks']) || !isset($parser->storage['blocks']))
 | 
			
		||||
            return ;
 | 
			
		||||
 | 
			
		||||
        # Blocks of parent template
 | 
			
		||||
        $blocks =& $this->nodelist->parser->storage['blocks'];
 | 
			
		||||
 | 
			
		||||
        # Push child blocks on top of parent blocks
 | 
			
		||||
        foreach($parser->storage['blocks'] as $name => &$block) {
 | 
			
		||||
            if (isset($blocks[$name])) {
 | 
			
		||||
                $blocks[$name]->addLayer($block);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function render($context, $stream) {
 | 
			
		||||
        $this->nodelist->render($context, $stream);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * include tag
 | 
			
		||||
 *
 | 
			
		||||
 * Usage:
 | 
			
		||||
 *
 | 
			
		||||
 * Simple inclusion
 | 
			
		||||
 *     {% include "./subtemplate.html" %}
 | 
			
		||||
 *
 | 
			
		||||
 *
 | 
			
		||||
 * Inclusion with additional context variables passing:
 | 
			
		||||
 *     {% include "./subtemplate.html" with foo=bar spam="eggs" %}
 | 
			
		||||
 *
 | 
			
		||||
 * Note: Double quotes matter. In this example 'foo' template variable of subtemplate.html
 | 
			
		||||
 * would be initialized with 'bar' variable contents (from main template context),
 | 
			
		||||
 * while 'spam' template variable of subtemplate.html would be set to simple string ('eggs').
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
class Include_Tag extends H2o_Node {
 | 
			
		||||
    private $nodelist;
 | 
			
		||||
    private $syntax = '/^["\'](.*?)["\'](\s+with\s+(.+))?$/';
 | 
			
		||||
    private $_additional_context = array();
 | 
			
		||||
 | 
			
		||||
    function __construct($argstring, $parser, $position = 0) {
 | 
			
		||||
        if (!preg_match($this->syntax, $argstring, $matches)) {
 | 
			
		||||
            throw new TemplateSyntaxError();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $matches_count = count($matches);
 | 
			
		||||
 | 
			
		||||
        if ($matches_count > 2) {
 | 
			
		||||
            // "with" statement supplied.
 | 
			
		||||
            $with_vars = explode(' ', $matches[3]);
 | 
			
		||||
            foreach ($with_vars as $var_str) {
 | 
			
		||||
                $eq_pos = strpos($var_str, '=');
 | 
			
		||||
                $this->_additional_context[substr($var_str, 0, $eq_pos)] = substr($var_str, $eq_pos+1);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $this->filename = stripcslashes($matches[1]);
 | 
			
		||||
        $this->nodelist = $parser->runtime->loadSubTemplate($this->filename, $parser->options);
 | 
			
		||||
        $parser->storage['templates'] = array_merge(
 | 
			
		||||
            $this->nodelist->parser->storage['templates'], $parser->storage['templates']
 | 
			
		||||
        );
 | 
			
		||||
        $parser->storage['templates'][] = $this->filename;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function render($context, $stream) {
 | 
			
		||||
        foreach ($this->_additional_context as $key => $value) {
 | 
			
		||||
            if (strpos($value, '"') === false) {
 | 
			
		||||
                // Context variable supplied as value. Needs to be resolved.
 | 
			
		||||
                $value = $context->getVariable($value);
 | 
			
		||||
            } else {
 | 
			
		||||
                $value = trim($value, '"');
 | 
			
		||||
            }
 | 
			
		||||
            $context[$key] = $value;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $this->nodelist->render($context, $stream);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class With_Tag extends H2o_Node {
 | 
			
		||||
    public $position;
 | 
			
		||||
    private $variable, $shortcut;
 | 
			
		||||
    private $nodelist;
 | 
			
		||||
    private $syntax = '/^([\w]+(:?\.[\w\d]+)*)\s+as\s+([\w]+(:?\.[\w\d]+)?)$/';
 | 
			
		||||
 | 
			
		||||
    function __construct($argstring, $parser, $position = 0) {
 | 
			
		||||
        if (!preg_match($this->syntax, $argstring, $matches))
 | 
			
		||||
            throw new TemplateSyntaxError('Invalid with tag syntax');
 | 
			
		||||
 | 
			
		||||
        # extract the long name and shortcut
 | 
			
		||||
        list(,$this->variable, ,$this->shortcut) = $matches;
 | 
			
		||||
        $this->nodelist = $parser->parse('endwith');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function render($context, $stream) {
 | 
			
		||||
        $variable = $context->getVariable($this->variable);
 | 
			
		||||
 | 
			
		||||
        $context->push(array($this->shortcut => $variable));
 | 
			
		||||
        $this->nodelist->render($context, $stream);
 | 
			
		||||
        $context->pop();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class Cycle_Tag extends H2o_Node {
 | 
			
		||||
    private $uid;
 | 
			
		||||
    private $sequence;
 | 
			
		||||
 | 
			
		||||
    function __construct($argstring, $parser, $pos) {
 | 
			
		||||
        $args = h2o_parser::parseArguments($argstring);
 | 
			
		||||
 | 
			
		||||
        if (count($args) < 2) {
 | 
			
		||||
            throw new Exception('Cycle tag require more than two items');
 | 
			
		||||
        }
 | 
			
		||||
        $this->sequence = $args;
 | 
			
		||||
        $this->uid = '__cycle__'.$pos;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function render($context, $stream) {
 | 
			
		||||
        if (!is_null($item = $context->getVariable($this->uid))) {
 | 
			
		||||
            $item = ($item + 1) % count($this->sequence);
 | 
			
		||||
        } else {
 | 
			
		||||
            $item = 0;
 | 
			
		||||
        }
 | 
			
		||||
        $stream->write($context->resolve($this->sequence[$item]));
 | 
			
		||||
        $context->set($this->uid, $item);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class Load_Tag extends H2o_Node {
 | 
			
		||||
    public $position;
 | 
			
		||||
    private $searchpath = array(H2O_ROOT);
 | 
			
		||||
    private $extension;
 | 
			
		||||
 | 
			
		||||
    function __construct($argstring, $parser, $pos = 0) {
 | 
			
		||||
        $this->extension = stripcslashes(preg_replace("/^[\"'](.*)[\"']$/", "$1", $argstring));
 | 
			
		||||
 | 
			
		||||
        if ($parser->runtime->searchpath)
 | 
			
		||||
            $this->appendPath($parser->runtime->searchpath);
 | 
			
		||||
 | 
			
		||||
        $parser->storage['included'][$this->extension] = $file = $this->load();
 | 
			
		||||
        $this->position = $pos;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function render($context, $stream) {
 | 
			
		||||
        $this->load();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function appendPath($path) {
 | 
			
		||||
        $this->searchpath[] = $path;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private function load() {
 | 
			
		||||
        if (isset(h2o::$extensions[$this->extension])) {
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
        foreach($this->searchpath as $path) {
 | 
			
		||||
            $file = $path.'ext'.DS.$this->extension.'.php';
 | 
			
		||||
            if (is_file($file)) {
 | 
			
		||||
                h2o::load($this->extension, $file);
 | 
			
		||||
                return $file;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        throw new H2o_Error(
 | 
			
		||||
            "Extension: {$this->extension} cannot be loaded, please confirm it exist in extension path"
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class Debug_Tag extends H2o_Node {
 | 
			
		||||
    private $argument;
 | 
			
		||||
    function __construct($argstring, $parser, $pos = 0) {
 | 
			
		||||
        $this->argument = $argstring;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function render($context, $stream) {
 | 
			
		||||
        if ($this->argument) {
 | 
			
		||||
            $object = $context->resolve(symbol($this->argument));
 | 
			
		||||
        } else {
 | 
			
		||||
            $object = $context->scopes[0];
 | 
			
		||||
        }
 | 
			
		||||
        $output = "<pre>" . htmlspecialchars( print_r($object, true) ) . "</pre>";
 | 
			
		||||
        $stream->write($output);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class Comment_Tag extends H2o_Node {
 | 
			
		||||
    function __construct($argstring, $parser, $position) {
 | 
			
		||||
        $parser->parse('endcomment');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function render($context, $stream, $index = 1) {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class Now_Tag extends H2o_Node {
 | 
			
		||||
    function __construct($argstring, $parser, $pos=0) {
 | 
			
		||||
        $this->format = $argstring;
 | 
			
		||||
        if (!$this->format) {
 | 
			
		||||
            $this->format = "D M j G:i:s T Y";
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function render($contxt, $stream) {
 | 
			
		||||
        $time = date($this->format);
 | 
			
		||||
        $stream->write($time);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class Autoescape_Tag extends H2o_Node {
 | 
			
		||||
    protected $enable;
 | 
			
		||||
 | 
			
		||||
    function __construct($argstring, $parser, $pos = 0) {
 | 
			
		||||
        if ($argstring === 'on')
 | 
			
		||||
            $this->enable = true;
 | 
			
		||||
        elseif ($argstring === 'off')
 | 
			
		||||
            $this->enable = false;
 | 
			
		||||
        else throw new H2o_Error(
 | 
			
		||||
            "Invalid syntax : autoescape on|off "
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function render($context, $stream) {
 | 
			
		||||
        $context->autoescape = $this->enable;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class Csrf_token_Tag extends H2o_Node {
 | 
			
		||||
    function render($context, $stream) {
 | 
			
		||||
        $token = "";
 | 
			
		||||
        if (isset($_COOKIE["csrftoken"]))
 | 
			
		||||
            $token = $_COOKIE["csrftoken"];
 | 
			
		||||
        else {
 | 
			
		||||
            global $SECRET_KEY;
 | 
			
		||||
            if (defined('SECRET_KEY'))
 | 
			
		||||
                $token = md5(mt_rand() . SECRET_KEY);
 | 
			
		||||
            else
 | 
			
		||||
                $token = md5(mt_rand());
 | 
			
		||||
        }
 | 
			
		||||
        setcookie("csrftoken", $token, time()+60*60*24*365, "/");
 | 
			
		||||
        $stream->write("<div style='display:none'><input type=\"hidden\" value=\"$token\" name=\"csrfmiddlewaretoken\" /></div>");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
H2o::addTag(array('block', 'extends', 'include', 'if', 'ifchanged', 'for', 'with', 'cycle', 'load', 'debug', 'comment', 'now', 'autoescape', 'csrf_token'));
 | 
			
		||||
		Reference in New Issue
	
	Block a user