Files
php-qml/framework/php/tests/snapshot/UpdateTodoDto.php

25 lines
537 B
PHP
Raw Normal View History

v0.2.0 (4/N): make:bridge:resource --with-dto + symfony/validator 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>
2026-05-03 20:10:52 +02:00
<?php
declare(strict_types=1);
namespace App\Dto;
use Symfony\Component\Validator\Constraints as Assert;
/**
* Validated payload for PATCH /api/todos/{id}.
*
* All fields are nullable so PATCH callers can send only the fields
* they want to change. The controller checks each for null and
* skips the corresponding entity setter.
*/
final readonly class UpdateTodoDto
{
public function __construct(
#[Assert\Length(max: 255)]
public ?string $title = null,
public ?bool $done = null,
) {
}
}