Jump to content
Larry Ullman's Book Forums

Registration In Yii


Jonathon
 Share

Recommended Posts

Right, I'm trying to put together some code to register a user in Yii.

 

I just wanted some feedback on it for problems or general logic within the whole Yii framework. This is what I did.

 

I created a new file called register.php

 

<?php
/* @var $this SiteController */
/* @var $model RegistrationForm */
/* @var $form CActiveForm  */

$this->pageTitle=Yii::app()->name . ' - Register';
/*$this->breadcrumbs=array(
	'Login',
);*/

$this->layout = 'sidebar';
?>
<div class="search">
	<div class="form-center span5">

        <h1>Register</h1>

<div class="form">
<?php $form=$this->beginWidget('CActiveForm', array(
	'id'=>'registration-form',
	'enableClientValidation'=>true,
	'clientOptions'=>array(
		'validateOnSubmit'=>true,
	),
)); ?>

	<div class="row">
		<?php echo $form->textField($model,'first_name', array('placeholder'=>'First Name')); ?>
		<?php echo $form->error($model,'first_name'); ?>
	</div>

	<div class="row">
		<?php echo $form->textField($model,'last_name', array('placeholder'=>'Last Name')); ?>
		<?php echo $form->error($model,'last_name'); ?>
	</div>

	<div class="row">
		<?php echo $form->textField($model,'email', array('placeholder'=>'Your Email')); ?>
		<?php echo $form->error($model,'email'); ?>
	</div>

	<div class="row">
		<?php echo $form->passwordField($model,'pass', array('placeholder'=>'Password')); ?>
		<?php echo $form->error($model,'pass'); ?>
	</div>
    
	<div class="row buttons">
		<?php echo CHtml::submitButton('Submit', array('class'=>'btn btn-primary')); ?>
	</div>

<?php $this->endWidget(); ?>
</div><!-- form -->
	</div>
		</div>

 

saved it in my views/site folder.

 

Then I created a RegisterForm.php that I basically copied from the LoginForm.php and edited.

 

<?php

/**
 * RegistrationForm class.
 * RegistrationForm is the data structure for submitting
 * user data. It is used by the 'registration' action of 'SiteController'.
 */
class RegistrationForm extends CFormModel
{
	public $first_name;
	public $last_name;
	public $email;
	public $pass;
	public $active;
	


	/** * Declares the validation rules.
     
* The rules state that first name, last name, email and pass are required,
     * email must be valid email.
     * email must be unique using User class.
     */
public function rules() { 
return array( 
// username and password are required 
array('first_name, last_name, email, pass', 'required'), 
// trim date for first names, further validation? strip_tags? 
array('first_name, last_name, email, pass', 'filter', 'filter' => 'trim'), 
// email must be valid email 
array('email', 'email'), 
// email must be unique and use User class 
array('email', 'unique', 'className' => 'User'), 
// default for date created ); } 

/** * Declares attribute labels. */ 
public function attributeLabels() { 
return array( 
'first name'=>'First Name', 
'last_name'=>'Last Name', 
'email'=>'Email', 
'password'=>'Password', 
); 
} 
}
   
 

 

And saved that in my models folder.

 

Thenin my site controller I added the following action

 

	/*
	* Displays and handles the registration process
	*/
	public function actionRegister() 
	{
	$model=new RegistrationForm;
	$newUser = new User;
                
	// if it is ajax validation request
	
	if(isset($_POST['ajax']) && $_POST['ajax']==='registration-form')
	{
			echo CActiveForm::validate($model);
			Yii::app()->end();
	}
	
	// collect user input data
	if(isset($_POST['RegistrationForm']))
	{
			$model->attributes=$_POST['RegistrationForm'];
			
			if ($model->validate()) {
					$newUser->first_name = $model->first_name;
					$newUser->last_name = $model->last_name;
					$newUser->email = $model->email;
					$newUser->pass = hash_hmac('sha256', $model->pass, Yii::app()->params['encryptionKey']);
					$newUser->active = md5(uniqid(rand(), true));
					$newUser->date_modified = NULL;
					$newUser->date_created = new CDbExpression('NOW()');
					//$newUser->live = 1;
					
					if($newUser->save()) {
						  
							// Everything saved, redirect
							 $this->redirect(array('site/index'));
					}
				}
			}
		 // display the register form
		 $this->render('register',array('model'=>$model));
	}

 

It does work, but I wanted an opinion of it it has any potential security flaws/issues or if the logic is in the wrong files/locations etc. You may see some of my own questions in there like "strip_tags()?" for example. Also I wondered about the rules() Those rules are in the RegistrationForm.php but I also have rules() in my User model. This would appear to be a wrong thing to be occurring. However, I wasn't sure what the best way to fix this was? 

 

Thanks in advance

 

Jonathon

Link to comment
Share on other sites

Personally, I would just use the User model and its create view. As it stands, you're duplicating all the functionality in two models, one of which will only ever be used once per site user. 

 

Also, I'd take some of that functionality (such as assignments to active, date_modified, and date_created) and put it in the model. 

 

And your RegistrationForm model wouldn't need the "active" attribute, as it's not used by that model. 

 

That being said, you did a great job creating the MVC components from scratch.

Link to comment
Share on other sites

Hi Larry,

Thanks for the nice words. I forgot about the create functions that come built into Yii, so I'm glad you pointed that out to me. I should really have twigged when I realised I had two sets of rules(). Anyway, thanks, I had a re-jig of things and came up with the following.

User Model

/*	* function to register new user internal variables	*/	
public function newUserRegistrationVariables()	{		
// Internally assigned variables		
$this->active = md5(uniqid(rand(), true));		
$this->date_modified = NULL;		
$this->date_created = new CDbExpression('NOW()');				

return array($this->active, $this->date_modified, $this->date_created);	
     }
}

User Controller


public function actionCreate()	{		
// new User model		
$model=new User;
				
// Bring internal registration variables from model()		
$registrationInternalVariables = $model->newUserRegistrationVariables();		
// Uncomment the following line if AJAX validation is needed		
// $this->performAjaxValidation($model);		
if(isset($_POST['User'])){			
$model->attributes=$_POST['User'];
						
// Validate date from form using rules()			
if ($model->validate()) {					
$model->first_name;
$model->last_name;					
$model->email;					
$model->pass = hash_hmac('sha256', $model->pass, Yii::app()->params['encryptionKey']);					
$model->active = $registrationInternalVariables[0];					
$model->date_modified = $registrationInternalVariables[1];					
$model->date_created = $registrationInternalVariables[2];								

if($model->save()) {								
// Everything was saved ok return success message				 
Yii::app()->user->setFlash('register-success','Thank you! An activation email has been sent to your email address.');		
        }	
    }
}		
$this->render('create',array(			
'model'=>$model,		
));	
}

So I hope that's a secure and better way to go about it

Thanks

Jonathon

Link to comment
Share on other sites

That's definitely better. The only thing left to change would be to make the newUserRegistrationVariables() method a beforeSave() method so it automatically sets those values. You can use isNewRecord to only do it for new registrations. There's an example in the book in Chapter 5, I believe.

Link to comment
Share on other sites

  • 2 years later...

I am getting the fatal error that the  class 'yii ' is not found 

CHttpException

The system is unable to find the requested action "Reg.php". please help me out to solve

Edited by saritha
Link to comment
Share on other sites

  • 3 years later...

CException

Property "RegisterForm.pass" is not defined.

/opt/lampp/htdocs/yii1.1/framework/web/helpers/CHtml.php(2760)

2748             $name=substr($attribute,0,$pos);
2749             $value=$model->$name;
2750             foreach(explode('][',rtrim(substr($attribute,$pos+1),']')) as $id)
2751             {
2752                 if((is_array($value) || $value instanceof ArrayAccess) && isset($value[$id]))
2753                     $value=$value[$id];
2754                 else
2755                     return null;
2756             }
2757             return $value;
2758         }
2759         else
2760             return $model->$attribute;
2761     }
2762 
2763     /**
2764      * Appends {@link errorCss} to the 'class' attribute.
2765      * @param array $htmlOptions HTML options to be modified
2766      */
2767     protected static function addErrorCss(&$htmlOptions)
2768     {
2769         if(empty(self::$errorCss))
2770             return;
2771 
2772         if(isset($htmlOptions['class']))

 

 

 

 

 

Link to comment
Share on other sites

 Share

×
×
  • Create New...