Passed
Push — master ( a0d60e...d9c4e6 )
by Jean-Christophe
12:17
created

DAORelationsAssignmentsTrait::_getIncludedNext()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 2
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 3

Importance

Changes 0
Metric Value
eloc 1
c 0
b 0
f 0
dl 0
loc 2
ccs 2
cts 2
cp 1
rs 10
cc 3
nc 4
nop 2
crap 3
1
<?php
2
3
namespace Ubiquity\orm\traits;
4
5
use Ubiquity\orm\OrmUtils;
6
use Ubiquity\log\Logger;
7
use Ubiquity\orm\parser\Reflexion;
8
use Ubiquity\orm\parser\ConditionParser;
9
use Ubiquity\orm\parser\ManyToManyParser;
10
11
/**
12
 * Used by DAO class, realize relations assignments.
13
 * Ubiquity\orm\traits$DAORelationsAssignmentsTrait
14
 * This class is part of Ubiquity
15
 *
16
 * @author jcheron <[email protected]>
17
 * @version 1.0.2
18
 *
19
 */
20
trait DAORelationsAssignmentsTrait {
21
22 48
	protected static function setToMember($member, $instance, $value, $accessor) {
23 48
		$instance->$accessor ( $value );
24 48
		$instance->_rest [$member] = $value;
25 48
	}
26
27 48
	protected static function getAccessor($member, $instance, $part) {
28 48
		$accessor = "set" . ucfirst ( $member );
29 48
		if (method_exists ( $instance, $accessor )) {
30 48
			return $accessor;
31
		}
32
		$class = get_class ( $instance );
33
		Logger::warn ( "DAO", "Missing modifier " . $accessor . " in " . $class, $part );
34
		return false;
35
	}
36
37 45
	protected static function _affectsRelationObjects($className, $classPropKey, $manyToOneQueries, $oneToManyQueries, $manyToManyParsers, $objects, $included, $useCache): void {
38 45
		if (\sizeof ( $manyToOneQueries ) > 0) {
39
			self::_affectsObjectsFromArray ( $manyToOneQueries, $included, function ($object, $member, $manyToOneObjects, $fkField, $accessor) {
40 23
				self::affectsManyToOneFromArray ( $object, $member, $manyToOneObjects, $fkField, $accessor );
41 23
			}, 'getManyToOne' );
42
		}
43 45
		if (\sizeof ( $oneToManyQueries ) > 0) {
44
			self::_affectsObjectsFromArray ( $oneToManyQueries, $included, function ($object, $member, $relationObjects, $fkField, $accessor, $class, $prop) use ($classPropKey) {
45 37
				self::affectsOneToManyFromArray ( $object, $member, $relationObjects, $fkField, $accessor, $class, $prop, $classPropKey );
46 37
			}, 'getOneToMany' );
47
		}
48 45
		if (\sizeof ( $manyToManyParsers ) > 0) {
49 23
			self::_affectsManyToManyObjectsFromArray ( $className, $manyToManyParsers, $objects, $included, $useCache );
50
		}
51 45
	}
52
53 23
	private static function affectsManyToOneFromArray($object, $member, $manyToOneObjects, $fkField, $accessor) {
54 23
		if (isset ( $object->$fkField )) {
55 23
			$value = $manyToOneObjects [$object->$fkField];
56 23
			self::setToMember ( $member, $object, $value, $accessor );
57
		}
58 23
	}
59
60
	/**
61
	 *
62
	 * @param object $instance
63
	 * @param string $member
64
	 * @param array $array
65
	 * @param string $mappedByAccessor
66
	 * @param string $class
67
	 * @param \ReflectionProperty $prop
68
	 */
69 37
	private static function affectsOneToManyFromArray($instance, $member, $array = null, $mappedByAccessor = null, $accessor = "", $class = "", $prop = null, $classPropKey = null) {
70 37
		$ret = [ ];
71 37
		self::_getOneToManyFromArray ( $ret, $array, Reflexion::getPropValue ( $instance, $classPropKey ), $mappedByAccessor, $prop );
72 37
		self::setToMember ( $member, $instance, $ret, $accessor );
73 37
	}
74
75 42
	private static function _affectsObjectsFromArray($queries, $included, $affectsCallback, $part, $useCache = NULL) {
76 42
		$includedNext = false;
77 42
		foreach ( $queries as $key => $pendingRelationsRequest ) {
78 42
			list ( $class, $member, $fkField, $fkClass ) = \explode ( "|", $key );
79 42
			if (is_array ( $included )) {
80 2
				$includedNext = self::_getIncludedNext ( $included, $member );
81
			}
82 42
			$objectsParsers = $pendingRelationsRequest->getObjectsConditionParsers ();
83 42
			$prop = null;
84 42
			if ('getOneToMany' === $part) {
85 37
				$prop = OrmUtils::getFirstPropKey ( $fkClass );
86 37
				$fkField = "get" . ucfirst ( $fkField );
87
			}
88 42
			foreach ( $objectsParsers as $objectsConditionParser ) {
89 42
				$objectsConditionParser->compileParts ();
90 42
				$relationObjects = self::_getAll ( self::getDb ( $class ), $class, $objectsConditionParser->getConditionParser (), $includedNext, $useCache );
91 42
				$objects = $objectsConditionParser->getObjects ();
92 42
				if ($accessor = self::getAccessor ( $member, current ( $objects ), $part )) {
93 42
					foreach ( $objects as $object ) {
94 42
						$affectsCallback ( $object, $member, $relationObjects, $fkField, $accessor, $class, $prop );
95
					}
96
				}
97
			}
98
		}
99 42
	}
100
101 23
	private static function _affectsManyToManyObjectsFromArray($objectsClass, $parsers, $objects, $included, $useCache = NULL) {
102 23
		$includedNext = false;
103 23
		$prop = OrmUtils::getFirstPropKey ( $objectsClass );
104 23
		foreach ( $parsers as $key => $parser ) {
105 23
			list ( $class, $member ) = \explode ( "|", $key );
106 23
			if (is_array ( $included )) {
107 3
				$includedNext = self::_getIncludedNext ( $included, $member );
108
			}
109 23
			$myPkValues = [ ];
110 23
			$cParser = self::generateManyToManyParser ( $parser, $myPkValues );
111 23
			$relationObjects = self::_getAll ( self::getDb ( $class ), $class, $cParser, $includedNext, $useCache );
112 23
			if ($accessor = self::getAccessor ( $member, current ( $objects ), 'getManyToMany' )) {
113 23
				foreach ( $objects as $object ) {
114 23
					$pkV = Reflexion::getPropValue ( $object, $prop );
115 23
					if (isset ( $myPkValues [$pkV] )) {
116 23
						$ret = self::getManyToManyFromArrayIds ( $class, $relationObjects, $myPkValues [$pkV] );
117 23
						self::setToMember ( $member, $object, $ret, $accessor );
118
					}
119
				}
120
			}
121
		}
122 23
	}
123
124 37
	private static function _getOneToManyFromArray(&$ret, $array, $fkv, $elementAccessor, $prop) {
125 37
		foreach ( $array as $element ) {
126 33
			$elementRef = $element->$elementAccessor ();
127 33
			if (($elementRef == $fkv) || (\is_object ( $elementRef ) && Reflexion::getPropValue ( $elementRef, $prop ) == $fkv)) {
128 33
				$ret [] = $element;
129
			}
130
		}
131 37
	}
132
133 23
	private static function generateManyToManyParser(ManyToManyParser $parser, &$myPkValues): ConditionParser {
134 23
		$sql = $parser->generateConcatSQL ();
135 23
		$result = self::getDb ( $parser->getTargetEntityClass () )->prepareAndFetchAll ( $sql, $parser->getWhereValues () );
136 23
		$condition = $parser->getParserWhereMask ( ' ?' );
137 23
		$cParser = new ConditionParser ();
138 23
		foreach ( $result as $row ) {
139 23
			$values = explode ( ',', $row ['_concat'] );
140 23
			$myPkValues [$row ['_field']] = $values;
141 23
			$cParser->addParts ( $condition, $values );
142
		}
143 23
		$cParser->compileParts ();
144 23
		return $cParser;
145
	}
146
147 5
	private static function _getIncludedNext($included, $member) {
148 5
		return (isset ( $included [$member] )) ? (\is_bool ( $included [$member] ) ? $included [$member] : [ $included [$member] ]) : false;
149
	}
150
151 23
	private static function getManyToManyFromArrayIds($objectClass, $relationObjects, $ids): array {
152 23
		$ret = [ ];
153 23
		$prop = OrmUtils::getFirstPropKey ( $objectClass );
154 23
		foreach ( $relationObjects as $targetEntityInstance ) {
155 23
			$id = Reflexion::getPropValue ( $targetEntityInstance, $prop );
156 23
			if (\array_search ( $id, $ids ) !== false) {
157 23
				\array_push ( $ret, $targetEntityInstance );
158
			}
159
		}
160 23
		return $ret;
161
	}
162
}
163
164