summaryrefslogtreecommitdiff
path: root/src/STECore.php
diff options
context:
space:
mode:
Diffstat (limited to 'src/STECore.php')
-rw-r--r--src/STECore.php342
1 files changed, 0 insertions, 342 deletions
diff --git a/src/STECore.php b/src/STECore.php
deleted file mode 100644
index c00bf67..0000000
--- a/src/STECore.php
+++ /dev/null
@@ -1,342 +0,0 @@
-<?php
-
-// File: STECore.php
-
-// Namespace: kch42\ste
-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);
- }
-
- /*
- * Function: set_local_var
- * Like <set_var_by_name>, but only sets the variable in the global scope (<set_var_by_name> will overwrite the variable in the parent scope, if it's defined there) .
- *
- * 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_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;
- }
- }
- }
-}