統計
| ブランチ: | リビジョン:

pictcode / lib / Cake / basics.php @ master

履歴 | 表示 | アノテート | ダウンロード (31.999 KB)

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 null;
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, otherwise null.
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 null;
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, otherwise null.
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 null;
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, otherwise null.
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 null;
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, otherwise null.
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 null;
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, otherwise null.
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 null;
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, otherwise null.
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 null;
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, otherwise null.
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 null;
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, otherwise null.
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 null;
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, otherwise null.
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 null;
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, otherwise null.
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 null;
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, otherwise null.
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 null;
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, otherwise null.
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 null;
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, otherwise null.
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 null;
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
}