Passed
Push — php8 ( 7ef3e2...94505a )
by Fabio
07:04 queued 01:51
created

TJavaScript   B

Complexity

Total Complexity 46

Size/Duplication

Total Lines 239
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 80
c 1
b 0
f 0
dl 0
loc 239
rs 8.72
wmc 46

13 Methods

Rating   Name   Duplication   Size   Complexity  
A renderScriptBlock() 0 3 1
A quoteString() 0 3 1
A quoteJsLiteral() 0 6 2
A renderScriptFile() 0 6 3
A renderScriptFiles() 0 7 2
A renderScriptBlocksCallback() 0 6 2
A isJsLiteral() 0 3 1
D encode() 0 58 23
A renderScriptBlocks() 0 6 2
A jsonEncode() 0 8 3
A convertToUtf8() 0 7 4
A JSMin() 0 3 1
A jsonDecode() 0 3 1

How to fix   Complexity   

Complex Class

Complex classes like TJavaScript 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 TJavaScript, and based on these observations, apply Extract Interface, too.

1
<?php
2
/**
3
 * TJavaScript class file
4
 *
5
 * @author Wei Zhuo<weizhuo[at]gmail[dot]com>
6
 * @link https://github.com/pradosoft/prado
7
 * @license https://github.com/pradosoft/prado/blob/master/LICENSE
8
 */
9
10
namespace Prado\Web\Javascripts;
11
12
use Prado\Web\THttpUtility;
13
use Prado\Prado;
14
15
/**
16
 * TJavaScript class.
17
 *
18
 * TJavaScript is a utility class containing commonly-used javascript-related
19
 * functions.
20
 *
21
 * @author Wei Zhuo<weizhuo[at]gmail[dot]com>
22
 * @since 3.0
23
 */
24
class TJavaScript
25
{
26
	/**
27
	 * Renders a list of javascript files
28
	 * @param array $files URLs to the javascript files
29
	 * @return string rendering result
30
	 */
31
	public static function renderScriptFiles($files)
32
	{
33
		$str = '';
34
		foreach ($files as $file) {
35
			$str .= self::renderScriptFile($file);
36
		}
37
		return $str;
38
	}
39
40
	/**
41
	 * Renders a javascript file
42
	 * @param \Prado\Web\Javascripts\TJavaScriptAsset|string $asset URL to the javascript file or TJavaScriptAsset
43
	 * @return string rendering result
44
	 */
45
	public static function renderScriptFile($asset)
46
	{
47
		if (is_object($asset) && ($asset instanceof TJavaScriptAsset)) {
48
			return $asset->__toString() . "\n";
49
		}
50
		return '<script src="' . THttpUtility::htmlEncode($asset) . "\"></script>\n";
51
	}
52
53
	/**
54
	 * Renders a list of javascript blocks
55
	 * @param array $scripts javascript blocks
56
	 * @return string rendering result
57
	 */
58
	public static function renderScriptBlocks($scripts)
59
	{
60
		if (count($scripts)) {
61
			return "<script>\n/*<![CDATA[*/\n" . implode("\n", $scripts) . "\n/*]]>*/\n</script>\n";
62
		} else {
63
			return '';
64
		}
65
	}
66
67
	/**
68
	 * Renders a list of javascript code
69
	 * @param array $scripts javascript blocks
70
	 * @return string rendering result
71
	 */
72
	public static function renderScriptBlocksCallback($scripts)
73
	{
74
		if (count($scripts)) {
75
			return implode("\n", $scripts) . "\n";
76
		} else {
77
			return '';
78
		}
79
	}
80
81
	/**
82
	 * Renders javascript block
83
	 * @param string $script javascript block
84
	 * @return string rendering result
85
	 */
86
	public static function renderScriptBlock($script)
87
	{
88
		return "<script>\n/*<![CDATA[*/\n{$script}\n/*]]>*/\n</script>\n";
89
	}
90
91
	/**
92
	 * Quotes a javascript string.
93
	 * After processing, the string is safely enclosed within a pair of
94
	 * quotation marks and can serve as a javascript string.
95
	 * @param string $js string to be quoted
96
	 * @return string the quoted string
97
	 */
98
	public static function quoteString($js)
99
	{
100
		return self::jsonEncode($js, JSON_HEX_QUOT | JSON_HEX_APOS | JSON_HEX_TAG);
101
	}
102
103
	/**
104
	 * @param mixed $js
105
	 * @return TJavaScriptLiteral Marks a string as a javascript function. Once marke, the string is considered as a
106
	 * raw javascript function that is not supposed to be encoded by {@link encode}
107
	 */
108
	public static function quoteJsLiteral($js)
109
	{
110
		if ($js instanceof TJavaScriptLiteral) {
111
			return $js;
112
		} else {
113
			return new TJavaScriptLiteral($js);
114
		}
115
	}
116
117
	/**
118
	 * @param mixed $js
119
	 * @return bool true if the parameter is marked as a javascript function, i.e. if it's considered as a
120
	 * raw javascript function that is not supposed to be encoded by {@link encode}
121
	 */
122
	public static function isJsLiteral($js)
123
	{
124
		return ($js instanceof TJavaScriptLiteral);
125
	}
126
127
	/**
128
	 * Encodes a PHP variable into javascript representation.
129
	 *
130
	 * Example:
131
	 * <code>
132
	 * $options['onLoading'] = "doit";
133
	 * $options['onComplete'] = "more";
134
	 * echo TJavaScript::encode($options);
135
	 * //expects the following javascript code
136
	 * // {'onLoading':'doit','onComplete':'more'}
137
	 * </code>
138
	 *
139
	 * For higher complexity data structures use {@link jsonEncode} and {@link jsonDecode}
140
	 * to serialize and unserialize.
141
	 *
142
	 * @param mixed $value PHP variable to be encoded
143
	 * @param bool $toMap whether the output is a map or a list.
144
	 * @since 3.1.5
145
	 * @param bool $encodeEmptyStrings wether to encode empty strings too. Default to false for BC.
146
	 * @return string the encoded string
147
	 */
148
	public static function encode($value, $toMap = true, $encodeEmptyStrings = false)
149
	{
150
		if (is_string($value)) {
151
			return self::quoteString($value);
152
		} elseif (is_bool($value)) {
153
			return $value ? 'true' : 'false';
154
		} elseif (is_array($value)) {
155
			$results = '';
156
			if (($n = count($value)) > 0 && array_keys($value) !== range(0, $n - 1)) {
157
				foreach ($value as $k => $v) {
158
					if ($v !== '' || $encodeEmptyStrings) {
159
						if ($results !== '') {
160
							$results .= ',';
161
						}
162
						$results .= "'$k':" . self::encode($v, $toMap, $encodeEmptyStrings);
163
					}
164
				}
165
				return '{' . $results . '}';
166
			} else {
167
				foreach ($value as $v) {
168
					if ($v !== '' || $encodeEmptyStrings) {
169
						if ($results !== '') {
170
							$results .= ',';
171
						}
172
						$results .= self::encode($v, $toMap, $encodeEmptyStrings);
173
					}
174
				}
175
				return '[' . $results . ']';
176
			}
177
		} elseif (is_int($value)) {
178
			return "$value";
179
		} elseif (is_float($value)) {
180
			switch ($value) {
181
				case -INF:
182
					return 'Number.NEGATIVE_INFINITY';
183
					break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
184
				case INF:
185
					return 'Number.POSITIVE_INFINITY';
186
					break;
187
				default:
188
					$locale = localeConv();
189
					if ($locale['decimal_point'] == '.') {
190
						return "$value";
191
					} else {
192
						return str_replace($locale['decimal_point'], '.', "$value");
193
					}
194
					break;
195
			}
196
		} elseif (is_object($value)) {
197
			if ($value instanceof TJavaScriptLiteral) {
198
				return $value->toJavaScriptLiteral();
199
			} else {
200
				return self::encode(get_object_vars($value), $toMap);
201
			}
202
		} elseif ($value === null) {
203
			return 'null';
204
		} else {
205
			return '';
206
		}
207
	}
208
	/**
209
	 * Encodes a PHP variable into javascript string.
210
	 * This method invokes json_encode to perform the encoding.
211
	 * @param mixed $value variable to be encoded
212
	 * @param mixed $options
213
	 * @return string encoded string
214
	 */
215
	public static function jsonEncode($value, $options = 0)
216
	{
217
		if (($g = Prado::getApplication()->getGlobalization(false)) !== null &&
218
			strtoupper($enc = $g->getCharset()) != 'UTF-8') {
219
			self::convertToUtf8($value, $enc);
220
		}
221
222
		return json_encode($value, $options | JSON_THROW_ON_ERROR);
223
	}
224
225
	/**
226
	 * Encodes an string or the content of an array to UTF8
227
	 * @param array|mixed|string $value
228
	 * @param string $sourceEncoding
229
	 */
230
	private static function convertToUtf8(&$value, $sourceEncoding)
231
	{
232
		if (is_string($value)) {
233
			$value = iconv($sourceEncoding, 'UTF-8', $value);
234
		} elseif (is_array($value)) {
235
			foreach ($value as &$element) {
236
				self::convertToUtf8($element, $sourceEncoding);
237
			}
238
		}
239
	}
240
241
	/**
242
	 * Decodes a javascript string into PHP variable.
243
	 * This method invokes json_decode to perform the decoding.
244
	 * @param string $value string to be decoded
245
	 * @param bool $assoc whether to convert returned objects to associative arrays
246
	 * @param int $depth recursion depth
247
	 * @return mixed decoded variable
248
	 */
249
	public static function jsonDecode($value, $assoc = false, $depth = 512)
250
	{
251
		return json_decode($value, $assoc, $depth, JSON_THROW_ON_ERROR);
252
	}
253
254
	/**
255
	 * Minimize the size of a javascript script.
256
	 * This method is based on Douglas Crockford's JSMin.
257
	 * @param string $code code that you want to minimzie
258
	 * @return string minimized version of the code
259
	 */
260
	public static function JSMin($code)
261
	{
262
		return \JSMin\JSMin::minify($code);
263
	}
264
}
265