Sorry my English… I’m from brazil and don’t practice my writing a lot.
Hey dude. I just did the same thing this week. So the content still fresh on my mind.
Follow these instructions. If you have any questions mail me at thiagovidal@gmail.com or add me on msn within the same email address.
Remember that you should have 3 things basically:
M - Model (../models/RegistrationForm.php)
V - View (../views/site/registration.php)
C - Controller (../controllers/SiteController.php) you can use another controller instead like (../controllers/RegistrationController.php). Remember that the URL should point to correct controller.
Ex:
(first scenario) http://localhost/yourapp/index.php?r=site/registration (this will look at SiteController)
(other scenario) http://localhost/yourapp/index.php?r=registration (this will look at RegistrationController)
Something like that.
I build my model using yiic tool, just to get the skeleton. After some changes my model became:
Remeber that your registration form should extends CActiveRecord insted CFormModel. On my case my extends model Users that already is a CActiveRecord.
Why? Because you are dealing with your database I think its best than CFormModel that doesn’t provide some functions.
class RegistrationForm extends Users
{
// don't forget to declare variables outside from your database table otherwise you will get anoing errors.
public $bDay;
public $bMonth;
public $bYear;
public $passwordConfirm;
public $verifyCode;
/**
* @return array validation rules for model attributes.
*/
public function rules()
{
return array(
//required fields
array('firstName, lastName, birthday, bDay, bMonth, bYear, username, password, passwordConfirm, secretQuestion, secretAnswer, email, verifyCode', 'required'),
//lenght
array('username', 'length', 'max'=>25, 'min' => 3,'message' => Yii::t('default', 'Incorrect username (length between 3 and 20 characters).')),
array('password', 'length', 'max'=>128, 'min' => 6,'message' => Yii::t('default', 'Incorrect password (minimal length 4 symbols).')),
array('secretQuestion','length','max'=>255),
array('secretAnswer','length','max'=>128, 'min' => 3),
//unique
array('username', 'unique', 'message' => Yii::t('default', "This user's name already exists.")),
array('email', 'unique', 'message' => Yii::t('default', "This users's email adress already exists.")),
//validation '/^[A-Za-z]+$/u'
array('firstName', 'match', 'pattern' => "/^[a-zá-úA-ZÁ-Úºª ]+$/", 'message' => Yii::t('default', 'Names can not contain numbers ou special characters')),
array('lastName', 'match', 'pattern' => "/^[a-zá-úA-ZÁ-Úºª ]+$/", 'message' => Yii::t('default', 'Names can not contain numbers ou special characters')),
array('username', 'match', 'pattern' => '/^[A-Za-z0-9]+$/u', 'message' => Yii::t('default', 'Username only can contain letters and numbers.')),
array('password', 'compare', 'compareAttribute'=>'passwordConfirm', 'message' => Yii::t('default', 'Retype Password is incorrect.')),
array('email', 'email'),
array('verifyCode', 'captcha', 'allowEmpty'=>!extension_loaded('gd')),
);
}
// this amazing feature let you make changes to data after validation
public function beforeSave()
{
if(parent::beforeSave())
{
$this->setAttribute('firstName', strtoupper($this->firstName));
$this->setAttribute('lastName', strtoupper($this->lastName));
$this->setAttribute('birthday', date('Y-m-d', strtotime($this->bYear . '-' . $this->bMonth . '-' . $this->bDay)));
$this->setAttribute('password',Yii::app()->user->_encrypt($this->password));
$this->setAttribute('activationKey',Yii::app()->user->_encrypt(microtime() . $this->password));
$this->setAttribute('secretAnswer',helpers::_encrypt(strtolower($this->secretAnswer)));
$this->setAttribute('dateCreation',date('Y-m-d H:i:s'));
$this->setAttribute('dateLastVisit',date('Y-m-d H:i:s'));
$this->setAttribute(status,1);
}
return true;
}
public function attributeLabels()
{
return array(
// here you can specify attribute labels and if you wish use Yii::t() to translations.
// only return labels
'username'=>'Username',
// or return labels with translations
'username'=>Yii::t('default','Username'),
);
}
}
View
<?php
$this->pageTitle=Yii::app()->name . ' - ' . Yii::t('default','Registration');
$this->breadcrumbs=array(
Yii::t('default','Registration'),
);
?>
<h1><?php echo Yii::t('default','Create new account'); ?></h1>
<?php if(Yii::app()->user->hasFlash('registration')): ?>
<div class="flash-success">
<?php echo Yii::app()->user->getFlash('registration'); ?>
</div>
<?php else: ?>
<p><?php echo Yii::t('default', 'Please fill out the following form to create a new account.'); ?></p>
<div class="form">
<?php $form=$this->beginWidget('CActiveForm', array(
'id'=>'registration-form',
'enableAjaxValidation'=>true,
)); ?>
<p class="note"><?php echo Yii::t('default', 'Fields with <span class="required">*</span> are required.'); ?></p>
<?php echo $form->errorSummary($model); ?>
<div class="row">
<?php echo $form->labelEx($model,'firstName'); ?>
<?php echo $form->textField($model,'firstName'); ?>
<?php echo $form->labelEx($model,'lastName'); ?>
<?php echo $form->textField($model,'lastName'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($model,'birthday'); ?>
<?php echo $form->dropDownList($model,'bDay',helpers::getDays(),array('prompt'=>Yii::t('default','Day'))); ?>
<?php echo $form->dropDownList($model,'bMonth',helpers::getMonths(),array('prompt'=>Yii::t('default','Month'))); ?>
<?php echo $form->dropDownList($model,'bYear',helpers::getYears(),array('prompt'=>Yii::t('default','Year'))); ?>
</div>
<div class="row">
<?php echo $form->labelEx($model,'username'); ?>
<?php echo $form->textField($model,'username'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($model,'password'); ?>
<?php echo $form->passwordField($model,'password'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($model,'passwordConfirm'); ?>
<?php echo $form->passwordField($model,'passwordConfirm'); ?>
</div>
<div class="row">
<?php echo $form->labelEx($model,'secretQuestion'); ?>
<?php echo $form->dropDownList($model,'secretQuestion',helpers::getSecretQuestions(),array('prompt'=>Yii::t('default','Select one please'))); ?>
</div>
<div class="row">
<?php echo $form->labelEx($model,'secretAnswer'); ?>
<?php echo $form->textField($model,'secretAnswer', array('size'=>45, 'max'=>255) ); ?>
</div>
<div class="row">
<?php echo $form->labelEx($model,'email'); ?>
<?php echo $form->textField($model,'email', array('size'=>45, 'max'=>255) ); ?>
</div>
<?php if(extension_loaded('gd')): ?>
<div class="row">
<?php echo $form->labelEx($model,'verifyCode'); ?>
<div class="hint"><?php echo Yii::t('default', 'Please enter the letters as they are shown in the image.'); ?></div>
<div>
<?php $this->widget('CCaptcha',array('showRefreshButton'=>false,'clickableImage'=>true,'imageOptions'=>array('title'=>'Click','style'=>'float: left;'))); ?>
<?php echo $form->textField($model,'verifyCode',array('size'=>10, 'class'=>'verifyCode')); ?>
</div>
</div>
<?php endif; ?>
<div class="row buttons">
<?php $this->widget('application.extensions.ui.uiButton', array('formID' => 'registration-form', 'title'=>Yii::t('default','Send'), 'linkTitle'=>Yii::t('default','Send message'), 'buttonType'=>'submit', 'color'=>'green')); ?>
<?php $this->widget('application.extensions.ui.uiButton', array('formID' => 'registration-form', 'title'=>Yii::t('default','Clear'), 'linkTitle'=>Yii::t('default','Clear form'),'buttonType'=>'reset', 'color'=>'gray', 'confirm'=>Yii::t('default','Clear form anyway?'))); ?>
</div>
<?php $this->endWidget(); ?>
</div><!-- form -->
<?php endif; ?>
Controller
public function actionRegistration()
{
if(Yii::app()->user->isGuest)
{
$model=new RegistrationForm;
if(isset($_POST['ajax']) && $_POST['ajax']==='registration-form')
{
echo CActiveForm::validate($model);
Yii::app()->end();
}
if(isset($_POST['RegistrationForm']))
{
$model->attributes=$_POST['RegistrationForm'];
$model->setAttribute('birthday', date('Y-m-d', strtotime($model->bYear . '-' . $model->bMonth . '-' . $model->bDay)));
if($model->validate() && $model->save())
{
Yii::app()->user->setFlash('registration', 'Thank you for creating your account. You may now go to login form to enter site.');
}
}
$this->render('registration',array('model'=>$model));
} else {
Yii::app()->user->setFlash('registration', "You already have your account. You can't create a new one. Please go to another page.");
//$this->render('registration',array('model'=>$model));
$this->redirect(Yii::app()->user->returnUrl);
}
}
Helpers (../components/Helpers.php)
I made this class extending Controller to use some own classes inside my code.
I really don’t know if it is the best place to put this but on my projet it works fine.
<?php
class Helpers extends Controller
{
final function _encrypt($value)
{
$valueHash = md5(md5($value));
return $valueHash;
}
//return valid days range
public static function getDays()
{
for ($i=1;$i<=31;$i++)
{
$days[$i]=$i;
}
return $days;
}
//return month names
public static function getMonths()
{
$monthNames = array('','January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December');
for ($i=1;$i<=12;$i++)
{
$months["{$i}"]=Yii::t('default',$monthNames[$i]);
}
return $months;
}
//return valid years range
public static function getYears() {
return array_combine($i=range((date('Y')-16),(date('Y') - 90)),$i);
}
//return secret questions
public function getSecretQuestions()
{
$question[] = Yii::t('default', 'What is your primary frequent flyer number?');
$question[] = Yii::t('default', 'What is your library card number?');
$question[] = Yii::t('default', 'What is your favorite car?');
$question[] = Yii::t('default', 'What was your first phone number?');
$question[] = Yii::t('default', 'What is your favorite place on world?');
$question[] = Yii::t('default', "What was your first teacher's name?");
$question[] = Yii::t('default', "What is your father's middle name?");
$question[] = Yii::t('default', "What is your gradmother's middle name?");
for ($i=0;$i<count($question);$i++)
{
$questions[$question[$i]]=$question[$i];
}
return $questions;
}
}