Completed
Push — master ( f662ec...5059ab )
by Jean-Christophe
02:58
created

BaseHtml   C

Complexity

Total Complexity 60

Size/Duplication

Total Lines 234
Duplicated Lines 7.69 %

Coupling/Cohesion

Components 1
Dependencies 4

Importance

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