summaryrefslogtreecommitdiff
path: root/framework/Data/ActiveRecord/TActiveRecordRelation.php
blob: 6fae5499763a71af748479551b6e57958db2a892 (plain)
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
{

}

?>