Używam FOSUserBundle i chciałem rozszerzyć tabelę użytkownika o dodatkowe informacje. Ale ponieważ te informacje są różne dla różnych typów użytkowników to postanowiłem stworzyć osobne obiekty dla tych zestawów danych. A więc poza encją User.php mam też DoctorData.php. Wybrałem do tego relację dwukierunkową OneToOne.
Zainstalowałem FOSUserBundle i nadpisałem RegistrationController.php ponieważ chciałem rejestrującym użytkownikom nadawać odpowiednie uprawnienia. To wszystko się udało i działa. No i nadszedł czas, że chciałem osadzić formularz z dodatkowymi danymi w formularzu rejestracji. Udało mi się to tak, że widzę wszystkie pola naraz i przy zapisaniu formularza tworzy się w bazie obiekt User oraz obiekt DoctorData.
Problem: obiekt DoctorData ma pustą wartość w polu, które powinno przechowywać identyfikator rekordu User. Trochę już się z tym męczę i nie umiem znaleźć elementu, który przegapiam bo jednocześnie nie jestem jeszcze doświadczony w SF2 oraz mam tu do czynienia z "obcym" bundlem.
User.php (fragment dotyczący relacji):
/**
* @ORM\Entity
* @ORM\Table(name="fos_user")
*/
class User extends BaseUser
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @ORM\OneToOne(targetEntity="DoctorData", mappedBy="fos_user", cascade={"remove","persist"})
**/
protected $doctorData;
DoctorData.php (fragment dotyczący relacji):
/**
* @ORM\Entity
* @ORM\Table(name="doctor_data")
*/
class DoctorData
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @ORM\OneToOne(targetEntity="User", inversedBy="doctor_data")
* @ORM\JoinColumn(name="fos_user_id", referencedColumnName="id")
*/
private $fos_user;
Osadzanie formularza (nadpisany formularz rejestracji):
class RegistrationFormType extends BaseType
{
public function buildForm
(FormBuilderInterface
$builder, array $options) {
parent::buildForm($builder, $options);
# Dołączam formularz danych lekarza (bo rejestrują się tylko lekarze)
$builder->add('doctor_data', new DoctorDataType());
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array( 'data_class' => 'Doctors\UserBundle\Entity\User',
'intention' => 'registration',
'cascade_validation' => true,
));
}
public function getName()
{
return 'doctors_user_registration';
}
}
Akcja zapisująca formularz (nadpisany kontroler z FOSUserBundle):
public function registerAction(Request $request)
{
/** @var $formFactory \FOS\UserBundle\Form\Factory\FactoryInterface */
$formFactory = $this->container->get('fos_user.registration.form.factory');
/** @var $userManager \FOS\UserBundle\Model\UserManagerInterface */
$userManager = $this->container->get('fos_user.user_manager');
/** @var $dispatcher \Symfony\Component\EventDispatcher\EventDispatcherInterface */
$dispatcher = $this->container->get('event_dispatcher');
$user = $userManager->createUser();
$user->setEnabled(true);
$user->addRole('ROLE_DOCTOR'); // nadaję uprawnienia
$dispatcher->dispatch(FOSUserEvents::REGISTRATION_INITIALIZE, new UserEvent($user, $request));
$form = $formFactory->createForm();
$form->setData($user);
if ('POST' === $request->getMethod()) {
$form->bind($request);
if ($form->isValid()) {
$event = new FormEvent($form, $request);
$dispatcher->dispatch(FOSUserEvents::REGISTRATION_SUCCESS, $event);
$userManager->updateUser($user);
if (null === $response = $event->getResponse()) {
$url = $this->container->get('router')->generate('fos_user_registration_confirmed');
$response = new RedirectResponse($url);
}
$dispatcher->dispatch(FOSUserEvents::REGISTRATION_COMPLETED, new FilterUserResponseEvent($user, $request, $response));
return $response;
}
}
return $this->container->get('templating')->renderResponse('FOSUserBundle:Registration:register.html.'.$this->getEngine(), array( 'form' => $form->createView(),
));
}
A więc byłbym wdzięczny za pomoc w odkrywaniu dlaczego w DoctorData nie zapisuje się ten identyfikator Usera. Oraz oczywiście za wskazanie innych błędów w rozumowaniu.