• Main Page
  • Related Pages
  • Namespaces
  • Classes
  • Files
  • Examples
  • File List

system/classes/multibyte.php

00001 <?php
00007 namespace Habari;
00008 
00018 class MultiByte
00019 {
00020 
00021   const USE_MBSTRING = 1;
00022 
00026   static $hab_enc = 'UTF-8';
00031   private static $use_library = self::USE_MBSTRING;
00032 
00036   private function __construct()
00037   {
00038   }
00039 
00048   public static function hab_encoding($use_enc = null)
00049   {
00050     if ( $use_enc === null ) {
00051       return self::$hab_enc;
00052     }
00053     else {
00054       $old_enc = self::$hab_enc;
00055       self::$hab_enc = $use_enc;
00056       return $old_enc;
00057     }
00058   }
00059 
00069   public static function library($new_library = null)
00070   {
00071     if ( $new_library === null ) {
00072       return self::$use_library;
00073     }
00074     elseif ( $new_library === self::USE_MBSTRING ) {
00075       $old_library = self::$use_library;
00076       self::$use_library = $new_library;
00077       return $old_library;
00078 
00079     }
00080     elseif ( $new_library === false ) {
00081       $old_library = self::$use_library;
00082       self::$use_library = $new_library;
00083       return $old_library;
00084     }
00085     else {
00086       return false;
00087     }
00088   }
00089 
00101   public static function convert_encoding($str, $use_enc = null, $from_enc = null)
00102   {
00103     $ret = false;
00104 
00105     $enc = self::$hab_enc;
00106     if ( $use_enc !== null ) {
00107       $enc = $use_enc;
00108     }
00109 
00110     if ( self::$use_library == self::USE_MBSTRING ) {
00111       if ( $from_enc == null ) {
00112         $from_enc = MultiByte::detect_encoding($str);
00113       }
00114       $ret = mb_convert_encoding($str, $enc, $from_enc);
00115     }
00116 
00117     return $ret;
00118   }
00119 
00127   public static function detect_encoding($str)
00128   {
00129     $enc = false;
00130 
00131     if ( self::$use_library == self::USE_MBSTRING ) {
00132       // get original detection order
00133       $old_order = mb_detect_order();
00134       // make sure  ISO-8859-1 is included
00135       mb_detect_order(array('ASCII', 'JIS', 'UTF-8', 'ISO-8859-1', 'EUC-JP', 'SJIS'));
00136       //detect the encoding . the detected encoding may be wrong, but it's better than guessing
00137       $enc = mb_detect_encoding($str);
00138       // reset detection order
00139       mb_detect_order($old_order);
00140     }
00141 
00142     return $enc;
00143   }
00144 
00153   public static function detect_bom_encoding($source_contents)
00154   {
00155     $ret = false;
00156     if ( "\xFE\xFF" == substr(0, 2, $source_contents) ) {
00157       $ret = 'UTF-16BE';
00158     }
00159     else if ( "\xFF\xFE" == substr(0, 2, $source_contents) ) {
00160       $ret = 'UTF-16LE';
00161     }
00162     else if ( "\xEF\xBB\xBF" == substr(0, 3, $source_contents) ) {
00163       $ret = 'UTF-8';
00164     }
00165 
00166     return $ret;
00167   }
00168 
00184   public static function substr($str, $begin, $len = null, $use_enc = null)
00185   {
00186     $enc = self::$hab_enc;
00187     if ( $use_enc !== null ) {
00188       $enc = $use_enc;
00189     }
00190 
00191     if ( self::$use_library == self::USE_MBSTRING ) {
00192       if ( !isset($len) ) {
00193         $len = MultiByte::strlen($str) - $begin;
00194       }
00195       $ret = mb_substr($str, $begin, $len, $enc);
00196     }
00197     else {
00198       $ret = substr($str, $begin, $len);
00199     }
00200     return $ret;
00201   }
00202 
00213   public static function strlen($str, $use_enc = null)
00214   {
00215     $enc = self::$hab_enc;
00216     if ( $use_enc !== null ) {
00217       $enc = $use_enc;
00218     }
00219 
00220     if ( self::$use_library == self::USE_MBSTRING ) {
00221       $len = mb_strlen($str, $enc);
00222     }
00223     else {
00224       $len = strlen($str);
00225     }
00226 
00227     return $len;
00228   }
00229 
00243   public static function strpos($haysack, $needle, $offset = 0, $use_enc = null)
00244   {
00245     $enc = self::$hab_enc;
00246     if ( $use_enc !== null ) {
00247       $enc = $use_enc;
00248     }
00249 
00250     if ( self::$use_library == self::USE_MBSTRING ) {
00251       $ret = mb_strpos($haysack, $needle, $offset, $enc);
00252     }
00253     else {
00254       $ret = strpos($haysack, $needle, $offset);
00255     }
00256     return $ret;
00257   }
00258 
00272   public static function stripos($haysack, $needle, $offset = 0, $use_enc = null)
00273   {
00274     $enc = self::$hab_enc;
00275     if ( $use_enc !== null ) {
00276       $enc = $use_enc;
00277     }
00278 
00279     if ( self::$use_library == self::USE_MBSTRING ) {
00280       $ret = mb_stripos($haysack, $needle, $offset, $enc);
00281     }
00282     else {
00283       $ret = stripos($haysack, $needle, $offset);
00284     }
00285     return $ret;
00286   }
00287 
00303   public static function strrpos($haysack, $needle, $offset = 0, $use_enc = null)
00304   {
00305     $enc = self::$hab_enc;
00306     if ( $use_enc !== null ) {
00307       $enc = $use_enc;
00308     }
00309 
00310     if ( self::$use_library == self::USE_MBSTRING ) {
00311       $ret = mb_strrpos($haysack, $needle, $offset, $enc);
00312     }
00313     else {
00314       $ret = strrpos($haysack, $needle, $offset);
00315     }
00316     return $ret;
00317   }
00318 
00332   public static function strripos($haysack, $needle, $offset = 0, $use_enc = null)
00333   {
00334     $enc = self::$hab_enc;
00335     if ( $use_enc !== null ) {
00336       $enc = $use_enc;
00337     }
00338 
00339     if ( self::$use_library == self::USE_MBSTRING ) {
00340       $ret = mb_strripos($haysack, $needle, $offset, $enc);
00341     }
00342     else {
00343       $ret = strripos($haysack, $needle, $offset);
00344     }
00345     return $ret;
00346   }
00347 
00360   public static function strtolower($str, $use_enc = null)
00361   {
00362     $enc = self::$hab_enc;
00363     if ( $use_enc !== null ) {
00364       $enc = $use_enc;
00365     }
00366 
00367     if ( self::$use_library == self::USE_MBSTRING ) {
00368       $ret = mb_strtolower($str, $enc);
00369     }
00370     else {
00371       $ret = strtolower($str);
00372     }
00373 
00374     return $ret;
00375   }
00376 
00387   public static function strtoupper($str, $use_enc = null)
00388   {
00389     $enc = self::$hab_enc;
00390     if ( $use_enc !== null ) {
00391       $enc = $use_enc;
00392     }
00393 
00394     if ( self::$use_library == self::USE_MBSTRING ) {
00395       $ret = mb_strtoupper($str, $enc);
00396     }
00397     else {
00398       $ret = strtoupper($str);
00399     }
00400 
00401     return $ret;
00402   }
00403 
00411   public static function valid_data($str, $use_enc = null)
00412   {
00413     $enc = self::$hab_enc;
00414     if ( $use_enc !== null ) {
00415       $enc = $use_enc;
00416     }
00417 
00418     if ( self::$use_library == self::USE_MBSTRING ) {
00419       return mb_check_encoding($str, $enc);
00420     }
00421 
00422     return true;
00423   }
00424 
00433   public static function ucfirst($str, $use_enc = null)
00434   {
00435 
00436     $enc = self::$hab_enc;
00437     if ( $use_enc !== null ) {
00438       $enc = $use_enc;
00439     }
00440 
00441     if ( self::$use_library == self::USE_MBSTRING ) {
00442 
00443       // get the first character
00444       $first = self::substr($str, 0, 1, $enc);
00445 
00446       // uppercase it
00447       $first = self::strtoupper($first, $enc);
00448 
00449       // get the rest of the characters
00450       $last = self::substr($str, 1, null, $enc);
00451 
00452       // put them back together
00453       $ret = $first . $last;
00454 
00455     }
00456     else {
00457       $ret = ucfirst($str);
00458     }
00459 
00460     return $ret;
00461 
00462   }
00463 
00472   public static function lcfirst($str, $use_enc = null)
00473   {
00474 
00475     $enc = self::$hab_enc;
00476     if ( $use_enc !== null ) {
00477       $enc = $use_enc;
00478     }
00479 
00480     if ( self::$use_library == self::USE_MBSTRING ) {
00481 
00482       // get the first character
00483       $first = self::substr($str, 0, 1, $enc);
00484 
00485       // lowercase it
00486       $first = self::strtolower($first, $enc);
00487 
00488       // get the rest of the characters
00489       $last = self::substr($str, 1, null, $enc);
00490 
00491       // put them back together
00492       $ret = $first . $last;
00493 
00494     }
00495     else {
00496 
00497       // lcfirst() is php 5.3+ so we'll emulate it
00498       $first = substr($str, 0, 1);
00499       $first = strtolower($first);
00500 
00501       $last = substr($str, 1);
00502 
00503       $ret = $first . $last;
00504 
00505     }
00506 
00507     return $ret;
00508 
00509   }
00510 
00511 
00523   public static function str_replace($search, $replace, $subject, &$count = 0, $use_enc = null)
00524   {
00525 
00526     $enc = self::$hab_enc;
00527     if ( $use_enc !== null ) {
00528       $enc = $use_enc;
00529     }
00530 
00531     if ( self::$use_library == self::USE_MBSTRING ) {
00532 
00533       // if search is an array and replace is not, we need to make replace an array and pad it to the same number of values as search
00534       if ( is_array($search) && !is_array($replace) ) {
00535         $replace = array_fill(0, count($search), $replace);
00536       }
00537 
00538       // if search is an array and replace is as well, we need to make sure replace has the same number of values - pad it with empty strings
00539       if ( is_array($search) && is_array($replace) ) {
00540         $replace = array_pad($replace, count($search), '');
00541       }
00542 
00543       // if search is not an array, make it one
00544       if ( !is_array($search) ) {
00545         $search = array($search);
00546       }
00547 
00548       // if replace is not an array, make it one
00549       if ( !is_array($replace) ) {
00550         $replace = array($replace);
00551       }
00552 
00553       // if subject is an array, recursively call ourselves on each element of it
00554       if ( is_array($subject) ) {
00555         foreach ($subject as $k => $v) {
00556           $subject[$k] = self::str_replace($search, $replace, $v, $count, $use_enc);
00557         }
00558 
00559         return $subject;
00560       }
00561 
00562 
00563       // now we've got an array of characters and arrays of search / replace characters with the same values - loop and replace them!
00564       $search_count = count($search); // we modify $search, so we can't include it in the condition next
00565       for ($i = 0; $i < $search_count; $i++) {
00566 
00567         // the values we'll match
00568         $s = array_shift($search);
00569         $r = array_shift($replace);
00570 
00571         // to avoid an infinite loop if you're replacing with a value that contains the subject we get the position of each instance first
00572         $positions = array();
00573 
00574         $offset = 0;
00575         while (self::strpos($subject, $s, $offset, $enc) !== false) {
00576 
00577           // get the position
00578           $pos = self::strpos($subject, $s, $offset, $enc);
00579 
00580           // add it to the list
00581           $positions[] = $pos;
00582 
00583           // and set the offset to skip over this value
00584           $offset = $pos + self::strlen($s, $enc);
00585 
00586         }
00587 
00588         // if we pick through from the beginning, our positions will change if the replacement string is longer
00589         // instead, we pick through from the last place
00590         $positions = array_reverse($positions);
00591 
00592         // now that we've got the position of each one, just loop through that and replace them
00593         foreach ($positions as $pos) {
00594 
00595           // pull out the part before the string
00596           $before = self::substr($subject, 0, $pos, $enc);
00597 
00598           // pull out the part after
00599           $after = self::substr($subject, $pos + self::strlen($s, $enc), null, $enc);
00600 
00601           // now we have the string in two parts without the string we're searching for
00602           // put it back together with the replacement
00603           $subject = $before . $r . $after;
00604 
00605           // increment our count, a replacement was made
00606           $count++;
00607 
00608         }
00609 
00610       }
00611 
00612     }
00613     else {
00614 
00615       $subject = str_replace($search, $replace, $subject, $count);
00616 
00617     }
00618 
00619     return $subject;
00620 
00621   }
00622 
00634   public static function str_ireplace($search, $replace, $subject, &$count = 0, $use_enc = null)
00635   {
00636 
00637     $enc = self::$hab_enc;
00638     if ( $use_enc !== null ) {
00639       $enc = $use_enc;
00640     }
00641 
00642     if ( self::$use_library == self::USE_MBSTRING ) {
00643 
00644       // if search is an array and replace is not, we need to make replace an array and pad it to the same number of values as search
00645       if ( is_array($search) && !is_array($replace) ) {
00646         $replace = array_fill(0, count($search), $replace);
00647       }
00648 
00649       // if search is an array and replace is as well, we need to make sure replace has the same number of values - pad it with empty strings
00650       if ( is_array($search) && is_array($replace) ) {
00651         $replace = array_pad($replace, count($search), '');
00652       }
00653 
00654       // if search is not an array, make it one
00655       if ( !is_array($search) ) {
00656         $search = array($search);
00657       }
00658 
00659       // if replace is not an array, make it one
00660       if ( !is_array($replace) ) {
00661         $replace = array($replace);
00662       }
00663 
00664       // if subject is an array, recursively call ourselves on each element of it
00665       if ( is_array($subject) ) {
00666         foreach ($subject as $k => $v) {
00667           $subject[$k] = self::str_ireplace($search, $replace, $v, $count, $use_enc);
00668         }
00669 
00670         return $subject;
00671       }
00672 
00673 
00674       $search_count = count($search); // we modify $search, so we can't include it in the condition next
00675       for ($i = 0; $i < $search_count; $i++) {
00676 
00677         // the values we'll match
00678         $s = array_shift($search);
00679         $r = array_shift($replace);
00680 
00681 
00682         // to avoid an infinite loop if you're replacing with a value that contains the subject we get the position of each instance first
00683         $positions = array();
00684 
00685         $offset = 0;
00686         while (self::stripos($subject, $s, $offset, $enc) !== false) {
00687 
00688           // get the position
00689           $pos = self::stripos($subject, $s, $offset, $enc);
00690 
00691           // add it to the list
00692           $positions[] = $pos;
00693 
00694           // and set the offset to skip over this value
00695           $offset = $pos + self::strlen($s, $enc);
00696 
00697         }
00698 
00699         // if we pick through from the beginning, our positions will change if the replacement string is longer
00700         // instead, we pick through from the last place
00701         $positions = array_reverse($positions);
00702 
00703         // now that we've got the position of each one, just loop through that and replace them
00704         foreach ($positions as $pos) {
00705 
00706           // pull out the part before the string
00707           $before = self::substr($subject, 0, $pos, $enc);
00708 
00709           // pull out the part after
00710           $after = self::substr($subject, $pos + self::strlen($s, $enc), null, $enc);
00711 
00712           // now we have the string in two parts without the string we're searching for
00713           // put it back together with the replacement
00714           $subject = $before . $r . $after;
00715 
00716           // increment our count, a replacement was made
00717           $count++;
00718 
00719         }
00720 
00721       }
00722 
00723     }
00724     else {
00725 
00726       $subject = str_ireplace($search, $replace, $subject, $count);
00727 
00728     }
00729 
00730     return $subject;
00731 
00732   }
00733 
00746   public static function ucwords($str, $use_enc = null)
00747   {
00748 
00749     $enc = self::$hab_enc;
00750     if ( $use_enc !== null ) {
00751       $enc = $use_enc;
00752     }
00753 
00754     if ( self::$use_library == self::USE_MBSTRING ) {
00755 
00756       $delimiters = array(
00757         chr(32), // space
00758         chr(12), // form-feed
00759         chr(10), // newline
00760         chr(13), // carriage return
00761         chr(9), // horizontal tab
00762         chr(11), // vertical tab
00763       );
00764 
00765       // loop through the delimiters and explode the string by each one
00766       foreach ($delimiters as $d) {
00767 
00768         $pieces = explode($d, $str);
00769 
00770         for ($i = 0; $i < count($pieces); $i++) {
00771 
00772           // capitalize each word
00773           $pieces[$i] = self::ucfirst($pieces[$i], $enc);
00774 
00775         }
00776 
00777         // put the string back together
00778         $str = implode($d, $pieces);
00779 
00780       }
00781 
00782     }
00783     else {
00784       $str = ucwords($str);
00785     }
00786 
00787 
00788     return $str;
00789   }
00790 
00791 }
00792 
00793 ?>

Generated on Sun Aug 4 2013 12:51:43 for Habari by  doxygen 1.7.1