Skip to content

Commit df61e13

Browse files
committed
Update EvalSandBox
Evaluate all codes and functions before process variables
1 parent bdc722b commit df61e13

File tree

2 files changed

+38
-12
lines changed

2 files changed

+38
-12
lines changed

src/Bubble/Util/EvalSandBox.php

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@
3434

3535
use Bubble\Exception\InvalidDataException;
3636
use Bubble\Exception\UnknownFunctionException;
37+
use Bubble\Data\DataResolver;
38+
use Bubble\Renderer\Template;
3739

3840
/**
3941
* Eval sandbox
@@ -53,7 +55,7 @@ class EvalSandBox
5355
*
5456
* @var string
5557
*/
56-
private static $_functionContext = "\Bubble\Util\FunctionsContext";
58+
private static $_functionContext = "\Bubble\Data\FunctionsContext";
5759

5860
/**
5961
* Changes the current functions context.
@@ -74,24 +76,38 @@ public static function setFunctionsContext(string $context): void
7476
self::$_functionContext = $context;
7577
}
7678

77-
public static function eval(string $code)
79+
public static function eval(string $code, DataResolver $resolver)
7880
{
79-
$code = self::_parseCode($code);
81+
$parsed = self::_parseCode($code, $resolver);
8082
$context = self::$_functionContext;
8183

8284
return eval(
83-
"\$context = new {$context}; return {$code};"
85+
"{$parsed[0]} \$context = new {$context}; return {$parsed[1]};"
8486
);
8587
}
8688

87-
private static function _parseCode(string $code): string
89+
private static function _parseCode(string $code, DataResolver $resolver): array
8890
{
89-
return preg_replace_callback("#@(\w+)\\(#U", function ($m) {
91+
$var_allocation = "";
92+
93+
do {
94+
$code = preg_replace_callback(Template::DATA_MODEL_QUERY_REGEX, function ($m) use ($resolver, &$var_allocation) {
95+
$var_name = uniqid("tempvar_");
96+
$var_value = Utilities::toEvalSandBoxValue($resolver->resolve($m[1]));
97+
$var_allocation .= "\${$var_name} = {$var_value}; ";
98+
99+
return "\${$var_name}";
100+
}, $code);
101+
} while (preg_match(Template::DATA_MODEL_QUERY_REGEX, $code, $matches));
102+
103+
$code = preg_replace_callback("/@(\w+)\\(/U", function ($m) {
90104
if (!method_exists(self::$_functionContext, $m[1])) {
91105
throw new UnknownFunctionException($m[1]);
92106
}
93107

94108
return str_replace("@{$m[1]}(", "\$context->{$m[1]}(", $m[0]);
95109
}, $code);
110+
111+
return [$var_allocation, $code];
96112
}
97113
}

src/Bubble/Util/Utilities.php

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -100,16 +100,16 @@ public static function resolveTemplate(string $path)
100100

101101
public static function populateData(string $templatePart, DataResolver $resolver)
102102
{
103+
$templatePart = preg_replace_callback(Template::EXPRESSION_REGEX, function ($m) use ($resolver) {
104+
$res = EvalSandBox::eval($m[1], $resolver);
105+
return self::toString($res);
106+
}, $templatePart);
107+
103108
do {
104109
$templatePart = preg_replace_callback(Template::DATA_MODEL_QUERY_REGEX, function ($m) use ($resolver) {
105110
return self::toString($resolver->resolve($m[1]));
106111
}, $templatePart);
107-
} while(preg_match(Template::DATA_MODEL_QUERY_REGEX, $templatePart, $matches));
108-
109-
$templatePart = preg_replace_callback(Template::EXPRESSION_REGEX, function ($m) {
110-
$res = EvalSandBox::eval($m[1]);
111-
return self::toString($res);
112-
}, $templatePart);
112+
} while (preg_match(Template::DATA_MODEL_QUERY_REGEX, $templatePart, $matches));
113113

114114
return $templatePart;
115115
}
@@ -130,4 +130,14 @@ public static function computeOutputString(\DOMDocument $parsed)
130130

131131
return $outDOM->saveHTML();
132132
}
133+
134+
public static function toEvalSandBoxValue($value)
135+
{
136+
if (is_string($value)) {
137+
$value = str_replace("\"", "\\\"", $value);
138+
$value = "\"{$value}\"";
139+
}
140+
141+
return self::toString($value);
142+
}
133143
}

0 commit comments

Comments
 (0)