Closes the input-validation gap that was the audit's headline finding.
The legacy generated controller's `if (isset($data['title']))…` body
accepted any JSON: empty title slipped through, malformed JSON got
swallowed by `?? []`, wrong types were silently coerced via casts.
The --with-dto flag generates:
- src/Dto/Create<Name>Dto.php — readonly DTO with #[Assert\NotBlank]
on title and #[Assert\Length(max: 255)]
- src/Dto/Update<Name>Dto.php — same DTO with all fields nullable
so PATCH callers send only what changed
- src/Controller/<Name>Controller.php — same shape as the legacy
controller but actions dispatch via #[MapRequestPayload]
Validation failures (missing required field, wrong type, malformed
JSON, oversize string) become RFC 7807 application/problem+json
automatically — Symfony's RequestPayloadValueResolver does the work.
No `if-isset` boilerplate, no silent coercion.
Behaviour:
- --with-dto is opt-in; legacy template still ships unchanged
- audit suggests flipping to default-on once stable; that's a
follow-up
- maker fails loud (composer require hint) if symfony/validator
isn't autoloadable
- skeleton + example/todo composer.json pull symfony/validator so
scaffolded apps work out of the box
Snapshot test exercises both modes (legacy + --with-dto). New
baselines TodoControllerWithDto.php / CreateTodoDto.php /
UpdateTodoDto.php under tests/snapshot/.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
48 lines
1.1 KiB
JSON
48 lines
1.1 KiB
JSON
{
|
|
"type": "project",
|
|
"license": "proprietary",
|
|
"minimum-stability": "stable",
|
|
"require": {
|
|
"php": "^8.4",
|
|
"symfony/framework-bundle": "^8.0",
|
|
"symfony/runtime": "^8.0",
|
|
"symfony/dotenv": "^8.0",
|
|
"symfony/yaml": "^8.0",
|
|
"symfony/security-bundle": "^8.0",
|
|
"symfony/mercure-bundle": "^0.4",
|
|
"symfony/uid": "^8.0",
|
|
"symfony/validator": "^8.0",
|
|
"doctrine/orm": "^3.0",
|
|
"doctrine/doctrine-bundle": "^3.0",
|
|
"doctrine/doctrine-migrations-bundle": "^4.0",
|
|
"php-qml/bridge": "@dev"
|
|
},
|
|
"require-dev": {
|
|
"symfony/maker-bundle": "^1.62"
|
|
},
|
|
"autoload": {
|
|
"psr-4": {
|
|
"App\\": "src/"
|
|
}
|
|
},
|
|
"config": {
|
|
"allow-plugins": {
|
|
"symfony/runtime": true
|
|
}
|
|
},
|
|
"extra": {
|
|
"runtime": {
|
|
"class": "Symfony\\Component\\Runtime\\SymfonyRuntime"
|
|
}
|
|
},
|
|
"repositories": [
|
|
{
|
|
"type": "path",
|
|
"url": "../../php",
|
|
"options": {
|
|
"symlink": true
|
|
}
|
|
}
|
|
]
|
|
}
|