mirror of
https://github.com/Universal-Omega/PortableInfobox.git
synced 2024-11-15 11:59:56 +00:00
DAT-2875 nodes refactoring, xmlParser will be used only for parsing
This commit is contained in:
parent
ed16bffd63
commit
1abbaab514
|
@ -31,6 +31,7 @@ $wgInfoboxParserNodes = [
|
|||
'NodeGroup',
|
||||
'NodeHeader',
|
||||
'NodeImage',
|
||||
'NodeInfobox',
|
||||
'NodeData',
|
||||
'NodeTitle',
|
||||
'NodeUnimplemented'
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
use Wikia\PortableInfobox\Parser\Nodes;
|
||||
|
||||
class PortableInfoboxParserTagController extends WikiaController {
|
||||
const PARSER_TAG_NAME = 'infobox';
|
||||
const INFOBOXES_PROPERTY_NAME = 'infoboxes';
|
||||
|
@ -18,6 +20,7 @@ class PortableInfoboxParserTagController extends WikiaController {
|
|||
if ( !isset( static::$instance ) ) {
|
||||
static::$instance = new PortableInfoboxParserTagController();
|
||||
}
|
||||
|
||||
return static::$instance;
|
||||
}
|
||||
|
||||
|
@ -25,20 +28,25 @@ class PortableInfoboxParserTagController extends WikiaController {
|
|||
* @desc Parser hook: used to register parser tag in MW
|
||||
*
|
||||
* @param Parser $parser
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function parserTagInit( Parser $parser ) {
|
||||
$parser->setHook( self::PARSER_TAG_NAME, [ static::getInstance(), 'renderInfobox' ] );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parser hook: used to replace infobox markes put on rendering
|
||||
*
|
||||
* @param $text
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function replaceInfoboxMarkers( &$parser, &$text ) {
|
||||
$text = static::getInstance()->replaceMarkers( $text );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -46,27 +54,31 @@ class PortableInfoboxParserTagController extends WikiaController {
|
|||
* @param $markup
|
||||
* @param Parser $parser
|
||||
* @param PPFrame $frame
|
||||
* @param array $params
|
||||
*
|
||||
* @return string
|
||||
* @throws UnimplementedNodeException when node used in markup does not exists
|
||||
* @throws XmlMarkupParseErrorException xml not well formatted
|
||||
*/
|
||||
public function render( $markup, Parser $parser, PPFrame $frame, $params = null ) {
|
||||
$infoboxParser = new Wikia\PortableInfobox\Parser\XmlParser( $this->getFrameParams( $frame ) );
|
||||
$infoboxParser->setExternalParser( new Wikia\PortableInfobox\Parser\MediaWikiParserService( $parser, $frame ) );
|
||||
$infoboxNode = Wikia\PortableInfobox\Parser\Nodes\NodeFactory::newFromXML(
|
||||
$markup, $this->getFrameParams( $frame ) );
|
||||
$infoboxNode->setExternalParser( new Wikia\PortableInfobox\Parser\MediaWikiParserService( $parser, $frame ) );
|
||||
|
||||
//get params if not overridden
|
||||
if ( !isset( $params ) ) {
|
||||
$params = $infoboxParser->getInfoboxParams( $markup );
|
||||
$params = ( $infoboxNode instanceof Nodes\NodeInfobox ) ? $infoboxNode->getParams() : [ ];
|
||||
}
|
||||
$data = $infoboxParser->getDataFromXmlString( $markup );
|
||||
$data = $infoboxNode->getData()[ 'value' ];
|
||||
$data = array_values( array_filter( $data, function ( $item ) {
|
||||
return !$item[ 'isEmpty' ];
|
||||
} ) );
|
||||
//save for later api usage
|
||||
$this->saveToParserOutput( $parser->getOutput(), $data );
|
||||
|
||||
//filter out empty nodes
|
||||
$render = array_filter( $data, function($item) { return !$item['isEmpty']; } );
|
||||
|
||||
$theme = $this->getThemeWithDefault( $params, $frame );
|
||||
return ( new PortableInfoboxRenderService() )->renderInfobox( $render, $theme );
|
||||
|
||||
return ( new PortableInfoboxRenderService() )->renderInfobox( $data, $theme );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -76,6 +88,7 @@ class PortableInfoboxParserTagController extends WikiaController {
|
|||
* @param Array $params
|
||||
* @param Parser $parser
|
||||
* @param PPFrame $frame
|
||||
*
|
||||
* @returns String $html
|
||||
*/
|
||||
public function renderInfobox( $text, $params, $parser, $frame ) {
|
||||
|
@ -98,6 +111,7 @@ class PortableInfoboxParserTagController extends WikiaController {
|
|||
|
||||
$marker = $parser->uniqPrefix() . "-" . self::PARSER_TAG_NAME . "-{$this->markerNumber}\x7f-QINU";
|
||||
$this->markers[ $marker ] = $renderedValue;
|
||||
|
||||
return [ $marker, 'markerType' => 'nowiki' ];
|
||||
}
|
||||
|
||||
|
@ -115,12 +129,14 @@ class PortableInfoboxParserTagController extends WikiaController {
|
|||
|
||||
private function handleError( $message ) {
|
||||
$renderedValue = '<strong class="error"> ' . $message . '</strong>';
|
||||
|
||||
return [ $renderedValue, 'markerType' => 'nowiki' ];
|
||||
}
|
||||
|
||||
private function getThemeWithDefault( $params, PPFrame $frame ) {
|
||||
$value = isset( $params[ 'theme-source' ] ) ? $frame->getArgument( $params[ 'theme-source' ] ) : false;
|
||||
$themeName = $this->getThemeName( $params, $value );
|
||||
|
||||
//make sure no whitespaces, prevents side effects
|
||||
return Sanitizer::escapeClass( self::INFOBOX_THEME_PREFIX . preg_replace( '|\s+|s', '-', $themeName ) );
|
||||
}
|
||||
|
@ -133,7 +149,9 @@ class PortableInfoboxParserTagController extends WikiaController {
|
|||
|
||||
/**
|
||||
* Function ensures that arrays are used for merging
|
||||
*
|
||||
* @param PPFrame $frame
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getFrameParams( PPFrame $frame ) {
|
||||
|
|
|
@ -13,7 +13,6 @@ class Node {
|
|||
const LABEL_TAG_NAME = 'label';
|
||||
|
||||
protected $xmlNode;
|
||||
protected $parent = null;
|
||||
protected $data = null;
|
||||
|
||||
/* @var $externalParser ExternalParser */
|
||||
|
@ -24,24 +23,6 @@ class Node {
|
|||
$this->infoboxData = $infoboxData;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getParent() {
|
||||
return $this->parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $parent
|
||||
*/
|
||||
public function setParent( Node $parent ) {
|
||||
$this->parent = $parent;
|
||||
}
|
||||
|
||||
public function ignoreNodeWhenEmpty() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getSource() {
|
||||
$source = $this->getXmlAttribute( $this->xmlNode, self::DATA_SRC_ATTR_NAME );
|
||||
if ( $this->xmlNode->{self::DEFAULT_TAG_NAME} ) {
|
||||
|
@ -66,12 +47,15 @@ class Node {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param mixed $externalParser
|
||||
* @param ExternalParser|null $externalParser
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setExternalParser( ExternalParser $externalParser ) {
|
||||
$this->externalParser = $externalParser;
|
||||
public function setExternalParser( $externalParser ) {
|
||||
// we can pass anything, and ignore it if not ExternalParser instance
|
||||
if ( $externalParser instanceof ExternalParser ) {
|
||||
$this->externalParser = $externalParser;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
@ -104,6 +88,22 @@ class Node {
|
|||
return !( isset( $data ) ) || ( empty( $data ) && $data != '0' );
|
||||
}
|
||||
|
||||
protected function getChildNodes() {
|
||||
$result = [ ];
|
||||
foreach ( $this->xmlNode as $child ) {
|
||||
$node = NodeFactory::newFromSimpleXml( $child, $this->infoboxData )
|
||||
->setExternalParser( $this->externalParser );
|
||||
$result[ ] = [
|
||||
'type' => $node->getType(),
|
||||
'data' => $node->getData(),
|
||||
'isEmpty' => $node->isEmpty(),
|
||||
'source' => $node->getSource()
|
||||
];
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
protected function getValueWithDefault( \SimpleXMLElement $xmlNode ) {
|
||||
$source = $this->getXmlAttribute( $xmlNode, self::DATA_SRC_ATTR_NAME );
|
||||
$value = null;
|
||||
|
|
|
@ -1,17 +1,11 @@
|
|||
<?php
|
||||
namespace Wikia\PortableInfobox\Parser\Nodes;
|
||||
|
||||
use Wikia\PortableInfobox\Parser\XmlParser;
|
||||
|
||||
class NodeComparison extends Node {
|
||||
|
||||
public function getData() {
|
||||
if ( !isset( $this->data ) ) {
|
||||
$nodeFactory = new XmlParser( $this->infoboxData );
|
||||
if ( $this->externalParser ) {
|
||||
$nodeFactory->setExternalParser( $this->externalParser );
|
||||
}
|
||||
$this->data = [ 'value' => $nodeFactory->getDataFromNodes( $this->xmlNode, $this ) ];
|
||||
$this->data = [ 'value' => $this->getChildNodes() ];
|
||||
}
|
||||
|
||||
return $this->data;
|
||||
|
@ -27,4 +21,17 @@ class NodeComparison extends Node {
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getSource() {
|
||||
$data = $this->getData();
|
||||
$result = [ ];
|
||||
foreach ( $data[ 'value' ] as $item ) {
|
||||
if ( isset( $item[ 'source' ] ) ) {
|
||||
$source = !is_array( $item[ 'source' ] ) ? [ $item[ 'source' ] ] : $item[ 'source' ];
|
||||
$result = array_merge( $result, $source );
|
||||
}
|
||||
}
|
||||
|
||||
return array_unique( $result );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,17 +5,17 @@ use Wikia\PortableInfobox\Helpers\SimpleXmlUtil;
|
|||
|
||||
class NodeData extends Node {
|
||||
|
||||
public function ignoreNodeWhenEmpty() {
|
||||
$parent = $this->getParent();
|
||||
if ( $parent instanceof NodeSet ) {
|
||||
if ( $parent->getParent() instanceof NodeComparison ) {
|
||||
// data tag inside comparison tag can not be ignored
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
// public function ignoreNodeWhenEmpty() {
|
||||
// $parent = $this->getParent();
|
||||
// if ( $parent instanceof NodeSet ) {
|
||||
// if ( $parent->getParent() instanceof NodeComparison ) {
|
||||
// // data tag inside comparison tag can not be ignored
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// return true;
|
||||
// }
|
||||
|
||||
public function getData() {
|
||||
if ( !isset( $this->data ) ) {
|
||||
|
|
|
@ -9,19 +9,37 @@
|
|||
namespace Wikia\PortableInfobox\Parser\Nodes;
|
||||
|
||||
|
||||
use Wikia\PortableInfobox\Parser\XmlParser;
|
||||
|
||||
class NodeFactory {
|
||||
|
||||
public static function newFromSimpleXml( \SimpleXMLElement $xmlNode, array $data = [] ) {
|
||||
wfProfileIn(__METHOD__);
|
||||
public static function newFromXML( $text, array $data = [ ] ) {
|
||||
return self::getInstance( XmlParser::parseXmlString( $text ), $data );
|
||||
}
|
||||
|
||||
public static function newFromSimpleXml( \SimpleXMLElement $xmlNode, array $data = [ ] ) {
|
||||
return self::getInstance( $xmlNode, $data );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \SimpleXMLElement $xmlNode
|
||||
* @param array $data
|
||||
*
|
||||
* @return Node|NodeUnimplemented
|
||||
*/
|
||||
protected static function getInstance( \SimpleXMLElement $xmlNode, array $data ) {
|
||||
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, $data );
|
||||
wfProfileOut( __METHOD__ );
|
||||
|
||||
return $instance;
|
||||
}
|
||||
wfProfileOut( __METHOD__ );
|
||||
|
||||
return new NodeUnimplemented( $xmlNode, $data );
|
||||
}
|
||||
|
||||
|
|
|
@ -1,17 +1,11 @@
|
|||
<?php
|
||||
namespace Wikia\PortableInfobox\Parser\Nodes;
|
||||
|
||||
use Wikia\PortableInfobox\Parser\XmlParser;
|
||||
|
||||
class NodeGroup extends Node {
|
||||
|
||||
public function getData() {
|
||||
if ( !isset( $this->data ) ) {
|
||||
$nodeFactory = new XmlParser( $this->infoboxData );
|
||||
if ( $this->externalParser ) {
|
||||
$nodeFactory->setExternalParser( $this->externalParser );
|
||||
}
|
||||
$this->data = [ 'value' => $nodeFactory->getDataFromNodes( $this->xmlNode, $this ) ];
|
||||
$this->data = [ 'value' => $this->getChildNodes() ];
|
||||
}
|
||||
|
||||
return $this->data;
|
||||
|
@ -27,4 +21,17 @@ class NodeGroup extends Node {
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getSource() {
|
||||
$data = $this->getData();
|
||||
$result = [ ];
|
||||
foreach ( $data[ 'value' ] as $item ) {
|
||||
if ( isset( $item[ 'source' ] ) ) {
|
||||
$source = !is_array( $item[ 'source' ] ) ? [ $item[ 'source' ] ] : $item[ 'source' ];
|
||||
$result = array_merge( $result, $source );
|
||||
}
|
||||
}
|
||||
|
||||
return array_unique( $result );
|
||||
}
|
||||
}
|
||||
|
|
51
services/Parser/Nodes/NodeInfobox.php
Normal file
51
services/Parser/Nodes/NodeInfobox.php
Normal file
|
@ -0,0 +1,51 @@
|
|||
<?php
|
||||
namespace Wikia\PortableInfobox\Parser\Nodes;
|
||||
|
||||
class NodeInfobox extends Node {
|
||||
|
||||
protected $params;
|
||||
|
||||
public function getData() {
|
||||
if ( !isset( $this->data ) ) {
|
||||
$this->data = [ 'value' => $this->getChildNodes() ];
|
||||
}
|
||||
|
||||
return $this->data;
|
||||
}
|
||||
|
||||
public function isEmpty() {
|
||||
$data = $this->getData();
|
||||
foreach ( $data[ 'value' ] as $item ) {
|
||||
if ( $item[ 'isEmpty' ] == false ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getParams() {
|
||||
if ( !isset( $this->params ) ) {
|
||||
$result = [ ];
|
||||
foreach ( $this->xmlNode->attributes() as $k => $v ) {
|
||||
$result[ $k ] = (string)$v;
|
||||
}
|
||||
$this->params = $result;
|
||||
}
|
||||
|
||||
return $this->params;
|
||||
}
|
||||
|
||||
public function getSource() {
|
||||
$data = $this->getData();
|
||||
$result = [ ];
|
||||
foreach ( $data[ 'value' ] as $item ) {
|
||||
if ( isset( $item[ 'source' ] ) ) {
|
||||
$source = !is_array( $item[ 'source' ] ) ? [ $item[ 'source' ] ] : $item[ 'source' ];
|
||||
$result = array_merge( $result, $source );
|
||||
}
|
||||
}
|
||||
|
||||
return array_unique( $result );
|
||||
}
|
||||
}
|
|
@ -1,17 +1,11 @@
|
|||
<?php
|
||||
namespace Wikia\PortableInfobox\Parser\Nodes;
|
||||
|
||||
use Wikia\PortableInfobox\Parser\XmlParser;
|
||||
|
||||
class NodeSet extends Node {
|
||||
|
||||
public function getData() {
|
||||
if ( !isset( $this->data ) ) {
|
||||
$nodeFactory = new XmlParser( $this->infoboxData );
|
||||
if ( $this->externalParser ) {
|
||||
$nodeFactory->setExternalParser( $this->externalParser );
|
||||
}
|
||||
$this->data = [ 'value' => $nodeFactory->getDataFromNodes( $this->xmlNode, $this ) ];
|
||||
$this->data = [ 'value' => $this->getChildNodes() ];
|
||||
}
|
||||
|
||||
return $this->data;
|
||||
|
@ -27,4 +21,17 @@ class NodeSet extends Node {
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getSource() {
|
||||
$data = $this->getData();
|
||||
$result = [ ];
|
||||
foreach ( $data[ 'value' ] as $item ) {
|
||||
if ( isset( $item[ 'source' ] ) ) {
|
||||
$source = !is_array( $item[ 'source' ] ) ? [ $item[ 'source' ] ] : $item[ 'source' ];
|
||||
$result = array_merge( $result, $source );
|
||||
}
|
||||
}
|
||||
|
||||
return array_unique( $result );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,96 +1,18 @@
|
|||
<?php
|
||||
namespace Wikia\PortableInfobox\Parser;
|
||||
|
||||
use Wikia\Logger\WikiaLogger;
|
||||
|
||||
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 = Nodes\NodeFactory::newFromSimpleXml( $node, $this->infoboxData );
|
||||
if ( $this->getExternalParser() ) {
|
||||
$nodeHandler->setExternalParser( $this->getExternalParser() );
|
||||
}
|
||||
if ( $parentNode ) {
|
||||
$nodeHandler->setParent( $parentNode );
|
||||
}
|
||||
$nodeData = $nodeHandler->getData();
|
||||
// add data if node is not empty or - when node can not be ignored when empty
|
||||
if ( !$nodeHandler->isEmpty() || !$nodeHandler->ignoreNodeWhenEmpty() ) {
|
||||
$data[ ] = [
|
||||
'type' => $nodeHandler->getType(),
|
||||
'data' => $nodeData,
|
||||
'isEmpty' => $nodeHandler->isEmpty( $nodeData ),
|
||||
'source' => $nodeHandler->getSource()
|
||||
];
|
||||
}
|
||||
}
|
||||
wfProfileOut(__METHOD__);
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $xmlString
|
||||
* @return array
|
||||
* @throws XmlMarkupParseErrorException
|
||||
*/
|
||||
public function getDataFromXmlString( $xmlString ) {
|
||||
wfProfileIn( __METHOD__ );
|
||||
|
||||
$xml = $this->parseXmlString( $xmlString );
|
||||
$data = $this->getDataFromNodes( $xml );
|
||||
|
||||
wfProfileOut( __METHOD__ );
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function getInfoboxParams( $xmlString ) {
|
||||
$xml = $this->parseXmlString( $xmlString );
|
||||
$result = [];
|
||||
foreach ( $xml->attributes() as $k => $v ) {
|
||||
$result[$k] = (string) $v;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
protected function logXmlParseError( $level, $code, $message ) {
|
||||
\Wikia\Logger\WikiaLogger::instance()->info( "PortableInfobox XML Parser problem", [
|
||||
"level" => $level,
|
||||
"code" => $code,
|
||||
"message" => $message ] );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $xmlString
|
||||
* @param string $xmlString XML to parse
|
||||
*
|
||||
* @param array $errors this array will be filled with errors if any found
|
||||
*
|
||||
* @return \SimpleXMLElement
|
||||
* @throws XmlMarkupParseErrorException
|
||||
*/
|
||||
protected function parseXmlString( $xmlString ) {
|
||||
public static function parseXmlString( $xmlString, &$errors = [ ] ) {
|
||||
$global_libxml_setting = libxml_use_internal_errors();
|
||||
libxml_use_internal_errors( true );
|
||||
$xml = simplexml_load_string( $xmlString );
|
||||
|
@ -99,14 +21,22 @@ class XmlParser {
|
|||
|
||||
if ( $xml === false ) {
|
||||
foreach ( $errors as $xmlerror ) {
|
||||
$this->logXmlParseError( $xmlerror->level, $xmlerror->code, trim( $xmlerror->message ) );
|
||||
self::logXmlParseError( $xmlerror->level, $xmlerror->code, trim( $xmlerror->message ) );
|
||||
}
|
||||
libxml_clear_errors();
|
||||
throw new XmlMarkupParseErrorException();
|
||||
}
|
||||
|
||||
return $xml;
|
||||
}
|
||||
|
||||
protected static function logXmlParseError( $level, $code, $message ) {
|
||||
WikiaLogger::instance()->info( "PortableInfobox XML Parser problem", [
|
||||
"level" => $level,
|
||||
"code" => $code,
|
||||
"message" => $message ] );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class XmlMarkupParseErrorException extends \Exception {
|
||||
|
|
|
@ -7,12 +7,9 @@ class XmlParserTest extends WikiaBaseTest {
|
|||
parent::setUp();
|
||||
}
|
||||
|
||||
/*
|
||||
public function testIsEmpty() {
|
||||
$parser = new \Wikia\PortableInfobox\Parser\XmlParser( [
|
||||
'elem2' => 'ELEM2',
|
||||
'lado2' => 'LALALA',
|
||||
'nonempty' => '111'
|
||||
] );
|
||||
$parser = new \Wikia\PortableInfobox\Parser\XmlParser( );
|
||||
$markup = '
|
||||
<infobox>
|
||||
<comparison>
|
||||
|
@ -27,18 +24,18 @@ class XmlParserTest extends WikiaBaseTest {
|
|||
</infobox>
|
||||
';
|
||||
$data = $parser->getDataFromXmlString( $markup );
|
||||
$this->assertTrue( $data[0]['data']['value'][0]['data']['value'][0]['data']['value'] == 'Combatientes' );
|
||||
\Wikia\PortableInfobox\Parser\Nodes\NodeFactory::newFromXML( $markup, [
|
||||
'elem2' => 'ELEM2',
|
||||
'lado2' => 'LALALA',
|
||||
'nonempty' => '111'
|
||||
] );
|
||||
$this->assertTrue( $data[ 0 ][ 'data' ][ 'value' ][ 0 ][ 'data' ][ 'value' ][ 0 ][ 'data' ][ 'value' ] == 'Combatientes' );
|
||||
// '111' should be at [1] position, becasue <data source="empty"> should be ommited
|
||||
$this->assertTrue( $data[1]['data']['value'] == '111' );
|
||||
$this->assertTrue( $data[ 1 ][ 'data' ][ 'value' ] == '111' );
|
||||
}
|
||||
|
||||
public function testExternalParser() {
|
||||
$parser = new \Wikia\PortableInfobox\Parser\XmlParser( [
|
||||
'elem2' => 'ELEM2',
|
||||
'lado2' => 'LALALA'
|
||||
] );
|
||||
$externalParser = new \Wikia\PortableInfobox\Parser\DummyParser();
|
||||
$parser->setExternalParser( $externalParser );
|
||||
$markup = '
|
||||
<infobox>
|
||||
<title><default>ABB</default></title>
|
||||
|
@ -52,22 +49,28 @@ class XmlParserTest extends WikiaBaseTest {
|
|||
<footer>[[aaa]]</footer>
|
||||
</infobox>
|
||||
';
|
||||
$data = $parser->getDataFromXmlString( $markup );
|
||||
$xml = \Wikia\PortableInfobox\Parser\XmlParser::parseXmlString( $markup );
|
||||
$infobox = Wikia\PortableInfobox\Parser\Nodes\NodeFactory::newFromSimpleXml( $xml, [
|
||||
'elem2' => 'ELEM2',
|
||||
'lado2' => 'LALALA'
|
||||
] );
|
||||
$infobox->setExternalParser( $externalParser );
|
||||
$data = $infobox->getData()['value'];
|
||||
|
||||
$this->assertTrue( $data[0]['data']['value'] == 'parseRecursive(ABB)' );
|
||||
$this->assertTrue( $data[ 0 ][ 'data' ][ 'value' ] == 'parseRecursive(ABB)' );
|
||||
// ledo1 ommited, ledo2 at [1] position
|
||||
$this->assertTrue( $data[1]['data']['value'][0]['data']['value'][2]['data']['value'] == 'parseRecursive(LALALA)' );
|
||||
$this->assertTrue( $data[ 1 ][ 'data' ][ 'value' ][ 0 ][ 'data' ][ 'value' ][ 2 ][ 'data' ][ 'value' ] == 'parseRecursive(LALALA)' );
|
||||
}
|
||||
|
||||
public function testNotProvidingDataSource() {
|
||||
$xmlParser = new \Wikia\PortableInfobox\Parser\XmlParser( ['a'=>'1'] );
|
||||
$xmlParser = new \Wikia\PortableInfobox\Parser\XmlParser( [ 'a' => '1' ] );
|
||||
|
||||
$data1 = $xmlParser->getDataFromXmlString('<infobox><data source="b" /><data source="a" /></infobox>');
|
||||
$this->assertTrue( $data1[0]['data']['value'] == '1', 'Data with empty source "b" should be ignored' );
|
||||
$data1 = $xmlParser->getDataFromXmlString( '<infobox><data source="b" /><data source="a" /></infobox>' );
|
||||
$this->assertTrue( $data1[ 0 ][ 'data' ][ 'value' ] == '1', 'Data with empty source "b" should be ignored' );
|
||||
}
|
||||
|
||||
public function testNotProvidingDataSourceInsideComparison() {
|
||||
$xmlParser = new \Wikia\PortableInfobox\Parser\XmlParser( ['a'=>'1'] );
|
||||
$xmlParser = new \Wikia\PortableInfobox\Parser\XmlParser( [ 'a' => '1' ] );
|
||||
|
||||
$data1 = $xmlParser->getDataFromXmlString( '<infobox>
|
||||
<comparison>
|
||||
|
@ -78,54 +81,35 @@ class XmlParserTest extends WikiaBaseTest {
|
|||
</comparison>
|
||||
</infobox>' );
|
||||
|
||||
$setElement = $data1[0]['data']['value'][0]['data']['value'];
|
||||
$setElement = $data1[ 0 ][ 'data' ][ 'value' ][ 0 ][ 'data' ][ 'value' ];
|
||||
|
||||
//Data with empty source "b" should not be ignored inside comparison:
|
||||
$this->assertTrue( $setElement[0]['data']['value'] == '', 'Data with empty source "b" inside comparison' );
|
||||
$this->assertTrue( $setElement[0]['isEmpty'] == true );
|
||||
$this->assertTrue( $setElement[ 0 ][ 'data' ][ 'value' ] == '', 'Data with empty source "b" inside comparison' );
|
||||
$this->assertTrue( $setElement[ 0 ][ 'isEmpty' ] == true );
|
||||
|
||||
$this->assertTrue( $setElement[1]['data']['value'] == '1', '' );
|
||||
$this->assertTrue( $setElement[ 1 ][ 'data' ][ 'value' ] == '1', '' );
|
||||
}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @dataProvider errorHandlingDataProvider
|
||||
*/
|
||||
public function testErrorHandling( $markup, $expectedErrors ) {
|
||||
|
||||
$parser = $this->getMockBuilder( 'Wikia\PortableInfobox\Parser\XmlParser' )
|
||||
->setConstructorArgs( [ [] ] )
|
||||
->setMethods( [ 'logXmlParseError' ] )
|
||||
->getMock();
|
||||
->setMethods( [ 'logXmlParseError' ] )
|
||||
->getMock();
|
||||
|
||||
|
||||
$errorCodes = [];
|
||||
$errorMsgs = [];
|
||||
|
||||
// Let's gather error codes and messages that comes to logXmlParseError function:
|
||||
$parser->expects($this->any())->method( 'logXmlParseError' )->will( $this->returnCallback(
|
||||
function( $level, $code, $msg ) use ( &$errorCodes, &$errorMsgs ) {
|
||||
$errorCodes[] = $code;
|
||||
$errorMsgs[] = $msg;
|
||||
}
|
||||
));
|
||||
|
||||
$throwsException = false;
|
||||
|
||||
// getDataFromXmlString should throw an exception, but we want to proceed in order to check parameters
|
||||
$errors = [ ];
|
||||
// parseXmlString should throw an exception, but we want to proceed in order to check parameters
|
||||
// from logXmlParseError
|
||||
try {
|
||||
$data = $parser->getDataFromXmlString( $markup );
|
||||
$data = $parser->parseXmlString( $markup, $errors );
|
||||
} catch ( \Wikia\PortableInfobox\Parser\XmlMarkupParseErrorException $e ) {
|
||||
$throwsException = true;
|
||||
}
|
||||
|
||||
$this->assertTrue( $throwsException );
|
||||
|
||||
// lets compare expectedErrors with real errors
|
||||
foreach ( $expectedErrors as $expectedError ) {
|
||||
$this->assertTrue( in_array( $expectedError['code'], $errorCodes ) );
|
||||
$this->assertTrue( in_array( $expectedError['msg'], $errorMsgs ) );
|
||||
}
|
||||
$this->assertEquals( $expectedErrors, array_map( function ( LibXMLError $error ) {
|
||||
return [ 'level' => $error->level, 'code' => $error->code, 'msg' => trim( $error->message ) ];
|
||||
}, $errors ) );
|
||||
}
|
||||
|
||||
public function errorHandlingDataProvider() {
|
||||
|
@ -135,56 +119,57 @@ class XmlParserTest extends WikiaBaseTest {
|
|||
* http://www.xmlsoft.org/html/libxml-xmlerror.html
|
||||
*/
|
||||
return [
|
||||
[
|
||||
'<data>d</dat/a>',
|
||||
[
|
||||
'<data>d</dat/a>',
|
||||
[
|
||||
['level' => LIBXML_ERR_FATAL, 'code' => 73, 'msg' => "expected '>'"],
|
||||
['level' => LIBXML_ERR_FATAL, 'code' => 76, 'msg' => "Opening and ending tag mismatch: data line 1 and dat"],
|
||||
['level' => LIBXML_ERR_FATAL, 'code' => 5, 'msg' => "Extra content at the end of the document"],
|
||||
]
|
||||
],
|
||||
[
|
||||
'<data> x </data></data>',
|
||||
[
|
||||
['level' => LIBXML_ERR_FATAL, 'code' => 5, 'msg' => "Extra content at the end of the document"],
|
||||
]
|
||||
],
|
||||
[
|
||||
'<data> > ddd < a ></data>',
|
||||
[
|
||||
['level' => LIBXML_ERR_FATAL, 'code' => 68, 'msg' => "StartTag: invalid element name"],
|
||||
]
|
||||
],
|
||||
[
|
||||
'<data>',
|
||||
[
|
||||
['level' => LIBXML_ERR_FATAL, 'code' => 77, 'msg' => "Premature end of data in tag data line 1"],
|
||||
]
|
||||
],
|
||||
[
|
||||
'<infobox><data source=caption></infobox>',
|
||||
[
|
||||
['level' => LIBXML_ERR_FATAL, 'code' => 39, 'msg' => "AttValue: \" or ' expected"],
|
||||
['level' => LIBXML_ERR_FATAL, 'code' => 65, 'msg' => "attributes construct error"],
|
||||
['level' => LIBXML_ERR_FATAL, 'code' => 73, 'msg' => "Couldn't find end of Start Tag data line 1"],
|
||||
]
|
||||
],
|
||||
[
|
||||
'<infobox><data source="caption"></infobox>',
|
||||
[
|
||||
['level' => LIBXML_ERR_FATAL, 'code' => 76, 'msg' => "Opening and ending tag mismatch: data line 1 and infobox"],
|
||||
]
|
||||
],
|
||||
[
|
||||
'<infobox><data source="caption></data></infobox>',
|
||||
[
|
||||
['level' => LIBXML_ERR_FATAL, 'code' => 38, 'msg' => "Unescaped '<' not allowed in attributes values"],
|
||||
['level' => LIBXML_ERR_FATAL, 'code' => 65, 'msg' => "attributes construct error"],
|
||||
['level' => LIBXML_ERR_FATAL, 'code' => 73, 'msg' => "Couldn't find end of Start Tag data line 1"],
|
||||
['level' => LIBXML_ERR_FATAL, 'code' => 76, 'msg' => "Opening and ending tag mismatch: infobox line 1 and data"],
|
||||
['level' => LIBXML_ERR_FATAL, 'code' => 5, 'msg' => "Extra content at the end of the document"]
|
||||
]
|
||||
[ 'level' => LIBXML_ERR_FATAL, 'code' => 73, 'msg' => "expected '>'" ],
|
||||
[ 'level' => LIBXML_ERR_FATAL, 'code' => 76, 'msg' => "Opening and ending tag mismatch: data line 1 and dat" ],
|
||||
[ 'level' => LIBXML_ERR_FATAL, 'code' => 5, 'msg' => "Extra content at the end of the document" ],
|
||||
]
|
||||
],
|
||||
[
|
||||
'<data> x </data></data>',
|
||||
[
|
||||
[ 'level' => LIBXML_ERR_FATAL, 'code' => 5, 'msg' => "Extra content at the end of the document" ],
|
||||
]
|
||||
],
|
||||
[
|
||||
'<data> > ddd < a ></data>',
|
||||
[
|
||||
[ 'level' => LIBXML_ERR_FATAL, 'code' => 68, 'msg' => "StartTag: invalid element name" ],
|
||||
]
|
||||
],
|
||||
[
|
||||
'<data>',
|
||||
[
|
||||
[ 'level' => LIBXML_ERR_FATAL, 'code' => 77, 'msg' => "Premature end of data in tag data line 1" ],
|
||||
]
|
||||
],
|
||||
[
|
||||
'<infobox><data source=caption></infobox>',
|
||||
[
|
||||
[ 'level' => LIBXML_ERR_FATAL, 'code' => 39, 'msg' => "AttValue: \" or ' expected" ],
|
||||
[ 'level' => LIBXML_ERR_FATAL, 'code' => 65, 'msg' => "attributes construct error" ],
|
||||
[ 'level' => LIBXML_ERR_FATAL, 'code' => 73, 'msg' => "Couldn't find end of Start Tag data line 1" ],
|
||||
]
|
||||
],
|
||||
[
|
||||
'<infobox><data source="caption"></infobox>',
|
||||
[
|
||||
[ 'level' => LIBXML_ERR_FATAL, 'code' => 76, 'msg' => "Opening and ending tag mismatch: data line 1 and infobox" ],
|
||||
[ 'level' => LIBXML_ERR_FATAL, 'code' => 77, 'msg' => "Premature end of data in tag infobox line 1" ],
|
||||
]
|
||||
],
|
||||
[
|
||||
'<infobox><data source="caption></data></infobox>',
|
||||
[
|
||||
[ 'level' => LIBXML_ERR_FATAL, 'code' => 38, 'msg' => "Unescaped '<' not allowed in attributes values" ],
|
||||
[ 'level' => LIBXML_ERR_FATAL, 'code' => 65, 'msg' => "attributes construct error" ],
|
||||
[ 'level' => LIBXML_ERR_FATAL, 'code' => 73, 'msg' => "Couldn't find end of Start Tag data line 1" ],
|
||||
[ 'level' => LIBXML_ERR_FATAL, 'code' => 76, 'msg' => "Opening and ending tag mismatch: infobox line 1 and data" ],
|
||||
[ 'level' => LIBXML_ERR_FATAL, 'code' => 5, 'msg' => "Extra content at the end of the document" ]
|
||||
]
|
||||
]
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue