Completed
Push — master ( 31895c...135d28 )
by Jean-Christophe
02:15
created

Reflexion   B

Complexity

Total Complexity 42

Size/Duplication

Total Lines 144
Duplicated Lines 22.22 %

Coupling/Cohesion

Components 1
Dependencies 1

Importance

Changes 0
Metric Value
wmc 42
lcom 1
cbo 1
dl 32
loc 144
rs 8.295
c 0
b 0
f 0

16 Methods

Rating   Name   Duplication   Size   Complexity  
A getProperties() 0 8 2
A getMethods() 0 8 2
A getKeyFields() 0 3 1
A getMemberValue() 0 5 1
A getProperty() 0 5 1
B getPropertiesAndValues() 4 17 9
A getAnnotationClass() 0 4 1
A getAnnotationMember() 0 6 2
A getAnnotationsMethod() 0 6 2
A getMembersAnnotationWithAnnotation() 0 10 3
A getMembersWithAnnotation() 10 10 3
A getMembersNameWithAnnotation() 10 10 3
A isNullable() 0 7 2
B isSerializable() 0 7 5
A getFieldName() 8 8 2
A getTableName() 0 13 3

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 Reflexion 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 Reflexion, and based on these observations, apply Extract Interface, too.

1
<?php
2
namespace micro\orm\parser;
3
4
use mindplay\annotations\Annotation;
5
use mindplay\annotations\Annotations;
6
use micro\orm\OrmUtils;
7
8
/**
9
 * Utilitaires de Reflexion
10
 * @author jc
11
 * @version 1.0.0.2
12
 * @package orm
13
 */
14
class Reflexion{
15
	public static function getProperties($instance){
16
		if(\is_string($instance)){
17
			$instance=new $instance();
18
		}
19
		$reflect = new \ReflectionClass($instance);
20
		$props = $reflect->getProperties();
21
		return $props;
22
	}
23
24
	public static function getMethods($instance,$filter=null){
0 ignored issues
show
Unused Code introduced by
The parameter $filter is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
25
		if(\is_string($instance)){
26
			$instance=new $instance();
27
		}
28
		$reflect = new \ReflectionClass($instance);
29
		$methods = $reflect->getMethods();
30
		return $methods;
31
	}
32
33
	public static function getKeyFields($instance){
34
		return Reflexion::getMembersNameWithAnnotation(get_class($instance), "@id");
35
	}
36
37
	public static function getMemberValue($instance,$member){
38
		$prop=self::getProperty($instance, $member);
39
		$prop->setAccessible(true);
40
		return $prop->getValue($instance);
41
	}
42
43
	public static function getProperty($instance,$member){
44
		$reflect = new \ReflectionClass($instance);
45
		$prop = $reflect->getProperty($member);
46
		return $prop;
47
	}
48
49
	public static function getPropertiesAndValues($instance,$props=NULL){
50
		$ret=array();
51
		$className=get_class($instance);
52
		if(is_null($props))
53
			$props=self::getProperties($instance);
54
		foreach ($props as $prop){
55
			$prop->setAccessible(true);
56
			$v=$prop->getValue($instance);
57
			if(OrmUtils::isSerializable($className,$prop->getName())){
58 View Code Duplication
				if(($v!==null && $v!=="") || (($v===null || $v==="") && OrmUtils::isNullable($className, $prop->getName()))){
0 ignored issues
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...
59
					$name=OrmUtils::getFieldName($className, $prop->getName());
60
					$ret[$name]=$v;
61
				}
62
			}
63
		}
64
		return $ret;
65
	}
66
67
	public static function getAnnotationClass($class,$annotation){
68
		$annot=Annotations::ofClass($class,$annotation);
69
		return $annot;
70
	}
71
72
	public static function getAnnotationMember($class,$member,$annotation){
73
		$annot=Annotations::ofProperty($class,$member,$annotation);
74
		if(\sizeof($annot)>0)
75
			return $annot[0];
76
		return false;
77
	}
78
79
	public static function getAnnotationsMethod($class,$method,$annotation){
80
		$annots=Annotations::ofMethod($class,$method,$annotation);
81
		if(\sizeof($annots)>0)
82
			return $annots;
83
		return false;
84
	}
85
86
	public static function getMembersAnnotationWithAnnotation($class,$annotation){
87
		$props=self::getProperties($class);
88
		$ret=array();
89
		foreach ($props as $prop){
90
			$annot=self::getAnnotationMember($class, $prop->getName(), $annotation);
91
			if($annot!==false)
92
				$ret[$prop->getName()]=$annot;
93
		}
94
		return $ret;
95
	}
96
97 View Code Duplication
	public static function getMembersWithAnnotation($class,$annotation){
98
		$props=self::getProperties($class);
99
		$ret=array();
100
		foreach ($props as $prop){
101
			$annot=self::getAnnotationMember($class, $prop->getName(), $annotation);
102
			if($annot!==false)
103
				$ret[]=$prop;
104
		}
105
		return $ret;
106
	}
107
108 View Code Duplication
	public static function getMembersNameWithAnnotation($class,$annotation){
109
		$props=self::getProperties($class);
110
		$ret=array();
111
		foreach ($props as $prop){
112
			$annot=self::getAnnotationMember($class, $prop->getName(), $annotation);
113
			if($annot!==false)
114
				$ret[]=$prop->getName();
115
		}
116
		return $ret;
117
	}
118
119
	public static function isNullable($class,$member){
120
		$ret=self::getAnnotationMember($class,$member,"@column");
121
		if (!$ret)
122
			return false;
123
		else
124
			return $ret->nullable;
125
	}
126
127
	public static function isSerializable($class,$member){
128
		if (self::getAnnotationMember($class,$member,"@transient")!==false || self::getAnnotationMember($class,$member,"@manyToOne")!==false ||
129
				self::getAnnotationMember($class,$member,"@manyToMany")!==false || self::getAnnotationMember($class,$member,"@oneToMany")!==false)
130
			return false;
131
		else
132
			return true;
133
	}
134
135 View Code Duplication
	public static function getFieldName($class,$member){
1 ignored issue
show
Duplication introduced by
This method seems to be duplicated in 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...
136
		$ret=self::getAnnotationMember($class, $member, "@column");
137
		if($ret===false)
138
			$ret=$member;
139
		else
140
			$ret=$ret->name;
141
		return $ret;
142
	}
143
144
	public static function getTableName($class){
145
		$ret=Reflexion::getAnnotationClass($class, "@table");
146
		if(\sizeof($ret)===0){
147
			$posSlash=strrpos($class, '\\');
148
			if($posSlash!==false)
149
				$class=substr($class,  $posSlash+ 1);
150
			$ret=$class;
151
		}
152
		else{
153
			$ret=$ret[0]->name;
154
		}
155
		return $ret;
156
	}
157
}
158