1
votes

I'm trying to integrate FOSUserBundle in my web application (symfony based). My application needs to have two different registration forms; one for company profile and one for simple user profile. I would like to have User entity from FOSUserBundle separated to company entity. I tried to extend company from user entity; in this way, it's easy to create a RegistrationFormType like this:

```

class RegistrationFormType extends AbstractType
{

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        // add your custom field
        $builder->add('name');
        $builder->add('works', 'entity', array(
            'class' => 'SkaLabFrontEndBundle:Works',
            'property' => 'name'
        ));

        $builder->add('address');
        .... 
    }

    $builder->add('email');
    $builder->add('username');
    $builder->add('plainPassword', 'repeated', array(
        'type' => 'password',
        'invalid_message' => 'The password fields must match.',
        'options' => array('attr' => array('class' => 'password-field')),
        'required' => true,
        'first_options'  => array('label' => 'Password'),
        'second_options' => array('label' => 'Repeat Password')));
    }

   /**
    * @param OptionsResolverInterface $resolver
    */
    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'SkaLab\Bundle\UserBundle\Entity\User'
        ));
    }

    public function getName()
    {
        return 'skalab_bundle_userbundle_registration_form';
    }

}

But i don't want to extend company from user entity because in this way, when i launch the follow command:

php app/console doctrine:schema:update --force

to update db schema, it should put fos user fields in company table. Insteed, i would like to keep user table (fos_user) separated from company table and to do an one-to-one relationship between company and user table. Obviously, registration form needs to have fields related with user and company table.

How can i do to implement something like that?

1

1 Answers

0
votes

I have created my social network using Symfony and FOSUserBundle. I encountered a similar challenge and will explain in detail how I solved it.

1) I created a new bundle called for profiles within which lies a profiles entity which has a 1-1 mapping with my default User Enity on the id field. Here is the code.

....
class AcmeProfiles
    {
    /**
    * @ORM\Id
    * @ORM\OneToOne(targetEntity="\AcmeBundle\UserBundle\Entity\User")
    * @ORM\JoinColumn(name="id", referencedColumnName="id")
    */
    protected $id;
...

I only needed to change the profiles entity. You can leave the User entity untouched. I found this easier for me to manage profiles and profile cache while leaving the default User Entity more or less untouched. So now every other related entity will be joined to the profile entity and User Enity just for managing users i.e user creation, login, deletion, etc.

Once you query the profiles table, you can access the User Entity directly using e.g

...
$user_name = $acme_profile->getId()->getUsername();
$user_id = $acme_profile->getId()->getId();
$user_email = $acme_profile->getId()->getEmail();
....

2) New User Registrations with extended forms and so on. Now, this is where I spent so many hours pondering on. Let me re-introduce you to a FOSUser feature people take for granted, the UserManager! Don't bother overriding FOSUserBundle to do simple things. Use the UserManager to create unlimited different registration forms and process. It is soooo simple, call it in your controller like so

...
$userManager = $this->get('fos_user.user_manager');

// Create a new User
$user = $userManager->createUser();
$user->setUsername('John');
$user->setEmail('[email protected]');
$userManager->updateUser($user);
...

Simple. Let me share some of my code to sanitize user input a bit, check for already existing details, alert the user if so and importantly, log in the new user after registration successfull

...
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
...

    if ( $form->isValid() ){
        $username = strip_tags($request->get('username'));
        $email = strip_tags($request->get('email'));
        $password = $request->get('password');

        $userManager = $this->get('fos_user.user_manager');

        $user_email_exists = $userManager->findUserByEmail($email);
        $user_username_exists = $userManager->findUserByUsername($username);

        $user_exists = 0;
        if($user_email_exists){
            $request->getSession()->getFlashBag()->add(
                'error',
                'The chosen email ' . $email . ' is already in use'
            );
            $user_exists = $user_exists + 1;
        }
        if($user_username_exists){
            $request->getSession()->getFlashBag()->add(
                'error',
                'The chosen username ' . $username . ' is already in use'
            );
            $user_exists = $user_exists + 1;
        }
        if($user_exists > 0){
            return $this->redirect($this->
                generateUrl(
                    'registration_page'
                )
            );
        }
        else{
            $new_user = $userManager->createUser();
            $new_user->setUsername($username);
            $new_user->setEmail($email);
            $new_user->setPlainPassword($password);
            $new_user->setEnabled(true);
            $userManager->updateUser($new_user);

            $firstname = strip_tags($form->get('firstname')->getData());
            $lastname = strip_tags($form->get('lastname')->getData());

....
            $em->flush();

            $token = new UsernamePasswordToken($new_user, $new_user->getPassword(), 'main', $new_user->getRoles());

            $context = $this->get('security.context');
            $context->setToken($token);

            $request->getSession()->getFlashBag()->add(
                'success',
                'Congrats '.$firstname.', You Have Successfully Created Your Profile
            );
...