Reputation: 2652
A Company can have multiple emails and all emails have to be unique.
This my Entites for Company and CompanyEmail
CompanyEmail Entity:
/**
* @ORM\Entity(repositoryClass="App\Repository\CompanyEmailRepository")
* @UniqueEntity("name")
*/
class CompanyEmail
{
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\Column(type="string", length=128, unique=true)
* @Assert\Email()
*/
private $name;
/**
* @ORM\ManyToOne(targetEntity="App\Entity\Company", inversedBy="emails")
* @ORM\JoinColumn(nullable=false)
*/
private $company;
// ...
}
Company Entity:
/**
* @ORM\Entity(repositoryClass="App\Repository\CompanyRepository")
*/
class Company
{
// ...
/**
* @ORM\OneToMany(targetEntity="App\Entity\CompanyEmail", mappedBy="company", orphanRemoval=true, cascade={"persist"})
* @Assert\Valid
*/
private $emails;
// ...
}
and I'm using an custom EmailsInputType that use this DataTransformer
class EmailArrayToStringTransformer implements DataTransformerInterface
{
public function transform($emails): string
{
return implode(', ', $emails);
}
public function reverseTransform($string): array
{
if ($string === '' || $string === null) {
return [];
}
$inputEmails = array_filter(array_unique(array_map('trim', explode(',', $string))));
$cEmails = [];
foreach($inputEmails as $email){
$cEmail = new CompanyEmail();
$cEmail->setName($email);
$cEmails[] = $cEmail;
}
return $cEmails;
}
}
and in the Controller a use this edit method
/**
* @Route("/edit/{id}", name="admin_company_edit", requirements={"id": "\d+"}, methods={"GET", "POST"})
*/
public function edit(Request $request, $id): Response
{
$entityManager = $this->getDoctrine()->getManager();
$company = $entityManager->getRepository(Company::class)->find($id);
$form = $this->createForm(CompanyType::class, $company);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$entityManager->flush();
}
}
There is two problems with this code
1 - In the edit form when i try to keep an already saved email Symfony generate a validation error that tells that this email is already exits.
2 - When I remove the validation restriction from the code, Symfony thrown the database error "*Integrity constraint violation: 1062 Duplicate entry ... *"
What i should do to make my code work as expected !
Upvotes: 0
Views: 537
Reputation: 29922
The problem is right here
public function reverseTransform($string): array
{
[...]
foreach($inputEmails as $email){
$cEmail = new CompanyEmail();
[...]
}
[...]
}
You need to retrieve the email
instead of creating new one.
So basically, inject a CompanyEmailRepository
, try to find if email already exists (findOneBy(['name'])
), if it does not exists, create a new one but if exists, use what you've retrieved.
Just few notes
CompanyEmail
as you can use a json
field where you can store them in a comma separated fashion (unless you need some extra parameters or unless you need to perform some indexing/querying operation on the emails)Upvotes: 1