Completed
Push — master ( 2db7b1...a4369d )
by Jean-Christophe
03:00
created

BaseHtml   C

Complexity

Total Complexity 60

Size/Duplication

Total Lines 230
Duplicated Lines 7.83 %

Coupling/Cohesion

Components 1
Dependencies 5

Importance

Changes 0
Metric Value
wmc 60
lcom 1
cbo 5
dl 18
loc 230
rs 6.0975
c 0
b 0
f 0

26 Methods

Rating   Name   Duplication   Size   Complexity  
run() 0 1 ?
A _callSetter() 0 13 4
A getTemplate() 0 3 1
A ctrl() 9 12 4
A setMemberCtrl() 0 6 2
A addToMemberUnique() 0 7 2
A addToMemberCtrl() 0 9 3
A addToMember() 0 4 1
A removeOldValues() 0 4 1
B _getElementBy() 0 18 8
A setWrapBefore() 0 4 1
A setWrapAfter() 0 4 1
A getTagName() 0 3 1
A setTagName() 0 4 1
B fromArray() 9 12 5
A fromDatabaseObjects() 0 8 3
A fromDatabaseObject() 0 2 1
A wrap() 0 7 2
A getElementById() 0 3 1
A getBsComponent() 0 3 1
A setBsComponent() 0 4 1
B compile_once() 0 15 5
C compile() 0 25 8
A __toString() 0 3 1
A onPostCompile() 0 3 1
A onPreCompile() 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 BaseHtml 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 BaseHtml, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace Ajax\common\html;
4
5
6
use Ajax\service\JString;
7
use Ajax\common\components\SimpleExtComponent;
8
use Ajax\JsUtils;
9
use Ajax\common\html\traits\BaseHtmlEventsTrait;
10
use Ajax\common\html\traits\BaseHtmlPropertiesTrait;
11
12
/**
13
 * BaseHtml for HTML components
14
 * @author jc
15
 * @version 1.3
16
 */
17
abstract class BaseHtml extends BaseWidget {
18
	use BaseHtmlEventsTrait,BaseHtmlPropertiesTrait;
19
	protected $_template;
20
	protected $tagName;
21
	protected $_wrapBefore=array ();
22
	protected $_wrapAfter=array ();
23
	protected $_bsComponent;
24
	protected $_compiled=false;
25
	protected $_postCompile;
26
	protected $_preCompile;
27
28
	/**
29
	 *
30
	 * @param JsUtils $js
31
	 * @return SimpleExtComponent
32
	 */
33
	abstract public function run(JsUtils $js);
34
35
	private function _callSetter($setter,$key,$value,&$array){
36
		$result=false;
37
		if (method_exists($this, $setter) && !JString::startswith($key, "_")) {
38
			try {
39
				$this->$setter($value);
40
				unset($array[$key]);
41
				$result=true;
42
			} catch ( \Exception $e ) {
43
				$result=false;
44
			}
45
		}
46
		return $result;
47
	}
48
49
	protected function getTemplate(JsUtils $js=NULL) {
50
		return PropertyWrapper::wrap($this->_wrapBefore, $js) . $this->_template . PropertyWrapper::wrap($this->_wrapAfter, $js);
51
	}
52
53
	protected function ctrl($name, $value, $typeCtrl) {
54 View Code Duplication
		if (\is_array($typeCtrl)) {
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...
55
			if (array_search($value, $typeCtrl) === false) {
56
				throw new \Exception("La valeur passée `" . $value . "` à la propriété `" . $name . "` ne fait pas partie des valeurs possibles : {" . implode(",", $typeCtrl) . "}");
57
			}
58
		} else {
59
			if (!$typeCtrl($value)) {
60
				throw new \Exception("La fonction " . $typeCtrl . " a retourné faux pour l'affectation de la propriété " . $name);
61
			}
62
		}
63
		return true;
64
	}
65
66
67
68
	protected function setMemberCtrl(&$name, $value, $typeCtrl) {
69
		if ($this->ctrl($name, $value, $typeCtrl) === true) {
70
			return $name=$value;
71
		}
72
		return $this;
73
	}
74
75
	protected function addToMemberUnique(&$name, $value, $typeCtrl, $separator=" ") {
76
		if (\is_array($typeCtrl)) {
77
			$this->removeOldValues($name, $typeCtrl);
78
			$name.=$separator . $value;
79
		}
80
		return $this;
81
	}
82
83
84
85
	protected function addToMemberCtrl(&$name, $value, $typeCtrl, $separator=" ") {
86
		if ($this->ctrl($name, $value, $typeCtrl) === true) {
87
			if (\is_array($typeCtrl)) {
88
				$this->removeOldValues($name, $typeCtrl);
89
			}
90
			$name.=$separator . $value;
91
		}
92
		return $this;
93
	}
94
95
	protected function addToMember(&$name, $value, $separator=" ") {
96
		$name=str_ireplace($value, "", $name) . $separator . $value;
97
		return $this;
98
	}
99
100
101
102
	protected function removeOldValues(&$oldValue, $allValues) {
103
		$oldValue=str_ireplace($allValues, "", $oldValue);
104
		$oldValue=trim($oldValue);
105
	}
106
107
	protected function _getElementBy($callback,$elements){
108
		if (\is_array($elements)) {
109
			$elements=\array_values($elements);
110
			$flag=false;
111
			$index=0;
112
			while ( !$flag && $index < sizeof($elements) ) {
113
				if ($elements[$index] instanceof BaseHtml)
114
					$flag=($callback($elements[$index]));
115
					$index++;
116
			}
117
			if ($flag === true)
118
				return $elements[$index - 1];
119
		} elseif ($elements instanceof BaseHtml) {
120
			if ($callback($elements))
121
				return $elements;
122
		}
123
		return null;
124
	}
125
126
	protected function setWrapBefore($wrapBefore) {
127
		$this->_wrapBefore=$wrapBefore;
128
		return $this;
129
	}
130
131
	protected function setWrapAfter($wrapAfter) {
132
		$this->_wrapAfter=$wrapAfter;
133
		return $this;
134
	}
135
136
	public function getTagName() {
137
		return $this->tagName;
138
	}
139
140
	public function setTagName($tagName) {
141
		$this->tagName=$tagName;
142
		return $this;
143
	}
144
145
	public function fromArray($array) {
146 View Code Duplication
		foreach ( $this as $key => $value ) {
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...
147
			if(array_key_exists($key, $array)===true)
148
				$this->_callSetter("set" . ucfirst($key), $key, $array[$key], $array);
149
		}
150 View Code Duplication
		foreach ( $array as $key => $value ) {
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...
151
			if($this->_callSetter($key, $key, $value, $array)===false){
152
				$this->_callSetter("set" . ucfirst($key), $key, $value, $array);
153
			}
154
		}
155
		return $array;
156
	}
157
158
	public function fromDatabaseObjects($objects, $function) {
159
		if (isset($objects)) {
160
			foreach ( $objects as $object ) {
161
				$this->fromDatabaseObject($object, $function);
162
			}
163
		}
164
		return $this;
165
	}
166
167
	public function fromDatabaseObject($object, $function) {
168
	}
169
170
	public function wrap($before, $after="") {
171
		if (isset($before)) {
172
			array_unshift($this->_wrapBefore, $before);
173
		}
174
		$this->_wrapAfter[]=$after;
175
		return $this;
176
	}
177
178
179
180
	public function getElementById($identifier, $elements) {
181
		return $this->_getElementBy(function(BaseWidget $element) use ($identifier){return $element->getIdentifier()===$identifier;}, $elements);
182
	}
183
184
	public function getBsComponent() {
185
		return $this->_bsComponent;
186
	}
187
188
	public function setBsComponent($bsComponent) {
189
		$this->_bsComponent=$bsComponent;
190
		return $this;
191
	}
192
193
	protected function compile_once(JsUtils $js=NULL, &$view=NULL) {
194
		if(!$this->_compiled){
195
			if(isset($js)){
196
				$beforeCompile=$js->getParam("beforeCompileHtml");
197
				if(\is_callable($beforeCompile)){
198
					$beforeCompile($this,$js,$view);
199
				}
200
			}
201
			if(\is_callable($this->_preCompile)){
202
				$pc=$this->_preCompile;
203
				$pc();
204
			}
205
			$this->_compiled=true;
206
		}
207
	}
208
209
	public function compile(JsUtils $js=NULL, &$view=NULL) {
210
		$this->compile_once($js,$view);
211
		$result=$this->getTemplate($js);
212
		foreach ( $this as $key => $value ) {
213
			if (JString::startswith($key, "_") === false && $key !== "events") {
214
				if (\is_array($value)) {
215
					$v=PropertyWrapper::wrap($value, $js);
216
				} else {
217
					$v=$value;
218
				}
219
				$result=str_ireplace("%" . $key . "%", $v, $result);
220
			}
221
		}
222
		if (isset($js)===true) {
223
			$this->run($js);
224
			if (isset($view) === true) {
225
				$js->addViewElement($this->_identifier, $result, $view);
226
			}
227
		}
228
		if(\is_callable($this->_postCompile)){
229
			$pc=$this->_postCompile;
230
			$pc();
231
		}
232
		return $result;
233
	}
234
235
	public function __toString() {
236
		return $this->compile();
237
	}
238
239
	public function onPostCompile($callback){
240
		$this->_postCompile=$callback;
241
	}
242
243
	public function onPreCompile($callback){
244
		$this->_preCompile=$callback;
245
	}
246
}
247