Completed
Push — master ( 303d01...8237e5 )
by Jean-Christophe
02:20
created

DAORelationsTrait::prepareOneToMany()   A

Complexity

Conditions 5
Paths 8

Size

Total Lines 16

Duplication

Lines 16
Ratio 100 %

Importance

Changes 0
Metric Value
dl 16
loc 16
rs 9.4222
c 0
b 0
f 0
cc 5
nc 8
nop 4
1
<?php
2
3
namespace Ubiquity\orm\traits;
4
5
use Ubiquity\orm\OrmUtils;
6
use Ubiquity\orm\parser\ManyToManyParser;
7
use Ubiquity\orm\parser\ConditionParser;
8
use Ubiquity\orm\core\PendingRelationsRequest;
9
10
/**
11
 * @author jc
12
 * @property \Ubiquity\db\Database $db
13
 */
14
trait DAORelationsTrait {
15
	abstract protected static function _getAll($className, ConditionParser $conditionParser, $included=true,$useCache=NULL);
16
	
17
	protected static function _affectsRelationObjects($manyToOneQueries,$oneToManyQueries,$manyToManyParsers,$objects,$included,$useCache){
18
		if(\sizeof($manyToOneQueries)>0){
19
			self::_affectsObjectsFromArray($manyToOneQueries,$included, function($object,$member,$manyToOneObjects,$fkField){
20
				self::affectsManyToOneFromArray($object,$member,$manyToOneObjects,$fkField);
21
			});
22
		}
23
		
24
		if(\sizeof($oneToManyQueries)>0){
25
			self::_affectsObjectsFromArray($oneToManyQueries,$included, function($object,$member,$relationObjects,$fkField){
26
				self::affectsOneToManyFromArray($object,$member,$relationObjects,$fkField);
27
			});
28
		}
29
		
30
		if(\sizeof($manyToManyParsers)>0){
31
			self::_affectsManyToManyObjectsFromArray($manyToManyParsers, $objects,$included,$useCache);
32
		}
33
	}
34
	
35
	private static function affectsManyToOneFromArray($object,$member,$manyToOneObjects,$fkField){
36
		$class=\get_class($object);
37
		if(isset($object->$fkField)){
38
			$value=$manyToOneObjects[$object->$fkField];
39
			self::setToMember($member, $object, $value, $class, "getManyToOne");
40
		}
41
	}
42
	
43
	private static function _affectsObjectsFromArray($queries,$included,$affectsCallback,$useCache=NULL){
44
		$includedNext=false;
45
		foreach ($queries as $key=>$pendingRelationsRequest){
46
			list($class,$member,$fkField)=\explode("|", $key);
47
			if(is_array($included)){
48
				$includedNext=self::_getIncludedNext($included, $member);
49
			}
50
			$objectsParsers=$pendingRelationsRequest->getObjectsConditionParsers();
51
			foreach ($objectsParsers as $objectsConditionParser){
52
				$objectsConditionParser->compileParts();
53
				$relationObjects=self::_getAll($class,$objectsConditionParser->getConditionParser(),$includedNext,$useCache);
54
				$objects=$objectsConditionParser->getObjects();
55
				foreach ($objects as $object){
56
					$affectsCallback($object, $member,$relationObjects,$fkField);
57
				}
58
			}
59
		}
60
	}
61
	
62
	private static function _affectsManyToManyObjectsFromArray($parsers,$objects,$included,$useCache=NULL){
63
		$includedNext=false;
64
		foreach ($parsers as $key=>$parser){
65
			list($class,$member)=\explode("|", $key);
66
			if(is_array($included)){
67
				$includedNext=self::_getIncludedNext($included, $member);
68
			}
69
			$myPkValues=[];
70
			$cParser=self::generateManyToManyParser($parser, $myPkValues);
71
			$relationObjects=self::_getAll($class,$cParser,$includedNext,$useCache);
72
			$oClass=get_class(reset($objects));
73
			foreach ($objects as $object){
74
				$pkV=OrmUtils::getFirstKeyValue($object);
75
				if(isset($myPkValues[$pkV])){
76
					$ret=self::getManyToManyFromArrayIds($relationObjects, $myPkValues[$pkV]);
77
					self::setToMember($member, $object, $ret, $oClass, "getManyToMany");
78
				}
79
			}
80
		}
81
	}
82
	
83
	private static function generateManyToManyParser(ManyToManyParser $parser,&$myPkValues){
84
		$sql=$parser->generateConcatSQL();
85
		$result=self::$db->prepareAndFetchAll($sql,$parser->getWhereValues());
86
		$condition=$parser->getParserWhereMask(" ?");
87
		$cParser=new ConditionParser();
88
		
89
		foreach ($result as $row){
90
			$values=explode(",", $row["_concat"]);
91
			$myPkValues[$row["_field"]]=$values;
92
			$cParser->addParts($condition, $values);
93
		}
94
		$cParser->compileParts();
95
		return $cParser;
96
	}
97
	
98
	private static function _getIncludedNext($included,$member){
99
		return (isset($included[$member]))?(is_bool($included[$member])?$included[$member]:[$included[$member]]):false;
100
	}
101
	
102
	
103
	
104
	private static function getManyToManyFromArrayIds($relationObjects, $ids){
105
		$ret=[];
106
		foreach ( $relationObjects as $targetEntityInstance ) {
107
			$id=OrmUtils::getFirstKeyValue($targetEntityInstance);
108
			if (array_search($id, $ids)!==false) {
109
				array_push($ret, $targetEntityInstance);
110
			}
111
		}
112
		return $ret;
113
	}
114
	
115
	protected static function getIncludedForStep($included){
116
		if(is_bool($included)){
117
			return $included;
118
		}
119
		$ret=[];
120
		if(is_array($included)){
121
			foreach ($included as &$includedMember){
122
				if(is_array($includedMember)){
123
					foreach ($includedMember as $iMember){
124
						self::parseEncludeMember($ret, $iMember);
125
					}
126
				}else{
127
					self::parseEncludeMember($ret, $includedMember);
128
				}
129
			}
130
		}
131
		
132
		return $ret;
133
	}
134
	
135
	private static function parseEncludeMember(&$ret,$includedMember){
136
		$array=explode(".", $includedMember);
137
		$member=array_shift($array);
138
		if(sizeof($array)>0){
139
			$newValue=implode(".", $array);
140
			if($newValue==='*'){
141
				$newValue=true;
142
			}
143
			if(isset($ret[$member])){
144
				if(!is_array($ret[$member])){
145
					$ret[$member]=[$ret[$member]];
146
				}
147
				$ret[$member][]=$newValue;
148
			}else{
149
				$ret[$member]=$newValue;
150
			}
151
		}else{
152
			if(isset($member) && ""!=$member){
153
				$ret[$member]=false;
154
			}else{
155
				return;
156
			}
157
		}
158
	}
159
	
160
	private static function getInvertedJoinColumns($included,&$invertedJoinColumns){
161
		foreach ($invertedJoinColumns as $column=>&$annot){
162
			$member=$annot["member"];
163
			if(isset($included[$member])===false){
164
				unset($invertedJoinColumns[$column]);
165
			}
166
		}
167
	}
168
	
169
	private static function getToManyFields($included,&$toManyFields){
170
		foreach ($toManyFields as $member=>$annotNotUsed){
171
			if(isset($included[$member])===false){
172
				unset($toManyFields[$member]);
173
			}
174
		}
175
	}
176
	
177
	protected static function _initRelationFields($included,$metaDatas,&$invertedJoinColumns,&$oneToManyFields,&$manyToManyFields){
178
		if (isset($metaDatas["#invertedJoinColumn"])){
179
			$invertedJoinColumns=$metaDatas["#invertedJoinColumn"];
180
		}
181
		if (isset($metaDatas["#oneToMany"])) {
182
			$oneToManyFields=$metaDatas["#oneToMany"];
183
		}
184
		if (isset($metaDatas["#manyToMany"])) {
185
			$manyToManyFields=$metaDatas["#manyToMany"];
186
		}
187
		if(is_array($included)){
188
			if(isset($invertedJoinColumns)){
189
				self::getInvertedJoinColumns($included, $invertedJoinColumns);
190
			}
191
			if(isset($oneToManyFields)){
192
				self::getToManyFields($included, $oneToManyFields);
193
			}
194
			if(isset($manyToManyFields)){
195
				self::getToManyFields($included, $manyToManyFields);
196
			}
197
		}
198
	}
199
}
200