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

OrmUtils   C

Complexity

Total Complexity 53

Size/Duplication

Total Lines 193
Duplicated Lines 0 %

Test Coverage

Coverage 95.41%

Importance

Changes 1
Bugs 0 Features 1
Metric Value
wmc 53
eloc 86
dl 0
loc 193
ccs 104
cts 109
cp 0.9541
rs 6.96
c 1
b 0
f 1

27 Methods

Rating   Name   Duplication   Size   Complexity  
A getKeyPropsAndValues_() 0 7 2
A getTableName() 0 2 1
A _is() 0 6 2
A getKeyFieldsAndValues() 0 3 1
A isNotNullOrNullAccepted() 0 3 5
A objectAsJSON() 0 4 1
A getMembers() 0 6 2
A getMembersWithAnnotation() 0 2 1
A isNullable() 0 2 1
A setFieldToMemberNames() 0 4 3
A getFieldsAndValues_() 0 8 2
A getModelMetadata() 0 2 1
A getFirstKeyValue() 0 3 1
A getMembersAndValues() 0 15 5
A clearMetaDatas() 0 2 1
A getPropKeyValues() 0 6 2
A getAnnotationInfo() 0 2 1
A getKeyValues() 0 3 1
A isSerializable() 0 2 1
A getAnnotationInfoMember() 0 14 5
A getAccessors() 0 3 2
A getFirstKeyValue_() 0 2 1
A hasAllMembersPublic() 0 9 3
A getPrimaryKeys() 0 2 1
A getFieldName() 0 2 1
A getTransformers() 0 3 2
A exists() 0 9 4

How to fix   Complexity   

Complex Class

Complex classes like OrmUtils 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 OrmUtils, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace Ubiquity\orm;
4
5
use Ubiquity\cache\CacheManager;
6
use Ubiquity\controllers\rest\formatters\ResponseFormatter;
7
use Ubiquity\orm\parser\Reflexion;
8
use Ubiquity\orm\traits\OrmUtilsFieldsTrait;
9
use Ubiquity\orm\traits\OrmUtilsRelationsTrait;
10
11
/**
12
 * Object/relational mapping utilities
13
 *
14
 * @author jc
15
 * @version 1.0.9
16
 */
17
class OrmUtils {
18
19
	use OrmUtilsFieldsTrait, OrmUtilsRelationsTrait;
20
21
	private static $modelsMetadatas;
22
23 165
	public static function getModelMetadata($className) {
24 165
		return self::$modelsMetadatas [$className] ??= CacheManager::getOrmModelCache($className);
25
	}
26
27 1
	public static function isSerializable($class, $member) {
28 1
		return !self::_is($class, $member, '#notSerializable');
29
	}
30
31 6
	public static function isNullable($class, $member) {
32 6
		return self::_is($class, $member, '#nullable');
33
	}
34
35 7
	protected static function _is($class, $member, $like) {
36 7
		$ret = self::getAnnotationInfo($class, $like);
37 7
		if ($ret !== false) {
38 7
			return \array_search($member, $ret) !== false;
39
		}
40
		return false;
41
	}
42
43 1
	public static function getFieldName($class, $member) {
44 1
		return (self::getAnnotationInfo($class, '#fieldNames') [$member]) ?? $member;
45
	}
46
47 82
	public static function getTableName($class) {
48 82
		return self::getModelMetadata($class) ['#tableName'];
49
	}
50
51 23
	public static function getKeyFieldsAndValues($instance, $prefix = '') {
52 23
		$class = \get_class($instance);
53 23
		return self::getFieldsAndValues_($instance, self::getKeyMembers($class), $prefix);
54
	}
55
56 24
	public static function getFieldsAndValues_($instance, $members, $prefix = '') {
57 24
		$ret = [];
58 24
		$fieldnames = self::getAnnotationInfo(\get_class($instance), '#fieldNames');
59 24
		foreach ($members as $member) {
60 24
			$v = Reflexion::getMemberValue($instance, $member);
61 24
			$ret [$prefix . ($fieldnames [$member] ?? $member)] = $v;
62
		}
63 24
		return $ret;
64
	}
65
66 1
	public static function getKeyPropsAndValues_($instance, $props) {
67 1
		$ret = [];
68 1
		foreach ($props as $prop) {
69 1
			$v = Reflexion::getPropValue($instance, $prop);
70 1
			$ret [$prop->getName()] = $v;
71
		}
72 1
		return $ret;
73
	}
74
75 65
	public static function getPrimaryKeys($className) {
76 65
		return self::getAnnotationInfo($className, '#primaryKeys');
77
	}
78
79 68
	public static function getMembers($className) {
80 68
		$fieldNames = self::getAnnotationInfo($className, '#fieldNames');
81 68
		if ($fieldNames !== false) {
82 68
			return \array_keys($fieldNames);
83
		}
84
		return [];
85
	}
86
87 1
	public static function getMembersAndValues($instance, $members = null) {
88 1
		$ret = array();
89 1
		$className = \get_class($instance);
90 1
		if (\is_null($members))
91 1
			$members = self::getMembers($className);
92 1
		foreach ($members as $member) {
93 1
			if (self::isSerializable($className, $member)) {
94 1
				$v = Reflexion::getMemberValue($instance, $member);
95 1
				if (self::isNotNullOrNullAccepted($v, $className, $member)) {
96 1
					$name = self::getFieldName($className, $member);
97 1
					$ret [$name] = $v;
98
				}
99
			}
100
		}
101 1
		return $ret;
102
	}
103
104 8
	public static function isNotNullOrNullAccepted($v, $className, $member) {
105 8
		$notNull = (isset ($v) && null !== $v && '' !== $v);
106 8
		return ($notNull) || (!$notNull && self::isNullable($className, $member));
107
	}
108
109 83
	public static function getFirstKeyValue($instance) {
110 83
		$prop = OrmUtils::getFirstPropKey(\get_class($instance));
111 83
		return $prop->getValue($instance);
112
	}
113
114 1
	public static function getFirstKeyValue_($instance, $members) {
115 1
		return \current(self::getFieldsAndValues_($instance, $members));
116
	}
117
118 2
	public static function getKeyValues($instance) {
119 2
		$fkv = self::getKeyFieldsAndValues($instance);
120 2
		return \implode('_', $fkv);
121
	}
122
123 110
	public static function getPropKeyValues($instance, $props) {
124 110
		$values = [];
125 110
		foreach ($props as $prop) {
126 110
			$values [] = $prop->getValue($instance);
127
		}
128 110
		return \implode('_', $values);
129
	}
130
131
	public static function getMembersWithAnnotation($class, $annotation) {
132
		return (self::getModelMetadata($class) [$annotation]) ?? [];
133
	}
134
135
	/**
136
	 *
137
	 * @param object $instance
138
	 * @param string $memberKey
139
	 * @param array $array
140
	 * @return boolean
141
	 */
142 1
	public static function exists($instance, $memberKey, $array) {
143 1
		$accessor = 'get' . \ucfirst($memberKey);
144 1
		if (\method_exists($instance, $accessor)) {
145 1
			foreach ($array as $value) {
146 1
				if ($value->$accessor () == $instance->$accessor ())
147 1
					return true;
148
			}
149
		}
150
		return false;
151
	}
152
153 147
	public static function getAnnotationInfo($class, $keyAnnotation) {
154 147
		return self::getModelMetadata($class) [$keyAnnotation] ?? false;
155
	}
156
157 80
	public static function getAnnotationInfoMember($class, $keyAnnotation, $member) {
158 80
		$info = self::getAnnotationInfo($class, $keyAnnotation);
159 80
		if ($info !== false) {
160 80
			if (!isset ($info [0])) { // isAssociative
161 80
				if (isset ($info [$member])) {
162 80
					return $info [$member];
163
				}
164
			} else {
165 1
				if (\array_search($member, $info) !== false) {
166 1
					return $member;
167
				}
168
			}
169
		}
170 1
		return false;
171
	}
172
173 5
	public static function setFieldToMemberNames(&$fields, $relFields) {
174 5
		foreach ($fields as $index => $field) {
175 5
			if (isset ($relFields [$field])) {
176 1
				$fields [$index] = $relFields [$field];
177
			}
178
		}
179
	}
180
181 1
	public static function objectAsJSON($instance) {
182 1
		$formatter = new ResponseFormatter ();
183 1
		$datas = $formatter->cleanRestObject($instance);
184 1
		return $formatter->format(['pk' => self::getFirstKeyValue($instance), 'object' => $datas]);
185
	}
186
187 1
	public static function getTransformers($class) {
188 1
		if (isset (self::getModelMetadata($class) ['#transformers']))
189 1
			return self::getModelMetadata($class) ['#transformers'];
190
	}
191
192 1
	public static function getAccessors($class) {
193 1
		if (isset (self::getModelMetadata($class) ['#accessors']))
194 1
			return self::getModelMetadata($class) ['#accessors'];
195
	}
196
197 4
	public static function clearMetaDatas() {
198 4
		self::$modelsMetadatas = [];
199
	}
200
201 65
	public static function hasAllMembersPublic($className) {
202 65
		$members = self::getMembers($className);
203 65
		foreach ($members as $memberName) {
204 65
			$field = new \ReflectionProperty ($className, $memberName);
205 65
			if (!$field->isPublic()) {
206 61
				return false;
207
			}
208
		}
209 4
		return true;
210
	}
211
}