diff options
Diffstat (limited to 'STECore.php')
-rw-r--r-- | STECore.php | 328 |
1 files changed, 0 insertions, 328 deletions
diff --git a/STECore.php b/STECore.php deleted file mode 100644 index add09ad..0000000 --- a/STECore.php +++ /dev/null @@ -1,328 +0,0 @@ -<?php - -namespace kch42\ste; - -/* - * Class: STECore - * The Core of STE - */ -class STECore { - private $tags; - private $storage_access; - private $cur_tpl_dir; - private $scope; - - /* - * Variables: Public variables - * - * $blocks - Associative array of blocks (see the language definition). - * $blockorder - The order of the blocks (an array) - * $mute_runtime_errors - If true (default) a <RuntimeError> exception will result in no output from the tag, if false a error message will be written to output. - * $fatal_error_on_missing_tag - If true, STE will throw a <FatalRuntimeError> if a tag was called that was not registered, otherwise (default) a regular <RuntimeError> will be thrown and automatically handled by STE (see <$mute_runtime_errors>). - */ - public $blocks; - public $blockorder; - public $mute_runtime_errors = true; - public $fatal_error_on_missing_tag = false; - - /* - * Constructor: __construct - * - * Parameters: - * $storage_access - An Instance of a <StorageAccess> implementation. - */ - public function __construct($storage_access) { - $this->storage_access = $storage_access; - $this->cur_tpl_dir = "/"; - STEStandardLibrary::_register_lib($this); - $this->blockorder = array(); - $this->blocks = array(); - - $this->set_scope(new Scope(array())); - } - - /* - * Function: register_tag - * Register a custom tag. - * - * Parameters: - * $name - The name of the tag. - * $callback - A callable function (This must take three parameters: The <STECore> instance, an associative array of parameters, and a function representing the tags content(This expects the <STECore> instance as its only parameter and returns its text result, i.e to get the text, you neeed to call this function with the <STECore> instance as a parameter)). - * - * Throws: - * An Exception if the tag could not be registered (if $callback is not callable or if $name is empty) - */ - public function register_tag($name, $callback) { - if(!is_callable($callback)) { - throw new \Exception("Can not register tag \"$name\", not callable."); - } - if(empty($name)) { - throw new \Exception("Can not register tag, empty name."); - } - $this->tags[$name] = $callback; - } - - /* - * Function: call_tag - * Calling a custom tag (builtin ones can not be called) - * - * Parameters: - * $name - The Tag's name - * $params - Associative array of parameters - * $sub - A callable function (expecting an <STECore> instance as it's parameter) that represents the tag's content. - * - * Throws: - * Might throw a <FatalRuntimeError> (see <$fatal_error_on_missing_tag>. - * - * Returns: - * The output of the tag or, if a <RuntimeError> was thrown, the appropiate result (see <$mute_runtime_errors>). - */ - public function call_tag($name, $params, $sub) { - try { - if(!isset($this->tags[$name])) { - if($this->fatal_error_on_missing_tag) { - throw new FatalRuntimeError("Can not call tag \"$name\": Does not exist."); - } else { - throw new RuntimeError("Can not call tag \"$name\": Does not exist."); - } - } - return call_user_func($this->tags[$name], $this, $params, $sub); - } catch(RuntimeError $e) { - if(!$this->mute_runtime_errors) { - return "RuntimeError occurred on tag '$name': " . $e->getMessage(); - } - } - } - - public function calc($expression) { - return Calc::calc($expression); - } - - /* - * Function: exectemplate - * Executes a template and returns the result. The huge difference to <load> is that this function will also output all blocks. - * - * Parameters: - * $tpl - The name of the template to execute. - * - * Throws: - * * A <CantLoadTemplate> exception if the template could not be loaded. - * * A <ParseCompileError> if the template could not be parsed or transcompiled. - * * A <FatalRuntimeError> if a tag threw it or if a tag was not found and <$fatal_error_on_missing_tag> is true. - * * Might also throw different exceptions, if a external tag threw it (but they should use <RuntimeError> or <FatalRuntimeError> to make it possible for STE to handle them correctly). - * - * Returns: - * The output of the template. - */ - public function exectemplate($tpl) { - $output = ""; - $lastblock = $this->load($tpl); - - foreach($this->blockorder as $blockname) { - $output .= $this->blocks[$blockname]; - } - - return $output . $lastblock; - } - - /* - * Function: get_var_reference - * Get a reference to a template variable using a variable name. - * This can be used,if your custom tag takes a variable name as a parameter. - * - * Parameters: - * $name - The variables name. - * $create_if_not_exist - Should the variable be created, if it does not exist? Otherwise NULL will be returned, if the variable does not exist. - * - * Throws: - * <RuntimeError> if the variable name can not be parsed (e.g. unbalanced brackets). - * - * Returns: - * A Reference to the variable. - */ - public function &get_var_reference($name, $create_if_not_exist) { - $ref = &$this->scope->get_var_reference($name, $create_if_not_exist); - return $ref; - } - - /* - * Function: set_var_by_name - * Set a template variable by its name. - * This can be used,if your custom tag takes a variable name as a parameter. - * - * Parameters: - * $name - The variables name. - * $val - The new value. - * - * Throws: - * <RuntimeError> if the variable name can not be parsed (e.g. unbalanced brackets). - */ - public function set_var_by_name($name, $val) { - $this->scope->set_var_by_name($name, $val); - } - - public function set_local_var($name, $val) { - $this->scope->set_local_var($name, $val); - } - - /* - * Function: get_var_by_name - * Get a template variable by its name. - * This can be used,if your custom tag takes a variable name as a parameter. - * - * Parameters: - * $name - The variables name. - * - * Throws: - * <RuntimeError> if the variable name can not be parsed (e.g. unbalanced brackets). - * - * Returns: - * The variables value. - */ - public function get_var_by_name($name) { - return $this->scope->get_var_by_name($name); - } - - /* - * Function: load - * Load a template and return its result (blocks not included, use <exectemplate> for this). - * - * Parameters: - * $tpl - The name of the template to be loaded. - * $quiet - If true, do not output anything and do not modify the blocks. This can be useful to load custom tags that are programmed in the STE Template Language. Default: false. - * - * Throws: - * * A <CantLoadTemplate> exception if the template could not be loaded. - * * A <ParseCompileError> if the template could not be parsed or transcompiled. - * * A <FatalRuntimeError> if a tag threw it or if a tag was not found and <$fatal_error_on_missing_tag> is true. - * * Might also throw different exceptions, if a external tag threw it (but they should use <RuntimeError> or <FatalRuntimeError> to make it possible for STE to handle them correctly). - * - * Returns: - * The result of the template (if $quiet == false). - */ - public function load($tpl, $quiet = false) { - $tpldir_b4 = $this->cur_tpl_dir; - - /* Resolve ".", ".." and protect from possible LFI */ - $tpl = str_replace("\\", "/", $tpl); - if($tpl[0] != "/") { - $tpl = $this->cur_tpl_dir . "/" . $tpl; - } - $pathex = array_filter(explode("/", $tpl), function($s) { return ($s != ".") and (!empty($s)); }); - $pathex = array_merge($pathex); - while(($i = array_search("..", $pathex)) !== false) { - if($i == 0) { - $pathex = array_slice($pathex, 1); - } else { - $pathex = array_merge(array_slice($pathex, 0, $i), array_slice($pathex, $i + 2)); - } - } - $tpl = implode("/", $pathex); - $this->cur_tpl_dir = dirname($tpl); - - if($quiet) { - $blocks_back = clone $this->blocks; - $blockorder_back = clone $this->blockorder; - } - - $mode = StorageAccess::MODE_TRANSCOMPILED; - $content = $this->storage_access->load($tpl, $mode); - if($mode == StorageAccess::MODE_SOURCE) { - try { - $ast = Parser::parse($content, $tpl); - $transc = Transcompiler::transcompile($ast); - } catch(ParseCompileError $e) { - $e->rewrite($content); - throw $e; - } - $this->storage_access->save($tpl, $transc, StorageAccess::MODE_TRANSCOMPILED); - eval("\$content = $transc;"); - } - - $output = $content($this); - - $this->cur_tpl_dir = $tpldir_b4; - - if($quiet) { - $this->blocks = $blocks_back; - $this->blockorder = $blockorder_back; - } else { - return $output; - } - } - - /* - * Function: evalbool - * Test, if a text represents false (an empty / only whitespace text) or true (everything else). - * - * Parameters: - * $txt - The text to test. - * - * Returns: - * true/false. - */ - public function evalbool($txt) { - return trim($txt . "") != ""; - } - - public function get_scope() { - return $this->scope; - } - - public function set_scope($scope) { - $this->scope = $scope; - } - - public function make_closure($fx) { - $bound_scope = $this->scope; - return function() use($bound_scope, $fx) { - $args = func_get_args(); - $ste = $args[0]; - - $prev = $ste->get_scope(); - $scope = $bound_scope->new_subscope(); - $ste->set_scope($scope); - - try { - $result = call_user_func_array($fx, $args); - $ste->set_scope($prev); - return $result; - } catch(\Exception $e) { - $ste->set_scope($prev); - throw $e; - } - }; - } - - public function __get($name) { - if($name === "vars") { - return $this->scope; - } - - $trace = debug_backtrace(); - trigger_error( - 'Undefined property via __get(): ' . $name . - ' in ' . $trace[0]['file'] . - ' on line ' . $trace[0]['line'], - E_USER_NOTICE); - return NULL; - } - - public function __set($name, $val) { - if($name !== "vars") { - $trace = debug_backtrace(); - trigger_error( - 'Undefined property via __set(): ' . $name . - ' in ' . $trace[0]['file'] . - ' on line ' . $trace[0]['line'], - E_USER_NOTICE); - return; - } - - if(is_array($val)) { - foreach($val as $k => $v) { - $this->scope[$k] = $v; - } - } - } -} |