Adding template engine
Adding error handling Adding basic SMTP class core routing is working
This commit is contained in:
		
							
								
								
									
										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