AutoTimestamp.php 3.23 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
<?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\Behavior;
use yii\db\Expression;
use yii\db\ActiveRecord;

/**
 * AutoTimestamp will automatically fill the attributes about creation time and updating time.
 *
 * AutoTimestamp fills the attributes when the associated AR model is being inserted or updated.
 * You may specify an AR to use this behavior like the following:
 *
 * ~~~
 * public function behaviors()
 * {
 *     return array(
 *         'timestamp' => array(
 *             'class' => 'yii\behaviors\AutoTimestamp',
 *         ),
 *     );
 * }
 * ~~~
 *
31
 * By default, AutoTimestamp will fill the `create_time` attribute with the current timestamp
Qiang Xue committed
32 33
 * when the associated AR object is being inserted; it will fill the `update_time` attribute
 * with the timestamp when the AR object is being updated.
34 35 36 37 38 39 40
 *
 * @author Qiang Xue <qiang.xue@gmail.com>
 * @since 2.0
 */
class AutoTimestamp extends Behavior
{
	/**
Qiang Xue committed
41 42 43 44
	 * @var array list of attributes that are to be automatically filled with timestamps.
	 * The array keys are the ActiveRecord events upon which the attributes are to be filled with timestamps,
	 * and the array values are the corresponding attribute to be updated. You can use a string to represent
	 * a single attribute, or an array to represent a list of attributes.
45
	 * The default setting is to update the `create_time` attribute upon AR insertion,
Qiang Xue committed
46
	 * and update the `update_time` attribute upon AR updating.
47
	 */
Qiang Xue committed
48
	public $attributes = array(
49
		ActiveRecord::EVENT_BEFORE_INSERT => 'create_time',
Qiang Xue committed
50 51
		ActiveRecord::EVENT_BEFORE_UPDATE => 'update_time',
	);
52
	/**
53 54
	 * @var \Closure|Expression The expression that will be used for generating the timestamp.
	 * This can be either an anonymous function that returns the timestamp value,
55 56 57 58 59 60 61 62 63 64 65 66
	 * or an [[Expression]] object representing a DB expression (e.g. `new Expression('NOW()')`).
	 * If not set, it will use the value of `time()` to fill the attributes.
	 */
	public $timestamp;


	/**
	 * Declares event handlers for the [[owner]]'s events.
	 * @return array events (array keys) and the corresponding event handler methods (array values).
	 */
	public function events()
	{
Qiang Xue committed
67 68 69 70 71 72 73 74 75
		$events = array();
		$behavior = $this;
		foreach ($this->attributes as $event => $attributes) {
			if (!is_array($attributes)) {
				$attributes = array($attributes);
			}
			$events[$event] = function () use ($behavior, $attributes) {
				$behavior->updateTimestamp($attributes);
			};
76
		}
Qiang Xue committed
77
		return $events;
78 79 80
	}

	/**
Qiang Xue committed
81 82
	 * Updates the attributes with the current timestamp.
	 * @param array $attributes list of attributes to be updated.
83
	 */
Qiang Xue committed
84
	public function updateTimestamp($attributes)
85
	{
Qiang Xue committed
86 87
		foreach ($attributes as $attribute) {
			$this->owner->$attribute = $this->evaluateTimestamp($attribute);
88 89 90 91
		}
	}

	/**
Qiang Xue committed
92
	 * Gets the appropriate timestamp for the specified attribute.
93 94 95 96 97 98 99 100
	 * @param string $attribute attribute name
	 * @return mixed the timestamp value
	 */
	protected function evaluateTimestamp($attribute)
	{
		if ($this->timestamp instanceof Expression) {
			return $this->timestamp;
		} elseif ($this->timestamp !== null) {
101
			return call_user_func($this->timestamp);
102 103 104 105 106
		} else {
			return time();
		}
	}
}