8

I'm using fos user bundle and pugx multi user bundle. I've read all the documentation and I'm new to Symfony. In the pugx multi user bundle there's a sample on every point but one: sucessful registration.

  • Samples of overriding controllers for generating forms => ok
  • Samples of overriding templates for generating forms => ok
  • Samples of overriding successful registration sample => nothing.

Here's my code:

class RegistrationController extends BaseController
{
    public function registerAction(Request $request)
    {   
        $response = parent::registerAction($request);
        return $response;
    }   

    public function registerTeacherAction()
    {   
        return $this->container
            ->get('pugx_multi_user.registration_manager')
            ->register('MyBundle\Entity\PersonTeacher');
    }   

    public function registerStudentAction()
    {   
        return $this->container
            ->get('pugx_multi_user.registration_manager')
            ->register('MyBundle\Entity\PersonStudent');
    }   
}

The problem is with ->get('pugx_multi_user.registration_manager') which returns a manager. In the fos user overring controllers help, they get either a form or a form.handler. I'm having hard times to "link" those with the pugx_multi_user manager.

What code should I put in the registerTeacherAction() to set roles for teacher, and in registerStudentAction() to set roles for student on a successful registration?

Olivier Pons
  • 15,363
  • 26
  • 117
  • 213

1 Answers1

9

Solution 1 (Doctrine Listener/Subscriber)


You can easily add a doctrine prePersist listener/subscriber that adds the roles/groups to your entities depending on their type before persisting.

The listener

namespace Acme\YourBundle\EventListener;

use Doctrine\ORM\Event\LifecycleEventArgs;
use Acme\YourBundle\Entity\Student;

class RoleListener
{
    public function prePersist(LifecycleEventArgs $args)
    {
        $entity = $args->getEntity();
        $entityManager = $args->getEntityManager();

        // check for students, teachers, whatever ...
        if ($entity instanceof Student) {
            $entity->addRole('ROLE_WHATEVER');
            // or
            $entity->addGroup('students');
            // ...
        }

       // ... 
    }
}

The service configuration

# app/config/config.yml or load inside a bundle extension
services:
    your.role_listener:
        class: Acme\YourBundle\EventListener\RoleListener
        tags:
            - { name: doctrine.event_listener, event: prePersist }

Solution 2 (Doctrine LifeCycle Callbacks):


Using lifecycle callbacks you can integrate the role-/group-operations directly into your entity.

/**
 * @ORM\Entity()
 * @ORM\HasLifecycleCallbacks()
 */
class Student
{
    /**
     * @ORM\PrePersist
     */
    public function setCreatedAtValue()
    {
        $this->addRole('ROLE_WHATEVER');
        $this->addGroup('students');
    }

Solution 3 (Event Dispatcher):


Register an event listener/subscriber for the "fos_user.registration.success" event.

How to create an event listener / The EventDispatcher component.

Nicolai Fröhlich
  • 51,330
  • 11
  • 126
  • 130
  • 1
    Quote of the link: `One important thing to notice is that a listener will be listening for all entities in your application.`... This implies that each time there's a persist action, *whatever* the persist entity is, this function will be called? If so, excuse me to say it that way, but it's a bit too much for just an action when registering a student or a teacher... that's kind of use a sledgehammer to crack a nut. Are you sure there's no other way? – Olivier Pons Oct 11 '13 at 16:27
  • well it's definitely a good way to go in terms of decoupling. the 1-2 little `instanceof` checks in there won't really slow you down. you could aswell integrate the role-adding directly into your entities using [lifecycle callbacks](http://symfony.com/doc/current/book/doctrine.html#lifecycle-callbacks) if that sounds better for you. Well there are several ways, override the RegistrationController, fire an event on successful-registration, ... – Nicolai Fröhlich Oct 11 '13 at 16:29
  • That's it! I've got `Person` which is abstract class, and `PersonTeacher` which implements `Person` and `PersonStudent` which implements `Person` too. So I'll add custom "lifecycle" callback for each class, and that should do the trick. May I ask you to add your comment in your answer? This would help anyone reading this. Thank you very much indeed. – Olivier Pons Oct 11 '13 at 16:36
  • there you go ... I'll probably come back to your [other question](http://stackoverflow.com/questions/19318065/how-to-pre-check-some-options-in-a-custom-form) regarding the "pre-checked" entity field-types later :) happy coding! – Nicolai Fröhlich Oct 11 '13 at 16:44
  • @nifr , you are great – hous Jun 15 '16 at 21:12
  • 4 years later, I've given up on Php and that Symfony marmelade... it's one line in Django, easier to read, instant work, at the right place. I'll never go back to such horrible things. Thanks again for your answer. – Olivier Pons Oct 06 '18 at 10:26