Subversion Repositories oidplus

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. <?php
  2.  
  3. // XML Encoding Utilities
  4. // (C) 2011-2019 Daniel Marschall, ViaThinkSoft
  5. // Licensed under the terms of the Apache 2.0 license
  6. // Version 1.7
  7.  
  8. // http://www.viathinksoft.de/?page=codelib&showid=89
  9.  
  10. // Unicode-proof htmlentities.
  11. // Returns 'normal' chars as chars and weirdos as numeric html entites.
  12. // Source: http://www.php.net/manual/en/function.htmlentities.php#107985 ; modified
  13. // Modified by Daniel Marschall, ViaThinkSoft
  14. function htmlentities_numeric($str, $allow_html=false, $encode_linebreaks=false) {
  15.         // Convert $str to UTF-8 if it is not already
  16.         if (mb_detect_encoding($str, "auto", true) != 'UTF-8') {
  17. #               $str = mb_convert_encoding($str, 'UTF-8', 'Windows-1252');
  18. #               $str = mb_convert_encoding($str, 'UTF-8', 'auto');
  19.                 $str = mb_convert_encoding($str, 'UTF-8');
  20.         }
  21.  
  22.         // get rid of existing entities else double-escape
  23. // DM 24.08.2016 Auskommentiert wegen oid+ xml export
  24. //      $str = html_entity_decode(stripslashes($str),ENT_QUOTES,'UTF-8');
  25.  
  26.         $ar = preg_split('/(?<!^)(?!$)/u', $str);  // return array of every multi-byte character
  27.         $str2 = '';
  28.         foreach ($ar as $c) {
  29.                 $o = ord($c);
  30.                 if (
  31.                         (strlen($c) > 1)      || /* multi-byte [unicode] */
  32.                         ($o < 32 || $o > 126) || /* <- control / latin weirdos -> */
  33.                         ($o > 33 && $o < 40)  || /* quotes + ampersand */
  34.                         ($o > 59 && $o < 63)     /* html */
  35.                 ) {
  36.                         // convert to numeric entity
  37.                         $c = mb_encode_numericentity($c, array(0x0, 0xffff, 0, 0xffff), 'UTF-8');
  38.  
  39.                         if ($allow_html) {
  40.                                 if ($c == '&#60;') $c = '<';
  41.                                 if ($c == '&#62;') $c = '>';
  42.                                 if ($c == '&#61;') $c = '=';
  43.                                 if ($c == '&#34;') $c = '"';
  44.                                 if ($c == '&#39;') $c = '\'';
  45.                                 if ($c == '&#38;') $c = '&'; // DM 24.08.2016 Re-Aktiviert wegen oid+ xml export
  46.                         }
  47.  
  48.                         if (!$encode_linebreaks) {
  49.                                 if ($allow_html) {
  50.                                         if ($c == "&#10;") $c = "<br />";
  51.                                         if ($c == "&#13;") $c = "<br />";
  52.                                 } else {
  53.                                         if ($c == "&#10;") $c = "\n";
  54.                                         if ($c == "&#13;") $c = "\r";
  55.                                 }
  56.                         }
  57.                 }
  58.                 $str2 .= $c;
  59.         }
  60.         return $str2;
  61. }
  62.  
  63. function ordUTF8($c, $index = 0, &$bytes = null) {
  64.         // http://de.php.net/manual/en/function.ord.php#78032
  65.  
  66.         $len = strlen($c);
  67.         $bytes = 0;
  68.  
  69.         if ($index >= $len) {
  70.                 return false;
  71.         }
  72.  
  73.         $h = ord($c{$index});
  74.  
  75.         if ($h <= 0x7F) {
  76.                 $bytes = 1;
  77.                 return $h;
  78.         } else if ($h < 0xC2) {
  79.                 return false;
  80.         } else if ($h <= 0xDF && $index < $len - 1) {
  81.                 $bytes = 2;
  82.                 return ($h & 0x1F) <<  6 | (ord($c{$index + 1}) & 0x3F);
  83.         } else if ($h <= 0xEF && $index < $len - 2) {
  84.                 $bytes = 3;
  85.                 return ($h & 0x0F) << 12 | (ord($c{$index + 1}) & 0x3F) << 6
  86.                         | (ord($c{$index + 2}) & 0x3F);
  87.         } else if ($h <= 0xF4 && $index < $len - 3) {
  88.                 $bytes = 4;
  89.                 return ($h & 0x0F) << 18 | (ord($c{$index + 1}) & 0x3F) << 12
  90.                         | (ord($c{$index + 2}) & 0x3F) << 6
  91.                         | (ord($c{$index + 3}) & 0x3F);
  92.         } else {
  93.                 return false;
  94.         }
  95. }
  96.  
  97. function utf16_to_utf8($str) {
  98.         // http://betamode.de/2008/09/08/php-utf-16-zu-utf-8-konvertieren/
  99.         // http://www.moddular.org/log/utf16-to-utf8
  100.  
  101.         $c0 = ord($str[0]);
  102.         $c1 = ord($str[1]);
  103.         if ($c0 == 0xFE && $c1 == 0xFF) {
  104.                 $be = true;
  105.         } else if ($c0 == 0xFF && $c1 == 0xFE) {
  106.                 $be = false;
  107.         } else {
  108.                 return $str;
  109.         }
  110.         $str = substr($str, 2);
  111.         $len = strlen($str);
  112.         $dec = '';
  113.         for ($i = 0; $i < $len; $i += 2) {
  114.                 $c = ($be) ? ord($str[$i]) << 8 | ord($str[$i + 1]) :
  115.                         ord($str[$i + 1]) << 8 | ord($str[$i]);
  116.                 if ($c >= 0x0001 && $c <= 0x007F) {
  117.                         $dec .= chr($c);
  118.                 } else if ($c > 0x07FF) {
  119.                         $dec .= chr(0xE0 | (($c >> 12) & 0x0F));
  120.                         $dec .= chr(0x80 | (($c >> 6) & 0x3F));
  121.                         $dec .= chr(0x80 | (($c >> 0) & 0x3F));
  122.                 } else {
  123.                         $dec .= chr(0xC0 | (($c >> 6) & 0x1F));
  124.                         $dec .= chr(0x80 | (($c >> 0) & 0x3F));
  125.                 }
  126.         }
  127.         return $dec;
  128. }
  129.  
  130. function html_named_to_numeric_entities($str) {
  131.         if (!function_exists('decodeNamedEntities')) {
  132.                 function decodeNamedEntities($string) {
  133.                         // https://stackoverflow.com/questions/20406599/how-to-encode-for-entity-igrave-not-defined-error-in-xml-feed
  134.                         static $entities = NULL;
  135.                         if (NULL === $entities) {
  136.                                 $entities = array_flip(
  137.                                         array_diff(
  138.                                                 get_html_translation_table(HTML_ENTITIES, ENT_COMPAT | ENT_HTML401, 'UTF-8'),
  139.                                                 get_html_translation_table(HTML_ENTITIES, ENT_COMPAT | ENT_XML1, 'UTF-8')
  140.                                         )
  141.                                 );
  142.                         }
  143.                         return str_replace(array_keys($entities), $entities, $string);
  144.                 }
  145.         }
  146.  
  147.         if (!function_exists('mb_convert_encoding')) {
  148.                 // https://riptutorial.com/php/example/15633/converting-unicode-characters-to-their-numeric-value-and-or-html-entities-using-php
  149.                 function mb_convert_encoding($str, $to_encoding, $from_encoding = NULL) {
  150.                         return iconv(($from_encoding === NULL) ? mb_internal_encoding() : $from_encoding, $to_encoding, $str);
  151.                 }
  152.         }
  153.  
  154.         if (!function_exists('mb_ord')) {
  155.                 // https://riptutorial.com/php/example/15633/converting-unicode-characters-to-their-numeric-value-and-or-html-entities-using-php
  156.                 function mb_ord($char, $encoding = 'UTF-8') {
  157.                         if ($encoding === 'UCS-4BE') {
  158.                                 list(, $ord) = (strlen($char) === 4) ? @unpack('N', $char) : @unpack('n', $char);
  159.                                 return $ord;
  160.                         } else {
  161.                                 return mb_ord(mb_convert_encoding($char, 'UCS-4BE', $encoding), 'UCS-4BE');
  162.                         }
  163.                 }
  164.         }
  165.  
  166.         if (!function_exists('mb_htmlentities')) {
  167.                 // https://riptutorial.com/php/example/15633/converting-unicode-characters-to-their-numeric-value-and-or-html-entities-using-php
  168.                 function mb_htmlentities($string, $hex = true, $encoding = 'UTF-8') {
  169.                         return preg_replace_callback('/[\x{80}-\x{10FFFF}]/u', function ($match) use ($hex) {
  170.                                 return sprintf($hex ? '&#x%X;' : '&#%d;', mb_ord($match[0]));
  171.                         }, $string);
  172.                 }
  173.         }
  174.  
  175.         if (!mb_detect_encoding($str, 'UTF-8', true)) $str = utf8_encode($str);
  176.         return mb_htmlentities(decodeNamedEntities($str));
  177. }
  178.