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
118
119
120
121
122
123
124
|
<?php
abstract class TActiveRecordRelation
{
}
class TActiveRecordHasMany extends TActiveRecordRelation
{
private $source;
private $dependent;
private $property;
private $criteria;
private $fkeys;
public function __construct($source,$criteria,$dependent,$property)
{
$this->source=$source;
$this->criteria=$criteria;
$this->dependent=$dependent;
$this->property=$property;
}
public function __call($method,$args)
{
$results = call_user_func_array(array($this->source,$method),$args);
$fkResults = $this->getForeignIndexResults($results);
$this->matchResultCollection($results,$fkResults);
return $results;
}
protected function getForeignIndexResults($results)
{
if(!is_array($results))
$results = array($results);
$fkeys = $this->getForeignKeys();
$values = $this->getForeignKeyIndices($results, $fkeys);
$fields = array_keys($fkeys);
return $this->dependent->findAllByIndex($this->criteria, $fields, $values);
}
protected function matchResultCollection(&$results,&$fkResults)
{
$keys = $this->getForeignKeys();
$collections=array();
foreach($fkResults as $fkObject)
{
$objId=array();
foreach($keys as $fkName=>$name)
$objId[] = $fkObject->{$fkName};
$collections[$this->getObjectId($objId)][]=$fkObject;
}
if(is_array($results))
{
for($i=0,$k=count($results);$i<$k;$i++)
{
$this->setFkObjectProperty($results[$i], $collections);
}
}
else
{
$this->setFkObjectProperty($results, $collections);
}
}
function setFKObjectProperty($source, &$collections)
{
$objId=array();
foreach($this->getForeignKeys() as $fkName=>$name)
$objId[] = $source->{$name};
$key = $this->getObjectId($objId);
$source->{$this->property} = isset($collections[$key]) ? $collections[$key] : array();
}
protected function getObjectId($objId)
{
return sprintf('%x',crc32(serialize($objId)));
}
protected function getForeignKeys()
{
if($this->fkeys===null)
{
$gateway = $this->dependent->getRecordGateway();
$depTableInfo = $gateway->getRecordTableInfo($this->dependent);
$fks = $depTableInfo->getForeignKeys();
$sourceTable = $gateway->getRecordTableInfo($this->source)->getTableName();
foreach($fks as $relation)
{
if($relation['table']===$sourceTable)
{
$this->fkeys=$relation['keys'];
break;
}
}
if(!$this->fkeys)
throw new TActiveRecordException('no fk defined for '.$depTableInfo->getTableFullName());
}
return $this->fkeys;
}
protected function getForeignKeyIndices($results,$keys)
{
$values = array();
foreach($results as $result)
{
$value = array();
foreach($keys as $name)
$value[] = $result->{$name};
$values[] = $value;
}
return $values;
}
}
class TActiveRecordHasOne extends TActiveRecordRelation
{
}
class TActiveRecordBelongsTo extends TActiveRecordRelation
{
}
?>
|