From 5ebf98cc1deaa98c7e0f9a7a9fc812eb09fc6759 Mon Sep 17 00:00:00 2001 From: Dmitry Dorogin Date: Sat, 25 Nov 2017 15:39:17 +0300 Subject: [PATCH] Fixes #5515: Added default value for `yii\behaviors\BlameableBehavior` for cases when the user is guest --- framework/CHANGELOG.md | 1 + framework/behaviors/AttributeBehavior.php | 2 +- framework/behaviors/BlameableBehavior.php | 29 +++++++++++++- .../framework/behaviors/BlameableBehaviorTest.php | 46 ++++++++++++++++++++++ 4 files changed, 75 insertions(+), 3 deletions(-) diff --git a/framework/CHANGELOG.md b/framework/CHANGELOG.md index c97c943..204a08c 100644 --- a/framework/CHANGELOG.md +++ b/framework/CHANGELOG.md @@ -4,6 +4,7 @@ Yii Framework 2 Change Log 2.0.14 under development ------------------------ +- Enh #5515: Added default value for `yii\behaviors\BlameableBehavior` for cases when the user is guest (dmirogin) - Bug #14276: Fixed I18N format with dotted parameters (developeruz) - Bug #14604: Fixed `yii\validators\CompareValidator` `compareAttribute` does not work if `compareAttribute` form ID has been changed (mikk150) - Bug #15194: Fixed `yii\db\QueryBuilder::insert()` to preserve passed params when building a `INSERT INTO ... SELECT` query for MSSQL, PostgreSQL and SQLite (sergeymakinen) diff --git a/framework/behaviors/AttributeBehavior.php b/framework/behaviors/AttributeBehavior.php index 89c1ba3..cc82b1b 100644 --- a/framework/behaviors/AttributeBehavior.php +++ b/framework/behaviors/AttributeBehavior.php @@ -140,7 +140,7 @@ class AttributeBehavior extends Behavior */ protected function getValue($event) { - if ($this->value instanceof Closure || is_array($this->value) && is_callable($this->value)) { + if ($this->value instanceof Closure || (is_array($this->value) && is_callable($this->value))) { return call_user_func($this->value, $event); } diff --git a/framework/behaviors/BlameableBehavior.php b/framework/behaviors/BlameableBehavior.php index 95e0796..9ce1899 100644 --- a/framework/behaviors/BlameableBehavior.php +++ b/framework/behaviors/BlameableBehavior.php @@ -73,6 +73,11 @@ class BlameableBehavior extends AttributeBehavior */ public $value; + /** + * @var mixed Default value for cases when the user is guest + * @since 2.0.14 + */ + public $defaultValue; /** * @inheritdoc @@ -92,14 +97,34 @@ class BlameableBehavior extends AttributeBehavior /** * @inheritdoc * - * In case, when the [[value]] property is `null`, the value of `Yii::$app->user->id` will be used as the value. + * In case, when the [[value]] property is `null`, the value of [[defaultValue]] will be used as the value. */ protected function getValue($event) { if ($this->value === null && Yii::$app->has('user')) { - return Yii::$app->get('user')->id; + $userId = Yii::$app->get('user')->id; + if ($userId === null) { + return $this->getDefaultValue($event); + } + + return $userId; } return parent::getValue($event); } + + /** + * Get default value + * @param \yii\base\Event $event + * @return array|mixed + * @since 2.0.14 + */ + protected function getDefaultValue($event) + { + if ($this->defaultValue instanceof \Closure || (is_array($this->defaultValue) && is_callable($this->defaultValue))) { + return call_user_func($this->defaultValue, $event); + } + + return $this->defaultValue; + } } diff --git a/tests/framework/behaviors/BlameableBehaviorTest.php b/tests/framework/behaviors/BlameableBehaviorTest.php index d1556b2..7b54c99 100644 --- a/tests/framework/behaviors/BlameableBehaviorTest.php +++ b/tests/framework/behaviors/BlameableBehaviorTest.php @@ -154,6 +154,52 @@ class BlameableBehaviorTest extends TestCase $this->assertEquals(20, $model->created_by); $this->assertEquals(20, $model->updated_by); } + + public function testDefaultValue() + { + $this->getUser()->logout(); + + $model = new ActiveRecordBlameable([ + 'as blameable' => [ + 'class' => BlameableBehavior::className(), + 'defaultValue' => 2 + ], + ]); + + $model->name = __METHOD__; + $model->beforeSave(true); + + $this->assertEquals(2, $model->created_by); + $this->assertEquals(2, $model->updated_by); + } + + public function testDefaultValueWithClosure() + { + $model = new ActiveRecordBlameableWithDefaultValueClosure(); + $model->name = __METHOD__; + $model->beforeSave(true); + + $this->getUser()->logout(); + $model->beforeSave(true); + + $this->assertEquals(11, $model->created_by); + $this->assertEquals(11, $model->updated_by); + } +} + +class ActiveRecordBlameableWithDefaultValueClosure extends ActiveRecordBlameable +{ + public function behaviors() + { + return [ + 'blameable' => [ + 'class' => BlameableBehavior::className(), + 'defaultValue' => function () { + return $this->created_by + 1; + } + ], + ]; + } } /**