Completed
Push — master ( 73e21a...085edf )
by Jean-Christophe
04:37
created

JsUtils   D

Complexity

Total Complexity 79

Size/Duplication

Total Lines 379
Duplicated Lines 8.97 %

Coupling/Cohesion

Components 3
Dependencies 12

Importance

Changes 26
Bugs 0 Features 1
Metric Value
wmc 79
c 26
b 0
f 1
lcom 3
cbo 12
dl 34
loc 379
rs 4.7368

27 Methods

Rating   Name   Duplication   Size   Complexity  
A _setDi() 0 4 3
getUrl() 0 1 ?
addViewElement() 0 1 ?
forward() 0 1 ?
renderContent() 0 1 ?
fromDispatcher() 0 1 ?
A ui() 14 14 4
A bootstrap() 14 14 4
A semantic() 0 14 4
A conflict() 0 3 1
B config() 0 12 5
A __construct() 0 14 4
A addToCompile() 0 3 1
A output() 0 3 1
A ready() 0 3 1
B compile() 0 11 5
A clear_compile() 0 3 1
A inline() 6 6 2
A _open_script() 0 5 2
A _close_script() 0 3 1
A generate_json() 0 16 4
B _create_json() 0 18 7
A _is_associative_array() 0 8 3
B _prep_args() 0 15 7
A getCDNs() 0 3 1
A setCDNs() 0 8 2
D genCDNs() 0 41 16

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

1
<?php
2
3
namespace Ajax;
4
5
use Ajax\config\DefaultConfig;
6
use Ajax\config\Config;
7
use Ajax\lib\CDNJQuery;
8
use Ajax\lib\CDNGuiGen;
9
use Ajax\lib\CDNCoreCss;
10
use Phalcon\Version;
11
use Ajax\common\traits\JsUtilsEventsTrait;
12
use Ajax\common\traits\JsUtilsActionsTrait;
13
use Ajax\common\traits\JsUtilsAjaxTrait;
14
15
/**
16
 * JQuery PHP library
17
 *
18
 * @author jcheron
19
 * @version 1.004
20
 * @license Apache 2 http://www.apache.org/licenses/
21
 */
22
/**
23
 * JsUtils Class : Service to be injected
24
 */
25
abstract class JsUtils{
26
	use JsUtilsEventsTrait,JsUtilsActionsTrait,JsUtilsAjaxTrait;
27
28
	protected $js;
29
	protected $cdns;
30
	/**
31
	 *
32
	 * @var JqueryUI
33
	 */
34
	protected $_ui;
35
	/**
36
	 *
37
	 * @var Bootstrap
38
	 */
39
	protected $_bootstrap;
40
41
	/**
42
	 *
43
	 * @var Semantic
44
	 */
45
	protected $_semantic;
46
	/**
47
	 *
48
	 * @var Config
49
	 */
50
	protected $config;
51
52
	protected function _setDi($di) {
53
		if ($this->js!=null&&$di!=null)
54
			$this->js->setDi($di);
55
	}
56
57
	public abstract function getUrl($url);
0 ignored issues
show
Coding Style introduced by
The abstract declaration must precede the visibility declaration
Loading history...
58
	public abstract function addViewElement($identifier,$content,$view);
0 ignored issues
show
Coding Style introduced by
The abstract declaration must precede the visibility declaration
Loading history...
59
	/**
60
	 * render the content of $controller::$action and set the response to the modal content
61
	 * @param Controller $initialController
62
	 * @param string $controller a Phalcon controller
63
	 * @param string $action a Phalcon action
64
	 */
65
	public abstract function forward($initialController,$controller,$action);
0 ignored issues
show
Coding Style introduced by
The abstract declaration must precede the visibility declaration
Loading history...
66
	/**
67
	 * render the content of an existing view : $controller/$action and set the response to the modal content
68
	 * @param View $view
69
	 * @param string $controller a Phalcon controller
70
	 * @param string $action a Phalcon action
71
	 * @param $params The parameters to pass to the view
72
	 */
73
	public abstract function renderContent($view, $controller, $action, $params=NULL);
0 ignored issues
show
Coding Style introduced by
The abstract declaration must precede the visibility declaration
Loading history...
74
75
	/**
76
	 * Collect url parts from the request dispatcher : controllerName, actionName, parameters
77
	 * @param mixed $dispatcher
78
	 * @return array
79
	 */
80
	public abstract function fromDispatcher($dispatcher);
0 ignored issues
show
Coding Style introduced by
The abstract declaration must precede the visibility declaration
Loading history...
81
82
	/**
83
	 *
84
	 * @param JqueryUI $ui
85
	 * @return \Ajax\JqueryUI
86
	 */
87 View Code Duplication
	public function ui($ui=NULL) {
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...
88
		if ($ui!==NULL) {
89
			$this->_ui=$ui;
90
			if ($this->js!=null) {
91
				$this->js->ui($ui);
92
				$ui->setJs($this);
93
			}
94
			$bs=$this->bootstrap();
95
			if (isset($bs)) {
96
				$this->conflict();
97
			}
98
		}
99
		return $this->_ui;
100
	}
101
102
	/**
103
	 *
104
	 * @param Bootstrap $bootstrap
105
	 * @return \Ajax\Bootstrap
106
	 */
107 View Code Duplication
	public function bootstrap($bootstrap=NULL) {
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...
108
		if ($bootstrap!==NULL) {
109
			$this->_bootstrap=$bootstrap;
110
			if ($this->js!=null) {
111
				$this->js->bootstrap($bootstrap);
112
				$bootstrap->setJs($this);
113
			}
114
			$ui=$this->ui();
115
			if (isset($ui)) {
116
				$this->conflict();
117
			}
118
		}
119
		return $this->_bootstrap;
120
	}
121
122
	/**
123
	 *
124
	 * @param Semantic $semantic
125
	 * @return \Ajax\Semantic
126
	 */
127
	public function semantic($semantic=NULL) {
128
		if ($semantic!==NULL) {
129
			$this->_semantic=$semantic;
130
			if ($this->js!=null) {
131
				$this->js->semantic($semantic);
132
				$semantic->setJs($this);
133
			}
134
			$ui=$this->ui();
135
			if (isset($ui)) {
136
				$this->conflict();
137
			}
138
		}
139
		return $this->_semantic;
140
	}
141
142
	protected function conflict() {
143
		$this->js->_addToCompile("var btn = $.fn.button.noConflict();$.fn.btn = btn;");
144
	}
145
146
	/**
147
	 *
148
	 * @param \Ajax\config\Config $config
149
	 * @return \Ajax\config\Config
150
	 */
151
	public function config($config=NULL) {
152
		if ($config===NULL) {
153
			if ($this->config===NULL) {
154
				$this->config=new DefaultConfig();
155
			}
156
		} elseif (is_array($config)) {
157
			$this->config=new Config($config);
158
		} elseif ($config instanceof Config) {
159
			$this->config=$config;
160
		}
161
		return $this->config;
162
	}
163
164
	public function __construct($params=array()) {
165
		$defaults=array (
166
				'driver' => 'Jquery',
167
				'debug' => true
168
		);
169
		foreach ( $defaults as $key => $val ) {
170
			if (isset($params[$key])&&$params[$key]!=="") {
171
				$defaults[$key]=$params[$key];
172
			}
173
		}
174
		extract($defaults);
175
		$this->js=new Jquery($defaults,$this);
176
		$this->cdns=array ();
177
	}
178
179
	public function addToCompile($jsScript) {
180
		$this->js->_addToCompile($jsScript);
181
	}
182
183
	/**
184
	 * Outputs the called javascript to the screen
185
	 *
186
	 * @param string $js code to output
187
	 * @return string
188
	 */
189
	public function output($js) {
190
		return $this->js->_output($js);
191
	}
192
193
	/**
194
	 * Document ready method
195
	 *
196
	 * @param string $js code to execute
197
	 * @return string
198
	 */
199
	public function ready($js) {
200
		return $this->js->_document_ready($js);
201
	}
202
203
	/**
204
	 * gather together all script needing to be output
205
	 *
206
	 * @param View $view
207
	 * @param $view_var
208
	 * @param $script_tags
209
	 * @return string
210
	 */
211
	public function compile($view=NULL, $view_var='script_foot', $script_tags=TRUE) {
212
		$bs=$this->_bootstrap;
213
		if (isset($bs)&&isset($view)) {
214
			$bs->compileHtml($this, $view);
215
		}
216
		$sem=$this->_semantic;
217
		if (isset($sem)&&isset($view)) {
218
			$sem->compileHtml($this, $view);
219
		}
220
		return $this->js->_compile($view, $view_var, $script_tags);
221
	}
222
223
	/**
224
	 * Clears any previous javascript collected for output
225
	 *
226
	 * @return void
227
	 */
228
	public function clear_compile() {
229
		$this->js->_clear_compile();
230
	}
231
232
	/**
233
	 * Outputs a <script> tag
234
	 *
235
	 * @param string $script
236
	 * @param boolean $cdata If a CDATA section should be added
237
	 * @return string
238
	 */
239 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...
240
		$str=$this->_open_script();
241
		$str.=($cdata) ? "\n// <![CDATA[\n{$script}\n// ]]>\n" : "\n{$script}\n";
242
		$str.=$this->_close_script();
243
		return $str;
244
	}
245
246
	/**
247
	 * Outputs an opening <script>
248
	 *
249
	 * @param string $src
250
	 * @return string
251
	 */
252
	private function _open_script($src='') {
253
		$str='<script type="text/javascript" ';
254
		$str.=($src=='') ? '>' : ' src="'.$src.'">';
255
		return $str;
256
	}
257
258
	/**
259
	 * Outputs an closing </script>
260
	 *
261
	 * @param string $extra
262
	 * @return string
263
	 */
264
	private function _close_script($extra="\n") {
265
		return "</script>$extra";
266
	}
267
268
269
	/**
270
	 * Can be passed a database result or associative array and returns a JSON formatted string
271
	 *
272
	 * @param mixed $result result set or array
273
	 * @param bool $match_array_type match array types (defaults to objects)
274
	 * @return string json formatted string
275
	 */
276
	public function generate_json($result=NULL, $match_array_type=FALSE) {
277
		// JSON data can optionally be passed to this function
278
		// either as a database result object or an array, or a user supplied array
279
		if (!is_null($result)) {
280
			if (is_object($result)) {
281
				$json_result=$result->result_array();
282
			} elseif (is_array($result)) {
283
				$json_result=$result;
284
			} else {
285
				return $this->_prep_args($result);
286
			}
287
		} else {
288
			return 'null';
289
		}
290
		return $this->_create_json($json_result, $match_array_type);
291
	}
292
293
	private function _create_json($json_result, $match_array_type) {
294
		$json=array ();
295
		$_is_assoc=TRUE;
296
		if (!is_array($json_result)&&empty($json_result)) {
297
			show_error("Generate JSON Failed - Illegal key, value pair.");
298
		} elseif ($match_array_type) {
299
			$_is_assoc=$this->_is_associative_array($json_result);
300
		}
301
		foreach ( $json_result as $k => $v ) {
302
			if ($_is_assoc) {
303
				$json[]=$this->_prep_args($k, TRUE).':'.$this->generate_json($v, $match_array_type);
304
			} else {
305
				$json[]=$this->generate_json($v, $match_array_type);
306
			}
307
		}
308
		$json=implode(',', $json);
309
		return $_is_assoc ? "{".$json."}" : "[".$json."]";
310
	}
311
312
	/**
313
	 * Checks for an associative array
314
	 *
315
	 * @param type
316
	 * @return type
317
	 */
318
	public function _is_associative_array($arr) {
319
		foreach ( array_keys($arr) as $key => $val ) {
320
			if ($key!==$val) {
321
				return TRUE;
322
			}
323
		}
324
		return FALSE;
325
	}
326
327
	/**
328
	 * Ensures a standard json value and escapes values
329
	 *
330
	 * @param type
331
	 * @return type
332
	 */
333
	public function _prep_args($result, $is_key=FALSE) {
334
		if (is_null($result)) {
335
			return 'null';
336
		} elseif (is_bool($result)) {
337
			return ($result===TRUE) ? 'true' : 'false';
338
		} elseif (is_string($result)||$is_key) {
339
			return '"'.str_replace(array (
340
					'\\',"\t","\n","\r",'"','/'
341
			), array (
342
					'\\\\','\\t','\\n',"\\r",'\"','\/'
343
			), $result).'"';
344
		} elseif (is_scalar($result)) {
345
			return $result;
346
		}
347
	}
348
349
	public function getCDNs() {
350
		return $this->cdns;
351
	}
352
353
	public function setCDNs($cdns) {
354
		if (is_array($cdns)===false) {
355
			$cdns=array (
356
					$cdns
357
			);
358
		}
359
		$this->cdns=$cdns;
360
	}
361
362
	public function genCDNs($template=NULL) {
363
		$hasJQuery=false;
364
		$hasJQueryUI=false;
365
		$hasBootstrap=false;
366
		$hasSemantic=false;
367
		$result=array ();
368
		foreach ( $this->cdns as $cdn ) {
369
			switch(get_class($cdn)) {
370
				case "Ajax\lib\CDNJQuery":
371
					$hasJQuery=true;
372
					$result[0]=$cdn;
373
					break;
374
				case "Ajax\lib\CDNJQuery":
375
					$hasJQueryUI=true;
376
					$result[1]=$cdn;
377
					break;
378
				case "Ajax\lib\CDNCoreCss":
379
					if($cdn->getFramework()==="Bootstrap")
380
						$hasBootstrap=true;
381
					elseif($cdn->getFramework()==="Semantic")
382
						$hasSemantic=true;
383
					if($hasSemantic || $hasBootstrap)
384
						$result[2]=$cdn;
385
					break;
386
			}
387
		}
388
		if ($hasJQuery===false) {
389
			$result[0]=new CDNJQuery("x");
390
		}
391
		if ($hasJQueryUI===false&&isset($this->_ui)) {
392
			$result[1]=new CDNGuiGen("x", $template);
393
		}
394
		if ($hasBootstrap===false&&isset($this->_bootstrap)) {
395
			$result[2]=new CDNCoreCss("Bootstrap","x");
396
		}
397
		if ($hasSemantic===false&&isset($this->_semantic)) {
398
			$result[2]=new CDNCoreCss("Semantic","x");
399
		}
400
		ksort($result);
401
		return implode("\n", $result);
402
	}
403
}
404