phpsymfonydoctrine-ormapi-platform.comsymfony6

Symfony 6 + API Platform - Update existing entity while posting new entity


I have the following use case:

In my user table I have a user that has been soft deleted and has a unique constraint with the email field.

The user does a sign up again with the same e-mail. Via API Platform POST request. My goal is to check in that POST request if the user existed, and recover it from the trash.

I've tried the following 2 options:

Option 1: Hook into the deserialise process of API Platform

While deserialising in the POST request I have tried to check if the user existed and add the user ID to the deserialised-data array.

But the problem is that API Platform says that an UPDATE is not possible during a POST request.

Option 2: check in the prePersist() in Doctrine

I tried the following:

public function prePersist(PrePersistEventArgs $args): void
{
    $entity = $args->getObject();

    // it must be a user!
    if (!$entity instanceof User) {
       return;
    }

    // check for old user
    $existing = $this->userRepository->findDeletedUser($entity);
    if (!empty($existing)) {
       $this->em->detach($entity);
       $entity = $this->userRepository->recoverUser($existing, $entity);
    }
    

   // continue on the normal sign up stuff...
   
}

But this gives me a unique constraint error that the user already exists.

How can I solve this?


Solution

  • Just use the state processor

    Smth like that:

    final class SignUpStateProcessor implements ProcessorInterface
    {
        /**
         * @param \App\ApiResource\SignUp $signUp
         */
        public function process(
            mixed $signUp,
            Operation $operation,
            ?array $uriVariables = null,
            ?array $context = null
        ): SignUp {
            $existing = $this->userRepository->findDeletedUser($signUp);
            if ($existing !== null) {
                return $this->userRepository->recoverUser($existing, $signUp);
            }
    
            $this->entityManager->persist($signUp);
            $this->entityManager->flush();
    
            return $signUp;
        }
    }