Completed
Push — master ( f99fed...57dceb )
by Jean-Christophe
03:29
created

JqueryAjaxTrait   B

Complexity

Total Complexity 47

Size/Duplication

Total Lines 287
Duplicated Lines 16.72 %

Coupling/Cohesion

Components 1
Dependencies 2

Importance

Changes 0
Metric Value
wmc 47
lcom 1
cbo 2
dl 48
loc 287
rs 8.439
c 0
b 0
f 0

18 Methods

Rating   Name   Duplication   Size   Complexity  
_add_event() 0 1 ?
A addLoading() 0 11 2
A _get() 0 3 1
A _post() 0 3 1
B _ajax() 0 15 5
B _getAjaxUrl() 0 16 7
B _getOnAjaxDone() 0 16 5
A _getResponseElement() 0 6 2
B _correctAjaxUrl() 0 8 5
A _json() 0 13 3
A _jsonOn() 12 12 1
A setAjaxDataCall() 0 9 2
B _jsonArray() 0 23 4
A _jsonArrayOn() 12 12 1
B _postForm() 0 22 5
A _getOn() 12 12 1
A _postOn() 12 12 1
A _postFormOn() 0 13 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 JqueryAjaxTrait 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 JqueryAjaxTrait, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace Ajax\common\traits;
4
5
use Ajax\service\JString;
6
use Ajax\service\Javascript;
7
use Ajax\service\AjaxTransition;
8
9
10
/**
11
 * @author jc
12
 * @property array $jquery_code_for_compile
13
 * @property Ajax\JsUtils $jsUtils
14
 * @property array $params
15
 */
16
trait JqueryAjaxTrait {
17
	protected $ajaxTransition;
18
	protected $ajaxLoader='<span></span><span></span><span></span><span></span><span></span>';
19
20
	abstract public function _add_event($element, $js, $event, $preventDefault=false, $stopPropagation=false,$immediatly=true);
21
	protected function addLoading(&$retour, $responseElement) {
22
		$loading_notifier='<div class="ajax-loader">';
23
		if ($this->ajaxLoader=='') {
24
			$loading_notifier.="Loading...";
25
		} else {
26
			$loading_notifier.=$this->ajaxLoader;
27
		}
28
		$loading_notifier.='</div>';
29
		$retour.="$({$responseElement}).empty();\n";
30
		$retour.="\t\t$({$responseElement}).prepend('{$loading_notifier}');\n";
31
	}
32
33
	public function _get($url, $params="{}", $responseElement="", $jsCallback=NULL, $attr="id", $hasLoader=true,$jqueryDone="html",$ajaxTransition=null,$immediatly=false) {
34
		return $this->_ajax("get", $url,$params,$responseElement,$jsCallback,$attr,$hasLoader,$jqueryDone,$ajaxTransition,$immediatly);
35
	}
36
	public function _post($url, $params="{}", $responseElement="", $jsCallback=NULL, $attr="id", $hasLoader=true,$jqueryDone="html",$ajaxTransition=null,$immediatly=false) {
37
		return $this->_ajax("post", $url,$params,$responseElement,$jsCallback,$attr,$hasLoader,$jqueryDone,$ajaxTransition,$immediatly);
38
	}
39
40
	protected function _ajax($method,$url, $params="{}", $responseElement="", $jsCallback=NULL, $attr="id", $hasLoader=true,$jqueryDone="html",$ajaxTransition=null,$immediatly=false) {
41
		if(JString::isNull($params)){$params="{}";}
42
		$jsCallback=isset($jsCallback) ? $jsCallback : "";
43
		$retour=$this->_getAjaxUrl($url, $attr);
44
		$responseElement=$this->_getResponseElement($responseElement);
45
		$retour.="var self=this;\n";
46
		if($hasLoader===true){
47
			$this->addLoading($retour, $responseElement);
48
		}
49
		$retour.="$.".$method."(url,".$params.").done(function( data ) {\n";
50
		$retour.=$this->_getOnAjaxDone($responseElement, $jqueryDone,$ajaxTransition,$jsCallback)."});\n";
51
		if ($immediatly)
52
			$this->jquery_code_for_compile[]=$retour;
53
		return $retour;
54
	}
55
56
	protected function setAjaxDataCall($params){
57
		$result=null;
58
		if(!\is_callable($params)){
59
			$result=function ($responseElement,$jqueryDone="html") use($params){
60
				return AjaxTransition::{$params}($responseElement,$jqueryDone);
61
			};
62
		}
63
		return $result;
64
	}
65
66
	protected function _getAjaxUrl($url,$attr){
67
		$url=$this->_correctAjaxUrl($url);
68
		$retour="url='".$url."';";
69
		$slash="/";
70
		if(JString::endswith($url, "/")===true)
71
			$slash="";
72
		if(JString::isNotNull($attr)){
73
			if ($attr==="value")
74
				$retour.="url=url+'".$slash."'+$(this).val();\n";
75
			elseif ($attr==="html")
76
			$retour.="url=url+'".$slash."'+$(this).html();\n";
77
			elseif($attr!=null && $attr!=="")
78
					$retour.="url=url+'".$slash."'+($(this).attr('".$attr."')||'');\n";
79
		}
80
		return $retour;
81
	}
82
83
	protected function _getOnAjaxDone($responseElement,$jqueryDone,$ajaxTransition,$jsCallback){
84
		$retour="";$call=null;
85
		if ($responseElement!=="") {
86
			if(isset($ajaxTransition)){
87
				$call=$this->setAjaxDataCall($ajaxTransition);
88
			}elseif(isset($this->ajaxTransition)){
89
				$call=$this->ajaxTransition;
90
			}
91
			if(\is_callable($call))
92
				$retour="\t".$call($responseElement,$jqueryDone).";\n";
93
			else
94
				$retour="\t$({$responseElement}).{$jqueryDone}( data );\n";
95
		}
96
		$retour.="\t".$jsCallback."\n";
97
		return $retour;
98
	}
99
100
	protected function _getResponseElement($responseElement){
101
		if ($responseElement!=="") {
102
			$responseElement=Javascript::prep_value($responseElement);
103
		}
104
		return $responseElement;
105
	}
106
107
	protected function _correctAjaxUrl($url) {
108
		if ($url!=="/" && JString::endsWith($url, "/")===true)
109
			$url=substr($url, 0, strlen($url)-1);
110
		if (strncmp($url, 'http://', 7)!=0&&strncmp($url, 'https://', 8)!=0) {
111
			$url=$this->jsUtils->getUrl($url);
112
		}
113
		return $url;
114
	}
115
116
	/**
117
	 * Makes an ajax request and receives the JSON data types by assigning DOM elements with the same name
118
	 * @param string $url the request address
119
	 * @param string $params Paramètres passés au format JSON
120
	 * @param string $method Method use
121
	 * @param string $jsCallback javascript code to execute after the request
122
	 * @param boolean $immediatly
123
	 */
124
	public function _json($url, $method="get", $params="{}", $jsCallback=NULL, $attr="id", $context="document",$immediatly=false) {
125
		$jsCallback=isset($jsCallback) ? $jsCallback : "";
126
		$retour=$this->_getAjaxUrl($url, $attr);
127
		$retour.="$.{$method}(url,".$params.").done(function( data ) {\n";
128
		$retour.="\tdata=$.parseJSON(data);for(var key in data){"
129
				."if($('#'+key,".$context.").length){ if($('#'+key,".$context.").is('[value]')) { $('#'+key,".$context.").val(data[key]);} else { $('#'+key,".$context.").html(data[key]); }}};\n";
130
				$retour.="\t".$jsCallback."\n".
131
						"\t$(document).trigger('jsonReady',[data]);\n".
132
						"});\n";
133
				if ($immediatly)
134
					$this->jquery_code_for_compile[]=$retour;
135
					return $retour;
136
	}
137
138
	/**
139
	 * Makes an ajax request and receives the JSON data types by assigning DOM elements with the same name when $event fired on $element
140
	 * @param string $element
141
	 * @param string $event
142
	 * @param string $url the request address
143
	 * @param array $parameters default : array("preventDefault"=>true,"stopPropagation"=>true,"jsCallback"=>NULL,"attr"=>"id","params"=>"{}","method"=>"get","immediatly"=>true)
144
	 */
145 View Code Duplication
	public function _jsonOn($event,$element, $url,$parameters=array()) {
0 ignored issues
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...
146
		$preventDefault=true;
147
		$stopPropagation=true;
148
		$jsCallback=null;
149
		$attr="id";
150
		$method="get";
151
		$context="document";
152
		$params="{}";
153
		$immediatly=true;
154
		extract($parameters);
155
		return $this->_add_event($element, $this->_json($url,$method, $params,$jsCallback, $attr,$context), $event, $preventDefault, $stopPropagation,$immediatly);
156
	}
157
158
	/**
159
	 * Makes an ajax request and receives a JSON array data types by copying and assigning them to the DOM elements with the same name
160
	 * @param string $url the request address
161
	 * @param string $params Paramètres passés au format JSON
162
	 * @param string $method Method use
163
	 * @param string $jsCallback javascript code to execute after the request
164
	 * @param string $context jquery DOM element, array container.
165
	 * @param boolean $immediatly
166
	 */
167
	public function _jsonArray($maskSelector, $url, $method="get", $params="{}", $jsCallback=NULL, $attr="id", $context=null,$immediatly=false) {
168
		$jsCallback=isset($jsCallback) ? $jsCallback : "";
169
		$retour=$this->_getAjaxUrl($url, $attr);
170
		if($context===null){
171
			$parent="$('".$maskSelector."').parent()";
172
			$newElm = "$('#'+newId)";
173
		}else{
174
			$parent=$context;
175
			$newElm = $context.".find('#'+newId)";
176
		}
177
		$appendTo="\t\tnewElm.appendTo(".$parent.");\n";
178
		$retour.="var self = $(this);\n$.{$method}(url,".$params.").done(function( data ) {\n";
179
		$retour.=$parent.".find('._json').remove();";
180
		$retour.="\tdata=$.parseJSON(data);$.each(data, function(index, value) {\n"."\tvar created=false;var maskElm=$('".$maskSelector."').first();maskElm.hide();"."\tvar newId=(maskElm.attr('id') || 'mask')+'-'+index;"."\tvar newElm=".$newElm.";\n"."\tif(!newElm.length){\n"."\t\tnewElm=maskElm.clone();
181
				newElm.attr('id',newId);\n;newElm.addClass('_json').removeClass('_jsonArrayModel');\nnewElm.find('[id]').each(function(){ var newId=$(this).attr('id')+'-'+index;$(this).attr('id',newId).removeClass('_jsonArrayChecked');});\n";
182
		$retour.= $appendTo;
183
		$retour.="\t}\n"."\tfor(var key in value){\n"."\t\t\tvar html = $('<div />').append($(newElm).clone()).html();\n"."\t\t\tif(html.indexOf('__'+key+'__')>-1){\n"."\t\t\t\tcontent=$(html.split('__'+key+'__').join(value[key]));\n"."\t\t\t\t$(newElm).replaceWith(content);newElm=content;\n"."\t\t\t}\n"."\t\tvar sel='[data-id=\"'+key+'\"]';if($(sel,newElm).length){\n"."\t\t\tvar selElm=$(sel,newElm);\n"."\t\t\t if(selElm.is('[value]')) { selElm.attr('value',value[key]);selElm.val(value[key]);} else { selElm.html(value[key]); }\n"."\t\t}\n"."}\n"."\t$(newElm).show(true);"."\n"."\t$(newElm).removeClass('hide');"."});\n";
184
		$retour.="\t$(document).trigger('jsonReady',[data]);\n";
185
		$retour.="\t".$jsCallback."\n"."});\n";
186
		if ($immediatly)
187
			$this->jquery_code_for_compile[]=$retour;
188
			return $retour;
189
	}
190
	/**
191
	 * Makes an ajax request and receives the JSON data types by assigning DOM elements with the same name when $event fired on $element
192
	 * @param string $element
193
	 * @param string $event
194
	 * @param string $url the request address
195
	 * @param array $parameters default : array("preventDefault"=>true,"stopPropagation"=>true,"jsCallback"=>NULL,"attr"=>"id","params"=>"{}","method"=>"get", "context"=>null)
196
	 */
197 View Code Duplication
	public function _jsonArrayOn($event,$element, $maskSelector,$url,$parameters=array()) {
0 ignored issues
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...
198
		$preventDefault=true;
199
		$stopPropagation=true;
200
		$jsCallback=null;
201
		$attr="id";
202
		$method="get";
203
		$context = null;
204
		$params="{}";
205
		$immediatly=true;
206
		extract($parameters);
207
		return $this->_add_event($element, $this->_jsonArray($maskSelector,$url,$method, $params,$jsCallback, $attr, $context), $event, $preventDefault, $stopPropagation,$immediatly);
208
	}
209
210
	public function _postForm($url, $form, $responseElement, $validation=false, $jsCallback=NULL, $attr="id", $hasLoader=true,$jqueryDone="html",$ajaxTransition=null,$immediatly=false) {
211
		$jsCallback=isset($jsCallback) ? $jsCallback : "";
212
		$retour=$this->_getAjaxUrl($url, $attr);
213
		$retour.="\nvar params=$('#".$form."').serialize();\n";
214
		$responseElement=$this->_getResponseElement($responseElement);
215
		$retour.="var self=this;\n";
216
		if($hasLoader===true){
217
			$this->addLoading($retour, $responseElement);
218
		}
219
		$retour.="$.post(url,params).done(function( data ) {\n";
220
		$retour.=$this->_getOnAjaxDone($responseElement, $jqueryDone,$ajaxTransition,$jsCallback)."});\n";
221
222
		if ($validation) {
223
			$retour="$('#".$form."').validate({submitHandler: function(form) {
224
			".$retour."
225
			}});\n";
226
			$retour.="$('#".$form."').submit();\n";
227
		}
228
		if ($immediatly)
229
			$this->jquery_code_for_compile[]=$retour;
230
			return $retour;
231
	}
232
233
	/**
234
	 * Effectue un get vers $url sur l'évènement $event de $element en passant les paramètres $params
235
	 * puis affiche le résultat dans $responseElement
236
	 * @param string $element
237
	 * @param string $event
238
	 * @param string $url
239
	 * @param string $params queryString parameters (JSON format). default : {}
240
	 * @param string $responseElement
241
	 * @param array $parameters default : array("preventDefault"=>true,"stopPropagation"=>true,"jsCallback"=>NULL,"attr"=>"id","hasLoader"=>true,"ajaxTransition"=>null,"jqueryDone"=>"html")
242
	 */
243 View Code Duplication
	public function _getOn($event,$element, $url, $params="{}", $responseElement="", $parameters=array()) {
0 ignored issues
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...
244
		$preventDefault=true;
245
		$stopPropagation=true;
246
		$jsCallback=null;
247
		$attr="id";
248
		$hasLoader=true;
249
		$immediatly=true;
250
		$jqueryDone="html";
251
		$ajaxTransition=null;
252
		extract($parameters);
253
		return $this->_add_event($element, $this->_get($url, $params, $responseElement, $jsCallback, $attr,$hasLoader,$jqueryDone,$ajaxTransition), $event, $preventDefault, $stopPropagation,$immediatly);
254
	}
255
256
	/**
257
	 * Effectue un post vers $url sur l'évènement $event de $element en passant les paramètres $params
258
	 * puis affiche le résultat dans $responseElement
259
	 * @param string $element
260
	 * @param string $event
261
	 * @param string $url
262
	 * @param string $params queryString parameters (JSON format). default : {}
263
	 * @param string $responseElement
264
	 * @param array $parameters default : array("preventDefault"=>true,"stopPropagation"=>true,"jsCallback"=>NULL,"attr"=>"id","hasLoader"=>true,"ajaxTransition"=>null)
265
	 */
266 View Code Duplication
	public function _postOn($event,$element, $url, $params="{}", $responseElement="", $parameters=array()) {
0 ignored issues
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...
267
		$preventDefault=true;
268
		$stopPropagation=true;
269
		$jsCallback=null;
270
		$attr="id";
271
		$hasLoader=true;
272
		$immediatly=true;
273
		$jqueryDone="html";
274
		$ajaxTransition=null;
275
		extract($parameters);
276
		return $this->_add_event($element, $this->_post($url, $params, $responseElement, $jsCallback, $attr,$hasLoader,$jqueryDone,$ajaxTransition), $event, $preventDefault, $stopPropagation,$immediatly);
277
	}
278
279
	/**
280
	 * Effectue un post vers $url sur l'évènement $event de $element en passant les paramètres du formulaire $form
281
	 * puis affiche le résultat dans $responseElement
282
	 * @param string $element
283
	 * @param string $event
284
	 * @param string $url
285
	 * @param string $form
286
	 * @param string $responseElement
287
	 * @param array $parameters default : array("preventDefault"=>true,"stopPropagation"=>true,"validation"=>false,"jsCallback"=>NULL,"attr"=>"id","hasLoader"=>true,"ajaxTransition"=>null,"immediatly"=>true)
288
	 */
289
	public function _postFormOn($event,$element, $url, $form, $responseElement="", $parameters=array()) {
290
		$preventDefault=true;
291
		$stopPropagation=true;
292
		$validation=false;
293
		$jsCallback=null;
294
		$attr="id";
295
		$hasLoader=true;
296
		$immediatly=true;
297
		$jqueryDone="html";
298
		$ajaxTransition=null;
299
		extract($parameters);
300
		return $this->_add_event($element, $this->_postForm($url, $form, $responseElement, $validation, $jsCallback, $attr,$hasLoader,$jqueryDone,$ajaxTransition), $event, $preventDefault, $stopPropagation,$immediatly);
301
	}
302
}