mirror of
				https://github.com/yiisoft/yii2.git
				synced 2025-11-04 06:37:55 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			142 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			142 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
<?php
 | 
						|
/**
 | 
						|
 * @link http://www.yiiframework.com/
 | 
						|
 * @copyright Copyright (c) 2008 Yii Software LLC
 | 
						|
 * @license http://www.yiiframework.com/license/
 | 
						|
 */
 | 
						|
 | 
						|
namespace yii\behaviors;
 | 
						|
 | 
						|
use yii\base\InvalidCallException;
 | 
						|
use yii\db\BaseActiveRecord;
 | 
						|
 | 
						|
/**
 | 
						|
 * TimestampBehavior automatically fills the specified attributes with the current timestamp.
 | 
						|
 *
 | 
						|
 * To use TimestampBehavior, insert the following code to your ActiveRecord class:
 | 
						|
 *
 | 
						|
 * ```php
 | 
						|
 * use yii\behaviors\TimestampBehavior;
 | 
						|
 *
 | 
						|
 * public function behaviors()
 | 
						|
 * {
 | 
						|
 *     return [
 | 
						|
 *         TimestampBehavior::className(),
 | 
						|
 *     ];
 | 
						|
 * }
 | 
						|
 * ```
 | 
						|
 *
 | 
						|
 * By default, TimestampBehavior will fill the `created_at` and `updated_at` attributes with the current timestamp
 | 
						|
 * when the associated AR object is being inserted; it will fill the `updated_at` attribute
 | 
						|
 * with the timestamp when the AR object is being updated. The timestamp value is obtained by `time()`.
 | 
						|
 *
 | 
						|
 * Because attribute values will be set automatically by this behavior, they are usually not user input and should therefore
 | 
						|
 * not be validated, i.e. `created_at` and `updated_at` should not appear in the [[\yii\base\Model::rules()|rules()]] method of the model.
 | 
						|
 *
 | 
						|
 * For the above implementation to work with MySQL database, please declare the columns(`created_at`, `updated_at`) as int(11) for being UNIX timestamp.
 | 
						|
 *
 | 
						|
 * If your attribute names are different or you want to use a different way of calculating the timestamp,
 | 
						|
 * you may configure the [[createdAtAttribute]], [[updatedAtAttribute]] and [[value]] properties like the following:
 | 
						|
 *
 | 
						|
 * ```php
 | 
						|
 * use yii\db\Expression;
 | 
						|
 *
 | 
						|
 * public function behaviors()
 | 
						|
 * {
 | 
						|
 *     return [
 | 
						|
 *         [
 | 
						|
 *             'class' => TimestampBehavior::className(),
 | 
						|
 *             'createdAtAttribute' => 'create_time',
 | 
						|
 *             'updatedAtAttribute' => 'update_time',
 | 
						|
 *             'value' => new Expression('NOW()'),
 | 
						|
 *         ],
 | 
						|
 *     ];
 | 
						|
 * }
 | 
						|
 * ```
 | 
						|
 *
 | 
						|
 * In case you use an [[\yii\db\Expression]] object as in the example above, the attribute will not hold the timestamp value, but
 | 
						|
 * the Expression object itself after the record has been saved. If you need the value from DB afterwards you should call
 | 
						|
 * the [[\yii\db\ActiveRecord::refresh()|refresh()]] method of the record.
 | 
						|
 *
 | 
						|
 * TimestampBehavior also provides a method named [[touch()]] that allows you to assign the current
 | 
						|
 * timestamp to the specified attribute(s) and save them to the database. For example,
 | 
						|
 *
 | 
						|
 * ```php
 | 
						|
 * $model->touch('creation_time');
 | 
						|
 * ```
 | 
						|
 *
 | 
						|
 * @author Qiang Xue <qiang.xue@gmail.com>
 | 
						|
 * @author Alexander Kochetov <creocoder@gmail.com>
 | 
						|
 * @since 2.0
 | 
						|
 */
 | 
						|
class TimestampBehavior extends AttributeBehavior
 | 
						|
{
 | 
						|
    /**
 | 
						|
     * @var string the attribute that will receive timestamp value
 | 
						|
     * Set this property to false if you do not want to record the creation time.
 | 
						|
     */
 | 
						|
    public $createdAtAttribute = 'created_at';
 | 
						|
    /**
 | 
						|
     * @var string the attribute that will receive timestamp value.
 | 
						|
     * Set this property to false if you do not want to record the update time.
 | 
						|
     */
 | 
						|
    public $updatedAtAttribute = 'updated_at';
 | 
						|
    /**
 | 
						|
     * {@inheritdoc}
 | 
						|
     *
 | 
						|
     * In case, when the value is `null`, the result of the PHP function [time()](http://php.net/manual/en/function.time.php)
 | 
						|
     * will be used as value.
 | 
						|
     */
 | 
						|
    public $value;
 | 
						|
 | 
						|
 | 
						|
    /**
 | 
						|
     * {@inheritdoc}
 | 
						|
     */
 | 
						|
    public function init()
 | 
						|
    {
 | 
						|
        parent::init();
 | 
						|
 | 
						|
        if (empty($this->attributes)) {
 | 
						|
            $this->attributes = [
 | 
						|
                BaseActiveRecord::EVENT_BEFORE_INSERT => [$this->createdAtAttribute, $this->updatedAtAttribute],
 | 
						|
                BaseActiveRecord::EVENT_BEFORE_UPDATE => $this->updatedAtAttribute,
 | 
						|
            ];
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * {@inheritdoc}
 | 
						|
     *
 | 
						|
     * In case, when the [[value]] is `null`, the result of the PHP function [time()](http://php.net/manual/en/function.time.php)
 | 
						|
     * will be used as value.
 | 
						|
     */
 | 
						|
    protected function getValue($event)
 | 
						|
    {
 | 
						|
        if ($this->value === null) {
 | 
						|
            return time();
 | 
						|
        }
 | 
						|
 | 
						|
        return parent::getValue($event);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Updates a timestamp attribute to the current timestamp.
 | 
						|
     *
 | 
						|
     * ```php
 | 
						|
     * $model->touch('lastVisit');
 | 
						|
     * ```
 | 
						|
     * @param string $attribute the name of the attribute to update.
 | 
						|
     * @throws InvalidCallException if owner is a new record (since version 2.0.6).
 | 
						|
     */
 | 
						|
    public function touch($attribute)
 | 
						|
    {
 | 
						|
        /* @var $owner BaseActiveRecord */
 | 
						|
        $owner = $this->owner;
 | 
						|
        if ($owner->getIsNewRecord()) {
 | 
						|
            throw new InvalidCallException('Updating the timestamp is not possible on a new record.');
 | 
						|
        }
 | 
						|
        $owner->updateAttributes(array_fill_keys((array) $attribute, $this->getValue(null)));
 | 
						|
    }
 | 
						|
}
 |