%PDF- %PDF-
Direktori : /home/lightco1/www/plugins/vmpayment/sofort/sofort/library/helper/ |
Current File : /home/lightco1/www/plugins/vmpayment/sofort/sofort/library/helper/xml_to_array.php |
<?php defined('_JEXEC') or die('Restricted access'); /** * @author SOFORT AG (integration@sofort.com) * @link http://www.sofort.com/ * * Copyright (c) 2012 SOFORT AG * * Released under the GNU General Public License (Version 2) * [http://www.gnu.org/licenses/gpl-2.0.html] */ require_once('xml_to_array_exception.php'); require_once('xml_to_array_node.php'); /** * * XML To Array conversion */ class XmlToArray { /** * Holds start tags in a row. * Used for error reporting and counting the current depth * @var array */ private $_tagStack = array(); /** * Reference to the current node the parser is at * @var XmlToArrayNode */ private $_CurrentXmlToArrayNode = null; /** * Object reference for logging purposes * @var Object */ private $_Object = null; /** * stop parsing when maxDepth is exceeded, defaults to no maximum (=0). * * @var $_maxDepth int */ private $_maxDepth = 0; private static $_htmlEntityExceptions = array( '€' => '€', ); /** * Loads XML into array representation. * @param string $input * @param int $maxDepth * @throws XmlToArrayException */ public function __construct($input, $maxDepth = 20) { if (!is_string($input)) throw new XmlToArrayException('No valid input.'); $this->_maxDepth = $maxDepth; $XMLParser = xml_parser_create(); xml_parser_set_option($XMLParser, XML_OPTION_SKIP_WHITE, false); xml_parser_set_option($XMLParser, XML_OPTION_CASE_FOLDING, false); xml_parser_set_option($XMLParser, XML_OPTION_TARGET_ENCODING, 'UTF-8'); xml_set_character_data_handler($XMLParser, array($this, '_contents')); xml_set_default_handler($XMLParser, array($this, '_default')); xml_set_element_handler($XMLParser, array($this, '_start'), array($this, '_end')); xml_set_external_entity_ref_handler($XMLParser, array($this, '_externalEntity')); xml_set_notation_decl_handler($XMLParser, array($this, '_notationDecl')); xml_set_processing_instruction_handler($XMLParser, array($this, '_processingInstruction')); xml_set_unparsed_entity_decl_handler($XMLParser, array($this, '_unparsedEntityDecl')); if (!xml_parse($XMLParser, $input, true)) { $errorCode = xml_get_error_code($XMLParser); $message = sprintf('%s. line: %d, char: %d'.($this->_tagStack ? ', tag: %s' : ''), xml_error_string($errorCode), xml_get_current_line_number($XMLParser), xml_get_current_column_number($XMLParser)+1, implode('->', $this->_tagStack)); xml_parser_free($XMLParser); throw new XmlToArrayException($message, $errorCode); } xml_parser_free($XMLParser); } /** * * Log messages (debugging purpose) * @param string $msg * @param int $type */ public function log($msg, $type = 2) { if (class_exists('Object')) { !($this->_Object instanceof Object) && $this->_Object = new Object(); return $this->_Object->log($msg, $type); } return false; } /** * Returns parsed XML as array structure * @return array */ public function toArray($simpleStructure = false) { return $this->_CurrentXmlToArrayNode->render($simpleStructure); } /** * Static entry point * @param string $input * @param bool $simpleStructure * @param int $maxDepth only parse XML to the provided depth * @return array * @throws XmlToArrayException */ public static function render($input, $simpleStructure = false, $maxDepth = 20) { $Instance = new XmlToArray($input, $maxDepth); return $Instance->toArray($simpleStructure); } /** * Handles cdata of the XML (user data between the tags) * @param resource $parser a resource handle of the XML parser * @param string $data */ private function _contents($parser, $data) { if (trim($data) !== '' && $this->_CurrentXmlToArrayNode instanceof XmlToArrayNode) $this->_CurrentXmlToArrayNode->setData($data); } /** * Default handler for all other XML sections not implemented as callback * @param resource $parser a resource handle of the XML parser * @param mixed $data * @throws XmlToArrayException */ private function _default($parser, $data) { $data = trim($data); if (in_array($data, get_html_translation_table(HTML_ENTITIES))) { $this->_CurrentXmlToArrayNode instanceof XmlToArrayNode && $this->_CurrentXmlToArrayNode->setData(html_entity_decode($data)); } elseif ($data && isset(self::$_htmlEntityExceptions[$data])) { $this->_CurrentXmlToArrayNode instanceof XmlToArrayNode && $this->_CurrentXmlToArrayNode->setData(self::$_htmlEntityExceptions[$data]); } elseif ($data && is_string($data) && strpos($data, '<!--') === false && strpos($data, '<?xml') === false) { if (getenv('sofortDebug') == 'true') { trigger_error('Default data handler used. The data passed was: '.$data, E_USER_WARNING); throw new XmlToArrayException('Unknown error occurred'); } } } /** * Handler for end tags * @param resource $parser a resource handle of the XML parser * @param string $name */ private function _end($parser, $name) { array_pop($this->_tagStack); if ($this->_CurrentXmlToArrayNode instanceof XmlToArrayNode) { $this->_CurrentXmlToArrayNode->setClosed(); $breaker = 0; // step up the stack and close all tags as long as current tag is reached in stack if ($this->_CurrentXmlToArrayNode->getName() != $name) { do { $this->_CurrentXmlToArrayNode = $this->_CurrentXmlToArrayNode->getParentXmlToArrayNode(); $this->_CurrentXmlToArrayNode->setClosed(); if ($breaker > 100) { trigger_error('Had to break out from endless loop.', E_USER_WARNING); break; } ++$breaker; } while($this->_CurrentXmlToArrayNode->getName() != $name); } elseif ($this->_CurrentXmlToArrayNode->hasParentXmlToArrayNode()) { $this->_CurrentXmlToArrayNode = $this->_CurrentXmlToArrayNode->getParentXmlToArrayNode(); } } } /** * * External Entity, no operation * @param unknown_type $parser * @param unknown_type $openEntityNames * @param unknown_type $base * @param unknown_type $systemId * @param unknown_type $publicId */ private function _externalEntity($parser , $openEntityNames , $base , $systemId , $publicId) { // noop } /** * * Notation Decl, no operation * @param unknown_type $parser * @param unknown_type $notationName * @param unknown_type $base * @param unknown_type $systemId * @param unknown_type $publicId */ private function _notationDecl($parser , $notationName , $base , $systemId , $publicId) { // noop } /** * * Processing Instruction, no operation * @param unknown_type $parser * @param unknown_type $target * @param unknown_type $data */ private function _processingInstruction($parser, $target, $data) { // noop } /** * * Unparsed Entity Decl, no operation * @param unknown_type $parser * @param unknown_type $entityName * @param unknown_type $base * @param unknown_type $systemId * @param unknown_type $publicd * @param unknown_type $notationName */ private function _unparsedEntityDecl($parser , $entityName , $base , $systemId , $publicd , $notationName) { // noop } /** * Handler for start tags * @param resource $parser a resource handle of the XML parser * @param string $name * @param array $attributes * @todo add check on max depth */ private function _start($parser, $name, $attributes) { $this->_tagStack[] = $name; if ($this->_maxDepth && count($this->_tagStack) > $this->_maxDepth) { throw new XmlToArrayException('Parse Error: max depth exceeded.', '7005'); } $XmlToArrayNode = new XmlToArrayNode($name, $attributes); if ($this->_CurrentXmlToArrayNode instanceof XmlToArrayNode && $this->_CurrentXmlToArrayNode->isOpen()) { $this->_CurrentXmlToArrayNode->addChild($XmlToArrayNode); $XmlToArrayNode->setParentXmlToArrayNode($this->_CurrentXmlToArrayNode); } $this->_CurrentXmlToArrayNode = $XmlToArrayNode; } } ?>