Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
111 views
in Technique[技术] by (71.8m points)

php - Api Platform validation group not working in UniqueEntity constraint

I'm trying to insert a duplicate key to test the UniqueEntity constraint. If a do it by the post operation it works fine.

If i try to do it by the add_association the UniqueEntity constraint is skipped (even if it has the right validation group) while the @AssertValid constraint on the $customer property is executed has it has to... any idea?

/**
 * @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"},
 *                      "denormalization_context"={"groups"={"user-customer:write"}},
 *                      "input"=UserCustomerAssociationInputDto::class,
 *                      "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>."
 *                      }
 *                  }
 *              })
 * @ORMTable(name="security_utente_cliente",
 *     uniqueConstraints={@ORMUniqueConstraint(name="unique_association", columns={"utente_id", "cliente_id"})})
 * @ORMEntity(repositoryClass=UserCustomerAssociationRepository::class)
 * @ORMHasLifecycleCallbacks
 * @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.
     *
     * @ORMId
     * @ORMColumn(type="uuid", unique=true)
     * @ORMGeneratedValue(strategy="CUSTOM")
     * @ORMCustomIdGenerator(class=UuidGenerator::class)
     * @Groups({"user-customer:read", "user:read"})
     */
    private ?UuidInterface $id = null;
    /**
     * Utente a cui appartiene l'associazione.
     *
     * @ORMManyToOne(targetEntity=User::class, inversedBy="userCustomerAssociations")
     * @ORMJoinColumn(name="utente_id", nullable=false, onDelete="CASCADE")
     * @Groups({"user-customer:read", "user-customer:write"})
     */
    private ?User $user;
    /**
     * Il cliente associato all'utente.
     *
     * @ORMManyToOne(targetEntity=Customer::class)
     * @ORMJoinColumn(name="cliente_id", nullable=false, onDelete="CASCADE")
     * @Groups({"user-customer:read", "user-customer:write", "user:read"})
     * @AssertValid(groups={"UserCustomerAssociation:Add"})
     */
    private ?Customer $customer;
}

The Dto validation is working fine in both cases.

namespace AppDtoSecurity;

use AppValidatorConstraints as AppAssert;
use SymfonyComponentSerializerAnnotationGroups;


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

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

And this is the transformer

use ApiPlatformCoreDataTransformerDataTransformerInterface;
use AppEntityDataCustomer;
use AppEntitySecurityUser;
use AppEntitySecurityUserCustomerAssociation;
use DoctrineORMEntityManagerInterface;
use ApiPlatformCoreValidatorValidatorInterface;

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, string $to, 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);
    }
}
question from:https://stackoverflow.com/questions/66050015/api-platform-validation-group-not-working-in-uniqueentity-constraint

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)
Waitting for answers

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...