Passed
Push — master ( abe30a...78bb6e )
by Jean-Christophe
01:41
created

DAORelationsTrait::affectsOneToManyFromArray()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 13
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

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