PortableInfobox/services/Parser/XmlParser.php

112 lines
3 KiB
PHP
Raw Normal View History

<?php
namespace Wikia\PortableInfobox\Parser;
class XmlParser {
protected $infoboxData;
protected $externalParser;
public function __construct( $infoboxData ) {
$this->infoboxData = $infoboxData;
}
/**
* @return mixed
*/
public function getExternalParser() {
return $this->externalParser;
}
/**
* @param mixed $externalParser
*/
public function setExternalParser( ExternalParser $externalParser ) {
$this->externalParser = $externalParser;
}
/**
* @param \SimpleXMLElement $xmlIterable
* @return array
*/
public function getDataFromNodes( \SimpleXMLElement $xmlIterable, $parentNode = null ) {
wfProfileIn(__METHOD__);
$data = [ ];
foreach ( $xmlIterable as $node ) {
$nodeHandler = $this->getNode( $node, $parentNode );
$nodeData = $nodeHandler->getData();
// add data if node is not empty or - when node can not be ignored when empty
if ( !$nodeHandler->isEmpty( $nodeData ) || !$nodeHandler->ignoreNodeWhenEmpty() ) {
2015-05-06 15:55:11 +00:00
$data[ ] = [
'type' => $nodeHandler->getType(),
'data' => $nodeData,
'isEmpty' => $nodeHandler->isEmpty( $nodeData )
2015-05-06 15:55:11 +00:00
];
}
}
wfProfileOut(__METHOD__);
return $data;
}
/**
2015-05-18 15:08:53 +00:00
* @param $xmlString
* @return array
2015-05-18 15:08:53 +00:00
* @throws XmlMarkupParseErrorException
*/
2015-05-08 12:28:56 +00:00
public function getDataFromXmlString( $xmlString ) {
wfProfileIn( __METHOD__ );
2015-05-18 15:08:53 +00:00
2015-05-18 13:36:04 +00:00
$global_libxml_setting = libxml_use_internal_errors();
2015-05-18 12:51:55 +00:00
libxml_use_internal_errors( true );
2015-05-08 12:28:56 +00:00
$xml = simplexml_load_string( $xmlString );
2015-05-18 15:08:53 +00:00
$errors = libxml_get_errors();
libxml_use_internal_errors( $global_libxml_setting );
2015-05-08 12:28:56 +00:00
if ( $xml === false ) {
2015-05-18 12:51:55 +00:00
foreach ( $errors as $xmlerror ) {
2015-05-19 14:01:53 +00:00
$this->logXmlParseError( $xmlerror->level, $xmlerror->code, trim( $xmlerror->message ) );
2015-05-18 12:51:55 +00:00
}
libxml_clear_errors();
2015-05-08 12:04:18 +00:00
throw new XmlMarkupParseErrorException();
2015-05-08 11:51:31 +00:00
}
2015-05-08 12:10:25 +00:00
$data = $this->getDataFromNodes( $xml );
wfProfileOut( __METHOD__ );
return $data;
}
protected function logXmlParseError( $level, $code, $message ) {
2015-05-19 10:49:35 +00:00
\Wikia\Logger\WikiaLogger::instance()->info( "PortableInfobox XML Parser problem", [
2015-05-19 14:01:53 +00:00
"level" => $level,
"code" => $code,
"message" => $message ] );
2015-05-19 10:49:35 +00:00
}
/**
* @param \SimpleXMLElement $xmlNode
* @param Node $parent
* @return \Wikia\PortableInfobox\Parser\Nodes\Node
*/
public function getNode( \SimpleXMLElement $xmlNode, $parent = null ) {
wfProfileIn(__METHOD__);
$tagType = $xmlNode->getName();
$className = 'Wikia\\PortableInfobox\\Parser\\Nodes\\' . 'Node' . ucfirst( strtolower( $tagType ) );
if ( class_exists( $className ) ) {
/* @var $instance \Wikia\PortableInfobox\Parser\Nodes\Node */
$instance = new $className( $xmlNode, $this->infoboxData );
if ( !empty( $this->externalParser ) ) {
$instance->setExternalParser( $this->externalParser );
}
if ( $parent ) {
$instance->setParent( $parent );
}
2015-05-20 08:39:31 +00:00
wfProfileOut( __METHOD__ );
return $instance;
}
2015-05-20 08:39:31 +00:00
wfProfileOut( __METHOD__ );
return new Nodes\NodeUnimplemented( $xmlNode, $this->infoboxData );
}
}
2015-05-08 12:04:18 +00:00
class XmlMarkupParseErrorException extends \Exception {
}