-
Notifications
You must be signed in to change notification settings - Fork 11
/
RelatedConverter.php
117 lines (108 loc) · 3.21 KB
/
RelatedConverter.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
<?php
namespace mdm\converter;
use Yii;
use yii\base\InvalidConfigException;
/**
* RelatedConverter
*
* ~~~
* // attach as behavior
* [
* 'class' => 'mdm\converter\RelatedConverter',
* 'attributes => [
* 'supplierName' => ['supplier', 'name'], // use avaliable relation
* 'branchName' => [[Branch::className(), 'id' => 'branch_id'], 'name'], // use classname
* ]
* ]
*
* // then attribute directly
* $model->supplierName = 'Donquixote Family';
* $model->branchName = 'North Blue';
* ~~~
*
* @property \yii\db\ActiveRecord $owner
*
* @author Misbahul D Munir <[email protected]>
* @since 1.0
*/
class RelatedConverter extends BaseConverter
{
/**
* @var array
*/
private $_relations = [];
/**
* @var boolean
*/
public $cacheValue = true;
/**
* @var array
*/
private static $_values = [];
/**
* @inheritdoc
*/
public function attach($owner)
{
/* @var $owner \yii\db\ActiveRecord */
foreach ($this->attributes as $attribute => $defition) {
list($relation, $field) = $defition;
if (is_string($relation)) {
$r = $owner->getRelation($relation);
$class = $r->modelClass;
$link = $r->link;
} elseif (is_array($relation)) {
$class = $relation[0];
$link = array_slice($relation, 1);
} else {
throw new InvalidConfigException("Invalid attribute definision for \"{$attribute}\"");
}
foreach ($link as $from => $to) {
$this->_relations[$attribute] = [$class, $field, $from];
$this->attributes[$attribute] = $to;
break;
}
}
parent::attach($owner);
}
/**
* @inheritdoc
*/
protected function convertToLogical($value, $attribute)
{
/* @var $class \yii\db\ActiveRecord */
list($class, $field, $key) = $this->_relations[$attribute];
if ($this->cacheValue && isset(self::$_values[$class][$key][$value][$field])) {
return self::$_values[$class][$key][$value][$field];
} else {
$related = $class::findOne([$key => $value]);
if ($related) {
if ($this->cacheValue) {
return self::$_values[$class][$key][$value][$field] = $related->$field;
}
return $related->$field;
}
return null;
}
}
/**
* @inheritdoc
*/
protected function convertToPhysical($value, $attribute)
{
/* @var $class \yii\db\ActiveRecord */
list($class, $field, $key) = $this->_relations[$attribute];
if ($this->cacheValue && isset(self::$_values[$class][$field][$value][$key])) {
return self::$_values[$class][$field][$value][$field];
} else {
$related = $class::findOne([$field => $value]);
if ($related) {
if ($this->cacheValue) {
return self::$_values[$class][$field][$value][$key] = $related->$key;
}
return $related->$key;
}
return null;
}
}
}