Monday, 22 April 2013

Yii MVC Architecture

 The MVC Architecture


Data flow diagram of MVC design pattern

The Model-View-Controller pattern defines the architecture on which an application using this model is designed and works. The image above shows the data flow between the three basic components of the pattern and the interactions with the user and the application itself (here in terms of database):

  • The user uses the controllers through what he sees on the view
  • The controller manipulates the data provided by the model
  • The model updates the view the user sees
  • Rinse and repeat

Each of the three components is made of one or more scripts (i.e.: PHP scripts, HTML and CSS files, JS scripts, etc.) usually residing on the server and being transferred on the client side via HTTP/S. It’s important to note here that the user can be a human being as well as another application (i.e.: think about web services).

YII's architecture is based on the MVC pattern therefore the structure is very similar, however can be confusing for a first timer to allocate each YII script/library to the right block and function. The following image should give you a better vision on how YII is structured and broken down in the MVC blocks

YII MVC Framework diagram

You can find more details on the implementation of the MVC pattern and best practices in YII by reading the easy-to-follow documentation on the YII website.

Customise the application

The customisation of the application can be performed in various way, you can:
  1. Download and add plug-in to the application
  2. Modify existing piece of code
  3. Create your own controllers and plug-in
What we'll do in this last part of the tutorial, is to modify existing piece of the code that has been automatically generated by YII. We will want to achieve the following:
  1. Enable the authentication through the database
  2. Align the password validation to a standard policy
  3. Modify the layout of the login screen.

Step Six – Enable the authentication through the database

The basic skeleton provided by the YII command line application, already includes a rudimentary authentication mechanism. This will check if the details entered matches the one specified in the controller. Now what we want to do is to modify the controller, so that the authentication method will check the data against the user table in the database.

The skeleton application uses the User Identity controller class for this purpose, we can find the file in WEBROOT\protected\components\UserIdentity.php. What we have to modify is the authenticate method, as shown in the code below:

class UserIdentity extends CUserIdentity
{
 
    private $_id;
 
    public function authenticate()
    {
        $username=strtolower($this->username);
        $user=User::model()->find('LOWER(username)=?',array($username));
        if($user===null)
            $this->errorCode=self::ERROR_USERNAME_INVALID;
        else if(!$user->validatePassword($this->password))
            $this->errorCode=self::ERROR_PASSWORD_INVALID;
        else
        {
            $this->_id=$user->id;
            $this->username=$user->username;
            $this->errorCode=self::ERROR_NONE;
        }
        return $this->errorCode==self::ERROR_NONE;
    }
 
  
    public function getId()
    {
        return $this->_id;
    }
}

You can see on line 8 the use of the ORM model for the user record, we access the user model and perform a search through the find method specifying the username.
$user=User::model()->find('LOWER(username)=?',array($username));

If the user is found then the password is validated (on line 9) using the method validatePassword
else if(!$user->validatePassword($this->password))

now this is a method you should add in the User’s model class (located in WEBROOT\protected\models\User.php) which will help to validate the password according to your need. Here is a very easy example
public function validatePassword($password)
 
 {
     return $this->hashPassword($password,$this->salt)===$this->password;
 }
 
  
 
 public function hashPassword($password,$salt)
 {
     return md5($salt.$password);
 }

During the registration phase we won't store the password in the database in plain text, but its hash instead and a randomly generated salt key. This is a common approach that enforce security and ensure we don't have access to such a sensitive personal user's data.

If everything is successful the user's ID will be returned back to the calling method.

In this step we have modified the User Identity component and the User's model class. Some of you may get confused, but it's really simple, the difference between these two script is that the former is like a plug-in used to aid in the authentication workflow, while the latter is used to represent the data related with the current user. You can use the User Identity multiple times depending on the various authentication methods you want to implement, while you will have only one User's model which is the currently logged user and all related data grabbed from the database's table.

Step Seven – Align the password validation to a standard policy

The password is one of the weakest point of any application, because it is the user's choice and this can be anything from a simple numeric sequence (i.e.: 12345) or a complex mix of letters, numbers and symbols (i.e.: aH72!k.). More likely the average user will chose something easy to remember and often something that has a meaning for him/her. This is called in IT jargon a weak password and it's easily broken by any good brute force or dictionary password hack.

Now any good developer should always introduce and reinforce password policies in their software. This is for the protection of the software, the infrastructure behind it and all the user's data. With your newly developed YII application you can easily achieve it.

YII has built-in validation rules which instruct YII to validate a specific input against a set of rules. Here is where you are going to implement your password policies.

It is important to understand that this is a very generic feature that can be applied to any parameter given in input to the application via the forms on the web pages; you need to be careful to implement the rules only where you need them and not everywhere.

Additionally rules implemented in forms models have no effect on record creation where the rules should be defined in the appropriate model. For example LoginForm model can have different rules than User model, where the former doesn't require any specific constraint for username and password and the latter requires minimum 8 chars long username and password.

If you want to add rules for user's registration, I suggest you implement it in the User's model by modifying the already built-in rules's method as shown in the code below

public function rules()
 
{
 
    // NOTE: you should only define rules for those attributes that
 
    // will receive user inputs.
 
    return array(
 
        array('username, password, salt, email', 'required'),
 
        array('username, password, salt, email', 'length', 'max'=>128),
 
        array('password','length','min'=>8,'max'=>12),
 
        array('profile', 'safe'),
 
        // The following rule is used by search().
 
        // Please remove those attributes that should not be searched.
 
        array('id, username, salt, email, profile', 'safe', 'on'=>'search'),
 
    );
 
}

you can add as many rules and validators as you want in your methods, here I’ve specified the fields: username, password, salt and email are required and a maximum length of 128 characters. I’ve also added an additional rule where the password’s length must be minimum 8 and maximum 12 characters.

Step Eight – Modify the layout of the user’s login screen

We have come so far touching various parts of the application but we never looked at the layout of our application's output. When you use the automatic YII generators you will get a basic and rather dull layout, which is OK while you are developing the application and focusing your efforts in functionalities. Now it is time to make our application beautiful, so you need to understand which scripts needs some modification.

Your main area of concern are the views, which as explained in the introduction of this post contains the structure of your web application in terms of look and feel. Views are a mix of PHP, HTML, CSS and JS; the first script you want to look at is the main layout which is applied throughout the application, it is located in WEBROOT\protected\views\layout\main.php. I strongly suggest you have a peek at all files contained in the WEBROOT\protected\views folder, you will find one folder for each of your controller and one file for each of the actions contained in your controller which requires user's iteraction.

I'm going to show you now how to modify one of these files, let's have a look at the login form located at WEBROOT\protectd\views\site\login.php

The first block of code will define via PHP the title of the page and will use a very nice but useful facilitator to show the whereabout in form of breadcrumbs
<?php
$this->pageTitle=Yii::app()->name . ' - Login';
 
$this->breadcrumbs=array(
    'Login'
);
 
?>

This is quite straight forward, the next block will define the form itself, as you can see from the code below there is a mixture of HTML and PHP code. Remember that you can write in the view script whatever you want and it will be displayed, if you enter any PHP code it will be interpreted.
<h1>Login</h1>
 
<pre>Please fill out the following form with your login credentials:</pre>
 
<div class="form">
<?php
$form=$this->beginWidget('CActiveForm', array(
 
 'id'=>'login-form',
 
 'enableClientValidation'=>true,
 
 'clientOptions'=>array(
 
 'validateOnSubmit'=>true,
 
 ),
 
)); ?>

let's spend few words on the form's definition code itself; You have two options at this stage, you can develop your own form validation/interaction or let YII do the work. I suggest the latter as you will have consistency across all your scripts, and a code easy to maintain and improve. You can achieve this through the usage of Widgets, which are on their own controllers and views but packaged to be used as “utility” code (there are a lot of widgets available on the YII website).

In this instance I have used the CActiveForm widget which will create a form in our view, it accepts several parameters so that you can customise it as much as you want. Here you can see that I've enabled the validation at client level, this mean that validation rules defined in the LoginForm controller will be used and related errors/warnings messages presented to the user on the web page while iterating with the form.

Validation Rule in action

Now we have to enter the input forms for each of the fields we want the user’s input, if you use the widget you will have to call in your code three different methods from the widget object as shown below.
</pre>
 
<div class="row"><?php echo $form->labelEx($model,'username'); ?>
 
 <?php echo $form->textField($model,'username'); ?>
 
 <?php echo $form->error($model,'username'); ?></div>
 
<pre>

The name of the methods give you an idea of what they do, the important thing is to note that those methods uses the main model object as first property in order to link with the data model and display the correct information and implement the correct validation rule (if needed). The second property is the name of the column as specified in your model, hence in your data dictionary. In this specific case we will have in output the label, the text field and a space reserved to show the errors if any. The last step is to add the buttons to submit the form and close the form itself. Once again this is easy to achieve, we will be using the CHTML core helper class to implement the button as this is not part of the form widget. The last bit is to invoke the method endWidget()which will close the form and add any final bit of code needed for the form to work.
</pre>
 
<div class="row buttons"></div>
 
<pre><?php $this->endWidget(); ?>

Saturday, 20 April 2013

Yii Interview Question

1Q. What is meant by Yii Framework?

A. Yii is an open source and highly performed component-based PHP framework used for Web application development. This application was started on January and completed in December 2008.

2Q. Why do Yii run so FAST?

A. Yii is so much faster because it uses sluggish loading technique widely. Like it doesn’t include a class file until the class is used initially and it doesn’t create object until it is accessed for the first time. Some of the frameworks get problems because of the performance hit because they would enable functionality no matter it is used or not during its request.

3Q. tell about the file that gets loaded when you run an application using Yii?

A. index.php

4Q. Explain about model, view, controller?

A. Model represents the underlying data structure of a Web application. Models often share different sub-applications of a Web application. B. View is responsible in presenting models in the format where the end users desire. In general view contains presentational code. C. Controllers are the adhesive that binds models, views and other components composed into a runnable application. Controllers are responsible in dealing with the end user requests. Controllers access $_GET, $_POST and other PHP variables according to the user requests.

5Q. What about the naming convention in Yii?

- We define table prefix while using Gii. In your case you need to set it to tbl_. Then it should generate UserController instead of TblUserController. - The Yii Framework employees a class naming convention whereby the names of the classes directly plot to the directories in where they are stored. The root level directory of the Yii Framework is the “framework/” directory, where all classes are stored hierarchically. Class names contain alphanumeric characters.

6Q. what is the component, uses, how can we do and what is the better way?

A. A component is a piece of code written for specific task is used by calling controllers, helper is used for helping Yii in rendering the data to be shown to user with views, these adds to modularity in code or else same coding will be implemented in controllers.

7Q. How do you continue when you have to use Yii for any application?

A. If you have changed according to your needs… Proceed with basic software engg. concepts as requirement gathering etc. This is the basic Understanding Concept in Yii. - Yii based apps are driven by data logic. - Yii can generate the shebang of PHP codes automatically. - Yii will generate an essential app for you automatically. - Yii uses MySQL and SQLite. - Yii is an open-source.

8Q. What is the first function that gets loaded from a controller?

A. Index

9Q. What is meant habtm?

A. Habtm means HasAndBelongsToMany. The” has and belongs to many” is a kind of associations that defined in models for retrieving related data across different entities.

10Q. How to use ajax in Yii?

A. We use by calling ajax helper, then using it in controller for rendering.

11Q. What are the possible ways to validate a registrations module for a user?

A. This can be done in two ways by i) submission in controller, or ii) using javascript/ajax while user is still filling the data. But, comparatively Second option will be better.

12Q. List out some database related functions in Yii?

A. Query find, findAll , findByPk , find By

13Q. How to include a javascript menu through a site?

A. We can include by adding the javascript files in webroot and then call them in default views if they are needed everywhere or in the related views.

14Q.Who was the developer of the Yii and when was it build?

A. The developer of the Yii is Yii Software LLC. It was started in the year 2008 in December 3, with the version of 1.0 and continued to 1.1.13. in PHP language.

15Q. What are the requirements of the Yii?

A. To run a Yii Web application, we need a Web server which supports PHP 5.1.0. Version. The developers who want to use Yii, should understand the object-oriented programming (OOP) which is very helpful, because it is a pure OOP framework.

16Q. How does Yii Compare with Other Frameworks?

A. Comparatively to most of PHP frameworks, Yii is a MVC framework. Yii bests PHP frameworks for its efficient, feature-rich and clearly-documented. Yii is designed to be fit for serious Web application development. It is neither a consequence of some project nor a corporation of third-party work.

17Q. How do we extend Yii?

A. Extending Yii is a common action during web development. Like when we write a new controller, we extend Yii by inheriting its CController class; when we write a new widget, we will extend CWidget or an existing class. If the code is designed to be reused by third-party then we call it an extension.

18Q. How to connect to the database?

A. Most of the web applications are assisted by databases. test-drive application is not an exception. For database, we need to see the application where and how to connect it. This is done through the application configuration file WebRoot/testdrive/protected/config/main.php, the following code represent the connectivity to the database

return array(
    ‘components’=>array(
        ‘db’=>array(
            ‘connectionString’=>’sqlite:protected/data/testdrive.db’,
        ),
    ),
);

19Q. What is a Yiibase?

A. YiiBase is a helper class that serves functionalities of common framework. We should not use YiiBase directly. Instead, have to use its child class where we can customise the methods of YiiBase.

20Q. How to generate CRUD code?

A. After creating a model class file, we shall generate the code that implements the CRUD operations for user data. We choose the Crud Generator in Gii. In the model class field, we enter ‘User’. In the Controller ID field, we enter ‘user’ in lower case. Then press the preview button followed by the Generate button. Now we are done with the CRUD code generation.

Yii Interview Question