Passed
Push — master ( 7b3a8c...be70ce )
by Jean-Christophe
22:44
created

DAOCoreTrait   B

Complexity

Total Complexity 48

Size/Duplication

Total Lines 215
Duplicated Lines 0 %

Test Coverage

Coverage 87.74%

Importance

Changes 1
Bugs 0 Features 1
Metric Value
wmc 48
eloc 95
dl 0
loc 215
ccs 93
cts 106
cp 0.8774
rs 8.5599
c 1
b 0
f 1

14 Methods

Rating   Name   Duplication   Size   Complexity  
A getFirstKeyValue_() 0 5 2
A getInstance_() 0 5 2
A getClass_() 0 5 2
A getValue_() 0 5 2
A _getOne() 0 22 6
A getModels() 0 8 3
A parseKey() 0 4 5
B _loadObjectFromRow() 0 21 7
A loadManys() 0 9 5
A _getAll() 0 26 6
A _loadSimpleObjectFromRow() 0 10 3
A storeDbCache() 0 4 2
A applyTransformers() 0 5 2
A _getFieldList() 0 2 1

How to fix   Complexity   

Complex Class

Complex classes like DAOCoreTrait often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use DAOCoreTrait, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace Ubiquity\orm\traits;
4
5
use Ubiquity\db\Database;
6
use Ubiquity\db\SqlUtils;
7
use Ubiquity\events\DAOEvents;
8
use Ubiquity\events\EventsManager;
9
use Ubiquity\orm\OrmUtils;
10
use Ubiquity\orm\parser\ConditionParser;
11
use Ubiquity\orm\parser\Reflexion;
12
13
/**
14
 * Core Trait for DAO class.
15
 * Ubiquity\orm\traits$DAOCoreTrait
16
 * This class is part of Ubiquity
17
 *
18
 * @author jcheron <[email protected]>
19
 * @version 1.1.7
20
 *
21
 * @property array $db
22
 * @property boolean $useTransformers
23
 * @property string $transformerOp
24
 * @property array $modelsDatabase
25
 *
26
 */
27
trait DAOCoreTrait {
28
	protected static $accessors = [];
29
	protected static $fields = [];
30
31
	abstract public static function _affectsRelationObjects($className, $classPropKey, $manyToOneQueries, $oneToManyQueries, $manyToManyParsers, $objects, $included, $useCache): void;
32
33
	abstract protected static function prepareManyToMany($db, &$ret, $instance, $member, $annot = null);
34
35
	abstract protected static function prepareManyToOne(&$ret, $instance, $value, $fkField, $annotationArray);
36
37
	abstract protected static function prepareOneToMany(&$ret, $instance, $member, $annot = null);
38
39
	abstract public static function _initRelationFields($included, $metaDatas, &$invertedJoinColumns, &$oneToManyFields, &$manyToManyFields): void;
40
41
	abstract public static function _getIncludedForStep($included);
42
43
	abstract protected static function getDb($model);
44
45 18
	protected static function getClass_($instance) {
46 18
		if (\is_object($instance)) {
47 17
			return get_class($instance);
48
		}
49 1
		return $instance [0];
50
	}
51
52
	protected static function getInstance_($instance) {
53
		if (\is_object($instance)) {
54
			return $instance;
55
		}
56
		return $instance [0];
57
	}
58
59
	protected static function getValue_($instance, $member) {
60
		if (\is_object($instance)) {
61
			return Reflexion::getMemberValue($instance, $member);
62
		}
63
		return $instance [1];
64
	}
65
66 13
	protected static function getFirstKeyValue_($instance) {
67 13
		if (\is_object($instance)) {
68 12
			return OrmUtils::getFirstKeyValue($instance);
69
		}
70 1
		return $instance [1];
71
	}
72
73 67
	protected static function _getOne(Database $db, $className, ConditionParser $conditionParser, $included, $useCache) {
74 67
		$conditionParser->limitOne();
75 67
		$included = self::_getIncludedForStep($included);
76 67
		$object = $invertedJoinColumns = $oneToManyFields = $manyToManyFields = null;
77
78 67
		$metaDatas = OrmUtils::getModelMetadata($className);
79 67
		$tableName = $metaDatas ['#tableName'];
80 67
		$hasIncluded = $included || (\is_array($included) && \count($included) > 0);
81 67
		if ($hasIncluded) {
82 45
			self::_initRelationFields($included, $metaDatas, $invertedJoinColumns, $oneToManyFields, $manyToManyFields);
83
		}
84 67
		$transformers = $metaDatas ['#transformers'] [self::$transformerOp] ?? [];
85 67
		$query = $db->prepareAndExecute($tableName, SqlUtils::checkWhere($conditionParser->getCondition()), self::_getFieldList($tableName, $metaDatas), $conditionParser->getParams(), $useCache, true);
86 67
		if ($query) {
87 66
			$oneToManyQueries = $manyToOneQueries = $manyToManyParsers = [];
88 66
			$object = self::_loadObjectFromRow($db, $query, $className, $invertedJoinColumns, $manyToOneQueries, $oneToManyFields, $manyToManyFields, $oneToManyQueries, $manyToManyParsers, $metaDatas ['#memberNames'] ?? null, $metaDatas ['#accessors'], $transformers, $metaDatas['#primaryKeys'] ?? []);
89 66
			if ($hasIncluded) {
90 45
				self::_affectsRelationObjects($className, OrmUtils::getFirstPropKey($className), $manyToOneQueries, $oneToManyQueries, $manyToManyParsers, [$object], $included, $useCache);
91
			}
92 66
			EventsManager::trigger(DAOEvents::GET_ONE, $object, $className);
93
		}
94 67
		return $object;
95
	}
96
97
	/**
98
	 *
99
	 * @param Database $db
100
	 * @param string $className
101
	 * @param ConditionParser $conditionParser
102
	 * @param boolean|array $included
103
	 * @param boolean|null $useCache
104
	 * @return array
105
	 */
106 109
	protected static function _getAll(Database $db, $className, ConditionParser $conditionParser, $included = true, $useCache = null) {
107 109
		$included = self::_getIncludedForStep($included);
108 109
		$objects = [];
109 109
		$invertedJoinColumns = $oneToManyFields = $manyToManyFields = null;
110
111 109
		$metaDatas = OrmUtils::getModelMetadata($className);
112 109
		$primaryKeys = $metaDatas['#primaryKeys'] ?? [];
113 109
		$tableName = $metaDatas ['#tableName'];
114 109
		if ($hasIncluded = ($included || (\is_array($included) && \count($included) > 0))) {
115 49
			self::_initRelationFields($included, $metaDatas, $invertedJoinColumns, $oneToManyFields, $manyToManyFields);
116
		}
117 109
		$transformers = $metaDatas ['#transformers'] [self::$transformerOp] ?? [];
118 109
		$query = $db->prepareAndExecute($tableName, SqlUtils::checkWhere($conditionParser->getCondition()), self::_getFieldList($tableName, $metaDatas), $conditionParser->getParams(), $useCache);
119
120 109
		$oneToManyQueries = $manyToOneQueries = $manyToManyParsers = [];
121
122 109
		$propsKeys = OrmUtils::getPropKeys($className);
123 109
		foreach ($query as $row) {
124 109
			$object = self::_loadObjectFromRow($db, $row, $className, $invertedJoinColumns, $manyToOneQueries, $oneToManyFields, $manyToManyFields, $oneToManyQueries, $manyToManyParsers, $metaDatas ['#memberNames'] ?? null, $metaDatas ['#accessors'], $transformers, $primaryKeys);
125 109
			$objects [OrmUtils::getPropKeyValues($object, $propsKeys)] = $object;
126
		}
127 109
		if ($hasIncluded) {
128 49
			self::_affectsRelationObjects($className, OrmUtils::getFirstPropKey($className), $manyToOneQueries, $oneToManyQueries, $manyToManyParsers, $objects, $included, $useCache);
129
		}
130 109
		EventsManager::trigger(DAOEvents::GET_ALL, $objects, $className);
131 109
		return $objects;
132
	}
133
134 160
	public static function _getFieldList($tableName, $metaDatas) {
135 160
		return self::$fields [$tableName] ??= SqlUtils::getFieldList(\array_diff($metaDatas ['#fieldNames'], $metaDatas ['#notSerializable']), $tableName);
136
	}
137
138
	/**
139
	 *
140
	 * @param Database $db
141
	 * @param array $row
142
	 * @param string $className
143
	 * @param array $invertedJoinColumns
144
	 * @param array $manyToOneQueries
145
	 * @param array $oneToManyFields
146
	 * @param array $manyToManyFields
147
	 * @param array $oneToManyQueries
148
	 * @param array $manyToManyParsers
149
	 * @param array $memberNames
150
	 * @param array $accessors
151
	 * @param array $transformers
152
	 * @return object
153
	 */
154 122
	public static function _loadObjectFromRow(Database $db, $row, $className, $invertedJoinColumns, &$manyToOneQueries, $oneToManyFields, $manyToManyFields, &$oneToManyQueries, &$manyToManyParsers, $memberNames, $accessors, $transformers, $primaryKeys) {
155 122
		$o = new $className ();
156 122
		if (self::$useTransformers) {
157 39
			self::applyTransformers($transformers, $row, $memberNames);
158
		}
159 122
		foreach ($row as $k => $v) {
160 122
			if ($accesseur = ($accessors [$k] ?? false)) {
161 122
				$o->$accesseur ($v);
162
			}
163 122
			$o->_rest [$memberNames [$k] ?? $k] = $v;
164 122
			if (isset($primaryKeys[$k])) {
165 122
				$o->_pkv['___' . $k] = $v;
166
			}
167 122
			if (isset ($invertedJoinColumns) && isset ($invertedJoinColumns [$k])) {
168 39
				$fk = '_' . $k;
169 39
				$o->$fk = $v;
170 39
				self::prepareManyToOne($manyToOneQueries, $o, $v, $fk, $invertedJoinColumns [$k]);
171
			}
172
		}
173 122
		self::loadManys($o, $db, $oneToManyFields, $oneToManyQueries, $manyToManyFields, $manyToManyParsers);
174 122
		return $o;
175
	}
176
177
	/**
178
	 *
179
	 * @param Database $db
180
	 * @param array $row
181
	 * @param string $className
182
	 * @param array $memberNames
183
	 * @param array $transformers
184
	 * @return object
185
	 */
186 4
	public static function _loadSimpleObjectFromRow(Database $db, $row, $className, $memberNames, $transformers) {
187 4
		$o = new $className ();
188 4
		if (self::$useTransformers) {
189
			self::applyTransformers($transformers, $row, $memberNames);
190
		}
191 4
		foreach ($row as $k => $v) {
192 4
			$o->$k = $v;
193 4
			$o->_rest [$memberNames [$k] ?? $k] = $v;
194
		}
195 4
		return $o;
196
	}
197
198 39
	protected static function applyTransformers($transformers, &$row, $memberNames) {
199 39
		foreach ($transformers as $member => $transformer) {
200 38
			$field = \array_search($member, $memberNames);
201 38
			$transform = self::$transformerOp;
202 38
			$row [$field] = $transformer::{$transform} ($row [$field]);
203
		}
204
	}
205
206 122
	protected static function loadManys($o, $db, $oneToManyFields, &$oneToManyQueries, $manyToManyFields, &$manyToManyParsers) {
207 122
		if (isset ($oneToManyFields)) {
208 74
			foreach ($oneToManyFields as $k => $annot) {
209 69
				self::prepareOneToMany($oneToManyQueries, $o, $k, $annot);
210
			}
211
		}
212 122
		if (isset ($manyToManyFields)) {
213 40
			foreach ($manyToManyFields as $k => $annot) {
214 36
				self::prepareManyToMany($db, $manyToManyParsers, $o, $k, $annot);
215
			}
216
		}
217
	}
218
219 5
	private static function parseKey(&$keyValues, $className, $quote) {
220 5
		if (!\is_array($keyValues)) {
221 5
			if (\strrpos($keyValues, '=') === false && \strrpos($keyValues, '>') === false && \strrpos($keyValues, '<') === false) {
222 5
				$keyValues = $quote . OrmUtils::getFirstKey($className) . $quote . "='" . $keyValues . "'";
223
			}
224
		}
225
	}
226
227
	public static function storeDbCache(string $model) {
228
		$offset = self::$modelsDatabase [$model] ?? 'default';
229
		if (isset (self::$db [$offset])) {
230
			self::$db [$offset]->storeCache();
231
		}
232
	}
233
234 2
	public static function getModels($dbOffset = 'default') {
235 2
		$result = [];
236 2
		foreach (self::$modelsDatabase as $model => $offset) {
237 2
			if ($offset === $dbOffset) {
238 2
				$result[] = $model;
239
			}
240
		}
241 2
		return $result;
242
	}
243
}