Adds SceneRenderer class based on twig to convert some logic and variables from Scenes, allowing them to be more flexible.
This commit is contained in:
@@ -21,6 +21,7 @@
|
|||||||
"monolog/monolog": "^2.0",
|
"monolog/monolog": "^2.0",
|
||||||
"symfony/console": "^5.0",
|
"symfony/console": "^5.0",
|
||||||
"symfony/yaml": "^5.0",
|
"symfony/yaml": "^5.0",
|
||||||
|
"twig/twig": "^3.0",
|
||||||
"ramsey/uuid-doctrine": "^1.5",
|
"ramsey/uuid-doctrine": "^1.5",
|
||||||
"jetbrains/phpstorm-attributes": "^1.0"
|
"jetbrains/phpstorm-attributes": "^1.0"
|
||||||
},
|
},
|
||||||
|
|||||||
Generated
+135
-58
@@ -4,7 +4,7 @@
|
|||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"content-hash": "9cab3ccd48d3179741e9597ca856fb08",
|
"content-hash": "948d1f1c6837be4e8ff616c5e7ee5924",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"name": "brick/math",
|
"name": "brick/math",
|
||||||
@@ -64,16 +64,16 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "composer/ca-bundle",
|
"name": "composer/ca-bundle",
|
||||||
"version": "1.2.8",
|
"version": "1.2.9",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/composer/ca-bundle.git",
|
"url": "https://github.com/composer/ca-bundle.git",
|
||||||
"reference": "8a7ecad675253e4654ea05505233285377405215"
|
"reference": "78a0e288fdcebf92aa2318a8d3656168da6ac1a5"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/composer/ca-bundle/zipball/8a7ecad675253e4654ea05505233285377405215",
|
"url": "https://api.github.com/repos/composer/ca-bundle/zipball/78a0e288fdcebf92aa2318a8d3656168da6ac1a5",
|
||||||
"reference": "8a7ecad675253e4654ea05505233285377405215",
|
"reference": "78a0e288fdcebf92aa2318a8d3656168da6ac1a5",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@@ -82,14 +82,15 @@
|
|||||||
"php": "^5.3.2 || ^7.0 || ^8.0"
|
"php": "^5.3.2 || ^7.0 || ^8.0"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"phpunit/phpunit": "^4.8.35 || ^5.7 || 6.5 - 8",
|
"phpstan/phpstan": "^0.12.55",
|
||||||
"psr/log": "^1.0",
|
"psr/log": "^1.0",
|
||||||
|
"symfony/phpunit-bridge": "^4.2 || ^5",
|
||||||
"symfony/process": "^2.5 || ^3.0 || ^4.0 || ^5.0"
|
"symfony/process": "^2.5 || ^3.0 || ^4.0 || ^5.0"
|
||||||
},
|
},
|
||||||
"type": "library",
|
"type": "library",
|
||||||
"extra": {
|
"extra": {
|
||||||
"branch-alias": {
|
"branch-alias": {
|
||||||
"dev-master": "1.x-dev"
|
"dev-main": "1.x-dev"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
@@ -119,7 +120,7 @@
|
|||||||
"support": {
|
"support": {
|
||||||
"irc": "irc://irc.freenode.org/composer",
|
"irc": "irc://irc.freenode.org/composer",
|
||||||
"issues": "https://github.com/composer/ca-bundle/issues",
|
"issues": "https://github.com/composer/ca-bundle/issues",
|
||||||
"source": "https://github.com/composer/ca-bundle/tree/1.2.8"
|
"source": "https://github.com/composer/ca-bundle/tree/1.2.9"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@@ -135,7 +136,7 @@
|
|||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2020-08-23T12:54:47+00:00"
|
"time": "2021-01-12T12:10:35+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "composer/composer",
|
"name": "composer/composer",
|
||||||
@@ -2524,16 +2525,16 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/polyfill-ctype",
|
"name": "symfony/polyfill-ctype",
|
||||||
"version": "v1.20.0",
|
"version": "v1.22.0",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/polyfill-ctype.git",
|
"url": "https://github.com/symfony/polyfill-ctype.git",
|
||||||
"reference": "f4ba089a5b6366e453971d3aad5fe8e897b37f41"
|
"reference": "c6c942b1ac76c82448322025e084cadc56048b4e"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/f4ba089a5b6366e453971d3aad5fe8e897b37f41",
|
"url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/c6c942b1ac76c82448322025e084cadc56048b4e",
|
||||||
"reference": "f4ba089a5b6366e453971d3aad5fe8e897b37f41",
|
"reference": "c6c942b1ac76c82448322025e084cadc56048b4e",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@@ -2545,7 +2546,7 @@
|
|||||||
"type": "library",
|
"type": "library",
|
||||||
"extra": {
|
"extra": {
|
||||||
"branch-alias": {
|
"branch-alias": {
|
||||||
"dev-main": "1.20-dev"
|
"dev-main": "1.22-dev"
|
||||||
},
|
},
|
||||||
"thanks": {
|
"thanks": {
|
||||||
"name": "symfony/polyfill",
|
"name": "symfony/polyfill",
|
||||||
@@ -2583,7 +2584,7 @@
|
|||||||
"portable"
|
"portable"
|
||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"source": "https://github.com/symfony/polyfill-ctype/tree/v1.20.0"
|
"source": "https://github.com/symfony/polyfill-ctype/tree/v1.22.0"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@@ -2599,20 +2600,20 @@
|
|||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2020-10-23T14:02:19+00:00"
|
"time": "2021-01-07T16:49:33+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/polyfill-intl-grapheme",
|
"name": "symfony/polyfill-intl-grapheme",
|
||||||
"version": "v1.20.0",
|
"version": "v1.22.0",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/polyfill-intl-grapheme.git",
|
"url": "https://github.com/symfony/polyfill-intl-grapheme.git",
|
||||||
"reference": "c7cf3f858ec7d70b89559d6e6eb1f7c2517d479c"
|
"reference": "267a9adeb8ecb8071040a740930e077cdfb987af"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/c7cf3f858ec7d70b89559d6e6eb1f7c2517d479c",
|
"url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/267a9adeb8ecb8071040a740930e077cdfb987af",
|
||||||
"reference": "c7cf3f858ec7d70b89559d6e6eb1f7c2517d479c",
|
"reference": "267a9adeb8ecb8071040a740930e077cdfb987af",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@@ -2624,7 +2625,7 @@
|
|||||||
"type": "library",
|
"type": "library",
|
||||||
"extra": {
|
"extra": {
|
||||||
"branch-alias": {
|
"branch-alias": {
|
||||||
"dev-main": "1.20-dev"
|
"dev-main": "1.22-dev"
|
||||||
},
|
},
|
||||||
"thanks": {
|
"thanks": {
|
||||||
"name": "symfony/polyfill",
|
"name": "symfony/polyfill",
|
||||||
@@ -2664,7 +2665,7 @@
|
|||||||
"shim"
|
"shim"
|
||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.20.0"
|
"source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.22.0"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@@ -2680,20 +2681,20 @@
|
|||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2020-10-23T14:02:19+00:00"
|
"time": "2021-01-07T16:49:33+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/polyfill-intl-normalizer",
|
"name": "symfony/polyfill-intl-normalizer",
|
||||||
"version": "v1.20.0",
|
"version": "v1.22.0",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/polyfill-intl-normalizer.git",
|
"url": "https://github.com/symfony/polyfill-intl-normalizer.git",
|
||||||
"reference": "727d1096295d807c309fb01a851577302394c897"
|
"reference": "6e971c891537eb617a00bb07a43d182a6915faba"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/727d1096295d807c309fb01a851577302394c897",
|
"url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/6e971c891537eb617a00bb07a43d182a6915faba",
|
||||||
"reference": "727d1096295d807c309fb01a851577302394c897",
|
"reference": "6e971c891537eb617a00bb07a43d182a6915faba",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@@ -2705,7 +2706,7 @@
|
|||||||
"type": "library",
|
"type": "library",
|
||||||
"extra": {
|
"extra": {
|
||||||
"branch-alias": {
|
"branch-alias": {
|
||||||
"dev-main": "1.20-dev"
|
"dev-main": "1.22-dev"
|
||||||
},
|
},
|
||||||
"thanks": {
|
"thanks": {
|
||||||
"name": "symfony/polyfill",
|
"name": "symfony/polyfill",
|
||||||
@@ -2748,7 +2749,7 @@
|
|||||||
"shim"
|
"shim"
|
||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.20.0"
|
"source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.22.0"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@@ -2764,20 +2765,20 @@
|
|||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2020-10-23T14:02:19+00:00"
|
"time": "2021-01-07T17:09:11+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/polyfill-mbstring",
|
"name": "symfony/polyfill-mbstring",
|
||||||
"version": "v1.20.0",
|
"version": "v1.22.0",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/polyfill-mbstring.git",
|
"url": "https://github.com/symfony/polyfill-mbstring.git",
|
||||||
"reference": "39d483bdf39be819deabf04ec872eb0b2410b531"
|
"reference": "f377a3dd1fde44d37b9831d68dc8dea3ffd28e13"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/39d483bdf39be819deabf04ec872eb0b2410b531",
|
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/f377a3dd1fde44d37b9831d68dc8dea3ffd28e13",
|
||||||
"reference": "39d483bdf39be819deabf04ec872eb0b2410b531",
|
"reference": "f377a3dd1fde44d37b9831d68dc8dea3ffd28e13",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@@ -2789,7 +2790,7 @@
|
|||||||
"type": "library",
|
"type": "library",
|
||||||
"extra": {
|
"extra": {
|
||||||
"branch-alias": {
|
"branch-alias": {
|
||||||
"dev-main": "1.20-dev"
|
"dev-main": "1.22-dev"
|
||||||
},
|
},
|
||||||
"thanks": {
|
"thanks": {
|
||||||
"name": "symfony/polyfill",
|
"name": "symfony/polyfill",
|
||||||
@@ -2828,7 +2829,7 @@
|
|||||||
"shim"
|
"shim"
|
||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"source": "https://github.com/symfony/polyfill-mbstring/tree/v1.20.0"
|
"source": "https://github.com/symfony/polyfill-mbstring/tree/v1.22.0"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@@ -2844,20 +2845,20 @@
|
|||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2020-10-23T14:02:19+00:00"
|
"time": "2021-01-07T16:49:33+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/polyfill-php73",
|
"name": "symfony/polyfill-php73",
|
||||||
"version": "v1.20.0",
|
"version": "v1.22.0",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/polyfill-php73.git",
|
"url": "https://github.com/symfony/polyfill-php73.git",
|
||||||
"reference": "8ff431c517be11c78c48a39a66d37431e26a6bed"
|
"reference": "a678b42e92f86eca04b7fa4c0f6f19d097fb69e2"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/8ff431c517be11c78c48a39a66d37431e26a6bed",
|
"url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/a678b42e92f86eca04b7fa4c0f6f19d097fb69e2",
|
||||||
"reference": "8ff431c517be11c78c48a39a66d37431e26a6bed",
|
"reference": "a678b42e92f86eca04b7fa4c0f6f19d097fb69e2",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@@ -2866,7 +2867,7 @@
|
|||||||
"type": "library",
|
"type": "library",
|
||||||
"extra": {
|
"extra": {
|
||||||
"branch-alias": {
|
"branch-alias": {
|
||||||
"dev-main": "1.20-dev"
|
"dev-main": "1.22-dev"
|
||||||
},
|
},
|
||||||
"thanks": {
|
"thanks": {
|
||||||
"name": "symfony/polyfill",
|
"name": "symfony/polyfill",
|
||||||
@@ -2907,7 +2908,7 @@
|
|||||||
"shim"
|
"shim"
|
||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"source": "https://github.com/symfony/polyfill-php73/tree/v1.20.0"
|
"source": "https://github.com/symfony/polyfill-php73/tree/v1.22.0"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@@ -2923,20 +2924,20 @@
|
|||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2020-10-23T14:02:19+00:00"
|
"time": "2021-01-07T16:49:33+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/polyfill-php80",
|
"name": "symfony/polyfill-php80",
|
||||||
"version": "v1.20.0",
|
"version": "v1.22.0",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/polyfill-php80.git",
|
"url": "https://github.com/symfony/polyfill-php80.git",
|
||||||
"reference": "e70aa8b064c5b72d3df2abd5ab1e90464ad009de"
|
"reference": "dc3063ba22c2a1fd2f45ed856374d79114998f91"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/e70aa8b064c5b72d3df2abd5ab1e90464ad009de",
|
"url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/dc3063ba22c2a1fd2f45ed856374d79114998f91",
|
||||||
"reference": "e70aa8b064c5b72d3df2abd5ab1e90464ad009de",
|
"reference": "dc3063ba22c2a1fd2f45ed856374d79114998f91",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@@ -2945,7 +2946,7 @@
|
|||||||
"type": "library",
|
"type": "library",
|
||||||
"extra": {
|
"extra": {
|
||||||
"branch-alias": {
|
"branch-alias": {
|
||||||
"dev-main": "1.20-dev"
|
"dev-main": "1.22-dev"
|
||||||
},
|
},
|
||||||
"thanks": {
|
"thanks": {
|
||||||
"name": "symfony/polyfill",
|
"name": "symfony/polyfill",
|
||||||
@@ -2990,7 +2991,7 @@
|
|||||||
"shim"
|
"shim"
|
||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"source": "https://github.com/symfony/polyfill-php80/tree/v1.20.0"
|
"source": "https://github.com/symfony/polyfill-php80/tree/v1.22.0"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@@ -3006,7 +3007,7 @@
|
|||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2020-10-23T14:02:19+00:00"
|
"time": "2021-01-07T16:49:33+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/process",
|
"name": "symfony/process",
|
||||||
@@ -3306,6 +3307,82 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2020-12-08T17:02:38+00:00"
|
"time": "2020-12-08T17:02:38+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "twig/twig",
|
||||||
|
"version": "v3.2.1",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/twigphp/Twig.git",
|
||||||
|
"reference": "f795ca686d38530045859b0350b5352f7d63447d"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/twigphp/Twig/zipball/f795ca686d38530045859b0350b5352f7d63447d",
|
||||||
|
"reference": "f795ca686d38530045859b0350b5352f7d63447d",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": ">=7.2.5",
|
||||||
|
"symfony/polyfill-ctype": "^1.8",
|
||||||
|
"symfony/polyfill-mbstring": "^1.3"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"psr/container": "^1.0",
|
||||||
|
"symfony/phpunit-bridge": "^4.4.9|^5.0.9"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-master": "3.2-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Twig\\": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"BSD-3-Clause"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Fabien Potencier",
|
||||||
|
"email": "fabien@symfony.com",
|
||||||
|
"homepage": "http://fabien.potencier.org",
|
||||||
|
"role": "Lead Developer"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Twig Team",
|
||||||
|
"role": "Contributors"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Armin Ronacher",
|
||||||
|
"email": "armin.ronacher@active-4.com",
|
||||||
|
"role": "Project Founder"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Twig, the flexible, fast, and secure template language for PHP",
|
||||||
|
"homepage": "https://twig.symfony.com",
|
||||||
|
"keywords": [
|
||||||
|
"templating"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/twigphp/Twig/issues",
|
||||||
|
"source": "https://github.com/twigphp/Twig/tree/v3.2.1"
|
||||||
|
},
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"url": "https://github.com/fabpot",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://tidelift.com/funding/github/packagist/twig/twig",
|
||||||
|
"type": "tidelift"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"time": "2021-01-05T15:40:36+00:00"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"packages-dev": [
|
"packages-dev": [
|
||||||
@@ -5656,16 +5733,16 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/polyfill-php72",
|
"name": "symfony/polyfill-php72",
|
||||||
"version": "v1.20.0",
|
"version": "v1.22.0",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/polyfill-php72.git",
|
"url": "https://github.com/symfony/polyfill-php72.git",
|
||||||
"reference": "cede45fcdfabdd6043b3592e83678e42ec69e930"
|
"reference": "cc6e6f9b39fe8075b3dabfbaf5b5f645ae1340c9"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/cede45fcdfabdd6043b3592e83678e42ec69e930",
|
"url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/cc6e6f9b39fe8075b3dabfbaf5b5f645ae1340c9",
|
||||||
"reference": "cede45fcdfabdd6043b3592e83678e42ec69e930",
|
"reference": "cc6e6f9b39fe8075b3dabfbaf5b5f645ae1340c9",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@@ -5674,7 +5751,7 @@
|
|||||||
"type": "library",
|
"type": "library",
|
||||||
"extra": {
|
"extra": {
|
||||||
"branch-alias": {
|
"branch-alias": {
|
||||||
"dev-main": "1.20-dev"
|
"dev-main": "1.22-dev"
|
||||||
},
|
},
|
||||||
"thanks": {
|
"thanks": {
|
||||||
"name": "symfony/polyfill",
|
"name": "symfony/polyfill",
|
||||||
@@ -5712,7 +5789,7 @@
|
|||||||
"shim"
|
"shim"
|
||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"source": "https://github.com/symfony/polyfill-php72/tree/v1.20.0"
|
"source": "https://github.com/symfony/polyfill-php72/tree/v1.22.0"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@@ -5728,7 +5805,7 @@
|
|||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2020-10-23T14:02:19+00:00"
|
"time": "2021-01-07T16:49:33+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/stopwatch",
|
"name": "symfony/stopwatch",
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
<?php
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace LotGD\Core\Exceptions;
|
||||||
|
|
||||||
|
class InsecureTwigTemplateError extends CoreException
|
||||||
|
{
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
<?php
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
|
||||||
|
namespace LotGD\Core\Services;
|
||||||
|
|
||||||
|
|
||||||
|
use Twig\Error\LoaderError;
|
||||||
|
use Twig\Loader\LoaderInterface;
|
||||||
|
use Twig\Source;
|
||||||
|
|
||||||
|
class TwigNullLoader implements LoaderInterface
|
||||||
|
{
|
||||||
|
public function getSourceContext(string $name): Source
|
||||||
|
{
|
||||||
|
throw new LoaderError("Should not get called.");
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getCacheKey(string $name): string
|
||||||
|
{
|
||||||
|
throw new LoaderError("Should not get called.");
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isFresh(string $name, int $time): bool
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function exists(string $name)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,74 @@
|
|||||||
|
<?php
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
|
||||||
|
namespace LotGD\Core\Services;
|
||||||
|
|
||||||
|
|
||||||
|
use LotGD\Core\Exceptions\InsecureTwigTemplateError;
|
||||||
|
use LotGD\Core\Game;
|
||||||
|
use LotGD\Core\Models\Character;
|
||||||
|
use LotGD\Core\Models\Scene;
|
||||||
|
use Twig\Environment;
|
||||||
|
use Twig\Extension\SandboxExtension;
|
||||||
|
use Twig\Sandbox\SecurityError;
|
||||||
|
use Twig\Sandbox\SecurityPolicy;
|
||||||
|
|
||||||
|
class TwigSceneRenderer
|
||||||
|
{
|
||||||
|
private Environment $twig;
|
||||||
|
|
||||||
|
public function __construct(
|
||||||
|
private Game $game
|
||||||
|
) {
|
||||||
|
$this->twig = new Environment(new TwigNullLoader());
|
||||||
|
|
||||||
|
$securityPolicy = $this->getSecurityPolicy();
|
||||||
|
|
||||||
|
# Add Sandbox extension
|
||||||
|
$this->twig->addExtension(new SandboxExtension($securityPolicy, sandboxed: true));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function render(string $string, Scene $scene, bool $ignoreErrors = false): string
|
||||||
|
{
|
||||||
|
$template = $this->twig->createTemplate($string);
|
||||||
|
|
||||||
|
$templateValues = [
|
||||||
|
"Character" => $this->game->getCharacter(),
|
||||||
|
"Scene" => $scene,
|
||||||
|
];
|
||||||
|
|
||||||
|
// @Todo: Event to add property to the template
|
||||||
|
|
||||||
|
try {
|
||||||
|
// This will throw a SecurityError
|
||||||
|
$result = $template->render($templateValues);
|
||||||
|
} catch (SecurityError $e) {
|
||||||
|
if ($ignoreErrors) {
|
||||||
|
return $string;
|
||||||
|
} else {
|
||||||
|
throw new InsecureTwigTemplateError("Template contains illegal calls: {$e->getMessage()}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getSecurityPolicy(): SecurityPolicy
|
||||||
|
{
|
||||||
|
$tags = ["if"];
|
||||||
|
$filters = ["lower", "upper", "escape"];
|
||||||
|
$functions = ["range"];
|
||||||
|
$methods = [
|
||||||
|
Character::class => ["getDisplayName", "getLevel", "isAlive", "getHealth", "getMaxHealth", "getProperty"],
|
||||||
|
Scene::class => ["getProperty"],
|
||||||
|
];
|
||||||
|
$properties = [
|
||||||
|
"Character" => ["displayName", "level", "health", "maxHealth"],
|
||||||
|
];
|
||||||
|
|
||||||
|
// @ToDo: Event to change Security Policy
|
||||||
|
|
||||||
|
return new SecurityPolicy($tags, $filters, $methods, $properties, $functions);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace LotGD\Core\Tests\Managers;
|
namespace LotGD\Core\Tests\Services;
|
||||||
|
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
|
|
||||||
@@ -0,0 +1,164 @@
|
|||||||
|
<?php
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace LotGD\Core\Tests\Services;
|
||||||
|
|
||||||
|
use LotGD\Core\Exceptions\InsecureTwigTemplateError;
|
||||||
|
use LotGD\Core\Game;
|
||||||
|
use LotGD\Core\Models\Character;
|
||||||
|
use LotGD\Core\Models\Scene;
|
||||||
|
use LotGD\Core\PHPUnit\LotGDTestCase;
|
||||||
|
use LotGD\Core\Services\TwigSceneRenderer;
|
||||||
|
|
||||||
|
class TwigSceneRendererTest extends LotGDTestCase
|
||||||
|
{
|
||||||
|
protected function getGameMock(): Game
|
||||||
|
{
|
||||||
|
$game = $this->getMockBuilder(Game::class)
|
||||||
|
->disableOriginalConstructor()
|
||||||
|
->getMock();
|
||||||
|
|
||||||
|
return $game;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testIfSceneRendererCanBeConstructed()
|
||||||
|
{
|
||||||
|
$renderer = new TwigSceneRenderer($this->getGameMock());
|
||||||
|
|
||||||
|
$this->assertInstanceOf(TwigSceneRenderer::class, $renderer);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testIfTwigSceneRendererReturnsANonTemplateStringUnmodified()
|
||||||
|
{
|
||||||
|
# Get renderer
|
||||||
|
$renderer = new TwigSceneRenderer($this->getGameMock());
|
||||||
|
|
||||||
|
# Get mock scene
|
||||||
|
$scene = $this->getMockBuilder(Scene::class)
|
||||||
|
->disableOriginalConstructor()
|
||||||
|
->getMock();
|
||||||
|
|
||||||
|
# Prepare the template string.
|
||||||
|
$template = "You enter a new location.\n\nA new location.";
|
||||||
|
|
||||||
|
# Create the result
|
||||||
|
$renderResult = $renderer->render($template, $scene);
|
||||||
|
|
||||||
|
# Assert result
|
||||||
|
$this->assertSame($template, $renderResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testIfTwigSceneRendererParsesStringsWithCharacters()
|
||||||
|
{
|
||||||
|
# Get mock character
|
||||||
|
$character = $this->getMockBuilder(Character::class)
|
||||||
|
->disableOriginalConstructor()
|
||||||
|
->getMock();
|
||||||
|
$character->method("getDisplayName")->willReturn("Frodo");
|
||||||
|
$character->method("getLevel")->willReturn(5);
|
||||||
|
$character->method("getHealth")->willReturn(10);
|
||||||
|
$character->method("getMaxHealth")->willReturn(100);
|
||||||
|
$character->method("isAlive")->willReturn(true);
|
||||||
|
|
||||||
|
# Get mock game
|
||||||
|
$game = $this->getMockBuilder(Game::class)
|
||||||
|
->disableOriginalConstructor()
|
||||||
|
->getMock();
|
||||||
|
$game->method("getCharacter")->willReturn($character);
|
||||||
|
|
||||||
|
# Get mock scene
|
||||||
|
$scene = $this->getMockBuilder(Scene::class)
|
||||||
|
->disableOriginalConstructor()
|
||||||
|
->getMock();
|
||||||
|
|
||||||
|
# Get renderer
|
||||||
|
$renderer = new TwigSceneRenderer($game);
|
||||||
|
|
||||||
|
# Prepare the template string.
|
||||||
|
$template = "Hi {{ Character.getDisplayName }}! How are you today? Your level is {{ Character.level}}, and you have "
|
||||||
|
."{{ Character.health }} out of {{ Character.maxHealth }} health points."
|
||||||
|
."{% if Character.isAlive %} You are alive.{% endif %}";
|
||||||
|
|
||||||
|
$result = "Hi Frodo! How are you today? Your level is 5, and you have "
|
||||||
|
."10 out of 100 health points. "
|
||||||
|
."You are alive.";
|
||||||
|
|
||||||
|
# Create the result
|
||||||
|
$renderResult = $renderer->render($template, $scene);
|
||||||
|
|
||||||
|
# Assert result
|
||||||
|
$this->assertSame($result, $renderResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testIfRawTemplateGetsReturnedIfTemplateContainsIllegalTokens()
|
||||||
|
{
|
||||||
|
# Get mock character
|
||||||
|
$character = $this->getMockBuilder(Character::class)
|
||||||
|
->disableOriginalConstructor()
|
||||||
|
->getMock();
|
||||||
|
$character->method("getDisplayName")->willReturn("Frodo");
|
||||||
|
$character->method("getLevel")->willReturn(5);
|
||||||
|
$character->method("getHealth")->willReturn(10);
|
||||||
|
$character->method("getMaxHealth")->willReturn(100);
|
||||||
|
$character->method("isAlive")->willReturn(true);
|
||||||
|
|
||||||
|
# Get mock game
|
||||||
|
$game = $this->getMockBuilder(Game::class)
|
||||||
|
->disableOriginalConstructor()
|
||||||
|
->getMock();
|
||||||
|
$game->method("getCharacter")->willReturn($character);
|
||||||
|
|
||||||
|
# Get mock scene
|
||||||
|
$scene = $this->getMockBuilder(Scene::class)
|
||||||
|
->disableOriginalConstructor()
|
||||||
|
->getMock();
|
||||||
|
|
||||||
|
# Get renderer
|
||||||
|
$renderer = new TwigSceneRenderer($game);
|
||||||
|
|
||||||
|
# Prepare the template string.
|
||||||
|
$template = "Viewpoint: {{ Character.viewpoint }}";
|
||||||
|
|
||||||
|
# Try to parse the result
|
||||||
|
$renderResult = $renderer->render($template, $scene, true);
|
||||||
|
|
||||||
|
# If there was an error, it should have gotten ignored, giving back the raw template.
|
||||||
|
$this->assertSame($template, $renderResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testIfExceptionGetsRaisedIfTemplateContainsIllegalTokens()
|
||||||
|
{
|
||||||
|
# Get mock character
|
||||||
|
$character = $this->getMockBuilder(Character::class)
|
||||||
|
->disableOriginalConstructor()
|
||||||
|
->getMock();
|
||||||
|
$character->method("getDisplayName")->willReturn("Frodo");
|
||||||
|
$character->method("getLevel")->willReturn(5);
|
||||||
|
$character->method("getHealth")->willReturn(10);
|
||||||
|
$character->method("getMaxHealth")->willReturn(100);
|
||||||
|
$character->method("isAlive")->willReturn(true);
|
||||||
|
|
||||||
|
# Get mock game
|
||||||
|
$game = $this->getMockBuilder(Game::class)
|
||||||
|
->disableOriginalConstructor()
|
||||||
|
->getMock();
|
||||||
|
$game->method("getCharacter")->willReturn($character);
|
||||||
|
|
||||||
|
# Get mock scene
|
||||||
|
$scene = $this->getMockBuilder(Scene::class)
|
||||||
|
->disableOriginalConstructor()
|
||||||
|
->getMock();
|
||||||
|
|
||||||
|
# Get renderer
|
||||||
|
$renderer = new TwigSceneRenderer($game);
|
||||||
|
|
||||||
|
# Prepare the template string.
|
||||||
|
$template = "Viewpoint: {{ Character.viewpoint }}";
|
||||||
|
|
||||||
|
# Prepare the exception expectation
|
||||||
|
$this->expectException(InsecureTwigTemplateError::class);
|
||||||
|
|
||||||
|
# Try to parse the result
|
||||||
|
$renderResult = $renderer->render($template, $scene, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user