Completed
Push — master ( 01a07f...707e60 )
by Jean-Christophe
01:23
created

OrmUtils   C

Complexity

Total Complexity 58

Size/Duplication

Total Lines 222
Duplicated Lines 11.71 %

Coupling/Cohesion

Components 1
Dependencies 4

Importance

Changes 1
Bugs 1 Features 0
Metric Value
wmc 58
c 1
b 1
f 0
lcom 1
cbo 4
dl 26
loc 222
rs 6.3005

25 Methods

Rating   Name   Duplication   Size   Complexity  
A getDefaultFk() 0 3 1
A getModelMetadata() 0 6 2
A isSerializable() 7 7 2
A isNullable() 7 7 2
A getFieldName() 8 8 2
A getFieldNames() 0 4 1
A getTableName() 0 3 1
A getKeyFieldsAndValues() 0 4 1
A getKeyFields() 0 6 2
A getMembers() 0 6 2
A getFieldTypes() 0 6 2
B getMembersAndValues() 4 16 5
A isNotNullOrNullAccepted() 0 4 3
A getFirstKey() 0 4 1
A getFirstKeyValue() 0 4 1
B getManyToOneMembersAndValues() 0 21 6
A getMembersWithAnnotation() 0 5 2
B exists() 0 12 5
A getJoinColumnName() 0 9 2
A getAnnotationInfo() 0 5 2
B getAnnotationInfoMember() 0 15 5
A getSerializableFields() 0 5 1
A getFieldsInRelations() 0 13 4
A getManyToOneFields() 0 3 1
A getManyToManyFields() 0 6 2

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

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. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

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 micro\orm;
4
5
use micro\orm\parser\Reflexion;
6
use micro\cache\CacheManager;
7
use micro\utils\StrUtils;
8
use micro\utils\JArray;
9
10
/**
11
 * Utilitaires de mappage Objet/relationnel
12
 * @author jc
13
 * @version 1.0.0.5
14
 */
15
class OrmUtils {
16
	private static $modelsMetadatas;
17
18
	public static function getModelMetadata($className) {
19
		if (!isset(self::$modelsMetadatas[$className])) {
20
			self::$modelsMetadatas[$className]=CacheManager::createOrmModelCache($className);
21
		}
22
		return self::$modelsMetadatas[$className];
23
	}
24
25 View Code Duplication
	public static function isSerializable($class, $member) {
26
		$ret=self::getAnnotationInfo($class, "#notSerializable");
27
		if ($ret !== false)
28
			return \array_search($member, $ret) === false;
29
		else
30
			return true;
31
	}
32
33 View Code Duplication
	public static function isNullable($class, $member) {
34
		$ret=self::getAnnotationInfo($class, "#nullable");
35
		if ($ret !== false)
36
			return \array_search($member, $ret) !== false;
37
		else
38
			return false;
39
	}
40
41 View Code Duplication
	public static function getFieldName($class, $member) {
42
		$ret=self::getAnnotationInfo($class, "#fieldNames");
43
		if ($ret === false)
44
			$ret=$member;
45
		else
46
			$ret=$ret[$member];
47
		return $ret;
48
	}
49
50
	public static function getFieldNames($model){
51
		$ret=\array_flip(self::getAnnotationInfo($model, "#fieldNames"));
52
		return \array_unique($ret);
53
	}
54
55
	public static function getTableName($class) {
56
		return self::getModelMetadata($class)["#tableName"];
57
	}
58
59
	public static function getKeyFieldsAndValues($instance) {
60
		$kf=self::getAnnotationInfo(get_class($instance), "#primaryKeys");
61
		return self::getMembersAndValues($instance, $kf);
62
	}
63
64
	public static function getKeyFields($instance) {
65
		if(!\is_string($instance)){
66
			$instance=\get_class($instance);
67
		}
68
		return self::getAnnotationInfo($instance, "#primaryKeys");
69
	}
70
71
	public static function getMembers($className) {
72
		$fieldNames=self::getAnnotationInfo($className, "#fieldNames");
73
		if ($fieldNames !== false)
74
			return \array_keys($fieldNames);
75
		return [ ];
76
	}
77
78
	public static function getFieldTypes($className) {
79
		$fieldTypes=self::getAnnotationInfo($className, "#fieldTypes");
80
		if ($fieldTypes !== false)
81
			return $fieldTypes;
82
		return [ ];
83
	}
84
85
	public static function getMembersAndValues($instance, $members=NULL) {
86
		$ret=array ();
87
		$className=get_class($instance);
88
		if (is_null($members))
89
			$members=self::getMembers($className);
90
		foreach ( $members as $member ) {
91
			if (OrmUtils::isSerializable($className, $member)) {
92
				$v=Reflexion::getMemberValue($instance, $member);
93 View Code Duplication
				if (self::isNotNullOrNullAccepted($v, $className, $member)) {
1 ignored issue
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
94
					$name=self::getFieldName($className, $member);
95
					$ret[$name]=$v;
96
				}
97
			}
98
		}
99
		return $ret;
100
	}
101
102
	public static function isNotNullOrNullAccepted($v, $className, $member) {
103
		$notNull=StrUtils::isNotNull($v);
104
		return ($notNull) || (!$notNull && OrmUtils::isNullable($className, $member));
105
	}
106
107
	public static function getFirstKey($class) {
108
		$kf=self::getAnnotationInfo($class, "#primaryKeys");
109
		return \reset($kf);
110
	}
111
112
	public static function getFirstKeyValue($instance) {
113
		$fkv=self::getKeyFieldsAndValues($instance);
114
		return \reset($fkv);
115
	}
116
117
	/**
118
	 *
119
	 * @param object $instance
120
	 * @return mixed[]
121
	 */
122
	public static function getManyToOneMembersAndValues($instance) {
123
		$ret=array ();
124
		$class=get_class($instance);
125
		$members=self::getAnnotationInfo($class, "#manyToOne");
126
		if ($members !== false) {
127
			foreach ( $members as $member ) {
128
				$memberAccessor="get" . ucfirst($member);
129
				if (method_exists($instance, $memberAccessor)) {
130
					$memberInstance=$instance->$memberAccessor();
131
					if (isset($memberInstance)) {
132
						$keyValues=self::getKeyFieldsAndValues($memberInstance);
133
						if (sizeof($keyValues) > 0) {
134
							$fkName=self::getJoinColumnName($class, $member);
135
							$ret[$fkName]=reset($keyValues);
136
						}
137
					}
138
				}
139
			}
140
		}
141
		return $ret;
142
	}
143
144
	public static function getMembersWithAnnotation($class, $annotation) {
145
		if (isset(self::getModelMetadata($class)[$annotation]))
146
			return self::getModelMetadata($class)[$annotation];
147
		return [ ];
148
	}
149
150
	/**
151
	 *
152
	 * @param object $instance
153
	 * @param string $memberKey
154
	 * @param array $array
155
	 * @return boolean
156
	 */
157
	public static function exists($instance, $memberKey, $array) {
158
		$accessor="get" . ucfirst($memberKey);
159
		if (method_exists($instance, $accessor)) {
160
			if ($array !== null) {
161
				foreach ( $array as $value ) {
162
					if ($value->$accessor() == $instance->$accessor())
163
						return true;
164
				}
165
			}
166
		}
167
		return false;
168
	}
169
170
	public static function getJoinColumnName($class, $member) {
171
		$annot=self::getAnnotationInfoMember($class, "#joinColumn", $member);
172
		if ($annot !== false) {
173
			$fkName=$annot["name"];
174
		} else {
175
			$fkName="id" . ucfirst(self::getTableName(ucfirst($member)));
176
		}
177
		return $fkName;
178
	}
179
180
	public static function getAnnotationInfo($class, $keyAnnotation) {
181
		if (isset(self::getModelMetadata($class)[$keyAnnotation]))
182
			return self::getModelMetadata($class)[$keyAnnotation];
183
		return false;
184
	}
185
186
	public static function getAnnotationInfoMember($class, $keyAnnotation, $member) {
187
		$info=self::getAnnotationInfo($class, $keyAnnotation);
188
		if ($info !== false) {
189
			if(JArray::isAssociative($info)){
190
				if (isset($info[$member])) {
191
					return $info[$member];
192
				}
193
			}else{
194
				if(\array_search($member, $info)!==false){
195
					return $member;
196
				}
197
			}
198
		}
199
		return false;
200
	}
201
202
	public static function getSerializableFields($class) {
203
		$notSerializable=self::getAnnotationInfo($class, "#notSerializable");
204
		$fieldNames=\array_keys(self::getAnnotationInfo($class, "#fieldNames"));
205
		return \array_diff($fieldNames, $notSerializable);
206
	}
207
208
	public static function getFieldsInRelations($class) {
209
		$result=[ ];
210
		if ($manyToOne=self::getAnnotationInfo($class, "#manyToOne")) {
211
			$result=\array_merge($result, $manyToOne);
212
		}
213
		if ($oneToMany=self::getAnnotationInfo($class, "#oneToMany")) {
214
			$result=\array_merge($result, \array_keys($oneToMany));
215
		}
216
		if ($manyToMany=self::getAnnotationInfo($class, "#manyToMany")) {
217
			$result=\array_merge($result, \array_keys($manyToMany));
218
		}
219
		return $result;
220
	}
221
222
	public static function getManyToOneFields($class) {
223
		return self::getAnnotationInfo($class, "#manyToOne");
224
	}
225
226
	public static function getManyToManyFields($class) {
227
		$result=self::getAnnotationInfo($class, "#manyToMany");
228
		if($result!==false)
229
			return \array_keys($result);
230
		return [];
231
	}
232
233
	public static function getDefaultFk($classname) {
234
		return "id" . \ucfirst(self::getTableName($classname));
235
	}
236
}
237