2015-04-27 14:05:31 +00:00
|
|
|
<?php
|
|
|
|
namespace Wikia\PortableInfobox\Parser;
|
|
|
|
|
|
|
|
class XmlParser {
|
|
|
|
|
|
|
|
protected $infoboxData;
|
|
|
|
protected $externalParser;
|
2015-05-29 14:37:35 +00:00
|
|
|
protected $xmlParseErrors;
|
2015-04-27 14:05:31 +00:00
|
|
|
|
|
|
|
public function __construct( $infoboxData ) {
|
|
|
|
$this->infoboxData = $infoboxData;
|
|
|
|
}
|
|
|
|
|
2015-05-29 14:37:35 +00:00
|
|
|
/**
|
|
|
|
* @return mixed
|
|
|
|
*/
|
|
|
|
public function getXmlParseErrors() {
|
|
|
|
return $this->xmlParseErrors;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param mixed $xmlParseErrors
|
|
|
|
*/
|
|
|
|
public function setXmlParseErrors( $xmlParseErrors ) {
|
|
|
|
$this->xmlParseErrors = $xmlParseErrors;
|
|
|
|
}
|
|
|
|
|
2015-04-27 14:05:31 +00:00
|
|
|
/**
|
|
|
|
* @return mixed
|
|
|
|
*/
|
|
|
|
public function getExternalParser() {
|
|
|
|
return $this->externalParser;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param mixed $externalParser
|
|
|
|
*/
|
|
|
|
public function setExternalParser( ExternalParser $externalParser ) {
|
|
|
|
$this->externalParser = $externalParser;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param \SimpleXMLElement $xmlIterable
|
|
|
|
* @return array
|
|
|
|
*/
|
2015-05-21 16:07:49 +00:00
|
|
|
public function getDataFromNodes( \SimpleXMLElement $xmlIterable, $parentNode = null ) {
|
2015-04-27 14:05:31 +00:00
|
|
|
wfProfileIn(__METHOD__);
|
|
|
|
$data = [ ];
|
|
|
|
foreach ( $xmlIterable as $node ) {
|
2015-05-21 16:07:49 +00:00
|
|
|
$nodeHandler = $this->getNode( $node, $parentNode );
|
2015-04-27 14:05:31 +00:00
|
|
|
$nodeData = $nodeHandler->getData();
|
2015-05-21 16:07:49 +00:00
|
|
|
// 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(),
|
2015-05-21 16:07:49 +00:00
|
|
|
'data' => $nodeData,
|
|
|
|
'isEmpty' => $nodeHandler->isEmpty( $nodeData )
|
2015-05-06 15:55:11 +00:00
|
|
|
];
|
|
|
|
}
|
2015-04-27 14:05:31 +00:00
|
|
|
}
|
|
|
|
wfProfileOut(__METHOD__);
|
|
|
|
return $data;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2015-05-18 15:08:53 +00:00
|
|
|
* @param $xmlString
|
2015-04-27 14:05:31 +00:00
|
|
|
* @return array
|
2015-05-18 15:08:53 +00:00
|
|
|
* @throws XmlMarkupParseErrorException
|
2015-04-27 14:05:31 +00:00
|
|
|
*/
|
2015-05-08 12:28:56 +00:00
|
|
|
public function getDataFromXmlString( $xmlString ) {
|
2015-04-27 14:05:31 +00:00
|
|
|
wfProfileIn( __METHOD__ );
|
2015-05-18 15:08:53 +00:00
|
|
|
|
2015-05-29 13:04:04 +00:00
|
|
|
$xml = $this->parseXmlString( $xmlString );
|
2015-05-08 12:10:25 +00:00
|
|
|
$data = $this->getDataFromNodes( $xml );
|
|
|
|
|
2015-04-27 14:05:31 +00:00
|
|
|
wfProfileOut( __METHOD__ );
|
|
|
|
return $data;
|
|
|
|
}
|
|
|
|
|
2015-05-29 13:04:04 +00:00
|
|
|
public function getInfoboxParams( $xmlString ) {
|
|
|
|
$xml = $this->parseXmlString( $xmlString );
|
|
|
|
$result = [];
|
|
|
|
foreach ( $xml->attributes() as $k => $v ) {
|
|
|
|
$result[$k] = (string) $v;
|
|
|
|
}
|
|
|
|
return $result;
|
|
|
|
}
|
|
|
|
|
2015-05-20 10:14:48 +00:00
|
|
|
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
|
|
|
}
|
|
|
|
|
2015-04-27 14:05:31 +00:00
|
|
|
/**
|
|
|
|
* @param \SimpleXMLElement $xmlNode
|
2015-05-21 16:07:49 +00:00
|
|
|
* @param Node $parent
|
2015-04-27 14:05:31 +00:00
|
|
|
* @return \Wikia\PortableInfobox\Parser\Nodes\Node
|
|
|
|
*/
|
2015-05-21 16:07:49 +00:00
|
|
|
public function getNode( \SimpleXMLElement $xmlNode, $parent = null ) {
|
2015-04-27 14:05:31 +00:00
|
|
|
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 );
|
|
|
|
}
|
2015-05-21 16:07:49 +00:00
|
|
|
if ( $parent ) {
|
|
|
|
$instance->setParent( $parent );
|
|
|
|
}
|
2015-05-20 08:39:31 +00:00
|
|
|
wfProfileOut( __METHOD__ );
|
2015-04-27 14:05:31 +00:00
|
|
|
return $instance;
|
|
|
|
}
|
2015-05-20 08:39:31 +00:00
|
|
|
wfProfileOut( __METHOD__ );
|
2015-04-27 14:05:31 +00:00
|
|
|
return new Nodes\NodeUnimplemented( $xmlNode, $this->infoboxData );
|
|
|
|
}
|
|
|
|
|
2015-05-29 13:04:04 +00:00
|
|
|
/**
|
|
|
|
* @param $xmlString
|
|
|
|
* @return \SimpleXMLElement
|
|
|
|
* @throws XmlMarkupParseErrorException
|
|
|
|
*/
|
|
|
|
protected function parseXmlString( $xmlString ) {
|
|
|
|
$global_libxml_setting = libxml_use_internal_errors();
|
|
|
|
libxml_use_internal_errors( true );
|
|
|
|
$xml = simplexml_load_string( $xmlString );
|
|
|
|
$errors = libxml_get_errors();
|
|
|
|
libxml_use_internal_errors( $global_libxml_setting );
|
|
|
|
|
|
|
|
if ( $xml === false ) {
|
|
|
|
foreach ( $errors as $xmlerror ) {
|
|
|
|
$this->logXmlParseError( $xmlerror->level, $xmlerror->code, trim( $xmlerror->message ) );
|
|
|
|
}
|
|
|
|
libxml_clear_errors();
|
2015-06-10 09:42:15 +00:00
|
|
|
$this->setXmlParseErrors( $errors );
|
2015-06-10 12:51:07 +00:00
|
|
|
throw new XmlMarkupParseErrorException( $this->getXmlParseErrors() );
|
2015-05-29 13:04:04 +00:00
|
|
|
}
|
|
|
|
return $xml;
|
|
|
|
}
|
|
|
|
|
2015-04-27 14:05:31 +00:00
|
|
|
}
|
2015-05-08 12:04:18 +00:00
|
|
|
|
|
|
|
class XmlMarkupParseErrorException extends \Exception {
|
2015-06-10 12:51:07 +00:00
|
|
|
private $errors;
|
|
|
|
|
|
|
|
public function __construct( $errors ) {
|
|
|
|
$this->errors = $errors;
|
|
|
|
return parent::__construct();
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getErrors() {
|
|
|
|
return $this->errors;
|
|
|
|
}
|
2015-05-21 18:38:33 +00:00
|
|
|
}
|