Completed
Push — master ( 4e6026...e0b9fa )
by Jean-Christophe
01:30
created

OrmUtils   C

Complexity

Total Complexity 61

Size/Duplication

Total Lines 229
Duplicated Lines 7.86 %

Coupling/Cohesion

Components 1
Dependencies 4

Importance

Changes 0
Metric Value
wmc 61
lcom 1
cbo 4
dl 18
loc 229
rs 6.018
c 0
b 0
f 0

25 Methods

Rating   Name   Duplication   Size   Complexity  
A getModelMetadata() 0 6 2
A isSerializable() 7 7 2
A isNullable() 7 7 2
A getFieldName() 0 8 2
A getFieldNames() 0 10 3
A getTableName() 0 4 2
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
A getDefaultFk() 0 3 1

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 Ubiquity\orm;
4
5
use Ubiquity\orm\parser\Reflexion;
6
use Ubiquity\cache\CacheManager;
7
use Ubiquity\utils\StrUtils;
8
use Ubiquity\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::getOrmModelCache($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
	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
		$fields=self::getAnnotationInfo($model, "#fieldNames");
52
		$result=[];
53
		$serializables=self::getSerializableFields($model);
54
		foreach ($fields as $member=>$field){
55
			if(\array_search($member, $serializables)!==false)
56
				$result[$field]=$member;
57
		}
58
		return $result;
59
	}
60
61
	public static function getTableName($class) {
62
		if(isset(self::getModelMetadata($class)["#tableName"]))
63
		return self::getModelMetadata($class)["#tableName"];
64
	}
65
66
	public static function getKeyFieldsAndValues($instance) {
67
		$kf=self::getAnnotationInfo(get_class($instance), "#primaryKeys");
68
		return self::getMembersAndValues($instance, $kf);
69
	}
70
71
	public static function getKeyFields($instance) {
72
		if(!\is_string($instance)){
73
			$instance=\get_class($instance);
74
		}
75
		return self::getAnnotationInfo($instance, "#primaryKeys");
76
	}
77
78
	public static function getMembers($className) {
79
		$fieldNames=self::getAnnotationInfo($className, "#fieldNames");
80
		if ($fieldNames !== false)
81
			return \array_keys($fieldNames);
82
		return [ ];
83
	}
84
85
	public static function getFieldTypes($className) {
86
		$fieldTypes=self::getAnnotationInfo($className, "#fieldTypes");
87
		if ($fieldTypes !== false)
88
			return $fieldTypes;
89
		return [ ];
90
	}
91
92
	public static function getMembersAndValues($instance, $members=NULL) {
93
		$ret=array ();
94
		$className=get_class($instance);
95
		if (is_null($members))
96
			$members=self::getMembers($className);
97
		foreach ( $members as $member ) {
98
			if (OrmUtils::isSerializable($className, $member)) {
99
				$v=Reflexion::getMemberValue($instance, $member);
100 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...
101
					$name=self::getFieldName($className, $member);
102
					$ret[$name]=$v;
103
				}
104
			}
105
		}
106
		return $ret;
107
	}
108
109
	public static function isNotNullOrNullAccepted($v, $className, $member) {
110
		$notNull=StrUtils::isNotNull($v);
111
		return ($notNull) || (!$notNull && OrmUtils::isNullable($className, $member));
112
	}
113
114
	public static function getFirstKey($class) {
115
		$kf=self::getAnnotationInfo($class, "#primaryKeys");
116
		return \reset($kf);
117
	}
118
119
	public static function getFirstKeyValue($instance) {
120
		$fkv=self::getKeyFieldsAndValues($instance);
121
		return \reset($fkv);
122
	}
123
124
	/**
125
	 *
126
	 * @param object $instance
127
	 * @return mixed[]
128
	 */
129
	public static function getManyToOneMembersAndValues($instance) {
130
		$ret=array ();
131
		$class=get_class($instance);
132
		$members=self::getAnnotationInfo($class, "#manyToOne");
133
		if ($members !== false) {
134
			foreach ( $members as $member ) {
135
				$memberAccessor="get" . ucfirst($member);
136
				if (method_exists($instance, $memberAccessor)) {
137
					$memberInstance=$instance->$memberAccessor();
138
					if (isset($memberInstance)) {
139
						$keyValues=self::getKeyFieldsAndValues($memberInstance);
140
						if (sizeof($keyValues) > 0) {
141
							$fkName=self::getJoinColumnName($class, $member);
142
							$ret[$fkName]=reset($keyValues);
143
						}
144
					}
145
				}
146
			}
147
		}
148
		return $ret;
149
	}
150
151
	public static function getMembersWithAnnotation($class, $annotation) {
152
		if (isset(self::getModelMetadata($class)[$annotation]))
153
			return self::getModelMetadata($class)[$annotation];
154
		return [ ];
155
	}
156
157
	/**
158
	 *
159
	 * @param object $instance
160
	 * @param string $memberKey
161
	 * @param array $array
162
	 * @return boolean
163
	 */
164
	public static function exists($instance, $memberKey, $array) {
165
		$accessor="get" . ucfirst($memberKey);
166
		if (method_exists($instance, $accessor)) {
167
			if ($array !== null) {
168
				foreach ( $array as $value ) {
169
					if ($value->$accessor() == $instance->$accessor())
170
						return true;
171
				}
172
			}
173
		}
174
		return false;
175
	}
176
177
	public static function getJoinColumnName($class, $member) {
178
		$annot=self::getAnnotationInfoMember($class, "#joinColumn", $member);
179
		if ($annot !== false) {
180
			$fkName=$annot["name"];
181
		} else {
182
			$fkName="id" . ucfirst(self::getTableName(ucfirst($member)));
183
		}
184
		return $fkName;
185
	}
186
187
	public static function getAnnotationInfo($class, $keyAnnotation) {
188
		if (isset(self::getModelMetadata($class)[$keyAnnotation]))
189
			return self::getModelMetadata($class)[$keyAnnotation];
190
		return false;
191
	}
192
193
	public static function getAnnotationInfoMember($class, $keyAnnotation, $member) {
194
		$info=self::getAnnotationInfo($class, $keyAnnotation);
195
		if ($info !== false) {
196
			if(JArray::isAssociative($info)){
197
				if (isset($info[$member])) {
198
					return $info[$member];
199
				}
200
			}else{
201
				if(\array_search($member, $info)!==false){
202
					return $member;
203
				}
204
			}
205
		}
206
		return false;
207
	}
208
209
	public static function getSerializableFields($class) {
210
		$notSerializable=self::getAnnotationInfo($class, "#notSerializable");
211
		$fieldNames=\array_keys(self::getAnnotationInfo($class, "#fieldNames"));
212
		return \array_diff($fieldNames, $notSerializable);
213
	}
214
215
	public static function getFieldsInRelations($class) {
216
		$result=[ ];
217
		if ($manyToOne=self::getAnnotationInfo($class, "#manyToOne")) {
218
			$result=\array_merge($result, $manyToOne);
219
		}
220
		if ($oneToMany=self::getAnnotationInfo($class, "#oneToMany")) {
221
			$result=\array_merge($result, \array_keys($oneToMany));
222
		}
223
		if ($manyToMany=self::getAnnotationInfo($class, "#manyToMany")) {
224
			$result=\array_merge($result, \array_keys($manyToMany));
225
		}
226
		return $result;
227
	}
228
229
	public static function getManyToOneFields($class) {
230
		return self::getAnnotationInfo($class, "#manyToOne");
231
	}
232
233
	public static function getManyToManyFields($class) {
234
		$result=self::getAnnotationInfo($class, "#manyToMany");
235
		if($result!==false)
236
			return \array_keys($result);
237
		return [];
238
	}
239
240
	public static function getDefaultFk($classname) {
241
		return "id" . \ucfirst(self::getTableName($classname));
242
	}
243
}
244