Call the expert: Simple Registration with sfDoctrineGuardPlugin

So, after my last tutorial demonstrating how to customize the sfGuardUser admin generator module in the sfDoctrineGuardPlugin I have had several requests for a simple tutorial on how to build a registration module for the plugin as well.

This tutorial assumes you have read my first post on customizing sfDoctrineGuardPlugin.

Generate the Module

First we need to generate a new module named register where we will implement our initial registration functionality.

$ ./symfony generate:module frontend register
 

Create RegisterForm

Next thing we need to do is create a custom form class that is a child of the generated sfGuardUserForm located in lib/model/doctrine/sfDoctrineGuardPlugin/sfGuardUserForm.class.php. You can put this file anywhere but I would recommend putting it in apps/frontend/modules/register/lib/RegisterForm.class.php.

<?php
class RegisterForm extends sfGuardUserForm
{
  public function configure()
  {
    // Remove all widgets we don't want to show
    unset(
      $this['is_active'],
      $this['is_super_admin'],
      $this['updated_at'],
      $this['groups_list'],
      $this['permissions_list'],
      $this['last_login'],
      $this['created_at'],
      $this['salt'],
      $this['algorithm']
    );
 
    // Setup proper password validation with confirmation
    $this->widgetSchema['password'] = new sfWidgetFormInputPassword();
    $this->validatorSchema['password']->setOption('required', true);
    $this->widgetSchema['password_confirmation'] = new sfWidgetFormInputPassword();
    $this->validatorSchema['password_confirmation'] = clone $this->validatorSchema['password'];
 
    $this->widgetSchema->moveField('password_confirmation', 'after', 'password');
 
    $this->mergePostValidator(new sfValidatorSchemaCompare('password', sfValidatorSchemaCompare::EQUAL, 'password_confirmation', array(), array('invalid' => 'The two passwords must be the same.')));
  }
}
 

Implement the Action

Now we need to implement the action which will handle the registration. This code needs to be added to apps/frontend/modules/register/actions.class.php in the executeIndex() function.

public function executeIndex(sfWebRequest $request)
{
  $this->form = new RegisterForm();
  if ($request->isMethod('post'))
  {
    $this->form->bind($request->getParameter('sf_guard_user'));
    if ($this->form->isValid())
    {
      $this->form->save();
 
      $this->getUser()->signIn($this->form->getObject());
      $this->redirect('@homepage');
    }
  }
}
 

The above action will process the form, save the user and sign the new user in.

Implement the Template

In the last step we implemented an action that creates a RegisterForm instance in the $this->form variable. This form instance is available in apps/frontend/modules/register/templates/indexSuccess.php in the $form variable so we can easily render the form like below:

<h1>Register</h1>
 
<?php echo $form->renderFormTag(url_for('register/index')) ?>
  <table>
    <?php echo $form ?>
  </table>
 
  <input type="submit" name="register" value="Register" />
</form>
 

Use sfGuardSecurityUser

The last thing we need to do is change apps/frontend/lib/myUser.class.php to extend sfGuardSecurityUser instead of sfBasicSecurityUser.

class myUser extends sfGuardSecurityUser
{
}
 

Now when you view http://localhost/register you should see the following in your browser.

sfDoctrineGuardPlugin Register

Comments

with doctrine? this is same for propel and doctrine..
When I try to register, I get an error: Call to undefined method myUser::signIn.
check if myUser is extending sfGuardSecurityUser
Please break lines in your source code at a reasonable width as otherwise some feed readers, such as the LiveJournal friendspage, will introduce a horizontal scrollbar for one's entire feed for the day. Thanks!
You probably want to ensure that the username provided is unique:

$this->validatorSchema['username'] = new sfValidatorDoctrineUnique(array('model' => 'sfGuardUser', 'column' => 'username'));
@jeremy

Uniqueness is enforced via Doctrine validators (through schema).

True, however, that sf should validate. I'm guessing this is an error of the Form base class generator.
If anyone is wondering how to add the custom Profile Form, just add this to the RegisterForm.class.php:

$profileForm = new ProfileForm($this->object->Profile);
unset($profileForm['id'], $profileForm['sf_guard_user_id']);
$this->embedForm('Profile', $profileForm);

Comments are closed.

To ensure that comments stay relevant, they are closed for old posts.