1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870
|
<?php
/**
* strings.php
*
* This code provides various string manipulation functions that are
* used by the rest of the SquirrelMail code.
*
* @copyright © 1999-2006 The SquirrelMail Project Team
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
* @version $Id: strings.php,v 1.184.2.61 2006/12/03 23:05:43 stekkel Exp $
* @package squirrelmail
*/
/**
* SquirrelMail version number -- DO NOT CHANGE
*/
global $version;
$version = '1.4.9a';
/**
* SquirrelMail internal version number -- DO NOT CHANGE
* $sm_internal_version = array (release, major, minor)
*/
global $SQM_INTERNAL_VERSION;
$SQM_INTERNAL_VERSION = array(1,4,9);
/**
* There can be a circular issue with includes, where the $version string is
* referenced by the include of global.php, etc. before it's defined.
* For that reason, bring in global.php AFTER we define the version strings.
*/
require_once(SM_PATH . 'functions/global.php');
/**
* Wraps text at $wrap characters
*
* Has a problem with special HTML characters, so call this before
* you do character translation.
*
* Specifically, ' comes up as 5 characters instead of 1.
* This should not add newlines to the end of lines.
*/
function sqWordWrap(&$line, $wrap, $charset=null) {
global $languages, $squirrelmail_language;
if (isset($languages[$squirrelmail_language]['XTRA_CODE']) &&
function_exists($languages[$squirrelmail_language]['XTRA_CODE'])) {
if (mb_detect_encoding($line) != 'ASCII') {
$line = $languages[$squirrelmail_language]['XTRA_CODE']('wordwrap', $line, $wrap);
return;
}
}
ereg("^([\t >]*)([^\t >].*)?$", $line, $regs);
$beginning_spaces = $regs[1];
if (isset($regs[2])) {
$words = explode(' ', $regs[2]);
} else {
$words = '';
}
$i = 0;
$line = $beginning_spaces;
while ($i < count($words)) {
/* Force one word to be on a line (minimum) */
$line .= $words[$i];
$line_len = strlen($beginning_spaces) + sq_strlen($words[$i],$charset) + 2;
if (isset($words[$i + 1]))
$line_len += sq_strlen($words[$i + 1],$charset);
$i ++;
/* Add more words (as long as they fit) */
while ($line_len < $wrap && $i < count($words)) {
$line .= ' ' . $words[$i];
$i++;
if (isset($words[$i]))
$line_len += sq_strlen($words[$i],$charset) + 1;
else
$line_len += 1;
}
/* Skip spaces if they are the first thing on a continued line */
while (!isset($words[$i]) && $i < count($words)) {
$i ++;
}
/* Go to the next line if we have more to process */
if ($i < count($words)) {
$line .= "\n";
}
}
}
/**
* Does the opposite of sqWordWrap()
* @param string body the text to un-wordwrap
* @return void
*/
function sqUnWordWrap(&$body) {
global $squirrelmail_language;
if ($squirrelmail_language == 'ja_JP') {
return;
}
$lines = explode("\n", $body);
$body = '';
$PreviousSpaces = '';
$cnt = count($lines);
for ($i = 0; $i < $cnt; $i ++) {
preg_match("/^([\t >]*)([^\t >].*)?$/", $lines[$i], $regs);
$CurrentSpaces = $regs[1];
if (isset($regs[2])) {
$CurrentRest = $regs[2];
} else {
$CurrentRest = '';
}
if ($i == 0) {
$PreviousSpaces = $CurrentSpaces;
$body = $lines[$i];
} else if (($PreviousSpaces == $CurrentSpaces) /* Do the beginnings match */
&& (strlen($lines[$i - 1]) > 65) /* Over 65 characters long */
&& strlen($CurrentRest)) { /* and there's a line to continue with */
$body .= ' ' . $CurrentRest;
} else {
$body .= "\n" . $lines[$i];
$PreviousSpaces = $CurrentSpaces;
}
}
$body .= "\n";
}
/**
* Truncates a string and take care of html encoded characters
*
* @param string $s string to truncate
* @param int $iTrimAt Trim at nn characters
* @return string Trimmed string
*/
function truncateWithEntities($s, $iTrimAt) {
global $languages, $squirrelmail_language;
$ent_strlen = strlen($s);
if (($iTrimAt <= 0) || ($ent_strlen <= $iTrimAt))
return $s;
if (isset($languages[$squirrelmail_language]['XTRA_CODE']) &&
function_exists($languages[$squirrelmail_language]['XTRA_CODE'])) {
return $languages[$squirrelmail_language]['XTRA_CODE']('strimwidth', $s, $iTrimAt);
} else {
/*
* see if this is entities-encoded string
* If so, Iterate through the whole string, find out
* the real number of characters, and if more
* than $iTrimAt, substr with an updated trim value.
*/
$trim_val = $iTrimAt;
$ent_offset = 0;
$ent_loc = 0;
while ( $ent_loc < $trim_val && (($ent_loc = strpos($s, '&', $ent_offset)) !== false) &&
(($ent_loc_end = strpos($s, ';', $ent_loc+3)) !== false) ) {
$trim_val += ($ent_loc_end-$ent_loc);
$ent_offset = $ent_loc_end+1;
}
if (($trim_val > $iTrimAt) && ($ent_strlen > $trim_val) && (strpos($s,';',$trim_val) < ($trim_val + 6))) {
$i = strpos($s,';',$trim_val);
if ($i !== false) {
$trim_val = strpos($s,';',$trim_val)+1;
}
}
// only print '...' when we're actually dropping part of the subject
if ($ent_strlen <= $trim_val)
return $s;
}
return substr_replace($s, '...', $trim_val);
}
/**
* If $haystack is a full mailbox name and $needle is the mailbox
* separator character, returns the last part of the mailbox name.
*
* @param string haystack full mailbox name to search
* @param string needle the mailbox separator character
* @return string the last part of the mailbox name
*/
function readShortMailboxName($haystack, $needle) {
if ($needle == '') {
$elem = $haystack;
} else {
$parts = explode($needle, $haystack);
$elem = array_pop($parts);
while ($elem == '' && count($parts)) {
$elem = array_pop($parts);
}
}
return( $elem );
}
/**
* php_self
*
* Creates an URL for the page calling this function, using either the PHP global
* REQUEST_URI, or the PHP global PHP_SELF with QUERY_STRING added.
*
* @return string the complete url for this page
*/
function php_self () {
if ( sqgetGlobalVar('REQUEST_URI', $req_uri, SQ_SERVER) && !empty($req_uri) ) {
return $req_uri;
}
if ( sqgetGlobalVar('PHP_SELF', $php_self, SQ_SERVER) && !empty($php_self) ) {
// need to add query string to end of PHP_SELF to match REQUEST_URI
//
if ( sqgetGlobalVar('QUERY_STRING', $query_string, SQ_SERVER) && !empty($query_string) ) {
$php_self .= '?' . $query_string;
}
return $php_self;
}
return '';
}
/**
* Find out where squirrelmail lives and try to be smart about it.
* The only problem would be when squirrelmail lives in directories
* called "src", "functions", or "plugins", but people who do that need
* to be beaten with a steel pipe anyway.
*
* @return string the base uri of squirrelmail installation.
*/
function sqm_baseuri(){
global $base_uri, $PHP_SELF;
/**
* If it is in the session, just return it.
*/
if (sqgetGlobalVar('base_uri',$base_uri,SQ_SESSION)){
return $base_uri;
}
$dirs = array('|src/.*|', '|plugins/.*|', '|functions/.*|');
$repl = array('', '', '');
$base_uri = preg_replace($dirs, $repl, $PHP_SELF);
return $base_uri;
}
/**
* get_location
*
* Determines the location to forward to, relative to your server.
* This is used in HTTP Location: redirects.
* If set, it uses $config_location_base as the first part of the URL,
* specifically, the protocol, hostname and port parts. The path is
* always autodetected.
*
* @return string the base url for this SquirrelMail installation
*/
function get_location () {
global $imap_server_type, $config_location_base;
/* Get the path, handle virtual directories */
if(strpos(php_self(), '?')) {
$path = substr(php_self(), 0, strpos(php_self(), '?'));
} else {
$path = php_self();
}
$path = substr($path, 0, strrpos($path, '/'));
// proto+host+port are already set in config:
if ( !empty($config_location_base) ) {
// register it in the session just in case some plugin depends on this
sqsession_register($config_location_base . $path, 'sq_base_url');
return $config_location_base . $path ;
}
// we computed it before, get it from the session:
if ( sqgetGlobalVar('sq_base_url', $full_url, SQ_SESSION) ) {
return $full_url . $path;
}
// else: autodetect
/* Check if this is a HTTPS or regular HTTP request. */
$proto = 'http://';
/*
* If you have 'SSLOptions +StdEnvVars' in your apache config
* OR if you have HTTPS=on in your HTTP_SERVER_VARS
* OR if you are on port 443
*/
$getEnvVar = getenv('HTTPS');
if ((isset($getEnvVar) && strcasecmp($getEnvVar, 'on') === 0) ||
(sqgetGlobalVar('HTTPS', $https_on, SQ_SERVER) && strcasecmp($https_on, 'on') === 0) ||
(sqgetGlobalVar('SERVER_PORT', $server_port, SQ_SERVER) && $server_port == 443)) {
$proto = 'https://';
}
/* Get the hostname from the Host header or server config. */
if ( !sqgetGlobalVar('HTTP_X_FORWARDED_HOST', $host, SQ_SERVER) || empty($host) ) {
if ( !sqgetGlobalVar('HTTP_HOST', $host, SQ_SERVER) || empty($host) ) {
if ( !sqgetGlobalVar('SERVER_NAME', $host, SQ_SERVER) || empty($host) ) {
$host = '';
}
}
}
$port = '';
if (! strstr($host, ':')) {
if (sqgetGlobalVar('SERVER_PORT', $server_port, SQ_SERVER)) {
if (($server_port != 80 && $proto == 'http://') ||
($server_port != 443 && $proto == 'https://')) {
$port = sprintf(':%d', $server_port);
}
}
}
/* this is a workaround for the weird macosx caching that
causes Apache to return 16080 as the port number, which causes
SM to bail */
if ($imap_server_type == 'macosx' && $port == ':16080') {
$port = '';
}
/* Fallback is to omit the server name and use a relative */
/* URI, although this is not RFC 2616 compliant. */
$full_url = ($host ? $proto . $host . $port : '');
sqsession_register($full_url, 'sq_base_url');
return $full_url . $path;
}
/**
* Encrypts password
*
* These functions are used to encrypt the password before it is
* stored in a cookie. The encryption key is generated by
* OneTimePadCreate();
*
* @param string string the (password)string to encrypt
* @param string epad the encryption key
* @return string the base64-encoded encrypted password
*/
function OneTimePadEncrypt ($string, $epad) {
$pad = base64_decode($epad);
if (strlen($pad)>0) {
// make sure that pad is longer than string
while (strlen($string)>strlen($pad)) {
$pad.=$pad;
}
} else {
// FIXME: what should we do when $epad is not base64 encoded or empty.
}
$encrypted = '';
for ($i = 0; $i < strlen ($string); $i++) {
$encrypted .= chr (ord($string[$i]) ^ ord($pad[$i]));
}
return base64_encode($encrypted);
}
/**
* Decrypts a password from the cookie
*
* Decrypts a password from the cookie, encrypted by OneTimePadEncrypt.
* This uses the encryption key that is stored in the session.
*
* @param string string the string to decrypt
* @param string epad the encryption key from the session
* @return string the decrypted password
*/
function OneTimePadDecrypt ($string, $epad) {
$pad = base64_decode($epad);
if (strlen($pad)>0) {
// make sure that pad is longer than string
while (strlen($string)>strlen($pad)) {
$pad.=$pad;
}
} else {
// FIXME: what should we do when $epad is not base64 encoded or empty.
}
$encrypted = base64_decode ($string);
$decrypted = '';
for ($i = 0; $i < strlen ($encrypted); $i++) {
$decrypted .= chr (ord($encrypted[$i]) ^ ord($pad[$i]));
}
return $decrypted;
}
/**
* Randomizes the mt_rand() function.
*
* Toss this in strings or integers and it will seed the generator
* appropriately. With strings, it is better to get them long.
* Use md5() to lengthen smaller strings.
*
* @param mixed val a value to seed the random number generator
* @return void
*/
function sq_mt_seed($Val) {
/* if mt_getrandmax() does not return a 2^n - 1 number,
this might not work well. This uses $Max as a bitmask. */
$Max = mt_getrandmax();
if (! is_int($Val)) {
$Val = crc32($Val);
}
if ($Val < 0) {
$Val *= -1;
}
if ($Val == 0) {
return;
}
mt_srand(($Val ^ mt_rand(0, $Max)) & $Max);
}
/**
* Init random number generator
*
* This function initializes the random number generator fairly well.
* It also only initializes it once, so you don't accidentally get
* the same 'random' numbers twice in one session.
*
* @return void
*/
function sq_mt_randomize() {
static $randomized;
if ($randomized) {
return;
}
/* Global. */
sqgetGlobalVar('REMOTE_PORT', $remote_port, SQ_SERVER);
sqgetGlobalVar('REMOTE_ADDR', $remote_addr, SQ_SERVER);
sq_mt_seed((int)((double) microtime() * 1000000));
sq_mt_seed(md5($remote_port . $remote_addr . getmypid()));
/* getrusage */
if (function_exists('getrusage')) {
/* Avoid warnings with Win32 */
$dat = @getrusage();
if (isset($dat) && is_array($dat)) {
$Str = '';
foreach ($dat as $k => $v)
{
$Str .= $k . $v;
}
sq_mt_seed(md5($Str));
}
}
if(sqgetGlobalVar('UNIQUE_ID', $unique_id, SQ_SERVER)) {
sq_mt_seed(md5($unique_id));
}
$randomized = 1;
}
/**
* Creates encryption key
*
* Creates an encryption key for encrypting the password stored in the cookie.
* The encryption key itself is stored in the session.
*
* @param int length optional, length of the string to generate
* @return string the encryption key
*/
function OneTimePadCreate ($length=100) {
sq_mt_randomize();
$pad = '';
for ($i = 0; $i < $length; $i++) {
$pad .= chr(mt_rand(0,255));
}
return base64_encode($pad);
}
/**
* Returns a string showing the size of the message/attachment.
*
* @param int bytes the filesize in bytes
* @return string the filesize in human readable format
*/
function show_readable_size($bytes) {
$bytes /= 1024;
$type = 'k';
if ($bytes / 1024 > 1) {
$bytes /= 1024;
$type = 'M';
}
if ($bytes < 10) {
$bytes *= 10;
settype($bytes, 'integer');
$bytes /= 10;
} else {
settype($bytes, 'integer');
}
return $bytes . '<small> ' . $type . '</small>';
}
/**
* Generates a random string from the caracter set you pass in
*
* @param int size the size of the string to generate
* @param string chars a string containing the characters to use
* @param int flags a flag to add a specific set to the characters to use:
* Flags:
* 1 = add lowercase a-z to $chars
* 2 = add uppercase A-Z to $chars
* 4 = add numbers 0-9 to $chars
* @return string the random string
*/
function GenerateRandomString($size, $chars, $flags = 0) {
if ($flags & 0x1) {
$chars .= 'abcdefghijklmnopqrstuvwxyz';
}
if ($flags & 0x2) {
$chars .= 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
}
if ($flags & 0x4) {
$chars .= '0123456789';
}
if (($size < 1) || (strlen($chars) < 1)) {
return '';
}
sq_mt_randomize(); /* Initialize the random number generator */
$String = '';
$j = strlen( $chars ) - 1;
while (strlen($String) < $size) {
$String .= $chars{mt_rand(0, $j)};
}
return $String;
}
/**
* Escapes special characters for use in IMAP commands.
*
* @param string the string to escape
* @return string the escaped string
*/
function quoteimap($str) {
return preg_replace("/([\"\\\\])/", "\\\\$1", $str);
}
/**
* Trims array
*
* Trims every element in the array, ie. remove the first char of each element
* Obsolete: will probably removed soon
* @param array array the array to trim
* @obsolete
*/
function TrimArray(&$array) {
foreach ($array as $k => $v) {
global $$k;
if (is_array($$k)) {
foreach ($$k as $k2 => $v2) {
$$k[$k2] = substr($v2, 1);
}
} else {
$$k = substr($v, 1);
}
/* Re-assign back to array. */
$array[$k] = $$k;
}
}
/**
* Removes slashes from every element in the array
*/
function RemoveSlashes(&$array) {
foreach ($array as $k => $v) {
global $$k;
if (is_array($$k)) {
foreach ($$k as $k2 => $v2) {
$newArray[stripslashes($k2)] = stripslashes($v2);
}
$$k = $newArray;
} else {
$$k = stripslashes($v);
}
/* Re-assign back to the array. */
$array[$k] = $$k;
}
}
/**
* Create compose link
*
* Returns a link to the compose-page, taking in consideration
* the compose_in_new and javascript settings.
* @param string url the URL to the compose page
* @param string text the link text, default "Compose"
* @return string a link to the compose page
*/
function makeComposeLink($url, $text = null, $target='')
{
global $compose_new_win,$javascript_on;
if(!$text) {
$text = _("Compose");
}
// if not using "compose in new window", make
// regular link and be done with it
if($compose_new_win != '1') {
return makeInternalLink($url, $text, $target);
}
// build the compose in new window link...
// if javascript is on, use onClick event to handle it
if($javascript_on) {
sqgetGlobalVar('base_uri', $base_uri, SQ_SESSION);
return '<a href="javascript:void(0)" onclick="comp_in_new(\''.$base_uri.$url.'\')">'. $text.'</a>';
}
// otherwise, just open new window using regular HTML
return makeInternalLink($url, $text, '_blank');
}
/**
* Print variable
*
* sm_print_r($some_variable, [$some_other_variable [, ...]]);
*
* Debugging function - does the same as print_r, but makes sure special
* characters are converted to htmlentities first. This will allow
* values like <some@email.address> to be displayed.
* The output is wrapped in <<pre>> and <</pre>> tags.
*
* @return void
*/
function sm_print_r() {
ob_start(); // Buffer output
foreach(func_get_args() as $var) {
print_r($var);
echo "\n";
}
$buffer = ob_get_contents(); // Grab the print_r output
ob_end_clean(); // Silently discard the output & stop buffering
print '<pre>';
print htmlentities($buffer);
print '</pre>';
}
/**
* version of fwrite which checks for failure
*/
function sq_fwrite($fp, $string) {
// write to file
$count = @fwrite($fp,$string);
// the number of bytes written should be the length of the string
if($count != strlen($string)) {
return FALSE;
}
return $count;
}
/**
* Tests if string contains 8bit symbols.
*
* If charset is not set, function defaults to default_charset.
* $default_charset global must be set correctly if $charset is
* not used.
* @param string $string tested string
* @param string $charset charset used in a string
* @return bool true if 8bit symbols are detected
* @since 1.5.1 and 1.4.4
*/
function sq_is8bit($string,$charset='') {
global $default_charset;
if ($charset=='') $charset=$default_charset;
/**
* Don't use \240 in ranges. Sometimes RH 7.2 doesn't like it.
* Don't use \200-\237 for iso-8859-x charsets. This ranges
* stores control symbols in those charsets.
* Use preg_match instead of ereg in order to avoid problems
* with mbstring overloading
*/
if (preg_match("/^iso-8859/i",$charset)) {
$needle='/\240|[\241-\377]/';
} else {
$needle='/[\200-\237]|\240|[\241-\377]/';
}
return preg_match("$needle",$string);
}
/**
* Function returns number of characters in string.
*
* Returned number might be different from number of bytes in string,
* if $charset is multibyte charset. Detection depends on mbstring
* functions. If mbstring does not support tested multibyte charset,
* vanilla string length function is used.
* @param string $str string
* @param string $charset charset
* @since 1.5.1 and 1.4.6
* @return integer number of characters in string
*/
function sq_strlen($str, $charset=null){
// default option
if (is_null($charset)) return strlen($str);
// lowercase charset name
$charset=strtolower($charset);
// use automatic charset detection, if function call asks for it
if ($charset=='auto') {
global $default_charset;
set_my_charset();
$charset=$default_charset;
}
// Use mbstring only with listed charsets
$aList_of_mb_charsets=array('utf-8','big5','gb2312','gb18030','euc-jp','euc-cn','euc-tw','euc-kr');
// calculate string length according to charset
if (in_array($charset,$aList_of_mb_charsets) && in_array($charset,sq_mb_list_encodings())) {
$real_length = mb_strlen($str,$charset);
} else {
// own strlen detection code is removed because missing strpos,
// strtoupper and substr implementations break string wrapping.
$real_length=strlen($str);
}
return $real_length;
}
/**
* Replacement of mb_list_encodings function
*
* This function provides replacement for function that is available only
* in php 5.x. Function does not test all mbstring encodings. Only the ones
* that might be used in SM translations.
*
* Supported strings are stored in session in order to reduce number of
* mb_internal_encoding function calls.
*
* If mb_list_encodings() function is present, code uses it. Main difference
* from original function behaviour - array values are lowercased in order to
* simplify use of returned array in in_array() checks.
*
* If you want to test all mbstring encodings - fill $list_of_encodings
* array.
* @return array list of encodings supported by php mbstring extension
* @since 1.5.1 and 1.4.6
*/
function sq_mb_list_encodings() {
// check if mbstring extension is present
if (! function_exists('mb_internal_encoding'))
return array();
// php 5+ function
if (function_exists('mb_list_encodings')) {
$ret = mb_list_encodings();
array_walk($ret,'sq_lowercase_array_vals');
return $ret;
}
// don't try to test encodings, if they are already stored in session
if (sqgetGlobalVar('mb_supported_encodings',$mb_supported_encodings,SQ_SESSION))
return $mb_supported_encodings;
// save original encoding
$orig_encoding=mb_internal_encoding();
$list_of_encoding=array(
'pass',
'auto',
'ascii',
'jis',
'utf-8',
'sjis',
'euc-jp',
'iso-8859-1',
'iso-8859-2',
'iso-8859-7',
'iso-8859-9',
'iso-8859-15',
'koi8-r',
'koi8-u',
'big5',
'gb2312',
'gb18030',
'windows-1251',
'windows-1255',
'windows-1256',
'tis-620',
'iso-2022-jp',
'euc-cn',
'euc-kr',
'euc-tw',
'uhc',
'utf7-imap');
$supported_encodings=array();
foreach ($list_of_encoding as $encoding) {
// try setting encodings. suppress warning messages
if (@mb_internal_encoding($encoding))
$supported_encodings[]=$encoding;
}
// restore original encoding
mb_internal_encoding($orig_encoding);
// register list in session
sqsession_register($supported_encodings,'mb_supported_encodings');
return $supported_encodings;
}
/**
* Callback function used to lowercase array values.
* @param string $val array value
* @param mixed $key array key
* @since 1.5.1 and 1.4.6
*/
function sq_lowercase_array_vals(&$val,$key) {
$val = strtolower($val);
}
/**
* Callback function to trim whitespace from a value, to be used in array_walk
* @param string $value value to trim
* @since 1.5.2 and 1.4.7
*/
function sq_trim_value ( &$value ) {
$value = trim($value);
}
$PHP_SELF = php_self();
?>
|