Added comment and a test for viewpoint data fields.

This commit is contained in:
Vassyli
2021-04-08 13:25:03 +02:00
parent 53ad63db86
commit 27a5e359f2
2 changed files with 52 additions and 10 deletions
+31 -9
View File
@@ -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"];
+21 -1
View File
@@ -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()