291 |
291 |
292 public static function LittleEndian2Int($byteword, $signed=false) { |
292 public static function LittleEndian2Int($byteword, $signed=false) { |
293 return self::BigEndian2Int(strrev($byteword), false, $signed); |
293 return self::BigEndian2Int(strrev($byteword), false, $signed); |
294 } |
294 } |
295 |
295 |
|
296 public static function LittleEndian2Bin($byteword) { |
|
297 return self::BigEndian2Bin(strrev($byteword)); |
|
298 } |
296 |
299 |
297 public static function BigEndian2Bin($byteword) { |
300 public static function BigEndian2Bin($byteword) { |
298 $binvalue = ''; |
301 $binvalue = ''; |
299 $bytewordlen = strlen($byteword); |
302 $bytewordlen = strlen($byteword); |
300 for ($i = 0; $i < $bytewordlen; $i++) { |
303 for ($i = 0; $i < $bytewordlen; $i++) { |
410 } elseif (!isset($newarray[$key])) { |
413 } elseif (!isset($newarray[$key])) { |
411 $newarray[$key] = $val; |
414 $newarray[$key] = $val; |
412 } |
415 } |
413 } |
416 } |
414 return $newarray; |
417 return $newarray; |
|
418 } |
|
419 |
|
420 public static function flipped_array_merge_noclobber($array1, $array2) { |
|
421 if (!is_array($array1) || !is_array($array2)) { |
|
422 return false; |
|
423 } |
|
424 # naturally, this only works non-recursively |
|
425 $newarray = array_flip($array1); |
|
426 foreach (array_flip($array2) as $key => $val) { |
|
427 if (!isset($newarray[$key])) { |
|
428 $newarray[$key] = count($newarray); |
|
429 } |
|
430 } |
|
431 return array_flip($newarray); |
415 } |
432 } |
416 |
433 |
417 |
434 |
418 public static function ksort_recursive(&$theArray) { |
435 public static function ksort_recursive(&$theArray) { |
419 ksort($theArray); |
436 ksort($theArray); |
517 } |
534 } |
518 return ($returnkey ? $minkey : $minvalue); |
535 return ($returnkey ? $minkey : $minvalue); |
519 } |
536 } |
520 |
537 |
521 public static function XML2array($XMLstring) { |
538 public static function XML2array($XMLstring) { |
522 if ( function_exists( 'simplexml_load_string' ) && function_exists( 'libxml_disable_entity_loader' ) ) { |
539 if (function_exists('simplexml_load_string') && function_exists('libxml_disable_entity_loader')) { |
523 $loader = libxml_disable_entity_loader( true ); |
540 // http://websec.io/2012/08/27/Preventing-XEE-in-PHP.html |
524 $XMLobject = simplexml_load_string( $XMLstring, 'SimpleXMLElement', LIBXML_NOENT ); |
541 // https://core.trac.wordpress.org/changeset/29378 |
525 $return = self::SimpleXMLelement2array( $XMLobject ); |
542 $loader = libxml_disable_entity_loader(true); |
526 libxml_disable_entity_loader( $loader ); |
543 $XMLobject = simplexml_load_string($XMLstring, 'SimpleXMLElement', LIBXML_NOENT); |
|
544 $return = self::SimpleXMLelement2array($XMLobject); |
|
545 libxml_disable_entity_loader($loader); |
527 return $return; |
546 return $return; |
528 } |
547 } |
529 return false; |
548 return false; |
530 } |
549 } |
531 |
550 |
942 |
961 |
943 if ($in_charset == $out_charset) { |
962 if ($in_charset == $out_charset) { |
944 return $string; |
963 return $string; |
945 } |
964 } |
946 |
965 |
|
966 // mb_convert_encoding() availble |
|
967 if (function_exists('mb_convert_encoding')) { |
|
968 if ($converted_string = @mb_convert_encoding($string, $out_charset, $in_charset)) { |
|
969 switch ($out_charset) { |
|
970 case 'ISO-8859-1': |
|
971 $converted_string = rtrim($converted_string, "\x00"); |
|
972 break; |
|
973 } |
|
974 return $converted_string; |
|
975 } |
|
976 return $string; |
|
977 } |
947 // iconv() availble |
978 // iconv() availble |
948 if (function_exists('iconv')) { |
979 else if (function_exists('iconv')) { |
949 if ($converted_string = @iconv($in_charset, $out_charset.'//TRANSLIT', $string)) { |
980 if ($converted_string = @iconv($in_charset, $out_charset.'//TRANSLIT', $string)) { |
950 switch ($out_charset) { |
981 switch ($out_charset) { |
951 case 'ISO-8859-1': |
982 case 'ISO-8859-1': |
952 $converted_string = rtrim($converted_string, "\x00"); |
983 $converted_string = rtrim($converted_string, "\x00"); |
953 break; |
984 break; |
959 // and return an empty string, but returning the unconverted string is more useful |
990 // and return an empty string, but returning the unconverted string is more useful |
960 return $string; |
991 return $string; |
961 } |
992 } |
962 |
993 |
963 |
994 |
964 // iconv() not available |
995 // neither mb_convert_encoding or iconv() is available |
965 static $ConversionFunctionList = array(); |
996 static $ConversionFunctionList = array(); |
966 if (empty($ConversionFunctionList)) { |
997 if (empty($ConversionFunctionList)) { |
967 $ConversionFunctionList['ISO-8859-1']['UTF-8'] = 'iconv_fallback_iso88591_utf8'; |
998 $ConversionFunctionList['ISO-8859-1']['UTF-8'] = 'iconv_fallback_iso88591_utf8'; |
968 $ConversionFunctionList['ISO-8859-1']['UTF-16'] = 'iconv_fallback_iso88591_utf16'; |
999 $ConversionFunctionList['ISO-8859-1']['UTF-16'] = 'iconv_fallback_iso88591_utf16'; |
969 $ConversionFunctionList['ISO-8859-1']['UTF-16BE'] = 'iconv_fallback_iso88591_utf16be'; |
1000 $ConversionFunctionList['ISO-8859-1']['UTF-16BE'] = 'iconv_fallback_iso88591_utf16be'; |
981 } |
1012 } |
982 if (isset($ConversionFunctionList[strtoupper($in_charset)][strtoupper($out_charset)])) { |
1013 if (isset($ConversionFunctionList[strtoupper($in_charset)][strtoupper($out_charset)])) { |
983 $ConversionFunction = $ConversionFunctionList[strtoupper($in_charset)][strtoupper($out_charset)]; |
1014 $ConversionFunction = $ConversionFunctionList[strtoupper($in_charset)][strtoupper($out_charset)]; |
984 return self::$ConversionFunction($string); |
1015 return self::$ConversionFunction($string); |
985 } |
1016 } |
986 throw new Exception('PHP does not have iconv() support - cannot convert from '.$in_charset.' to '.$out_charset); |
1017 throw new Exception('PHP does not has mb_convert_encoding() or iconv() support - cannot convert from '.$in_charset.' to '.$out_charset); |
987 } |
1018 } |
988 |
1019 |
989 public static function recursiveMultiByteCharString2HTML($data, $charset='ISO-8859-1') { |
1020 public static function recursiveMultiByteCharString2HTML($data, $charset='ISO-8859-1') { |
990 if (is_string($data)) { |
1021 if (is_string($data)) { |
991 return self::MultiByteCharString2HTML($data, $charset); |
1022 return self::MultiByteCharString2HTML($data, $charset); |
1002 |
1033 |
1003 public static function MultiByteCharString2HTML($string, $charset='ISO-8859-1') { |
1034 public static function MultiByteCharString2HTML($string, $charset='ISO-8859-1') { |
1004 $string = (string) $string; // in case trying to pass a numeric (float, int) string, would otherwise return an empty string |
1035 $string = (string) $string; // in case trying to pass a numeric (float, int) string, would otherwise return an empty string |
1005 $HTMLstring = ''; |
1036 $HTMLstring = ''; |
1006 |
1037 |
1007 switch ($charset) { |
1038 switch (strtolower($charset)) { |
1008 case '1251': |
1039 case '1251': |
1009 case '1252': |
1040 case '1252': |
1010 case '866': |
1041 case '866': |
1011 case '932': |
1042 case '932': |
1012 case '936': |
1043 case '936': |
1013 case '950': |
1044 case '950': |
1014 case 'BIG5': |
1045 case 'big5': |
1015 case 'BIG5-HKSCS': |
1046 case 'big5-hkscs': |
1016 case 'cp1251': |
1047 case 'cp1251': |
1017 case 'cp1252': |
1048 case 'cp1252': |
1018 case 'cp866': |
1049 case 'cp866': |
1019 case 'EUC-JP': |
1050 case 'euc-jp': |
1020 case 'EUCJP': |
1051 case 'eucjp': |
1021 case 'GB2312': |
1052 case 'gb2312': |
1022 case 'ibm866': |
1053 case 'ibm866': |
1023 case 'ISO-8859-1': |
1054 case 'iso-8859-1': |
1024 case 'ISO-8859-15': |
1055 case 'iso-8859-15': |
1025 case 'ISO8859-1': |
1056 case 'iso8859-1': |
1026 case 'ISO8859-15': |
1057 case 'iso8859-15': |
1027 case 'KOI8-R': |
1058 case 'koi8-r': |
1028 case 'koi8-ru': |
1059 case 'koi8-ru': |
1029 case 'koi8r': |
1060 case 'koi8r': |
1030 case 'Shift_JIS': |
1061 case 'shift_jis': |
1031 case 'SJIS': |
1062 case 'sjis': |
1032 case 'win-1251': |
1063 case 'win-1251': |
1033 case 'Windows-1251': |
1064 case 'windows-1251': |
1034 case 'Windows-1252': |
1065 case 'windows-1252': |
1035 $HTMLstring = htmlentities($string, ENT_COMPAT, $charset); |
1066 $HTMLstring = htmlentities($string, ENT_COMPAT, $charset); |
1036 break; |
1067 break; |
1037 |
1068 |
1038 case 'UTF-8': |
1069 case 'utf-8': |
1039 $strlen = strlen($string); |
1070 $strlen = strlen($string); |
1040 for ($i = 0; $i < $strlen; $i++) { |
1071 for ($i = 0; $i < $strlen; $i++) { |
1041 $char_ord_val = ord($string{$i}); |
1072 $char_ord_val = ord($string{$i}); |
1042 $charval = 0; |
1073 $charval = 0; |
1043 if ($char_ord_val < 0x80) { |
1074 if ($char_ord_val < 0x80) { |
1061 $HTMLstring .= '&#'.$charval.';'; |
1092 $HTMLstring .= '&#'.$charval.';'; |
1062 } |
1093 } |
1063 } |
1094 } |
1064 break; |
1095 break; |
1065 |
1096 |
1066 case 'UTF-16LE': |
1097 case 'utf-16le': |
1067 for ($i = 0; $i < strlen($string); $i += 2) { |
1098 for ($i = 0; $i < strlen($string); $i += 2) { |
1068 $charval = self::LittleEndian2Int(substr($string, $i, 2)); |
1099 $charval = self::LittleEndian2Int(substr($string, $i, 2)); |
1069 if (($charval >= 32) && ($charval <= 127)) { |
1100 if (($charval >= 32) && ($charval <= 127)) { |
1070 $HTMLstring .= chr($charval); |
1101 $HTMLstring .= chr($charval); |
1071 } else { |
1102 } else { |
1072 $HTMLstring .= '&#'.$charval.';'; |
1103 $HTMLstring .= '&#'.$charval.';'; |
1073 } |
1104 } |
1074 } |
1105 } |
1075 break; |
1106 break; |
1076 |
1107 |
1077 case 'UTF-16BE': |
1108 case 'utf-16be': |
1078 for ($i = 0; $i < strlen($string); $i += 2) { |
1109 for ($i = 0; $i < strlen($string); $i += 2) { |
1079 $charval = self::BigEndian2Int(substr($string, $i, 2)); |
1110 $charval = self::BigEndian2Int(substr($string, $i, 2)); |
1080 if (($charval >= 32) && ($charval <= 127)) { |
1111 if (($charval >= 32) && ($charval <= 127)) { |
1081 $HTMLstring .= chr($charval); |
1112 $HTMLstring .= chr($charval); |
1082 } else { |
1113 } else { |
1149 |
1180 |
1150 |
1181 |
1151 public static function GetDataImageSize($imgData, &$imageinfo=array()) { |
1182 public static function GetDataImageSize($imgData, &$imageinfo=array()) { |
1152 static $tempdir = ''; |
1183 static $tempdir = ''; |
1153 if (empty($tempdir)) { |
1184 if (empty($tempdir)) { |
|
1185 if (function_exists('sys_get_temp_dir')) { |
|
1186 $tempdir = sys_get_temp_dir(); // https://github.com/JamesHeinrich/getID3/issues/52 |
|
1187 } |
|
1188 |
1154 // yes this is ugly, feel free to suggest a better way |
1189 // yes this is ugly, feel free to suggest a better way |
1155 require_once(dirname(__FILE__).'/getid3.php'); |
1190 if (include_once(dirname(__FILE__).'/getid3.php')) { |
1156 $getid3_temp = new getID3(); |
1191 if ($getid3_temp = new getID3()) { |
1157 $tempdir = $getid3_temp->tempdir; |
1192 if ($getid3_temp_tempdir = $getid3_temp->tempdir) { |
1158 unset($getid3_temp); |
1193 $tempdir = $getid3_temp_tempdir; |
|
1194 } |
|
1195 unset($getid3_temp, $getid3_temp_tempdir); |
|
1196 } |
|
1197 } |
1159 } |
1198 } |
1160 $GetDataImageSize = false; |
1199 $GetDataImageSize = false; |
1161 if ($tempfilename = tempnam($tempdir, 'gI3')) { |
1200 if ($tempfilename = tempnam($tempdir, 'gI3')) { |
1162 if (is_writable($tempfilename) && is_file($tempfilename) && ($tmp = fopen($tempfilename, 'wb'))) { |
1201 if (is_writable($tempfilename) && is_file($tempfilename) && ($tmp = fopen($tempfilename, 'wb'))) { |
1163 fwrite($tmp, $imgData); |
1202 fwrite($tmp, $imgData); |
1164 fclose($tmp); |
1203 fclose($tmp); |
1165 $GetDataImageSize = @getimagesize($tempfilename, $imageinfo); |
1204 $GetDataImageSize = @getimagesize($tempfilename, $imageinfo); |
|
1205 if (($GetDataImageSize === false) || !isset($GetDataImageSize[0]) || !isset($GetDataImageSize[1])) { |
|
1206 return false; |
|
1207 } |
|
1208 $GetDataImageSize['height'] = $GetDataImageSize[0]; |
|
1209 $GetDataImageSize['width'] = $GetDataImageSize[1]; |
1166 } |
1210 } |
1167 unlink($tempfilename); |
1211 unlink($tempfilename); |
1168 } |
1212 } |
1169 return $GetDataImageSize; |
1213 return $GetDataImageSize; |
1170 } |
1214 } |
1231 } |
1275 } |
1232 |
1276 |
1233 } |
1277 } |
1234 if (is_array($value) || empty($ThisFileInfo['comments'][$tagname]) || !in_array(trim($value), $ThisFileInfo['comments'][$tagname])) { |
1278 if (is_array($value) || empty($ThisFileInfo['comments'][$tagname]) || !in_array(trim($value), $ThisFileInfo['comments'][$tagname])) { |
1235 $value = (is_string($value) ? trim($value) : $value); |
1279 $value = (is_string($value) ? trim($value) : $value); |
1236 if (!is_numeric($key)) { |
1280 if (!is_int($key) && !ctype_digit($key)) { |
1237 $ThisFileInfo['comments'][$tagname][$key] = $value; |
1281 $ThisFileInfo['comments'][$tagname][$key] = $value; |
1238 } else { |
1282 } else { |
1239 $ThisFileInfo['comments'][$tagname][] = $value; |
1283 if (isset($ThisFileInfo['comments'][$tagname])) { |
|
1284 $ThisFileInfo['comments'][$tagname] = array($value); |
|
1285 } else { |
|
1286 $ThisFileInfo['comments'][$tagname][] = $value; |
|
1287 } |
1240 } |
1288 } |
1241 } |
1289 } |
1242 } |
1290 } |
1243 } |
1291 } |
|
1292 } |
|
1293 } |
|
1294 |
|
1295 // attempt to standardize spelling of returned keys |
|
1296 $StandardizeFieldNames = array( |
|
1297 'tracknumber' => 'track_number', |
|
1298 'track' => 'track_number', |
|
1299 ); |
|
1300 foreach ($StandardizeFieldNames as $badkey => $goodkey) { |
|
1301 if (array_key_exists($badkey, $ThisFileInfo['comments']) && !array_key_exists($goodkey, $ThisFileInfo['comments'])) { |
|
1302 $ThisFileInfo['comments'][$goodkey] = $ThisFileInfo['comments'][$badkey]; |
|
1303 unset($ThisFileInfo['comments'][$badkey]); |
1244 } |
1304 } |
1245 } |
1305 } |
1246 |
1306 |
1247 // Copy to ['comments_html'] |
1307 // Copy to ['comments_html'] |
1248 if (!empty($ThisFileInfo['comments'])) { |
1308 if (!empty($ThisFileInfo['comments'])) { |