Api 平台验证组在 UniqueEntity 约束中不起作用

问题描述

我正在尝试插入重复键来测试 UniqueEntity 约束。如果通过 post 操作执行它,它工作正常。

如果我尝试通过 add_association 执行此操作,则会跳过 UniqueEntity 约束(即使它具有正确的验证组),而 @Assert\Valid 上的 $customer 约束财产被执行了它必须......知道吗?

/**
 * @ApiResource(normalizationContext={"groups"={"user-customer:read"},"skip_null_values"=false},*              denormalizationContext={"groups"={"user-customer:write"}},*              collectionoperations={
 *                  "get"={
 *                      "openapi_context"={
 *                          "summary"="Recupera la lista di associazioni.",*                          "description"="Recupera la lista delle associazioni.<br>
                               Se l'operazione è eseguita <b>dagli operatori del backoffice (ROLE_BACKOFFICE)</b> non ha
                               restrizioni.<br>
                               Per un utente (ROLE_USER) recupera solo le proprie associazioni attualmente verificate."
 *                      }
 *                  },*                  "post"={
 *                      "security"="is_granted('ROLE_BACKOFFICE')",*                      "validation_groups"={"Insert"},*                      "denormalization_context"={"groups"={"user-customer:write"}},*                      "input"=UserCustomerAssociationInputDto::class,*                      "openapi_context"={
 *                          "summary"="Crea un'associazione.",*                          "description"="Permette la creazione di un'associazione User/Customer e la rende attiva
                                <b>agli operatori del backoffice (ROLE_BACKOFFICE)</b>.<br>
                                Questo metodo non invia alcun sms con il codice di verifica all'utente,in quanto
                                deve venire utilizzato direttamente dagli operatori."
 *                      }
 *                  },*                  "add_association"={
 *                      "method"="POST",*                      "controller"=AddUserCustomerAssociation::class,*                      "path"="/user_customer_associations/add_association",*                      "validation_groups"={"UserCustomerAssociation:Add"},*                      "openapi_context"={
 *                          "summary"="Aggiunge un'associazione.",*                          "description"="Aggiunge un'associazione User/Customer e invia un codice di attivazione
                                ad uno dei contatti di Customer (Cliente).<br>
                                L'associazione viene bloccata se Customer non ha nessun contatto (email o telefono)
                                impostato come <em>main</em>."
 *                      }
 *                  }
 *              })
 * @ORM\Table(name="security_utente_cliente",*     uniqueConstraints={@ORM\UniqueConstraint(name="unique_association",columns={"utente_id","cliente_id"})})
 * @ORM\Entity(repositoryClass=UserCustomerAssociationRepository::class)
 * @ORM\HasLifecycleCallbacks
 * @ActiveEntityAware(activeFieldName="verificato",rolesToExclude={"ROLE_BACKOFFICE"})
 * @UniqueEntity(fields={"user","customer"},*     errorPath="customer",*     message="Questo codice cliente è già associato all'utente",*     groups={"Insert","UserCustomerAssociation:Add"})
 */
class UserCustomerAssociation
{
    /**
     * Identificativo univoco dell'utente (Uuid) di 36 caratteri.
     *
     * @ORM\Id
     * @ORM\Column(type="uuid",unique=true)
     * @ORM\GeneratedValue(strategy="CUSTOM")
     * @ORM\CustomIdGenerator(class=UuidGenerator::class)
     * @Groups({"user-customer:read","user:read"})
     */
    private ?UuidInterface $id = null;
    /**
     * Utente a cui appartiene l'associazione.
     *
     * @ORM\ManyToOne(targetEntity=User::class,inversedBy="userCustomerAssociations")
     * @ORM\JoinColumn(name="utente_id",nullable=false,onDelete="CASCADE")
     * @Groups({"user-customer:read","user-customer:write"})
     */
    private ?User $user;
    /**
     * Il cliente associato all'utente.
     *
     * @ORM\ManyToOne(targetEntity=Customer::class)
     * @ORM\JoinColumn(name="cliente_id","user-customer:write","user:read"})
     * @Assert\Valid(groups={"UserCustomerAssociation:Add"})
     */
    private ?Customer $customer;
}

Dto 验证在这两种情况下都可以正常工作。

namespace App\Dto\Security;

use App\Validator\Constraints as AppAssert;
use Symfony\Component\Serializer\Annotation\Groups;


class UserCustomerAssociationInputDto
{
    /**
     * Id dell'utente per creare l'associazione
     *
     * @var null|string
     * @Groups({"user-customer:write"})
     * @AppAssert\UserExists
     */
    public ?string $userId;

    /**
     * Codice cliente da associare
     *
     * @var null|string
     * @Groups({"user-customer:write"})
     * @AppAssert\CustomerExists
     */
    public ?string $customerCode;
}

这是变压器

use ApiPlatform\Core\DataTransformer\DataTransformerInterface;
use App\Entity\Data\Customer;
use App\Entity\Security\User;
use App\Entity\Security\UserCustomerAssociation;
use Doctrine\ORM\EntityManagerInterface;
use ApiPlatform\Core\Validator\ValidatorInterface;

class UserCustomerAssociationInputDataTransformer implements DataTransformerInterface
{
    private EntityManagerInterface $entityManager;
    private ValidatorInterface $validator;

    public function __construct(EntityManagerInterface $entityManager,ValidatorInterface $validator)
    {
        $this->entityManager = $entityManager;
        $this->validator = $validator;
    }

    /**
     * @inheritDoc
     */
    public function transform($object,string $to,array $context = [])
    {
        $this->validator->validate($object);

        $userCustomerAssociation = new UserCustomerAssociation();

        $user = $this->entityManager
            ->getRepository(User::class)
            ->find($object->userId);

        $customer = $this->entityManager
            ->getRepository(Customer::class)
            ->findOneBy(['code' => $object->customerCode]);

        $userCustomerAssociation->setUser($user);
        $userCustomerAssociation->setCustomer($customer);

        return $userCustomerAssociation;
    }

    /**
     * @inheritDoc
     */
    public function supportsTransformation($data,array $context = []): bool
    {
        // in the case of an input,the value given here is an array (the JSON decoded).
        // if it's a book we transformed the data already
        if ($data instanceof UserCustomerAssociation) {
            return false;
        }

        return UserCustomerAssociation::class === $to && null !== ($context['input']['class'] ?? null);
    }
}

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)