/mvc/helpers/cakeBasics
[return to app]1
<?php
2
3 /**
4 * Basic Cake functionality.
5 *
6 * This is CakePHP 2.0 BasicsHelper class updated to PHP5 syntax for Vork
7 *
8 * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
9 * Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
10 *
11 * Licensed under The MIT License
12 * Redistributions of files must retain the above copyright notice.
13 *
14 * @copyright Copyright 2005-2010, 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 MIT License (http://www.opensource.org/licenses/mit-license.php)
19 */
20
21 class cakeBasicsHelper{
22
23 /**
24 * Loads configuration files. Receives a set of configuration files
25 * to load.
26 * Example:
27 *
28 * `config('config1', 'config2');`
29 *
30 * @return boolean Success
31 * @link http://book.cakephp.org/view/1125/config
32 */
33 public function config() {
34 $args = func_get_args();
35 foreach ($args as $arg) {
36 if ($arg === 'database' && file_exists(APP . 'Config' . DS . 'database.php')) {
37 include_once(APP . 'Config' . DS . $arg . '.php');
38 } elseif (file_exists(APP . 'Config' . DS . $arg . '.php')) {
39 include_once(APP . 'Config' . DS . $arg . '.php');
40
41 if (count($args) == 1) {
42 return true;
43 }
44 } else {
45 if (count($args) == 1) {
46 return false;
47 }
48 }
49 }
50 return true;
51 }
52
53 public function sortByKey(&$array, $sortby, $order = 'asc', $type = SORT_NUMERIC) {
54 if (!is_array($array)) {
55 return null;
56 }
57
58 foreach ($array as $key => $val) {
59 $sa[$key] = $val[$sortby];
60 }
61
62 if ($order == 'asc') {
63 asort($sa, $type);
64 } else {
65 arsort($sa, $type);
66 }
67
68 foreach ($sa as $key => $val) {
69 $out[] = $array[$key];
70 }
71 return $out;
72 }
73
74
75 /**
76 * Convenience method for htmlspecialchars.
77 *
78 * @param string $text Text to wrap through htmlspecialchars
79 * @param boolean $double Encode existing html entities
80 * @param string $charset Character set to use when escaping. Defaults to config value in 'App.encoding' or
'UTF-8'
81 * @return string Wrapped text
82 * @link http://book.cakephp.org/view/1132/h
83 */
84 public function h($text, $double = true, $charset = null) {
85 if (is_array($text)) {
86 $texts = array();
87 foreach ($text as $k => $t) {
88 $texts[$k] = h($t, $double, $charset);
89 }
90 return $texts;
91 }
92
93 static $defaultCharset = false;
94 if ($defaultCharset === false) {
95 if ($defaultCharset === null) {
96 $defaultCharset = 'UTF-8';
97 }
98 }
99 if (is_string($double)) {
100 $charset = $double;
101 }
102 return htmlspecialchars($text, ENT_QUOTES, ($charset) ? $charset : $defaultCharset, $double);
103 }
104
105 /**
106 * Splits a dot syntax plugin name into its plugin and classname.
107 * If $name does not have a dot, then index 0 will be null.
108 *
109 * Commonly used like `list($plugin, $name) = pluginSplit($name);`
110 *
111 * @param string $name The name you want to plugin split.
112 * @param boolean $dotAppend Set to true if you want the plugin to have a '.' appended to it.
113 * @param string $plugin Optional default plugin to use if no plugin is found. Defaults to null.
114 * @return array Array with 2 indexes. 0 => plugin name, 1 => classname
115 */
116 public function pluginSplit($name, $dotAppend = false, $plugin = null) {
117 if (strpos($name, '.') !== false) {
118 $parts = explode('.', $name, 2);
119 if ($dotAppend) {
120 $parts[0] .= '.';
121 }
122 return $parts;
123 }
124 return array($plugin, $name);
125 }
126
127 /**
128 * Print_r convenience function, which prints out <PRE> tags around
129 * the output of given array. Similar to debug().
130 *
131 * @see debug()
132 * @param array $var Variable to print out
133 * @link http://book.cakephp.org/view/1136/pr
134 */
135 public function pr($var) {
136 if (Configure::read('debug') > 0) {
137 echo '<pre>';
138 print_r($var);
139 echo '</pre>';
140 }
141 }
142
143 /**
144 * Merge a group of arrays
145 *
146 * @param array First array
147 * @param array Second array
148 * @param array Third array
149 * @param array Etc...
150 * @return array All array parameters merged into one
151 * @link http://book.cakephp.org/view/1124/am
152 */
153 public function am() {
154 $r = array();
155 $args = func_get_args();
156 foreach ($args as $a) {
157 if (!is_array($a)) {
158 $a = array($a);
159 }
160 $r = array_merge($r, $a);
161 }
162 return $r;
163 }
164
165 /**
166 * Gets an environment variable from available sources, and provides emulation
167 * for unsupported or inconsistent environment variables (i.e. DOCUMENT_ROOT on
168 * IIS, or SCRIPT_NAME in CGI mode). Also exposes some additional custom
169 * environment information.
170 *
171 * @param string $key Environment variable name.
172 * @return string Environment variable setting.
173 * @link http://book.cakephp.org/view/1130/env
174 */
175 public function env($key) {
176 if ($key === 'HTTPS') {
177 if (isset($_SERVER['HTTPS'])) {
178 return (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off');
179 }
180 return (strpos(env('SCRIPT_URI'), 'https://') === 0);
181 }
182
183 if ($key === 'SCRIPT_NAME') {
184 if (env('CGI_MODE') && isset($_ENV['SCRIPT_URL'])) {
185 $key = 'SCRIPT_URL';
186 }
187 }
188
189 $val = null;
190 if (isset($_SERVER[$key])) {
191 $val = $_SERVER[$key];
192 } elseif (isset($_ENV[$key])) {
193 $val = $_ENV[$key];
194 } elseif (getenv($key) !== false) {
195 $val = getenv($key);
196 }
197
198 if ($key === 'REMOTE_ADDR' && $val === env('SERVER_ADDR')) {
199 $addr = env('HTTP_PC_REMOTE_ADDR');
200 if ($addr !== null) {
201 $val = $addr;
202 }
203 }
204
205 if ($val !== null) {
206 return $val;
207 }
208
209 switch ($key) {
210 case 'SCRIPT_FILENAME':
211 if (defined('SERVER_IIS') && SERVER_IIS === true) {
212 return str_replace('\\\\', '\\', env('PATH_TRANSLATED'));
213 }
214 break;
215 case 'DOCUMENT_ROOT':
216 $name = env('SCRIPT_NAME');
217 $filename = env('SCRIPT_FILENAME');
218 $offset = 0;
219 if (!strpos($name, '.php')) {
220 $offset = 4;
221 }
222 return substr($filename, 0, strlen($filename) - (strlen($name) + $offset));
223 break;
224 case 'PHP_SELF':
225 return str_replace(env('DOCUMENT_ROOT'), '', env('SCRIPT_FILENAME'));
226 break;
227 case 'CGI_MODE':
228 return (PHP_SAPI === 'cgi');
229 break;
230 case 'HTTP_BASE':
231 $host = env('HTTP_HOST');
232 $parts = explode('.', $host);
233 $count = count($parts);
234
235 if ($count === 1) {
236 return '.' . $host;
237 } elseif ($count === 2) {
238 return '.' . $host;
239 } elseif ($count === 3) {
240 $gTLD = array(
241 'aero',
242 'asia',
243 'biz',
244 'cat',
245 'com',
246 'coop',
247 'edu',
248 'gov',
249 'info',
250 'int',
251 'jobs',
252 'mil',
253 'mobi',
254 'museum',
255 'name',
256 'net',
257 'org',
258 'pro',
259 'tel',
260 'travel',
261 'xxx'
262 );
263 if (in_array($parts[1], $gTLD)) {
264 return '.' . $host;
265 }
266 }
267 array_shift($parts);
268 return '.' . implode('.', $parts);
269 break;
270 }
271 return null;
272 }
273
274 /**
275 * Reads/writes temporary data to cache files or session.
276 *
277 * @param string $path File path within /tmp to save the file.
278 * @param mixed $data The data to save to the temporary file.
279 * @param mixed $expires A valid strtotime string when the data expires.
280 * @param string $target The target of the cached data; either 'cache' or 'public'.
281 * @return mixed The contents of the temporary file.
282 * @deprecated Please use Cache::write() instead
283 */
284 public function cache($path, $data = null, $expires = '+1 day', $target = 'cache') {
285
286 $now = time();
287
288 if (!is_numeric($expires)) {
289 $expires = strtotime($expires, $now);
290 }
291
292 switch (strtolower($target)) {
293 case 'cache':
294 $filename = CACHE . $path;
295 break;
296 case 'public':
297 $filename = WWW_ROOT . $path;
298 break;
299 case 'tmp':
300 $filename = TMP . $path;
301 break;
302 }
303 $timediff = $expires - $now;
304 $filetime = false;
305
306 if (file_exists($filename)) {
307 $filetime = @filemtime($filename);
308 }
309
310 if ($data === null) {
311 if (file_exists($filename) && $filetime !== false) {
312 if ($filetime + $timediff < $now) {
313 @unlink($filename);
314 } else {
315 $data = @file_get_contents($filename);
316 }
317 }
318 } elseif (is_writable(dirname($filename))) {
319 @file_put_contents($filename, $data);
320 }
321 return $data;
322 }
323
324 /**
325 * Used to delete files in the cache directories, or clear contents of cache directories
326 *
327 * @param mixed $params As String name to be searched for deletion, if name is a directory all files in
328 * directory will be deleted. If array, names to be searched for deletion. If clearCache() without params,
329 * all files in app/tmp/cache/views will be deleted
330 * @param string $type Directory in tmp/cache defaults to view directory
331 * @param string $ext The file extension you are deleting
332 * @return true if files found and deleted false otherwise
333 */
334 public function clearCache($params = null, $type = 'views', $ext = '.php') {
335 if (is_string($params) || $params === null) {
336 $params = preg_replace('/\/\//', '/', $params);
337 $cache = CACHE . $type . DS . $params;
338
339 if (is_file($cache . $ext)) {
340 @unlink($cache . $ext);
341 return true;
342 } elseif (is_dir($cache)) {
343 $files = glob($cache . '*');
344
345 if ($files === false) {
346 return false;
347 }
348
349 foreach ($files as $file) {
350 if (is_file($file) && strrpos($file, DS . 'empty') !== strlen($file) - 6) {
351 @unlink($file);
352 }
353 }
354 return true;
355 } else {
356 $cache = array(
357 CACHE . $type . DS . '*' . $params . $ext,
358 CACHE . $type . DS . '*' . $params . '_*' . $ext
359 );
360 $files = array();
361 while ($search = array_shift($cache)) {
362 $results = glob($search);
363 if ($results !== false) {
364 $files = array_merge($files, $results);
365 }
366 }
367 if (empty($files)) {
368 return false;
369 }
370 foreach ($files as $file) {
371 if (is_file($file) && strrpos($file, DS . 'empty') !== strlen($file) - 6) {
372 @unlink($file);
373 }
374 }
375 return true;
376 }
377 } elseif (is_array($params)) {
378 foreach ($params as $file) {
379 clearCache($file, $type, $ext);
380 }
381 return true;
382 }
383 return false;
384 }
385
386 /**
387 * Recursively strips slashes from all values in an array
388 *
389 * @param array $values Array of values to strip slashes
390 * @return mixed What is returned from calling stripslashes
391 * @link http://book.cakephp.org/view/1138/stripslashes_deep
392 */
393 public function stripslashes_deep($values) {
394 if (is_array($values)) {
395 foreach ($values as $key => $value) {
396 $values[$key] = stripslashes_deep($value);
397 }
398 } else {
399 $values = stripslashes($values);
400 }
401 return $values;
402 }
403
404 /**
405 * Returns a translated string if one is found; Otherwise, the submitted message.
406 *
407 * @param string $singular Text to translate
408 * @param mixed $args Array with arguments or multiple arguments in function
409 * @return mixed translated string
410 * @link http://book.cakephp.org/view/1121/_
411 */
412 public function _($singular, $args = null) {
413 if (!$singular) {
414 return;
415 }
416
417 //App::uses('I18n', 'I18n');
418 $i18n = get::component('i18n');
419 $translated = $i18n->translate($singular);
420 if ($args === null) {
421 return $translated;
422 } elseif (!is_array($args)) {
423 $args = array_slice(func_get_args(), 1);
424 }
425 return vsprintf($translated, $args);
426 }
427
428 /**
429 * Returns correct plural form of message identified by $singular and $plural for count $count.
430 * Some languages have more than one form for plural messages dependent on the count.
431 *
432 * @param string $singular Singular text to translate
433 * @param string $plural Plural text
434 * @param integer $count Count
435 * @param mixed $args Array with arguments or multiple arguments in function
436 * @return mixed plural form of translated string
437 */
438 public function _n($singular, $plural, $count, $args = null) {
439 if (!$singular) {
440 return;
441 }
442
443 //App::uses('I18n', 'I18n');
444 $i18n = get::component('i18n');
445 $translated = $i18n->translate($singular, $plural, null, 6, $count);
446 if ($args === null) {
447 return $translated;
448 } elseif (!is_array($args)) {
449 $args = array_slice(func_get_args(), 3);
450 }
451 return vsprintf($translated, $args);
452 }
453
454 /**
455 * Allows you to override the current domain for a single message lookup.
456 *
457 * @param string $domain Domain
458 * @param string $msg String to translate
459 * @param mixed $args Array with arguments or multiple arguments in function
460 * @return translated string
461 */
462 public function _d($domain, $msg, $args = null) {
463 if (!$msg) {
464 return;
465 }
466 //App::uses('I18n', 'I18n');
467 $i18n = get::component('i18n');
468 $translated = $i18n->translate($msg, null, $domain);
469 if ($args === null) {
470 return $translated;
471 } elseif (!is_array($args)) {
472 $args = array_slice(func_get_args(), 2);
473 }
474 return vsprintf($translated, $args);
475 }
476
477 /**
478 * Allows you to override the current domain for a single plural message lookup.
479 * Returns correct plural form of message identified by $singular and $plural for count $count
480 * from domain $domain.
481 *
482 * @param string $domain Domain
483 * @param string $singular Singular string to translate
484 * @param string $plural Plural
485 * @param integer $count Count
486 * @param mixed $args Array with arguments or multiple arguments in function
487 * @return plural form of translated string
488 */
489 public function _dn($domain, $singular, $plural, $count, $args = null) {
490 if (!$singular) {
491 return;
492 }
493 //App::uses('I18n', 'I18n');
494 $i18n = get::component('i18n');
495 $translated = $i18n->translate($singular, $plural, $domain, 6, $count);
496 if ($args === null) {
497 return $translated;
498 } elseif (!is_array($args)) {
499 $args = array_slice(func_get_args(), 4);
500 }
501 return vsprintf($translated, $args);
502 }
503
504 /**
505 * Allows you to override the current domain for a single message lookup.
506 * It also allows you to specify a category.
507 *
508 * The category argument allows a specific category of the locale settings to be used for fetching a message.
509 * Valid categories are: LC_CTYPE, LC_NUMERIC, LC_TIME, LC_COLLATE, LC_MONETARY, LC_MESSAGES and LC_ALL.
510 *
511 * Note that the category must be specified with a numeric value, instead of the constant name. The values
are:
512 *
513 * - LC_ALL 0
514 * - LC_COLLATE 1
515 * - LC_CTYPE 2
516 * - LC_MONETARY 3
517 * - LC_NUMERIC 4
518 * - LC_TIME 5
519 * - LC_MESSAGES 6
520 *
521 * @param string $domain Domain
522 * @param string $msg Message to translate
523 * @param integer $category Category
524 * @param mixed $args Array with arguments or multiple arguments in function
525 * @return translated string
526 */
527 public function _dc($domain, $msg, $category, $args = null) {
528 if (!$msg) {
529 return;
530 }
531 //App::uses('I18n', 'I18n');
532 $i18n = get::component('i18n');
533 $translated = $i18n->translate($msg, null, $domain, $category);
534 if ($args === null) {
535 return $translated;
536 } elseif (!is_array($args)) {
537 $args = array_slice(func_get_args(), 3);
538 }
539 return vsprintf($translated, $args);
540 }
541
542 /**
543 * Allows you to override the current domain for a single plural message lookup.
544 * It also allows you to specify a category.
545 * Returns correct plural form of message identified by $singular and $plural for count $count
546 * from domain $domain.
547 *
548 * The category argument allows a specific category of the locale settings to be used for fetching a message.
549 * Valid categories are: LC_CTYPE, LC_NUMERIC, LC_TIME, LC_COLLATE, LC_MONETARY, LC_MESSAGES and LC_ALL.
550 *
551 * Note that the category must be specified with a numeric value, instead of the constant name. The values
are:
552 *
553 * - LC_ALL 0
554 * - LC_COLLATE 1
555 * - LC_CTYPE 2
556 * - LC_MONETARY 3
557 * - LC_NUMERIC 4
558 * - LC_TIME 5
559 * - LC_MESSAGES 6
560 *
561 * @param string $domain Domain
562 * @param string $singular Singular string to translate
563 * @param string $plural Plural
564 * @param integer $count Count
565 * @param integer $category Category
566 * @param mixed $args Array with arguments or multiple arguments in function
567 * @return plural form of translated string
568 */
569 public function _dcn($domain, $singular, $plural, $count, $category, $args = null) {
570 if (!$singular) {
571 return;
572 }
573 //App::uses('I18n', 'I18n');
574 $i18n = get::component('i18n');
575 $translated = $i18n->translate($singular, $plural, $domain, $category, $count);
576 if ($args === null) {
577 return $translated;
578 } elseif (!is_array($args)) {
579 $args = array_slice(func_get_args(), 5);
580 }
581 return vsprintf($translated, $args);
582 }
583
584 /**
585 * The category argument allows a specific category of the locale settings to be used for fetching a message.
586 * Valid categories are: LC_CTYPE, LC_NUMERIC, LC_TIME, LC_COLLATE, LC_MONETARY, LC_MESSAGES and LC_ALL.
587 *
588 * Note that the category must be specified with a numeric value, instead of the constant name. The values
are:
589 *
590 * - LC_ALL 0
591 * - LC_COLLATE 1
592 * - LC_CTYPE 2
593 * - LC_MONETARY 3
594 * - LC_NUMERIC 4
595 * - LC_TIME 5
596 * - LC_MESSAGES 6
597 *
598 * @param string $msg String to translate
599 * @param integer $category Category
600 * @param mixed $args Array with arguments or multiple arguments in function
601 * @return translated string
602 */
603 public function _c($msg, $category, $args = null) {
604 if (!$msg) {
605 return;
606 }
607 //App::uses('I18n', 'I18n');
608 $i18n = get::component('i18n');
609 $translated = $i18n->translate($msg, null, null, $category);
610 if ($args === null) {
611 return $translated;
612 } elseif (!is_array($args)) {
613 $args = array_slice(func_get_args(), 2);
614 }
615 return vsprintf($translated, $args);
616 }
617
618 /**
619 * Shortcut to Log::write.
620 *
621 * @param string $message Message to write to log
622 */
623 public function LogError($message) {
624 App::uses('CakeLog', 'Log');
625 $bad = array("\n", "\r", "\t");
626 $good = ' ';
627 CakeLog::write('error', str_replace($bad, $good, $message));
628 }
629
630 /**
631 * Searches include path for files.
632 *
633 * @param string $file File to look for
634 * @return Full path to file if exists, otherwise false
635 * @link http://book.cakephp.org/view/1131/fileExistsInPath
636 */
637 public function fileExistsInPath($file) {
638 $paths = explode(PATH_SEPARATOR, ini_get('include_path'));
639 foreach ($paths as $path) {
640 $fullPath = $path . DS . $file;
641
642 if (file_exists($fullPath)) {
643 return $fullPath;
644 } elseif (file_exists($file)) {
645 return $file;
646 }
647 }
648 return false;
649 }
650
651 /**
652 * Convert forward slashes to underscores and removes first and last underscores in a string
653 *
654 * @param string String to convert
655 * @return string with underscore remove from start and end of string
656 * @link http://book.cakephp.org/view/1126/convertSlash
657 */
658 public function convertSlash($string) {
659 $string = trim($string, '/');
660 $string = preg_replace('/\/\//', '/', $string);
661 $string = str_replace('/', '_', $string);
662 return $string;
663 }
664 }