EMongoTimestampBehaviour.php 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. <?php
  2. /**
  3. * CTimestampBehavior class file.
  4. *
  5. * @author Jonah Turnquist <poppitypop@gmail.com>
  6. * @link http://www.yiiframework.com/
  7. * @copyright Copyright &copy; 2008-2011 Yii Software LLC
  8. * @license http://www.yiiframework.com/license/
  9. *
  10. * Rewritten to work with MongoDB
  11. */
  12. /**
  13. * EMongoTimestampBheaviour will automatically fill date and time related attributes.
  14. *
  15. * EMongoTimestampBehaviour will automatically fill date and time related attributes when the active record
  16. * is created and/or upadated.
  17. * You may specify an active record model to use this behavior like so:
  18. * <pre>
  19. * public function behaviors(){
  20. * return array(
  21. * 'EMongoTimestampBehaviour' => array(
  22. * 'class' => 'EMongoTimestampBehaviour',
  23. * 'createAttribute' => 'create_time_attribute',
  24. * 'updateAttribute' => 'update_time_attribute',
  25. * 'onScenario' => array('scenarioName'),
  26. * )
  27. * );
  28. * }
  29. * </pre>
  30. * The {@link createAttribute} and {@link updateAttribute} options actually default to 'create_time' and 'update_time'
  31. * respectively, so it is not required that you configure them. If you do not wish EMongoTimestampBheaviour
  32. * to set a timestamp for record update or creation, set the corresponding attribute option to null.
  33. *
  34. * By default, the update attribute is only set on record update. If you also wish it to be set on record creation,
  35. * set the {@link setUpdateOnCreate} option to true.
  36. *
  37. * Although EMongoTimestampBheaviour attempts to figure out on it's own what value to inject into the timestamp attribute,
  38. * you may specify a custom value to use instead via {@link timestampExpression}
  39. */
  40. class EMongoTimestampBehaviour extends CActiveRecordBehavior
  41. {
  42. /**
  43. * @var mixed The name of the attribute to store the creation time. Set to null to not
  44. * use a timestamp for the creation attribute. Defaults to 'create_time'
  45. */
  46. public $createAttribute = 'create_time';
  47. /**
  48. * @var mixed The name of the attribute to store the modification time. Set to null to not
  49. * use a timestamp for the update attribute. Defaults to 'update_time'
  50. */
  51. public $updateAttribute = 'update_time';
  52. /**
  53. * @var array set attributes only on this scenarios
  54. */
  55. public $onScenario = array();
  56. /**
  57. * @var array not set attributes only on this scenarios
  58. */
  59. public $notOnScenario = array();
  60. /**
  61. * @var bool Whether to set the update attribute to the creation timestamp upon creation.
  62. * Otherwise it will be left alone. Defaults to false.
  63. */
  64. public $setUpdateOnCreate = false;
  65. /**
  66. * @var mixed The expression that will be used for generating the timestamp.
  67. * This can be either a string representing a PHP expression (e.g. 'time()'),
  68. * or a {@link CDbExpression} object representing a DB expression (e.g. new CDbExpression('NOW()')).
  69. * Defaults to null, meaning that we will attempt to figure out the appropriate timestamp
  70. * automatically. If we fail at finding the appropriate timestamp, then it will
  71. * fall back to using the current UNIX timestamp
  72. */
  73. public $timestampExpression;
  74. /**
  75. * Responds to {@link CModel::onBeforeSave} event.
  76. * Sets the values of the creation or modified attributes as configured
  77. *
  78. * @param CModelEvent $event event parameter
  79. */
  80. public function beforeSave($event)
  81. {
  82. if($this->checkScenarios()){
  83. if($this->getOwner()->getIsNewRecord() && ($this->createAttribute !== null)){
  84. $this->getOwner()->{$this->createAttribute} = $this->getTimestampByAttribute($this->createAttribute);
  85. }
  86. if((!$this->getOwner()->getIsNewRecord() || $this->setUpdateOnCreate) && ($this->updateAttribute !== null)){
  87. $this->getOwner()->{$this->updateAttribute} = $this->getTimestampByAttribute($this->updateAttribute);
  88. }
  89. }
  90. }
  91. /**
  92. * Gets the approprate timestamp depending on the column type $attribute is
  93. *
  94. * @param string $attribute $attribute
  95. * @return mixed timestamp (eg unix timestamp or a mysql function)
  96. */
  97. protected function getTimestampByAttribute($attribute)
  98. {
  99. if($this->timestampExpression instanceof MongoDate){
  100. return $this->timestampExpression;
  101. }elseif($this->timestampExpression !== null){
  102. return @eval('return '.$this->timestampExpression.';');
  103. }
  104. return new MongoDate();
  105. }
  106. protected function checkScenarios()
  107. {
  108. if(!is_array($this->onScenario) or !is_array($this->notOnScenario)){
  109. throw new CException('onScenario and notOnScenario must be an array');
  110. }
  111. if(count($this->onScenario)){
  112. if(count($this->notOnScenario)){
  113. throw new CException('You can not specify both the parameter and onScenario notOnScenario');
  114. }
  115. if(in_array($this->getOwner()->getScenario(), $this->onScenario)){
  116. return true;
  117. }else{
  118. return false;
  119. }
  120. }
  121. if(count($this->notOnScenario)){
  122. if(count($this->onScenario)){
  123. throw new CException('You can not specify both the parameter and onScenario notOnScenario');
  124. }
  125. if(in_array($this->getOwner()->getScenario(), $this->notOnScenario)){
  126. return false;
  127. }else{
  128. return true;
  129. }
  130. }
  131. return true;
  132. }
  133. }