How to activate user registration by email?

Hi,

I try google about how to activate user registration by email but didnt find the answer.

Any one could share tips on how to do it in Yii?

The way i do it -

  1. Generate a random sha1 key using the user’s email -

$model->activation_key = sha1(mt_rand(10000, 99999).time().$model->email);

  1. Store that in the database along with other user details and the activation status as ‘false’ or 0.

  2. Construct a url which points to another action within the controller and has the activation key as a GET parameter, which will verify the activation key by comparing with the keys in the database. Send that url in an email to the user.


$activation_url = $this->createAbsoluteUrl('registration/validateKey', array('key'=>$model->activation_key));

  1. In the activation key validation action, compare the key in the get parameter against the keys in the database. If match found and activation status = 0, change activation status to 1 and tell user that everything is now hunky dory ;)

That’s it.

Wah so fast! Thanks Mukesh! I will try it right away!

i already got it. Can you comment any add on or weakness? Sorry yii newb here.

i make actionRegister() in SiteController.php


  public function actionRegister() {

                   

                    $model=new RegisterForm;

                    $newUser = new User;

                    

                    // if it is ajax validation request

                    if(isset($_POST['ajax']) && $_POST['ajax']==='login-form')

                    {

                            echo CActiveForm::validate($model);

                            Yii::app()->end();

                    }

    

                    // collect user input data

                    if(isset($_POST['RegisterForm']))

                    {

                            $model->attributes=$_POST['RegisterForm'];

                            

                         //   if ($model->validate()) {

                                    $newUser->username = $model->username;

                                    //$newSalt = $newUser->generateSalt();

                                    $newSalt=$newUser->generateSalt(); 

                                    

                                    $newUser->password = $newUser->hashPassword($model->password,$newSalt);

                                    $newUser->salt = $newSalt;

                                    

                                    $newUser->activationcode = $newUser->generateActivationCode($model->email);

                                  // $newUser->activationcode = sha1(mt_rand(10000, 99999).time().$email);

                                   $newUser->activationstatus = 0;

    

                                    //return $this->hashPassword($password,$this->salt)===$this->password;

                                    $newUser->username = $model->username;

    

                                    $newUser->email = $model->email;

                                    $newUser->joined = date('Y-m-d');

                                            

                                    if ($model->validate() && $newUser->save()) {

                                           //if want to go login, just uncomment this below

                                           // $identity=new UserIdentity($newUser->username,$model->password);

                                           // $identity->authenticate();

                                           // Yii::app()->user->login($identity,0);

                                            //redirect the user to page he/she came from

                                            

                                            //email activation code starts-----------------------------------------

                                           

                                            $to = $model->email;

                                            $subject = "Welcome To GhazaliTajuddin.com!";

                                            $message = "Thank you for joining!, we have sent you a separate email that contains your activation link";

                                            $from = "FROM: mr.ghazali@gmail.com";

                                            

                                            mail($to,$subject,$message,$from);

                                            

                                            //echo $to.$subject.$message.$from;

                                            

                                           $headers  = 'MIME-Version: 1.0' . "\r\n";

                                           $headers .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n";

                                           $headers .= 'From: Mr. Ghazali < mr.ghazali@gmail.com>' . "\r\n";

                                            

                                           $subject2 = "Your Activation Link";

    

                                           $message2 = "<html><body>Please click this below to activate your membership<br />".

                                                                    Yii::app()->createAbsoluteUrl('site/activate', array('email' => $newUser->email)).

                                                                    

                                                                   "

                                                                   

                                                                   Thanks you.

                                                                   ". sha1(mt_rand(10000, 99999).time().$email) ."

                                                                   </body></html>";

                                                                    

                                          mail($to, $subject2, $message2, $headers);

                                            //email activation code end-----------------------------------------

                                            

                                            $this->redirect(Yii::app()->user->returnUrl);

                                            

                                    }

                          //  }

                                    

                    }

                    // display the register form

                    $this->render('register',array('model'=>$model));

I also create actionActivate() in SiteController.php


    	

/**

    	 * Activation Action

    	 */

    	public function actionActivate()

    	{

     

            $email = Yii::app()->request->getQuery('email');

            

    		// collect user input data

    		if(isset($email))

    		{

    		  

              $model = User::model()->find('email=:email', array(':email'=>$email));   

              

              if($email == $model->email){            

                $model->activationstatus=1;

                $model->validate();

                $model->save();

              }

                        

    		}

      

    		// display the login form

    		 $this->render('activate',array('model'=>$model));

    

    	}

I’m just gonna answer here real quick if you don’t mind.

Because it’s sth you most likely will use more often I would sugggest to build a Mail Component extending CModel.

That way you can just do sth around the lines of:




$mail = new Mail;

$mail->to = $model->email;

$mail->body = $this->renderPartial('_mailTemplate', compact('model'), true);

if (!$mail->send())

    throw new CHttpException(500, 'something went horrible wrong');

else

    // set flash if needed here

    $this->redirect('site/index');



That would slim down your registerAction by quite a bit, and follows DRY.

Also the Mail Sending happens in the Component (either with normal mailsend or smtp with swiftMailer)

Thanks to inheriting from CModel you can use validation rules like in any other model.

Mail->send() pretty much just runs Mail->validate and send mail out afterwards.

example for actionActivate:




public funciton actionActivate($activation) {

    $model= User::model()->findByAttributes(array(

      'activation_code' => $activation

    ));

    if ($model === null)

       throw new CHttpException(404, 'Not found');

    else 

       $model->activationstatus = 1;

    $model->save();

    //redirect / flash / login whatever

}



just my two cents to get some more structure in the code… yours will most likely work, but be a pain to maintain over time.

rho

Thanks for your suggestion. Will looking forward on creating mail component.

Thank you Mukesh and friends. That’s exactly what I was looking for.

Hi,

After click on email activation link http://www.example.com/devtest/index.php?r=user/check&activationcode=bc74873d0e3f684d3e6b99a36169a793ee688406 then it redirect to login page. I think my following controller code not working for view file check.php which located on user directory.


public function actionCheck()

  {

    $model=new User;

    $activationcode = Yii::app()->request->getQuery('activationcode');

    

    if(isset($activationcode))

    {

      $model = User::model()->findByAttributes(array('activationcode'=>$activationcode));

      

      if($model !== null)

      {            

        $model->status=1;

        $model->save();

        Yii::app()->user->setFlash('check','Thank you for register with us');

        $this->refresh();

      }

      

    }


    $this->render('check',array(

			'model'=>$model,

		));


  }

I am not sure how I can handle GET URL action in UserController. Also, I already tested by adding word ‘check’ in accessRules but then browser show me Page not redirect properly.


public function accessRules()

	{

		return array(

			array('allow',  // allow all users to perform 'index' and 'view' actions

				'actions'=>array('index','create','view','captcha'),

				'users'=>array('*'),

			),

.....

.....

);

}

Any idea? Please give me a solution.

You will find complete discussion in http://www.yiiframework.com/forum/index.php/topic/35249-facing-difficulties-to-activate-user-registration-by-email/page__gopid__169538#entry169538

With Thanks,

MRS

Hi ter,

Im also looking for same solution. got any working solution.

pls share it

thank you.

for each users maintain one status column like ‘active’ in Table, default value for this column is inactive.

when user clicks the link from mail/invitation, activate the user by updating the value from inactive to active?

Not sure if you are running into this, but I had to set up my urlManager in config/main.php like this:


			

'<controller:\w+>/<cact:\w+>/<id:\d+>/<sha1:\w+>'=>'<controller>/<cact>',



FYI… this caused a infinite loopback when using Gii. I think there is a fix for this, but I just comment it out on the rare times I use Gii in an up and running application.

try this config for URL manager

‘urlManager’ => array(

            'urlFormat' 	=&gt; 'path',


            'showScriptName'=&gt; false,


            'rules' 		=&gt; array(               


					                '&lt;controller:&#092;w+&gt;/&lt;id:&#092;d+&gt;' =&gt; '&lt;controller&gt;/view',


					                '&lt;controller:&#092;w+&gt;/&lt;action:&#092;w+&gt;/&lt;id:&#092;d+&gt;' =&gt; '&lt;controller&gt;/&lt;action&gt;',


					                '&lt;controller:&#092;w+&gt;/&lt;action:&#092;w+&gt;' =&gt; '&lt;controller&gt;/&lt;action&gt;',


            					),


    	)	


),

Hi I am new in Yii. What is RegisterForm in line 2. :( I created members model and create register form.Can i know the meanings of your sample code sir. Plz