Problem fixed, check my answer.
I'm building a registration endpoint on my Symfony2.7 rest api. I am using FosRestBundle and FosUserBundle
Here is the user model :
<?php
namespace AppBundle\Entity;
use FOS\UserBundle\Model\User as BaseUser;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity
* @ORM\Table(name="fos_user")
*/
class User extends BaseUser {
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
public function __construct() {
parent::__construct();
// your own logic
}
}
\ Here is the UserType form : \
class UserType extends AbstractType
{
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('email', 'email')
->add('username', null)
->add('plainPassword', 'repeated', array(
'type' => 'password',
'first_options' => array('label' => 'password'),
'second_options' => array('label' => 'password_confirmation'),
))
;
}
/**
* @param OptionsResolverInterface $resolver
*/
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\User',
'csrf_protection' => false,
));
}
/**
* @return string
*/
public function getName()
{
return 'user';
}
}
And this the post user controller :
public function postUserAction(\Symfony\Component\HttpFoundation\Request $request) {
$user = new \AppBundle\Entity\User();
$form = $this->createForm(new \AppBundle\Form\UserType(), $user);
$form->handleRequest($request);
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($user);
$em->flush();
$view = $this->view(array('token'=>$this->get("lexik_jwt_authentication.jwt_manager")->create($user)), Codes::HTTP_CREATED);
return $this->handleView($view);
}
return array(
'form' => $form,
);
}
The problem is that when i submit wrong information, or empty information, the server return a bad formated 500 error with doctrine / mysql details of null value for not null row in state of a json response with the list of bad formated entries.
Any idea on how to fix this behaviour ? How come the validation get by passed and
Ok after spending a lot of time reading the FOSUserBundle code, and particularly the registration controller and the form factory, i came up with a fully working solution.
Before doing anything don't forget to disable CSRF in your symfony2 configuration.
Here is the controller I use to register :
public function postUserAction(\Symfony\Component\HttpFoundation\Request $request) {
/** @var $formFactory \FOS\UserBundle\Form\Factory\FactoryInterface */
$formFactory = $this->get('fos_user.registration.form.factory');
/** @var $userManager \FOS\UserBundle\Model\UserManagerInterface */
$userManager = $this->get('fos_user.user_manager');
/** @var $dispatcher \Symfony\Component\EventDispatcher\EventDispatcherInterface */
$dispatcher = $this->get('event_dispatcher');
$user = $userManager->createUser();
$user->setEnabled(true);
$event = new \FOS\UserBundle\Event\GetResponseUserEvent($user, $request);
$dispatcher->dispatch(\FOS\UserBundle\FOSUserEvents::REGISTRATION_INITIALIZE, $event);
if (null !== $event->getResponse()) {
return $event->getResponse();
}
$form = $formFactory->createForm();
$form->setData($user);
$form->handleRequest($request);
if ($form->isValid()) {
$event = new \FOS\UserBundle\Event\FormEvent($form, $request);
$dispatcher->dispatch(\FOS\UserBundle\FOSUserEvents::REGISTRATION_SUCCESS, $event);
$userManager->updateUser($user);
if (null === $response = $event->getResponse()) {
$url = $this->generateUrl('fos_user_registration_confirmed');
$response = new \Symfony\Component\HttpFoundation\RedirectResponse($url);
}
$dispatcher->dispatch(\FOS\UserBundle\FOSUserEvents::REGISTRATION_COMPLETED, new \FOS\UserBundle\Event\FilterUserResponseEvent($user, $request, $response));
$view = $this->view(array('token' => $this->get("lexik_jwt_authentication.jwt_manager")->create($user)), Codes::HTTP_CREATED);
return $this->handleView($view);
}
$view = $this->view($form, Codes::HTTP_BAD_REQUEST);
return $this->handleView($view);
}
Now the tricky part was submiting the form using REST. The problem was that when I sent i JSON like this one :
{
"email":"[email protected]",
"username":"xxx",
"plainPassword":{
"first":"xxx",
"second":"xxx"
}
}
The API was responding like nothing was submited.
The solution is that Symfony2 is waiting for you to encapsulate your form data in the form name !
The question was "I didnt create this form so i dont know what is its name..". So i went again in the bundle code and found out that the form type was fos_user_registration and the getName function was returning fos_user_registration_form.
As a result i tried to submit my JSON this way :
{"fos_user_registration_form":{
"email":"[email protected]",
"username":"xxxxxx",
"plainPassword":{
"first":"xxxxx",
"second":"xxxxx"
}
}}
And voila! it worked. If you are struggling setting up your fosuserbundle with fosrestbundle and LexikJWTAuthenticationBundle just ask me i'll be glad to help.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With