Added comment and a test for viewpoint data fields.
This commit is contained in:
@@ -5,15 +5,16 @@ declare(strict_types=1);
|
|||||||
namespace LotGD\Core\Services;
|
namespace LotGD\Core\Services;
|
||||||
|
|
||||||
|
|
||||||
use Doctrine\DBAL\Schema\View;
|
|
||||||
use LotGD\Core\Events\EventContextData;
|
use LotGD\Core\Events\EventContextData;
|
||||||
|
use LotGD\Core\Exceptions\CharacterNotFoundException;
|
||||||
use LotGD\Core\Exceptions\InsecureTwigTemplateError;
|
use LotGD\Core\Exceptions\InsecureTwigTemplateError;
|
||||||
use LotGD\Core\Game;
|
use LotGD\Core\Game;
|
||||||
use LotGD\Core\Models\Character;
|
use LotGD\Core\Models\Character;
|
||||||
use LotGD\Core\Models\CharacterProperty;
|
|
||||||
use LotGD\Core\Models\Scene;
|
use LotGD\Core\Models\Scene;
|
||||||
use LotGD\Core\Models\Viewpoint;
|
use LotGD\Core\Models\Viewpoint;
|
||||||
use Twig\Environment;
|
use Twig\Environment;
|
||||||
|
use Twig\Error\LoaderError;
|
||||||
|
use Twig\Error\SyntaxError;
|
||||||
use Twig\Extension\SandboxExtension;
|
use Twig\Extension\SandboxExtension;
|
||||||
use Twig\Sandbox\SecurityError;
|
use Twig\Sandbox\SecurityError;
|
||||||
use Twig\Sandbox\SecurityPolicy;
|
use Twig\Sandbox\SecurityPolicy;
|
||||||
@@ -28,12 +29,31 @@ class TwigSceneRenderer
|
|||||||
) {
|
) {
|
||||||
$this->twig = new Environment(new TwigNullLoader());
|
$this->twig = new Environment(new TwigNullLoader());
|
||||||
|
|
||||||
$securityPolicy = $this->getSecurityPolicy();
|
// Add a hook for additional fields
|
||||||
|
// This is for global changes only. Viewpoint-dependent changes should try to store the important values within
|
||||||
|
// the viewpoint itself.
|
||||||
|
$eventManager = $this->game->getEventManager();
|
||||||
|
$contextData = EventContextData::create(["templateValues" => []]);
|
||||||
|
$newContextData = $eventManager->publish("h/lotgd/core/scene-renderer/templateValues", $contextData);
|
||||||
|
$this->templateValues = $newContextData->get("templateValues") ?? [];
|
||||||
|
|
||||||
# Add Sandbox extension
|
// Add Sandbox extension
|
||||||
|
$securityPolicy = $this->getSecurityPolicy();
|
||||||
$this->twig->addExtension(new SandboxExtension($securityPolicy, sandboxed: true));
|
$this->twig->addExtension(new SandboxExtension($securityPolicy, sandboxed: true));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renders a given string in the context if a given viewpoint.
|
||||||
|
*
|
||||||
|
* @param string $string
|
||||||
|
* @param Viewpoint $viewpoint
|
||||||
|
* @param bool $ignoreErrors If set to true, errors are ignored and the unparsed string will be returned instead.
|
||||||
|
* @return string
|
||||||
|
* @throws InsecureTwigTemplateError
|
||||||
|
* @throws CharacterNotFoundException
|
||||||
|
* @throws LoaderError
|
||||||
|
* @throws SyntaxError
|
||||||
|
*/
|
||||||
public function render(string $string, Viewpoint $viewpoint, bool $ignoreErrors = false): string
|
public function render(string $string, Viewpoint $viewpoint, bool $ignoreErrors = false): string
|
||||||
{
|
{
|
||||||
// We catch here "Tag" errors. If error, we'll exit either by returning the input ($ignoreError === true) or
|
// We catch here "Tag" errors. If error, we'll exit either by returning the input ($ignoreError === true) or
|
||||||
@@ -54,11 +74,8 @@ class TwigSceneRenderer
|
|||||||
"Viewpoint" => $viewpoint,
|
"Viewpoint" => $viewpoint,
|
||||||
];
|
];
|
||||||
|
|
||||||
// Publish event to change $templateValues
|
// Merges additional template values with important ones.
|
||||||
$eventManager = $this->game->getEventManager();
|
$templateValues = array_merge($this->templateValues, $templateValues);
|
||||||
$contextData = EventContextData::create(["templateValues" => $templateValues]);
|
|
||||||
$newContextData = $eventManager->publish("h/lotgd/core/scene-renderer/templateValues", $contextData);
|
|
||||||
$templateValues = $newContextData->get("templateValues");
|
|
||||||
|
|
||||||
// Try to render the template
|
// Try to render the template
|
||||||
try {
|
try {
|
||||||
@@ -75,6 +92,11 @@ class TwigSceneRenderer
|
|||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the current security policy.
|
||||||
|
* This method provides a hook.
|
||||||
|
* @return SecurityPolicy
|
||||||
|
*/
|
||||||
public function getSecurityPolicy(): SecurityPolicy
|
public function getSecurityPolicy(): SecurityPolicy
|
||||||
{
|
{
|
||||||
$tags = ["if"];
|
$tags = ["if"];
|
||||||
|
|||||||
@@ -104,6 +104,26 @@ class TwigSceneRendererTest extends LotGDTestCase
|
|||||||
$this->assertSame($result, $renderResult);
|
$this->assertSame($result, $renderResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testIfViewpointDataCanBeAccessed()
|
||||||
|
{
|
||||||
|
[$game, $viewpoint, $character, $eventManager] = $this->getMockeries();
|
||||||
|
$eventManager->method("publish")->willReturnArgument(1);
|
||||||
|
$viewpoint->method("getData")->willReturn(["test" => 7, "other" => "Hi"]);
|
||||||
|
|
||||||
|
# Get renderer
|
||||||
|
$renderer = new TwigSceneRenderer($game);
|
||||||
|
|
||||||
|
# Prepare the template string.
|
||||||
|
$template = "Hi {{ Viewpoint.data.test }}! {{ Viewpoint.data.other }}";
|
||||||
|
$result = "Hi 7! Hi";
|
||||||
|
|
||||||
|
# Create the result
|
||||||
|
$renderResult = $renderer->render($template, $viewpoint);
|
||||||
|
|
||||||
|
# Assert result
|
||||||
|
$this->assertSame($result, $renderResult);
|
||||||
|
}
|
||||||
|
|
||||||
public function testIfRawTemplateGetsReturnedIfTemplateContainsIllegalTokens()
|
public function testIfRawTemplateGetsReturnedIfTemplateContainsIllegalTokens()
|
||||||
{
|
{
|
||||||
[$game, $viewpoint, $character, $eventManager] = $this->getMockeries();
|
[$game, $viewpoint, $character, $eventManager] = $this->getMockeries();
|
||||||
@@ -173,7 +193,7 @@ class TwigSceneRendererTest extends LotGDTestCase
|
|||||||
$renderer->render("{% if 5*1 %}Hallo{%endif%}", $viewpoint, false);
|
$renderer->render("{% if 5*1 %}Hallo{%endif%}", $viewpoint, false);
|
||||||
|
|
||||||
$this->expectException(InsecureTwigTemplateError::class);
|
$this->expectException(InsecureTwigTemplateError::class);
|
||||||
$renderer->render("{{ Character.name }}", $scene, false);
|
$renderer->render("{{ Character.name }}", $viewpoint, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testIfPublishedEventCanModifyValueScope()
|
public function testIfPublishedEventCanModifyValueScope()
|
||||||
|
|||||||
Reference in New Issue
Block a user