|
TYPO3 API
SVNRelease
|
00001 <?php 00002 /* ************************************************************** 00003 * Copyright notice 00004 * 00005 * (c) 2006-2010 Karsten Dambekalns <karsten@typo3.org> 00006 * All rights reserved 00007 * 00008 * This script is part of the TYPO3 project. The TYPO3 project is 00009 * free software; you can redistribute it and/or modify 00010 * it under the terms of the GNU General Public License as published by 00011 * the Free Software Foundation; either version 2 of the License, or 00012 * (at your option) any later version. 00013 * 00014 * The GNU General Public License can be found at 00015 * http://www.gnu.org/copyleft/gpl.html. 00016 * A copy is found in the textfile GPL.txt and important notices to the license 00017 * from the author is found in LICENSE.txt distributed with these scripts. 00018 * 00019 * 00020 * This script is distributed in the hope that it will be useful, 00021 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00022 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00023 * GNU General Public License for more details. 00024 * 00025 * This copyright notice MUST APPEAR in all copies of the script! 00026 ***************************************************************/ 00027 00028 /** 00029 * XML handling class for the TYPO3 Extension Manager. 00030 * 00031 * It contains methods for handling the XML files involved with the EM, 00032 * such as the list of extension mirrors and the list of available extensions. 00033 * 00034 * @author Karsten Dambekalns <karsten@typo3.org> 00035 * @package TYPO3 00036 * @subpackage EM 00037 */ 00038 class tx_em_Tools_XmlHandler { 00039 00040 00041 /** 00042 * Holds the parsed XML from extensions.xml.gz 00043 * @see parseExtensionsXML() 00044 * 00045 * @var array 00046 */ 00047 protected $extXMLResult = array(); 00048 00049 /** 00050 * @var array 00051 */ 00052 public $extensionsXML = array(); 00053 00054 /** 00055 * @var NULL 00056 */ 00057 protected $reviewStates = NULL; 00058 00059 /** 00060 * @var bool 00061 */ 00062 public $useObsolete = FALSE; 00063 00064 /** 00065 * @var array 00066 */ 00067 protected $catArr = array(); 00068 00069 /** 00070 * @var array 00071 */ 00072 protected $stateArr = array(); 00073 00074 /** 00075 * @var int 00076 */ 00077 public $matchingCount = 0; 00078 00079 /** 00080 * @var array 00081 */ 00082 protected $revCatArr = array(); 00083 00084 /** 00085 * @var array 00086 */ 00087 protected $revStateArr = array(); 00088 00089 /** 00090 * @var string 00091 */ 00092 protected $currentExt = ''; 00093 00094 /** 00095 * @var string 00096 */ 00097 protected $currentVersion = ''; 00098 00099 /** 00100 * @var string 00101 */ 00102 protected $currentTag = ''; 00103 00104 /** 00105 * Reduces the entries in $this->extensionsXML to the latest version per extension and removes entries not matching the search parameter 00106 * 00107 * @param string $search The list of extensions is reduced to entries matching this. If empty, the full list is returned. 00108 * @param string $owner If set only extensions of that user are fetched 00109 * @param string $order A field to order the result by 00110 * @param boolean $allExt If set also unreviewed and obsolete extensions are shown 00111 * @param boolean $allVer If set returns all version of an extension, otherwise only the last 00112 * @param integer $offset Offset to return result from (goes into LIMIT clause) 00113 * @param integer $limit Maximum number of entries to return (goes into LIMIT clause) 00114 * @param boolean $exactMatch If set search is done for exact matches of extension keys only 00115 * @return void 00116 */ 00117 function searchExtensionsXML($search, $owner = '', $order = '', $allExt = FALSE, $allVer = FALSE, $offset = 0, $limit = 500, $exactMatch = FALSE) { 00118 $where = '1=1'; 00119 if ($search && $exactMatch) { 00120 $where .= ' AND extkey=' . $GLOBALS['TYPO3_DB']->fullQuoteStr($search, 'cache_extensions'); 00121 } elseif ($search) { 00122 $quotedSearch = $GLOBALS['TYPO3_DB']->escapeStrForLike( 00123 $GLOBALS['TYPO3_DB']->quoteStr($search, 'cache_extensions'), 00124 'cache_extensions' 00125 ); 00126 $where .= ' AND (extkey LIKE \'%' . $quotedSearch . '%\' OR title LIKE \'%' . $quotedSearch . '%\')'; 00127 00128 } 00129 if ($owner) { 00130 $where .= ' AND ownerusername=' . $GLOBALS['TYPO3_DB']->fullQuoteStr($owner, 'cache_extensions'); 00131 } 00132 00133 // Show extensions without a review or that have passed a review, but not insecure extensions 00134 $where .= ' AND reviewstate >= 0'; 00135 00136 if (!$this->useObsolete) { 00137 // 5 == obsolete 00138 $where .= ' AND state != 5'; 00139 } 00140 00141 switch ($order) { 00142 case 'author_company': 00143 $forder = 'authorname, authorcompany'; 00144 break; 00145 case 'state': 00146 $forder = 'state'; 00147 break; 00148 case 'cat': 00149 default: 00150 $forder = 'category'; 00151 break; 00152 } 00153 $order = $forder . ', title'; 00154 if (!$allVer) { 00155 $where .= ' AND lastversion > 0'; 00156 } 00157 00158 $idx = 0; 00159 $defaultCategories = tx_em_Tools::getDefaultCategory(); 00160 foreach ($defaultCategories as $catKey => $tmp) { 00161 $this->catArr[$idx] = $catKey; 00162 $idx++; 00163 } 00164 00165 $idx = 0; 00166 $states = tx_em_Tools::getStates(); 00167 foreach ($states as $state => $tmp) { 00168 $this->stateArr[$idx] = $state; 00169 $idx++; 00170 } 00171 00172 // Fetch count 00173 $count = $GLOBALS['TYPO3_DB']->exec_SELECTcountRows('*', 'cache_extensions', $where); 00174 $this->matchingCount = $count; 00175 00176 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*', 'cache_extensions', $where, '', $order, $offset . ',' . $limit); 00177 $this->extensionsXML = array(); 00178 while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) { 00179 $row['category'] = $this->catArr[$row['category']]; 00180 $row['state'] = $this->stateArr[$row['state']]; 00181 00182 if (!is_array($this->extensionsXML[$row['extkey']])) { 00183 $this->extensionsXML[$row['extkey']] = array(); 00184 $this->extensionsXML[$row['extkey']]['downloadcounter'] = $row['alldownloadcounter']; 00185 } 00186 if (!is_array($this->extensionsXML[$row['extkey']]['versions'])) { 00187 $this->extensionsXML[$row['extkey']]['versions'] = array(); 00188 } 00189 $row['dependencies'] = unserialize($row['dependencies']); 00190 $this->extensionsXML[$row['extkey']]['versions'][$row['version']] = $row; 00191 } 00192 $GLOBALS['TYPO3_DB']->sql_free_result($res); 00193 } 00194 00195 /** 00196 * Reduces the entries in $this->extensionsXML to the latest version per extension and removes entries not matching the search parameter 00197 * The extension key has to be a valid one as search is done for exact matches only. 00198 * 00199 * @param string $search The list of extensions is reduced to entries with exactely this extension key. If empty, the full list is returned. 00200 * @param string $owner If set only extensions of that user are fetched 00201 * @param string $order A field to order the result by 00202 * @param boolean $allExt If set also unreviewed and obsolete extensions are shown 00203 * @param boolean $allVer If set returns all version of an extension, otherwise only the last 00204 * @param integer $offset Offset to return result from (goes into LIMIT clause) 00205 * @param integer $limit Maximum number of entries to return (goes into LIMIT clause) 00206 * @return void 00207 */ 00208 function searchExtensionsXMLExact($search, $owner = '', $order = '', $allExt = FALSE, $allVer = FALSE, $offset = 0, $limit = 500) { 00209 $this->searchExtensionsXML($search, $owner, $order, $allExt, $allVer, $offset, $limit, TRUE); 00210 } 00211 00212 function countExtensions() { 00213 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('extkey', 'cache_extensions', '1=1', 'extkey'); 00214 $cnt = $GLOBALS['TYPO3_DB']->sql_num_rows($res); 00215 $GLOBALS['TYPO3_DB']->sql_free_result($res); 00216 return $cnt; 00217 } 00218 00219 /** 00220 * Loads the pre-parsed extension list 00221 * 00222 * @return boolean TRUE on success, FALSE on error 00223 */ 00224 function loadExtensionsXML() { 00225 $this->searchExtensionsXML('', '', '', TRUE); 00226 } 00227 00228 /** 00229 * Frees the pre-parsed extension list 00230 * 00231 * @return void 00232 */ 00233 function freeExtensionsXML() { 00234 unset($this->extensionsXML); 00235 $this->extensionsXML = array(); 00236 } 00237 00238 /** 00239 * Removes all extension with a certain state from the list 00240 * 00241 * @param array &$extensions The "versions" subpart of the extension list 00242 * @return void 00243 */ 00244 function removeObsolete(&$extensions) { 00245 if ($this->useObsolete) { 00246 return; 00247 } 00248 00249 foreach ($extensions as $version => $data) { 00250 if ($data['state'] == 'obsolete') { 00251 unset($extensions[$version]); 00252 } 00253 } 00254 } 00255 00256 /** 00257 * Returns the reviewstate of a specific extension-key/version 00258 * 00259 * @param string $extKey 00260 * @param string $version: ... 00261 * @return integer Review state, if none is set 0 is returned as default. 00262 */ 00263 function getReviewState($extKey, $version) { 00264 $where = 'extkey=' . $GLOBALS['TYPO3_DB']->fullQuoteStr($extKey, 'cache_extensions') . ' AND version=' . $GLOBALS['TYPO3_DB']->fullQuoteStr($version, 'cache_extensions'); 00265 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('reviewstate', 'cache_extensions', $where); 00266 $reviewState = 0; 00267 if ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) { 00268 $reviewState = $row['reviewstate']; 00269 } 00270 $GLOBALS['TYPO3_DB']->sql_free_result($res); 00271 00272 return $reviewState; 00273 } 00274 00275 00276 /** 00277 * ***************PARSING METHODS*********************** 00278 */ 00279 /** 00280 * Enter description here... 00281 * 00282 * @param unknown_type $parser 00283 * @param unknown_type $name 00284 * @param unknown_type $attrs 00285 * @return [type] ... 00286 */ 00287 function startElement($parser, $name, $attrs) { 00288 switch ($name) { 00289 case 'extensions': 00290 break; 00291 case 'extension': 00292 $this->currentExt = $attrs['extensionkey']; 00293 break; 00294 case 'version': 00295 $this->currentVersion = $attrs['version']; 00296 $this->extXMLResult[$this->currentExt]['versions'][$this->currentVersion] = array(); 00297 break; 00298 default: 00299 $this->currentTag = $name; 00300 } 00301 } 00302 00303 /** 00304 * Enter description here... 00305 * 00306 * @param unknown_type $parser 00307 * @param unknown_type $name 00308 * @return [type] ... 00309 */ 00310 function endElement($parser, $name) { 00311 switch ($name) { 00312 case 'extension': 00313 unset($this->currentExt); 00314 break; 00315 case 'version': 00316 unset($this->currentVersion); 00317 break; 00318 default: 00319 unset($this->currentTag); 00320 } 00321 } 00322 00323 /** 00324 * Enter description here... 00325 * 00326 * @param unknown_type $parser 00327 * @param unknown_type $data 00328 * @return [type] ... 00329 */ 00330 function characterData($parser, $data) { 00331 if (isset($this->currentTag)) { 00332 if (!isset($this->currentVersion) && $this->currentTag == 'downloadcounter') { 00333 $this->extXMLResult[$this->currentExt]['downloadcounter'] = trim($data); 00334 } elseif ($this->currentTag == 'dependencies') { 00335 $data = @unserialize($data); 00336 if (is_array($data)) { 00337 $dep = array(); 00338 foreach ($data as $v) { 00339 $dep[$v['kind']][$v['extensionKey']] = $v['versionRange']; 00340 } 00341 $this->extXMLResult[$this->currentExt]['versions'][$this->currentVersion]['dependencies'] = $dep; 00342 } 00343 } elseif ($this->currentTag == 'reviewstate') { 00344 $this->reviewStates[$this->currentExt][$this->currentVersion] = (int) trim($data); 00345 $this->extXMLResult[$this->currentExt]['versions'][$this->currentVersion]['reviewstate'] = (int) trim($data); 00346 } else { 00347 $this->extXMLResult[$this->currentExt]['versions'][$this->currentVersion][$this->currentTag] .= trim($data); 00348 } 00349 } 00350 } 00351 00352 /** 00353 * Parses content of mirrors.xml into a suitable array 00354 * 00355 * @param string XML data file to parse 00356 * @return string HTLML output informing about result 00357 */ 00358 function parseExtensionsXML($filename) { 00359 00360 $parser = xml_parser_create(); 00361 xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0); 00362 xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 0); 00363 xml_parser_set_option($parser, XML_OPTION_TARGET_ENCODING, 'utf-8'); 00364 xml_set_element_handler($parser, array(&$this, 'startElement'), array(&$this, 'endElement')); 00365 xml_set_character_data_handler($parser, array(&$this, 'characterData')); 00366 00367 $fp = gzopen($filename, 'rb'); 00368 if (!$fp) { 00369 return 'Error opening XML extension file "' . $filename . '"'; 00370 } 00371 $string = gzread($fp, 0xffff); // Read 64KB 00372 00373 00374 $idx = 0; 00375 $defaultCategories = tx_em_Tools::getDefaultCategory(); 00376 foreach ($defaultCategories as $catKey => $tmp) { 00377 $this->revCatArr[$catKey] = $idx++; 00378 } 00379 00380 00381 $idx = 0; 00382 $states = tx_em_Tools::getStates(); 00383 foreach ($states as $state => $tmp) { 00384 $this->revStateArr[$state] = $idx++; 00385 } 00386 00387 $GLOBALS['TYPO3_DB']->exec_TRUNCATEquery('cache_extensions'); 00388 00389 $extcount = 0; 00390 $content = ''; 00391 @ini_set('pcre.backtrack_limit', 500000); 00392 do { 00393 if (preg_match('/.*(<extension\s+extensionkey="[^"]+">.*<\/extension>)/suU', $string, $match)) { 00394 // Parse content: 00395 if (!xml_parse($parser, $match[0], 0)) { 00396 $content .= 'Error in XML parser while decoding extensions XML file. Line ' . xml_get_current_line_number($parser) . ': ' . xml_error_string(xml_get_error_code($parser)); 00397 $error = TRUE; 00398 break; 00399 } 00400 $this->storeXMLResult(); 00401 $this->extXMLResult = array(); 00402 $extcount++; 00403 $string = substr($string, strlen($match[0])); 00404 } elseif (function_exists('preg_last_error') && preg_last_error()) { 00405 $errorcodes = array( 00406 0 => 'PREG_NO_ERROR', 00407 1 => 'PREG_INTERNAL_ERROR', 00408 2 => 'PREG_BACKTRACK_LIMIT_ERROR', 00409 3 => 'PREG_RECURSION_LIMIT_ERROR', 00410 4 => 'PREG_BAD_UTF8_ERROR' 00411 ); 00412 $content .= 'Error in regular expression matching, code: ' . $errorcodes[preg_last_error()] . '<br />See <a href="http://www.php.net/manual/en/function.preg-last-error.php" target="_blank">http://www.php.net/manual/en/function.preg-last-error.php</a>'; 00413 $error = TRUE; 00414 break; 00415 } else { 00416 if (gzeof($fp)) { 00417 break; 00418 } // Nothing more can be read 00419 $string .= gzread($fp, 0xffff); // Read another 64KB 00420 } 00421 } while (TRUE); 00422 00423 xml_parser_free($parser); 00424 gzclose($fp); 00425 00426 if (!$error) { 00427 /** @var $flashMessage t3lib_FlashMessage */ 00428 $flashMessage = t3lib_div::makeInstance( 00429 't3lib_FlashMessage', 00430 sprintf($GLOBALS['LANG']->getLL('ext_import_extlist_updated'), $extcount), 00431 $GLOBALS['LANG']->getLL('ext_import_extlist_updated_header') 00432 ); 00433 $content .= $flashMessage->render(); 00434 } 00435 00436 return $content; 00437 } 00438 00439 function storeXMLResult() { 00440 foreach ($this->extXMLResult as $extkey => $extArr) { 00441 $max = -1; 00442 $maxrev = -1; 00443 $last = ''; 00444 $lastrev = ''; 00445 $usecat = ''; 00446 $usetitle = ''; 00447 $usestate = ''; 00448 $useauthorcompany = ''; 00449 $useauthorname = ''; 00450 $verArr = array(); 00451 foreach ($extArr['versions'] as $version => $vArr) { 00452 $iv = tx_em_Tools::makeVersion($version, 'int'); 00453 if ($vArr['title'] && !$usetitle) { 00454 $usetitle = $vArr['title']; 00455 } 00456 if ($vArr['state'] && !$usestate) { 00457 $usestate = $vArr['state']; 00458 } 00459 if ($vArr['authorcompany'] && !$useauthorcompany) { 00460 $useauthorcompany = $vArr['authorcompany']; 00461 } 00462 if ($vArr['authorname'] && !$useauthorname) { 00463 $useauthorname = $vArr['authorname']; 00464 } 00465 $verArr[$version] = $iv; 00466 if ($iv > $max) { 00467 $max = $iv; 00468 $last = $version; 00469 if ($vArr['title']) { 00470 $usetitle = $vArr['title']; 00471 } 00472 if ($vArr['state']) { 00473 $usestate = $vArr['state']; 00474 } 00475 if ($vArr['authorcompany']) { 00476 $useauthorcompany = $vArr['authorcompany']; 00477 } 00478 if ($vArr['authorname']) { 00479 $useauthorname = $vArr['authorname']; 00480 } 00481 $usecat = $vArr['category']; 00482 } 00483 if ($vArr['reviewstate'] && ($iv > $maxrev)) { 00484 $maxrev = $iv; 00485 $lastrev = $version; 00486 } 00487 } 00488 if (!strlen($usecat)) { 00489 $usecat = 4; // Extensions without a category end up in "misc" 00490 } else { 00491 if (isset($this->revCatArr[$usecat])) { 00492 $usecat = $this->revCatArr[$usecat]; 00493 } else { 00494 $usecat = 4; // Extensions without a category end up in "misc" 00495 } 00496 } 00497 if (isset($this->revStateArr[$usestate])) { 00498 $usestate = $this->revCatArr[$usestate]; 00499 } else { 00500 $usestate = 999; // Extensions without a category end up in "misc" 00501 } 00502 foreach ($extArr['versions'] as $version => $vArr) { 00503 $vArr['version'] = $version; 00504 $vArr['intversion'] = $verArr[$version]; 00505 $vArr['extkey'] = $extkey; 00506 $vArr['alldownloadcounter'] = $extArr['downloadcounter']; 00507 $vArr['dependencies'] = serialize($vArr['dependencies']); 00508 $vArr['category'] = $usecat; 00509 $vArr['title'] = $usetitle; 00510 if ($version == $last) { 00511 $vArr['lastversion'] = 1; 00512 } 00513 if ($version == $lastrev) { 00514 $vArr['lastreviewedversion'] = 1; 00515 } 00516 $vArr['state'] = isset($this->revStateArr[$vArr['state']]) ? $this->revStateArr[$vArr['state']] : $usestate; // 999 = not set category 00517 $GLOBALS['TYPO3_DB']->exec_INSERTquery('cache_extensions', $vArr); 00518 } 00519 } 00520 } 00521 00522 /** 00523 * Parses content of mirrors.xml into a suitable array 00524 * 00525 * @param string $string: XML data to parse 00526 * @return string HTLML output informing about result 00527 */ 00528 function parseMirrorsXML($string) { 00529 global $TYPO3_CONF_VARS; 00530 00531 // Create parser: 00532 $parser = xml_parser_create(); 00533 $vals = array(); 00534 $index = array(); 00535 00536 xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0); 00537 xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 0); 00538 00539 $preg_result = array(); 00540 preg_match('/^[[:space:]]*<\?xml[^>]*encoding[[:space:]]*=[[:space:]]*"([^"]*)"/', substr($string, 0, 200), $preg_result); 00541 $theCharset = $preg_result[1] ? $preg_result[1] : ($TYPO3_CONF_VARS['BE']['forceCharset'] ? $TYPO3_CONF_VARS['BE']['forceCharset'] : 'iso-8859-1'); 00542 xml_parser_set_option($parser, XML_OPTION_TARGET_ENCODING, $theCharset); // us-ascii / utf-8 / iso-8859-1 00543 00544 // Parse content: 00545 xml_parse_into_struct($parser, $string, $vals, $index); 00546 00547 // If error, return error message: 00548 if (xml_get_error_code($parser)) { 00549 $line = xml_get_current_line_number($parser); 00550 $error = xml_error_string(xml_get_error_code($parser)); 00551 xml_parser_free($parser); 00552 return 'Error in XML parser while decoding mirrors XML file. Line ' . $line . ': ' . $error; 00553 } else { 00554 // Init vars: 00555 $stack = array(array()); 00556 $stacktop = 0; 00557 $mirrornumber = 0; 00558 $current = array(); 00559 $tagName = ''; 00560 $documentTag = ''; 00561 00562 // Traverse the parsed XML structure: 00563 foreach ($vals as $val) { 00564 00565 // First, process the tag-name (which is used in both cases, whether "complete" or "close") 00566 $tagName = ($val['tag'] == 'mirror' && $val['type'] == 'open') ? '__plh' : $val['tag']; 00567 if (!$documentTag) { 00568 $documentTag = $tagName; 00569 } 00570 00571 // Setting tag-values, manage stack: 00572 switch ($val['type']) { 00573 case 'open': // If open tag it means there is an array stored in sub-elements. Therefore increase the stackpointer and reset the accumulation array: 00574 $current[$tagName] = array(); // Setting blank place holder 00575 $stack[$stacktop++] = $current; 00576 $current = array(); 00577 break; 00578 case 'close': // If the tag is "close" then it is an array which is closing and we decrease the stack pointer. 00579 $oldCurrent = $current; 00580 $current = $stack[--$stacktop]; 00581 end($current); // Going to the end of array to get placeholder key, key($current), and fill in array next: 00582 if ($tagName == 'mirror') { 00583 unset($current['__plh']); 00584 $current[$oldCurrent['host']] = $oldCurrent; 00585 } else { 00586 $current[key($current)] = $oldCurrent; 00587 } 00588 unset($oldCurrent); 00589 break; 00590 case 'complete': // If "complete", then it's a value. If the attribute "base64" is set, then decode the value, otherwise just set it. 00591 $current[$tagName] = (string) $val['value']; // Had to cast it as a string - otherwise it would be evaluate FALSE if tested with isset()!! 00592 break; 00593 } 00594 } 00595 return $current[$tagName]; 00596 } 00597 } 00598 00599 /** 00600 * Parses content of *-l10n.xml into a suitable array 00601 * 00602 * @param string $string: XML data to parse 00603 * @return array Array representation of XML data 00604 */ 00605 function parseL10nXML($string) { 00606 // Create parser: 00607 $parser = xml_parser_create(); 00608 $vals = array(); 00609 $index = array(); 00610 00611 xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0); 00612 xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 0); 00613 00614 // Parse content: 00615 xml_parse_into_struct($parser, $string, $vals, $index); 00616 00617 // If error, return error message: 00618 if (xml_get_error_code($parser)) { 00619 $line = xml_get_current_line_number($parser); 00620 $error = xml_error_string(xml_get_error_code($parser)); 00621 xml_parser_free($parser); 00622 return 'Error in XML parser while decoding l10n XML file. Line ' . $line . ': ' . $error; 00623 } else { 00624 // Init vars: 00625 $stack = array(array()); 00626 $stacktop = 0; 00627 $mirrornumber = 0; 00628 $current = array(); 00629 $tagName = ''; 00630 $documentTag = ''; 00631 00632 // Traverse the parsed XML structure: 00633 foreach ($vals as $val) { 00634 00635 // First, process the tag-name (which is used in both cases, whether "complete" or "close") 00636 $tagName = ($val['tag'] == 'languagepack' && $val['type'] == 'open') ? $val['attributes']['language'] : $val['tag']; 00637 if (!$documentTag) { 00638 $documentTag = $tagName; 00639 } 00640 00641 // Setting tag-values, manage stack: 00642 switch ($val['type']) { 00643 case 'open': // If open tag it means there is an array stored in sub-elements. Therefore increase the stackpointer and reset the accumulation array: 00644 $current[$tagName] = array(); // Setting blank place holder 00645 $stack[$stacktop++] = $current; 00646 $current = array(); 00647 break; 00648 case 'close': // If the tag is "close" then it is an array which is closing and we decrease the stack pointer. 00649 $oldCurrent = $current; 00650 $current = $stack[--$stacktop]; 00651 end($current); // Going to the end of array to get placeholder key, key($current), and fill in array next: 00652 $current[key($current)] = $oldCurrent; 00653 unset($oldCurrent); 00654 break; 00655 case 'complete': // If "complete", then it's a value. If the attribute "base64" is set, then decode the value, otherwise just set it. 00656 $current[$tagName] = (string) $val['value']; // Had to cast it as a string - otherwise it would be evaluate FALSE if tested with isset()!! 00657 break; 00658 } 00659 } 00660 return $current[$tagName]; 00661 } 00662 } 00663 } 00664 00665 if (defined('TYPO3_MODE') && isset($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['typo3/sysext/em/classes/tools/class.tx_em_tools_smlhandler.php'])) { 00666 include_once($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['typo3/sysext/em/classes/tools/class.tx_em_tools_xmlhandler.php']); 00667 } 00668 00669 ?>
1.8.0