Completed
Push — master ( ad329f...099915 )
by Fabio
05:37
created

PradoBase::using()   D

Complexity

Conditions 22
Paths 14

Size

Total Lines 48

Duplication

Lines 12
Ratio 25 %

Code Coverage

Tests 21
CRAP Score 38.2494

Importance

Changes 0
Metric Value
cc 22
nc 14
nop 1
dl 12
loc 48
ccs 21
cts 31
cp 0.6774
crap 38.2494
rs 4.1666
c 0
b 0
f 0

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * PradoBase class file.
4
 *
5
 * This is the file that establishes the PRADO component model
6
 * and error handling mechanism.
7
 *
8
 * @author Qiang Xue <[email protected]>
9
 * @link https://github.com/pradosoft/prado
10
 * @license https://github.com/pradosoft/prado/blob/master/LICENSE
11
 * @package Prado
12
 */
13
14
namespace Prado;
15
16
use Prado\Exceptions\TInvalidDataValueException;
17
use Prado\Exceptions\TInvalidOperationException;
18
use Prado\Exceptions\TPhpErrorException;
19
use Prado\Exceptions\TPhpFatalErrorException;
20
use Prado\Util\TLogger;
21
use Prado\Util\TVarDumper;
22
use Prado\I18N\Translation;
23
24
// Defines the PRADO framework installation path.
25
if (!defined('PRADO_DIR')) {
26
	define('PRADO_DIR', __DIR__);
27
}
28
29
// Defines the default permission for writable directories and files
30
if (!defined('PRADO_CHMOD')) {
31
	define('PRADO_CHMOD', 0777);
32
}
33
34
// Defines the Composer's vendor/ path.
35
if (!defined('PRADO_VENDORDIR')) {
36
	$reflector = new \ReflectionClass('\Composer\Autoload\ClassLoader');
37
	define('PRADO_VENDORDIR', dirname($reflector->getFileName(), 2));
38
}
39
40
/**
41
 * PradoBase class.
42
 *
43
 * PradoBase implements a few fundamental static methods.
44
 *
45
 * To use the static methods, Use Prado as the class name rather than PradoBase.
46
 * PradoBase is meant to serve as the base class of Prado. The latter might be
47
 * rewritten for customization.
48
 *
49
 * @author Qiang Xue <[email protected]>
50
 * @package Prado
51
 * @since 3.0
52
 */
53
class PradoBase
54
{
55
	/**
56
	 * File extension for Prado class files.
57
	 */
58
	const CLASS_FILE_EXT = '.php';
59
	/**
60
	 * @var array list of path aliases
61
	 */
62
	private static $_aliases = [
63
		'Prado' => PRADO_DIR,
64
		'Vendor' => PRADO_VENDORDIR
65
		];
66
	/**
67
	 * @var array list of namespaces currently in use
68
	 */
69
	private static $_usings = [
70
		'Prado' => PRADO_DIR
71
		];
72
	/**
73
	 * @var array list of namespaces currently in use
74
	 */
75
	public static $classMap = [];
76
	/**
77
	 * @var TApplication the application instance
78
	 */
79
	private static $_application = null;
80
	/**
81
	 * @var TLogger logger instance
82
	 */
83
	private static $_logger = null;
84
	/**
85
	 * @var array list of class exists checks
86
	 */
87
	protected static $classExists = [];
88
	/**
89
	 * @return string the version of Prado framework
90
	 */
91 3
	public static function getVersion()
92
	{
93 3
		return '4.1.0';
94
	}
95
96
	public static function init()
97
	{
98
		static::initAutoloader();
99
		static::initErrorHandlers();
100
	}
101
102
	/**
103
	 * Loads the static classmap and registers the autoload function.
104
	 */
105
	public static function initAutoloader()
106
	{
107
		self::$classMap = require(__DIR__ . '/classes.php');
108
109
		spl_autoload_register([get_called_class(), 'autoload']);
110
	}
111
112
	/**
113
	 * Initializes error handlers.
114
	 * This method set error and exception handlers to be functions
115
	 * defined in this class.
116
	 */
117
	public static function initErrorHandlers()
118
	{
119
		/**
120
		 * Sets error handler to be Prado::phpErrorHandler
121
		 */
122
		set_error_handler(['\Prado\PradoBase', 'phpErrorHandler']);
123
		/**
124
		 * Sets shutdown function to be Prado::phpFatalErrorHandler
125
		 */
126
		register_shutdown_function(['PradoBase', 'phpFatalErrorHandler']);
127
		/**
128
		 * Sets exception handler to be Prado::exceptionHandler
129
		 */
130
		set_exception_handler(['\Prado\PradoBase', 'exceptionHandler']);
131
		/**
132
		 * Disable php's builtin error reporting to avoid duplicated reports
133
		 */
134
		ini_set('display_errors', 0);
135
	}
136
137
	/**
138
	 * Class autoload loader.
139
	 * This method is provided to be invoked within an __autoload() magic method.
140
	 * @param string $className class name
141
	 */
142 9
	public static function autoload($className)
143
	{
144 9
		static::using($className);
145 9
	}
146
147
	/**
148
	 * @param int $logoType the type of "powered logo". Valid values include 0 and 1.
149
	 * @return string a string that can be displayed on your Web page showing powered-by-PRADO information
150
	 */
151
	public static function poweredByPrado($logoType = 0)
152
	{
153
		$logoName = $logoType == 1 ? 'powered2' : 'powered';
154
		if (self::$_application !== null) {
155
			$am = self::$_application->getAssetManager();
156
			$url = $am->publishFilePath(self::getPathOfNamespace('Prado\\' . $logoName, '.gif'));
157
		} else {
158
			$url = 'http://pradosoft.github.io/docs/' . $logoName . '.gif';
159
		}
160
		return '<a title="Powered by PRADO" href="https://github.com/pradosoft/prado" target="_blank"><img src="' . $url . '" style="border-width:0px;" alt="Powered by PRADO" /></a>';
161
	}
162
163
	/**
164
	 * PHP error handler.
165
	 * This method should be registered as PHP error handler using
166
	 * {@link set_error_handler}. The method throws an exception that
167
	 * contains the error information.
168
	 * @param int $errno the level of the error raised
169
	 * @param string $errstr the error message
170
	 * @param string $errfile the filename that the error was raised in
171
	 * @param int $errline the line number the error was raised at
172
	 */
173 14
	public static function phpErrorHandler($errno, $errstr, $errfile, $errline)
174
	{
175 14
		if (error_reporting() & $errno) {
176
			throw new TPhpErrorException($errno, $errstr, $errfile, $errline);
177
		}
178 14
	}
179
180
	/**
181
	 * PHP shutdown function used to catch fatal errors.
182
	 * This method should be registered as PHP error handler using
183
	 * {@link register_shutdown_function}. The method throws an exception that
184
	 * contains the error information.
185
	 */
186
	public static function phpFatalErrorHandler()
187
	{
188
		$error = error_get_last();
189
		if ($error &&
0 ignored issues
show
Bug Best Practice introduced by
The expression $error of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
190
			TPhpErrorException::isFatalError($error) &&
191
			error_reporting() & $error['type']) {
192
			self::exceptionHandler(new TPhpFatalErrorException($error['type'], $error['message'], $error['file'], $error['line']));
193
		}
194
	}
195
196
	/**
197
	 * Default exception handler.
198
	 * This method should be registered as default exception handler using
199
	 * {@link set_exception_handler}. The method tries to use the errorhandler
200
	 * module of the Prado application to handle the exception.
201
	 * If the application or the module does not exist, it simply echoes the
202
	 * exception.
203
	 * @param Exception $exception exception that is not caught
204
	 */
205
	public static function exceptionHandler($exception)
206
	{
207
		if (self::$_application !== null && ($errorHandler = self::$_application->getErrorHandler()) !== null) {
208
			$errorHandler->handleError(null, $exception);
209
		} else {
210
			echo $exception;
211
		}
212
		exit(1);
213
	}
214
215
	/**
216
	 * Stores the application instance in the class static member.
217
	 * This method helps implement a singleton pattern for TApplication.
218
	 * Repeated invocation of this method or the application constructor
219
	 * will cause the throw of an exception.
220
	 * This method should only be used by framework developers.
221
	 * @param TApplication $application the application instance
222
	 * @throws TInvalidOperationException if this method is invoked twice or more.
223
	 */
224 55
	public static function setApplication($application)
225
	{
226 55
		if (self::$_application !== null && !defined('PRADO_TEST_RUN')) {
227
			throw new TInvalidOperationException('prado_application_singleton_required');
228
		}
229 55
		self::$_application = $application;
230 55
	}
231
232
	/**
233
	 * @return TApplication the application singleton, null if the singleton has not be created yet.
234
	 */
235 96
	public static function getApplication()
236
	{
237 96
		return self::$_application;
238
	}
239
240
	/**
241
	 * @return string the path of the framework
242
	 */
243 108
	public static function getFrameworkPath()
244
	{
245 108
		return PRADO_DIR;
246
	}
247
248
	/**
249
	 * Convert old Prado namespaces to PHP namespaces
250
	 * @param string $type old class name in Prado3 namespace format
251
	 * @return string Equivalent class name in PHP namespace format
252
	 */
253 116
	protected static function prado3NamespaceToPhpNamespace($type)
254
	{
255 116
		if (substr($type, 0, 6) === 'System') {
256 1
			$type = 'Prado' . substr($type, 6);
257
		}
258
259 116
		if (false === strpos($type, '\\')) {
260 106
			return str_replace('.', '\\', $type);
261
		} else {
262 14
			return $type;
263
		}
264
	}
265
266
	/**
267
	 * Creates a component with the specified type.
268
	 * A component type can be either the component class name
269
	 * or a namespace referring to the path of the component class file.
270
	 * For example, 'TButton', '\Prado\Web\UI\WebControls\TButton' are both
271
	 * valid component type.
272
	 * This method can also pass parameters to component constructors.
273
	 * All parameters passed to this method except the first one (the component type)
274
	 * will be supplied as component constructor parameters.
275
	 * @param string $requestedType component type
276
	 * @param array $params
277
	 * @throws TInvalidDataValueException if the component type is unknown
278
	 * @return TComponent component instance of the specified type
279
	 */
280 103
	public static function createComponent($requestedType, ...$params)
281
	{
282 103
		$type = static::prado3NamespaceToPhpNamespace($requestedType);
283 103
		if (!isset(self::$classExists[$type])) {
284 24
			self::$classExists[$type] = class_exists($type, false);
285
		}
286
287 103
		if (!isset(self::$_usings[$type]) && !self::$classExists[$type]) {
288 6
			static::using($type);
289 6
			self::$classExists[$type] = class_exists($type, false);
290
		}
291
292
		/*
293
		 * Old apps compatibility support: if the component name has been specified using the
294
		 * old namespace syntax (eg. Application.Common.MyDataModule), assume that the calling
295
		 * code expects the class not to be php5.3-namespaced (eg: MyDataModule instead of
296
		 * \Application\Common\MyDataModule)
297
		 * Skip this if the class is inside the Prado\* namespace, since all Prado classes are now namespaced
298
		 */
299 103
		if (($pos = strrpos($type, '\\')) !== false && ($requestedType != $type) && strpos($type, 'Prado\\') !== 0) {
300
			$type = substr($type, $pos + 1);
301
		}
302
303 103
		if (count($params) > 0) {
304 10
			return new $type(...$params);
305
		} else {
306 96
			return new $type;
307
		}
308
	}
309
310
	/**
311
	 * Uses a namespace.
312
	 * A namespace ending with an asterisk '*' refers to a directory, otherwise it represents a PHP file.
313
	 * If the namespace corresponds to a directory, the directory will be appended
314
	 * to the include path. If the namespace corresponds to a file, it will be included (include_once).
315
	 * @param string $namespace namespace to be used
316
	 * @throws TInvalidDataValueException if the namespace is invalid
317
	 */
318 15
	public static function using($namespace)
319
	{
320 15
		$namespace = static::prado3NamespaceToPhpNamespace($namespace);
321
322 15
		if (isset(self::$_usings[$namespace]) ||
323 15
			class_exists($namespace, false) ||
324 15
			interface_exists($namespace, false)) {
325 2
			return;
326
		}
327
328 13
		if (array_key_exists($namespace, self::$classMap)) {
329
			// fast autoload a Prado3 class name
330 9
			$phpNamespace = self::$classMap[$namespace];
331 9 View Code Duplication
			if (class_exists($phpNamespace, true) || interface_exists($phpNamespace, true)) {
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...
332 9
				if (!class_exists($namespace) && !interface_exists($namespace)) {
333 9
					class_alias($phpNamespace, $namespace);
334
				}
335 9
				return;
336
			}
337 5
		} elseif (($pos = strrpos($namespace, '\\')) === false) {
338
			// trying to autoload an old class name
339
			foreach (self::$_usings as $k => $v) {
340
				$path = $v . DIRECTORY_SEPARATOR . $namespace . self::CLASS_FILE_EXT;
341
				if (file_exists($path)) {
342
					$phpNamespace = '\\' . $k . '\\' . $namespace;
343 View Code Duplication
					if (class_exists($phpNamespace, true) || interface_exists($phpNamespace, true)) {
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...
344
						if (!class_exists($namespace) && !interface_exists($namespace)) {
345
							class_alias($phpNamespace, $namespace);
346
						}
347
						return;
348
					}
349
				}
350
			}
351 5
		} elseif (($path = self::getPathOfNamespace($namespace, self::CLASS_FILE_EXT)) !== null) {
352 2
			$className = substr($namespace, $pos + 1);
353 2
			if ($className === '*') {  // a directory
354
				self::$_usings[substr($namespace, 0, $pos)] = $path;
355
			} else {  // a file
356 2
				if (class_exists($className, false) || interface_exists($className, false))
357
					return;
358
359 2
				include_once($path);
360 2
				if (!class_exists($className, false) && !interface_exists($className, false)) {
361 2
					class_alias($namespace, $className);
362
				}
363
			}
364
		}
365 5
	}
366
367
	/**
368
	 * Translates a namespace into a file path.
369
	 * The first segment of the namespace is considered as a path alias
370
	 * which is replaced with the actual path. The rest segments are
371
	 * subdirectory names appended to the aliased path.
372
	 * If the namespace ends with an asterisk '*', it represents a directory;
373
	 * Otherwise it represents a file whose extension name is specified by the second parameter (defaults to empty).
374
	 * Note, this method does not ensure the existence of the resulting file path.
375
	 * @param string $namespace namespace
376
	 * @param string $ext extension to be appended if the namespace refers to a file
377
	 * @return string file path corresponding to the namespace, null if namespace is invalid
378
	 */
379 10
	public static function getPathOfNamespace($namespace, $ext = '')
380
	{
381 10
		$namespace = static::prado3NamespaceToPhpNamespace($namespace);
382
383 10
		if (self::CLASS_FILE_EXT === $ext || empty($ext)) {
384 6
			if (isset(self::$_usings[$namespace])) {
385
				return self::$_usings[$namespace];
386
			}
387
388 6
			if (isset(self::$_aliases[$namespace])) {
389 1
				return self::$_aliases[$namespace];
390
			}
391
		}
392
393 10
		$segs = explode('\\', $namespace);
394 10
		$alias = array_shift($segs);
395
396 10
		if (null !== ($file = array_pop($segs)) && null !== ($root = self::getPathOfAlias($alias))) {
397 6
			return rtrim($root . DIRECTORY_SEPARATOR . implode(DIRECTORY_SEPARATOR, $segs), '/\\') . (($file === '*') ? '' : DIRECTORY_SEPARATOR . $file . $ext);
398
		}
399
400 5
		return null;
401
	}
402
403
	/**
404
	 * @param string $alias alias to the path
405
	 * @return string the path corresponding to the alias, null if alias not defined.
406
	 */
407 9
	public static function getPathOfAlias($alias)
408
	{
409 9
		return isset(self::$_aliases[$alias]) ? self::$_aliases[$alias] : null;
410
	}
411
412
	protected static function getPathAliases()
413
	{
414
		return self::$_aliases;
415
	}
416
417
	/**
418
	 * @param string $alias alias to the path
419
	 * @param string $path the path corresponding to the alias
420
	 * @throws TInvalidOperationException $alias if the alias is already defined
421
	 * @throws TInvalidDataValueException $path if the path is not a valid file path
422
	 */
423 61
	public static function setPathOfAlias($alias, $path)
424
	{
425 61
		if (isset(self::$_aliases[$alias]) && !defined('PRADO_TEST_RUN')) {
426
			throw new TInvalidOperationException('prado_alias_redefined', $alias);
427 61
		} elseif (($rp = realpath($path)) !== false && is_dir($rp)) {
428 61
			if (strpos($alias, '.') === false) {
429 61
				self::$_aliases[$alias] = $rp;
430
			} else {
431 61
				throw new TInvalidDataValueException('prado_aliasname_invalid', $alias);
432
			}
433
		} else {
434
			throw new TInvalidDataValueException('prado_alias_invalid', $alias, $path);
435
		}
436 61
	}
437
438
	/**
439
	 * Fatal error handler.
440
	 * This method displays an error message together with the current call stack.
441
	 * The application will exit after calling this method.
442
	 * @param string $msg error message
443
	 */
444
	public static function fatalError($msg)
445
	{
446
		echo '<h1>Fatal Error</h1>';
447
		echo '<p>' . $msg . '</p>';
448
		if (!function_exists('debug_backtrace')) {
449
			return;
450
		}
451
		echo '<h2>Debug Backtrace</h2>';
452
		echo '<pre>';
453
		$index = -1;
454
		foreach (debug_backtrace() as $t) {
455
			$index++;
456
			if ($index == 0) {  // hide the backtrace of this function
457
				continue;
458
			}
459
			echo '#' . $index . ' ';
460
			if (isset($t['file'])) {
461
				echo basename($t['file']) . ':' . $t['line'];
462
			} else {
463
				echo '<PHP inner-code>';
464
			}
465
			echo ' -- ';
466
			if (isset($t['class'])) {
467
				echo $t['class'] . $t['type'];
468
			}
469
			echo $t['function'] . '(';
470
			if (isset($t['args']) && count($t['args']) > 0) {
471
				$count = 0;
472
				foreach ($t['args'] as $item) {
473
					if (is_string($item)) {
474
						$str = htmlentities(str_replace("\r\n", "", $item), ENT_QUOTES);
475
						if (strlen($item) > 70) {
476
							echo "'" . substr($str, 0, 70) . "...'";
477
						} else {
478
							echo "'" . $str . "'";
479
						}
480
					} elseif (is_int($item) || is_float($item)) {
481
						echo $item;
482
					} elseif (is_object($item)) {
483
						echo get_class($item);
484
					} elseif (is_array($item)) {
485
						echo 'array(' . count($item) . ')';
486
					} elseif (is_bool($item)) {
487
						echo $item ? 'true' : 'false';
488
					} elseif ($item === null) {
489
						echo 'NULL';
490
					} elseif (is_resource($item)) {
491
						echo get_resource_type($item);
492
					}
493
					$count++;
494
					if (count($t['args']) > $count) {
495
						echo ', ';
496
					}
497
				}
498
			}
499
			echo ")\n";
500
		}
501
		echo '</pre>';
502
		exit(1);
503
	}
504
505
	/**
506
	 * Returns a list of user preferred languages.
507
	 * The languages are returned as an array. Each array element
508
	 * represents a single language preference. The languages are ordered
509
	 * according to user preferences. The first language is the most preferred.
510
	 * @return array list of user preferred languages.
511
	 */
512 1
	public static function getUserLanguages()
513
	{
514 1
		static $languages = null;
515 1
		if ($languages === null) {
516 1
			if (!isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
517
				$languages[0] = 'en';
518
			} else {
519 1
				$languages = [];
520 1
				foreach (explode(',', $_SERVER['HTTP_ACCEPT_LANGUAGE']) as $language) {
521 1
					$array = explode(';q=', trim($language));
522 1
					$languages[trim($array[0])] = isset($array[1]) ? (float) $array[1] : 1.0;
523
				}
524 1
				arsort($languages);
525 1
				$languages = array_keys($languages);
526 1
				if (empty($languages)) {
527
					$languages[0] = 'en';
528
				}
529
			}
530
		}
531 1
		return $languages;
532
	}
533
534
	/**
535
	 * Returns the most preferred language by the client user.
536
	 * @return string the most preferred language by the client user, defaults to English.
537
	 */
538 113
	public static function getPreferredLanguage()
539
	{
540 113
		static $language = null;
541 113
		if ($language === null) {
542 1
			$langs = Prado::getUserLanguages();
543 1
			$lang = explode('-', $langs[0]);
544 1
			if (empty($lang[0]) || !ctype_alpha($lang[0])) {
545
				$language = 'en';
546
			} else {
547 1
				$language = $lang[0];
548
			}
549
		}
550 113
		return $language;
551
	}
552
553
	/**
554
	 * Writes a log message.
555
	 * This method wraps {@link log()} by checking the application mode.
556
	 * When the application is in Debug mode, debug backtrace information is appended
557
	 * to the message and the message is logged at DEBUG level.
558
	 * When the application is in Performance mode, this method does nothing.
559
	 * Otherwise, the message is logged at INFO level.
560
	 * @param string $msg message to be logged
561
	 * @param string $category category of the message
562
	 * @param (string|TControl) $ctl control of the message
563
	 * @see log, getLogger
564
	 */
565 32
	public static function trace($msg, $category = 'Uncategorized', $ctl = null)
566
	{
567 32
		if (self::$_application && self::$_application->getMode() === TApplicationMode::Performance) {
568
			return;
569
		}
570 32
		if (!self::$_application || self::$_application->getMode() === TApplicationMode::Debug) {
571 32
			$trace = debug_backtrace();
572 32
			if (isset($trace[0]['file']) && isset($trace[0]['line'])) {
573 32
				$msg .= " (line {$trace[0]['line']}, {$trace[0]['file']})";
574
			}
575 32
			$level = TLogger::DEBUG;
576
		} else {
577
			$level = TLogger::INFO;
578
		}
579 32
		self::log($msg, $level, $category, $ctl);
580 32
	}
581
582
	/**
583
	 * Logs a message.
584
	 * Messages logged by this method may be retrieved via {@link TLogger::getLogs}
585
	 * and may be recorded in different media, such as file, email, database, using
586
	 * {@link TLogRouter}.
587
	 * @param string $msg message to be logged
588
	 * @param int $level level of the message. Valid values include
589
	 * TLogger::DEBUG, TLogger::INFO, TLogger::NOTICE, TLogger::WARNING,
590
	 * TLogger::ERROR, TLogger::ALERT, TLogger::FATAL.
591
	 * @param string $category category of the message
592
	 * @param (string|TControl) $ctl control of the message
593
	 */
594 32
	public static function log($msg, $level = TLogger::INFO, $category = 'Uncategorized', $ctl = null)
595
	{
596 32
		if (self::$_logger === null) {
597 1
			self::$_logger = new TLogger;
598
		}
599 32
		self::$_logger->log($msg, $level, $category, $ctl);
600 32
	}
601
602
	/**
603
	 * @return TLogger message logger
604
	 */
605
	public static function getLogger()
606
	{
607
		if (self::$_logger === null) {
608
			self::$_logger = new TLogger;
609
		}
610
		return self::$_logger;
611
	}
612
613
	/**
614
	 * Converts a variable into a string representation.
615
	 * This method achieves the similar functionality as var_dump and print_r
616
	 * but is more robust when handling complex objects such as PRADO controls.
617
	 * @param mixed $var variable to be dumped
618
	 * @param int $depth maximum depth that the dumper should go into the variable. Defaults to 10.
619
	 * @param bool $highlight whether to syntax highlight the output. Defaults to false.
620
	 * @return string the string representation of the variable
621
	 */
622
	public static function varDump($var, $depth = 10, $highlight = false)
623
	{
624
		return TVarDumper::dump($var, $depth, $highlight);
625
	}
626
627
	/**
628
	 * Localize a text to the locale/culture specified in the globalization handler.
629
	 * @param string $text text to be localized.
630
	 * @param array $parameters a set of parameters to substitute.
631
	 * @param string $catalogue a different catalogue to find the localize text.
632
	 * @param string $charset the input AND output charset.
633
	 * @return string localized text.
634
	 * @see TTranslate::formatter()
635
	 * @see TTranslate::init()
636
	 */
637
	public static function localize($text, $parameters = [], $catalogue = null, $charset = null)
638
	{
639
		$app = Prado::getApplication()->getGlobalization(false);
640
641
		$params = [];
642
		foreach ($parameters as $key => $value) {
643
			$params['{' . $key . '}'] = $value;
644
		}
645
646
		//no translation handler provided
647
		if ($app === null || ($config = $app->getTranslationConfiguration()) === null) {
648
			return strtr($text, $params);
649
		}
650
651
		if ($catalogue === null) {
652
			$catalogue = $config['catalogue'] ?? 'messages';
653
		}
654
655
		Translation::init($catalogue);
656
657
		//globalization charset
658
		$appCharset = $app === null ? '' : $app->getCharset();
659
660
		//default charset
661
		$defaultCharset = ($app === null) ? 'UTF-8' : $app->getDefaultCharset();
662
663
		//fall back
664
		if (empty($charset)) {
665
			$charset = $appCharset;
666
		}
667
		if (empty($charset)) {
668
			$charset = $defaultCharset;
669
		}
670
671
		return Translation::formatter($catalogue)->format($text, $params, $catalogue, $charset);
672
	}
673
}
674