From 101d771ecf0e506b160f72d0dd780cb28e98c638 Mon Sep 17 00:00:00 2001 From: Klimov Paul Date: Tue, 12 Aug 2014 12:01:23 +0300 Subject: [PATCH] `yii\behaviors\Sluggable::validateSlug()` fixed to respect updating record --- framework/behaviors/SluggableBehavior.php | 34 ++++++++++++------- .../behaviors/SluggableBehaviorTest.php | 6 ++++ 2 files changed, 28 insertions(+), 12 deletions(-) diff --git a/framework/behaviors/SluggableBehavior.php b/framework/behaviors/SluggableBehavior.php index 4391b05f54..91cfbcb509 100644 --- a/framework/behaviors/SluggableBehavior.php +++ b/framework/behaviors/SluggableBehavior.php @@ -7,10 +7,11 @@ namespace yii\behaviors; -use yii\base\DynamicModel; use yii\base\InvalidConfigException; use yii\db\BaseActiveRecord; use yii\helpers\Inflector; +use yii\validators\UniqueValidator; +use Yii; /** * SluggableBehavior automatically fills the specified attribute with a value that can be used a slug in a URL. @@ -82,15 +83,19 @@ class SluggableBehavior extends AttributeBehavior */ public $ensureUnique = false; /** - * @var array configuration for slug uniqueness validator. This configuration should not contain validator name - * and validated attributes - only options in format 'name => value' are allowed. + * @var array configuration for slug uniqueness validator. Parameter 'class' may be omitted - by default + * [[UniqueValidator]] will be used. * For example: + * + * ```php * [ * 'filter' => ['type' => 1, 'status' => 2] * ] - * @see yii\validators\UniqueValidator + * ``` + * + * @see UniqueValidator */ - public $uniqueValidatorConfig = []; + public $uniqueValidator = []; /** * @var callable slug unique value generator. It is used in case [[ensureUnique]] enabled and generated * slug is not unique. This should be a PHP callable with following signature: @@ -179,15 +184,20 @@ class SluggableBehavior extends AttributeBehavior */ private function validateSlug($slug) { - $validator = array_merge( + /* @var $validator UniqueValidator */ + /* @var $model BaseActiveRecord */ + $validator = Yii::createObject(array_merge( [ - ['slug'], - 'unique', - 'targetClass' => get_class($this->owner) + 'class' => UniqueValidator::className() ], - $this->uniqueValidatorConfig - ); - $model = DynamicModel::validateData(compact('slug'), [$validator]); + $this->uniqueValidator + )); + + $model = clone $this->owner; + $model->clearErrors(); + $model->{$this->slugAttribute} = $slug; + + $validator->validateAttribute($model, $this->slugAttribute); return !$model->hasErrors(); } diff --git a/tests/unit/framework/behaviors/SluggableBehaviorTest.php b/tests/unit/framework/behaviors/SluggableBehaviorTest.php index 68da93bdaf..3bd6b7269f 100644 --- a/tests/unit/framework/behaviors/SluggableBehaviorTest.php +++ b/tests/unit/framework/behaviors/SluggableBehaviorTest.php @@ -129,9 +129,15 @@ class SluggableBehaviorTest extends TestCase $model->name = $name; $model->save(); + $model->save(); + $this->assertEquals('test-name', $model->slug); + $model = ActiveRecordSluggableUnique::find()->one(); $model->save(); + $this->assertEquals('test-name', $model->slug); + $model->name = 'test-name'; + $model->save(); $this->assertEquals('test-name', $model->slug); } }