Symfony Forms встроенные формы

Следуя документации Symfony, я пытаюсь встроить коллекцию в форму. Но при отправке почтового запроса на мою конечную точку встроенная форма с коллекцией People остается пустой.
Мои сущности:

user.php

<?php

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Symfony\Component\Security\Core\User\UserInterface;

/**
* User
*
* @ORM\Entity
* @UniqueEntity(fields="email", message="Email already taken")
* @ORM\HasLifecycleCallbacks()
*/
class User implements UserInterface
{
use Mapping\UserTrait;

/**
* @param Person $person
*/
public function addPeople(Person $person)
{
$this->people->add($person);
$person->setOwner($this);
}

/**
* @param Person $person
*/
public function removePeople(Person $person)
{
$this->people->removeElement($person);
}
}

UserTrait.php

<?php

namespace App\Entity\Mapping;

use App\Entity\Person;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;

/**
* User
*
* @ORM\Table()
*/
trait UserTrait
{
/**
* @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;

/**
* @var string
*
* @ORM\Column(name="hash", type="string")
*/
private $hash;

/**
* @var bool
*
* @ORM\Column(name="is_active", type="boolean")
*/
private $isActive;

/**
* @var \DateTime
*
* @ORM\Column(name="updated_at", type="datetime")
*/
private $updatedAt;

/**
* @var \DateTime
*
* @ORM\Column(name="created_at", type="datetime")
*/
private $createdAt;

/**
* @var string
* @ORM\Column(name="email", type="string")
* @Assert\NotBlank
* @Assert\Email
*/
private $email;

/**
* @var \Doctrine\Common\Collections\Collection
*
* @ORM\OneToMany(targetEntity="App\Entity\Person", mappedBy="owner", cascade={"persist"})
*/
private $people;

/**
* @var string
* @Assert\NotBlank
* @Assert\Length(max=4096)
*/
private $plainPassword;

/**
* Constructor
*/
public function __construct()
{
$this->people = new ArrayCollection();
$this->roles = ['ROLE_USER'];
$this->isActive = 1;
}

/**
* @return int
*/
public function getId(): int
{
return $this->id;
}

/**
* @param int $id
*/
public function setId(int $id): void
{
$this->id = $id;
}

/**
* @return bool
*/
public function isActive(): bool
{
return $this->isActive;
}

/**
* @param bool $isActive
*/
public function setIsActive(bool $isActive): void
{
$this->isActive = $isActive;
}

/**
* @return string
*/
public function getEmail()
{
return $this->email;
}

/**
* @param string $email
*/
public function setEmail(string $email): void
{
$this->email = $email;
}

/**
* @return \Doctrine\Common\Collections\Collection
*/
public function getPeople(): \Doctrine\Common\Collections\Collection
{
return $this->people;
}

/**
* @param \Doctrine\Common\Collections\Collection $people
*/
public function setPeople(\Doctrine\Common\Collections\Collection $people): void
{
$this->people = $people;
}

/**
* @return string
*/
public function getPlainPassword()
{
return $this->plainPassword;
}

/**
* @param string $plainPassword
*/
public function setPlainPassword(string $plainPassword): void
{
$this->plainPassword = $plainPassword;
}

/**
* Implementation of UserInterface: Get password hash.
* @return string
*/
public function getPassword()
{
return $this->hash;
}

/**
* Implementation of UserInterface
*/
public function eraseCredentials()
{
$this->plainPassword = null;
}

/**
* Implementation of UserInterface
*/
public function getUsername()
{
return $this->email;
}

public function getSalt()
{
return null;
}

public function getRoles()
{
return ["User"];
}

/**
* @return string
*/
public function getHash(): string
{
return $this->hash;
}

/**
* @param string $hash
*/
public function setHash(string $hash): void
{
$this->hash = $hash;
}

/**
* @ORM\PrePersist
* @ORM\PreUpdate
*/
public function updatedTimestamps(): void
{
$dateTimeNow = new \DateTime('now');
$this->setUpdatedAt($dateTimeNow);
if ($this->getCreatedAt() === null) {
$this->setCreatedAt($dateTimeNow);
}
}

/**
* @return \DateTime
*/
public function getUpdatedAt(): \DateTime
{
return $this->updatedAt;
}

/**
* @param \DateTime $updatedAt
*/
public function setUpdatedAt(\DateTime $updatedAt): void
{
$this->updatedAt = $updatedAt;
}

/**
* @return \DateTime
*/
public function getCreatedAt()
{
return $this->createdAt;
}

/**
* @param \DateTime $createdAt
*/
public function setCreatedAt(\DateTime $createdAt): void
{
$this->createdAt = $createdAt;
}

}

Person.php

<?php

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
* Person
*
* @ORM\Entity
*/
class Person
{
use Mapping\PersonTrait;
}

PersonTrait.php

<?php

namespace App\Entity\Mapping;

use Doctrine\ORM\Mapping as ORM;

use Symfony\Component\Validator\Constraints as Assert;


/**
* Person
*
* @ORM\Table()
*/
trait PersonTrait
{
/**
* @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;

/**
* @var string
*
* @ORM\Column(name="family_name", type="string")
* @Assert\NotBlank
*/
private $familyName;

/**
* @var string
*
* @ORM\Column(name="given_name", type="string")
* @Assert\NotBlank
*/
private $givenName;

/**
* @var string
*
* @ORM\Column(name="title", type="string")
*/
private $title;

/**
* @var \DateTime
*
* @ORM\Column(name="birth_date", type="datetime")
*/
private $birthDate;

/**
* @var string
*
* @ORM\Column(name="salutation", type="string")
*/
private $salutation;

/**
* @var string
*
* @ORM\Column(name="gender", type="string")
*/
private $gender;

/**
* @var \App\Entity\User
*
* @ORM\ManyToOne(targetEntity="App\Entity\User", inversedBy="people")
* @ORM\JoinColumns({
*   @ORM\JoinColumn(name="owner_id", referencedColumnName="id")
* })
*/
private $owner;

/**
* @return string
*/
public function getFamilyName()
{
return $this->familyName;
}

/**
* @param string $familyName
*/
public function setFamilyName($familyName)
{
var_dump($familyName);
$this->familyName = $familyName;
}

/**
* @return string
*/
public function getGivenName()
{
return $this->givenName;
}

/**
* @param string $givenName
*/
public function setGivenName($givenName)
{
$this->givenName = $givenName;
}

/**
* @return string
*/
public function getTitle(): string
{
return $this->title;
}

/**
* @param string $title
*/
public function setTitle(string $title): void
{
$this->title = $title;
}

/**
* @return \DateTime
*/
public function getBirthDate(): \DateTime
{
return $this->birthDate;
}

/**
* @param \DateTime $birthDate
*/
public function setBirthDate(\DateTime $birthDate): void
{
$this->birthDate = $birthDate;
}

/**
* @return string
*/
public function getSalutation(): string
{
return $this->salutation;
}

/**
* @param string $salutation
*/
public function setSalutation(string $salutation): void
{
$this->salutation = $salutation;
}

/**
* @return string
*/
public function getGender(): string
{
return $this->gender;
}

/**
* @param string $gender
*/
public function setGender(string $gender): void
{
$this->gender = $gender;
}

/**
* @return \App\Entity\User
*/
public function getOwner(): \App\Entity\User
{
return $this->owner;
}

/**
* @param \App\Entity\User $owner
*/
public function setOwner(\App\Entity\User $owner): void
{
$this->owner = $owner;
}
}

Теперь к моим типам форм:

UserType.php

<?php

namespace App\Form;


use App\Entity\User;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
use Symfony\Component\Form\Extension\Core\Type\RepeatedType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;

class UserType extends AbstractType
{


public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('email', EmailType::class)
->add('plainPassword', PasswordType::class)
->add(
"people",
CollectionType::class,
[
'entry_type' => PersonType::class,
'allow_add' => true,
'by_reference' => false,
]
);
}

public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(
[
'data_class' => User::class,
'csrf_protection' => false
]
);
}

}

PersonType.php

<?php

namespace App\Form;


use App\Entity\Person;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;

class PersonType extends AbstractType
{


public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('familyName', TextType::class)
->add('givenName', TextType::class);
}

public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(
[
'data_class' => Person::class,
'csrf_protection' => false,
]
);
}

}

Используя эти типы, я сейчас пытаюсь зарегистрировать пользователя и создать человека и добавить его к пользователю с помощью этого кода:

/**
* @Route("/register")
* @param Request $request
* @param UserPasswordEncoderInterface $passwordEncoder
*/
public function register(Request $request, UserPasswordEncoderInterface $passwordEncoder)
{
$user = new User();
$form = $this->createForm(UserType::class, $user);
$form->submit($request->request->all());

if ($form->isSubmitted() && $form->isValid()) {
$password = $passwordEncoder->encodePassword($user, $user->getPlainPassword());
$user->setHash($password);

$entityManager = $this->getDoctrine()->getManager();
$entityManager->persist($user);
$entityManager->flush();
return new Response("ok", 300);
}
return new Response("not ok", 500);

}

Моя проблема сейчас заключается в том, что когда я отправляю почтовый запрос с почтальоном со следующими параметрами и содержанием:

email: test@test.de
plainPassword: test1234
people.familyName: testLastname
people.givenName: testFirstname

Я получаю следующую ошибку, которая означает, что он не распознает данные для лица лица

«Эта форма не должна содержать лишних полей».

Как сделать формы Symfony, чтобы распознать, что people.givenName и people.familyName предназначены для создания экземпляра Person

Редактировать: комментарий от u_mulder предложил изменить тело сообщения на person [0] .givenName, и теперь я получаю сообщение об ошибке

Это значение недопустимо.

0

Решение

У меня были две проблемы, которые должны были быть исправлены. Первый намек от u_mulder состоял в том, что я должен использовать индекс для людей с момента его сбора. Так что вместо

people["givenName"]

Я должен был использовать

people[0]["givenName"]

Вторая ошибка заключалась в том, что структура тела почтальона была неправильной. Вместо

people[0]["givenName"]

Я должен был удалить цитаты.

people[0][givenName]

После исправления обеих проблем формы работают как положено.

0

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector