Algorithm: Generating random numbers without duplicates using PHP

No Comments »

Creating a new helper function called “contain(arg1, arg2)”. Where arg1 = an array of number, arg2 = a number.
“checkItem” function checks whether the number is include in the array. If yes, return true, o/w false. The difference from the previous method is that this function replace the variable $j from Method 1. In my opinion, this method is a lot clearer. The way of thinking would be more useful when conquering harder problems in the future and thus avoiding bad code in the long-run.

function checkItem($prevItems, $number) {
     for ($k=0; $k<sizeof($prevItems); $k++) {
       if ($prevItems[$k] == $number)
          return true;
     }
       return false;
   } 
   $num[0] = rand(1,100);
   $prevItems[0] = $num[0];
   for ($i=1; $i<=20; $i++) 
   {      
      $num[$i] = rand(1,100);      
      while (checkItem($prevItems, $num[$i])) 
      {         
         $num[$i] = rand (1,100);      
      }      
      $prevItems[$i] = $num[$i];
    }  
   sort($num);  
   print_r($num);

Get selected value in dropdown list

No Comments »
dropDownList($controllerName,
'modelId',
CHtml::listData(ModelName2::model()->findAll(array('id'=>$id)), 'id', 'attributeName'),
array('options' => array('id'=>array('selected'=>true))));

if thats coming from database use something like below (in case of list box or multiple dropDownList use multiple=>true)

foreach ($result as $data)
  $optionsArray[$data->attributeName] = array('class'=>'selected','selected'=>'selected');

echo  $form->dropDownList($model,
'modelId', 
CHtml::listData(ModelName::model()->findAll(array('id'=>$id)), 'id','attributeName'),
array('multiple'=>'true','prompt'=>'select','options'=>$optionsArrayns));

Hiding module name in URL

No Comments »

I need to hide the module section of the URL. Is there any way this can be done?
In config (protected/config/main.php) under urlManager:

'urlManager'=>array(
        'urlFormat'=>'path',
        'showScriptName' => false,
        'rules'=>array(
            'customer/login' => 'module/controller/action',

            '<controller:\w+>/<id:\d+>'=>'/view',
            '<controller:\w+>/<action:\w+>/<id:\d+>'=>'/',
            '<controller:\w+>/<action:\w+>'=>'/',
        ),
    ),

To make any controller action go to module/controller/action (as discussed below) you can use:

 "<controller:\w+>/<action:\w+>"=>"module/controller/action",

or

"<controller:\w+>/<action:\w+>"=>"module/<controller:w+>/<action:\w+>",

if i want any controller/action to go to the exact url module/controller/action, i would use the first example.

If i want any controller/action to go to a dynamic controller/action you use the second.


multiple attributes in listData/DropDownList

No Comments »

Let’s say we need to make the text attribute in the list consist of both first_name and last_name from the Test model. What is the recommended/Yii way to do that?
In the model:

   public function getFullName()
   {
      return $this->firstname . " " . $this->lastname;
   }

a getter function cannot be assigned to, its value can always be fetched from anywhere in the code, including in CHtml::listData when creating a dropdown list. It’s quite common to want to display multiple parts of a model record to the user even though it nevertheless selects just a single ID:
in a view somewhere :

  echo $form->dropDownList($model, 'personid',
    CHtml::listData( Person::model()->findAll(), 'id', 'fullname' )
 );

If you show data on other model attributes then join model with this
model that is like this below :

  echo $form->dropDownList($model, 'personid',
    CHtml::listData( Person::model()->with("relational model name")->findAll(), 'id', 'fullname' ) );

Now, the dropdown will show full user names in the dropdown, which makes for a better user experience. Attempting to provide a dropdown including firstname + lastname without a model helper function like this is more work and less useful.

EXTRA BONUS – In the future, if you add a MiddleName to the Person database table, you only have to modify the getFullname() method in order to automatically update all the views that use $model->fullname.

This is in addition to the benefit of $model->fullname being more clear in the first place.

If you details to this please visit below this yii wiki.

http://www.yiiframework.com/wiki/167/understanding-virtual-attributes-and-get-set-methods/


Change the Row Color Based on the Column value in CGridView in Yii

No Comments »

In Yii, CGridView has it’s own background color in the row. But I want to do is highlight particular row based on the value of one of the column.

For Instance, I have three column, id, name, status. Now, If the Value of status is Inactive or 0, I should highlight the row with some color.

Use rowCssClass and rowCssClassExpression for your functionality. I did not tested this code but the trick you can use to get your solution.

$this->widget('zii.widgets.grid.CGridView', array(
    'dataProvider'=>$dataProvider,
    //'rowCssClass'=>array('odd','even'),
    'rowCssClassExpression'=>'($data->status==0)?"even":"odd"',
    'columns'=>array(
    ),
));


Yii Model Validation

1 Comment »

Yii provides a great resource to validate forms. It also provides functionality to create custom validation. We can write our own validations or can use yii validations in our custom validation function.

Validation rules:

Validate form by defining rules function in model in this way. Also i have declared my custom validation function myvalidation.

public function rules()
{
    return array(
        array('firstname, lastname', 'required'),
        array('email', 'myvalidation'),
        array('field', 'myvalidation1'),
    );
}

Custom validation function: myvalidation

public function myvalidation($attribute, $params)
	{
                $params = array();
		$req = CValidator::createValidator( 'email', $this, array('email'),$params);
		$req->validate( $this );		
	}


Custom validation function without using CValidatior:

public function myvalidation1($attribute, $params)
	{
                if(empty($this->field))
                          $this->addError('field','Field can not be blank.');
	}


Yii Model Client validation

No Comments »

Yii provides functionality to create form using CActiveForm widget which provides client side validation, ajax based validation and server side validation. CActiveForm provides a set of methods that can help to simplify the creation of complex and interactive HTML forms that are associated with data models.

How to enable client side validation:

To enable client validation we have to make some configuration to the from created from CActiveForm widget. We have to make enableClientValiadation to true, by default it is false. We have some options for client side validation which can enabled or disabled through clientOptions as mentioned in the example below.


$form=$this->beginWidget('CActiveForm', array(
	'id'=>'my-form',
	'enableAjaxValidation'=>false,
	'enableClientValidation'=>true,
	'clientOptions'=>array('validateOnSubmit'=>true,'validateOnChange'=>false, 'afterValidate'=>"js:afterValidate"),
)); 

Most important point about client side validation:

Ajax/client-side validation will not work without calling

$form->error(). If you are using CHtml::error()
than the client side validation will not work.
You can user $form->error() in this way.

$form->error($model, 'field')

Append your own code for client side validation to some fields:

CActiveForm provides two clientOptions for this, they are afterValidation & beforeValidate. You can write your own js validation code for specific field. Write your own javascript function and assign it to a php variable in this way. After assigning js function to a php
Client validation
variable, register it using registerScript function that has been mentioned below.

$js = <<< EOJ
function afterValidate(form) {
        
        // write here custom validation code and if not validated than show error.
        // always return true. yii automatically handles it.       
        return true;
}
EOJ;
Yii::app()->clientScript->registerScript('afterValidate', $js);

After this you have to configure afterValidate or beforeValidate client option of the form parameter in this way.

	'clientOptions'=>array('validateOnSubmit'=>true,'validateOnChange'=>false, 'afterValidate'=>"js:afterValidate")


Yii multiple themes

No Comments »

Theming is a very feature for any framework or cms. Yii supports multiple theming for the application. Yii themes has a very nice architecture & easy of access multiple themes. Yii themes can include common style-sheets, script files or images or may have separate file for each theme.
Themes directory structure

WebRoot/
    assets
    protected/
        .htaccess
        components/
        controllers/
        models/
        views/
            layouts/
                main.php
            site/
                index.php
    themes/
       classic/
            views/
                .htaccess
                layouts/
                    main.php
                site/
                    index.php
        mytheme/
                views/
                   .htaccess
                   layouts/
                      main.php
                  site/
                      index.php

Setting default theme
You can configure default theme in config file

main.php

....
'theme' => 'mytheme',
....

How to set multiple theme multiple users
You can’t configure multiple themes in config file because this is first file which is loaded after initializing application & you don’t have any way to choose which theme you want to use. It can be done in your controller.

Yii uses

init()

function, it is used in controllers and called when an objects is initialized. We can configure theme in this function.

public function init()
{
   if(Yii::app()->user->isGuest)
      Yii::app()->theme = 'mytheme1';
   else
      Yii::app()->theme = 'classic';

   parent::init();
}

Include theme css or image files in view

// Include css
Yii::app()->theme->baseUrl . '/css/style.css'

// Include image
Yii::app()->theme->baseUrl . '/images/image.gif'


Yii error handler

No Comments »

Error handling is very important to provide user friendly application. Yii provides an easy way to handle errors in organized and customized way. Yii has a component CErrorHandler which provides the functionality of error handling. Also yii provides a way to handle exception using CHttpException.

Default Error handling configuration

CErrorHandler named as errorHandler component. It has default action to site/error.

'errorHandler'=>array(
			// use 'site/error' action to display errors
            'errorAction'=>'site/error',
        ),

site/error

/**
* This is the action to handle external exceptions.
*/
public function actionError()
{
   if($error=Yii::app()->errorHandler->error)
   {
	if(Yii::app()->request->isAjaxRequest)
	    echo $error['message'];
	else
	  $this->render('error', $error);
   }
}

We can get error using

 
Yii::app()->errorHandler->error or Yii::app()->errorHandler->getError().

Both return an array containing the error details.

Returned array elements:

  • code – the HTTP status code (e.g. 403, 500)
  • type – the error type (e.g. ‘CHttpException’, ‘PHP Error’)
  • message – the error message
  • file – the name of the PHP script file where the error occurs
  • line – the line number of the code where the error occurs
  • trace – the call stack of the error
  • source – the context source code where the error occurs

You can customize both the things as default error action & error method. It uses error view you can also customize this. This is the easy way to customize errors.


Yii Soap Web Service

1 Comment »

Web Service is a method of communication between two different web application over the Internet. Two method that are used for web services are very popular which are REST & SOAP. I am very fond of using web service so I got interest in writing about it. I am writing about SOAP web service with Yii Framework. SOAP is Simple Object Access Protocol used for exchanging information.

Yii provides this functionality through the help of class CWebServiceAction. We follow some steps to create Yii Soap Web Service.

Create web service action:

We create a controller action that expose web service, here we create service action. Here SoapController is called as Service Provider.

class SoapController extends CController
{
public function actions()
    {
        return array(
            'service'=>array(
                'class'=>'CWebServiceAction',
            ),
        );
    }
 
/**
 * @param string symbol
 * @return string cost
 * @soap
 */
    public function getPrice($symbol)
    {
        //...return stock price for $symbol
    }
}

Create method that will be called through SOAP Api:

We create getPrice Method to explain it. We pass some parameters to it like $symbol. This function returns prices. For the SOAP functiona Yii follow some PHPDoc rules or ways. If we do not use the comments mentioned above the method the SOAP service will not work. Above comments should be mentioned appropriately like We have to mention @soap, it tell that the function is a soap function. We should also declare @param & @return with their appropriate data type otherwise it will not work.

class SoapController extends CController
{
public function actions()
    {
        return array(
            'service'=>array(
                'class'=>'CWebServiceAction',
            ),
        );
    }
 
/**
 * @param string symbol
 * @return string cost
 * @soap
 */
    public function getPrice($symbol)
    {
        $prices=array('IBM'=>100, 'GOOGLE'=>350);
        return isset($prices[$symbol]) ? $prices[$symbol] : 0;
//return "Hello web service!";
        //...return stock price for $symbol
    }
}

Callling SOAP Web Service:

To call soap service we have to create SOAP client that is created through PHP Class SoapClient. We pass soap service url as argument while creating soap client.

We can call soap method through the client object. We can also lookup all the soap functions through calling __getFunctions() from client object.

class SiteController extends CController
{
public function actionCallSoapRequest()
{
ini_set ( 'soap.wsdl_cache_enable' , 0 ); ini_set ( 'soap.wsdl_cache_ttl' , 0 );
$client=new SoapClient('http://localhost:81/yiitestapp/index.php?r=soap/quote');
//var_dump($client);
var_dump($client->__getFunctions());

echo $client->getPrice('GOOGLE');
}

}