diff --git a/.github/workflows/symfony.yml b/.github/workflows/symfony.yml index 70cbb52..891f7ad 100644 --- a/.github/workflows/symfony.yml +++ b/.github/workflows/symfony.yml @@ -49,7 +49,7 @@ jobs: strategy: fail-fast: true matrix: - php-versions: ['8.2', '8.3'] + php-versions: ['8.3'] runs-on: ubuntu-latest # Setup ———————————————————————————————————————————————————————————————— @@ -122,5 +122,7 @@ jobs: run: castor lint:php - name: PHPStan static analysis run: castor stan + - name: Lint Twig templates with twigstan + run: castor lint:twigstan # The end. 🙃 diff --git a/.gitignore b/.gitignore index b0de3ae..5374e73 100644 --- a/.gitignore +++ b/.gitignore @@ -30,3 +30,7 @@ .phpunit.result.cache .phpunit.cache ###< phpunit/phpunit ### + +###> twigstan/twigstan ### +.twigstan +###< twigstan/twigstan ### diff --git a/castor.php b/castor.php index f3c6c9c..7ace00d 100644 --- a/castor.php +++ b/castor.php @@ -205,6 +205,14 @@ function lint_twig(): int return exit_code('bin/console lint:twig templates/'); } +#[AsTask(name: 'twigstan', namespace: 'lint', description: 'Lint Twig files with twigstan', aliases: ['lint-twigstan'])] +function lint_twigstan(): int +{ + title('lint:twigstan'); + + return exit_code('vendor/bin/twigstan'); +} + #[AsTask(name: 'yaml', namespace: 'lint', description: 'Lint Yaml files', aliases: ['lint-yaml'])] function lint_yaml(): int { @@ -220,7 +228,8 @@ function lint_all(): int $ec1 = lint_php(); $ec2 = lint_container(); $ec3 = lint_twig(); - $ec4 = lint_yaml(); + $ec4 = lint_twigstan(); + $ec5 = lint_yaml(); return success($ec1 + $ec2 + $ec3 + $ec4); diff --git a/composer.json b/composer.json index 27b1a20..e87e433 100644 --- a/composer.json +++ b/composer.json @@ -49,7 +49,7 @@ "require-dev": { "bamarni/composer-bin-plugin": "^1.8", "phpstan/extension-installer": "^1.3", - "phpstan/phpstan-symfony": "^2.0", + "phpstan/phpstan-symfony": "^1.0", "phpunit/phpunit": "^11.0", "roave/security-advisories": "dev-latest", "symfony/browser-kit": "~7.1.0", @@ -57,7 +57,8 @@ "symfony/maker-bundle": "^1.61", "symfony/requirements-checker": "^2.0", "symfony/stopwatch": "~7.1.0", - "symfony/web-profiler-bundle": "~7.1.0" + "symfony/web-profiler-bundle": "~7.1.0", + "twigstan/twigstan": "dev-main" }, "replace": { "symfony/polyfill-ctype": "*", diff --git a/composer.lock b/composer.lock index fea43a0..f3e08df 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": "e037fde2e1ee94aa91287693db228676", + "content-hash": "67fcdc4cef755ca3c9a28b2c8bab3e32", "packages": [ { "name": "composer/semver", @@ -4739,23 +4739,23 @@ }, { "name": "twig/extra-bundle", - "version": "v3.13.0", + "version": "v3.15.0", "source": { "type": "git", "url": "https://github.com/twigphp/twig-extra-bundle.git", - "reference": "21a9a7aa9f79d4493bb6fed4eb2794339f9551f5" + "reference": "9746573ca4bc1cd03a767a183faadaf84e0c31fa" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/twig-extra-bundle/zipball/21a9a7aa9f79d4493bb6fed4eb2794339f9551f5", - "reference": "21a9a7aa9f79d4493bb6fed4eb2794339f9551f5", + "url": "https://api.github.com/repos/twigphp/twig-extra-bundle/zipball/9746573ca4bc1cd03a767a183faadaf84e0c31fa", + "reference": "9746573ca4bc1cd03a767a183faadaf84e0c31fa", "shasum": "" }, "require": { "php": ">=8.0.2", "symfony/framework-bundle": "^5.4|^6.4|^7.0", "symfony/twig-bundle": "^5.4|^6.4|^7.0", - "twig/twig": "^3.0|^4.0" + "twig/twig": "^3.2|^4.0" }, "require-dev": { "league/commonmark": "^1.0|^2.0", @@ -4797,7 +4797,7 @@ "twig" ], "support": { - "source": "https://github.com/twigphp/twig-extra-bundle/tree/v3.13.0" + "source": "https://github.com/twigphp/twig-extra-bundle/tree/v3.15.0" }, "funding": [ { @@ -4809,11 +4809,11 @@ "type": "tidelift" } ], - "time": "2024-09-01T20:39:12+00:00" + "time": "2024-09-26T19:22:23+00:00" }, { "name": "twig/markdown-extra", - "version": "v3.13.0", + "version": "v3.15.0", "source": { "type": "git", "url": "https://github.com/twigphp/markdown-extra.git", @@ -4869,7 +4869,7 @@ "twig" ], "support": { - "source": "https://github.com/twigphp/markdown-extra/tree/v3.13.0" + "source": "https://github.com/twigphp/markdown-extra/tree/v3.15.0" }, "funding": [ { @@ -4885,16 +4885,16 @@ }, { "name": "twig/twig", - "version": "v3.14.2", + "version": "v3.15.0", "source": { "type": "git", "url": "https://github.com/twigphp/Twig.git", - "reference": "0b6f9d8370bb3b7f1ce5313ed8feb0fafd6e399a" + "reference": "2d5b3964cc21d0188633d7ddce732dc8e874db02" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/0b6f9d8370bb3b7f1ce5313ed8feb0fafd6e399a", - "reference": "0b6f9d8370bb3b7f1ce5313ed8feb0fafd6e399a", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/2d5b3964cc21d0188633d7ddce732dc8e874db02", + "reference": "2d5b3964cc21d0188633d7ddce732dc8e874db02", "shasum": "" }, "require": { @@ -4948,7 +4948,7 @@ ], "support": { "issues": "https://github.com/twigphp/Twig/issues", - "source": "https://github.com/twigphp/Twig/tree/v3.14.2" + "source": "https://github.com/twigphp/Twig/tree/v3.15.0" }, "funding": [ { @@ -4960,7 +4960,7 @@ "type": "tidelift" } ], - "time": "2024-11-07T12:36:22+00:00" + "time": "2024-11-17T15:59:19+00:00" } ], "packages-dev": [ @@ -5239,6 +5239,363 @@ ], "time": "2024-11-08T17:47:46+00:00" }, + { + "name": "nette/bootstrap", + "version": "v3.2.4", + "source": { + "type": "git", + "url": "https://github.com/nette/bootstrap.git", + "reference": "4876d25955b4164d714bc17c265f664f6594685b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/bootstrap/zipball/4876d25955b4164d714bc17c265f664f6594685b", + "reference": "4876d25955b4164d714bc17c265f664f6594685b", + "shasum": "" + }, + "require": { + "nette/di": "^3.1", + "nette/utils": "^3.2.1 || ^4.0", + "php": "8.0 - 8.4" + }, + "conflict": { + "tracy/tracy": "<2.6" + }, + "require-dev": { + "latte/latte": "^2.8 || ^3.0", + "nette/application": "^3.1", + "nette/caching": "^3.0", + "nette/database": "^3.0", + "nette/forms": "^3.0", + "nette/http": "^3.0", + "nette/mail": "^3.0 || ^4.0", + "nette/robot-loader": "^3.0 || ^4.0", + "nette/safe-stream": "^2.2", + "nette/security": "^3.0", + "nette/tester": "^2.4", + "phpstan/phpstan-nette": "^1.0", + "tracy/tracy": "^2.9" + }, + "suggest": { + "nette/robot-loader": "to use Configurator::createRobotLoader()", + "tracy/tracy": "to use Configurator::enableTracy()" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.2-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "🅱 Nette Bootstrap: the simple way to configure and bootstrap your Nette application.", + "homepage": "https://nette.org", + "keywords": [ + "bootstrapping", + "configurator", + "nette" + ], + "support": { + "issues": "https://github.com/nette/bootstrap/issues", + "source": "https://github.com/nette/bootstrap/tree/v3.2.4" + }, + "time": "2024-06-18T22:13:57+00:00" + }, + { + "name": "nette/di", + "version": "v3.2.3", + "source": { + "type": "git", + "url": "https://github.com/nette/di.git", + "reference": "9b9bfb43dac31c7804b2c8900217046cc0ca3307" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/di/zipball/9b9bfb43dac31c7804b2c8900217046cc0ca3307", + "reference": "9b9bfb43dac31c7804b2c8900217046cc0ca3307", + "shasum": "" + }, + "require": { + "ext-ctype": "*", + "ext-tokenizer": "*", + "nette/neon": "^3.3 || ^4.0", + "nette/php-generator": "^4.1.6", + "nette/robot-loader": "^4.0", + "nette/schema": "^1.2.5", + "nette/utils": "^4.0", + "php": "8.1 - 8.4" + }, + "require-dev": { + "nette/tester": "^2.5.2", + "phpstan/phpstan": "^1.0", + "tracy/tracy": "^2.9" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.2-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "💎 Nette Dependency Injection Container: Flexible, compiled and full-featured DIC with perfectly usable autowiring and support for all new PHP features.", + "homepage": "https://nette.org", + "keywords": [ + "compiled", + "di", + "dic", + "factory", + "ioc", + "nette", + "static" + ], + "support": { + "issues": "https://github.com/nette/di/issues", + "source": "https://github.com/nette/di/tree/v3.2.3" + }, + "time": "2024-10-05T03:14:33+00:00" + }, + { + "name": "nette/neon", + "version": "v3.4.4", + "source": { + "type": "git", + "url": "https://github.com/nette/neon.git", + "reference": "3411aa86b104e2d5b7e760da4600865ead963c3c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/neon/zipball/3411aa86b104e2d5b7e760da4600865ead963c3c", + "reference": "3411aa86b104e2d5b7e760da4600865ead963c3c", + "shasum": "" + }, + "require": { + "ext-json": "*", + "php": "8.0 - 8.4" + }, + "require-dev": { + "nette/tester": "^2.4", + "phpstan/phpstan": "^1.0", + "tracy/tracy": "^2.7" + }, + "bin": [ + "bin/neon-lint" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.4-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "🍸 Nette NEON: encodes and decodes NEON file format.", + "homepage": "https://ne-on.org", + "keywords": [ + "export", + "import", + "neon", + "nette", + "yaml" + ], + "support": { + "issues": "https://github.com/nette/neon/issues", + "source": "https://github.com/nette/neon/tree/v3.4.4" + }, + "time": "2024-10-04T22:00:08+00:00" + }, + { + "name": "nette/php-generator", + "version": "v4.1.6", + "source": { + "type": "git", + "url": "https://github.com/nette/php-generator.git", + "reference": "c90961e782ae86e517fe5ed732eb2b512945565b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/php-generator/zipball/c90961e782ae86e517fe5ed732eb2b512945565b", + "reference": "c90961e782ae86e517fe5ed732eb2b512945565b", + "shasum": "" + }, + "require": { + "nette/utils": "^3.2.9 || ^4.0", + "php": "8.0 - 8.4" + }, + "require-dev": { + "jetbrains/phpstorm-attributes": "dev-master", + "nette/tester": "^2.4", + "nikic/php-parser": "^4.18 || ^5.0", + "phpstan/phpstan": "^1.0", + "tracy/tracy": "^2.8" + }, + "suggest": { + "nikic/php-parser": "to use ClassType::from(withBodies: true) & ClassType::fromCode()" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "🐘 Nette PHP Generator: generates neat PHP code for you. Supports new PHP 8.3 features.", + "homepage": "https://nette.org", + "keywords": [ + "code", + "nette", + "php", + "scaffolding" + ], + "support": { + "issues": "https://github.com/nette/php-generator/issues", + "source": "https://github.com/nette/php-generator/tree/v4.1.6" + }, + "time": "2024-09-10T09:31:55+00:00" + }, + { + "name": "nette/robot-loader", + "version": "v4.0.3", + "source": { + "type": "git", + "url": "https://github.com/nette/robot-loader.git", + "reference": "45d67753fb4865bb718e9a6c9be69cc9470137b7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/robot-loader/zipball/45d67753fb4865bb718e9a6c9be69cc9470137b7", + "reference": "45d67753fb4865bb718e9a6c9be69cc9470137b7", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "nette/utils": "^4.0", + "php": "8.0 - 8.4" + }, + "require-dev": { + "nette/tester": "^2.4", + "phpstan/phpstan": "^1.0", + "tracy/tracy": "^2.9" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "🍀 Nette RobotLoader: high performance and comfortable autoloader that will search and autoload classes within your application.", + "homepage": "https://nette.org", + "keywords": [ + "autoload", + "class", + "interface", + "nette", + "trait" + ], + "support": { + "issues": "https://github.com/nette/robot-loader/issues", + "source": "https://github.com/nette/robot-loader/tree/v4.0.3" + }, + "time": "2024-06-18T20:26:39+00:00" + }, { "name": "nikic/php-parser", "version": "v5.3.1", @@ -5463,22 +5820,69 @@ }, "time": "2024-09-04T20:21:43+00:00" }, + { + "name": "phpstan/phpdoc-parser", + "version": "1.33.0", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpdoc-parser.git", + "reference": "82a311fd3690fb2bf7b64d5c98f912b3dd746140" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/82a311fd3690fb2bf7b64d5c98f912b3dd746140", + "reference": "82a311fd3690fb2bf7b64d5c98f912b3dd746140", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "require-dev": { + "doctrine/annotations": "^2.0", + "nikic/php-parser": "^4.15", + "php-parallel-lint/php-parallel-lint": "^1.2", + "phpstan/extension-installer": "^1.0", + "phpstan/phpstan": "^1.5", + "phpstan/phpstan-phpunit": "^1.1", + "phpstan/phpstan-strict-rules": "^1.0", + "phpunit/phpunit": "^9.5", + "symfony/process": "^5.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "PHPStan\\PhpDocParser\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PHPDoc parser with support for nullable, intersection and generic types", + "support": { + "issues": "https://github.com/phpstan/phpdoc-parser/issues", + "source": "https://github.com/phpstan/phpdoc-parser/tree/1.33.0" + }, + "time": "2024-10-13T11:25:22+00:00" + }, { "name": "phpstan/phpstan", - "version": "2.0.1", + "version": "1.12.11", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "ab4e9b4415a5fc9e4d27f7fe16c8bc9d067dcd6d" + "reference": "0d1fc20a962a91be578bcfe7cf939e6e1a2ff733" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/ab4e9b4415a5fc9e4d27f7fe16c8bc9d067dcd6d", - "reference": "ab4e9b4415a5fc9e4d27f7fe16c8bc9d067dcd6d", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/0d1fc20a962a91be578bcfe7cf939e6e1a2ff733", + "reference": "0d1fc20a962a91be578bcfe7cf939e6e1a2ff733", "shasum": "" }, "require": { - "php": "^7.4|^8.0" + "php": "^7.2|^8.0" }, "conflict": { "phpstan/phpstan-shim": "*" @@ -5519,35 +5923,36 @@ "type": "github" } ], - "time": "2024-11-11T15:43:04+00:00" + "time": "2024-11-17T14:08:01+00:00" }, { "name": "phpstan/phpstan-symfony", - "version": "2.0.0", + "version": "1.4.12", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan-symfony.git", - "reference": "1ef4dce2baabd464c2dd3109d051bad94efa1e79" + "reference": "c7b7e7f520893621558bfbfdb2694d4364565c1d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan-symfony/zipball/1ef4dce2baabd464c2dd3109d051bad94efa1e79", - "reference": "1ef4dce2baabd464c2dd3109d051bad94efa1e79", + "url": "https://api.github.com/repos/phpstan/phpstan-symfony/zipball/c7b7e7f520893621558bfbfdb2694d4364565c1d", + "reference": "c7b7e7f520893621558bfbfdb2694d4364565c1d", "shasum": "" }, "require": { "ext-simplexml": "*", - "php": "^7.4 || ^8.0", - "phpstan/phpstan": "^2.0" + "php": "^7.2 || ^8.0", + "phpstan/phpstan": "^1.12" }, "conflict": { "symfony/framework-bundle": "<3.0" }, "require-dev": { + "nikic/php-parser": "^4.13.0", "php-parallel-lint/php-parallel-lint": "^1.2", - "phpstan/phpstan-phpunit": "^2.0", - "phpstan/phpstan-strict-rules": "^2.0", - "phpunit/phpunit": "^9.6", + "phpstan/phpstan-phpunit": "^1.3.11", + "phpstan/phpstan-strict-rules": "^1.5.1", + "phpunit/phpunit": "^8.5.29 || ^9.5", "psr/container": "1.0 || 1.1.1", "symfony/config": "^5.4 || ^6.1", "symfony/console": "^5.4 || ^6.1", @@ -5588,9 +5993,9 @@ "description": "Symfony Framework extensions and rules for PHPStan", "support": { "issues": "https://github.com/phpstan/phpstan-symfony/issues", - "source": "https://github.com/phpstan/phpstan-symfony/tree/2.0.0" + "source": "https://github.com/phpstan/phpstan-symfony/tree/1.4.12" }, - "time": "2024-11-06T10:13:40+00:00" + "time": "2024-11-06T10:13:18+00:00" }, { "name": "phpunit/php-code-coverage", @@ -6021,12 +6426,12 @@ "source": { "type": "git", "url": "https://github.com/Roave/SecurityAdvisories.git", - "reference": "1b71197bf4ffb07c6beb67162144e07052aac77c" + "reference": "9f1d9b2460cdd0422e8cfd58763bf3156ad7f487" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/1b71197bf4ffb07c6beb67162144e07052aac77c", - "reference": "1b71197bf4ffb07c6beb67162144e07052aac77c", + "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/9f1d9b2460cdd0422e8cfd58763bf3156ad7f487", + "reference": "9f1d9b2460cdd0422e8cfd58763bf3156ad7f487", "shasum": "" }, "conflict": { @@ -6072,6 +6477,7 @@ "azuracast/azuracast": "<0.18.3", "backdrop/backdrop": "<1.27.3|>=1.28,<1.28.2", "backpack/crud": "<3.4.9", + "backpack/filemanager": "<3.0.9", "bacula-web/bacula-web": "<8.0.0.0-RC2-dev", "badaso/core": "<2.7", "bagisto/bagisto": "<2.1", @@ -6403,7 +6809,7 @@ "mojo42/jirafeau": "<4.4", "mongodb/mongodb": ">=1,<1.9.2", "monolog/monolog": ">=1.8,<1.12", - "moodle/moodle": "<4.3.6|>=4.4,<4.4.2", + "moodle/moodle": "<4.3.6|>=4.4,<4.4.4", "mos/cimage": "<0.7.19", "movim/moxl": ">=0.8,<=0.10", "movingbytes/social-network": "<=1.2.1", @@ -6717,7 +7123,7 @@ "ua-parser/uap-php": "<3.8", "uasoft-indonesia/badaso": "<=2.9.7", "unisharp/laravel-filemanager": "<2.6.4", - "unopim/unopim": "<0.1.4", + "unopim/unopim": "<0.1.5", "userfrosting/userfrosting": ">=0.3.1,<4.6.3", "usmanhalalit/pixie": "<1.0.3|>=2,<2.0.2", "uvdesk/community-skeleton": "<=1.1.1", @@ -6854,7 +7260,7 @@ "type": "tidelift" } ], - "time": "2024-11-13T16:05:45+00:00" + "time": "2024-11-13T19:05:18+00:00" }, { "name": "sebastian/cli-parser", @@ -8134,16 +8540,16 @@ }, { "name": "symfony/requirements-checker", - "version": "v2.0.2", + "version": "v2.0.3", "source": { "type": "git", "url": "https://github.com/symfony/requirements-checker.git", - "reference": "10e35b45057bd44ad1bffbde9e92fe1bb11d7a3b" + "reference": "e68f11c6753d586fb465e17c6c3c8e8d9f642627" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/requirements-checker/zipball/10e35b45057bd44ad1bffbde9e92fe1bb11d7a3b", - "reference": "10e35b45057bd44ad1bffbde9e92fe1bb11d7a3b", + "url": "https://api.github.com/repos/symfony/requirements-checker/zipball/e68f11c6753d586fb465e17c6c3c8e8d9f642627", + "reference": "e68f11c6753d586fb465e17c6c3c8e8d9f642627", "shasum": "" }, "require": { @@ -8175,7 +8581,7 @@ ], "support": { "issues": "https://github.com/symfony/requirements-checker/issues", - "source": "https://github.com/symfony/requirements-checker/tree/v2.0.2" + "source": "https://github.com/symfony/requirements-checker/tree/v2.0.3" }, "funding": [ { @@ -8191,7 +8597,7 @@ "type": "tidelift" } ], - "time": "2024-11-09T08:04:39+00:00" + "time": "2024-11-14T22:24:57+00:00" }, { "name": "symfony/stopwatch", @@ -8385,12 +8791,95 @@ } ], "time": "2024-03-03T12:36:25+00:00" + }, + { + "name": "twigstan/twigstan", + "version": "dev-main", + "source": { + "type": "git", + "url": "https://github.com/twigstan/twigstan.git", + "reference": "0b377246f9df05ea40eaa444fe43247a4eb89615" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/twigstan/twigstan/zipball/0b377246f9df05ea40eaa444fe43247a4eb89615", + "reference": "0b377246f9df05ea40eaa444fe43247a4eb89615", + "shasum": "" + }, + "require": { + "composer-runtime-api": "^2.2", + "nette/bootstrap": "^3.2", + "nette/di": "^3.2.2", + "nette/neon": "^3.4", + "nikic/php-parser": "^5.1.0", + "php": "^8.3", + "phpstan/phpdoc-parser": "^1.30", + "phpstan/phpstan": "^1.12.8", + "symfony/console": "^7.1", + "symfony/filesystem": "^7.1", + "symfony/finder": "^7.1", + "symfony/process": "^7.1", + "twig/twig": "3.15.0" + }, + "require-dev": { + "editorconfig-checker/editorconfig-checker": "^10.6", + "ergebnis/composer-normalize": "^2.43", + "erickskrauch/php-cs-fixer-custom-fixers": "^1.3", + "friendsofphp/php-cs-fixer": "^3.59", + "phpstan/extension-installer": "^1.4", + "phpstan/phpstan-deprecation-rules": "^1.2", + "phpstan/phpstan-strict-rules": "^1.6", + "phpstan/phpstan-symfony": "^1.4", + "phpunit/phpunit": "^11.4", + "shipmonk/composer-dependency-analyser": "^1.7", + "staabm/phpstan-todo-by": "^0.1.32", + "symfony/form": "^7.1", + "symfony/framework-bundle": "^7.1", + "symfony/http-foundation": "^7.1", + "symfony/http-kernel": "^7.1", + "symfony/routing": "^7.1", + "symfony/twig-bridge": "^7.1", + "symfony/var-dumper": "^7.1", + "ticketswap/phpstan-error-formatter": "^1.0.3", + "vincentlanglet/twig-cs-fixer": "^3.1" + }, + "default-branch": true, + "bin": [ + "bin/twigstan" + ], + "type": "library", + "autoload": { + "psr-4": { + "TwigStan\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "TwigStan is a static analyzer for Twig templates powered by PHPStan", + "keywords": [ + "static analysis", + "twig" + ], + "support": { + "issues": "https://github.com/twigstan/twigstan/issues", + "source": "https://github.com/twigstan/twigstan/tree/main" + }, + "funding": [ + { + "url": "https://github.com/twigstan", + "type": "github" + } + ], + "time": "2024-11-18T08:17:03+00:00" } ], "aliases": [], "minimum-stability": "beta", "stability-flags": { - "roave/security-advisories": 20 + "roave/security-advisories": 20, + "twigstan/twigstan": 20 }, "prefer-stable": true, "prefer-lowest": false, @@ -8403,6 +8892,6 @@ "ext-simplexml": "*", "ext-xml": "*" }, - "platform-dev": [], - "plugin-api-version": "2.3.0" + "platform-dev": {}, + "plugin-api-version": "2.6.0" } diff --git a/templates/App/Controller/FormAction.html.twig b/templates/App/Controller/FormAction.html.twig index 6601f31..409a945 100644 --- a/templates/App/Controller/FormAction.html.twig +++ b/templates/App/Controller/FormAction.html.twig @@ -45,7 +45,7 @@ Birthay - {{ dto.birthday|date('Y-m-d') }} + {{ dto.birthday ? dto.birthday|date('Y-m-d') : 'NA' }} diff --git a/templates/_form.html.twig b/templates/_form.html.twig index 73db647..38eaf98 100644 --- a/templates/_form.html.twig +++ b/templates/_form.html.twig @@ -1,3 +1,5 @@ +{% types { form: 'Symfony\\Component\\Form\\FormView' } %} +
{{ form(form, {'attr': {'novalidate': 'novalidate'}}) }}
\ No newline at end of file diff --git a/templates/bundles/TwigBundle/Exception/error.html.twig b/templates/bundles/TwigBundle/Exception/error.html.twig index 957e2fa..2426670 100644 --- a/templates/bundles/TwigBundle/Exception/error.html.twig +++ b/templates/bundles/TwigBundle/Exception/error.html.twig @@ -1,5 +1,10 @@ {% extends 'base.html.twig' %} +{% types { + status_code: 'int', + status_text: 'string', +} %} + {% block icon %}⛔️{% endblock %} {% block title %}Error {{ status_code }}{% endblock %} diff --git a/twig-loader.php b/twig-loader.php new file mode 100644 index 0000000..76e9de1 --- /dev/null +++ b/twig-loader.php @@ -0,0 +1,15 @@ +bootEnv(__DIR__.'/.env'); + +$kernel = new Kernel('test', true); +$kernel->boot(); + +return $kernel->getContainer()->get('test.service_container')->get('twig'); diff --git a/twigstan.php b/twigstan.php new file mode 100644 index 0000000..7c45286 --- /dev/null +++ b/twigstan.php @@ -0,0 +1,14 @@ +reportUnmatchedIgnoredErrors(true) + ->phpstanConfigurationFile(__DIR__.'/phpstan.neon') + ->phpstanMemoryLimit(false) + ->twigEnvironmentLoader(__DIR__.'/twig-loader.php') + ->twigPaths(__DIR__.'/templates') + ->phpPaths(__DIR__.'/src/Controller') + ->create(); diff --git a/vendor-bin/php-cs-fixer/composer.lock b/vendor-bin/php-cs-fixer/composer.lock index c660d95..95c2cad 100644 --- a/vendor-bin/php-cs-fixer/composer.lock +++ b/vendor-bin/php-cs-fixer/composer.lock @@ -2541,10 +2541,10 @@ ], "aliases": [], "minimum-stability": "stable", - "stability-flags": [], + "stability-flags": {}, "prefer-stable": false, "prefer-lowest": false, - "platform": [], - "platform-dev": [], - "plugin-api-version": "2.3.0" + "platform": {}, + "platform-dev": {}, + "plugin-api-version": "2.6.0" }