Commit 039ed688 by Qiang Xue

Fixes #1301: fixed scenario generation when there are "except" scenarios.

parent 337b1b08
...@@ -165,7 +165,7 @@ class Model extends Component implements IteratorAggregate, ArrayAccess ...@@ -165,7 +165,7 @@ class Model extends Component implements IteratorAggregate, ArrayAccess
* ] * ]
* ~~~ * ~~~
* *
* By default, an active attribute that is considered safe and can be massively assigned. * By default, an active attribute is considered safe and can be massively assigned.
* If an attribute should NOT be massively assigned (thus considered unsafe), * If an attribute should NOT be massively assigned (thus considered unsafe),
* please prefix the attribute with an exclamation character (e.g. '!rank'). * please prefix the attribute with an exclamation character (e.g. '!rank').
* *
...@@ -178,29 +178,48 @@ class Model extends Component implements IteratorAggregate, ArrayAccess ...@@ -178,29 +178,48 @@ class Model extends Component implements IteratorAggregate, ArrayAccess
*/ */
public function scenarios() public function scenarios()
{ {
$scenarios = []; $scenarios = [self::DEFAULT_SCENARIO => []];
$defaults = [];
/** @var $validator Validator */
foreach ($this->getValidators() as $validator) { foreach ($this->getValidators() as $validator) {
if (empty($validator->on)) { foreach ($validator->on as $scenario) {
foreach ($validator->attributes as $attribute) { $scenarios[$scenario] = [];
$defaults[$attribute] = true; }
foreach ($validator->except as $scenario) {
$scenarios[$scenario] = [];
}
}
$names = array_keys($scenarios);
foreach ($this->getValidators() as $validator) {
if (empty($validator->on) && empty($validator->except)) {
foreach ($names as $name) {
foreach ($validator->attributes as $attribute) {
$scenarios[$name][$attribute] = true;
}
}
} elseif (empty($validator->on)) {
foreach ($names as $name) {
if (!in_array($name, $validator->except, true)) {
foreach ($validator->attributes as $attribute) {
$scenarios[$name][$attribute] = true;
}
}
} }
} else { } else {
foreach ($validator->on as $scenario) { foreach ($validator->on as $name) {
foreach ($validator->attributes as $attribute) { foreach ($validator->attributes as $attribute) {
$scenarios[$scenario][$attribute] = true; $scenarios[$name][$attribute] = true;
} }
} }
} }
} }
foreach ($scenarios as $scenario => $attributes) { foreach ($scenarios as $scenario => $attributes) {
foreach (array_keys($defaults) as $attribute) { if (empty($attributes)) {
$attributes[$attribute] = true; unset($scenarios[$scenario]);
} else {
$scenarios[$scenario] = array_keys($attributes);
} }
$scenarios[$scenario] = array_keys($attributes);
} }
$scenarios[self::DEFAULT_SCENARIO] = array_keys($defaults);
return $scenarios; return $scenarios;
} }
......
...@@ -217,6 +217,20 @@ class ModelTest extends TestCase ...@@ -217,6 +217,20 @@ class ModelTest extends TestCase
{ {
$singer = new Singer(); $singer = new Singer();
$this->assertEquals(['default' => ['lastName', 'underscore_style']], $singer->scenarios()); $this->assertEquals(['default' => ['lastName', 'underscore_style']], $singer->scenarios());
$scenarios = [
'default' => ['id', 'name', 'description'],
'administration' => ['name', 'description', 'is_disabled'],
];
$model = new ComplexModel1();
$this->assertEquals($scenarios, $model->scenarios());
$scenarios = [
'default' => ['id', 'name', 'description'],
'suddenlyUnexpectedScenario' => ['name', 'description'],
'administration' => ['id', 'name', 'description', 'is_disabled'],
];
$model = new ComplexModel2();
$this->assertEquals($scenarios, $model->scenarios());
} }
public function testIsAttributeRequired() public function testIsAttributeRequired()
...@@ -234,3 +248,27 @@ class ModelTest extends TestCase ...@@ -234,3 +248,27 @@ class ModelTest extends TestCase
$invalid->createValidators(); $invalid->createValidators();
} }
} }
class ComplexModel1 extends Model
{
public function rules()
{
return [
[['id'], 'required', 'except' => 'administration'],
[['name', 'description'], 'filter', 'filter' => 'trim'],
[['is_disabled'], 'boolean', 'on' => 'administration'],
];
}
}
class ComplexModel2 extends Model
{
public function rules()
{
return [
[['id'], 'required', 'except' => 'suddenlyUnexpectedScenario'],
[['name', 'description'], 'filter', 'filter' => 'trim'],
[['is_disabled'], 'boolean', 'on' => 'administration'],
];
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment