DAORelationsTrait::affectsManyToManys()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 6
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

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