<?php
define(
'H2O_VERSION'
,
'0.3'
);
defined(
'DS'
)
or
define(
'DS'
, DIRECTORY_SEPARATOR);
defined(
'H2O_ROOT'
)
or
define(
'H2O_ROOT'
, dirname(
__FILE__
) . DS);
require
H2O_ROOT.
'h2o/datatype.php'
;
require
H2O_ROOT.
'h2o/loaders.php'
;
require
H2O_ROOT.
'h2o/nodes.php'
;
require
H2O_ROOT.
'h2o/tags.php'
;
require
H2O_ROOT.
'h2o/errors.php'
;
require
H2O_ROOT.
'h2o/filters.php'
;
require
H2O_ROOT.
'h2o/context.php'
;
require
H2O_ROOT.
'h2o/parser.php'
;
class
H2o {
var
$searchpath
;
var
$context
;
var
$loader
= false;
static
$tags
=
array
();
static
$filters
=
array
();
static
$extensions
=
array
();
static
function
getOptions(
$options
=
array
()) {
return
array_merge
(
array
(
'loader'
=>
'file'
,
'cache'
=>
'file'
,
'cache_prefix'
=>
'h2o_'
,
'cache_ttl'
=> 3600,
'searchpath'
=> false,
'autoescape'
=> true,
'BLOCK_START'
=>
'{%'
,
'BLOCK_END'
=>
'%}'
,
'VARIABLE_START'
=>
'{{'
,
'VARIABLE_END'
=>
'}}'
,
'COMMENT_START'
=>
'{*'
,
'COMMENT_END'
=>
'*}'
,
'TRIM_TAGS'
=> true
),
$options
);
}
function
__construct(
$file
= null,
$options
=
array
()) {
# Init a environment
$this
->options =
$this
->getOptions(
$options
);
$loader
=
$this
->options[
'loader'
];
if
(!
$loader
)
return
true;
if
(
is_object
(
$loader
)) {
$this
->loader =
$loader
;
$this
->loader->setOptions(
$this
->options);
}
else
{
$loader
=
"H2o_{$loader}_Loader"
;
if
(!
class_exists
(
$loader
, false))
throw
new
Exception(
'Invalid template loader'
);
if
(isset(
$options
[
'searchpath'
])){
$this
->searchpath =
$options
[
'searchpath'
];
}
else
if
(
$file
) {
$this
->searchpath = dirname(
realpath
(
$file
)).DS;
}
else
{
$this
->searchpath =
getcwd
().DS;
}
$loader_searchpath
=
is_array
(
$this
->searchpath) ?
$this
->searchpath :
array
(
$this
->searchpath);
$this
->loader =
new
$loader
(
$loader_searchpath
,
$this
->options);
}
$this
->loader->runtime =
$this
;
if
(isset(
$options
[
'i18n'
])) {
h2o::load(
'i18n'
);
$this
->i18n =
new
H2o_I18n(
$this
->searchpath,
$options
[
'i18n'
]);
}
if
(
$file
) {
$this
->nodelist =
$this
->loadTemplate(
$file
);
}
}
function
loadTemplate(
$file
) {
return
$this
->nodelist =
$this
->loader->read_cache(
$file
);
}
function
loadSubTemplate(
$file
) {
return
$this
->loader->read(
$file
);
}
# Build a finalized nodelist from template ready to be cached
function
parse(
$source
,
$filename
=
''
,
$env
= null) {
if
(!
$env
)
$env
=
$this
->options;
if
(!
class_exists
(
'H2o_Parser'
, false))
require
H2O_ROOT.
'h2o/parser.php'
;
$parser
=
new
H2o_Parser(
$source
,
$filename
,
$this
,
$env
);
$nodelist
=
$parser
->parse();
return
$nodelist
;
}
function
set(
$context
,
$value
= null) {
# replace with
new
context object
if
(
is_object
(
$context
) &&
$context
instanceof
H2o_Context) {
return
$this
->context =
$context
;
}
# Init context
if
(!
$this
->context) {
$this
->context =
new
H2o_Context(
$this
->defaultContext(),
$this
->options);
}
# Extend
or
set value
if
(
is_array
(
$context
)) {
return
$this
->context->extend(
$context
);
}
elseif
(
is_string
(
$context
)) {
return
$this
->context[
$context
] =
$value
;
}
return
false;
}
# Render the nodelist
function
render(
$context
=
array
()) {
$this
->set(
$context
);
$this
->stream =
new
StreamWriter;
$this
->nodelist->render(
$this
->context,
$this
->stream);
return
$this
->stream->close();
}
static
function
parseString(
$source
,
$options
=
array
()) {
$instance
=
new
H2o(null,
array_merge
(
$options
,
array
(
'loader'
=> false)));
$instance
->nodelist =
$instance
->parse(
$source
);
return
$instance
;
}
static
function
&createTag(
$tag
,
$args
= null,
$parser
,
$position
= 0) {
if
(!isset(self::
$tags
[
$tag
])) {
throw
new
H2o_Error(
$tag
.
" tag doesn't exist"
);
}
$tagClass
= self::
$tags
[
$tag
];
$tag
=
new
$tagClass
(
$args
,
$parser
,
$position
);
return
$tag
;
}
static
function
addTag(
$tag
,
$class
= null) {
$tags
=
array
();
if
(
is_string
(
$tag
)) {
if
(
is_null
(
$class
))
$class
= ucwords(
"{$tag}_Tag"
);
$tags
[
$tag
] =
$class
;
}
elseif
(
is_array
(
$tag
)) {
$tags
=
$tag
;
}
foreach
(
$tags
as
$tag
=>
$tagClass
) {
if
(
is_integer
(
$tag
)) {
unset(
$tags
[
$tag
]);
$tag
=
$tagClass
;
$tagClass
= ucwords(
"{$tagClass}_Tag"
);
}
if
(!
class_exists
(
$tagClass
, false)) {
throw
new
H2o_Error(
"{$tagClass} tag is not found"
);
}
$tags
[
$tag
] =
$tagClass
;
}
self::
$tags
=
array_merge
(self::
$tags
,
$tags
);
}
static
function
addFilter(
$filter
,
$callback
= null) {
if
(
is_array
(
$filter
)) {
$filters
=
$filter
;
foreach
(
$filters
as
$key
=>
$filter
) {
if
(
is_numeric
(
$key
))
$key
=
$filter
;
self::addFilter(
$key
,
$filter
);
}
return
true;
}
elseif
(
is_string
(
$filter
) &&
class_exists
(
$filter
, false) &&
is_subclass_of
(
$filter
,
'FilterCollection'
)) {
foreach
(get_class_methods(
$filter
)
as
$f
) {
if
(
is_callable
(
array
(
$filter
,
$f
)))
self::
$filters
[
$f
] =
array
(
$filter
,
$f
);
}
return
true;
}
if
(
is_null
(
$callback
))
$callback
=
$filter
;
if
(!
is_callable
(
$callback
)) {
return
false;
}
self::
$filters
[
$filter
] =
$callback
;
}
static
function
addLookup(
$callback
) {
if
(
is_callable
(
$callback
)) {
H2o_Context::
$lookupTable
[] =
$callback
;
}
else
die
(
'damm it'
);
}
static
function
load(
$extension
,
$file
= null) {
if
(!
$file
) {
$file
= H2O_ROOT.
'ext'
.DS.
$extension
.
'.php'
;
}
if
(
is_file
(
$file
)) {
include_once
(
$file
);
self::
$extensions
[
$extension
] =
$file
;
}
}
function
defaultContext() {
return
array
(
'h2o'
=>
new
H2o_Info);
}
}
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
;
}
?>