[TYPO3] Problem after Typo3 upgrade :-(
Dmitry Martynenko
dima at realt.by
Thu Mar 27 12:03:23 CET 2008
Hi Nino,
NK> After upgrade from ver. 3.8.1 to 4.1.6 i get following php warning when
NK> displaying page:
NK> Warning: xml_parser_set_option() [function.xml-parser-set-option]:
NK> Unsupported target encoding "iso-8859-2" in
NK> /www/htdocs/typo3_src-4.1.6/t3lib/class.t3lib_div.php on line 2174
NK> I searched for a solution but only one i found was to change encoding to
NK> UTF8. I can't make this because all sites under my Typo3 are made with
NK> iso-8859-2 encoding. Is there a way to solve this? Thx.
We also had this problem when using TYPO3 4.1.xx with Windows-1251 encoding.
It was solved with this patch to class.t3lib_div.php
Replace (or smartly merge) function xml2array() with the following code.
It does conversion of source XML to required UTF-8 encoding before xml parser.
----------------------------------------------------------------------------------
function xml2array($string,$NSprefix='',$reportDocTag=FALSE) {
global $TYPO3_CONF_VARS;
// Create parser:
$parser = xml_parser_create();
$vals = array();
$index = array();
$is_encoded = false;
xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);
xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 0);
// PHP4 doesn't like Unicode byte order marks (BOM), so we have to check for them
// The BOM check comes first, so that the PHP5 preg_match() below doesn't have to check for it
if(substr($string,0,3)=="\xEF\xBB\xBF") {
xml_parser_set_option($parser, XML_OPTION_TARGET_ENCODING, 'utf-8');
}
// PHP 4.x: output charset is the same as the input charset, charsets are handled transparently if not specified in xml_parser_create()
// PHP 5.0.0 & 5.0.1: default output charset is ISO-8859-1, only ASCII, ISO-8859-1 and UTF-8 are supported!!!
// PHP 5.0.2+: default output charset is UTF-8 , only ASCII, ISO-8859-1 and UTF-8 are supported!!!
elseif ((double)phpversion()>=5) {
$match = array();
preg_match('/^[[:space:]]*<\?xml[^>]*encoding[[:space:]]*=[[:space:]]*"([^"]*)"/',substr($string,0,200),$match);
$theCharset = $match[1] ? $match[1] : ($TYPO3_CONF_VARS['BE']['forceCharset'] ? $TYPO3_CONF_VARS['BE']['forceCharset'] : 'iso-8859-1');
$encoding = strtoupper($theCharset);
if($encoding != "UTF-8" && $encoding != "US-ASCII" && $encoding != "ISO-8859-1") {
# debug($encoding, 'ENCODING');
$string = @mb_convert_encoding($string, "UTF-8", $encoding);
$rx = '/<\?xml.*\?>/m';
$string = preg_replace($rx, '', $string);
# debug($string, 'ENCODED STRING');
$theCharset = "utf-8";
$is_encoded = true;
}
xml_parser_set_option($parser, XML_OPTION_TARGET_ENCODING, $theCharset); // us-ascii / utf-8 / iso-8859-1
}
// Parse content:
xml_parse_into_struct($parser, $string, $vals, $index);
// If error, return error message:
if (xml_get_error_code($parser)) {
return 'Line '.xml_get_current_line_number($parser).': '.xml_error_string(xml_get_error_code($parser));
}
xml_parser_free($parser);
// Init vars:
$stack = array(array());
$stacktop = 0;
$current=array();
$tagName = '';
$documentTag = '';
// Traverse the parsed XML structure:
foreach($vals as $key => $val) {
// First, process the tag-name (which is used in both cases, whether "complete" or "close")
$tagName = $val['tag'];
if (!$documentTag) $documentTag = $tagName;
// Test for name space:
$tagName = ($NSprefix && substr($tagName,0,strlen($NSprefix))==$NSprefix) ? substr($tagName,strlen($NSprefix)) : $tagName;
// Test for numeric tag, encoded on the form "nXXX":
$testNtag = substr($tagName,1); // Closing tag.
$tagName = (substr($tagName,0,1)=='n' && !strcmp(intval($testNtag),$testNtag)) ? intval($testNtag) : $tagName;
// Test for alternative index value:
if (strlen($val['attributes']['index'])) { $tagName = $val['attributes']['index']; }
// Setting tag-values, manage stack:
switch($val['type']) {
case 'open': // If open tag it means there is an array stored in sub-elements. Therefore increase the stackpointer and reset the accumulation array:
$current[$tagName] = array(); // Setting blank place holder
$stack[$stacktop++] = $current;
$current = array();
break;
case 'close': // If the tag is "close" then it is an array which is closing and we decrease the stack pointer.
$oldCurrent = $current;
$current = $stack[--$stacktop];
end($current); // Going to the end of array to get placeholder key, key($current), and fill in array next:
$current[key($current)] = $oldCurrent;
unset($oldCurrent);
break;
case 'complete': // If "complete", then it's a value. If the attribute "base64" is set, then decode the value, otherwise just set it.
if ($val['attributes']['base64']) {
$current[$tagName] = base64_decode($val['value']);
} else {
$current[$tagName] = $is_encoded ? @mb_convert_encoding((string)$val['value'], $encoding, "UTF-8") : (string)$val['value']; // Had to cast it as a string - otherwise it would be evaluate false if tested with isset()!!
// Cast type:
switch((string)$val['attributes']['type']) {
case 'integer':
$current[$tagName] = (integer)$current[$tagName];
break;
case 'double':
$current[$tagName] = (double)$current[$tagName];
break;
case 'boolean':
$current[$tagName] = (bool)$current[$tagName];
break;
case 'array':
$current[$tagName] = array(); // MUST be an empty array since it is processed as a value; Empty arrays would end up here because they would have no tags inside...
break;
}
}
break;
}
}
if ($reportDocTag) {
$current[$tagName]['_DOCUMENT_TAG'] = $documentTag;
}
// Finally return the content of the document tag.
return $current[$tagName];
}
----------------------------------------------------------------------------------
--
Dmitry Martynenko
Developer
Web: http://realt.by
More information about the TYPO3-english
mailing list