Yii 1.1: Implementing a Registration Process using the yii-user-management module

22 followers

Hi Folks,

in this page i want to show you how to implement your own registration process using the yii-user-management module. This document is also included in the docs/ directory of the module.

We want our user to only register with a email address and requires him to add some information about him in a text area.

We also do not want him to enter a password. The password should be automatically generated and send to him by Email.

This differs from the example registration logic provided by yii-user-management. We are going to extend the provided classes and change the places that are necessary. In Yum all classes are prefixed with Yum for exactly this purpose.

Lets assume you have the profile and the registration submodule of the yii-user-management installed. You will have the following directory structure:

modules/
    profile/
        controllers/
            YumProfileController
            YumFieldController
        models/
            YumProfile
            YumProfileField
 
    registration/
        controllers/
            YumRegistrationController
        views/
            registration/
                registration.php

1.) Overriding YumRegistrationController

Create a file RegistrationController.php in your project-specific controllers/ directory containing some code like this:

Yii::import(
        'application.modules.registration.controllers.YumRegistrationController');
class RegistrationController extends YumRegistrationController {
 
}

This class extends the YumRegistrationController and has all the abilities that the yum registration class has. We will adjust the behavior of this controller later.

2.) Adjusting the registration view files

Now we create the view directory for our new created controller and copy our example view files over there:

$ cd /path/to/my/webapp/protected
$ mkdir views/registration
$ cp modules/registration/views/registration/* views/registration

Our new Controller now uses this view file for its rendering.

We change the registration.php to look something like this:

<h2> My Registration Page </h2>
 
<p> Hi there, please enter your E-Mail address and drop a note about you </p>
 
<?php $this->breadcrumbs = array(Yum::t('Registration')); ?>
 
<div class="form">
<?php $activeform = $this->beginWidget('CActiveForm', array(
            'id'=>'registration-form',
            'enableAjaxValidation'=>false,
            'focus'=>array($profile,'email'),
            ));
?>
 
<?php echo Yum::requiredFieldNote(); ?>
<?php echo CHtml::errorSummary($profile); ?>
 
<div class="row"> <?php
echo $activeform->labelEx($profile,'email');
echo $activeform->textField($profile,'email');
?> </div>  
 
 
<div class="row"> <?php
echo $activeform->labelEx($profile,'about');
echo $activeform->textArea($profile,'about');
?> </div>  
 
<div class="row submit">
    <?php echo CHtml::submitButton(Yum::t('Registration')); ?>
</div>
 
<?php $this->endWidget(); ?>

3.) Changing the Controller Behavior

override the actionRegistration() of your Controller like this:

public function actionRegistration() {
        Yii::import('application.modules.profile.models.*');
        $profile = new YumProfile;
 
        if (isset($_POST['Profile'])) { 
            $profile->attributes = $_POST['YumProfile'];
 
            if($profile->save())
                $user = new YumUser;
                $password = YumUser::generatePassword();
// we generate a dummy username here, since yum requires one
                $user->register(md5($profile->email), $password, $profile);
 
                $this->sendRegistrationEmail($user, $password);
                Yum::setFlash('Thank you for your registration. Please check your email.');
                $this->redirect(Yum::module()->loginUrl);
            }
 
        $this->render('registration', array(
                    'profile' => $profile,
                    )
                );  
    }

Now, we also need to override the sendRegistrationEmail method, because we want to include the clear-text password in the email:

public function sendRegistrationEmail($user, $password) {
            if (!isset($user->profile->email)) {
                throw new CException(Yum::t('Email is not set when trying to send Registration Email'));
            }
            $activation_url = $user->getActivationUrl();
 
            if (is_object($content)) {
                    $body = strtr('Hi, {email}, your new password is {password}. Please activate your account by clicking this link: {activation_url}', array(
                                '{email}' => $user->profile->email,
                                '{password}' => $password,
                                '{activation_url}' => $activation_url));
 
                $mail = array(
                        'from' => Yum::module('registration')->registrationEmail,
                        'to' => $user->profile->email,
                        'subject' => 'Your registration on my example Website',
                        'body' => $body,
                        );
                $sent = YumMailer::send($mail);
            }
 
            return $sent;
        }

4.) Making the "about" field required.

create a file models/Profile.php that extends the YumProfile:

Yii::import('application.modules.profile.models.YumProfile');
class Profile extends YumProfile {
 
    function rules() {
        $rules = parent::rules();
        $rules[] = array('about', 'required');
        return $rules;
    }
}

5.) Thats it. Thanks to the good OOP-paradigma, in general, and the strict usage of yii & yum, its really easy to adjust the logic. Even more complicated (or simpler) registration techniques can easily be implemented.

Total 6 comments

#17457 report it
Federico Benedetti at 2014/06/15 12:02pm
How many little error in this tutorial?

Hi all, this extension has a big potential, but this tutorial has many little errors. Possible anyone corrects them?

For example:

1) First Name and Second Name are fields set with 1 (required) in database table "profile_field". I must set them to 0 or i get an error in the form validation because they are required

2) in ActionRegistration() how many error: public function actionRegistration() {

Yii::import('application.modules.profile.models.*');
        $profile = new YumProfile; // <-- ERROR: the right is: $profile = new Profile; 
 
        if (isset($_POST['Profile'])) { 
            $profile->attributes = $_POST['YumProfile']; // <-- ERROR: the right is: $profile->attributes = $_POST['Profile'];
 
            if($profile->save()) // <-- ERROR: the save() is called by $user->register(...) method. I just replace: if($profile->validate()) { 
                $user = new YumUser;
                $password = YumUser::generatePassword();
// we generate a dummy username here, since yum requires one
                $user->register(md5($profile->email), $password, $profile); // i prefere to do username=email so i replace with: $user->register($profile->email, $password, $profile); and i rewrite the $usernameRequirements['match'] in the UserModule.php with an email pattern

3) Remember to call your new registration with this url: index.php?r=Registration/registration , otherwise you call the DEFAULT extension registration. Be ATTENTION! It's different the (r)egistration/registration [default] and the (R)egistration/registration [your new registration]

4) Remember to add in the 'modules' section of the main.php configuration:

'registration' => array(),

5) the right BASIC 'user' section in the main.php configuration must be:

'user'=>array(
            // enable cookie-based authentication
            'allowAutoLogin'=>true,
                        'loginUrl' => array('//user/user/login'),
                        'class' => 'application.modules.user.components.YumWebUser',
        ),

6) in the SendRegistrationEmail() what is the scope of the $content variable???

if (is_object($content)) {
                    $body = strtr('Hi, {email}, your new password is {password}. Please activate your account by clicking this link: {activation_url}', array(
                                '{email}' => $user->profile->email,
                                '{password}' => $password,
                                '{activation_url}' => $activation_url));
 
                $mail = array(
                        'from' => Yum::module('registration')->registrationEmail,
                        'to' => $user->profile->email,
                        'subject' => 'Your registration on my example Website',
                        'body' => $body,
                        );
                $sent = YumMailer::send($mail);
            }

Extremelly basic error...(probabilly a too fast copy/paste) So i delete the "if (is_object($content)) { " and the last " }"

7) YumProfile.php in the method beforeValidate()

if($this->isNewRecord)
            //$this->timestamp = time(); //<--ERROR ORIGINAL
                        $this->timestamp = new CDbExpression('NOW()'); // I solve in this way
 
        return parent::beforeValidate();

After many and many hours spent between google, forums and debugging, i'm able to register a valid user simply with a Mail form. I think to write here the main errors i find, and i hope this post could help in the future, until this tutorial will be fixed. (sorry for my english if i do language errors)

#17270 report it
Haule at 2014/05/18 07:32pm
Undefined variable: form

01 02

<?php echo Yum::t('Registration'); ?>

03 04 <?php $this->breadcrumbs = array(Yum::t('Registration')); ?> 05 06

<

div class="form"> 07 <?php $activeform = $this->beginWidget('CActiveForm', array( 08 'id'=>'registration-form', 09 'enableAjaxValidation'=>true, 10 'enableClientValidation'=>true, 11 'focus'=>array($form,'username'), 12 )); 13 ?> 14 15 <?php echo Yum::requiredFieldNote(); ?> 16 <?php echo CHtml::errorSummary(array($form, $profile)); ?> 17 18

<? 19 echo $activeform->labelEx($form,'username'); 20 echo $activeform->textField($form,'username'); 21 ?>

22 23

<

div class="row"> <?

#15882 report it
Shahir Reza Ali at 2013/12/26 05:16am
error

followed your tutorial, but had to add this into my config/main.php

'modules' => array(
'registration' => array(
            'enableRegistration' => true,
            'enableCaptcha' => true,
            'registrationView' => 'application.views.registration.registration',
            'controllerMap' => array(
                'registration' => array(
                    'class' => 'application.controllers.RegistrationController' ),
            ),
        ),
),

before i could access the page using http://localhost/index.php?r=registration/registration

but it gives me this error. any ideas?

Declaration of RegistrationController::sendRegistrationEmail() should be compatible with YumRegistrationController::sendRegistrationEmail($user)
#14886 report it
yiibeginer at 2013/09/18 08:51am
I'm getting following error while overriding "sendRegistrationEmail"

Edit:

Even Overriding is not working for sendRegistration()


I'm getting following error while overriding "sendRegistrationEmail"

Declaration of RegistrationController::sendRegistrationEmail() should be compatible with YumRegistrationController::sendRegistrationEmail($user)

#7278 report it
pligor at 2012/03/09 04:14am
First Name Last Name required

Because First Name and Last Name are missing from this wiki the example is not functional. I guess it is outdate. However it is still a good example of the extensibility of the user management extension :)

#5108 report it
DG Esteban A. PĂ©rez at 2011/09/14 04:15pm
Missing $content assignation

You checked if $content is an object, but is never assigned. This variable, $content, is checked to be an object in the original sendRegistrationEmail method, because text is taken from the translations table. Here, in your example, is useless, therefore the if block could be removed painless.

Leave a comment

Please to leave your comment.

Write new article