首页 > 解决方案 > Symfony 5 未验证多个独立的唯一字段

问题描述

我正在尝试验证数据库中的唯一用户名和电子邮件。

想象一下 DB Users 表中的这种情况:

用户名 电子邮件
艾孔 aykon@aykon.sk
艾康94 aykon94@aykon.sk

我在用户实体中有此代码:

/**
 * @ORM\Table(name="users")
 * @ORM\Entity(repositoryClass="App\Repository\UserRepository")
 * @Gedmo\SoftDeleteable(fieldName="deletedAt", timeAware=false)
 * @UniqueEntity(fields={"email"}, groups={"register", "edit"})
 * @UniqueEntity(fields={"username"}, groups={"register", "edit"})
 */
class User implements UserInterface
{

这是我的注册功能:

/**
 * @Route("/register", name="api_auth_register", methods={"POST"})
 * @return JsonResponse|RedirectResponse
 */
public function register(
    Request $request,
    EntityManagerInterface $entityManager,
    CustomSerializer $serializer,
    ValidatorInterface $validator,
    UserPasswordEncoderInterface $passwordEncoder
) {
    $user = $serializer->serializer->deserialize($request->getContent(), User::class, 'json');
    assert($user instanceof User);
    $errors = $validator->validate($user, null, 'register');

    if ($errors->count() !== 0) {
        return new JsonResponse(
            $serializer->serializer->serialize($errors, 'json'),
            Response::HTTP_UNPROCESSABLE_ENTITY,
            [],
            true,
        );
    }

    $user->setPassword($passwordEncoder->encodePassword($user, $user->getPassword()));

    $entityManager->persist($user);
    $entityManager->flush();

    return $this->json([], Response::HTTP_CREATED);
}

当我发送此有效负载时:

{
    "username": "aykon",
    "email": "aykon@aykon.sk",
    "password": "password"
}

我得到正确422的响应,错误是用户名和电子邮件已被使用!

但是当我发送这个时:

{
    "username": "aykon94",
    "email": "aykon@aykon.sk",
    "password": "password"
}

我收到不正确 422的回复,并显示电子邮件已被使用!

如何强制 symfony 继续验证并为用户名显示错误?

这在注册过程中不是大问题,因为当我更改电子邮件以通过验证时,smt 就像aykon199@aykon.sk它会在用户名上显示验证错误一样。我可以忍受这一点。

但是当我尝试编辑用户时,例如aykon,这意味着我已经在数据库中拥有用户名和电子邮件,并且我只将用户名更改为aykon94,验证在非唯一电子邮件处停止aykon@aykon.sk并且它忽略它,因为它是同一个对象。我从数据库得到错误

 SQLSTATE[23000]: Integrity constraint violation: 19 UNIQUE constraint failed: users.username"

编辑: 提供编辑功能:

    /** @Route("/{id}", methods={"PUT"}) */
    public function updateUser(
        Request $request,
        ValidatorInterface $validator,
        UserRepository $userRepository,
        CustomSerializer $serializer,
        string $id
    ): JsonResponse {
        $groups = ['user', 'currentUser', 'userPicture'];

        $oldUser = $userRepository->find($id);

        if ($oldUser === null) {
            throw $this->createNotFoundException();
        }

        $this->denyAccessUnlessGranted(UserVoter::EDIT_PROFILE, $oldUser);

        $user = $serializer->serializer->deserialize($request->getContent(), User::class, 'json');
        assert($user instanceof User);

        $oldUser->setEmail($user->getEmail());
        $oldUser->setUsername($user->getUsername());
        $oldUser->setBio($user->getBio());

        //        $validationGroups = $user->isEnabled() ? ['default', 'enabled'] : null;
        $validationGroups = ['default', 'enabled', 'edit'];
        $errors = $validator->validate($oldUser, null, $validationGroups);

        if ($errors->count() !== 0) {
            return new JsonResponse(
                $serializer->serializer->serialize($errors, 'json'),
                Response::HTTP_UNPROCESSABLE_ENTITY,
                [],
                true,
            );
        }

标签: phpsymfonyvalidationsymfony5symfony-validator

解决方案


推荐阅读