Subversion Repositories SmartDukaan

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
16591 anikendra 1
<?php
2
/**
3
 * Basic CakePHP functionality.
4
 *
5
 * Core functions for including other source files, loading models and so forth.
6
 *
7
 * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
8
 * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
9
 *
10
 * Licensed under The MIT License
11
 * For full copyright and license information, please see the LICENSE.txt
12
 * Redistributions of files must retain the above copyright notice.
13
 *
14
 * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
15
 * @link          http://cakephp.org CakePHP(tm) Project
16
 * @package       Cake
17
 * @since         CakePHP(tm) v 0.2.9
18
 * @license       http://www.opensource.org/licenses/mit-license.php MIT License
19
 */
20
 
21
/**
22
 * Basic defines for timing functions.
23
 */
24
	define('SECOND', 1);
25
	define('MINUTE', 60);
26
	define('HOUR', 3600);
27
	define('DAY', 86400);
28
	define('WEEK', 604800);
29
	define('MONTH', 2592000);
30
	define('YEAR', 31536000);
31
 
32
if (!function_exists('config')) {
33
 
34
/**
35
 * Loads configuration files. Receives a set of configuration files
36
 * to load.
37
 * Example:
38
 *
39
 * `config('config1', 'config2');`
40
 *
41
 * @return bool Success
42
 * @link http://book.cakephp.org/2.0/en/core-libraries/global-constants-and-functions.html#config
43
 */
44
	function config() {
45
		$args = func_get_args();
46
		$count = count($args);
47
		$included = 0;
48
		foreach ($args as $arg) {
49
			if (file_exists(APP . 'Config' . DS . $arg . '.php')) {
50
				include_once APP . 'Config' . DS . $arg . '.php';
51
				$included++;
52
			}
53
		}
54
		return $included === $count;
55
	}
56
 
57
}
58
 
59
if (!function_exists('debug')) {
60
 
61
/**
62
 * Prints out debug information about given variable.
63
 *
64
 * Only runs if debug level is greater than zero.
65
 *
66
 * @param mixed $var Variable to show debug information for.
67
 * @param bool $showHtml If set to true, the method prints the debug data in a browser-friendly way.
68
 * @param bool $showFrom If set to true, the method prints from where the function was called.
69
 * @return void
70
 * @link http://book.cakephp.org/2.0/en/development/debugging.html#basic-debugging
71
 * @link http://book.cakephp.org/2.0/en/core-libraries/global-constants-and-functions.html#debug
72
 */
73
	function debug($var, $showHtml = null, $showFrom = true) {
74
		if (!Configure::read('debug')) {
75
			return;
76
		}
77
		App::uses('Debugger', 'Utility');
78
 
79
		$file = '';
80
		$line = '';
81
		$lineInfo = '';
82
		if ($showFrom) {
83
			$trace = Debugger::trace(array('start' => 1, 'depth' => 2, 'format' => 'array'));
84
			$file = str_replace(array(CAKE_CORE_INCLUDE_PATH, ROOT), '', $trace[0]['file']);
85
			$line = $trace[0]['line'];
86
		}
87
		$html = <<<HTML
88
<div class="cake-debug-output">
89
%s
90
<pre class="cake-debug">
91
%s
92
</pre>
93
</div>
94
HTML;
95
		$text = <<<TEXT
96
%s
97
########## DEBUG ##########
98
%s
99
###########################
100
 
101
TEXT;
102
		$template = $html;
103
		if (PHP_SAPI === 'cli' || $showHtml === false) {
104
			$template = $text;
105
			if ($showFrom) {
106
				$lineInfo = sprintf('%s (line %s)', $file, $line);
107
			}
108
		}
109
		if ($showHtml === null && $template !== $text) {
110
			$showHtml = true;
111
		}
112
		$var = Debugger::exportVar($var, 25);
113
		if ($showHtml) {
114
			$template = $html;
115
			$var = h($var);
116
			if ($showFrom) {
117
				$lineInfo = sprintf('<span><strong>%s</strong> (line <strong>%s</strong>)</span>', $file, $line);
118
			}
119
		}
120
		printf($template, $lineInfo, $var);
121
	}
122
 
123
}
124
 
125
if (!function_exists('stackTrace')) {
126
 
127
/**
128
 * Outputs a stack trace based on the supplied options.
129
 *
130
 * ### Options
131
 *
132
 * - `depth` - The number of stack frames to return. Defaults to 999
133
 * - `args` - Should arguments for functions be shown? If true, the arguments for each method call
134
 *   will be displayed.
135
 * - `start` - The stack frame to start generating a trace from. Defaults to 1
136
 *
137
 * @param array $options Format for outputting stack trace
138
 * @return mixed Formatted stack trace
139
 * @see Debugger::trace()
140
 */
141
	function stackTrace(array $options = array()) {
142
		if (!Configure::read('debug')) {
143
			return;
144
		}
145
		App::uses('Debugger', 'Utility');
146
 
147
		$options += array('start' => 0);
148
		$options['start']++;
149
		echo Debugger::trace($options);
150
	}
151
 
152
}
153
 
154
if (!function_exists('sortByKey')) {
155
 
156
/**
157
 * Sorts given $array by key $sortBy.
158
 *
159
 * @param array &$array Array to sort
160
 * @param string $sortBy Sort by this key
161
 * @param string $order Sort order asc/desc (ascending or descending).
162
 * @param int $type Type of sorting to perform
163
 * @return array|null Sorted array, or null if not an array.
164
 * @link http://book.cakephp.org/2.0/en/core-libraries/global-constants-and-functions.html#sortByKey
165
 */
166
	function sortByKey(&$array, $sortBy, $order = 'asc', $type = SORT_NUMERIC) {
167
		if (!is_array($array)) {
168
			return null;
169
		}
170
 
171
		foreach ($array as $key => $val) {
172
			$sa[$key] = $val[$sortBy];
173
		}
174
 
175
		if ($order === 'asc') {
176
			asort($sa, $type);
177
		} else {
178
			arsort($sa, $type);
179
		}
180
 
181
		foreach ($sa as $key => $val) {
182
			$out[] = $array[$key];
183
		}
184
		return $out;
185
	}
186
 
187
}
188
 
189
if (!function_exists('h')) {
190
 
191
/**
192
 * Convenience method for htmlspecialchars.
193
 *
194
 * @param string|array|object $text Text to wrap through htmlspecialchars. Also works with arrays, and objects.
195
 *    Arrays will be mapped and have all their elements escaped. Objects will be string cast if they
196
 *    implement a `__toString` method. Otherwise the class name will be used.
197
 * @param bool $double Encode existing html entities
198
 * @param string $charset Character set to use when escaping. Defaults to config value in 'App.encoding' or 'UTF-8'
199
 * @return string Wrapped text
200
 * @link http://book.cakephp.org/2.0/en/core-libraries/global-constants-and-functions.html#h
201
 */
202
	function h($text, $double = true, $charset = null) {
203
		if (is_string($text)) {
204
			//optimize for strings
205
		} elseif (is_array($text)) {
206
			$texts = array();
207
			foreach ($text as $k => $t) {
208
				$texts[$k] = h($t, $double, $charset);
209
			}
210
			return $texts;
211
		} elseif (is_object($text)) {
212
			if (method_exists($text, '__toString')) {
213
				$text = (string)$text;
214
			} else {
215
				$text = '(object)' . get_class($text);
216
			}
217
		} elseif (is_bool($text)) {
218
			return $text;
219
		}
220
 
221
		static $defaultCharset = false;
222
		if ($defaultCharset === false) {
223
			$defaultCharset = Configure::read('App.encoding');
224
			if ($defaultCharset === null) {
225
				$defaultCharset = 'UTF-8';
226
			}
227
		}
228
		if (is_string($double)) {
229
			$charset = $double;
230
		}
231
		return htmlspecialchars($text, ENT_QUOTES, ($charset) ? $charset : $defaultCharset, $double);
232
	}
233
 
234
}
235
 
236
if (!function_exists('pluginSplit')) {
237
 
238
/**
239
 * Splits a dot syntax plugin name into its plugin and class name.
240
 * If $name does not have a dot, then index 0 will be null.
241
 *
242
 * Commonly used like `list($plugin, $name) = pluginSplit($name);`
243
 *
244
 * @param string $name The name you want to plugin split.
245
 * @param bool $dotAppend Set to true if you want the plugin to have a '.' appended to it.
246
 * @param string $plugin Optional default plugin to use if no plugin is found. Defaults to null.
247
 * @return array Array with 2 indexes. 0 => plugin name, 1 => class name
248
 * @link http://book.cakephp.org/2.0/en/core-libraries/global-constants-and-functions.html#pluginSplit
249
 */
250
	function pluginSplit($name, $dotAppend = false, $plugin = null) {
251
		if (strpos($name, '.') !== false) {
252
			$parts = explode('.', $name, 2);
253
			if ($dotAppend) {
254
				$parts[0] .= '.';
255
			}
256
			return $parts;
257
		}
258
		return array($plugin, $name);
259
	}
260
 
261
}
262
 
263
if (!function_exists('pr')) {
264
 
265
/**
266
 * print_r() convenience function
267
 *
268
 * In terminals this will act the same as using print_r() directly, when not run on cli
269
 * print_r() will wrap <PRE> tags around the output of given array. Similar to debug().
270
 *
271
 * @param mixed $var Variable to print out
272
 * @return void
273
 * @link http://book.cakephp.org/2.0/en/core-libraries/global-constants-and-functions.html#pr
274
 * @see debug()
275
 */
276
	function pr($var) {
277
		if (Configure::read('debug') > 0) {
278
			$template = PHP_SAPI !== 'cli' ? '<pre>%s</pre>' : "\n%s\n";
279
			printf($template, print_r($var, true));
280
		}
281
	}
282
 
283
}
284
 
285
if (!function_exists('am')) {
286
 
287
/**
288
 * Merge a group of arrays
289
 *
290
 * Accepts variable arguments. Each argument will be converted into an array and then merged.
291
 *
292
 * @return array All array parameters merged into one
293
 * @link http://book.cakephp.org/2.0/en/core-libraries/global-constants-and-functions.html#am
294
 */
295
	function am() {
296
		$r = array();
297
		$args = func_get_args();
298
		foreach ($args as $a) {
299
			if (!is_array($a)) {
300
				$a = array($a);
301
			}
302
			$r = array_merge($r, $a);
303
		}
304
		return $r;
305
	}
306
 
307
}
308
 
309
if (!function_exists('env')) {
310
 
311
/**
312
 * Gets an environment variable from available sources, and provides emulation
313
 * for unsupported or inconsistent environment variables (i.e. DOCUMENT_ROOT on
314
 * IIS, or SCRIPT_NAME in CGI mode). Also exposes some additional custom
315
 * environment information.
316
 *
317
 * @param string $key Environment variable name.
318
 * @return string|bool|null Environment variable setting.
319
 * @link http://book.cakephp.org/2.0/en/core-libraries/global-constants-and-functions.html#env
320
 */
321
	function env($key) {
322
		if ($key === 'HTTPS') {
323
			if (isset($_SERVER['HTTPS'])) {
324
				return (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off');
325
			}
326
			return (strpos(env('SCRIPT_URI'), 'https://') === 0);
327
		}
328
 
329
		if ($key === 'SCRIPT_NAME') {
330
			if (env('CGI_MODE') && isset($_ENV['SCRIPT_URL'])) {
331
				$key = 'SCRIPT_URL';
332
			}
333
		}
334
 
335
		$val = null;
336
		if (isset($_SERVER[$key])) {
337
			$val = $_SERVER[$key];
338
		} elseif (isset($_ENV[$key])) {
339
			$val = $_ENV[$key];
340
		} elseif (getenv($key) !== false) {
341
			$val = getenv($key);
342
		}
343
 
344
		if ($key === 'REMOTE_ADDR' && $val === env('SERVER_ADDR')) {
345
			$addr = env('HTTP_PC_REMOTE_ADDR');
346
			if ($addr !== null) {
347
				$val = $addr;
348
			}
349
		}
350
 
351
		if ($val !== null) {
352
			return $val;
353
		}
354
 
355
		switch ($key) {
356
			case 'DOCUMENT_ROOT':
357
				$name = env('SCRIPT_NAME');
358
				$filename = env('SCRIPT_FILENAME');
359
				$offset = 0;
360
				if (!strpos($name, '.php')) {
361
					$offset = 4;
362
				}
363
				return substr($filename, 0, -(strlen($name) + $offset));
364
			case 'PHP_SELF':
365
				return str_replace(env('DOCUMENT_ROOT'), '', env('SCRIPT_FILENAME'));
366
			case 'CGI_MODE':
367
				return (PHP_SAPI === 'cgi');
368
			case 'HTTP_BASE':
369
				$host = env('HTTP_HOST');
370
				$parts = explode('.', $host);
371
				$count = count($parts);
372
 
373
				if ($count === 1) {
374
					return '.' . $host;
375
				} elseif ($count === 2) {
376
					return '.' . $host;
377
				} elseif ($count === 3) {
378
					$gTLD = array(
379
						'aero',
380
						'asia',
381
						'biz',
382
						'cat',
383
						'com',
384
						'coop',
385
						'edu',
386
						'gov',
387
						'info',
388
						'int',
389
						'jobs',
390
						'mil',
391
						'mobi',
392
						'museum',
393
						'name',
394
						'net',
395
						'org',
396
						'pro',
397
						'tel',
398
						'travel',
399
						'xxx'
400
					);
401
					if (in_array($parts[1], $gTLD)) {
402
						return '.' . $host;
403
					}
404
				}
405
				array_shift($parts);
406
				return '.' . implode('.', $parts);
407
		}
408
		return null;
409
	}
410
 
411
}
412
 
413
if (!function_exists('cache')) {
414
 
415
/**
416
 * Reads/writes temporary data to cache files or session.
417
 *
418
 * @param string $path File path within /tmp to save the file.
419
 * @param mixed $data The data to save to the temporary file.
420
 * @param mixed $expires A valid strtotime string when the data expires.
421
 * @param string $target The target of the cached data; either 'cache' or 'public'.
422
 * @return mixed The contents of the temporary file.
423
 * @deprecated 3.0.0 Will be removed in 3.0. Please use Cache::write() instead.
424
 */
425
	function cache($path, $data = null, $expires = '+1 day', $target = 'cache') {
426
		if (Configure::read('Cache.disable')) {
427
			return null;
428
		}
429
		$now = time();
430
 
431
		if (!is_numeric($expires)) {
432
			$expires = strtotime($expires, $now);
433
		}
434
 
435
		switch (strtolower($target)) {
436
			case 'cache':
437
				$filename = CACHE . $path;
438
				break;
439
			case 'public':
440
				$filename = WWW_ROOT . $path;
441
				break;
442
			case 'tmp':
443
				$filename = TMP . $path;
444
				break;
445
		}
446
		$timediff = $expires - $now;
447
		$filetime = false;
448
 
449
		if (file_exists($filename)) {
450
			//@codingStandardsIgnoreStart
451
			$filetime = @filemtime($filename);
452
			//@codingStandardsIgnoreEnd
453
		}
454
 
455
		if ($data === null) {
456
			if (file_exists($filename) && $filetime !== false) {
457
				if ($filetime + $timediff < $now) {
458
					//@codingStandardsIgnoreStart
459
					@unlink($filename);
460
					//@codingStandardsIgnoreEnd
461
				} else {
462
					//@codingStandardsIgnoreStart
463
					$data = @file_get_contents($filename);
464
					//@codingStandardsIgnoreEnd
465
				}
466
			}
467
		} elseif (is_writable(dirname($filename))) {
468
			//@codingStandardsIgnoreStart
469
			@file_put_contents($filename, $data, LOCK_EX);
470
			//@codingStandardsIgnoreEnd
471
		}
472
		return $data;
473
	}
474
 
475
}
476
 
477
if (!function_exists('clearCache')) {
478
 
479
/**
480
 * Used to delete files in the cache directories, or clear contents of cache directories
481
 *
482
 * @param string|array $params As String name to be searched for deletion, if name is a directory all files in
483
 *   directory will be deleted. If array, names to be searched for deletion. If clearCache() without params,
484
 *   all files in app/tmp/cache/views will be deleted
485
 * @param string $type Directory in tmp/cache defaults to view directory
486
 * @param string $ext The file extension you are deleting
487
 * @return true if files found and deleted false otherwise
488
 */
489
	function clearCache($params = null, $type = 'views', $ext = '.php') {
490
		if (is_string($params) || $params === null) {
491
			$params = preg_replace('/\/\//', '/', $params);
492
			$cache = CACHE . $type . DS . $params;
493
 
494
			if (is_file($cache . $ext)) {
495
				//@codingStandardsIgnoreStart
496
				@unlink($cache . $ext);
497
				//@codingStandardsIgnoreEnd
498
				return true;
499
			} elseif (is_dir($cache)) {
500
				$files = glob($cache . '*');
501
 
502
				if ($files === false) {
503
					return false;
504
				}
505
 
506
				foreach ($files as $file) {
507
					if (is_file($file) && strrpos($file, DS . 'empty') !== strlen($file) - 6) {
508
						//@codingStandardsIgnoreStart
509
						@unlink($file);
510
						//@codingStandardsIgnoreEnd
511
					}
512
				}
513
				return true;
514
			}
515
			$cache = array(
516
				CACHE . $type . DS . '*' . $params . $ext,
517
				CACHE . $type . DS . '*' . $params . '_*' . $ext
518
			);
519
			$files = array();
520
			while ($search = array_shift($cache)) {
521
				$results = glob($search);
522
				if ($results !== false) {
523
					$files = array_merge($files, $results);
524
				}
525
			}
526
			if (empty($files)) {
527
				return false;
528
			}
529
			foreach ($files as $file) {
530
				if (is_file($file) && strrpos($file, DS . 'empty') !== strlen($file) - 6) {
531
					//@codingStandardsIgnoreStart
532
					@unlink($file);
533
					//@codingStandardsIgnoreEnd
534
				}
535
			}
536
			return true;
537
 
538
		} elseif (is_array($params)) {
539
			foreach ($params as $file) {
540
				clearCache($file, $type, $ext);
541
			}
542
			return true;
543
		}
544
		return false;
545
	}
546
 
547
}
548
 
549
if (!function_exists('stripslashes_deep')) {
550
 
551
/**
552
 * Recursively strips slashes from all values in an array
553
 *
554
 * @param array $values Array of values to strip slashes
555
 * @return mixed What is returned from calling stripslashes
556
 * @link http://book.cakephp.org/2.0/en/core-libraries/global-constants-and-functions.html#stripslashes_deep
557
 */
558
	function stripslashes_deep($values) {
559
		if (is_array($values)) {
560
			foreach ($values as $key => $value) {
561
				$values[$key] = stripslashes_deep($value);
562
			}
563
		} else {
564
			$values = stripslashes($values);
565
		}
566
		return $values;
567
	}
568
 
569
}
570
 
571
if (!function_exists('__')) {
572
 
573
/**
574
 * Returns a translated string if one is found; Otherwise, the submitted message.
575
 *
576
 * @param string $singular Text to translate
577
 * @param mixed $args Array with arguments or multiple arguments in function
578
 * @return mixed translated string
579
 * @link http://book.cakephp.org/2.0/en/core-libraries/global-constants-and-functions.html#__
580
 */
581
	function __($singular, $args = null) {
582
		if (!$singular) {
583
			return;
584
		}
585
 
586
		App::uses('I18n', 'I18n');
587
		$translated = I18n::translate($singular);
588
		$arguments = func_get_args();
589
		return I18n::insertArgs($translated, array_slice($arguments, 1));
590
	}
591
 
592
}
593
 
594
if (!function_exists('__n')) {
595
 
596
/**
597
 * Returns correct plural form of message identified by $singular and $plural for count $count.
598
 * Some languages have more than one form for plural messages dependent on the count.
599
 *
600
 * @param string $singular Singular text to translate
601
 * @param string $plural Plural text
602
 * @param int $count Count
603
 * @param mixed $args Array with arguments or multiple arguments in function
604
 * @return mixed plural form of translated string
605
 * @link http://book.cakephp.org/2.0/en/core-libraries/global-constants-and-functions.html#__n
606
 */
607
	function __n($singular, $plural, $count, $args = null) {
608
		if (!$singular) {
609
			return;
610
		}
611
 
612
		App::uses('I18n', 'I18n');
613
		$translated = I18n::translate($singular, $plural, null, I18n::LC_MESSAGES, $count);
614
		$arguments = func_get_args();
615
		return I18n::insertArgs($translated, array_slice($arguments, 3));
616
	}
617
 
618
}
619
 
620
if (!function_exists('__d')) {
621
 
622
/**
623
 * Allows you to override the current domain for a single message lookup.
624
 *
625
 * @param string $domain Domain
626
 * @param string $msg String to translate
627
 * @param mixed $args Array with arguments or multiple arguments in function
628
 * @return string translated string
629
 * @link http://book.cakephp.org/2.0/en/core-libraries/global-constants-and-functions.html#__d
630
 */
631
	function __d($domain, $msg, $args = null) {
632
		if (!$msg) {
633
			return;
634
		}
635
		App::uses('I18n', 'I18n');
636
		$translated = I18n::translate($msg, null, $domain);
637
		$arguments = func_get_args();
638
		return I18n::insertArgs($translated, array_slice($arguments, 2));
639
	}
640
 
641
}
642
 
643
if (!function_exists('__dn')) {
644
 
645
/**
646
 * Allows you to override the current domain for a single plural message lookup.
647
 * Returns correct plural form of message identified by $singular and $plural for count $count
648
 * from domain $domain.
649
 *
650
 * @param string $domain Domain
651
 * @param string $singular Singular string to translate
652
 * @param string $plural Plural
653
 * @param int $count Count
654
 * @param mixed $args Array with arguments or multiple arguments in function
655
 * @return string plural form of translated string
656
 * @link http://book.cakephp.org/2.0/en/core-libraries/global-constants-and-functions.html#__dn
657
 */
658
	function __dn($domain, $singular, $plural, $count, $args = null) {
659
		if (!$singular) {
660
			return;
661
		}
662
		App::uses('I18n', 'I18n');
663
		$translated = I18n::translate($singular, $plural, $domain, I18n::LC_MESSAGES, $count);
664
		$arguments = func_get_args();
665
		return I18n::insertArgs($translated, array_slice($arguments, 4));
666
	}
667
 
668
}
669
 
670
if (!function_exists('__dc')) {
671
 
672
/**
673
 * Allows you to override the current domain for a single message lookup.
674
 * It also allows you to specify a category.
675
 *
676
 * The category argument allows a specific category of the locale settings to be used for fetching a message.
677
 * Valid categories are: LC_CTYPE, LC_NUMERIC, LC_TIME, LC_COLLATE, LC_MONETARY, LC_MESSAGES and LC_ALL.
678
 *
679
 * Note that the category must be specified with a class constant of I18n, instead of the constant name. The values are:
680
 *
681
 * - LC_ALL       I18n::LC_ALL
682
 * - LC_COLLATE   I18n::LC_COLLATE
683
 * - LC_CTYPE     I18n::LC_CTYPE
684
 * - LC_MONETARY  I18n::LC_MONETARY
685
 * - LC_NUMERIC   I18n::LC_NUMERIC
686
 * - LC_TIME      I18n::LC_TIME
687
 * - LC_MESSAGES  I18n::LC_MESSAGES
688
 *
689
 * @param string $domain Domain
690
 * @param string $msg Message to translate
691
 * @param int $category Category
692
 * @param mixed $args Array with arguments or multiple arguments in function
693
 * @return string translated string
694
 * @link http://book.cakephp.org/2.0/en/core-libraries/global-constants-and-functions.html#__dc
695
 */
696
	function __dc($domain, $msg, $category, $args = null) {
697
		if (!$msg) {
698
			return;
699
		}
700
		App::uses('I18n', 'I18n');
701
		$translated = I18n::translate($msg, null, $domain, $category);
702
		$arguments = func_get_args();
703
		return I18n::insertArgs($translated, array_slice($arguments, 3));
704
	}
705
 
706
}
707
 
708
if (!function_exists('__dcn')) {
709
 
710
/**
711
 * Allows you to override the current domain for a single plural message lookup.
712
 * It also allows you to specify a category.
713
 * Returns correct plural form of message identified by $singular and $plural for count $count
714
 * from domain $domain.
715
 *
716
 * The category argument allows a specific category of the locale settings to be used for fetching a message.
717
 * Valid categories are: LC_CTYPE, LC_NUMERIC, LC_TIME, LC_COLLATE, LC_MONETARY, LC_MESSAGES and LC_ALL.
718
 *
719
 * Note that the category must be specified with a class constant of I18n, instead of the constant name. The values are:
720
 *
721
 * - LC_ALL       I18n::LC_ALL
722
 * - LC_COLLATE   I18n::LC_COLLATE
723
 * - LC_CTYPE     I18n::LC_CTYPE
724
 * - LC_MONETARY  I18n::LC_MONETARY
725
 * - LC_NUMERIC   I18n::LC_NUMERIC
726
 * - LC_TIME      I18n::LC_TIME
727
 * - LC_MESSAGES  I18n::LC_MESSAGES
728
 *
729
 * @param string $domain Domain
730
 * @param string $singular Singular string to translate
731
 * @param string $plural Plural
732
 * @param int $count Count
733
 * @param int $category Category
734
 * @param mixed $args Array with arguments or multiple arguments in function
735
 * @return string plural form of translated string
736
 * @link http://book.cakephp.org/2.0/en/core-libraries/global-constants-and-functions.html#__dcn
737
 */
738
	function __dcn($domain, $singular, $plural, $count, $category, $args = null) {
739
		if (!$singular) {
740
			return;
741
		}
742
		App::uses('I18n', 'I18n');
743
		$translated = I18n::translate($singular, $plural, $domain, $category, $count);
744
		$arguments = func_get_args();
745
		return I18n::insertArgs($translated, array_slice($arguments, 5));
746
	}
747
 
748
}
749
 
750
if (!function_exists('__c')) {
751
 
752
/**
753
 * The category argument allows a specific category of the locale settings to be used for fetching a message.
754
 * Valid categories are: LC_CTYPE, LC_NUMERIC, LC_TIME, LC_COLLATE, LC_MONETARY, LC_MESSAGES and LC_ALL.
755
 *
756
 * Note that the category must be specified with a class constant of I18n, instead of the constant name. The values are:
757
 *
758
 * - LC_ALL       I18n::LC_ALL
759
 * - LC_COLLATE   I18n::LC_COLLATE
760
 * - LC_CTYPE     I18n::LC_CTYPE
761
 * - LC_MONETARY  I18n::LC_MONETARY
762
 * - LC_NUMERIC   I18n::LC_NUMERIC
763
 * - LC_TIME      I18n::LC_TIME
764
 * - LC_MESSAGES  I18n::LC_MESSAGES
765
 *
766
 * @param string $msg String to translate
767
 * @param int $category Category
768
 * @param mixed $args Array with arguments or multiple arguments in function
769
 * @return string translated string
770
 * @link http://book.cakephp.org/2.0/en/core-libraries/global-constants-and-functions.html#__c
771
 */
772
	function __c($msg, $category, $args = null) {
773
		if (!$msg) {
774
			return;
775
		}
776
		App::uses('I18n', 'I18n');
777
		$translated = I18n::translate($msg, null, null, $category);
778
		$arguments = func_get_args();
779
		return I18n::insertArgs($translated, array_slice($arguments, 2));
780
	}
781
 
782
}
783
 
784
if (!function_exists('__x')) {
785
 
786
/**
787
 * Returns a translated string if one is found; Otherwise, the submitted message.
788
 *
789
 * @param string $context Context of the text
790
 * @param string $singular Text to translate
791
 * @param mixed $args Array with arguments or multiple arguments in function
792
 * @return mixed translated string
793
 * @link http://book.cakephp.org/2.0/en/core-libraries/global-constants-and-functions.html#__
794
 */
795
	function __x($context, $singular, $args = null) {
796
		if (!$singular) {
797
			return;
798
		}
799
 
800
		App::uses('I18n', 'I18n');
801
		$translated = I18n::translate($singular, null, null, null, null, null, $context);
802
		$arguments = func_get_args();
803
		return I18n::insertArgs($translated, array_slice($arguments, 2));
804
	}
805
 
806
}
807
 
808
if (!function_exists('__xn')) {
809
 
810
/**
811
 * Returns correct plural form of message identified by $singular and $plural for count $count.
812
 * Some languages have more than one form for plural messages dependent on the count.
813
 *
814
 * @param string $context Context of the text
815
 * @param string $singular Singular text to translate
816
 * @param string $plural Plural text
817
 * @param int $count Count
818
 * @param mixed $args Array with arguments or multiple arguments in function
819
 * @return mixed plural form of translated string
820
 * @link http://book.cakephp.org/2.0/en/core-libraries/global-constants-and-functions.html#__n
821
 */
822
	function __xn($context, $singular, $plural, $count, $args = null) {
823
		if (!$singular) {
824
			return;
825
		}
826
 
827
		App::uses('I18n', 'I18n');
828
		$translated = I18n::translate($singular, $plural, null, I18n::LC_MESSAGES, $count, null, $context);
829
		$arguments = func_get_args();
830
		return I18n::insertArgs($translated, array_slice($arguments, 4));
831
	}
832
 
833
}
834
 
835
if (!function_exists('__dx')) {
836
 
837
/**
838
 * Allows you to override the current domain for a single message lookup.
839
 *
840
 * @param string $domain Domain
841
 * @param string $context Context of the text
842
 * @param string $msg String to translate
843
 * @param mixed $args Array with arguments or multiple arguments in function
844
 * @return string translated string
845
 * @link http://book.cakephp.org/2.0/en/core-libraries/global-constants-and-functions.html#__d
846
 */
847
	function __dx($domain, $context, $msg, $args = null) {
848
		if (!$msg) {
849
			return;
850
		}
851
		App::uses('I18n', 'I18n');
852
		$translated = I18n::translate($msg, null, $domain, null, null, null, $context);
853
		$arguments = func_get_args();
854
		return I18n::insertArgs($translated, array_slice($arguments, 3));
855
	}
856
 
857
}
858
 
859
if (!function_exists('__dxn')) {
860
 
861
/**
862
 * Allows you to override the current domain for a single plural message lookup.
863
 * Returns correct plural form of message identified by $singular and $plural for count $count
864
 * from domain $domain.
865
 *
866
 * @param string $domain Domain
867
 * @param string $context Context of the text
868
 * @param string $singular Singular string to translate
869
 * @param string $plural Plural
870
 * @param int $count Count
871
 * @param mixed $args Array with arguments or multiple arguments in function
872
 * @return string plural form of translated string
873
 * @link http://book.cakephp.org/2.0/en/core-libraries/global-constants-and-functions.html#__dn
874
 */
875
	function __dxn($domain, $context, $singular, $plural, $count, $args = null) {
876
		if (!$singular) {
877
			return;
878
		}
879
		App::uses('I18n', 'I18n');
880
		$translated = I18n::translate($singular, $plural, $domain, I18n::LC_MESSAGES, $count, null, $context);
881
		$arguments = func_get_args();
882
		return I18n::insertArgs($translated, array_slice($arguments, 5));
883
	}
884
 
885
}
886
 
887
if (!function_exists('__dxc')) {
888
 
889
/**
890
 * Allows you to override the current domain for a single message lookup.
891
 * It also allows you to specify a category.
892
 *
893
 * The category argument allows a specific category of the locale settings to be used for fetching a message.
894
 * Valid categories are: LC_CTYPE, LC_NUMERIC, LC_TIME, LC_COLLATE, LC_MONETARY, LC_MESSAGES and LC_ALL.
895
 *
896
 * Note that the category must be specified with a class constant of I18n, instead of the constant name. The values are:
897
 *
898
 * - LC_ALL       I18n::LC_ALL
899
 * - LC_COLLATE   I18n::LC_COLLATE
900
 * - LC_CTYPE     I18n::LC_CTYPE
901
 * - LC_MONETARY  I18n::LC_MONETARY
902
 * - LC_NUMERIC   I18n::LC_NUMERIC
903
 * - LC_TIME      I18n::LC_TIME
904
 * - LC_MESSAGES  I18n::LC_MESSAGES
905
 *
906
 * @param string $domain Domain
907
 * @param string $context Context of the text
908
 * @param string $msg Message to translate
909
 * @param int $category Category
910
 * @param mixed $args Array with arguments or multiple arguments in function
911
 * @return string translated string
912
 * @link http://book.cakephp.org/2.0/en/core-libraries/global-constants-and-functions.html#__dc
913
 */
914
	function __dxc($domain, $context, $msg, $category, $args = null) {
915
		if (!$msg) {
916
			return;
917
		}
918
		App::uses('I18n', 'I18n');
919
		$translated = I18n::translate($msg, null, $domain, $category, null, null, $context);
920
		$arguments = func_get_args();
921
		return I18n::insertArgs($translated, array_slice($arguments, 4));
922
	}
923
 
924
}
925
 
926
if (!function_exists('__dxcn')) {
927
 
928
/**
929
 * Allows you to override the current domain for a single plural message lookup.
930
 * It also allows you to specify a category.
931
 * Returns correct plural form of message identified by $singular and $plural for count $count
932
 * from domain $domain.
933
 *
934
 * The category argument allows a specific category of the locale settings to be used for fetching a message.
935
 * Valid categories are: LC_CTYPE, LC_NUMERIC, LC_TIME, LC_COLLATE, LC_MONETARY, LC_MESSAGES and LC_ALL.
936
 *
937
 * Note that the category must be specified with a class constant of I18n, instead of the constant name. The values are:
938
 *
939
 * - LC_ALL       I18n::LC_ALL
940
 * - LC_COLLATE   I18n::LC_COLLATE
941
 * - LC_CTYPE     I18n::LC_CTYPE
942
 * - LC_MONETARY  I18n::LC_MONETARY
943
 * - LC_NUMERIC   I18n::LC_NUMERIC
944
 * - LC_TIME      I18n::LC_TIME
945
 * - LC_MESSAGES  I18n::LC_MESSAGES
946
 *
947
 * @param string $domain Domain
948
 * @param string $context Context of the text
949
 * @param string $singular Singular string to translate
950
 * @param string $plural Plural
951
 * @param int $count Count
952
 * @param int $category Category
953
 * @param mixed $args Array with arguments or multiple arguments in function
954
 * @return string plural form of translated string
955
 * @link http://book.cakephp.org/2.0/en/core-libraries/global-constants-and-functions.html#__dcn
956
 */
957
	function __dxcn($domain, $context, $singular, $plural, $count, $category, $args = null) {
958
		if (!$singular) {
959
			return;
960
		}
961
		App::uses('I18n', 'I18n');
962
		$translated = I18n::translate($singular, $plural, $domain, $category, $count, null, $context);
963
		$arguments = func_get_args();
964
		return I18n::insertArgs($translated, array_slice($arguments, 6));
965
	}
966
 
967
}
968
 
969
if (!function_exists('__xc')) {
970
 
971
/**
972
 * The category argument allows a specific category of the locale settings to be used for fetching a message.
973
 * Valid categories are: LC_CTYPE, LC_NUMERIC, LC_TIME, LC_COLLATE, LC_MONETARY, LC_MESSAGES and LC_ALL.
974
 *
975
 * Note that the category must be specified with a class constant of I18n, instead of the constant name. The values are:
976
 *
977
 * - LC_ALL       I18n::LC_ALL
978
 * - LC_COLLATE   I18n::LC_COLLATE
979
 * - LC_CTYPE     I18n::LC_CTYPE
980
 * - LC_MONETARY  I18n::LC_MONETARY
981
 * - LC_NUMERIC   I18n::LC_NUMERIC
982
 * - LC_TIME      I18n::LC_TIME
983
 * - LC_MESSAGES  I18n::LC_MESSAGES
984
 *
985
 * @param string $context Context of the text
986
 * @param string $msg String to translate
987
 * @param int $category Category
988
 * @param mixed $args Array with arguments or multiple arguments in function
989
 * @return string translated string
990
 * @link http://book.cakephp.org/2.0/en/core-libraries/global-constants-and-functions.html#__c
991
 */
992
	function __xc($context, $msg, $category, $args = null) {
993
		if (!$msg) {
994
			return;
995
		}
996
		App::uses('I18n', 'I18n');
997
		$translated = I18n::translate($msg, null, null, $category, null, null, $context);
998
		$arguments = func_get_args();
999
		return I18n::insertArgs($translated, array_slice($arguments, 3));
1000
	}
1001
 
1002
}
1003
 
1004
if (!function_exists('LogError')) {
1005
 
1006
/**
1007
 * Shortcut to Log::write.
1008
 *
1009
 * @param string $message Message to write to log
1010
 * @return void
1011
 * @link http://book.cakephp.org/2.0/en/core-libraries/global-constants-and-functions.html#LogError
1012
 */
1013
	function LogError($message) {
1014
		App::uses('CakeLog', 'Log');
1015
		$bad = array("\n", "\r", "\t");
1016
		$good = ' ';
1017
		CakeLog::write('error', str_replace($bad, $good, $message));
1018
	}
1019
 
1020
}
1021
 
1022
if (!function_exists('fileExistsInPath')) {
1023
 
1024
/**
1025
 * Searches include path for files.
1026
 *
1027
 * @param string $file File to look for
1028
 * @return string Full path to file if exists, otherwise false
1029
 * @link http://book.cakephp.org/2.0/en/core-libraries/global-constants-and-functions.html#fileExistsInPath
1030
 */
1031
	function fileExistsInPath($file) {
1032
		$paths = explode(PATH_SEPARATOR, ini_get('include_path'));
1033
		foreach ($paths as $path) {
1034
			$fullPath = $path . DS . $file;
1035
 
1036
			if (file_exists($fullPath)) {
1037
				return $fullPath;
1038
			} elseif (file_exists($file)) {
1039
				return $file;
1040
			}
1041
		}
1042
		return false;
1043
	}
1044
 
1045
}
1046
 
1047
if (!function_exists('convertSlash')) {
1048
 
1049
/**
1050
 * Convert forward slashes to underscores and removes first and last underscores in a string
1051
 *
1052
 * @param string $string String to convert
1053
 * @return string with underscore remove from start and end of string
1054
 * @link http://book.cakephp.org/2.0/en/core-libraries/global-constants-and-functions.html#convertSlash
1055
 */
1056
	function convertSlash($string) {
1057
		$string = trim($string, '/');
1058
		$string = preg_replace('/\/\//', '/', $string);
1059
		$string = str_replace('/', '_', $string);
1060
		return $string;
1061
	}
1062
 
1063
}
1064
 
1065
if (!function_exists('json_last_error_msg')) {
1066
 
1067
/**
1068
 * Provides the fallback implementation of json_last_error_msg() available in PHP 5.5 and above.
1069
 *
1070
 * @return string Error message.
1071
 */
1072
	function json_last_error_msg() {
1073
		static $errors = array(
1074
			JSON_ERROR_NONE => '',
1075
			JSON_ERROR_DEPTH => 'Maximum stack depth exceeded',
1076
			JSON_ERROR_STATE_MISMATCH => 'Invalid or malformed JSON',
1077
			JSON_ERROR_CTRL_CHAR => 'Control character error, possibly incorrectly encoded',
1078
			JSON_ERROR_SYNTAX => 'Syntax error',
1079
			JSON_ERROR_UTF8 => 'Malformed UTF-8 characters, possibly incorrectly encoded'
1080
		);
1081
		$error = json_last_error();
1082
		return array_key_exists($error, $errors) ? $errors[$error] : "Unknown error ({$error})";
1083
	}
1084
 
1085
}