Showing posts with label yii. Show all posts
Showing posts with label yii. Show all posts

Saturday, June 15, 2013

YII use beforeSave and beforeValidate function as common for all Model

Create a file suppose named 'MyActiveRecord.php' suppose in 'components' folder.


<?php
class MyActiveRecord extends CActiveRecord {
    public function beforeValidate()
    {
        if(parent::beforeValidate())
        {
            /* Do some common work */
            return true;
        }
    }
    function beforeSave() {
        if (parent::beforeSave()) {
            if($this->isNewRecord) {
                $maxOrderNumber = Yii::app()->db->createCommand()
                ->select('max(id) as max')
                ->from($this->tableName())
                ->queryScalar();
              $this->id = intval($maxOrderNumber) + 1;
            }
        }
        return true;
    }
}
?>

Now create a Model named 'Email' in 'models' folder.
See the highlighted extends object that is the previous one.
The MyActiveRecord does when a new Email inserted to database, set its id as
current id+1 as new id.
<?php
class Email extends MyActiveRecord {
    public static function model($className=__CLASS__)
    {
        return parent::model($className);
    }
    public function tableName()
    {
        return 'email';
    }
    public function rules()
    {
        return array(
            array('address, contact_id, contact_user_id', 'required'),
            array('contact_id, contact_user_id', 'numerical'),
            array('address, email_label', 'length', 'max'=>250),
            array('email_label, address', 'safe', 'on'=>'search')
        );
    }
    public function attributeLabels()
    {
        return array(
            "address" => "Address",
            "email_label" => "Category"
        );
    }
    
    public function findByParameters($parameters)
    {
        $criteria=new CDbCriteria;
        foreach ($parameters as $key => $value) {
            $criteria->compare($key, $value,true);
        }                
        return new CActiveDataProvider($this, array(
            'criteria'=>$criteria
        ));
    }
}
?>

Wednesday, June 12, 2013

Styling CMenu and CMenu items and links with CSS class in Yii

Many times we would want to style our CMenu by adding id or css classes to it. We can easily do this through htmlOptions, itemOptions, and linkOptions.

Adding id and class names to CMenu

We use the id and htmlOptions to accomplish this. Watch.

//in your view
$this->widget('zii.widgets.CMenu', array(
 'id'=>'myMenu',
 'items'=>$this->myMenu,
 'htmlOptions'=>array('class'=>'span-24 last'),
));
this will make Yii render
<ul class="span-24 last" id="myMenu">
...
</ul>

Adding class names to CMenu items and CMenu item links

We use itemOptions and linkOptions for this. Example.
//in your controller
$this->myMenu = array(
'id'=>'myMenu',
'items'=>array(
 array(
  'label'=>'Home',
  'url'=>array('site/index'),
  'itemOptions'=>array('class'=>'visited'),
  'linkOptions'=>array('class'=>'bar'),
 ),
 array('label'=>'Sign Out', 'url'=>array('site/signout')),
),
);
[ad]
This will let Yii render
...
<ul id="myMenu">
 <li class="visited">
  <a class="bar" href="/site/index">Home</a>
 </li>
...
http://code.dimilow.com/styling-cmenu-and-cmenu-items-and-links-with-css-class-in-yii/ 

Tuesday, June 11, 2013

YII Get active controller and action name

Current Controller
Yii::app()->controller->id;
and Current Action
Yii::app()->controller->action->id;

Sunday, June 9, 2013

YII load model dynamically by model name


$phoneModel = $this->loadMyModel(100, "PhoneNumber"); 
 
public function loadMyModel($id, $modelName){
    $model = new $modelName();
    $criteria = new CDbCriteria;
    $criteria->condition = $model->getTableAlias().".id = :id";
    $criteria->params = array(
        "id" => $id
    );
    $data = new CActiveDataProvider($model, array(
        'criteria'=>$criteria
    ));
    if(count($data->getData()) > 0) {
        $data = $data->getData();
        $data = $data[0];
        return $data;
    }
    return null;
}

YII execute delete, update and select custom sql query

$command = Yii::app()->db->createCommand();

$sql='DELETE FROM phone WHERE contact_id=:contact_id AND id=:id';
$params = array(
    "contact_id" => $contactId,
    "id" => $id
);
$command->setText($sql)->execute($params);


$command=$connection->createCommand($sql); 
$rowCount=$command->execute();   // execute the non-query SQL
$dataReader=$command->query();   // execute a query SQL
$rows=$command->queryAll();      // query and return all rows of result
$row=$command->queryRow();       // query and return the first row of result
$column=$command->queryColumn(); // query and return the first column of result
$value=$command->queryScalar();  // query and return the first field in the first row
 
 
 
After CDbCommand::query() generates the CDbDataReader instance, one can retrieve rows of resulting data by calling CDbDataReader::read() repeatedly. One can also use CDbDataReader in PHP's foreach language construct to retrieve row by row.
$dataReader=$command->query();
// calling read() repeatedly until it returns false
while(($row=$dataReader->read())!==false) { ... }
// using foreach to traverse through every row of data
foreach($dataReader as $row) { ... }
// retrieving all rows at once in a single array
$rows=$dataReader->readAll();
 
 
 

Using Transactions

When an application executes a few queries, each reading and/or writing information in the database, it is important to be sure that the database is not left with only some of the queries carried out. A transaction, represented as a CDbTransaction instance in Yii, may be initiated in this case:
  • Begin the transaction.
  • Execute queries one by one. Any updates to the database are not visible to the outside world.
  • Commit the transaction. Updates become visible if the transaction is successful.
  • If one of the queries fails, the entire transaction is rolled back.
The above workflow can be implemented using the following code:
$transaction=$connection->beginTransaction();
try
{
    $connection->createCommand($sql1)->execute();
    $connection->createCommand($sql2)->execute();
    //.... other SQL executions
    $transaction->commit();
}
catch(Exception $e) // an exception is raised if a query fails
{
    $transaction->rollback();
}
 
 
 
 

Binding Parameters

To avoid SQL injectionattacks and to improve performance of executing repeatedly used SQL statements, one can "prepare" an SQL statement with optional parameter placeholders that are to be replaced with the actual parameters during the parameter binding process.
The parameter placeholders can be either named (represented as unique tokens) or unnamed (represented as question marks). Call CDbCommand::bindParam() or CDbCommand::bindValue() to replace these placeholders with the actual parameters. The parameters do not need to be quoted: the underlying database driver does it for you. Parameter binding must be done before the SQL statement is executed.
// an SQL with two placeholders ":username" and ":email"
$sql="INSERT INTO tbl_user (username, email) VALUES(:username,:email)";
$command=$connection->createCommand($sql);
// replace the placeholder ":username" with the actual username value
$command->bindParam(":username",$username,PDO::PARAM_STR);
// replace the placeholder ":email" with the actual email value
$command->bindParam(":email",$email,PDO::PARAM_STR);
$command->execute();
// insert another row with a new set of parameters
$command->bindParam(":username",$username2,PDO::PARAM_STR);
$command->bindParam(":email",$email2,PDO::PARAM_STR);
$command->execute();
 
 


http://www.yiiframework.com/doc/api/1.1/CDbCommand#delete-detail

Saturday, June 1, 2013

YII extend the class CGridView CDataColumn

Extend the class CDataColumn

Under protected/components/ create the file DataColumn.php with the following content:

<?php
/**
 * DataColumn class file.
 * Extends {@link CDataColumn}
 */
class DataColumn extends CDataColumn
{
    /**
     * @var boolean whether the htmlOptions values should be evaluated. 
     */
    public $evaluateHtmlOptions = false;
 
     /**
     * Renders a data cell.
     * @param integer $row the row number (zero-based)
     * Overrides the method 'renderDataCell()' of the abstract class CGridColumn
     */
    public function renderHeaderCell() {
        if($this->evaluateHtmlOptions) {
            foreach($this->headerHtmlOptions as $key=>$value) {
                $options[$key] = $this->evaluateExpression($value,array('row'=>$row,'data'=>$data));
            }
        } else {
            $options=$this->headerHtmlOptions;
        }
        echo CHtml::openTag('td', $options);
        $this->renderHeaderCellContent();
        echo "</th>";
    }
    public function renderFilterCell() {
        if($this->evaluateHtmlOptions) {
            foreach($this->filterHtmlOptions as $key=>$value) {
                $options[$key] = $this->evaluateExpression($value,array('row'=>$row,'data'=>$data));
            }
        } else {
            $options=$this->filterHtmlOptions;
        }
        echo CHtml::openTag('td', $options);
        $this->renderFilterCellContent();
        echo "d</td>";
    }
    public function renderDataCell($row)
    {
        $data=$this->grid->dataProvider->data[$row];
        if($this->evaluateHtmlOptions) {
            foreach($this->htmlOptions as $key=>$value) {
                $options[$key] = $this->evaluateExpression($value,array('row'=>$row,'data'=>$data));
            }
        } else {
            $options=$this->htmlOptions;
        }
        if($this->cssClassExpression!==null) {
            $class=$this->evaluateExpression($this->cssClassExpression,array('row'=>$row,'data'=>$data));
            if(isset($options['class'])) {
                $options['class'].=' '.$class;
            } else {
                $options['class']=$class;
            }
        }
        echo CHtml::openTag('td', $options);
        $this->renderDataCellContent($row,$data);
        echo '</td>';
    }
}
?>
Use as following:

<?php 
$this->widget('zii.widgets.grid.CGridView', array(
    'dataProvider'=>$model->search(),
    'filter'=>$model,
    "itemsCssClass" => "table_design_1",
    "htmlOptions" => array(
        "class" => "div_contact_admin_grid_view"
    ),
    "ajaxUpdate" => false,
    'columns'=>array(
        array(
            'class'=>'DataColumn',
            'name'=>'family_name',
            'evaluateHtmlOptions'=>true,
            'htmlOptions'=>array('id'=>'"ordering_{$data->id}"'),
            "cssClassExpression" => "none",
            "filterHtmlOptions" => array("class" => "filterHtmlOptions"),
            "headerHtmlOptions" => array('class' => 'headerHtmlOptions')
        )
    )
)); ?>

YII CGridView with custom action button


<?php 
$this->widget('zii.widgets.grid.CGridView', array(
    'dataProvider'=>$model->search(),
    'filter'=>$model,
    "itemsCssClass" => "table_design_1",
    "htmlOptions" => array(
        "class" => "div_contact_admin_grid_view"
    ),
    "ajaxUpdate" => false,
    'columns'=>array(
        array(
            'name'=>'family_name', 
            'header'=>'First name',
            'type' => 'raw',
            'value' => 'CHtml::link($data->family_name,$data->id)'
        ),
        array(
            'name'=>'given_name', 
            'header'=>'Last name',
            'type' => 'raw',
            'value' => 'CHtml::link($data->given_name,$data->id)'
        ),
        array(
            'class'=>'CButtonColumn',
            'template'=>'{delete_contact}{view}{update}',
            'buttons'=>array (
                'delete_contact' => array (
                    'label'=>'Delete this contact',
                    'imageUrl'=>Yii::app()->request->baseUrl.'/images/delete.png',
                    'url'=>'Yii::app()->createUrl("contact/delete", array("id"=>$data->id))',
                    'visible' => '1',
                    "options" => array(
                        "class" => "delete_contact"
                    )
                )
            ),
            'viewButtonUrl'=>'Yii::app()->request->getBaseUrl(true)."/contact/view/".$data["id"]',
            'updateButtonUrl'=>'Yii::app()->request->getBaseUrl(true)."/contact/update/".$data["id"]',
            "htmlOptions" => array(
                'style'=>'width: 60px;',
                'class' => 'action_class'
            )
        )
    )
)); ?>

YII CGridView with CActiveDataProvider customer limit and offset params

It is a CGridView example with CActiveDataProvider class:
<?php 
$this->widget('zii.widgets.grid.CGridView', array(
    'dataProvider'=>$model->search(),
    'filter'=>$model,
    "itemsCssClass" => "table_design_1",
    "htmlOptions" => array(
        "class" => "div_design_1"
    ),
    'columns'=>array(
        array(
            'name'=>'family_name', 
            'header'=>'First name',
            'type' => 'raw',
            'value' => 'CHtml::link($data->family_name,$data->id)'
        ),
        array(
            'name'=>'given_name', 
            'header'=>'Last name',
            'type' => 'raw',
            'value' => 'CHtml::link($data->given_name,$data->id)'
        ),
        array(
            'class'=>'CButtonColumn',
            'viewButtonUrl'=>'Yii::app()->request->getBaseUrl(true)."/contact/view/".$data["id"]',
            'updateButtonUrl'=>'Yii::app()->controller->createUrl("update",$data->primaryKey)',
            'deleteButtonUrl'=>'Yii::app()->controller->createUrl("delete",$data->primaryKey)',
            "htmlOptions" => array(
                'style'=>'width: 60px;'
            )
        )
    )
)); ?> 
If you need to get total items count find by CDbCriteria you need to write:
$model->search()->getTotalItemCount(); 
 
But if you want to customize your data provider with custom limit and offset params then you need
to set 'offset' and 'limit' option to 'CDbCriteria' class as following and need to set pagination to false:

 
$criteria=new CDbCriteria;
$criteria->order = $this->sortString;
$criteria->offset = 5;
$criteria->limit = 10;

return new CActiveDataProvider($this, array(
    'criteria'=>$criteria,
    "pagination" => false
));

How to Change CgridView table class? - Yii Framework

I can see in the source code of my page that CgridView has
<table class="items">
 
and I want to change this to
<table class="example">
 
It can be done by defining the 'itemsCssClass' key as widget's configuration.

So:

$this->widget('zii.widgets.grid.CGridView', array(
'itemsCssClass' => 'table-class',
'htmlOptions' => array('class' => 'example'))



gives me:

<div class="example"><table class="table-class"></table></div> 
 
Complete example of using CGridView: 

<?php 
$this->widget('zii.widgets.grid.CGridView', array(
    'dataProvider'=>$model->search(),
    'filter'=>$model,
    "itemsCssClass" => "table_design_1",
    "htmlOptions" => array(
        "class" => "div_design_1"
    ),
    'columns'=>array(
        array(
            'name'=>'family_name', 
            'header'=>'First name',
            'type' => 'raw',
            'value' => 'CHtml::link($data->family_name,$data->id)'
        ),
        array(
            'name'=>'given_name', 
            'header'=>'Last name',
            'type' => 'raw',
            'value' => 'CHtml::link($data->given_name,$data->id)'
        ),
        array(
            'class'=>'CButtonColumn',
            'viewButtonUrl'=>'Yii::app()->request->getBaseUrl(true)."/contact/view/".$data["id"]',
            'updateButtonUrl'=>'Yii::app()->controller->createUrl("update",$data->primaryKey)',
            'deleteButtonUrl'=>'Yii::app()->controller->createUrl("delete",$data->primaryKey)',
            "htmlOptions" => array(
                'style'=>'width: 60px;'
            )
        )
    )
)); ?>

Thursday, May 23, 2013

YII TbButtonColumn Urlencode() Expects Parameter 1 To Be String, Array Given

I can not understand anything the global did not, I put to show the button in CGridView when table has multiple primary key.

array(
                'class'=>'bootstrap.widgets.TbButtonColumn',
                'htmlOptions'=>array('style'=>'width: 50px'),
            ),
it gives me:
urlencode() expects parameter 1 to be string, array given
C:\xampp\htdocs\contactwebspace\framework\web\CUrlManager.php(758)
746 
747         if($manager->matchValue && $this->matchValue===null || $this->matchValue)
748         {
749             foreach($this->params as $key=>$value)
750             {
751                 if(!preg_match('/\A'.$value.'\z/u'.$case,$params[$key]))
752                     return false;
753             }
754         }
755 
756         foreach($this->params as $key=>$value)
757         {
758             $tr["<$key>"]=urlencode($params[$key]);
759             unset($params[$key]);
760         }
761 
762         $suffix=$this->urlSuffix===null ? $manager->urlSuffix : $this->urlSuffix;
763 
764         $url=strtr($this->template,$tr);
765 
766         if($this->hasHostInfo)
767         {
768             $hostInfo=Yii::app()->getRequest()->getHostInfo();
769             if(stripos($url,$hostInfo)===0)
770                 $url=substr($url,strlen($hostInfo));
It seems that my yii does not like composite primary keys in models.
I use it with GridView, CButtonColumn and an url issue update like :

array('class'=>'CButtonColumn', 
'viewButtonUrl'=>'Yii::app()->controller->createUrl("view",$data->primaryKey)', 
'updateButtonUrl'=>'Yii::app()->controller->createUrl("update",$data->primaryKey)', 
'deleteButtonUrl'=>'Yii::app()->controller->createUrl("delete",$data->primaryKey)',
)

Or you can use as following:
array('class'=>'CButtonColumn', 
'viewButtonUrl'=>'Yii::app()->request->getBaseUrl(true)."/contact/view/".$data["id"]', 
'updateButtonUrl'=>'Yii::app()->request->getBaseUrl(true)."/contact/update/".$data["id"]', 
'deleteButtonUrl'=>'Yii::app()->request->getBaseUrl(true)."/contact/delete/".$data["id"]',
)

Yii - How to print SQL used by the application

You can log the executed queries in the application log and review that. Something like this in the config file, and the file named "db.log" most probably created in "protected/runtime" folder.
'components' => array(
  'db'=>array(
    'enableParamLogging' => true,
  ),
  'log'=>array(
    'class'=>'CLogRouter',
    'routes'=>array( 
      array(
        'class'=>'CFileLogRoute',
        'levels'=>'trace,log',
        'categories' => 'system.db.CDbCommand',
        'logFile' => 'db.log',
      ), 
    ),
  ),
);
In some cases (e.g. when running tests), you will also need to call Yii::app()->log->processLogs(null); at the end of the process for this to work.
Of course, once you're there nothing's stopping you from writing your own log route that does something different with the logged messages, but mind that the logs are processed at the end of the request (or when you call processLogs), not every time you log something.

By the way, the proper way to create dynamic query with parameters:
$criteria = new CDbCriteria();
$criteria->condition = 't.date BETWEEN :from_date AND :to_date';
$criteria->params = array(
  ':from_date' => $from_date,
  ':to_date' => $to_date,
);
$criteria->with = array('order');

$orders = ProductOrder::model()->findAll($criteria);

Saturday, May 4, 2013

Yii Examples of Using CDbCriteria

Basic Usage
$Criteria = new CDbCriteria();
$Criteria->condition = "price > 30";
$Products = Product::model()->findAll($Criteria);
OR
//An example using the constructor to populate the properties.
$Criteria = new CDbCriteria(array('condition' => 'price > 30'));
$Products = Product::model()->findAll($Criteria);
Personally, I like to go with the first approach. I think it’s generally easier to read, but that’s just my personal preference.
Adding A Limit
$Criteria = new CDbCriteria();
$Criteria->condition = "price > 30";
$Criteria->limit = 1;
$Products = Product::model()->findAll($Criteria);
Limit with Offset
$Criteria = new CDbCriteria();
$Criteria->condition = "price > 30";
$Criteria->limit = 1;
$Criteria->offset = 1;
$Products = Product::model()->findAll($Criteria);
Ordering Results
$Criteria = new CDbCriteria();
$Criteria->condition = "price > 30";
$Criteria->limit = 1;
$Criteria->offset = 1;
$Criteria->order = "name ASC";
$Products = Product::model()->findAll($Criteria);
Limiting Selected Fields
$Criteria = new CDbCriteria();
$Criteria->condition = "price > 30";
$Criteria->limit = 1;
$Criteria->offset = 1;
$Criteria->order = "name ASC";
$Criteria->select = "id, name";
$Products = Product::model()->findAll($Criteria);
Example relation with :
$criteria = new CDbCriteria;
/* You can use condition as first parameter and must one conditions,
which will make and conditions with other compare values  */
$criteria->conditions = 'is_user_deleted = 0 OR is_user_deleted = 2'; 
 
$criteria->with = array('groupGroup');
$criteria->together = true; // ADDED THIS
$criteria->compare( 'groupGroup.id', $this->group_id, true ); 
/* true means compare as like '% value %' */
$criteria->compare('first_name',$this->first_name,true);
$criteria->compare('last_name',$this->last_name,true);
$criteria->order = 'first_name ASC';
$criteria->limit = 10;
If two table has same column, then need to modify some code suppose-
1. $criteria->compare($this->getTableAlias().'.deleted','0',true);
Here both this table and 'group' table has same column named 'deleted', but now 
only compare with current tables 'deleted' field. 
And foreign table must be in relations...
public function relations() {
    return array(
         'groupGroup' => array(self::BELONGS_TO, 'Group', 'group_id')
        /* group_id is current models foreign key from 'group' table. */
     );
}

Tuesday, April 30, 2013

Get document root path using yii application

dirname(Yii::app()->request->scriptFile)

CGridView a CLinkColumn with sortable header using yii

I have it working with the latest yii (non-stable but might work with the current stable release). (could do with some improvement but it does what I need)

Try this; create a new component under components/SCLinkColumnWithSort.php

<?php
class SCLinkColumnWithSort extends CLinkColumn
{

  public $name;
  public $sortable = true;
  public $filter;

  protected function renderFilterCellContent()
  {
    $this->linkHtmlOptions['class'] = $this->name;
    if($this->filter!==false && $this->grid->filter!==null && strpos($this->name,'.')===false)
    {
      if(is_array($this->filter))
        echo CHtml::activeDropDownList($this->grid->filter, $this->name, $this->filter, array('id'=>false,'prompt'=>''));
      else if($this->filter===null)
        echo CHtml::activeTextField($this->grid->filter, $this->name, array('id'=>false));
      else
        echo $this->filter;
    }
    else
      parent::renderFilterCellContent();
  }

  protected function renderHeaderCellContent()
  {
    if($this->grid->enableSorting && $this->sortable && $this->name!==null)
      echo $this->grid->dataProvider->getSort()->link($this->name,$this->header);
    else
      parent::renderHeaderCellContent();
  }

}
?> 
Use this as following: 

<?php
$this->widget('zii.widgets.grid.CGridView', array(
  'dataProvider' => $dataProvider,
  'columns' => array(
    array(
      'class' => 'SCLinkColumnWithSort',
      'name' => 'column_name_to_sort',
     )
  )
))
?> 
 
Or you can directly use, but upper one used for more customization:
array(
  'name' => 'mobile_number',
  'type' => 'raw',
  'value' => 'CHtml::link($data->mobile_number,$data->contact_id)'
) 
Where mobile_number is filed value in name, in value, mobile_number is for sorting
and contact_id is for making link.

Sunday, April 21, 2013

Yii throw 404 custom exception

You need to define a view file under protected/views/site folder (any folder and that shoud be configured in config/main.php file as below) suppose named error.php, and throw CHttpException from where you want to show error page.


Define error view in config/main.php file:
'errorHandler'=>array(
    // use 'site/error' action to display errors
    'errorAction'=>'site/error',
)
That means a file named error.php shoud be in views/site/ folder.

Throw 404 custom exception using the following php  code:
throw new CHttpException(404,'The requested page does not exist.');

And the error.php file look like:
<?php
$this->pageTitle=Yii::app()->name . ' - Error';
$this->breadcrumbs=array(
    'Error'
);
?>
<h2>Error <?php echo $code; ?></h2>
<div class="error">
<?php echo CHtml::encode($message); ?>
</div>

Yii upload image or file to server

Model Image:
<?php
class Image extends CActiveRecord
{
    public $uploaded_owner_img;
  
    public static function model($className=__CLASS__)
    {
        return parent::model($className);
    }
    
    public function tableName()
    {
        return 'table_name';
    }
    
    public function rules()
    {
        return array(
            array('owner_img', 'file', 'allowEmpty'=>true,'types'=>'jpg','maxSize'=>1024*1024*1, 'tooLarge'=>'Image must be less than�1MB'),
            array('owner_name, owner_img', 'required'),
            array('owner_name', 'unique'),
            array('owner_name', 'length', 'max'=>20, 'encoding'=>'utf-8'),
            array('owner_name', 'safe', 'on'=>'search'),
        );
    }
    
    public function attributeLabels()
    {
        return array(
            'owner_img' => 'Select image.',
            'owner_name' => 'Name'
        );
    }
    
    protected function beforeSave() {
        if (parent::beforeSave ()) {
            if ($this->isNewRecord) {
                $this->created = date('Ymd');
            }
            return true;
        }else {
            return false;
        }
    }
}
Controller ImageController.php
<?php
class ImageController extends Controller
{
    public function actions()
    {
        return array(
            // captcha action renders the CAPTCHA image displayed on the contact page
            'captcha'=>array(
                'class'=>'CCaptchaAction',
                'backColor'=>0xFFFFFF,
            ),
            // page action renders "static" pages stored under 'protected/views/site/pages'
            // They can be accessed via: index.php?r=site/page&view=FileName
            'page'=>array(
                'class'=>'CViewAction',
            )
        );
    }
        
    public function actionCreate()
    {
        $model=new Image;
        //AJAX validation is needed
        $this->performAjaxValidation($model);
        if(isset($_POST['Image'])) {
            $model->attributes=$_POST['Image'];
            if (@!empty($_FILES['Image']['name']['owner_img'])){
                $model->owner_img = time().".jpg";
                if ($model->validate(array('owner_img'))){
                    $model->uploaded_owner_img = CUploadedFile::getInstance($model, 'owner_img');
                    $model->uploaded_owner_img->saveAs(Yii::app()->basePath.'/'.$model->owner_img);
                    
                    if($model->save()){
                        echo "Model saved"; die(0);
                    }
                }
            }
        }

        $this->render('create',array(
            'model'=>$model,
        ));
    }
    
    protected function performAjaxValidation($model)
    {
        if(isset($_POST['ajax']) && $_POST['ajax']==='map-form')
        {
            echo CActiveForm::validate($model);
            Yii::app()->end();
        }
    }
}
View file
<?php
$this->breadcrumbs=array(
    "image/create"
);

$this->menu=array(
);
?>

<h1>Image Upload</h1>

<div class="form">

<?php 
$form=$this->beginWidget('CActiveForm', array(
    'id'=>'map-form',
    'enableAjaxValidation'=>false,
    'htmlOptions' =>array('enctype'=>"multipart/form-data" ),
    'enableAjaxValidation' => false,
    'enableClientValidation'=>true,
    'clientOptions'=>array('validateOnSubmit'=>true)
)); 
?>

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

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

<div class="row">
    <?php echo $form->labelEx($model,'owner_name'); ?>
    <?php echo $form->textField($model,'owner_name',array('size'=>32,'maxlength'=>20)); ?>
    <?php echo $form->error($model,'owner_name'); ?>
</div>

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

<div class="row buttons">
    <?php echo CHtml::submitButton($model->isNewRecord ? 'Create' : 'Save'); ?>
</div>

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