You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

141 lines
4.6KB

  1. <?php
  2. /**
  3. * @link http://www.yiiframework.com/
  4. * @copyright Copyright (c) 2008 Yii Software LLC
  5. * @license http://www.yiiframework.com/license/
  6. */
  7. namespace yii\behaviors;
  8. use yii\base\InvalidCallException;
  9. use yii\db\BaseActiveRecord;
  10. /**
  11. * TimestampBehavior automatically fills the specified attributes with the current timestamp.
  12. *
  13. * To use TimestampBehavior, insert the following code to your ActiveRecord class:
  14. *
  15. * ```php
  16. * use yii\behaviors\TimestampBehavior;
  17. *
  18. * public function behaviors()
  19. * {
  20. * return [
  21. * TimestampBehavior::className(),
  22. * ];
  23. * }
  24. * ```
  25. *
  26. * By default, TimestampBehavior will fill the `created_at` and `updated_at` attributes with the current timestamp
  27. * when the associated AR object is being inserted; it will fill the `updated_at` attribute
  28. * with the timestamp when the AR object is being updated. The timestamp value is obtained by `time()`.
  29. *
  30. * Because attribute values will be set automatically by this behavior, they are usually not user input and should therefore
  31. * not be validated, i.e. `created_at` and `updated_at` should not appear in the [[\yii\base\Model::rules()|rules()]] method of the model.
  32. *
  33. * For the above implementation to work with MySQL database, please declare the columns(`created_at`, `updated_at`) as int(11) for being UNIX timestamp.
  34. *
  35. * If your attribute names are different or you want to use a different way of calculating the timestamp,
  36. * you may configure the [[createdAtAttribute]], [[updatedAtAttribute]] and [[value]] properties like the following:
  37. *
  38. * ```php
  39. * use yii\db\Expression;
  40. *
  41. * public function behaviors()
  42. * {
  43. * return [
  44. * [
  45. * 'class' => TimestampBehavior::className(),
  46. * 'createdAtAttribute' => 'create_time',
  47. * 'updatedAtAttribute' => 'update_time',
  48. * 'value' => new Expression('NOW()'),
  49. * ],
  50. * ];
  51. * }
  52. * ```
  53. *
  54. * In case you use an [[\yii\db\Expression]] object as in the example above, the attribute will not hold the timestamp value, but
  55. * the Expression object itself after the record has been saved. If you need the value from DB afterwards you should call
  56. * the [[\yii\db\ActiveRecord::refresh()|refresh()]] method of the record.
  57. *
  58. * TimestampBehavior also provides a method named [[touch()]] that allows you to assign the current
  59. * timestamp to the specified attribute(s) and save them to the database. For example,
  60. *
  61. * ```php
  62. * $model->touch('creation_time');
  63. * ```
  64. *
  65. * @author Qiang Xue <qiang.xue@gmail.com>
  66. * @author Alexander Kochetov <creocoder@gmail.com>
  67. * @since 2.0
  68. */
  69. class TimestampBehavior extends AttributeBehavior
  70. {
  71. /**
  72. * @var string the attribute that will receive timestamp value
  73. * Set this property to false if you do not want to record the creation time.
  74. */
  75. public $createdAtAttribute = 'created_at';
  76. /**
  77. * @var string the attribute that will receive timestamp value.
  78. * Set this property to false if you do not want to record the update time.
  79. */
  80. public $updatedAtAttribute = 'updated_at';
  81. /**
  82. * @inheritdoc
  83. *
  84. * In case, when the value is `null`, the result of the PHP function [time()](http://php.net/manual/en/function.time.php)
  85. * will be used as value.
  86. */
  87. public $value;
  88. /**
  89. * @inheritdoc
  90. */
  91. public function init()
  92. {
  93. parent::init();
  94. if (empty($this->attributes)) {
  95. $this->attributes = [
  96. BaseActiveRecord::EVENT_BEFORE_INSERT => [$this->createdAtAttribute, $this->updatedAtAttribute],
  97. BaseActiveRecord::EVENT_BEFORE_UPDATE => $this->updatedAtAttribute,
  98. ];
  99. }
  100. }
  101. /**
  102. * @inheritdoc
  103. *
  104. * In case, when the [[value]] is `null`, the result of the PHP function [time()](http://php.net/manual/en/function.time.php)
  105. * will be used as value.
  106. */
  107. protected function getValue($event)
  108. {
  109. if ($this->value === null) {
  110. return time();
  111. }
  112. return parent::getValue($event);
  113. }
  114. /**
  115. * Updates a timestamp attribute to the current timestamp.
  116. *
  117. * ```php
  118. * $model->touch('lastVisit');
  119. * ```
  120. * @param string $attribute the name of the attribute to update.
  121. * @throws InvalidCallException if owner is a new record (since version 2.0.6).
  122. */
  123. public function touch($attribute)
  124. {
  125. /* @var $owner BaseActiveRecord */
  126. $owner = $this->owner;
  127. if ($owner->getIsNewRecord()) {
  128. throw new InvalidCallException('Updating the timestamp is not possible on a new record.');
  129. }
  130. $owner->updateAttributes(array_fill_keys((array) $attribute, $this->getValue(null)));
  131. }
  132. }