diff --git a/PhpEcho.php b/PhpEcho.php index 89b82c6..5d67436 100644 --- a/PhpEcho.php +++ b/PhpEcho.php @@ -94,7 +94,8 @@ class PhpEcho implements ArrayAccess { - private static string $ALPHA_NUM = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'; + private const ALPHA_NUM = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'; + private const RESERVED_KEY_RAW = 'raw'; private string $id = ''; private array $vars = []; @@ -168,6 +169,10 @@ public function __construct(string $file = '', array $vars = [], string $id = '' } $this->vars = $vars; + + if ( ! isset($this->vars[self::RESERVED_KEY_RAW])) { + $this->vars[self::RESERVED_KEY_RAW] = []; + } } /** @@ -363,8 +368,9 @@ public function offsetExists($offset): bool public function offsetGet($offset): mixed { if (self::$use_space_notation) { - $keys = explode(' ', $offset); $data = $this->vars; + $keys = explode(' ', $offset); + $is_raw = $keys[0] === self::RESERVED_KEY_RAW; foreach ($keys as $k) { if (isset($data[$k])) { $data = $data[$k]; @@ -375,6 +381,7 @@ public function offsetGet($offset): mixed $v = $data; } elseif (isset($this->vars[$offset])) { $v = $this->vars[$offset]; + $is_raw = $offset === self::RESERVED_KEY_RAW; } else { return null; } @@ -382,6 +389,8 @@ public function offsetGet($offset): mixed // intercept the case where $v is an array of PhpEcho blocks if ($this->isArrayOfPhpEchoBlocks($v)) { return implode('', array_map('strval', $v)); + } elseif ($is_raw) { + return $v; } elseif ($this('toEscape', $v)) { return $this('hsc', $v); } else { @@ -458,6 +467,10 @@ public function offsetUnset($offset): void } unset($data[$last]); + return; + } elseif ($offset === self::RESERVED_KEY_RAW) { + $this->vars[self::RESERVED_KEY_RAW] = []; + return; } } @@ -493,7 +506,7 @@ public static function getToken(int $length = 12): string { $length = ($length < 12) ? 12 : $length; do { - $token = substr(str_shuffle(self::$ALPHA_NUM.mt_rand(100000000, 999999999)), 0, $length); + $token = substr(str_shuffle(self::ALPHA_NUM.mt_rand(100000000, 999999999)), 0, $length); } while (isset(self::$tokens[$token])); self::$tokens[$token] = true; @@ -579,7 +592,7 @@ public static function isHelperOfType(string $helper_name, int $type): bool /** * @param array $type array of types [type] - * @param bool $strict when match, check if the helper has only the asked types + * @param bool $strict when matched, check if the helper has only the asked types * @return array [helper's name => closure] */ public static function getHelpersByType(array $type, bool $strict = false): array diff --git a/README.md b/README.md index b6228db..40b77a9 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # **PhpEcho** -`2022-01-22` `PHP 8.0+` `v.4.0.6` +`2022-01-28` `PHP 8.0+` `v.4.0.7` ## **A native PHP template engine : One class to rule them all** ## **VERSION 4.X IS ONLY FOR PHP 8 AND ABOVE** @@ -36,8 +36,9 @@ The class will manage : composer require rawsrc/phpecho ``` -**NEW FEATURE IN PhpEcho v4.0.6:**
-1. Get the full file path to a view file from its path segments using the static method `getFullFilepath()` +**NEW FEATURE IN PhpEcho v4.0.7:**
+1. Add a reserved word for vars: `raw`. Stores the raw code of the instance, on rendering +the code extracted from the var `raw` is never escaped, see SHORT EXAMPLE **What you must know to use it** 1. All values read from a PhpEcho instance are escaped and safe in HTML context. @@ -63,6 +64,10 @@ $y = $block->hsc('any value to escape'); // using IDE highlight $z = $block('raw', 'foo'); // $z = 'abc " < >' or $z = $block->raw('foo'); // $z = 'abc " < >' +// new feature v4.0.7, raw is reserved, equivalent to the previous code +$z = $block['raw foo'] = 'abc " < >'; +$v = $block['raw foo']; // $v = 'abc " < >' + // the type of value is preserved, are escaped all strings and objects having __toString() $block['bar'] = new stdClass(); $bar = $block['bar'];