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.

AttributeBehavior.php 3.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  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;
  9. use Closure;
  10. use yii\base\Behavior;
  11. use yii\base\Event;
  12. /**
  13. * AttributeBehavior automatically assigns a specified value to one or multiple attributes of an ActiveRecord object when certain events happen.
  14. *
  15. * To use AttributeBehavior, configure the [[attributes]] property which should specify the list of attributes
  16. * that need to be updated and the corresponding events that should trigger the update. For example,
  17. * Then configure the [[value]] property with a PHP callable whose return value will be used to assign to the current
  18. * attribute(s). For example,
  19. *
  20. * ~~~
  21. * use yii\behaviors\AttributeBehavior;
  22. *
  23. * public function behaviors()
  24. * {
  25. * return [
  26. * [
  27. * 'class' => AttributeBehavior::className(),
  28. * 'attributes' => [
  29. * ActiveRecord::EVENT_BEFORE_INSERT => 'attribute1',
  30. * ActiveRecord::EVENT_BEFORE_UPDATE => 'attribute2',
  31. * ],
  32. * 'value' => function ($event) {
  33. * return 'some value';
  34. * },
  35. * ],
  36. * ];
  37. * }
  38. * ~~~
  39. *
  40. * @author Luciano Baraglia <luciano.baraglia@gmail.com>
  41. * @author Qiang Xue <qiang.xue@gmail.com>
  42. * @since 2.0
  43. */
  44. class AttributeBehavior extends Behavior
  45. {
  46. /**
  47. * @var array list of attributes that are to be automatically filled with the value specified via [[value]].
  48. * The array keys are the ActiveRecord events upon which the attributes are to be updated,
  49. * and the array values are the corresponding attribute(s) to be updated. You can use a string to represent
  50. * a single attribute, or an array to represent a list of attributes. For example,
  51. *
  52. * ```php
  53. * [
  54. * ActiveRecord::EVENT_BEFORE_INSERT => ['attribute1', 'attribute2'],
  55. * ActiveRecord::EVENT_BEFORE_UPDATE => 'attribute2',
  56. * ]
  57. * ```
  58. */
  59. public $attributes = [];
  60. /**
  61. * @var mixed the value that will be assigned to the current attributes. This can be an anonymous function
  62. * or an arbitrary value. If the former, the return value of the function will be assigned to the attributes.
  63. * The signature of the function should be as follows,
  64. *
  65. * ```php
  66. * function ($event)
  67. * {
  68. * // return value will be assigned to the attribute
  69. * }
  70. * ```
  71. */
  72. public $value;
  73. /**
  74. * @inheritdoc
  75. */
  76. public function events()
  77. {
  78. return array_fill_keys(array_keys($this->attributes), 'evaluateAttributes');
  79. }
  80. /**
  81. * Evaluates the attribute value and assigns it to the current attributes.
  82. * @param Event $event
  83. */
  84. public function evaluateAttributes($event)
  85. {
  86. if (!empty($this->attributes[$event->name])) {
  87. $attributes = (array) $this->attributes[$event->name];
  88. $value = $this->getValue($event);
  89. foreach ($attributes as $attribute) {
  90. // ignore attribute names which are not string (e.g. when set by TimestampBehavior::updatedAtAttribute)
  91. if (is_string($attribute)) {
  92. $this->owner->$attribute = $value;
  93. }
  94. }
  95. }
  96. }
  97. /**
  98. * Returns the value of the current attributes.
  99. * This method is called by [[evaluateAttributes()]]. Its return value will be assigned
  100. * to the attributes corresponding to the triggering event.
  101. * @param Event $event the event that triggers the current attribute updating.
  102. * @return mixed the attribute value
  103. */
  104. protected function getValue($event)
  105. {
  106. return $this->value instanceof Closure ? call_user_func($this->value, $event) : $this->value;
  107. }
  108. }