string) */ private static $lowerToUpper = null; /** * Upper to lower case conversion table. * * Included on demand when mbstring functions are not available. * Generated from http://www.unicode.org/Public/UNIDATA/UnicodeData.txt. * * @var array(string=>string) */ private static $upperToLower = null; /** * Escapes all special chars within the given $charlist for using it within * a regular expression character class definition (i.e []^-\ and the * pattern delimiter). By default the pattern delimiter is '/'. * * @param string $charlist * @param string $patternDelimiter * @return string */ private static function escapeCharacterClassCharlist( $charlist, $patternDelimiter = '/' ) { return preg_replace( '!([\\\\\\-\\]\\[^'. $patternDelimiter .'])!', '\\\${1}', $charlist ); } /** * Multibyte safe ltrim(). * * Based on http://de.php.net/manual/en/function.trim.php#72562. * Added the charlist to the regexp. rtrim seems to be safe for whitespaces. * * @param string $str * @param string $charlist * @return string */ public static function ltrim( $str, $charlist = null ) { if ( is_null( $charlist ) ) { return ltrim( $str ); } $charlist = self::escapeCharacterClassCharlist( $charlist ); return preg_replace( '/^['.$charlist.']+/u', '', $str ); } /** * Multibyte safe rtrim(). * * Based on http://de.php.net/manual/en/function.trim.php#72562. * Added the charlist to the regexp. rtrim seems to be safe for whitespaces. * * @param string $str * @param string $charlist * @return string */ public static function rtrim( $str, $charlist = null ) { if ( is_null( $charlist ) ) { return rtrim( $str ); } $charlist = self::escapeCharacterClassCharlist( $charlist ); return preg_replace( '/['.$charlist.']+$/u', '', $str ); } /** * Multibyte safe str_pad(). * * @param string $input * @param int $pad_length * @param string $pad_string * @param mixed $pad_type * @return string */ public static function str_pad( $input, $pad_length, $pad_string = ' ', $pad_type = STR_PAD_RIGHT ) { $diff = strlen( $input ) - iconv_strlen( $input, self::CHARSET ); return str_pad( $input, $pad_length + $diff, $pad_string, $pad_type ); } /** * Returns the number of paragraphs found in the given string. * * @param string $string * @return int */ public static function str_paragraph_count( $string ) { if ( iconv_strlen( $string, self::CHARSET ) == 0 ) { return 0; } $pos = 0; $count = 1; while ( preg_match( "/\n\n+/u", $string, $m, PREG_OFFSET_CAPTURE, $pos ) ) { ++$count; $pos = $m[0][1] + 1; } return $count; } /** * Multibyte safe str_word_count(). * * Based on http://de.php.net/manual/en/function.str-word-count.php#85592. * Added the $charlist parameter and fixed the offsets for $format=2. * * @param string $string * @param int $format * 0 - returns the number of words found * 1 - returns an array containing all the words found inside the string * 2 - returns an associative array, where the key is the numeric position of the word inside the string and the value is the actual word itself * @param string $charlist * @return mixed */ public static function str_word_count( $string, $format = 0, $charlist = null ) { if ( !is_null( $charlist ) ) { $charlist = self::escapeCharacterClassCharlist( $charlist ); } else { $charlist = ''; } $pattern = "/\p{L}[\p{L}\p{Mn}\p{Pd}'\x{2019}".$charlist."]*/u"; $matches = array(); switch ( $format ) { case 1: preg_match_all( $pattern, $string, $matches ); return $matches[0]; case 2: preg_match_all( $pattern, $string, $matches, PREG_OFFSET_CAPTURE ); $result = array(); $diff = 0; foreach ( $matches[0] as $match ) { // reduce wrong offset by multibyte difference $offset = $match[1] - $diff; $result[$offset] = $match[0]; // add multibyte offset difference of current word $diff += strlen( $match[0] ) - iconv_strlen( $match[0], self::CHARSET ); } return $result; default: return preg_match_all( $pattern, $string, $matches ); } } /** * Multibyte safe strpos(). * * @param string $haystack * @param mixed $needle * @param int $offset * @return int|bool */ public static function strpos( $haystack, $needle, $offset = 0 ) { return iconv_strpos( $haystack, $needle, $offset, self::CHARSET ); } /** * Multibyte safe strrpos(). * * @param string $haystack * @param mixed $needle * @param int $offset * @param bool $useMbString * @return string */ public static function strrpos( $haystack, $needle, $offset = 0, $useMbString = true ) { if ( $useMbString === true && function_exists( 'mb_strrpos' ) ) { return mb_strrpos( $haystack, $needle, $offset, self::CHARSET ); } else { $addOffset = 0; if ( $offset > 0 ) { $haystack = iconv_substr( $haystack, $offset, iconv_strlen( $haystack, self::CHARSET ), self::CHARSET ); $addOffset = $offset; } elseif( $offset < 0 ) { $haystack = iconv_substr( $haystack, 0, $offset, self::CHARSET ); } $result = iconv_strrpos( $haystack, $needle, self::CHARSET ); return ( $result === false ) ? $result : $result + $addOffset; } } /** * Multibyte safe strrev(). * * Based on http://de.php.net/manual/en/function.strrev.php#62422. * * @param string $str * @return string */ public static function strrev( $string ) { if ( empty( $string ) ) { return $string; } $matches = array(); preg_match_all( '/./us', $string, $matches ); return implode( '', array_reverse( $matches[0] ) ); } /** * Multibyte safe strtolower(). * Uses mb_strtolower() if available otherwise falls back to own conversion * table. * * @param string $str * @param bool $useMbString * @return string */ public static function strtolower( $str, $useMbString = true ) { if ( empty( $str ) ) { return $str; } if ( $useMbString === true && function_exists( 'mb_strtolower' ) ) { return mb_strtolower( $str, self::CHARSET ); } if ( is_null( self::$upperToLower ) ) { self::$upperToLower = new ezcTemplateStringUpperToLowerUnicodeMap(); } return strtr( $str, self::$upperToLower->unicodeTable ); } /** * Multibyte safe strtoupper(). * Uses mb_strtoupper() if available otherwise falls back to own conversion * table. * * @param string $str * @param bool $useMbString * @return string */ public static function strtoupper( $str, $useMbString = true ) { if ( empty( $str ) ) { return $str; } if ( $useMbString === true && function_exists( 'mb_strtoupper' ) ) { return mb_strtoupper( $str, self::CHARSET ); } if ( is_null( self::$lowerToUpper ) ) { self::$lowerToUpper = new ezcTemplateStringLowerToUpperUnicodeMap(); } return strtr( $str, self::$lowerToUpper->unicodeTable ); } /** * Multibyte safe trim(). * * @param string $str * @param string $charlist * @return string */ public static function trim( $str, $charlist = null ) { if ( is_null( $charlist ) ) { return trim( $str ); } return self::ltrim( self::rtrim( $str, $charlist ), $charlist ); } /** * Multibyte safe ucfirst(). * * @param string $string * @return string */ public static function ucfirst( $string ) { $strlen = iconv_strlen( $string, self::CHARSET ); if ( $strlen == 0 ) { return ''; } elseif ( $strlen == 1 ) { return self::strtoupper( $string ); } else { $matches = array(); preg_match( '/^(.{1})(.*)$/us', $string, $matches ); return self::strtoupper( $matches[1] ) . $matches[2]; } } /** * Multibyte safe wordwrap(). * * @param string $str * @param int $width * @param string $break * @param bool $cut * @return string */ public static function wordwrap( $str, $width = 75, $break = "\n", $cut = false ) { if ( empty( $str ) ) { return $str; } $lines = explode( $break, $str ); $return = ''; foreach ( $lines as $line ) { $line = trim( $line ); $length = iconv_strlen( $line, self::CHARSET ); if ( $length > $width ) { if ( $cut ) { while ( $length > $width ) { $return .= iconv_substr( $line, 0, $width, self::CHARSET ) . $break; $line = iconv_substr( $line, $width, iconv_strlen( $line, self::CHARSET ) - $width, self::CHARSET ); $length = iconv_strlen( $line, self::CHARSET ); } $return .= $line; } else { $words = explode( ' ', $line ); $tmp = ''; foreach ( $words as $word ) { $word = trim( $word ); if ( iconv_strlen( $tmp . $word, self::CHARSET ) <= $width ) { $tmp .= $word . ' '; } else { $return .= trim( $tmp ) . $break; $tmp = $word . ' '; } } $return .= trim( $tmp ); } } else { $return .= $line. $break; } } return $return; } } ?>