Jquery   C
last analyzed

Complexity

Total Complexity 60

Size/Duplication

Total Lines 363
Duplicated Lines 6.61 %

Coupling/Cohesion

Components 2
Dependencies 3

Importance

Changes 0
Metric Value
wmc 60
c 0
b 0
f 0
lcom 2
cbo 3
dl 24
loc 363
rs 6.0975

22 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() 7 7 2
A _open_script() 0 5 2
A _close_script() 0 3 1
A setLibraryFile() 0 3 1
A _setAjaxLoader() 0 3 1
A _output() 0 11 3
A _genericCallValue() 11 11 3
A _genericCallElement() 0 8 2
A sortable() 0 13 3
A tablesorter() 0 3 1
B _add_event() 0 18 6
D _compile() 0 52 11
A _addToCompile() 0 3 1
A _clear_compile() 0 3 1
A _document_ready() 0 11 3
A _prep_element() 3 6 4
B _prep_value() 3 9 5
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
9
/**
10
 * JQuery Phalcon library
11
 *
12
 * @author jcheron
13
 * @version 1.002
14
 * @license Apache 2 http://www.apache.org/licenses/
15
 */
16
/**
17
 * jQuery Class
18
 */
19
class Jquery {
20
	use JqueryEventsTrait,JqueryAjaxTrait,JqueryActionsTrait;
21
	protected $_ui;
22
	protected $_bootstrap;
23
	protected $_semantic;
24
	protected $libraryFile;
25
	protected $_javascript_folder='js';
26
	protected $jquery_code_for_load=array ();
27
	protected $jquery_code_for_compile=array ();
28
	protected $jquery_corner_active=FALSE;
29
	protected $jquery_table_sorter_active=FALSE;
30
	protected $jquery_table_sorter_pager_active=FALSE;
31
	protected $jsUtils;
32
33
	protected $jquery_events=array (
34
			"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"
35
	);
36
37
	public function ui($ui=NULL) {
38
		if ($ui!==NULL) {
39
			$this->_ui=$ui;
40
		}
41
		return $this->_ui;
42
	}
43
44
	public function bootstrap($bootstrap=NULL) {
45
		if ($bootstrap!==NULL) {
46
			$this->_bootstrap=$bootstrap;
47
		}
48
		return $this->_bootstrap;
49
	}
50
51
	public function semantic($semantic=NULL) {
52
		if ($semantic!==NULL) {
53
			$this->_semantic=$semantic;
54
		}
55
		return $this->_semantic;
56
	}
57
58
	public function __construct($params,$jsUtils) {
59
		$this->params=array();
0 ignored issues
show
Bug introduced by
The property params does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
60
		foreach ( $params as $key => $val ) {
61
				$this->params[$key]=$params[$key];
62
		}
63
		$this->jsUtils=$jsUtils;
64
	}
65
66
	/**
67
	 * Inline
68
	 *
69
	 * Outputs a <script> tag
70
	 *
71
	 * @access public
72
	 * @param string $script
73
	 * @param boolean $cdata a CDATA section should be added
74
	 * @return string
75
	 */
76 View Code Duplication
	public function inline($script, $cdata=TRUE) {
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...
77
		$str=$this->_open_script();
78
		$str.=($cdata) ? "\n// <![CDATA[\n{$script}\n// ]]>\n" : "\n{$script}\n";
79
		$str.=$this->_close_script();
80
81
		return $str;
82
	}
83
84
	/**
85
	 * Open Script
86
	 *
87
	 * Outputs an opening <script>
88
	 *
89
	 * @access private
90
	 * @param string $src
91
	 * @return string
92
	 */
93
	private function _open_script($src='') {
94
		$str='<script type="text/javascript" ';
95
		$str.=($src=='') ? '>' : ' src="'.$src.'">';
96
		return $str;
97
	}
98
99
	/**
100
	 * Close Script
101
	 *
102
	 * Outputs an closing </script>
103
	 *
104
	 * @param string
105
	 * @return string
106
	 */
107
	private function _close_script($extra="\n") {
108
		return "</script>{$extra}";
109
	}
110
111
	public function setLibraryFile($name) {
112
		$this->libraryFile=$name;
113
	}
114
115
	public function _setAjaxLoader($loader) {
116
		$this->ajaxLoader=$loader;
117
	}
118
119
	/**
120
	 * Outputs script directly
121
	 *
122
	 * @param string The element to attach the event to
123
	 * @param string The code to execute
124
	 * @return string
125
	 */
126
	public function _output($array_js='') {
127
		if (!is_array($array_js)) {
128
			$array_js=array (
129
					$array_js
130
			);
131
		}
132
133
		foreach ( $array_js as $js ) {
134
			$this->jquery_code_for_compile[]="\t$js\n";
135
		}
136
	}
137
138
	/**
139
	 * Execute a generic jQuery call with a value.
140
	 * @param string $jQueryCall
141
	 * @param string $element
142
	 * @param string $param
143
	 * @param boolean $immediatly delayed if false
144
	 */
145 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...
146
		$element=$this->_prep_element($element);
147
		if (isset($param)) {
148
			$param=$this->_prep_value($param);
149
			$str="$({$element}).{$jQueryCall}({$param});";
150
		} else
151
			$str="$({$element}).{$jQueryCall}();";
152
			if ($immediatly)
153
				$this->jquery_code_for_compile[]=$str;
154
			return $str;
155
	}
156
	/**
157
	 * Execute a generic jQuery call with 2 elements.
158
	 * @param string $jQueryCall
159
	 * @param string $to
160
	 * @param string $element
161
	 * @param boolean $immediatly delayed if false
162
	 * @return string
163
	 */
164
	public function _genericCallElement($jQueryCall,$to='this', $element, $immediatly=false) {
165
		$to=$this->_prep_element($to);
166
		$element=$this->_prep_element($element);
167
		$str="$({$to}).{$jQueryCall}({$element});";
168
		if ($immediatly)
169
			$this->jquery_code_for_compile[]=$str;
170
			return $str;
171
	}
172
173
	/**
174
	 * Creates a jQuery sortable
175
	 *
176
	 * @param string $element
177
	 * @param array $options
178
	 * @return void
179
	 */
180
	public function sortable($element, $options=array()) {
181
		if (count($options)>0) {
182
			$sort_options=array ();
183
			foreach ( $options as $k => $v ) {
184
				$sort_options[]="\n\t\t".$k.': '.$v."";
185
			}
186
			$sort_options=implode(",", $sort_options);
187
		} else {
188
			$sort_options='';
189
		}
190
191
		return "$(".$this->_prep_element($element).").sortable({".$sort_options."\n\t});";
192
	}
193
194
	/**
195
	 * Table Sorter Plugin
196
	 *
197
	 * @param string $table table name
198
	 * @param string $options plugin location
199
	 * @return string
200
	 */
201
	public function tablesorter($table='', $options='') {
202
		$this->jquery_code_for_compile[]="\t$(".$this->_prep_element($table).").tablesorter($options);\n";
203
	}
204
205
	/**
206
	 * Constructs the syntax for an event, and adds to into the array for compilation
207
	 *
208
	 * @param string $element The element to attach the event to
209
	 * @param string $js The code to execute
210
	 * @param string $event The event to pass
211
	 * @param boolean $preventDefault If set to true, the default action of the event will not be triggered.
212
	 * @param boolean $stopPropagation Prevents the event from bubbling up the DOM tree, preventing any parent handlers from being notified of the event.
213
	 * @return string
214
	 */
215
	public function _add_event($element, $js, $event, $preventDefault=false, $stopPropagation=false,$immediatly=true) {
216
		if (is_array($js)) {
217
			$js=implode("\n\t\t", $js);
218
		}
219
		if ($preventDefault===true) {
220
			$js="event.preventDefault();\n".$js;
221
		}
222
		if ($stopPropagation===true) {
223
			$js="event.stopPropagation();\n".$js;
224
		}
225
		if (array_search($event, $this->jquery_events)===false)
226
			$event="\n\t$(".$this->_prep_element($element).").bind('{$event}',function(event){\n\t\t{$js}\n\t});\n";
227
		else
228
			$event="\n\t$(".$this->_prep_element($element).").{$event}(function(event){\n\t\t{$js}\n\t});\n";
229
		if($immediatly)
230
			$this->jquery_code_for_compile[]=$event;
231
		return $event;
232
	}
233
234
	/**
235
	 * As events are specified, they are stored in an array
236
	 * This function compiles them all for output on a page
237
	 * @param view $view
238
	 * @param string $view_var
239
	 * @param boolean $script_tags
240
	 * @return string
241
	 */
242
	public function _compile(&$view=NULL, $view_var='script_foot', $script_tags=TRUE) {
243
		// Components UI
244
		$ui=$this->ui();
245
		if ($this->ui()!=NULL) {
246
			if ($ui->isAutoCompile()) {
247
				$ui->compile(true);
248
			}
249
		}
250
251
		// Components BS
252
		$bootstrap=$this->bootstrap();
253
		if ($this->bootstrap()!=NULL) {
254
			if ($bootstrap->isAutoCompile()) {
255
				$bootstrap->compile(true);
256
			}
257
		}
258
259
		// Components Semantic
260
		$semantic=$this->semantic();
261
		if ($semantic!=NULL) {
262
			if ($semantic->isAutoCompile()) {
263
				$semantic->compile(true);
264
			}
265
		}
266
267
		// External references
268
		$external_scripts=implode('', $this->jquery_code_for_load);
269
		extract(array (
270
				'library_src' => $external_scripts
271
		));
272
273
		if (count($this->jquery_code_for_compile)==0) {
274
			// no inline references, let's just return
275
			return;
276
		}
277
278
		// Inline references
279
		$script='$(document).ready(function() {'."\n";
280
		$script.=implode('', $this->jquery_code_for_compile);
281
		$script.='});';
282
283
		$this->jquery_code_for_compile=array();
284
		if($this->params["debug"]==false){
285
			$script=$this->minify($script);
286
		}
287
		$output=($script_tags===FALSE) ? $script : $this->inline($script);
288
289
		if ($view!==NULL){
290
			$this->jsUtils->createScriptVariable($view,$view_var, $output);
291
		}
292
		return $output;
293
	}
294
295
	public function _addToCompile($jsScript) {
296
		$this->jquery_code_for_compile[]=$jsScript;
297
	}
298
299
	/**
300
	 * Clears the array of script events collected for output
301
	 *
302
	 * @return void
303
	 */
304
	public function _clear_compile() {
305
		$this->jquery_code_for_compile=array ();
306
	}
307
308
	/**
309
	 * A wrapper for writing document.ready()
310
	 * @return string
311
	 */
312
	public function _document_ready($js) {
313
		if (!is_array($js)) {
314
			$js=array (
315
					$js
316
			);
317
		}
318
319
		foreach ( $js as $script ) {
320
			$this->jquery_code_for_compile[]=$script;
321
		}
322
	}
323
324
	/**
325
	 * Puts HTML element in quotes for use in jQuery code
326
	 * unless the supplied element is the Javascript 'this'
327
	 * object, in which case no quotes are added
328
	 *
329
	 * @param string $element
330
	 * @return string
331
	 */
332
	public function _prep_element($element) {
333 View Code Duplication
		if (strrpos($element, 'this')===false&&strrpos($element, 'event')===false&&strrpos($element, 'self')===false) {
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...
334
			$element='"'.addslashes($element).'"';
335
		}
336
		return $element;
337
	}
338
339
	/**
340
	 * Puts HTML values in quotes for use in jQuery code
341
	 * unless the supplied value contains the Javascript 'this' or 'event'
342
	 * object, in which case no quotes are added
343
	 *
344
	 * @param string $value
345
	 * @return string
346
	 */
347
	public function _prep_value($value) {
348
		if (is_array($value)) {
349
			$value=implode(",", $value);
350
		}
351 View Code Duplication
		if (strrpos($value, 'this')===false&&strrpos($value, 'event')===false&&strrpos($value, 'self')===false) {
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...
352
			$value='"'.$value.'"';
353
		}
354
		return $value;
355
	}
356
357
	private function minify($input) {
358
	if(trim($input) === "") return $input;
359
	return preg_replace(
360
			array(
361
					// Remove comment(s)
362
					'#\s*("(?:[^"\\\]++|\\\.)*+"|\'(?:[^\'\\\\]++|\\\.)*+\')\s*|\s*\/\*(?!\!|@cc_on)(?>[\s\S]*?\*\/)\s*|\s*(?<![\:\=])\/\/.*(?=[\n\r]|$)|^\s*|\s*$#',
363
					// Remove white-space(s) outside the string and regex
364
					'#("(?:[^"\\\]++|\\\.)*+"|\'(?:[^\'\\\\]++|\\\.)*+\'|\/\*(?>.*?\*\/)|\/(?!\/)[^\n\r]*?\/(?=[\s.,;]|[gimuy]|$))|\s*([!%&*\(\)\-=+\[\]\{\}|;:,.<>?\/])\s*#s',
365
					// Remove the last semicolon
366
					'#;+\}#',
367
					// Minify object attribute(s) except JSON attribute(s). From `{'foo':'bar'}` to `{foo:'bar'}`
368
					'#([\{,])([\'])(\d+|[a-z_][a-z0-9_]*)\2(?=\:)#i',
369
					// --ibid. From `foo['bar']` to `foo.bar`
370
					'#([a-z0-9_\)\]])\[([\'"])([a-z_][a-z0-9_]*)\2\]#i'
371
			),
372
			array(
373
					'$1',
374
					'$1$2',
375
					'}',
376
					'$1$3',
377
					'$1.$3'
378
			),
379
			$input);
380
	}
381
}
382