Question

I'm using zfcUser for registration and auth, and i have some question. User can register by 2 types of profile, and the forms are different, so the question is, what is the best practice to use few registration forms in zfcUser, on one page, using tabs.

Was it helpful?

Solution

I can think of a few solutions. This is the one I think is the best for your purpose. It is a bit of code.

Before all, you have to think about the database, probably you will have one table with diferent fields, or one common table and the different tables with the extra fields depending on the user type. The solution is the the same.

First, As you know, there is a service for retrieving the register form. You could use the register event callbacks to modify them, but, since you need to different forms, and none of them is the standard one, i think that the best is to create 2 new services for the two new forms.

For that, in your module in the getServiceConfig() function, you create this two services, that reply the zfcuser_register_form service but add and remove fields and input filter fields

<?
public function getServiceConfig()
{
    return array(

        'factories' => array(

            'zfcuser_register_form_usertype1' => function ($sm) {
                $options = $sm->get('zfcuser_module_options');
                $form = new Form\Register(null, $options);

                ///for type:
                $this->add(array(
                    'name' => 'usertype',
                    'attributes' => array(
                        'type'  => 'hidden',
                        'value' => '1',
                    ),
                ));

                /*
                * Add o remove fields to the form
                */


                $form->setInputFilter(new Form\RegisterFilter(
                    new Validator\NoRecordExists(array(
                        'mapper' => $sm->get('zfcuser_user_mapper'),
                        'key'    => 'email'
                    )),
                    new Validator\NoRecordExists(array(
                        'mapper' => $sm->get('zfcuser_user_mapper'),
                        'key'    => 'username'
                    )),
                    $options
                ));


                /*
                 * Add o remove fields to the input filter
                 */
                return $form;
            },

            ////////////////////////////////////////////////////////////


            'zfcuser_register_form_usertype2' => function ($sm) {
                $options = $sm->get('zfcuser_module_options');
                $form = new Form\Register(null, $options);

                ///for type:
                $this->add(array(
                    'name' => 'usertype',
                    'attributes' => array(
                        'type'  => 'hidden',
                        'value' => '2',
                    ),
                ));

                /*
                * Add o remove fields to the form
                */


                $form->setInputFilter(new Form\RegisterFilter(
                    new Validator\NoRecordExists(array(
                        'mapper' => $sm->get('zfcuser_user_mapper'),
                        'key'    => 'email'
                    )),
                    new Validator\NoRecordExists(array(
                        'mapper' => $sm->get('zfcuser_user_mapper'),
                        'key'    => 'username'
                    )),
                    $options
                ));


                /*
                 * Add o remove fields to the input filter
                 */
                return $form;
            },




        ),
    );

}

For a guide on how to add o remove fields go to the official manual page on forms

Then, in the controler/action that will show the registration forms (it should be your own, route, rather than the standard zfuser one)

public function registerAction()
{
    //get the first form
    $form1 = $this->getServiceLocator ()->get ( 'zfcuser_register_form_usertype1' );

    //set the action to the zfuser registation route
    $form1->setAttribute('action', $this->url('zfcuser/register'));
    $form1->setAttribute('method', 'post');


    //the same for the second form
    $form2 = $this->getServiceLocator ()->get ( 'zfcuser_register_form_usertype2' );
    $form2->setAttribute('action', $this->url('zfcuser/register'));
    $form2->setAttribute('method', 'post');

    //send both form to the view
    return array('form1' => $form1,'form2' => $form2);
}

Then the view, just retrieve the forms, and render them, as you would with any form (If you have any doubt go to the above linked manual, that also contains the information on how to render forms)

<?php

/*
 * html for tabs
 */

$form = $this->form1;
$form->prepare();

echo $this->form()->openTag($form);
echo $this->formHidden($form->get('usertype'));
echo $this->formRow($form->get('field1'));
echo $this->formRow($form->get('field2'));
echo $this->formSubmit($form->get('submit'));
echo $this->form()->closeTag();

/*
* other html for tabs
*/

$form2 = $this->form2;
$form2->prepare();

echo $this->form()->openTag($form2);

echo $this->formHidden($form->get('usertype'));
echo $this->formRow($form2->get('field1'));
echo $this->formRow($form2->get('field2'));
echo $this->formSubmit($form2->get('submit'));
echo $this->form()->closeTag();


/*
* other html for tabs
*/

Now, you have your forms. The only remaining thing is to process the registration. As you probably knows, zfcuser has an event manager that alows us to schedule actions for some events, for example, when a new account is created

For that, in your module, in the onBootstrap function you

 <?
 /**
 * executes on boostrap
 *
 * @param \Zend\Mvc\MvcEvent $e         
 * @return null
 */
public function onBootstrap(MvcEvent $e) {


    //retrieve the zfcuser event manager
    $sm = $e->getApplication()->getServiceManager();
    $zfcServiceEvents = $sm->get('zfcuser_user_service')->getEventManager();

    // add a callback to Store the field when the form is submited
    $zfcServiceEvents->attach('register', function ($e) use($sm)
    {
        $form = $e->getParam('form');//here you have the submited form
        $user = $e->getParam('user');//here you have the already created standard user entity


        $type=$form->get("usertype")->getValue();//retrieve the user type
        //with this, you can decide what other fields to retrieve, 
        //and how to asign it to the entity or to other related entities:

        if ($type==1) {
              //...
         }
         else {
              //...

        }


   });
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top