Completed
Push — master ( d27f99...f4e97d )
by Jean-Christophe
03:35
created

Jquery   B

Complexity

Total Complexity 47

Size/Duplication

Total Lines 306
Duplicated Lines 6.21 %

Coupling/Cohesion

Components 2
Dependencies 4

Importance

Changes 0
Metric Value
wmc 47
lcom 2
cbo 4
dl 19
loc 306
rs 8.439
c 0
b 0
f 0

20 Methods

Rating   Name   Duplication   Size   Complexity  
A ui() 0 6 2
A bootstrap() 0 6 2
A semantic() 0 6 2
A __construct() 0 7 2
A inline() 0 7 2
A _open_script() 0 5 2
A _close_script() 0 3 1
A _setAjaxLoader() 0 3 1
A _output() 0 11 3
A _genericCallValue() 11 11 3
A _genericCallElement() 8 8 2
A sortable() 0 13 3
A tablesorter() 0 3 1
B _add_event() 0 18 6
B _compile() 0 29 5
A _compileLibrary() 0 7 3
A _addToCompile() 0 3 1
A _clear_compile() 0 3 1
A _document_ready() 0 11 3
B minify() 0 24 2

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

1
<?php
2
3
namespace Ajax;
4
5
use Ajax\common\traits\JqueryEventsTrait;
6
use Ajax\common\traits\JqueryAjaxTrait;
7
use Ajax\common\traits\JqueryActionsTrait;
8
use Ajax\service\Javascript;
9
10
/**
11
 * jQuery Class
12
 *
13
 * @author jcheron
14
 * @version 1.002
15
 * @license Apache 2 http://www.apache.org/licenses/
16
 **/
17
class Jquery {
18
	use JqueryEventsTrait,JqueryAjaxTrait,JqueryActionsTrait;
19
	protected $_ui;
20
	protected $_bootstrap;
21
	protected $_semantic;
22
	protected $jquery_code_for_compile=array ();
23
	protected $jsUtils;
24
	protected $params;
25
26
	protected $jquery_events=array (
27
			"bind","blur","change","click","dblclick","delegate","die","error","focus","focusin","focusout","hover","keydown","keypress","keyup","live","load","mousedown","mousseenter","mouseleave","mousemove","mouseout","mouseover","mouseup","off","on","one","ready","resize","scroll","select","submit","toggle","trigger","triggerHandler","undind","undelegate","unload"
28
	);
29
30
	public function ui($ui=NULL) {
31
		if ($ui!==NULL) {
32
			$this->_ui=$ui;
33
		}
34
		return $this->_ui;
35
	}
36
37
	public function bootstrap($bootstrap=NULL) {
38
		if ($bootstrap!==NULL) {
39
			$this->_bootstrap=$bootstrap;
40
		}
41
		return $this->_bootstrap;
42
	}
43
44
	public function semantic($semantic=NULL) {
45
		if ($semantic!==NULL) {
46
			$this->_semantic=$semantic;
47
		}
48
		return $this->_semantic;
49
	}
50
51
	public function __construct($params,$jsUtils) {
52
		$this->params=array();
53
		foreach ( $params as $key => $val ) {
54
				$this->params[$key]=$params[$key];
55
		}
56
		$this->jsUtils=$jsUtils;
57
	}
58
59
	/**
60
	 * Inline
61
	 *
62
	 * Outputs a <script> tag
63
	 *
64
	 * @access public
65
	 * @param string $script
66
	 * @param boolean $cdata a CDATA section should be added
67
	 * @return string
68
	 */
69
	public function inline($script, $cdata=TRUE) {
70
		$str=$this->_open_script();
71
		$str.=($cdata) ? "\n// <![CDATA[\n{$script}\n// ]]>\n" : "\n{$script}\n";
72
		$str.=$this->_close_script();
73
74
		return $str;
75
	}
76
77
	/**
78
	 * Open Script
79
	 *
80
	 * Outputs an opening <script>
81
	 *
82
	 * @access private
83
	 * @param string $src
84
	 * @return string
85
	 */
86
	private function _open_script($src='') {
87
		$str='<script type="text/javascript" ';
88
		$str.=($src=='') ? '>' : ' src="'.$src.'">';
89
		return $str;
90
	}
91
92
	/**
93
	 * Close Script
94
	 *
95
	 * Outputs an closing </script>
96
	 *
97
	 * @param string
98
	 * @return string
99
	 */
100
	private function _close_script($extra="\n") {
101
		return "</script>{$extra}";
102
	}
103
104
	public function _setAjaxLoader($loader) {
105
		$this->ajaxLoader=$loader;
106
	}
107
108
	/**
109
	 * Outputs script directly
110
	 *
111
	 * @param string The element to attach the event to
112
	 * @param string The code to execute
113
	 * @return string
114
	 */
115
	public function _output($array_js='') {
116
		if (!is_array($array_js)) {
117
			$array_js=array (
118
					$array_js
119
			);
120
		}
121
122
		foreach ( $array_js as $js ) {
123
			$this->jquery_code_for_compile[]="\t$js\n";
124
		}
125
	}
126
127
	/**
128
	 * Execute a generic jQuery call with a value.
129
	 * @param string $jQueryCall
130
	 * @param string $element
131
	 * @param string $param
132
	 * @param boolean $immediatly delayed if false
133
	 */
134 View Code Duplication
	public function _genericCallValue($jQueryCall,$element='this', $param="", $immediatly=false) {
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...
135
		$element=Javascript::prep_element($element);
136
		if (isset($param)) {
137
			$param=Javascript::prep_value($param);
138
			$str="$({$element}).{$jQueryCall}({$param});";
139
		} else
140
			$str="$({$element}).{$jQueryCall}();";
141
			if ($immediatly)
142
				$this->jquery_code_for_compile[]=$str;
143
			return $str;
144
	}
145
	/**
146
	 * Execute a generic jQuery call with 2 elements.
147
	 * @param string $jQueryCall
148
	 * @param string $to
149
	 * @param string $element
150
	 * @param boolean $immediatly delayed if false
151
	 * @return string
152
	 */
153 View Code Duplication
	public function _genericCallElement($jQueryCall,$to='this', $element, $immediatly=false) {
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...
154
		$to=Javascript::prep_element($to);
155
		$element=Javascript::prep_element($element);
156
		$str="$({$to}).{$jQueryCall}({$element});";
157
		if ($immediatly)
158
			$this->jquery_code_for_compile[]=$str;
159
			return $str;
160
	}
161
162
	/**
163
	 * Creates a jQuery sortable
164
	 *
165
	 * @param string $element
166
	 * @param array $options
167
	 * @return void
168
	 */
169
	public function sortable($element, $options=array()) {
170
		if (count($options)>0) {
171
			$sort_options=array ();
172
			foreach ( $options as $k => $v ) {
173
				$sort_options[]="\n\t\t".$k.': '.$v."";
174
			}
175
			$sort_options=implode(",", $sort_options);
176
		} else {
177
			$sort_options='';
178
		}
179
180
		return "$(".Javascript::prep_element($element).").sortable({".$sort_options."\n\t});";
181
	}
182
183
	/**
184
	 * Table Sorter Plugin
185
	 *
186
	 * @param string $table table name
187
	 * @param string $options plugin location
188
	 * @return string
189
	 */
190
	public function tablesorter($table='', $options='') {
191
		$this->jquery_code_for_compile[]="\t$(".Javascript::prep_element($table).").tablesorter($options);\n";
192
	}
193
194
	/**
195
	 * Constructs the syntax for an event, and adds to into the array for compilation
196
	 *
197
	 * @param string $element The element to attach the event to
198
	 * @param string $js The code to execute
199
	 * @param string $event The event to pass
200
	 * @param boolean $preventDefault If set to true, the default action of the event will not be triggered.
201
	 * @param boolean $stopPropagation Prevents the event from bubbling up the DOM tree, preventing any parent handlers from being notified of the event.
202
	 * @return string
203
	 */
204
	public function _add_event($element, $js, $event, $preventDefault=false, $stopPropagation=false,$immediatly=true) {
205
		if (is_array($js)) {
206
			$js=implode("\n\t\t", $js);
207
		}
208
		if ($preventDefault===true) {
209
			$js="event.preventDefault();\n".$js;
210
		}
211
		if ($stopPropagation===true) {
212
			$js="event.stopPropagation();\n".$js;
213
		}
214
		if (array_search($event, $this->jquery_events)===false)
215
			$event="\n\t$(".Javascript::prep_element($element).").bind('{$event}',function(event){\n\t\t{$js}\n\t});\n";
216
		else
217
			$event="\n\t$(".Javascript::prep_element($element).").{$event}(function(event){\n\t\t{$js}\n\t});\n";
218
		if($immediatly)
219
			$this->jquery_code_for_compile[]=$event;
220
		return $event;
221
	}
222
223
	/**
224
	 * As events are specified, they are stored in an array
225
	 * This function compiles them all for output on a page
226
	 * @param view $view
227
	 * @param string $view_var
228
	 * @param boolean $script_tags
229
	 * @return string
230
	 */
231
	public function _compile(&$view=NULL, $view_var='script_foot', $script_tags=TRUE) {
232
		// Components UI
233
		$this->_compileLibrary($this->ui());
234
		// Components BS
235
		$this->_compileLibrary($this->bootstrap());
236
		// Components Semantic
237
		$this->_compileLibrary($this->semantic());
238
239
		if (\sizeof($this->jquery_code_for_compile)==0) {
240
			// no inline references, let's just return
241
			return;
242
		}
243
244
		// Inline references
245
		$script='$(document).ready(function() {'."\n";
246
		$script.=implode('', $this->jquery_code_for_compile);
247
		$script.='});';
248
249
		$this->jquery_code_for_compile=array();
250
		if($this->params["debug"]==false){
251
			$script=$this->minify($script);
252
		}
253
		$output=($script_tags===FALSE) ? $script : $this->inline($script);
254
255
		if ($view!==NULL){
256
			$this->jsUtils->createScriptVariable($view,$view_var, $output);
257
		}
258
		return $output;
259
	}
260
261
	private function _compileLibrary($library){
262
		if ($library!=NULL) {
263
			if ($library->isAutoCompile()) {
264
				$library->compile(true);
265
			}
266
		}
267
	}
268
269
	public function _addToCompile($jsScript) {
270
		$this->jquery_code_for_compile[]=$jsScript;
271
	}
272
273
	/**
274
	 * Clears the array of script events collected for output
275
	 *
276
	 * @return void
277
	 */
278
	public function _clear_compile() {
279
		$this->jquery_code_for_compile=array ();
280
	}
281
282
	/**
283
	 * A wrapper for writing document.ready()
284
	 * @return string
285
	 */
286
	public function _document_ready($js) {
287
		if (!is_array($js)) {
288
			$js=array (
289
					$js
290
			);
291
		}
292
293
		foreach ( $js as $script ) {
294
			$this->jquery_code_for_compile[]=$script;
295
		}
296
	}
297
298
	private function minify($input) {
299
	if(trim($input) === "") return $input;
300
	return preg_replace(
301
			array(
302
					// Remove comment(s)
303
					'#\s*("(?:[^"\\\]++|\\\.)*+"|\'(?:[^\'\\\\]++|\\\.)*+\')\s*|\s*\/\*(?!\!|@cc_on)(?>[\s\S]*?\*\/)\s*|\s*(?<![\:\=])\/\/.*(?=[\n\r]|$)|^\s*|\s*$#',
304
					// Remove white-space(s) outside the string and regex
305
					'#("(?:[^"\\\]++|\\\.)*+"|\'(?:[^\'\\\\]++|\\\.)*+\'|\/\*(?>.*?\*\/)|\/(?!\/)[^\n\r]*?\/(?=[\s.,;]|[gimuy]|$))|\s*([!%&*\(\)\-=+\[\]\{\}|;:,.<>?\/])\s*#s',
306
					// Remove the last semicolon
307
					'#;+\}#',
308
					// Minify object attribute(s) except JSON attribute(s). From `{'foo':'bar'}` to `{foo:'bar'}`
309
					'#([\{,])([\'])(\d+|[a-z_][a-z0-9_]*)\2(?=\:)#i',
310
					// --ibid. From `foo['bar']` to `foo.bar`
311
					'#([a-z0-9_\)\]])\[([\'"])([a-z_][a-z0-9_]*)\2\]#i'
312
			),
313
			array(
314
					'$1',
315
					'$1$2',
316
					'}',
317
					'$1$3',
318
					'$1.$3'
319
			),
320
			$input);
321
	}
322
}
323