'file')); * * * $h2o = new H2O('template.html', array("loader"=>'hash')); */ class H2o { public $searchpath; public $context; public $loader = false; static $tags = array(); static $filters = array(); static $extensions = array(); static public function getOptions($options = array()) { global $base_path; global $cms_active, $cms_cache_ttl; return array_merge(array( 'loader' => 'file', 'cache' => 'file', // file | apc | memcache 'cache_dir' => $base_path.'/temp', 'cache_prefix' => 'h2o_', 'cache_ttl' => ($cms_active ? $cms_cache_ttl : 3600), // file | apc | memcache 'searchpath' => false, 'autoescape' => false, // Enviroment setting 'BLOCK_START' => '{%', 'BLOCK_END' => '%}', 'VARIABLE_START' => '{{', 'VARIABLE_END' => '}}', 'COMMENT_START' => '{*', 'COMMENT_END' => '*}', 'TRIM_TAGS' => true ), $options); } public function __construct($file = null, $options = array()) { # Init a environment $this->options = $this->getOptions($options); $loader = $this->options['loader']; if (!$loader) return true; if (is_object($loader)) { $this->loader = $loader; $this->loader->setOptions($this->options); } else { $loader = "H2o_{$loader}_Loader"; if (!class_exists($loader, false)) throw new Exception('Invalid template loader'); if (isset($options['searchpath'])){ $this->searchpath = $options['searchpath']; } else if ($file) { $this->searchpath = dirname(realpath($file)).DS; } else { $this->searchpath = getcwd().DS; } $loader_searchpath = is_array($this->searchpath) ? $this->searchpath : array($this->searchpath); $this->loader = new $loader($loader_searchpath, $this->options); } $this->loader->runtime = $this; if (isset($options['i18n'])) { h2o::load('i18n'); $this->i18n = new H2o_I18n($this->searchpath, $options['i18n']); } if ($file) { $this->nodelist = $this->loadTemplate($file); } } public function loadTemplate($file) { return $this->nodelist = $this->loader->read_cache($file); } public function loadSubTemplate($file) { return $this->loader->read($file); } # Build a finalized nodelist from template ready to be cached public function parse($source, $filename = '', $env = null) { if (!$env) $env = $this->options; if (!class_exists('H2o_Parser', false)) require H2O_ROOT.'h2o/parser.php'; $parser = new H2o_Parser($source, $filename, $this, $env); $nodelist = $parser->parse(); return $nodelist; } public function set($context, $value = null) { # replace with new context object if (is_object($context) && $context instanceof H2o_Context) { return $this->context = $context; } # Init context if (!$this->context) { $this->context = new H2o_Context($this->defaultContext(), $this->options); } # Extend or set value if (is_array($context)) { return $this->context->extend($context); } elseif (is_string($context)) { return $this->context[$context] = $value; } return false; } # Render the nodelist public function render($context = array()) { $this->set($context); $this->stream = new StreamWriter; $this->nodelist->render($this->context, $this->stream); return $this->stream->close(); } static public function parseString($source, $options = array()) { $instance = new H2o(null, array_merge($options, array('loader' => false))); $instance->nodelist = $instance->parse($source); return $instance; } static public function &createTag($tag, $args = null, $parser, $position = 0) { if (!isset(self::$tags[$tag])) { throw new H2o_Error($tag . " tag doesn't exist"); } $tagClass = self::$tags[$tag]; $tag = new $tagClass($args, $parser, $position); return $tag; } /** * Register a new tag * * * h2o::addTag('tag_name', 'ClassName'); * * h2o::addTag(array( * 'tag_name' => 'MagClass', * 'tag_name2' => 'TagClass2' * )); * * h2o::addTag('tag_name'); // Tag_name_Tag * * h2o::addTag(array('tag_name', * @param unknown_type $tag * @param unknown_type $class */ static public function addTag($tag, $class = null) { $tags = array(); if (is_string($tag)) { if (is_null($class)) $class = ucwords("{$tag}_Tag"); $tags[$tag] = $class; } elseif (is_array($tag)) { $tags = $tag; } foreach ($tags as $tag => $tagClass) { if (is_integer($tag)) { unset($tags[$tag]); $tag = $tagClass; $tagClass = ucwords("{$tagClass}_Tag"); } if (!class_exists($tagClass, false)) { throw new H2o_Error("{$tagClass} tag is not found"); } $tags[$tag] = $tagClass; } self::$tags = array_merge(self::$tags, $tags); } /** * Register a new filter to h2o runtime * * @param unknown_type $filter * @param unknown_type $callback * @return unknown */ static public function addFilter($filter, $callback = null) { if (is_array($filter)) { $filters = $filter; foreach($filters as $key => $filter) { if (is_numeric($key)) $key = $filter; self::addFilter($key, $filter); } return true; } elseif (is_string($filter) && class_exists($filter, false) && is_subclass_of($filter, 'FilterCollection')) { foreach (get_class_methods($filter) as $f) { if (is_callable(array($filter, $f))) self::$filters[$f] = array($filter, $f); } return true; } if (is_null($callback)) $callback = $filter; if (!is_callable($callback)) { return false; } self::$filters[$filter] = $callback; } static public function addLookup($callback) { if (is_callable($callback)) { H2o_Context::$lookupTable[] = $callback; } else die('damm it'); } static public function load($extension, $file = null) { if (!$file) { $file = H2O_ROOT.'ext'.DS.$extension.'.php'; } if (is_file($file)) { include_once ($file); self::$extensions[$extension] = $file; } } public function defaultContext() { return array('h2o' => new H2o_Info); } static public function getFilenameWithGlobal($filename) { $varGlobal = ''; $tempNeedle = ''; $needles = ["{{ global.", "{{global."]; foreach ($needles as $needle){ $haystack = $filename; $nb_occurence = substr_count($haystack, $needle); for ($i = 0; $i < $nb_occurence; $i++){ $firstChar = strpos($haystack,$needle); $lastChar = strpos($haystack,'}}', $firstChar)+2; $length = $lastChar-$firstChar; $tempNeedle = substr($haystack, $firstChar, $length); $varGlobal = trim(substr($haystack, $firstChar+strlen($needle), $length-strlen($needle)-2)); global ${$varGlobal}; if (!empty(${$varGlobal})){ $filename = str_replace($tempNeedle, ${$varGlobal}, $filename); } $haystack = substr($haystack, $lastChar); } } return $filename; } } /** * Convenient wrapper for loading template file or string * @param $name * @param $options - H2o options * @return Instance of H2o Template */ function h2o($name, $options = array()) { $is_file = '/([^\s]*?)(\.[^.\s]*$)/'; if (!preg_match($is_file, $name)) { return H2o::parseString($name, $options); } $instance = new H2o($name, $options); return $instance; } ?>