diff --git a/.editorconfig b/.editorconfig index 95342bf..08323bb 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,12 +1,27 @@ +# EditorConfig helps developers define and maintain consistent +# coding styles between different editors and IDEs # editorconfig.org root = true [*] -charset = utf-8 -indent_size = 2 +# Change these settings to your own preference indent_style = space -trim_trailing_whitespace = true +indent_size = 2 +max_line_length = 80 +# We recommend you to keep these unchanged +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true [*.{md,markdown}] trim_trailing_whitespace = false + +[*.php] +indent_style = space +indent_size = 4 + +[composer.json] +indent_style = space +indent_size = 4 diff --git a/.gitignore b/.gitignore index 38593c7..99de54b 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,8 @@ node_modules vendor dist src/shared-config* + +###> friendsofphp/php-cs-fixer ### +/.php-cs-fixer.php +/.php-cs-fixer.cache +###< friendsofphp/php-cs-fixer ### diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php new file mode 100644 index 0000000..1c79035 --- /dev/null +++ b/.php-cs-fixer.dist.php @@ -0,0 +1,12 @@ +in(__DIR__) + ->exclude('var'); + +return (new PhpCsFixer\Config()) + ->setRules([ + '@PhpCsFixer' => true, + ]) + ->setFinder($finder) + ->setCacheFile(__DIR__.'/.php-cs-fixer.cache'); diff --git a/__tests__/twig-extensions/alter-twig.php b/__tests__/twig-extensions/alter-twig.php index 0cf652f..a4b8f24 100644 --- a/__tests__/twig-extensions/alter-twig.php +++ b/__tests__/twig-extensions/alter-twig.php @@ -1,10 +1,11 @@ addFunction(new TwigFunction('customTwigFunctionThatSaysWorld', static fn(): string => 'Custom World')); +function addCustomExtension(Environment &$twigEnvironment, $config): void +{ + $twigEnvironment->addFunction(new TwigFunction('customTwigFunctionThatSaysWorld', static fn (): string => 'Custom World')); } diff --git a/composer.json b/composer.json index be681fc..41483a0 100644 --- a/composer.json +++ b/composer.json @@ -1,15 +1,25 @@ { - "name": "basaltinc/twig-renderer", - "description": "Render templates using Twig PHP, via this Node JS renderer.", - "license": "MIT", - "autoload": { - "psr-4": { - "BasaltInc\\TwigRenderer\\": "dist/" - } - }, - "require": { - "ext-json": "*", - "twig/twig": "^2.12", - "react/http": "^0.8.3" - } + "name": "basaltinc/twig-renderer", + "description": "Render templates using Twig PHP, via this Node JS renderer.", + "license": "MIT", + "autoload": { + "psr-4": { + "BasaltInc\\": "dist/" + } + }, + "config": { + "platfrom": { + "php": "8.2" + } + }, + "require": { + "php": ">=8.1", + "ext-json": "*", + "react/http": "^0.8.3", + "twig/twig": "^2.12" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^3.38.0" + }, + "sort-packages": true } diff --git a/composer.lock b/composer.lock index f965997..a7db20f 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "6e7695ac4ac0be2f471e853a31c12c38", + "content-hash": "e1f5f6aea865b648b21ffea9826cf00e", "packages": [ { "name": "evenement/evenement", @@ -256,16 +256,16 @@ }, { "name": "react/event-loop", - "version": "v1.4.0", + "version": "v1.5.0", "source": { "type": "git", "url": "https://github.com/reactphp/event-loop.git", - "reference": "6e7e587714fff7a83dcc7025aee42ab3b265ae05" + "reference": "bbe0bd8c51ffc05ee43f1729087ed3bdf7d53354" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/reactphp/event-loop/zipball/6e7e587714fff7a83dcc7025aee42ab3b265ae05", - "reference": "6e7e587714fff7a83dcc7025aee42ab3b265ae05", + "url": "https://api.github.com/repos/reactphp/event-loop/zipball/bbe0bd8c51ffc05ee43f1729087ed3bdf7d53354", + "reference": "bbe0bd8c51ffc05ee43f1729087ed3bdf7d53354", "shasum": "" }, "require": { @@ -316,7 +316,7 @@ ], "support": { "issues": "https://github.com/reactphp/event-loop/issues", - "source": "https://github.com/reactphp/event-loop/tree/v1.4.0" + "source": "https://github.com/reactphp/event-loop/tree/v1.5.0" }, "funding": [ { @@ -324,7 +324,7 @@ "type": "open_collective" } ], - "time": "2023-05-05T10:11:24+00:00" + "time": "2023-11-13T13:48:05+00:00" }, { "name": "react/http", @@ -1070,13 +1070,1671 @@ "time": "2023-05-03T17:49:41+00:00" } ], - "packages-dev": [], + "packages-dev": [ + { + "name": "composer/pcre", + "version": "3.1.1", + "source": { + "type": "git", + "url": "https://github.com/composer/pcre.git", + "reference": "00104306927c7a0919b4ced2aaa6782c1e61a3c9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/pcre/zipball/00104306927c7a0919b4ced2aaa6782c1e61a3c9", + "reference": "00104306927c7a0919b4ced2aaa6782c1e61a3c9", + "shasum": "" + }, + "require": { + "php": "^7.4 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^1.3", + "phpstan/phpstan-strict-rules": "^1.1", + "symfony/phpunit-bridge": "^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Pcre\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "PCRE wrapping library that offers type-safe preg_* replacements.", + "keywords": [ + "PCRE", + "preg", + "regex", + "regular expression" + ], + "support": { + "issues": "https://github.com/composer/pcre/issues", + "source": "https://github.com/composer/pcre/tree/3.1.1" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2023-10-11T07:11:09+00:00" + }, + { + "name": "composer/semver", + "version": "3.4.0", + "source": { + "type": "git", + "url": "https://github.com/composer/semver.git", + "reference": "35e8d0af4486141bc745f23a29cc2091eb624a32" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/semver/zipball/35e8d0af4486141bc745f23a29cc2091eb624a32", + "reference": "35e8d0af4486141bc745f23a29cc2091eb624a32", + "shasum": "" + }, + "require": { + "php": "^5.3.2 || ^7.0 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^1.4", + "symfony/phpunit-bridge": "^4.2 || ^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Semver\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nils Adermann", + "email": "naderman@naderman.de", + "homepage": "http://www.naderman.de" + }, + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + }, + { + "name": "Rob Bast", + "email": "rob.bast@gmail.com", + "homepage": "http://robbast.nl" + } + ], + "description": "Semver library that offers utilities, version constraint parsing and validation.", + "keywords": [ + "semantic", + "semver", + "validation", + "versioning" + ], + "support": { + "irc": "ircs://irc.libera.chat:6697/composer", + "issues": "https://github.com/composer/semver/issues", + "source": "https://github.com/composer/semver/tree/3.4.0" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2023-08-31T09:50:34+00:00" + }, + { + "name": "composer/xdebug-handler", + "version": "3.0.3", + "source": { + "type": "git", + "url": "https://github.com/composer/xdebug-handler.git", + "reference": "ced299686f41dce890debac69273b47ffe98a40c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/ced299686f41dce890debac69273b47ffe98a40c", + "reference": "ced299686f41dce890debac69273b47ffe98a40c", + "shasum": "" + }, + "require": { + "composer/pcre": "^1 || ^2 || ^3", + "php": "^7.2.5 || ^8.0", + "psr/log": "^1 || ^2 || ^3" + }, + "require-dev": { + "phpstan/phpstan": "^1.0", + "phpstan/phpstan-strict-rules": "^1.1", + "symfony/phpunit-bridge": "^6.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Composer\\XdebugHandler\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "John Stevenson", + "email": "john-stevenson@blueyonder.co.uk" + } + ], + "description": "Restarts a process without Xdebug.", + "keywords": [ + "Xdebug", + "performance" + ], + "support": { + "irc": "irc://irc.freenode.org/composer", + "issues": "https://github.com/composer/xdebug-handler/issues", + "source": "https://github.com/composer/xdebug-handler/tree/3.0.3" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2022-02-25T21:32:43+00:00" + }, + { + "name": "friendsofphp/php-cs-fixer", + "version": "v3.38.2", + "source": { + "type": "git", + "url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git", + "reference": "d872cdd543797ade030aaa307c0a4954a712e081" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/d872cdd543797ade030aaa307c0a4954a712e081", + "reference": "d872cdd543797ade030aaa307c0a4954a712e081", + "shasum": "" + }, + "require": { + "composer/semver": "^3.3", + "composer/xdebug-handler": "^3.0.3", + "ext-json": "*", + "ext-tokenizer": "*", + "php": "^7.4 || ^8.0", + "sebastian/diff": "^4.0 || ^5.0", + "symfony/console": "^5.4 || ^6.0", + "symfony/event-dispatcher": "^5.4 || ^6.0", + "symfony/filesystem": "^5.4 || ^6.0", + "symfony/finder": "^5.4 || ^6.0", + "symfony/options-resolver": "^5.4 || ^6.0", + "symfony/polyfill-mbstring": "^1.27", + "symfony/polyfill-php80": "^1.27", + "symfony/polyfill-php81": "^1.27", + "symfony/process": "^5.4 || ^6.0", + "symfony/stopwatch": "^5.4 || ^6.0" + }, + "require-dev": { + "facile-it/paraunit": "^1.3 || ^2.0", + "justinrainbow/json-schema": "^5.2", + "keradus/cli-executor": "^2.0", + "mikey179/vfsstream": "^1.6.11", + "php-coveralls/php-coveralls": "^2.5.3", + "php-cs-fixer/accessible-object": "^1.1", + "php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.2", + "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.2.1", + "phpspec/prophecy": "^1.16", + "phpspec/prophecy-phpunit": "^2.0", + "phpunit/phpunit": "^9.5", + "symfony/phpunit-bridge": "^6.2.3", + "symfony/yaml": "^5.4 || ^6.0" + }, + "suggest": { + "ext-dom": "For handling output formats in XML", + "ext-mbstring": "For handling non-UTF8 characters." + }, + "bin": [ + "php-cs-fixer" + ], + "type": "application", + "autoload": { + "psr-4": { + "PhpCsFixer\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Dariusz RumiĆski", + "email": "dariusz.ruminski@gmail.com" + } + ], + "description": "A tool to automatically fix PHP code style", + "keywords": [ + "Static code analysis", + "fixer", + "standards", + "static analysis" + ], + "support": { + "issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues", + "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.38.2" + }, + "funding": [ + { + "url": "https://github.com/keradus", + "type": "github" + } + ], + "time": "2023-11-14T00:19:22+00:00" + }, + { + "name": "psr/container", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/container.git", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "shasum": "" + }, + "require": { + "php": ">=7.4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Container\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common Container Interface (PHP FIG PSR-11)", + "homepage": "https://github.com/php-fig/container", + "keywords": [ + "PSR-11", + "container", + "container-interface", + "container-interop", + "psr" + ], + "support": { + "issues": "https://github.com/php-fig/container/issues", + "source": "https://github.com/php-fig/container/tree/2.0.2" + }, + "time": "2021-11-05T16:47:00+00:00" + }, + { + "name": "psr/event-dispatcher", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/event-dispatcher.git", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/event-dispatcher/zipball/dbefd12671e8a14ec7f180cab83036ed26714bb0", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0", + "shasum": "" + }, + "require": { + "php": ">=7.2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\EventDispatcher\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Standard interfaces for event handling.", + "keywords": [ + "events", + "psr", + "psr-14" + ], + "support": { + "issues": "https://github.com/php-fig/event-dispatcher/issues", + "source": "https://github.com/php-fig/event-dispatcher/tree/1.0.0" + }, + "time": "2019-01-08T18:20:26+00:00" + }, + { + "name": "psr/log", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/fe5ea303b0887d5caefd3d431c3e61ad47037001", + "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001", + "shasum": "" + }, + "require": { + "php": ">=8.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "support": { + "source": "https://github.com/php-fig/log/tree/3.0.0" + }, + "time": "2021-07-14T16:46:02+00:00" + }, + { + "name": "sebastian/diff", + "version": "5.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "912dc2fbe3e3c1e7873313cc801b100b6c68c87b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/912dc2fbe3e3c1e7873313cc801b100b6c68c87b", + "reference": "912dc2fbe3e3c1e7873313cc801b100b6c68c87b", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0", + "symfony/process": "^4.2 || ^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + } + ], + "description": "Diff implementation", + "homepage": "https://github.com/sebastianbergmann/diff", + "keywords": [ + "diff", + "udiff", + "unidiff", + "unified diff" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/diff/issues", + "security": "https://github.com/sebastianbergmann/diff/security/policy", + "source": "https://github.com/sebastianbergmann/diff/tree/5.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-05-01T07:48:21+00:00" + }, + { + "name": "symfony/console", + "version": "v6.3.8", + "source": { + "type": "git", + "url": "https://github.com/symfony/console.git", + "reference": "0d14a9f6d04d4ac38a8cea1171f4554e325dae92" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/console/zipball/0d14a9f6d04d4ac38a8cea1171f4554e325dae92", + "reference": "0d14a9f6d04d4ac38a8cea1171f4554e325dae92", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/polyfill-mbstring": "~1.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/string": "^5.4|^6.0" + }, + "conflict": { + "symfony/dependency-injection": "<5.4", + "symfony/dotenv": "<5.4", + "symfony/event-dispatcher": "<5.4", + "symfony/lock": "<5.4", + "symfony/process": "<5.4" + }, + "provide": { + "psr/log-implementation": "1.0|2.0|3.0" + }, + "require-dev": { + "psr/log": "^1|^2|^3", + "symfony/config": "^5.4|^6.0", + "symfony/dependency-injection": "^5.4|^6.0", + "symfony/event-dispatcher": "^5.4|^6.0", + "symfony/lock": "^5.4|^6.0", + "symfony/process": "^5.4|^6.0", + "symfony/var-dumper": "^5.4|^6.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Console\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Eases the creation of beautiful and testable command line interfaces", + "homepage": "https://symfony.com", + "keywords": [ + "cli", + "command-line", + "console", + "terminal" + ], + "support": { + "source": "https://github.com/symfony/console/tree/v6.3.8" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-10-31T08:09:35+00:00" + }, + { + "name": "symfony/deprecation-contracts", + "version": "v3.3.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/deprecation-contracts.git", + "reference": "7c3aff79d10325257a001fcf92d991f24fc967cf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/7c3aff79d10325257a001fcf92d991f24fc967cf", + "reference": "7c3aff79d10325257a001fcf92d991f24fc967cf", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.4-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "files": [ + "function.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "A generic function and convention to trigger deprecation notices", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.3.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-05-23T14:45:45+00:00" + }, + { + "name": "symfony/event-dispatcher", + "version": "v6.3.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher.git", + "reference": "adb01fe097a4ee930db9258a3cc906b5beb5cf2e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/adb01fe097a4ee930db9258a3cc906b5beb5cf2e", + "reference": "adb01fe097a4ee930db9258a3cc906b5beb5cf2e", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/event-dispatcher-contracts": "^2.5|^3" + }, + "conflict": { + "symfony/dependency-injection": "<5.4", + "symfony/service-contracts": "<2.5" + }, + "provide": { + "psr/event-dispatcher-implementation": "1.0", + "symfony/event-dispatcher-implementation": "2.0|3.0" + }, + "require-dev": { + "psr/log": "^1|^2|^3", + "symfony/config": "^5.4|^6.0", + "symfony/dependency-injection": "^5.4|^6.0", + "symfony/error-handler": "^5.4|^6.0", + "symfony/expression-language": "^5.4|^6.0", + "symfony/http-foundation": "^5.4|^6.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/stopwatch": "^5.4|^6.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\EventDispatcher\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/event-dispatcher/tree/v6.3.2" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-07-06T06:56:43+00:00" + }, + { + "name": "symfony/event-dispatcher-contracts", + "version": "v3.3.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher-contracts.git", + "reference": "a76aed96a42d2b521153fb382d418e30d18b59df" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/a76aed96a42d2b521153fb382d418e30d18b59df", + "reference": "a76aed96a42d2b521153fb382d418e30d18b59df", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/event-dispatcher": "^1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.4-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\EventDispatcher\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to dispatching event", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.3.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-05-23T14:45:45+00:00" + }, + { + "name": "symfony/filesystem", + "version": "v6.3.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/filesystem.git", + "reference": "edd36776956f2a6fcf577edb5b05eb0e3bdc52ae" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/edd36776956f2a6fcf577edb5b05eb0e3bdc52ae", + "reference": "edd36776956f2a6fcf577edb5b05eb0e3bdc52ae", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-mbstring": "~1.8" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Filesystem\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides basic utilities for the filesystem", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/filesystem/tree/v6.3.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-06-01T08:30:39+00:00" + }, + { + "name": "symfony/finder", + "version": "v6.3.5", + "source": { + "type": "git", + "url": "https://github.com/symfony/finder.git", + "reference": "a1b31d88c0e998168ca7792f222cbecee47428c4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/finder/zipball/a1b31d88c0e998168ca7792f222cbecee47428c4", + "reference": "a1b31d88c0e998168ca7792f222cbecee47428c4", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "symfony/filesystem": "^6.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Finder\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Finds files and directories via an intuitive fluent interface", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/finder/tree/v6.3.5" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-09-26T12:56:25+00:00" + }, + { + "name": "symfony/options-resolver", + "version": "v6.3.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/options-resolver.git", + "reference": "a10f19f5198d589d5c33333cffe98dc9820332dd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/options-resolver/zipball/a10f19f5198d589d5c33333cffe98dc9820332dd", + "reference": "a10f19f5198d589d5c33333cffe98dc9820332dd", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.5|^3" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\OptionsResolver\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides an improved replacement for the array_replace PHP function", + "homepage": "https://symfony.com", + "keywords": [ + "config", + "configuration", + "options" + ], + "support": { + "source": "https://github.com/symfony/options-resolver/tree/v6.3.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-05-12T14:21:09+00:00" + }, + { + "name": "symfony/polyfill-intl-grapheme", + "version": "v1.28.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-grapheme.git", + "reference": "875e90aeea2777b6f135677f618529449334a612" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/875e90aeea2777b6f135677f618529449334a612", + "reference": "875e90aeea2777b6f135677f618529449334a612", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.28-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Grapheme\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's grapheme_* functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "grapheme", + "intl", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.28.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-01-26T09:26:14+00:00" + }, + { + "name": "symfony/polyfill-intl-normalizer", + "version": "v1.28.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-normalizer.git", + "reference": "8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92", + "reference": "8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.28-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Normalizer\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's Normalizer class and related functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "intl", + "normalizer", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.28.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-01-26T09:26:14+00:00" + }, + { + "name": "symfony/polyfill-php80", + "version": "v1.28.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php80.git", + "reference": "6caa57379c4aec19c0a12a38b59b26487dcfe4b5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/6caa57379c4aec19c0a12a38b59b26487dcfe4b5", + "reference": "6caa57379c4aec19c0a12a38b59b26487dcfe4b5", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.28-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php80\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ion Bazan", + "email": "ion.bazan@gmail.com" + }, + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php80/tree/v1.28.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-01-26T09:26:14+00:00" + }, + { + "name": "symfony/polyfill-php81", + "version": "v1.28.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php81.git", + "reference": "7581cd600fa9fd681b797d00b02f068e2f13263b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/7581cd600fa9fd681b797d00b02f068e2f13263b", + "reference": "7581cd600fa9fd681b797d00b02f068e2f13263b", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.28-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php81\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.1+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php81/tree/v1.28.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-01-26T09:26:14+00:00" + }, + { + "name": "symfony/process", + "version": "v6.3.4", + "source": { + "type": "git", + "url": "https://github.com/symfony/process.git", + "reference": "0b5c29118f2e980d455d2e34a5659f4579847c54" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/process/zipball/0b5c29118f2e980d455d2e34a5659f4579847c54", + "reference": "0b5c29118f2e980d455d2e34a5659f4579847c54", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Process\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Executes commands in sub-processes", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/process/tree/v6.3.4" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-08-07T10:39:22+00:00" + }, + { + "name": "symfony/service-contracts", + "version": "v3.3.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/service-contracts.git", + "reference": "40da9cc13ec349d9e4966ce18b5fbcd724ab10a4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/40da9cc13ec349d9e4966ce18b5fbcd724ab10a4", + "reference": "40da9cc13ec349d9e4966ce18b5fbcd724ab10a4", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/container": "^2.0" + }, + "conflict": { + "ext-psr": "<1.1|>=2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.4-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\Service\\": "" + }, + "exclude-from-classmap": [ + "/Test/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to writing services", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/service-contracts/tree/v3.3.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-05-23T14:45:45+00:00" + }, + { + "name": "symfony/stopwatch", + "version": "v6.3.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/stopwatch.git", + "reference": "fc47f1015ec80927ff64ba9094dfe8b9d48fe9f2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/stopwatch/zipball/fc47f1015ec80927ff64ba9094dfe8b9d48fe9f2", + "reference": "fc47f1015ec80927ff64ba9094dfe8b9d48fe9f2", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/service-contracts": "^2.5|^3" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Stopwatch\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides a way to profile code", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/stopwatch/tree/v6.3.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-02-16T10:14:28+00:00" + }, + { + "name": "symfony/string", + "version": "v6.3.8", + "source": { + "type": "git", + "url": "https://github.com/symfony/string.git", + "reference": "13880a87790c76ef994c91e87efb96134522577a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/string/zipball/13880a87790c76ef994c91e87efb96134522577a", + "reference": "13880a87790c76ef994c91e87efb96134522577a", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-intl-grapheme": "~1.0", + "symfony/polyfill-intl-normalizer": "~1.0", + "symfony/polyfill-mbstring": "~1.0" + }, + "conflict": { + "symfony/translation-contracts": "<2.5" + }, + "require-dev": { + "symfony/error-handler": "^5.4|^6.0", + "symfony/http-client": "^5.4|^6.0", + "symfony/intl": "^6.2", + "symfony/translation-contracts": "^2.5|^3.0", + "symfony/var-exporter": "^5.4|^6.0" + }, + "type": "library", + "autoload": { + "files": [ + "Resources/functions.php" + ], + "psr-4": { + "Symfony\\Component\\String\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides an object-oriented API to strings and deals with bytes, UTF-8 code points and grapheme clusters in a unified way", + "homepage": "https://symfony.com", + "keywords": [ + "grapheme", + "i18n", + "string", + "unicode", + "utf-8", + "utf8" + ], + "support": { + "source": "https://github.com/symfony/string/tree/v6.3.8" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-11-09T08:28:21+00:00" + } + ], "aliases": [], "minimum-stability": "stable", "stability-flags": [], "prefer-stable": false, "prefer-lowest": false, "platform": { + "php": ">=8.1", "ext-json": "*" }, "platform-dev": [], diff --git a/src/TwigRenderer.php b/src/TwigRenderer.php index 03a6c05..7983769 100644 --- a/src/TwigRenderer.php +++ b/src/TwigRenderer.php @@ -1,147 +1,151 @@ config['relativeFrom'])) { - $rootPath = $this->config['relativeFrom']; - } - $this->loader = new FilesystemLoader($this->config['src']['roots'], $rootPath); +final class TwigRenderer +{ + private readonly Environment $twigEnvironment; + + private readonly FilesystemLoader $filesystemLoader; + + private readonly ChainLoader $chainLoader; + + public function __construct(public array $config) + { + $rootPath = getcwd(); + if (isset($this->config['relativeFrom'])) { + $rootPath = $this->config['relativeFrom']; + } - if (isset($this->config['src']['namespaces'])) { - foreach ($this->config['src']['namespaces'] as $namespace) { - foreach ($namespace['paths'] as $path) { - $this->loader->addPath($path, $namespace['id']); + $this->filesystemLoader = new FilesystemLoader($this->config['src']['roots'], $rootPath); + + if (isset($this->config['src']['namespaces'])) { + foreach ($this->config['src']['namespaces'] as $namespace) { + foreach ($namespace['paths'] as $path) { + $this->filesystemLoader->addPath($path, $namespace['id']); + } + } } - } + + $this->chainLoader = new ChainLoader([ + $this->filesystemLoader, + ]); + + $this->twigEnvironment = $this->createTwigEnv($this->chainLoader); } - $this->loaders = new ChainLoader([ - $this->loader, - ]); - - $this->twig = $this->createTwigEnv($this->loaders); - } - - private function createTwigEnv(\Twig\Loader\ChainLoader $chainLoader): \Twig\Environment { - $twigEnvironment = new Environment($chainLoader, [ - 'debug' => $this->config['debug'], - 'autoescape' => $this->config['autoescape'], - 'cache' => false, // @todo Implement Twig caching - ]); - - if (isset($this->config['alterTwigEnv'])) { - foreach ($this->config['alterTwigEnv'] as $alter) { - $file = $alter['file']; - require_once $file; - foreach ($alter['functions'] as $function) { - $function($twigEnvironment, $this->config); + public function renderString($templateString, array $data = []) + { + $templateName = 'StringRenderer'; // @todo ensure this simple name is ok; should be! + $arrayLoader = new ArrayLoader([ + $templateName => $templateString, + ]); + + $chainLoader = new ChainLoader([ + $arrayLoader, + $this->filesystemLoader, + ]); + + $twig = $this->createTwigEnv($chainLoader); + + try { + $html = $twig->render($templateName, $data); + $response = [ + 'ok' => true, + 'html' => trim((string) $html), + 'message' => '', + ]; + } catch (\Exception $exception) { + $message = 'Error trying to render twig string. '.$exception->getMessage(); + $response = [ + 'ok' => false, + 'message' => $message, + 'html' => '
'.$message.'
',
+ ];
}
- }
+
+ return $response;
}
- return $twigEnvironment;
- }
-
- public function renderString($templateString, array $data = []) {
- $templateName = 'StringRenderer'; // @todo ensure this simple name is ok; should be!
- $arrayLoader = new ArrayLoader([
- $templateName => $templateString,
- ]);
-
- $chainLoader = new ChainLoader([
- $arrayLoader,
- $this->loader,
- ]);
-
- $twig = $this->createTwigEnv($chainLoader);
-
- try {
- $html = $twig->render($templateName, $data);
- $response = [
- 'ok' => true,
- 'html' => trim((string) $html),
- 'message' => '',
- ];
- } catch (\Exception $exception) {
- $message = 'Error trying to render twig string. ' . $exception->getMessage();
- $response = [
- 'ok' => false,
- 'message' => $message,
- 'html' => '' . $message . '
',
- ];
+ public function render(string $templatePath, array $data = [])
+ {
+ try {
+ $template = $this->twigEnvironment->load($templatePath);
+ $html = $template->render($data);
+ $response = [
+ 'ok' => true,
+ 'html' => trim((string) $html),
+ 'message' => '',
+ ];
+ } catch (\Exception $exception) {
+ $message = 'Error trying to render "'.$templatePath.'". '.$exception->getMessage();
+ $response = [
+ 'ok' => false,
+ 'message' => $message,
+ 'html' => ''.$message.'
',
+ ];
+ }
+
+ if ($this->config['hasExtraInfoInResponses']) {
+ $response['info'] = $this->getInfo();
+ }
+
+ return $response;
}
- return $response;
- }
-
- public function render(string $templatePath, array $data = []) {
- try {
- $template = $this->twig->load($templatePath);
- $html = $template->render($data);
- $response = [
- 'ok' => true,
- 'html' => trim((string) $html),
- 'message' => '',
- ];
- } catch (\Exception $exception) {
- $message = 'Error trying to render "' . $templatePath . '". ' . $exception->getMessage();
- $response = [
- 'ok' => false,
- 'message' => $message,
- 'html' => '' . $message . '
',
- ];
+
+ public function getTwig(): Environment
+ {
+ return $this->twigEnvironment;
}
- if ($this->config['hasExtraInfoInResponses']) {
- $response['info'] = $this->getInfo();
+
+ public function getInfo()
+ {
+ try {
+ $info = [
+ 'namespaces' => $this->filesystemLoader->getNamespaces(),
+ 'src' => array_map(fn ($x): array => [
+ 'namespace' => $x,
+ 'paths' => $this->filesystemLoader->getPaths($x),
+ ], $this->filesystemLoader->getNamespaces()),
+ 'extensions' => array_map(static fn ($ext): array => [
+ 'name' => $ext->getName(),
+ ], $this->twigEnvironment->getExtensions()),
+ ];
+ } catch (\Exception $exception) {
+ $info = [
+ 'message' => 'Exception thrown trying to get info. '.$exception->getMessage(),
+ ];
+ }
+
+ return $info;
}
- return $response;
- }
-
- public function getTwig(): \Twig\Environment {
- return $this->twig;
- }
-
- public function getInfo() {
- try {
- $info = [
- 'namespaces' => $this->loader->getNamespaces(),
- 'src' => array_map(fn($x): array => [
- 'namespace' => $x,
- 'paths' => $this->loader->getPaths($x),
- ], $this->loader->getNamespaces()),
- 'extensions' => array_map(fn($ext): array => [
- 'name' => $ext->getName(),
- ], $this->twig->getExtensions()),
- ];
- } catch (\Exception $e) {
- $info = [
- 'message' => 'Exception thrown trying to get info. ' . $e->getMessage(),
- ];
+
+ private function createTwigEnv(ChainLoader $chainLoader): Environment
+ {
+ $twigEnvironment = new Environment($chainLoader, [
+ 'debug' => $this->config['debug'],
+ 'autoescape' => $this->config['autoescape'],
+ 'cache' => false, // @todo Implement Twig caching
+ ]);
+
+ if (isset($this->config['alterTwigEnv'])) {
+ foreach ($this->config['alterTwigEnv'] as $alter) {
+ $file = $alter['file'];
+
+ require_once $file;
+ foreach ($alter['functions'] as $function) {
+ $function($twigEnvironment, $this->config);
+ }
+ }
+ }
+
+ return $twigEnvironment;
}
- return $info;
- }
}
diff --git a/src/server--async.php b/src/server--async.php
index f6a9f8c..e5b7883 100644
--- a/src/server--async.php
+++ b/src/server--async.php
@@ -1,8 +1,8 @@
getMessage();
- $responseCode = 500;
+ $config = json_decode($configString, true, 512, JSON_THROW_ON_ERROR);
+} catch (\Exception $exception) {
+ $msgs[] = 'Error parsing JSON from config';
+ $msgs[] = $exception->getMessage();
+ $responseCode = 500;
}
$loop = Loop::get();
if ($config) {
- $twigRenderer = new TwigRenderer($config);
-// file_put_contents(__DIR__ . '/info.json', json_encode($twigRenderer->getInfo()));
+ $twigRenderer = new TwigRenderer($config);
+ // file_put_contents(__DIR__ . '/info.json', json_encode($twigRenderer->getInfo()));
}
-function formatResponseBody($msgs = [], $ok = false, $html = ''): string {
- return json_encode([
- 'ok' => $ok,
- 'message' => implode(' ', $msgs),
- 'html' => $html,
- ], JSON_THROW_ON_ERROR);
+function formatResponseBody($msgs = [], $ok = false, $html = ''): string
+{
+ return json_encode([
+ 'ok' => $ok,
+ 'message' => implode(' ', $msgs),
+ 'html' => $html,
+ ], JSON_THROW_ON_ERROR);
}
-$server = new Server(function (ServerRequestInterface $request) use (
- $config,
- $twigRenderer,
- &$counter,
- $responseCode,
- $loop
-): \React\Http\Response|\React\Promise\Promise {
- $headers = [
- 'Content-Type' => 'application/json',
- 'Access-Control-Allow-Origin' => '*',
- ];
- $msgs = [];
- $counter++;
- $method = $request->getMethod();
- $query = $request->getQueryParams();
- $body = $request->getBody()->getContents();
- try {
- $body = json_decode($body ?: '{}', true, 512, JSON_THROW_ON_ERROR);
- } catch (\Exception $e) {
- // @todo why doesn't this catch errors from malformed JSON?
- $msgs[] = 'Not able to parse JSON. ' . $e->getMessage();
- return new Response(400, $headers, formatResponseBody($msgs));
- }
-
- if (!isset($query['type'])) {
- return new Response(
- 202,
- $headers,
- json_encode([
- 'ok' => true,
- 'message' => 'No action correctly requested. Url must have a query param of \'templatePath\' for which twig template to render, but yes - the server is running.',
- ])
- );
- }
- // one of: meta, renderFile, renderString
- $type = $query['type'];
-
- switch ($type) {
- case 'meta':
- return new Response(
- 200,
- $headers,
- json_encode([
- 'ok' => true,
- 'info' => $twigRenderer->getInfo(),
- 'meta' => [
- 'counter' => $counter,
- 'query' => $query,
- 'body' => $body,
- 'method' => $method,
- ],
- ], JSON_THROW_ON_ERROR)
- );
-
- case 'renderFile':
- return new Promise(function ($resolve, $reject) use ($twigRenderer, $query, $body, $headers): void {
- $results = $twigRenderer->render($body['template'], $body['data']);
- $response = new Response(
- $results['ok'] ? 200 : 404,
- $headers,
- json_encode($results, JSON_THROW_ON_ERROR)
+$server = new Server(static function (ServerRequestInterface $request) use ($twigRenderer, &$counter): Response|Promise {
+ $headers = [
+ 'Content-Type' => 'application/json',
+ 'Access-Control-Allow-Origin' => '*',
+ ];
+ $msgs = [];
+ ++$counter;
+ $method = $request->getMethod();
+ $query = $request->getQueryParams();
+ $body = $request->getBody()->getContents();
+
+ try {
+ $body = json_decode($body ?: '{}', true, 512, JSON_THROW_ON_ERROR);
+ } catch (\Exception $exception) {
+ // @todo why doesn't this catch errors from malformed JSON?
+ $msgs[] = 'Not able to parse JSON. '.$exception->getMessage();
+
+ return new Response(400, $headers, formatResponseBody($msgs));
+ }
+
+ if (!isset($query['type'])) {
+ return new Response(
+ 202,
+ $headers,
+ json_encode([
+ 'ok' => true,
+ 'message' => "No action correctly requested. Url must have a query param of 'templatePath' for which twig template to render, but yes - the server is running.",
+ ])
);
- $resolve($response);
- });
-
- case 'renderString':
- return new Promise(function ($resolve, $reject) use ($twigRenderer, $query, $body, $headers): void {
- $results = $twigRenderer->renderString($body['template'], $body['data']);
- $response = new Response(
- $results['ok'] ? 200 : 404,
- $headers,
- json_encode($results, JSON_THROW_ON_ERROR)
- );
- $resolve($response);
- });
- }
+ }
+
+ // one of: meta, renderFile, renderString
+ $type = $query['type'];
+
+ switch ($type) {
+ case 'meta':
+ return new Response(
+ 200,
+ $headers,
+ json_encode([
+ 'ok' => true,
+ 'info' => $twigRenderer->getInfo(),
+ 'meta' => [
+ 'counter' => $counter,
+ 'query' => $query,
+ 'body' => $body,
+ 'method' => $method,
+ ],
+ ], JSON_THROW_ON_ERROR)
+ );
+
+ case 'renderFile':
+ return new Promise(static function ($resolve, $reject) use ($twigRenderer, $body, $headers): void {
+ $results = $twigRenderer->render($body['template'], $body['data']);
+ $response = new Response(
+ $results['ok'] ? 200 : 404,
+ $headers,
+ json_encode($results, JSON_THROW_ON_ERROR)
+ );
+ $resolve($response);
+ });
+
+ case 'renderString':
+ return new Promise(static function ($resolve, $reject) use ($twigRenderer, $body, $headers): void {
+ $results = $twigRenderer->renderString($body['template'], $body['data']);
+ $response = new Response(
+ $results['ok'] ? 200 : 404,
+ $headers,
+ json_encode($results, JSON_THROW_ON_ERROR)
+ );
+ $resolve($response);
+ });
+ }
});
$context = [];
-$uri = sprintf("127.0.0.1:%u",$port);
+$uri = sprintf('127.0.0.1:%u', $port);
$socket = new SocketServer($uri, $context, $loop);
-$server->on('error', function (Exception $e): void {
- echo 'PHP TwigRenderer Error: ' . $e->getMessage() . PHP_EOL;
+$server->on('error', static function (Exception $exception): void {
+ echo 'PHP TwigRenderer Error: '.$exception->getMessage().PHP_EOL;
});
$server->listen($socket);
if ($config['verbose']) {
- echo 'PHP Twig Render Server listening on ' . str_replace('tcp:', 'http:', $socket->getAddress()) . PHP_EOL;
+ echo 'PHP Twig Render Server listening on '.str_replace('tcp:', 'http:', $socket->getAddress()).PHP_EOL;
}
$loop->run();
diff --git a/src/server--sync.php b/src/server--sync.php
index 6cb2809..200eb13 100644
--- a/src/server--sync.php
+++ b/src/server--sync.php
@@ -1,12 +1,12 @@
getMessage();
- $responseCode = 500;
+ $config = json_decode($configString, true, 512, JSON_THROW_ON_ERROR);
+} catch (\Exception $exception) {
+ $msgs[] = 'Error parsing JSON from config';
+ $msgs[] = $exception->getMessage();
+ $responseCode = 500;
}
// `GET` or `POST`
@@ -48,61 +49,62 @@
// All query string params parsed
$query = [];
if (isset($_SERVER['QUERY_STRING'])) {
- parse_str((string) $_SERVER['QUERY_STRING'], $query);
+ parse_str((string) $_SERVER['QUERY_STRING'], $query);
}
if ($config) {
- try {
- $twigRenderer = new TwigRenderer($config);
- } catch (\Exception $e) {
- $msg = 'Error creating Twig Environment. ' . $e->getMessage();
- $msgs[] = $msg;
- $responseCode = 400;
- $response['ok'] = false;
- $response['message'] = $msg;
- }
+ try {
+ $twigRenderer = new TwigRenderer($config);
+ } catch (\Exception $e) {
+ $msg = 'Error creating Twig Environment. '.$e->getMessage();
+ $msgs[] = $msg;
+ $responseCode = 400;
+ $response['ok'] = false;
+ $response['message'] = $msg;
+ }
}
-if ($twigRenderer instanceof \BasaltInc\TwigRenderer\TwigRenderer) {
- if (array_key_exists('templatePath', $query)) {
- $templatePath = $query['templatePath'];
- } else {
- // @todo Provide more clear way to "ping" the server and know that it is ready.
- $msgs[] = "Url must have a query param of 'templatePath' for which twig template to render, but yes - the server is running.";
- $responseCode = 202;
- }
-
- if ($templatePath && $method === 'POST') {
- try {
- $json = file_get_contents('php://input');
- } catch(\Exception $e) {
- $msgs[] = 'No POST body found. ' . $e->getMessage();
- $responseCode = 400;
+if ($twigRenderer instanceof TwigRenderer) {
+ if (array_key_exists('templatePath', $query)) {
+ $templatePath = $query['templatePath'];
+ } else {
+ // @todo Provide more clear way to "ping" the server and know that it is ready.
+ $msgs[] = "Url must have a query param of 'templatePath' for which twig template to render, but yes - the server is running.";
+ $responseCode = 202;
}
- if ($json) {
- try {
- $data = json_decode($json, true, 512, JSON_THROW_ON_ERROR);
- } catch (\Exception $e) {
- $msgs[] = 'Not able to parse JSON. ' . $e->getMessage();
- $responseCode = 400;
- }
+
+ if ($templatePath && 'POST' === $method) {
+ try {
+ $json = file_get_contents('php://input');
+ } catch (\Exception $e) {
+ $msgs[] = 'No POST body found. '.$e->getMessage();
+ $responseCode = 400;
+ }
+
+ if ($json) {
+ try {
+ $data = json_decode($json, true, 512, JSON_THROW_ON_ERROR);
+ } catch (\Exception $e) {
+ $msgs[] = 'Not able to parse JSON. '.$e->getMessage();
+ $responseCode = 400;
+ }
+ }
}
- }
- if ($templatePath) {
- try {
- $response = $twigRenderer->render($templatePath, $data);
- $responseCode = 200;
- } catch (\Exception $e) {
- $msgs[] = $e->getMessage();
- $responseCode = 400;
+ if ($templatePath) {
+ try {
+ $response = $twigRenderer->render($templatePath, $data);
+ $responseCode = 200;
+ } catch (\Exception $e) {
+ $msgs[] = $e->getMessage();
+ $responseCode = 400;
+ }
}
- }
}
if ($msgs) {
- header('Warning: ' . implode(' ', $msgs));
-// $response['message'] = join(' ', $msgs);
+ header('Warning: '.implode(' ', $msgs));
+ // $response['message'] = join(' ', $msgs);
}
http_response_code($responseCode);