Passed
Push — master ( f1fefd...f56e5b )
by Morris
14:52 queued 11s
created

Util   A

Complexity

Total Complexity 42

Size/Duplication

Total Lines 462
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 42
eloc 76
dl 0
loc 462
rs 9.0399
c 0
b 0
f 0

33 Methods

Rating   Name   Duplication   Size   Complexity  
A getVersion() 0 2 1
A linkToPublic() 0 6 2
A isValidFileName() 0 2 1
A naturalSortCompare() 0 2 1
A linkToRemote() 0 5 2
A isSharingDisabledForUser() 0 11 3
A sanitizeHTML() 0 2 1
A linkToAbsolute() 0 4 1
A addStyle() 0 2 1
A getChannel() 0 2 1
A uploadLimit() 0 2 1
A connectHook() 0 2 1
A humanFileSize() 0 2 1
A callRegister() 0 5 2
A needUpgrade() 0 5 2
A maxUploadFilesize() 0 2 1
A isDefaultExpireDateEnforced() 0 2 1
A writeLog() 0 3 1
A addScript() 0 2 1
A isPublicLinkPasswordRequired() 0 2 1
A addTranslations() 0 2 1
A getDefaultEmailAddress() 0 14 2
A hasExtendedSupport() 0 8 2
A addHeader() 0 2 1
A freeSpace() 0 2 1
A computerFileSize() 0 2 1
A mb_array_change_key_case() 0 2 1
A getL10N() 0 2 1
A setChannel() 0 2 1
A getServerHostName() 0 8 2
A recursiveArraySearch() 0 2 1
A encodePath() 0 2 1
A emitHook() 0 2 1

How to fix   Complexity   

Complex Class

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

1
<?php
2
/**
3
 * @copyright Copyright (c) 2016, ownCloud, Inc.
4
 *
5
 * @author Arthur Schiwon <[email protected]>
6
 * @author Bart Visscher <[email protected]>
7
 * @author Björn Schießle <[email protected]>
8
 * @author Christoph Wurst <[email protected]>
9
 * @author Frank Karlitschek <[email protected]>
10
 * @author Georg Ehrke <[email protected]>
11
 * @author Individual IT Services <[email protected]>
12
 * @author J0WI <[email protected]>
13
 * @author Jens-Christian Fischer <[email protected]>
14
 * @author Joas Schilling <[email protected]>
15
 * @author John Molakvoæ (skjnldsv) <[email protected]>
16
 * @author Julius Härtl <[email protected]>
17
 * @author Lukas Reschke <[email protected]>
18
 * @author Michael Gapczynski <[email protected]>
19
 * @author Morris Jobke <[email protected]>
20
 * @author Pellaeon Lin <[email protected]>
21
 * @author Randolph Carter <[email protected]>
22
 * @author Robin Appelman <[email protected]>
23
 * @author Robin McCorkell <[email protected]>
24
 * @author Roeland Jago Douma <[email protected]>
25
 * @author Thomas Müller <[email protected]>
26
 * @author Victor Dubiniuk <[email protected]>
27
 * @author Vincent Petry <[email protected]>
28
 *
29
 * @license AGPL-3.0
30
 *
31
 * This code is free software: you can redistribute it and/or modify
32
 * it under the terms of the GNU Affero General Public License, version 3,
33
 * as published by the Free Software Foundation.
34
 *
35
 * This program is distributed in the hope that it will be useful,
36
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
37
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
38
 * GNU Affero General Public License for more details.
39
 *
40
 * You should have received a copy of the GNU Affero General Public License, version 3,
41
 * along with this program. If not, see <http://www.gnu.org/licenses/>
42
 *
43
 */
44
45
/**
46
 * Public interface of ownCloud for apps to use.
47
 * Utility Class.
48
 *
49
 */
50
51
// use OCP namespace for all classes that are considered public.
52
// This means that they should be used by apps instead of the internal ownCloud classes
53
54
namespace OCP;
55
56
/**
57
 * This class provides different helper functions to make the life of a developer easier
58
 *
59
 * @since 4.0.0
60
 */
61
class Util {
62
	/**
63
	 * @deprecated 14.0.0 use \OCP\ILogger::DEBUG
64
	 */
65
	public const DEBUG = 0;
66
	/**
67
	 * @deprecated 14.0.0 use \OCP\ILogger::INFO
68
	 */
69
	public const INFO = 1;
70
	/**
71
	 * @deprecated 14.0.0 use \OCP\ILogger::WARN
72
	 */
73
	public const WARN = 2;
74
	/**
75
	 * @deprecated 14.0.0 use \OCP\ILogger::ERROR
76
	 */
77
	public const ERROR = 3;
78
	/**
79
	 * @deprecated 14.0.0 use \OCP\ILogger::FATAL
80
	 */
81
	public const FATAL = 4;
82
83
	/** \OCP\Share\IManager */
84
	private static $shareManager;
85
86
	/**
87
	 * get the current installed version of Nextcloud
88
	 * @return array
89
	 * @since 4.0.0
90
	 */
91
	public static function getVersion() {
92
		return \OC_Util::getVersion();
93
	}
94
95
	/**
96
	 * @since 17.0.0
97
	 */
98
	public static function hasExtendedSupport(): bool {
99
		try {
100
			/** @var \OCP\Support\Subscription\IRegistry */
101
			$subscriptionRegistry = \OC::$server->query(\OCP\Support\Subscription\IRegistry::class);
102
			return $subscriptionRegistry->delegateHasExtendedSupport();
103
		} catch (AppFramework\QueryException $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
104
		}
105
		return \OC::$server->getConfig()->getSystemValueBool('extendedSupport', false);
106
	}
107
108
	/**
109
	 * Set current update channel
110
	 * @param string $channel
111
	 * @since 8.1.0
112
	 */
113
	public static function setChannel($channel) {
114
		\OC::$server->getConfig()->setSystemValue('updater.release.channel', $channel);
115
	}
116
117
	/**
118
	 * Get current update channel
119
	 * @return string
120
	 * @since 8.1.0
121
	 */
122
	public static function getChannel() {
123
		return \OC_Util::getChannel();
124
	}
125
126
	/**
127
	 * write a message in the log
128
	 * @param string $app
129
	 * @param string $message
130
	 * @param int $level
131
	 * @since 4.0.0
132
	 * @deprecated 13.0.0 use log of \OCP\ILogger
133
	 */
134
	public static function writeLog($app, $message, $level) {
135
		$context = ['app' => $app];
136
		\OC::$server->getLogger()->log($level, $message, $context);
137
	}
138
139
	/**
140
	 * check if sharing is disabled for the current user
141
	 *
142
	 * @return boolean
143
	 * @since 7.0.0
144
	 * @deprecated 9.1.0 Use \OC::$server->getShareManager()->sharingDisabledForUser
145
	 */
146
	public static function isSharingDisabledForUser() {
147
		if (self::$shareManager === null) {
148
			self::$shareManager = \OC::$server->getShareManager();
149
		}
150
151
		$user = \OC::$server->getUserSession()->getUser();
152
		if ($user !== null) {
153
			$user = $user->getUID();
154
		}
155
156
		return self::$shareManager->sharingDisabledForUser($user);
157
	}
158
159
	/**
160
	 * get l10n object
161
	 * @param string $application
162
	 * @param string|null $language
163
	 * @return \OCP\IL10N
164
	 * @since 6.0.0 - parameter $language was added in 8.0.0
165
	 */
166
	public static function getL10N($application, $language = null) {
167
		return \OC::$server->getL10N($application, $language);
168
	}
169
170
	/**
171
	 * add a css file
172
	 * @param string $application
173
	 * @param string $file
174
	 * @since 4.0.0
175
	 */
176
	public static function addStyle($application, $file = null) {
177
		\OC_Util::addStyle($application, $file);
178
	}
179
180
	/**
181
	 * add a javascript file
182
	 * @param string $application
183
	 * @param string $file
184
	 * @since 4.0.0
185
	 */
186
	public static function addScript($application, $file = null) {
187
		\OC_Util::addScript($application, $file);
188
	}
189
190
	/**
191
	 * Add a translation JS file
192
	 * @param string $application application id
193
	 * @param string $languageCode language code, defaults to the current locale
194
	 * @since 8.0.0
195
	 */
196
	public static function addTranslations($application, $languageCode = null) {
197
		\OC_Util::addTranslations($application, $languageCode);
198
	}
199
200
	/**
201
	 * Add a custom element to the header
202
	 * If $text is null then the element will be written as empty element.
203
	 * So use "" to get a closing tag.
204
	 * @param string $tag tag name of the element
205
	 * @param array $attributes array of attributes for the element
206
	 * @param string $text the text content for the element
207
	 * @since 4.0.0
208
	 */
209
	public static function addHeader($tag, $attributes, $text = null) {
210
		\OC_Util::addHeader($tag, $attributes, $text);
211
	}
212
213
	/**
214
	 * Creates an absolute url to the given app and file.
215
	 * @param string $app app
216
	 * @param string $file file
217
	 * @param array $args array with param=>value, will be appended to the returned url
218
	 * 	The value of $args will be urlencoded
219
	 * @return string the url
220
	 * @since 4.0.0 - parameter $args was added in 4.5.0
221
	 */
222
	public static function linkToAbsolute($app, $file, $args = []) {
223
		$urlGenerator = \OC::$server->getURLGenerator();
224
		return $urlGenerator->getAbsoluteURL(
225
			$urlGenerator->linkTo($app, $file, $args)
226
		);
227
	}
228
229
	/**
230
	 * Creates an absolute url for remote use.
231
	 * @param string $service id
232
	 * @return string the url
233
	 * @since 4.0.0
234
	 */
235
	public static function linkToRemote($service) {
236
		$urlGenerator = \OC::$server->getURLGenerator();
237
		$remoteBase = $urlGenerator->linkTo('', 'remote.php') . '/' . $service;
238
		return $urlGenerator->getAbsoluteURL(
239
			$remoteBase . (($service[strlen($service) - 1] != '/') ? '/' : '')
240
		);
241
	}
242
243
	/**
244
	 * Creates an absolute url for public use
245
	 * @param string $service id
246
	 * @return string the url
247
	 * @since 4.5.0
248
	 * @deprecated 15.0.0 - use OCP\IURLGenerator
249
	 */
250
	public static function linkToPublic($service) {
251
		$urlGenerator = \OC::$server->getURLGenerator();
252
		if ($service === 'files') {
253
			return $urlGenerator->getAbsoluteURL('/s');
254
		}
255
		return $urlGenerator->getAbsoluteURL($urlGenerator->linkTo('', 'public.php').'?service='.$service);
256
	}
257
258
	/**
259
	 * Returns the server host name without an eventual port number
260
	 * @return string the server hostname
261
	 * @since 5.0.0
262
	 */
263
	public static function getServerHostName() {
264
		$host_name = \OC::$server->getRequest()->getServerHost();
265
		// strip away port number (if existing)
266
		$colon_pos = strpos($host_name, ':');
267
		if ($colon_pos != false) {
0 ignored issues
show
Bug Best Practice introduced by
It seems like you are loosely comparing $colon_pos of type integer to the boolean false. If you are specifically checking for non-zero, consider using something more explicit like > 0 or !== 0 instead.
Loading history...
268
			$host_name = substr($host_name, 0, $colon_pos);
269
		}
270
		return $host_name;
271
	}
272
273
	/**
274
	 * Returns the default email address
275
	 * @param string $user_part the user part of the address
276
	 * @return string the default email address
277
	 *
278
	 * Assembles a default email address (using the server hostname
279
	 * and the given user part, and returns it
280
	 * Example: when given lostpassword-noreply as $user_part param,
281
	 *     and is currently accessed via http(s)://example.com/,
282
	 *     it would return '[email protected]'
283
	 *
284
	 * If the configuration value 'mail_from_address' is set in
285
	 * config.php, this value will override the $user_part that
286
	 * is passed to this function
287
	 * @since 5.0.0
288
	 */
289
	public static function getDefaultEmailAddress($user_part) {
290
		$config = \OC::$server->getConfig();
291
		$user_part = $config->getSystemValue('mail_from_address', $user_part);
292
		$host_name = self::getServerHostName();
293
		$host_name = $config->getSystemValue('mail_domain', $host_name);
294
		$defaultEmailAddress = $user_part.'@'.$host_name;
295
296
		$mailer = \OC::$server->getMailer();
297
		if ($mailer->validateMailAddress($defaultEmailAddress)) {
298
			return $defaultEmailAddress;
299
		}
300
301
		// in case we cannot build a valid email address from the hostname let's fallback to 'localhost.localdomain'
302
		return $user_part.'@localhost.localdomain';
303
	}
304
305
	/**
306
	 * Make a human file size (2048 to 2 kB)
307
	 * @param int $bytes file size in bytes
308
	 * @return string a human readable file size
309
	 * @since 4.0.0
310
	 */
311
	public static function humanFileSize($bytes) {
312
		return \OC_Helper::humanFileSize($bytes);
313
	}
314
315
	/**
316
	 * Make a computer file size (2 kB to 2048)
317
	 * @param string $str file size in a fancy format
318
	 * @return float a file size in bytes
319
	 *
320
	 * Inspired by: https://www.php.net/manual/en/function.filesize.php#92418
321
	 * @since 4.0.0
322
	 */
323
	public static function computerFileSize($str) {
324
		return \OC_Helper::computerFileSize($str);
0 ignored issues
show
Bug Best Practice introduced by
The expression return OC_Helper::computerFileSize($str) could also return false which is incompatible with the documented return type double. Did you maybe forget to handle an error condition?

If the returned type also contains false, it is an indicator that maybe an error condition leading to the specific return statement remains unhandled.

Loading history...
325
	}
326
327
	/**
328
	 * connects a function to a hook
329
	 *
330
	 * @param string $signalClass class name of emitter
331
	 * @param string $signalName name of signal
332
	 * @param string|object $slotClass class name of slot
333
	 * @param string $slotName name of slot
334
	 * @return bool
335
	 *
336
	 * This function makes it very easy to connect to use hooks.
337
	 *
338
	 * TODO: write example
339
	 * @since 4.0.0
340
	 * @deprecated 21.0.0 use \OCP\EventDispatcher\IEventDispatcher::addListener
341
	 */
342
	public static function connectHook($signalClass, $signalName, $slotClass, $slotName) {
343
		return \OC_Hook::connect($signalClass, $signalName, $slotClass, $slotName);
344
	}
345
346
	/**
347
	 * Emits a signal. To get data from the slot use references!
348
	 * @param string $signalclass class name of emitter
349
	 * @param string $signalname name of signal
350
	 * @param array $params default: array() array with additional data
351
	 * @return bool true if slots exists or false if not
352
	 *
353
	 * TODO: write example
354
	 * @since 4.0.0
355
	 * @deprecated 21.0.0 use \OCP\EventDispatcher\IEventDispatcher::dispatchTypedEvent
356
	 */
357
	public static function emitHook($signalclass, $signalname, $params = []) {
358
		return \OC_Hook::emit($signalclass, $signalname, $params);
359
	}
360
361
	/**
362
	 * Cached encrypted CSRF token. Some static unit-tests of ownCloud compare
363
	 * multiple OC_Template elements which invoke `callRegister`. If the value
364
	 * would not be cached these unit-tests would fail.
365
	 * @var string
366
	 */
367
	private static $token = '';
368
369
	/**
370
	 * Register an get/post call. This is important to prevent CSRF attacks
371
	 * @since 4.5.0
372
	 */
373
	public static function callRegister() {
374
		if (self::$token === '') {
375
			self::$token = \OC::$server->getCsrfTokenManager()->getToken()->getEncryptedValue();
376
		}
377
		return self::$token;
378
	}
379
380
	/**
381
	 * Used to sanitize HTML
382
	 *
383
	 * This function is used to sanitize HTML and should be applied on any
384
	 * string or array of strings before displaying it on a web page.
385
	 *
386
	 * @param string|array $value
387
	 * @return string|array an array of sanitized strings or a single sanitized string, depends on the input parameter.
388
	 * @since 4.5.0
389
	 */
390
	public static function sanitizeHTML($value) {
391
		return \OC_Util::sanitizeHTML($value);
392
	}
393
394
	/**
395
	 * Public function to encode url parameters
396
	 *
397
	 * This function is used to encode path to file before output.
398
	 * Encoding is done according to RFC 3986 with one exception:
399
	 * Character '/' is preserved as is.
400
	 *
401
	 * @param string $component part of URI to encode
402
	 * @return string
403
	 * @since 6.0.0
404
	 */
405
	public static function encodePath($component) {
406
		return \OC_Util::encodePath($component);
407
	}
408
409
	/**
410
	 * Returns an array with all keys from input lowercased or uppercased. Numbered indices are left as is.
411
	 *
412
	 * @param array $input The array to work on
413
	 * @param int $case Either MB_CASE_UPPER or MB_CASE_LOWER (default)
414
	 * @param string $encoding The encoding parameter is the character encoding. Defaults to UTF-8
415
	 * @return array
416
	 * @since 4.5.0
417
	 */
418
	public static function mb_array_change_key_case($input, $case = MB_CASE_LOWER, $encoding = 'UTF-8') {
419
		return \OC_Helper::mb_array_change_key_case($input, $case, $encoding);
420
	}
421
422
	/**
423
	 * performs a search in a nested array
424
	 *
425
	 * @param array $haystack the array to be searched
426
	 * @param string $needle the search string
427
	 * @param mixed $index optional, only search this key name
428
	 * @return mixed the key of the matching field, otherwise false
429
	 * @since 4.5.0
430
	 * @deprecated 15.0.0
431
	 */
432
	public static function recursiveArraySearch($haystack, $needle, $index = null) {
433
		return \OC_Helper::recursiveArraySearch($haystack, $needle, $index);
434
	}
435
436
	/**
437
	 * calculates the maximum upload size respecting system settings, free space and user quota
438
	 *
439
	 * @param string $dir the current folder where the user currently operates
440
	 * @param int $free the number of bytes free on the storage holding $dir, if not set this will be received from the storage directly
441
	 * @return int number of bytes representing
442
	 * @since 5.0.0
443
	 */
444
	public static function maxUploadFilesize($dir, $free = null) {
445
		return \OC_Helper::maxUploadFilesize($dir, $free);
446
	}
447
448
	/**
449
	 * Calculate free space left within user quota
450
	 * @param string $dir the current folder where the user currently operates
451
	 * @return int number of bytes representing
452
	 * @since 7.0.0
453
	 */
454
	public static function freeSpace($dir) {
455
		return \OC_Helper::freeSpace($dir);
456
	}
457
458
	/**
459
	 * Calculate PHP upload limit
460
	 *
461
	 * @return int number of bytes representing
462
	 * @since 7.0.0
463
	 */
464
	public static function uploadLimit() {
465
		return \OC_Helper::uploadLimit();
466
	}
467
468
	/**
469
	 * Returns whether the given file name is valid
470
	 * @param string $file file name to check
471
	 * @return bool true if the file name is valid, false otherwise
472
	 * @deprecated 8.1.0 use \OC\Files\View::verifyPath()
473
	 * @since 7.0.0
474
	 * @suppress PhanDeprecatedFunction
475
	 */
476
	public static function isValidFileName($file) {
477
		return \OC_Util::isValidFileName($file);
478
	}
479
480
	/**
481
	 * Compare two strings to provide a natural sort
482
	 * @param string $a first string to compare
483
	 * @param string $b second string to compare
484
	 * @return int -1 if $b comes before $a, 1 if $a comes before $b
485
	 * or 0 if the strings are identical
486
	 * @since 7.0.0
487
	 */
488
	public static function naturalSortCompare($a, $b) {
489
		return \OC\NaturalSort::getInstance()->compare($a, $b);
490
	}
491
492
	/**
493
	 * check if a password is required for each public link
494
	 * @return boolean
495
	 * @since 7.0.0
496
	 */
497
	public static function isPublicLinkPasswordRequired() {
498
		return \OC_Util::isPublicLinkPasswordRequired();
499
	}
500
501
	/**
502
	 * check if share API enforces a default expire date
503
	 * @return boolean
504
	 * @since 8.0.0
505
	 */
506
	public static function isDefaultExpireDateEnforced() {
507
		return \OC_Util::isDefaultExpireDateEnforced();
508
	}
509
510
	protected static $needUpgradeCache = null;
511
512
	/**
513
	 * Checks whether the current version needs upgrade.
514
	 *
515
	 * @return bool true if upgrade is needed, false otherwise
516
	 * @since 7.0.0
517
	 */
518
	public static function needUpgrade() {
519
		if (!isset(self::$needUpgradeCache)) {
520
			self::$needUpgradeCache = \OC_Util::needUpgrade(\OC::$server->getSystemConfig());
521
		}
522
		return self::$needUpgradeCache;
523
	}
524
}
525