Passed
Push — master ( 36e11f...247cd1 )
by Jean-Christophe
01:24
created

DAORelationsTrait::setToMember()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

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