Completed
Push — master ( cbe892...9bd3b4 )
by Jean-Christophe
02:05
created

DAORelationsTrait::generateManyToManyParser()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 14
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 14
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 11
nc 2
nop 2
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
	private static function _affectsRelationObjects($manyToOneQueries,$oneToManyQueries,$manyToManyParsers,$objects,$included,$useCache){
17
		if(\sizeof($manyToOneQueries)>0){
18
			self::_affectsObjectsFromArray($manyToOneQueries, $objects,$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, $objects,$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
	private static function _affectsObjectsFromArray($queries,$objects,$included,$affectsCallback,$useCache=NULL){
43
		$includedNext=false;
44
		foreach ($queries as $key=>$cParser){
45
			list($class,$member,$fkField)=\explode("|", $key);
46
			if(is_array($included)){
47
				$includedNext=self::_getIncludedNext($included, $member);
48
			}
49
			$cParser->compileParts();
50
			$relationObjects=self::_getAll($class,$cParser,$includedNext,$useCache);
51
			foreach ($objects as $object){
52
				$affectsCallback($object, $member,$relationObjects,$fkField);
53
			}
54
		}
55
	}
56
	
57
	private static function _affectsManyToManyObjectsFromArray($parsers,$objects,$included,$useCache=NULL){
58
		$includedNext=false;
59
		foreach ($parsers as $key=>$parser){
60
			list($class,$member,$inversedBy)=\explode("|", $key);
0 ignored issues
show
Unused Code introduced by
The assignment to $inversedBy is unused. Consider omitting it like so list($first,,$third).

This checks looks for assignemnts to variables using the list(...) function, where not all assigned variables are subsequently used.

Consider the following code example.

<?php

function returnThreeValues() {
    return array('a', 'b', 'c');
}

list($a, $b, $c) = returnThreeValues();

print $a . " - " . $c;

Only the variables $a and $c are used. There was no need to assign $b.

Instead, the list call could have been.

list($a,, $c) = returnThreeValues();
Loading history...
61
			if(is_array($included)){
62
				$includedNext=self::_getIncludedNext($included, $member);
63
			}
64
			$myPkValues=[];
65
			$cParser=self::generateManyToManyParser($parser, $myPkValues);
66
			$relationObjects=self::_getAll($class,$cParser,$includedNext,$useCache);
67
			$oClass=get_class(reset($objects));
68
			foreach ($objects as $object){
69
				$pkV=OrmUtils::getFirstKeyValue($object);
70
				if(isset($myPkValues[$pkV])){
71
					$ret=self::getManyToManyFromArrayIds($object, $relationObjects, $myPkValues[$pkV]);
72
					self::setToMember($member, $object, $ret, $oClass, "getManyToMany");
73
				}
74
			}
75
		}
76
	}
77
	
78
	private static function generateManyToManyParser(ManyToManyParser $parser,&$myPkValues){
79
		$sql=$parser->generateConcatSQL();
80
		$result=self::$db->prepareAndFetchAll($sql,$parser->getWhereValues());
81
		$condition=$parser->getParserWhereMask(" ?");
82
		$cParser=new ConditionParser();
83
		
84
		foreach ($result as $row){
85
			$values=explode(",", $row["_concat"]);
86
			$myPkValues[$row["_field"]]=$values;
87
			$cParser->addParts($condition, $values);
88
		}
89
		$cParser->compileParts();
90
		return $cParser;
91
	}
92
	
93
	private static function _getIncludedNext($included,$member){
94
		return (isset($included[$member]))?(is_bool($included[$member])?$included[$member]:[$included[$member]]):false;
95
	}
96
	
97
	
98
	
99
	private static function getManyToManyFromArrayIds($object, $relationObjects, $ids){
0 ignored issues
show
Unused Code introduced by
The parameter $object is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
100
		$ret=[];
101
		foreach ( $relationObjects as $targetEntityInstance ) {
102
			$id=OrmUtils::getFirstKeyValue($targetEntityInstance);
103
			if (array_search($id, $ids)!==false) {
104
				array_push($ret, $targetEntityInstance);
105
			}
106
		}
107
		return $ret;
108
	}
109
	
110
	/**
111
	 * Prepares members associated with $instance with a ManyToMany type relationship
112
	 * @param $ret array of sql conditions
113
	 * @param object $instance
114
	 * @param string $member Member on which a ManyToMany annotation must be present
115
	 * @param array $annot used internally
116
	 */
117
	private static function prepareManyToMany(&$ret,$instance, $member, $annot=null) {
118
		$class=get_class($instance);
119
		if (!isset($annot)){
120
			$annot=OrmUtils::getAnnotationInfoMember($class, "#ManyToMany", $member);
121
		}
122
		if ($annot !== false) {
123
			$key=$annot["targetEntity"]."|".$member."|".$annot["inversedBy"];
124
			if(!isset($ret[$key])){
125
				$parser=new ManyToManyParser($instance, $member);
126
				$parser->init($annot);
127
				$ret[$key]=$parser;
128
			}
129
			$accessor="get" . ucfirst($ret[$key]->getMyPk());
130
			if(method_exists($instance, $accessor)){
131
				$fkv=$instance->$accessor();
132
				$ret[$key]->addValue($fkv);
133
			}
134
		}
135
	}
136
	
137
	/**
138
	 * Prepares members associated with $instance with a oneToMany type relationship
139
	 * @param $ret array of sql conditions
140
	 * @param object $instance
141
	 * @param string $member Member on which a OneToMany annotation must be present
142
	 * @param array $annot used internally
143
	 */
144
	private static function prepareOneToMany(&$ret,$instance, $member, $annot=null) {
145
		$class=get_class($instance);
146
		if (!isset($annot))
147
			$annot=OrmUtils::getAnnotationInfoMember($class, "#oneToMany", $member);
148
			if ($annot !== false) {
149
				$fkAnnot=OrmUtils::getAnnotationInfoMember($annot["className"], "#joinColumn", $annot["mappedBy"]);
150
				if ($fkAnnot !== false) {
151
					$fkv=OrmUtils::getFirstKeyValue($instance);
152
					$key=$annot["className"]."|".$member."|".$annot["mappedBy"];
153
					if(!isset($ret[$key])){
154
						$ret[$key]=new ConditionParser();
155
					}
156
					$ret[$key]->addPart($fkAnnot["name"] . "= ?",$fkv);
157
				}
158
			}
159
	}
160
	
161
	/**
162
	 * Prepares members associated with $instance with a manyToOne type relationship
163
	 * @param $ret array of sql conditions
164
	 * @param mixed $value
165
	 * @param string $fkField
166
	 * @param array $annotationArray
167
	 */
168
	private static function prepareManyToOne(&$ret, $value, $fkField,$annotationArray) {
169
		$member=$annotationArray["member"];
170
		$fk=OrmUtils::getFirstKey($annotationArray["className"]);
171
		$key=$annotationArray["className"]."|".$member."|".$fkField;
172
		if(!isset($ret[$key])){
173
			$ret[$key]=new ConditionParser();
174
		}
175
		$ret[$key]->addPart($fk . "= ?",$value);
176
	}
177
	
178
	private static function getIncludedForStep($included){
179
		if(is_bool($included)){
180
			return $included;
181
		}
182
		$ret=[];
183
		if(is_array($included)){
184
			foreach ($included as $index=>&$includedMember){
185
				if(is_array($includedMember)){
186
					foreach ($includedMember as $iMember){
187
						self::parseEncludeMember($ret, $iMember);
188
					}
189
				}else{
190
					self::parseEncludeMember($ret, $includedMember);
191
				}
192
			}
193
		}
194
		
195
		return $ret;
196
	}
197
	
198
	private static function parseEncludeMember(&$ret,$includedMember){
199
		$array=explode(".", $includedMember);
200
		$member=array_shift($array);
201
		if(sizeof($array)>0){
202
			$newValue=implode(".", $array);
203
			if($newValue==='*'){
204
				$newValue=true;
205
			}
206
			if(isset($ret[$member])){
207
				if(!is_array($ret[$member])){
208
					$ret[$member]=[$ret[$member]];
209
				}
210
				$ret[$member][]=$newValue;
211
			}else{
212
				$ret[$member]=$newValue;
213
			}
214
		}else{
215
			if(isset($member) && ""!=$member){
216
				$ret[$member]=false;
217
			}else{
218
				return;
219
			}
220
		}
221
	}
222
	
223
	private static function getInvertedJoinColumns($included,&$invertedJoinColumns){
224
		foreach ($invertedJoinColumns as $column=>&$annot){
225
			$member=$annot["member"];
226
			if(isset($included[$member])===false){
227
				unset($invertedJoinColumns[$column]);
228
			}
229
		}
230
	}
231
	
232
	private static function getToManyFields($included,&$toManyFields){
233
		foreach ($toManyFields as $member=>&$annot){
234
			if(isset($included[$member])===false){
235
				unset($toManyFields[$member]);
236
			}
237
		}
238
	}
239
	
240
	private static function _initRelationFields($included,$metaDatas,&$invertedJoinColumns,&$oneToManyFields,&$manyToManyFields){
241
		if (isset($metaDatas["#invertedJoinColumn"])){
242
			$invertedJoinColumns=$metaDatas["#invertedJoinColumn"];
243
		}
244
		if (isset($metaDatas["#oneToMany"])) {
245
			$oneToManyFields=$metaDatas["#oneToMany"];
246
		}
247
		if (isset($metaDatas["#manyToMany"])) {
248
			$manyToManyFields=$metaDatas["#manyToMany"];
249
		}
250
		if(is_array($included)){
251
			if(isset($invertedJoinColumns)){
252
				self::getInvertedJoinColumns($included, $invertedJoinColumns);
253
			}
254
			if(isset($oneToManyFields)){
255
				self::getToManyFields($included, $oneToManyFields);
256
			}
257
			if(isset($manyToManyFields)){
258
				self::getToManyFields($included, $manyToManyFields);
259
			}
260
		}
261
	}
262
}
263