Skip to content

Commit cddf89b

Browse files
authored
Merge pull request #319 from execut/adding-value-preparer
Added support prepare values of attributes with same name as the relation
2 parents 83e76bd + 1442258 commit cddf89b

File tree

9 files changed

+250
-30
lines changed

9 files changed

+250
-30
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ Yii2 multiple input change log
44
2.22.0 (in development)
55
=======================
66
- Ignore dev files in zip distribution (sup-ham)
7+
- #292 Fixed tests for last PHPUnit
8+
- Added support prepare values of attributes with same name as the relation
79

810
2.21.4
911
======

src/components/BaseColumn.php

Lines changed: 2 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -248,37 +248,13 @@ protected function prepareValue($contextParams = [])
248248
if ($this->value instanceof \Closure) {
249249
$value = call_user_func($this->value, $data, $contextParams);
250250
} else {
251-
$value = null;
252-
if ($data instanceof ActiveRecordInterface ) {
253-
$relation = $data->getRelation($this->name, false);
254-
if ($relation !== null) {
255-
$value = $relation->findFor($this->name, $data);
256-
} elseif ($data->hasAttribute($this->name)) {
257-
$value = $data->getAttribute($this->name);
258-
} else {
259-
$value = $data->{$this->name};
260-
}
261-
} elseif ($data instanceof Model) {
262-
$value = $data->{$this->name};
263-
} elseif (is_array($data)) {
264-
$value = ArrayHelper::getValue($data, $this->name, null);
265-
} elseif(is_string($data) || is_numeric($data)) {
266-
$value = $data;
267-
}
268-
269-
if ($this->defaultValue !== null && $this->isEmpty($value)) {
270-
$value = $this->defaultValue;
271-
}
251+
$valuePreparer = new ValuePreparer($this->name, $this->defaultValue);
252+
$value = $valuePreparer->prepare($data);
272253
}
273254

274255
return $value;
275256
}
276257

277-
protected function isEmpty($value)
278-
{
279-
return $value === null || $value === [] || $value === '';
280-
}
281-
282258
/**
283259
* Returns element id.
284260
*

src/components/ValuePreparer.php

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
<?php
2+
3+
/**
4+
* @link https://github.com/unclead/yii2-multiple-input
5+
* @copyright Copyright (c) 2014 unclead
6+
* @license https://github.com/unclead/yii2-multiple-input/blob/master/LICENSE.md
7+
*/
8+
9+
namespace unclead\multipleinput\components;
10+
11+
12+
use yii\base\Model;
13+
use yii\db\ActiveRecordInterface;
14+
use yii\helpers\ArrayHelper;
15+
16+
/**
17+
* Class ValuePreparer.
18+
*
19+
* @package unclead\multipleinput\components
20+
*/
21+
class ValuePreparer
22+
{
23+
/**
24+
* @var string Key of prepared attribute
25+
*/
26+
protected $name = null;
27+
28+
/**
29+
* @var mixed default value
30+
*/
31+
protected $defaultValue = null;
32+
33+
/**
34+
* ValuePreparer constructor.
35+
* @param string|null $name
36+
* @param mixed|null $defaultValue
37+
*/
38+
public function __construct($name = null, $defaultValue = null)
39+
{
40+
$this->name = $name;
41+
$this->defaultValue = $defaultValue;
42+
}
43+
44+
/**
45+
* @param $data Prepared data
46+
*
47+
* @return int|mixed|null|string
48+
*/
49+
public function prepare($data)
50+
{
51+
$value = null;
52+
if ($data instanceof ActiveRecordInterface) {
53+
if ($data->canGetProperty($this->name)) {
54+
$value = $data->{$this->name};
55+
} else {
56+
$relation = $data->getRelation($this->name, false);
57+
if ($relation !== null) {
58+
$value = $relation->findFor($this->name, $data);
59+
} else {
60+
$value = $data->{$this->name};
61+
}
62+
}
63+
} elseif ($data instanceof Model) {
64+
$value = $data->{$this->name};
65+
} elseif (is_array($data)) {
66+
$value = ArrayHelper::getValue($data, $this->name, null);
67+
} elseif(is_string($data) || is_numeric($data)) {
68+
$value = $data;
69+
}
70+
71+
if ($this->defaultValue !== null && $this->isEmpty($value)) {
72+
$value = $this->defaultValue;
73+
}
74+
75+
return $value;
76+
}
77+
78+
protected function isEmpty($value)
79+
{
80+
return $value === null || $value === [] || $value === '';
81+
}
82+
}

tests/unit/MultipleInputTest.php

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,18 +28,22 @@ public function testGuessColumn()
2828
$this->assertEquals($expected, $widget->columns);
2929
}
3030

31-
public function testGlobalErrorGuessColumn()
31+
public function testEnableGuessTitleInsideGuessColumn()
3232
{
3333
$model = new TestModel();
3434

3535
$widget = new MultipleInput([
3636
'model' => $model,
3737
'attribute' => 'email',
38-
'enableError' => true,
38+
'enableGuessTitle' => true,
3939
]);
4040

4141
$expected = [
42-
['name' => 'email', 'type' => MultipleInputColumn::TYPE_TEXT_INPUT, 'enableError' => true]
42+
[
43+
'name' => 'email',
44+
'type' => MultipleInputColumn::TYPE_TEXT_INPUT,
45+
'title' => 'Email',
46+
]
4347
];
4448

4549
$this->assertEquals($expected, $widget->columns);

tests/unit/TestCase.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
namespace unclead\multipleinput\tests\unit;
44

55

6-
abstract class TestCase extends \PHPUnit_Framework_TestCase
6+
abstract class TestCase extends \PHPUnit\Framework\TestCase
77
{
88

99
}
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
<?php
2+
namespace unclead\multipleinput\tests\unit\components;
3+
4+
use unclead\multipleinput\components\ValuePreparer;
5+
use unclead\multipleinput\tests\unit\data\TestActiveRecord;
6+
use unclead\multipleinput\tests\unit\data\TestActiveRecordRelated;
7+
use unclead\multipleinput\tests\unit\data\TestModel;
8+
use unclead\multipleinput\tests\unit\TestCase;
9+
use yii\db\ActiveQuery;
10+
11+
class ValuePreparerTest extends TestCase
12+
{
13+
public function testPrepareWithEmptyValue() {
14+
$model = new TestModel();
15+
$defaultValue = 1;
16+
$preparer = new ValuePreparer(null, $defaultValue);
17+
$this->assertEquals($defaultValue, $preparer->prepare(null));
18+
$this->assertEquals($defaultValue, $preparer->prepare([]));
19+
$this->assertEquals($defaultValue, $preparer->prepare(''));
20+
}
21+
22+
public function testPrepareStringOrNumber() {
23+
$model = new TestModel();
24+
$preparer = new ValuePreparer();
25+
$this->assertEquals(1, $preparer->prepare(1));
26+
$this->assertEquals('1', $preparer->prepare('1'));
27+
}
28+
29+
public function testPrepareArrayKey() {
30+
$model = new TestModel();
31+
$preparer = new ValuePreparer('test');
32+
$this->assertEquals(1, $preparer->prepare([
33+
'test' => 1
34+
]));
35+
}
36+
37+
public function testPrepareModelAttribute() {
38+
$model = new TestModel();
39+
$exprectedValue = [
40+
'test'
41+
];
42+
$model->email = $exprectedValue;
43+
$preparer = new ValuePreparer('email');
44+
$this->assertEquals($exprectedValue, $preparer->prepare($model));
45+
}
46+
47+
public function testPrepareActiveRecordDirectAttribute() {
48+
$model = new TestActiveRecord();
49+
$exprectedValue = 'test';
50+
$model->email = $exprectedValue;
51+
$preparer = new ValuePreparer('email');
52+
$this->assertEquals($exprectedValue, $preparer->prepare($model));
53+
}
54+
55+
public function testPrepareActiveRecordRelation() {
56+
$relatedModel = new TestActiveRecordRelated();
57+
$model = $this->createMock(TestActiveRecord::class);
58+
$query = $this->createMock(ActiveQuery::class);
59+
$query->expects($this->once())
60+
->method('findFor')
61+
->with('testRelation', $model)
62+
->willReturn($relatedModel);
63+
64+
$model->expects($this->once())
65+
->method('getRelation')
66+
->with('testRelation', false)
67+
->willReturn($query);
68+
69+
$preparer = new ValuePreparer('testRelation');
70+
71+
$result = $preparer->prepare($model);
72+
73+
$this->assertEquals($relatedModel, $result);
74+
}
75+
76+
public function testPrepareActiveRecordRelationWithSameAsAttributeName() {
77+
$model = new TestActiveRecord();
78+
$relatedModel = new TestActiveRecordRelated();
79+
$model->testRelation = $relatedModel;
80+
81+
$preparer = new ValuePreparer( 'testRelation');
82+
$this->assertEquals($relatedModel, $preparer->prepare($model));
83+
}
84+
}

tests/unit/data/TestActiveRecord.php

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<?php
2+
namespace unclead\multipleinput\tests\unit\data;
3+
4+
5+
use yii\db\ActiveRecord;
6+
7+
class TestActiveRecord extends ActiveRecord
8+
{
9+
/**
10+
* @var string
11+
*/
12+
public $email;
13+
public $testRelation = null;
14+
15+
public function rules()
16+
{
17+
return [
18+
['email', 'safe']
19+
];
20+
}
21+
22+
public function attributeLabels()
23+
{
24+
return [
25+
'email' => 'Email',
26+
];
27+
}
28+
29+
public function getTestHasOneRelation() {}
30+
31+
public function attributes()
32+
{
33+
return ['testRelation']; // TODO: Change the autogenerated stub
34+
}
35+
36+
public function getAttribute($name)
37+
{
38+
if ($name === 'testRelation') {
39+
return $this->testRelation;
40+
}
41+
42+
return parent::getAttribute($name);
43+
}
44+
45+
public function getTestRelation() {
46+
return $this->hasOne(TestActiveRecordRelated::class, []);
47+
}
48+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?php
2+
/**
3+
* Created by PhpStorm.
4+
* User: execut
5+
* Date: 12/3/19
6+
* Time: 2:14 PM
7+
*/
8+
9+
namespace unclead\multipleinput\tests\unit\data;
10+
11+
12+
use yii\db\ActiveRecord;
13+
14+
class TestActiveRecordRelated extends ActiveRecord
15+
{
16+
17+
}

tests/unit/data/TestModel.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,11 @@ public function rules()
2121
['email', 'safe']
2222
];
2323
}
24+
25+
public function attributeLabels()
26+
{
27+
return [
28+
'email' => 'Email',
29+
];
30+
}
2431
}

0 commit comments

Comments
 (0)