Passed
Push — master ( 9b7ff5...a0d60e )
by Jean-Christophe
10:08
created

DAORelationsTrait::getToManyFields()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 4
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 3

Importance

Changes 0
Metric Value
eloc 3
dl 0
loc 4
ccs 4
cts 4
cp 1
rs 10
c 0
b 0
f 0
cc 3
nc 3
nop 2
crap 3
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\parser\Reflexion;
9
use Ubiquity\db\Database;
10
use Ubiquity\log\Logger;
11
use Ubiquity\db\SqlUtils;
12
13
/**
14
 *
15
 * @author jc
16
 * @property \Ubiquity\db\Database $db
17
 */
18
trait DAORelationsTrait {
19
20
	abstract protected static function _getAll(Database $db, $className, ConditionParser $conditionParser, $included = true, $useCache = NULL);
21
22 23
	private static function generateManyToManyParser(ManyToManyParser $parser, &$myPkValues) {
23 23
		$sql = $parser->generateConcatSQL ();
24 23
		$result = self::getDb ( $parser->getTargetEntityClass () )->prepareAndFetchAll ( $sql, $parser->getWhereValues () );
25 23
		$condition = $parser->getParserWhereMask ( " ?" );
26 23
		$cParser = new ConditionParser ();
27 23
		foreach ( $result as $row ) {
28 23
			$values = explode ( ",", $row ["_concat"] );
29 23
			$myPkValues [$row ["_field"]] = $values;
30 23
			$cParser->addParts ( $condition, $values );
31
		}
32 23
		$cParser->compileParts ();
33 23
		return $cParser;
34
	}
35
36 5
	private static function _getIncludedNext($included, $member) {
37 5
		return (isset ( $included [$member] )) ? (\is_bool ( $included [$member] ) ? $included [$member] : [ $included [$member] ]) : false;
38
	}
39
40 23
	private static function getManyToManyFromArrayIds($objectClass, $relationObjects, $ids) {
41 23
		$ret = [ ];
42 23
		$prop = OrmUtils::getFirstPropKey ( $objectClass );
43 23
		foreach ( $relationObjects as $targetEntityInstance ) {
44 23
			$id = Reflexion::getPropValue ( $targetEntityInstance, $prop );
45 23
			if (\array_search ( $id, $ids ) !== false) {
46 23
				\array_push ( $ret, $targetEntityInstance );
47
			}
48
		}
49 23
		return $ret;
50
	}
51
52 61
	protected static function getIncludedForStep($included) {
53 61
		if (\is_bool ( $included )) {
54 61
			return $included;
55
		}
56 7
		$ret = [ ];
57 7
		if (\is_array ( $included )) {
58 7
			foreach ( $included as &$includedMember ) {
59 7
				if (\is_array ( $includedMember )) {
60
					foreach ( $includedMember as $iMember ) {
61
						self::parseEncludeMember ( $ret, $iMember );
62
					}
63
				} else {
64 7
					self::parseEncludeMember ( $ret, $includedMember );
65
				}
66
			}
67
		}
68 7
		return $ret;
69
	}
70
71 7
	private static function parseEncludeMember(&$ret, $includedMember) {
72 7
		$array = \explode ( ".", $includedMember );
73 7
		$member = \array_shift ( $array );
74 7
		if (\sizeof ( $array ) > 0) {
75
			$newValue = \implode ( ".", $array );
76
			if ($newValue === '*') {
77
				$newValue = true;
78
			}
79
			if (isset ( $ret [$member] )) {
80
				if (! \is_array ( $ret [$member] )) {
81
					$ret [$member] = [ $ret [$member] ];
82
				}
83
				$ret [$member] [] = $newValue;
84
			} else {
85
				$ret [$member] = $newValue;
86
			}
87
		} else {
88 7
			if (isset ( $member ) && "" != $member) {
89 7
				$ret [$member] = false;
90
			} else {
91
				return;
92
			}
93
		}
94 7
	}
95
96 3
	private static function getInvertedJoinColumns($included, &$invertedJoinColumns) {
97 3
		foreach ( $invertedJoinColumns as $column => &$annot ) {
98 3
			$member = $annot ["member"];
99 3
			if (isset ( $included [$member] ) === false) {
100 3
				unset ( $invertedJoinColumns [$column] );
101
			}
102
		}
103 3
	}
104
105 7
	private static function getToManyFields($included, &$toManyFields) {
106 7
		foreach ( $toManyFields as $member => $annotNotUsed ) {
107 7
			if (isset ( $included [$member] ) === false) {
108 7
				unset ( $toManyFields [$member] );
109
			}
110
		}
111 7
	}
112
113 45
	protected static function _initRelationFields($included, $metaDatas, &$invertedJoinColumns, &$oneToManyFields, &$manyToManyFields) {
114 45
		if (isset ( $metaDatas ["#invertedJoinColumn"] )) {
115 26
			$invertedJoinColumns = $metaDatas ["#invertedJoinColumn"];
116
		}
117 45
		if (isset ( $metaDatas ["#oneToMany"] )) {
118 40
			$oneToManyFields = $metaDatas ["#oneToMany"];
119
		}
120 45
		if (isset ( $metaDatas ["#manyToMany"] )) {
121 23
			$manyToManyFields = $metaDatas ["#manyToMany"];
122
		}
123 45
		if (\is_array ( $included )) {
124 7
			if (isset ( $invertedJoinColumns )) {
125 3
				self::getInvertedJoinColumns ( $included, $invertedJoinColumns );
126
			}
127 7
			if (isset ( $oneToManyFields )) {
128 7
				self::getToManyFields ( $included, $oneToManyFields );
129
			}
130 7
			if (isset ( $manyToManyFields )) {
131 3
				self::getToManyFields ( $included, $manyToManyFields );
132
			}
133
		}
134 45
	}
135
136
	private static function getManyToManyFromArray($instance, $array, $class, $parser) {
137
		$ret = [ ];
138
		$continue = true;
139
		$accessorToMember = "get" . \ucfirst ( $parser->getInversedBy () );
140
		$myPkAccessor = "get" . \ucfirst ( $parser->getMyPk () );
141
		$pk = self::getFirstKeyValue_ ( $instance );
142
143
		if (sizeof ( $array ) > 0) {
144
			$continue = \method_exists ( current ( $array ), $accessorToMember );
145
		}
146
		if ($continue) {
147
			foreach ( $array as $targetEntityInstance ) {
148
				$instances = $targetEntityInstance->$accessorToMember ();
149
				if (is_array ( $instances )) {
150
					foreach ( $instances as $inst ) {
151
						if ($inst->$myPkAccessor () == $pk)
152
							\array_push ( $ret, $targetEntityInstance );
153
					}
154
				}
155
			}
156
		} else {
157
			Logger::warn ( "DAO", "L'accesseur au membre " . $parser->getInversedBy () . " est manquant pour " . $parser->getTargetEntity (), "ManyToMany" );
158
		}
159
		return $ret;
160
	}
161
162
	/**
163
	 * Loads member associated with $instance by a ManyToOne relationship
164
	 *
165
	 * @param object|array $instance The instance object or an array with [classname,id]
166
	 * @param string $member The member to load
167
	 * @param boolean|array $included if true, loads associate members with associations, if array, example : ["client.*","commands"]
168
	 * @param boolean|null $useCache
169
	 */
170 4
	public static function getManyToOne($instance, $member, $included = false, $useCache = NULL) {
171 4
		$classname = self::getClass_ ( $instance );
172 4
		if (is_array ( $instance )) {
173 1
			$instance = self::getById ( $classname, $instance [1], false, $useCache );
174
		}
175 4
		$fieldAnnot = OrmUtils::getMemberJoinColumns ( $classname, $member );
176 4
		if ($fieldAnnot !== null) {
177 4
			$annotationArray = $fieldAnnot [1];
178 4
			$member = $annotationArray ["member"];
179 4
			$value = Reflexion::getMemberValue ( $instance, $member );
180 4
			$key = OrmUtils::getFirstKey ( $annotationArray ["className"] );
181 4
			$kv = array ($key => $value );
182 4
			$obj = self::getById ( $annotationArray ["className"], $kv, $included, $useCache );
183 4
			if ($obj !== null) {
184 4
				Logger::info ( "DAO", "Loading the member " . $member . " for the object " . $classname, "getManyToOne" );
185 4
				$accesseur = "set" . ucfirst ( $member );
186 4
				if (\is_object ( $instance ) && \method_exists ( $instance, $accesseur )) {
187 4
					$instance->$accesseur ( $obj );
188 4
					$instance->_rest [$member] = $obj->_rest;
189
				}
190 4
				return $obj;
191
			}
192
		}
193
	}
194
195
	/**
196
	 * Assign / load the child records in the $member member of $instance.
197
	 *
198
	 * @param object|array $instance The instance object or an array with [classname,id]
199
	 * @param string $member Member on which a oneToMany annotation must be present
200
	 * @param boolean|array $included if true, loads associate members with associations, if array, example : ["client.*","commands"]
201
	 * @param boolean $useCache
202
	 * @param array $annot used internally
203
	 */
204 7
	public static function getOneToMany($instance, $member, $included = true, $useCache = NULL, $annot = null) {
205 7
		$ret = array ();
206 7
		$class = self::getClass_ ( $instance );
207 7
		if (! isset ( $annot )) {
208 7
			$annot = OrmUtils::getAnnotationInfoMember ( $class, "#oneToMany", $member );
209
		}
210 7
		if ($annot !== false) {
211 7
			$fkAnnot = OrmUtils::getAnnotationInfoMember ( $annot ["className"], "#joinColumn", $annot ["mappedBy"] );
212 7
			if ($fkAnnot !== false) {
213 7
				$fkv = self::getFirstKeyValue_ ( $instance );
214 7
				$db = self::getDb ( $annot ["className"] );
215 7
				$ret = self::_getAll ( $db, $annot ["className"], ConditionParser::simple ( $db->quote . $fkAnnot ["name"] . $db->quote . "= ?", $fkv ), $included, $useCache );
216 7
				if (is_object ( $instance ) && $modifier = self::getAccessor ( $member, $instance, 'getOneToMany' )) {
217 6
					self::setToMember ( $member, $instance, $ret, $modifier );
218
				}
219
			}
220
		}
221 7
		return $ret;
222
	}
223
224
	/**
225
	 * Assigns / loads the child records in the $member member of $instance.
226
	 * If $array is null, the records are loaded from the database
227
	 *
228
	 * @param object|array $instance The instance object or an array with [classname,id]
229
	 * @param string $member Member on which a ManyToMany annotation must be present
230
	 * @param boolean|array $included if true, loads associate members with associations, if array, example : ["client.*","commands"]
231
	 * @param array $array optional parameter containing the list of possible child records
232
	 * @param boolean $useCache
233
	 */
234 4
	public static function getManyToMany($instance, $member, $included = false, $array = null, $useCache = NULL) {
235 4
		$ret = [ ];
236 4
		$class = self::getClass_ ( $instance );
237 4
		$parser = new ManyToManyParser ( $class, $member );
238 4
		if ($parser->init ()) {
239 4
			if (\is_null ( $array )) {
240 4
				$pk = self::getFirstKeyValue_ ( $instance );
241 4
				$quote = SqlUtils::$quote;
242 4
				$condition = " INNER JOIN " . $quote . $parser->getJoinTable () . $quote . " on " . $quote . $parser->getJoinTable () . $quote . "." . $quote . $parser->getFkField () . $quote . "=" . $quote . $parser->getTargetEntityTable () . $quote . "." . $quote . $parser->getPk () . $quote . " WHERE " . $quote . $parser->getJoinTable () . $quote . "." . $quote . $parser->getMyFkField () . $quote . "= ?";
243 4
				$targetEntityClass = $parser->getTargetEntityClass ();
244 4
				$ret = self::_getAll ( self::getDb ( $targetEntityClass ), $targetEntityClass, ConditionParser::simple ( $condition, $pk ), $included, $useCache );
245
			} else {
246
				$ret = self::getManyToManyFromArray ( $instance, $array, $class, $parser );
247
			}
248 4
			if (\is_object ( $instance ) && $modifier = self::getAccessor ( $member, $instance, 'getManyToMany' )) {
249 3
				self::setToMember ( $member, $instance, $ret, $modifier );
250
			}
251
		}
252 4
		return $ret;
253
	}
254
255
	/**
256
	 *
257
	 * @param object $instance
258
	 * @param array $array
259
	 * @param boolean $useCache
260
	 */
261
	public static function affectsManyToManys($instance, $array = NULL, $useCache = NULL) {
262
		$metaDatas = OrmUtils::getModelMetadata ( \get_class ( $instance ) );
263
		$manyToManyFields = $metaDatas ["#manyToMany"];
264
		if (\sizeof ( $manyToManyFields ) > 0) {
265
			foreach ( $manyToManyFields as $member ) {
266
				self::getManyToMany ( $instance, $member, false, $array, $useCache );
267
			}
268
		}
269
	}
270
}
271