Tutorial: Remove index.php on localhost in Yii framework

This is another simple tutorial i find it useful for every Yii framework developer to know. Especially people who really want SEO capability on their Yii project. Without further crap from me, i will demonstrate how this can be done.

Setup Apache

The most important thing to get the thing you want in a local environment is to setup your Apache properly. Luckily setting up Apache for this tutorial wasn't that difficult, all you have to do is two step. Firstly, fire up your httpd.conf and look for the following line.

<Directory />
    Options FollowSymLinks
    AllowOverride None
    Order deny,allow
    Deny from all
</Directory>

Change AllowOverride None to Allow as shown below,

<Directory />
    Options FollowSymLinks
    AllowOverride All
    Order deny,allow
    Deny from all
</Directory>

Next we will have to enable mod_rewrite. Look for the following line,

#LoadModule proxy_ftp_module modules/mod_proxy_ftp.so
#LoadModule proxy_http_module modules/mod_proxy_http.so
#LoadModule rewrite_module modules/mod_rewrite.so
LoadModule setenvif_module modules/mod_setenvif.so
#LoadModule speling_module modules/mod_speling.so
#LoadModule ssl_module modules/mod_ssl.so
#LoadModule status_module modules/mod_status.so

And uncomment LoadModule rewrite_module bla bla bla and we should get something like this.

#LoadModule proxy_ftp_module modules/mod_proxy_ftp.so
#LoadModule proxy_http_module modules/mod_proxy_http.so
LoadModule rewrite_module modules/mod_rewrite.so
LoadModule setenvif_module modules/mod_setenvif.so
#LoadModule speling_module modules/mod_speling.so
#LoadModule ssl_module modules/mod_ssl.so
#LoadModule status_module modules/mod_status.so

Now, save this changes and restart your Apache server and we are done here.

Setup .htaccess

Now, the important thing is to tell Apache how to handle things that we are going to setup on our Yii framework. Hence, we will have to write some .htaccess rule to cater this. Firstly, where to place this?! Simple, we will put this just at the level where the "/protected/" folder is located (not inside the protected folder). Next, we should create a new .htaccess file with the following rules.

Options +FollowSymLinks
IndexIgnore */*
RewriteEngine on
RewriteBase /project name/

# if a directory or a file exists, use it directly
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d

# otherwise forward it to index.php
RewriteRule . index.php

The whole world are using this rule so i won't bother to explain but do take note that you will need to rebase your project by changing "project name" to your folder name on this .htaccess file. And we are done here too.

Setup Yii Config

Finally, we can setup our Yii config! Fire up your /config/main.php file and overwrite your UrlManager rules with the following one.

		'urlManager'=>array(
			'urlFormat'=>'path',
			'rules'=>array(
				'<controller:\w+>/<id:\d+>'=>'<controller>/view',
				'<controller:\w+>/<action:\w+>/<id:\d+>'=>'<controller>/<action>',
				'<controller:\w+>/<action:\w+>'=>'<controller>/<action>',
			),
			'showScriptName'=>false,
			'caseSensitive'=>false,
		),

Once you do this, you should be gettting your index.php removed permanently!

Tutorial: How To Reuse Yii Contact Form

Here's another tutorial on Yii framework that i find it useful to write it down. I was using Yii framework on a project currently and wanted to reuse Yii built-in contact from into another view. Reusing Yii framework contact form is pretty straight forward until i find my captcha not showing out for some reason. Lucky, i manage to get it work with a little debugging and decides to write it down just in case someone gets stuck as well.

Contact Form Model

In order to reuse Yii contact form, we do not need to rebuild another new model for our contact form. Unless you want to do something extra that will affect your existing contact form model, you can actually reuse the model without creating a new one. In short, we can skip the model 😀

Contact Form View

Next, the model part will also be pretty straight forward. Since we are using the same model, all you have to do is to copy the content on the contact form view into your own view file. In this case, it will be these:

<?php $form=$this->beginWidget('CActiveForm'); ?>

	<p class="note">Fields with <span class="required">*</span> are required.</p>

	<?php echo $form->errorSummary($model); ?>

	<div class="row">
		<?php echo $form->labelEx($model,'name'); ?>
		<?php echo $form->textField($model,'name'); ?>
	</div>

	<div class="row">
		<?php echo $form->labelEx($model,'email'); ?>
		<?php echo $form->textField($model,'email'); ?>
	</div>

	<div class="row">
		<?php echo $form->labelEx($model,'subject'); ?>
		<?php echo $form->textField($model,'subject',array('size'=>60,'maxlength'=>128)); ?>
	</div>

	<div class="row">
		<?php echo $form->labelEx($model,'body'); ?>
		<?php echo $form->textArea($model,'body',array('rows'=>6, 'cols'=>50)); ?>
	</div>

	<?php if(extension_loaded('gd')): ?>
	<div class="row">
		<?php echo $form->labelEx($model,'verifyCode'); ?>
		<div>
		<?php $this->widget('CCaptcha'); ?>
		<?php echo $form->textField($model,'verifyCode'); ?>
		</div>
		<div class="hint">Please enter the letters as they are shown in the image above.
		<br/>Letters are not case-sensitive.</div>
	</div>
	<?php endif; ?>

	<div class="row buttons">
		<?php echo CHtml::submitButton('Submit'); ?>
	</div>

<?php $this->endWidget(); ?>

That's it.

Contact Form Controller

The trick to reuse Yii contact form lies on the controller. The main code without saying would be the following one.

		$model=new ContactForm;
		if(isset($_POST['ContactForm']))
		{
			$model->attributes=$_POST['ContactForm'];
			if($model->validate())
			{
				$headers="From: {$model->email}\r\nReply-To: {$model->email}";
				mail(Yii::app()->params['adminEmail'],$model->subject,$model->body,$headers);
				Yii::app()->user->setFlash('contact','Thank you for contacting us. We will respond to you as soon as possible.');
				$this->refresh();
			}
		}
		$this->render('contact',array('model'=>$model));

The render part you would need to change that because it will most likely be your view file instead. Next important things to take note of would be the captcha part.

You would need to add another method called 'action' which will define a need method for your captcha image to be created as shown below,

/**
	 * Declares class-based actions.
	 */
	public function actions()
	{
		return array(
			// captcha action renders the CAPTCHA image displayed on the contact page
			'captcha'=>array(
				'class'=>'CCaptchaAction',
				'backColor'=>0xFFFFFF,
			),
		);
	}

Next, you will need to add captcha action into your permission list in order for it to display out else you would find that your image will always be empty although you did everything correctly. (no permission. Hence, permission denial)

	/**
	 * Specifies the access control rules.
	 * This method is used by the 'accessControl' filter.
	 * @return array access control rules
	 */
	public function accessRules()
	{
		return array(
			array('allow',  // allow all users to perform 'index' and 'view' actions
				'actions'=>array('index','view', 'captcha'),
				'users'=>array('*'),
			),
			array('allow', // allow authenticated user to perform 'create' and 'update' actions
				'actions'=>array('create','update'),
				'users'=>array('@'),
			),
			array('allow', // allow admin user to perform 'admin' and 'delete' actions
				'actions'=>array('admin','delete'),
				'users'=>array('admin'),
			),
			array('deny',  // deny all users
				'users'=>array('*'),
			),
		);
	}

Once this is done, you should get your reused Yii contact form working on your new view file!

Summary

In case you are not interested in all of the tutorial, Here are the summary that you should take note of:

  • Contact Form is also build in MVC
  • You do not need to rebuild the model class unless you wanted something different
  • You will need to placed the code on the contact form controller into your own controller file
  • You will need to copy and paste the contact form view file into your own view file
  • Remmeber to add the action sections in order to use 'captcha' on your contact form.
  • Remember to allow 'captcha' action by users or else the image will never display

Tutorial: Populate 2 Model Information Using 1 Controller And 1 View In CRUD

Recently i have been playing with Yii to get something up for someone. However, i came into a lot of problem because i am very new to Yii framework. Hence, there is a lot of reading and try and error method for me. I faced a problem where i need to populate 2 model information into 1 view. However, the CRUD that produce the codes seems to only cater for 1 to 1 sort of relationship. Furthermore, there wasn't any good information on how to tackle this problem other than the one shown on the cook book. On the cook book, it is demonstrating a 1 to 1 model relationship. In my case, it is a 1 to many relationship. What should i do?

1 to many relationship model

The main problem that i'm facing was the 1 to many relationship between my model. I have a database structured similar to the one shown on my previous article, relational active record tutorial. The scheme is shown below,

CREATE TABLE IF NOT EXISTS `invoice` (
	`invoiceId` MEDIUMINT UNSIGNED NOT NULL,
	`invoiceTotalAmount` DOUBLE NOT NULL,
	PRIMARY KEY (`invoiceId`)
) 

CREATE TABLE IF NOT EXISTS `invoice_item` (
	`invoiceItemId` MEDIUMINT UNSIGNED NOT NULL AUTO_INCREMENT,
	`invoiceItemLineId` MEDIUMINT UNSIGNED NOT NULL,
	`invoiceId` MEDIUMINT UNSIGNED NOT NULL COMMENT "CONSTRAINT FOREIGN KEY (invoiceId) REFERENCES be_invoice(invoiceId)",
	PRIMARY KEY (`invoiceItemId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;

In my situation, i have 1 invoice having multiple line of items. So how do i show it out on my invoice view and manage my InvoiceItem and Invoice model with 1 Invoice controller?

Requirement

You should have the following files for a 1 to many relationship model to populate on 1 view.

  • CRUD Invoice
  • Model InvoiceItem

That's it!

How to create a 1 to many relationship model to populate into 1 view

Firstly, you will have to setup the relationship between Invoice and InvoiceItem as shown on my previous tutorial. Once, you have done that, you shouldn't touch any of your models. The only thing you should be looking at would be the controller and view created by the Invoice CRUD.

Controller Setup

Majority settings will be done on the controller. Hence, it will be quite a challenge for me to explain it clearly without dumping you too much code. Therefore, i will only be focusing on the method actionUpdate which is the update page controller method. You should have a default controller method which only cater for 1 to 1 model controller method as shown below,

	public function actionUpdate()
	{
		$model=$this->loadModel();

		// Uncomment the following line if AJAX validation is needed
		// $this->performAjaxValidation($model);

		if(isset($_POST['Invoice']))
		{
			$model->attributes=$_POST['Invoice'];
			if($model->save())
				$this->redirect(array('view','id'=>$model->invoiceItemId));
		}

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

Right. At this point, this is not something we want. Hence, we will have to modified it to handle 1 to many relationship models.

	public function actionUpdate()
	{
		$Invoice=$this->loadModel();
		$InvoiceItem=$this->loadManyModel($Invoice);
		// Uncomment the following line if AJAX validation is needed
		// $this->performAjaxValidation($model);

		if(isset($_POST['Invoice']) && isset($_POST['InvoiceItem']))
		{
			$Invoice->attributes=$_POST['Invoice'];
			$valid=$Invoice->validate();
			$i = 0;
			$InvoiceItemLine = new InvoiceItem;
			foreach($_POST['InvoiceItem'] as $item){
				if(isset($InvoiceItem[$i]))
					$InvoiceItemLine = $InvoiceItem[$i];
				$InvoiceItemLine->attributes= $item;
				$valid=$InvoiceItemLine->validate() && $valid;
				if(!$valid){
					$valid = false;
				}
				$i++;
			}

			if($Invoice->save() && $valid){
				$i = 0;
				foreach($_POST['InvoiceItem'] as $item){
					if(isset($InvoiceItem[$i]))
					$InvoiceItemLine = $InvoiceItem[$i];
					$InvoiceItemLine->save();
					$i++;
				}
				$this->redirect(array('view','id'=>$Invoice->invoiceId));
			}
		}

		$this->render('update',array(
			'Invoice'=>$Invoice,
			'InvoiceItem'=>$InvoiceItem,
		));
	}

You will notice that the above method has been modified significantly to cater for 1 to many relationship. In this method, there is one new method named 'loadManyModel'. This method basically uses the lazy loading approach to get the many relationship model record into display and is shown below,

	public function loadManyModel($model)
	{
		if($this->_models===null)
		{
			if(isset($_GET['id']))
				$this->_models=$model->invoiceItems;
			if($this->_models===null)
				throw new CHttpException(404,'The requested page does not exist.');
		}
		return $this->_models;
	}

The method will required to take in the loadModel return value which is the single relationship model object so that we can use the lazy loading approach. If you have no idea what i am talking about, please read my previous tutorial before coming here. This is being done this way to improve the efficiency and reduce the number of SQL query being called by using the eager loading approach. (take note that there is a new global variables called $_models which you would have to declared next to the global variables $_model)

I'm pretty lazy to explain what is the actionUpdate method is trying to do. But i will explain the concept behind this which it probably makes more sense. In my case, there are two model where Invoice only has 1 records but InvoiceItem would have more than 1 records. By using the loadManyModel, i can retrieved these many records object into a variables and passed it into my view for display. Once, the user hits submit, i will have to loop through the items that has been submitted for those records that are in InvoiceItem and perform the same verification and methods as a single record by looping each individual records in InvoiceItem. Just that simple 🙂

Setting up the view

If you think you could use the variables that you just passed through the controller, by editing _form.php, you might be wrong. You would also required to update the corresponding method view files to take in the new variables as shown below,

<?php
$this->breadcrumbs=array(
	'Invoices'=>array('index'),
	$Invoice->invoiceId=>array('view','id'=>$Invoice->invoiceId),
	'Update',
);

$this->menu=array(
	array('label'=>'List Invoice', 'url'=>array('index')),
	array('label'=>'Create Invoice', 'url'=>array('create')),
	array('label'=>'View Invoice', 'url'=>array('view', 'id'=>$Invoice->invoiceId)),
	array('label'=>'Manage Invoice', 'url'=>array('admin')),
);
?>

<h1>Update Invoice <?php echo $Invoice->invoiceId; ?></h1>

<?php echo $this->renderPartial('_form', array('Invoice'=>$Invoice, 'InvoiceItem'=>$InvoiceItem)); ?>

Btw, the above code is took from my view/update.php file where you see at the last sentence i passed in the variables that i have given through my controller. Once you have setup the view, you should be able to used it on the view/_form.php file. In this file, you should only see the code generated for Invoice class. All you have to do is to loop through the InvoiceItem variables that you have just passed through the controller and display it out as shown below,

	<?php echo $form->errorSummary($InvoiceItem); ?>
<?php
foreach($InvoiceItem as $item){
?>
	<div class="row">
		<?php echo $form->labelEx($item,'['.$item->invoiceItemLineId.']invoiceItemLineId'); ?>
		<?php echo $form->textField($item,'['.$item->invoiceItemLineId.']invoiceItemLineId' ); ?>
		<?php echo $form->error($item,'['.$item->invoiceItemLineId.']invoiceItemLineId'); ?>
	</div>

<?php }	?>

Just that simple! And i spend a few days to figure this out! hahaha! This way, you can easily populate 2 modle information using just 1 controller and 1 view. In other words, 1 CRUD and 1 Model. Hope this helps someone else out 🙂

Yii Relational Active Record Tutorial

Yii website has an excellent written document on relational active record. I was confused at first with the example and some of the terms Yii used for their relational active record that really cause me to waste some time on this section. Therefore i decided to write a quick and dirty tutorial on Yii relational active record hoping it will post some benefits for those who are still learning Yii framework.

Yii Relational Active Record Approaches

In Yii there are two approaches mainly the lazy loading approach and the eager loading approach. Both approaches have been documented on Yii relational active record tutorial. But if you are lazy to read, this is how each approach is being use. Lazy loading approach is use when you are dealing with 1 record and eager loading approach comes in handy when there are more than 1 records you wish to access. This is made in this way to reduce the number of join which lead to inefficiency according to Yii document page

Setup Relational Active Record

In order to get relational active record to work, we have to setup the relationship between each model. Assuming we have two table, Invoice and InvoiceItem tables as shown below,

CREATE TABLE IF NOT EXISTS `invoice` (
	`invoiceId` MEDIUMINT UNSIGNED NOT NULL,
	`invoiceTotalAmount` DOUBLE NOT NULL,
	PRIMARY KEY (`invoiceId`)
) 

CREATE TABLE IF NOT EXISTS `invoice_item` (
	`invoiceItemId` MEDIUMINT UNSIGNED NOT NULL AUTO_INCREMENT,
	`invoiceItemLineId` MEDIUMINT UNSIGNED NOT NULL,
	`invoiceId` MEDIUMINT UNSIGNED NOT NULL COMMENT "CONSTRAINT FOREIGN KEY (invoiceId) REFERENCES be_invoice(invoiceId)",
	PRIMARY KEY (`invoiceItemId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;

Now, if we use Gii to create our models, we will get 2 models, InvoiceItem and Invoice class model. Now we will need to overwrite the method 'relations' in Invoice class model in order to retrieve Invoice and its items into the same page. In this case, using relational active record is the best option we have. In order to use relational active record, we have to modified the Invoice class model method, 'relations'. Hence, in this method we will declare the following relationship with InvoiceItem.

	/**
	 * @return array relational rules.
	 */
	public function relations()
	{
		// NOTE: you may need to adjust the relation name and the related
		// class name for the relations automatically generated below.
		return array(
			'invoiceItems' => array(self::HAS_MANY, 'InvoiceItem', 'invoiceId', 'together'=>true ),
		);
	}

The above means that i have a 1 to many relationship with InvoiceItem class that share the same key called 'invoiceid' and i will name my relationship 'invoiceitems'. Usually here is the most confusing part for everyone to pick up (to setup a relationship). The format for this relationship can be seen on Yii documentation too but i will show it here just for your conveniences.

'VarName'=>array('RelationType', 'ClassName', 'ForeignKey', ...additional options)

In layman term, my relationship means "My invoice class model has a one to many relationship with InvoiceItem class model and we are tie together with our primary and foreign key which in this case foreign key is InvoiceItems". Hope it helps anyone stucked here to understand how a relationship can be initialized. Let's continue.

Getting The Relational Active Record

Now, we can get our counterpart data after we have setup our relational active record. In my case, I'm confused and stucked here since i am not very familiar with the example given in the document. Anyway, we can now utilized the two approaches mentioned previously to retrieve our relational active records. I will first introduce the lazy loading approach.

Lazy Loading Approach

Please bear in mind that the lazy loading approach will not automatically populate the wanted data to you. You will have to initialize it. And this is the mindset i had and got stuck with because i always though the "lazy" means i will not have to initialize it. Anyhow, assuming you have your crud setup for your invoice table. In this case, there should be a controller called 'InvoiceController.php'. In my example, i want my data for both table to appear on my create invoice page. In order to do that, i will have to go to the view folder and open up '_form.php' where the structure is being made as shown below.

<div class="form">

<?php $form=$this->beginWidget('CActiveForm', array(
	'id'=>'invoice-form',
	'enableAjaxValidation'=>false,
)); 

?>

	<p class="note">Fields with <span class="required">*</span> are required.</p>

	<?php echo $form->errorSummary($model); ?>
	
	<div class="row">
		<?php echo $form->labelEx($model,'invoiceId'); ?>
		<?php echo $form->textField($model,'invoiceId'); ?>
		<?php echo $form->error($model,'invoiceId'); ?>
	</div>
	
	<div class="row">
		<?php echo $form->labelEx($model,'invoiceTotalAmount'); ?>
		<?php echo $form->textField($model,'invoiceTotalAmount'); ?>
		<?php echo $form->error($model,'invoiceTotalAmount'); ?>
	</div>
</div>

Now, we will need to add in the lazy loading approach method.

$items=$model->invoiceItems;
foreach($items as $item){
	echo $item->invoiceItemLineId . "<br/>";
}

Take note that the invoiceItems is my relationship name that i have declared in my relations method on the model. You can also do it this way which is shown on Yii website.

// retrieve a record object
$invoice=Invoice::model()->findByPk(1);
// invoiceItems is the relationship name i have declared
$author=$invoice->invoiceItems;

Once we put this into the _forms structure file, we will have this.

<div class="form">

<?php $form=$this->beginWidget('CActiveForm', array(
	'id'=>'invoice-form',
	'enableAjaxValidation'=>false,
)); 
$items=$model->invoiceItems;
foreach($items as $item){
	echo $item->invoiceItemLineId . "<br/>";
}
?>

	<p class="note">Fields with <span class="required">*</span> are required.</p>

	<?php echo $form->errorSummary($model); ?>
	
	<div class="row">
		<?php echo $form->labelEx($model,'invoiceId'); ?>
		<?php echo $form->textField($model,'invoiceId'); ?>
		<?php echo $form->error($model,'invoiceId'); ?>
	</div>
	
	<div class="row">
		<?php echo $form->labelEx($model,'invoiceTotalAmount'); ?>
		<?php echo $form->textField($model,'invoiceTotalAmount'); ?>
		<?php echo $form->error($model,'invoiceTotalAmount'); ?>
	</div>
</div>

the above should just print out the line number of the items to show you how many items are available in this invoice.

Eager Loading Approach

Eager loading approach will be much MUCH easier. This can be easily figured just by reading what is written on Yii website. The eager loading approach required the word 'with' to join the 2 table together. A simple example which you can is shown below,

$invoices = Invoice::model()->with('invoiceItems')->findAll();

By the way, you can use this sentence anywhere as long as you need the data. What the above is saying in layman term is that "Using the Invoice class model, we fire up model to initial the db call and use the relationship called invoiceItems and show all results to me".

Summary

Hopefully this tutorial can help further explain what has already existed in the Yii documentation for anyone to get the hang of Yii relational active record. The tutorial here is pretty simple and high level. Hopefully to solve starters on Yii on issues on Yii relational active record.

Customize Authentication On Yii Framework Using MySQL Database

Just managed to find some time to play around with Yii. Yii is powerful but there is still a long way to go if we are talking about documentation for Yii framework. In Yii framework, we can see that it is very different from CodeIgniter where documentation is really structured and well understood. Nonetheless, i still feel that Yii framework is worth to explore. I managed to get my own customized authentication on Yii by adding some secure feature such as hashing, salt, key and etc. So here i am writing this tutorial to share with you more about Yii framework using MySQL database.

Requirement

Since this is more like a follow up tutorial, there are a few requirements before you start reading this tutorial.

  1. Installed Yii with a MySQL database.
  2. Setup Gii and get the user CRUD completed.

Customize Authentication - Database

Now here comes the tricky part. We need a database that stored our hashed password which is 128 bits since i am using sha512. Our data schema should looks like this,

CREATE TABLE tbl_user (
    id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
    username VARCHAR(128) NOT NULL,
    password VARCHAR(128) NOT NULL,
    email VARCHAR(128) NOT NULL
);

Well, it looks the same as the demo one so just ignore me lol. Create this table and we are ready to do some MVC. If you are following the tutorial you would most likely get a CRUD user setup. But we only have 'admin' and 'demo' login account. We would definitely want something better.

Customize Authentication - Model

In order to validate a user, we need to create a few methods in the model folder in order to authenticate and store user password. We will need to create these functions on our User.php file on our model folder.

	/**
	 * @return boolean validate user
	 */
	public function validatePassword($password, $username){
		return $this->hashPassword($password, $username) === $this->password;
	}
	/**
	 * @return hashed value
	 */
	DEFINE('SALT_LENGTH', 10);
	public function hashPassword($phrase, $salt = null){
		$key = 'Gf;B&yXL|beJUf-K*PPiU{wf|@9K9j5?d+YW}?VAZOS%e2c -:11ii<}ZM?PO!96';
		if($salt == '')
			$salt = substr(hash('sha512', $key), 0, SALT_LENGTH);
		else
			$salt = substr($salt, 0, SALT_LENGTH);
		return hash('sha512', $salt . $key . $phrase);
	}

the two methods above is used to validate the user password during login and the other method returns a hashed password given the original plain password value. Once these two methods are pasted into the user.php file. We are done with our modal!

Customize Authentication - Controller

In controller, we need to modify the create and update handler but i will just demonstrate the create user handler. Go to your controller folder and look for UserController.php. Change the method actionCreate to the following

	/**
	 * Creates a new model.
	 * If creation is successful, the browser will be redirected to the 'view' page.
	 */
	public function actionCreate()
	{
		$model=new User;

		// Uncomment the following line if AJAX validation is needed
		// $this->performAjaxValidation($model);

		if(isset($_POST['User']))
		{
			$model->attributes=$_POST['User'];
			$model->password = $model->hashPassword($_POST['User']['password'], $_POST['User']['email']);
			if($model->save())
				$this->redirect(array('view','id'=>$model->ID));
			else
				$model->password = $_POST['User']['password'];
		}

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

This way, we can create user with hashed password instead of plain password stored in our database.

Customize Authentication - Component

Next we need to authenticate our users. The original one just defined 'demo' and 'admin' as the only users that we are able to login. But now we have a database and a list of user and password. We should really secure our login. Here we modify our original authentication method to the following one.

	public function authenticate()
	{
		$username = $this->username;
		$user = User::model()->find('username=?', array($username));
		if($user === NULL)
			$this->errorCode=self::ERROR_USERNAME_INVALID;
		else if(!$user->validatePassword($this->password, $this->username))
			$this->errorCode=self::ERROR_PASSWORD_INVALID;
		else{
			$this->username = $user->username;
			$this->errorCode=self::ERROR_NONE;

		}
		return !$this->errorCode;
	}

this allowed us to go through the users in our database table instead of the hardcoded one by using the method we wrote previously on the modal folder.

Now, our user will be authenticate using our customized authentication process rather than using the default one!