Passed
Push — master ( 489ec7...331007 )
by Jean-Christophe
03:41
created

BaseHtml   F

Complexity

Total Complexity 69

Size/Duplication

Total Lines 283
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
dl 0
loc 283
rs 2.8301
c 0
b 0
f 0
wmc 69

29 Methods

Rating   Name   Duplication   Size   Complexity  
B fromArray() 0 11 5
B _getElementBy() 0 17 8
A setWrapBefore() 0 3 1
A fromDatabaseObject() 0 1 1
A fromDatabaseObjects() 0 7 3
A getTagName() 0 2 1
A setTagName() 0 3 1
A getElementById() 0 2 1
A setBsComponent() 0 3 1
A addToMember() 0 3 1
A removeOldValues() 0 3 1
A setWrapAfter() 0 3 1
A getBsComponent() 0 2 1
A wrap() 0 6 2
A addToMemberUnique() 0 6 2
A onPreCompile() 0 2 1
A setDraggable() 0 9 3
A asDropZone() 0 6 1
A onPostCompile() 0 2 1
A __toString() 0 2 1
A addToMemberCtrl() 0 7 2
A ctrl() 0 11 4
A _callSetter() 0 12 4
A setMemberCtrl() 0 4 1
A getTemplate() 0 2 1
D compile() 0 29 9
A callCallback() 0 7 4
A addCallback() 0 9 3
A compile_once() 0 11 4

How to fix   Complexity   

Complex Class

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.

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
use Ajax\service\Javascript;
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 $_runned=false;
26
	protected $_postCompile;
27
	protected $_preCompile;
28
29
	/**
30
	 *
31
	 * @param JsUtils $js
32
	 * @return SimpleExtComponent
33
	 */
34
	abstract public function run(JsUtils $js);
35
36
	private function _callSetter($setter,$key,$value,&$array){
37
		$result=false;
38
		if (method_exists($this, $setter) && substr($setter, 0, 1) !== "_") {
39
			try {
40
				$this->$setter($value);
41
				unset($array[$key]);
42
				$result=true;
43
			} catch ( \Exception $e ) {
44
				$result=false;
45
			}
46
		}
47
		return $result;
48
	}
49
50
	protected function getTemplate(JsUtils $js=NULL,$view=null) {
51
		return PropertyWrapper::wrap($this->_wrapBefore, $js,$view) . $this->_template . PropertyWrapper::wrap($this->_wrapAfter, $js,$view);
52
	}
53
54
	protected function ctrl($name, $value, $typeCtrl) {
55
		if (\is_array($typeCtrl)) {
56
			if (array_search($value, $typeCtrl) === false) {
57
				throw new \Exception("La valeur passée `" . $value . "` à la propriété `" . $name . "` ne fait pas partie des valeurs possibles : {" . implode(",", $typeCtrl) . "}");
58
			}
59
		} else {
60
			if (!$typeCtrl($value)) {
61
				throw new \Exception("La fonction " . $typeCtrl . " a retourné faux pour l'affectation de la propriété " . $name);
62
			}
63
		}
64
		return true;
65
	}
66
67
68
69
	protected function setMemberCtrl(&$name, $value, $typeCtrl) {
70
		$this->ctrl($name, $value, $typeCtrl);
71
		$name=$value;
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
		$this->ctrl($name, $value, $typeCtrl);
87
		if (\is_array($typeCtrl)) {
88
			$this->removeOldValues($name, $typeCtrl);
89
		}
90
		$name.=$separator . $value;
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
		foreach ( $this as $key => $value ) {
146
			if(array_key_exists($key, $array)===true)
147
				$this->_callSetter("set" . ucfirst($key), $key, $array[$key], $array);
148
		}
149
		foreach ( $array as $key => $value ) {
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
			$this->callCallback($this->_preCompile);
201
			unset($this->properties["jsCallback"]);
202
			$this->_compiled=true;
203
		}
204
	}
205
206
	public function compile(JsUtils $js=NULL, &$view=NULL) {
207
		$this->compile_once($js,$view);
208
		$result=$this->getTemplate($js,$view);
209
		foreach ( $this as $key => $value ) {
210
				if(\strstr($result, "%{$key}%")!==false){
211
					if (\is_array($value)) {
212
						$v=PropertyWrapper::wrap($value, $js,$view);
213
					}elseif($value instanceof \stdClass){
214
							$v=\print_r($value,true);
215
					}elseif ($value instanceof BaseHtml){
216
						$v=$value->compile($js,$view);
217
					}else{
218
						$v=$value;
219
					}
220
					$result=str_replace("%{$key}%", $v, $result);
221
				}
222
		}
223
		if (isset($js)===true) {
224
			$this->run($js);
225
			if (isset($view) === true) {
226
				$js->addViewElement($this->_identifier, $result, $view);
227
			}
228
		}
229
230
		if(\is_callable($this->_postCompile)){
231
			$pc=$this->_postCompile;
232
			$pc($this);
233
		}
234
		return $result;
235
	}
236
	
237
	/**
238
	 * Sets the element draggable, and eventualy defines the dropzone (HTML5 drag and drop)
239
	 * @param string $attr default: "id"
240
	 * @param BaseHtml $dropZone the dropzone element
241
	 * @param array $parameters default: ["jsCallback"=>"","jqueryDone"=>"append"]
242
	 * @return \Ajax\common\html\BaseHtml
243
	 */
244
	public function setDraggable($attr="id",$dropZone=null,$parameters=[]){
245
		$this->setProperty("draggable", "true");
246
		$this->addEvent("dragstart",Javascript::draggable($attr));
247
		if(isset($dropZone)&& $dropZone instanceof BaseHtml){
248
			$jqueryDone="append";$jsCallback="";
249
			extract($parameters);
250
			$dropZone->asDropZone($jsCallback,$jqueryDone,$parameters);
251
		}
252
		return $this;
253
	}
254
	
255
	/**
256
	 * Declares the element as a drop zone (HTML5 drag and drop)
257
	 * @param string $jsCallback
258
	 * @param string $jqueryDone
259
	 * @param array $parameters
260
	 * @return \Ajax\common\html\BaseHtml
261
	 */
262
	public function asDropZone($jsCallback="",$jqueryDone="append",$parameters=[]){
263
		$stopPropagation=false;
264
		$this->addEvent("dragover", '', $stopPropagation,true);
265
		extract($parameters);
266
		$this->addEvent("drop",Javascript::dropZone($jqueryDone,$jsCallback),$stopPropagation,true);
267
		return $this;
268
	}
269
270
	public function __toString() {
271
		return $this->compile();
272
	}
273
274
	public function onPostCompile($callback){
275
		$this->_postCompile=$callback;
276
	}
277
278
	public function onPreCompile($callback){
279
		$this->_preCompile=$this->addCallback($this->_preCompile, $callback);
280
	}
281
	
282
	private function addCallback($originalValue,$callback){
283
		if(isset($originalValue)){
284
			if(!is_array($originalValue)){
285
				$result=[$originalValue];
286
			}
287
			$result[]=$callback;
288
			return $result;
289
		}
290
		return $callback;
291
	}
292
	
293
	private function callCallback($callable){
294
		if(\is_callable($callable)){
295
			return $callable($this);
296
		}
297
		if(is_array($callable)){
298
			foreach ($callable as $call){
299
				$this->callCallback($call);
300
			}
301
		}
302
	}
303
}
304