Magento 2 Experten — Hyvä Theme, Tailwind CSS & SEO aus einer Hand ›

Ein eigener Validator

Ein eigener Validator

~16 Min. Lesezeit Zuletzt aktualisiert am 8. August 2026

Die eingebauten Constraints reichen nicht IMMER aus – ein EIGENER Validator prüft hier, ob der name eines Projekts BEREITS existiert.

Die Constraint-Klasse anlegen

docker compose exec php bin/console make:validator UniqueProjectName
api/src/Validator/UniqueProjectName.php
<?php

declare(strict_types=1);

namespace App\Validator;

use Symfony\Component\Validator\Constraint;

#[\Attribute]
final class UniqueProjectName extends Constraint
{
    public string $message = 'Ein Projekt mit dem Namen "{{ value }}" existiert bereits.';
}

Den Validator implementieren

api/src/Validator/UniqueProjectNameValidator.php
<?php

declare(strict_types=1);

namespace App\Validator;

use App\Repository\ProjectRepository;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;

final class UniqueProjectNameValidator extends ConstraintValidator
{
    public function __construct(
        private readonly ProjectRepository $projectRepository,
    ) {
    }

    public function validate(mixed $value, Constraint $constraint): void
    {
        if (!$constraint instanceof UniqueProjectName) {
            return;
        }

        if (null === $value || '' === $value) {
            return;
        }

        $existing = $this->projectRepository->findOneBy(['name' => $value]);

        if (null !== $existing) {
            $this->context->buildViolation($constraint->message)
                ->setParameter('{{ value }}', $value)
                ->addViolation();
        }
    }
}

GENAU dasselbe Constraint/ConstraintValidator-Paar-Prinzip wie in der Symfony-Schulung (Kapitel 26) – Dependency Injection funktioniert im Validator NORMAL, ProjectRepository wird AUTOMATISCH injiziert.

Den Validator anwenden

use App\Validator\UniqueProjectName;

#[ORM\Column(length: 255)]
#[Assert\NotBlank]
#[UniqueProjectName]
#[Groups(['project:read', 'project:write'])]
private string $name = '';

Das Verhalten testen

curl -k -X POST https://localhost/api/projects \
  -H 'Content-Type: application/json' \
  -d '{"name": "Website-Relaunch"}'
{
  "violations": [
    {"propertyPath": "name", "message": "Ein Projekt mit dem Namen \"Website-Relaunch\" existiert bereits."}
  ]
}

Tipp: Symfony bietet AUCH eine fertige #[UniqueEntity]-Constraint für GENAU diesen Fall – dieses Kapitel zeigt bewusst den MANUELLEN Weg, da er zeigt, WIE beliebige EIGENE Geschäftsregeln (nicht nur Eindeutigkeit) als Validator umgesetzt werden können.