Showing posts with label model. Show all posts
Showing posts with label model. 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
        ));
    }
}
?>

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;
}

Thursday, May 23, 2013

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, April 20, 2013

YII model with some action perform

Add custom error to a model:
$model->addError('email', 'No valid account associated with this email address.');

Validate a model:
$model->validate();

Yii model without table

<?php
class RegistrationForm extends CFormModel
{
    public $email;
    public $password;
    public $repassword;
    public $displayname;
    public $verifycode;


    public function rules()
    {
        return array(
            array('email, password, repassword', 'required'),
            array('password, repassword', 'length', 'min'=>4),
            array('email, password, repassword, displayname', 'length', 'max'=>200),
            array('email', 'unique'),
            array('repassword', 'compare', 'compareAttribute'=>'password'),
            array('email', 'email'),
            array('verifycode', 'captcha', 'allowEmpty'=>!CCaptcha::checkRequirements()),
        );
    }
    
    
    public function attributeLabels()
    {
        return array(
            'email'=>'Email',
            'password'=>'Password',
            'repassword'=>'Re-Password',
            'displayname'=>'Display Name',
            'verifycode'=>'Confirm you are not alien',
        );
    }
           
}

Yii create a new model with common attributes

The rules() method, like most of the Yii methods, returns an array of data:
public function rules()
{
    return array(/* actual rules */);
}
The first, most obvious, restriction is to indicate that a field is required. Just use a comma-separated string of field names as the first returned value and the word required as the second:
array('name, email, subject, body', 'required'),
You can also specify that a value must be a number or, more specifically, an integer. This syntax is slightly different. Here, I indicate that the ext field must be an integer:
array('ext', 'numerical', 'integerOnly'=>true),
For strings, you can restrict the length to a maximum value:
array('name','length','max'=>40),
Or a minimum value:
array('name','length','min'=>6),
Or both:
array('name','length','min'=>6, 'max'=>40),
Another useful validation routine is to check that a string is an email address. I do that here, to a userEmail field:
array('userEmail', 'email'),
To indicate that a string needs to be a URL, use:
array('link', 'url'),
Another useful rule is for comparisons, like when a user registers and you have to make sure that the confirmed password matches the password:
array('password1', 'compare', 'compareAttribute'=>'password2', 'on'=>'register'),
There is also the “safe” rule. This rule is used to provide access to data that isn’t otherwise validated. For example, an email address is already considered to be “safe” because it must abide by the email rule, but the Employee Model has the leaveDate field which won’t have any rules applied to it (in part, because there are no date-specific rules and also because the field can be null). To be able to refer to that value, it must be declared as safe:
array('leaveDate', 'safe'),
If there are multiple fields to make safe, just separate them with commas.
There’s also a rule to indicate which fields should be safe to search on. By default, every rule is made safe in a search, but you may want to change that behavior by removing fields from the list:
array('id, departmentId, firstName, lastName, email, ext, hireDate, leaveDate', 'safe', 'on'=>'search'),
So, using this information, the complete rules() method for my Employee Model is:
public function rules()
{
    return array(
        array('departmentId, firstName, lastName, email, hireDate', 'required'),
        array('departmentId, ext', 'numerical', 'integerOnly'=>true),
        array('firstName', 'length', 'max'=>20),
        array('lastName', 'length', 'max'=>40),
        array('email', 'length', 'max'=>60),
        array('email', 'email'),
        array('leaveDate', 'safe'),
        array('id, departmentId, firstName, lastName, email, ext, hireDate, leaveDate', 'safe', 'on'=>'search'),
 );
}
Moving on, another key Model method is relations(), which indicates the relationship between Models. If your database is designed properly, this method will already be properly filled out, again thanks to Gii. Here’s how the relations() method in the Employee Model looks:
public function relations()
{
    return array( 
        'department' => array(self::BELONGS_TO, 'Department', 'departmentId'
    );
}
The relation is given a name, here department. The relation indicates that the departmentId column in the Employee Model (i.e., this one) belongs to the Department Model. Here’s how this will come into play: When loading the information for an employee, you can also load any of its relations. By doing so, references to department will equate to the Department Model record that is the employee’s department. So if the $model object represents the Employee being viewed, then $model->department->name would be the name of the department that the employee is associated with.
In the Department Model, this relation is defined:
public function relations()
{
    return array('employees' => array(self::HAS_MANY, 'Employee', 'departmentId') );
}
So if $model represents a specific Department being viewed, then $model->employees is an array of Employee objects, each of which representing one Employee in that department.
The relations between Models is a key player in complex MVC sites. Through properly defined relations, associated content can be retrieved. You’ll learn more about this in the next couple of posts.
Moving on, a more trivial, but still nice, method is attributeLabels(). This method returns an associative array of fields and the labels to use for those fields in forms, error messages, and so forth. The Yii framework does a great job of making these conversations automatically, like firstName becoming First Name and departmentId becoming just Department. But you may want to still customize these. For the Employee Model, here’s what I have:
public function attributeLabels()
{
    return array(
        'id' => 'Employee ID',
        'departmentId' => 'Department',
        'firstName' => 'First Name',
        'lastName' => 'Last Name',
        'email' => 'Email',
        'ext' => 'Ext',
        'hireDate' => 'Hire Date',
        'leaveDate' => 'Leave Date',
    );
}

Complete Example


<?php
class PasswordReset extends CActiveRecord {
    public static function model($className=__CLASS__)
    {
        return parent::model($className);
    }
    public function tableName()
    {
        return 'password_reset';
    }
    public function rules()
    {
        return array(
            array('user_user_id, request_time, request_hash, request_done', 'required'),
            array('user_user_id, request_time, request_done', 'numerical'),
            array('request_done','length','min'=>6, 'max'=>1),
            array('request_time','length','min'=>6, 'max'=>10),
            array('request_hash','length','max'=>100),
            array('user_user_id, request_time, request_hash, request_done', 'safe', 'on'=>'search')
        );
    }
    public function relations()
    {
        return array(
            'User' => array(self::BELONGS_TO, 'User', 'user_user_id')
        );
    }
    public function attributeLabels()
    {
        return array(
            'request_time' => 'Request Time',
            'request_hash' => 'Request Hash',
            'request_done' => 'Request Done'	
        );
    }
    public function search()
    {
        $criteria=new CDbCriteria;

        $criteria->compare('request_time', $this->request_time, true);
        $criteria->compare('request_hash', $this->request_hash, true);
        $criteria->compare('request_done', $this->request_done, true);
        $criteria->compare('User.id', $this->User->id);
        $criteria->compare('request_done', '0', true);

        return new CActiveDataProvider($this, array(
            'criteria'=>$criteria
        ));
    }
    public function findByParameter($fieldname, $fieldvalue)
    {
        $criteria=new CDbCriteria;
        $criteria->compare($fieldname, $fieldvalue, true);		
        return new CActiveDataProvider($this, array(
            'criteria' => $criteria
        ));
    }
    public function findByParameters($parameters)
    {
        $criteria=new CDbCriteria;
        foreach ($parameters as $key => $value) {
            $criteria->compare($key, $value, true);
        }                
        return new CActiveDataProvider($this, array(
            'criteria' => $criteria,
        ));
    }
    public function getRequestList() {
        $parameters = array('request_done' => '0');
        $requests = PasswordReset::model()->findByParameters($parameters);
        return CHtml::listData($requests->getData(), 'password_reset_id', 'request_hash');
    }
}
?>