Subversion-Projekte lars-tiefland.cakephp

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
1 lars 1
<?php
2
/* SVN FILE: $Id: basics.php 7945 2008-12-19 02:16:01Z gwoo $ */
3
/**
4
 * Basic Cake functionality.
5
 *
6
 * Core functions for including other source files, loading models and so forth.
7
 *
8
 * PHP versions 4 and 5
9
 *
10
 * CakePHP(tm) :  Rapid Development Framework (http://www.cakephp.org)
11
 * Copyright 2005-2008, Cake Software Foundation, Inc. (http://www.cakefoundation.org)
12
 *
13
 * Licensed under The MIT License
14
 * Redistributions of files must retain the above copyright notice.
15
 *
16
 * @filesource
17
 * @copyright     Copyright 2005-2008, Cake Software Foundation, Inc. (http://www.cakefoundation.org)
18
 * @link          http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
19
 * @package       cake
20
 * @subpackage    cake.cake
21
 * @since         CakePHP(tm) v 0.2.9
22
 * @version       $Revision: 7945 $
23
 * @modifiedby    $LastChangedBy: gwoo $
24
 * @lastmodified  $Date: 2008-12-18 18:16:01 -0800 (Thu, 18 Dec 2008) $
25
 * @license       http://www.opensource.org/licenses/mit-license.php The MIT License
26
 */
27
/**
28
 * Basic defines for timing functions.
29
 */
30
	define('SECOND', 1);
31
	define('MINUTE', 60 * SECOND);
32
	define('HOUR', 60 * MINUTE);
33
	define('DAY', 24 * HOUR);
34
	define('WEEK', 7 * DAY);
35
	define('MONTH', 30 * DAY);
36
	define('YEAR', 365 * DAY);
37
/**
38
 * Patch for PHP < 5.0
39
 */
40
if (!function_exists('clone')) {
41
	if (version_compare(PHP_VERSION, '5.0') < 0) {
42
		eval ('
43
		function clone($object)
44
		{
45
			return $object;
46
		}');
47
	}
48
}
49
/**
50
 * Loads configuration files. Receives a set of configuration files
51
 * to load.
52
 * Example:
53
 * <code>
54
 * config('config1', 'config2');
55
 * </code>
56
 *
57
 * @return boolean Success
58
 */
59
	function config() {
60
		$args = func_get_args();
61
		foreach ($args as $arg) {
62
			if ($arg === 'database' && file_exists(CONFIGS . 'database.php')) {
63
				include_once(CONFIGS . $arg . '.php');
64
			} elseif (file_exists(CONFIGS . $arg . '.php')) {
65
				include_once(CONFIGS . $arg . '.php');
66
 
67
				if (count($args) == 1) {
68
					return true;
69
				}
70
			} else {
71
				if (count($args) == 1) {
72
					return false;
73
				}
74
			}
75
		}
76
		return true;
77
	}
78
/**
79
 * Loads component/components from LIBS. Takes optional number of parameters.
80
 *
81
 * Example:
82
 * <code>
83
 * uses('flay', 'time');
84
 * </code>
85
 *
86
 * @param string $name Filename without the .php part
87
 */
88
	function uses() {
89
		$args = func_get_args();
90
		foreach ($args as $file) {
91
			require_once(LIBS . strtolower($file) . '.php');
92
		}
93
	}
94
/**
95
 * Prints out debug information about given variable.
96
 *
97
 * Only runs if debug level is greater than zero.
98
 *
99
 * @param boolean $var Variable to show debug information for.
100
 * @param boolean $showHtml If set to true, the method prints the debug data in a screen-friendly way.
101
 * @param boolean $showFrom If set to true, the method prints from where the function was called.
102
 * @link http://book.cakephp.org/view/458/Basic-Debugging
103
 */
104
	function debug($var = false, $showHtml = false, $showFrom = true) {
105
		if (Configure::read() > 0) {
106
			if ($showFrom) {
107
				$calledFrom = debug_backtrace();
108
				echo '<strong>' . substr(str_replace(ROOT, '', $calledFrom[0]['file']), 1) . '</strong>';
109
				echo ' (line <strong>' . $calledFrom[0]['line'] . '</strong>)';
110
			}
111
			echo "\n<pre class=\"cake-debug\">\n";
112
 
113
			$var = print_r($var, true);
114
			if ($showHtml) {
115
				$var = str_replace('<', '&lt;', str_replace('>', '&gt;', $var));
116
			}
117
			echo $var . "\n</pre>\n";
118
		}
119
	}
120
if (!function_exists('getMicrotime')) {
121
/**
122
 * Returns microtime for execution time checking
123
 *
124
 * @return float Microtime
125
 */
126
	function getMicrotime() {
127
		list($usec, $sec) = explode(' ', microtime());
128
		return ((float)$usec + (float)$sec);
129
	}
130
}
131
if (!function_exists('sortByKey')) {
132
/**
133
 * Sorts given $array by key $sortby.
134
 *
135
 * @param array $array Array to sort
136
 * @param string $sortby Sort by this key
137
 * @param string $order  Sort order asc/desc (ascending or descending).
138
 * @param integer $type Type of sorting to perform
139
 * @return mixed Sorted array
140
 */
141
	function sortByKey(&$array, $sortby, $order = 'asc', $type = SORT_NUMERIC) {
142
		if (!is_array($array)) {
143
			return null;
144
		}
145
 
146
		foreach ($array as $key => $val) {
147
			$sa[$key] = $val[$sortby];
148
		}
149
 
150
		if ($order == 'asc') {
151
			asort($sa, $type);
152
		} else {
153
			arsort($sa, $type);
154
		}
155
 
156
		foreach ($sa as $key => $val) {
157
			$out[] = $array[$key];
158
		}
159
		return $out;
160
	}
161
}
162
if (!function_exists('array_combine')) {
163
/**
164
 * Combines given identical arrays by using the first array's values as keys,
165
 * and the second one's values as values. (Implemented for backwards compatibility with PHP4)
166
 *
167
 * @param array $a1 Array to use for keys
168
 * @param array $a2 Array to use for values
169
 * @return mixed Outputs either combined array or false.
170
 */
171
	function array_combine($a1, $a2) {
172
		$a1 = array_values($a1);
173
		$a2 = array_values($a2);
174
		$c1 = count($a1);
175
		$c2 = count($a2);
176
 
177
		if ($c1 != $c2) {
178
			return false;
179
		}
180
		if ($c1 <= 0) {
181
			return false;
182
		}
183
		$output = array();
184
 
185
		for ($i = 0; $i < $c1; $i++) {
186
			$output[$a1[$i]] = $a2[$i];
187
		}
188
		return $output;
189
	}
190
}
191
/**
192
 * Convenience method for htmlspecialchars.
193
 *
194
 * @param string $text Text to wrap through htmlspecialchars
195
 * @param string $charset Character set to use when escaping.  Defaults to config value in 'App.encoding' or 'UTF-8'
196
 * @return string Wrapped text
197
 * @link http://book.cakephp.org/view/703/h
198
 */
199
	function h($text, $charset = null) {
200
		if (is_array($text)) {
201
			return array_map('h', $text);
202
		}
203
		if (empty($charset)) {
204
			$charset = Configure::read('App.encoding');
205
		}
206
		if (empty($charset)) {
207
			$charset = 'UTF-8';
208
		}
209
		return htmlspecialchars($text, ENT_QUOTES, $charset);
210
	}
211
/**
212
 * Returns an array of all the given parameters.
213
 *
214
 * Example:
215
 * <code>
216
 * a('a', 'b')
217
 * </code>
218
 *
219
 * Would return:
220
 * <code>
221
 * array('a', 'b')
222
 * </code>
223
 *
224
 * @return array Array of given parameters
225
 * @link http://book.cakephp.org/view/694/a
226
 */
227
	function a() {
228
		$args = func_get_args();
229
		return $args;
230
	}
231
/**
232
 * Constructs associative array from pairs of arguments.
233
 *
234
 * Example:
235
 * <code>
236
 * aa('a','b')
237
 * </code>
238
 *
239
 * Would return:
240
 * <code>
241
 * array('a'=>'b')
242
 * </code>
243
 *
244
 * @return array Associative array
245
 * @link http://book.cakephp.org/view/695/aa
246
 */
247
	function aa() {
248
		$args = func_get_args();
249
		$argc = count($args);
250
		for ($i = 0; $i < $argc; $i++) {
251
			if ($i + 1 < $argc) {
252
				$a[$args[$i]] = $args[$i + 1];
253
			} else {
254
				$a[$args[$i]] = null;
255
			}
256
			$i++;
257
		}
258
		return $a;
259
	}
260
/**
261
 * Convenience method for echo().
262
 *
263
 * @param string $text String to echo
264
 * @link http://book.cakephp.org/view/700/e
265
 */
266
	function e($text) {
267
		echo $text;
268
	}
269
/**
270
 * Convenience method for strtolower().
271
 *
272
 * @param string $str String to lowercase
273
 * @return string Lowercased string
274
 * @link http://book.cakephp.org/view/705/low
275
 */
276
	function low($str) {
277
		return strtolower($str);
278
	}
279
/**
280
 * Convenience method for strtoupper().
281
 *
282
 * @param string $str String to uppercase
283
 * @return string Uppercased string
284
 * @link http://book.cakephp.org/view/710/up
285
 */
286
	function up($str) {
287
		return strtoupper($str);
288
	}
289
/**
290
 * Convenience method for str_replace().
291
 *
292
 * @param string $search String to be replaced
293
 * @param string $replace String to insert
294
 * @param string $subject String to search
295
 * @return string Replaced string
296
 * @link http://book.cakephp.org/view/708/r
297
 */
298
	function r($search, $replace, $subject) {
299
		return str_replace($search, $replace, $subject);
300
	}
301
/**
302
 * Print_r convenience function, which prints out <PRE> tags around
303
 * the output of given array. Similar to debug().
304
 *
305
 * @see	debug()
306
 * @param array $var Variable to print out
307
 * @param boolean $showFrom If set to true, the method prints from where the function was called
308
 * @link http://book.cakephp.org/view/707/pr
309
 */
310
	function pr($var) {
311
		if (Configure::read() > 0) {
312
			echo '<pre>';
313
			print_r($var);
314
			echo '</pre>';
315
		}
316
	}
317
/**
318
 * Display parameters.
319
 *
320
 * @param mixed $p Parameter as string or array
321
 * @return string
322
 */
323
	function params($p) {
324
		if (!is_array($p) || count($p) == 0) {
325
			return null;
326
		}
327
		if (is_array($p[0]) && count($p) == 1) {
328
			return $p[0];
329
		}
330
		return $p;
331
	}
332
/**
333
 * Merge a group of arrays
334
 *
335
 * @param array First array
336
 * @param array Second array
337
 * @param array Third array
338
 * @param array Etc...
339
 * @return array All array parameters merged into one
340
 * @link http://book.cakephp.org/view/696/am
341
 */
342
	function am() {
343
		$r = array();
344
		$args = func_get_args();
345
		foreach ($args as $a) {
346
			if (!is_array($a)) {
347
				$a = array($a);
348
			}
349
			$r = array_merge($r, $a);
350
		}
351
		return $r;
352
	}
353
/**
354
 * Gets an environment variable from available sources, and provides emulation
355
 * for unsupported or inconsistent environment variables (i.e. DOCUMENT_ROOT on
356
 * IIS, or SCRIPT_NAME in CGI mode).  Also exposes some additional custom
357
 * environment information.
358
 *
359
 * @param  string $key Environment variable name.
360
 * @return string Environment variable setting.
361
 * @link http://book.cakephp.org/view/701/env
362
 */
363
	function env($key) {
364
		if ($key == 'HTTPS') {
365
			if (isset($_SERVER) && !empty($_SERVER)) {
366
				return (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on');
367
			}
368
			return (strpos(env('SCRIPT_URI'), 'https://') === 0);
369
		}
370
 
371
		if ($key == 'SCRIPT_NAME') {
372
			if (env('CGI_MODE') && isset($_ENV['SCRIPT_URL'])) {
373
				$key = 'SCRIPT_URL';
374
			}
375
		}
376
 
377
		$val = null;
378
		if (isset($_SERVER[$key])) {
379
			$val = $_SERVER[$key];
380
		} elseif (isset($_ENV[$key])) {
381
			$val = $_ENV[$key];
382
		} elseif (getenv($key) !== false) {
383
			$val = getenv($key);
384
		}
385
 
386
		if ($key === 'REMOTE_ADDR' && $val === env('SERVER_ADDR')) {
387
			$addr = env('HTTP_PC_REMOTE_ADDR');
388
			if ($addr !== null) {
389
				$val = $addr;
390
			}
391
		}
392
 
393
		if ($val !== null) {
394
			return $val;
395
		}
396
 
397
		switch ($key) {
398
			case 'SCRIPT_FILENAME':
399
				if (defined('SERVER_IIS') && SERVER_IIS === true) {
400
					return str_replace('\\\\', '\\', env('PATH_TRANSLATED'));
401
				}
402
			break;
403
			case 'DOCUMENT_ROOT':
404
				$name = env('SCRIPT_NAME');
405
				$filename = env('SCRIPT_FILENAME');
406
				$offset = 0;
407
				if (!strpos($name, '.php')) {
408
					$offset = 4;
409
				}
410
				return substr($filename, 0, strlen($filename) - (strlen($name) + $offset));
411
			break;
412
			case 'PHP_SELF':
413
				return str_replace(env('DOCUMENT_ROOT'), '', env('SCRIPT_FILENAME'));
414
			break;
415
			case 'CGI_MODE':
416
				return (PHP_SAPI === 'cgi');
417
			break;
418
			case 'HTTP_BASE':
419
				$host = env('HTTP_HOST');
420
				if (substr_count($host, '.') !== 1) {
421
					return preg_replace('/^([^.])*/i', null, env('HTTP_HOST'));
422
				}
423
			return '.' . $host;
424
			break;
425
		}
426
		return null;
427
	}
428
if (!function_exists('file_put_contents')) {
429
/**
430
 * Writes data into file.
431
 *
432
 * If file exists, it will be overwritten. If data is an array, it will be join()ed with an empty string.
433
 *
434
 * @param string $fileName File name.
435
 * @param mixed  $data String or array.
436
 * @return boolean Success
437
 */
438
	function file_put_contents($fileName, $data) {
439
		if (is_array($data)) {
440
			$data = join('', $data);
441
		}
442
		$res = @fopen($fileName, 'w+b');
443
 
444
		if ($res) {
445
			$write = @fwrite($res, $data);
446
			if ($write === false) {
447
				return false;
448
			} else {
449
				@fclose($res);
450
				return $write;
451
			}
452
		}
453
		return false;
454
	}
455
}
456
/**
457
 * Reads/writes temporary data to cache files or session.
458
 *
459
 * @param  string $path	File path within /tmp to save the file.
460
 * @param  mixed  $data	The data to save to the temporary file.
461
 * @param  mixed  $expires A valid strtotime string when the data expires.
462
 * @param  string $target  The target of the cached data; either 'cache' or 'public'.
463
 * @return mixed  The contents of the temporary file.
464
 * @deprecated Please use Cache::write() instead
465
 */
466
	function cache($path, $data = null, $expires = '+1 day', $target = 'cache') {
467
		if (Configure::read('Cache.disable')) {
468
			return null;
469
		}
470
		$now = time();
471
 
472
		if (!is_numeric($expires)) {
473
			$expires = strtotime($expires, $now);
474
		}
475
 
476
		switch (low($target)) {
477
			case 'cache':
478
				$filename = CACHE . $path;
479
			break;
480
			case 'public':
481
				$filename = WWW_ROOT . $path;
482
			break;
483
			case 'tmp':
484
				$filename = TMP . $path;
485
			break;
486
		}
487
		$timediff = $expires - $now;
488
		$filetime = false;
489
 
490
		if (file_exists($filename)) {
491
			$filetime = @filemtime($filename);
492
		}
493
 
494
		if ($data === null) {
495
			if (file_exists($filename) && $filetime !== false) {
496
				if ($filetime + $timediff < $now) {
497
					@unlink($filename);
498
				} else {
499
					$data = @file_get_contents($filename);
500
				}
501
			}
502
		} elseif (is_writable(dirname($filename))) {
503
			@file_put_contents($filename, $data);
504
		}
505
		return $data;
506
	}
507
/**
508
 * Used to delete files in the cache directories, or clear contents of cache directories
509
 *
510
 * @param mixed $params As String name to be searched for deletion, if name is a directory all files in directory will be deleted.
511
 *              If array, names to be searched for deletion.
512
 *              If clearCache() without params, all files in app/tmp/cache/views will be deleted
513
 *
514
 * @param string $type Directory in tmp/cache defaults to view directory
515
 * @param string $ext The file extension you are deleting
516
 * @return true if files found and deleted false otherwise
517
 */
518
	function clearCache($params = null, $type = 'views', $ext = '.php') {
519
		if (is_string($params) || $params === null) {
520
			$params = preg_replace('/\/\//', '/', $params);
521
			$cache = CACHE . $type . DS . $params;
522
 
523
			if (is_file($cache . $ext)) {
524
				@unlink($cache . $ext);
525
				return true;
526
			} elseif (is_dir($cache)) {
527
				$files = glob($cache . '*');
528
 
529
				if ($files === false) {
530
					return false;
531
				}
532
 
533
				foreach ($files as $file) {
534
					if (is_file($file)) {
535
						@unlink($file);
536
					}
537
				}
538
				return true;
539
			} else {
540
				$cache = array(
541
					CACHE . $type . DS . '*' . $params . $ext,
542
					CACHE . $type . DS . '*' . $params . '_*' . $ext
543
				);
544
				$files = array();
545
				while ($search = array_shift($cache)) {
546
					$results = glob($search);
547
					if ($results !== false) {
548
						$files = array_merge($files, $results);
549
					}
550
				}
551
				if (empty($files)) {
552
					return false;
553
				}
554
				foreach ($files as $file) {
555
					if (is_file($file)) {
556
						@unlink($file);
557
					}
558
				}
559
				return true;
560
			}
561
		} elseif (is_array($params)) {
562
			foreach ($params as $file) {
563
				clearCache($file, $type, $ext);
564
			}
565
			return true;
566
		}
567
		return false;
568
	}
569
/**
570
 * Recursively strips slashes from all values in an array
571
 *
572
 * @param array $values Array of values to strip slashes
573
 * @return mixed What is returned from calling stripslashes
574
 * @link http://book.cakephp.org/view/709/stripslashes_deep
575
 */
576
	function stripslashes_deep($values) {
577
		if (is_array($values)) {
578
			foreach ($values as $key => $value) {
579
				$values[$key] = stripslashes_deep($value);
580
			}
581
		} else {
582
			$values = stripslashes($values);
583
		}
584
		return $values;
585
	}
586
/**
587
 * Returns a translated string if one is found; Otherwise, the submitted message.
588
 *
589
 * @param string $singular Text to translate
590
 * @param boolean $return Set to true to return translated string, or false to echo
591
 * @return mixed translated string if $return is false string will be echoed
592
 * @link http://book.cakephp.org/view/693/__
593
 */
594
	function __($singular, $return = false) {
595
		if (!$singular) {
596
			return;
597
		}
598
		if (!class_exists('I18n')) {
599
			App::import('Core', 'i18n');
600
		}
601
 
602
		if ($return === false) {
603
			echo I18n::translate($singular);
604
		} else {
605
			return I18n::translate($singular);
606
		}
607
	}
608
/**
609
 * Returns correct plural form of message identified by $singular and $plural for count $count.
610
 * Some languages have more than one form for plural messages dependent on the count.
611
 *
612
 * @param string $singular Singular text to translate
613
 * @param string $plural Plural text
614
 * @param integer $count Count
615
 * @param boolean $return true to return, false to echo
616
 * @return mixed plural form of translated string if $return is false string will be echoed
617
 */
618
	function __n($singular, $plural, $count, $return = false) {
619
		if (!$singular) {
620
			return;
621
		}
622
		if (!class_exists('I18n')) {
623
			App::import('Core', 'i18n');
624
		}
625
 
626
		if ($return === false) {
627
			echo I18n::translate($singular, $plural, null, 5, $count);
628
		} else {
629
			return I18n::translate($singular, $plural, null, 5, $count);
630
		}
631
	}
632
/**
633
 * Allows you to override the current domain for a single message lookup.
634
 *
635
 * @param string $domain Domain
636
 * @param string $msg String to translate
637
 * @param string $return true to return, false to echo
638
 * @return translated string if $return is false string will be echoed
639
 */
640
	function __d($domain, $msg, $return = false) {
641
		if (!$msg) {
642
			return;
643
		}
644
		if (!class_exists('I18n')) {
645
			App::import('Core', 'i18n');
646
		}
647
 
648
		if ($return === false) {
649
			echo I18n::translate($msg, null, $domain);
650
		} else {
651
			return I18n::translate($msg, null, $domain);
652
		}
653
	}
654
/**
655
 * Allows you to override the current domain for a single plural message lookup.
656
 * Returns correct plural form of message identified by $singular and $plural for count $count
657
 * from domain $domain.
658
 *
659
 * @param string $domain Domain
660
 * @param string $singular Singular string to translate
661
 * @param string $plural Plural
662
 * @param integer $count Count
663
 * @param boolean $return true to return, false to echo
664
 * @return plural form of translated string if $return is false string will be echoed
665
 */
666
	function __dn($domain, $singular, $plural, $count, $return = false) {
667
		if (!$singular) {
668
			return;
669
		}
670
		if (!class_exists('I18n')) {
671
			App::import('Core', 'i18n');
672
		}
673
 
674
		if ($return === false) {
675
			echo I18n::translate($singular, $plural, $domain, 5, $count);
676
		} else {
677
			return I18n::translate($singular, $plural, $domain, 5, $count);
678
		}
679
	}
680
/**
681
 * Allows you to override the current domain for a single message lookup.
682
 * It also allows you to specify a category.
683
 *
684
 * The category argument allows a specific category of the locale settings to be used for fetching a message.
685
 * Valid categories are: LC_CTYPE, LC_NUMERIC, LC_TIME, LC_COLLATE, LC_MONETARY, LC_MESSAGES and LC_ALL.
686
 *
687
 * Note that the category must be specified with a numeric value, instead of the constant name.  The values are:
688
 * LC_CTYPE     0
689
 * LC_NUMERIC   1
690
 * LC_TIME      2
691
 * LC_COLLATE   3
692
 * LC_MONETARY  4
693
 * LC_MESSAGES  5
694
 * LC_ALL       6
695
 *
696
 * @param string $domain Domain
697
 * @param string $msg Message to translate
698
 * @param integer $category Category
699
 * @param boolean $return true to return, false to echo
700
 * @return translated string if $return is false string will be echoed
701
 */
702
	function __dc($domain, $msg, $category, $return = false) {
703
		if (!$msg) {
704
			return;
705
		}
706
		if (!class_exists('I18n')) {
707
			App::import('Core', 'i18n');
708
		}
709
 
710
		if ($return === false) {
711
			echo I18n::translate($msg, null, $domain, $category);
712
		} else {
713
			return I18n::translate($msg, null, $domain, $category);
714
		}
715
	}
716
/**
717
 * Allows you to override the current domain for a single plural message lookup.
718
 * It also allows you to specify a category.
719
 * Returns correct plural form of message identified by $singular and $plural for count $count
720
 * from domain $domain.
721
 *
722
 * The category argument allows a specific category of the locale settings to be used for fetching a message.
723
 * Valid categories are: LC_CTYPE, LC_NUMERIC, LC_TIME, LC_COLLATE, LC_MONETARY, LC_MESSAGES and LC_ALL.
724
 *
725
 * Note that the category must be specified with a numeric value, instead of the constant name.  The values are:
726
 * LC_CTYPE     0
727
 * LC_NUMERIC   1
728
 * LC_TIME      2
729
 * LC_COLLATE   3
730
 * LC_MONETARY  4
731
 * LC_MESSAGES  5
732
 * LC_ALL       6
733
 *
734
 * @param string $domain Domain
735
 * @param string $singular Singular string to translate
736
 * @param string $plural Plural
737
 * @param integer $count Count
738
 * @param integer $category Category
739
 * @param boolean $return true to return, false to echo
740
 * @return plural form of translated string if $return is false string will be echoed
741
 */
742
	function __dcn($domain, $singular, $plural, $count, $category, $return = false) {
743
		if (!$singular) {
744
			return;
745
		}
746
		if (!class_exists('I18n')) {
747
			App::import('Core', 'i18n');
748
		}
749
 
750
		if ($return === false) {
751
			echo I18n::translate($singular, $plural, $domain, $category, $count);
752
		} else {
753
			return I18n::translate($singular, $plural, $domain, $category, $count);
754
		}
755
	}
756
/**
757
 * The category argument allows a specific category of the locale settings to be used for fetching a message.
758
 * Valid categories are: LC_CTYPE, LC_NUMERIC, LC_TIME, LC_COLLATE, LC_MONETARY, LC_MESSAGES and LC_ALL.
759
 *
760
 * Note that the category must be specified with a numeric value, instead of the constant name.  The values are:
761
 * LC_CTYPE     0
762
 * LC_NUMERIC   1
763
 * LC_TIME      2
764
 * LC_COLLATE   3
765
 * LC_MONETARY  4
766
 * LC_MESSAGES  5
767
 * LC_ALL       6
768
 *
769
 * @param string $msg String to translate
770
 * @param integer $category Category
771
 * @param string $return true to return, false to echo
772
 * @return translated string if $return is false string will be echoed
773
 */
774
	function __c($msg, $category, $return = false) {
775
		if (!$msg) {
776
			return;
777
		}
778
		if (!class_exists('I18n')) {
779
			App::import('Core', 'i18n');
780
		}
781
 
782
		if ($return === false) {
783
			echo I18n::translate($msg, null, null, $category);
784
		} else {
785
			return I18n::translate($msg, null, null, $category);
786
		}
787
	}
788
/**
789
 * Computes the difference of arrays using keys for comparison.
790
 *
791
 * @param array First array
792
 * @param array Second array
793
 * @return array Array with different keys
794
 */
795
	if (!function_exists('array_diff_key')) {
796
		function array_diff_key() {
797
			$valuesDiff = array();
798
 
799
			$argc = func_num_args();
800
			if ($argc < 2) {
801
				return false;
802
			}
803
 
804
			$args = func_get_args();
805
			foreach ($args as $param) {
806
				if (!is_array($param)) {
807
					return false;
808
				}
809
			}
810
 
811
			foreach ($args[0] as $valueKey => $valueData) {
812
				for ($i = 1; $i < $argc; $i++) {
813
					if (isset($args[$i][$valueKey])) {
814
						continue 2;
815
					}
816
				}
817
				$valuesDiff[$valueKey] = $valueData;
818
			}
819
			return $valuesDiff;
820
		}
821
	}
822
/**
823
 * Computes the intersection of arrays using keys for comparison
824
 *
825
 * @param array First array
826
 * @param array Second array
827
 * @return array Array with interesected keys
828
 */
829
	if (!function_exists('array_intersect_key')) {
830
		function array_intersect_key($arr1, $arr2) {
831
			$res = array();
832
			foreach ($arr1 as $key => $value) {
833
				if (isset($arr2[$key])) {
834
					$res[$key] = $arr1[$key];
835
				}
836
			}
837
			return $res;
838
		}
839
	}
840
/**
841
 * Shortcut to Log::write.
842
 *
843
 * @param string $message Message to write to log
844
 */
845
	function LogError($message) {
846
		if (!class_exists('CakeLog')) {
847
			App::import('Core', 'CakeLog');
848
		}
849
		$bad = array("\n", "\r", "\t");
850
		$good = ' ';
851
		CakeLog::write('error', str_replace($bad, $good, $message));
852
	}
853
/**
854
 * Searches include path for files.
855
 *
856
 * @param string $file File to look for
857
 * @return Full path to file if exists, otherwise false
858
 * @link http://book.cakephp.org/view/702/fileExistsInPath
859
 */
860
	function fileExistsInPath($file) {
861
		$paths = explode(PATH_SEPARATOR, ini_get('include_path'));
862
		foreach ($paths as $path) {
863
			$fullPath = $path . DS . $file;
864
 
865
			if (file_exists($fullPath)) {
866
				return $fullPath;
867
			} elseif (file_exists($file)) {
868
				return $file;
869
			}
870
		}
871
		return false;
872
	}
873
/**
874
 * Convert forward slashes to underscores and removes first and last underscores in a string
875
 *
876
 * @param string String to convert
877
 * @return string with underscore remove from start and end of string
878
 * @link http://book.cakephp.org/view/697/convertSlash
879
 */
880
	function convertSlash($string) {
881
		$string = trim($string, '/');
882
		$string = preg_replace('/\/\//', '/', $string);
883
		$string = str_replace('/', '_', $string);
884
		return $string;
885
	}
886
/**
887
 * Implements http_build_query for PHP4.
888
 *
889
 * @param string $data Data to set in query string
890
 * @param string $prefix If numeric indices, prepend this to index for elements in base array.
891
 * @param string $argSep String used to separate arguments
892
 * @param string $baseKey Base key
893
 * @return string URL encoded query string
894
 * @see http://php.net/http_build_query
895
 */
896
	if (!function_exists('http_build_query')) {
897
		function http_build_query($data, $prefix = null, $argSep = null, $baseKey = null) {
898
			if (empty($argSep)) {
899
				$argSep = ini_get('arg_separator.output');
900
			}
901
			if (is_object($data)) {
902
				$data = get_object_vars($data);
903
			}
904
			$out = array();
905
 
906
			foreach ((array)$data as $key => $v) {
907
				if (is_numeric($key) && !empty($prefix)) {
908
					$key = $prefix . $key;
909
				}
910
				$key = urlencode($key);
911
 
912
				if (!empty($baseKey)) {
913
					$key = $baseKey . '[' . $key . ']';
914
				}
915
 
916
				if (is_array($v) || is_object($v)) {
917
					$out[] = http_build_query($v, $prefix, $argSep, $key);
918
				} else {
919
					$out[] = $key . '=' . urlencode($v);
920
				}
921
			}
922
			return implode($argSep, $out);
923
		}
924
	}
925
/**
926
 * Wraps ternary operations. If $condition is a non-empty value, $val1 is returned, otherwise $val2.
927
 * Don't use for isset() conditions, or wrap your variable with @ operator:
928
 * Example:
929
 * <code>
930
 * ife(isset($variable), @$variable, 'default');
931
 * </code>
932
 *
933
 * @param mixed $condition Conditional expression
934
 * @param mixed $val1 Value to return in case condition matches
935
 * @param mixed $val2 Value to return if condition doesn't match
936
 * @return mixed $val1 or $val2, depending on whether $condition evaluates to a non-empty expression.
937
 * @link http://book.cakephp.org/view/704/ife
938
 */
939
	function ife($condition, $val1 = null, $val2 = null) {
940
		if (!empty($condition)) {
941
			return $val1;
942
		}
943
		return $val2;
944
	}
945
?>